Prhub

#25109 spec: defer verify() idle hidden_size to worker fixup

原始 PR 作者 hnyls2002 合并时间 2026-05-13 13:13 文件变更 3 提交数 2 评论 6 代码增减 +18 / -7

执行摘要

将 idle 时 hidden_size 计算延迟到 worker fixup 统一处理

PR body 指出:'Schema cleanup: EagleVerifyInput.verify() idle stubs no longer compute hidden_size locally from batch.model_config.spec_hidden_size; they hand off to the worker fixup in forward_draft_extend_after_decode, which rebuilds via EagleDraftExtendInput.hidden_size_for(self) (single source, incl. EAGLE-3 aux widening).' 目的是统一 hidden_size 来源,避免 verify() 中直接引用 model_config,提高代码一致性和可维护性。

值得精读,展示了如何通过延迟绑定(lazy binding)消除重复逻辑,是良好的架构清理范例。可关注 hidden_size_for 方法的设计。

讨论亮点

无 review 评论,PR 由作者自行合并。

实现拆解

  1. eagle_info.py:verify() idle 分支传 None:在两个 idle stub(完全 idle batch 和所有请求完成的 batch)中,create_idle_input()hidden_sizedtype 参数改为 None,并添加注释说明由 worker fixup 重建。
  2. eagle_worker.py / multi_layer_eagle_worker.py:forward_draft_extend_after_decode 修复条件:将 if not input_is_idle and draft_extend_input.input_ids.shape[0] == 0 改为 if draft_extend_input.input_ids.shape[0] == 0,使得 fully-idle batch(DP rank 无请求)也能进入修复路径,并通过 prepare_for_idle() 的幂等性安全处理。修复路径内使用 EagleDraftExtendInput.hidden_size_for(self) 作为 single source。
  3. 注释更新:所有相关位置添加了注释说明变更意图。
文件 模块 状态 重要度
python/sglang/srt/speculative/eagle_info.py 投机解码 modified 6.11
python/sglang/srt/speculative/eagle_worker.py 投机解码 modified 5.92
python/sglang/srt/speculative/multi_layer_eagle_worker.py 投机解码 modified 5.53

关键符号

verify forward_draft_extend_after_decode

关键源码片段

python/sglang/srt/speculative/eagle_info.py core-logic

核心变更:verify() idle stub 中 hidden_size/dtype 传 None,将计算责任转移给 worker。

# python/sglang/srt/speculative/eagle_info.py
if batch.forward_mode.is_idle():
    # hidden_size=None: worker fixup 在 forward_draft_extend_after_decode
    # 中通过 EagleDraftExtendInput.hidden_size_for(worker) 重建
    # (单一来源,包含 EAGLE-3 aux widening)。
    draft_extend_input = EagleDraftExtendInput.create_idle_input(
        device=batch.device,
        hidden_size=None, # 之前是 batch.model_config.spec_hidden_size
        dtype=None, # 之前是 batch.model_config.dtype
        capture_hidden_mode=CaptureHiddenMode.LAST,
    )
    return EagleVerifyOutput.create_idle(
        draft_extend_input=draft_extend_input,
        logits_output=logits_output,
        device=batch.device,
        spec_steps=self.spec_steps,
    )
python/sglang/srt/speculative/eagle_worker.py core-logic

worker 侧修复条件:将 `not input_is_idle and` 改为直接检查 input_ids.shape[0]==0,使 fully-idle 分支也被覆盖。

# python/sglang/srt/speculative/eagle_worker.py
if draft_extend_input.input_ids.shape[0] == 0:
    # 通过 hidden_size_for(self) 获得单一隐藏大小来源(包含 EAGLE-3 aux widening)。
    # 两个 stub 来源:完全 idle batch(DP attention rank 无请求)和所有请求完成的 active batch。
    # prepare_for_idle() 在已经是 idle 的 batch 上是幂等的。
    batch = batch.copy()
    batch.prepare_for_idle()
    draft_extend_input = EagleDraftExtendInput.create_idle_input(
        device=self.device,
        hidden_size=EagleDraftExtendInput.hidden_size_for(self),
        dtype=EagleDraftExtendInput.dtype_for(self),
        capture_hidden_mode=draft_extend_capture_mode,
    )
    batch.spec_info = draft_extend_input
python/sglang/srt/speculative/multi_layer_eagle_worker.py core-logic

与 eagle_worker.py 相同的条件修复,用于多层的 Eagle worker。

# python/sglang/srt/speculative/multi_layer_eagle_worker.py
if draft_extend_input.input_ids.shape[0] == 0:
    # 注释同 eagle_worker.py,隐藏大小来源统一。
    batch = batch.copy()
    batch.prepare_for_idle()
    draft_extend_input = EagleDraftExtendInput.create_idle_input(
        device=self.device,
        hidden_size=EagleDraftExtendInput.hidden_size_for(self),
        dtype=EagleDraftExtendInput.dtype_for(self),
        capture_hidden_mode=draft_extend_capture_mode,
    )
    batch.spec_info = draft_extend_input

评论区精华

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

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

风险与影响

低风险。变更仅影响 idle stub 路径(无实际计算),通过已有测试验证(测试全部通过)。但需注意:hidden_size=None 的 idle input 在进入 worker fixup 之前被误使用可能导致错误,但所有下游调用都已同步修改。

影响范围:仅 speculative decoding 的 idle 分支,无用户可见行为变化。对系统:减少了 model_config 的直接依赖,使 hidden_size 获取路径单一化,有利于后续 EAGLE-3 等算法扩展。

逻辑变更影响 idle 路径 缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论