Prhub

#30071 [refactor] Sweep disable_hybrid_swa_memory writers; close the dtype family (stack 9/15)

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

执行摘要

迁移混合 SWA 和 dtype 配置到声明式 override 系统

作为声明式配置重构 stack (9/15) 的一部分,目标是移除所有在 ServerArgs 上直接写入配置的遗留代码,将模型特定的配置调整统一注册到 overrides.py 的声明式模型中。PR body 指出:“every dtype writer inside the arch monolith is now declarative”,零新增白名单成本(zero new whitelist cost)地完成字段族清理。

推荐审核或后续开发者关注 Exaone 分支的 explicit-backend assert 是否也应迁移到 override provider 中以完全消除 server_args.py 中的模型特定逻辑。本 PR 是声明式配置 stack 的重要组成部分,值得精读以理解如何将遗留命令式配置改写为声明式 override。

讨论亮点

无 review 讨论。PR 由作者自行合并,仅包含一条 gemini-code-assist 的配额提示评论。

实现拆解

  1. 在 overrides.py 中新增四个 override provider
    • _gemma2_gemma3_overrides:为 Gemma2、Gemma3 及其变体无条件返回 {"disable_hybrid_swa_memory": True},忠实移植原来整个条件分支。
    • _exaone_overrides:根据 hf_config.sliding_window_pattern 是否为 None 条件返回,同时说明原分支中的 explicit-backend assert 保留在 server_args.py 中未迁移。
    • _olmo2_overrides:与 Gemma 类似,无条件禁用 hybrid SWA memory。
    • _gpt_oss_overrides:整合了两段原逻辑:XPU dtype 校验(读取 pristine server_args.dtype 并抛出 NotImplementedError)和 mxfp4 量化时强制 dtypebfloat16;这是第一个由模型配置推导出的 dtype 声明(model-config-derived declaration)。
  2. 清理 server_args.py 中对应的分支:删除 Gemma2ForCausalLMExaone4ForCausalLMOlmo2ForCausalLM 中写入 disable_hybrid_swa_memory 的赋值,删除 GptOssForCausalLM 中 XPU dtype 校验以及 mxfp4 强制 bfloat16 的赋值,保留平台相关的 attention_backend 选择和 moe_runner_backend 选择等不受影响的部分,并在删除处添加迁移注释。
  3. 新增 7 个测试用例:在 test_model_overrides.py 中增加直接测试每个新 provider 行为的用例,覆盖:Gemma2 和 Olmo2 的无条件禁用、Exaone 的条件分支、Exaone 无 pattern 时返回空、GptOss 在 mxfp4 量化时强制 bfloat16、无量化时保持原始 dtype、以及 XPU 平台对 float16 的校验抛出异常。测试同时验证 dual-apply(直接写 ServerArgs)和 publish 后的 flag 层结果,确保与旧行为一致。
文件 模块 状态 重要度
python/sglang/srt/arg_groups/overrides.py 配置层 modified 8.17
test/registered/unit/test_model_overrides.py 测试 modified 7.26
python/sglang/srt/server_args.py 服务器参数 modified 6.59

关键符号

_gemma2_gemma3_overrides _exaone_overrides _gpt_oss_overrides _olmo2_overrides test_gemma2_disables_hybrid_swa_memory test_olmo2_disables_hybrid_swa_memory test_exaone_conditional_on_sliding_window_pattern test_exaone_without_pattern_declares_nothing test_gpt_oss_mxfp4_forces_bfloat16 test_gpt_oss_without_mxfp4_keeps_pristine_dtype test_gpt_oss_xpu_dtype_validation_reads_pristine

关键源码片段

python/sglang/srt/arg_groups/overrides.py dependency-wiring

核心配置注册表,新增 4 个 override provider,定义了 Gemma2/Gemma3、Exaone、GptOss、Olmo2 的模型特定配置迁移逻辑,是声美化重构的关键文件。

