前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【笔记】PyTorch DDP 与 Ring-AllReduce

【笔记】PyTorch DDP 与 Ring-AllReduce

作者头像
小锋学长生活大爆炸
发布2023-07-31 14:35:27
1.1K0
发布2023-07-31 14:35:27
举报

转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn]

文内若有错误,欢迎指出!


image.png
image.png

         今天我想跟大家分享的是一篇虽然有点老,但是很经典的文章,这是一个在分布式训练中会用到的一项技术, 实际上叫ringallreduce。 为什么要叫这个吗?因为现在很多框架,比如像pytorch他内部的分布式训练用到的就是这个。 所以知道他的原理的话也方便我们后面给他进行改进和优化。他是一项来自HPC的技术,但实际上现在分布式机器学习上的很多技术都是借鉴自HPC。下面的内容一部分来自论文,另一部分是来自网络。

        这里先介绍一点背景知识。         以数据并行为例,在分布式训练中,需要将数据分布到不同的GPU上面进行训练,然后训练一个epoch后进行梯度更新。这里的更新可以分为同步和异步,为了方便理解,这里我画了几张图。 同步比较好理解,每个GPU在完成之后,需要等其他GPU也完成才能进行梯度更新。异步的话,就是说每个GPU可以独自进行梯度更新,并且在一定的时间点进行梯度交换,因此并不需要等其他的GPU也完成。而这两种方式中的梯度交换也引申出了很多研究内容。         总的来说是基于两种方式,一种是使用参数服务器,另一种是通过reduce操作。 参数服务器的方式是通过指定一个服务器来协调计算每个GPU的梯度。他的缺点也很明显,随着GPU的增加,参数服务器的通信成为了瓶颈。 而reduce的方式是去除了参数服务器的存在,让每个GPU互相通信,他也分了map-reduce、all-reduce、ring-reduce、ring-allreduce等等。

https://zh.d2l.ai/chapter_computational-performance/parameterserver.html

image.png
image.png

        这里先介绍一下一些通信原语的概念,方便后面理解。 

image.png
image.png

        然后回到论文中来。         在allreduce中用的比较多的是蝶形算法。在没有网络竞争的情况下,这个算法在延迟和带宽中都是最优的,但是事实上,这种通信模式会导致在许多当代集群中产生网络竞争,如广泛部署的SMP/多核集群,因为这些集群往往共享了一些网络资源。 在没有网络竞争的情况下,蝶形算法之所以在延迟和带宽方面都表现最优,主要有以下几个原因:         1.对等通信模式: 蝶形算法采用了对等通信模式,即每个节点都与其他节点建立了直接连接。在没有网络竞争的情况下,节点之间的通信路径是独立的,不存在其他节点的干扰。这使得通信的延迟最小化,因为消息可以通过最短的路径尽快到达目标节点。         2.逐级通信: 蝶形算法通过多个通信阶段逐级地将数据进行聚合。每个阶段中,节点与距离它最近的节点进行通信,然后逐渐扩展到更远的节点。这种逐级通信方式使得数据的聚合过程更加高效,减少了通信的次数和总延迟。         3.负载平衡: 蝶形算法通过分阶段聚合数据,确保了在通信过程中负载的平衡。即使在节点之间的计算能力或带宽存在差异的情况下,蝶形算法仍能在通信过程中保持相对均衡的负载,最大限度地利用每个节点的计算资源。         4.带宽优化: 蝶形算法在每个阶段的通信中只传输部分数据,而不是直接传输全部数据。这样可以减少单次通信的数据量,从而更好地利用带宽资源。在没有网络竞争的情况下,节点之间的通信通常能够占用整个可用带宽,因此通过优化单次通信的数据量,蝶形算法可以最大程度地提高带宽利用率。         (蝶形全局求和的过程是,第一步将两个相邻的节点分作一组,互相通信他们的 sum,那么这个两节点小组的每个结点中的 sum 都是这个小组的局部和。第二步将四个节点分作一组,前半部分与后半部分相互通信,那么这个四节点小组的每个结点中的 sum 都是这个小组的局部和。循环进行这个步骤直到小组容量大于总进程数。)         而作者提出的基于环的方式,声称可以在几乎所有当代集群中实现无争用通信,并且可以需要比较少的内存需求,也不需要2的幂个节点。但它也存在一些问题,比如只在带宽上有优化;而且可能存在精度问题。这个精度问题是指,由于并行计算中涉及到浮点数运算,不同节点上进行计算的结果可能受到舍入误差的影响,因为不同节点对于浮点数计算的精度可能会有差异。此外,Ring算法虽然在中等规模的运算中非常有优势,较小的传输数据量,无瓶颈,带宽完全利用起来。不过在大型规模集群运算中,巨大的服务器内数据,极长的Ring环,Ring的这种切分数据块的方式就不再占优势。

