费曼说:学习一件事情最好的方式是做它的老师,这也是写这篇博文的目的,写这篇博文,即便有其他原因,但更多的还是写给自己,话不多说,让我们开始进入大模型吧
任务说明:任务说明
基座课程:斯坦福大学大规模语言模型课程
本次讲到的内容是大模型的分布式训练,首先讲的是训练大模型的原因,接着是几种训练大模型的分布式计算的策略
9.1 为什么分布式训练越来越流行
用一张图就可以解释:
图表 1:该图表展示了,目前 SOTA 模型训练的浮点数运算量(以 FLOPs为衡量单位)。蓝线上的是 CV,NLP和语音模型,模型运算量平均每两年翻 15 倍,红线上的是 Transformer 的模型,模型运算量平均每两年翻 750 倍。而灰线则标志摩尔定律下内存硬件大小的增长,平均每两年翻 2 倍。
这张图显示了大模型与日俱增的参数增长的趋势。
下面来说一下内存墙:内存墙问题不仅与内存容量大小相关,也包括内存的传输带宽。这涉及到多个级别的内存数据传输。例如,在计算逻辑单元和片上内存之间,或在计算逻辑单元和主存之间,或跨不同插槽上的不同处理器之间的数据传输。上述所有情况中,容量和数据传输的速度都大大落后于硬件的计算能力。
那么如果是分布式的策略使用多个AI硬件呢,这其实是另一种形式的内存墙,显卡间的通讯肯定是要比片上通信更慢的(缓存不同)
如图表4所示,其中展示了在过去20年中,硬件的峰值计算能力增加了90,000倍,但是内存/硬件互连带宽却只是提高了30倍。而要增加内存和硬件互连带宽[1],需要克服非常大的困难。因此,分布式策略的横向扩展仅在通信量和数据传输量很少的情况下,才适合解决计算密集型问题。
这就引出了分布式训练策略的问题:有以下几种策略:优化算法、参数剪枝、还有就是硬件方面“用算力换缓存”的操作。
下面主要简述一下训练的分布式训练算法问题,实际上还是一种任务分配的问题,在软件工程系列导论书中《人月神话》中谈到的一个观点就是,一个人完成一项软件工程开发的时间并不等于十个人开发同样规模软件的时间,因为人与人之间的通信等就需要大量时间,还有队伍中人与人间协同的问题,实际的效率必然是相对减少的,单纯的按数学的方式用人·月的方式来机械地计算工程时间是一个可以逼近但永远都不可能实现的定律。同样,Ai训练中多张显卡也是。
9.2 常见的并行策略
单纯的算法堆叠带不来算力的线性增长,因为中间的通信过程是耗时的,但是,好的分布式策略能够让我们不断逼近同等算力一张卡的数值
所谓分布式,主要就是一个分配的问题:分配什么、怎样分配、这样的分配方式是否有效,这都是大模型的从业人员去需要考虑的问题。
常见的分配策略有:数据并行、数据串行、流水并行等
9.2.1 数据并行
所谓数据并行,就是将数据进行切分,分配给不同的设备进行训练,同时,为了解决训练中反向传播过程中计算的梯度不一至的问题,我们还需要对梯度进行一定的调整,AllReduce。
下面是AllReduce介绍:全部归约
AllReduce 操作是对跨设备的数据(例如 sum、min、max)进行约简,并将结果写入每个Rank 的接收缓冲区。
在 k 列之间的 allreduce 操作中并执行求和,每个列将提供一个包含 N 个值的数组 Vk,并接收一个包含 N 个值的相同数组 S,其中 S[i] = V0[i]+V1[i]+… +Vk-1[i]。
同时,适用的场景是小模型,且数据量较大的训练,如视觉分类任务
9.2.2 模型并行
与数据并行相反:适用于大模型,而数据量小的场景,如BERT
优势在于不需要对模型参数进行AllReduce操作,缺点是需要对数据进行广播的操作
9.2.3 流水并行
简而言之,因为大模型有多层,可以将不同层之间进行任务的分包,不同层之间分包给不通透的机器进行计算,输出作为下一层的输入。可以在多个处理单元上同时执行不同的阶段,从而充分利用计算资源,提高计算效率。它适用于一些具有明显的阶段性和依赖关系的任务,例如图像和视频处理、信号处理、编译器优化等。
在流水线中,每个阶段的处理时间应该尽量相等,以避免某个阶段的处理速度成为整个流水线的瓶颈。如果某个阶段的处理时间较长,会导致整个流水线的效率下降,因为后续阶段需要等待前一阶段的计算结果。
流水并行的优点包括高效利用计算资源、降低响应时间、提高系统吞吐量等。然而,它也面临一些挑战,如阶段之间的数据依赖关系、负载均衡、流水线的冲突和调度等问题,需要合理的任务划分和调度策略来解决。
9.2.4 混合并行
简而言之,GPT的混合并行的训练策略是流水并行的每个阶段中进行数据并行,符合前面讲到的语言处理大模型适用的数据并行策略:
任务被分为64个阶段,采用流水并行的方式进行处理。每个阶段在6台DGX-A100主机上并行执行,这是共享内存并行的一种形式。而在6台主机之间,采用数据并行的方式进行训练,即每台主机上的8张GPU显卡同时处理不同的数据。同时,在同一台机器上的8张GPU显卡之间进行模型并行训练,即将模型划分为多个部分,每个GPU负责处理其中的一部分。通过这种混合并行的方式,可以充分利用多台主机和多个GPU的计算资源,提高训练的效率和性能。
混合并行是一种并行计算策略,结合了共享内存并行和分布式内存并行,以充分利用多种计算资源来提高计算效率和性能。它通过在单个计算节点内部使用共享内存并行和在多个计算节点之间使用分布式内存并行来并行执行任务。混合并行能够处理大规模数据和复杂任务,并在高性能计算、科学计算和数据分析等领域广泛应用。
参考链接:Collective Operations — NCCL 2.18.1 documentation (nvidia.com)