环境搭建:Python虚拟环境配置、ONNX Runtime安装、ONNX opset版本选择
好,咱们正式开始动手了。
这一章,说白了就是搭台子。台子搭不好,后面唱戏全得摔跟头。我见过太多同学,模型导出报错、推理结果不对,最后发现是环境版本打架。嗯,咱们今天就把这事彻底理清楚。
Python虚拟环境:别偷懒,这是底线
我个人习惯,每个项目都开独立的虚拟环境。为什么?你想想看,项目A用ONNX Runtime 1.12,项目B用1.15,要是装在一个全局环境里,迟早出幺蛾子。
我推荐用 conda 或者 venv。如果你主要做深度学习,conda更方便,因为它能顺带管理CUDA和cuDNN的版本。
我的标准操作流程:
# 创建Python 3.8环境(我个人最推荐的版本)
conda create -n onnx_deploy python=3.8
# 激活环境
conda activate onnx_deploy
# 如果喜欢用venv也行
python -m venv onnx_deploy
source onnx_deploy/bin/activate # Linux/Mac
# onnx_deploy\Scripts\activate # Windows
为什么推荐Python 3.8?我在项目中踩过坑——Python 3.10以上某些ONNX Runtime的旧版本不支持,而3.7又太老,很多新库已经放弃维护了。3.8是个黄金平衡点。
小技巧: 创建环境时顺手把pip升到最新,能避免很多依赖解析的奇怪报错。
pip install --upgrade pip
ONNX Runtime安装:选对版本很重要
ONNX Runtime有三种安装方式,我按推荐度排序:
- CPU版本:
pip install onnxruntime - GPU版本:
pip install onnxruntime-gpu - 直接编译:源码编译,不推荐新手尝试
这里有个坑——我曾经以为GPU版本肯定比CPU版本快,结果在树莓派上装了个GPU版,跑都跑不起来。说白了,你得先搞清楚目标平台有没有CUDA。
警告: 别在ARM架构的板子上装onnxruntime-gpu,它只支持x86_64的NVIDIA显卡。我见过有人拿Jetson Nano装这个,折腾了两天...
对于嵌入式部署,我建议这样选:
| 目标平台 | 推荐安装方式 | 备注 |
|---|---|---|
| PC端(有NVIDIA显卡) | onnxruntime-gpu | 需要CUDA 11.x + cuDNN 8.x |
| PC端(无显卡) | onnxruntime | CPU推理,够用 |
| ARM开发板(如树莓派) | onnxruntime | 或者用ONNX Runtime的ARM预编译包 |
| Jetson系列 | 源码编译或JetPack自带 | 别用pip直接装,会哭 |
验证安装是否成功:
python -c "import onnxruntime; print(onnxruntime.__version__)"
# 如果能打印出版本号,比如 '1.15.0',就说明装好了
ONNX opset版本选择:别小看这个数字
opset,全称是Operator Set。它定义了ONNX支持哪些算子,以及这些算子的行为。说白了,opset版本越高,支持的算子越新,但兼容性可能越差。
我刚开始做部署时,觉得opset版本越高越好,直接选了21。结果模型导出到板子上,算子不支持,报错报得我头皮发麻。
后来我总结了一套选择策略:
- PC端部署:选opset 15-18,新算子支持好,性能也稳定
- 嵌入式部署:选opset 11-13,兼容性最好,老算子基本都支持
- 特殊需求:比如要用到最新的Transformer算子,才考虑opset 19+
我的经验: 如果你不确定,就选opset 13。这个版本是个分水岭——它支持了大部分常用算子,而且几乎所有推理框架都兼容。我在RK3588、树莓派4B、Jetson Nano上都验证过,稳得很。
怎么在导出时指定opset版本?以PyTorch为例:
import torch
import torch.onnx
# 假设你有一个训练好的模型
model = YourModel()
dummy_input = torch.randn(1, 3, 224, 224)
# 指定opset版本为13
torch.onnx.export(
model,
dummy_input,
"model.onnx",
opset_version=13, # 这里!关键!
input_names=["input"],
output_names=["output"]
)
注意: 如果你用了某些高级算子(比如Einsum、ScatterND),低版本opset可能不支持。这时候要么升级opset,要么手动替换算子。我曾经为了一个ScatterND算子,把整个模型结构都改了...嗯,那是个教训。
环境验证:跑个简单的例子
环境搭好了,咱们跑个Hello World验证一下:
import onnxruntime as ort
import numpy as np
# 创建一个简单的ONNX模型(这里用代码生成,实际部署时是加载文件)
# 假设你已经有了一个model.onnx文件
session = ort.InferenceSession("model.onnx")
# 准备输入数据
input_name = session.get_inputs()[0].name
input_shape = session.get_inputs()[0].shape
input_data = np.random.randn(*input_shape).astype(np.float32)
# 推理
outputs = session.run(None, {input_name: input_data})
print("推理成功!输出形状:", outputs[0].shape)
如果这段代码能跑通,恭喜你,环境搭建成功了。如果报错,别慌——90%的情况是版本不匹配。检查一下Python版本、ONNX Runtime版本、opset版本,三者要能对上。
总结一下今天的内容:
- 用conda创建独立的Python 3.8环境
- 根据目标平台选择ONNX Runtime版本
- 嵌入式部署优先选opset 13
- 跑个简单推理验证环境
下一章,咱们开始讲模型导出。到时候你会感谢今天把环境搭好的自己——因为导出时遇到的各种奇葩问题,90%都是环境没配好导致的。嗯,我当年就是这么过来的。