第 13 课:分布式训练

上一课我们把"怎么把参数练出来"这条线走完了:从预训练到对齐、再到推理模型。但那些方法默认了一件事——模型训得动。这一课补上前提:405B 的模型,光训练状态就有 6.5 TB,怎么切到上千张卡上?讲清四把刀(数据并行、张量并行、流水线并行、专家/上下文并行)各切什么、各自付出什么代价(数据并行那一档的分片做法叫 FSDP,即把参数、梯度、优化器状态都切开放到各卡),最后看 LLaMA-3 405B 的 1024 卡配置是怎么配出来的。

🎯 学完这 6 步你将能够:
① 用「16 B/参数」现算任何模型的训练显存账,并判断该切数据还是切模型
② 说清 DP / ZeRO(把优化器状态也切开、分片存到各张卡)、TP、PP、CP / EP 四把刀各切什么、各付出什么代价
③ 会拆解一个真实的并行配置(TP×PP×CP×DP = 总卡数),并给出 TP 为何 ≤8 的理由
🗺 本节推理链(4 把刀的判据递进 + 3 条支链:长序列 / MoE(即混合专家,每层用多个专家网络、每个 token 只激活其中少数几个)专用刀 / 选型;从"装不下"到"该切哪把刀")
1训一个 405B 稠密模型,要求把 6.5 TB 的训练状态分摊到每张只有 80 GB 的卡上,而这一批 token 的激活还要另占地方——这就要求把"数据"和"模型"切成两块不同的刀。
↓
2承接上一步的「切的维度」:切"数据"的那把刀(DP)把整份模型复制到每张卡,这就要求单卡必须装得下整个模型——于是它只能解决"训得慢",要靠切分优化器状态与 gradient 才勉强解决"装不下",代价是通信涨、每层峰值仍在。
↓
3要真正放不下就得切模型本身,即 TP 的通信瓶颈:把一层矩阵按列/行切开、注意力 heads 分到不同卡,所以每层要多做 4 次 all-reduce;通信量 ∝ b·s·h 且与 TP 度数无关,而每卡算力 ∝ 1/TP——于是通信/计算比随 TP 上升,TP 必须待在 NVLink 域内。
↓
4TP 跨不了节点,这就要求一把能跨节点、且通信量小的刀——因此沿层数切出 pipeline parallelism(PP):stage 之间只传这一批 token 的中间激活,但要付出流水线气泡。
↓
5气泡所以不能靠无限加卡解决,于是用虚拟流水线把气泡缩小 v 倍。【支链 · 长序列】序列一长(128K)激活又爆,这就撞上「长序列的显存墙」,需要第四把刀 context parallelism(CP)沿序列维切;【支链 · MoE】MoE 模型则另用 expert parallelism(EP)沿专家切——两者都要交换 attention 的 K/V 或 token。
↓
6【支链 · 选型】长序列的显存墙逼出最后一步组合拳:因此 1024 卡的推荐配置是 TP8 × PP8 × CP2 × DP8;MoE 则用 EP 换掉 TP——每张卡只放一部分专家,输出 logits(即模型输出的、还没做归一化的原始分数向量)前要跨卡做 all-to-all 汇总,而最小卡数按 PP × max(TP×CP, EP×ETP) 算,不是连乘。
Data ParallelismTensor ParallelismPipeline ParallelismContext ParallelismExpert ParallelismZeRO / FSDP
1
80GB 装不下的 405B,要想训起来,第一刀该切在哪?
提示:先算一笔账——一个参数在混合精度训练里同时要占几份内存?把权重、梯度、优化器状态都算上,再除以一张 80 GB 的卡。
▾
知识背景
LLaMA-3 405B(Meta,2024-07):126 层、模型维度 16,384、128 个注意力头、FFN 维 53,248,在 15.6T token 上用 3.8×10²⁵ FLOPs 预训练(Llama 3 论文 Table 3)。训练显存的行业口径(DeepSpeed/ZeRO 文档给出)是"每个参数 16 字节":bf16 权重 2 B + bf16 梯度(gradient)2 B + fp32 master 权重 4 B + Adam 一阶动量 4 B + Adam 二阶动量 4 B。把"切模型"做成可复用方案的是 Megatron-LM(Shoeybi 等,arXiv:1909.08053,2019)。

