跳到正文
动手理解 · CONCEPT LAB

同样一组 GPU,切哪里会发生什么通信?

DP 切 batch,TP 切层内矩阵,PP 切层,SP/CP 切不同范围的序列激活,EP 切专家,ZeRO/FSDP 切模型状态。它们解决的不是同一个“放不下”。

已经发生 正在观察 接下来
01 / 06

状态传导图

B0 Batch 分片 0
GPU0 完整模型
GRAD0 本地梯度
AR All-Reduce
UPDATE 一致更新

模型副本相同,数据不同;通信集中在梯度同步。

观察点 01

每张卡一份模型,各算不同样本再同步梯度

GPU 看到不同 mini-batch,前向和反向独立进行;随后对梯度做 All-Reduce,让每份模型用相同更新。模型仍需单卡放得下。

单卡模型副本完整复制
层内通信频率主要同步梯度
此刻要记住

DP 主要扩吞吐,不直接解决一份模型权重放不下。

训练系统 · Distributed Training

分布式训练:把一个训不动的大模型切到几千张 GPU 上

大模型训练不是“多买几张卡就自动变快”。你要决定:样本怎么切、矩阵怎么切、层怎么切、长序列怎么切、专家怎么切、优化器状态怎么切。切错了,显存省了但通信爆了;切对了,千卡才能像一个系统一样工作。

← 左右滑动查看完整链路 · 打开原图

先看“切哪一维”,再看“用什么通信拼回结果”:SP 与 CP 虽都沿序列切,但覆盖模块不同;图中 EP 展示最常见的 All-to-All 去程与回程,当前框架还可能提供 All-Gather 或 Flex dispatcher。
00 · 先抓住

分布式训练就是把“放不下、算太慢、搬太多”分别拆开

生活类比
做一部电影:DP 像多组同时拍不同镜头;TP 像多人一起做同一个复杂特效镜头;PP 像前期、剪辑、调色流水线;ZeRO/FSDP 像把道具清单分给不同仓库保管。
容量下界
70B 参数仅以 BF16/FP16 存权重就是 70×10⁹×2 bytes ≈ 140 GB(十进制),已超过单张 80GB GPU;训练还需梯度、优化器状态、激活和临时 buffer。实际是否保留 FP32 master weights 取决于精度与优化器实现。
先记一句DDP 切 batch,TP 切层内矩阵,PP 切层,SP 切部分序列维激活,CP 切全网络序列,EP 切专家,ZeRO/FSDP 切模型状态。
真正难点切开以后要拼回正确结果,通信会变成新的瓶颈。
读法初学者先看“切什么”;进阶读者再看 all-reduce、all-gather、reduce-scatter、all-to-all 的通信代价。
01 · 为什么分布式

单卡放不下,多卡也不等于自然训得动

训练显存不只是权重,还包括梯度、优化器状态、激活与临时通信/算子 buffer。70B FP16/BF16 权重约 140GB;若再用 BF16 梯度、FP32 Adam 一阶/二阶矩并保留 FP32 master weights,一个常见粗算可到每参数约 16 bytes。这个数字会被混合精度策略、量化优化器和分片方式改变,不能当固定常数。

手算:70B 的“16 bytes/参数”示意从哪来

一种常见混合精度账本:BF16 参数 2B + BF16 梯度 2B + FP32 master 参数 4B + Adam 的 FP32 m/v 8B = 16B/参数。于是模型状态约 70×10⁹×16 = 1.12 TB,尚未计激活和临时 buffer。理想 ZeRO-3/FSDP full-shard 在 16 卡上把这部分均分为约 70 GB/卡;真实峰值还要加层级 all-gather、prefetch、碎片和激活。

容量问题

单卡装不下权重、梯度、优化器状态和激活。需要 ZeRO/FSDP/TP/PP 把状态拆开。

吞吐问题

数据量太大,单卡训练周期不可接受。需要 DP 扩 batch、TP/PP 扩模型计算。

通信问题

