ONNX Runtime 基础与安装
咱们开始聊 ONNX Runtime。说实话,这东西我第一次见就觉得——嗯,这名字挺直白的。Runtime,运行时,专门用来跑 ONNX 模型的。我最早接触它是在一个图像分类项目里,模型用 PyTorch 训练完,导出成 ONNX,然后丢到 ONNX Runtime 里一跑——速度直接翻倍。
你想想看,ONNX 只是个中间格式,谁来执行它?目前主流的选择就是 ONNX Runtime。微软开源的推理引擎,支持 Windows、Linux、Mac,还能无缝切到 CPU、GPU、甚至边缘设备。我个人的习惯是:只要模型结构固定,上线前我一定先试 ONNX Runtime + TensorRT 后端。
ONNX Runtime 到底是什么?
说白了一个跨平台推理加速库。它把 ONNX 模型解析成计算图,然后针对不同硬件做图优化、算子融合、内存复用。你不需要改模型代码,只要换一行代码就能切后端。核心优势有三点:
- 高性能:内置图优化 pass,自动选择最优 kernel。
- 跨平台:从服务器到手机嵌入式,全都能跑。
- 多后端:CPU、CUDA、TensorRT、OpenVINO、DirectML、CoreML,想用哪个用哪个。
我遇到过不少团队,模型跑在 GPU 上嫌贵,想改 CPU 又怕慢。这时候 ONNX Runtime 的 OpenVINO 后端就很香——Intel CPU 上能达到接近 GPU 的性能。
安装方式:pip vs 源码编译
安装 ONNX Runtime 有两种主流方式:pip 安装和源码编译。怎么选?我的经验是:90% 的场景用 pip 就够了,除非你需要定制算子或编译非官方后端。
pip 安装(推荐新手)
一句话搞定:
pip install onnxruntime
这是 CPU 版。想要 GPU 加速?那就装 GPU 版:
pip install onnxruntime-gpu
但注意啊,GPU 版默认依赖 CUDA 和 cuDNN,版本要对齐。我有一回手快装了最新版,结果 CUDA 11.8 没装,报错找不到库——浪费时间。
如果你用 Intel CPU,想用 OpenVINO 后端,可以用:
pip install onnxruntime-openvino
还有针对 ARM 的:
pip install onnxruntime-arm64
不同变体对比:
| pip 包名 | 后端 | 适用场景 |
|---|---|---|
onnxruntime |
CPU (通用) | 开发测试、CPU 推理 |
onnxruntime-gpu |
CUDA + TensorRT | NVIDIA GPU 推理 |
onnxruntime-openvino |
OpenVINO | Intel CPU/GPU/VPU |
onnxruntime-arm64 |
ARM CPU | 树莓派、Jetson |
我的提示:装 GPU 版之前,先查你的 CUDA 版本。运行 nvidia-smi 看左上角。然后去 ONNX Runtime 官网查对应版本表,避免版本不匹配。我曾经就吃过亏,装好之后推理结果全错——后来发现是 cuDNN 版本不对。
源码编译(进阶玩家)
为什么要自己编译?三个原因:
- 需要自定义算子(比如你写了个特殊的激活函数)
- 需要实验性后端(比如 ONNX Runtime Web)
- 需要极致优化(针对特定 CPU 指令集)
编译步骤大致如下:
# 1. 克隆仓库
git clone --recursive https://github.com/microsoft/onnxruntime
# 2. 配置构建(以 Linux + CUDA + TensorRT 为例)
cd onnxruntime
./build.sh --config Release \
--build_shared_lib \
--use_cuda \
--cuda_home /usr/local/cuda \
--cudnn_home /usr/lib/x86_64-linux-gnu/ \
--use_tensorrt \
--tensorrt_home /usr/src/tensorrt
# 3. 编译(多核加速)
./build.sh --parallel
如果你要同时支持 OpenVINO,加参数:
--use_openvino /path/to/openvino
Windows 下用 CMake+Visual Studio:
# 在 build 目录下
cmake -G "Visual Studio 16 2019" \
-A x64 \
-DONNX_CUDA=ON \
-DONNX_CUDNN_HOME=... \
..
cmake --build . --config Release
编译完会生成 libonnxruntime.so 或 onnxruntime.dll,以及 Python 的 .so/.pyd 文件。然后你就能 import onnxruntime 用了。
注意事项:源码编译耗时很长(我试过在 8 核机器上编译 GPU 版,差不多 40 分钟)。而且 CMake 参数容易写错——我就曾经少写了 --use_tensorrt,结果 RTX 显卡只能用 CUDA 后端,浪费了 TensorRT 加速。建议编译前先跑 ./build.sh --help 看所有选项。
支持后端一览
ONNX Runtime 的核心设计叫 "Execution Provider"(执行提供程序)。每个后端就是一个 EP。你可以在创建 InferenceSession 时指定:
import onnxruntime as ort
# 选择 CUDA 后端
session = ort.InferenceSession(
"model.onnx",
providers=['CUDAExecutionProvider', 'CPUExecutionProvider']
)
优先级:数组越靠前越优先。如果 CUDA 不可用,会自动 fallback 到 CPU。以下是常见后端:
| 后端名称 | 硬件 | 特点 |
|---|---|---|
| CPUExecutionProvider | 任意 CPU | 通用、稳定、无依赖 |
| CUDAExecutionProvider | NVIDIA GPU | GPU 基础加速,支持 FP16 |
| TensorrtExecutionProvider | NVIDIA GPU | TensorRT 优化,极致性能 |
| OpenVINOExecutionProvider | Intel CPU/GPU/VPU | Intel 平台优化,支持 INT8 |
| DirectMLExecutionProvider | DirectX 12 GPU | Windows 平台,兼容 AMD/NVIDIA |
| CoreMLExecutionProvider | Apple Neural Engine | Mac/iOS 推理加速 |
经验之谈:我一般在 GPU 机器上同时注册 CUDA 和 TensorRT 两个后端。原因是某些算子在 TensorRT 里不支持(比如动态 shape 很大的场景),fallback 到 CUDA 反而更稳定。你可以在代码里打印支持的 providers 来确认:ort.get_available_providers()。
一张图看懂 ONNX Runtime 生态
下面这张图概括了 ONNX Runtime 的安装路径和后端关系。
避坑指南与常用命令
讲几个我实际踩过的坑:
- GPU 版 pip 装完发现只用了 CPU:检查环境变量
CUDA_VISIBLE_DEVICES有没有被设置,或者LD_LIBRARY_PATH没包含 CUDA 库。我曾经被 Docker 里的环境变量坑过整整半天。 - pip 版本不是最新:有时候你想要新后端,但 pip 上还是旧版。这时候你就得等——或者直接源码编译。我建议关注 ONNX Runtime Release,新后端出来一般 month 内上 pip。
- 源码编译失败:最常见的是 CMake 权重配置问题。先确认你装了所有依赖:
apt install build-essential cmake libprotobuf-dev。然后./build.sh --clean再试。
快速检查安装结果:运行下面代码,看看支持哪些后端:
import onnxruntime as ort
print("可用后端:", ort.get_available_providers())
print("版本:", ort.__version__)
如果输出里没有你想要的(比如 Tensorrt),那就是安装包不对或环境没配好。