1. 课程导入
各位同学,咱们今天正式开课。第一讲,先聊聊ONNX到底是什么,以及为什么整个行业都在用它做模型转换。
我刚开始做嵌入式AI那会儿,模型转换简直是噩梦。训练用PyTorch,部署用TensorRT,中间还得过一遍Caffe……每个框架都有自己的模型格式,互不兼容。那时候我就在想,要是能有个统一的“中间格式”就好了。后来ONNX出现了,嗯,它就是这个“中间人”。
1.1 什么是ONNX
ONNX的全称是Open Neural Network Exchange,直译过来就是“开放神经网络交换格式”。说白了,它就是一种模型描述语言,用一套标准化的计算图结构,把训练好的模型“存”下来。
你可以把ONNX想象成AI界的通用语言。不管你是用PyTorch、TensorFlow还是Keras训练的模型,都能导出成ONNX格式。然后,这份ONNX文件可以被任何支持ONNX的推理引擎读取并执行。
核心要点:ONNX不是训练框架,也不是推理引擎。它只是一个中间表示(Intermediate Representation, IR),负责在不同框架之间搭桥。
我个人习惯把ONNX模型看作一个“模型快照”。它记录了:
- 网络结构:有哪些层、层与层怎么连接
- 权重参数:训练好的数值
- 输入输出信息:数据类型、形状、名字
举个例子,你训练了一个ResNet-50分类模型。导出成ONNX后,这个文件里就包含了所有卷积层、池化层、全连接层的定义,以及它们之间的连接关系。任何支持ONNX的运行时,都能把这个计算图“复现”出来,然后跑推理。
1.2 ONNX的生态定位
ONNX在AI部署生态里到底处在什么位置?我画了一张图,你看完就明白了。
从这张图你能看到,ONNX处在整个AI部署流程的正中间。左边是各种训练框架,右边是各种推理引擎。ONNX就像一个万能转接头,让左边的东西能被右边理解。
你想想看,如果没有ONNX,你要把PyTorch模型部署到TensorRT上,得先转成Caffe,再转成TensorRT支持的格式。中间但凡有一个环节出错,整个流程就得重来。有了ONNX,你只需要做一次转换:PyTorch → ONNX → TensorRT。省心多了。
1.3 为什么选择ONNX做模型转换
这个问题,我当年也问过自己。市面上又不是没有其他中间格式,为什么偏偏是ONNX?
我总结了几点核心原因,你感受一下:
| 优势 | 说明 | 我的实际感受 |
|---|---|---|
| 生态最广 | 几乎所有主流框架都支持导出ONNX | 我在项目中用过PyTorch、TensorFlow、PaddlePaddle导出,都很顺畅 |
| 算子标准 | ONNX定义了统一的算子集(Opset),不同框架的算子都能映射过来 | 曾经有个自定义算子卡了我两天,后来发现ONNX支持自定义算子注册,问题迎刃而解 |
| 工具链成熟 | 有ONNX Runtime、ONNX Simplifier、onnx-tensorrt等配套工具 | 我习惯用ONNX Simplifier简化模型结构,能减少20%~30%的推理耗时 |
| 硬件适配好 | NVIDIA、Intel、ARM、Qualcomm等厂商都提供ONNX到自家硬件的转换工具 | 在RK3588上部署时,RKNN Toolkit直接支持ONNX导入,省了中间转换步骤 |
| 社区活跃 | 微软、Facebook、AWS等大厂都在维护,更新频繁 | 遇到问题去GitHub提issue,通常24小时内就有回复 |
我的建议:如果你刚开始接触模型部署,优先选择ONNX作为中间格式。它虽然不是性能最优的(比如TensorRT直接加载可能更快),但胜在通用性强、踩坑成本低。等你把ONNX流程跑通了,再针对特定硬件做优化也不迟。
1.4 避坑指南:ONNX不是万能的
说了这么多ONNX的好处,我也得泼点冷水。ONNX不是银弹,它有自己的局限性。
常见坑点:
- 算子兼容性问题:不是所有框架的算子都能映射到ONNX。比如PyTorch的某些高级操作(如torch.einsum),导出时可能报错。
- 动态形状支持有限:ONNX对动态输入形状的支持不够完善。如果你模型的输入尺寸会变化,导出时得做额外处理。
- 性能不是最优:ONNX Runtime虽然快,但跟TensorRT、OpenVINO等专有引擎比,还有差距。
我曾经在一个项目中,用PyTorch训练了一个带Mask R-CNN的模型。导出ONNX时,RoI Align算子死活不支持。后来我查了ONNX的算子文档,发现这个算子直到Opset 16才被加入。嗯,版本问题,得注意。
所以我的建议是:导出前先查ONNX算子支持列表。如果遇到不支持的算子,要么换实现方式,要么用ONNX的自定义算子机制。
1.5 本章小结
咱们这一章就讲这些。核心就三句话:
- ONNX是模型转换的中间格式,不是训练框架也不是推理引擎
- 它在AI部署生态里扮演枢纽角色,连接训练和推理
- 选择ONNX是因为它生态广、工具链成熟、硬件适配好