1.如果我有8片卡,但只想用其中的两片,比如显卡7和显卡8(假设索引从1开始,其实可能是0)

我们先创建好模型:

import torch.nn as nn
inport torchvision.models as models

model = models.vgg16(pretrained = False)
model = nn.DataParallel(model)
model = model.cuda()

在这种情况下,模型及训练过程中的参数都会被加载到默认的显卡上(。。我感觉是模块1),但我们需要的是将模型放在显卡G上作为控制单元,然后将模型复制到其他计算显卡,再将batch_size数据等分成几分,平摊到其他计算显卡,计算完成后,统一由G进行调度并在G中更新。

model = nn.DataParallel(model)
#会把模型复制到8块显卡中,但我们只需要显卡7和显卡8,所以需要修改为:
model = nn.DataParallel(model,device_ids = [7,8])  #使用device_ids进行指定
model = model.cuda(device_ids[0])#不确定是否正确

上面的代码只是针对模型进行操作,对于batch_size数据,则是在训练过程中进行加载,需要注意的地方是,模型与batch_size数据需要加载到先加载到同一张显卡,如果加载到不同的显卡,会报错:需要将所有的数据加载到显卡1。

所以在加载数据时,需要指定:

input_var = Variable(data.cuda(device[0]))

2.单机多卡下模型并行的方式

将Module放在GPU上运行也十分简单,只需两步:(单机单卡模式下可直接使用,不需要下面的并行操作)
model = model.cuda():将模型的所有参数转存到GPU
input = input.cuda():将输入数据也放置到GPU上
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
output = nn.parallel.data_parallel(new_net, input, device_ids=[0, 1])
# method 2
model = nn.DataParallel(model, device_ids=[0, 1])
output = model(input)   #需要两步   个人习惯用方法二   此处需要对原始的input进行相关操作

DataParallel并行的方式,是将输入一个batch的数据均分成多份,分别送到对应的GPU进行计算,各个GPU得到的梯度累加。与Module相关的所有数据也都会以浅复制的方式复制多份

3.引入了一个新的函数model = torch.nn.parallel.DistributedDataParallel(model)为的就是支持分布式模式

不同于原来在multiprocessing中的model = torch.nn.DataParallel(model,device_ids=[0,1,2,3]).cuda()函数,这个函数只是实现了在单机上的多GPU训练,根据官方文档的说法,甚至在单机多卡的模式下,新函数表现也会优于这个旧函数。