【YOLOV8模型部署实战】从训练权重.pt到ONNX格式的完整转换指南

张开发
2026/4/14 7:16:14 15 分钟阅读

分享文章

【YOLOV8模型部署实战】从训练权重.pt到ONNX格式的完整转换指南
1. YOLOv8模型部署前的准备工作当你完成YOLOv8模型的训练后会得到一个.pt格式的权重文件。这个文件包含了模型的所有参数和结构信息但它并不是最优的部署格式。在实际应用中我们通常需要将模型转换为ONNX格式以便在不同平台上进行高效推理。为什么选择ONNX格式ONNXOpen Neural Network Exchange是一种开放的模型表示格式它可以让模型在不同的框架和硬件平台之间无缝迁移。比如你想在Intel的OpenVINO上运行模型或者使用NVIDIA的TensorRT进行加速ONNX都是最佳选择。在开始转换之前你需要确保环境配置正确。我建议使用Python 3.8或更高版本并安装最新版的ultralytics库。你可以通过以下命令安装pip install ultralytics onnx onnxruntime安装完成后建议先测试一下YOLOv8的基本功能是否正常。可以尝试加载一个预训练模型进行简单的推理测试from ultralytics import YOLO model YOLO(yolov8n.pt) results model(test.jpg)如果这段代码能正常运行说明你的环境已经准备就绪。接下来我们还需要了解几个关键概念opset版本这是ONNX的操作集版本号决定了模型可以使用哪些算子。不同版本的推理引擎支持的opset可能不同通常建议使用较新的稳定版本。动态维度ONNX支持定义动态输入尺寸这在处理不同分辨率的图像时非常有用。简化优化转换后的ONNX模型可能包含冗余操作后续可以进行优化简化。2. 从.pt到ONNX的完整转换过程2.1 基本转换方法使用ultralytics库将.pt转换为ONNX非常简单官方已经封装好了大部分功能。下面是一个完整的转换示例from ultralytics import YOLO def convert_pt_to_onnx(pt_path, opset12): # 加载训练好的YOLOv8模型 model YOLO(pt_path) # 执行导出 model.export( formatonnx, opsetopset, dynamicTrue, # 启用动态输入尺寸 simplifyTrue, # 简化模型 imgsz(640, 640) # 指定输入尺寸 ) if __name__ __main__: pt_file runs/detect/train/weights/best.pt convert_pt_to_onnx(pt_file)这段代码会生成一个与原始.pt文件同名的.onnx文件保存在相同目录下。几个关键参数说明opset我通常设置为12或13这是目前大多数推理引擎都支持的稳定版本。dynamic设置为True可以让模型接受不同尺寸的输入这在实际部署中很有用。simplify启用模型简化可以去除一些冗余操作。imgsz指定模型的默认输入尺寸需要与训练时的设置一致。2.2 高级参数调优除了基本参数外还有一些高级选项可以优化转换结果model.export( formatonnx, opset13, dynamic{ images: {0: batch, 2: height, 3: width}, # 完全动态输入 output0: {0: batch, 1: anchors} # 动态输出 }, halfTrue, # 使用FP16精度 workspace4, # 指定GPU显存大小(GB) batch1 # 指定批处理大小 )这些参数可以根据你的具体需求调整动态维度控制更精细地定义哪些维度可以是动态的。比如让模型支持任意批处理大小和输入分辨率。半精度浮点使用FP16可以减少模型大小并提高推理速度但可能会轻微影响精度。批处理设置如果你知道部署时的固定批处理大小可以在这里指定以获得更好的优化。3. 转换后的验证与优化3.1 ONNX模型验证转换完成后强烈建议进行验证。可以使用ONNX Runtime进行简单的推理测试import onnxruntime as ort import numpy as np # 创建推理会话 sess ort.InferenceSession(best.onnx) # 准备模拟输入 input_name sess.get_inputs()[0].name fake_input np.random.rand(1, 3, 640, 640).astype(np.float32) # 运行推理 outputs sess.run(None, {input_name: fake_input}) print(outputs[0].shape) # 检查输出形状是否符合预期如果这段代码能正常运行说明ONNX模型的基本结构是正确的。但为了确保完全正确还应该对比原始模型输出使用相同的输入比较.pt模型和ONNX模型的输出是否一致。检查模型结构可以使用Netron工具可视化ONNX模型确认所有节点都正确转换。3.2 模型优化技巧ONNX模型还可以进一步优化图优化使用ONNX Runtime的图优化功能sess_options ort.SessionOptions() sess_options.graph_optimization_level ort.GraphOptimizationLevel.ORT_ENABLE_ALL sess ort.InferenceSession(best.onnx, sess_options)量化将FP32模型量化为INT8可以显著减小模型大小并提高推理速度from onnxruntime.quantization import quantize_dynamic quantize_dynamic( best.onnx, best_quant.onnx, weight_typequantization.QuantType.QInt8 )层融合某些推理引擎支持自动融合操作可以减少内存访问和提升性能。4. 在不同推理引擎上的部署实践4.1 OpenVINO部署ONNX模型可以轻松转换为OpenVINO的IR格式from openvino.tools import mo ov_model mo.convert_model(best.onnx) ov.serialize(ov_model, best.xml) # 生成IR文件OpenVINO会自动优化模型以适应Intel硬件。转换时可以指定目标设备ov_model mo.convert_model( best.onnx, compress_to_fp16True, # 压缩为FP16 deviceCPU # 指定目标设备 )4.2 TensorRT部署对于NVIDIA GPU可以使用TensorRT加速import tensorrt as trt logger trt.Logger(trt.Logger.INFO) builder trt.Builder(logger) network builder.create_network(1 int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser trt.OnnxParser(network, logger) with open(best.onnx, rb) as model: parser.parse(model.read()) config builder.create_builder_config() config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 30) # 1GB engine builder.build_engine(network, config)TensorRT会针对特定GPU进行深度优化通常能获得最佳性能。4.3 跨平台部署建议在实际项目中我遇到过各种部署场景总结几点经验Intel CPUOpenVINO是最佳选择特别是对于x86架构。NVIDIA GPUTensorRT能发挥最大性能但需要针对不同显卡单独优化。ARM设备可以考虑ONNX Runtime的ARM版本或者转换为特定框架的格式。边缘设备可能需要进一步量化或剪枝来减小模型大小。无论选择哪种方案ONNX作为中间格式都能大大简化部署流程。我在一个工业检测项目中使用ONNX格式成功将同一个模型部署到了Intel NUC、NVIDIA Jetson和华为Atlas三种不同的硬件平台上大大减少了开发工作量。

更多文章