Repository navigation
[AMD] Fix FP4 indexer OOR - #37660
Merged
Merged
Conversation
RolaoDenthu
requested review from
BBuf,
DarkSharpness,
Fridge003,
HaiShaw,
HydraQYH,
Qiaolin-Yu,
celve,
hebiao064,
ispobock,
merrymercy and
yuan-luo
as code owners
September 2, 2026 21:37
RolaoDenthu
force-pushed
the
dsv4/fp4-indexer-fix-oor
branch
from
September 2, 2026 23:49
1f7f7bd to
3bf337d
Compare
1am9trash
approved these changes
Sep 3, 2026
1am9trash
left a comment
Collaborator
There was a problem hiding this comment.
This PR
- Pre-allocate a large buffer up front and reuse it. Only reallocate when the decode req exceeds the current capacity. This avoids repeated alloc/free cycles that cause fragmentation.
- When the required size is larger than buffer supported (e.g. prefill with long ctx), process the rows in chunks.
LGTM.
HaiShaw
approved these changes
Sep 3, 2026
HaiShaw
left a comment
Collaborator
There was a problem hiding this comment.
Changes hip gated. LGTM.
This was referenced Sep 3, 2026
This was referenced Sep 5, 2026
StevenChenSE
pushed a commit
to StevenChenSE/sglang
that referenced
this pull request
Sep 6, 2026
Co-authored-by: Thomas Wang <1am9trash@gmail.com>
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
On MI355X, DeepSeek-V4-Pro with the FP4 indexer aborts under long-running agentic workloads:
The indexer allocates a fresh torch.empty(num_tokens, max_seq_len) for logits on every layer of every forward. If no cached block is large enough to reuse, it has to allocate a new one. Torch does release the tensor when it's done, but only back to its own caching allocator — the driver still sees that memory as taken. And max_seq_len follows the context length, which in an agentic session only grows, so each request is slightly larger than the last, the older blocks never get a chance to be reused, and they just pile up in the pool. Driver-visible memory drains block by block until the allocation fails with out of resources.
Modifications
Prefill logits are served as a view into one pre-allocated block instead of a fresh torch.empty per call. The request size becomes constant, so the block is always reused and nothing strands. Decode keeps the plain allocation: its rectangle is bounded by the capture shapes and lives in the graph memory pool, and creating the pooled block mid-capture would hand graph-pool memory to later replays. Budget is set by SGLANG_DSV4_FP4_LOGITS_BUDGET_MB (default 2048).
A fixed block alone isn't enough — a batch that doesn't fit would fall back to a dynamic allocation and start stranding again. logits_rows_per_chunk() reports how many rows fit, and the FP4 prefill path loops over row chunks, running each chunk's top-k before reusing the block. This decouples peak scratch from context length. Rows are scored and reduced independently, so the result is elementwise-identical to a single pass; the single-chunk case (the common one) passes the whole batch through without slicing. The KV payload/scale getters are hoisted out of the loop since they await the layer's KV transfer, and topk_v2 metadata is re-planned per chunk because the cached plan routes rows by their index in the full range.
Accuracy Tests
Speed Tests and Profiling
Checklist
Review and Merge Process
/tag-and-rerun-ci,/tag-run-ci-label,/rerun-failed-ciCI States
Latest PR Test (Base): ❌ Run #33735112082
Latest PR Test (Extra): ❌ Run #33735111880
Latest PR Test (AMD ROCm 7.2): ⏳ Run #33735112202