上一课我们把"怎么把参数练出来"走完了——从预训练到对齐、再到推理模型。但那条线上的每一步都默认了一件事:模型训得动。这一课补上前提。

先统一口径:混合精度训练指的是"用 16 位算得快、用 32 位存得准"两种精度混着来。可以把训练一个参数类比成搬家:bf16 权重是家具本身,梯度是搬运清单,fp32 master 与 Adam 的两个动量是三本记账簿——搬一件家具,实际要带五样东西。

🧮 第一笔账:405B 到底占多少
Step 1:每参数 16 字节拆开看
项每参数字节405B 总量
bf16 权重2405e9 × 2 = 810 GB
bf16 梯度2405e9 × 2 = 810 GB
fp32 master 权重4405e9 × 4 = 1.62 TB
Adam 一阶动量 m4405e9 × 4 = 1.62 TB
Adam 二阶动量 v4405e9 × 4 = 1.62 TB
合计166.48 TB
810 GB ×2 + 1.62 TB ×3 = 6.48 TB。所以"405B 的权重有多大"这句话取决于算哪一份:只算 bf16 权重是 810 GB,只算 fp32 master 是 1.62 TB,两者都是"权重",差在精度与用途。
Step 2:换成"至少要几张卡"
口径总量一张 80 GB 卡需要几张
只放 bf16 权重810 GB810 ÷ 80 = 10.1 → 至少 11 张
只放 fp32 master1.62 TB1620 ÷ 80 = 20.3 → 至少 21 张
训练全状态6.48 TB6480 ÷ 80 = 81 → 至少 81 张
再留激活的地方(示意 +30%)约 8.4 TB8400 ÷ 80 ≈ 105 张(示意)
注意这些还只是"放得下"——没算能不能算得快、通信扛不扛得住。所以真实训练要的不是 81 张,而是数百到上万张。
Step 3:只有两把刀,切数据还是切模型
切什么刀能解决的问题不能解决的问题
切数据(同一份模型,不同数据)DP训得慢单卡放不下
切模型(同一批数据,不同参数)TP / PP / CP / EP放不下引入通信与流水线气泡
所以第一刀该先问一句:我缺的是"显存"还是"吞吐"?缺显存就切模型,缺吞吐就切数据——混着上也没关系,但要先知道每把刀各自在治什么。
🎯 关键认知

训练显存不是一个数字,而是一句乘法:每参数几字节 × 参数量。记住"混合精度 + Adam ≈ 16 B/参数"这个口径,任何模型的账都能当场算出来:405B 是 6.48 TB,70B 是 1.12 TB,7B 是 112 GB。算完账才知道该切哪一刀——不先算账就堆卡,是最常见的浪费。

AI 助教
👋 对显存账有疑问?比如"为什么 master 要用 fp32?""LoRA(即冻结大部分权重、只训练一小部分低秩增量参数的省显存微调)微调能不能少算几份?"

我会用具体数字帮你算。
2
每张卡都拿着完整模型副本时,堆更多卡能解决"单层放不下"吗?
提示:先分清 DP 里每张卡手里拿的是什么——是"模型的一部分"还是"整套模型的完整副本"?再想:要让一份副本变小,靠的是"副本多几份",还是"每份更小"?
▾
知识背景
DP 的经典形态是 DDP:每张卡放一份完整模型、各算一部分数据,反向结束后用 all-reduce 平均梯度(gradient)。通信原语先说白:all-reduce = 所有卡把各自的值求和后同步给每张卡;reduce-scatter = 求和后只把结果按片分给各卡(每人只拿一份);all-gather = 把各卡手里的一小片拼回完整张量。三者是"求和+分发"的三种切法。ZeRO(Rajbhandari 等,arXiv:1910.02054,2019-10)把 DDP 改造成"不切计算、只切状态"——ZeRO-1 切优化器状态,ZeRO-2 再切梯度,ZeRO-3 连参数也切;PyTorch 里的实现叫 FSDP(Fully Sharded Data Parallel)。

上一张卡片说有两把刀:切数据(DP)和切模型。这一张先看第一把刀到底能治什么、治不了什么。

