本节将以模型静态shape和动态shape两种场景分别介绍量化配置步骤,其中静态shape模型以ResNet50为例,动态shape模型以YoloV5m为例,指导用户调用Python API接口对模型进行Data-Free模式的识别和量化,并将量化后的模型保存为.onnx文件,量化后的模型可以在推理服务器上运行。
如下命令如果使用非root用户安装,需要在安装命令后加上--user,例如:pip3 install onnx --user。
pip3 install numpy #需大于等于1.21.0版本 pip3 install onnx #需大于等于1.11.0版本 pip3 install onnxruntime #需大于等于1.12.1版本 pip3 install torch==1.11.0 #支持1.8.1和1.11.0,须为CPU版本的torch pip3 install onnx-simplifier #需大于等于0.3.10版本
from modelslim.onnx.squant_ptq import OnnxCalibrator, QuantConfig # 导入squant_ptq量化接口 from modelslim import set_logger_level # 可选,导入日志配置接口 set_logger_level("info") # 可选,调整日志输出等级,配置为info时,启动量化任务后将打屏显示量化调优的日志信息 config = QuantConfig() # 使用QuantConfig接口,配置量化参数,并返回量化配置实例,当前示例使用默认配置 input_model_path = "./resnet50_official.onnx" # 配置待量化模型的输入路径,请根据实际路径配置 output_model_path = "./resnet50_official_quant.onnx" # 配置量化后模型的名称及输出路径,请根据实际路径配置 calib = OnnxCalibrator(input_model_path, config) # 使用OnnxCalibrator接口,输入待量化模型路径,量化配置数据,生成calib量化任务实例,其中calib_data为可选配置,可参考精度保持策略的方式三输入真实的数据 calib.run() # 执行量化 calib.export_quant_onnx(output_model_path) # 导出量化后模型
python3 resnet50_quant.py
bash pth2onnx.sh --tag 6.1 --model yolov5m --nms_mode nms_script
from modelslim.onnx.squant_ptq import OnnxCalibrator, QuantConfig # 导入squant_ptq量化接口 from modelslim import set_logger_level # 可选,导入日志配置接口 set_logger_level("info") # 可选,调整日志输出等级,配置为info时,启动量化任务后将打屏显示量化调优的日志信息 config = QuantConfig(is_dynamic_shape = True, input_shape = [[1,3,640,640]]) # 使用QuantConfig接口,配置量化参数,返回量化配置实例,其中is_dynamic_shape和input_shape参数在动态shape场景下必须配置,其余参数使用默认配置 input_model_path = "./yolov5m.onnx" # 配置待量化模型的输入路径,请根据实际路径配置 output_model_path = "./yolov5m_quant.onnx" # 配置量化后模型的名称及输出路径,请根据实际路径配置 calib = OnnxCalibrator(input_model_path, config) # 使用OnnxCalibrator接口,输入待量化模型路径,量化配置数据,生成calib量化任务实例,其中calib_data为可选配置,可参考精度保持策略的方式三输入真实的数据 calib.run() # 执行量化 calib.export_quant_onnx(output_model_path) # 导出量化后模型
python3 yolov5m_quant.py
为了进一步降低量化精度损失,Data-Free模式下集成了多种精度保持方式,具体如下:
def get_calib_data(): import cv2 import numpy as np img = cv2.imread('/xxx/cat.jpg') img_data = cv2.resize(img, (224, 224)) img_data = img_data[:, :, ::-1].transpose(2, 0, 1).astype(np.float32) img_data /= 255. img_data = np.expand_dims(img_data, axis=0) return [[img_data]]