Prhub

#24359 Minor scheduler fixes

原始 PR 作者 ispobock 合并时间 2026-05-05 02:01 文件变更 1 提交数 1 评论 2 代码增减 +2 / -3

执行摘要

优化混合 SWA 预 fill 及容量检查

PR body 明确指出两个动机:

1) get_num_allocatable_reqs 未考虑某些情况下 slot 被保留,需要始终用 req_to_token_pool.available_size() 做上限;
2) 混合 SWA 在 decode 阶段滑动窗口淘汰会释放页面,但 batch_is_full 只在请求结束时才清除,导致即使有空余也无法加入新请求,造成预Fill停滞。

值得合并的微小修复,逻辑清晰。建议在合并前添加针对混合 SWA 及非 PP 场景下 get_num_allocatable_reqs 行为的单元测试,尤其是边界 case(token pool 接近耗尽)。

讨论亮点

只有一次来自 gemini-code-assist[bot] 的自动 review,确认了变更内容且没有反馈意见。没有人工 review 或争议讨论。

实现拆解

python/sglang/srt/managers/scheduler.py 中做了两处微小调整:

  1. get_num_allocatable_reqs 方法(第 2566-2569 行):移除 if self.pp_size > 1: 条件判断,改为无条件将 req_to_token_pool.available_size()pp_max_micro_batch_size - running_bs 取最小值。这一改动确保无论是否启用流水线并行,可分配的请求数都不会超过 token pool 的可用容量,避免因遗漏检查导致调度器认为有空位却实际无法分配。
  2. _get_new_batch_prefill_raw 方法(第 2601-2603 行):在 if self.enable_priority_preemption: 条件中增加 or self.is_hybrid_swa,使得混合 SWA 模型也能在每个调度周期开始时将 self.running_batch.batch_is_full 重置为 False。这是因为混合 SWA 的 sliding window eviction 可能在 decode 过程中释放页面,但原来的 batch_is_full 仅在请求结束时才清除,导致预Fill一直无法加入新请求。注意 batch_is_full 的完整条件是 self.get_num_allocatable_reqs <= 0chunked_req is None 且非 priority preemption 模式(第 2617-2624 行),修改后混合 SWA 不会因该标志而提前拒绝。
文件 模块 状态 重要度
python/sglang/srt/managers/scheduler.py 调度器 modified 5.85

关键符号

get_num_allocatable_reqs _get_new_batch_prefill_raw

关键源码片段

python/sglang/srt/managers/scheduler.py core-logic

调度器核心文件,包含 get_num_allocatable_reqs 和 _get_new_batch_prefill_raw 两个关键方法的修改,直接影响请求准入和预 Fill 行为。

# python/sglang/srt/managers/scheduler.pydef get_num_allocatable_reqs(self, running_bs):
    res = get_global_server_args().pp_max_micro_batch_size - running_bs
    # 始终以 token pool 可用容量为上限,避免因保留 slot 而错误地拒绝请求
    res = min(res, self.req_to_token_pool.available_size())
    return resdef _get_new_batch_prefill_raw(self, prefill_delayer_single_pass):
    # ... 前置检查代码 ...
​
    # 对于混合 SWA 模型,滑动窗口可能在 decode 中途释放页面,
    # 因此需要在每个调度周期重置 batch_is_full,允许新增请求
    if self.enable_priority_preemption or self.is_hybrid_swa:
        self.running_batch.batch_is_full = False
​
    if (
        self.running_batch.batch_is_full or len(self.waiting_queue) == 0
    ) and self.chunked_req is None:
        return None
    # ... 后续逻辑 ...

评论区精华

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

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

风险与影响

风险较低。两处改动均为条件放宽或限制收紧:

  • get_num_allocatable_reqs 的变更始终引入 token pool 容量约束,在非 PP 场景下可能略微降低最大并发数,但符合资源安全预期。
  • batch_is_full 重置条件增加 is_hybrid_swa,只影响混合 SWA 模型;可能带来的副作用是 prefill 尝试更频繁,但每次依然受 get_num_allocatable_reqsbatch_is_full 的其他条件限制,不会导致无限制加入。
    未引入测试,回归风险依赖已有 CI 覆盖。

影响范围:仅 SGLang 调度器核心逻辑,面向所有使用混合 SWA 或非 PP 部署的用户。对混合 SWA 模型(如 DeepSeek V2/V3 等)的预Fill吞吐有正面影响,修复了之前可能出现的预Fill长期停滞问题;对非 PP 场景的 request admission 增加了 token pool 容量检查,提升了资源使用的安全性。影响程度较低——5 行代码变更,两者都是条件分支调整。

缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论