Skip to content

[Perf] Qwen3.8: Allow breakable prefill CUDA graphs for image batches - #2

Closed
eppaneamd wants to merge 1 commit into
mainfrom
qwen38-mm-breakable-prefill-graphs
Closed

eppaneamd wants to merge 1 commit into
mainfrom
qwen38-mm-breakable-prefill-graphs

Conversation

@eppaneamd

@eppaneamd eppaneamd commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Motivation

With --cuda-graph-backend-prefill breakable, the prefill runner refuses graph replay for every Qwen3.8-Flash-Next (Qwen4-Exp) batch that carries multimodal inputs, so image prefills always run eager.

Scope: this enables graph replay for image prefills in deployments without speculative decoding. With speculative decoding enabled (any algorithm, including NGRAM), behavior is unchanged.

This PR keys the refusal on whether speculative decoding is enabled, a launch-time property identical on every rank. Without speculative decoding, image batches become replay-eligible; with any speculative algorithm (including NGRAM), behavior is unchanged. No new flag, environment variable or API.

Modifications

  • python/sglang/srt/model_executor/runner/prefill_cuda_graph_runner.py (+8/-4): replace _qwen_bcg_mtp_draft (no other reader) with _qwen_bcg_multimodal_eager = qwen_bcg and model_runner.spec_algorithm.is_speculative(), and gate multimodal batches on it.
  • test/registered/unit/model_executor/test_prefill_cuda_graph_runner.py: flag derivation over backend, architecture, worker role and speculative algorithm.
  • test/registered/unit/managers/scheduler_components/test_dp_attn.py: DP vote with one image rank and one text rank, refusal on and off.
  • test/registered/unit/configs/test_multimodal_piecewise_cuda_graph.py: forward-time gate for image and text batches.
  • test/registered/unit/model_executor/test_prefill_cuda_graph_runner_helpers.py: drop fixture lines for the removed flag.

The breakable prefill backend is the default on CUDA, so there this applies by default to Qwen3.8-Flash-Next without speculative decoding. On ROCm it is opt-in.

Accuracy Tests

Mean probability of the gold answer over 805 MMMU validation items at concurrency 1, prefill graph off vs on: +0.20 pp (95% CI -0.35 to +0.76). Setup as below.

Speed Tests and Profiling

Setup

  • Image: lmsysorg/sglang-rocm:v0.5.22-rocm724-mi35x-20261021 (SGLang source tree at a2e4ffbcea, AITER 285579b6, torch 2.11.0+rocm7.2).
  • Hardware: 2x MI355X (gfx950).
  • Model: amd/Qwen3.8-Flash-Next-Quark-MXFP4 (revision b2091c38), MTP off.
  • Server (both arms): TP2 + EP2, --attention-backend aiter --linear-attn-backend triton --context-length 8192 --max-running-requests 128 --disable-radix-cache --mm-enable-dp-encoder.
  • Baseline: no prefill CUDA graph (the ROCm default).
  • Patched: this gate change plus
    --cuda-graph-backend-prefill breakable
    --cuda-graph-bs-prefill 256 512 768 1024 1280 1408 2560 2752 3840 4096 5376
    
    The bucket list was derived from this workload's prefill sizes; the default list has not been measured yet.
  • Benchmark: sglang.bench_serving, one 512x512 image per request, 1024 input / 128 output tokens (range ratio 0.8), prompts = 10x concurrency; 2 server launches x 2 runs per row, mirrored order.
  • Revision: measured with an equivalent gate (refusing multimodal batches only on the MTP draft), which admits the same batches as this commit when speculative decoding is off. A re-measure on this commit, including the default bucket list, is in progress.
Concurrency Output tok/s base Patched Change SE (pp) TTFT TPOT
4 246.9 268.0 +8.5% 0.97 -31.9% -5.4%
16 564.6 689.8 +22.2% 0.77 -30.7% -17.3%
32 804.9 1000.3 +24.3% 0.83 -24.1% -19.3%
64 1028.1 1244.9 +21.1% 0.81 -18.3% -17.5%
128 1342.9 1538.7 +14.6% 0.10 -10.2% -13.1%

SE: standard error of the change in percentage points, estimated from baseline-vs-baseline (A/A) runs with the same procedure; a change beyond about 2 SE is outside run-to-run noise. One stalled baseline run at c16 is excluded.

Replay coverage: 3179 of 3408 prefill steps (93.3%) replayed; the rest exceeded the largest bucket or the 2x padding cap, none was refused for multimodal input.

Checklist

  • Format your code: ruff check and ruff format --check clean on the five files.
  • Add unit tests: the four suites above, 65 passed (53 subtests) on CPU (torch 2.14.1+cpu).
  • Update documentation: not needed (no new flag or API).
  • Provide accuracy and speed benchmark results: above; the re-measure on this commit is in progress.
  • Follow the SGLang code style guidance.

Notes

🤖 Generated with Claude Code

The breakable prefill graph runner for Qwen3.8-Flash-Next (Qwen4-Exp:
Qwen4ExpForConditionalGeneration and its MTP draft,
Qwen4ExpForCausalLMMTP) refuses every batch that carries multimodal
inputs, on the target and on the MTP draft alike, so image requests
always run eager prefill even when the breakable prefill backend is
enabled.

Key the refusal on whether speculative decoding is enabled instead of on
the worker's role. Without speculative decoding there is no draft runner
and multimodal batches are replay-eligible: the eager outer forward
builds the merged text and vision embeddings and replay copies them into
the captured body's static input_embeds slot, the same path text batches
already take. With speculative decoding enabled the behavior is
unchanged and the target keeps refusing them. Dropping only the target's
refusal would let DP ranks disagree on replay versus eager for the draft
runner: its verdict is the target's schedule-time vote, which consults
only the target runner, combined with the draft's own rank-local
refusal, so a rank holding images would run its draft eager while the
other ranks replay theirs. That is the disagreement can_replay_locally
exists to prevent. The predicate is the speculative algorithm rather
than the presence of a draft model, so an algorithm without one (NGRAM)
also keeps refusing.

The breakable prefill backend is the default on CUDA and opt-in
elsewhere, so on CUDA this applies by default to Qwen3.8-Flash-Next
without speculative decoding.

The private _qwen_bcg_mtp_draft flag had no other reader and is replaced
by _qwen_bcg_multimodal_eager.

Tests cover the flag across backend, architecture, worker role and
speculative algorithm (including NGRAM), the DP vote with one image rank
and one text rank with the refusal on and off, and the forward-time gate
for image and text batches. Fixtures that set the removed flag are
updated.

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Rony Leppänen <rony.leppanen@amd.com>
@eppaneamd eppaneamd changed the title [Perf] Qwen3.8: allow breakable prefill CUDA graphs for image batches [Perf] Qwen3.8: Allow breakable prefill CUDA graphs for image batches Oct 24, 2026
@eppaneamd

Copy link
Copy Markdown
Owner Author

Superseded by sgl-project#46329.

@eppaneamd eppaneamd closed this Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant