2. 环境搭建与工具链:安装ONNX、ONNX Runtime、protobuf及常见调试工具
说实话,环境搭建这事儿,看着简单,但坑是真不少。我见过太多同学在模型转换这一步卡住,最后发现是protobuf版本没对齐。嗯,咱们今天就把这事儿一次性捋清楚。
2.1 为什么这三样东西必须装?
你想想看,ONNX是个中间格式,它本身不负责推理。就像你写了个PDF文件,总得有个阅读器吧?ONNX Runtime就是那个阅读器。而protobuf呢,它是ONNX的底层序列化协议——说白了,就是定义模型结构该怎么存、怎么读的规则。
我个人的习惯是:先装protobuf,再装ONNX,最后装ONNX Runtime。这个顺序别搞反了,否则你会遇到一些莫名其妙的链接错误。
2.2 protobuf 安装与版本选择
protobuf分两部分:一个是编译器 protoc,一个是Python绑定的 protobuf 包。两者版本必须匹配。
推荐版本:
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| protoc (编译器) | 3.21.12 | 这个版本最稳定,兼容ONNX 1.14+ |
| protobuf (Python) | 3.21.12 | 必须和protoc版本一致 |
安装命令:
# 1. 安装protoc编译器(Linux/Mac)
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.21.12/protoc-3.21.12-linux-x86_64.zip
unzip protoc-3.21.12-linux-x86_64.zip -d /usr/local/protoc
export PATH=$PATH:/usr/local/protoc/bin
# 2. 安装Python包
pip install protobuf==3.21.12
# 3. 验证
protoc --version # 应该输出 libprotoc 3.21.12
python -c "import google.protobuf; print(google.protobuf.__version__)" # 应该输出 3.21.12
conda install protobuf=3.21.12。conda会自动帮你处理编译器路径问题,省心很多。
2.3 ONNX 安装
ONNX的安装其实很简单,但要注意:不要用pip install onnx直接装最新版。我建议指定版本,因为不同版本的ONNX对算子支持有差异。
# 推荐安装1.14.1(稳定且功能完整)
pip install onnx==1.14.1
# 验证安装
python -c "import onnx; print(onnx.__version__)"
装完之后,我建议你立刻跑一个简单的测试:
import onnx
import onnx.helper as helper
# 创建一个最简单的模型:输入 -> 输出
input = helper.make_tensor_value_info('input', onnx.TensorProto.FLOAT, [1, 3, 224, 224])
output = helper.make_tensor_value_info('output', onnx.TensorProto.FLOAT, [1, 3, 224, 224])
node = helper.make_node('Relu', ['input'], ['output'])
graph = helper.make_graph([node], 'test_graph', [input], [output])
model = helper.make_model(graph)
# 检查模型是否合法
onnx.checker.check_model(model)
print("模型检查通过!")
如果这段代码能跑通,说明你的ONNX环境基本没问题了。
2.4 ONNX Runtime 安装
ONNX Runtime分CPU版和GPU版。我个人建议:开发阶段先用CPU版,调试方便;部署时再切GPU版。
CPU版安装:
pip install onnxruntime==1.16.3
GPU版安装(需要CUDA 11.8 + cuDNN 8.6):
pip install onnxruntime-gpu==1.16.3
nvidia-smi 和 nvcc --version 先确认你的CUDA版本,再去ONNX Runtime官网查对应的兼容矩阵。
验证GPU是否可用:
import onnxruntime as ort
print(ort.get_device()) # 如果是GPU版且可用,输出 "GPU"
print(ort.get_available_providers()) # 列出所有可用的执行提供程序
2.5 常见调试工具
光有运行环境还不够,调试工具才是救命稻草。我平时最常用的有这几个:
| 工具 | 用途 | 安装方式 |
|---|---|---|
| Netron | 可视化模型结构 | pip install netron |
| onnx-simplifier | 简化模型,去除冗余算子 | pip install onnx-simplifier |
| onnx2txt | 将ONNX模型转为文本,方便对比 | pip install onnx2txt |
| polygraphy | NVIDIA官方工具,调试精度问题 | pip install polygraphy |
Netron 的使用方法:
import netron
netron.start('your_model.onnx') # 会在浏览器中打开可视化界面
我个人特别喜欢Netron的一点是:它能直接显示每个算子的输入输出形状。有一次我排查一个维度不对齐的问题,就是靠Netron一眼看出来的——某个卷积层的输出通道数比预期少了64。
onnx-simplifier 的使用:
python -m onnxsim your_model.onnx simplified_model.onnx
这个工具能帮你干掉模型里那些多余的Shape、Gather、Unsqueeze操作。我遇到过最夸张的一次,一个原本200MB的模型,简化后只剩120MB——里面塞了一大堆没用的常量节点。
1. 先用Netron看结构,确认算子类型和连接关系
2. 用onnx-simplifier清理冗余节点
3. 用polygraphy对比原始模型和ONNX模型的输出差异(精度调试时必用)
2.6 环境验证脚本
最后,我建议你保存下面这个脚本。每次换机器或重装环境时,跑一遍就能确认所有组件是否就绪:
import sys
import onnx
import onnxruntime as ort
import google.protobuf
print(f"Python版本: {sys.version}")
print(f"ONNX版本: {onnx.__version__}")
print(f"ONNX Runtime版本: {ort.__version__}")
print(f"protobuf版本: {google.protobuf.__version__}")
print(f"推理设备: {ort.get_device()}")
# 检查protoc编译器
import subprocess
try:
result = subprocess.run(['protoc', '--version'], capture_output=True, text=True)
print(f"protoc编译器: {result.stdout.strip()}")
except:
print("⚠️ protoc编译器未安装或不在PATH中")
好了,环境搭建这部分就到这儿。下一章咱们开始动手,把PyTorch模型转成ONNX——那才是真正有意思的地方。