Prhub

#27764 [Spec] Extract move_accept_tokens_to_target_kvcache into spec_utils

原始 PR 作者 hnyls2002 合并时间 2026-06-10 12:55 文件变更 3 提交数 2 评论 3 代码增减 +70 / -68

执行摘要

提取 EAGLE v2 的 KV 缓存移动函数至 spec_utils

PR body指出:“Extract the EAGLE v2 worker method into a shared spec_utils function so other spec workers can reuse it; no behavior change。”主要动机是提升代码复用性,降低未来添加新spec worker的集成成本。

此PR展示了安全的提取共享工具模式,值得参考。若计划新增其他spec worker(如MTP、Medusa),可直接复用此函数。

讨论亮点

PR无实质review评论,但作者通过/rerun-test触发了测试重跑,所有eagle测试均通过,无回归。

实现拆解

  1. 在spec_utils.py中新增函数move_accept_tokens_to_target_kvcache,包含batch、accept_index、num_correct_drafts、token_to_kv_pool_allocator参数,函数体沿用原有逻辑。
  2. 为spec_utils.py添加必要的导入:ScheduleBatch、BaseTokenToKVPoolAllocator、next_power_of_2、maybe_detect_oob、assign_extend_cache_locs、fill_accept_out_cache_loc。
  3. 从eagle_worker_v2.py中删除原方法,在_finalize_accept_tree_path中改为调用spec_utils.move_accept_tokens_to_target_kvcache,并传入self.token_to_kv_pool_allocator。
  4. 更新eagle_worker_v2.py的导入:从spec_utils导入新函数,移除不再需要的assign_extend_cache_locs、fill_accept_out_cache_loc、next_power_of_2。
  5. 从eagle_info_v2.py中移除未使用的导入(assign_extend_cache_locs、fill_accept_out_cache_loc)。
  6. 通过重新运行eagle相关测试(test_spec_eagle系列)验证功能等价,全部通过。
文件 模块 状态 重要度
python/sglang/srt/speculative/spec_utils.py 推测解码 modified 7.52
python/sglang/srt/speculative/eagle_worker_v2.py 推测解码 modified 6.93
python/sglang/srt/speculative/eagle_info_v2.py 推测解码 modified 4.39

关键符号

move_accept_tokens_to_target_kvcache

关键源码片段

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

核心变更文件:新增 move_accept_tokens_to_target_kvcache 函数并添加所需导入,成为共享函数宿主。

def move_accept_tokens_to_target_kvcache(
    batch: ScheduleBatch,
    accept_index: torch.Tensor,
    num_correct_drafts: torch.Tensor,
    token_to_kv_pool_allocator: BaseTokenToKVPoolAllocator,
):
    """
    Move accepted tokens (drafts + bonus) to the target KV cache.    Args:
        batch: The batch to run.
        accept_index: The index of the accepted tokens (incl. bonus).
        num_correct_drafts: Per-req count of correct drafts (excludes bonus);
            seq_lens is advanced by ``num_correct_drafts + 1`` to cover the bonus slot.
    """
    bs = len(batch.seq_lens)
    device = batch.seq_lens.device
    # accept_index element count, NOT bs * num_draft_tokens: for topk > 1 the
    # tree exceeds the accepted chain, over-reading accept_index (illegal memory).
    size = bs * accept_index.shape[1]
​
    # fill_accept_out_cache_loc reads out_cache_loc[accept_index]; -1 sentinel ok.
    maybe_detect_oob(
        accept_index,
        -1,
        batch.out_cache_loc.size(0),
        "spec v2 move_accept_tokens accept_index",
    )
​
    tgt_cache_loc = torch.zeros(
        size,
        dtype=torch.int64,
        device=device,
    )
    accept_out_cache_loc = torch.zeros(size, dtype=torch.int64, device=device)
    assign_extend_cache_locs[(bs,)](
        batch.req_pool_indices,
        batch.req_to_token_pool.req_to_token,
        batch.seq_lens,
        batch.seq_lens + num_correct_drafts + 1,
        tgt_cache_loc,
        batch.req_to_token_pool.req_to_token.shape[1],
        next_power_of_2(bs),
    )
    fill_accept_out_cache_loc[(size,)](
        accept_index,
        batch.out_cache_loc,
        accept_out_cache_loc,
        next_power_of_2(size),
    )
    token_to_kv_pool_allocator.get_kvcache().move_kv_cache(
        tgt_cache_loc, accept_out_cache_loc
    )

评论区精华

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

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

风险与影响

纯重构,行为不变,风险低。但函数脱离类后调用者需显式传递token_to_kv_pool_allocator,若未来其他worker误用可能引发问题。现有测试覆盖了主要路径,暂未新增测试。

对用户无影响;对开发团队,spec_utils.py成为共享函数宿主,减少重复代码,有利于新spec worker的统一维护。

核心路径变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论