前言:去年NCNN发布了模型量化的解决方案,作为目前中国大陆被使用最多的端侧模型推理解决方案,NCNN开源的代码值得认真阅读和研究。这篇博客笔者和大家一起探索NCNN的模型量化部分,希望大家在NCNN的世界里玩得开心。
目录
量化方法分类
INT8静态离线量化
源码解析
第一步:Optimize model
第二步:创建校准数据
第三步:量化模型
量化后模型推理
量化方法分类
量化方法根据是否需要校正数据可以分成在线量化和离线量化。动态离线量化是不需要任何校准数据的,但是损失精度较多,所以使用的并不是很多。我觉得在生成类任务中,这种很难有校准数据的场景下,可以使用动态离线量化。但是实际的业务场景中,使用静态离线量化会比较多一些,在易用性和精度损失之间做了一个平衡。
相关的知识可以看看飞桨中文的手册,总结的非常清楚:量化 — PaddleSlim 文档
NCNN使用的是INT8静态离线量化,超低比特量化(INT4/INT2)在工业界尚未大规模应用,但是学术界已经有不少论文讨论这一问题,后面我会专门写一些文章讨论这些问题的,先埋个坑。
INT8静态离线量化
首先我们要准备校准数据,下载地址:GitHub - nihui/imagenet-sample-images: 1000 images, one per image-net class. For easy visualization/exploration of classes.
动工前观察一下数据,是一个算法工程师的好习惯:
一共1k张,来自imagenet-1k,也就是每个类有有一张图片,图片的大小不一。
源码解析
量化部分放在ncnn/tools/quantize/目录下:
ncnn/tools/quantize at master · Tencent/ncnn · GitHub
使用文档:ncnn/quantized-int8-inference.md at master · Tencent/ncnn · GitHub
以mobilenet 量化为例子,只需要三个步骤就可以完成静态离线量化:
第一步:Optimize model
./ncnnoptimize mobilenet.param mobilenet.bin mobilenet-opt.param mobilenet-opt.bin 0
第二步:创建校准数据
find images/ -type f > imagelist.txt
./ncnn2table mobilenet-opt.param mobilenet-opt.bin imagelist.txt mobilenet.table mean=[104,117,123] norm=[0.017,0.017,0.017] shape=[224,224,3] pixel=BGR thread=8 method=kl
./ncnn2table mobilenet-opt.param mobilenet-opt.bin imagelist-bgr.txt,imagelist-depth.txt mobilenet.table mean=[104,117,123],[128] norm=[0.017,0.017,0.017],[0.0078125] shape=[224,224,3],[224,224,1] pixel=BGR,GRAY thread=8 method=kl
第三步:量化模型
./ncnn2int8 mobilenet-opt.param mobilenet-opt.bin mobilenet-int8.param mobilenet-int8.bin mobilenet.table
./ncnn2int8 rnn-model.param rnn-model.bin rnn-model-int8.param rnn-model-int8.bin
量化后模型推理
ncnn::Net mobilenet;
mobilenet.load_param("mobilenet-int8.param");
mobilenet.load_model("mobilenet-int8.bin");