Prhub

#7221 [megatron] feat: support contiguous context-parallel layout for DeepSeek V4

原始 PR 作者 ISEEKYAN 合并时间 2026-08-01 12:23 文件变更 6 提交数 3 评论 1 代码增减 +250 / -14

执行摘要

Megatron 新增 contiguous CP 布局支持 DeepSeek V4

PR body 明确指出 DeepSeek V4 的注意力期望每个 CP rank 拥有全局 padded THD buffer 的一个连续区间,而现有 zigzag 布局给每个 rank 的是从序列两端取出的块,"Running DS4 under the zigzag layout silently produces wrong attention results." 即静默产生错误注意力结果,因此需要引入 contiguous 布局并自动为 DS4 启用,同时保持默认 zigzag 以向后兼容。

值得精读。这是 Megatron THD 数据通路的核心切片逻辑变更,展示了如何为特定注意力变体扩展序列并行布局而不破坏默认路径。关注点:_get_context_parallel_layout 的集中决策方式、contiguous 切片的区间求交写法、以及 postprocess 的按序拼接反解。对需要在 Megatron 后端接入新模型并行语义的工程师有直接参考价值。上线前需要补齐 DS4 端到端回归与更大 CP 规模验证。

讨论亮点

该 PR 未收到人工 review 评论,仅有 Gemini 机器人提示服务停用的自动化评论。设计权衡集中在 PR body:

1) roll 语义按布局拆分,全局 torch.roll 仅用于 zigzag,contiguous 逐序列独立 roll;
2) 未知 cp_layout 显式抛 ValueError 而非静默回退;
3) 双 GPU 验证以 CP1 单卡为参考,并额外运行两次 CP1 测量确定性下限。

实现拆解

  1. THD 预处理入口扩展(verl/models/mcore/util.py):preprocess_thd_engine 与 postprocess_thd_engine 新增 cp_layout: Literal["zigzag", "contiguous"] = "zigzag" 参数,并在入口校验非法值直接抛 ValueError。对齐因子改为 tp_size * cp_size * cp_layout_factor,其中 cp_layout_factor 仅在 zigzag 且 cp_size > 1 时为 2,避免 contiguous 布局下的过度 padding。
  2. contiguous 切片与独立 roll:在 preprocess_thd_engine 中,每个 rank 计算自己在全局 padded buffer 上的区间 [shape[0] * cp_rank, shape[0] * (cp_rank + 1)),逐序列求交集后拷贝;跳过与本地区间无交集的序列。需要 roll 时,用 (idx + 1) % seqlen 逐序列独立 roll,不再做 zigzag 所需的全局 torch.roll。
  3. postprocess 反解:postprocess_thd_engine 在 contiguous 模式下按 CP rank 顺序 torch.cat 各 rank 输出,再按 cu_seqlens 切回每条有效序列,恢复原始嵌套张量结构;zigzag 路径保持不变。
  4. 引擎层统一布局决策(verl/workers/engine/megatron/transformer_impl.py):MegatronEngine 新增静态方法 _get_context_parallel_layout(unwrapped_model),按 experimental_attention_variant == "dsv4_hybrid" 返回 contiguous,否则返回 zigzag。LM head 的 forward_step(fused 与非 fused)和 value head 的 forward_step 都调用该方法并把 cp_layout 传给前向函数,避免两条路径漂移。
  5. 前向路径透传(verl/models/mcore/model_forward.py、model_forward_fused.py):gptmodel_forward_model_engine 与 fused_forward_model_engine_inner 增加 cp_layout 参数,并在所有 preprocess_thd_engine / postprocess_thd_engine 调用点透传。测试配套:新增/扩展 CPU 单测覆盖区间选择、独立 roll、postprocess 反解和非法布局报错,value head 布局透传测试保证引擎层改动被覆盖。
文件 模块 状态 重要度
verl/models/mcore/util.py 序列预处理 modified 7.47
verl/workers/engine/megatron/transformer_impl.py 引擎层 modified 6.83
tests/utils/test_megatron_bshd_preprocess.py 测试 modified 6.86
tests/workers/test_megatron_value_head_cp_layout_on_cpu.py 测试 added 6.07
verl/models/mcore/model_forward.py 前向路径 modified 6.04
verl/models/mcore/model_forward_fused.py 前向路径 modified 6.13

关键符号

preprocess_thd_engine postprocess_thd_engine _get_context_parallel_layout gptmodel_forward_model_engine fused_forward_model_engine_inner

关键源码片段

verl/models/mcore/util.py core-logic

THD 序列预处理 / 后处理的核心实现,新增 cp_layout 参数以支持 contiguous 布局,是本次变更的技术核心。

# verl/models/mcore/util.py — contiguous 布局下每个 rank 取全局 padded buffer 的连续区间
local_global_start = shape[0] * cp_rank
local_global_end = local_global_start + shape[0]
​
for i in range(batch_size):
    if cp_layout == 'contiguous':
        # 本条序列在全局 buffer 中的起点与有效终点(不含 padding)
        seq_global_start = cu_seqlens_padded_cpu[i]
        seq_valid_end = seq_global_start + seqlens_in_batch_cpu[i]
        # 与本 rank 区间求交;完全不相交则跳过
        copy_global_start = max(local_global_start, seq_global_start)
        copy_global_end = min(local_global_end, seq_valid_end)
        if copy_global_start >= copy_global_end:
            continue
​
        # 换算为序列内偏移与本地缓冲内偏移
        source_start = copy_global_start - seq_global_start
        source_end = copy_global_end - seq_global_start
        destination_start = copy_global_start - local_global_start
        destination_end = copy_global_end - local_global_start
        d = input_ids[i]
​
        if need_roll:
            # contiguous 布局按序列独立 roll:(idx + 1) % seqlen
            source_indices = torch.arange(source_start, source_end, device=d.device)
            source_indices = (source_indices + 1) % seqlens_in_batch_cpu[i]
            input_ids_rmpad[destination_start:destination_end] = torch.index_select(d, 0, source_indices)
            position_ids_rmpad[destination_start:destination_end] = source_indices
        else:
            input_ids_rmpad[destination_start:destination_end] = d[source_start:source_end]
            position_ids_rmpad[destination_start:destination_end] = torch.arange(
                source_start, source_end, dtype=torch.long, device=input_ids.device
            )
        continue
verl/workers/engine/megatron/transformer_impl.py core-logic

MegatronEngine 新增 _get_context_parallel_layout(),统一 policy 与 value head 的 CP 布局选择,避免两条路径漂移。

# verl/workers/engine/megatron/transformer_impl.py — 统一 CP 布局决策
@staticmethod
def _get_context_parallel_layout(unwrapped_model) -> str:
    # DeepSeek V4 的注意力通过 rank 本地 global_start 寻址行,
    # 必须使用 contiguous 布局;其余模型保持 zigzag 以利用因果掩码负载均衡。
    if getattr(unwrapped_model.config, 'experimental_attention_variant', None) == 'dsv4_hybrid':
        return 'contiguous'
    return 'zigzag'
​
# forward_step 中,LM head 与 value head 统一从这里取布局再透传
unwrapped_model = unwrap_model(model)
cp_layout = self._get_context_parallel_layout(unwrapped_model)

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

端到端验证缺口:PR body 明确说明没有覆盖经过 DeepSeek V4 model provider 的 SFT 路径,只验证了原生 mcore 模块;verl main 不存在不依赖 Megatron-Bridge 的 deepseek_v4 provider。CP 规模覆盖有限:仅验证 CP 1 和 CP 2,更大 CP 规模未实测,跨序列 straddle 行为在更大 CP 下可能有边界问题。负载均衡特性变化:zigzag 专为因果掩码负载均衡设计(每个 rank 拿序列两端),contiguous 会使长序列的尾部区间集中到部分 rank,DS4 下这是内核要求,但长尾场景的显存/计算倾斜需要观察。动态 CP 组合未验证:local_cp_size(动态 CP)路径与 cp_layout 的组合没有测试,如果 DS4 与动态 CP 一起使用需要额外验证。核心数据通路变更:preprocess_thd_engine / postprocess_thd_engine 是 Megatron THD 训练的统一入口,虽然默认分支未动,但任何对公共函数的修改都值得在常规模型上跑一次回归。

影响范围:主要影响 Megatron 后端 + THD(use_remove_padding)路径,对使用 experimental_attention_variant == 'dsv4_hybrid' 的 DeepSeek V4 用户,CP 布局自动变为 contiguous;其他模型与 cp_size == 1 场景完全不受影响。同时改动多个模型前向入口的数据契约(新增可选参数),对内部 API 调用方有传导。团队影响:为 DS4 在 verl 的训练支持补齐关键的一块拼图。

核心预处理路径变更 端到端 DS4 训练未验证 CP 规模大于 2 未覆盖 contiguous 改变负载均衡特性 动态 CP 与 cp_layout 组合未验证

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论