searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

分布式训练Allreduce算法

2024-12-11 08:57:54
30
0

1. 通信概念

该章节包含DDP的一些知识。

计算机的算法都是基于一个一个函数操作组合在一起得到的,那么我们在讲解分布式算法之前,我们必须先了解一下组成这种算法所应用于硬件的函数操作——集合通信的基本概念

  1. ​Broadcast(广播):​将根服务器(Root Rank)上的数据分发广播给所有其他服务器(Rank)

如图所示,当一台服务器计算完成了自己部分的参数数据,在分布式训练中想要把自己这部分数据同时发送给其他所有服务器,那么这种操作方式就叫做广播(broadcast)。

  1. Scatter​(散射):将根服务器上的数据散射为同等大小的数据块,每一个其他服务器得到一个数据块

如图所示,当一台服务器计算完成自己部分的参数数据,但是因为有时候服务器上全部的参数数据过大,于是我们想要把这台服务器上的数据切分成几个同等大小的数据块(buffer),再按照序列(rank index)向其他服务器发送其中的一个数据块,这就叫做散射(Scatter)。

  1. Gather​(聚集):将其他服务器上的数据块直接拼接到一起,根服务器(Root Rank)获取这些数据

如图所示,当服务器都做了散射之后,每个服务器获得了其他服务器的一个数据块,我们将一台服务器获得的数据块拼接在一起的操作就叫做聚集(Gather)。

  1. AllGather​(全聚集):所有的服务器都做上述Gather的操作,于是所有服务器都获得了全部服务器上的数据

如图所示,所有的服务器都将自己收到的数据块拼接在一起(都做聚集的操作),那么就是全聚集(AllGather)。

  1. ReduceScatter​(散射规约):服务器将自己的数据分为同等大小的数据块,每个服务器将根据index得到的数据做一个规约操作即,即先做Scatter再做Reduce。

概念中,我们也常常遇到散射规约(ReduceScatter)这样的名词,简单来讲,就是先做散射(Scatter),将服务器中数据切分成同等大小的数据块,再按照序列(Rank Index),每一个服务器所获得的参数数据做规约(Reduce)。这就类似于全聚集,只不过我们将数据不是简单拼接到一起而是做了规约操作(求和或最大值等操作)。

​上述文章参考来源:​[分布式训练Allreduce算法]

2. Server-Work架构介绍(DP)

server和worker就对应了我们训练用到的多卡,通常DP接口中输入参数的​第一张卡被用作「server」,其他卡号就是对应的workers​。该架构也是实现DP训练的一种框架。

实现DP的一种经典编程框架叫“参数服务器”(PS),在这个框架里,计算GPU称为Worker,梯度聚合GPU称为Server。在实际应用中,为了尽量减少通讯量,一般可选择一个Worker同时作为Server。比如可把梯度全发到GPU0上做聚合。需要再额外说明几点:

  • 1个Worker或者Server下可以不止1块GPU。
  • Server可以只做梯度聚合,也可以梯度聚合+全量参数更新一起做
  • 在参数服务器的语言体系下,DP的过程又可以被描述下图

DP的框架理解起来不难,但实战中确有两个主要问题:

  • ​存储开销大。​每块GPU上都存了一份完整的模型,造成冗余。关于这一点的优化,我们将在后文ZeRO部分做讲解。
  • ​通讯开销大。​Server需要和每一个Worker进行梯度传输。当Server和Worker不在一台机器上时,Server的带宽将会成为整个系统的计算效率瓶颈。

在通信的过程中work节点也不能闲置,因此需要work节点继续进行运算。

