关于 CUDA initialization: Unexpected error from cudaGetDeviceCount() 的问题

2025博客之星年度评选已开启 10w+人浏览 1.5k人参与

在这里插入图片描述

之前服务器一直好好的,忽然在执行 torch.cuda.is_available() 的时候出现了如下问题

CUDA initialization: Unexpected error from cudaGetDeviceCount()

经过搜索我发现很多帖子都指向了 nvidia-fabric-manager 这个软件包相关的问题,但是我的服务器原来也没有安装过 nvidia-fabric-manager 相关的软件包呀,看起来方向不太对,但为何很多帖子都这么写呢?

经过仔细对比我才发现,CUDA initialization: Unexpected error from cudaGetDeviceCount() 这个错误,在很多时候都会有!
要结合具体后面的详细信息,区分不同的问题,具体整理如下

一、问题类型:Error 802 system not yet initialized

主要和 nvidia-fabric-manager 软件包相关,一般是解决方案是安装并确认正确版本的 nvidia-fabric-manager 运行

具体细节可以参考上面给出的参考文章,但整体来说可以按照如下步骤解决
(假设驱动版本是 510,具体驱动版本可以通过 nvidia-smi 命令查看)

# 其他版本的下载路径可以从链接 https://developer.download.nvidia.cn/compute/cuda/repos/ubuntu1804/x86_64/ 中找到
wget https://developer.download.nvidia.cn/compute/cuda/repos/ubuntu1804/x86_64/nvidia-fabricmanager-510_510.47.03-1_amd64.deb
apt-get remove nvidia-fabricmanager-510
apt-get install ./nvidia-fabricmanager-510_510.47.03-1_amd64.deb
systemctl enable nvidia-fabricmanager
systemctl restart nvidia-fabricmanager
systemctl status nvidia-fabricmanager

二、问题类型:Error 101: invalid device ordinal

这个具体原因不详,但看上面的参考内容,重启服务器可以解决问题

三、问题类型:Error 804: forward compatibility was attempted on non supported HW

这个是我遇到的问题,也是下面要详细介绍的问题。

这个问题是版本兼容性问题。英伟达显卡相关的软件组件包含如下层级(由最底层到高层)

  • 最底层:显卡型号
  • NVIDIA 内核模块(Kernel-space):驱动版本要和显卡型号兼容
    • nvidia.ko (主内核驱动模块)
    • nvidia-uvm.ko (统一虚拟内存支持,用于 CUDA)
    • nvidia-drm.ko (显示 / 图形相关,可选)
  • NVIDIA 用户态驱动库(User-space)内核模块与用户态驱动版本需保持一致,版本号完全一致
    • libnvidia-ml.so (NVML, for monitoring)
    • libnvidia-compute.so (核心计算功能)
    • libnvidia-opencl.so (OpenCL 支持)
    • libcuda.so (CUDA Driver API,驱动核心接口)
  • CUDA Toolkit(CUDA 工具包)** CUDA Toolkit 版本需与驱动版本兼容**
    • libcudart.so (CUDA Runtime,运行时库)
    • nvcc (CUDA 编译器,用于编译 cuda 算子,允许缺失)
    • libcublas.so 等配套计算库
  • 应用层(User Applications)应用层要和驱动层版本兼容
    • PyTorch, TensorFlow, CUDA C++ programs 等

如果不符合兼容性,就会出问题!

备注:NVIDIA 从 450+ 驱动开始支持一定程度的前向兼容,但 Error 804 是因为该机制在特定硬件上不被支持(forward compatibility was attempted on non supported HW)

1. 如何查看显卡型号

对于没安装任何工具的服务器,使用如下命令来查看显卡硬件信息

lspci | grep -E 'VGA|3D|Display'

比如我的输出是

root@x-ran:~# lspci | grep -E 'VGA|3D|Display'
02:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics Family (rev 41)
ca:00.0 VGA compatible controller: NVIDIA Corporation Device 2684 (rev a1)
e3:00.0 3D controller: NVIDIA Corporation GP102GL [Tesla P40] (rev a1)

对应的显卡信息如下

总线地址设备类型具体硬件核心用途
02:00.0ASPEED BMC 显卡AST2500/AST2600服务器远程管理、BIOS 显示(系统自带)
ca:00.0NVIDIA 显卡(未识别型号)设备 ID 0x2684(H100/A100)高端算力 / AI 计算(主卡)
e3:00.0NVIDIA 3D 控制器Tesla P40(GP102GL)AI 推理 / 离线渲染(算力卡)

其中 NVIDIA Corporation Device 2684 没有具体型号,可以访问网址 https://admin.pci-ids.ucw.cz/read/PC/10de/2684 查看,其中 10de 是英伟达的编号。

2. 如何查看内核模块(Kernel-space)版本

使用如下命令查看磁盘上的内核模块文件元数据(可能和运行时不一致)