DDP 里每张卡都拿着一份完整模型。类比一下:这就像全班每人手里都有一本一模一样的教材——加人只是让你同时改更多本作业,并不会让每本书变薄。所以加卡能提吞吐,但单卡的显存占用一动不动。

🧮 第二笔账:ZeRO 把状态摊薄到什么程度
Step 1:DDP 加卡不省显存
DP 规模 N每卡要放405B 每卡显存80 GB 装得下吗
N = 8完整模型状态(16 B/参数)6.48 TB否
N = 512完整模型状态(16 B/参数)6.48 TB否
两行的每卡占用完全一样——因为 DDP 里 N 只对应"多存几份副本",不改变"一份副本多大"。这就是"加卡救不了显存"的准确含义。
Step 2:ZeRO 三个阶段各切掉什么
方案(N = 512)每参数显存405B 每卡装得下吗
DDP16 B6.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是
算术校验:405e9 × 0.03125 = 12.7 GB;405e9 × 0.015625 = 6.3 GB。关键在最后两行——ZeRO-3 把 16 B 全部按 N 平分,卡越多每卡越小,这才是真正意义上的"切"。
Step 3:为什么它仍有边界
情形ZeRO-3(切状态)TP(切层内计算)
参数总量可按卡数继续摊薄也能摊,但受"矩阵能切多细"限制
单层峰值用到某层时要先把那层 all-gather 回来,峰值仍是整层每卡只留 1/TP,峰值同步下降
每卡计算量不变(每卡仍要算完整层)降到 1/TP
额外通信all-gather + reduce-scatter,约为 DDP 的 1.5 倍每层 4 次 all-reduce
405B 单层约 3.22e9 个参数(12 × 16,384² ≈ 3.22e9;12h² 是用"4h 的标准 FFN"做快速估算的经验近似,与 405e9 ÷ 126 ≈ 3.21e9 恰好接近,用来判断量级足够),bf16 下 all-gather 回来约 6.4 GB——这一层放得下,所以 ZeRO-3 在技术上能装 405B。真实原因在通信:Meta 的 Llama 3 并行论文在讨论并行组合时写明,他们没有选择"ZeRO-3 这一档叠加 PP",理由是它会在 PP 每个 stage 的前向与反向都引入额外通信开销。注意别误读成"Meta 不用 FSDP"——该论文描述的 4D 并行里 FSDP 用在数据并行那个维度上(下一张卡片会看到具体配置)。
🎯 关键认知

纯 DP(DDP)救不了显存——加卡只增加副本数,不减少副本大小。ZeRO/FSDP 能救,靠的是"把 16 B 按卡数平分",代价是通信量上升、且每层仍需临时凑回整层。所以工业界的超大模型更常走另一条路:DP 负责规模、TP/PP 负责把模型本身切小。下一张卡片从 TP 开始。

AI 助教
👋 对 ZeRO/FSDP 有疑问?比如"1.5 倍通信从哪来?""为什么不用 ZeRO-3 一路走到底?"

我会用具体数字帮你算。
3
TP 把一层矩阵切开,为什么通信会变成瓶颈?
提示:先数一个层里要做几次通信,再想每次通信搬多少数据。然后问一个关键问题:把计算分给更多卡之后,每张卡的计算量变了,通信量变了吗?
▾
知识背景
Megatron-LM(Shoeybi 等,arXiv:1909.08053,2019)给出一条极省通信的切法:MLP 按列切、128 个 attention heads 按头分到不同卡,于是一个 transformer 层只需 4 次 all-reduce(all-reduce = 所有卡把各自算出的部分结果求和、再把和同步给每一张卡;本层里注意力块与 FFN 块各自在前向 1 次、反向 1 次)。原文用 512 张 V100、8 路模型并行训 8.3B 模型,达到 15.1 PFLOP/s、相对单卡 76% 的扩展效率。

上一张卡片看到:DP 能摊薄状态,但每层还是要凑回整层、通信也不便宜,所以该动刀切模型本身了。第一把刀就是张量并行(TP,Tensor Parallelism)——把一层的权重矩阵切开,几张卡各算一部分,算完把结果加起来。