上图刻画了在梯度异步更新的场景下,某个Worker的计算顺序为:

  • 在第10轮计算中,该Worker正常计算梯度,并向Server发送push&pull梯度请求。
  • 但是,该Worker并不会实际等到把聚合梯度拿回来,更新完参数W后再做计算。而是直接拿旧的W,吃新的数据,继续第11轮的计算。这样就保证在通讯的时间里,Worker也在马不停蹄做计算,提升计算通讯比。
  • 当然,异步也不能太过份。只计算梯度,不更新权重,那模型就无法收敛。图中刻画的是延迟为1的异步更新,也就是在开始第12轮对的计算时,必须保证W已经用第10、11轮的梯度做完2次更新了。

总结一下,异步很香,但对一个Worker来说,只是等于W不变,batch的数量增加了而已,在SGD下,会减慢模型的整体​​收敛速度​。​异步的整体思想是,比起让Worker闲着,倒不如让它多吃点数据,虽然反馈延迟了,但只要它在干活在学习就行。

3. 分布式数据并行(DDP)

受通讯负载不均的影响,DP​​一般用于单机多卡场景​。因此,DDP作为一种更通用的解决方案出现了,既能多机,也能单机。DDP首先要解决的就是通讯问题:将Server上的通讯压力均衡转到各个Worker上。实现这一点后,可以进一步去Server,留Worker。

前文我们说过,聚合梯度 + 下发梯度这一轮操作,称为AllReduce。接下来我们介绍​目前最通用的AllReduce方法:Ring-AllReduce。​它由百度最先提出,非常有效地解决了数据并行中通讯负载不均的问题,使得DDP得以实现。

3.1 Ring-AllReduce

如下图,假设有4块GPU,每块GPU上的数据也对应被切成4份。AllReduce的最终目标,就是让每块GPU上的数据都变成箭头右边汇总的样子。

Ring-ALLReduce则分两大步骤实现该目标:Reduce-Scatter和All-Gather。

3.1.1 Ring-AllReduce

如下图,假设有4块GPU,每块GPU上的数据也对应被切成4份。AllReduce的最终目标,就是让每块GPU上的数据都变成箭头右边汇总的样子。

Ring-ALLReduce则分两大步骤实现该目标:Reduce-Scatter和All-Gather。

3.1.2 Reduce-Scatter

定义网络拓扑关系,使得每个GPU只和其相邻的两块GPU通讯。每次发送对应位置的数据进行累加。每一次累加更新都形成一个拓扑环,因此被称为Ring。看到这觉得困惑不要紧,我们用图例把详细步骤画出来。

一次累加完毕后,蓝色位置的数据块被更新,被更新的数据块将成为下一次更新的起点,继续做累加操作。

3次更新之后,每块GPU上都有一块数据拥有了对应位置完整的聚合(图中红色)。此时,Reduce-Scatter阶段结束。进入All-Gather阶段。目标是把红色块的数据广播到其余GPU对应的位置上。

3.1.3 All-Gather

如名字里Gather所述的一样,这操作里依然按照“相邻GPU对应位置进行通讯”的原则,但对应位置数据不再做相加,而是直接替换。All-Gather以红色块作为起点。

以此类推,同样经过3轮迭代后,使得每块GPU上都汇总到了完整的数据,变成如下形式:

3.2 Ring-AllReduce通讯量分析

假设模型参数W的大小为 Φ ,GPU个数为 N 。则梯度大小也为 Φ ,每个梯度块的大小为 ΦN

对单卡GPU来说(只算其send通讯量):

  • Reduce-Scatter阶段,通讯量为 (N−1)ΦN·
  • All-Gather阶段,通讯量为 (N−1)ΦN

单卡总通讯量为 2(N−1)ΦN ,随着N的增大,可以近似为 2Φ 。全卡总通讯量为 2NΦ

而对前文的DP来说,它的Server承载的通讯量是 NΦ ,Workers为 NΦ ,全卡总通讯量依然为 2NΦ 。虽然通讯量相同,但搬运相同数据量的时间却不一定相同。DDP把通讯量均衡负载到了每一时刻的每个Worker上,而DP仅让Server做勤劳的搬运工。当越来越多的GPU分布在距离较远的机器上时,DP的通讯时间是会增加的。

