Pytorch实现多GPU分布式训练

  1. 何为分布式训练
    分布式计算指的是一种编写程序的方式,它利用网络中多个连接的不同组件。通常,大规模计算通过以这种方式布置计算机来实现,这些计算机能够并行地处理高密度的数值运算。在分布式计算的术语中,这些计算机通常被称为节点(node),这些节点的集合就是集群。这些节点一般是通过以太网连接的,但是其他的高带宽网络也可以利用分布式架构的优势。

  2. 并行策略的类型
    并行深度学习模型有两种流行的方式:模型并行、数据并行。

  3. 模型并行
    模型并行指的是一个模型从逻辑上被分成了几个部分(例如,一些层在一部分,其他层在另一部分),然后把它们部署在不同的硬件/设备上。
    尽管从执行时间上来看,将模型的不同部分部署在不同设备上确实有好处,但是它通常是出于避免内存限制才使用。具有特别多参数的模型会受益于这种并行策略,因为这类模型需要很高的内存占用,很难适应到单个系统。

  4. 数据并行
    另一方面,数据并行指的是,通过位于不同硬件/设备上的同一个网络的多个副本来处理数据的不同批(batch)。不同于模型并行,每个副本可能是整个网络,而不仅仅是一部分。
    正如你可能猜到的,这种策略随着数据的增长可以很好地扩展。但是,由于整个网络必须部署在一个设备上,因此可能无法帮助到具有高内存占用的模型。下图应该可以说清楚这个问题。
    Pytorch实现多GPU分布式训练_第1张图片

  5. 下面重点介绍我使用模型并行训练踩过的坑
    按照官网上提供的方法添加这一段代码

    if torch.cuda.device_count() > 1:
        print("Let's use", torch.cuda.device_count(), "GPUs to train model!")
        gpus=[0, 1]  # 定义电脑可见的GPU
        model = nn.DataParallel(model, device_ids=gpus).cuda()
        model.to(torch.device("cuda:1"))

默认GPU的编号为0,1,如果这里定义的是gpus=[1,2],其实在电脑中1对应的还是GPU0,2对应的是GPU1,在后面使用时不要搞混,默认会使用GPU0进行训练,并且在训练过程中产生的缓存会默认存储在GPU0中。

我的网络模型是一个Deeplab网络也就是model后面连接了一个对抗网络model_D,将model网络放在第二个GPU上跑,将model_D放在第一个GPU上跑,为什么要这样分配呢?因为model模型较大,运行过程中产生的参数较多,而model_D模型较小放在第一个GPU上,训练过程中产生的参数也会默认存储在第一个GPU上,为防止GPU内存不足做了这样的分配。

 if torch.cuda.device_count() > 1:
        print("Let's use", torch.cuda.device_count(), "GPUs to train model_D!")
        model_D = nn.DataParallel(model_D, device_ids=[0, 1]).cuda()
        model_D.to(torch.device("cuda:0"))

首先就是我运行后报的第一个错误,Error(s) in loading state_dict for Dataparallel,大概意思就是字典中的关键词对不上,导致加载模型错误。
Pytorch实现多GPU分布式训练_第2张图片
遇事不决,打印出来看看,对,然后我把存储模型的dict中的key 全部打印出来,发现使用Dataparallel加载模型时,所有关键字外面都加了一个module.,就是下图中的第二列。
Pytorch实现多GPU分布式训练_第3张图片
解决办法是将load_state_dict的strict参数设置为False。

model.load_state_dict(new_params, False)

接下来是我遇到的第二个bug,ModuleAttributeError: ‘DataParallel‘ object has no attribute ‘ xxx ’,我猜这个错误是因为前面的参数设置strict=False的原因,解决办法就是在所有报错的地方加上module.
Pytorch实现多GPU分布式训练_第4张图片
这个时候可能还会报一个错误:CUDA out of memory
在这里插入图片描述
我曾经一度以为这个错误就是GPU内存不够大导致的,翻来覆去调了好几次代码,还叫同学一起调,所以,这个时候不要着急!不要着急!不要着急!等GPU缓存自己清掉,GPU利用率自己降下来之后,再运行代码,下面是见证奇迹的时刻!开始训练了!
Pytorch实现多GPU分布式训练_第5张图片
还有一个问题就是,网上有的直接说要将batch_size调整为GPU个数的倍数,但我的batch_size是1,也可以正常运行,(因为我把batch_size设置为2 的时候会报错),我猜大概是使用模型并行训练不需要调整batch_size,使用数据并行训练的时候要将batch_size设置为GPU的倍数,这里并没有验证过,如果有哪位大佬做过这方面,欢迎在评论区留言指导!

到此就是我使用多GPU训练网络的心酸血泪史!!!

参考文献:分布式入门,怎样用PyTorch实现多GPU分布式训练

你可能感兴趣的:(pytorch,深度学习,pytorch,深度学习,神经网络)