
本文详解 ONNX Runtime 启用 CUDAExecutionProvider 时因缺失 CUDA 相关共享库(如 libcublasLt.so.11、libcudnn.so.8)导致的加载失败问题,提供环境变量配置、依赖定位与自动化解决方案。
本文详解 onnx runtime 启用 `cudaexecutionprovider` 时因缺失 cuda 相关共享库(如 `libcublaslt.so.11`、`libcudnn.so.8`)导致的加载失败问题,提供环境变量配置、依赖定位与自动化解决方案。
在使用 ONNX Runtime 的 CUDAExecutionProvider 加速推理时,常见错误如下:
FAIL : Failed to load library libonnxruntime_providers_cuda.so with error: libcublasLt.so.11: cannot open shared object file: No such file or directory
或后续报错:
libcudnn.so.8: cannot open shared object file: No such file or directory
这并非 libonnxruntime_providers_cuda.so 本身缺失(它通常已随 onnxruntime-gpu 安装在 site-packages/onnxruntime/capi/ 下),而是其运行时依赖的 NVIDIA 库未被系统动态链接器(ld.so)发现。这些依赖包括:
- libcublasLt.so.11(或 .so.12)→ 来自 nvidia-cublas-cu11 或 nvidia-cublas-cu12
- libcudnn.so.8 → 来自 nvidia-cudnn-cu11(对应 CUDA 11.x)或 nvidia-cudnn-cu12
- libcurand.so.10, libcufft.so.10, libcudart.so.11.0 等 → 分别来自 nvidia-curand-cu11、nvidia-cufft-cu11、nvidia-cuda-runtime-cu11
✅ 关键点:ONNX Runtime 的 CUDA provider 是一个 独立的共享库(libonnxruntime_providers_cuda.so),它在加载时会递归解析自身依赖链,而 Python 的 LD_LIBRARY_PATH 必须包含所有间接依赖库所在的目录,而不仅是 provider 本体所在路径。
正确设置 LD_LIBRARY_PATH
根据你的 locate 输出,相关库位于 PyPI 安装的 nvidia-* 包内(典型于 pip install onnxruntime-gpu + nvidia-cudnn-cu11 等)。需将每个依赖库所在的具体 lib/ 目录加入 LD_LIBRARY_PATH:
export LD_LIBRARY_PATH="/home/roroco/.pyenv/versions/3.9.1/lib/python3.9/site-packages/onnxruntime/capi:\ /home/roroco/.pyenv/versions/3.9.1/lib/python3.9/site-packages/nvidia/cublas/lib:\ /home/roroco/.pyenv/versions/3.9.1/lib/python3.9/site-packages/nvidia/cudnn/lib:\ /home/roroco/.pyenv/versions/3.9.1/lib/python3.9/site-packages/nvidia/curand/lib:\ /home/roroco/.pyenv/versions/3.9.1/lib/python3.9/site-packages/nvidia/cufft/lib:\ /home/roroco/.pyenv/versions/3.9.1/lib/python3.9/site-packages/nvidia/cuda_runtime/lib:$LD_LIBRARY_PATH"
然后运行脚本:
python onnx/run_onnx.py
⚠️ 注意事项:
- LD_LIBRARY_PATH 中路径必须精确到 lib/ 目录(不是包根目录),因为 .so 文件实际存放于此;
- 路径顺序无关紧要,但建议把 onnxruntime/capi 放最前,确保 provider 本体优先被找到;
- 不要设置 PYTHONPATH 来解决此问题——Python 模块路径不影响 native 共享库加载;
- 若使用 Conda,推荐改用 conda install -c conda-forge onnxruntime-gpu,它会自动处理 CUDA 依赖和 rpath,避免手动配置。
更优雅的自动化方案(推荐)
手动拼接 LD_LIBRARY_PATH 易出错且不可移植。推荐以下两种健壮方式:
✅ 方案一:使用 patchelf 修复 rpath(高级用户)
为 libonnxruntime_providers_cuda.so 注入相对路径或 $ORIGIN,使其自动查找同级或子目录下的依赖:
# 假设当前在 onnxruntime/capi/ 目录下
patchelf --set-rpath '$ORIGIN/../nvidia/cublas/lib:$ORIGIN/../nvidia/cudnn/lib:$ORIGIN/../nvidia/curand/lib:$ORIGIN/../nvidia/cufft/lib:$ORIGIN/../nvidia/cuda_runtime/lib' \
libonnxruntime_providers_cuda.so之后无需设置 LD_LIBRARY_PATH 即可运行。
✅ 方案二:Python 启动前动态注入(跨平台兼容)
在 Python 脚本开头添加以下代码(需在 import onnxruntime 之前执行):
import os
import sys
from pathlib import Path
# 自动探测并注入 NVIDIA 库路径(适配 pip 安装的 onnxruntime-gpu)
def add_nvidia_lib_paths():
try:
import onnxruntime
ort_root = Path(onnxruntime.__file__).parent.parent / "capi"
# 查找所有 nvidia/*/*/lib 目录
for p in Path(ort_root).rglob("nvidia/*/lib"):
if p.is_dir() and p.exists():
lib_path = str(p.resolve())
if lib_path not in os.environ.get("LD_LIBRARY_PATH", ""):
os.environ["LD_LIBRARY_PATH"] = lib_path + ":" + os.environ.get("LD_LIBRARY_PATH", "")
print(f"[INFO] Added to LD_LIBRARY_PATH: {lib_path}")
except ImportError:
pass
add_nvidia_lib_paths()✅ 此方法可嵌入脚本,实现“零配置”启动,尤其适合 Docker 部署或 CI 环境。
验证是否生效
成功加载后,日志中不再出现 Failed to load library 错误,且 InferenceSession 将真实使用 GPU:
print("Available providers:", ort_session.get_providers())
# 应输出包含 'CUDAExecutionProvider'
print("Provider config:", ort_session.get_provider_options())总结
| 问题根源 | libonnxruntime_providers_cuda.so 运行时依赖的 NVIDIA 库未被 ld.so 发现 |
|---|---|
| 根本解法 | 将所有依赖 .so 所在的 lib/ 目录加入 LD_LIBRARY_PATH |
| 最佳实践 | 使用 Conda 安装,或在 Python 中动态注入路径,避免硬编码绝对路径 |
| 排查技巧 | 用 ldd libonnxruntime_providers_cuda.so 查看缺失项;用 strace -e trace=openat python ... 观察加载行为 |
遵循上述方法,即可稳定启用 ONNX Runtime 的 CUDA 加速,显著提升高分辨率图像超分(如 Real-ESRGAN)等模型的推理性能。

