但这并不说明参数服务器不能打(有很多文章将参数服务器当作old dinosaur来看)。事实上,参数服务器也提供了多Server方法,如下图:

在多Server的模式下,进一步,每个Server可以只负责维护和更新某一块梯度(也可以某块梯度+参数一起维护),此时虽然每个Server仍然需要和所有Worker通讯,但它的带宽压力会小非常多。经过调整设计后,依然可以用来做DDP。虽然这篇文章是用递进式的方式来介绍两者,但不代表两者间一定要决出优劣。我想表达的观点是,方法是多样性的。对参数服务器有兴趣的朋友,可以阅读参考的第1个链接。

最后,请大家记住Ring-AllReduce的方法,因为在之后的ZeRO,Megatron-LM中,它将频繁地出现,是分布式训练系统中重要的算子。

3.3 总结

1、在DP中,每个GPU上都拷贝一份完整的模型,每个GPU上处理batch的一部分数据,所有GPU算出来的梯度进行累加后,再传回各GPU用于更新参数

2、DP多采用参数服务器这一编程框架,一般由若个计算Worker和1个梯度聚合Server组成。Server与每个Worker通讯,Worker间并不通讯。因此Server承担了系统所有的通讯压力。基于此DP常用于单机多卡场景。

3、异步梯度更新是提升计算通讯比的一种方法,延迟更新的步数大小决定了模型的收敛速度。

4、Ring-AllReduce通过定义网络环拓扑的方式,将通讯压力均衡地分到每个GPU上,使得跨机器的数据并行(DDP)得以高效实现。

5、DP和DDP的总通讯量相同,但因负载不均的原因,DP需要耗费更多的时间搬运数据

上述​文章参考来源:​[图解大模型训练之:数据并行上篇(DP, DDP与ZeRO)]

0条评论
0 / 1000
1****m
11文章数
0粉丝数
1****m
11 文章 | 0 粉丝
1****m
11文章数
0粉丝数
1****m
11 文章 | 0 粉丝
原创

分布式训练Allreduce算法

2024-12-11 08:57:54
30
0

1. 通信概念

该章节包含DDP的一些知识。

计算机的算法都是基于一个一个函数操作组合在一起得到的,那么我们在讲解分布式算法之前,我们必须先了解一下组成这种算法所应用于硬件的函数操作——集合通信的基本概念

  1. ​Broadcast(广播):​将根服务器(Root Rank)上的数据分发广播给所有其他服务器(Rank)

如图所示,当一台服务器计算完成了自己部分的参数数据,在分布式训练中想要把自己这部分数据同时发送给其他所有服务器,那么这种操作方式就叫做广播(broadcast)。

  1. Scatter​(散射):将根服务器上的数据散射为同等大小的数据块,每一个其他服务器得到一个数据块

如图所示,当一台服务器计算完成自己部分的参数数据,但是因为有时候服务器上全部的参数数据过大,于是我们想要把这台服务器上的数据切分成几个同等大小的数据块(buffer),再按照序列(rank index)向其他服务器发送其中的一个数据块,这就叫做散射(Scatter)。

  1. Gather​(聚集):将其他服务器上的数据块直接拼接到一起,根服务器(Root Rank)获取这些数据

如图所示,当服务器都做了散射之后,每个服务器获得了其他服务器的一个数据块,我们将一台服务器获得的数据块拼接在一起的操作就叫做聚集(Gather)。

  1. AllGather​(全聚集):所有的服务器都做上述Gather的操作,于是所有服务器都获得了全部服务器上的数据

如图所示,所有的服务器都将自己收到的数据块拼接在一起(都做聚集的操作),那么就是全聚集(AllGather)。

  1. ReduceScatter​(散射规约):服务器将自己的数据分为同等大小的数据块,每个服务器将根据index得到的数据做一个规约操作即,即先做Scatter再做Reduce。

