第一步: 生成混精度量化表
使用 run_qtable.py 生成混精度量化表, 相关参数说明如下:
run_qtable.py 参数功能
参数名 | 必选? | 说明 |
---|
无 | 是 | 指定mlir文件 |
dataset | 否 | 指定输入样本的目录, 该路径放对应的图片, 或npz, 或npy |
data_list | 否 | 指定样本列表, 与dataset必须二选一 |
calibration_table | 是 | 输入校准表 |
chip | 是 | 指定模型将要用到的平台, 支持bm1684x/bm1684/cv183x/cv182x/cv181x/cv180x |
fp_type | 否 | 指定混精度使用的float类型, 支持auto,F16,F32,BF16,默认为auto,表示由程序内部自动选择 |
input_num | 否 | 指定输入样本数量, 默认用10个 |
expected_cos | 否 | 指定期望网络最终输出层的最小cos值,一般默认为0.99即可,越小时可能会设置更多层为浮点计算 |
min_layer_cos | 否 | 指定期望每层输出cos的最小值,低于该值会尝试设置浮点计算, 一般默认为0.99即可 |
debug_cmd | 否 | 指定调试命令字符串,开发使用, 默认为空 |
o | 是 | 输出混精度量化表 |
本例中采用默认10张图片校准, 执行命令如下(对于CV18xx系列的芯片,将chip设置为对应的芯片名称即可):
$ run_qtable.py yolov3_tiny.mlir \
--dataset ../COCO2017 \
--calibration_table yolov3_cali_table \
--chip bm1684x \
--min_layer_cos 0.999 \ #若这里使用默认的0.99时,程序会检测到原始int8模型已满足0.99的cos,从而直接不再搜素
--expected_cos 0.9999 \
-o yolov3_qtable
执行完后最后输出如下打印:
int8 outputs_cos:0.999317
mix model outputs_cos:0.999739
Output mix quantization table to yolov3_qtable
total time:44 second
上面int8 outputs_cos表示int8模型原本网络输出和fp32的cos相似度,mix model outputs_cos表示部分层使用混精度后网络输出的cos相似度,total time表示搜索时间为44秒,
另外,生成的混精度量化表 yolov3_qtable, 内容如下:
# op_name quantize_mode
convolution_output11_Conv F16
model_1/leaky_re_lu_2/LeakyRelu:0_LeakyRelu F16
model_1/leaky_re_lu_2/LeakyRelu:0_pooling0_MaxPool F16
convolution_output10_Conv F16
convolution_output9_Conv F16
model_1/leaky_re_lu_4/LeakyRelu:0_LeakyRelu F16
model_1/leaky_re_lu_5/LeakyRelu:0_LeakyRelu F16
model_1/leaky_re_lu_5/LeakyRelu:0_pooling0_MaxPool F16
model_1/concatenate_1/concat:0_Concat F16
该表中, 第一列表示相应的layer, 第二列表示类型, 支持的类型有F32/F16/BF16/INT8。
另外同时也会生成一个loss表文件 full_loss_table.txt, 内容如下:
# chip: bm1684x mix_mode: F16
###
No.0 : Layer: convolution_output11_Conv Cos: 0.984398
No.1 : Layer: model_1/leaky_re_lu_5/LeakyRelu:0_LeakyRelu Cos: 0.998341
No.2 : Layer: model_1/leaky_re_lu_2/LeakyRelu:0_pooling0_MaxPool Cos: 0.998500
No.3 : Layer: convolution_output9_Conv Cos: 0.998926
No.4 : Layer: convolution_output8_Conv Cos: 0.999249
No.5 : Layer: model_1/leaky_re_lu_4/LeakyRelu:0_pooling0_MaxPool Cos: 0.999284
No.6 : Layer: model_1/leaky_re_lu_1/LeakyRelu:0_LeakyRelu Cos: 0.999368
No.7 : Layer: model_1/leaky_re_lu_3/LeakyRelu:0_LeakyRelu Cos: 0.999554
No.8 : Layer: model_1/leaky_re_lu_1/LeakyRelu:0_pooling0_MaxPool Cos: 0.999576
No.9 : Layer: model_1/leaky_re_lu_3/LeakyRelu:0_pooling0_MaxPool Cos: 0.999723
No.10 : Layer: convolution_output12_Conv Cos: 0.999810
该表按cos从小到大顺利排列, 表示该层的前驱Layer根据各自的cos已换成相应的浮点模式后, 该层计算得到的cos, 若该cos仍小于前面min_layer_cos参数,则会将该层及直接后继层设置为浮点计算。
run_qtable.py 会在每次设置某相邻2层为浮点计算后,接续计算整个网络的输出cos,若该cos大于指定的expected_cos,则退出搜素。因此,若设置更大的expected_cos,会尝试将更多层设为浮点计算
第三步: 验证混精度模型
$ detect_yolov3.py \
--model yolov3_mix.bmodel \
--input ../COCO2017/000000366711.jpg \
--output yolov3_mix.jpg
执行完后打印结果为:
person:63.9%
orange:73.0%
得到图片yolov3_mix.jpg, 如下( yolov3_tiny 混精度对称量化执行效果 ):
可以看出混精度后, 检测结果更接近原始模型的结果。
需要说明的是,除了使用run_qtable生成量化表外,也可根据模型中每一层的相似度对比结果,自行设置量化表中需要做混精度量化的OP的名称和量化类型。