不同切法引入不同频率与大小的 collective/P2P;拆得更细不一定总字节更多,但常更依赖延迟、拓扑和 overlap。

并行方式切什么主要通信典型目的
DDP数据 / batchgradient all-reduce模型能单卡容纳时扩吞吐,工程相对成熟。
TP矩阵 / hidden dimensionall-reduce / all-gather单层矩阵太大时切计算。
PP层 / pipeline stagestage 间传激活和梯度模型层数太多时切模型。
SP / CP序列维激活(范围不同)gather/scatter、P2P 或 all-to-all 等SP 配合 TP 省部分激活;CP 面向长上下文切全网络序列。
EPMoE 专家典型为 all-to-all;也有 all-gather / flex dispatcher专家太多时切专家权重和 token 路由。
ZeRO / FSDP参数、梯度、优化器状态all-gather / reduce-scatter让每卡不再复制全套训练状态。
02 · Data Parallel

DP:每张卡一份模型,各算一部分 batch,再同步梯度

经典 DDP 把模型复制 N 份,数据切成 N 份,各 rank 前向/反向后同步梯度。它能提高吞吐,但完整模型和未分片状态仍要在每卡存在;ZeRO/FSDP 属于数据并行域内的状态分片,正是为突破这个限制。

W=1Ni=1NWi(all-reduce gradients)\nabla W=\frac{1}{N}\sum_{i=1}^{N}\nabla W_i\quad(\text{all-reduce gradients})

上式假设每个 rank 的本地样本数相同、loss 采用相同归一化。若有效样本数因 padding/mask 不同,应按有效权重汇总,不能无条件把 rank 均值再简单平均。

经典 DDP 常以梯度 all-reduce 保持副本一致;bucket 与 backward overlap 可隐藏部分通信。reduce-scatter 更常见于梯度/状态分片方案,不能把它当成所有 DDP 的同义实现。
手算:本地 batch 不等大时
GPU A 用 2 个有效样本得到平均梯度 g_A=1,GPU B 用 6 个得到 g_B=3。直接平均 rank 得 (1+3)/2=2;按样本加权才是 (2×1+6×3)/8=2.5。所以分布式 loss 归一化必须和有效 token/样本口径一致。
两种“不齐”要分开
同一步里有效 token 数不同,是梯度权重问题:应聚合分子与分母或等价加权。各 rank 迭代步数不同,则是collective 次数问题:PyTorch DDP 可用 join() 为已结束 rank 镜像通信;若训练图里还有 SyncBatchNorm 等非 DDP collective,官方要求用提前终止保护,不能靠加权避免 hang。

适合

  • 模型单卡能放下,但数据很多,需要提高吞吐。
  • 大 batch 训练,通信能被计算摊薄。
  • 作为其他并行方式外层组合。

不适合

  • 模型和 optimizer state 单卡放不下。
  • batch 太小,all-reduce 成主要开销。
  • 跨节点网络弱,梯度同步拖慢扩展。
03 · Tensor Parallel

TP:把一层里的大矩阵切开,让多卡合算一个 layer

当单层权重或激活过大,可把线性层按输出维(column parallel)或输入维(row parallel)切给多个 rank。Megatron-LM 通过成对安排 column/row-parallel 线性层,减少需要物化完整中间激活的次数;实际 collective 取决于前后层布局。

Y=XW,W=[W1,W2,,Wk]Y=[XW1,,XWk]Y=XW,\quad W=[W_1,W_2,\ldots,W_k]\Rightarrow Y=[XW_1,\ldots,XW_k]

上式只展示 column shard:每卡算一段输出。是否立刻 all-gather 取决于下一算子能否继续消费分片输出;row shard 则通常需要对局部结果求和。

