Conversation
Co-authored-by: Cheng Wan <54331508+ch-wan@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: DarkSharpness <2040703891@qq.com> Co-authored-by: DarkSharpness <76582120+DarkSharpness@users.noreply.github.com> Co-authored-by: Ke Bao <ispobaoke@gmail.com> Co-authored-by: Khoa Pham <khoa.pham@radixark.ai> Co-authored-by: Xiaoyu Zhang <1182563586@qq.com> Co-authored-by: Xiaoyu Zhang <xiaoyu.zhang@radixark.ai> Co-authored-by: Yuhao Yang <47235274+yhyang201@users.noreply.github.com> Co-authored-by: Yuwei An <ayw.sirius19@gmail.com> Co-authored-by: Zhichen Zeng <zczeng@uw.edu> Co-authored-by: Ziyi Xu <ziyi.xu@radixark.ai>
…or the lanes outside a row (sgl-project#38829) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…gl-project#38879) Co-authored-by: DarkSharpness <2040703891@qq.com>
…project#38952) Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…L names (sgl-project#38951) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…ok/s) (sgl-project#38976) Co-authored-by: DarkSharpness <2040703891@qq.com> Co-authored-by: Liangsheng Yin <lsyincs@gmail.com>
…oject#38963) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…-project#39068) Co-authored-by: DarkSharpness <2040703891@qq.com> Co-authored-by: DarkSharpness <ziyi.xu@radixark.ai>
…) (sgl-project#39098) Co-authored-by: weireweire <20922698+weireweire@users.noreply.github.com>
…parse MQA logits (sgl-project#38944) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2e0e3b6 to
40683f0
Compare
…logits, tail-only candidate masks The eager dense fp4 indexer materialized fp32 logits [T, lc] in one shot (30 GiB per rank for a 16384-token chunk of a 488K-token request) and the candidate-source layer built bool masks [T, lc] in pieces then torch.cat-copied them (7.5 GiB each), so long agentic prompts OOMed at --mem-fraction-static 0.80. Score each request in row chunks under _DENSE_INDEXER_LOGITS_BUDGET_BYTES, write mask rows into a preallocated tensor, and under decoder SWA bounded replay publish only the tail rows the late layers read. Transient memory is now ~10 GB from 300K to 1M context on 4x GB300; page/raw indices and masks are unchanged where the original path is deterministic. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
40683f0 to
cb8dd03
Compare
|
Independent GB10 serving evidence for the logic in We backported the row-chunked logits and tail-only candidate-mask changes to SGLang Conditions: four DGX Sparks / GB10 (128 GB unified memory per host), TP4/EP4 over a switchless RoCE cycle with SparkRing's patched NCCL 2.30.7; model revision
Both configurations passed seven-key authentication, vision/tools, chunk/tail-boundary and mixed prefill/decode checks. All 20 first-token outputs and all 20 greedy continuations (up to 48 tokens) matched our fixed reference, including four longer prompts. Exact retrieval passed at 130258, 260119 and 406713 prompt tokens. No benchmark request errors were observed. We retained the backport for the additional measured headroom. Limits: the memory measurement is a five-second host MemAvailable sample, not an isolated CUDA peak-allocation measurement. The baseline was already serving and the candidate was rebooted before qualification; page-cache/boot state remains a confound, and this is one qualification pair rather than repeated independent boot trials. The long retrieval timing is one observation per arm; the small short-prefill change is not a demonstrated speedup. The nominal 64K workload uses fresh random prompts (about 59K actual tokens), one output token, and throughput including request overhead. We have not yet qualified a larger context, tested CP, or independently reproduced your bitwise internal-index comparison. Our original deployment/replay reference is in SparkRing PR267; this new patch result is separate from the six-hour soak recorded there. Sharing the bounded result because the reduced transient also appears useful on GB10's much tighter unified-memory budget. |
c81d5c2 to
660722f
Compare
Motivation
Serving DeepSeek-V4.1-Flash on 4x GB300 (TP4 + EP4,
--chunked-prefill-size 16384,--enable-encoder-swa-bounded-replay --enable-decoder-swa-bounded-replay,--mem-fraction-static 0.80) under an agentic-coding workload (DeepSWE, prompts up to 705K tokens) crashed with CUDA OOM on all ranks in_publish_or_consume_candidatesduring a 16384-token chunk of a 487,936-token request. The eager dense fp4 prefill indexer (_low_ratio_index_topk_dense, DeepGEMMfp8_fp4_mqa_logits) scores a whole prefill chunk against the full context in one fp32 tensor[T, lc](16384 x 487936 x 4 B = 29.8 GiB per rank), and the candidate-source layer then builds bool masks[T, lc]in 550-row pieces andtorch.cat-copies them (7.45 GiB each). Peak transient is ~6 B x chunk tokens x context tokens per rank, so it grows without bound with context; the prefill CUDA graph path and the torch fallback are already row-chunked, but every context above 16K runs eager.Reproduction on the unpatched branch: a single 600K-token prompt kills the server within 18 s; even a cold 300K prompt reaches a 49.7 GB transient against 50 GB free after graph capture.
Modifications
In
_low_ratio_index_topk_dense:_DENSE_INDEXER_LOGITS_BUDGET_BYTES(2 GiB of fp32 logits), running the ragged top-k per chunk into the sharedselectedbuffer. Short contexts still take a single chunk, so the common path is unchanged.[rows, lc]tensor instead of a list plus a concatenation copy.enter_late_layer_tailslices every mask down to those rows anyway, so the full-row masks were computed and copied for nothing.The separate
_publish_or_consume_candidateshelper folds into the loop.Accuracy / equivalence
Exact in-forward check (debug build, not in this PR): the original and the new implementation ran back to back on identical inputs and their
page_indices/raw_indices/ published masks were compared bitwise, over cold single prompts (8K, 60K, 200K), a batch of four 7K prompts, and a prefix-hit prefill.0ff9c986c)f3c3e7c7aThe residual is top-k tie ordering on ratio-2 layers with heavily repeated prompt text, at the same rate and magnitude as the original path disagrees with itself. DeepGEMM's
fp8_fp4_mqa_logitsis bitwise row-count invariant (16384 rows in one call vs chunks of 128..4096, all equal) and deterministic across runs, so the chunking itself introduces no numerical change.Benchmarks
4x GB300, TP4 + EP4, both replays on, chunk 16384, mem-fraction 0.80 (50 GB free after graph capture), cold prompts, greedy 4 new tokens:
Without decoder replay the published mask is still 1 B per row per context token (16 GiB for a 16K chunk at 1M context); a block-level mask would remove that but changes the consumer format, so it is left for a follow-up.
Checklist
🤖 Generated with Claude Code
CI States
Latest PR Test (Base): ❌ Run #34830063530
Latest PR Test (Extra): ❌ Run #34830063321
Latest PR Test (AMD ROCm 10): ❌ Run #34830063499