Prhub

#30076 [refactor] Migrate the DeepSeek family and the parallel-request chains (stack 14/15)

原始 PR 作者 ch-wan 合并时间 2026-07-04 17:22 文件变更 4 提交数 1 评论 3 代码增减 +517 / -182

执行摘要

迁移 DeepSeek 配置到声明式系统

作为声明式配置解析迁移堆栈(15 步中的第 14 步)的一部分,将 DeepSeek 系列和并行请求相关的配置从 __post_init__ 内联代码迁移到模块化、可注册的覆盖函数,使每个模型家族的覆盖逻辑独立可测试,最终拆解 server_args.py 的 monolith。

值得精读,特别是 _deepseek_family_overrides 的实现展示了如何将复杂条件分支组织为声明式函数,以及 post-process pass 的拆分模式。测试用例也很完整,可作为后续迁移的参考。

讨论亮点

Codex 机器人指出,在 dummy model 路径上调用 _handle_a2a_moe() 时,_resolved_overrides 尚未初始化,新的 post-process passes 可能引发 AttributeError。作者 ch-wan 回应:已在堆栈步骤 6 中修复——在 __post_init__ 顶部初始化 self._resolved_overrides = [],确保 dummy 路径也能安全使用。

实现拆解

  1. 注册 DeepSeek 家族覆盖函数:在 overrides.py 中使用 @_register_for 注册 _deepseek_family_overrides,集中处理 DSA attention backend 选择、预填充上下文并行逻辑(zigzag/interleave 分支)、aiter preshuffle probe 以及 MLA sm100 trtllm_mla fill。
  2. 提取数据并行和 A2A 后端覆盖为独立 pass:将原本内联的 dp_size==1 重置和 moe_a2a_backend 覆盖拆分为 _data_parallelism_defaults_a2a_backend_overrides_a2a_ep_size 等 post-process passes,每个 pass 可单独测试。
  3. 清理 legacy 代码:在 server_args.py 中删除 _handle_model_specific_adjustments 中对应 DSA 的代码,移除不再使用的 has_fp8_weights_in_checkpoint 导入,并将 enable_dp_attentionep_sizemoe_a2a_backendattn_cp_sizemoe_dense_tp_size 标记为 model_overridable=True
  4. 扩展运行时标志:在 runtime_context.pyFlags 类中添加 enable_dp_attentionenable_dp_lm_headmoe_a2a_backendep_sizemoe_dense_tp_sizeattn_cp_size 六个字段,作为过渡性展平节点。
  5. 补充测试:在 test_model_overrides.py 中新增 test_deepseek_moe_quant_slot_passtest_data_parallelism_and_a2a_passestest_deepseek_family_order_safe_declarations,验证新函数行为,并更新白名单断言。
文件 模块 状态 重要度
python/sglang/srt/arg_groups/overrides.py 覆盖层 modified 8.84
test/registered/unit/test_model_overrides.py 覆盖测试 modified 7.95
python/sglang/srt/server_args.py 配置系统 modified 7.44
python/sglang/srt/runtime_context.py 运行时上下文 modified 5.27

关键符号

_deepseek_family_overrides _deepseek_moe_quant_resolution _data_parallelism_defaults _a2a_backend_overrides _a2a_ep_size

关键源码片段

python/sglang/srt/arg_groups/overrides.py core-logic

核心变更文件,新增 DeepSeek 家族覆盖函数和 post-process passes,是本次迁移的主阵地。

@_register_for(
    "DeepseekV3ForCausalLM",
    "DeepseekV32ForCausalLM",
    "KimiK25ForConditionalGeneration",
    "MistralLarge3ForCausalLM",
    "PixtralForConditionalGeneration",
    "GlmMoeDsaForCausalLM",
)
def _deepseek_family_overrides(server_args: Any, hf_config: Any) -> dict:
    """Order-safe declarations of the DeepSeek/DSA branch."""
    from sglang.srt.configs.model_config import is_deepseek_dsa
