Chapter 04

核心概念:rank / parallel state / micro-batch

📌 本章引用的所有源码路径与符号名均基于 NVIDIA/Megatron-LM · commit 432d76b2b8bf 。

阅读 Megatron 源码或调试它的训练任务,必须先把下面这一组"词汇表"内化掉。这一章不教你"怎么做",而是给你一份字典,后续 5–10 章会反复用到它们。

4.1 rank 一族:global / dp / tp / pp / ep / cp

PyTorch 原生只有一个 rank(全局编号),Megatron 把它拆成了一组:

名字含义从哪取
global rank 这张卡在整个集群里的编号,$0 \sim W{-}1$ torch.distributed.get_rank()
data parallel rank 在 DP group 内的位置 parallel_state.get_data_parallel_rank()
tensor parallel rank 在 TP group 内的位置 parallel_state.get_tensor_model_parallel_rank()
pipeline parallel rank在 PP group 内的位置(即第几个 pipeline stage) parallel_state.get_pipeline_model_parallel_rank()
expert parallel rank 在 MoE expert group 内的位置 parallel_state.get_expert_model_parallel_rank()
context parallel rank 在 CP group 内的位置(沿 sequence 维切分) parallel_state.get_context_parallel_rank()
提示 源码里有时会用别名 mpu(model parallel utility)—— 它是 from megatron.core import mpu,等价于 parallel_statepretrain_gpt.py 顶部就 import 了 mpu

为什么要拆这么细? 因为一张物理 GPU 同时属于多个 group:它既是某个 DP group 的一员(要做梯度 all-reduce),又是某个 TP group 的一员(要做参数 all-gather),还是某个 PP group 的一员(要把激活值传给下一个 stage)。每种 group 都有自己独立的通信拓扑,所以 rank 必须分别记。

举个具体例子。8 卡机,配 $\mathrm{TP}=2,\;\mathrm{PP}=2,\;\mathrm{DP}=2$:

