ONNX全栈部署指南

1- 🚀 ONNX 全栈部署指南

图 1

image

图 2

image

图 1. ONNX 生态系统架构图

1.1- 🔍 核心价值

1.1.1- 技术优势矩阵

特性 描述 适用场景
跨框架互操作性 支持 PyTorch/TF/Keras 等 12+ 框架转换 多框架协同开发
动态计算图 支持动态 batch/sequence 长度(1.15+) NLP 可变长输入
量化压缩 支持 INT8/QAT/混合精度 移动端部署
异构加速 统一接口对接 CUDA/DML/NNAPI 等 20+EP 多硬件适配

1.2- ⚙️ 环境配置

1.2.1- 版本矩阵

组件 推荐版本 关键依赖
ONNX 1.15.0 Protobuf >=3.20
ONNX Runtime 1.17.0 CUDA 11.8 / DirectML 1.9
PyTorch 2.2.1 LibTorch 2.2
TensorFlow 2.15.0 TF-TRT 2.15
# 全功能安装(Linux)
conda create -n onnx-env python=3.10
conda install -c pytorch pytorch=2.2.1 torchvision cudatoolkit=11.8
pip install onnx==1.15.0 onnxruntime-gpu==1.17.0 tf2onnx==1.16.0 onnxscript==0.1.0

1.3- 🛠️ 模型转换

1.3.1- PyTorch 转换最佳实践

# 动态维度示例
dynamic_axes = {
    'input': {
        0: 'batch_size',
        2: 'width', 
        3: 'height'
    },
    'output': {0: 'batch_size'}
}

with torch.no_grad():
    torch.onnx.export(
        model,
        (torch.rand(1,3,224,224),),
        "model.onnx",
        export_params=True,
        opset_version=18,
        do_constant_folding=True,
        input_names=['input'],
        output_names=['output'],
        dynamic_axes=dynamic_axes,
        training=torch.onnx.TrainingMode.EVAL,
        _retain_param_name=True  # 保持参数可读性
    )

1.3.2- 转换验证工具链

  1. 基础验证

    onnx.checker.check_model(model)
    
  2. 形状推断

    inferred_model = shape_inference.infer_shapes(loaded_model)
    
  3. **可视化诊断

    netron model.onnx -p 8080
    

1.4- 🚀 推理优化

1.4.1- 优化策略对比

方法 收益 适用场景 工具链
图优化 ~15-30% 静态模型 ONNX Optimizer
动态量化 ~2-4x 压缩 后处理模型 ORT Quantizer
静态量化 ~4-8x 加速 校准数据可用 QAT+ORT
内核融合 ~10-20% 密集计算模型 TensorRT

1.4.2- 混合量化示例

from onnxruntime.quantization import CalibrationDataReader

class CustomDataReader(CalibrationDataReader):
    def __init__(self, dataset):
        self.dataset = iter(dataset)
        
    def get_next(self):
        try:
            return {'input': next(self.dataset)}
        except StopIteration:
            return None

# 创建量化配置
quant_config = QuantConfig(
    calibration_data_reader=CustomDataReader(val_loader),
    activation_type=QuantType.QInt8,
    weight_type=QuantType.QInt8,
    per_channel=True,
    optimize_model=True
)

quant_model = quantize_static(
    "model.onnx",
    "model_quant.onnx",
    quant_config,
    calibrate_method=CalibrationMethod.Entropy
)

1.5- 🏭 工业部署

1.5.1- 部署架构选型

graph TD
    A[训练框架] --> B(ONNX模型)
    B --> C{部署环境}
    C -->|云服务| D[ONNX Runtime]
    C -->|边缘设备| E[TensorRT]
    C -->|移动端| F[NCNN/MNN]
    D --> G[CPU/GPU/FPGA]

1.5.2- Android 部署示例

// 构建ORT会话
val ortEnv = OrtEnvironment.getEnvironment()
val sessionOptions = OrtSession.SessionOptions().apply {
    addNnapi()  // 启用Android NPU加速
    setMemoryOptimizationEnabled(true)
}

val session = ortEnv.createSession(
    assets.open("model.quant.onnx"),
    sessionOptions
)

// 执行推理
val inputBuffer = TensorBuffer.createFixedSize(intArrayOf(1,3,224,224), DataType.FLOAT32)
val outputs = session.run(
    mapOf("input" to OnnxTensor.createTensor(ortEnv, inputBuffer))
)

1.6- 🚨 问题排查

1.6.1- 典型错误处理

- 错误 [ONNXRuntimeError] : Non-zero status code returned while running Conv node
+ 解决方案:
  1. 检查输入通道数与模型权重是否匹配
  2. 验证opset版本是否支持当前算子
  3. 使用onnx.defs.get_schema('Conv', opset_version)确认参数要求

1.6.2- 性能分析工具链

  1. ORT 性能分析

    session = ort.InferenceSession(..., enable_profiling=True)
    session.end_profiling("profile.json") 
    
  2. Nsys 系统级分析

    nsys profile -o ort_report python inference.py
    
  3. TensorRT 可视化

    polygraphy run model.onnx --trt --verbose
    

1.7- 📦 资源扩展

1.7.1- 官方工具矩阵

工具 用途 关键特性
ONNX Script 模型构建/转换 类 Python 语法
ONNX Runtime Web 浏览器部署 WebAssembly 支持
ONNX Model Zoo 预训练模型库 300+ 生产级模型

1.7.2- 学习路径

基础篇
├─ 模型转换 → 验证 → 基础推理
进阶篇
├─ 量化 → 图优化 → 异构部署
专家篇
├─ 自定义算子 → 混合精度训练 → 分布式推理

更新日志
2024.03 Update - 同步 ONNX Runtime 1.17 新特性,新增 Android NPU 部署示例

⚠️ 注意事项

  • 生产环境建议锁定版本依赖
  • 动态 shape 模型需测试各维度边界情况
  • 优先使用框架原生量化工具(如 Torch.quantization)