2、环境搭建:安装ONNX、ONNX Runtime、Protobuf,验证环境是否可用
好,咱们正式开始动手了。这一章我带你搭环境。
说实话,很多同学学ONNX卡住,不是因为模型多难,而是环境没配好。我见过有人折腾Protobuf版本搞了三天,最后发现是Python和系统库冲突。所以这一章,咱们稳扎稳打,把坑提前填上。
2.1 为什么需要这三样东西?
先理清概念。ONNX本身是一个模型格式标准,就像你写Word文档需要.doc格式一样。但光有格式不行,你得有工具去读写它、运行它。
- ONNX(核心库):负责模型的序列化、反序列化、结构操作。说白了,就是让你能加载一个.onnx文件,看看里面长什么样。
- ONNX Runtime(推理引擎):负责真正跑模型。你训练好的模型转成ONNX后,用它来做推理。
- Protobuf(底层依赖):ONNX的序列化格式基于Protobuf。没有它,ONNX文件都打不开。
嗯,这里要注意:Protobuf的版本非常敏感。我曾经在一个项目里,因为系统自带的Protobuf是3.6,而ONNX需要3.8以上,结果模型加载直接崩了,报错信息还特别隐晦。
2.2 安装前的准备工作
我个人习惯用Python 3.8到3.11之间的版本。太老的Python对ONNX新特性支持不好,太新的(比如3.12)有些依赖还没适配。
我曾经在Python 3.12上安装ONNX 1.15,结果protobuf编译失败。后来降级到3.10,一次过。所以建议你直接用3.10,稳。
另外,建议用虚拟环境。别偷懒,直接装到系统Python里,后面项目多了会乱成一锅粥。
# 创建虚拟环境(我习惯用venv)
python -m venv onnx_env
# 激活环境
# Windows:
onnx_env\Scripts\activate
# Linux/Mac:
source onnx_env/bin/activate
2.3 安装Protobuf
其实ONNX安装时会自动拉Protobuf依赖。但有时候自动拉的不对,或者版本冲突。所以我建议手动先装好。
# 安装指定版本的protobuf
pip install protobuf==3.20.3
为什么选3.20.3?这个版本我测试过,兼容ONNX 1.13到1.16全系列。你想想看,如果装了个4.0以上的版本,有些旧模型可能就解析不了了。
装完后可以跑一下:
protoc --version。如果能显示版本号,说明系统级的protoc也装好了。但注意,Python用的protobuf和系统protoc是两回事,别搞混。
2.4 安装ONNX核心库
这一步很简单,但有个细节:我建议指定版本安装,不要装最新版。最新版有时候会引入breaking change。
# 安装ONNX 1.15.0(稳定版)
pip install onnx==1.15.0
装完之后,验证一下:
python -c "import onnx; print(onnx.__version__)"
如果输出了1.15.0,恭喜你,第一步成了。如果报错,多半是Protobuf版本问题。这时候检查一下:
pip list | grep protobuf
看看是不是装了多个版本?我遇到过pip list里显示3.20.3,但实际用的是系统自带的2.6。解决办法:在虚拟环境里重新装一遍,确保环境隔离。
2.5 安装ONNX Runtime
ONNX Runtime分CPU版和GPU版。咱们先装CPU版,后面讲优化时再上GPU。
# CPU版
pip install onnxruntime==1.17.0
# 如果你有NVIDIA显卡,也可以装GPU版(需要CUDA和cuDNN)
# pip install onnxruntime-gpu==1.17.0
验证方法:
python -c "import onnxruntime; print(onnxruntime.__version__)"
ONNX Runtime的版本最好和ONNX版本匹配。比如ONNX 1.15搭配ORT 1.17,我测试过完全没问题。如果版本差太多,可能会出现算子不支持的情况。
2.6 完整验证:跑一个简单的ONNX模型
光装完不行,得真跑起来才算数。我写了个小脚本,你直接复制运行:
import onnx
import onnxruntime as ort
import numpy as np
# 1. 创建一个简单的ONNX模型(加法运算)
# 这里用onnx.helper手动构建,后面章节会细讲
import onnx.helper as helper
import onnx.numpy_helper as numpy_helper
# 定义输入输出
X = helper.make_tensor_value_info('X', onnx.TensorProto.FLOAT, [1, 3])
Y = helper.make_tensor_value_info('Y', onnx.TensorProto.FLOAT, [1, 3])
Z = helper.make_tensor_value_info('Z', onnx.TensorProto.FLOAT, [1, 3])
# 定义加法节点
add_node = helper.make_node('Add', inputs=['X', 'Y'], outputs=['Z'])
# 构建计算图
graph = helper.make_graph(
[add_node],
'test_graph',
[X, Y],
[Z]
)
# 构建模型
model = helper.make_model(graph, producer_name='onnx_example')
# 保存模型
onnx.save(model, 'test_add.onnx')
print("✅ 模型创建并保存成功")
# 2. 用ONNX Runtime推理
session = ort.InferenceSession('test_add.onnx')
# 准备输入数据
x_data = np.array([[1.0, 2.0, 3.0]], dtype=np.float32)
y_data = np.array([[4.0, 5.0, 6.0]], dtype=np.float32)
# 运行推理
outputs = session.run(['Z'], {'X': x_data, 'Y': y_data})
print(f"输入X: {x_data}")
print(f"输入Y: {y_data}")
print(f"输出Z: {outputs[0]}")
# 验证结果
expected = x_data + y_data
assert np.allclose(outputs[0], expected), "结果不对!"
print("✅ 推理结果验证通过!")
跑完之后,你应该看到类似这样的输出:
✅ 模型创建并保存成功
输入X: [[1. 2. 3.]]
输入Y: [[4. 5. 6.]]
输出Z: [[5. 7. 9.]]
✅ 推理结果验证通过!
如果看到这个,说明你的环境完全可用。嗯,这里要注意:如果报错说找不到某个算子,别慌,可能是ONNX Runtime版本太老。升级一下就好。
2.7 常见问题速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| ImportError: No module named 'onnx' | 没安装或虚拟环境没激活 | 检查pip list,确认在正确的虚拟环境中 |
| RuntimeError: Protobuf version mismatch | 系统protobuf和Python protobuf版本冲突 | 卸载系统protobuf,或用虚拟环境隔离 |
| onnxruntime.capi.onnxruntime_pybind11_state.Fail | 模型中有不支持的算子 | 升级ONNX Runtime版本,或检查算子兼容性 |
| 模型加载慢 | 模型太大或磁盘IO瓶颈 | 后面章节会讲模型优化,先忽略 |
2.8 我的个人建议
环境搭好之后,我建议你多做一件事:把刚才那个test_add.onnx文件留着。后面学模型结构解析时,可以用它做实验。
另外,如果你在公司内网或者有代理限制,装包时加个国内镜像:
pip install onnx==1.15.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
好了,环境搭完了。下一章咱们开始解剖ONNX模型,看看里面到底长什么样。你想想看,一个模型文件,里面存的到底是什么?是权重?是计算图?还是别的?到时候你就知道了。
- 安装了三件套:Protobuf 3.20.3、ONNX 1.15.0、ONNX Runtime 1.17.0
- 用虚拟环境隔离,避免系统污染
- 跑通了第一个ONNX模型,验证了环境可用
- 记住了常见问题的排查方法
下一章见。