flowchart LR subgraph PP0 [pipeline stage 0] subgraph DP00 [dp_rank=0] R0(("R0
tp=0")) R1(("R1
tp=1")) end subgraph DP01 [dp_rank=1] R2(("R2
tp=0")) R3(("R3
tp=1")) end end subgraph PP1 [pipeline stage 1] subgraph DP10 [dp_rank=0] R4(("R4
tp=0")) R5(("R5
tp=1")) end subgraph DP11 [dp_rank=1] R6(("R6
tp=0")) R7(("R7
tp=1")) end end R0 -. all-reduce TP .- R1 R2 -. all-reduce TP .- R3 R4 -. all-reduce TP .- R5 R6 -. all-reduce TP .- R7 R0 ==> R4 R1 ==> R5 R2 ==> R6 R3 ==> R7

掌握"一张卡同时持有多个身份"是后面读所有并行代码的前提。

4.2 parallel state:那个全局对象

megatron/core/parallel_state.py 维护一组 module-level 全局变量,记录上面这些 group。初始化它的入口是:

parallel_state.initialize_model_parallel(
    tensor_model_parallel_size=2,
    pipeline_model_parallel_size=2,
    # virtual_pipeline_model_parallel_size=None,
    # context_parallel_size=1,
    # expert_model_parallel_size=1,
)

这一个调用之后,整个进程后续所有 get_xxx_rank()get_xxx_world_size()get_xxx_group() 才有意义。在你的最小例子 examples/run_simple_mcore_train_loop.py 里,initialize_distributed() 就在干这件事。

陷阱 parallel_state进程级单例。一旦初始化,想换一套并行配置必须先 parallel_state.destroy_model_parallel()。在多次启动 / 测试场景容易出错。

4.3 micro-batch vs global-batch

Megatron 里"batch"有两层含义,记混就理解不了 PP:

名字含义CLI flag
micro batch 一次 forward 实际进 GPU 的样本数 --micro-batch-size
global batch一次 optimizer step 累计的样本数 --global-batch-size

三者关系(设 micro batch 为 $b$,micro batch 数为 $m$,数据并行度为 $d$):

$$B_\text{global} = b \times m \times d$$

关键变量 $m$(num_micro_batches:一次 optimizer step 内塞进 pipeline 的小批次数量。它对 pipeline bubble 影响巨大——越大 bubble 占比越小,但单步显存越紧。

$$\mathrm{Bubble\ Ratio} \approx \frac{\mathrm{PP}-1}{m + \mathrm{PP}-1}$$

典型例子(175B 配置):--global-batch-size 1536--micro-batch-size 1,$\mathrm{DP}=12$ →

$$m = \frac{1536}{1 \times 12} = 128$$

记忆口诀:micro 是显存维度,global 是收敛维度,二者通过 pipeline depth × DP 联系起来

4.4 sequence_length / context_parallel / virtual pipeline

这些是稍后才会用到、但概念要早知道的:

名字定义
--seq-length 训练时每条样本的固定 token 长度。Megatron 默认要求所有样本同长,靠 padding / packing 实现。
context_parallel_size(CP) 沿 sequence 维度切分。用于长文本(32K / 128K / 1M)训练,避免一张卡装不下 attention 矩阵。CP=4 表示一条 64K 序列被切成 4 份,每张卡处理 16K,attention 跨卡做 ring。
virtual_pipeline_model_parallel_size(interleaved PP)在物理 PP 之上再做一层"虚拟切分",让每张卡持有多个不连续的 transformer layer,减少 pipeline bubble。

第 8、9 章会详细讲,这里只要知道这些词在说什么维度即可。

4.5 model providers 和 forward step:你需要传给框架的两个函数

Megatron 的训练入口本质上是一个泛型循环,它要求你提供两件东西:

  1. model_provider(pre_process, post_process):告诉框架"给定这个 stage 上应不应该有 embedding 和 output layer,请构造对应 module"。pretrain_gpt.py 里这个函数在 gpt_builders.gpt_builder() 里实现。
  2. forward_step(data_iterator, model) -> (output, loss_func):定义"拿一份 micro batch 跑一次 forward 应该做什么、loss 怎么算"。examples/run_simple_mcore_train_loop.py 第 ~140 行附近就是教科书式范本。

框架自身(pretrain_gpt.py 的 main 函数)只负责调度、optimizer step、checkpoint。算法可变的部分(模型 / 数据 / loss)通过这两个 callback 注入。这种"框架 + 用户回调"的关系一旦内化,后面读源码就知道每个文件的角色。

4.6 dataset config:BlendedMegatronDatasetBuilder 与 mock

预训练的 dataset 抽象比微调复杂:

from megatron.core.datasets.blended_megatron_dataset_builder import BlendedMegatronDatasetBuilder
from megatron.core.datasets.gpt_dataset import GPTDatasetConfig, MockGPTDataset

config = GPTDatasetConfig(
    random_seed=0,
    sequence_length=2048,
    reset_position_ids=False,
    reset_attention_mask=False,
    eod_mask_loss=False,
    tokenizer=...,
    ...
)
train_ds, val_ds, test_ds = BlendedMegatronDatasetBuilder(
    GPTDataset,                         # 或 MockGPTDataset 走假数据
    [train_samples, val_samples, test_samples],
    is_built_on_this_rank=lambda: True,
    config=config,
).build()
角色
BlendedMegatronDatasetBuilder"按权重混合多个数据源"的工厂
GPTDatasetConfig 控制 padding、attention mask、文档分隔
MockGPTDataset 测试用的随机数据源

第 6 章讲得更细,这里先认识它们的名字。

4.7 一张图把这章串起来

flowchart TB S["torchrun 启动 N 个进程"] --> A["① parallel_state.
initialize_model_parallel(TP, PP, ...)"] A --> B["② 拿到 tp_rank, pp_rank,
dp_rank, cp_rank, ep_rank"] B --> C["③ TransformerConfig 描述模型"] C --> D["④ model_provider() 在
每个 stage 构造对应部分"] B --> E["⑤ BlendedMegatronDatasetBuilder
准备数据"] D --> F["⑥ 训练循环:
forward_backward_func(
forward_step, data, model,
num_micro_batches)"] E --> F F --> G["optimizer.step()"] G --> H{"达到 max_steps?"} H -- 否 --> F H -- 是 --> I["save_distributed_checkpoint()"]

后面所有章节都在拆这个流程里的某一格。

4.8 TransformerConfig 字段分类速览

第 5 章会讲 CLI;这里看一下底层 dataclassmegatron/core/transformer/transformer_config.py:52 起的 TransformerConfig208 个字段,分八类:

类别代表字段
架构 num_layers / hidden_size / num_attention_heads / ffn_hidden_size / kv_channels
注意力 attention_dropout / num_query_groups (GQA) / attention_backend
MLA(新) multi_latent_attention / kv_lora_rank / qk_nope_head_dim / qk_rope_head_dim
归一 / 激活 normalization (RMSNorm/LayerNorm) / activation_func / gated_linear_unit
并行 tensor_model_parallel_size / pipeline_model_parallel_size / context_parallel_size / expert_model_parallel_size
精度 fp16 / bf16 / fp8_recipe / params_dtype
MoE num_moe_experts / moe_router_topk / moe_token_dispatcher_type / moe_aux_loss_coeff
2025+ 新 mtp_num_layers / use_packed_sequences / heterogeneous_mode / use_context_parallel

查字段最快:grep -n "^ [a-z_]*:" megatron/core/transformer/transformer_config.py。CLI flag 对应字段名通常 dash → underscore(--num-layersnum_layers)。

4.9 ParallelState 全表:12 种并行维度

megatron/core/parallel_state.py(1790 行)提供 53 个 get_*_world_size / get_*_rank 函数,覆盖如下并行维度:

维度简称典型 group 函数
Tensor Parallel TP get_tensor_model_parallel_group()
Pipeline Parallel PP get_pipeline_model_parallel_group()
Data Parallel DP get_data_parallel_group()
Virtual Pipeline VP get_virtual_pipeline_model_parallel_rank()
Context Parallel CP get_context_parallel_group() (line 1503)
Expert Parallel EP get_expert_model_parallel_group()
Expert Data Parallel ExpDPget_expert_data_parallel_group()
Tensor & Expert ParallelTP×EPget_tensor_and_expert_parallel_group()
Hybrid DP × CP get_hybrid_data_context_parallel_groups() (line 1526)
Embedding(PP 头尾两 stage)get_embedding_group()
Pos Embedding get_position_embedding_group()
Inter-Partial DP(DistOpt) get_data_parallel_group_gloo()

初始化入口:parallel_state.initialize_model_parallel(tp, pp, vp, cp, ep, ...),按笛卡尔积生成所有 group 并存到 module-global 变量里。所有并行的"分卡逻辑"都从这一个函数出发