# 查询 nvidia.ko 版本
modinfo nvidia | grep -E '^filename|^version|^vermagic'
# 查询 nvidia-uvm.ko 版本
modinfo nvidia-uvm | grep -E '^filename|^version|^vermagic'
# 查询 nvidia-drm.ko 版本
modinfo nvidia-drm | grep -E '^filename|^version|^vermagic'

我的输出如下,重点关注 version

filename:       /lib/modules/5.15.0-134-generic/kernel/nvidia-550/nvidia.ko
version:        550.120
vermagic:       5.15.0-134-generic SMP mod_unload modversions

filename:       /lib/modules/5.15.0-134-generic/kernel/nvidia-550/nvidia-uvm.ko
version:        550.120
vermagic:       5.15.0-134-generic SMP mod_unload modversions

filename:       /lib/modules/5.15.0-134-generic/kernel/nvidia-550/nvidia-drm.ko
version:        550.120
vermagic:       5.15.0-134-generic SMP mod_unload modversions

使用 cat /proc/driver/nvidia/version 查看内核中运行的驱动实时信息(运行时真实版本)

# cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module  550.144.03  Mon Dec 30 17:44:08 UTC 2024
GCC version:  gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)

版本 550.144.03

3. 查看用户态驱动库版本信息

libnvidia-ml.so、libnvidia-compute.so、libnvidia-opencl.so、libcuda.so

以 libnvidia-ml.so 为例,先使用命令 ldconfig -p | grep libnvidia-ml

# ldconfig -p | grep libnvidia-ml
	libnvidia-ml.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libnvidia-ml.so.1
	libnvidia-ml.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libnvidia-ml.so

再查看 /lib/x86_64-linux-gnu/libnvidia-ml.so.1 的详细信息

# ls -alh /lib/x86_64-linux-gnu/libnvidia-ml.so.1
lrwxrwxrwx 1 root root 26 Apr  8  2025 /lib/x86_64-linux-gnu/libnvidia-ml.so.1 -> libnvidia-ml.so.550.163.01

我们可以看到 libnvidia-ml.so 使用的是 550.163.01 版本。

类似的,可以查出来其余 so 版本,发现都是 550.163.01 版本

4. 查看 CUDA Toolkit 版本

使用类似 3 中的命令,可以查看

  • libcudart.so
    • 路径:/usr/local/cuda-11.8/targets/x86_64-linux/lib/libcudart.so.11.8.89
    • 版本:11.8
  • libcublas.so
    • 路径:/usr/local/cuda-11.8/targets/x86_64-linux/lib/libcublas.so.11.11.3.6
    • 版本:11.11.3.6

5. 信息汇总

让我们汇总上面的信息

  • NVIDIA 内核模块(Kernel-space):驱动版本要和显卡型号兼容
    • 磁盘元信息:550.120
    • 加载信息:550.144.03
  • NVIDIA 用户态驱动库(User-space)内核模块与用户态驱动版本需保持一致,版本号完全一致
    • 550.163.01
  • CUDA Toolkit(CUDA 工具包)** CUDA Toolkit 版本需与驱动版本兼容**
    • libcudart.so:11.8
    • libcublas.so:11.11.3.6

这里内核模块元信息和加载信息不匹配的问题,可能来自于服务器安装了多个版本的驱动,但在运行时的不匹配,和这个问题关系不大。

最明显的可能问题就是NVIDIA 内核模块和NVIDIA 用户态驱动库不匹配(550.144.03 vs 550.163.01)

解决途径一个是整体重装所有的驱动,我是用的方法是降级 “用户态驱动库”:550.163.01 -> 550.144.03

sudo apt install \
  libnvidia-compute-550=550.144.03-0ubuntu1 \
  libnvidia-gl-550=550.144.03-0ubuntu1 \
  libnvidia-decode-550=550.144.03-0ubuntu1 \
  libnvidia-encode-550=550.144.03-0ubuntu1 \
  libnvidia-fbc1-550=550.144.03-0ubuntu1 \
  libnvidia-common-550=550.144.03-0ubuntu1 \
  nvidia-utils-550=550.144.03-0ubuntu1

降级后,为了防止版本被意外改动,可以将其版本固定住

sudo apt-mark hold \
  libnvidia-compute-550 \
  libnvidia-gl-550 \
  libnvidia-decode-550 \
  libnvidia-encode-550 \
  libnvidia-fbc1-550 \
  libnvidia-common-550 \
  nvidia-utils-550

⚠️ 注意:锁定版本后,后续的安全更新将不会自动应用到这些包
建议定期检查是否有安全补丁,必要时手动更新并确保内核模块同步

修复后,运行如下命令,验证是否修复了该问题

nvidia-smi
python3 -c "import torch; print(torch.cuda.is_available())"
# 输出 True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小郎碎碎念

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值