[None][fix] Autotuner deadlock fixes (split from #14053) - #14240
Closed
lancelly wants to merge 2 commits into
Closed
[None][fix] Autotuner deadlock fixes (split from #14053)#14240lancelly wants to merge 2 commits into
lancelly wants to merge 2 commits into
Conversation
Bracket _run_autotuner_warmup with TP-group barriers so every rank enters and exits the autotuner together. Without this, when one rank's autotuner cache is already populated and it returns near-instantly (e.g. "Cache size after warmup is 0"), it races ahead into the next collective-issuing _general_warmup step while a peer is still inside its own autotuner -- the two collectives then mismatch and the slower rank's autotuner spins forever waiting for peers that have moved on, producing a silent hang with no error message. Barriers only fire when tp_size > 1 (no overhead on single-GPU). Helix CP is excluded by the existing outer has_cp_helix() check. Split out from PR NVIDIA#14053 (DSv4 mem-opts master switch) as an independent distributed-correctness fix that benefits any model running with attention warmup and tp_size > 1. Signed-off-by: Lance Liao <108499334+lancelly@users.noreply.github.com>
…id rank-divergent deadlock With ADP + MoE EP, different ranks see different per-expert routing shapes, so the result of profiling_cache.search_cache (is_cache_hit) can diverge across ranks. The slow path below ends in _maybe_sync_cache_data, which issues a TP/CP collective (allgather or broadcast). If some ranks early-return at the cache-hit shortcut while others enter the collective, the collective deadlocks. This patch makes the early-return decision a collective vote: every rank runs tp_cp_allgather(is_cache_hit) and only short-circuits if ALL ranks hit. The allgather is unconditional (not gated on local is_cache_hit) so that hit and miss ranks all participate symmetrically. Validated on DSv4-Pro ctx-only with TP=4 EP=4, gpu_frac=0.5: 4/5 jobs PASS bench (50.4-50.7k tok/s) + gsm8k (96.40-96.47%). The remaining 1/5 failure is a different rank-divergent issue inside _profile_runners (PARALLEL strategy distributes tactics across ranks and MoE forward calls on different tactics can desync on internal all-to-all collectives); not addressed by this patch. Signed-off-by: Xianjie <5410381+qiaoxj07@users.noreply.github.com> Signed-off-by: Lance Liao <108499334+lancelly@users.noreply.github.com>
lancelly
requested review from
Tabrizian and
yizhang-nv
and removed request for
a team
May 18, 2026 06:57
lancelly
marked this pull request as draft
May 18, 2026 07:01
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.
Summary
Split out the autotuner deadlock fixes from #14053 as an independent, model-agnostic distributed-correctness PR. These two changes were always-on (gated only by
tp_size > 1) in #14053 and have no dependency on the DSv4 mem-opts in that PR.Changes
1. Pre/post
tp_barrieraround_run_autotuner_warmup(pyexecutor/model_engine.py)Symptom: when one rank's autotuner cache is already populated and
_run_autotuner_warmupreturns near-instantly (e.g. "Cache size after warmup is 0"), that rank races ahead into the next collective-issuing_general_warmupstep while a peer is still inside its own autotuner. The two collectives then mismatch, and the slower rank's autotuner spins forever waiting for peers that have moved on — producing a silent hang with no error message.Fix: bracket
_run_autotuner_warmupwith TP-group barriers so every rank enters and exits the autotuner together. Barriers only fire whentp_size > 1(no overhead on single-GPU). Helix CP is excluded by the existing outerhas_cp_helix()check.2. Collective vote on cache hit in
AutoTuner.choose_one(autotuner.py)Symptom: with ADP + MoE EP, different ranks see different per-expert routing shapes →
is_cache_hit(profiling_cache.search_cache) diverges across ranks. The slow path below ends in_maybe_sync_cache_data, which issues a TP/CP collective (allgather or broadcast). If some ranks early-return at the cache-hit shortcut while others enter the collective, the collective deadlocks.Fix: insert an unconditional
tp_cp_allgather(is_cache_hit)collective vote so every rank participates in the allgather regardless of local cache state, and only short-circuit when all ranks hit. The allgather must be unconditional (not gated on localis_cache_hit) — otherwise hit ranks call the allgather while miss ranks skip it, recreating the deadlock at the vote site.Validation
Validated on DSv4-Pro on GB300 (TP=4 EP=4, ADP on, gpu_frac=0.5) — same workload as #14053:
expandable_segments)The remaining 1/5 failure is a different rank-divergent issue inside
_profile_runners(PARALLEL strategy distributes tactics across ranks; MoE forward calls on different tactics can desync on internal all-to-all collectives). Not addressed by this patch — tracked as a follow-up.Scope
Both changes are always-on (gated only by
tp_size > 1or_is_distributed()). They are NOT gated onTRTLLM_DSV4_MEM_OPTS. Behavior fortp_size == 1is unchanged.The unconditional
tp_cp_allgatheradds one extra collective perAutoTuner.choose_oneinvocation in tuning mode — autotuner warmup only, not steady-state inference, so the overhead ceiling is hundreds-of-tactics × microseconds, paid once per engine init.Why split this out
In #14053 these autotuner fixes were bundled with three DSv4-specific memory optimizations gated on a new env switch. The autotuner deadlock fixes are correctness bugs that benefit any distributed PyTorch backend run, so they can land independently and earlier than the env-gated mem-opts. This also reduces the review surface for both PRs.