MNN推理引擎框架简介

1.MNN介绍

随着手机算力的不断提升,以及深度学习的快速发展,特别是小网络模型不断成熟,原本在云端执行的推理预测就可以转移到端上来做。端智能即在端侧部署运行AI算法,相比服务端智能,端智能具有低延时、兼顾数据隐私、节省云端资源等优势。

MNN(Mobile Neural Network)一个轻量级的深度神经网络推理引擎,在端侧加载深度神经网络模型进行推理预测。目前,MNN已经在阿里巴巴的手机淘宝、手机天猫、优酷等20多个App中使用,覆盖直播、短视频、搜索推荐、商品图像搜索、互动营销、权益发放、安全风控等场景。此外,IoT等场景下也有若干应用。

图 1:MNN概述图

2.MNN整体方案

图 2:MNN框架

由上图所示,MNN基本的工作流由两部分组成,即Offline Conversion和On-device Inference。

Converter由Frontends和Graph Optimize构成。前者负责支持不同的训练框架,MNN当前支持Tensorflow(Lite)、Caffe和ONNX(PyTorch/MXNet的模型可先转为ONNX模型再转到MNN),最终全部转换为MNN自定义的模型格式(.mnn);后者通过算子融合、算子替代、模型压缩、布局调整等方式对图进行基本的优化操作。

On-device Inference由三部分组成,分别是:Pre-inference、算子级优化和Backend Abstraction。在Pre-inference模块中引入了一种对可选计算方案的代价评估机理,在已知输入大小和内核形状的前提下,从多种方案中选择一种最优的方案;算子级优化主要包括在卷积和反卷积中应用Winograd算法、在矩阵乘法中应用Strassen算法、低精度计算、手写汇编、多线程优化、内存复用等;Backend Abstraction主要是提供了一套统一的接口来隐藏后端的差异,支持多种硬件架构,支持OpenCL,OpenGL,Vulkan和Metal等,可以方便地进行扩展,比如TPU、FPGA等。

3. Pre-inference

图 3:加速方案选择

在移动应用中,计算速度和轻量化是主要考虑的因素,为了实现轻量化,就不能使用OpenBLAS和Eigen等加速库,所以有一些推理引擎框架中使用手工搜索的方式,不依赖于任何外部库,使用汇编指令case by case地实现算子,这种方式可以使推理引擎变得轻量化和高效,但是case by case的优化是非常耗时的,而且很难覆盖所有算子。这种推理引擎的代表如NCNN (Tencent, 2017),MACE (Xiaomi, 2018)和Anakin (Baidu, 2018)。

与手工搜索形成强烈对比的是全自动搜索,其典型代表是TVM,它不仅解决了多余依赖的问题,同时为模型和后端提供了图级和算子级的优化,所以TVM在模型和设备多样性方面的支持非常好,但是这也是有代价的,TVM生成的运行时是模型特例化的,换句话说,当需要更新模型时,就需要TVM重新生成运行时库,这对于移动应用来说是不可接受的。MNN采用的是一种半自动搜索的方式,在通用性和高性能上都实现了增强。

3.1 计算方案选择

MNN实现了一种代价评估机理,充分考虑了算法实现和后端特性,从多种实现方案中找到最优的方案,如下是代价计算公式:

为了使总的代价最小,那么就需要在算法和后端上分别选择最快的方式,针对算法部分的代价,以卷积为例,目前最快的实现算法有两种选择Sliding window和Winograd,针对各种各样的卷积配置,动态地选择计算代价最小的算法,选择方式是:

- 如果kernel size为1,就是一个矩阵乘,那么使用Strassen算法是最合适的。

- 如果kernel size大于1,使用Winograd 将卷积操作转换为矩阵乘,理论上卷积的代价用如下公式表示:

基于这个公式,可以选择最优的输出大小来最小化cost。所以对于卷积的代价评估如下:

第二个问题就是怎么计算后端的代价,最小化后端代价,其实就是针对每个算子,选择最佳的后端,这样可以保证全局是代价最小的:

3.2 准备—执行解耦

在程序执行期间,正常情况下计算是伴随着内存的申请和释放的,对于移动应用来说,在内存管理上的开销是不可忽视的。考虑到输入大小已经确定,引擎可以将所有的算子虚拟执行一遍,得到确切的内存需求。这样的话,可以在Pre-Inference阶段预先将需要的内存分配出来,并在在执行阶段重复利用,原理如图4所示:

图 4:内存分配和计算解耦

MNN宣称采用准备—执行解耦,在CPU上有7%~8%的提升,在GPU上50%~75%的提升,GPU上提升明显,是因为GPU上需要设置命令Buffer和与之相关的命令描述等,这些工作对于GPU来说也是非常耗时的,将其放在准备阶段,能有非常大的性能提升。

4. 内核优化

内核指的是一个算子的详细实现。这块的优化主要来源于两个方面:算法和调度,即选择具有最低复杂度的算法和对硬件资源进行充分利用。

4.1 Winograd 优化

Winograd快速卷积算法已经被很多推理框架所广泛采用,定义如下:

其中内核W(大小为[k,k]),输入为X(大小为[n+k-1,n+k-1]),输出Y(大小为[n,n]),G,B,A分别为对应的转换矩阵。

块划分和Pipelining

在Winograd卷积算法中,X只是整个输入的一小部分,问题是怎么进行块划分,划分多少个块?从输出看,假如输出的大小为[![img](file:///C:\Users\00239830\AppData\Local\Temp\ksohtml16672\wps13.png)],用T表示每次并行计算的Blocks数,则T为:

其中

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux基金会AI&Data基金会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值