使用GPU服务器租用运行深度学习任务时,程序明明已经退出,nvidia-smi却仍显示显存被占用,新的大模型训练因此无法启动。这类问题常与残留进程、父子进程未回收或容器退出不完整有关,盲目重启实例虽然有效,却会中断其他任务。
一、问题背景
训练脚本可能启动数据加载、日志记录和分布式通信等多个子进程。主进程异常退出后,部分子进程仍持有CUDA上下文;Jupyter内核、推理部署服务或容器也可能继续驻留。需要注意,Linux僵尸进程本身已经结束,通常不占用显存,真正占用资源的往往是孤儿进程或未退出的工作进程。
GPU算力平台提供远程实例后,开发者仍应建立“确认任务归属—终止服务—复查资源”的处理顺序。AI算力平台上的同一实例可能同时运行多个实验,直接执行全局清理容易误伤正常任务。
二、环境准备
准备SSH终端和当前用户权限,记录正在运行的任务、容器及端口。润云智算提供GPU云服务器、开发镜像和模型资源,开发者可通过官网www.smoothcloud.com.cn/了解相关环境。排查前先保存日志与检查点,避免未写盘结果丢失。
hostname
nvidia-smi
ps -eo pid,ppid,state,user,cmd --sort=ppid
三、实操步骤
1. 找出显存占用进程
先查看GPU进程列表,再用PID追踪命令、用户和父进程:
nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv
ps -fp <PID>
pstree -aps <PID>
不要只根据进程名称判断归属。应同时核对启动时间、工作目录和父进程,确认它是否属于当前实验。
2. 区分僵尸、孤儿与正常进程
STAT包含Z表示僵尸进程,它等待父进程回收;父进程号变为1的后台任务可能是孤儿进程。继续检查打开的设备文件:
ps -o pid,ppid,stat,etime,cmd -p <PID>
lsof /dev/nvidia* 2>/dev/null | head
如果僵尸进程不在nvidia-smi计算进程列表中,就不应把它当成显存占用源。
3. 按由轻到重的顺序停止
先向目标进程发送正常退出信号:
kill -TERM <PID>
sleep 5
ps -p <PID>
nvidia-smi
服务由systemd、Docker或任务管理器启动时,应通过原启动方式停止,避免守护程序再次拉起。只有确认进程无响应且检查点已保存,才考虑kill -KILL。
4. 处理多进程训练残留
分布式大模型训练可能遗留多个worker。可先按父进程或当前用户筛选,不要使用宽泛的pkill python:
pgrep -a -P <PARENT_PID>
ps -u "$USER" -o pid,ppid,stat,cmd | grep train
终止主任务后再次检查子进程、通信进程和共享内存。多人共用实例时,清理前必须确认用户名与命令行。
5. 验证显存是否真正释放
进程退出后连续观察GPU状态:
watch -n 1 nvidia-smi
若进程列表为空但显存仍异常,应检查容器、Jupyter内核和驱动日志。不要在仍有其他用户任务时执行GPU重置;必要时先停止相关服务,再安排维护窗口重启。
四、常见问题与解决方案
1. nvidia-smi有PID,但ps查不到
可能是进程刚退出、命名空间差异或驱动状态未刷新。检查容器进程与系统日志,短暂等待后复查。
2. 结束进程后又自动出现
通常由守护服务或容器重启策略拉起,应停止对应服务,而不是反复杀进程。
3. 为什么不建议直接重启
重启会中断同机的科研训练、模型下载和在线接口。先定位资源归属,通常能以更小影响恢复运行。
4. 如何减少再次发生
为训练脚本增加信号处理、finally清理和检查点保存;退出前关闭数据加载进程及分布式进程组。
五、总结
显存残留排查的关键不是“强制清空”,而是确认真正持有CUDA上下文的进程,再按服务管理方式安全退出。使用润云智算等GPU计算环境时,可把PID、父进程、容器和显存复查写入运维清单,让训练与推理任务恢复更可控。
FAQ
Q1:僵尸进程一定占显存吗?
不一定。僵尸进程通常已释放运行资源,应以nvidia-smi和设备文件占用为准。
Q2:可以直接执行pkill python吗?
不建议,它可能结束无关任务,应使用明确PID或服务名称。
Q3:什么时候可以重启实例?
确认关键数据已保存、其他任务已停止,且常规清理无效时再安排重启。
Q4:显存释放后需要重新安装CUDA吗?
通常不需要。运行最小CUDA测试,确认框架能识别GPU即可。