2、环境准备与工具链:安装ONNX、ONNX Runtime、protobuf版本冲突与解决

说实话,环境配置这件事,看着简单,但坑是真不少。我见过太多人模型写好了,结果卡在安装这一步,一卡就是半天。今天咱们就把ONNX、ONNX Runtime和protobuf这几个东西的安装和版本冲突问题彻底讲清楚。

2.1 先搞清楚这几个东西的关系

ONNX本身是一个模型格式标准,说白了就是一套协议。你装ONNX包,是为了能导出和操作这个格式的模型。ONNX Runtime是推理引擎,用来跑ONNX模型的。protobuf呢?它是ONNX的底层序列化工具,模型文件就是用protobuf序列化出来的。

这三者的关系,我习惯这么理解:

  • ONNX:定义了菜谱(模型结构)
  • protobuf:负责把菜谱写成文件
  • ONNX Runtime:照着菜谱把菜做出来(推理)

嗯,这里要注意:protobuf的版本问题,是绝大多数环境冲突的根源。

2.2 安装ONNX和ONNX Runtime

我个人习惯用pip安装,简单直接。但版本一定要选对。

# 安装ONNX
pip install onnx

# 安装ONNX Runtime(CPU版本)
pip install onnxruntime

# 安装ONNX Runtime(GPU版本,需要CUDA)
pip install onnxruntime-gpu

你可能会问:为什么不直接装最新版?我在项目中遇到过,最新版ONNX Runtime有时候和旧版ONNX模型不兼容。所以我的建议是:

  • 如果你只是做模型转换,ONNX版本选1.12到1.15之间比较稳
  • 如果你要跑推理,ONNX Runtime选1.10到1.16之间
  • GPU版本记得先确认CUDA版本,别装完发现跑不了
小技巧:pip list | grep onnx 查看已安装版本。如果发现版本不对,用 pip install onnx==1.14.0 指定版本安装。

2.3 protobuf版本冲突——最常见的坑

这个坑我踩过不止一次。你装完ONNX,然后装TensorFlow或者PyTorch,突然发现ONNX导不出模型了。报错信息通常是:

google.protobuf.message.DecodeError: Error parsing message

为什么会这样?因为不同框架对protobuf的版本要求不一样。比如:

  • ONNX 1.14 要求 protobuf >= 3.20.2
  • TensorFlow 2.10 可能要求 protobuf <= 3.20.1
  • PyTorch 1.13 对protobuf版本相对宽松

你看,这就冲突了。我曾经在一个项目里,因为protobuf版本不对,折腾了整整一个下午。最后发现是TensorFlow偷偷把protobuf降级了。

2.4 解决protobuf冲突的几种方案

方案一:统一版本。我建议把protobuf固定在3.20.3:

pip install protobuf==3.20.3

这个版本对ONNX和大多数深度学习框架都比较友好。

方案二:用虚拟环境隔离。每个项目单独建一个环境:

# 创建虚拟环境
python -m venv onnx_env

# 激活(Windows)
onnx_env\Scripts\activate

# 激活(Linux/Mac)
source onnx_env/bin/activate

# 然后在这个环境里安装
pip install onnx onnxruntime protobuf==3.20.3

方案三:如果实在冲突得厉害,用conda环境。conda的依赖解析比pip强一些:

conda create -n onnx_env python=3.9
conda activate onnx_env
conda install onnx onnxruntime -c conda-forge
警告: 不要同时用pip和conda混装protobuf。我见过有人pip装了一个版本,conda又装了一个,结果两个版本打架,模型解析直接崩溃。

2.5 验证安装是否成功

装完之后,一定要验证一下。我习惯写个简单脚本:

import onnx
import onnxruntime as ort

# 检查ONNX版本
print(f"ONNX版本: {onnx.__version__}")

# 检查ONNX Runtime版本
print(f"ONNX Runtime版本: {ort.__version__}")

# 检查protobuf版本
import google.protobuf
print(f"protobuf版本: {google.protobuf.__version__}")

# 创建一个简单的模型验证
import numpy as np
import onnx.helper as helper

# 定义一个输入
input_tensor = helper.make_tensor_value_info(
    "input", onnx.TensorProto.FLOAT, [1, 3, 224, 224]
)
output_tensor = helper.make_tensor_value_info(
    "output", onnx.TensorProto.FLOAT, [1, 1000]
)

# 创建节点
node = helper.make_node("Relu", ["input"], ["output"])

# 创建图
graph = helper.make_graph([node], "test", [input_tensor], [output_tensor])

# 创建模型
model = helper.make_model(graph)

# 保存并加载
onnx.save(model, "test.onnx")
loaded_model = onnx.load("test.onnx")

print("模型创建和加载成功!")

# 用ONNX Runtime推理
session = ort.InferenceSession("test.onnx")
print("ONNX Runtime推理引擎初始化成功!")

如果这段代码能跑通,说明你的环境基本没问题了。

2.6 常见错误速查表

错误信息 原因 解决方法
ModuleNotFoundError: No module named 'onnx' ONNX没安装 pip install onnx
google.protobuf.message.DecodeError protobuf版本冲突 固定protobuf版本为3.20.3
RuntimeError: ONNX Runtime only supports ... ONNX Runtime版本与模型不匹配 升级或降级ONNX Runtime
ImportError: DLL load failed Windows下缺少VC++运行库 安装Visual C++ Redistributable
CUDA error: no kernel image is available GPU版本与CUDA不匹配 检查CUDA版本,安装对应ONNX Runtime

2.7 我的个人建议

如果你刚开始接触ONNX,我建议你这样做:

  1. 用Python 3.8或3.9,这两个版本兼容性最好
  2. 先装protobuf==3.20.3,再装ONNX和ONNX Runtime
  3. 每个项目用独立的虚拟环境
  4. 装完立刻跑验证脚本,别等到用的时候才发现问题

嗯,环境准备这部分就这些。说白了就是版本匹配的问题,搞清楚依赖关系,按顺序装,基本不会出大问题。下一章咱们开始讲实际的模型转换操作。

核心要点: ONNX、ONNX Runtime、protobuf三者版本必须匹配。protobuf是冲突重灾区,建议固定为3.20.3。用虚拟环境隔离不同项目,避免全局污染。