Prhub

#24878 [Bug] Add dsv4 state_type branch to mooncake disaggregation

原始 PR 作者 ch-wan 合并时间 2026-05-10 16:13 文件变更 1 提交数 1 评论 5 代码增减 +7 / -2

执行摘要

修复 Mooncake 后端未传输 DSv4 状态池的 Bug

DSv4 解耦推理时,Mooncake 后端未传输 SWA/compress/indexer 状态池,导致解码节点使用脏数据,产生错误输出,如 gsm8k 问题返回干扰答案。详见 PR body 中的复现步骤和对比结果。

值得精读,尤其是关注解耦推理、MLA 状态传输或 Mooncake 后端的开发者。设计决策(委托 _send_kvcache_generic 而非新建扁平路径)体现了对 MTP 场景兼容性的考量,值得学习。

讨论亮点

Reviewer ShangmingCai 建议将 "dsv4" 分支合并到已有的 state_type in ["swa", "nsa"] 分支中(而非独立分支)。作者 ch-wan 采纳建议,force-push 将 "dsv4" 加入列表,最终 diff 为 +7/-1。

实现拆解

  1. 修改文件python/sglang/srt/disaggregation/mooncake/conn.pymaybe_send_extra 方法。
  2. 变更点:将条件判断从 elif state_type in ["swa", "nsa"] 扩展为 elif state_type in ["swa", "nsa", "dsv4"],并更新注释说明 DSv4 的扁平异构状态池(SWA + compress + indexer)可通过同一 _send_kvcache_generic 路径传输。
  3. 为什么委托而非新建分支:NIXL 使用的按页扁平路径会断言 src_state_item_lens[i] == dst_state_item_lens[i],在 MTP 启用时 decode 的 indexer 池条目是 prefill 的 2 倍,导致断言失败;而委托 _send_kvcache_generic 利用 get_mla_kv_ptrs_with_pp 处理 offset 算术,prefill 写入半大小到自然偏移,decode 的 MTP 半保留不动,这是正确的。
  4. 配套改动:本次无测试文件修改,但 PR body 提供了详细的端到端验证结果(TTFT ~977 ms, TPOT ~6.32 ms, 输出吞吐 ~136 tok/s)。
文件 模块 状态 重要度
python/sglang/srt/disaggregation/mooncake/conn.py 解耦传输 modified 5.71

关键符号

maybe_send_extra

关键源码片段

python/sglang/srt/disaggregation/mooncake/conn.py core-logic

核心变更文件,在 `maybe_send_extra` 方法中添加 `"dsv4"` 分支,复用 `_send_kvcache_generic` 路径,修复 Mooncake 后端 DSv4 状态池未传输的 Bug。

# 文件 : python/sglang/srt/disaggregation/mooncake/conn.py
# 在 maybe_send_extra 方法中,将 dsv4 加入现有的 swa/nsa 分支
# 通过复用 _send_kvcache_generic 处理扁平异构状态池传输if state_type == "mamba":
    # ... 原有 mamba 分支 ...
elif state_type in ["swa", "nsa", "dsv4"]:
    # SWA / NSA / DSv4 混合模型暂不支持 PD 不同 TP 大小
    # DSv4 携带扁平异构状态池 (SWA + compress + indexer)
    # 复用此分支路由到 _send_kvcache_generic,该路径已通过
    # get_mla_kv_ptrs_with_pp 处理了压缩 MLA 的 PP/MTP 布局
    if (
        target_rank_registration_info is not None
        and not self.is_mla_backend
        and self.attn_tp_size != target_rank_registration_info.dst_attn_tp_size
    ):
        raise RuntimeError(
            f"PD Disaggregation does NOT support PD different TP sizes "
            f"for non-MLA {state_type.upper()} hybrid models yet."
        )
    dst_state_indices = req.dst_state_indices
    if len(prefill_state_indices) > len(dst_state_indices):
        logger.warning(...)
        prefill_state_indices = prefill_state_indices[:len(dst_state_indices)]
    elif len(prefill_state_indices) < len(dst_state_indices):
        logger.warning(...)
        dst_state_indices = dst_state_indices[:len(prefill_state_indices)]
    # 最终调用 _send_kvcache_generic 执行实际传输
    prefill_state_indices = np.array(prefill_state_indices, dtype=np.int32)
    dst_state_indices = np.array(dst_state_indices, dtype=np.int32)
    return self._send_kvcache_generic(
        mooncake_session_id=req.mooncake_session_id,
        src_data_ptrs=self.kv_args.state_data_ptrs,
        dst_data_ptrs=dst_state_data_ptrs,
        item_lens=self.kv_args.state_item_lens,
        prefill_data_indices=prefill_state_indices,
        dst_data_indices=dst_state_indices,
        executor=executor,
    )

评论区精华

将 dsv4 分支合并到现有 swa/nsa 分支 设计

Reviewer 建议将 `dsv4` 分支合并到已有的 `state_type in ["swa", "nsa"]` 分支中,而非独立成 `elif state_type == "dsv4"` 分支。

结论:作者采纳建议,将 `"dsv4"` 加入列表,force-push 更新,最终 diff 仅为 +7/-1。 · 已解决

风险与影响

风险较低。变更仅扩展了一个条件分支,复用了已有的传输逻辑,且已在 GB300 1P+1D DSv4-Pro 环境下验证非 MTP 和 MTP 场景均正确。未覆盖的潜在风险:不同 TP 配置下的行为——当前分支在非 MLA 后端且 TP 不匹配时会抛出 RuntimeError,但 NIXL 的 dsv4 分支支持不同 TP(通过 per-page flat path),Mooncake 的 dsv4 分支尚不支持不同 TP,这可能导致未来在某些配置下出错。但 PR 明确标注了此约束。

影响范围限于 Mooncake 后端 + DSv4 模型(如 DeepSeek-V4-Pro)的解耦推理场景;修复了正确的状态传输,使输出与 NIXL 后端及非解耦模式一致;对非 DSv4 模型无影响。影响程度:对于受影响用户,此修复是关键的,恢复正确输出;对于其他用户,无感知。

解耦传输核心路径 缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论