AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

MXNet 视频 I/O 读取速度提升 18 倍的优化策略

  • 2020-02-24
  • 本文字数:2116 字

    阅读完需:约 7 分钟

MXNet 视频I/O读取速度提升18倍的优化策略

大规模视频数据的模型训练中,视频读取时间严重影响模型的训练速度。MXNet 仅提供读取图像的迭代器,没有提供读取视频的迭代器,本文提出一种优化策略,可以将训练速度提升 18 倍。

一、前言

大规模视频数据的模型训练中,视频读取时间严重影响模型的训练速度。MXNet 仅提供读取图像的迭代器,没有提供读取视频的迭代器。传统方法基于 opencv 或 skimage 直接读取原始图像,速度较慢。我们将原始图像打包成 Rec 格式,然后使用 ImageRecordIter 迭代器构建新的迭代器,具体代码实现见 MTCloudVision/mxnet-videoio(https://github.com/MTCloudVision/mxnet-videoio)。使用4个Titan 1080ti GPU,优化后训练速度提升了~18 倍。


MXNet 框架使用迭代器器模式实现读取硬盘中图像的 I/O 接口。目前 MXNet 官方提供的读取图像的迭代器有:image.ImageIter、io.ImageRecordIter(io.ImageRecordUInt8Iter)、io.MNISTIter。MXNet 的 I/O 接口可扩展性强,支持开发者对于图像进行打包,生成用于训练模型的迭代器。目前 MXNet 没有提供读取视频的 I/O 接口。


本文首先比较 MXNet 不同接口的图像 I/O 性能;然后在 Rec 图像迭代器基础上,实现视频 I/O 迭代器,同时对比了优化前后的性能指标。

二、图像 I/O 接口性能对比

MXNet 三种图像 I/O 迭代器:


  • io.MNISTIter:该接口是为 MNIST 数据集设计的,仅支持读取 MNIST 图像数据,数据增强格式支持有限;

  • io.ImageRecordIter:支持 Rec 格式的数据读取。该接口同时支持多种图像增强方式。基于 C++实现,执行效率较高,读取速度较快。缺点是需要将所有训练图像一次性打包成 Rec 格式,占用磁盘空间较大;

  • image.ImageIter:同时支持读取 Rec 和原始图像,相比以上两接口,更加灵活,同时也支持多种图像增强方式。接口基于 Python 实现,读取速度慢于 io.ImageRecordIter 接口;


我们对 image.ImageIter 和 io.ImageRecordIter 做了如下对比测试:


测试环境:


MXNet 版本:0.11.0


网络结构:Inception-v3


类别(num-classes):3


GPU:titan x


测试结果:


单 GPU,batchsize=128



可以看出,前两种读取方式的 I\O 时间主要消耗在 data_iter 阶段,第三种 I\O 时间主要消耗在 update_metric 阶段,且前两种时间消耗大约是第三种的 1.4 倍。调试 ImageRecordIter 接口的 update_metric 阶段操作,发现耗时主要集中在 pred_label.asnumpy()或 pred.asnumpy()操作。


多 GPU(3),batchsize=128*3



可以看出,多 GPU 时,前两种 io 时间约为第三种的 4.4 倍。


结论:单 GPU 时,ImageRecordIter(Rec 格式)的读取速度是其他接口的 1.4 倍;多 GPU 时,ImageRecordIter(Rec 格式)是其他接口的 4.4 倍。原因是其他接口 I/O 读取数据时间是训练时间的 30 倍+,多 GPU 时,其他接口速度基本不变。如果数据集是固定的,建议使用 ImageRecordIter 接口进行图像读取,缺点是占用磁盘空间较大。

三、视频 I/O 优化性能分析

本部分介绍基于 mxnet 图像 io 迭代器 ImageRecordIter 的视频读取迭代器的实现方法,具体实现可以参考:MTCloudVision/mxnet-videoio(https://github.com/MTCloudVision/mxnet-videoio)。


mxnet 图像 I/O 迭代器的输出结构:(batchsize, channel, height, width)。


我们要实现的读取视频的迭代器输出结构:(batchsize, frame_pervideo, channel, height, width),有两种方式可以实现这种迭代器,即基于 opencv 接口实现迭代器和对已有迭代器接口进行封装。


  • 基于 OpenCV 接口实现迭代器:使用 OpenCV 读取视频,将读取数据进行打包成结构为(batchsize,frame_pervideo, channel, height, width)的数据。该方法优点:基于 Python 代码容易实现。缺点:视频读取很慢,对于大规模视频训练任务,严重影响模型的迭代效率。

  • 封装 ImageRecordIter 接口:以每个视频取 3 帧为例,先将视频的数据封装成结构为(3batchsize, channel, height, width)的图像数据,将标签封装成(3batchsize,)的结构;然后调用 ImageRecordIter,将图像数据 reshape 成(batchsize, 3, channel, height, width),并将标签进行稀疏采样成(batchsize,)的结构。

  • 基于以上两种方法,我们做了三组性能对比实验,结果如下:




通过对比,可以看到:


  • 基于 Rec 格式的数据读取速度约为使用 opencv 读取图像速度的 18 倍;

  • 基于 Rec 格式的数据读取速度与 GPU 数正相关,4 个 GPU 的训练速度大概是单个 GPU 的 4 倍,即多 GPU 训练性能提升显著;

  • OpenCV 读取视频图像时,单 GPU 和多 GPU 的读取速度相近,即使用多 GPU 对训练速度的提升几乎没有帮助;

  • OpenCV 读取视频图像,多线程(10)读取比单线程读取速度有提升,但提升有限;


以上实验结果的测试环境:


MXNet 版本:1.0.1


网络结构:BN-Inception


批次数(BatchSize):50


机器:GTX1080ti


训练数据类别数(num_class):101


视频处理:视频采样 3 帧,每帧大小 256x320


实际应用中,训练数据 10W 视频,每个视频截取 10 帧时,采用 resnet-200 在 titan x 上训练 20 个 epoch,采用 cv2.imread 四个线程 io 需要~228 小时,而基于 Rec 视频迭代器只需~22 小时。


作者介绍:付志康,美图云视觉技术部门,计算机视觉工程师。


本文转载自美图技术公众号。


原文链接:https://mp.weixin.qq.com/s/Nq-fZY1L_ULO5DtBVg8eAw


2020-02-24 19:18987

评论

发布
暂无评论
发现更多内容

SchedulerX 如何帮助用户解决分布式任务调度难题?

阿里巴巴云原生

阿里云 云原生 公有云 SchedulerX

年度盘点|2021 年阿里云可观测实践回顾

阿里巴巴云原生

阿里云 云原生 可观测 Arms Arms 告警运维中心

设计模式【15】--从审批流中学习责任链模式

秦怀杂货店

Java 设计模式

人人都是 Serverless 架构师 | 弹幕应用开发实战

阿里巴巴云原生

阿里云 Serverless 架构 云原生

MyBatis3源码解析(6)TypeHandler使用

Java mybatis

MyBatis Demo 编写(2)结果映射转换处理

Java mybatis

【高并发】深入解析Callable接口

冰河

Java 并发编程 多线程 高并发 异步编程

Kubernetes集群统一日志管理方案(Elasticsearch+Filebeat+Kibana+Metricbeat)搭建教程

山河已无恙

Kubernetes 2月月更

AI生明月,万里共文心

脑极体

MySQL RC事务隔离级别的实现

JavaEdge

2月月更

如何做“健康码”的性能压测

阿里巴巴云原生

云原生 压测 健康码

MyBatis3源码解析(4)参数解析

Java mybatis

MyBatis3源码解析(7)TypeHandler注册与获取

Java mybatis

如何实现一个人管理1000个主播?

优秀

低代码 直播带货, 主播

《MySQL入门很轻松》第4章:数据表的创建修改删除

乌龟哥哥

数据库 2月月更

云原生年度技术盘点出炉!乘风破浪正当时

阿里巴巴云原生

阿里云 云原生 年度盘点

网络安全之小程序抓包渗透测试流程

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

Apache RocketMQ + Hudi 快速构建 Lakehouse

阿里巴巴云原生

阿里云 开源 云原生 消息队列

MyBatis3源码解析(2)数据库连接

Java mybatis

MyBatis3源码解析(8)MyBatis与Spring的结合

Java mybatis

一个cpp协程库的前世今生(二十六)共享栈

SkyFire

c++ cocpp

创新推出 | Serverless 调试大杀器:端云联调

阿里巴巴云原生

阿里云 Serverless 云原生 端云联调

架构训练营模块二作业

苍狼

作业 模块二 架构训练营5期

性能分析之用户登录TPS低以及CPU被打满问题分析

zuozewei

性能分析 2月月更

服务网格 ASM 年终总结:最终用户如何使用服务网格?

阿里巴巴云原生

阿里云 云原生 服务网格 容器服务

MyBatis3源码解析(3)查询语句执行

Java mybatis

Linux系统编程-进程间通信(共享内存)

DS小龙哥

Linux 共享内存 2月月更

【架构师训练营】模块七作业

樰巳-堕~Horry

架构实战营 「架构实战营」

MyBatis3源码解析(5)查询结果处理

Java mybatis

MyBatis Demo 编写(1)基础功能搭建

Java mybatis

Mybatis3 源码解析系列

Java mybatis

MXNet 视频I/O读取速度提升18倍的优化策略_行业深度_付志康_InfoQ精选文章