ss928v100模型的导出、量化和转换
1、yolov8导出为onnx
from ultralytics import YOLOmodel = YOLO("./best.pt")
model.export(format="onnx", imgsz=640, dynamic=False, simplify=True, opset=11, batch=1, half=False)
以下是model.export()
方法各参数的详细解释:
-
format="onnx"
指定导出模型的目标格式为ONNX(Open Neural Network Exchange),这是一种跨平台的神经网络模型交换格式45。 -
imgsz=640
设置模型输入图像的尺寸为640x640像素,需与训练时的输入尺寸保持一致27。 -
dynamic=False
禁用动态输入维度,导出固定输入尺寸的模型。若为True
则允许可变输入尺寸(如批处理维度可变)2。 -
simplify=True
启用ONNX模型的简化优化,去除冗余计算节点以减小模型体积并提升推理效率14。 -
opset=11
指定ONNX算子集的版本为11,不同版本支持的操作符可能不同,需根据部署环境选择兼容版本45。 -
batch=1
设置导出模型的默认批处理大小为1,即单张图片推理。若需支持批量推理需结合dynamic=True
调整26。 -
half=False
禁用FP16半精度浮点数导出,保持FP32全精度。设为True
可减小模型体积但可能损失精度1。
注:参数组合需根据实际部署需求调整,例如边缘设备部署可能需启用simplify
和half
以优化性能14。
2、利用amct工具进行模型量化
amct_onnx calibration --model yolov8n_finetuned.onnx --save_path yolov8n_ll --input_shape "images:1,3,640,640" --data_dir "./images640" --data_types "float32"
其中./images640中放的是resize到640*640的图像的二进制文件,即bin文件。图像转二进制方法:
import cv2
import os
import numpy as npimages = os.listdir("images")
for name in images:img = cv2.imread(os.path.join("images", name),1)img = cv2.resize(img, (640,640))print(img.shape)binary_data = img.flatten().astype('float32').tobytes()print(len(binary_data))with open(os.path.join("images640", name.split('.')[0] + ".bin"), "wb") as file:file.write(binary_data)
对于模型的输入尺寸可以通过代码查询:
import onnxmodel = onnx.load("yolov8n_finetuned.onnx")inputs = model.graph.input
for input in inputs:print(f"Input name: {input.name}")shape = []for dim in input.type.tensor_type.shape.dim:dim_value = dim.dim_value if dim.dim_value != 0 else "?"shape.append(dim_value)print(f"Input shape: {tuple(shape)}")print(f"Data type: {onnx.TensorProto.DataType.Name(input.type.tensor_type.elem_type)}")
--input_shape "images:1,3,640,640"参数中images对应inputname,后面的数字表示shape
3、量化后依然是onnx,需要使用atc工具转换为om格式,即离线模型后才能放入板端运行。
atc --model=yolov8n_finetuned.onnx --framework=5 --output=yolov8n_finetuned --soc_version=OPTG --output_type=FP32 --insert_op_conf=./op-yolo.cfg
其中,framework=5,表示onnx
insert_op_conf需要输入一个配置:op-yolo.cfg 内容如下:
aipp_op {aipp_mode : staticrelated_input_rank : 0max_src_image_size : 1228800support_rotation : falseinput_format : YUV420SP_U8 # RGB888_U8src_image_size_w : 640src_image_size_h : 640cpadding_value: 0.0csc_switch : truerbuv_swap_switch : falseax_swap_switch : falsematrix_r0c0 : 298matrix_r0c1 : 0matrix_r0c2 : 459matrix_r1c0 : 298matrix_r1c1 : -55matrix_r1c2 : -136matrix_r2c0 : 298matrix_r2c1 : 541matrix_r2c2 : 0input_bias_0 : 16input_bias_1 : 128input_bias_2 : 128crop : falseload_start_pos_h : 0load_start_pos_w : 0crop_size_w : 640crop_size_h : 640mean_chn_0 : 124mean_chn_1 : 116mean_chn_2 : 104min_chn_0 : 0.0min_chn_1 : 0.0min_chn_2 : 0.0var_reci_chn_0 : 0.0039215686274509803921568627451var_reci_chn_1 : 0.0039215686274509803921568627451var_reci_chn_2 : 0.0039215686274509803921568627451}
转换完成之后,即可以导入板端运行。