图解大模型训练之:数据并行上篇(DP, DDP与ZeRO)

在上一篇的介绍中,我们介绍了以google gpipe为代表的流水线并行范式。当模型太大,一块gpu放不下时,流水线并行将模型的不同层放到不同的gpu上,通过切割mini-batch实现对训练数据的流水线处理,提升gpu计算通讯比。同时通过re-materialization机制降低显存消耗。
但在实际应用中,流水线并行并不特别流行,主要原因是模型能否均匀切割,影响了整体计算效率,这就需要算法工程师做手调。因此,今天我们来介绍一种应用最广泛,最易于理解的并行范式:数据并行。
数据并行的核心思想是:在各个gpu上都拷贝一份完整模型,各自吃一份数据,算一份梯度,最后对梯度进行累加来更新整体模型。理念不复杂,但到了大模型场景,巨大的存储和gpu间的通讯量,就是系统设计要考虑的重点了。在本文中,我们将递进介绍三种主流数据并行的实现方式:
dp(data parallelism) :最早的数据并行模式,一般采用参数服务器(parameters server)这一编程框架。实际中多用于单机多卡ddp(distributed data parallelism) :分布式数据并行,采用ring allreduce的通讯方式,实际中多用于多机场景zero :零冗余优化器。由微软推出并应用于其deepspeed框架中。严格来讲zero采用数据并行+张量并行的方式,旨在降低存储。本文将首先介绍dp和ddp,在下一篇文章里,介绍zero。全文内容如下:
1、数据并行(dp)
1.1 整体架构1.2 通讯瓶颈与梯度异步更2、分布式数据并行(ddp)
2.1 图解ring-allreduce2.2 dp与ddp通讯分析推荐阅读:
图解大模型训练之:流水线并行,以gpipe为例
一、数据并行(dp)1.1 整体架构
一个经典数据并行的过程如下:
若干块 计算gpu ,如图中gpu0~gpu2;1块 梯度收集gpu ,如图中allreduce操作所在gpu。在每块计算gpu上都拷贝一份完整的模型参数。把一份数据x(例如一个batch)均匀分给不同的计算gpu。每块计算gpu做一轮fwd和bwd后,算得一份梯度g。每块计算gpu将自己的梯度push给梯度收集gpu,做聚合操作。这里的聚合操作一般指 梯度累加 。当然也支持用户自定义。梯度收集gpu聚合完毕后,计算gpu从它那pull下完整的梯度结果,用于更新模型参数w。更新完毕后,计算gpu上的模型参数依然保持一致。聚合再下发梯度的操作,称为allreduce。前文说过,实现dp的一种经典编程框架叫“参数服务器”,在这个框架里,计算gpu称为worker,梯度聚合gpu称为server。在实际应用中,为了尽量减少通讯量,一般可选择一个worker同时作为server。比如可把梯度全发到gpu0上做聚合。需要再额外说明几点:
1个worker或者server下可以不止1块gpu。server可以只做梯度聚合,也可以梯度聚合+全量参数更新一起做 在参数服务器的语言体系下,dp的过程又可以被描述下图:
1.2 通讯瓶颈与梯度异步更新dp的框架理解起来不难,但实战中确有两个主要问题:
存储开销大 。每块gpu上都存了一份完整的模型,造成冗余。关于这一点的优化,我们将在后文zero部分做讲解。通讯开销大 。server需要和每一个worker进行梯度传输。当server和worker不在一台机器上时,server的带宽将会成为整个系统的计算效率瓶颈。我们对通讯开销再做详细说明。如果将传输比作一条马路,带宽就是马路的宽度,它决定每次并排行驶的数据量。例如带宽是100g/s,但每秒却推给server 1000g的数据,消化肯定需要时间。
人类老板不愿意了:“打工系统里不允许有串行存在的任务!”,于是梯度异步更新这一管理层略诞生了。
上图刻画了在梯度异步更新的场景下,某个worker的计算顺序为:
在第10轮计算中,该worker正常计算梯度,并向server发送push&pull梯度请求。但是,该worker并不会实际等到把聚合梯度拿回来,更新完参数w后再做计算。而是直接拿旧的w,吃新的数据,继续第11轮的计算。 这样就保证在通讯的时间里,worker也在马不停蹄做计算,提升计算通讯比 。当然,异步也不能太过份。只计算梯度,不更新权重,那模型就无法收敛。图中刻画的是延迟为1的异步更新,也就是在开始第12轮对的计算时,必须保证w已经用第10、11轮的梯度做完2次更新了。参数服务器的框架下,延迟的步数也可以由用户自己决定,下图分别刻划了几种延迟情况:
(a) 无延迟(b) 延迟但不指定延迟步数 。也即在迭代2时,用的可能是老权重,也可能是新权重,听天由命。(c) 延迟且指定延迟步数为1 。例如做迭代3时,可以不拿回迭代2的梯度,但必须保证迭代0、1的梯度都已拿回且用于参数更新。总结一下, 异步很香,但对一个worker来说,只是等于w不变,batch的数量增加了而已,在sgd下,会减慢模型的整体收敛速度。 异步的整体思想是,比起让worker闲着,倒不如让它多吃点数据,虽然反馈延迟了,但只要它在干活在学习就行。
batch就像活,异步就像画出去的饼,且往往不指定延迟步数,每个worker干越来越多的活,但模型却没收敛取效。读懂分布式训练系统其实也不难。
二、分布式数据并行(ddp)受通讯负载不均的影响, dp一般用于单机多卡场景 。因此,ddp作为一种更通用的解决方案出现了,既能多机,也能单机。ddp首先要解决的就是通讯问题:将server上的通讯压力均衡转到各个worker上。实现这一点后,可以进一步去server,留worker。
前文我们说过,聚合梯度 + 下发梯度这一轮操作,称为allreduce。 接下来我们介绍目前最通用的allreduce方法:ring-allreduce 。它由百度最先提出,非常有效地解决了数据并行中通讯负载不均的问题,使得ddp得以实现。
2.1 ring-allreduce如下图,假设有4块gpu,每块gpu上的数据也对应被切成4份。allreduce的最终目标,就是让每块gpu上的数据都变成箭头右边汇总的样子。
ring-allreduce则分两大步骤实现该目标: reduce-scatter和all-gather 。
reduce-scatter定义网络拓扑关系,使得每个gpu只和其相邻的两块gpu通讯 。每次发送对应位置的数据进行 累加 。每一次累加更新都形成一个拓扑环,因此被称为ring。看到这觉得困惑不要紧,我们用图例把详细步骤画出来。
一次累加完毕后,蓝色位置的数据块被更新,被更新的数据块将成为下一次更新的起点,继续做累加操作。
3次更新之后,每块gpu上都有一块数据拥有了对应位置完整的聚合(图中红色)。此时,reduce-scatter阶段结束。进入all-gather阶段。目标是把红色块的数据广播到其余gpu对应的位置上。
all-gather如名字里gather所述的一样,这操作里依然按照“相邻gpu对应位置进行通讯”的原则,但对应位置数据不再做相加,而是直接替换。all-gather以红色块作为起点。
以此类推,同样经过 3轮迭代后 ,使得每块gpu上都汇总到了完整的数据,变成如下形式:
建议读者们手动推一次,加深理解(注:最后一图箭头画错,公众号不许修改
2.2 ring-allreduce通讯量分析假设模型参数w的大小为,gpu个数为。则梯度大小也为,每个梯度块的大小为。
对单卡gpu来说:
reduce-scatter阶段,通讯量为all-gather阶段,通讯量为总通讯量为,随着n的增大,可以近似
而对前文的dp来说,它的server承载的总通讯量也是。 虽然通讯量相同,但搬运相同数据量的时间却不一定相同 。ddp把通讯量均衡负载到了每一时刻的每个worker上,而dp仅让server做勤劳的搬运工。当越来越多的gpu分布在距离较远的机器上时,dp的通讯时间是会增加的。
但这并不说明参数服务器不能打(有很多文章将参数服务器当作old dinosaur来看)。事实上,参数服务器也提供了多server方法,如下图:
在多server的模式下,进一步,每个server可以只负责维护和更新某一块梯度(也可以某块梯度+参数一起维护),此时虽然每个server仍然需要和所有worker通讯,但它的带宽压力会小非常多。经过调整设计后,依然可以用来做ddp。虽然这篇文章是用递进式的方式来介绍两者,但不代表两者间一定要决出优劣。 我想表达的观点是,方法是多样性的 。对参数服务器有兴趣的朋友,可以阅读参考的第1个链接。
最后,请大家记住ring-allreduce的方法,因为在之后的zero,megatron-lm中,它将频繁地出现,是分布式训练系统中重要的算子。
三、总结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需要耗费更多的时间搬运数据。


电压增益怎么计算?电压增益的定义?电压增益表达式
苹果CEO库克去年薪酬超1400万美元 身家突破10亿美元
诺基亚500港行即将开卖 或售1600元
一台蚂蚁矿机一天能挖多少比特币
台积电追逐全球晶圆代工霸主地位
图解大模型训练之:数据并行上篇(DP, DDP与ZeRO)
圣邦微电子荣获2023“全球电子成就奖”两项提名
利用RFID技术实现仓管人员提货的自动化管理方案
数字示波器介绍_数字示波器操作规程
魔视智能荣获北汽重卡「B-MARK认证优质供应商」称号
开放性硬件趋势能否蔓延至芯片领域?
光伏电池数学模型概述
NAND Flash下游库存水位大幅降低 为涨价带来了新的契机
航天电器林泉电机与华为联合举办“2022·第二届精密微特电机技术论坛”胜利召开
广和通5G R16模组FM160-EAU获得澳洲主流运营商Telstra认证
中兴“无芯”之痛过后,中国智能语音操作系统落地速度快过硅谷
中国智能产业区域竞争力指数,上海远不及北京
什么是接口?为什么要做接口测试
鸿蒙系统基于linux来开发研发的原因
升压变压器在光伏发电系统中的作用