​
    overrides: Dict[str, Any] = {}
    # 仅对 DSA 架构(DeepSeek 3.2 / GLM 5)应用后续覆盖
    if is_deepseek_dsa(hf_config):
        # 如果没有指定 attention backend,则默认使用 dsa
        if server_args.is_attention_backend_not_set():
            overrides["attention_backend"] = "dsa"
            logger.info("Use dsa attention backend for DeepSeek with DSA.")
        if not is_npu() and not is_xpu(): # CUDA or ROCm GPU
            if server_args.enable_prefill_cp:
                # 启用上下文并行时,设置 dp_attention、moe_dense_tp_size 等
                overrides["enable_dp_attention"] = True
                overrides["moe_dense_tp_size"] = 1
                if server_args.cp_strategy == "zigzag":
                    overrides["moe_a2a_backend"] = "deepep"
                    overrides["ep_size"] = server_args.tp_size
                else:
                    # interleave 模式:dp_size 必须为 1,tp_size <= 8
                    assert server_args.dp_size == 1
                    assert server_args.tp_size <= 8
                    attn_cp_size = server_args.tp_size // server_args.dp_size
                    overrides["attn_cp_size"] = attn_cp_size
                # ... 后续还有 page-size 选择、ROCm 回退等逻辑
            # ...
    return overrides
test/registered/unit/test_model_overrides.py test-coverage

新增了针对 DeepSeek 覆盖函数和 post-process passes 的单元测试,确保迁移后行为正确。

def test_deepseek_moe_quant_slot_pass(self):
    from sglang.srt.arg_groups.overrides import (
        ResolvedView,
        _deepseek_moe_quant_resolution,
    )
​
    # 辅助函数:构造一个带默认值的视图对象
    def _view(arch="DeepseekV32ForCausalLM", quant_cfg=None, **kw):
        defaults = dict(
            quantization=None,
            _quantization_explicitly_unset=False,
            moe_a2a_backend="none",
            moe_runner_backend="auto",
            get_model_config=lambda: SimpleNamespace(
                hf_config=SimpleNamespace(
                    architectures=[arch], quantization_config=quant_cfg
                )
            ),
        )
        defaults.update(kw)
        return ResolvedView(SimpleNamespace(**defaults))
​
    with patch.object(overrides_module, "is_sm100_supported", return_value=True):
        with patch.object(
            overrides_module, "get_quantization_config", return_value="fp8"
        ):
            # config 中声明了量化:检测到并设置 moe runner
            self.assertEqual(
                _deepseek_moe_quant_resolution(_view()),
                {"quantization": "fp8", "moe_runner_backend": "flashinfer_trtllm"},
            )
            # 非 DeepSeek 架构的守卫检查
            self.assertEqual(
                _deepseek_moe_quant_resolution(_view(arch="LlamaForCausalLM")), {}
            )
    with patch.object(overrides_module, "is_sm100_supported", return_value=False):
        self.assertEqual(_deepseek_moe_quant_resolution(_view()), {})

评论区精华

Dummy model 路径中 post-process pass 的安全性问题 正确性

Codex 机器人指出,在 dummy model 路径上调用 `_handle_a2a_moe()` 时,`_resolved_overrides` 尚未初始化,新的 post-process passes 可能引发 `AttributeError`。

结论:作者 ch-wan 在回复中表示已在堆栈步骤 6 中修复:在 `__post_init__` 顶部初始化 `self._resolved_overrides = []`,确保 dummy 路径也能安全使用。 · 已解决

风险与影响

  • _resolved_overrides 初始化顺序:虽然已修复,但未来新增 pass 时需确保 __post_init__ 中初始化在最前。
  • 移除 has_fp8_weights_in_checkpoint:该函数在旧代码中用于检查 checkpoint 是否有 fp8 权重,被移除后可能影响某些量化检测路径,需确认所有引用已迁移。
  • 逻辑等价性风险:迁移过程中可能遗漏某些边缘条件(如 DSA 的某个特定环境变量组合),但通过测试和回归 CI 覆盖。
  • 性能影响:overrides 函数和 post-process passes 在启动时执行,预期开销可忽略。
  • 用户:无感知,所有 DeepSeek 系列模型行为保持兼容。
  • 系统:配置解析更加模块化,启动时新增调用链但影响极小。
  • 团队:后续模型的覆盖规则可直接在 overrides.py 中添加,无需修改 server_args.py;但需理解新的 pass 注册机制。
初始化顺序依赖 legacy 代码移除风险 核心路径变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论