Prhub

#25945 [Scheduler] Defer prefill input_ids H2D to forward stream, unify resolve via future_map

原始 PR 作者 hnyls2002 合并时间 2026-05-30 17:58 文件变更 8 提交数 27 评论 2 代码增减 +167 / -127

执行摘要

推迟 prefill input_ids 的 H2D 拷贝至 forward 流,统一 resolve 路径

减少调度流上的 GPU 拷贝开销,统一 overlap 和非 overlap 场景的 input_ids 生成方式,简化代码维护。同时修复了 penalty 路径在 input_ids 为 None 时的崩溃以及 spec_v2 隔离的 staging 问题。

值得精读,展示了如何通过 FutureMap 统一不同模式(overlap/non-overlap、prefill/decode)下的输入准备。设计决策如“始终初始化 FutureMap”和“通过 sentinel None 触发 relay”值得关注。建议合并前确保 benchmark 无性能回退。

讨论亮点

无公开 review 讨论。作者在提交消息中标记了修复的 BUG-1(penalty 读取 None input_ids)和 BUG-3(spec_v2 隔离重新安装已消费的 staging)。

实现拆解

  1. 新增 pinned CPU 中继字段:在 ScheduleBatch 类中添加 prefill_input_ids_cpumix_running_indices 字段(schedule_batch.py),分别暂存 prefill 的 prompt tokens(CPU pinned)和混合 batch 中 decode 部分的 req_pool_indices。
  2. 拆分 flatten 工具:在 common.py 中将原来的 flatten_arrays_to_int64_tensor 拆分为 flatten_arrays_to_pinned_cpu(仅返回 CPU tensor,可 pin)和原函数(调用它后执行 to(device)),方便调度流仅保留 CPU 版本。
  3. 调整 prepare_for_extendschedule_batch.pyprepare_for_extend 不再直接创建 GPU tensor 赋值给 self.input_ids,而是调用 flatten_arrays_to_pinned_cpu 得到 pinned CPU tensor 赋值给 self.prefill_input_ids_cpu,并将 self.input_ids 置为 None。类似调整了 prepare_encoder_info_extendmix_with_running
  4. 新增 resolve_forward_inputs:在 overlap_utils.py 中新增核心函数 resolve_forward_inputs,它在 forward 流上被调用,根据 batch.prefill_input_ids_cpu 执行 H2D(若存在)或从 future_map.output_tokens_buf gather decode token,并拼接混合 batch。同时从此函数中处理 spec_v2 的 extra relay。
  5. 统一 FutureMap 初始化:在 scheduler.pyinit_overlap 中,无论是否开启 overlap,都初始化 forward_stream_ctxFutureMap(但 overlap 关闭时不创建 batch_record_buf 等),并将 resolve_forward_inputs 的调用插入到 forward 流隔离的开头。
  6. 适配其余路径:包括 hisparse 重新加入、disagg PREBUILT 非 spec 路径、PP rank-0 的 mixed-chunk、encoder-decoder 重建等,均改为先 stash token 到 FutureMap 再设置 input_ids=None,由 resolve_forward_inputs 统一处理。spec_v1(非 overlap spec)保持原有直接赋值,不通过 relay(因为形状不匹配)。
  7. 修复相关问题:修复 penalty 路径读取 None input_ids 的问题(改为从 Req.output_ids 累加);修复 spec_v2 隔离中重新安装已消费的 staging 导致的问题。
文件 模块 状态 重要度
python/sglang/srt/managers/overlap_utils.py 调度器 modified 8.44
python/sglang/srt/managers/scheduler.py 调度器 modified 7.51
python/sglang/srt/managers/schedule_batch.py 调度批处理 modified 6.84
python/sglang/srt/utils/common.py 工具函数 modified 6.85

关键符号

resolve_forward_inputs flatten_arrays_to_pinned_cpu prepare_for_extend mix_with_running process_prebuilt

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

评论区精华

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

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

风险与影响

核心调度路径变更,涉及 input_ids 可能为 None 的广泛处理,若某条路径未正确设置 prefill_input_ids_cpu 或未通过 FutureMap relay,可能导致空指针崩溃或静默错误。spec_v1 未使用新的 relay,保持原有逻辑,但需要确保 shape 兼容性。性能方面,H2D 推迟到 forward 流可能增加 forward 流负担,但与调度流重叠可能提升整体吞吐,需 benchmark 验证。本 PR 未包含直接测试,存在回归风险。

对用户无功能变化,但可能提升 prefill 与 decode 混合场景的吞吐。对系统调度流减少了 GPU 同步操作,forward 流增加了 H2D 异步拷贝。对团队统一了 input_ids 生成逻辑,简化了后续维护。影响范围包括所有使用 SGLang Runtime 的模型,特别是启用 overlap 或 PP 的场景。

核心路径变更 spec 兼容性 缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论