乐趣区

关于集合:利用共享内存实现比-NCCL-更快的集合通信

作者:曹彬 | 旷视 MegEngine 架构师

简介

从 2080Ti 这一代显卡开始,所有的民用游戏卡都勾销了 P2P copy,导致训练速度显著的变慢。针对这种状况下的单机多卡训练,MegEngine 中实现了更快的汇合通信算法,对多个不同的网络训练绝对于 NCCL 有 3% 到 10% 的减速成果。

MegEngine v1.5 版本,能够手动切换汇合通信后端为 shm(默认是 nccl),只须要改一个参数。(因为 shm 模式对 CPU 有额定的占用,且只有在特定卡下能力提高效率,因而并没有默认关上)

gm = GradManager()
gm.attach(model.parameters(), callbacks=[dist.make_allreduce_cb("sum", backend="shm")])
目前只实现了单机版本,多机暂不反对 

背景

在大规模训练中,数据并行是最简略最常见的训练形式,每张卡运行齐全一样的网络结构,而后加上参数同步就能够了。

对于 数据并行的参数同步,目前有两种罕用的办法,Parameter Server 和 Gradient AllReduce:

  • Parameter Server 计划须要额定机器作为参数服务器来更新参数,而且核心式的通信形式对带宽的压力很大,减少训练机器的同时通信量也线性减少;
  • 而 AllReduce 计划只是参加训练的机器之间相互同步参数,不须要额定的机器,可扩展性好。

MegEngine 目前也是应用 AllReduce 计划作为数据并行的参数同步计划。而在 AllReduce 计划中,大家目前罕用的是 NCCL,Nvidia 自家写的 GPU 汇合通信库,通信效率很高。

看到这里,能够失去一个论断,数据并行的状况,用 NCCL 通信库能达到不错的成果。

到这里就完结了?当然不是,在 2080Ti 8 卡训练的状况下,在多个网络下,咱们绝对 NCCL 有 3% 到 10% 的性能晋升。(以 2080Ti 为例子是因为游戏卡不反对 P2P 通信,相对来说通信较慢,通信工夫长,节俭通信工夫能取得的收益较大)

这是怎么做到的呢,咱们一步一步来剖析(以下数据都是用 megengine.utils.profiler 导出,相干文档在 profiler 文档)。

通常咱们是在 backward 阶段同时做 gradient 的同步,咱们来看单卡的 backward 耗时,只有 164ms:

再来看 8 卡训练时 backward 的耗时,增长到了 203ms,比单卡的状况下多了 39ms:

的确,backward 工夫变长了不少,可是为什么?咱们有没有可能打消它?

1)为什么

一句话:NCCL AllReduce 占用了 cuda 计算资源,所以计算变慢。

具体起因是 NCCL AllReduce 对应的 cuda kernel 须要既做通信又做计算,所以占用了计算对应须要的计算资源,然而大部分工夫都花在了通信上,导致计算资源的利用率不够高。

2)能不能打消它

当然是能够的,cuda 计算和通信是能够并行的,让计算和通信运行在两个不同的 cuda stream 上,就能够并行起来,这一点在 cuda 开发者文档中有提到。

3)理论测试计算和通信并行的例子

stream0 进行矩阵乘法运算,stream1 进行拷贝,前后矩阵乘法的速度没有受到影响:

实现思路

这里先介绍一下 AllReduce 的两种实现办法。

1)ReduceScatter + AllGather

Ring AllReduce 就是用的 ReduceScatter + AllGather 的模式:首先第一轮通信在各个节点上计算出局部和,而后第二轮通信把局部和汇集一下失去最终后果。

2)Reduce + Broadcast

Reduce + Broadcast 的形式像 Parameter Server,会先在一个节点计算出残缺的累加和,而后再播送到各个节点上。

新的算法采纳的是 Reduce + Broadcast 的办法,首先将数据全副拷贝到 cpu(应用 Shared Memory),而后由 cpu 进行累加,再拷贝回 gpu。

因为间接拷贝累加没有把计算和通信 overlap 起来,咱们还采纳了相似 Ring AllReduce 的分块策略,让通信和计算充沛 overlap,如下图所示。

因为用到了 Shared Memory,所以把这个后端简称为 SHM。

实现成果

1)算子性能

绝对 NCCL 来说,SHM 的提早略微高了一些,带宽低了一些,数据大一些的状况能够达到 NCCL 的 90% 左右的性能。

SHM 性能须要在数据包大的状况施展,和 ParamPack 策略搭配能最大施展 SHM 的作用(在 MegEngine 中 distributed.make_allreduce_cb 中应用了 ParamPack 策略,默认打包大小为 10M)。ParamPack 策略是指将参数对应的梯度打包进行发送,缩小小包发送,以缩小通信提早减少带宽利用率。

2)理论训练成果

持续应用 ResNet50 8 卡训练的例子,SHM 与 NCCL 相比,backward 工夫快了近 30ms(203ms->174ms)。

Shared Memory AllReduce 的不足之处 / 后续改良

1)cpu 占用多

因为占用了 cpu 资源做 reduce 运算,所以在 cpu 资源缓和的状况下会比较慢,须要确定 cpu 资源是否够用再进行应用。

2)额定通信老本

因为 copy 和 reduce 之间有数据依赖关系,copy 须要期待上一次的 reduce 实现能力开始,reduce 要期待 copy 数据就位能力开始,所以两头插入了信号量的同步,引入了额定的通信老本,在分块越多的状况越显著。

3)多过程负载平衡

各个过程的 copy 和 reduce 速度不统一导致了进度不同步的问题,会造成多余的等待时间,依据理论运行速度进行分配任务性能会有进一步的晋升。

4)更多的 overlap

目前只用到了 copy 和 reduce 之间的 overlap,然而其实 h2d 和 d2h 拷贝也是能够 overlap 起来的,能够有进一步减速。


附:

GitHub:MegEngine 天元

官网:MegEngine- 深度学习,简略开发

欢送退出 MegEngine 技术交换 QQ 群:1029741705

退出移动版