切计算确实能让每卡算得更少、装得更少。类比一下:TP 像几个人合写一份稿子——每人只写一段(算得快、纸也省),但每段写完都要互相读一遍(all-reduce)。人越多,读稿的时间越久。这张卡片就把"读稿"的时间算出来。

🧮 第三笔账:TP 的通信量
Step 1:4 次 all-reduce 从哪来
位置前向反向小计
注意力块1 次1 次2 次
FFN 块1 次1 次2 次
单层合计2 次2 次4 次
整个模型(126 层)——4 × 126 = 504 次
次数与 TP 度数无关——不管切 2 路还是 64 路,每层固定 4 次。变的是每次要搬多少、以及每次要等多久。
Step 2:通信量按具体数字算一遍
项算式结果
单次 all-reduce 元素数 Sb × s × h = 1 × 8192 × 16384(示意:b=1、s=8192 取自 Llama 3 训练配置)1.34×10⁸ 个
S 的 bf16 字节数1.34e8 × 2 B268 MB
环状 all-reduce 每卡实际发送2(TP−1)/TP × S;TP=8 → 1.75 × 268 MB约 470 MB
单层 4 次4 × 470 MB1.88 GB
整个迭代(126 层)1.88 GB × 126约 237 GB
237 GB 是"每卡每迭代要搬的量级"(简化口径:按每次搬一份完整激活算,未计与计算的重叠)。换成时间:237 GB ÷ 450 GB/s ≈ 0.53 s——H100 的 NVLink 标称 900 GB/s,此处按"双向合计"口径取单向 450 GB/s(不同资料对 900 是"双向合计"还是"单向 per-GPU"口径不一,来源:NVIDIA H100 官方规格与 NVLink 文档)。如果这些 all-reduce 走节点间的 InfiniBand(约 400 GB/s 双向、单向约 200 GB/s),时间还会更长;实际训练要靠"通信与计算重叠"把这部分尽量藏起来。
Step 3:为什么 TP 越大越亏
TP 度数每卡计算量(相对)每卡通信量(每次 all-reduce)通信 ÷ 计算(相对)
81/81.75 S基准
641/641.97 S(只涨 13%)约 9 倍
算术:通信量之比 1.97 ÷ 1.75 = 1.13;计算量之比 8 ÷ 64 = 0.125;两者相除得 1.13 ÷ 0.125 = 9.0。通信量几乎不随 TP 变(每次都搬完整的激活),而计算量按 1/TP 掉——这就是 TP 的通信瓶颈,也是"TP 一般不超过 8"的根本原因。
🎯 关键认知

TP 切的是"每一层都要用的东西"(权重与激活),所以每层都得通信一次,次数固定 4 次、数据量固定 ∝ b·s·h。TP 度数越大,通信在总时间里的占比越高——到 64 路时通信/计算比涨约 9 倍。所以 TP 必须待在 NVLink 域内(NVLink = 同一服务器内 GPU 之间的高带宽直连;H100 一节点 8 卡、双向 900 GB/s;GB200 NVL72 才把上限抬到 72)。要跨节点,就得换一把通信量更小的刀。

AI 助教
👋 对 TP 通信有疑问?比如"序列并行能省多少通信?""为什么是 4 次而不是更多?"

我会用具体数字帮你算。
4
流水线并行为什么会产生气泡,虚拟流水线又是怎么减掉的?
提示:把模型按层切成几段、每段一台设备,数据像流水线一样流过。想想"开班"和"收班"那两段时间里,哪些设备在空转?
▾
知识背景
GPipe(Huang 等,arXiv:1811.06965,NeurIPS 2019)提出"按层切 stage + 把批次拆成微批次"的流水线方案;1F1B 调度(PipeDream-Flush)把在飞微批次数限制在流水线深度,显存占用不再随微批次数增长。Megatron-LM(Narayanan 等,arXiv:2104.04473,2021)进一步提出交错(虚拟)流水线:把气泡缩小约 v 倍,代价是点对点通信次数约 ×v。该论文在 3072 张 A100 上以 502 PFLOP/s 跑通万亿参数模型(约 52% 峰值)。

