0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一套高性能高灵活性的硬编解码推理技术方案

电子工程师 来源:DeepBlue深兰科技 作者:DeepBlue深兰科技 2021-03-15 09:44 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在基于NVIDIA平台上推理时,通常会遇到读取视频进行解码然后输入到GPU进行推理的需求。视频一般以RTMP/RTSP的流媒体,文件等形式出现。解码通常有VideoCapture/FFmpeg/GStreamer等选择,推理一般选择TensorRT。

NVIDIA已经为用户提供了基于GStreamer插件拼装的DeepStream Toolkit来解决上述需求,实现RTMP/RTSP/FileSystem到GStreamer再到TensorRT,从视频数据的输入到高性能解码推理,再到渲染编码,直到最终结果输出。端到端的屏蔽了细节,易于上手使用,用户只需要开发对应GStreamer插件即可轻易实现高性能解码推理。这个方案涵盖了服务端GPU、边缘端嵌入式设备的高性能支持。 由于项目的缘故,面临了大规模(96路)视频文件的同时处理,同时推理的模型种类有6种(Object Detection[Anchor base/Anchor free]、Instance Segmentation、Semantic Segmentation、Keypoint Detection、Classification),处理的模型约96个(分类器36个,检测分割60个)。项目需要极高的灵活度(模型种类和数量增加变化)、稳定性和高性能,考察DeepStream后发现其灵活度无法满足需求,因此针对该需求,使用FFMPEG、NVDEC(CUVID)、CUDA、TensorRT、ThreadPool、Lua等技术实现了一套高性能高灵活性的硬编解码推理技术方案,高扩展性,灵活的性能自动调整,任务调度。

解码器

VideoCapture/FFMPEG/NVDEC

VideoCapture基于FFMPEG,如果单独使用FFMPEG则可以做到更细粒度的性能控制,如果配合NVDEC则需要修改FFMPEG。

其中尤为重要的部分是:

a. 谨慎使用cvtColor,在OpenCV底层,cvtColor函数是一个多线程运行加速的函数,即使仅仅是CV_BGR2RGB这个通道交换的操作也如此。他是一个非常消耗CPU的操作。

通过上面可以观察到,具有64线程的服务器,也只能实时处理3路带有cvtColor的视频文件。没有cvtColor时,指标约为12路。也侧面反映了CPU解码效率其实很感人。 而cvtColor在CPU上运行的替代方案是sws_scale,具有灵活的性能配置选择。不过也仅仅是比cvtColor稍好一点,问题并没有得到解决。 颜色空间转换,第一个使用场景为H264解码后得到的是YUV格式图像,需要转换为BGR(这个过程在VideoCapture中默认存在sws_scale,输出图像为BGR格式)。第二个使用场景是神经网络推理所需要的转换(训练时指定为RGB格式)。 解决方案是: 1) 使用BGR进行训练,尽量避免颜色空间转换; 2) 使用FFMPEG解码,并输出YUV格式,使用CUDA把YUV格式转换为BGR,同时还进行进行标准化、BGRBGRBGR转为BBBGGGRRR等推理常有操作。实现多个步骤合并为一个cuda核,降低数据流转,提升吞吐量。例如yolov5,则可以把Focus也合并到一个cuda核中。如果需要中心对齐等操作,依旧可以把仿射变换矩阵传入到cuda核中,一次完成整个预处理流程。 下图为同时实现归一化、focus、bgr到rgb、bgrbgrbgr转bbbgggrrr共4个操作。

c25f8d9c-845b-11eb-8b86-12bb97331649.png

b. 仅考虑CPU解码,使用FFMPEG可以配合nasm编译(--enable_asm)支持CPU的SIMD流指令集(SSE、AVX、MMX),比默认VideoCapture配置的ffmpeg性能更好。同时还可以根据需要配置解码所使用的线程数,控制sws_scale、decode的消耗。

编码而言,ffmpeg可以使用preset=veryfast实现更高的速度提升于VideoWriter,设置合理的gop_size、bit_rate可以实现更加高效的编码速度、更小的编码后文件、以及更快的解码速度。