概念中,我们也常常遇到散射规约(ReduceScatter)这样的名词,简单来讲,就是先做散射(Scatter),将服务器中数据切分成同等大小的数据块,再按照序列(Rank Index),每一个服务器所获得的参数数据做规约(Reduce)。这就类似于全聚集,只不过我们将数据不是简单拼接到一起而是做了规约操作(求和或最大值等操作)。

​上述文章参考来源:​[分布式训练Allreduce算法]

2. Server-Work架构介绍(DP)

server和worker就对应了我们训练用到的多卡,通常DP接口中输入参数的​第一张卡被用作「server」,其他卡号就是对应的workers​。该架构也是实现DP训练的一种框架。

实现DP的一种经典编程框架叫“参数服务器”(PS),在这个框架里,计算GPU称为Worker,梯度聚合GPU称为Server。在实际应用中,为了尽量减少通讯量,一般可选择一个Worker同时作为Server。比如可把梯度全发到GPU0上做聚合。需要再额外说明几点:

  • 1个Worker或者Server下可以不止1块GPU。
  • Server可以只做梯度聚合,也可以梯度聚合+全量参数更新一起做
  • 在参数服务器的语言体系下,DP的过程又可以被描述下图

DP的框架理解起来不难,但实战中确有两个主要问题:

  • ​存储开销大。​每块GPU上都存了一份完整的模型,造成冗余。关于这一点的优化,我们将在后文ZeRO部分做讲解。
  • ​通讯开销大。​Server需要和每一个Worker进行梯度传输。当Server和Worker不在一台机器上时,Server的带宽将会成为整个系统的计算效率瓶颈。

在通信的过程中work节点也不能闲置,因此需要work节点继续进行运算。

上图刻画了在梯度异步更新的场景下,某个Worker的计算顺序为:

  • 在第10轮计算中,该Worker正常计算梯度,并向Server发送push&pull梯度请求。
  • 但是,该Worker并不会实际等到把聚合梯度拿回来,更新完参数W后再做计算。而是直接拿旧的W,吃新的数据,继续第11轮的计算。这样就保证在通讯的时间里,Worker也在马不停蹄做计算,提升计算通讯比。
  • 当然,异步也不能太过份。只计算梯度,不更新权重,那模型就无法收敛。图中刻画的是延迟为1的异步更新,也就是在开始第12轮对的计算时,必须保证W已经用第10、11轮的梯度做完2次更新了。

总结一下,异步很香,但对一个Worker来说,只是等于W不变,batch的数量增加了而已,在SGD下,会减慢模型的整体​​收敛速度​。​异步的整体思想是,比起让Worker闲着,倒不如让它多吃点数据,虽然反馈延迟了,但只要它在干活在学习就行。

3. 分布式数据并行(DDP)

受通讯负载不均的影响,DP​​一般用于单机多卡场景​。因此,DDP作为一种更通用的解决方案出现了,既能多机,也能单机。DDP首先要解决的就是通讯问题:将Server上的通讯压力均衡转到各个Worker上。实现这一点后,可以进一步去Server,留Worker。

前文我们说过,聚合梯度 + 下发梯度这一轮操作,称为AllReduce。接下来我们介绍​目前最通用的AllReduce方法:Ring-AllReduce。​它由百度最先提出,非常有效地解决了数据并行中通讯负载不均的问题,使得DDP得以实现。

3.1 Ring-AllReduce

如下图,假设有4块GPU,每块GPU上的数据也对应被切成4份。AllReduce的最终目标,就是让每块GPU上的数据都变成箭头右边汇总的样子。

Ring-ALLReduce则分两大步骤实现该目标:Reduce-Scatter和All-Gather。

3.1.1 Ring-AllReduce

如下图,假设有4块GPU,每块GPU上的数据也对应被切成4份。AllReduce的最终目标,就是让每块GPU上的数据都变成箭头右边汇总的样子。

