训练系统与 Kernel / 并行与通信 原理笔记进阶 7 分钟阅读 查看源文件 ↗

Megatron-LM 并行策略#

本页内容12 个部分
查看概览图
MEGATRON-LM · 7 STRATEGIES

两条 RankGenerator 路径
约束住七种并行的组合

不是「一个公式覆盖所有」——Dense 与 MoE 两条路径各有自己的 RankGenerator,七种策略在进程组约束下组合。

DDense / Attention 路径
world_size = TP × CP × DP × PP

DP 不用手动指定:DP = world / (TP×CP×PP)

EMoE Expert 路径
world_size = ETP × EP × expert_DP × PP

expert_DP 同样自动推导;ETP 默认 = TP

TP 权重矩阵(列 / 行切)
AllReduce · ReduceScatter
SP 激活值(序列维)
AllGather · ReduceScatter
PP Transformer 层
P2P Send/Recv
DP 训练数据(梯度同步)
AllReduce(+ ZeRO-1/2)
CP 输入序列长度
Ring P2P · AllToAll
EP MoE 专家
AllToAll(Token 路由)
ETP 专家内部权重
独立 TP 组
同一颜色 = 同一张卡持有的那一份
模型规模推荐组合说明
1B–7BDP only单卡放得下
7B–20BTP + DPTP=4/8 走 NVLink
20B–100BTP + PP + DP加流水线跨节点切层
100B+TP + PP + DP + CP长序列加 CP
MoETP/ETP + PP + DP/expert_DP + EP专家层可单独设 ETP
关键约束
六条硬约束决定哪些组合合法

① world 整除 TP×CP×PP;② 单个 RankGenerator 不混合 EP 与 CP;两套生成器允许全局 CP、EP 同时 >1;③ VPP 要求 PP>1;④ SP 要求 TP>1;⑤ world 整除 ETP×EP×PP,ETP 默认 = TP;⑥ order 不以 pp 结尾时两路 DP 须相等。

源码版本 core_v0.18.0 2026-06-22 release · commit ba7b5eb
策略数 7 SP 复用 TP 组,不单独占维度
各拆一样东西、配一种通信 TP 走机内 NVLink,PP 放机间,DP / expert_DP 自动推导
TP · SP · PP · DP · CP · EP · ETPworld = TP × CP × DP × PPworld = ETP × EP × expert_DP × PP

源码版本:Megatron-LM core_v0.18.0(2026-06-22 release, commit ba7b5eb)。核心文件:megatron/core/parallel_state.py、model_parallel_config.py。

训练千亿参数模型,单卡装不下,就得把模型「拆」到成百上千张 GPU 上。怎么拆是关键——拆权重、拆激活、拆层、拆数据、拆序列、拆专家、拆专家内部权重,七种策略各有适用场景,并受源码里进程组和整除约束的限制。

一句话总览:

七种策略各司其职,由两条等式约束组合:Dense/Attention 路径 world = TP × CP × DP × PP,MoE Expert 路径 world = ETP × EP × expert_DP × PP。SP 复用 TP 组(不单独占维度);DP、expert_DP 自动推导。


1. 全局:两条 RankGenerator 路径#

Megatron core_v0.18.0 里不是「一个公式覆盖所有」,而是 Dense 与 MoE 两条路径各有自己的 RankGenerator:

Dense / Attention:  world_size = TP × CP × DP × PP
MoE Expert:         world_size = ETP × EP × expert_DP × PP

Dense 路径的 DP 不用手动指定(parallel_state.py L733–738):

model_size = tensor_model_parallel_size * pipeline_model_parallel_size * context_parallel_size
if world_size % model_size != 0:
    raise RuntimeError(f"world_size ({world_size}) is not divisible by {model_size}")
data_parallel_size = world_size // model_size      # DP = world /(TP×CP×PP)
缩写 拆的对象 核心通信
TP 权重矩阵(列/行切) AllReduce / ReduceScatter
SP 激活值(序列维) AllGather / ReduceScatter(复用 TP 组)
PP Transformer 层 P2P Send/Recv
DP 训练数据(梯度同步) AllReduce(+分布式优化器 = ZeRO-1/2)
CP 输入序列长度 Ring P2P / AllToAll
EP MoE 专家 AllToAll(Token 路由)
ETP 专家内部权重 AllReduce / ReduceScatter(独立 TP 组)

2. 张量并行(TP):把权重矩阵切开#

TP

图源:Parallelism-TP.excalidraw(可编辑)

把单层的权重矩阵切到多卡。对线性层 Y=XAY = XA,Megatron 提供两种切法:

  • 列并行 ColumnParallelLinear(layers.py L778):A=[A0∣A1∣… ]A=[A_0|A_1|\dots] 按列切,权重形状 [out/TP, in],每卡算 Yi=XAiY_i = X A_i(输出是完整 YY 的一段)。
  • 行并行 RowParallelLinear(layers.py L1142):AA 按行切,输入也切,权重 [out, in/TP],各卡算部分结果后 AllReduce 求和。

