SS928V100(Hi3403V100)----NNN推理引擎,AMCT-ONNX模型压缩量化踩坑记录(LINUX版)
上篇文章讲解了如何使用 ATC 工具将 ONNX / CAFFE 模型转换为能在 NNN 引擎和 SVP_NNN 引擎上推理用的 om 模型,其中 SVP_NNN 由于只支持 INT8 / INT16 类型,所以在模型转换时通过设置参数的方式直接可以完成浮点模型 ONNX / CAFFE 到 INT8 / INT16 om 模型的流程。但是如是要在 NNN 引擎上运行量化模型,就需要借助 AMCT 模型压缩量化工具了,本文以 AMCT-ONNX 进行讲解。别问我为啥不用 AMCT-CAFFE ,实不相瞒,CAFFE 我量化失败了,proto的合并不是很好搞明白,有关搭建 caffe 环境,可以参考我的这篇文章:Ubuntu18.04 安装py-fast-rcnn步骤
ps:没想到刚工作写的这篇文章,竟然还能帮助到现在的我,这就是命运的回旋镖啊,诸君!
本文所有操作均在 WSL (Windows 虚拟子系统)上操作的,默认 root 环境,默认开发板系统为LINUX,所有环境变量均写入 bashrc 了,非虚拟机用户谨慎写入,相关资源以及代码见文末。
基础环境以及交叉编译工具链的安装,可以参考这篇文章:SS928V100(Hi3403V100)----ATC模型转换工具----SVP_NNN 和 NNN 使用入门指南(LINUX版)
1.简介
- 昇腾模型压缩工具当前使用的压缩方法主要为量化,量化过程中可以实现模型部署优化(主要为算子融合)。
- 昇腾模型压缩工具仅支持在 Ubuntu 18.04 x86_64 架构服务器安装。
- 环境如下,没有使用GPU,所以就没安装cuda相关环境
依赖 | 版本要求(本文使用) |
ONNX |
|
numpy | 1.20.0+ |
protobuf | 3.13.0+ |
Python | Python3.9.x(3.9.0~3.9.2) |
1.1 AMCT-ONNX 安装
解压工具包,本文使用的工具包是:CANN-amct-5.20.t6.2.b060-ubuntu18.04.x86_64.tar.gz
tar -zxvf CANN-amct-5.20.t6.2.b060-ubuntu18.04.x86_64.tar.gz
cd amct_onnx
pip3 install amct_onnx-0.3.2-py3-none-linux_x86_64.whl
1.2 编译并安装自定义算子包
# 该算在包在 amct_onnx 目录下
tar -zvxf amct_onnx_op.tar.gz
cd amct_onnx_op && python3 setup.py build
2. 模型量化(以 RESNET50 为例)
命令行方式 | Python API 接口方式 |
量化过程简单,只涉及参数选择,无需对量化脚本进行适配 | 需要适配修改量化脚本 |
当前仅支持如下特性: (1)训练后量化中的均匀量化 (2)QAT模型适配 CANN 模型 | 支持量化的所有功能 |
2.1 量化前准备
文末链接有完整 samples 以及转换前后的模型,也可以从如下链接获取源码:
- 参考代码源自gitee仓库:
git clone https://gitee.com/ascend/samples.git
- resnet50.onnx模型来自:
wget https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/003_Atc_Models/resnet50/resnet50.onnx
- 量化数据集来自:
wget https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/models/amct_acl/classification/imagenet_calibration.tar.gz
2.2 命令行量化
由于官方samples会随着版本更新出现某些目录变动,本文以文末链接samples为主
# 1.NNN_Quant_resnet_50是文章末尾附带的资源,官方samples目录为{PATH}/samples/python/level1_single_api/9_amct/amct_onnx/cmd
cd {PATH}/NNN_Quant_resnet_50# 2.将下载得到的 onnx_model, imagenet_calibration.tar.gz 分别上传到 model 以及 data 目录
# 3.解压 imagenet_calibration.tar.gz 并转换成量化数据
tar -zxvf imagenet_calibration.tar.gz
# 注意修改 process_data.py 中的 CALIBRATION_SIZE ,需要和实际 onnx 模型的 batch 保持一致
python3 ./data/process_data.py# 4.进行模型量化,量化成功后会在指定目录 results 下生成 deploy_model 结尾的 onnx 模型
amct_onnx calibration \--model ./model/resnet50.onnx \--save_path ./results/resnet50_int8 \--input_shape "actual_input_1:16,3,224,224" \--data_dir "./data/calibration_resnet50/" \--data_types "float32"# 5.量化模型转 om 模型方法1
atc \--model=./results/resnet50_int8_deploy_model.onnx \--framework=5 \--output=./model/resnet50_int8 \--input_fp16_nodes="actual_input_1" \--input_shape="actual_input_1:1,3,224,224" \--soc_version=OPTG# 6.量化模型转 om 模型方法2
atc \--model=./results/resnet50_int8_deploy_model.onnx \--framework=5 \--output=./model/resnet50_int8 \--input_shape="actual_input_1:1,3,224,224" \--soc_version=OPTG# 7.量化模型转 om 模型方法3
atc \--model=./results/resnet50_int8_deploy_model.onnx \--framework=5 \--output=./model/resnet50_int8 \--insert_op_conf=./resnet50_aipp.cfg \--input_shape="actual_input_1:1,3,224,224" \--soc_version=OPTG# resnet50_aipp.cfg 配置内容如下aipp_op {aipp_mode : static # 静态 aapprelated_input_rank : 0 # 标识对第 1 个输入进行 AAPP 处理 src_image_size_w : 224 # 源输入宽高src_image_size_h : 224 input_format : RGB888_U8 # 源输入格式:YUV420SP_U8、XRGB8888_U8、RGB888_U8、YUV400_U8、ARGB8888_U8、YUYV_U8、YUV422SP_U8、AYUV444_U8、RAW10、RAW12、RAW16mean_chn_0 : 123 # 注意,均值的设置必须用整数,否则转换会出问题mean_chn_1 : 116mean_chn_2 : 103var_reci_chn_0 : 0.017120 # = 1 / 58.395var_reci_chn_1 : 0.017496 # = 1 / 57.12var_reci_chn_2 : 0.017433 # = 1 / 57.375
}
- 方法1:模型转换时,设置了 --input_fp16_nodes="actual_input_1",此时需要注意,模型的输入是 FP16 类型的。由于没有采用 AAPP 预处理,数据在送入模型前需要进行resize,crop,normalize 等操作。
- 方法2:模型转换时,没有设置 --input_fp16_nodes,此时模型的输入是 FP32 类型的。由于没有采用 AAPP 预处理,数据在送入模型前需要进行resize,crop,normalize 等操作。
- 方法3:模型转化时,设置了--insert_op_conf=./resnet50_aapp.cfg,此时模型的输入数据类型取决于resnet50_aipp.cfg种设置的数据类型,此时可以设置UINT8类型了。注意输入的数据,需要转换成uint8类型。
量化前模型fp32推理结果 | 量化前模型fp16推理结果 |
![]() | ![]() |
量化后模型推理结果-fp16输入 | 量化后模型推理结果-int8输入 |
![]() | ![]() |
2.3 源码传送门
链接: https://pan.baidu.com/s/1q7mxMK5gUxf-YnRmxzpmXQ 提取码: 5vrq