Prhub

#33888 config: delete the dead get_server_args() bindings across the repo

原始 PR 作者 ch-wan 合并时间 2026-08-08 13:41 文件变更 14 提交数 1 评论 0 代码增减 +13 / -54

执行摘要

清理 bag 迁移遗留的 get_server_args() 死绑定

仓库此前把全局 server_args 读取迁移到 get_exec() / get_spec() / get_parallel() 等 namespace bag,但若干文件留下了“赋值后从未读取”的 server_args = get_server_args() 绑定。这些死绑定既误导读者(看起来像在使用全局配置),又妨碍后续彻底移除旧的 get_server_args() 接口。PR body 明确定位为 "dead get_server_args() bindings that earlier bag-migration flips left behind",并通过 closure-aware AST 扫描证明删除后零残留。

值得快速浏览,重点看两点:一是 topk.py “调用有副作用、绑定是死代码”的区分,二是 closure-aware AST 扫描的死代码发现方法(先断言行内容再删除)。该 PR 可作为大规模机械清理 + 语义保留的参考范式;若团队后续还要继续清理 get_server_args() 残留,建议补一个针对 _eplb_remap_enabled 发布探测语义的回归测试。

讨论亮点

diff 上无行内评论,两轮自审(reviewer: ch-wan)均给出 LGTM 结论。核心确认点:(1) 每个被删绑定都是“赋值后从未加载”,剩余控制流已读 get_exec() / get_spec() / get_model() / get_schedule() bag;(2) _eplb_remap_enabled 是唯一有副作用的调用点,保留裸调用作为 except ValueError 下的发布探测;(3) test_sampling_batch_infosetUp 已注入 get_exec() bag,去掉 7 个 mock 安全。两轮审核均为 0 bug / 0 suggestion / 0 nit,作为 commit stack 的中间 commit 合入。

实现拆解

  1. 发现与核验:对 python/test/ 做 closure-aware AST 扫描,判定条件是“某名字在其作用域(含嵌套函数)内从未被加载”;普通扫描会对闭包误报(如 triton_symm_mem_ag),因此必须感知嵌套作用域。每个删除点按精确行号执行,且先断言行内容再删除。
  2. 逐文件删除绑定与孤立 import:涉及 sampling_batch_info.from_schedule_batchdeepseek_v2forward_normal / forward_normal_dual_stream / determine_num_fused_shared_experts(3 处)、forward_mla._skip_rope_for_dsa_tilelang_fusedminimax_m3_vl._determine_num_fused_shared_expertsdeepseek_v4_memory_pool.__init__ / get_ring_size(2 处)、flexkv_radix_cache / lmc_radix_cachecache_finished_reqindexer_topk.__init__loader._get_weights_iteratorrouted_expertsinkling_sconv_backendschedule_batch。同步删除被孤立的 get_server_args import。
  3. 保留 load-bearing 调用layers/moe/topk.py_eplb_remap_enabled 中,get_server_args() 裸调用承担“配置是否已发布”的探测职责——except ValueError 表示未发布、不做 EPLB remap,因此只删赋值、调用保留。
  4. 测试配套test_sampling_batch_info.py 的 7 个 @patch(...get_server_args) mock 恰好打在已删除的绑定上;生产代码读的是 get_exec() bag(测试 setUp 已注入并按测试覆盖 deterministic / custom-logit 开关),于是移除装饰器与 mock 参数。
  5. 验证:涉及子系统(sampling、mem_cache、models、layers、managers)单测全绿;对 base commit 跑完整 16 分区 CPU 测试矩阵,零新增失败;AST 复扫确认零残留。