Transformer 里的巧妙搭配:MLP(第一层列并行、第二层行并行)、Attention(QKV 投影列并行、输出投影行并行)。「列在前、行在后」让两层之间只需 一次 AllReduce(或 ReduceScatter+AllGather),省掉中间通信。

通信非常密集(前向 1 次、反向 1 次集合通信)→ 一般只在节点内 NVLink做 TP。


3. 序列并行(SP):TP 的显存优化搭档#

SP

图源:Parallelism-SP.excalidraw(可编辑)

TP 切不了 LayerNorm / Dropout / 残差——纯 TP 下这些算子的激活在每卡都是完整副本,随序列长度膨胀成显存瓶颈。SP 在这些区域沿序列维切激活,每卡只存 1/TP 长度。

LayerNorm/Dropout 区:[seq/TP, batch, hidden]      ← 按序列切
   ↓ 进 TP 线性层前:AllGather → [seq, batch, hidden]
Attention/MLP 区(TP 切权重)
   ↓ RowParallel 输出后:ReduceScatter → [seq/TP, ...]
Dropout/残差:在切分后的激活上做,显存 1/TP

关键洞察:通信量不变。纯 TP 的 RowParallel 输出本要做一次 AllReduce(= ReduceScatter + AllGather);SP 只是把它拆成两步插到两层之间,却让中间区域省了 1/TP 激活显存。三个通信原语在 tensor_parallel/mappings.py L512–539。

约束:SP 要求 TP > 1(layers.py L952–958,否则自动关闭并告警);SP 复用 TP 组(_TENSOR_MODEL_PARALLEL_GROUP),所以不单独占 world-size 维度。


4. 流水线并行(PP):把层摞成流水线#

PP

图源:Parallelism-PP.excalidraw(可编辑)

把 N 层按层切到不同卡(32 层、PP=4 → 每卡 8 层),数据像流水线依次过 stage,相邻 stage 间 P2P Send/Recv 传激活。核心问题是流水线气泡(bubble)。两种调度(pipeline_parallel/schedules.py):

  • 1F1B(非交错,L2101):warmup 填满流水线后进入稳态,一前向接一反向。
  • 交错式 1F1B(virtual_pipeline_model_parallel_size>1,L958):每卡持有不连续的多组虚拟 stage。
16 层, PP=4, VPP=2:
GPU0: [L1,2]  [L9,10]     GPU1: [L3,4]  [L11,12]
GPU2: [L5,6]  [L13,14]    GPU3: [L7,8]  [L15,16]

理想均衡、忽略通信时,气泡时间相对有效计算时间的比值约为 p−1m→交错 VPP=vp−1m⋅v\dfrac{p-1}{m} \xrightarrow{\text{交错 VPP}=v} \dfrac{p-1}{m \cdot v};非交错时,占总时间的气泡比例则为 p−1m+p−1\dfrac{p-1}{m+p-1}(pp=stage 数, mm=micro-batch 数, vv=虚拟 stage 数)。代价是虚拟 stage 间通信增多。PP 还支持 UCC 后端,更省 GPU SM。约束:VPP 要求 PP > 1。


5. 数据并行(DP):最简单也最常用#

DP

图源:Parallelism-DP.excalidraw(可编辑)

纯 DP 时每卡一份完整模型;与模型并行组合时,每个 DP 副本持有相应模型分片、喂不同数据,反向后 AllReduce 同步梯度。大小自动推导 DP = world /(TP×CP×PP)。Megatron 自实现的 DDP(distributed/distributed_data_parallel.py)优化:连续梯度缓冲区、分桶通信与反向计算重叠、可选 FP32 梯度累加。

分布式优化器(≈ ZeRO-1/2):启用 use_distributed_optimizer 后,优化器状态在相应数据并行组内分片;num_distributed_optimizer_instances 控制分布式优化器实例/分片组划分,取 1 也可使用分布式优化器。典型路径,用 ReduceScatter 替代 AllReduce 同步梯度,再 AllGather 广播更新后的参数:

分布式优化器 / ZeRO 切分模型状态

图源:Parallelism-ZeRO.excalidraw(可编辑)

ZeRO-1:切 优化器状态 ·  ZeRO-2:+ 梯度 ·  ZeRO-3 / FSDP:+ 参数(用通信换显存)

6. 上下文并行(CP):为长序列而生#

CP

图源:Parallelism-CP.excalidraw(可编辑)

Self-Attention 开销随序列长度平方增长,128K/1M 序列单卡放不下。CP 把输入序列沿长度维切到多卡,每卡只持一段。但 attention 要每个 token 看到所有 token → CP 组内必须交换 KV。Megatron 通过 cp_comm_type 支持四种通信:

类型 机制 适用
p2p Ring Attention:KV 环形逐步传递 通用,NVLink 好
all_gather AllGather 收完整 KV 再算 简单,无法重叠
a2a AllToAll(Ulysses)按注意力头拆 头数多时高效
a2a+p2p 分层混合:局部 A2A、跨组 P2P 跨节点分层拓扑

