分布式训练
第 13 课:分布式训练
上一课我们把"怎么把参数练出来"这条线走完了:从预训练到对齐、再到推理模型。但那些方法默认了一件事——模型训得动。这一课补上前提:405B 的模型,光训练状态就有 6.5 TB,怎么切到上千张卡上?讲清四把刀(数据并行、张量并行、流水线并行、专家/上下文并行)各切什么、各自付出什么代价(数据并行那一档的分片做法叫 FSDP,即把参数、梯度、优化器状态都切开放到各卡),最后看 LLaMA-3 405B 的 1024 卡配置是怎么配出来的。
② 说清 DP / ZeRO(把优化器状态也切开、分片存到各张卡)、TP、PP、CP / EP 四把刀各切什么、各付出什么代价
③ 会拆解一个真实的并行配置(TP×PP×CP×DP = 总卡数),并给出 TP 为何 ≤8 的理由
上一课我们把"怎么把参数练出来"走完了——从预训练到对齐、再到推理模型。但那条线上的每一步都默认了一件事:模型训得动。这一课补上前提。
先统一口径:混合精度训练指的是"用 16 位算得快、用 32 位存得准"两种精度混着来。可以把训练一个参数类比成搬家:bf16 权重是家具本身,梯度是搬运清单,fp32 master 与 Adam 的两个动量是三本记账簿——搬一件家具,实际要带五样东西。
| 项 | 每参数字节 | 405B 总量 |
|---|---|---|
| bf16 权重 | 2 | 405e9 × 2 = 810 GB |
| bf16 梯度 | 2 | 405e9 × 2 = 810 GB |
| fp32 master 权重 | 4 | 405e9 × 4 = 1.62 TB |
| Adam 一阶动量 m | 4 | 405e9 × 4 = 1.62 TB |
| Adam 二阶动量 v | 4 | 405e9 × 4 = 1.62 TB |
| 合计 | 16 | 6.48 TB |
| 口径 | 总量 | 一张 80 GB 卡需要几张 |
|---|---|---|
| 只放 bf16 权重 | 810 GB | 810 ÷ 80 = 10.1 → 至少 11 张 |
| 只放 fp32 master | 1.62 TB | 1620 ÷ 80 = 20.3 → 至少 21 张 |
| 训练全状态 | 6.48 TB | 6480 ÷ 80 = 81 → 至少 81 张 |
| 再留激活的地方(示意 +30%) | 约 8.4 TB | 8400 ÷ 80 ≈ 105 张(示意) |
| 切什么 | 刀 | 能解决的问题 | 不能解决的问题 |
|---|---|---|---|
| 切数据(同一份模型,不同数据) | DP | 训得慢 | 单卡放不下 |
| 切模型(同一批数据,不同参数) | TP / PP / CP / EP | 放不下 | 引入通信与流水线气泡 |
训练显存不是一个数字,而是一句乘法:每参数几字节 × 参数量。记住"混合精度 + Adam ≈ 16 B/参数"这个口径,任何模型的账都能当场算出来:405B 是 6.48 TB,70B 是 1.12 TB,7B 是 112 GB。算完账才知道该切哪一刀——不先算账就堆卡,是最常见的浪费。
上一张卡片说有两把刀:切数据(DP)和切模型。这一张先看第一把刀到底能治什么、治不了什么。
DDP 里每张卡都拿着一份完整模型。类比一下:这就像全班每人手里都有一本一模一样的教材——加人只是让你同时改更多本作业,并不会让每本书变薄。所以加卡能提吞吐,但单卡的显存占用一动不动。
| DP 规模 N | 每卡要放 | 405B 每卡显存 | 80 GB 装得下吗 |
|---|---|---|---|
| N = 8 | 完整模型状态(16 B/参数) | 6.48 TB | 否 |
| N = 512 | 完整模型状态(16 B/参数) | 6.48 TB | 否 |
| 方案(N = 512) | 每参数显存 | 405B 每卡 | 装得下吗 |
|---|---|---|---|
| DDP | 16 B | 6.48 TB | 否 |
| ZeRO-1:切优化器状态(12 B ÷ N) | 2 + 2 + 12÷512 ≈ 4.02 B | 约 1.63 TB | 否 |
| ZeRO-2:再切梯度(14 B ÷ N) | 2 + 14÷512 ≈ 2.03 B | 约 821 GB | 否 |
| ZeRO-3:连参数也切(16 B ÷ N) | 16÷512 = 0.031 B | 约 12.7 GB | 是 |
| ZeRO-3(N = 1024) | 16÷1024 = 0.0156 B | 约 6.3 GB | 是 |
| 情形 | ZeRO-3(切状态) | TP(切层内计算) |
|---|---|---|
| 参数总量 | 可按卡数继续摊薄 | 也能摊,但受"矩阵能切多细"限制 |
| 单层峰值 | 用到某层时要先把那层 all-gather 回来,峰值仍是整层 | 每卡只留 1/TP,峰值同步下降 |
| 每卡计算量 | 不变(每卡仍要算完整层) | 降到 1/TP |
| 额外通信 | all-gather + reduce-scatter,约为 DDP 的 1.5 倍 | 每层 4 次 all-reduce |
纯 DP(DDP)救不了显存——加卡只增加副本数,不减少副本大小。ZeRO/FSDP 能救,靠的是"把 16 B 按卡数平分",代价是通信量上升、且每层仍需临时凑回整层。所以工业界的超大模型更常走另一条路:DP 负责规模、TP/PP 负责把模型本身切小。下一张卡片从 TP 开始。
上一张卡片看到:DP 能摊薄状态,但每层还是要凑回整层、通信也不便宜,所以该动刀切模型本身了。第一把刀就是张量并行(TP,Tensor Parallelism)——把一层的权重矩阵切开,几张卡各算一部分,算完把结果加起来。
切计算确实能让每卡算得更少、装得更少。类比一下:TP 像几个人合写一份稿子——每人只写一段(算得快、纸也省),但每段写完都要互相读一遍(all-reduce)。人越多,读稿的时间越久。这张卡片就把"读稿"的时间算出来。
| 位置 | 前向 | 反向 | 小计 |
|---|---|---|---|
| 注意力块 | 1 次 | 1 次 | 2 次 |
| FFN 块 | 1 次 | 1 次 | 2 次 |
| 单层合计 | 2 次 | 2 次 | 4 次 |
| 整个模型(126 层) | — | — | 4 × 126 = 504 次 |
| 项 | 算式 | 结果 |
|---|---|---|
| 单次 all-reduce 元素数 S | b × s × h = 1 × 8192 × 16384(示意:b=1、s=8192 取自 Llama 3 训练配置) | 1.34×10⁸ 个 |
| S 的 bf16 字节数 | 1.34e8 × 2 B | 268 MB |
| 环状 all-reduce 每卡实际发送 | 2(TP−1)/TP × S;TP=8 → 1.75 × 268 MB | 约 470 MB |
| 单层 4 次 | 4 × 470 MB | 1.88 GB |
| 整个迭代(126 层) | 1.88 GB × 126 | 约 237 GB |
| TP 度数 | 每卡计算量(相对) | 每卡通信量(每次 all-reduce) | 通信 ÷ 计算(相对) |
|---|---|---|---|
| 8 | 1/8 | 1.75 S | 基准 |
| 64 | 1/64 | 1.97 S(只涨 13%) | 约 9 倍 |
TP 切的是"每一层都要用的东西"(权重与激活),所以每层都得通信一次,次数固定 4 次、数据量固定 ∝ b·s·h。TP 度数越大,通信在总时间里的占比越高——到 64 路时通信/计算比涨约 9 倍。所以 TP 必须待在 NVLink 域内(NVLink = 同一服务器内 GPU 之间的高带宽直连;H100 一节点 8 卡、双向 900 GB/s;GB200 NVL72 才把上限抬到 72)。要跨节点,就得换一把通信量更小的刀。
上一张卡片说 TP 跨不了节点。要跨节点,就得换一把"通信量小"的刀——流水线并行(PP,Pipeline Parallelism):把 126 层切成若干段(stage),每段放在不同卡上,一个批次里的 token 拆成若干微批次,像流水线一样依次流过各段。stage 之间只传激活,数据量比 all-reduce 小得多,所以能跑在慢速的跨节点网络上。
类比一下:PP 像工厂流水线——第一站干完才能轮到第二站。于是"开班"时后面的站等着、"收班"时前面的站等着,那两段时间总有站在空转。这段空转就叫流水线气泡(bubble)。
| 项 | 取值 |
|---|---|
| stage 数 P | 8 |
| 每个批次的微批次数 M | 48 |
| 气泡占比 = (P−1) ÷ (M+P−1) | 7 ÷ 55 = 12.7% |
| 常用近似 (P−1) ÷ M | 7 ÷ 48 = 14.6%(偏悲观) |
| 调度 | 在飞微批次数 | 气泡占比 | 激活显存 |
|---|---|---|---|
| GPipe(先全前向、再全反向) | M(全部,示例 48) | (P−1)/(M+P−1) | 最大,随 M 增长 |
| 1F1B(一个前向一个反向) | P(与 M 无关,示例 8) | 相同 | 恒定 |
| 配置 | stage 数 P | 每卡 chunk 数 v | 气泡占比 | 点对点通信次数 |
|---|---|---|---|---|
| 普通 1F1B | 8 | 1 | 7 ÷ 55 = 12.7% | 2 × (P−1) = 14 |
| 虚拟流水线(v = 2) | 8 | 2 | 约 6.4% | 约 28 |
PP 用"只传相邻 stage 的激活"换来跨节点能力,代价是气泡。三个旋钮分工明确:1F1B 治显存(在飞微批次固定为 P)、虚拟流水线治气泡(约 ÷v,代价是通信 ×v 与显存 +v)、加大 M 也能压气泡(但吃显存)。工程上三者一起调,目标通常是把气泡压到 10% 量级。
上一张卡片发现:TP 受 NVLink 域限制、PP 有气泡。可还有两类模型会撞上更硬的墙——参数总量巨大的 MoE,和序列极长的长上下文训练。
先把两个术语说白:MoE(混合专家)= 把一个大 FFN 换成很多个小专家,每个 token 只走其中几个(所以总参数很大、激活参数很小);EP(专家并行)= 把不同的专家放在不同的卡上。这两把刀的共同点是:它们切的东西本来就不需要"每张卡都有"——MoE 的专家天然分散,长序列的 token 天然排成一条链。
类比一下 EP:它像把一家医院的科室分散到不同楼栋——病人(token)只去自己要挂的那几个科室,不必每栋楼都建一套完整科室。这正是它比 TP 便宜的根本原因。
| 对比项 | TP(切每层都要用的权重) | EP(切本来就分散的专家) |
|---|---|---|
| 通信原语 | all-reduce | all-to-all |
| 触发位置 | 每层固定 4 次 | 每个 MoE 层 2 次(dispatch 派发 + combine 收回) |
| 单卡计算量 | ∝ 1/TP | ∝ 本卡上的专家数 ÷ 总专家数 |
| 每卡显存 | 1/TP 的权重 | 1/EP 的专家 |
| 配置 | TP | PP | EP | 单卡权重(bf16,示意) |
|---|---|---|---|---|
| DeepSeek-V3 实际 | 1 | 16 | 64 | 671e9 ÷ 16 ÷ 64 = 0.66e9 → 约 1.3 GB |
| 若按稠密思路切(TP=8) | 8 | 16 | 1 | 671e9 ÷ 16 ÷ 8 = 5.24e9 → 约 10.5 GB |
| 项 | 不用 CP | 用 CP = 16 |
|---|---|---|
| 每卡负责的序列长度 | 131,072 | 131,072 ÷ 16 = 8,192 |
| 每卡激活显存(相对) | 1 | 1/16 |
| 额外通信 | — | 每个 attention 层要交换 K/V(环形传递或 all-gather) |
四把刀的判据只有一句话:要切的东西是不是"每层都要用的"。
是(权重、激活这类每层都要过一遍的)→ 只能在 NVLink 域内切,即 TP ≤ 8;
不是(层、token、专家这类天然分散的)→ 可以跨节点切,即 PP / CP / EP。
这也解释了 DeepSeek-V3 为什么敢把 TP 设成 1:MoE 的专家本来就分散,不需要动 TP 这把最贵的刀。
上一张卡片把四把刀的判据收敛成一句话:每层都要用的只能在 NVLink 域内切(TP≤8),天然分散的可以跨节点切(PP/CP/EP)。所以这一张就用这句话去拆真实的配置——先从"每个维度为什么取这个值"开始推。
组合的原则可以类比成装箱:先按"不能跨箱的易碎品"(TP)确定内层格子,再按"可以摆远的东西"(PP/CP)确定外层货架,剩下的空间全部留给 DP(复制模型、铺开数据)。
| 维度 | 取值 | 为什么是这个数 |
|---|---|---|
| TP | 8 | 一个 NVLink 域 8 张卡(H100 为 900 GB/s);TP 跨节点会因通信而吃亏 |
| PP | 8 | 126 层 ÷ 8 ≈ 每段 16 层;跨节点只传激活,带宽要求低 |
| CP | 2 | 训练序列 ≥8K(含 8K)即可启用;切 2 份,每卡一半 |
| DP | 8 | 剩下的全给它:1024 ÷ (8 × 8 × 2) = 8 |
| 来源 | 卡数 | TP | PP | CP | DP | 校验式 |
|---|---|---|---|---|---|---|
| Megatron-Core 推荐(405B) | 1,024 | 8 | 8 | 2 | 8 | 8×8×2×8 = 1024 |
| NeMo FP8 基准(405B) | 512 或 576(源不一致) | 8 | 9 | 2 | 4 | 8×9×2×4 = 576(某文档记 512) |
| Meta 实际(8K 序列) | 8,192 | 8 | 16 | 1 | 64 | 8×16×1×64 = 8,192 |
| Meta 实际(扩容档) | 16,384 | 8 | 16 | 1 | 128 | 8×16×1×128 = 16,384 |
| 项 | 稠密模型 | MoE 模型 |
|---|---|---|
| 最小卡数(DP=1) | PP × TP × CP | PP × max(TP×CP, EP×ETP)(ETP = 专家张量并行度) |
| 原因 | 一张卡要能装下完整的一层 | dense 网格与 expert 网格共享同一批卡,不连乘 |
| NVIDIA Megatron-Bridge 对 DeepSeek-V3 的推荐(TP=2, PP=16, EP=64) | — | 16 × max(2×1, 64×1) = 16 × 64 = 1,024 |
口径注意:这里的 TP=2 是 NVIDIA 的推荐值;DeepSeek 自己训 V3 时用的是 TP=1(见上一张卡片),代入 max(·) 后结果同样是 1,024。
组合拳只有三条判据:① 每层都要用的东西(权重)→ 只能在 NVLink 域内切,TP ≤ 8;② 天然分散的东西(层 / token / 专家)→ 可以跨节点切,PP / CP / EP;③ 剩下的全部给 DP。先定 TP(受硬件约束),再定 PP/CP(受显存与序列约束),最后用 DP 把卡数凑到目标值。记住这个顺序,任何并行配置表你都能自己拆开——也能一眼看出哪些数字是错的。