Skip to content

[AMD][Spec] Prune unused EAGLE draft-extend LM-head rows - #34005

Closed
chuyeh wants to merge 26 commits into
sgl-project:mainfrom
chuyeh:feat/eagle-aiter-draft-topk1
Closed

chuyeh wants to merge 26 commits into
sgl-project:mainfrom
chuyeh:feat/eagle-aiter-draft-topk1

Conversation

@chuyeh

@chuyeh chuyeh commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Motivation

During EAGLE draft extend, each request processes a fixed four-position window: one target-model token followed by three draft tokens. The draft model must process all four positions to update its KV cache, but only the hidden state at the last accepted position is used to predict the next draft token.

The existing path projects all four hidden-state rows through the large-vocabulary LM head and then discards three rows. This PR moves row selection before the LM head so only the required row is projected.

Modifications

  • Publish the per-request selected draft-extend row through spec_info on eligible ROCm paths.
  • Capture full hidden states for the next draft iteration while projecting only selected rows through the LM head.
  • Size graph logits buffers for one row per request when pruning is active.
  • Keep the established full-row path when a gathered buffer is required or on non-ROCm platforms.

The independent top-k1 softmax-skip optimization is intentionally handled by #35872.

Correctness

test_eagle_worker_v2_topk1_fastpath.py: 11 passed, 7 subtests passed

The tests cover hidden-state preservation, pruning eligibility, graph output sizing, and fallback behavior. A full InferenceX sweep completed every request at C4/C32/C64/C128.

Performance

  • Hardware: 2× MI355X, TP2 per arm
  • Image: rocm/sgl-dev:v0.5.18-rocm724-mi35x-20260825
  • Model: amd/Qwen3.5-397B-A17B-MXFP4
  • Workload: InferenceX 8192/1024 random lengths, range ratio 0.8
  • AITER unified attention; EAGLE 3 steps / top-k 1 / 4 draft tokens; FP8 E4M3 KV
Conc. Baseline tok/s PR tok/s Throughput Baseline TTFT PR TTFT TTFT Baseline TPOT PR TPOT TPOT Median E2E
4 6,053.89 6,126.07 +1.19% 328.00 ms 327.55 ms −0.14% 5.501 ms 5.379 ms −2.22% −1.42%
32 14,082.48 14,182.76 +0.71% 365.04 ms 361.19 ms −1.06% 19.878 ms 19.718 ms −0.81% −1.74%
64 16,900.01 17,208.39 +1.82% 407.37 ms 495.03 ms +21.52% 33.506 ms 33.005 ms −1.50% −2.40%
128 20,014.44 20,168.92 +0.77% 667.53 ms 658.09 ms −1.41% 57.150 ms 56.865 ms −0.50% −0.70%

Median throughput improves by 0.98% and median TPOT by 1.15%. C32 was repeated after an inconsistent first throughput result; the repeat above aligns throughput with its TPOT and E2E changes. C64 TTFT is a prefill-scheduling outlier: decode TPOT, E2E latency, and throughput all improve at that point.

Checklist

  • Keep the PR scoped to LM-head row pruning.
  • Preserve gathered-buffer and non-ROCm fallbacks.
  • Add focused unit coverage.
  • Run end-to-end serving benchmarks.

CI States

Latest PR Test (Base): ❌ Run #33704304480
Latest PR Test (Extra): ❌ Run #33704304000
Latest PR Test (AMD ROCm 7.2): ⏳ Run #33704304319

chuyeh and others added 6 commits August 7, 2026 10:23
Avoid materializing softmax for greedy draft selection while preserving the established fallback path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Project only the selected draft-extend row through the LM head while preserving full hidden-state capture and gathered-buffer fallbacks.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep full-row LM-head projection as the default exactness path while allowing the selected-row optimization to be enabled explicitly.

Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve the AITER top-k fast path inside upstream's scoped MTP index-sharing lifecycle.

Co-authored-by: Cursor <cursoragent@cursor.com>
Apply the repository's pinned Black formatting so the PR lint check passes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve accelerator and GPU metadata at runtime so the benchmark can cover multiple architectures and model vocabulary sizes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@chuyeh chuyeh changed the title [AMD][Spec] Accelerate EAGLE top-k=1 sampling with AITER [AMD][Spec] Optimize Qwen3.5 EAGLE with AITER top-k1, LM-head pruning, and shared-KV verification Aug 11, 2026
Comment thread python/sglang/srt/environ.py Outdated
@chuyeh
chuyeh force-pushed the feat/eagle-aiter-draft-topk1 branch from e5a43cf to 47190af Compare August 12, 2026 03:48
Select AITER top-k1 and draft-extend row pruning from backend and buffer requirements instead of process-global optimization flags.

