共计 9237 个字符,预计需要花费 24 分钟才能阅读完成。
音视频生产的新场景催生了越来越多新的技术需要,从当下的直播、点播、RTC,到将来的 XR 和元宇宙,音视频技术对新场景的撑持越来越趋向于综合性,近年来 AI 算法倒退迅猛,然而较好的算法成果往往须要耗费很大的算力资源,这使算法商业化落地面临十分大的挑战。咱们应该如何充分发挥软硬一体的能力?如何无效均衡算法成果和性能?
在 LiveVideoStackCon2021 北京峰会,阿里云智能视频云高级算法专家杨凤海,从阿里云视频云的最新场景摸索登程,带来了阿里云视频云在虚构背景、视频超分等方向的最佳翻新实践经验分享。
文 | 杨凤海
整顿 | LiveVideoStack
本次分享次要分为 5 局部,包含前言、算法层面的翻新和优化、软硬件层面的深度优化、将来瞻望和 QA。
1. 前言
音视频从业务状态上来说包含直播、点播、RTC、媒体生产和解决,以及云游戏、云桌面等。从技术链路上来讲包含采集、编码、传输、云端转码 / 解决 / 渲染、网络散发、接收端解码和渲染,其中波及到算法的局部包含编码前解决、解码后处理、云端视频解决。
依照算力高下排序,服务端算力最强,端上绝对较差,因而能够大抵形容为一个正态分布的模式。依据该正态分布曲线,当初大部分算法都部署在云端,少部分会部署在端侧。
从音视频和算法部署的现状来看,整个软硬件体系是异构的,基本上涵盖了云端服务器和边缘服务器、各种终端设备和 IOT 设施。
从硬件层面来讲,包含 CPU+GPU、CPU+FPGA、CPU+DSP 和 CPU+ASIC 芯片等。波及到的芯片厂商也十分多,支流的包含 Intel、AMD、ARM、Nvidia、高通、苹果等,操作系统笼罩也比拟全面。另外,软件规范、开发编译环境、深度学习的训练和推理框架也千差万别。
如此简单的异构软硬件环境对算法落地提出了前所未有的挑战,如何充分发挥软硬一体的能力?如何无效均衡算法成果和性能?这是两个必须要解决的问题。
2. 算法层面的翻新和优化
上面我将通过虚构背景和超分两个算法来介绍咱们是如何从算法层面做到性能和成果的均衡,从而为业务发明价值的。
虚构背景
咱们先来看下算法的背景,置信大家从去年疫情到当初都体验过线上视频会议、陪娃上网课等,当然没娃的敌人必定也看过直播、短视频、关注过线上相亲等场景,这些场景大家其实十分心愿可能把本人置身到一个虚构的环境中,一方面能够爱护个人隐私,另一方面也能无效的减少趣味性和沉迷式的体验。
理解了算法背景,咱们当初来看下如何在业务中落地?
首先是场景可能会非常复杂,光线、噪声、场景(室内、室外、单人 / 多人、会议室、办公区、场馆、居家等)、前景背景边界不清晰、手持物、服装装璜十分多样化;
其次是可用来训练学习的数据非常少,各开源数据集标注规范不同而且精度不满足商用要求,人工标注费时费力;
最初是计算性能方面,云端要求高并发低延时、终端要求低延时低功耗低资源占用。
这就要求咱们必须设计一个鲁棒性十分好的算法,并且可能满足不同部署端的性能要求。咱们晓得辨别人像的像素级算法有宰割和抠图两大类,当然还有一些细分的畛域,例如语义宰割、实例宰割、视频指标宰割(VOS)、全景宰割(Panoptic Segmentation)、蓝绿幕抠图、天然场景抠图。
咱们应该抉择哪一种来进行落地呢?首先要晓得咱们落地的场景目前次要是教育 / 会议 / 泛娱乐场景,通过成果和性能的综合评估,咱们认为针对人像的语义宰割能够满足业务诉求。
确定好算法方向后,咱们首先要做的就是要站在伟人的肩膀上进行翻新,那就必须要理解过往多年该畛域的算法倒退脉络。
能够看到从最后的 FCN 到起初的 segnet、Unet 系列、DeepLab 系列、HRNet 等,从算法设计和翻新角度基本上遵循了 Encoder-Decoder 的构造,而后尝试设计不同的 backbone 和 Block 来均衡算法成果和性能,再就是多分枝设计、多分辨率的交融、以及 Coarse2Fine 的构造和各种 Attention 等等。
从发论文的角度很多算法模型会设计的更深(更多层)、更宽(更多并行分支、更多的 channel、更大的 featuremap)、更密集的连贯、更大的感触野、获取更多全局信息等,然而从业务落地的角度来讲,这些简单的算法都很难在端侧设施上实时运行。
大道至简,咱们算法天生是要以满足不同异构平台的部署为指标的,因而咱们采纳了 Unet 的框架,而后交融了各种轻量化 Block 的设计思路,参考了包含 SqueezeNet、MobileNet、ShuffleNet、EfficienNet、GhostNet 等。
另外充分利用空间维度和 channel 维度的 attention 构造,充沛交融多分辨率特色,但同时又要保障计算不被拖慢,针对不同硬件平台差异化的设计、最初就是联合业务场景设计特定构造和损失函数等,包含特定的边缘 loss,在线难样本开掘等。
神经网络模型的晋升离不开场景和数据,因而在设计算法之前咱们首先要定义好以后的业务场景,而后再构建数据集,并通过数据训练迭代算法,算法反过来再通过线上业务实际收集 badcase,从新荡涤和裁减数据集,再次 fintune 算法模型,最终场景、数据和算法三者有机联合、循环迭代能力趋于完满。
因为数据集自身的散布无限,因而数据加强是必不可少的。传统人像贴图色温差别大,合成成果蹩脚。如果拿这样的数据退出训练,对整体的收益不会很高,而且合成成果不好的话可能还会有副作用。因而咱们采取动静白平衡和金字塔交融的策略,来保障前景和背景交融更实在。
因为人工数据采集老本较高,而且也很难笼罩所有人像动作姿势、环境和服饰等,因而像左下角图中所示,咱们通过特定人像、动作、场景的 3D 动画贴图来进行数据裁减;左边别离是对光照、噪声和静止含糊的抗干扰能力的晋升,咱们对原始数据和加强后的数据经网络输入的后果计算一致性 loss,以晋升模型的鲁棒性。
算法设计的再好,理论业务场景中难免会呈现一些 badcase。例如人坐在桌前,手臂和身材不是一个连通体,如果单纯应用之前的模型,可能手臂会被误认为背景,为此咱们研发了多任务联结学习办法。同时联合人像宰割、人体关键点,人体解析等对模型进行多任务联结训练学习。
最终推理时,其余工作不参加推理,只在训练阶段用于帮忙宰割模型提取和学习相干信息。这样做不仅能够晋升模型成果,还不会减少模型的复杂度。
另外大家或多或少应该都体验过虚构背景的利用,能够看到不管哪家厂商,在边缘的解决上都不是很好,因而咱们针对边缘还专门设计了非凡的 loss 束缚,使得边缘精度失去明显改善。
在最终落地时须要对模型进行轻量化解决。罕用的办法包含剪枝、压缩、蒸馏、量化和 NAS,这里以蒸馏为例来介绍下咱们是如何进行模型轻量化的。
首先来看下常识蒸馏的倒退历程,2014 年 Hinton 公布了开山之作 Distill the knowledge in a neural network,简略来说就是别离训练一个简单的老师网络和轻量的学生网络,而后利用 KL 散度使学生的输入和老师的输入迫近,起初一些改良的文章中也有人探讨了在分类网络中传递的 spatial attention 给学生网络的办法。
蒸馏在分类工作上体现绝对较好,但在像素级任务,无论是宰割、matting,还是超分,蒸馏都十分难调节。这些年也有论文在阐述该问题,比方微软的文章:structured knowledge distillation for semantic segmentation 就提出利用特色图中任意两个像素之间的类似关系进行蒸馏,同时还利用了像素分类的 KL 散度蒸馏、以及基于 GAN 的反抗式蒸馏等。
除此之外,还有论文利用 focal loss 的思维进行蒸馏。首先计算学生网络 loss,对 loss 大的地位赋予更大的权重,最初依据这些权重来计算蒸馏的 loss。
咱们充沛联合了像素分类的 KL 散度蒸馏和基于 GAN 的蒸馏办法等来进行蒸馏。
这是理论的算法成果,有单人换背景、虚构课堂、虚构会议室等,能够在爱护隐衷的同时为干燥的会议和课堂等提供一些小小的乐趣。
视频超分辨率算法
目前视频超分算法利用在端上功耗十分大,所以其次要利用在服务端视频超高清场景中,包含 2K 超 4K、4K 超 8K 等。
如何在端上进行超分?咱们当初落地场景次要为 RTC,RTC 无论是延时、包的大小、功耗还是资源占用要求都很极致。基于 RTC 业务个性,阿里云抉择端上弱网场景进行超分。
弱网时,通过 QOS 策略能够把分辨率、码率、帧率升高来满足网络晦涩传输的要求。在播放端通过超分算法对画面进行高清重建。这样不仅能够在弱网状况下保障传输品质,还能够使用户取得不错的观看体验。
回顾近几年超分模型倒退历程。次要分为传统算法和深度学习算法两大类。传统算法就是大家熟知的几种插值算法。从 2014 年的 SRCNN 开始到当初,一直的有新的对于深度学习的论文呈现,然而这些论文真正可能在端上跑起来的很少。
通过这些网络结构能够总结提炼出一些设计思路,基本上就是采纳残差构造,或者递归结构,亦或者 Dense 构造,还有一种是基于 GAN 的,然而 GAN 在端上实现起来更为艰难。为了提取视频帧之间的相关性信息,能够应用 3D 卷积、可变性卷积、光流和静止预计等办法,计算资源耗费同样很大。
超分算法自身要解决的是个病态问题,无论是从低分辨率到高分辨率,还是从高分辨率到低分辨率,不存在一个确定的映射函数,所以学习起来十分困难,而且在视频中,要利用帧间的信息进行对齐,难以满足在端上的实时性和功耗要求。
在 RTC 的场景下,要在低功耗的前提下保障算法成果,并且对包大小、CPU 占用率、GPU 占用率、功耗发热等要求都非常刻薄。另外,即使笼罩了中高端机型,如果依然有很大一部分中低端机型无奈笼罩,从业务和商业化的角度来讲会损失掉一部分客户,因而咱们的指标是要笼罩所有的机型。
图中大抵形容了咱们超分的网络结构。咱们晓得算法离不开实在场景,只有场景化的算法才会有更好的业务价值,在 RTC 场景中,首要思考的就是编码的压缩以及下采样导致的损失。
咱们在设计模型时,就曾经将编码的压缩以及下采样的损失思考进去,在模型前半部分增加了失真修复的模块。在模型的后半局部是对上采样后的图加强来迫近 GroundTruth。两局部都采纳了 Attention 的构造辅助特征提取。
对人像和一般画面进行超分绝对容易,然而对存在文字、字幕的场景进行超分,文字高频信息不仅在下采样过程中易失落,同时在编码过程中也极易被毁坏,非常容易呈现 badcase,咱们针对该问题进行了一系列优化。
首先会对文字进行大量的数据加强,包含字体、色彩、角度等,另外,引入针对边缘优化的 EdgeLoss,可能无效地晋升文字超分成果。
在落地时轻量化始终是须要思考的问题。咱们应用构造重参数化来设计网络,构造重参数化的实质就是通过并联一些特征提取分支进行训练。
例如自身只存在一条 3×3 的连贯提取特色,能够并行几条其余的卷积,最终推理时通过构造重参数化公式进行合并。尽管在训练时会减少大量的计算量,然而在推理时齐全没有影响,而且能够提取更多的信息和特色。通过这种构造,咱们很好的均衡了算法成果和功耗。
轻量化不仅能够应用构造重参数化,还能够应用稠密化剪枝。如果纯正对连贯进行稠密,稠密完后在 CPU、GPU 的计算不肯定会变快。对于 GPU 的计算来说,高度并行的数据相对来说更为敌对,纯正对连贯进行稠密,看似将局部连贯被掏空简化参数和计算量,但理论计算时因为 channel 对齐或访存不间断等不肯定会缩小计算延时。
因而,目前业界大多采纳结构化的稠密形式。右边两张图某个卷积核相干的参数,在统计其参数绝对值的和随工夫变动的曲线后发现,如果逐步趋向于 0,阐明这个分支自身十分稠密。对于其中一些数值十分小的连贯,能够进行裁剪,但在裁剪时,也要思考到前后 layer 的连贯问题,从整体构造上进行裁剪。
这里的两张图上示意了超分算法的统计基线比照。通过左图能够发现,超分算法在不同的档位成果都比传统算法好,很显著不在一个品位上。右图,咱们统计了超分算法在不同的码率帧率下 PSNR 大抵的散布,有了这个分布图之后,就能够反过来领导 QoS 策略,在不同带宽下正当的降码率和帧率。
这是直播场景的超分算法成果。
这是文字场景的超分算法成果。
3. 软硬件层面的深度优化
在结尾咱们曾经提到异构硬件十分多,然而在理论业务场景中 CPU 和 GPU 优化会工作会占据 90% 以上,所以这部分咱们次要以 CPU 和 GPU 为例来介绍优化策略。比照来看 CPU 更适宜做管制逻辑比较复杂、串行的工作,而 GPU 因为有大量 ALU 单元,更适宜做并行的计算。
该图简略介绍了 CPU 的软硬件架构。从整体的设计来看,CPU 的架构分为简单指令集和精简指令集两类。简单指令集以 X86 为代表,精简指令集以 MIPS、ARM、RISC-V 为代表。CPU 有一个重要的特色是其三级缓存。在优化时必须要先理解其软硬件构造,能力选取更适宜的优化办法。
图中形容了 CPU 计算的流程,要实现计算首先要取数据,须要拿一个虚拟地址去内存治理单元通过 TBL 查表寻址,如果命中能够间接从 Cache 外面取数据进行计算,这样的效率十分高,如果没有找到(Cache miss),就须要通过总线(效率较低)去拜访主存甚至磁盘来加载数据,这种状况下对功耗、性能、延时影响都十分大,在做优化时必须重点思考。
由此引出了 CPU 的优化办法。大体上分为代码级别、循环级别,内存级别,指令级别和线程级别。代码级别须要尽量减少内存的读写、尽量选用小的数据类型,还须要构造体对齐以及分枝优化。
循环级别罕用的办法为循环展开,循环合并,循环拆分。内存级别次要遵循工夫局部性和空间局部性原理,保障一次读取数据能够为多条计算指令用到。
另外须要尽量减少内存的频繁申请和开释,以及保障对内存的间断拜访、对齐拜访、合并拜访、强制对齐加载、缓存预取、内存复用等。指令级别要缩小数据依赖、优化乘除法、充分利用零碎寄存器资源、利用指令流水暗藏访存和指令延时执行、SIMD 指令优化等。
对于 SIMD 指令优化,对于 ARM 有 NEON,对于 X86 有 SSE/AVX 等。所谓向量化,例如一个矩阵计算 A×B+C=D,用标量计算的话须要屡次访存和计算,然而如果应用向量计算,能够大幅缩小访存和计算次数。
在 CPU 的指令流水外面,一条指令的执行须要通过取指、译码、执行和回写几个过程。能够在上一条指令取指实现开始译码的同时启动下一条指令的取值操作,周而复始,通过这样的办法不仅能够最大化 CPU 的吞吐量,还能够暗藏访存和计算延时。线程级别的优化,包含数据分块多线程、计算分支多线程以及异步解决多线程。
编译和汇编能够采纳利用编译器主动优化、内联汇编或者手写汇编等形式。CPU 绑定方面,如果常常在 CPU Core 之间切换会导致上下文切换频繁,对性能的影响十分大,因而能够选择性的绑定 Core 来晋升性能。手机端存在大核和小核的区别,要依据须要绑定不同性能的核以失去最优的性能。
上面来看下 GPU 的软硬件架构,服务器 GPU 次要厂商是英伟达和 AMD,PC 端 GPU 次要是英特尔的 HD 系列以及 AMD 的 APU 系列以及 Radeon 系列。挪动 GPU 支流的是高通骁龙 Adreno 系列、ARM 的 Mali 系列以及苹果的 A 系列,Imagination PowerR 系列当初应用的绝对较少。
GPU 软件规范次要包含微软的 DirectX 系列、Khronos Group 保护的 OpenGL、Vulkan、OpenGL ES、OpenCL 等、Apple 的 Metal、AMD 的 Mantle 以及 Intel 的 ONE API 等。
通过这张图简略理解 GPU 的软硬件构造。在硬件层面分为主设施和从设施。主设施一般来说是 CPU 端,从设施一般来说是 GPU 端。这里以 OpenCl 和 CUDA 为例来介绍下软硬件层面的架构。
CUDA 的硬件层面次要包含多流处理器 SM、泛滥的流处理器 SP 和一些寄存器等,Open CL 蕴含 CU 和 PE。从内存角度看,CPU 端主存,GPU 端显存。显存也分为全局内存、常量内存、纹理内存、部分内存和共享内存、公有内存等。从线程执行角度,CUDA 分为 Grid、Block、Thread 三个档次,OpenCL 分为 WorkGroup 和 WorkItem。
理解 GPU 的根本构造后,当初来介绍下 GPU 的优化形式。
代码级别,串行计算尽量应用 CPU,大量并行计算尽量应用 GPU。CPU 和 GPU 之间尽量采纳异步形式,缩小间接交互,否则会受到访存和 IO 的限度而影响性能。大规模程序的读写数据、单次 Load 多指令计算、应用向量化 load 和 store、缩小除法运算、低比特量化和应用内置函数也能够划归代码级别优化的办法。
Kernel 级别优化形式包含依据 kernel 正当调整线程分组、用大量线程数暗藏指令执行延时和屡次试验确定最优 kernel 等。
线程级别的分组优化在 OpenCL 中能够由零碎主动决定如何划分 WorkGroup size。依据教训通常也能够将 WorkGroup size 设定为 NDRange size 的因子或 2 的幂次方。保底的办法是 Auto-Tuning 找到最优分组形式。
CUDA 方面,SM 的配置会影响其所反对的线程块和 warp 并发数量,另外,因为 warp 的大小个别为 32,所以 block 所含的 thread 的大小个别要设置为 32 的倍数。
内存级别优化,包含应用线性拜访和高局部性的数据结构、优化数据排布最大化 Cache 利用率、最大化空间局部性和工夫局部性、合并访存、Zero Copy、Image 和 buffer 的辨别应用等。
实践上,在高通骁龙系列中,Image-object 性能更优,ARM Mali 系列,Buffer-object 更有劣势,但这不是相对的,能够提前试跑失去内存模式推理性能的更优者。另外要防止 bank 抵触、缩小片外内存拜访,充分利用 Local Memory 以及数据的分片复用。
GPU 的数据块片复用和 CPU 相似,适当增大数据分块能够在计算复杂度不变的前提下,无效的升高数据内存拜访次数,对于晋升性能有很重要的作用。
如何依据软件个性设计更为轻量的算子,我列出了以下 6 点:
第一,运算量较小、并行度较低的模型适宜 CPU 计算。
第二,大量并行的模型适宜 GPU 计算。
第三,缩小低计算量、无计算量和高访存算子的应用,能够采取和其余算子交融的办法缩小访存次数。
第四,防止应用不好并行的算子。
第五,卷积核不宜太大,必要时可用多个小卷积核代替。例如 1 个 5×5 可用 2 个 3×3 代替,参数量能够缩小到原来 18/25;1 个 7×7 的卷积核能够用 3 个 3×3 的卷积核来代替,参数量能够缩小为原来的 27/49。
第六,通道数对齐要联合硬件和推理框架来调整。MNN 推理时数据个别是依照 NC4H4W4 组织,华为的 HiAI 对应的排布个别抉择 16 对齐。如果不理解这些框架的底层实现,就会造成计算资源的节约。
对于深度学习来说,计算图优化是非常外围的局部。这里包含节点的替换、分支优化、子图变换和算子交融,其中算子交融相对来说应用最多。左边是卷积和 BN 交融的例子,从数学上能够通过公式推导出 BN 能够和卷积齐全交融,简化成一个卷积来应用,从而缩小推理阶段的访存和计算耗费。
上面另外一个例子,能够将多个 1×1 卷积合并,之后再进行 3 x3 和 5 x5 的卷积,因为最初的 concat 是纯访存操作,因而能够和卷积操作交融到一起,在内存开释前同步实现 concat 操作。
卷积和矩阵乘法是应用频率最高的两个算子。卷积有很多种实现形式,它能够采纳滑窗的形式间接实现,通过循环展开、数据分块多线程以及指令集并行等进行优化。还能够通过矩阵乘实现,但须要先进行 img2col 而后再进行矩阵乘法。
FFT 当初用到的比拟少,FFT 适宜大 kernel 的卷积,小 kernel 的卷积采取间接实现的办法会比 FFT 更快。Winograd 是当初用的比拟多的一种优化形式,它的思路也很简略,就是利用加法比乘法耗费的指令周期较短的劣势,尽量合并计算把一些常量算式提前计算好,并用加法代替乘法,以缩小访存和计算总量。
左边是矩阵乘法的 Strassen 算法优化办法,次要是对矩阵进行分块计算,简化掉很多乘法,再引入一个用于辅助计算的两头矩阵,使得计算量进一步升高。该算法能够通过 7 次乘法和 18 次加法,将矩阵乘的算法复杂度升高到了。
这是算法层面的优化,最终工程优化层面还须要从以下几方面着手,包含循环优化、数据分块和重排、减少数据复用度、缩小 cache miss、向量化、浮点转定点、低比特量化、多线程等。
整个算法优化的过程大略如图中所述,先设计好轻量化的算法模型,而后进行软件优化,包含各种前后解决所用到的 CV-Filter 和 Inference Engine 的优化,再往下就是须要各种平台操作系统的适配,最初是硬件加速。
OpenCL 框架下首先须要创立很多个 kernel 将计算工作散发至各个硬件上运行,线程和指令的执行会通过队列的形式来治理,这个队列也存在肯定优化策略,能够依赖 OpenCL 零碎的最优化调度,也能够利用 OpenCL 提供的 flush 接口,在调度上退出人为的动静队列刷新机制来进步性能。
优化业务 pipline,缩小 host 和 device 数据拷贝。关注性能瓶颈在访存还是计算,确定之后再抉择优化策略。关注 CPU 大小核切换、降频等的影响。关注业务流程或其余算法对资源的抢占。关注系统资源占用率、功耗、音视频卡顿率。异构设施在优化时能够思考进行计算性能 Pre-Tuning 来抉择最佳的计算形式。还能够借助开源工具进行性能优化。
以上就是我对于算法和软硬件层面的优化办法的分享,上面咱们来一起瞻望下将来。
四、将来瞻望
随着音视频技术的倒退,人们的交互方式在逐步进化,线上和线下、虚构和事实会越来越严密的交融。新的交互方式必然呈现催生全新一代云边端一体、软硬一体的实时音视频解决架构。并且会对软硬件的倒退和算法的优化提出了更低延时、更大算力、更低功耗的极致挑战。
这是阿里云视频云“云端一体”的解决方案。思考到端侧设施计算资源无限,将一些对算力和延时要求比拟高的算法能够放在云端 GRTP 引擎进行解决和渲染,解决实现之后端上只须要做一般的渲染即可,真正做到端侧“零解决”。左边是咱们云端一体实时换背景 + 构建虚构主播 + 美声变声的视频演示成果。
将来 AI、AR、VR、XR、元宇宙等对算力的要求会越来越高,单纯依附算法和软件优化实质上是有局限性的,因而必须独特推动硬件的疾速倒退,真正关上算力和性能的天花板。咱们判断将来须要云边端更加深度交融、通过软硬一体的计划进一步降本增效,如此算法能力真正赋能千行百业。
以上是我本次的分享,谢谢大家!
「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实际技术文章,在这里与音视频畛域一流工程师交换切磋。公众号后盾回复【技术】可退出阿里云视频云产品技术交换群,和业内大咖一起探讨音视频技术,获取更多行业最新信息。