pytorch 多GPU训练过程

 

1、torch.cuda.is_available() #cuda是否可用

2、torch.cuda.device_count()#GPU 的数量

3、torch.cuda.current_device() #当前设备的索引,从0开始

4、torch.cuda.get_device_name(0)#返回GPU名字

5、

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 如果这里cuda:0改为cuda,则系统默认为cuda:0

使用pytorch进行多GPU计算,这里默认会使用所有的GPU

model = torch.nn.DataParallel(model)
print(model)

 将模型放到之前定义的device中:

model.to(device)

 若我们只想使用1、3号显卡,那么我们可以用参数device_ids指定即可:

model = torch.nn.DataParallel(model, device_ids=[0, 2])

注意:因为前面定义的device为cuda:0,所以device_ids中必须包含cuda:0,否则训练模型时会报错:

RuntimeError: module must have its parameters and buffers on device cuda:1 (device_ids[0]) but found one of them on device: cuda:0

 

batch size太大了训练收敛会很慢,所以还要把学习率调大一点。大学习率也会使得模型的训练在早期的阶段变得十分不稳定,所以这里需要一个学习率的热身(warm up) 来稳定梯度的下降,然后在逐步的提高学习率。

这种热身只有在超级大的批次下才需要进行,一般我们这种一机4卡或者说在batch size 小于 5000(个人测试)基本上是不需要的。

DataParallel的并行处理机制是,首先将模型加载到主 GPU 上(默认的第一个GPU,GPU0为主GPU),然后再将模型复制到各个指定的从 GPU 中,然后将输入数据按 batch 维度进行划分,具体来说就是每个 GPU 分配到的数据 batch 数量是总输入数据的 batch 除以指定 GPU 个数。每个 GPU 将针对各自的输入数据独立进行 forward 计算,最后将各个 GPU 的 loss 进行求和,再用反向传播更新单个 GPU 上的模型参数,再将更新后的模型参数复制到剩余指定的 GPU 中,这样就完成了一次迭代计算。

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

 

6、load下一个batch、预处理这些batch、在GPU上跑出结果后打印日志、保存模型等,都要靠CPU去完成。

你可能感兴趣的:(python学习)