[bugfix] Gate the fused Ulysses all-to-all kernel on one host, and stop re-voting per call - #1807
Open
shaoxiongduan wants to merge 1 commit into
Open
Conversation
…er call Two defects measured on 4x GB200, MiniMax-H3 geometry, per attention layer (NCCL baseline 2421us at sp=4, 1295us at sp=8 across two trays): as shipped sp=4 2035us (1.19x) sp=8 3102us (2.4x SLOWER than NCCL) with these sp=4 1590us (1.52x) sp=8 declines, 1300us ncclTeamLsa answers "addressable", not "fast". NCCL 2.29 extends the LSA team across a multi-node NVLink domain, so on a GB200 rack the gate passes for ranks on different trays and the kernel arms. Its fine-grained 16B remote stores are far slower there than NCCL's bulk transfers. Require a single host, which is the regime the slab decomposition was tuned for, and which matches flashinfer's own gate. torch 2.12 (the pin) bundles NCCL 2.29.7, so this is reachable today. _can_attempt now computes its local verdict without collectives and then runs one unconditional all_gather_object carrying (hostname, local_ok). A collective behind a rank-local early return hangs the group whenever ranks disagree -- exactly the case this gate exists to detect. Verified: with one rank reporting the kernel unavailable, the earlier ordering timed out at 180s while this completes with correct results on every rank. The per-call agreement cost a flat ~227us regardless of operand size -- a host-side gloo all_gather before every collective. The signature is architectural: two distinct values (scatter and gather shapes) across 50 layers x 4 steps. Cache the verdict so the collective runs twice per generation instead of ~400 times. The cache trades one property: a rank whose signature diverges mid-run now misses the cache and calls the collective alone, hanging rather than falling back. Re-voting every N calls would bound that if wanted.
Contributor
Merge Protections🔴 1 of 1 protections blocking · waiting on 👀 reviews and 🤖 CI
🔴 PR merge requirementsWaiting for
This rule is failing.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
Two defects in the fused Ulysses all-to-all from #1740.
On a sequence-parallel group that spans two nodes of a GB200 rack, the kernel engages
and runs about 2.4x slower than the NCCL path it replaces.
ncclTeamLsareportswhether peer memory is addressable, not whether it is fast, and NCCL 2.29 extends the
LSA team across a multi-node NVLink domain. The kernel's fine-grained 16-byte remote
stores lose badly to NCCL's bulk transfers over that fabric.
Separately, the per-call agreement collective costs a flat ~227us, which eats most of
the speedup on a single node: 1.52x drops to 1.19x, and on the smaller gather operand
it goes net negative.
Fixes #
Changes
Require a single host. The topology gate now compares hostnames alongside the
LSA check. This is the regime the slab decomposition was tuned for, and matches
FlashInfer's own gate (
ulysses_topology.py:222).Make the topology exchange unconditional.
_can_attemptcomputes its localverdict without collectives, then runs one
all_gather_objectcarrying(hostname, local_ok), then decides. A collective behind a rank-local early returnhangs the group exactly when ranks disagree, which is what this gate detects.
Cache the per-call agreement by signature.
_agree_callissued a host-side glooall_gatherbefore every collective. A generation has two distinct signatures, thescatter and gather shapes, across 50 layers x 4 steps, so this drops ~400 collectives
to 2. Arming, window growth, and a new resolution each change the signature, so a
stale verdict cannot be served.
Test Plan
4x GB200 (sm_100a), MiniMax-H3 and Wan2.1-14B at 5s 720p, bf16, p50 of 60 rank-max
samples. sp=8 spans two nodes.
Test Results
Test output
The shipped FastH3 profile is unchanged, because the fused path declines inside a
regionally compiled region and that profile enables regional compile. These fixes
apply to uncompiled inference and to training.
Checklist
pre-commit run --all-filesand fixed all issuesFor model/pipeline changes, also check: n/a, this changes a device communicator only.