Skip to content

[Fix] [AMD] dsv4.1: Fix decode graph capture with quantized low-ratio activations - #46151

Merged
hnyls2002 merged 6 commits into
sgl-project:mainfrom
kevin-mii:amd/dsv41-low-ratio-act-rows
Oct 24, 2026
Merged

hnyls2002 merged 6 commits into
sgl-project:mainfrom
kevin-mii:amd/dsv41-low-ratio-act-rows

Conversation

@kevin-mii

@kevin-mii kevin-mii commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

#45407 made forward_low_ratio_sources cut x and q_lora to the hoisted rows on every step (x[:n], q_lora[:n]); before, it cut them only when DP attention padded an eager extend. On ROCm, q_lora (and on some routes x) reaches it quantized, as an Mxfp8Activation (q and scale) or an Fp8GridActivation: structs that refuse a slice. Since #45407, a DeepSeek-V4.1 server on MI35x fails while capturing its decode graphs (seen with --monokernel-backend amd; the failing call is SGLang's own forward, which every decode step of a plain server runs):

File ".../layers/attention/deepseek_v4_backend.py", line 3402, in forward_low_ratio_sources
    q_lora = q_lora[:n]
TypeError: 'Mxfp8Activation' object is not subscriptable

Modifications

Accuracy Tests

MI350X, TP4, DeepSeek-V4.1-Flash, this branch on main 74c08f3, with sgl-project/sgl-amd-mono main 52dceb0:

  • test/registered/unit/layers/test_dsv41_late_layer_tail_readers.py: 13 passed. The new case (DP padding cuts a quantized q_lora field by field) fails on main with the error above.
  • test/registered/kernels/ops/attention/dsv4/test_dsv41_decode_glue_hip.py: 6 passed.
  • sgl-amd-mono's test/e2e/test_deepseek_v41_server.py (--monokernel-backend amd): 9 passed. GSM8K: 0.930 (DSpark verify server), 0.905 (decode server). Both servers step past the monokernels' widths onto this path.
  • SGLang alone, without the monokernels, the same two servers, GSM8K (200 questions, 8 shots): 0.895 (DSpark verify), 0.905 (decode).
  • sgl-amd-mono's test/kernels/test_deepseek_v41_kernels.py against this SGLang (K1, K2 and the FFN launch bit for bit, with and without aiter's preshuffle, every width the spec builds): 6 passed, on 048555d.

The other GPU runs used e62ad22. The commits after it change only docstrings and the unit test.

Speed Tests and Profiling

No speed change intended: decode and verify steps now skip a cut that kept every row. AgentX (InferenceX agentic coding, TP4, concurrency 1, 900 s) with the monokernels, on this PR's first version (048555d, same decode and verify path): P90 637.6 tok/s/user, P50 668.0, 6627 tok/s/GPU, acceptance length 3.52.

Checklist

🤖 Generated with Claude Code


CI States

Latest PR Test (Base): ⏳ Run #40030122492
Latest PR Test (Extra): ❌ Run #40030122499
Latest PR Test (AMD ROCm 10): ❌ Run #40030122510

sgl-project#45407 made forward_low_ratio_sources slice x and q_lora to the hoisted rows on
every step. On HIP q_lora (and on some routes x) arrives quantized, an
Mxfp8Activation or Fp8GridActivation struct, which a slice cannot cut, so every
DeepSeek-V4.1 decode graph capture failed with "'Mxfp8Activation' object is not
subscriptable". A struct is now cut field by field, and kept as is when all its
rows are live (every decode and verify step); a tensor slices as before.
write_tail_source_kv counts a struct's rows the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kevin-mii

Copy link
Copy Markdown
Collaborator Author

/tag-and-rerun-ci

@github-actions github-actions Bot added the run-ci CI: run the baseline test suite on this PR label Oct 23, 2026
Kevin Mi and others added 4 commits October 23, 2026 21:23
…rows

Simpler form of the fix: forward_low_ratio_sources cuts x and q_lora only when
the step has rows past the hoisted ones (DP attention padding an eager extend),
as before sgl-project#45407; in every other case they already have n rows. That cut keeps
HIP's quantized activations whole, field by field. write_tail_source_kv's input
is a bf16 tensor (fused_boundary_attn_input), so it keeps sgl-project#45407's check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… rows

The all-rows-live pass-through (the crash sgl-project#45407 caused) and the DP-padding cut are
separate cases, each with the failure it prevents in its docstring. The hoisted
req / pos assertions go: test_tail_break_uses_live_prefix_of_hoisted_rows pins them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…guards

`_first_rows` states its contract and why a struct is cut by fields; the two
test docstrings state the TypeError each prevents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orts

The q_lora fixture sits beside `_run` and the cut struct is named `cut`
rather than `got`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kevin-mii kevin-mii changed the title [Fix] [AMD] dsv4.1: Cut HIP's quantized low-ratio activations by rows [Fix] [AMD] dsv4.1: Fix decode graph capture with quantized low-ratio activations Oct 23, 2026
The DP padding case also fails on main's unconditional slice, so the
pass-through case for all-live rows guarded nothing more; the helper goes
with it. Decode and verify steps stay covered by the HIP e2e.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kevin-mii

Copy link
Copy Markdown
Collaborator Author

/rerun-test test/registered/e2e/models/test_deepseek_v41_flash_gb300_dp2ep2.py test/registered/e2e/models/test_deepseek_v41_flash_gb300_trtllm_bounded_bcg.py

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

🚀 2-gpu-gb300 (2 tests): ✅ View workflow run

cd test/ && python3 registered/e2e/models/test_deepseek_v41_flash_gb300_dp2ep2.py
cd test/ && python3 registered/e2e/models/test_deepseek_v41_flash_gb300_trtllm_bounded_bcg.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deepseek run-ci CI: run the baseline test suite on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants