1. YOLO与ONNX基础:从模型到部署的桥梁
各位同学好,我是老张。做AI部署这些年,我最大的感触就是:模型训练只是开始,真正落地才是硬仗。今天咱们就从YOLO的发展史和ONNX这个中间格式讲起,把地基打牢。
本章核心脉络:理解YOLO各版本的演进逻辑 → 掌握ONNX作为中间表示的价值 → 学会用ONNX Runtime做推理验证
1.1 YOLO发展史:从v3到v10,我踩过的坑
YOLO(You Only Look Once)系列,说白了就是把目标检测当成回归问题来做。一张图进去,直接出边界框和类别概率。跟两阶段检测器比,它快得多。
YOLOv3(2018)——我入坑的第一个版本。它引入了Darknet-53骨干网络、多尺度预测(FPN思想),还有Logistic分类器替代Softmax。说实话,v3在精度和速度上取得了很好的平衡,至今很多工业场景还在用。
YOLOv5(2020)——注意,这不是官方延续,是Ultralytics团队用PyTorch实现的。我当年从v3切到v5,最直观的感受就是:训练更稳,部署更友好。它引入了自适应锚框计算、Focus结构、CSPNet,还有Mosaic数据增强。嗯,这里要提醒一句:v5的模型导出到ONNX非常顺畅,这也是它成为工业首选的原因之一。
YOLOv8(2023)——同样是Ultralytics出品。v8把Anchor-Free和Anchor-Based统一了,还支持分类、分割、姿态估计等多任务。我个人习惯用v8做新项目,因为它的代码结构清晰,导出ONNX几乎零改动。
YOLOv10(2024)——清华团队的最新成果。它最大的变化是去掉了NMS后处理,用一致双分配策略实现端到端检测。我在测试时发现,v10的延迟比v8低了30%以上,但精度基本持平。
| 版本 | 核心改进 | 部署友好度 | 我的评价 |
|---|---|---|---|
| YOLOv3 | 多尺度预测、Darknet-53 | 中等(需手动转ONNX) | 经典但老了 |
| YOLOv5 | CSPNet、自适应锚框 | 高(官方支持导出) | 工业首选 |
| YOLOv8 | Anchor-Free、多任务 | 极高(一键导出) | 新项目首选 |
| YOLOv10 | 无NMS、端到端 | 高(需注意算子兼容) | 未来趋势 |
我的建议:如果你刚接触YOLO部署,从v5或v8开始。v3的算子太老,有些TensorRT版本不支持。v10虽然新,但无NMS的设计在部分硬件上还有兼容问题。
1.2 ONNX格式介绍:为什么需要它?
ONNX(Open Neural Network Exchange),说白了就是模型的通用语言。你想想看,PyTorch训练出来的模型是.pt文件,TensorFlow是.pb文件,Keras是.h5文件……每个框架各说各话,部署时怎么办?
ONNX就是那个翻译官。它定义了一套标准化的计算图表示,让模型可以在不同框架和推理引擎之间自由迁移。
我曾经在一个项目里,客户要求用TensorRT做推理,但团队只会PyTorch。怎么办?先转ONNX,再转TensorRT。整个过程只花了半天,如果重写模型,至少一周。
ONNX的核心组成:
- 计算图(Graph):描述数据流向和算子节点
- 算子集(Opset):定义了每个操作的标准接口
- 元数据(Metadata):模型版本、输入输出信息等
避坑指南:我曾经因为Opset版本不匹配,在转TensorRT时卡了两天。ONNX的算子集是向下兼容的,但不同推理引擎支持的Opset版本不同。建议统一用Opset 11或12,兼容性最好。
1.3 ONNX与PyTorch的关系
PyTorch从1.2版本开始内置了torch.onnx.export接口。你训练好的模型,一行代码就能导出为ONNX格式。
但这里有个关键点:ONNX不是PyTorch的附属品。它只是一个中间表示,PyTorch负责把模型“翻译”成ONNX,之后PyTorch就不管了。推理时,你可以用ONNX Runtime、TensorRT、OpenVINO等任何支持ONNX的引擎。
我见过不少新手问:“转成ONNX后还能用PyTorch推理吗?”当然可以,但那就失去意义了。ONNX的价值在于脱离框架依赖,让模型跑在更高效的推理引擎上。
# PyTorch导出ONNX的标准流程
import torch
import torch.onnx
# 假设model是训练好的YOLOv8模型
model = torch.load('yolov8n.pt')
model.eval()
# 构造一个虚拟输入
dummy_input = torch.randn(1, 3, 640, 640)
# 导出ONNX
torch.onnx.export(
model,
dummy_input,
'yolov8n.onnx',
opset_version=12,
input_names=['images'],
output_names=['output'],
dynamic_axes={'images': {0: 'batch_size'},
'output': {0: 'batch_size'}}
)
注意:dynamic_axes参数很关键。如果你需要动态batch推理,一定要加上。否则导出的ONNX只能固定batch=1。
1.4 ONNX Runtime简介
ONNX Runtime(简称ORT)是微软开源的跨平台推理引擎。它直接读取ONNX模型,不需要任何框架依赖。
我为什么推荐它?三个理由:
- 速度快:比PyTorch原生推理快2-5倍
- 跨平台:Windows、Linux、ARM、甚至浏览器都能跑
- 优化自动:图优化、算子融合、内存复用都是自动的
用ORT做推理,代码非常简洁:
import onnxruntime as ort
import numpy as np
# 创建推理会话
session = ort.InferenceSession('yolov8n.onnx')
# 准备输入
input_data = np.random.randn(1, 3, 640, 640).astype(np.float32)
# 执行推理
outputs = session.run(['output'], {'images': input_data})
# outputs就是模型输出
print(outputs[0].shape)
你看,不需要PyTorch,不需要CUDA,一个ONNX文件加一个ORT库就能跑起来。这就是ONNX生态的魅力。
本章小结:YOLO从v3到v10,部署越来越友好;ONNX作为中间格式,解决了框架碎片化问题;ONNX Runtime是验证ONNX模型的最佳工具。下一章,我们会手把手带你完成YOLOv8到ONNX的完整转换。