a0+a1+a2+a3 b1+b2+b3
d0+d1+d2+d3
a0+al+a2
b1+b2
b0+b1+b2+b3 c0+C1+C2+C3
d1+d0+d3
d0+d1+d2+d3
a0+al+a2+a3 b0+b1+b2+b3
d0+d1+d2+d3
a0+a1+a2+a3 b0+b1+b2+b3
以此类推,同样经过 3 轮迭代后,使得每块 GPU 上都汇总到了完整的数据,变成如下形式:
二、nn.parallel.DistributedDataParallel 函数介绍一下? nn.parallel.DistributedDataParallel 函数 CLASS torch.nn. parallel.DistributedDataParallel ( module, device_ids=None, output_device=None, dim=0, broadcast_buffers=True, process_group=None, bucket_cap_mb=25, find_unused_parameters=False, check_reduction=False
- module 是要放到多卡训练的模型;
- device_ids 数据类型是一个列表,表示可用的 gpu 卡号;
- output_devices 数据类型也是列表,表示模型输出结果存放的卡号(如果不指定的话,默认放在 0 卡,这也 是为什么多 gpu 训 l 练并不是负载均衡的,一般 0 卡会占用的多,这里还涉及到一个小知识点——如果程序 开始加 os.environ ["CUDA_VISIBLE_DEVICES"] ="2, 3",那么 0 卡(逻辑卡号)指的是 2 卡(物理卡号))。
- dim 指按哪个维度进行数据的划分,默认是输入数据的第一个维度,即按 batchsize 划分(设数据数据的格 式是 B,C, H,W) 三,nn.parallel.DistributedDataParallel 函数如何多卡加速训练? DDP 在各进程梯度计算完成之,各进程需要将梯度进行汇总平均;然后再由 rank=0 的进程,将其 broadcast 到所有 进程后,各进程用该梯度来独立的更新参数,而 DP 是梯度汇总到 GPUO,反向传播更新参数,再广播参数给其他剩余 的 GPU。由于 DDP 各进程中的模型,初始参数一致(初始时刻进行一次 broadcast),而每次用于更新参数的梯度也 一致,因此,各进程的模型参数始终保持一致。而在 DP 中,全程维护一个 optimizer,对各个 GPU 上梯度进行求,而在 主卡进行参数更新,之后再将模型参数 broadcast 到其他 GPU 四、nn.parallel.DistributedDataParallel 实现流程介绍一下? 1. init_process_group 初始化进程组(如果需要进行前面提到的小组内集体通信,用 new_group 创建子分组) #初始化使用 ncc1 后端,官网还提供了‘gl00’作为 backend,俺觉得知道 nccl 是用来 GPU 之
间进行通信的就可以 torch.distributed.init_process_group (backend="nccl”) 2. 使用 DistributedSampler (改 dataloader 中 sampler=train_sampler) # train_dataset 就是自己的数据集 train_sampler = torch.utils.data.distributed. DistributedSampler (train_dataset)