其他
不同的AI视频推理场景下,如何构建通用高效的抽帧工具?
导读
AI算法在视频娱乐行业得到了广泛应用,在处理视频数据过程中最大瓶颈之一是视频抽帧延时,抽帧延时往往占据了整体服务的大部分时间。此外,不同的AI算法应用于不同业务时,对视频抽帧需求也不同。
对此,本文介绍一种高效通用的抽帧工具在AI视频推理服务中的应用,可以降低服务整体处理延时;并针对AI算法对视频抽帧的不同需求,在不同的使用场景下,提供通用化的功能。
AI算法已经广泛应用于AI视频推理服务中,目前爱奇艺AI服务中与视频数据相关的服务多达数百个,每个服务又由多个算法组成。这些AI算法对输入视频数据的需求不同,部署硬件平台也不同,导致AI算法在视频推理服务面临多方面的挑战。
例如:以用户上传的短视频为主的视频审核业务而言,其主要挑战为:为了提升用户体验,需要在很短的时间内审核完成;用户上传的视频编码格式多样,需要视频抽帧工具能够支持不同的编码格;视频审核业务需要对低俗、血腥、暴力、政治、儿童邪典等多方面进行审核,有的算法部署在GPU上,有的算法部署在CPU上,这需要抽帧工具无论是在CPU上还是在GPU上都能够以很短的延时处理。
而以长视频为主的词生产、转场点、行为识别、视频插帧等业务而言,其主要挑战为:抽帧工具需要确保抽帧的结果精准,即抽取的视频帧以及其时间戳与原视频完全吻合,此外长视频抽帧在高吞吐来提升资源利用率的使用场景下,也希望尽快处理完成,来提升不同业务线同学的工作效率。
当AI视频推理在预处理或者抽帧时使用CPU资源计算时,GPU资源没有被充分使用;或者单个算法模型对GPU硬件资源消耗较少,都有可能导致整体GPU资源利用率偏低。
二、算法需求差异较大、部署硬件资源不同爱奇艺AI算法在视频图像领域蓬勃发展,不同的AI算法用在不同的业务时,对抽帧需求也不一致:每秒抽取的帧数,抽帧时是否需要保存不同格式的图像,抽帧时RGB数据是否直接存放内存或显存,对特定时间段抽帧,只对关键帧抽帧,抽帧时缩放、裁剪图像,获取图像时间戳等等。不同的需求导致很难通过某一套现有的方案来满足所有需求。
方案调研
一、CPU抽帧应用于AI算法的通用方案目前在CPU上使用FFmpeg抽帧运用于AI算法最常见的方法主要有以下两种:
1.FFmpeg将视频抽帧保存为图像后,AI算法调用:最传统的做法将视频下载后,使用FFmpeg解码并保存图像,AI算法读取图像,预处理后进行推理,后处理完成后将结果上传。这种传统的方式导致整体服务处理增加一些没必要的时间开销,具有主要的两个缺陷:
一、视频抽帧和算法推理处理延时太大,每个模块均为阻塞方式,需要前置步骤完全处理完成后,后续步骤才能够开始处理;
二、一张1080P的RGB无损原图保存需要5MB存储空间,1小时、1080P视频全部抽帧并保存原图将需要450G的存储空间,这将带来巨大的存储压力。
为此视频抽帧往往保存JPEG格式图像,JPEG图像具有极高的压缩率,1张1080P的JPEG图像往往只需要0.1MB存储空间,相比保存原图能够节约数十倍存储空间。但其缺陷为有损压缩,即JPEG保存后的图像读取后与原图相比存在一定的信息丢失,有可能导致AI算法推理时精度降低。此外AI算法读取图像时又需要将JPEG格式图像解码为YUV格式,并将YUV格式图像转换为算法需要的RGB格式。由此可见,抽帧保存为JPEG图像提供给算法使用实为下策,然而有的服务中又确实需要将图像完全保存,故该方案还是在一些服务中被使用。
方案一 CPU抽帧落盘
方案二 CPU抽帧不落盘
方案3 GPU抽帧不落盘
通用高效抽帧在视频推理中的方案实施
1. CPU抽帧的完善与优化(1)准确获取抽帧图像时间戳:视频中的时间戳有显示时间戳PTS和解码时间戳DTS,DTS主要用来标识待解码视频帧送入解码器解码的顺序,而PTS指的是图像帧在视频中实际显示的时间点位,如果视频中没有B帧时,DTS和PTS顺序一样,但当时视频中存在B、P帧时,则DTS和PTS的顺序不一样。AI服务中,使用的时间戳为PTS,对应视频帧在实际播放时的时间点位。抽帧的图像通过AI算法推理得到的结果需要与视频中的PTS时间点位完全一致,这就严格要求抽帧时获取的PTS必须完全准确。然而FFmpeg抽帧时无法直接返回该帧的PTS,本方案通过优化FFMPEG输出控制逻辑,来保证抽帧获取的PTS与原视频流中的点位一致。
(2)CPU抽帧在不落盘与落盘情况下加速优化:本方案采用资源换速度的方法,对于落盘的加速优化,使用多线程分别抽取视频中的部分片段。而不落盘的视频抽帧,使用多线程分片抽帧时,需要保证将抽帧结果顺序提供给算法使用,每个子线程负责多个小时间段,每个子线程抽取后获取的图像使用时间戳做顺序校准。确保每个子线程依次提供的数据能够与单线程抽取结果完全一致。
2. GPU抽帧的完善与优化(1)GPU抽帧功能增加与完善:在与算法和业务沟通需求后,本方案增加了GPU对视频单位时间内抽n帧,对视频关键帧抽帧,对视频的某个时间段抽帧,准确获取时间戳,抽帧时可保存JPEG等图像格式,以及其它一些功能。鉴于视频编码为YUV格式的图像后,保存JPEG图像时需要对YUV格式图像进行编码,编码使用CPU处理延时较大。为了能够减少存JPEG延时,本方案通过编写CUDA函数实现YUV格式图像编码为JPEG格式。在GPU V100上,峰值性能可达3000 FPS。
(2)对抽帧后图像直接使用GPU显存情形的优化:一些重要的服务需要及时的返回结果,业务希望能够最大限度的减少延时。对此,本方案将视频解码的YUV数据,在GPU上调用CUDA core实现YUV转RGB以及其他的所有预处理函数,确保整体处理尽量减少CPU与GPU之间的数据拷贝。
(3)增加抽帧后的图像回传至内存,AI算法直接使用Python调用GPU抽帧、CUDA函数功能:考虑到当前AI算法大多基于Python开发,开发人员难以完全对所有的AI算法进行改造。为了基于Python开发的AI算法能够使用GPU抽帧(C++开发),本方案采用Pybind11,使得C++和Python很方便的混合调用。此外,对于某些处理延时很大的服务,也希望能够在Python端调用CUDA函数来实现预处理加速,对此我们提供了上述相同的策略。
图五为GPU抽帧整体框架图,视频数据以及抽帧需求信息,通过Pybind11传递给GPU抽帧模块使用。cuda初始化模块仅在主线程中初始化CUDA上下文一次,子线程解码时将cuda上下文压栈来避免每个视频抽帧时需要重新初始化。视频帧解码后,通过后续处理模块完成颜色空间转换以及AI算法对解码后的图像处理需求。如果算法需要将预处理、后处理放在GPU上处理,则调用对应的CUDA函数否则直接将图像数据输出给AI算法使用。此外,GPU抽帧和AI算法推理并行处理,其他环节为异步执行,能够最大层度减少延时。
3. 整体流程的优化GPU抽帧相比CPU抽帧延时更小,但只支持H.264、H265、VPx等常用格式,对于H263等目前较少使用的编码格式并没有提供支持,客户上传的视频编码格式无法确定GPU解码是否支持。本方案使用ffprobe获取视频的编码格式后,来判断该视频使用GPU或者CPU进行抽帧解码。此外考虑到输入数据或许并非视频,AI算法存在bug等情况,本方案进行了详细的异常处理和日志管理。
总结
随着AI视频推理服务在爱奇艺各个业务线的广泛使用, AI服务团队除了需要提供丰富的AI算法模型,从节约硬件资源、提升工作效率、以及满足某些业务延时敏感的角度考量,都需要尽可能的减少服务处理时间。为此,后续还需改造原线上延时较大的服务,完善抽帧工具,在算法的预处理、后处理提供加速函数库,AI算法模型深入优化等多个方面深入展开工作。