TP 降低每卡部分权重与计算压力,但层内 collective 频繁、对低延迟高带宽互联敏感。把 TP 放同节点是常见经验,不是所有集群的硬规则。
切法直觉通信
Column parallel每卡算一部分输出通道。可保持分片给下一层,或在需要时 all-gather。
Row parallel每卡持有一部分输入通道权重。局部 matmul 后 all-reduce 求和。
Attention head split不同 rank 计算不同 attention heads。通常在 row-parallel 输出投影处归并,不一定在“前后”都同步。
Megatron Sequence Parallel配合 TP,把 LayerNorm/Dropout 等区域的激活沿序列分片。以 reduce-scatter / all-gather 衔接 TP 区域;不同于长上下文 CP。
04 · Pipeline Parallel

PP:把层切成流水线,但要和“气泡”作斗争

Pipeline Parallel 把模型按层分成多个 stage,不同 GPU 负责不同层。一个 micro-batch 像流水线上的工件,从 stage 0 流到 stage p-1,再反向流回来。

ideal flush-pipeline bubble fractionp1m+p1\text{ideal flush-pipeline bubble fraction}\approx \frac{p-1}{m+p-1}

p=stage 数、m=micro-batch 数。该式是“各 stage 等时、前后向对称、同步 flush、只计理想填充/排空”的简化模型;GPipe flush 与基础非交错 1F1B 在这些假设下具有同一 bubble fraction。交错/virtual pipeline、stage 不均衡、前后向耗时不等与通信会改变结果。

PP 的核心问题是 bubble 与 stage 不均衡。GPipe 用 micro-batch 填流水线;基础 1F1B 的主要优势是更早反向、降低峰值激活,而不是在上述理想模型里自动消灭 bubble。交错 1F1B 可用 virtual stages 进一步缩短气泡,但调度与通信更复杂。
手算:简化 bubble 比例
p=4m=8,简化式给出 (4-1)/(8+4-1)=3/11≈27.3%。把 micro-batch 增至 32 时变为 3/35≈8.6%;但 micro-batch 更小可能降低单次 GEMM 利用率,数量更多也会增加调度开销,所以不是越多越好。
优点

按层切模型,适合很深且单卡装不下的场景。与每层多次 collective 的 TP 相比,PP 通信频率通常更低,因此常被考虑跨节点放置;仍需核对激活张量大小和网络。

代价

有 pipeline bubble、调度复杂、stage 负载不均会拖慢整体;激活保存和重计算策略也更难。

05 · ZeRO / FSDP

ZeRO/FSDP:按数据并行组分片模型状态

普通 DDP 每卡复制参数、梯度和优化器状态。ZeRO 按 stage 分片这些状态;PyTorch 现有 FSDP1 wrapper 与 FSDP2 fully_shard 两套接口。两者的 full-shard 数据流都可抽象为计算前 All-Gather 参数、反向后 Reduce-Scatter 梯度,概念上接近 ZeRO-3,但参数表示、API、调度和 state dict 不能混为同一实现。

← 左右滑动查看完整链路 · 打开原图

绿色表示持久状态已按 DP 组分片;stage 定义“哪些状态被切”,不唯一规定每个实现的 collective。Stage 3 / full shard 不代表计算时永远没有完整参数:轮到某层时仍需按需 All-Gather,再在反向 Reduce-Scatter 梯度。
ideal full-shard persistent state/GPUparams+grads+optimizer statesN\text{ideal full-shard persistent state/GPU}\approx \frac{\text{params}+\text{grads}+\text{optimizer states}}{N}

这只近似 ZeRO-3 / full-shard 的持久模型状态理想均分,不适用于 ZeRO-1/2,也不包含激活、临时 all-gather、prefetch、未分片模块、bucket 和内存碎片。

