张新栋 · 2020年04月15日

实战MNN之量化部署

首发:https://zhuanlan.zhihu.com/p/73207495
作者:张新栋

今天MNN更新了新的工具包---CNN网络量化工具(quantization),作者也第一时间进行了测试。提升的效果还是很可观的,量化前的CNN网络大小约为5.7M,在rk3399(android-8.1)的inference速度约为45ms。使用MNN提供的quantization工具进行量化后,模型大小减少为1.5M,在rk3399中的inference速度为29ms

其使用的流程非常友好,首先使用MNN提供的量化工具对CNN的模型参数文件进行量化编码,编码后的模型可直接由MNN提供的inference-api进行调用,输入和输入跟进行float32的inference一样,接口和调用方式不需要进行任何改变,目前的目标平台主要还是针对CPU上的int8进行加速。所以,很多对时延有要求的小模型,同时恰好平台中没有GPU或其他辅助计算的协处理器的,可以考虑利用量化模型和量化int8推断的方式来进一步提升网络的性能效率。

具体量化的算法和过程,我们会在后续的文章跟大家进行讨论。下面我们进入实际操作环节,首先要同步到最近版本的MNN代码。如果你已经clone过,执行如下命令进行同步即可

git pull

进入MNN的主目录,在进行编译前,需要确认打开CMakeList.txt的如下几个选项:

option(MNN_BUILD_QUANTOOLS "Build Quantized Tools or not" ON)
option(MNN_USE_INT8_FAST "Enable Int8 Fast Optimization" ON)

然后生成项目所需的schema文件,并建立文件夹进行编译。

./schema/generate.sh
mkdir build && cd build && cmake .. && make -j4

此时你会在build目录中看见quantized.out文件,这个就是编译好的量化工具。使用很简单,MNN中也给出了使用案例,命令行中执行

./quantized.out face_det_300.mnn face_det_300_quant.mnn face_det.json 

其中json文件为量化的一些预定义参数,可参考我的配置文件。在进行给定均值方差的白化操作时,MNN的量化工具使用的方式为O = (image - mean) * normal的方式,跟我们常见的除以std是一样的。另外需要注意的是,path目录需要给定一个,否则程序在运行过程中可能会崩溃(当然你也可以对量化的源码进行修改)。为了得到较好的量化精度,给定path的文件夹内的数据的domain需要和训练模型的数据domain一致。或者干脆把训练数据选取一些放到该目录下,理论上数据越多效果越好,量化的速度越慢。笔者在实验的时候在目录下放了100张的图片数据。

{
    "format":"RGB",
    "mean":[
        123.0,
        123.0,
        123.0
    ],
    "normal":[
        0.017,
        0.017,
        0.017
    ],
    "width":224,
    "height":224,
    "path":"../resource/images"
}

得到量化后的模型文件face\_det\_300\_quant.mnn以后,就可以直接用来进行推断了。如果你想在PC中进行测试,使用编译好的benchmark.out文件就可以,将face\_det\_300\_quant.mnn和face\_det\_300.mnn一起放入测试文件夹路径下,然后执行如下命令即可,

./benchmark.out models_folder [loop_count] [forwardtype]

其中models\_folder为face\_det\_300\_quant.mnn所在的目录,loop\_count为循环的次数,forwardtype为推断的类型,有cpu、opencl、opengl、vulkan等等,这里forwardtype选择0即可。写好的测试脚本如下

./benchmark.out ./models 10 0

随后就可以看到face\_det\_300\_quant.mnn和face\_det\_300.mnn的测试平均耗时了。

另外需要注意的是,本人文中开始的实验结果为基于android-8.1系统的rk3399平台。在PC上不一定能达到好的加速效果,只能保证量化好模型的正确性。

  • 最后

如果对如何在安卓平台上进行MNN部署感兴趣的话,可以参考我之前写过的两篇文章进行部署,详解MNN的tf-MobilenetSSD-cpp部署流程详解MNN的tflite-MobilenetSSD-c++部署流程


推荐阅读

专注嵌入式端的AI算法实现,欢迎关注作者微信公众号和知乎嵌入式AI算法实现专栏

WX20200305-192544.png

更多嵌入式AI相关的技术文章请关注极术嵌入式AI专栏

推荐阅读
关注数
18808
内容数
1352
嵌入式端AI,包括AI算法在推理框架Tengine,MNN,NCNN,PaddlePaddle及相关芯片上的实现。欢迎加入微信交流群,微信号:aijishu20(备注:嵌入式)
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息