关键交互:CP 与 DP 共享梯度同步组(CP 不切权重,梯度在 DP×CP 范围 AllReduce → _DATA_PARALLEL_GROUP_WITH_CP);单个 RankGenerator 中 EP 与 CP 不同时展开(断言 ep==1 or cp==1);attention 与 expert 使用两套生成器,因此不能据此禁止全局配置同时使用 CP>1 与 EP>1。详见 Packed Sequence × CP。


7. 专家并行(EP):MoE 专属#

EP

图源:Parallelism-EP.excalidraw(可编辑)

MoE 把每层 MLP 换成多个专家,Router 把 token 分给不同专家。EP 把不同专家放不同卡(64 专家、EP=8 → 每卡 8 个),token 经 AllToAll 路由到目标专家卡,算完再 AllToAll 返回。EP 有独立于 TP/DP 的进程组体系(_EXPERT_MODEL_PARALLEL_GROUP 等)。Token 分发三策略(moe/token_dispatcher.py):MoEAllGatherTokenDispatcher / MoEAlltoAllTokenDispatcher / MoEFlexTokenDispatcher。

专家侧变长 matmul 见 Grouped GEMM;高效 dispatch/combine 通信库见 DeepEP。


8. 专家张量并行(ETP):专家内部的 TP#

ETP

图源:Parallelism-ETP.excalidraw(可编辑)

MoE 里 Attention 层和 Expert 层对 TP 的需求可能不同。若专家 FFN 隐藏层小(如 1024),硬套 TP=8 会切成每片 128 维——粒度过小、通信占比过大。ETP 让专家层用独立的、更小的张量并行(如 ETP=2),Attention 仍用 TP=8。通过 expert_tensor_parallel_size 配置,默认 ETP = TP。

ETP 有完全独立的进程组(parallel_state.py L56–60)和独立 RankGenerator(cp=1,专家不参与 CP)。Expert 层用 expt_tp 组而非 attention 的 tp 组(moe/experts.py)。于是两路 DP 各自推导:

Attention 层: DP        = world /(TP × CP × PP)
Expert 层:    expert_DP  = world /(ETP × EP × PP)
# 例 32 GPU, TP=8, ETP=2, EP=4, PP=2:  DP=2, expert_DP=2

约束:world 整除 ETP×EP×PP;Expert 与 Attention 必须用相同 PP 组;order 不以 pp 结尾时两路 DP 须相等。


9. Rank 映射:五维并行怎么落到 GPU#

Rank 映射

图源:Parallelism-rankmap.excalidraw(可编辑)

RankGenerator(parallel_state.py L446)按 order(默认 "tp-cp-ep-dp-pp")把 GPU 编号分解到各维度。设计原则:通信量大的维度排在机内(NVLink),小的排到机间(IB)——所以 TP 组编号最连续(同机 NVLink),PP 组跨度最大(可跨机,P2P 量小)。


10. 组合实战与约束#

模型规模 推荐 说明
1B–7B DP only 单卡放得下
7B–20B TP + DP TP=4/8 走 NVLink
20B–100B TP + PP + DP 加流水线跨节点切层
100B+ TP + PP + DP + CP 长序列加 CP
MoE TP/ETP + PP + DP/expert_DP + EP 专家层可单独设 ETP

关键约束:① world 整除 TP×CP×PP;② 单个 RankGenerator 的 EP/CP 不同时 >1,但全局 CP 与 EP 可通过两套路径组合;③ VPP 要求 PP>1;④ SP 要求 TP>1;⑤ world 整除 ETP×EP×PP,ETP 默认 = TP;⑥ order 不以 pp 结尾时两路 DP 须相等。

源码地图:parallel_state.py(进程组/RankGenerator)· tensor_parallel/layers.py(Column/RowParallelLinear)· tensor_parallel/mappings.py(通信原语)· pipeline_parallel/schedules.py(1F1B/交错)· distributed/distributed_data_parallel.py(DDP)· transformer/moe/token_dispatcher.py、experts.py(MoE/ETP)。


11. 要点回顾#

七种策略各拆一样东西、配一种通信,在进程组约束下组合。 TP 拆权重、SP 拆激活(复用 TP 组)、PP 拆层(micro-batch 填气泡)、DP 拆数据(+分布式优化器=ZeRO-1/2)、CP 拆序列(Ring 交换 KV)、EP 拆专家(AllToAll 路由)、ETP 拆专家内部权重(独立于 Attention 的 TP)。两条等式 world=TP×CP×DP×PP 与 world=ETP×EP×expert_DP×PP 是骨架;TP 走机内 NVLink、PP 放机间、DP/expert_DP 自动推导。

参考:Megatron-LM 源码(core_v0.18.0)· arXiv:1909.08053 · arXiv:2104.04473 · arXiv:2205.05198

版本源码:Megatron-LM core_v0.18.0 parallel_state.py。表中模型规模与并行组合只是规划起点,不能代替显存估算和拓扑测量。

延伸阅读#

相关阅读路线

理解 MoE 的系统执行 ↗