https://community.arm.com/developer/ip-products/processors/b/ml-ip-blog/posts/cnn-inference-with-ar-on-mobile
帕维尔·鲁德科(Pavel Rudko)2021年3月15日
现代增强现实(AR)应用程序基于机器学习(ML),这需要运行大量的计算工作负载。在上一个博客中, 我们描述了构建此类应用程序的经验。
在移动设备上,通常进行设备上神经网络(NN)推理而不将任何数据发送到远程服务器的做法。这有一些优点:
- 安全和隐私-您将数据保留在设备上。
- 低延迟-您不依赖于网络(云)。
- 数据质量-在Cloud上进行推理时,数据将被压缩或修改以节省带宽,这会改变原始数据的质量。
在处理单个图像并将其保存到图库时,该过程应该足够快。但是,通过实时处理,性能变得尤为重要,开发人员正在寻找任何机会来节省每帧额外的毫秒数。在此博客中,我们解释了一些常见的方法,这些方法可提高Mobile上NN推理的性能。
选择和优化神经网络模型
加快工作量的最大方法是减少已完成的计算数量。
架构
对于基于编码器-解码器的体系结构,值得尝试使用现有的优化优化的编码器(例如MobileNet)。MobileNet和其他流行的网络使用巧妙的优化方法,例如可分离的卷积。使用现有的经过预训练的解码器还可以在训练过程中节省一些时间,因为您将仅针对特定任务训练解码器。
模型的深度是要试验的参数之一。如果您要构建自己的模型或使用现有模型并对其进行修改,则可以简化模型并检查准确性是否仍然可以接受。要尝试的另一件事是通过减少卷积层中输出特征的数量来使操作本身更轻便。例如,在Keras中,某些模型(例如MobileNet)是可配置的,而参数(例如 alpha和depth_multiplier)则可以使模型更小。
修剪
设计,训练模型并达到良好的准确性后,就值得对其进行修剪。这意味着摆脱无关紧要的图层权重(权重修剪)或连接(通道修剪)。它有助于使模型更小,更快。您可以在此处找到有关这两种修剪方法的更多信息。
测量与比较
要比较不同的模型或查看优化后的差异,有必要估算网络的强度。
让我们说,我们有一个卷积层,其输入大小为H×W×C(高度,宽度,通道数,图1a),内核大小为N×N×C×F(宽度,高度,输入通道数,输出特征的数量,图1b)。
然后,输出的大小为(H-N + 1)×(W-N + 1),如图1c所示。这也是卷积的数量,因为它们每个都属于输出图像的单个像素。
在每次卷积期间,我们需要遍历N个N个区域,并对所有C个通道进行权重求和。必须对F个输出功能中的每个功能都进行此操作。因此,在一次卷积过程中乘法的总数为N×N×C×F。
这样就得出了乘法的总数:
N mul =(H – N + 1)×(W – N + 1)×N×N×C×F
请注意,步幅和填充会影响输出的大小以及每个卷积的乘法次数,因此也必须考虑这些参数。
在我们的项目中,我们使用MOPS(数百万次操作)来估算细分模型的大小。在我们减小深度之后,该数字从〜4000减少到〜600,这很好地证明了影响。其他流行的度量标准是MAC(也称为MADD)-乘累加数和模型中参数的数量(权重,偏差)。例如,在Keras中,model.summary()方法显示模型具有多少个参数。
跨各种硬件单元的性能优化
大多数用于移动NN推理的框架(例如Tensorflow Lite)允许您选择将用于计算的设备。
显卡
有时,GPU是首选,尤其是在使用卷积神经网络时。有关充分利用Arm NN进行GPU推理以及可用的不同性能增强器选项的更多详细信息,我建议阅读以前的两个有关Open CL调谐器 以及FP16和Fastmath的博客。
张量可以在内部表示为纹理或缓冲区,并且相同的操作(如卷积)在独立的线程中独立地应用于多个数据单元。ML工作负载通常允许这种独立性,因此可扩展为高度多线程执行。
中央处理器
当使用CPU进行推理时,其他NN模型表现出更好的性能。值得尝试两个选项,测量推理时间,然后再决定。当模型较小时,CPU可能是一个不错的选择,并且实际工作量可与在设备之间传输输入和输出数据的开销相提并论。或者,在某些情况下,有必要使用特定层的自定义实现。如果该框架仅允许CPU使用(例如,使用C ++),则将进行其他数据传输(不一定会显着影响性能,但这是需要考虑的事情)。
对CPU的推断还依赖于使用多个线程,并且可以使用SIMD指令。这也与图像处理非常吻合(例如,在卷积中,可以一次将多个权重值乘以多个输入值)。Unity Barracuda推理引擎的后端之一使用其Burst Compiler技术,该技术利用SIMD功能并显示出非常好的效果。在Arm Compute Library中,可用的后端之一允许您使用Arm Neon技术,该技术也是SIMD。您可以在Arm Community的ML部分的博客中找到有关CPU推理的更多信息。
并发执行
要考虑的另一件事是使用不同的处理单元并行执行不同的工作负载。例如,如果每个帧执行两个神经网络,则可以为其中一个执行CPU,而为另一个执行GPU。或者,可以将ML工作负载委派给CPU,而GPU将忙于另一种工作负载。
AR是一组并发任务(NN推理,图像处理,图形渲染),因此整体性能取决于整个SoC如何协同工作,而不仅仅是CPU或GPU。Arm的全新Total Compute方法对AR尤为重要,需要将许多计算元素整合在一起,以允许不同的AR用例和工作负载在设备上无缝运行。CPU以省电的方式驱动性能。GPU正在驱动图形。从用户的位置到特定的对象和地标,都使用AI进行检测。然后,我们需要将该IP整合在一起,以在系统中无缝工作,而Arm的互连,安全IP和控制器则可以带来巨大的价值。帮助构建更好的系统,以低功耗约束和高安全性保护为重点。
对于AR而言,重要的不仅是Total Compute的性能和安全性元素。这种新方法还设计并提供了使开发人员能够访问可跨多个平台部署的高性能,以创建最令人兴奋,引人入胜和身临其境的应用程序的技术。此外,我们为开发人员提供了跨我们所有IP(CPU,GPU和NPU)进行编程,调试和分析的框架。
选择框架
正确选择移动ML框架不仅可以简化开发过程,而且可以根据目标设备提高性能。
在我们的移动AR筛选器应用程序项目中,我们需要在每个框架上执行三个神经网络。因此,我们决定付出一些努力将Arm NN集成到我们的项目中,以在Arm设备上获得最佳性能并更好地控制可用的优化选项。
Arm NN是一个低级的机器学习框架,通常不被应用程序开发人员直接使用。但就我们而言,这是值得的。除了针对Arm CPU和GPU进行了优化外,Arm NN还提供了一些选项,使开发人员可以获得更高的性能并减少内存带宽和占用空间。例如,通过使用16位浮点数或OpenCL工作组大小调谐器。您可以在此处找到有关这些功能的更多信息。
当然,选择还取决于框架的可移植性以及使用和调整您的NN模型的容易程度。但是,如果性能是最重要的因素,那么使用Arm NN或CoreML之类的低级选项可能会有所帮助。
管道优化
除了加快NN推理速度外,还可能需要优化管道的其他部分。
在大多数情况下,需要对输入图像进行预处理。它可以是缩放,裁剪或标准化。这些操作的成本可能很高,尤其是当源图像为高分辨率时,因为这些图像是从移动相机流式传输或从图库中加载的。一种提高速度的方法是使用现有的经过优化的库,例如OpenCV。但是在GPU上执行这些操作可能会更加有益。它需要为OpenGL ES,Vulkan或Metal编写自定义着色器,或使用其他工具(例如Android RenderScript)。在我们的项目中,我们使用了Unity着色器,这使我们可以将预处理和后处理速度提高几倍。
oat4 frag(v2f_img i) : COLOR {
float4 foreground = tex2D(_MainTex, i.uv);
float4 background = tex2D(_Background, i.uv * _BackgroundOffsetScale.zw + _BackgroundOffsetScale.xy);
float maskValue = tex2D(_Mask, float2(i.uv.x, 1.0 - i.uv.y)).r;
float4 result = foreground * maskValue + background * (1.0 - maskValue);
return result;
}
自定义Unity着色器,可通过遮罩混合两个纹理并应用偏移以创建视差效果
有时使用电话摄像头(例如YUV)使用的格式的输入图像来训练模型可能是有益的,因为它消除了将输入转换为RGB的需要。
如果输入图像由纹理表示(在GPU上进行了某些处理或如果您使用Android SurfaceTexture之后),并且推理在GPU上运行,则最好将其直接提供给推理引擎(如果可能)。在将纹理作为输入传递之前在CPU上读取纹理的内容(图2a)可能是多余的,并且会影响性能。
同样值得尝试的是在不影响性能的情况下提高质量。可以使用某些技巧来隐藏NN模型的缺陷。例如,如果将人类分割用于背景替换滤镜,则将原始帧与新背景图像融合的方式可能很重要。如果人的边缘看起来不错,那么即使是一个小分辨率的神经网络也足够了-分辨率越小,推理时间就越好。
当您处理连续的帧流时,还有另一种方法可以提高产生灰度蒙版的分段神经网络的质量。如果推论是在GPU上运行,则对当前帧数据使用输入RGBA纹理的三个通道是有意义的。第四个(alpha)通道将用作前一帧的遮罩。必须对模型进行相应的训练。
剖析
当您试图获得更好的性能时,衡量管道的每一步至关重要。它不仅有助于发现瓶颈,而且还可以了解如何重新布置和并行执行管道的不同部分,以避免CPU或GPU停顿。
对神经网络本身进行概要分析也可能非常有用。它显示了哪些层花费最多的时间,诸如修剪之类的某些优化如何提供帮助,以及体系结构的哪些部分对于优化而言不太重要。使用Arm NN进行推理时,最新版本的Arm Streamline允许用户查看各个NN层的执行时间。
图3-Streamline中的Arm NN时间线跟踪
结论
AR涉及执行繁重的计算工作负载。即使具有更强大的移动CPU,GPU和NPU,获得实时性能仍然是一个挑战。但是,移动AR和神经网络模型的普及以及ML框架的不断发展,使开发人员能够以最小的努力获得最高的性能。
该博客展示了一些优化AR移动性能的常用方法。但是,神经网络和技术的选择在很大程度上取决于特定的用例和目标平台。
了解有关Arm NN的更多信息