深度学习模型交换格式_ONNX

ONNX(Open Neural Network Exchange)已经成为目前深度学习模型交换(Model Exchange)的事实行业标准(de facto standard) 。虽然不是所有框架和厂商都完全支持 ONNX 的所有算子,但在模型部署领域,它几乎是最通用的中间格式。


为什么大家都用 ONNX?

核心原因只有一句话:

训练框架和部署框架是分离的,需要一个"通用语言"。

例如,一个典型的开发流程:

text 复制代码
PyTorch
    │
    │ 训练模型
    ▼
model.pt
    │
    │ 导出
    ▼
model.onnx
    │
 ┌──┴───────────────┐
 │                  │
TensorRT         OpenVINO
 │                  │
Jetson          Intel CPU
 │
SNPE
 │
Qualcomm

如果没有 ONNX,每个平台都要支持所有训练框架,几乎不可能。


ONNX 是什么?

ONNX 可以理解成:

深度学习领域的"PDF"。

例如:

Word

PDF

任何电脑都能打开

同样:

text 复制代码
PyTorch

↓

ONNX

↓

TensorRT
OpenVINO
SNPE
MNN
NCNN
ONNX Runtime

大家都认识 ONNX。


为什么不用 PyTorch 模型直接部署?

例如:

text 复制代码
model.pt

里面包含很多 PyTorch 特有的信息:

  • Python 对象
  • Autograd(自动求导)
  • Optimizer
  • 梯度
  • Module

TensorRT 根本不需要这些。

部署时只需要:

text 复制代码
输入 Tensor

↓

Conv

↓

BN

↓

Relu

↓

输出 Tensor

因此需要导出计算图。


ONNX 保存的是什么?

ONNX 保存的是:

① 网络结构(Graph)

例如:

text 复制代码
Input

↓

Conv

↓

Relu

↓

MaxPool

↓

FC

↓

Softmax

② 权重(Weights)

例如:

text 复制代码
Conv Weight

3×3×64×128

全部保存。


③ 算子(Operator)

例如:

text 复制代码
Conv

Add

Mul

Concat

Resize

Gemm

MatMul

这些都是标准 ONNX Operator。


④ 输入输出信息

例如:

text 复制代码
Input

1×3×640×640

float32

输出:

text 复制代码
1×80×8400

所以:

ONNX 本质就是:

一个描述神经网络计算图的标准文件。


为什么 TensorRT、SNPE 都支持 ONNX?

因为它们都只负责:

推理(Inference)

而不是训练。

例如:

PyTorch:

负责:

text 复制代码
训练

反向传播

梯度

Optimizer

TensorRT:

负责:

text 复制代码
Inference

Forward

因此:

text 复制代码
PyTorch

↓

Export ONNX

↓

TensorRT

最自然。


ONNX 是谁制定的?

ONNX 最早由:

  • Meta(Facebook)
  • Microsoft

联合提出。

后来:

越来越多公司加入:

  • NVIDIA
  • Qualcomm
  • Intel
  • AMD
  • IBM
  • ARM

因此现在几乎所有 AI 厂商都会支持 ONNX。


为什么说它是"事实标准"?

几乎所有部署框架都支持:

部署框架 是否支持 ONNX
TensorRT
ONNX Runtime
OpenVINO
SNPE(部分版本)
MNN
NCNN
TNN
Paddle Lite
RKNN(瑞芯微) ✅(通常先导出 ONNX 再转换)
Horizon Runtime(地平线) ✅(通常支持 ONNX 转换)

几乎所有国产 AI 芯片也都会提供:

text 复制代码
ONNX

↓

自家模型格式

例如:

text 复制代码
ONNX

↓

RKNN

或者:

text 复制代码
ONNX

↓

OM(昇腾)

↓

ACL Runtime

ONNX 的优势

① 框架无关(Framework Agnostic)

训练可以使用:

text 复制代码
PyTorch

TensorFlow

Paddle

MXNet

最终:

text 复制代码
↓

ONNX

② 硬件无关(Hardware Agnostic)

同一个 ONNX:

text 复制代码
ONNX

↓

Intel

↓

NVIDIA

↓

Qualcomm

↓

ARM

↓

国产AI芯片

都可以部署。


③ 易于优化

TensorRT 可以直接读取:

text 复制代码
ONNX Graph

然后:

text 复制代码
Layer Fusion

↓

Kernel Selection

↓

Engine

无需理解 PyTorch 内部实现。


④ 社区生态最好

几乎所有模型都会提供:

text 复制代码
PyTorch

↓

ONNX

例如:

  • YOLO
  • ResNet
  • EfficientNet
  • ViT
  • SAM
  • 部分 LLM(通常还会配合专用优化工具)

ONNX 有没有缺点?

当然有。

1. 新模型支持滞后

例如:

最新 Transformer 算子:

text 复制代码
FlashAttention

PyTorch 已经支持。

ONNX:

可能没有对应标准算子。

需要:

text 复制代码
Custom Op

或者:

text 复制代码
Plugin

2. 算子兼容问题

例如:

PyTorch:

python 复制代码
torch.grid_sample()

不同版本 ONNX:

可能:

text 复制代码
不能导出

或者

导出后 TRT 不支持

需要改模型。


3. 并非所有框架都支持全部算子

例如:

ONNX 有:

text 复制代码
300+
Operator

TensorRT:

可能只支持其中一部分。

SNPE:

支持得更少。

因此很多时候:

text 复制代码
ONNX

↓

Simplify

↓

修改模型

↓

TensorRT

是实际工程中的常见流程。


总结

可以把整个 AI 软件栈理解为:

text 复制代码
        训练阶段
 ┌─────────────────────┐
 │ PyTorch             │
 │ TensorFlow          │
 │ Paddle              │
 └─────────┬───────────┘
           │ 导出
           ▼
      ONNX(统一中间表示)
           │
  ┌────────┼────────────┐
  ▼        ▼            ▼
TensorRT  SNPE      OpenVINO
  │        │            │
NVIDIA  Qualcomm    Intel
  │        │            │
GPU      DSP/HTP      CPU/NPU

因此,ONNX 可以看作深度学习部署领域的"通用接口"或"中间语言(Intermediate Representation,IR)" 。它将模型训练硬件部署解耦,使同一个模型能够方便地迁移到 NVIDIA、Qualcomm、Intel、ARM 以及众多国产 AI 芯片平台,这也是它成为行业事实标准的主要原因。