文件 模块 状态 重要度
python/sglang/srt/models/deepseek_v2.py 模型层 modified 5.2
python/sglang/srt/models/deepseek_common/attention_forward_methods/forward_mla.py 注意力前向 modified 5.37
test/registered/unit/sampling/test_sampling_batch_info.py 采样模块 modified 5.84
python/sglang/srt/layers/moe/topk.py MoE 路由 modified 4.89
python/sglang/srt/mem_cache/deepseek_v4_memory_pool.py KV 缓存 modified 4.83
python/sglang/srt/models/minimax_m3_vl.py 模型层 modified 4.97
python/sglang/srt/sampling/sampling_batch_info.py 采样模块 modified 4.76
python/sglang/srt/mem_cache/storage/flexkv/flexkv_radix_cache.py KV 缓存 modified 4.36
python/sglang/srt/mem_cache/storage/lmcache/lmc_radix_cache.py KV 缓存 modified 4.36
python/sglang/srt/state_capturer/indexer_topk.py 状态捕获 modified 4.36
python/sglang/srt/model_loader/loader.py 权重加载 modified 4.16
python/sglang/srt/state_capturer/routed_experts.py 状态捕获 modified 4.09
python/sglang/srt/layers/attention/linear/inkling_sconv_backend.py 注意力后端 modified 3.95
python/sglang/srt/managers/schedule_batch.py 调度模块 modified 3.95

关键符号

SamplingBatchInfo.from_schedule_batch DeepseekV2MoE.forward_normal DeepseekV2MoE.forward_normal_dual_stream deepseek_v2.determine_num_fused_shared_experts forward_mla._skip_rope_for_dsa_tilelang_fused minimax_m3_vl._determine_num_fused_shared_experts deepseek_v4_memory_pool.get_ring_size flexkv_radix_cache.cache_finished_req lmc_radix_cache.cache_finished_req topk._eplb_remap_enabled loader._get_weights_iterator

关键源码片段

python/sglang/srt/models/deepseek_v2.py data-contract

本次清理覆盖面最大的模型核心文件,删除 3 处热路径死绑定(forward_normal、forward_normal_dual_stream、determine_num_fused_shared_experts),最能体现 bag 迁移后的读取方式。

# deepseek_v2.py — determine_num_fused_shared_experts 变更后头部
# 变更点:删除 `server_args = get_server_args()` 死绑定;
# 后续 enable / disable 判定全部改读 get_exec().moe.* 与 get_parallel()
# 等 namespace bag,该局部变量在旧版本中从未被使用。
def determine_num_fused_shared_experts(
    self, architecture: str = "DeepseekV3ForCausalLM"
):
    self.num_fused_shared_experts = 0
​
    # 共享专家融合的总开关来自 get_exec().moe 的 namespace bag
    if get_exec().moe.disable_shared_experts_fusion:
        return
​
    disable_reason = None
    if get_exec().moe.enforce_shared_experts_fusion:
        pass
    elif is_sbo_enabled() or is_tbo_enabled():
        disable_reason = "SBO/TBO enabled: incompatible with fusing shared expert into MoE kernel."
    elif is_deepep_class_backend():
        disable_reason = "DeepEP: fusion off by default (use --enforce-shared-experts-fusion to enable)."
    elif (
        self.config.architectures[0] != architecture
        # n_routed_experts 白名单:256 -> DeepSeek-V3 / R1;
        # 384 -> Kimi-K2.5,仅限 Quark MXFP4 checkpoint(预融合),
        # 标准 compressed-tensors checkpoint 的共享专家是松散存储的,
        # 走融合路径会静默加载错误,因此被排除。
        or self.config.n_routed_experts not in (256, 384)
        or self.config.n_shared_experts != 1
        or (
            self.config.n_routed_experts == 384
            and (
                self.quant_config is None
                or self.quant_config.get_name() != "quark"
            )
        )
    ):
        disable_reason = "Config does not support fused shared expert(s)."
    # ... 后续其余 disable_reason 分支与最终决策逻辑保持不变
python/sglang/srt/models/deepseek_common/attention_forward_methods/forward_mla.py data-contract

MLA 注意力前向的公共文件,删除 import 与 _skip_rope_for_dsa_tilelang_fused 内的死绑定,是 attention 侧 bag 迁移的典型代表。

# forward_mla.py — _skip_rope_for_dsa_tilelang_fused 变更后
# 变更前函数体内有一行从未被读取的 `server_args = get_server_args()` 绑定,
# 本次连同 import 列表中的 get_server_args 一起删除。
# 本函数真正依赖的运行时配置来自 get_exec() 返回的 namespace bag
# (由 runtime_context 在 runner 启动时注入),与全局 server_args 无关。
def _skip_rope_for_dsa_tilelang_fused(self: DeepseekV2AttentionMLA) -> bool:
    """
    Check if we should skip rope and use fused rope+cache path for
    TileLang DSA on gfx95.
    """
    # 跳过 rope 的条件只看 gfx95 后端开关、当前 attention backend,
    # 以及 get_exec().kernel 中 dsa 的 decode / prefill 后端是否为 tilelang。
    return (
        _use_aiter_gfx95
        and self.current_attention_backend in ("dsa", "nsa")
        and (
            get_exec().kernel.dsa_decode_backend == "tilelang"
            or get_exec().kernel.dsa_prefill_backend == "tilelang"
        )
    )
