本文最后更新于:2026年6月3日 晚上
最近在服务器上跑 MMDetection / PyTorch 实验时遇到了一个比较迷惑的问题:机器明明有 4 张 RTX 4090,nvidia-smi 也能正常识别 GPU,但 PyTorch 却突然无法使用 CUDA。由于之前同一个环境一直能正常跑实验,因此一开始很容易误判为 PyTorch、CUDA 或驱动版本不匹配。最后排查发现,问题实际出在 NVIDIA 的 nvidia_uvm 内核模块状态异常,重载该模块后恢复正常。
本文记录一下完整排查过程和解决方法。
1. 问题现象 运行分析脚本时,程序在 model.to(device) 阶段报错:
1 RuntimeError: CUDA driver initialization failed, you might not have a CUDA gpu.
对应代码大致是:
其中 device 设置为:
同时,PyTorch 在初始化 CUDA 时给出如下 warning:
1 UserWarning: CUDA initialization: CUDA driver initialization failed, you might not have a CUDA gpu.
最开始看到这个报错,很容易以为是机器没有 GPU、CUDA 不可用,或者 PyTorch 装错了。但实际情况并不是这样。
2. 基础环境检查 首先检查 PyTorch 和 CUDA 信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 conda activate openmmlab python - <<'PY' import torchprint ("torch:" , torch.__version__)print ("cuda version:" , torch.version.cuda)print ("cuda available:" , torch.cuda.is_available())print ("device count:" , torch.cuda.device_count())if torch.cuda.is_available(): print ("gpu:" , torch.cuda.get_device_name(0)) PY
输出结果如下:
1 2 3 4 torch: 2.4.1 cuda version: 12.4 cuda available: False device count: 4
这个结果很关键:
1 2 torch.cuda.is_available() = False torch.cuda.device_count() = 4
也就是说,PyTorch 实际上能枚举到 4 张 GPU,但是 CUDA runtime 初始化失败。
这类情况和“完全没有 GPU”不一样。它说明 NVIDIA 驱动 / NVML 层面可以看到设备,但 CUDA runtime 在创建 context 时失败。
随后检查 nvidia-smi:
输出中可以看到:
1 2 3 NVIDIA-SMI 575.57.08 Driver Version: 575.57.08 CUDA Version: 12.9
驱动版本是 575.57.08,支持 CUDA 12.9。对于 PyTorch 2.4.1 + CUDA 12.4 来说,驱动版本足够新,因此基本可以排除“驱动版本太旧”的问题。
3. 典型误判:不是 PyTorch CUDA 版本问题 因为环境中 PyTorch 显示:
1 torch.version.cuda = 12.4
而 nvidia-smi 显示:
这里需要注意:nvidia-smi 里显示的 CUDA Version 代表当前 NVIDIA driver 最高支持的 CUDA runtime API 版本,并不等同于系统实际安装的 CUDA toolkit 版本,也不要求必须和 PyTorch 的 CUDA 版本完全一致。
只要 driver 版本足够新,一般可以向下兼容 PyTorch 自带的 CUDA runtime。因此这里不是因为 12.9 和 12.4 不一致导致的问题。
4. 尝试 GPU reset 由于之前同一环境能正常运行,只是跑了几组实验后突然出问题,因此更像是 GPU driver runtime 状态异常、残留 CUDA context 或某些监控进程占用设备。
尝试 reset GPU:
1 sudo nvidia-smi --gpu-reset -i 0,1,2,3
结果提示:
1 2 3 4 5 6 7 The following GPUs could not be reset: GPU 00000000:18:00.0: In use by another client GPU 00000000:3B:00.0: In use by another client GPU 00000000:86:00.0: In use by another client GPU 00000000:D8:00.0: In use by another client 4 devices are currently being used by one or more other processes.
这说明 GPU 当前仍然被某些 client 占用,无法直接 reset。
5. 检查设备占用 先用 fuser 查看 /dev/nvidia* 的占用情况:
1 sudo fuser -v /dev/nvidia*
最开始发现是 nvidia-persistenced 占用:
1 2 3 4 5 /dev/nvidia0: nvidia-persistenced 1326 F.... nvidia-persiste /dev/nvidia1: nvidia-persistenced 1326 F.... nvidia-persiste /dev/nvidia2: nvidia-persistenced 1326 F.... nvidia-persiste /dev/nvidia3: nvidia-persistenced 1326 F.... nvidia-persiste /dev/nvidiactl: nvidia-persistenced 1326 F.... nvidia-persiste
停止该服务:
1 sudo systemctl stop nvidia-persistenced
再次 reset,仍然失败。
继续检查:
1 sudo fuser -v /dev/nvidia*
发现还有 gpustat 在占用设备:
1 2 3 4 5 6 /dev/nvidia0: chenjiajun 3863230 F.... gpustat /dev/nvidia1: chenjiajun 3863230 F.... gpustat /dev/nvidia2: chenjiajun 3863230 F.... gpustat /dev/nvidia3: chenjiajun 3863230 F.... gpustat /dev/nvidiactl: chenjiajun 3863230 F...m gpustat /dev/nvidia-uvm: chenjiajun 3863230 F.... gpustat
杀掉该进程:
然后再次确认:
1 sudo fuser -v /dev/nvidia*
这时已经没有用户态进程占用了。
但此时执行 GPU reset 仍然提示:
1 In use by another client
这说明可能不是普通用户进程占用,而是 NVIDIA 驱动内部状态、UVM 模块、内核级 client 或残留 context 的问题。
6. 最终解决:重载 nvidia_uvm 尝试重载 NVIDIA Unified Virtual Memory 模块:
1 2 sudo rmmod nvidia_uvm sudo modprobe nvidia_uvm
然后重新测试 PyTorch:
1 2 3 4 5 6 7 8 9 python - <<'PY' import torchprint ("available:" , torch.cuda.is_available())print ("count:" , torch.cuda.device_count()) x = torch.zeros(1, device="cuda:0" )print ("CUDA OK:" , x) PY
输出恢复正常:
1 2 3 available: True count: 4 CUDA OK: tensor([0.], device='cuda:0')
至此问题解决。
7. 原因分析 这次问题的核心现象是:
1 2 3 4 nvidia-smi 正常 PyTorch 能看到 GPU 数量 但 torch.cuda.is_available() 为 False 创建 cuda tensor 失败
这种情况下,问题通常不在于 GPU 是否存在,而在于 CUDA runtime 无法成功初始化 driver context。
nvidia_uvm 是 NVIDIA Unified Virtual Memory 相关的内核模块。PyTorch 初始化 CUDA、创建 CUDA context、分配显存时都会依赖相关驱动组件。当该模块状态异常时,可能出现如下现象:
1 2 3 4 5 NVML / nvidia-smi 可以正常枚举 GPU CUDA runtime 初始化失败 torch.cuda.device_count() 能返回 GPU 数量 torch.cuda.is_available() 返回 False torch.cuda.get_device_name() 或 cuda tensor 创建时报错
也就是:设备可见,但 CUDA 不可用。
这类问题在长时间多卡实验、频繁中断训练、异常退出、监控工具长时间占用 GPU、CUDA context 未正常释放时都有可能出现。
8. 推荐排查流程 以后如果再次遇到类似问题,可以按下面顺序排查。
8.1 检查 PyTorch CUDA 状态 1 2 3 4 5 6 7 8 9 10 11 12 13 14 python - <<'PY' import torchprint ("torch:" , torch.__version__)print ("torch cuda:" , torch.version.cuda)print ("available:" , torch.cuda.is_available())print ("count:" , torch.cuda.device_count()) try: x = torch.zeros(1, device="cuda:0" ) print ("CUDA OK:" , x) except Exception as e: print ("CUDA FAILED:" , repr(e)) PY
如果出现:
1 2 3 available: False count: 4 CUDA driver initialization failed
说明 GPU 可见但 CUDA runtime 初始化失败。
8.2 检查驱动
确认 driver 正常,GPU 正常显示。
8.3 检查用户进程占用 1 sudo fuser -v /dev/nvidia*
或者:
如果有残留进程,例如:
1 2 3 4 5 python torchrun gpustat nvtop nvidia-smi
可以先杀掉:
1 2 3 4 pkill -9 -f gpustat pkill -9 -f nvtop pkill -9 -f torchrun pkill -9 -u $USER -f python
杀进程时要谨慎,尤其是多人服务器,避免误杀其他人的任务。
8.4 重载 UVM 模块 如果确认没有重要进程占用,可以执行:
1 2 sudo rmmod nvidia_uvm sudo modprobe nvidia_uvm
然后重新测试:
1 2 3 4 5 python - <<'PY' import torchprint (torch.cuda.is_available(), torch.cuda.device_count())print (torch.zeros(1, device="cuda:0" )) PY
如果恢复正常,说明问题就是 UVM 模块状态异常。
8.5 如果 rmmod 提示模块正在使用 如果执行:
提示:
1 Module nvidia_uvm is in use
说明仍然有进程占用 /dev/nvidia-uvm。继续查:
1 2 sudo fuser -v /dev/nvidia-uvm sudo lsof /dev/nvidia-uvm
找到 PID 后杀掉:
然后再重载:
1 2 sudo rmmod nvidia_uvm sudo modprobe nvidia_uvm
8.6 实在不行再重启 如果:
1 2 3 4 5 fuser 查不到进程 lsof 查不到进程 rmmod nvidia_uvm 失败 gpu-reset 失败 PyTorch 仍然无法初始化 CUDA
那大概率是驱动内部状态已经卡死。最稳妥的方式是重启服务器:
9. 最终可复用命令 这次问题的最小修复命令是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 pkill -9 -f gpustat pkill -9 -f nvtop sudo fuser -v /dev/nvidia* sudo rmmod nvidia_uvm sudo modprobe nvidia_uvm python - <<'PY' import torchprint ("available:" , torch.cuda.is_available())print ("count:" , torch.cuda.device_count())print (torch.zeros(1, device="cuda:0" )) PY
如果需要 reset GPU,可以在无进程占用后执行:
1 sudo nvidia-smi --gpu-reset -i 0,1,2,3
但这次实际并不需要 reset GPU,只需要重载 nvidia_uvm 即可恢复。
10. 小结 这次问题的关键点是:
1 2 3 torch.cuda.device_count() = 4 torch.cuda.is_available() = False CUDA driver initialization failed
这类报错不一定是 PyTorch 安装错误,也不一定是 CUDA 版本不匹配。特别是当 nvidia-smi 正常、之前环境也能正常跑时,更应该优先怀疑:
1 2 3 4 5 残留 CUDA 进程 监控工具占用 nvidia-persistenced nvidia_uvm 状态异常 driver 内部 context 未释放
最终通过:
1 2 sudo rmmod nvidia_uvm sudo modprobe nvidia_uvm
成功恢复。
对于多卡深度学习服务器来说,nvidia-smi 正常只能说明 NVML 层面能看到 GPU,并不等价于 CUDA runtime 一定能正常创建 context。PyTorch 能枚举 GPU 数量但不能初始化 CUDA 时,nvidia_uvm 是一个非常值得优先检查的方向。