大规模训练:稳定性与分布式并行
前面几章的架构选择,只有在训练能够执行时才算数。一个前沿模型放不进单张加速器,而产出它的那次训练,会横跨数千张加速器、连续运行数周。一旦把工作切到这么多设备上,三种资源就开始相互角力:每个分片必须持有的显存、维持各分片一致所需的通信,还有这种规模的机群把故障当成常态后产生的故障恢复成本。训练系统要做的,就是在三者之间反复权衡,让达成的吞吐保持高位,让一张失效 GPU 的代价是几分钟,而不是几天。贯穿这一层的记分牌是模型 FLOPs 利用率(MFU):通信、气泡、重算和故障各自分走一块之后,机器还有多少时间真正在做有效的模型计算。
相互角力的三种力量
接下来的一切,都由两个事实决定:一个前沿模型的参数、梯度与优化器状态,放不进单张设备的显存;训练它所需的算术,也无法在单张设备上以任何能接受的时间完成。于是工作被切到数千张加速器上,而一旦切开,三个约束便开始相互制约。
第一个是显存。权重、占主导地位的 Adam 矩估计状态(即优化器为每个权重维护的梯度滑动平均,见 第 5 章)、激活(前向传播时保存、留给反向传播使用的中间值)与梯度,全都得各有去处,而峰值激活显存还随序列长度往上涨。第二个是通信。每一次切分都引入一份用来维持各分片一致的流量,这份流量又和计算抢同一份时间预算。第三个是故障。在数千个节点上连跑数周,一张失效的 GPU 或网卡是常态,而非例外,单单一个就足以让整个集合通信失败。训练系统层的职责,就是把显存、通信与恢复三者拿来彼此权衡,让达成的吞吐保持高位,让一次故障的代价是几分钟,而不是几天。没有哪一种单一切法能同时解决这三者,所以设计里给出了好几种正交的切法,再把它们组合起来用。
四种切法,以及各自的代价
每个轴回答一个不同的扩展问题、切分一种不同的资源,而且都是在上一代遇到某个限制时才进入文献的。按这个顺序读下来,它们并不是一份简单菜单,而是一份记录,记下这套工具箱怎样逐步形成。
张量并行(TP)先切开单层内部的矩阵乘法:把注意力头和前馈网络的列与行分散到各设备上。Megatron-LM 展示了怎样靠每层仅两次 all-reduce 做到这件事,让一个数十亿参数的模型在放不下单张设备之后仍然可以训练 (Shoeybi et al. 2019)。代价是它通信密集:每个 TP 层都要在每一次前向与反向的关键路径上做一次 all-reduce(或者一对 reduce-scatter 与 all-gather)。这笔开销只有在最快的互连上才用得起,所以 TP 通常限制在节点内。
流水线并行(PP)几乎同期出现,切掉的是另一种资源。它把层栈拆成若干阶段、摆到不同节点上,再让微批一个个流式穿过,于是第二阶段处理第一个微批时,第一阶段已经在处理第二个微批了。GPipe 确立了让各阶段不闲着的微批化做法 (Huang et al. 2019),PipeDream 又把调度推广开来,进一步压缩气泡 (Narayanan et al. 2019)。PP 在带宽上很省,只搬运各阶段边界处的激活,但要付出流水线气泡的代价:每一步两端的填充与排空期间,总有一些阶段空着。图 10.1 画出了这段空闲时间落在哪里。
数据并行(DP)把模型复制开来,再把批切到各副本上;每个副本在自己那一份切片上算梯度,最后由一次 all-reduce 求平均。朴素的 DP 并不省显存,因为每个副本都保存一份完整的拷贝。零冗余优化器(ZeRO) 注意到,标准 DP 里的优化器状态、梯度和参数是被冗余复制的,于是把它们沿 DP 组分三个递进阶段切开 (Rajbhandari et al. 2019);ZeRO-Infinity 进一步把这一思路扩展到卸载至 CPU 与 NVMe (Rajbhandari et al. 2021),而 PyTorch 全分片数据并行(FSDP) 则是同一全分片思路的原生版本,只在某层真正运行时才聚合那层权重 (Zhao et al. 2023)。切分能在不改动数学的前提下压低每设备显存:某一层的参数,要用之前才 all-gather 取回,用完立刻释放。这正是 第 5 章 指出优化器状态是占主导的显存项时,所指向的那种切分。
*序列与上下文并行(SP/CP)*沿序列维度切分,激活显存恰好就落在这根轴上。SP 把一层里被 TP 留作复制的那些部分,也就是归一化和 dropout,沿序列切开,以削减激活显存;它和选择性重算一并引入,后者只重做那些重做廉价、却占显存大的算子,而不是整层 (Korthikanti et al. 2022)。CP 的典范形式是 ring attention,它切分的是注意力计算本身,让一段对单张设备来说过长的上下文,能拆成若干块来处理,键与值的瓦片绕着环传递,上下文于是几乎可以无界地增长 (Liu et al. 2023)。
对每个轴,要问的设计问题都一样:它切分什么、通信成本是多少、用得起互连里的哪一层级。图 10.2 把这些答案并排摆开。
混合专家(MoE)层添了第五种切法。专家被切到各设备上,每个词元经一次 all-to-all 集合通信派发给它选中的专家,再由第二次 all-to-all 把结果合并回来,这套派发模式可追溯到 GShard (Lepikhin et al. 2020)。系统层只讨论这部分执行:每个 MoE 层的两次 all-to-all 交换、某个热门专家吸走超出份额的词元时引发的负载不均和掉队节点、用来给每个专家工作量设上限的容量填充,以及把派发和合并跟专家计算重叠起来。产生这套流量模式的路由决策和负载均衡损失,则留给 第 9 章。
以位宽为代价:精度轴
算术不是非在 fp32 下跑不可。混合精度把前向和反向的矩阵乘法及激活留在 bf16,同时保有一份 fp32 的主权重副本和 fp32 的优化器状态,这样微小的更新加到一个大权重上时才不至于消失,这套配方由 Micikevicius 等确立 (Micikevicius et al. 2017)。bf16 更宽的指数位正是它安全的根源:它免掉了 fp16 为把梯度推离其狭窄范围下限而需要的损失缩放(把梯度整体放大,使其中的小值不致下溢)。
fp8(即 E4M3 与 E5M2 格式)在 Hopper 级及更新的硬件上,把矩阵乘法又往前推了一步,大致让矩阵乘法吞吐翻倍、让操作数占的显存减半;那篇格式论文为支持 fp8 矩阵乘法的那一代硬件,定义了 E4M3 与 E5M2 (Micikevicius et al. 2022)。代价在范围上:fp8 的指数位实在太少,操作数必须逐张量、甚至更细地重新缩放,才能把数值压在可表示的区间里。它的用法是有选择的,矩阵乘法走 fp8,而那些数值敏感的算子,也就是归一化、残差相加和注意力 softmax,仍留在更高精度上。用得过度时,fp8 不会崩溃,它只是悄悄折损质量,这正是它难以用好的地方。
这条边界后来又往下挪了。2024 年底,DeepSeek-V3 用 fp8 矩阵乘法完成了前沿规模的训练,证明这个格式撑得起一次完整的预训练 (DeepSeek-AI 2024)。活跃的边界如今在四位。NVFP4 与 MXFP4 这类 fp4 格式是微缩放(microscaling)格式:数值本身只存四位,每一小块(十六或三十二个数)另带一个自己的缩放因子,在局部补回四位装不下的范围,而 Blackwell 级硬件原生支持四位矩阵乘法。NVIDIA 已用 NVFP4 在十万亿词元上训练一个 12B 模型,追平 fp8 基线,靠 Hadamard 变换与随机舍入让这个狭窄格式不产生偏差 (NVIDIA 2025);四位训练靠哪些设计才能站得住,这一设计空间也正被系统梳理 (Hu et al. 2025)。这场押注的硬件一面,也就是计算前沿为何想要更少的操作数字节,是 第 66 章 的主题。
图 10.4 说明了指数位为何要紧。bf16 保留了 fp32 的八个指数位,所以跨越的动态范围一样,从来不需要 fp16 那种损失缩放;而 fp8 只能把寥寥几位,分给范围(E5M2)与精度(E4M3)之间的取舍。fp4 的 E2M1 布局已经到底:一位尾数、两位指数,其余全靠逐块的缩放因子来承担。
掩盖流量
上面每一种切法都产生流量,而这些流量都走一小组集合通信:all-reduce、reduce-scatter、all-gather 与 all-to-all。NCCL(在 AMD 上叫 RCCL)实现这些通信,并各自映射到拓扑上,挑选环算法还是树算法,在节点内经 NVLink、在节点间经网络来路由 (NVIDIA 2024)。
集合通信纯属开销,除非它们能趁设备忙于别的计算时一起跑,所以重叠是吞吐的核心手段。FSDP 在当前层计算时,用一次 all-gather 预取下一层的参数 (Zhao et al. 2023)。梯度的 reduce-scatter 折进反向传播,PP 通信折进阶段计算,EP 的 all-to-all 折进专家矩阵乘法。无法掩盖的部分,就是暴露的通信,会直接表现为吞吐下降。
MFU是衡量重叠有没有奏效的记分牌。它等于达成的 FLOPs 除以硬件峰值 FLOPs,只计入模型在数学上真正需要的那些 FLOPs。它和 HFU(硬件 FLOPs 利用率)不是一回事,后者还把激活重算的冗余 FLOPs 也算进去,所以只要开了重算,HFU 就会超过 MFU。MFU 是判定系统层实现是否到位的核心数字,它的预算是一组损失项之和:暴露的通信、流水线气泡、重算和未融合的内核各分走一块。MFU 偏低,要靠每步的时间线来诊断,而不是看损失曲线。它是贯穿整章的共同指标,因为每一种切法、每一个精度选择,最终都在这里被记分。
训练精度能压到多低,至今没有定论,但问题的前沿已经下移。bf16 是保守的默认值;自 DeepSeek-V3 用 fp8 撑过一次前沿规模的训练之后,fp8 成了主力 (Micikevicius et al. 2022; DeepSeek-AI 2024);活跃的边界如今是 fp4,NVFP4 一类微缩放格式加上 Blackwell 的原生四位矩阵乘法,吞吐收益明确,但配方还年轻 (NVIDIA 2025; Hu et al. 2025)。每一级上的分歧都相同:哪些算子可以下移、缩放得做到多细,以及一次训练能撑过多少万亿词元,才不至于因范围收窄而折损最终质量。让这件事难以靠经验判断的,正是它的失效方式:精度推得太远不会崩溃,而是悄悄劣化模型,于是代价在一次靠后的评估之前都是隐形的。把这条边界当成一个逐算子、逐配方、必须验证的选择,别当成一个能照搬的设定。
互连决定并行布局。张量并行要在每一层的关键路径上做一次 all-reduce,这只有在最快的链路上才用得起,所以 NVLink 域的大小,就划定了最大的 TP 组;一旦越界,TP 流量便跨上网络,整体吞吐会迅速下降 (Shoeybi et al. 2019)。搬运更少、又能把通信藏起来的流水线并行与数据并行,才是跨节点的那两根轴,而专家并行另有自己的 all-to-all 组。所以 第 62 章 那套带宽层级,位于本章每一个网格决策的上游:底层的线缆,决定了上层能在哪里用上哪种切分。
调整各项参数
每个轴消耗一种不同的资源,最终胜出的布局,是对某个特定模型形态、在某个特定互连上,能把最多通信藏到计算之下的那一个。到 2021 年,各轴开始被刻意组合:PTD-P 那项工作把数据、张量与流水线并行作为一个组合的 3D 布局,映射到单个 GPU 集群上,确立了前沿训练至今仍沿用的排序 (Narayanan et al. 2021)。下面这些参数,正是工程师在那套布局里实际需要调整的。
- 并行布局,以及它不可移植。 TP 削减每设备显存和延迟,却消耗节点内带宽,所以它以 NVLink 域为上限。PP 在带宽上廉价,却要付出流水线气泡,可以靠更多微批和交错调度来缓解 (Narayanan et al. 2019),不过一旦气泡已经很小,再加就收益递减(图 10.5)。DP 和 ZeRO 把批扩大,但优化器状态分片和 all-gather 流量会随 DP 度增长 (Rajbhandari et al. 2019)。对的布局并不通用:换个模型规模、换个序列长度或者换个集群,最优点就挪了位。
把这个精确公式运行一遍,亲眼看看收益递减:改改阶段数或微批的取值范围,看看曲线在哪儿趋平。
import numpy as np
import matplotlib.pyplot as plt
m = np.arange(1, 33) # 每步微批数
for p in [4, 8, 16, 32]: # 流水线阶段数
bubble = (p - 1) / (m + p - 1)
plt.plot(m, bubble, marker="o", markersize=3, label=f"p={p} 个阶段")
print("p=8 个阶段:", {int(mm): round((8 - 1) / (mm + 8 - 1), 3) for mm in [1, 4, 8, 16, 32]})
plt.xlabel("每步微批数 m")
plt.ylabel("流水线气泡占比")
plt.title("气泡占比 (p-1)/(m+p-1)")
plt.legend()
plt.grid(alpha=0.3)
plt.show()
- 显存换计算。 激活与梯度检查点,用反向传播里额外的前向 FLOPs,换更低的峰值激活显存。选择性重算只重做那些廉价、却占显存大的算子 (Korthikanti et al. 2022)。重算越多,就越能塞下 更大的模型或更长的序列,代价是 MFU,这正是开启重算时 HFU 超过 MFU 的缘由。
- 精度换稳定性。 bf16 是安全的默认值,而 fp32 主权重对优化器来说没有商量余地 (Micikevicius et al. 2017)。fp8 是经过验证的主力:换来吞吐与显存,却收窄范围,所以要配上逐张量或更细的缩放来用,并避开敏感算子 (Micikevicius et al. 2022; DeepSeek-AI 2024)。 fp4 是活跃的边界,只有靠逐块缩放和最新的硬件才用得起 (NVIDIA 2025)。无论哪一级,推得太远,得到的都是静默的质量损失,而不是崩溃。
- 检查点频率。 检查点越频繁,每次故障丢掉的工作量就越小,但会加重存储带宽负担,还可能把训练拖停。异步与切分检查点,是让高频率变得可承受的机制,而最优值取决于集群的平均无故障时间和写入 成本 (Mohan et al. 2021)。
布置一次真实的训练,以及它如何失败
组合各轴
一次前沿训练,会把设备网格映射成各轴之积,惯例写作(DP x TP x PP),碰上 MoE 再添个 EP,并把 SP 叠在 TP 之上。排序的经验法则,直接来自这条下层约束和 PTD-P 的结果:把 TP 放在节点内的 NVLink 之下,把 PP 和 DP 放到节点间,因为它们更廉价的通信更容易被隐藏,再给 EP 自己的 all-to-all 组 (Narayanan et al. 2021)。布局要和 第 8 章 与 第 9 章 给出的模型形态协同设计,并随模型规模、序列长度与互连而变。
图 10.7 勾勒了惯常的摆法。
框架
各框架的差别,主要在于谁让哪种布局、哪种硬件用起来更顺手。Megatron-LM 与 Megatron-Core 在 NVIDIA 技术栈上承载 TP、PP、SP 与 EP (Shoeybi et al. 2019)。DeepSpeed 把 ZeRO 和卸载整合在一起 (Rajbhandari et al. 2019)。PyTorch FSDP 是原生的切分 DP (Zhao et al. 2023)。JAX 与 XLA 在 TPU 上把切分写成 GSPMD 风格的注解,由 JAX 的 pjit 接口驱动分区器 (Xu et al. 2021)。实践中,一套前沿技术栈会拼几个部件,比如让 Megatron-Core 负责模型并行,再配上自研的数据与检查点层。
容错
在数千个节点上连跑数周,恢复就是一个一等的子系统。检查点频率由写入成本和每次故障丢掉的工作量之间的权衡来定;异步与切分检查点,比如 CheckFreq,把写入挪出关键路径,让高频率仍然负担得起 (Mohan et al. 2021)。弹性重启会检测到一个失效节点、把它隔离,再从最近的检查点恢复,理想情况下落到备用容量上,不必整体重启。掉队节点和静默数据损坏,比明确的崩溃更难对付,因为训练还在往下跑,只是变慢了,或者悄悄出了错。
还有一个容错要求会影响数据层:一次重启必须恢复完全相同的数据顺序,这意味着采样器与打乱状态也是检查点的一部分。少了这一块,恢复时就会重复送入或跳过数据,破坏来自 第 6 章 的配比契约,表现为每次重启都冒出一段没法解释的损失不连续。流式送出语料的存储底座,以及调度训练的集群编排,归 第 65 章;本章只保留可恢复性契约。
失效模式
症状成簇出现。MFU 偏低是个总括性症状,靠每步剖析追到暴露的通信、过大的气泡、过多的重算,或者未融合的内核。通信瓶颈意味着瓶颈在网络:TP 溢出了 NVLink 域、一次藏不进反向传播之下的 DP all-gather,或者 MoE 的 all-to-all 卡在某个热门专家上。OOM 意味着布局不能满足显存预算:长序列长度下的激活显存、优化器状态切分不够,或者只在某个微批数量下才出现的碎片化拐点。一次节点故障,若没有快速检测、隔离与新近的检查点,就会把训练回滚到上一次保存,中间那段间隔都会被浪费。
最快的注意力内核也不改变这笔账:FlashAttention 让注意力保持精确,又让分数矩阵用得起,办法是从不把它写进高带宽显存。这是内核层面的一处巧解,位于这些并行轴之下,而不是替换掉其中任何一个 (Dao et al. 2022)。图 10.8 把两种扩展规律摆在一起对照:一个被物化的分数矩阵,显存随序列长度二次增长;一个从不物化分数的流式内核,则只带来线性增长。
拖动指数,感受两种规律之间的差距:指数为 2 时,显存是被物化的 O(L²) 分数矩阵;指数为 1 时,则是 FlashAttention 的 O(L) 流式处理。
配方层面的稳定性,也就是让优化器不发散的 z-loss、QK-norm 与损失尖峰恢复,归 第 5 章。这里讨论的稳定性有两层:数值层面的,由精度选择决定;以及运行层面的,由容错决定。
延伸阅读
- Shoeybi et al., “Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism,” 2019. arXiv:1909.08053
- Rajbhandari et al., “ZeRO: Memory Optimizations Toward Training Trillion Parameter Models,” 2019. arXiv:1910.02054
- Narayanan et al., “Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM” (SC'21; PTD-P 3D parallelism), 2021. arXiv:2104.04473
- Korthikanti et al., “Reducing Activation Recomputation in Large Transformer Models” (sequence parallelism + selective recomputation), 2022. arXiv:2205.05198本文提出序列并行与选择性激活重计算,在结合张量并行训练大型 Transformer 模型时,将激活内存降低 5 倍,并将激活重计算的执行时间开销减少 90
- Huang et al., “GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism” (NeurIPS), 2019. arXiv:1811.06965GPipe 通过微批量切分实现流水线并行(PP),突破单加速器显存限制,在多加速器上实现近线性加速以训练超大规模神经网络。
- Narayanan et al., “PipeDream: Generalized Pipeline Parallelism for DNN Training” (SOSP), 2019. doi.orgPipeDream 将流水线并行与数据并行结合,使 GPU 间通信量降低最多 95
- Zhao et al., “PyTorch FSDP: Experiences on Scaling Fully Sharded Data Parallel” (VLDB), 2023. arXiv:2304.11277
- Rajbhandari et al., “ZeRO-Infinity: Breaking the GPU Memory Wall for Extreme Scale Deep Learning,” 2021. arXiv:2104.07857ZeRO-Infinity 是一种异构训练系统,将模型状态卸载至 CPU 和 NVMe 内存,使现有 GPU 集群无需修改模型代码即可训练数十万亿参数规模的模型。
- Micikevicius et al., “Mixed Precision Training,” 2017. arXiv:1710.03740本文提出混合精度训练方法,结合 FP16 存储与计算、FP32 主权重副本、损失缩放和 FP32 累加,在不损失精度的情况下将训练显存减少约一半。
- Micikevicius et al., “FP8 Formats for Deep Learning,” 2022. arXiv:2209.05433
- DeepSeek-AI, “DeepSeek-V3 Technical Report” (前沿规模的 fp8 预训练), 2024. arXiv:2412.19437介绍 DeepSeek-V3,一个 671B 参数、每词元激活 37B 的混合专家模型,用 14.8T 词元与 fp8 矩阵乘法训练,采用无辅助损失的负载均衡,以低成本比肩闭源模型。
- NVIDIA, “Pretraining Large Language Models with NVFP4” (微缩放的 4 位预训练), 2025. arXiv:2509.25149用 NVFP4 这一 4 位微缩放格式在 10 万亿词元上训练一个 12B 模型,借助随机 Hadamard 变换、二维缩放与随机舍入,达到与 fp8 基线相当的效果。
- Hu et al., “Elucidating the Design Space of FP4 training” (4 位训练靠什么站得住), 2025. arXiv:2509.17791系统梳理 4 位训练的设计空间,涵盖分块缩放格式、Hadamard 变换与随机舍入,指出哪些组合能让 fp4 矩阵乘法在可接受的开销下逼近基线质量。
- Dao et al., “FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness” (kernel-level IO-awareness; also in 03), 2022. arXiv:2205.14135
- Liu et al., “Ring Attention with Blockwise Transformers for Near-Infinite Context” (context-parallel attention), 2023. arXiv:2310.01889Ring Attention 将长序列分布到多设备环形拓扑中,通过将键值块通信与分块自注意力计算重叠,实现无近似的近乎无限上下文长度。
- Lepikhin et al., “GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding” (expert sharding + all-to-all; also in 04), 2020. arXiv:2006.16668
- NVIDIA, “NCCL: NVIDIA Collective Communications Library” (optimized inter-GPU collective primitives (all-reduce, all-gather, reduce-scatter, all-to-all) over NVLink/PCIe/InfiniBand; engineering library, not a single canonical paper), 2024. github.com
- Mohan et al., “CheckFreq: Frequent, Fine-Grained DNN Checkpointing” (USENIX FAST'21; asynchronous, low-overhead checkpointing), 2021. usenix.org
- Xu et al., “GSPMD: General and Scalable Parallelization for ML Computation Graphs” (XLA/TPU sharding annotations underlying JAX `pjit`), 2021. arXiv:2105.04663
评论
登录后评论