上一张卡片说 TP 跨不了节点。要跨节点,就得换一把"通信量小"的刀——流水线并行(PP,Pipeline Parallelism):把 126 层切成若干段(stage),每段放在不同卡上,一个批次里的 token 拆成若干微批次,像流水线一样依次流过各段。stage 之间只传激活,数据量比 all-reduce 小得多,所以能跑在慢速的跨节点网络上。

类比一下:PP 像工厂流水线——第一站干完才能轮到第二站。于是"开班"时后面的站等着、"收班"时前面的站等着,那两段时间总有站在空转。这段空转就叫流水线气泡(bubble)。

🧮 第四笔账:气泡有多大、怎么缩小
Step 1:气泡占比的公式与算例
项取值
stage 数 P8
每个批次的微批次数 M48
气泡占比 = (P−1) ÷ (M+P−1)7 ÷ 55 = 12.7%
常用近似 (P−1) ÷ M7 ÷ 48 = 14.6%(偏悲观)
想让气泡小,就要 M ≫ P。但 M 越多,同时在飞的微批次越多、要留的激活显存越大——气泡和显存是一对反向的旋钮。
Step 2:1F1B 换来了什么(以及没换来什么)
调度在飞微批次数气泡占比激活显存
GPipe(先全前向、再全反向)M(全部,示例 48)(P−1)/(M+P−1)最大,随 M 增长
1F1B(一个前向一个反向)P(与 M 无关,示例 8)相同恒定
注意:1F1B 不改善气泡,只把显存从"随 M 增长"变成"只与 P 有关"。这两件事经常被混为一谈——一个治显存,一个治气泡。
Step 3:虚拟(交错)流水线把气泡再除 v
配置stage 数 P每卡 chunk 数 v气泡占比点对点通信次数
普通 1F1B817 ÷ 55 = 12.7%2 × (P−1) = 14
虚拟流水线(v = 2)82约 6.4%约 28
思路是让每张卡负责多个"虚拟 stage"(chunk),把空转填上,气泡约缩小 v 倍;代价是每卡要多存 v 份激活与参数分片、点对点通信次数也约 ×v。(公式口径:这里按"精确式 ÷ v"估,即 12.7% ÷ 2 ≈ 6.4%;Megatron 原文给的是插值式 (1/v) × (P−1)/M ≈ 7.3%,两者不冲突、只是口径不同。)NVIDIA NeMo 的配置表里那个 "VP" 列就是这里的 v(例如 405B 用 VP=7)。
🎯 关键认知

PP 用"只传相邻 stage 的激活"换来跨节点能力,代价是气泡。三个旋钮分工明确:1F1B 治显存(在飞微批次固定为 P)、虚拟流水线治气泡(约 ÷v,代价是通信 ×v 与显存 +v)、加大 M 也能压气泡(但吃显存)。工程上三者一起调,目标通常是把气泡压到 10% 量级。

AI 助教
👋 对气泡有疑问?比如"零气泡流水线是怎么做到的?""P 和 M 该怎么选?"

我会用具体数字帮你算。
5
MoE 模型和长序列,为什么各需要一把专门的刀?
提示:先想这两种模型的"可切点"在哪——MoE 里不同 token 走不同专家,长序列里 token 本来就排成一条链。它们和"每层都要用的权重"是同一种东西吗?
▾
知识背景
DeepSeek-V3(arXiv:2412.19437,2024-12):671B 总参数、每个 token 只激活 37B,在 2048 张 H800 上训练;并行配置是 16 路 PP + 64 路 EP(跨 8 节点)+ 跨 8 节点的 ZeRO-1 DP,完全不用 TP(原文明确写"without using costly Tensor Parallelism"),并用 DualPipe(DeepSeek 的双向流水线调度)把跨节点 all-to-all 与计算重叠;总成本 2.788M H800 GPU 小时。序列侧:ring attention(Liu 等,2023)把长序列切到多卡上,Llama 3 训练用的是 all-gather 式 pass-KV(PyTorch 上下文并行文档;Meta 的 CP 论文 arXiv:2411.01783 报告在 128 张 H100/16 节点上做 1M 上下文预填只用 77 s,并行效率 93%)。

