注:本文内容多参考自 一文说清楚Tensorflow分布式训练必备知识 - 知乎

PS架构中,当worker数量较多时,ps节点的网络带宽将成为系统的瓶颈。

AllReduce 架构是指不带有参数服务器的分布式集群架构。在该架构中,集群中的所有节点都作为 worker 来执行计算操作,该架构会在每个 batch 训练完成后使用 AllReduce 算法在所有 worker 节点间进行模型变量的同步更新。

目前应用于深度学习的 AllReduce 算法有多种,如 Ring AllReduce 以及 NCCL 等

传统的同步更新方法(各个gpu卡算好梯度,求和算平均的方式),在融合梯度时,会产生巨大的通信数据量,这种通信压力往往在模型参数量很大时,显得很明显。因此我们需要找到一种方法,来解决同步更新的网络瓶颈问题。其中最具代表性的一种方法就是:ring all-reduce。

Ring AllReduce架构中各个设备都是worker,没有中心节点来聚合所有worker计算的梯度。Ring AllReduce算法将 device 放置在一个逻辑环路(logical ring)中。每个 device 从上行的device 接收数据,并向下行的 deivce 发送数据,因此可以充分利用每个 device 的上下行带宽。

梯度融合过程分为两阶段:

  1. Scatter Reduce:在这个 Scatter Reduce阶段,GPU 会逐步交换彼此的梯度并融合,最后每个 GPU 都会包含完整融合梯度的一部分

  2. Allgather:GPU 会逐步交换彼此不完整的融合梯度,最后所有 GPU 都会得到完整的融合梯度

使用 Ring Allreduce 算法进行某个稠密梯度的平均值的基本过程如下:

将每个设备上的梯度 tensor 切分成长度大致相等的 num_devices 个分片;

ScatterReduce 阶段:通过 num_devices - 1 轮通信和相加,在每个 device 上都计算出一个 tensor 分片的和;

AllGather 阶段:通过 num_devices - 1 轮通信和覆盖,将上个阶段计算出的每个 tensor 分片的和广播到其他 device;

在每个设备上合并分片,得到梯度和,然后除以 num_devices,得到平均梯度;

以 4 个 device上的梯度求和过程为例:

ScatterReduce 阶段:

图片来自知乎-杨旭东

经过 num_devices - 1 轮后,每个 device 上都有一个 tensor 分片进得到了这个分片各个 device 上的和;

AllGather 阶段:

图片来自知乎-杨旭东

经过 num_devices - 1 轮后,每个 device 上都每个 tensor 分片都得到了这个分片各个 device 上的和;

相比PS架构,Ring Allreduce架构是带宽优化的,因为集群中每个节点的带宽都被充分利用。此外,在深度学习训练过程中,计算梯度采用BP算法,其特点是后面层的梯度先被计算,而前面层的梯度慢于前面层,Ring-allreduce架构可以充分利用这个特点,在前面层梯度计算的同时进行后面层梯度的传递,从而进一步减少训练时间。Ring Allreduce的训练速度基本上线性正比于GPUs数目(worker数)。

通信代价分析:每个 GPU 在Scatter Reduce 阶段,接收 N-1 次数据,N 是 GPU 数量;每个 GPU 在allgather 阶段,接收 N-1 次 数据;每个 GPU 每次发送 K/N 大小数据块,K 是总数据大小;所以,Data Transferred=2(N−1)*K/N ,随着 GPU 数量 N 增加,总传输量恒定。也就是理论上,随着gpu数量的增加,ring all-reduce有线性加速能力。

参考资料

浅谈Tensorflow分布式架构:ring all-reduce算法 - 知乎

一文说清楚Tensorflow分布式训练必备知识 - 知乎

【第一期】AI Talk:TensorFlow 分布式训练的线性加速实践 - 知乎

腾讯机智团队分享--AllReduce算法的前世今生 - 知乎