# python/sglang/srt/arg_groups/overrides.py@_register_for(
    "Gemma2ForCausalLM",
    "Gemma3ForCausalLM",
    "Gemma3ForConditionalGeneration",
    "Gemma3nForCausalLM",
    "Gemma3nForConditionalGeneration",
)
def _gemma2_gemma3_overrides(server_args: Any, hf_config: Any) -> dict:
    # FIXME: #7367 与 Gemma2 不兼容,见关联 CI 失败
    logger.warning(
        f"Disable hybrid SWA memory for {hf_config.architectures[0]} as it is not yet supported."
    )
    # 无条件禁用 hybrid SWA memory,忠实移植原无条件分支
    return {"disable_hybrid_swa_memory": True}
​
​
@_register_for("GptOssForCausalLM")
def _gpt_oss_overrides(server_args: Any, hf_config: Any) -> dict:
    # XPU dtype 校验:读取 pristine server_args.dtype,与旧代码读取 self.dtype 等价
    if is_xpu():
        if server_args.dtype == "auto":
            logger.warning(
                "GptOssForCausalLM on Intel XPU currently supports bfloat16 dtype only"
            )
        elif server_args.dtype not in ["bfloat16"]:
            raise NotImplementedError(
                f"GptOssForCausalLM on Intel XPU only supports bfloat16 dtype, "
                f"but got '{server_args.dtype}'. Please use --dtype bfloat16 or remove --dtype to use auto."
            )
    # mxfp4 量化时强制 dtype 为 bfloat16,读取 hf_config 中的 quantization_config
    quantization_config = getattr(hf_config, "quantization_config", None)
    if (
        quantization_config is not None
        and quantization_config.get("quant_method") == "mxfp4"
    ):
        return {"dtype": "bfloat16"}
    return {}
test/registered/unit/test_model_overrides.py test-coverage

新增 7 个测试用例,覆盖所有新 override provider 的主路径和边界条件,确保迁移后行为与旧代码一致。

# test/registered/unit/test_model_overrides.pydef test_gpt_oss_mxfp4_forces_bfloat16(self):
    from sglang.srt.layers.quantization import QUANTIZATION_METHODS
    # mxfp4 注册是平台依赖的,非 CUDA/CPU 引擎可能跳过
    if "mxfp4" not in QUANTIZATION_METHODS:
        self.skipTest("mxfp4 quantization is not registered on this platform")
    sa = self._construct(
        "GptOssForCausalLM",
        "llama",
        config_extra={"quantization_config": {"quant_method": "mxfp4"}},
    )
    # dual-apply 后应与旧行为一致:dtype 被强制为 bfloat16
    self.assertEqual(sa.dtype, "bfloat16")
    self.assertEqual(self._publish(sa).dtype, "bfloat16")def test_gpt_oss_xpu_dtype_validation_reads_pristine(self):
    from sglang.srt.arg_groups.overrides import _gpt_oss_overrides
    # 模拟 XPU 环境下传入 float16,应抛出 NotImplementedError
    with patch.object(overrides_module, "is_xpu", return_value=True):
        with self.assertRaises(NotImplementedError):
            _gpt_oss_overrides(
                SimpleNamespace(dtype="float16"),
                SimpleNamespace(architectures=["GptOssForCausalLM"]),
            )

评论区精华

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

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

风险与影响

主要风险在于迁移过程中逻辑可能不一致,特别是 GptOss 的 mxfp4 dtype 强制:旧代码在 server_args.py 中分两处计算 is_mxfp4_quant_format(重复计算),迁移后只在 override provider 中计算一次,行为需要对齐;测试已覆盖主路径。XPU dtype 校验从读取 self.dtype(可能已被前置分支修改)改为读取 server_args.dtype(pristine 输入),旧代码在 GptOss 分支之前没有其他 dtype 写入,因此 server_args.dtypeself.dtype 等价,风险较低。Exaone 的 explicit-backend assert 留在 server_args.py 中未迁移,若未来改动可能遗漏。

对用户无功能影响(纯重构)。对开发者影响:配置逻辑集中到 overrides.py,减少 server_args.py 中的条件蔓延;新增的 override provider 遵循统一的声明式模式,便于后续维护;测试覆盖增强,提高回归防护。server_args.py 精简了 37 行代码。

配置迁移行为需对齐 Exaone 分支断言未迁移 mxfp4 测试依赖平台 核心路径变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论