阶段切什么直觉
ZeRO-1Optimizer statesAdam 的一阶/二阶矩,以及实现中属于优化器状态的 FP32 master weights,不再每卡全量复制。
ZeRO-2Optimizer states + gradients梯度也分片,反向后 reduce-scatter。
ZeRO-3 / FSDP full shard参数 + 梯度 + 优化器状态参数也分片,计算模块前按需 all-gather;FSDP 另有不分/只分梯度等策略。
OffloadCPU/NVMe进一步救 GPU 显存,但会付带宽/延迟代价。
截至 2026-07-14 的 PyTorch 边界
FSDP1FullyShardedDataParallel wrapper 和 flat-parameter/state-dict 语义为主;FSDP2fully_shard 给每个参数建立 DTensor 分片,并在 forward/backward hook 中按需 all-gather、reshard 与 reduce-scatter。当前官方文档建议 FSDP1 用户评估迁移,但这不表示两套 checkpoint 可直接互换;迁移与恢复都应按具体版本做 round-trip 测试。
一句话
ZeRO/FSDP 最像“仓储系统”:每张卡只保管一部分模型状态,轮到某层计算时临时把需要的权重取出来,算完再还回去。它省显存,但会增加通信和调度复杂度。
06 · SP / CP / EP

SP 与 CP 分工不同;MoE 再沿专家维切

长序列会近似线性增加多数激活,并增加 attention 计算;是否保存二次方 attention 矩阵取决于 FlashAttention 等实现。Megatron SP 与 CP 都沿序列维分片,但覆盖模块不同;MoE 的 EP 则沿专家维分布权重并路由 token。

SP/CP

先区分 Sequence 与 Context Parallel

same axis, different scope
Megatron SP配合 TP,只让 LayerNorm、Dropout 等不必跨 token 交互的区域保持序列分片;进入 TP 线性层时通过 gather/scatter 转换布局。CP则把输入和所有层激活都沿序列分片,attention 必须通过 P2P/ring、all-gather 或 all-to-all 变体获得其他分片的 KV。

所以 SP 主要减少 TP 中原本重复保存的部分激活;CP 才是面向超长上下文、让每卡只常驻一段序列的并行维度。Megatron CP rank 仍复制模型权重,因此 backward 的 weight gradients 还要沿相应数据并行/CP 组归并;切序列不等于把权重也切掉。

EP

Expert Parallel

split experts
standard EP path: routerall-to-all dispatchexpertsall-to-all combine\text{standard EP path}:\ \text{router}\rightarrow\text{all-to-all dispatch}\rightarrow\text{experts}\rightarrow\text{all-to-all combine}
不同 GPU 持有不同专家。标准路径是 Router 选专家后用 All-to-All 把 token 发到 owner,专家算完再 All-to-All 返回;这不是唯一 dispatcher。当前 Megatron Core 还提供 All-Gather 与 Flex 路径,后者可接 DeepEP / HybridEP。
和 MoE 专题怎么连
MoE 专题里重点讲标准 All-to-All EP:MoE 省每 token 计算,但 dispatch/combine 若没有与专家 FFN 重叠,扩展效率会很快掉下来。当前 Megatron Core 还要求 TP 与 EP 同开时启用 SP;这是该框架的数据布局约束,不能外推成所有 EP 实现的数学定律。
07 · 怎么组合

真实大模型训练不是选一个并行,而是组合多组 rank

“3D/4D/5D”是常见教学简称,不是统一标准。TP、PP、CP、EP、DP 的分组要同时满足模型形状、全局 batch、序列长度与网络拓扑;ZeRO/FSDP 又是在数据并行域内选择状态分片策略。对 MoE 而言,attention 与 expert 甚至可以采用不同的 rank 映射。

← 左右滑动查看完整拓扑 · 打开原图

