Repository navigation
Conversation
available_chunk_tokens only looked at the token budget, so under memory pressure a continuing chunk could ask alloc_extend for more KV than is free and fail. Cap it by the free + evictable KV (minus the page alloc_extend over-asks); when the decode-headroom estimate leaves nothing, progress with the free KV or defer the chunk. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…licy Only one unfinished chunked request can be tracked, but the guard that stops a second one was limited to shortest-prefill-first. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
batch_is_full was otherwise only cleared when the running batch shrank, so a latched flag stalled the waiting queue until an unrelated request finished. PrefillAdder already enforces the real limits. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> # Conflicts: # test/registered/unit/mem_cache/test_prefill_memory_budget.py
[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)
[Fix] scheduler: preserve Mamba fork+tail states across chunked prefills via opt-in SGLANG_SPLIT_PREFILL_AT_MAMBA_FORK (EnvBool, default False = byte-identical). One extend tracks one Mamba state, so a chunk crossing the cached fork loses it; with the flag on (requires extra-buffer radix strategy + hybrid SSM cache, non-dllm) eligible prefills end at the aligned fork so the fork state and the tail state both reach the cache — through initial admission, continuation, and a host load-back that moved the prefix. UNION / DEVIATIONS: - Single-unfinished-chunk guard reconciled per instruction in favor of the landed sgl-project#46643 logic: the unconditional 'if has_chunked_req' guard is kept (it subsumes this PR's split-conditioned reopening); the PR's 'or split_prefill_at_mamba_fork' term is a no-op against it. - Consequently the PR's test test_second_unfinished_chunk_guard_follows_policy_unless_fork_split is re-pinned to test_second_unfinished_chunk_guard_is_unconditional: every policy + both flag states now refuse the second unfinished chunk. All other 8 fork tests verbatim. - add_chunked_req: the fork cut is applied after the sgl-project#45607 hybrid page-align (both land on page multiples; order-safe) and before the request-slot reserve, matching the PR's position relative to that line. truncation_align_size now threads from the scheduler (PR's scheduler.py hunk) but is consumed only by _mamba_fork_split_len — our entry-177 _align_prefill_chunk call keeps its existing (default) argument so no QSA-continuation behavior drifts. - Test import hunk: the PR base's PrefillBootstrapQueue import does not exist in our file; resolved to os + environ.envs + policy-enum additions only. CPU: test_prefill_adder + held_row_admission 69P/85sub (8 fork-matrix cases pass incl. re-pinned guard); full managers dir + prefill_memory_budget + mamba donated/capacity + unified_radix_cache_unittest = 1091P/2888skip/969sub; the only 2F are the pre-existing order-dependent test_mm_process_config failures (verified identical on the ported-branch baseline at sgl-project#46643). (cherry picked from commit 0e20970) (cherry picked from commit 8832eae148114995e251aed28c16a20985dfd8c5)
…gl-project#45607/sgl-project#45789 (entries 267-270) Second admission docs commit. Records: sgl-project#46496 DRAFT-upstream status; sgl-project#46643's BEHAVIOR CHANGE (admission re-runs every round for ALL models -- TTFT/starvation watch at the owed restart, entry-198 precedent; the two entry-198 arms removed as strict subsets, COW-retry semantics untouched); sgl-project#45607 page-align composition with entry-177's lcm aligner (both shrink- only; exact_chunk_fill arm untouched upstream too); sgl-project#45789 default-OFF fork-split with the guard reconciliation vs sgl-project#46643 (policy-reopening term proven no-op, test re-pinned), fork cut after sgl-project#45607 align, and the deliberate no-thread of truncation_align_size into entry-177's aligner. Battery: every worker number REPRODUCED EXACT AT THEIR OWN TREES (method identity), then re-measured on the combined tree with full attribution of every drift; managers dir RE-PINNED 1013P/2F/3S/933sub (base 988). The worker's stashed-baseline '992P' decomposes only as fresh-base 988 + their own picks (+5 at sgl-project#46643 EXACT) -- flagged as measurement noise.
…20 commits since 12dc623 @ merge-sgl-project#4) Conflicts: 167 files (149 content / 14 add/add / 4 modify/delete) at the settled 309 tip d28e7cd -- dossier predicted 146 +/-25; the +21 shift is entries 275-309 landing qsa-ring/hicache-ctrl/gdn/moe/llguard deltas into the conflict zone. By class: A 13 (auto-takes-upstream, dedupe-verified), B 80, C 56, D 18. 102 TODO(merge5) re-plant/fold markers planted: B1 x15, B2 x29, B3 x12, B4 x23, B5 x23. Re-plant stock: 117 files under /tmp/opencode/merge5-dossier/replant/ (76 fork-hunks patches, 19 upstream-side patches, 14 AA fork copies, 8 preremove snapshots) -- sessions 2/3 re-plant from real code, not memory. D-list outcomes (must-not-auto-resolve, handled personally): - sgl-project#45289-vs-sgl-project#44858 (entry 301): VERIFIED, not re-resolved -- the gate/up-order final form is in origin/main (5b1dbc2 in range); scales test taken as upstream oracle, fork 191-line version saved to replant/ for B5 diffing. sgl-project#44858's call-site shape CANNOT survive (our base never had it). - entry-230 dispatcher vs sgl-project#44993/sgl-project#44994: took upstream structure in token_dispatcher/standard.py; published-value CONTRACT lives upstream via get_moe_runner_backend() in the LoRA-EP guard; fork's warn-once mismatch diagnostic re-plants (B5 marker). UNION GATE: standard_dispatcher 16P (was 12P, suite grew), model_overrides 121P/1S/210sub (was 112P/1S/181sub), fold probe 6P/2F (upstream added a runner_backend arg to the predicate -- B5 re-pins the probe). - entry-219 gauge names vs sgl-project#43727 return + sgl-project#44968: PER-POOL NAMES KEPT as the serving schema -- hicache_host_pool_{used,total}_tokens{pool} dataclass fields, Gauge registrations and labels(pool=) emission re-restored over the #4697x structure; hicache_host_pool_evicted_tokens_total already survived auto-merge; producer dict restored by union in metrics_reporter. ANTI-NEEDLE SATISFIED: old mamba-only gauges are NOT the serving schema. - entry-221 eager-direct add/add: DEDUPED to upstream (bodies identical except est_time 15->9); MEASUREMENT DEBT RECORDED: prefill t/s must be re-measured post-B4 before trusting the est_time. - entry-168 D2H fence vs sgl-project#44800: the fence is ALREADY UPSTREAM (both load_fence_stream + write_fence_stream with the load-thread-corruption comment in origin/main's cache_controller.py) -- nothing re-planted; the two real regions resolved as import-union + comment wording (merge sgl-project#4 stale-tail pattern avoided). Fork hunks still saved to replant/ (belt). - entry-209 clamp + 216/218 ordering + 288-295 hicache-ctrl-era vs #46970x KV rewrite: ADOPTED-UPSTREAM across unified_radix_cache/hicache_storage/ hybrid_cache_controller/memory_pool/kv_cache_builder; EVERY fork hunk extracted to replant/*.fork-hunks.patch; B3 re-plant markers planted. sgl-project#45703's short-full-match seam arrives with upstream. - sgl-project#45090 SGLANG_ENABLE_UNIFIED_RADIX_TREE: REMOVAL TAKEN (fork had already moved it to _DeprecatedEnv; now gone). grep: ZERO .py readers repo-wide; 2 upstream-owned docs jsx snippets still export it (deepseek-v4, glm-5.2 -- upstream's own debt). OPERATOR-OWED CHECK: confirm no /root harness exports it (unreadable from this seat). - sgl-project#39727 unified L3 key: VERIFIED OPT-IN -- merged hicache_storage.py keeps the DEFAULT legacy suffix composition _<model>_<tp_rank>_<tp_size> (content-anchor: HiCacheFile._init_config_suffix, raise-guarded when _unified_chunk_spans is set). ANTI-NEEDLE: no silent key-scheme switch; warm /root/hicache_store contents stay addressable. Modify/delete (4, all victims of upstream sgl-project#45672 test prune + URC split): - test_unified_radix_cache_unittest.py: REMOVED (adopted split) -- its bare unified_tree_core_inspector imports are unreachable post-sgl-project#45236 re-home; fork source + hunks saved; B2 marker planted in the new core test. - test_fused_moe_triton_config.py: REMOVED -- imports common_utils, absent from both sides post-sgl-project#45672; the 2 live entry-3/235 tests re-plant in B2. - test_scheduler_batch_is_full_latch.py: REMOVED -- fork delta was 3 stub-attr lines documenting sgl-project#46643's absorbed arms; upstream deletion correct. - test_qsa_kv_pool.py: KEPT -- fork's 147 added lines are entry-187/200 sharding + 285-287 QSA-ring tests with NO upstream replacement; qsa_kv_pool.py sides converged byte-identical; collects clean. B2 marker. Cascading silent-auto-merge repairs (classes not in the conflict set but broken by auto-merge + union splices -- all found by gates, now fixed): kernels/ops/activation/__init__.py (dead _CUDA registration dup), kernels/ops/ diffusion/__init__.py (5-tuple _SPECS entry), kernels ops embeddings/moe/ attention/mamba __init__ (KernelSpec fields removed upstream: description/ format_signature stripped, CapabilityRequirement->CUDA_ONLY), base_runner/ eager_runner cp_extend + shared_read_event imports retargeted per upstream's "no imports in runner_utils/__init__" contract, and 4 fork helpers grafted back onto their take-upstream homes because merged code/tests still import them (memory_pool.spec_intermediate_bytes_per_req, kv_cache_builder. _adjust_hicache_size_for_draft + _device_pool_size_per_token, hybrid_cache_controller.local_restorable_mask, validation_hook. validate_replayssm_spec_algorithm, arg_groups/moe_hook b12x validator). flashinfer_cutlass.py flipped to FORK-OWNED (b12x route is fork-only, 760 vs 95 lines; upstream sgl-project#44993 hunks = B5 fold patch saved). Silent-semantics notes: sgl-project#46127/sgl-project#44912 riders arrived via per-PR picks (union); sgl-project#45520 (entry 302) is STILL OPEN upstream -- entry-230 fail-safe layer stays as entry 303 records; if a future sync brings it, re-apply the fail-safe reads. qwen4_exp holder-contract fused (ctor takes optional batch). Gates at commit: import sglang OK (CVD=9, prod venv); check_registered_tests/ check_no_bare_pytest_main/check_no_registered_tests_in_package rc=0; ruff F821 +E9+format clean on the resolution set; collect-only over unit/{mem_cache, model_executor,distributed,layers/moe} = 4337 nodes, 3 ERRORS: 2x cargo/torch- sys libtorch probe (REPRODUCED IDENTICALLY AT THE PRE-MERGE TIP -- env issue, not merge damage) + test_hicache_async_ready_sync.py (entry-253-era attribute gone with the URC rewrite -- EXPECTED pre-B3). sessions 2/3 owed: B2 test re-home, B3 mem_cache+rust re-plant (+hicache-ctrl re-ports), B4 scheduler/admission, B5 moe/quant/dispatcher, B6 environ+C0a+ CAVEATS re-pin. PROD BOOT FORBIDDEN until B3 completes (209 clamp + 218 ordering re-plant).
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> # Conflicts: # python/sglang/srt/mem_cache/prefill_budget.py
…entries 122,198,200,211,215,220,267,268,305 Re-plants the scheduler.py fork-hunks (replant/...managers__scheduler.py.fork-hunks.patch) onto the post-sgl-project#46977 admission structure. tp_worker marker consumed (15/23 B4 markers still on the tree; per-file counts, damage-state from entry 310's map). PER-HUNK DECISIONS (all VERIFIED against the merged tree, not taken on faith): - entry 122 (sgl-project#40458): grammar-sync overlap disable RE-PLANTED for mixed mode (is_decode() OR is_mixed()) + the fork's trimmed comments; upstream's host-draft-only arm was the pre-sgl-project#40458 form (origin/main verified: absent). - entry 220 (sgl-project#39765, OPEN port): _has_pending_mamba_cache_update + the early pop_and_process/short-circuited disable-overlap RE-PLANTED into event_loop_overlap; the require_mlp_sync/disable/extra-buffer gate verbatim. - entry 198 (sgl-project#37612): THE CATCHER — B3-5 landed the raiser; the try/except MambaCowAllocError around init_next_round_input (res=NO_TOKEN, request stays queued; the revert block + unconditional alloc_group_end were already in the merged tree = the no-leak halves VERIFIED PRESENT) RE-PLANTED with the import. COW component test re-anchored to the #46970x kv_storage seam the B3-5 replant moved _state() behind (stub was the pre-split mamba_allocator shape). - entry 268 (sgl-project#46643, OPEN port -- VERIFIED NEVER MERGED: git log 12dc623..2a6c204 --grep 46643 = ZERO; only sgl-project#45491/sgl-project#45435/sgl-project#45472/sgl-project#45670 of the briefed merged-list arrived in-range): the UNCONDITIONAL batch_is_full clear RE-PLANTED on the scheduler side, subsuming the entry-198 hybrid-SSM arm and the priority-preemption/is_empty arms (policy side lands in B4-3). - entry 267 (sgl-project#46496): retract_decode new_token_ratio FLOOR clamp RE-PLANTED. - entry 211: triton_load_watch.prewarm_device_loads(self.model_worker) line RE-PLANTED between install() and mark_serving_started (the utils-side function survived the merge; only the call site was dropped). - entry 200 (sgl-project#43527) CAPACITY PAIR RE-PLANTED: model_runner .logical_max_total_num_tokens passes allocator= again (the configurator's PageInterleavePoolAllocator -> allocator.size branch SURVIVED the merge byte-identical, so the merged tree had the fork predicate with upstream's consumer-side multiplications = DOUBLE-COUNT); the three scheduler * kv_shard_widening multipliers back to the fork form (pool-stats shape, load_inquirer, and the init_req one-page-per-shard subtraction); tp_worker drops page_interleave_shard_size x + import. Upstream's invariant-checker hunk: OBSOLETE (the constructor no longer takes max_total_num_tokens -- absorbed by refactor). - entry 215 (sgl-project#44351/sgl-project#44401/sgl-project#44420): VERIFIED ALREADY PRESENT at the merge (filter_batch-every-step + reset ride, num_held_rows, budget_state FIRST statement, PD-gate deletion all byte-compare to the fork form) -- DEDUPED, no edit. Entry 107's local early-revision of sgl-project#40940 stays superseded (entry 215 rule), and its re-plant here would double-count. - entry 220's/305's pause-window busy accounting + write_fence_stream + is_empty arm: VERIFIED PRESENT (entry 305 landed patch-identical via sgl-project#46127; the fence assignment is the B3-2 controller half) -- DEDUPED. TEST FIXTURE RE-ANCHORS (not B2's: no markers, pure new-upstream-contract drift, per the entry-198 fixture-adaptation precedent): the two hybrid-ssm admission stubs gain disagg_prefill_bootstrap_queue=None (upstream's routing-key bootstrap_queue arg in calc_priority arrived in-range). PRUNE vs BREAKAGE (managers −523sub audit): the three managers test files vanished in-range (test_schedule_policy_dfs_weight, test_scheduler_batch_is _full_latch, test_uno_token_accounting) were ALL deleted by upstream's OWN sgl-project#45672 prune (3438ed6). Two are byte-identical upstream copies = zero fork delta. The third carried a 3-line fork comment/stub delta whose SEMANTICS the re-planted unconditional clear pins: its case was the is_empty-arm mirror of test_scheduler_hybrid_ssm_admission_latch (present, green, hybrid_swa/non-hybrid arms included) -- NOT re-homed, recorded. ACTUALS (damage -> after, CVD=9, prod venv, PYTHONPATH=python, per-file): test_scheduler_hybrid_ssm_admission_retry 4F -> ** 4P ** test_scheduler_hybrid_ssm_admission_latch 3F -> ** 4P ** test_mamba_prefill_cache_boundary 2F/12subF -> ** 5P/12sub EXACT (220 pin) ** test_scheduler_retract_ratio 1F -> ** 2P EXACT (267 pin) ** test_scheduler_init_req_max_new_tokens 1F -> ** 10P/6sub ** test_scheduler_grammar_mixed_tail_sync 1F -> ** 4P ** adjacent scheduler-stub files (held_row, running_batch_finished, pause_generation, disagg_idle, dp_converted, hicache_events) 56P/64sub UNMOVED -- no regression from the clear/catcher/capacity edits. Lint: ruff format + F821/E9 clean on all five files; imports OK (no GPU execution, no push). Co-Authored-By: OpenCode <noreply@opencode.ai>
…46977 pricing reconciliation (entries 177,266,268,269,270 + 217) 2 markers consumed (schedule_policy.py, scheduler.py). B4 tree count now 15. prefill_budget.py needed NO edit: sgl-project#46643's fix(1) (available_chunk_tokens capped by real free KV minus the one-page over-ask, defer-not-force) SURVIVED the merge byte-identical in the base class -- deduped with evidence (diff 309-tip vs HEAD shows only upstream's additive state_slot plumbing). DECISION TABLE (per-hunk, sgl-project#46977 new admission pricing vs entries 265..270): - entry 177 prefill_chunk_alignment: RE-PLANTED as-is -- kwarg + attribute + _align_prefill_chunk (LCM w/ kv_shard_granule) verbatim; the new tree's add_chunked_req grew a kv_shard_granule floor (upstream) that idempotently composes with the LCM (both floor-to-multiple); scheduler-side get_kvcache read RE-PLANTED too (dropped at the merge = the held_row/adder TypeErrors). - entry 266 sgl-project#43484 classic-pool slot ledger: RE-ADAPTED. The unified half is SUPERSEDED-BY-EQUIVALENT: sgl-project#46977 moved the exact fork ledger onto the budget (ChainPrefillBudget.rem_state_slots = mamba_allocator.schedulable + mamba_evictable; debit rem -= state_slot_tokens//cost in reserve(); gate via budget_state's state_slots_exhausted()) -- factor 1, charge == reserve // cost, byte-for-byte identical semantics; the adder-side twin was DROPPED to avoid a double ledger. The CLASSIC half SURVIVES as fork delta (the base-class budget never sees state): isinstance(HybridReqToTokenPool) gate (NOT hasattr -- MagicMock discipline, 266(c) preserved), per-req charge 1 + mamba_initial_tracking_slots (PR-bug math substitution kept, 266(a)), budget_state gate on the FULL charge (< per_req), add_one_req required-slot check incl. the defer_staged mamba branch, and slot-unit DEBIT threading at all five commit sites + _commit_prefill_admission. - entry 267: (B4-1) done. entry 268 fix(2): RE-PLANTED -- the second-unfinished-chunk guard now applies to ALL policies (the merged shortest-prefill-first-only restriction was upstream's own pre-sgl-project#46643 form; git log: sgl-project#46643 never merged). sgl-project#45789's policy-reopening term stays the recorded PROVEN NO-OP (270(i)); test re-pins ..._is_unconditional. - entry 269 page-align: RE-PLANTED verbatim at its 3 sites, composed with sgl-project#46977's floor_chunked_tokens (DCP grid) as page-align-then-grid-then-fork. - entry 270 fork-split: RE-PLANTED (gate on get_exec().mamba.enable_mamba_ extra_buffer + SGLANG_SPLIT_PREFILL_AT_MAMBA_FORK on our env -- the env union landed complete at the merge, environ.py untouched), incl. the continuation/commit/new-chunk/ignore-eos sites, the larger-host-hit re-clamp (270's fork cut lands AFTER page-align, order-safe), the truncation_align_size threading from scheduler (270(iii): _align_prefill_chunk call KEEPS its default arg deliberately), and the 'no other prefill may take its slot' return. - entry 217 (PrefillAdder closes admission on retraction): the finish_storage_prefetch_admission sites VERIFIED PRESENT (retraction/discard x2) -- DEDUPED, no edit. - entry 265: the brp required-slot block's defer/NO_TOKEN shape above; id-set half was B4-2. BEHAVIOR (DEFAULT-ON) reaffirmed for the owed restart-watch: sgl-project#45472's sync-free planning (B4-2 verified in-tree) + sgl-project#46643's UNCONDITIONAL per-round admission re-runs (re-planting this cluster) are the two entry-198-class behavior changes owed TTFT/starvation A/B at the prod restart (still banned; zero GPU execution this session). TEST RE-ANCHORS (upstream rewrites of these files silently dropped the fork's fixture halves -- restored from the 309-tip versions, each pinned by entry 215/266's own text): held_row's _Adder.add_chunked_req truncation_ align_size kwarg + get_kvcache allocator stub (entry-177 pair, upstream sgl-project#46980 rewrite dropped them); dcp_logical's pools NS gains state=None (#46970x _InitializedPools field) and test_scheduler_consumers_receives _logical_capacity re-adapted to the new seams (pool-stats via the storage shape, invariant checker's capacity kwarg REMOVED upstream, load_inquirer direct) -- same anti-double-widening intent, kv_shard_widening=4 fixture obsolete by design after the B4-1 re-plant. ACTUALS (damage -> after, CVD=9, prod venv, per-file): test_prefill_adder 7F/32subF (39F storm) -> ** 71P/0F/94sub ** test_dcp_logical_capacity 1F/6subF -> ** 5P/6sub ** test_scheduler_held_row_admission (regressed by my scheduler wiring, then repaired) -> ** 1P/2sub EXACT (215 pin) ** hybrid_ssm latch+retry family ** 9P ** (entry-198's '8P' + B4-1's case) DIR: unit/managers 1048P/48F/9S/439sub -> ** 1055P/3F/9S/474sub ** (3F = the two order-dependent test_mm_process_config ENV F's [reproduce at base] + test_io_struct 1F [diagnosed B4-5, fixture half]). Lint: ruff format + F821/E9 clean. No GPU; no push. Co-Authored-By: OpenCode <noreply@opencode.ai>
…re-plant) SESSION 2B COMPLETE Entry 312 records: the 5 cluster commits (9bd9007..5cde7a5) with per- cluster batteries; THE sgl-project#46977 RECONCILIATION DECISION TABLE (per-hunk survive-as-is / re-adapt / supersede, incl. the git-log proof that the spec-mamba four arrived in-range while the admission six NEVER merged -- correcting the briefing's dedupe list, and sgl-project#46643 fix(1)'s reconcile as already-merged base-PrefillBudget form = the reason prefill_budget.py got ZERO B4 edits); the entry-200 CAPACITY-PAIR restoration (our configurator's allocator.size branch survived -> upstream's consumer-side multiplications double-counted -> model_runner allocator= kwarg + tp_worker/scheduler subtractive forms re-planted; invariant-checker hunk OBSOLETE by upstream refactor); the io_struct NEEDS-ATTENTION VERDICT (upstream's own pointer_head guard vs stale fork stub -- test-side one-field re-anchor, matching sibling stubs); the -523sub PRUNE-vs-BREAKAGE audit (all three vanished managers files died to upstream's OWN sgl-project#45672 prune, two byte- identical to origin/main, the third's fork delta subsumed by sgl-project#46643 -- recorded, not re-homed); the B3 cross-note closures (MambaCowAllocError CATCHER landed; 216/217 admission interplay VERIFIED absorbed); the 2err population correction (replayssm_ring_fold pruned by sgl-project#44690, gdn cutedsl probe lives in the kernels zone, the spec dir's real err was merge damage, now 0err); the runner-zone finds the damage map missed (_init_model_hooks BOOT-INTEGRITY loss -- real decode-runner builds AttributeError, and component_manager's dropped residency half that parallel_executor already CALLS: both re-planted, 7F+crash-class closed); the true marker census (23 tree-carried, NOT the briefing's 20 -- B3 lesson applied; ALL consumed, B4=0, B1/B2/B5 diff-audited intact). GATES: trailing_endpoint ** 17P = 17P ** re-verified post-B4 (DoD-d, B3's gate unmoved). DoD(e) diff audit: ZERO mem_cache/ files changed, ZERO in qsa/moe-quant zones (moe_hook diff is marker-removal-only). NEW PINS: unit/managers 1009P/81F/9S/412sub/2err -> 1056P/2F/9S/474sub (2F = the two documented order-dependent mm_process_config ENV F's; the dir's 2err never reproduced -- population is the spec row's); unit/spec 363P/20F/21S/238sub/2err -> 388P/0F/21S/238sub/0err EXACT over 7 consecutive full-dir runs. OWED RESTART-WATCH REAFFIRMED: sgl-project#45472's sync-free planning (verified present, upstream form) + sgl-project#46643's unconditional per-round admission re-runs (re-planted) ride the entry-201 restart; entry-198's TTFT/starvation measure STILL OWED. Header: STACK -> qwennext-stack-312+merge5-b4-2026-10-29; +merge5-b4 wave tag; tip -> 5cde7a5; entries 1-312; INTEGRATION OWED annotated B4 LANDED (boot ban STAYS). wanted_stack: UNTOUCHED (no S-item changed by B4 findings -- recorded here). ENV debts recorded NOT-fixed: pcie_vocab_gather GPU suite (27F identical at the merge commit), openai 2.6.1<2.8.0 serving_responses import (upstream's own beam.py), imageio (whole diffusion import chain). NOTHING PUSHED; tree clean; zero GPU execution; zero prod boots all session. Co-Authored-By: OpenCode <noreply@opencode.ai>
rkarhila-amd
left a comment
There was a problem hiding this comment.
This PR has three small changes on scheduling:
(1) bysassing "shortest-prefill-first" check in chunked prefill policy means that all policies lead to same branch
(2) always resetting "batch_is_full" in _get_new_batch_prefill_raw function in the scheduler
(3) changing available_chunk_count calculation in prefill budget, so that available tokens calculation take into account evictable KV tokens among other factors. Also if 0 tokens are available, None is returned, as opposed to old behaviour where full chunk size was returned.
The changes are small but impact all models, and for this reason, I kindly ask for reproduction commands to show the problems that are fixed, and to verify with several other models that the performance with these scheduling changes is not adversely affected.
|
@rkarhila-amd thanks. Reproductions and the multi-model A/B are below. Reproduction commandsEach fix has a unit test that fails on the merge base ( git worktree add /tmp/sched-base fbc90a860e
cd /tmp/sched-base
git checkout ae64753ca5 -- \
test/registered/unit/managers/test_prefill_adder.py \
test/registered/unit/managers/test_scheduler_batch_is_full_latch.py \
test/registered/unit/mem_cache/test_prefill_memory_budget.py \
test/registered/unit/models/test_aiter_attention_backend_handler.py
PYTHONPATH=python python -m pytest -q <the four files above>
Result: 6 failed, 71 passed on base with the PR tests, and 77 passed on the PR branch. CPU only. Multi-model performance (MI355X, TP1)Same image for both arms; only python -m sglang.bench_serving --backend sglang --dataset-name random \
--random-input-len 3000 --random-output-len 300 --random-range-ratio 0.5 \
--num-prompts 320 --max-concurrency 64 --seed 1
Values are means of the two runs. One exception: the first base run of each model in the All runs (output tok/s, mean TTFT ms)
Every request completed in all 24 runs. Differences are within ±1% on every row except Qwen3-30B-A3B default, which is −1.8% against a single warm base run; that is inside the base r1-to-r2 spread on the same row. DeepSeek-V2-Lite server logs had 2–4 lines matching |
Motivation
Under overload on Kimi-K3 (MI355X, TP8, chunked prefill + hybrid KDA/MLA), the scheduler could stall or fail allocations:
alloc_extendfor more KV than is free.batch_is_fullwas cleared only when the running batch shrank, so the waiting queue stalled.Modifications
available_chunk_tokenscaps a continuing chunk by free + evictable KV, less the pagealloc_extendover-asks. When that leaves nothing, the chunk proceeds with the free KV or is deferred.batch_is_fullis re-evaluated every scheduling step;PrefillAdderstill enforces the real limits.Accuracy Tests
New unit tests (
test_prefill_memory_budget.py,test_prefill_adder.py,test_scheduler_batch_is_full_latch.py,test_aiter_attention_backend_handler.py): all 5 new cases fail onmainand pass with this PR (76 passed).End to end, the Kimi-K3 MI355X production build includes these fixes. On a 40-min overload soak (48 concurrent requests against 12 slots), 901/901 completed requests returned 200, the queue peaked at 37, and there were 0 OOM, HSA or assert errors.
Speed Tests and Profiling
Scheduling only; no kernel change.
Checklist
CI States
Latest PR Test (Base): ❌ Run #40956379040
Latest PR Test (Extra): ❌ Run #40956378917
Latest PR Test (AMD ROCm 10): ❌ Run #40956378897