5.1.3. INT 模型生成
TPU-MLIR的整体架构如下图所示:
图 5.3 TPU-MLIR的整体架构
相比于迁移float模型,如果要转INT8模型, 则需要调用 run_calibration.py 生成校准表, 然后传给 model_deploy.py。
具体更多细节请参考doc目录下的《TPU-MLIR快速入门指南》
本文以 yolov5s.onnx 为例,介绍TPU-MLIR如何转换模型为INT8格式的BModel并部署。开发环境的配置,可以参考 tpu-mlir 环境初始化, 其他模型迁移请参考doc目录下的《TPU-MLIR快速入门指南》。
yolov5的模型来自 yolov5的官网,可点击本链接进行下载。
5.1.3.1. 加载tpu-mlir
参考 tpu-mlir 环境初始化 ,进入x86主机的Docker环境,并通过pip命令安装tpu-mlir
5.1.3.2. 准备工作目录
建立 model_yolov5s 目录, 建议与tpu-mlir同级目录;并把模型文件和图片文件都放入 model_yolov5s 目录中。
1$ mkdir model_yolov5s && cd model_yolov5s
2$ wget https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.onnx
3$ cp -rf $TPUC_ROOT/regression/dataset/COCO2017 .
4$ cp -rf $TPUC_ROOT/regression/image .
5$ mkdir workspace && cd workspace
这里的 $TPUC_ROOT 是环境变量, 对应tpu-mlir_xxxx目录。
5.1.3.3. ONNX转MLIR
如果模型是图片输入, 在转模型之前我们需要了解模型的预处理。如果模型用预处理后的npz文件做输入, 则不需要考虑预处理。 预处理过程用公式表达如下( \(x\) 代表输入):
官网yolov5的图片是rgb, 每个值会乘以 1/255 , 转换成mean和scale对应为
0.0,0.0,0.0 和 0.0039216,0.0039216,0.0039216 。
模型转换命令如下:
$ model_transform.py \
--model_name yolov5s \
--model_def ../yolov5s.onnx \
--input_shapes [[1,3,640,640]] \
--mean 0.0,0.0,0.0 \
--scale 0.0039216,0.0039216,0.0039216 \
--keep_aspect_ratio \
--pixel_format rgb \
--output_names 350,498,646 \
--test_input ../image/dog.jpg \
--test_result yolov5s_top_outputs.npz \
--mlir yolov5s.mlir
model_transform.py的相关参数已在上一小节说过,这里不再赘述。
对于INT8模型的量化与迁移,需要确保前处理参数准确无误,否则生成的INT8可能会有严重的精度损失。
转成mlir文件后, 会生成一个 ${model_name}_in_f32.npz 文件, 该文件是模型的输入文件。
5.1.3.4. MLIR转INT8模型
5.1.3.4.1. 生成校准表
转INT8模型前需要跑calibration, 得到校准表; 输入数据的数量根据情况准备100~1000张左右,需要 保证量化数据集与测试数据集的数据分布保持一致。
然后用校准表, 生成对称或非对称bmodel模型。如果对称量化精度符合需求, 一般不建议用非对称量化, 因为非对称量化的bmodel模型性能会略差于对称bmodel模型。
这里用现有的100张来自COCO2017的图片举例, 执行calibration:
$ run_calibration.py yolov5s.mlir \
--dataset ../COCO2017 \
--input_num 100 \
-o yolov5s_cali_table
运行完成后会生成名为 yolov5s_cali_table 的文件, 该文件用于后续编译INT8模型的量化表文件。
5.1.3.4.2. 编译为INT8对称量化模型
转成INT8对称量化模型, 执行如下命令:
# bm1688
$ model_deploy.py \
--mlir yolov5s.mlir \
--quantize INT8 \
--calibration_table yolov5s_cali_table \
--processor bm1688 \
--test_input yolov5s_in_f32.npz \
--test_reference yolov5s_top_outputs.npz \
--tolerance 0.85,0.45 \
--num_core 2 \
--model yolov5s_1688_int8_sym_2core.bmodel
# cv186ah
$ model_deploy.py \
--mlir yolov5s.mlir \
--quantize INT8 \
--calibration_table yolov5s_cali_table \
--processor cv186x \
--test_input yolov5s_in_f32.npz \
--test_reference yolov5s_top_outputs.npz \
--tolerance 0.85,0.45 \
--model yolov5s_cv186ah_int8_sym.bmodel
编译完成后, 会生成名为 yolov5s_1688_int8_sym_2core.bmodel 或者 yolov5s_cv186ah_int8_sym.bmodel 的文件。