+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2020-03(50)

2020-04(67)

2020-05(28)

2020-06(46)

2020-07(42)

DistributedDataParallel简单使用与显存不释放问题的解决

发布于2020-11-29 18:02     阅读(953)     评论(0)     点赞(20)     收藏(3)


0

1

2

3

4

5

6

7

前言

想变得更快

使用

import

from torch.utils.data.distributed import DistributedSampler
import torch.distributed as dist

argments

在参数中添加local_rank

parser.add_argument("--local_rank",type = int,default=-1)

主函数中配置

local_rank = parser.local_rank
    if local_rank != -1:
        dist_backend = 'nccl'
        dist.init_process_group(backend=dist_backend) #  初始化进程组,同时初始化 distributed 包
    device = local_rank if local_rank != -1 else (torch.device('cuda:0') if torch.cuda.is_available() else torch.device('cpu'))
    torch.cuda.set_device(local_rank)  # 配置每个进程的gpu

模型

model.to(device) #  封装之前要把模型移到对应的gpu
    if torch.cuda.device_count() > 1: 
        print("Let's use", torch.cuda.device_count(), "GPUs!")
        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[local_rank], find_unused_parameters=True)

sampler

# 使用DistributedSampler
train_loader = DataLoader(train_data,
                          shuffle=True if not train_sampler else False,
                          sampler = train_sampler,
                          batch_size=args.batch_size)
                              
train_sampler = DistributedSampler(train_data) # 这里的train_data是一个dataset
# 下面错了,valid不需要分布
valid_sampler = DistributedSampler(valid_data)
valid_loader = DataLoader(valid_data,
                              shuffle=False,
                              sampler=valid_sampler,
                              batch_size=batch_size)

命令行执行

CUDA_VISIBLE_DEVICES=0,1,2,3 python -m torch.distributed.launch --nproc_per_node=4 train_snli.py --checkpoint=False --batch_size=128

torch.distributed.launch 会给模型分配一个args.local_rank的参数,也可以通过torch.distributed.get_rank()获取进程id

后记(问题记录)

问题一:显存不释放

我认为是我的代码有问题:
在这里插入图片描述
代码逻辑是这样:在0节点上我去判断accuracy有没有下降,没有的话patience_counter就会+1…
然后下面的if是判断程序是否要提前stop…
由于只在0节点上判断,patience_counter也只可能在0节点上+1,导致其它子进程不会随着0节点的进程一起停止,这就会导致子进程依旧占用着显存的问题。

解决问题一(1):

其实,上面的代码那样写的本意是想让一个节点去保存模型,因为多个节点好像会出错(?)。那我其实可以让所有节点做判断,然后让其中一个节点保存模型:
在这里插入图片描述

解决问题一(2):

我试着在程序的最后加上了(还不知道有没有用):

dist.destroy_process_group()

解决问题一(3):

话说,如果产生了显存不释放的问题怎么办?这时候可能你用nvidia-smi语句都会卡住,解决方法如下:
首先,执行下面语句,会看到很多卡死的进程

fuser -v /dev/nvidia*

在这里插入图片描述

然后试着用kill -9去杀死它们,我因为使用kill -9没有用…所以直接执行下面的语句,杀死了我的所有进程:

killall -u usrname

参考

解决GPU显存未释放问题
解决进程杀死,显存仍在的问题

0

1

2

3

4

5

6

7

8



所属网站分类: 技术文章 > 博客

作者:天青色等烟雨

链接: https://www.pythonheidong.com/blog/article/636151/8eb1d2acdb4d9a9e04a2/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

20 0
收藏该文
已收藏

评论内容:(最多支持255个字符)