第一章:ONNX基础认知
大家好,我是你们这门课的主讲。在AI芯片部署这个行当摸爬滚打了七八年,踩过的坑比走过的路还多。今天咱们聊聊ONNX——这个在模型部署圈子里几乎绕不开的东西。
说实话,我第一次接触ONNX的时候,心里也犯嘀咕:这玩意儿到底能干啥?后来用顺手了才发现,它简直就是模型部署的「通用语言」。嗯,咱们今天就把它彻底聊透。
ONNX是什么?
ONNX的全称是Open Neural Network Exchange,直译过来就是「开放神经网络交换格式」。说白了,它就是一种模型文件的中间格式。
你想想看,PyTorch训练出来的模型是.pt文件,TensorFlow的是.pb或.h5,Keras又是.h5。这些格式彼此之间互不兼容。ONNX就是那个「翻译官」——把各家格式统一成一个标准。
我个人习惯把ONNX比作「模型界的USB-C接口」。不管你的训练框架是什么,只要导出成ONNX,就能在各种推理引擎和硬件上跑起来。
核心要点:ONNX不是训练框架,也不是推理引擎。它只是一个中间表示(Intermediate Representation, IR),负责定义模型的计算图和算子。
为什么需要ONNX?
这个问题我经常被问到。其实原因很简单——碎片化太严重了。
我在项目中遇到过这样的情况:算法团队用PyTorch训练了一个检测模型,效果很好。但部署到NPU芯片上时,发现NPU的SDK只支持Caffe和ONNX。你说怎么办?总不能让人家重写一遍吧?
这时候ONNX就派上用场了。PyTorch模型转成ONNX,NPU的推理引擎直接加载,前后不到半小时。要是没有ONNX,你得手动把网络结构一层层翻译过去,那工作量...想想都头疼。
具体来说,ONNX解决了三个核心痛点:
- 框架解耦:训练用PyTorch,部署用ONNX,互不依赖
- 硬件适配:一个ONNX模型,可以跑在CPU、GPU、NPU、FPGA上
- 生态统一:算子定义标准化,不同厂商都按这个标准来
我的经验:如果你团队里既有PyTorch用户,又有TensorFlow用户,ONNX就是那个「和事佬」。我曾经在两个团队之间用ONNX做模型交换,省去了无数扯皮的时间。
ONNX的生态与工具链概览
ONNX不是孤零零的一个格式,它背后有一套完整的工具链。我把它分成三块来说:
1. 模型导出工具
这是最常用的。PyTorch有torch.onnx.export,TensorFlow有tf2onnx,Keras有keras2onnx。基本上主流框架都支持导出ONNX。
# PyTorch导出ONNX示例
import torch
import torch.onnx
model = torch.load('model.pth')
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(model, dummy_input, 'model.onnx',
input_names=['input'],
output_names=['output'],
dynamic_axes={'input': {0: 'batch_size'},
'output': {0: 'batch_size'}})
这段代码我用了无数次。注意那个dynamic_axes参数,它允许你动态调整batch size。我在部署视频流模型时,这个参数帮了大忙——不用因为batch size变化就重新导出模型。
2. 模型优化工具
导出ONNX只是第一步。接下来要优化。ONNX Runtime自带的onnxruntime.optimization可以做常量折叠、算子融合。还有onnx-simplifier,专门用来简化模型结构。
避坑指南:我曾经直接用导出的ONNX模型去部署,结果NPU报错说有不支持的算子。后来用onnx-simplifier一跑,发现模型里有很多冗余的Reshape和Transpose操作。简化之后,NPU跑得飞快。所以记住:导出后一定要做简化!
3. 推理与部署工具
ONNX Runtime是微软官方的推理引擎,支持CPU、GPU、NPU。还有onnx-tensorrt可以把ONNX转成TensorRT引擎,onnx-numpy可以在纯CPU上跑。
我整理了一个表格,方便你快速了解:
| 工具名称 | 主要功能 | 适用场景 |
|---|---|---|
| ONNX Runtime | 跨平台推理引擎 | 通用部署 |
| onnx-simplifier | 模型结构简化 | 导出后必做 |
| onnx-tensorrt | 转TensorRT引擎 | NVIDIA GPU加速 |
| onnx2npu | 转NPU专用格式 | NPU芯片部署 |
| Netron | 模型可视化 | 调试与检查 |
说到Netron,我强烈建议你装一个。它能把ONNX模型的计算图可视化出来。有一次我排查一个模型精度问题,就是靠Netron发现某个算子的输入输出维度对不上。要是没有可视化工具,这种问题查起来简直大海捞针。
小结
好了,这一章的内容就这些。总结一下:
- ONNX是模型部署的「通用语言」,解决框架碎片化问题
- 它让训练和部署解耦,一个模型跑遍各种硬件
- 工具链包括导出、优化、推理三大部分,缺一不可
下一章咱们会深入ONNX的模型结构,聊聊它的计算图、节点和算子。到时候我会拿一个实际模型来拆解,保证你看完就能上手操作。
嗯,今天就到这儿。有什么问题欢迎交流。