大模型只是一个占用显存比较大的深度学习模型,整体训练流程和以往的深度学习模型差别不大,因为占用显存过大,单GPU往往无法装下大模型整体,所以提出了切分大模型的模型并行训练方法,而并行就会涉及同步、单点失败后的恢复等种种问题,但是如今DeepSpeed、Megatron-LM等框架已经把并行训练流程封装得很干净了,大幅降低了开发门槛。要想了解针对大模型训练提出的方法,首先要回顾以往的模型训练流程。

一 模型训练

1 先导知识

1.1 训练数据如何加载到GPU

一份训练数据集最终一定是落到硬盘中进行存储的,当启动模型训练时:

1)CPU从硬盘读取需要训练的数据(batch)到内存

2)GPU通过PCIe总线从CUP内存读取数据到显存

一般情况下GPU是无法绕过CPU直接从硬盘读取训练数据到显存的。

上述过程的一些细节如下:

图片

图片

图片

什么是“页锁定内存”

图片

但是这种方式对GPU DMA不友好

图片

图片

为什么GPU无法绕过CPU直接对硬盘读写

图片

1.2 模型如何加载到GPU

以PyTorch定义神经网络模型,加载到GPU进行训练的过程为例

图片

图片

图片

图片

图片

图片

图片

我们使用PyTorch等深度学习框架编写神经网络模型时,其实反过来在这些深度学习框架眼中,我们是在向它们规定计算的顺序(如先对输入进行卷积、然后池化,这就是卷积神经网络某个卷积层的计算顺序),这些计算顺序会被深度学习框架抽象为“计算图”这种数据结构,图结构中边表示计算顺序流程、节点表示具体的计算操作,有了计算图就可以完成输入到输出前向传递过程(对应PyTorch的 def forward),以及自动梯度计算,完成反向传播更新参数过程(对应PyTorch的loss.backward)。计算图中每个计算节点对应的具体计算,框架会自动帮我们替换成底层硬件支持的操作,这个具体的操作就是平时常说的算子

图片

2 并行训练

并行训练(并发训练)指利用多个计算设备加速模型训练过程、突破单设备资源限制(如训练更大模型或使用更大 batch),主要分为数据并行和模型并行。

2.1 数据并行

数据并行(Data Parallelism, DP)中每个GPU 持有一份完整的模型副本,但处理的是不同的训练数据子集,计算完梯度后,同步所有 GPU 的梯度(All Reduce),再更新各GPU上的模型,保证最终模型一致。

图片

数据并行中的通信如下:

图片

图片

图片

图片

2.2 模型并行

模型并行(Model Parallelism, MP)用于突破设备显存限制,是训练超大规模模型的核心技术,数据并行解决“训练慢”,模型并行解决“模型大”的问题,二者并不相悖,工程上常搭配使用。模型并行将一个神经网络模型拆分为多个部分,这些部分分布到多个计算设备上,解决“模型太大,单卡放不下”的问题。

图片

3 训练过程

根据训练模型时使用的机器数量和显卡数量,模型训练可以分为单机单卡、单机多卡、多机单卡、多机多卡。

单机/多机:一台/多台有独立 CPU、内存、操作系统的物理机器实体(裸金属架构)、或者一个/多个运行着的镜像(云平台)

单卡/多卡:训练显卡的个数

下面以裸金属架构上机器的训练过程说明,云平台上训练过程同理。

3.1 单机单卡

这是我们刚接触深度学习训练时使用的基础方式,手中就有一台机器,这台机器上装载有一个显卡。

图片

图片

3.2 单机多卡

当我们需要训练的模型或者数据量变的越来越大时,我们发现单机单卡要么硬件资源跟不上,经常报显存溢出(OOM),或者训练的太慢了,项目截止日期前无法训练出来模型,这时候就会考虑为这台机器配备多张显卡,采取并行训练来解决这些问题。

单机多卡中我们常使用的是数据并行训练方式,将原先一个显卡装不下的batch数据,分发到多张显卡上同时进行训练,避免显存溢出,或者每个机器上还是原先的batch大小,但是多卡同时训练,缩短整体训练时间。