test/registered/unit/sampling/test_sampling_batch_info.py test-coverage

删除 7 个 @patch(...get_server_args) mock 与对应参数,是本次“测试联动清理”的核心证据文件,验证生产路径已完全转向 get_exec() bag。

# test_sampling_batch_info.py — 测试去掉 @patch 装饰器
# 变更前这 7 个测试都带 `@patch("...sampling_batch_info.get_server_args")`
# 装饰器与 mock_server_args 参数;而生产路径 from_schedule_batch 早已改读
# get_exec() 返回的 bag,这些 mock 恰好打在本次删除的死绑定上,
# 属于无用 mock,一并移除。测试所需开关由 setUp 注入的 _exec_ns 按测试覆盖。
def test_deterministic_seed(self):
    """Test that explicit seed=123 is kept and missing seed defaults to 42."""
    self._exec_ns.deterministic.enable_deterministic_inference = True
​
    reqs = [self._make_req(seed=123), self._make_req(seed=None)]
    batch = MagicMock()
    batch.reqs = reqs
    batch.device = DEVICE
    info = SamplingBatchInfo.from_schedule_batch(batch, VOCAB_SIZE)
    self.assertIsNotNone(info.sampling_seed)
    self.assertEqual(info.sampling_seed[0].item(), 123)
    self.assertEqual(info.sampling_seed[1].item(), 42) # 缺省 seed 默认值

评论区精华

删除范围与正确性核查 设计

自审确认每个被删绑定都是“赋值后从未加载”,剩余控制流已读 get_exec() / get_spec() / get_model() / get_schedule() bag;孤儿 import 仅在无活跃使用时移除。

结论:0 bug / 0 suggestion / 0 nit,LGTM,可作为 commit stack 中间 commit 合入。 · 已解决

topk.py 发布探测调用保留 正确性

_eplb_remap_enabled 中裸 get_server_args() 调用是 config 是否已发布的探测(except ValueError -> 不做 EPLB remap),因此只删绑定、保留调用。

结论:保留裸调用作为有副作用的生效路径,两轮自审均确认无遗留消费者被误删。 · 已解决

测试 mock 移除安全性 测试

test_sampling_batch_info 的 7 个 @patch(...get_server_args) mock 恰好打在已删除的死绑定上;setUp 已注入 get_exec() bag(含 per-test 覆盖 deterministic / custom-logit 开关),移除安全。

结论:确认移除后相关子系统单测全绿,16 分区 CPU 矩阵零新增失败。 · 已解决

风险与影响

行为风险低:所有删除均被 AST 证明为死代码,纯删除、无逻辑改写;但改动横跨 14 个文件、触及 deepseek_v2.pyforward_normal / forward_normal_dual_stream 等热路径函数,与并行迁移 PR 合并时冲突面较大。topk.py_eplb_remap_enabled 依赖 get_server_args() 对未发布配置抛 ValueError 这一契约;若未来该函数不再抛错,EPLB remap 判定会静默改变。当前调用保留,风险可控,但值得在后续退役 get_server_args() 时专项测试。测试清理依赖 setUp 注入的 _exec_ns 与生产路径 get_exec() 的等价性,单测全绿与 16 分区 CPU 矩阵零新增失败已覆盖主要风险。

对用户无行为影响(纯死代码删除)。对系统而言,消除了“看起来在读配置、实际是死代码”的误导,降低后续维护者误用 server_args 绑定或拷贝该模式的可能;测试文件去掉 7 个 mock 后更简洁,也避免了 mock 对象与被删绑定的隐性耦合。对团队而言,这是 get_server_args() 旧式全局配置读取的系统性退役的一部分,为后续收紧 runtime_context 接口、统一 namespace bag 读取铺路。

纯删除、行为零变更 topk.py 探测依赖 except ValueError 契约 跨 14 文件合并冲突面大 热路径函数改动

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论