注意:本工具为“离线量化”工具,即训练之后的量化。 带训练量化请看这里
由于MNN训练框架不太成熟,如果你的模型用MNN训练框架训练不起来,可以试试MNNPythonOfflineQuant工具

量化的作用

量化将网络中主要算子(卷积)由原先的浮点计算转成低精度的Int8计算,减少模型大小并提升性能
本文介绍离线无训练量化工具,对于精度有进一步要求请使用训练量化方式:
https://www.yuque.com/mnn/cn/bhz5eu

编译

编译宏

编译MNN时开启MNN_BUILD_QUANTOOLS宏,即开启量化工具的编译
eg:

  1. cmake .. -DMNN_BUILD_QUANTOOLS=on

编译产物

量化模型的工具: quantized.out

量化工具的使用

命令

  1. ./quantized.out origin.mnn quan.mnn imageInputConfig.json

第一个参数为原始模型文件路径,即待量化的浮点模
第二个参数为目标模型文件路径,即量化后的模型
第三个参数为预处理的配置项,参考imageInputConfig.json

Json 配置

format

图片统一按RGBA读取,然后转换到format指定格式
可选:”RGB”, “BGR”, “RGBA”, “GRAY”

mean, normal

同 ImageProcess 的配置
dst = (src - mean) * normal

width, height

模型输入的宽高

path

存放校正特征量化系数的图片目录

used_image_num

用于指定使用上述目录下多少张图片进行校正,默认使用path下全部图片

注意:请确保图片经过上述步骤处理之后的数据是输入到模型input接口的数据

feature_quantize_method

指定计算特征量化系数的方法
可选:

  1. “KL”: 使用KL散度进行特征量化系数的校正,一般需要100 ~ 1000张图片(若发现精度损失严重,可以适当增减样本数量,特别是检测/对齐等回归任务模型,样本建议适当减少)
  2. “ADMM”: 使用ADMM(Alternating Direction Method of Multipliers)方法进行特征量化系数的校正,一般需要一个batch的数据
  3. “EMA”:使用指数滑动平均来计算特征量化参数,这个方法会对特征进行非对称量化,精度可能比上面两种更好。这个方法也是MNNPythonOfflineQuant的底层方法,建议使用这个方法量化时,保留你pb或onnx模型中的BatchNorm,并使用 —forTraining 将你的模型转到MNN,然后基于此带BatchNorm的模型使用EMA方法量化。另外,使用这个方法时batch size应设置为和训练时差不多最好。

默认:”KL”

weight_quantize_method

指定权值量化方法
可选:

  1. “MAX_ABS”: 使用权值的绝对值的最大值进行对称量化
  2. “ADMM”: 使用ADMM方法进行权值量化

默认:”MAX_ABS”

上述特征量化方法和权值量化方法可进行多次测试,择优使用

feature_clamp_value

特征的量化范围,默认为127,即[-127, 127]对称量化,有时,量化之后溢出会很多,造成误差较大,可适当减小此范围,如减小至120,但范围减小太多会导致分辨率下降,使用时需测试

weight_clamp_value

权值的量化范围,默认127,作用同feature_clamp_value,由于权值精度模型效果影响较大,建议调整feature_clamp_value即可

skip_quant_op_names

跳过不量化的op的卷积op名字,因为有些层,如第一层卷积层,对模型精度影响较大,可以选择跳过不量化,可用netron可视化模型,找到相关op名字

batch_size

EMA方法中指定batch size,应该和模型训练时差不多

debug

是否输出debug信息,true或者false,输出的debug信息包含原始模型和量化模型各层输入输出的余弦距离和溢出率

量化模型的使用

和浮点模型同样使用方法,输入输出仍然为浮点类型

参考资料

Extremely Low Bit Neural Network: Squeeze the Last Bit Out with ADMM https://www.aaai.org/ocs/index.php/AAAI/AAAI18/paper/viewFile/16767/16728