Ring-ALLReduce则分两大步骤实现该目标:Reduce-Scatter和All-Gather。

3.1.2 Reduce-Scatter

定义网络拓扑关系,使得每个GPU只和其相邻的两块GPU通讯。每次发送对应位置的数据进行累加。每一次累加更新都形成一个拓扑环,因此被称为Ring。看到这觉得困惑不要紧,我们用图例把详细步骤画出来。

一次累加完毕后,蓝色位置的数据块被更新,被更新的数据块将成为下一次更新的起点,继续做累加操作。

3次更新之后,每块GPU上都有一块数据拥有了对应位置完整的聚合(图中红色)。此时,Reduce-Scatter阶段结束。进入All-Gather阶段。目标是把红色块的数据广播到其余GPU对应的位置上。

3.1.3 All-Gather

如名字里Gather所述的一样,这操作里依然按照“相邻GPU对应位置进行通讯”的原则,但对应位置数据不再做相加,而是直接替换。All-Gather以红色块作为起点。

以此类推,同样经过3轮迭代后,使得每块GPU上都汇总到了完整的数据,变成如下形式:

3.2 Ring-AllReduce通讯量分析

假设模型参数W的大小为 Φ ,GPU个数为 N 。则梯度大小也为 Φ ,每个梯度块的大小为 ΦN

对单卡GPU来说(只算其send通讯量):

  • Reduce-Scatter阶段,通讯量为 (N−1)ΦN·
  • All-Gather阶段,通讯量为 (N−1)ΦN

单卡总通讯量为 2(N−1)ΦN ,随着N的增大,可以近似为 2Φ 。全卡总通讯量为 2NΦ

而对前文的DP来说,它的Server承载的通讯量是 NΦ ,Workers为 NΦ ,全卡总通讯量依然为 2NΦ 。虽然通讯量相同,但搬运相同数据量的时间却不一定相同。DDP把通讯量均衡负载到了每一时刻的每个Worker上,而DP仅让Server做勤劳的搬运工。当越来越多的GPU分布在距离较远的机器上时,DP的通讯时间是会增加的。

但这并不说明参数服务器不能打(有很多文章将参数服务器当作old dinosaur来看)。事实上,参数服务器也提供了多Server方法,如下图:

在多Server的模式下,进一步,每个Server可以只负责维护和更新某一块梯度(也可以某块梯度+参数一起维护),此时虽然每个Server仍然需要和所有Worker通讯,但它的带宽压力会小非常多。经过调整设计后,依然可以用来做DDP。虽然这篇文章是用递进式的方式来介绍两者,但不代表两者间一定要决出优劣。我想表达的观点是,方法是多样性的。对参数服务器有兴趣的朋友,可以阅读参考的第1个链接。

最后,请大家记住Ring-AllReduce的方法,因为在之后的ZeRO,Megatron-LM中,它将频繁地出现,是分布式训练系统中重要的算子。

3.3 总结

1、在DP中,每个GPU上都拷贝一份完整的模型,每个GPU上处理batch的一部分数据,所有GPU算出来的梯度进行累加后,再传回各GPU用于更新参数

2、DP多采用参数服务器这一编程框架,一般由若个计算Worker和1个梯度聚合Server组成。Server与每个Worker通讯,Worker间并不通讯。因此Server承担了系统所有的通讯压力。基于此DP常用于单机多卡场景。

3、异步梯度更新是提升计算通讯比的一种方法,延迟更新的步数大小决定了模型的收敛速度。

4、Ring-AllReduce通过定义网络环拓扑的方式,将通讯压力均衡地分到每个GPU上,使得跨机器的数据并行(DDP)得以高效实现。

5、DP和DDP的总通讯量相同,但因负载不均的原因,DP需要耗费更多的时间搬运数据

上述​文章参考来源:​[图解大模型训练之:数据并行上篇(DP, DDP与ZeRO)]

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0