Repository navigation
Fix stale batch fullness after chunked prefill - #35609
guptaishaan wants to merge 1 commit into
Conversation
|
Rebased onto current main. The scheduler change is unchanged. In the regression test I added The I re-ran |
Reset batch_is_full before each prefill admission pass so current request capacity is evaluated. Add a regression test for a waiting request after the final chunked-prefill pass.
4f6ef15 to
3a5870e
Compare
|
Rebased onto current main. One conflict in I also set |
|
Thanks @guptaishaan, the symptom was real. Its cause was a slot double count rather than the latch itself: a chunked request keeps its |
[Fix] scheduler: keep chunked prefill within allocatable KV under memory pressure. Three admission bugs: (1) a continuation chunk could ask alloc_extend for more KV than is free -- PrefillBudget. available_chunk_tokens now caps by real free KV minus the one-page over-ask and defers (None) instead of forcing a full chunk; (2) the single-unfinished-chunk guard now applies to ALL policies, not just shortest-prefill-first (a second unfinished chunk was untrackable); (3) batch_is_full is cleared unconditionally each round -- a latched flag was otherwise only cleared when the running batch shrinks, stalling the waiting queue until an unrelated finish (absorbs closed sgl-project#35609). UNION / DEVIATIONS: - scheduler.py hunk hand-merged: our region carried the entry-198 hybrid-SSM reset arm + is_empty arm; both are strict subsets of the unconditional clear and were removed. Entry-198's COW NO_TOKEN-retry semantics are unaffected (admission re-runs every round anyway). - Consequently the two entry-198 gate tests were re-pinned to the new unconditional behavior (non-hybrid now retries every round too); their mamba-arm and COW-recovery cases pass unchanged. - PR's new test_scheduler_batch_is_full_latch.py NOT imported: the file already exists in-tree (entry-222 wave) with fork stubs; kept ours, refreshed the stale sgl-project#37612-arm comment. - AITER backend hunk + test_aiter_attention_backend_handler.py SKIPPED per instruction (ROCm aiter path irrelevant to this stack). - test_prefill_memory_budget import hunk conflicted (our tree lacks the upstream ChainAllocator test rework): resolved as PrefillBudget + SWAPrefillBudget union; new TestContinuingChunkCap verbatim. - Chunk-guard hunk applied verbatim: our _select_prefill_admission matched the PR base exactly; no mixed-chunk adaptation fights it (mixed-chunk tracks its rows via the scheduler, not new_chunked_req). CPU: targeted (prefill_adder + memory_budget + 3 latch/retry + held_row) 83P/67sub; full managers dir 993P/2F/3skip/904sub == the 2F are pre-existing order-dependent test_mm_process_config failures (verified identical on the stashed baseline, 992P/2F). (cherry picked from commit 0954308) (cherry picked from commit d2bf2d29c4b5382291e672a3a1f0ac844cba196b)
Motivation
Fixes #35537.
batch_is_fullcould remain set after the final chunked-prefill pass. The next scheduler pass returned before recalculating available request slots, which left a waiting request queued until a running request finished.Thanks to @atlantistony for the report and detailed trace.
Modifications
Reset
batch_is_fullat the start of each prefill admission pass. Add a regression test that starts with the stale post-chunk state and verifies that the waiting request reaches admission.Accuracy Tests
Not applicable. This does not change model output computation.
Speed Tests and Profiling
Not run. The focused scheduler test passed on a Linux node with 8 NVIDIA A40 GPUs, with CUDA hidden for the CPU unit test. The full reported Qwen3.8 NVFP4 setup could not run because A40 is sm_86.
Checklist
Review and Merge Process
/tag-and-rerun-ci,/tag-run-ci-label,/rerun-failed-ciCI States
Latest PR Test (Base): ❌ Run #38208264284
Latest PR Test (Extra): ❌ Run #38208264108
Latest PR Test (AMD ROCm 10): ❌ Run #38208264211