3.3 多机单卡

一旦涉及到多机,就要考虑多台机器之间通过网络进行通信的瓶颈问题,因为很可能机器上训练计算过程很快,一个小时就完成了,但是多台机器之间通过网络同步训练信息用了两个小时或者更久,这样的话所有机器上的计算资源都在闲置。

多机单卡一般现实场景下不常见,除非手中闲置的资源就是多台具有单个显卡的机器,将这些机器组合起来进行训练。或者是按需计费的云平台上训练,可以根据自己需要租显卡。

图片

InfiniBand (IB) 和 RoCE (RDMA over Converged Ethernet) 是现代高性能计算(HPC)、人工智能训练和大规模数据中心中用于低延迟、高带宽通信的两种核心技术。它们都基于 RDMA (Remote Direct Memory Access) 技术,旨在绕过操作系统内核和 CPU,实现网卡直连内存的高效数据传输。

RDMA(Remote Direct Memory Access)允许一台计算机直接读写另一台计算机的内存,无需对方 CPU 参与,也不经过操作系统内核协议栈。

图片

图片

图片

图片

图片

图片

3.4 多机多卡

多机多卡训练是当前大规模深度学习训练的工业标准架构,尤其在大模型训练中被广泛采用。它结合了单机内的高速互联(如 NVLink)与跨机的高性能网络(如 InfiniBand / RoCE),实现数百甚至数千块GPU的高效协同。并行训练策略通常结合数据并行+模型并行,同时解决训练慢+模型大的问题。

多机多卡训练中的通信分为机内通信和跨机通信

图片

图片

二 模型并行

2.1 流水线并行

既然单个显卡放不下大模型,最简单的想法就是将模型按照网络层进行拆分,然后将拆分出来的每部分放到不同显卡上,假设模型拆分为4部分,分别放到不同显卡上。

图片

图片

因为在前向传递过程中,当前网络层必须等前一个网络层产生输出,传递到当前网络层,当前网络层才能开始计算,所以层与层之间是串行的,反向传播同理

图片

可以画出来时序图如下:

图片

那么就有一个问题,Device1(对应上图Stage1)处理当前Batch0训练数据时,Device0是空闲的,同理Device2处理Batch0训练数据时,Device0、Device1都是空闲的,我们称这种空闲为气泡(bubble),计算资源被浪费。

如何减少气泡?最自然的想法是在上图t1的时候将Batch1输入给Device0,让Device0开始处理下一批次数据,这样就可以避免设备空闲。但是这种方式存在以下问题:

1)继续爆显存:我们最初的问题就是模型太大,一个显卡显存装不下,这样才进行分割的,显卡训练模型时除了要存储模型参数,还要存储激活值、优化器状态等参数,一个Batch0的中间参数显卡可能勉强能存储下,再加一个Batch1相关信息的存储,很有可能继续爆显存

2)退一步,假设显存能够同时存储下Batch0,Batch1等批次的中间参数数据,通信呢?同时传递多个这样batch的信息,训练集群的网络是否能支撑

3)模型必须等一个batch完全反向传播完,更新完最新的参数后,才能计算下一个batch的训练数据,这样才是训练语义上正确的,现在没等一个batch反向更新完参数,就计算下一个batch,训练语义不正确,而且即使正确,需要同时考虑多个batch的状态,哪个batch完成了前向?哪些batch完成了反向?哪些梯度可以累积了?开发起来会非常复杂

那么应该如何减少气泡呢?

正确的做法是将一个batch进行切分为多个子集(流水线并行原论文中称原始的batch为‘mini batch’,切分出来的子集是‘micro batch’),依次输入这些切分出来的子集到Device0中,子集1在Device0完成前向传递后,Device0可以继续前向传递子集2...,当子集1在Device3完成前向传递后,开始进行子集1的反向传播,但是针对子集的反向传播,只是记录梯度的信息,不真正更新模型的参数,等待所有子集都完成反向传播后,再累加到一起,用整体的梯度信息更新模型参数,这样训练语义上是和batch等同的,还避免了设备空闲,减少了气泡(没完全减少,中间还是存在等待计算结果过程的设备空闲,但是可以通过增加子集数量的大小,大幅缩减气泡的大小)

