Skip to content

[Bugfix] DeepSeek-V4 DP+PIECEWISE: force aiter unreg collective capture path#1596

Open
ZhangLirong-amd wants to merge 1 commit into
mainfrom
fix/dp-piecewise-collective-accuracy
Open

[Bugfix] DeepSeek-V4 DP+PIECEWISE: force aiter unreg collective capture path#1596
ZhangLirong-amd wants to merge 1 commit into
mainfrom
fix/dp-piecewise-collective-accuracy

Conversation

@ZhangLirong-amd

@ZhangLirong-amd ZhangLirong-amd commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

DeepSeek-V4 DP+PIECEWISE corrupts long outputs (repeated tokens, GSM8K 0.87 vs 0.94). Root cause: aiter custom ag/rs registered read-path relies on FULL whole-graph cross-rank ordering, which PIECEWISE breaks — pool-recycled input is overwritten before peers read it. Fix: force the unreg copy-in path under PIECEWISE. Restores 0.94+.

Tasks Version Filter n-shot Metric Value Stderr
gsm8k 3 flexible-extract 3 exact_match 0.9477 ± 0.0061
strict-match 3 exact_match 0.9484 ± 0.0061

…re path

DP-attention + PIECEWISE cudagraph corrupts long generations (repeated-token
garbage; GSM8K ~0.87 vs 0.94 baseline). Root cause is in aiter's custom
all_gather/reduce_scatter 'registered' capture path used by the DP-MoE
all_gather/reduce_scatter collectives.

The registered path lets each collective kernel directly read every peer's
ORIGINAL input pointer, cross-registered at register_graph_buffers(). This is
only safe under a single whole-forward FULL cudagraph, whose global
read/overwrite ordering of every collective's input holds across all ranks.
PIECEWISE splits the forward into many small per-piece graphs with eager
sections between them, losing that ordering: the caching allocator recycles the
same input address across layers, so a fast rank can overwrite its input via a
later piece while a slow peer is still reading it -> stale cross-rank reads ->
progressive hidden corruption -> repeated-token garbage. Only DP hits this
(TP uses in-place all_reduce; DP+EP uses all2all); FULL and eager are clean.

Fix: when the runner uses PIECEWISE, set enable_register_for_capturing=False on
the aiter tp/dp/ep ca_comm before capture, forcing the copy-in ('unreg') path
that snapshots the input into a pre-registered pool before each collective and
is therefore order-independent (same path as eager / gfx1250). FULL is
unaffected and keeps the faster direct-read path.

Verified: DP+PIECEWISE GSM8K back to 0.94+ (from 0.87), no repeated-token
collapse; TP and FULL paths unchanged.
Copilot AI review requested due to automatic review settings July 14, 2026 12:18
@github-actions

Copy link
Copy Markdown
Contributor

🏷️ CI Guide

Runs automatically on every eligible PR before approval:

  • ✅ Pre Checkin: Black, Ruff, catalog schema validation, non-GPU unit tests

Heavy model tests:

  • ✅ Run after the PR is approved and Pre Checkin passes
  • ✅ Run immediately when an approval review is submitted
  • ✅ Can be requested before approval with labels
Label Tests
ci:full Run all heavy PR model tests: native ATOM, vLLM, and SGLang
ci:atom Run native ATOM model accuracy tests
ci:vllm Run ATOM vLLM OOT model accuracy tests
ci:sglang Run ATOM SGLang model accuracy tests

Heavy jobs are skipped when the PR is not approved and no matching ci:* label is present.
Add labels via the sidebar or gh pr edit 1596 --add-label <label>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR mitigates a DeepSeek-V4 correctness bug seen specifically under DP-attention + --cudagraph-mode PIECEWISE by forcing aiter’s DP/TP/EP collective communicator to use the unregistered (“copy-in”) cudagraph capture path, avoiding cross-rank stale reads caused by allocator pointer reuse across piecewise captures.

Changes:

  • Add ModelRunner._force_aiter_unreg_capture_for_piecewise() to disable ca_comm.enable_register_for_capturing when PIECEWISE cudagraph mode is active.
  • Invoke that helper early in ModelRunner.capture_cudagraph() when _piecewise_cg_active() is true.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2438 to +2445
seen = set()
for getter in ("get_tp_group", "get_dp_group", "get_ep_group"):
try:
from aiter.dist import parallel_state as _ps

group = getattr(_ps, getter)()
except Exception:
continue
@zufayu zufayu requested a review from yitingw1 July 15, 2026 02:20
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.

3 participants