N卡用户必看:当nvidia-smi不显示进程却占用显存时的5种排查方法
你是否也遇到过这种令人抓狂的情况?在终端里敲下 nvidia-smi,期望看到哪个“贪吃”的进程占满了宝贵的显存,结果却发现GPU利用率居高不下,显存被占用了一大块,但“Processes”那一栏却空空如也,或者只显示一个孤零零的“No running processes found”。模型训练卡住了,新任务启动失败,重启机器又怕丢失中间状态。这感觉就像家里电表飞转,却找不到哪个电器在耗电。对于依赖GPU进行深度学习、科学计算或图形渲染的开发者来说,这种“幽灵显存”问题不仅影响效率,更让人心生不安。
别担心,这并非灵异事件,而是Linux系统与NVIDIA驱动、CUDA运行时交互中一些特定状态的体现。显存被占用却找不到对应进程,通常意味着有进程已经异常终止,但其申请的内存资源未被驱动或操作系统正确释放;或者,进程本身以某种“隐藏”或非标准的方式在访问GPU。本文将为你系统性地梳理五种从基础到进阶的排查与解决方法,不仅告诉你“怎么做”,更解释“为什么”,让你下次遇到时能从容应对,彻底告别显存迷雾。
1. 理解显存管理的“黑匣子”:为何进程消失,显存犹在?
在深入具体命令之前,我们有必要先拆解一下GPU显存管理的机制。这能帮助你理解问题的根源,而不是死记硬背命令。
简单来说,当一个应用程序(比如你的PyTorch训练脚本)通过CUDA运行时库申请显存时,流程涉及多个层面:
- 应用层:你的代码调用
cudaMalloc或框架的Tensor.to(‘cuda’)。 - 运行时层:CUDA Runtime 或 Driver API 处理请求。
- 驱动层:NVIDIA 内核驱动模块(
nvidia.ko)最终在物理显存上分配空间。 - 内核层:Linux内核维护着进程与驱动模块之间的关联。
当进程正常退出时,它会通过CUDA运行时发起释放请求,驱动层清理显存,内核更新状态,一切井然有序。问题就出在非正常退出的场景:
- 进程崩溃 (Crash):进程突然终止,未能执行清理例程。如果崩溃发生在用户态,且CUDA运行时有机会进行一些清理,可能不会泄露。但如果是严重的段错误或直接被
kill -9,清理流程可能被打断。 - 僵尸进程 (Zombie/Defunct Process):这是Linux进程状态的一种。子进程已经终止,但其退出状态尚未被父进程读取(通过
wait()系统调用)。此时,进程在内核的进程表里仍占有一个条目(PID),但已不执行任何代码,也无法被信号杀死。关键点在于:一个僵尸进程本身不占用计算资源(CPU/GPU),但它可能持有一些未关闭的资源句柄。如果这个句柄恰好关联着GPU显存,那么驱动层面可能因为句柄未释放而认为显存仍在被使用。 - 内核上下文残留:更底层的情况是,进程在内核驱动中创建的上下文(Context)没有被完全销毁。这就像在GPU上开了一个“工作间”,进程走了,但“工作间”的门没关,里面的“物品”(显存)就被标记为占用。
所以,nvidia-smi 不显示进程,可能是因为:
- 占用显存的实体已经不是传统意义上的“运行中进程”(如僵尸进程)。
- 进程访问GPU的方式绕过了
nvidia-smi默认的监控(如通过MIG模式、特定计算实例,或某些容器环境)。 nvidia-smi工具本身的缓存或显示逻辑存在延迟。
注意:
nvidia-smi显示的进程列表主要来源于对/proc文件系统和驱动接口的查询,它可能无法捕获所有类型的GPU资源持有者。
理解了这些,我们就能有的放矢地进行排查。接下来,我们从最直接的命令开始。



被折叠的 条评论
为什么被折叠?



