pytorch 单机多卡训练--DataParallel的使用

**********************************原文    https://zhuanlan.zhihu.com/p/158375055   ***************************

 

具体是将输入一个batch的数据均匀分成多份,分别送到对应的GPU进行计算。与module有关的所有数据也都会以浅复制的方式复制多份。每个GPU在单独的线程上对各自输入的数据独立并行地forward计算。然后在主GPU上收集网络输出。并通过将网络输出与批次中每个元素的真实数据进行比较来计算损失函数值。接下来,损失值分散给各个GPU。各个GPU进行反向传播并计算梯度。最后在主GPU上规约梯度,进行梯度下降,并更新主GPU上的模型参数。由于模型参数更新仅仅在主GPU上进行,而其他从属GPU此时并不是同步更新的,所以需要将更新后的模型参数复制到剩余的从属GPU中,以此实现并行。

 

DataParallel会将定义的网络模型参数默认在GPU 0上,多以dataparallel实质可以看做把训练参数从GPU拷贝到其他GPU同时训练训练。这样会导致内存和GPU使用率出现严重的负载不均衡现象,即GPU 0的使用内存和使用率会大大超出其他显卡的使用内存。因为在这里GPU 0作为master 来进行梯度的汇总和模型的更新。再将计算任务下发给其他的GPU,所以他的内存和使用率会比其他的高。 

 

 

 一机多卡并发 backward思路:

1  在gpu1上计算gpu1  gpu2  gpu3 ...gpuN上面对应的梯度

2   将gpu1 计算的梯度分发到各自对应的gpu上面 gpu1 gpu2 gpu3....gpuN

3    将gpu1  gpuN上面各自进行梯度更新

4   然后将更新完梯度的模型参数合并到主gpu上面

 

dataparallel会自动帮我们将数据分发load到相应GPU,将模型复制到相应的GPU·,进行正向传播计算梯度并汇总

model=nn.DataParallel(model.cuda(),devices_is=gpulist,output_devices=gpu[0])

 

值得注意的是,模型和数据都需要先load到各个gpu中,dataparallel的module才能对其进行处理。

将数据分发到各自的GPU里面用  traindata/testdata.cuda()

缺点:

1 在每个训练批次上,因为模型的权重都是在一个进程先计算出来,然后把他们分发到每个GPU上面,所以网络通信就成为了一个瓶颈,而gpu使用率也通常很低。

2  nn.DataParallel需要所有的GPU都在一个节点上,并不支持混合进度训练。

 

posted @ 2021-12-23 10:39  大大的海棠湾  阅读(902)  评论(0)    收藏  举报