c. NVDEC是一个基于CUDA的GPU硬件解码器库,CUVID(NVENC)是编码库。

地址是:https://developer.nvidia.com/nvidia-video-codec-sdk

对于ffmpeg配合NVDEC时,需要修改libavutil/hwcontext_cuda.c:356 对于hwctx->cuda_ctx 的创建不能放到ffmpeg内部进行管理。这对于大规模(例如超过32路同时创建解码器时)是个灾难。硬件解码的一个核心就是CUcontext的管理,CUcontext应该在线程池的一个线程上下文中全局存在一个,而不是重复创建。TensorRT的模型加载时(cudaStreamCreate时),会在上下文中创建CUcontext,直接与其公用一个context即可。

对于没有合理管理CUcontext的,异步获取ffmpeg的输出数据会存在异常并且难以排查。如果大规模同时创建32个解码器,则同时执行的程序,其前后最大时长差为32秒。并且由于占用GPU显存,导致程序稳定性差,极其容易出现OOM。

frames_ctx->format指定为AV_PIX_FMT_CUDA后,解码出的图像数据直接在GPU显存上,格式是YUV_NV12,可以直接在显卡上对接后续的pipline。

在ffmpeg解码流程中,配合硬件解码,需要在avcodec_send_packet/avcodec_decode_video2之前,将codec_ctx_->pix_fmt设置为AV_PIX_FMT_CUDA,该操作每次执行都需要存在,并不是全局设置一次。

基于以上的结论为:

a) CPU编解码,使用配置了nasm的ffmpeg进行,避免使用VideoCapture/VideoWriter;

b) GPU编解码,服务器使用配置了NVDEC的ffmpeg进行,嵌入式使用DeepStream(不支持NVDEC);

c) 避免使用cvtColor,尽量合并为一个cuda kernel减少数据扭转实现多重功能。

CUDA/TensorRT

关于推理的一些优化

a. 对于图像预处理部分,通常有居中对齐操作:把图像等比缩放后,图像中心移动到目标中心。通常可以使用resize+ROI复制实现,也可以使用copyMakeBorder等CPU操作。

在这里推荐采用GPU的warpAffine来替代resize+坐标运算。原因是warpAffine可以达到一样效果,并且代码逻辑简单,而且更加容易实现框坐标反算回图像尺度。对于反变换,计算warpAffine矩阵的逆矩阵即可(使用invertAffineTransform)。GPU的warpAffine实现,也仅仅只需要实现双线性插值即可。

b. 注意计算的密集性问题。

cudaStream的使用,将图像预处理、模型推理、后处理全部加入到同一个cudaStream中,使得计算密集性增加。实现更好的计算效率,统一的流进行管理。所有的GPU操作均采用Async异步,并尽可能减少主机到显存复制的情况发生。方案是定义MemoryManager类型,实现自动内存管理,在需要GPU内存时检查GPU是否是最新来决定是否发生复制操作。取自caffe的blob类。

c. 检测器通常遇到的sigmoid操作,是一个可以加速的地方。

例如通常onnx导出后会增加一个sigmoid节点,对数据进行sigmoid变为概率后进行后处理得到结果。Yolov5为例,我们有BxHxWx [(num_classes + 5) * num_anchor]个通道需要做sigmoid,假设B=8,H=80,W=80,num_classes=80,num_anchor=3,则我们有8x80x80x255个数字需要进行sigmoid。而真实情况是,我们仅仅只需要保留confidence > threshold的框需要保留。而大于threshold的框一般是很小的比例,例如200个以内。真正需要计算sigmoid的其实只有最多200个。这之间相差65280倍。这个问题适用全部存在类似需求的检测器后处理上。 解决对策为,实现cuda核时,使用desigmoid threshold为阈值过滤掉绝大部分不满足条件的框,仅对满足的少量框进行后续计算。

d. 在cuda核中,避免使用例如1.0,应该使用1.0f。

因为1.0是双精度浮点数,这会导致这个核的计算使用了双精度计算。众所周知,双精度性能远低于单精度,更低于半精度。

线程池Thread Pool

