解决GPU显存未释放问题

前言

今早我想用多块GPU测试模型,于是就用了PyTorch里的torch.nn.parallel.DistributedDataParallel(下面简称其为Dist)来支持用多块GPU的同时使用。

在程序运行时由于程序中一些与Dist无关的代码出现了错误导致程序退出,而如果在程序退出前没有用Dist关闭生成的所有进程,就会导致程序崩溃后GPU显存未释放。笔者观察发现,由于没有用Dist关闭所有进程,导致程序结束运行后还有一部分进程在运行,所以显存未释放。

下面介绍这次我解决该问题的过程。

正文

MVE

Minimal Verifiable Examples,关于本问题的程序代码如下:

import torch.distributed as dist

# 一些代码:定义model等
some code

# 初始化并行训练
dist.init_process_group(xxxx)  # 函数参数省略
model = torch.nn.parallel.DistributedDataParallel(model, find_unused_parameters=True)

# 一些代码:训练、测试模型等
some code  # 我的程序在这个部分出错且程序直接退出,导致下面的关闭进程的代码没有运行

# 关闭所有进程
dist.destroy_process_group()

问题的出现

如下图所示,程序退出后,并没有进程在使用0号GPU,但0号GPU的显存却被占用。原因是程序退出前没有用Dist关闭所有进程,一部分进程还在运行,这些进程占用0号GPU的显存。

占用7号GPU的进程是我的另外一个进程,与本文讨论的问题无关。

image-20200404070619631

定位占用GPU显存的PID

执行下面的指令

fuser -v /dev/nvidia*

该命令执行后得到下图所示的结果,可以看到是PID为285448的进程占用了0号GPU。

下面的图中忘记打了马赛克,后来用黑色遮挡了一下信息,所以USER这一列是看起来是空的。

image-20200404070704618

执行下面这条命令,查看该进程的信息,可以发现该进程的PPID(其父进程的PID)是1,说明该进程不是我占用7号GPU的进程生成的,并且现在只有它在使用0号GPU。可以推断出这个进程是因为程序运行错误导致其没有被关闭,因此可以手动关闭该进程。

ps -f -p 285448

下面的图中忘记打了马赛克,后来用黑色遮挡了一下信息,所以图中的路径不是很清晰。

image-20200404070805983

先后执行下面这两条命令,杀掉该进程,再查看GPU情况,可以看到0号GPU的显存已经被释放,现在的GPU显存占用情况是正常的。

kill -9 2885448
nvidia-smi

image-20200404070901921


作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!


posted @ 2020-04-04 10:30  臭咸鱼  阅读(12829)  评论(0编辑  收藏  举报