执行摘要
- 一句话:为 Eagle 推测解码引入 spec_hidden_size,修复 hidden size 不匹配
- 推荐动作:推荐合并并部署。该 PR 改动量小但影响面广,修复了关键的维度不匹配问题,且经过多场景 CI 验证。值得关注的设计决策是将
hc_mult 从模型配置中显式读取,而不是硬编码扩展系数,保持了灵活性和可扩展性。
功能与动机
现有代码在 speculative decoding 流程中始终使用 model_config.hidden_size,但对于某些模型(例如需要 hc_mult 扩展隐藏层维度的架构),draft 模型的隐藏层大小可能不等于 target 模型的 hidden_size,导致张量维度不匹配或显存浪费。PR 通过新增 spec_hidden_size 属性,并统一替换所有相关位置的 hidden_size 引用,修复了此问题。
实现拆解
- 数据契约扩充 - 在
python/sglang/srt/configs/model_config.py 的 _derive_model_shapes 方法中,从 hf_text_config 读取 hc_mult 字段(默认 1),计算出 spec_hidden_size = hidden_size * hc_mult if hc_mult > 1 else hidden_size。
- Eagle 预处理器替换 - 在
eagle_worker.py 的 _draft_preprocess_idle 和 forward_draft_extend_after_decode 中,创建 EagleDraftInput.create_idle_input 时改用 model_config.spec_hidden_size。
- Verify 流程修正 - 在
eagle_info.py 的 verify 方法中,两处创建 EagleDraftInput.create_idle_input 的位置(空闲分支和非空闲分支)均更新为 batch.model_config.spec_hidden_size。
- Worker 与 Runner 同步 - 在
eagle_worker_v2.py、multi_layer_eagle_worker_v2.py、eagle_draft_cuda_graph_runner.py、eagle_draft_extend_cuda_graph_runner.py 中,将对应的 hidden_size 赋值替换为 spec_hidden_size。
- 调度器 Disaggregation 适配 - 在
scheduler.py 的 init_disaggregation 方法中,创建 MetadataBuffers 时,Eagle 模式下的 hidden_size 参数同样改用 model_config.spec_hidden_size。
- 测试验证 - 通过手动触发 1-gpu-5090 与 1-gpu-h100 上的 Eagle 系列测试,CI 全部通过,表明该修正确保了功能正确性。
关键文件:
python/sglang/srt/configs/model_config.py(模块 模型配置;类别 source;类型 data-contract;符号 _derive_model_shapes, spec_hidden_size): 新增 spec_hidden_size 属性的定义,是本次数据契约变更的源头。
python/sglang/srt/speculative/eagle_worker.py(模块 推测解码;类别 source;类型 core-logic;符号 _draft_preprocess_idle, forward_draft_extend_after_decode): 该文件是 Eagle 推测解码的核心 worker,修改了两处创建 idle input 的 hidden_size 源。
python/sglang/srt/managers/scheduler.py(模块 调度器;类别 source;类型 core-logic;符号 init_disaggregation): 调度器在初始化 disaggregation 时使用 spec_hidden_size 来正确设置 metadata 缓冲区大小。
python/sglang/srt/speculative/eagle_info.py(模块 推测解码;类别 source;类型 core-logic;符号 verify): verify 方法中两处 create_idle_input 使用了 spec_hidden_size,贯穿验证流程。
python/sglang/srt/speculative/eagle_draft_extend_cuda_graph_runner.py(模块 推测解码;类别 source;类型 core-logic;符号 init): CUDA graph runner 在分配 hidden_states 缓冲区时使用 spec_hidden_size,确保图捕获尺寸正确。
python/sglang/srt/speculative/eagle_worker_v2.py(模块 推测解码;类别 source;类型 core-logic;符号 forward_batch_generation): Eagle v2 worker 中创建 idle input 时替换 hidden_size 为 spec_hidden_size。
python/sglang/srt/speculative/multi_layer_eagle_worker_v2.py(模块 推测解码;类别 source;类型 core-logic): 与 eagle_worker_v2 类似的修改,保证多层 Eagle 场景一致性。
python/sglang/srt/speculative/eagle_draft_cuda_graph_runner.py(模块 推测解码;类别 source;类型 core-logic): 另一个 cuda graph runner 的尺寸调整。
关键符号:_derive_model_shapes, _draft_preprocess_idle, forward_draft_extend_after_decode, verify, forward_batch_generation, init, init_disaggregation
关键源码片段
python/sglang/srt/configs/model_config.py
新增 spec_hidden_size 属性的定义,是本次数据契约变更的源头。
# 在 _derive_model_shapes 方法中,设置完 hidden_size 后立即计算 spec_hidden_size
self.hidden_size = self.hf_text_config.hidden_size
# 读取 hc_mult,默认 1(即大多数模型不扩展)
hc_mult = getattr(self.hf_text_config, "hc_mult", 1)
# 当 hc_mult > 1 时使用扩展后的尺寸,否则等于 hidden_size
self.spec_hidden_size = (
self.hidden_size * hc_mult if hc_mult > 1 else self.hidden_size
)
python/sglang/srt/speculative/eagle_worker.py
该文件是 Eagle 推测解码的核心 worker,修改了两处创建 idle input 的 hidden_size 源。
# _draft_preprocess_idle 中的改动
batch.spec_info = EagleDraftInput.create_idle_input(
device=self.device,
hidden_size=self.model_config.spec_hidden_size, # 之前是 hidden_size
dtype=self.model_config.dtype,
topk=self.topk,
capture_hidden_mode=CaptureHiddenMode.LAST,
)
# forward_draft_extend_after_decode 中的条件分支
hidden_size = (
self.model_config.hidden_size * 3
if self.speculative_algorithm.is_eagle3() and self.eagle_use_aux_hidden_state
else self.model_config.spec_hidden_size # 之前是 hidden_size
)
评论区精华
无 review 讨论。PR 作者独立完成并合并,未出现设计争论或悬而未决的问题。
风险与影响
关联脉络
参与讨论