主要利用了c++11提供的condition_variable、promise、 future、mutex、queue、thread实现。线程池是整个系统的基本单元,由于线程池的存在,轻易实现模型推理的高度并行化异步化。

使用线程池后,任务通过 commit提交,推理时序图为:

当线程池配合硬件解码后,时序图为:

此时实现了GPU运算的连续化,异步化。GPU与CPU之间没有等待。

资源管理的RAII机制

Resource Acquisition Is Initialization

在C++中,使用RAII机制封装后,具有头文件干净,依赖简单,管理容易等好处。

其要点在于:第一,资源创建即初始化,创建失败返回空指针;第二,使用shared_ptr自动内存管理,避免丑陋的create、release,new、delete等操作;第三,使用接口模式,hpp声明,cpp实现,隐藏细节。外界只需要看到必要的部分,不需要知道细节。

头文件:interface.hpp

实现文件:interface.cpp

责任编辑:lq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • gpu
    gpu
    +关注

    关注

    28

    文章

    5102

    浏览量

    134487
  • 编解码器
    +关注

    关注

    0

    文章

    279

    浏览量

    25240
  • 流媒体
    +关注

    关注

    1

    文章

    200

    浏览量

    17153

原文标题:实战 | 硬编解码技术的AI应用

文章出处:【微信号:kmdian,微信公众号:深兰科技】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    瑞芯微RK3562平台FFmpeg硬件编解码移植及性能测试实战攻略

    本文介绍瑞芯微RK3562平台,FFmpeg硬件编解码移植及性能测试方法。FFmpeg简介与实测数据FFmpeg简介FFmpeg是一套多媒体框架,能够解码、编码、转码、复用、解复用、流
    的头像 发表于 11-28 19:02 735次阅读
    瑞芯微RK3562平台FFmpeg硬件<b class='flag-5'>编解码</b>移植及<b class='flag-5'>性能</b>测试实战攻略

    德州仪器ADS644X系列ADC:高性能灵活性的完美结合

      在当今的电子设计领域,模数转换器(ADC)的性能灵活性对于系统的整体表现起着至关重要的作用。德州仪器(TI)的ADS6445、ADS6444、ADS6443和ADS6442(统称ADS644X
    的头像 发表于 11-27 18:07 1139次阅读
    德州仪器ADS644X系列ADC:<b class='flag-5'>高性能</b>与<b class='flag-5'>灵活性</b>的完美结合

    TI ADS642X系列ADC:高性能灵活性的完美结合

    富的功能,成为众多应用场景的理想选择。今天,我们就来深入探讨下这款ADC的特点、应用以及设计要点。 文件下载: ads6422.pdf 、产品概述 ADS642X是系列高性能的1
    的头像 发表于 11-27 15:57 291次阅读
    TI ADS642X系列ADC:<b class='flag-5'>高性能</b>与<b class='flag-5'>灵活性</b>的完美结合

    音视频编解码封装解封装部件介绍

    是否有探索开源鸿蒙音视频编解码技术的欲望?是否对开源鸿蒙音视频编解码格式支持有诉求?别急——今天这份开源鸿蒙AVCodec Kit介绍文章,就是解答疑惑的指南!参考这份指南,可以使用开源鸿蒙的音视频
    的头像 发表于 10-31 09:15 258次阅读
    音视频<b class='flag-5'>编解码</b>封装解封装部件介绍

    瑞芯微RK3588平台FFmpeg硬件编解码移植及性能测试实战攻略

    本文介绍瑞芯微RK3588平台,FFmpeg硬件编解码移植及性能测试方法。FFmpeg简介与实测数据FFmpeg简介FFmpeg是一套多媒体框架,能够解码、编码、转码、复用、解复用、流
    的头像 发表于 10-21 13:51 1000次阅读
    瑞芯微RK3588平台FFmpeg硬件<b class='flag-5'>编解码</b>移植及<b class='flag-5'>性能</b>测试实战攻略

    EtherCAT热插拔技术:提升工业自动化系统灵活性的关键

    在工业自动化领域,系统灵活性和维护性至关重要。本文将探讨EtherCAT从站热插拔技术,介绍其如何通过动态管理从站设备,提高系统的灵活性和维护性。EtherCAT热插拔技术EtherC
    的头像 发表于 10-16 11:36 345次阅读
    EtherCAT热插拔<b class='flag-5'>技术</b>:提升工业自动化系统<b class='flag-5'>灵活性</b>的关键

    瑞芯微RK3576平台FFmpeg硬件编解码移植及性能测试实战攻略 触觉智能RK3576开发板演示

    本文介绍瑞芯微RK3576平台,FFmpeg硬件编解码移植及性能测试方法。演示设备:触觉智能RK3576开发板FFmpeg简介与实测数据FFmpeg简介FFmpeg是一套多媒体框架,能够解码
    的头像 发表于 09-08 13:58 731次阅读
    瑞芯微RK3576平台FFmpeg硬件<b class='flag-5'>编解码</b>移植及<b class='flag-5'>性能</b>测试实战攻略 触觉智能RK3576开发板演示

    寻求集成度电池驱动方案?剖析SiLM2661CA-DG的独立双使能与边保护架构

    的优势——确保即使在地线断开时系统通信不中断,还通过独立使能控制为充放电路径管理提供了出色的灵活性。 核心特性SiLM2661CA-DG 虽身形小巧,却蕴藏强劲性能边NFET驱动:具备极短的开关
    发表于 09-02 08:26

    视耀T1 MINI-4路4K编解码器丨端到端超低延时赋能4K超清视界

    源信号接入,配合动态编解码通道分配(4编/4解/2编+2解),灵活适配复杂场景需求。 核心技术突破与跨场景适配 采用最新代编码技术,T
    发表于 08-28 13:43

    SL3075 DC-DC65V宽输入电压范围高性能降压转换器 优势兼容TPS54560

    的可靠性和稳定性。 结论综上所述,SL3075作为高性能的宽输入电压范围降压转换器,为TPS54560的用户提供了理想的兼容替换选择。其出色的性能、能效优化、设计灵活性和可靠性提升
    发表于 07-16 10:24

    【Firefly自研】高性能全流程视频处理框架:FFMedia

    性能、官方原始api太靠近底层、学习成本、周期长、开发工作量大等问题。为此,Firefly基于RockchipMPP/RGA库,开发了一套性能高效、接口简洁、功
    的头像 发表于 07-01 16:32 1561次阅读
    【Firefly自研】<b class='flag-5'>高性能</b>全流程视频处理框架:FFMedia

    将M.2 SSD转为可插拔设计:提升工作站灵活性与维护效率的解决方案

    在日常工作站PC电脑使用中,内置的M.2SSD虽然具备高速传输和节省空间的优势,但在频繁维护、更换或数据交换时,拆装过程较为繁琐。将M.2SSD转换为外置可插拔的形式,不仅大幅提升了操作灵活性,也有
    的头像 发表于 05-09 17:10 1138次阅读
    将M.2 SSD转为可插拔设计:提升工作站<b class='flag-5'>灵活性</b>与维护效率的解决<b class='flag-5'>方案</b>

    迅为iTOP-RK3576开发板/核心板视频编解码能力强高性能低功耗的应用处理芯片

    、PyTorch、Caffe等系列框架的网络模型。满足多种应用场景。 iTOP-3576拥有强大的视频编解码能力,支持4K@120fps的H.265、VP9、AVS2和AV1解码器,支持4k@60fps
    发表于 04-07 14:18

    探索 RK3576 方案:卓越性能灵活框架,诚邀开发定制合作!

    高性能扩展性的芯片方案进行产品开发定制,RK3576 方案绝对是您的不二之选。我们公司拥有专业的技术团队,可与您紧密合作,共同基于 R
    发表于 02-05 15:21

    如何使用Java语言快速开发一套智慧工地系统(源码)

    系统的可扩展性和灵活性。 前后端分离:前端使用Vue或UniApp进行开发,后端基于Spring Boot,确保快速响应和良好的用户体验。  2、技术选型 开发工具:使用IntelliJ IDEA或Eclipse作为主要的开发环境。 数据库:MySQL作为主要数据库,Mo
    的头像 发表于 01-09 17:39 1026次阅读