复现步骤:
pytorch dataloader的num_worker设为大于0的数(例如8),然后执行后台运行脚本的命令:nohup python -u script.py &
,shell会返回进程pid,下图中我还加了指定GPU的环境变量以及输出重定向:
使用 watch -n .5 ps aux --sort -rss'
持续按照内存从大到小查看进程,dataloader的代码执行之后会发现有1+8个你创建的进程是占用内存排在前列的(下图中我的用户名是xiepengyu):
其中第一个进程就是主进程,即pid(第二列)为19528的进程,其状态为Rl,即正在运行中。其余进程状态为Sl,即睡眠中。此时使用kill -9 19528
命令来kill掉主进程后,会发现其余子进程还没有被kill掉。
为了清理掉这些进程,第一种方法是在前面查看进程后一个一个地kill掉其余进程,例如kill -9 21319
等等。另一种方案,首先确保自己没有其他python进程在跑了,则在准备结束脚本时不要使用 kill -9
,而是使用 killall python
,这样你的账号创建的python进程都会被kill掉,而其他用户的python进程则提示没权限kill:
2020.11.24:今天发现直接kill掉还可能导致显存没有被释放,下图,使用nvidia-smi查看,显示没有进程在1号GPU跑,但是显存仍没有被释放,占用了9个多G:
解决办法,依然是 killall python
2020.11.30:今天又遇到直接kill掉pytorch训练的主进程,然后dataloader的进程还在sleeping的情况,主要是显存也莫名其妙被占用了,所以得全部kill掉。如下图所示,0号gpu没有训练进程(占用49M那个不是训练进程),但是显存却几乎全部占满了。另外,1号gpu上有另一个训练进程在跑,所以不能直接用 killall python
,否则会将1号gpu的python训练进程也杀掉。
我的做法是,首先找到不能误杀的 pid=7547 的训练进程的子进程,排除这些,其他都可以直接kill掉。
使用 watch -n .5 'ps -ef |grep 7547'
,其中PPID一列表示父进程的PID,如果是7547,就说明这些进程是7547的子进程,不能kill,当然,7547本身也不能kill。我忘了截图,总之我看到的结果是PID为 248XX 的几个进程。
然后再使用 ps aux|grep xiepeng
,其中xiepeng改为你的用户名,就可以看到所有自己在跑的进程,然后就是把下图的框中的python训练进程kill掉即可(通过最后一列看进程命令,然后排除 248XX 的进程)