Skip to content

Fix stale track rows corrupting conv checkpoints under the prefill graph - #34184

Merged
ispobock merged 3 commits into
mainfrom
fix-prefill-graph-stale-track-rows
Aug 10, 2026
Merged

ispobock merged 3 commits into
mainfrom
fix-prefill-graph-stale-track-rows

Conversation

@ispobock

@ispobock ispobock commented Aug 9, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

A prefix-cache hit on a hybrid-SWA model can decode off a conv state it never produced. The replayed prefill graph reads _capture_req_slots rows, but mamba_track_mask / mamba_track_indices keep whatever the previous replay left past the live batch, so the captured track scatter lands the current window in an earlier request's checkpoint. Whichever request later restores that prefix is wrong for its whole generation.

The sentinel tail directly above exists for this reason -- "the captured graph reads all req_slots entries, so stale values from the previous replay must be cleared" -- and clears six fields. The two track buffers live in the buffer registry instead, and their clear is guarded by bs != raw_bs in PrefillInputBuffers.fill_from; the prefill graph passes padded_bs == raw_bs because it pads tokens rather than requests, so that branch never runs.

This needs no speculative decoding. It takes the prefill CUDA graph, chunked prefill, concurrency and a prefix hit together, and disabling the prefill graph alone makes it go away. #34043 fixed a neighbouring failure on the spec path -- the scatter being specialised out of the capture -- whereas here the checkpoint is written and scattered to a stale destination; it still reproduces with #34043 in.

Modifications

Zero the two track rows alongside the six the sentinel tail already covers.

#34168 test_inkling_small_nvfp4.py drops the --disable-prefill-cuda-graph it was carrying. That flag was steering the deterministic KL case around this bug, and that case is the regression guard for it, so it belongs back on the graph path.

The alternative is to make padded_bs report the captured slot count, which makes fill_from's clear live and stops its bs != raw_bs branch from being dead code. That is the more honest shape -- while the request dimension claims to be unpadded, the next captured kernel that reads req_slots rows repeats this -- but it changes behaviour under every phase sharing those buffers, so this PR takes the local fix. Happy to switch.

Accuracy

Shrunken Inkling checkpoint, tp=1, 32 concurrent prompts, prefill graph on, --enable-deterministic-inference. Differing logprobs against a flushed reference prefill:

              prefill_cache_hit                match
           512 tokens    8 tokens
before     1022/16384      16/256              0
after         0/16384       0/256              0

The two corrupted checkpoints were observed rather than inferred: instrumenting the slot at insert time shows exactly two whose conv state differs from the same run without the graph, and their claimed track seqlens are the prefixes of the two requests that go wrong.

The A/B above is the shrunken checkpoint at tp=1. The CI case runs the real NVFP4 weights at tp=4, where the batch packs differently and picks different victims, so I have not reproduced-and-fixed on that exact configuration -- if it stays red, the same shape of gap exists somewhere else and the instrumentation above finds it.


CI States

Latest PR Test (Base): 🚫 Run #31327464791
Latest PR Test (Extra): ❌ Run #31327464735

@github-actions github-actions Bot added the blackwell SM100/SM120 label Aug 9, 2026
@ispobock ispobock added run-ci CI: run the baseline test suite on this PR bypass-fastfail run-ci-extra CI: also run the extra suite (requires run-ci) labels Aug 9, 2026
@ispobock

ispobock commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator Author

/rerun-test test/registered/models_e2e/test_inkling_small_nvfp4.py

@github-actions

github-actions Bot commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

Results for /rerun-test test/registered/models_e2e/test_inkling_small_nvfp4.py:

🚀 4-gpu-b200 (1 test): ✅ View workflow run

cd test/ && python3 registered/models_e2e/test_inkling_small_nvfp4.py

@ispobock

ispobock commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator Author

/rerun-failed-ci

@ispobock

ispobock commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator Author

@ispobock
ispobock merged commit 25b7015 into main Aug 10, 2026
222 of 264 checks passed
@ispobock
ispobock deleted the fix-prefill-graph-stale-track-rows branch August 10, 2026 00:57
saturn-acc pushed a commit to saturn-acc/sglang that referenced this pull request Aug 16, 2026
Atituiset pushed a commit to Atituiset/sglang that referenced this pull request Sep 10, 2026
efschu pushed a commit to efschu/htsglang that referenced this pull request Sep 26, 2026
…-prefill-graph(-split/-tiny/-max-prefix), --p-deep-split-from

Picks der 27B-Linie in Reihenfolge (alle Schalter Default aus, P-Env/argv ohne Flag
byte-gleich): upstream-Ports bac77bc (sgl-project#37657) eb6d7d6 (sgl-project#34184) dc9fbf9
(sgl-project#32219 Teil) als Voraussetzung des Prefill-Graphen; 5fd4e77 5d8612b 02e218f
d24a17d 6b24aa6 3e093fe (P-Host-Overlap, #PGAP, P-NOSYNC); d32ddcb fb7ea2b
37ea1db 3e6ce57 (P-Prefill-Graph); 735db6a (+ 4e03821 als reine Verschiebung
durch die Auflösung erledigt) f49f2fd 51e39d4 dc128e3 18639ea.

Konfliktauflösungen:
- scheduler_pp_mixin: NF H49 PP-HOST-PERIOD und 27B P-HOST-OVERLAP komponiert (die im
  Inventar genannte Doppel-Instrumentierung): H49 note_launch/note_no_batch/note_sync
  bleiben, der d2h-Wait steht zusätzlich im #PGAP-Span, deferred publish + Lead-Bound
  nach dem Launch wie 27B. Beide Instrumente getrennt schaltbar (H49-Env / --p-host-overlap).
- unified_radix_cache: Chunk-Publish unter H2-sync_trace UND #PGAP-Span.
- launcher common_flags: p_chunked_prefill_tokens() = Graph-Bucket oder
  P_CHUNKED_PREFILL_TOKENS (NF-Env, Default = Konstante; 27B byte-gleich).
- argv_p: NF p_micro_batch_flags + 27B p_prefill_graph_flags() vor extra/H25-Strip.
- solve_p_cut: prefill_graph_pool_mib neben NF sgl-project#114 activation_reserve.
- --d-replayssm-spec der 27B-Hunks nicht doppelt registriert (NF-Form bleibt).

Tests (test27b.sh): 20 portierte Testdateien 204 passed, 2 skipped;
test_weg2_vision_prefill_graph_seam_0924 nicht gelaufen (Boot aktiv, incg-Schlange),
nachzufahren. dup_defs_gate: 0 neu.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blackwell SM100/SM120 bypass-fastfail run-ci CI: run the baseline test suite on this PR run-ci-extra CI: also run the extra suite (requires run-ci)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant