pytorch的并行分为模型并行、数据并行
左侧模型并行:是网络太大,一张卡存不了,那么拆分,然后进行模型并行训练。
右侧数据并行:多个显卡同时采用数据训练网络的副本。
一、模型并行
二、数据并行
数据并行的操作要求我们将数据划5分成多份,然后发送给多个 GPU 进行并行的计算。
注意:多卡训练要考虑通信开销的,是个trade off的过程,不见得四块卡一定比两块卡快多少,可能是训练到四块卡的时候通信开销已经占了大头
下面是一个简单的示例。要实现数据并行,第一个方法是采用 nn.parallel中的几个函数,分别实现的功能如下所示:
复制(Replicate):将模型拷贝到多个 GPU 上;
分发(Scatter):将输入数据根据其第一个维度(通常就是 batch 大小)划分多份,并传送到多个 GPU 上;
收集(Gather):从多个 GPU 上传送回来的数据,再次连接回一起;
并行的应用(parallel_apply):将第三步得到的分布式的输入数据应用到第一步中拷贝的多个模型上。
实现代码如下
#Replicate module to devices in device_ids
replicas =nn.parallel.replicate(module, device_ids)#Distribute input to devices in device_ids
inputs =nn.parallel.scatter(input, device_ids)#Apply the models to corresponding inputs
outputs =nn.parallel.parallel_apply(replicas, inputs)#Gather result from all devices to output_device
result = nn.parallel.gather(outputs, output_device)
6.事实上PyTorch也提供了简单的函数,只用几行代码可实现简单高效的并行GPU计算。
①nn.parallel.data_parallel(module, inputs, device_ids=None, output_device=None, dim=0, module_kwargs=None)
②class torch.nn.DataParallel(module, device_ids=None, output_device=None, dim=0)
可见二者的参数十分相似,通过device_ids参数可以指定在哪些GPU上进行优化,output_device指定输出到哪个GPU上。唯一的不同就在于前者直接利用多GPU并行计算得出结果,而后者则返回一个新的module,能够自动在多GPU上进行并行加速。
#method 1
new_net= nn.DataParallel(net, device_ids=[0, 1])
output=new_net(input)#method 2
output= nn.parallel.data_parallel(new_net, input, device_ids=[0, 1])
数据并行torch.nn.DataParallel
PyTorch 中实现数据并行的操作可以通过使用 torch.nn.DataParallel。
一、DataParallel的并行处理机制
DataParallel,是将输入一个 batch 的数据均分成多份,分别送到对应的 GPU 进行计算,各 个 GPU 得到的梯度累加。与 Module 相关的所有数据也都会以浅复制的方式复制多份。每个 GPU 将针对各自的输入数据独立进行 forward 计算,在 backward 时,每个卡上的梯度会汇总到原始的 module 上,再用反向传播更新单个 GPU 上的模型参数,再将更新后的模型参数复制到剩余指定的 GPU 中,以此来实现并行。
DataParallel会将定义的网络模型参数默认放在GPU 0上,所以dataparallel实质是可以看做把训练参数从GPU拷贝到其他的GPU同时训练,这样会导致内存和GPU使用率出现很严重的负载不均衡现象,即GPU 0的使用内存和使用率会大大超出其他显卡的使用内存,因为在这里GPU0作为master来进行梯度的汇总和模型的更新,再将计算任务下发给其他GPU,所以他的内存和使用率会比其他的高。
(图