程序停止后GPU仍被占用

在跑深度学习程序的时候,有时强制终止程序,可是程序占用的GPU资源仍然没有被释放,被这个坑了好久,还以为是GPU一直被别人抢占了,结果是GPU资源泄露。

可以使用这个命令查看Linux系统GPU的使用情况

nvidia-smi

得到如图结果
GPU资源使用情况

此时可以手动kill掉占用GPU的进程,以此来释放GPU资源

kill -9 49461

若是使用了Screen命令在后台运行的程序终止后占用了GPU,也可以先关掉所有了Screen窗口来释放GPU

killall screen

当然直接kill掉进程也是可以的

<think> 我们参考了用户提供的引用内容,特别是引用[2]中提到的情况:即使使用kill -9杀死进程,GPU显存仍然被占用,以及引用[1]中关于Docker容器内僵尸进程的问题。用户的需求是彻底杀死占用GPU进程的程序,包括僵尸进程和内核级占用的情况。 根据之前的对话历史,我们了解到用户遇到了GPU利用率和显存占用满的问题,但没有运行任何训练程序。我们之前已经提供了解决方案,包括终止用户级进程和重新加载NVIDIA内核模块。现在用户进一步询问彻底杀死占用GPU进程的方法,我们将结合引用内容,提供更详细的步骤,特别是针对Docker容器和僵尸进程的处理。 ### 解决方案步骤 #### 1. 识别占用GPU的进程 首先,使用以下命令查看哪些进程正在占用GPU资源: ```bash nvidia-smi ``` 或者使用更详细的命令: ```bash sudo fuser -v /dev/nvidia* # 显示所有占用GPU设备的进程[^2] ``` 如果进程属于Docker容器,我们可以使用以下方法找到对应的容器: ```bash docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}' | grep <PID> ``` 其中`<PID>`是占用GPU的进程ID。通过这个命令可以找到进程所属的容器[^1]。 #### 2. 终止用户级进程 对于用户级进程,可以通过以下命令终止: ```bash sudo kill -9 <PID> # 强制终止指定进程 ``` 或者批量终止所有占用GPU的进程: ```bash sudo kill -9 $(sudo lsof -t /dev/nvidia*) # 终止所有使用GPU的进程 ``` #### 3. 处理僵尸进程 如果进程已经被杀死(在`nvidia-smi`中不显示),但显存仍然被占用,这可能是僵尸进程或内核级占用。此时,需要检查进程状态: ```bash cat /proc/<PID>/status # 查看进程状态,注意State字段是否为Z (zombie) ``` 如果是僵尸进程,需要杀死其父进程: ```bash sudo kill -9 <PPID> # PPID是父进程ID ``` #### 4. 处理Docker容器内的僵尸进程 如果僵尸进程位于Docker容器内,可以尝试重启容器: ```bash docker restart <container_id> ``` 或者直接停止容器: ```bash docker stop <container_id> ``` #### 5. 处理内核级占用 如果以上方法无效,可能是内核模块未释放显存。此时需要重新加载NVIDIA内核模块: ```bash sudo rmmod nvidia_uvm nvidia_drm nvidia_modeset nvidia sudo modprobe nvidia sudo modprobe nvidia_modeset sudo modprobe nvidia_drm sudo modprobe nvidia_uvm ``` 注意:重新加载模块会重置所有GPU状态,可能导致短暂的图形界面卡顿,但通常不需要重启系统。 #### 6. 验证释放效果 使用以下命令监控GPU状态: ```bash watch -n 0.5 nvidia-smi # 每0.5秒刷新一次 ``` 显存占用应降至很低(如100MB以下),GPU利用率应为0%。 ### 预防措施 - **定期监控**:使用脚本监控GPU使用情况,及时发现僵尸进程。 - **容器管理**:在Docker容器中运行训练任务时,确保任务结束后正确退出,避免产生僵尸进程。 - **脚本自动清理**:可以编写脚本定期清理占用GPU的僵尸进程。 ### 示例脚本:批量终止占用GPU的进程 参考引用[3],我们可以使用Python脚本终止所有占用GPU的Python进程: ```python import os import time def get_exec_out(execute_str): out_list = os.popen(execute_str).readlines() return out_list if __name__ == '__main__': execute_str = 'nvidia-smi' out_list = get_exec_out(execute_str) pids = [] for line in out_list: if 'python' in line: # 可以根据需要修改为其他进程名 parts = line.split() pid = parts[2].strip() pids.append(pid) if pids: kill_cmd = 'kill -9 ' + ' '.join(pids) print(kill_cmd) os.system(kill_cmd) else: print("No processes found.") ``` ### 注意事项 - 重新加载NVIDIA内核模块(`rmmod`和`modprobe`)需要root权限,且会重置所有GPU状态,但不会影响CPU任务。 - 如果遇到模块无法卸载(如`rmmod: ERROR: Module nvidia is in use`),需先终止所有使用GPU的进程(包括图形界面进程),或重启系统。 §§相关问题§§ 1. 如何防止Docker容器中的僵尸进程占用GPU显存? 2. 重新加载NVIDIA驱动模块后图形界面异常如何处理? 3. 除了`fuser`,还有哪些命令可以检测GPU资源占用? 4. 如何设置系统在GPU异常占用时自动报警? </think> 以下是彻底杀死占用GPU进程的完整解决方案,结合系统级操作和容器级处理: ### 彻底清除GPU占用进程的方法 #### 1. 定位占用进程(关键步骤) ```bash # 查看所有占用GPU的进程(包括隐藏进程) sudo fuser -v /dev/nvidia* 2>/dev/null # 显示进程树关系(找出僵尸进程的父进程) ps auxf | grep -A 15 -B 5 nvidia ``` #### 2. 强制终止普通进程 ```bash # 批量终止所有GPU进程 sudo kill -9 $(sudo lsof -t /dev/nvidia*) # 针对残留进程(如僵尸进程) sudo kill -9 $(ps -e -o pid,comm,stat | awk '/^ *[0-9]+.*Z/ {print $1}') ``` #### 3. 处理Docker容器内进程 ```bash # 查找容器内占用GPU的进程 docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}' | \ while read line; do pid=$(echo $line | cut -d',' -f1) name=$(echo $line | cut -d',' -f2) sudo ls -l /proc/$pid/root/dev | grep nvidia >/dev/null && echo "$name (PID: $pid) 占用GPU" done # 强制终止容器内所有GPU进程 docker ps -q | xargs -I{} docker exec {} /bin/bash -c "kill -9 $(lsof -t /dev/nvidia* 2>/dev/null)" ``` #### 4. 内核级清理(终极方案) ```bash # 卸载并重载NVIDIA内核模块 sudo rmmod nvidia_uvm sudo rmmod nvidia_drm sudo rmmod nvidia_modeset sudo rmmod nvidia # 重载模块(按依赖顺序) sudo modprobe nvidia sudo modprobe nvidia_modeset sudo modprobe nvidia_drm sudo modprobe nvidia_uvm # 验证模块状态 lsmod | grep nvidia ``` #### 5. 预防性脚本(自动清理) 创建监控脚本 `gpu_cleaner.sh`: ```bash #!/bin/bash while true; do # 检测GPU利用率>90%且持续5分钟 if nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader | \ awk '{if($1>90) count++} END{if(count>0) exit 1}'; then sleep 300 # 正常状态等待5分钟 else # 自动清理流程 echo "[$(date)] 检测到异常GPU占用,开始清理..." sudo kill -9 $(sudo lsof -t /dev/nvidia*) sudo rmmod nvidia_uvm nvidia_drm nvidia_modeset nvidia sudo modprobe nvidia nvidia_modeset nvidia_drm nvidia_uvm nvidia-smi > /var/log/gpu_clean.log fi done ``` ### 效果验证 ```bash # 实时监控GPU状态 watch -n 1 -d "nvidia-smi && echo '---进程列表---' && ps aux | grep -i nvidia" ``` 预期结果: 1. GPU利用率降至 0-5% 2. 显存占用降至 100MB 以下 3. 无任何用户进程显示在 `nvidia-smi` 中 ### 疑难解答 **若仍存在占用**: 1. 检查内核日志: ```bash dmesg | grep -i nvidia ``` 2. 彻底重置GPU(需root): ```bash echo 1 > /sys/bus/pci/devices/$(lspci | grep VGA | grep NVIDIA | awk '{print "0000:"$1}')/reset ``` ### 根本原因分析 | 现象 | 原因 | 解决方案 | |---------------------|-----------------------|------------------------| | 进程已杀但显存不释放| 内核模块状态错误 | 重载`nvidia_uvm`模块 | | 无进程但GPU利用率高 | 僵尸进程/DMA残留 | PCI设备重置 | | 容器内进程残留 | CGroup资源未释放 | 重启容器引擎 |
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值