图中集群部分故意展示传统笛卡尔积 placement:横轴是 PP stage、纵轴是 DP replica,节点内部展开 TP×CP×EP;它不是固定模板。当前 Megatron MoE Parallel Folding 可分别定义 attention 的 TP×CP×DP×PP 与 expert 的 ETP×EP×EDP×PP,让物理 rank 复用而不是把 CP、EP 度数机械相乘。
新边界:MoE Parallel Folding
把并行度相乘只适合解释一类传统 rank grid。当前 Megatron Core 可把 attention 与 expert 的并行映射“折叠”在同一批 GPU 上:attention 侧用 TP×CP×DP×PP,expert 侧可改用 ETP×EP×EDP×PP。两套映射都覆盖同一个 world,因此满足 TP×CP×DP×PP = ETP×EP×EDP×PP = world size;CP 与 EP 是在同一批 ranks 上重映射,不再机械相乘。
组合解决什么常见取舍
DP + ZeRO/FSDP复制的模型状态成为容量瓶颈。分片程度越高,持久状态越少,但参数 gather 与调度更复杂。
TP + DP单层矩阵太大,同时要扩吞吐。TP 放节点内高速互联,DP 放外层。
TP + PP + DP大 dense Transformer 经典 3D 并行。要平衡 pipeline bubble、TP 通信和全局 batch。
DP + TP + PP + EPMoE frontier 模型。all-to-all 和 all-reduce 同时存在,调度复杂。
SP + TP减少 TP 区域之间原本重复保存的部分激活。SP 不负责让每个 attention 只常驻一段超长上下文;需要与 TP 的布局转换配套。
CP + FlashAttention长上下文的跨卡容量与单卡 attention I/O。CP 分片序列并引入跨 rank KV 通信;FlashAttention 降低各 rank 内 attention 的 HBM 往返,两者解决不同层级的问题。
低精度 + 并行降低部分参数、激活或通信张量的字节数。并非使用 FP8/FP4 就自动压缩所有 collective;通信 dtype、累加精度和 scale 策略必须逐路径确认。
拓扑

并行策略要贴着硬件拓扑设计

topology-aware parallelism
常见起点是把高频 TP collective 放在 NVLink/NVSwitch 等高速域,把 DP/PP 扩到节点间;EP 还要结合 all-to-all 拓扑与 token 负载。最终方案应以实测通信时间、MFU、峰值显存和尾延迟决定,而不是把这条经验当硬规则。
08 · 常见误区

分布式训练不是“卡越多越快”

误区 1:DDP 能解决所有显存问题

经典 DDP 复制模型状态;超出单卡容量时可选 ZeRO/FSDP、TP、PP 或它们的组合,不是只有一种必选方案。

误区 2:TP 越大越好

TP 会增加层内通信。超过高速互联范围后,通信可能吞掉计算收益。

误区 3:PP 没有通信瓶颈

PP 通信较粗,但有 bubble 和负载均衡问题;micro-batch 太少会空等。

误区 4:ZeRO/FSDP 只省不花

它省显存,但参数 all-gather、reshard、prefetch 都会增加通信和实现复杂度。

误区 5:MoE 只省计算

MoE 会引入 EP 和 all-to-all。专家路由不均衡时,慢专家决定整层速度。

误区 6:只看 checkpoint 能写出

超大训练还要验证恢复:模型、优化器、scheduler、RNG 与数据游标缺一不可;并行拓扑改变后是否能 reshard,也必须实际演练。

验收

并行方案上线前要对四本账

correctness · memory · speed · recovery
数值账单卡/小规模基线与目标拓扑的 loss、梯度和短程收敛是否在容差内;不能只看“能跑”。
显存账同时记录 allocated、reserved 与峰值,并覆盖 warmup、首次 all-gather、重计算和 optimizer step。
性能账看 tokens/s、step time、扩展效率、collective overlap 和慢 rank;MFU 只是一种派生口径。
恢复账做真实 save→kill→load→继续训练。PyTorch Distributed Checkpoint 支持多 rank 保存与 load-time resharding,但应用仍要完整保存非模型状态,并验证不同拓扑的恢复路径。
速查

一句话总结

Cheat sheet
DP切 batch,模型复制;靠 all-reduce 同步梯度。
TP切矩阵/hidden/head;层内通信频繁,适合同节点高速互联。
PP切层;用 micro-batch 填流水线,核心问题是 bubble。
ZeRO/FSDP切参数/梯度/优化器状态;省显存,增加 gather/scatter。
SP / CPSP 配合 TP 分片部分非 attention 激活;CP 分片全网络序列并为 attention 交换 KV。
EP切 MoE 专家;标准 dispatcher 常用双向 all-to-all,具体框架也可能用 all-gather / flex。
资料来源

主要参考