离线环境加载 ONNX Runtime 时报缺少 CPUExecutionProvider,通常不是 ONNX Runtime 主包没装,而是它依赖的底层库(如 libgomp、libiomp5、oneDNN 相关运行库)不完整,或者推理脚本在导入时直接检查了 ExecutionProvider 列表,导致加载中断。很多离线服务器没有安装完整编译器运行时,Python 包自带的二进制动态库链接不到系统库,就会在初始化阶段报错。
排查方向应优先锁定 ONNX Runtime 的安装方式和系统运行库是否齐全。先用 pip show 确认 onnxruntime 已安装,再用一段简单导入代码复现报错;如果报错指向 libgomp.so.1 或 libiomp5.so,直接安装运行时库或调整 LD_LIBRARY_PATH 通常可以解决。不要一开始就回到编译源码路径,离线环境先处理二进制依赖。
先确认 ONNX Runtime 与 Python 环境的现实状态
在动手之前,先确认当前环境到底缺少什么。执行下面的命令,注意在干净终端里运行,不要带上你项目的环境变量:
python -c "import onnxruntime; print(onnxruntime.__version__); print(onnxruntime.get_available_providers())"如果这条命令直接输出 ['CPUExecutionProvider'],说明运行环境本身没问题,问题出在你的导入顺序或自定义构建参数上。如果报错提前发生在 import 阶段,终端会显示类似 libgomp.so.1: cannot open shared object file 或 libiomp5md.dll not found 的提示,这就进入下一步依赖排查。另一种情况是安装包来源不对,比如在 macOS 上装了 Windows 的 wheel,或 Python 位数不匹配,这种错误同样会在导入阶段暴露。
补齐缺少的 CPUExecutionProvider 动态依赖
离线环境没有网络,优先使用系统自带的软件源或已有的离线安装包。先按操作系统区分处理:
- Ubuntu / Debian:通常需要
libgomp1。在离线机器上,从同版本系统的安装介质或已缓存 deb 包中安装:dpkg -i libgomp1_*.deb。如果报缺少 libiomp5,那是 Intel OpenMP 运行时,可从已有的 intel-openmp 包补齐。 - CentOS / RHEL:检查
libgomp是否已安装,使用yum localinstall安装本地 rpm。另外确认 glibc 版本,ONNX Runtime 1.17 之前的版本对旧 glibc 更友好,新版本往往要求 glibc 2.28 以上。 - Windows 离线环境:优先下载 Microsoft Visual C++ Redistributable(x64)离线包安装,同时确认 Python 是 64 位。
安装后再用 ldd 检查 onnxruntime 的动态库链接情况(Linux 下):
python -c "import onnxruntime, os; print(os.path.dirname(onnxruntime.__file__))"找到 onnxruntime 包目录后,执行:
ldd 路径/onnxruntime/capi/libonnxruntime.so.1 | grep "not found"如果输出为空,说明依赖已补齐;如果还有 not found,按照缺失的具体库名继续安装对应运行库。
用最小 demo 验证 CPUExecutionProvider 能正常加载
依赖解决后再验证推理链路。不要直接跑复杂模型,先用下面的最小脚本确认 Provider 能被识别:
import onnxruntime as ort
print(ort.get_available_providers())
sess = ort.InferenceSession('一个简单模型.onnx', providers=['CPUExecutionProvider'])
print(sess.get_providers())如果第一行输出包含 CPUExecutionProvider 且 session 创建成功,说明依赖问题已解决。注意 providers 参数要放在 InferenceSession 里指定,不要依赖环境变量去猜。实际加载模型时,建议在代码里显式写 providers=['CPUExecutionProvider'],避免同时安装 GPU 版本时自动选错。若仍报错,把完整异常栈贴出来,定位是缺库还是模型算子不支持。
常见问题
为什么 pip 安装 onnxruntime 后还是找不到 CPUExecutionProvider?
通常不是找不到,而是导入阶段崩溃导致 Provider 列表没有生成。先执行打开终端单独运行 import onnxruntime,观察报错信息是缺动态库还是 Python 崩溃。如果是崩溃且提示非法指令或段错误,可能与 CPU 指令集有关,需要更换为兼容当前 CPU 的 onnxruntime 版本(如从 1.15 降到 1.10)再试。离线环境不要盲目升级到最新版。
能否直接把整套 ONNX Runtime 内置到项目目录里避免依赖问题?
可以把 onnxruntime 的 .so 文件和对应运行库放在项目目录中,并通过 LD_LIBRARY_PATH 指定路径,在正式交付前用上述最小脚本验证一遍。但需要注意的是,这种方式不能完全绕开 glibc 这类基础库依赖,只适合同一发行版内部的迁移。软件包升级时需重新验证,否则容易出现“这台机器能跑,换一台就报错”的情况。