参考:https://zhuanlan.zhihu.com/p/73207495
https://blog.csdn.net/qq_37643960/article/details/97182962
今天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的如下几个选项:
MNN_USE_INT8_FAST没有这个参数也能编译
option(MNN_BUILD_QUANTOOLS "Build Quantized Tools or not" ON)
option(MNN_USE_INT8_FAST "Enable Int8 Fast Optimization" ON)
然后生成项目所需的schema文件,并建立文件夹进行编译。
如果以前有build目录,需要把build目录清空,或者备份后清空.
./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++部署流程。另外欢迎大家留言讨论、关注专栏,谢谢大家!