• 解决GPU显存未释放问题


    前言

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

    程序运行时,由于程序中其他部分的代码(与Dist无关的代码)出现了错误,导致程序退出。这次使用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/

    欢迎讨论和交流!


  • 相关阅读:
    java实现亲密数
    java实现亲密数
    java实现亲密数
    java实现亲密数
    java实现坐标
    java实现坐标
    java实现坐标
    java实现坐标
    java实现坐标
    spring中注解注入 context:component-scan 的使用说明
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/12630665.html
Copyright © 2020-2023  润新知