上一张卡片发现:TP 受 NVLink 域限制、PP 有气泡。可还有两类模型会撞上更硬的墙——参数总量巨大的 MoE,和序列极长的长上下文训练。

先把两个术语说白:MoE(混合专家)= 把一个大 FFN 换成很多个小专家,每个 token 只走其中几个(所以总参数很大、激活参数很小);EP(专家并行)= 把不同的专家放在不同的卡上。这两把刀的共同点是:它们切的东西本来就不需要"每张卡都有"——MoE 的专家天然分散,长序列的 token 天然排成一条链。

类比一下 EP:它像把一家医院的科室分散到不同楼栋——病人(token)只去自己要挂的那几个科室,不必每栋楼都建一套完整科室。这正是它比 TP 便宜的根本原因。

🧮 第五笔账:EP 与 CP 各切什么
Step 1:EP 与 TP 的通信形态不一样
对比项TP(切每层都要用的权重)EP(切本来就分散的专家)
通信原语all-reduceall-to-all
触发位置每层固定 4 次每个 MoE 层 2 次(dispatch 派发 + combine 收回)
单卡计算量∝ 1/TP∝ 本卡上的专家数 ÷ 总专家数
每卡显存1/TP 的权重1/EP 的专家
差别在"切的东西是不是每层都要用":权重每层都要用,所以必须每层通信;专家的使用本来就是稀疏的(一个 token 只走少数专家),所以通信只在 MoE 层发生、且天然是小流量。
Step 2:算一算 EP 让单卡省了多少
配置TPPPEP单卡权重(bf16,示意)
DeepSeek-V3 实际11664671e9 ÷ 16 ÷ 64 = 0.66e9 → 约 1.3 GB
若按稠密思路切(TP=8)8161671e9 ÷ 16 ÷ 8 = 5.24e9 → 约 10.5 GB
算术:671e9 ÷ 16 ÷ 64 = 6.55e8 个参数;× 2 B = 1.31 GB。而同样的模型用 TP=8 的稠密切法,每卡要放 5.24e9 个参数(约 10.5 GB)。注意这只是权重口径(未计梯度、优化器状态与激活,也未计 ZeRO-1 的再切分)——真正的省在于:MoE 的激活参数只有 37B,计算量按 37B 算,不是按 671B 算。
Step 3:CP 沿序列切,省的是激活
项不用 CP用 CP = 16
每卡负责的序列长度131,072131,072 ÷ 16 = 8,192
每卡激活显存(相对)11/16
额外通信—每个 attention 层要交换 K/V(环形传递或 all-gather)
131072 ÷ 16 = 8192。CP 与 TP 的关键区别:TP 切"每层都要用的权重",CP 切"沿序列天然可分的 token"——所以 CP 的通信量小得多,能在普通跨节点网络上跑(这正是 Meta 报告 93% 并行效率的原因)。
🎯 关键认知

四把刀的判据只有一句话:要切的东西是不是"每层都要用的"。
是(权重、激活这类每层都要过一遍的)→ 只能在 NVLink 域内切,即 TP ≤ 8;
不是(层、token、专家这类天然分散的)→ 可以跨节点切,即 PP / CP / EP。
这也解释了 DeepSeek-V3 为什么敢把 TP 设成 1:MoE 的专家本来就分散,不需要动 TP 这把最贵的刀。

AI 助教
👋 对 EP/CP 有疑问?比如"all-to-all 为什么比 all-reduce 便宜?""CP 和序列并行(SP)是一回事吗?"