1.png
1.png
2.png
2.png
3.png
3.png
1.png
1.png
4.png
4.png
5.png
5.png
6.png
6.png
7.png
7.png
8.png
8.png
9.png
9.png
10.png
10.png

        这篇论文很长,而且数学公式较多,我们就不看数学证明,直接来看他的实现流程。不过他对流程介绍的也少,所以又从网上找了一些资料过来。         所提的方法主要是结合了三种现有技术于一身。以下图为例,看一下他的执行流程。         首先将数据分为 N 个块,每个GPU负责1个块。         然后,第N个GPU发送第N个块,并接收第N-1个块。         ……         这么做有什么好处呢?         每个 GPU 在Scatter Reduce阶段,接收 N-1 次数据,N 是 GPU 数量;每个 GPU 在allgather 阶段,接收 N-1 次数据;每个 GPU 每次发送 K/N 大小数据块,K 是总数据大小;所以,每个GPU的Data Transferred=2(N−1)*K/N = (2(N−1)/N)*K,随着 GPU 数量 N 增加,总传输量恒定!(我的理解是,随着N变大,1/N不断减小,总传输量趋近于固定值?)总传输量恒定意味着通信成本不随 GPU 数量增长而增长,也就是说我们系统拥有理论上的线性加速能力。         allreduce的速度受到环中相邻GPU之间最慢(最低带宽)连接的限制。给定每个GPU的正确邻居选择,该算法是带宽最优的,并且是执行allreduce的最快算法(假设延迟成本与带宽相比可以忽略不计)。

image.png
image.png

        在Pytorch中有两种实现分布式数据并行训练的方式,分别是DP和DDP。DP由于只在主进程中管理多个任务和更新参数,因此其计算量和通讯量都很重,训练效率很低。         现在普遍用的较多的是DDP的方式,简单来讲,DDP就是在每个计算节点上复制模型,并独立地生成梯度,然后在每次迭代中互相传递这些梯度并同步,以保持各节点模型的一致性。         而在pytorch中的DDP实际就是使用了Ring-ALLReduce来实现AllReduce算法。         DDP的执行流程大致如下:         各个GPU首先进行环境初始化和模型的广播,使初始状态相同。然后初始化模型bucket和reducer。在训练阶段,通过采样获取数据,计算前向传播,然后进行反向传播和使用all-reduce进行梯度同步,最后完成参数的更新。         这里说明了allreduce是在前向传播完成后用于梯度同步的,并且提到了一个新词 bucket。         (模型参数以(大致)与给定模型 Model.parameters() 相反的顺序分配到存储桶中。使用相反顺序的原因是,DDP 期望梯度在向后传递期间大致按照该顺序准备就绪。)

image.png
image.png

        实际上,DDP中的设计是通过将全部模型参数划分为无数个小的bucket,然后在bucket级别建立allreduce。比如当所有进程中bucket0的梯度计算完成后就立刻开始通信,而此时bucket1中梯度还在计算。         这样可以实现计算和通信过程的时间重叠。这种设计能够使得DDP的训练更高效,可以在参数量很大时,获得很好的加速效果。

        简单总结一下前面的内容。         1、Pytorch中分布式训练用的比较多的是DDP;         2、DDP中的Allreduce使用的是ring-allreduce,并且使用bucket来引入异步;         3、Allreduce发生在前向传播后的梯度同步阶段,并且与反向传播计算重叠;         4、Ring-allreduce优化了带宽,适用于中规模的集群,但其可能存在精度问题,切不适合大规模的集群;         5、allreduce的速度受到环中相邻GPU之间最慢连接的限制;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
GPU 云服务器
GPU 云服务器(Cloud GPU Service,GPU)是提供 GPU 算力的弹性计算服务,具有超强的并行计算能力,作为 IaaS 层的尖兵利器,服务于深度学习训练、科学计算、图形图像处理、视频编解码等场景。腾讯云随时提供触手可得的算力,有效缓解您的计算压力,提升业务效率与竞争力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档