Skip to content

[AMD][DSV4.1][CP] Support interleave prefill CP with breakable CUDA graphs on ROCm - #44013

Open
AMD-yanfeiwang wants to merge 5 commits into
sgl-project:mainfrom
AMD-yanfeiwang:amd/dsv41-rocm-prefill-cp-bcg
Open

AMD-yanfeiwang wants to merge 5 commits into
sgl-project:mainfrom
AMD-yanfeiwang:amd/dsv41-rocm-prefill-cp-bcg

Conversation

@AMD-yanfeiwang

@AMD-yanfeiwang AMD-yanfeiwang commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

This extends ROCm interleave prefill CP + breakable CUDA graphs (BCG) to DeepSeek-V4.1-Flash. On HIP, V4.1 uses the low-ratio (C1/C2) layout, and its breakable prefill graph path rejects attention CP.

Stacked PR. Please review only the last commit.

Modifications (last commit)

  • deepseek_v4_backend_hip_radix.py
    • Allows attention CP in the low-ratio breakable prefill graph path.
    • On CP replays, builds the low-ratio write metadata from the live rows of the bucket-padded out_cache_loc.
  • deepseek_v4.py
    • _forward_low_ratio_sources_cp uses the live logical token count. Under CP BCG, total_seq_lens is the capture bucket.
    • Engram hashing in the CP branch runs at an eager break under BCG, as in the non-CP BCG path.
  • layers/cp/bcg.py: on HIP, CP BCG capture buckets start at cp_size * 16, the HIP minimum CP tokens per rank from [Feat] [AMD] DeepSeek-v4.1: Support prefill context parallel #43465. This ensures every captured bucket is CP-active.
  • Tests: test_dsv4_prefill_cp_bcg.py and test_cp_strategy_unit.py (38 passed; 14 of the new tests fail without this commit).

Accuracy Tests

Setup:

  • DeepSeek-V4.1-Flash, TP4 on MI355X, DSpark block 5
  • Image: lmsysorg/sglang-rocm:v0.5.21-rocm724-mi35x-20261011
  • GSM8K: 5-shot, 1319 questions, greedy

Arms:

The CP arms need --language-model-only, because V4.1 vision does not support CP. The stock image rejects this flag, so the BCG arm runs without it. A control run of this branch, BCG with the flag, matches stock BCG within 1%.