我会用具体数字帮你算。
6
为什么 1024 张卡的推荐配置是 TP8 × PP8 × CP2,而不是把 TP 开到 64?
提示:先用"哪把刀能跨节点"给四个维度排序,再看总卡数怎么被一个乘法式拆开。别忘了 TP 上一张卡片刚算过的那笔账。
▾
知识背景
NVIDIA Megatron-Core 的并行策略指南给出 LLaMA-3.1 405B 的推荐配置:1024 张卡,TP=8、PP=8、CP=2(称为 3D 并行,TP+PP+CP)。Meta 自己训 Llama 3 405B 用的是 4D 并行(FSDP + TP + PP + CP):主训练跑在 8,192 张 H100(TP8 × PP16 × DP64,序列 8,192,BF16 MFU 43%——MFU 指"实际算力 ÷ 硬件峰值算力",43% 就是跑到了峰值的 43%),也扩到过 16,384 张(TP8 × PP16 × DP128);128K 长上下文那档再加 CP=16(Llama 3 论文 §3.3.1 的配置表)。NVIDIA NeMo 的 FP8 基准对应 TP8 × PP9 × CP2 × DP4(VP=7)——这一配置的总卡数在 NVIDIA 官方文档之间不一致:有文档记 512 张(https://docs.nvidia.com/dl-cuda-graph/examples/llama-31-405b.html),而按并行度连乘 8×9×2×4 = 576,两者对不上。本课不替它选定一个,引用时两处数字与来源都要注明。

上一张卡片把四把刀的判据收敛成一句话:每层都要用的只能在 NVLink 域内切(TP≤8),天然分散的可以跨节点切(PP/CP/EP)。所以这一张就用这句话去拆真实的配置——先从"每个维度为什么取这个值"开始推。

组合的原则可以类比成装箱:先按"不能跨箱的易碎品"(TP)确定内层格子,再按"可以摆远的东西"(PP/CP)确定外层货架,剩下的空间全部留给 DP(复制模型、铺开数据)。

🧮 第六笔账:拆开 1024 这个数
Step 1:每个维度为什么取这个值
维度取值为什么是这个数
TP8一个 NVLink 域 8 张卡(H100 为 900 GB/s);TP 跨节点会因通信而吃亏
PP8126 层 ÷ 8 ≈ 每段 16 层;跨节点只传激活,带宽要求低
CP2训练序列 ≥8K(含 8K)即可启用;切 2 份,每卡一半
DP8剩下的全给它:1024 ÷ (8 × 8 × 2) = 8
校验:8 × 8 × 2 × 8 = 1024 ✓。四个维度不是拍脑袋,而是按"能不能跨节点"的顺序依次定下来的。
Step 2:四种真实配置横向比
来源卡数TPPPCPDP校验式
Megatron-Core 推荐(405B)1,02488288×8×2×8 = 1024
NeMo FP8 基准(405B)512 或 576(源不一致)89248×9×2×4 = 576(某文档记 512)
Meta 实际(8K 序列)8,1928161648×16×1×64 = 8,192
Meta 实际(扩容档)16,38481611288×16×1×128 = 16,384
除 NeMo 那行外,其余三行都能整除回原数(NeMo 行记 512 与连乘 576 对不上,属源文档不一致)。请注意一个共同点:TP 全部是 8,没有一家开到 16 以上——这正是上一张卡片"通信/计算比随 TP 涨约 9 倍"的直接工程后果。
Step 3:MoE 的最小卡数不能连乘
项稠密模型MoE 模型
最小卡数(DP=1)PP × TP × CPPP × 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
算术:16 × max(2, 64) = 16 × 64 = 1,024。如果按"连乘"的直觉算,会得到 16 × 2 × 64 = 2,048——比真实最小卡数大一倍。这是 MoE 并行里最常见的算错点:专家要跨卡 all-to-all 汇总后,每张卡再算自己那部分 logits(logits = 模型输出的、还没做归一化的原始分数向量),两张网格是重叠的,不是相乘的。
口径注意:这里的 TP=2 是 NVIDIA 的推荐值;DeepSeek 自己训 V3 时用的是 TP=1(见上一张卡片),代入 max(·) 后结果同样是 1,024。
🎯 关键认知

组合拳只有三条判据:① 每层都要用的东西(权重)→ 只能在 NVLink 域内切,TP ≤ 8;② 天然分散的东西(层 / token / 专家)→ 可以跨节点切,PP / CP / EP;③ 剩下的全部给 DP。先定 TP(受硬件约束),再定 PP/CP(受显存与序列约束),最后用 DP 把卡数凑到目标值。记住这个顺序,任何并行配置表你都能自己拆开——也能一眼看出哪些数字是错的。

AI 助教
👋 对配置有疑问?比如"DP 为什么总是最大的那个数?""GB200 NVL72 会改变什么?"

我会用具体数字帮你算。