Co-authored-by: Cursor <cursoragent@cursor.com>
@chuyeh chuyeh changed the title [AMD][Spec] Optimize Qwen3.5 EAGLE with AITER top-k1, LM-head pruning, and shared-KV verification [AMD][Spec] Accelerate Qwen3.5 EAGLE with AITER top-k1 and LM-head pruning Aug 12, 2026
chuyeh and others added 6 commits August 13, 2026 00:28
Keep CUDA and other backends on the established full-row LM-head path while sharing one ROCm eligibility gate across eager and graph execution.
Reuse the same raw-logit greedy helper as draft_forward so eligible ROCm
requests no longer materialize a full-vocab softmax after selected-row
LM-head pruning.

Co-authored-by: Cursor <cursoragent@cursor.com>
Reuse the same greedy helper as decode draft-extend so eligible ROCm
requests no longer materialize a full-vocab softmax on the prefill seed.

Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve the EAGLE top-k1 fast-path coverage alongside upstream's new idle-draft regression test.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace AITER's unmasked vector-tail argmax with the split Triton reduction so nonfinite and non-aligned vocabulary rows cannot emit out-of-range draft tokens while preserving the raw-logit fast path.

Co-authored-by: Cursor <cursoragent@cursor.com>
@chuyeh chuyeh changed the title [AMD][Spec] Accelerate Qwen3.5 EAGLE with AITER top-k1 and LM-head pruning [AMD][Spec] Accelerate Qwen3.5 EAGLE with Triton top-k1 and LM-head pruning Aug 25, 2026
Reuse the existing postprocess entry point with an optional positions tensor, avoiding an extra wrapper and registry entry while preserving the bounds-safe ROCm path.

Co-authored-by: Cursor <cursoragent@cursor.com>
@chuyeh
chuyeh marked this pull request as ready for review August 25, 2026 10:51
@chuyeh
chuyeh requested a review from yichiche August 27, 2026 02:27
chuyeh and others added 3 commits August 26, 2026 21:36
Resolve the runtime-context helper API migration while preserving ROCm draft-extend logit pruning.

Co-authored-by: Cursor <cursoragent@cursor.com>
Restore the upstream benchmark scope so the PR contains only functional coverage needed for the ROCm Triton path.

Co-authored-by: Cursor <cursoragent@cursor.com>
@chuyeh

chuyeh commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

/rerun-failed-ci

Move the independent ROCm top-k1 selector work to sgl-project#35872 so this PR only projects selected draft-extend rows through the LM head.

Co-authored-by: Cursor <cursoragent@cursor.com>
@chuyeh chuyeh changed the title [AMD][Spec] Accelerate Qwen3.5 EAGLE with Triton top-k1 and LM-head pruning [AMD][Spec] Prune unused EAGLE draft-extend LM-head rows Aug 28, 2026
@chuyeh

chuyeh commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

/rerun-failed-ci

@chuyeh

chuyeh commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

/rerun-failed-ci

@chuyeh

chuyeh commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

/rerun-failed-ci

@chuyeh

chuyeh commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

/rerun-failed-ci

base-b-test-1-gpu-small (2) failed on test_openai_completion_rust.py::test_logprobs_have_zero_kl_against_python_frontend (Rust vs Python token_logprobs exact-equality). Unrelated to this PR's EAGLE draft-extend change; same partition passed on latest scheduled main. Rerunning the failed jobs.

chuyeh and others added 3 commits September 2, 2026 20:15
…aft-topk1

Co-authored-by: Cursor <cursoragent@cursor.com>
Bring the eager-only follow-up onto the latest upstream baseline before revalidating its incremental value.

Co-authored-by: Cursor <cursoragent@cursor.com>
Build on the graph-path implementation from sgl-project#35546 and retain only the incremental eager ROCm optimization, removing duplicated graph behavior and test coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
@chuyeh

chuyeh commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Closing as superseded by #35546, which now owns selected-row LM-head pruning for the draft-extend CUDA-graph path.

After merging current main, I reduced this PR to only its remaining ROCm eager-path delta and reran Qwen3.5 with CUDA graphs disabled:

Concurrency Δ total throughput Δ median TPOT Δ median E2E
4 +0.46% +0.98% −2.17%
8 −0.11% −0.29% +1.17%

Both arms completed all requests with identical input/output token counts. The signs reverse between C4 and C8, so the residual eager-only effect is indistinguishable from run variance. The earlier graph-enabled performance numbers primarily measured functionality that is now upstream through #35546.

Validation after the rescope: 10 focused worker tests passed, 44 inherited selected-row infrastructure tests passed, and pre-commit passed.

@chuyeh chuyeh closed this Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants