Prhub

#56429 Revert "[Rocm][Kimi-k3] Fix pipeline_parallel support for the kimik3 DCP mode (#53664)"

原始 PR 作者 shen-shanshan 合并时间 2026-09-12 00:17 文件变更 2 提交数 1 评论 4 代码增减 +0 / -12

执行摘要

回滚 KimiK3 DCP 死代码 fallback,恢复 runner 单一事实来源

PR body 明确指出:#53664 添加的 fallback 是死代码,因为 dcp_local_seq_lens 在 V1 模型 runner(vllm/v1/worker/gpu_model_runner.py)和 MRV2 模块化 runner(vllm/v1/worker/gpu/model_runner.py + cp_utils.py)中都会在 MLA decode 路径运行前被无条件填充。保留 fallback 会掩盖未来 runner 侧的回归——如果某个路径停止填充 dcp_local_seq_lens,layer 会静默派生而不是响亮失败;移除它才能恢复单一事实来源(模型 runner)。

值得快速阅读,作为一个“删除死代码”的范例:作者没有直接 revert,而是通过逐行路径可达性分析论证 fallback 不可达,并解释保留它的危害(掩盖回归、破坏单一事实来源)。对理解 vLLM 中模型 runner 与 attention layer 之间的数据契约,以及 DCP(decode context parallel)的 dcp_local_seq_lens 传递机制有参考价值。

讨论亮点

本次 PR 无实质 review 讨论。reviewer tjtanaa 直接批准(空评论),claude[bot] 仅提示 fork PR 自动审核已禁用。核心论证完全来自 PR body:作者逐条给出了 runner 侧填充 dcp_local_seq_lens 的证据(V1 runner 在 gpu_model_runner.py:2456-2466 无条件填充;MRV2 通过 maybe_prepare_dcp_local_seq_lens() 在 gpu/model_runner.py:1728 填充,helper 仅在 dcp_size == 1 时返回 None,而该分支只在 dcp_world_size > 1 时进入),并说明保留 fallback 会掩盖未来回归。

实现拆解

  1. 删除 MLA attention 层中的 fallback 与断言:在 vllm/model_executor/layers/attention/mla_attention.py 的 MLAAttentionLayer.build() 中,DCP decode 分支(self.dcp_world_size > 1)原本包含 assert seq_lens is not None 以及 if dcp_local_seq_lens is None 时通过 get_dcp_local_seq_lens() 派生的逻辑,本次全部删除(共 10 行)。改动后 decode 分支直接信任 runner 填充的 dcp_local_seq_lens,并保留 dcp_tot_seq_lens_device = seq_lens[:num_decodes] 与 max_seq_len 的 DCP 分区计算。
  2. 移除测试注册表中的 Kimi PP 断言条目:在 tests/models/test_registry.py 的 test_registry_is_pp 参数化列表中,删除了 KimiLinearForCausalLM 和 KimiK3ForConditionalGeneration 两项(原本断言 supports_pp 为 True),避免测试固化已被撤销的行为。
  3. CI 配套验证:通过 /ci run 触发 Buildkite CI,失败作业经 /ci retry 重试后通过,未出现新回归。无配置、依赖或部署变更。
文件 模块 状态 重要度
vllm/model_executor/layers/attention/mla_attention.py 注意力层 modified 5.72
tests/models/test_registry.py 注册表 modified 3.46

关键符号

MLAAttentionLayer.build test_registry_is_pp

关键源码片段

vllm/model_executor/layers/attention/mla_attention.py data-contract

核心变更文件:删除 `MLAAttentionLayer.build()` 中 DCP decode 分支的 assert 与 `get_dcp_local_seq_lens()` fallback,使 runner 成为 `dcp_local_seq_lens` 的唯一生产者。

# MLAAttentionLayer.build() 中 DCP decode 分支(revert 后)
# 这里直接信任 runner 已填充的 dcp_local_seq_lens,
# 不再提供 fallback 派生逻辑,以免掩盖 runner 侧回归。
if num_decodes > 0:
    dcp_tot_seq_lens_device = None
    if self.dcp_world_size > 1:
        # DCP 模式下,dcp_local_seq_lens 由 model runner 构建
        # CommonAttentionMetadata 时无条件填充(V1 与 MRV2 均如此),
        # 因此这里不再需要 assert 或 get_dcp_local_seq_lens() 回退。
        dcp_tot_seq_lens_device = seq_lens[:num_decodes]
        seq_lens = dcp_local_seq_lens
​
        # DCP 分发后,任意 rank 的最大 token 数为
        # ceil(L / (N * I)) * I,其中 L 为 max_seq_len,
        # N 为 dcp_world_size,I 为 cp_kv_cache_interleave_size。
        # 该公式消除 GPU->CPU 同步并最小化 workspace 过量分配。
        num_partitions = self.dcp_world_size * self.cp_kv_cache_interleave_size
        max_seq_len = (
            (max_seq_len + num_partitions - 1) // num_partitions
        ) * self.cp_kv_cache_interleave_size
​
    # 构建 decode 注意力元数据,seq_lens 此时已是 DCP 本地视角
    decode_metadata = self._build_decode(
        block_table_tensor=block_table_tensor[:num_decodes, ...],
        seq_lens_device=seq_lens[:num_decodes],
        max_seq_len=max_seq_len,
        query_start_loc_cpu=query_start_loc_cpu[: num_decodes + 1],
        query_start_loc_device=query_start_loc[: num_decodes + 1],
        num_decode_tokens=num_decode_tokens,
        dcp_tot_seq_lens_device=dcp_tot_seq_lens_device,
    )

评论区精华

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

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

风险与影响

  1. 依赖 runner 契约:删除 fallback 后,若未来某条 runner 路径忘记填充 dcp_local_seq_lens,MLA DCP decode 会直接使用 None 导致运行时错误(如空指针或类型错误)。这是有意为之的快速失败设计,但要求所有 DCP 入口始终遵守契约。
  2. 测试覆盖减少:tests/models/test_registry.py 中 Kimi 两个模型的 PP 断言被移除,未来若 Kimi 模型 PP 支持出现回归,该测试不再拦截。不过这两个条目本就是为 #53664 添加的,移除属于配套清理。
  3. 影响范围:改动位于通用 MLAAttentionLayer.build(),理论上影响所有 MLA DCP 模式模型(如 KimiK3),但由于删除的是不可达分支,实际运行时行为无变化。非 DCP 路径完全不涉及。

对用户和系统无行为变化(死代码删除),但提升了代码可维护性:明确了模型 runner 是 dcp_local_seq_lens 的唯一生产者,注意力层只消费不兜底,降低了未来排查 DCP 相关问题的认知负担。对团队而言,消除了一个可能误导后续维护者的“假 fallback”,避免新路径在未填充 DCP 信息时被静默掩盖。影响面局限在 ROCm + KimiK3 的 DCP 模式相关代码路径,但代码结构上属于通用 MLA 层,需要保证未来所有 runner 路径遵守数据契约。

回滚核心路径变更 依赖 runner 契约 测试覆盖减少

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论