Skip to content

[AMD] Fix DSv4 draft extend taking the target compression path during prefill - #37713

Merged
HaiShaw merged 1 commit into
sgl-project:mainfrom
Duyi-Wang:fix/dsv4-draft-extend-need-compress
Sep 3, 2026
Merged

HaiShaw merged 1 commit into
sgl-project:mainfrom
Duyi-Wang:fix/dsv4-draft-extend-need-compress

Conversation

@Duyi-Wang

@Duyi-Wang Duyi-Wang commented Sep 3, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

On MI355X (gfx950), DeepSeek-V4-Pro with EAGLE/MTP at TP 4 with DP attention aborts within
90 s of the server becoming ready — on the first batch of real prefills, before a single decode
step completes:

HSA_STATUS_ERROR_EXCEPTION: An HSAIL operation resulted in a hardware exception. code: 0x1016
torch.AcceleratorError: HIP error: unspecified launch failure  (hipErrorLaunchFailure)

  eagle_worker_v2.py         _draft_extend_for_prefill
    deepseek_v4_backend_hip_radix.py  init_forward_metadata_prefill
      _attach_unified_kv_prefill_meta -> torch.repeat_interleave

Deterministic, reproduced on clean nodes across several configurations. The reporting rank
varies (DP1 and DP2 observed), so it is not rank-specific.

Root cause

Two call sites reach the prefill branch of init_forward_metadata for a draft model, and only
one rewrites forward_mode:

path call site forward_mode
decode eagle_worker_common.prepare_for_draft_extend() sets ForwardMode.DRAFT_EXTEND_V2
prefill eagle_worker_v2._draft_extend_for_prefill() hands over the target's batch untouched → stays ForwardMode.EXTEND

The backend decides compression from forward_mode alone (need_compress = not is_draft), so on
the prefill path a draft model is sent down the compression path. It owns no compression pool to
begin with — the two pools initialise as

draft:  c4_size=0        c128_size=0
target: c4_size=1832064  c128_size=57252

so this is not a draft/target size mismatch but compression metadata computed against a pool that
does not exist. The resulting out-of-bounds access is reported asynchronously and surfaces at the
next synchronisation point — the repeat_interleave in _attach_unified_kv_prefill_meta, which
omits output_size and therefore implies a sum() D2H copy. That line is where the fault is
observed, not where it occurs.

Instrumenting the branch confirms it at runtime: on the failing ranks the draft worker is handed
ForwardMode.EXTEND, and the write offsets it computes (c4_out_loc up to 64) point into a pool
of size 0.

Modifications

The backend already reads model_runner.is_draft_worker in __init__ (for the dspark check).
Keep it as a named attribute and use it as a second, mode-independent source of truth:

is_draft = (
    forward_batch.forward_mode.is_draft_extend_v2() or self.is_draft_worker
)

A draft worker now never takes the compression path regardless of the forward_mode it is
handed. Only draft-worker backend instances are affected; the target is unchanged.

Fixing it here rather than by rewriting forward_mode in _draft_extend_for_prefill keeps the
blast radius to this backend — forward_mode is read by the logits processor, the CUDA-graph
runners and several other backends.

Tests

Full agentic replay (long-context, tool-heavy, multi-turn) on a single MI355X node, TP 4 + DP
attention, EAGLE MTP (3 steps, topk 1, 4 draft tokens), hierarchical cache, concurrency 32.

before after
hipErrorLaunchFailure crash 57 s after ready 0
Prefill batch stops at the crash 915
Decode batch 0 reached
client warmup returned=1/354, then stalled returned=330/354, errors=0

Same image, same node class, same workload; the only difference is this patch.

🤖 Generated with Claude Code


CI States

Latest PR Test (Base): ❌ Run #33732720236
Latest PR Test (Extra): ❌ Run #33735198934
Latest PR Test (AMD ROCm 7.2): ❌ Run #33732720244

@Duyi-Wang
Duyi-Wang force-pushed the fix/dsv4-draft-extend-need-compress branch 2 times, most recently from 36ecc90 to 068f9d9 Compare September 3, 2026 07:56
… prefill

On MI355X, DeepSeek-V4-Pro with EAGLE/MTP at TP 4 with DP attention aborts
within 90 s of the server becoming ready, on the first batch of real prefills
and before a single decode step:

    HSA_STATUS_ERROR_EXCEPTION ... code: 0x1016
    torch.AcceleratorError: HIP error: unspecified launch failure
      eagle_worker_v2.py _draft_extend_for_prefill
        deepseek_v4_backend_hip_radix.py init_forward_metadata_prefill
          _attach_unified_kv_prefill_meta -> torch.repeat_interleave

Two call sites reach the prefill branch of init_forward_metadata for a draft
model, and only one rewrites forward_mode:

  * eagle_worker_common.prepare_for_draft_extend() -- the decode path -- sets
    ForwardMode.DRAFT_EXTEND_V2.
  * eagle_worker_v2._draft_extend_for_prefill() -- the prefill path -- hands
    the draft runner the target's batch untouched, so it stays
    ForwardMode.EXTEND.

The backend decides compression from forward_mode alone, so on the prefill
path need_compress stays True and the draft model is sent down the compression
path. It owns no compression pool to begin with -- the two pools initialise as

    draft:  c4_size=0        c128_size=0
    target: c4_size=1832064  c128_size=57252

so this is not a draft/target size mismatch but compression metadata computed
against a pool that does not exist. The resulting out-of-bounds access is
reported asynchronously and surfaces at the next synchronisation point, the
repeat_interleave in _attach_unified_kv_prefill_meta, which omits output_size
and so implies a sum() D2H copy. That line is where it is observed, not where
it faults.

The backend already reads model_runner.is_draft_worker in __init__ (for the
dspark check). Keep it as a second, mode-independent source of truth, so a
draft worker never takes the compression path regardless of the forward_mode
it is handed. Only draft-worker backend instances are affected.
@Duyi-Wang
Duyi-Wang force-pushed the fix/dsv4-draft-extend-need-compress branch from 068f9d9 to 8c28a05 Compare September 3, 2026 08:19
@kkHuang-amd kkHuang-amd added the run-ci CI: run the baseline test suite on this PR label Sep 3, 2026

@kkHuang-amd kkHuang-amd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

One question, this issue should be not related to TP size, right?

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.

4 participants