图片

图片

图片

图片

但是流水线并行对于BN不友好,因为BN需要mini-batch整体的信息,但是现在每个显卡可见的只是micro-batch的,所以采取累计信息、最终汇总的方式进行解决。但是语言大模型一般使用的是LN,所以BN问题也不用考虑。

图片

2.2 张量并行

流水线并行解决的是一个大模型单卡放不下,这时候可以将这个大模型沿着不同网络层进行切分,切出来的每部分放到不同显卡上,联合起来进行训练。

张量并行解决的是:如果切出来的每部分,单卡还是放不下该怎么办?也就是说哪怕现在已经按照一层一层的切分大模型了,每个单独的网络层显卡还是放不下,还是爆显存。

我们知道,每个模型层在数学上对应的就是一个矩阵,矩阵中的数值称作参数,其具体数值是通过训练过程逐步得到的,模型层的计算对应着矩阵乘法。那么由矩阵分块乘法的性质可知,我们可以想办法将大矩阵分成小矩阵块,多个小矩阵块的乘法结果就是最终的大矩阵乘法结果,对应到张量并行训练就是:

图片

图片

在张量并行(Tensor Parallelism, TP)中,按行切分(row-wise)还是按列切分(column-wise)并非随意选择,而是由模型层矩阵乘法的计算顺序、通信开销最小化、以及激活值显存优化共同决定的,其背后有一套清晰的设计规则。

图片

图片

图片

图片

图片

图片

原论文中的张量并行示意图如下

图片

三 ZeRO

ZeRO进一步分析显存到底浪费在了哪里。

数据并行是显存浪费比较严重的,在数据并行中,每个显卡都需要存储完整的模型参数,每个显卡独立的对输入到自己这张显卡中的数据进行前向传播,得到的只是自己显卡中这部分数据对应的梯度,但是模型反向传播使用的是全局梯度,需要将自己的梯度和其它显卡的梯度求平均,才是全局梯度,但是以往的做法是每个显卡都存储一份全局梯度,全局梯度是唯一的,但是被存储了多次,这就是一种显存浪费,因为Adam优化器是Eelement-wise的,可以独立的进行部分参数优化,我们可以将全局梯度进行分片,分别存储到不同显卡上,然后不同显卡只使用分配到的梯度更新自己对应的那一部分参数,所有显卡更新完自己那部分参数后,通过网络通信汇总所有更新,这样就得到了完整的模型参数更新,但是因为每个显卡只存储一部分全局梯度,显存占用大幅减少

图片

图片

图片

图片

图片

图片

图片

图片

四 高效微调

大模型参数高效微调(Parameter-Efficient Fine-Tuning, PEFT)指的是在不训练大模型全部参数的条件下,如何让大模型的效果达到最优。

4.1 Prefix tunning

Prefix-Tuning是参数高效微调领域的奠基性工作之一,与 Prompt Tuning、LoRA 并列为大模型轻量化适配的三大经典方法。

图片

图片

只训练这些后插入的Prefix参数就可以达到整体模型微调的效果

图片

图片

图片

4.2 Prompt tunning

Prompt tunning由Google Research团队发表

图片

图片

图片

越大的Base模型,Prompt tunning效果越好

图片

图片

图片

4.3 LoRA

LoRA(Low-Rank Adaptation)是目前最主流、最实用的参数高效微调方法,由Microsoft 在 2021 年提出。它的核心思想是:通过低秩矩阵分解的方式,在不修改原始大模型权重的前提下,仅训练少量额外参数,即可高效适配下游任务。LoRA 因其简单、通用、高效、推理无损等优点,已成为大模型微调的事实标准,被广泛应用于 LLaMA、ChatGLM、Qwen、Stable Diffusion 等各类模型中。

图片

图片

图片

图片

原论文中的示意图如下

图片

为了控制LoRA的更新,在更新权重前用α/r进行缩放

图片

图片

图片

图片

更多推荐