随着终端播放设备的升级,观众对于视频的品质需求也逐步提升。需求从最开始的高清过渡到4K,最近8K也有开始流行的趋势。除了对于分辨率提升的需求之外,视频在采集的过程中,也难免引入一些瑕疵,如物体运动过快导致的模糊,压缩算法导致的画质降低,拍摄/灯光等参数设置不佳导致的细节缺失,噪点增加等。经典插帧算法一般采用插值等算法,虽然速度很快,但细节丰富的图片放大之后都会比较模糊,去噪更是困难。深度学习方法的引入,因为其庞大的参数空间,很好的拟合了画质的降噪过程,从而在提升分辨率的时候可以提供更多的细节,实现画质和分辨率的双重提升。
但深度学习模型,相比传统方法,其运行时间大幅的提升,单个视频的处理可能要达到数小时或者数天,难以满足对海量视频进行生产的需求。本文在这种背景下,介绍了爱奇艺在视频4K 超分模型上进行的优化加速和生产落地实践,将4K超分模型的性能在GPU 上提升了10倍。
01
复杂模型的部署挑战
1.1 Nvidia在模型加速上提供的方法
Nvidia在Volta架构后,引入了tensorcore,一种domain specific accelerator [DSA],用于对深度学习中常见的矩阵运算做加速处理。该加速器取得了极大的成功,大幅的降低了大型深度学习模型的推理时间。但tensor core作为DSA也继承了其普遍缺点,它的编程逻辑特别复杂,普通的程序员在用底层暴露API的方式几乎难以使得tensor core达到它的理论运行速度。为了降低编程的门槛,Nvidia构建了TensorRT[1]框架,将若干针对特定input/output tensor shape,用手工打磨汇编的方式,得到对应最优tensorcore性能的kernel,并通过抽象的接口暴露给TensorRT上层。
TensorRT在模型编译时,会针对当前模型的状况,依次在各个合适的内核上运行,最终挑选出耗时最小的内核,固定在最终编译的TensorRT engine中。Engine即为最终的部署binary,TensorRT推理时会加载engine,提取对应的内核名称,以及对应的启动参数,按照模型的推理顺序,依次启动内核从而完成推理过程。
虽然TensorRT方便了模型借助tensorcore得到极大加速,但是由于tensor core本身的复杂性,TensorRT在对外暴露的接口较少,且核心算子实现目前还是闭源,进行模型深度优化时使用方式还是限制较多。举例来说,目前TensorRT内部算子都是以NCHW进行开发的且仅支持NCHW的tensor输入,但tensor core底层又需要以NHWC进行输入,中间会进行多次tensor reshape 而降低效率。
1.2 爱奇艺在复杂视频推理模型优化上的实践
为了进一步提高模型推理性能,爱奇艺对TensorRT底层机制做了详细的解析。通过本文,您将得到如下的知识点:
a. 如何对复杂模型推理进行 TensorRT的格式转换。
b. TensorRT的int8量化推理内部机制,以及如何更好的提升视频推理中int8量化模型的推理精度。
02
复杂模型TensorRT的转换方法
对于TensorRT模型部署来说,相信用过的人都碰到一个很头疼的问题,即某个算子不支持,或者对于torch模型来说,很多算子是需要开发者使用CUDA来自定义实现的。其实这个不是TensorRT一家的问题,对于TensorRT立志成为的通用深度学习编译器来说,深度学习模型和框架迭代非常快速,各种模型的计算需求层出不穷,想要归一化成为一个通用的IR表示是非常的困难,更不用说将模型推向性能的极致。
针对不支持op或者自定义CUDA kernel的处理方法,我们实践中通常用二字口诀来解决,《拆》,《合》。
2.1 模型《拆》解
就一般意义来说,模型的推理过程,其实就是一个完整计算