BCG CP (#43465) CP + BCG (this PR)
GSM8K 0.895 0.896 0.896
DSpark accept length (GSM8K) 3.39 3.40 3.40

Speed Tests (preliminary)

Prefill TTFT p50 (ms), ISL as listed, OSL 1, measured with bench_serving random. This is preliminary data: InferenceX-recipe and client results (fixed-seq 1k/1k, 8k/1k) will be added.

ISL conc BCG CP (#43465) CP + BCG vs BCG vs CP
2048 1 68 88 62 1.10x 1.42x
2048 4 217 218 191 1.14x 1.14x
2048 16 760 612 609 1.25x 1.00x
8192 1 216 173 179 1.21x 0.97x
8192 4 752 583 596 1.26x 0.98x
8192 16 2867 2264 2276 1.26x 0.99x
32768 1 730 572 605 1.21x 0.95x
32768 4 2852 2222 2233 1.28x 1.00x
32768 16 11852 9274 9424 1.26x 0.98x

Serving 8k/1k: TTFT, TPOT and throughput are within ±5% across arms. Decode already uses graphs in all of them.

Takeaways:

  • CP + BCG improves prefill TTFT over BCG at every point measured, by 1.10–1.28x.
  • It is 1.14–1.42x faster than eager CP for small prefills.
  • From ISL 8k up, it is within 2–5% of eager CP. The largest gap is ISL 32k / conc 1, which is under investigation with profiler traces.

Checklist

  • Format your code with pre-commit.
  • Add unit tests.
  • Provide accuracy and speed benchmark results (InferenceX-method speed results in progress).

CI States

Latest PR Test (Base): ❌ Run #38731361472
Latest PR Test (Extra): ❌ Run #38731361598
Latest PR Test (AMD ROCm 10): ❌ Run #38731361474

…phs on ROCm

Port sgl-project#38603 to the HIP DSv4 attention backend:
- HIP init_forward_metadata_prefill writes the global KV fields with the
  bucket-sized out_cache_loc under prefill graphs (num_write_tokens), passes
  the CP local_index and pads swa_replay_start, matching the CUDA backend.
- CP BCG keeps forward_batch.positions global and feeds the captured body
  CP-local positions and ids through _cp_positions/_cp_input_ids, so the HIP
  unified-KV SWA ring store sees global positions.
- CP BCG sets input_ids_global (rank-major for TP MoE, local for a2a) so the
  DSv4 hash-routed MoE layers route the right tokens (from sgl-project#40333).
… tail

DSV4's body returns (hidden_states, pre_hc_head), and both CP tails (eager
and breakable-graph replay) all-gathered both. The logits processor reads
pre_hc_head only to store hidden states for MTP/EAGLE, and DSpark drops it,
so plain serving and DSpark gathered ~4x the hidden-state bytes for nothing.
On large prefill buckets that gather also exceeds the custom all-gather size
limit and falls back to a lazily initialized RCCL communicator, which showed
up as a one-off multi-second TTFT stall on the first large CP+BCG prefill.
… for DSV4 on ROCm

sgl-project#44022 dropped (interleave, dsv4) from the supported CP BCG combinations
because the capture path did not shard input_ids with the hidden states for
DSV4 hash routing. This branch fills input_ids_global from the CP BCG input
buffers, so add the combination back on ROCm, where it is validated. CUDA
keeps it disabled until the same path is validated on B200.

Restore test_dsv4_prefill_cp_bcg.py with the DSV4 CP BCG checks and make the
supported-configuration check follow the platform.
@AMD-yanfeiwang
AMD-yanfeiwang force-pushed the amd/dsv41-rocm-prefill-cp-bcg branch from 0c983ac to beb70b2 Compare October 15, 2026 11:53
…oject#43465 by At1a8)

Applied sgl-project#43465 (head 5c5862f, author At1a8, open) on top of
the HIP CP+BCG port (sgl-project#43819), plus its later test update (07efa4b) that drops
the stale V4.1 HIP CP rejection case. Conflict resolution in
deepseek_v4_backend_hip_radix.py: both PRs pad swa_replay_start and pass
cp_metadata.local_index to apply_cp_reindex; kept the single copy from sgl-project#43819,
which also keeps num_write_tokens for breakable prefill graphs.
…raphs on ROCm

Stacked on the HIP V4.1 prefill CP (sgl-project#43465) and the HIP CP+BCG port (sgl-project#43819):
- HIP low-ratio BCG capture accepts attention CP (the late-layer tail of decoder
  SWA bounded replay is already rejected with prefill graphs by the hook).
- A CP replay builds the low-ratio metadata from the static batch, whose
  out_cache_loc is padded to the bucket. The write fields (raw/c1/c2 out_loc)
  are built from the live prefix, since the eager low-ratio sources write only
  the live rows; init_forward_metadata_in_graph still pins the bucket-sized SWA
  store target read by the captured segments.
- _forward_low_ratio_sources_cp reads the live logical rows; CP BCG sets
  total_seq_lens to the capture bucket.
- Engram hashing in the CP branch runs at an eager break under BCG.
- On HIP, interleave CP BCG capture buckets start at cp_size * 16, the HIP
  minimum CP tokens per rank, so every captured bucket shards.
- CP decode attention TP also slices the gfx950 MXFP8 weight copies
  (weight_scale_mx_e8m0, weight_scale_inv_mx, weight_bf16) that V4.1's 32x32
  ue8m0 fp8 blocks are served from; slicing only weight and the block scales
  failed the first decode-graph capture of wq_b with mismatched scale shapes.

This branch has not been deployed

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant