[Fix] fsdp_overlap: dynamic-shape symbol names are per-rank noise; key by structure, not name - #51
Open
wtr0504 wants to merge 1 commit into
Open
[Fix] fsdp_overlap: dynamic-shape symbol names are per-rank noise; key by structure, not name#51wtr0504 wants to merge 1 commit into
wtr0504 wants to merge 1 commit into
Conversation
…y by structure, not name
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.
…y by structure, not name
🗂️ PR Category
📝 Description
Root cause
Dynamo allocates shape symbols from a process-local ShapeEnv counter with no cross-process coordination: the name a dynamic dim gets (s27, s82, …) depends on the order and history of symbol allocation during that rank's trace — not on the graph's structure. As long as every symbol in the graph derives from the ranks' common inputs (e.g. the local token count, marked dynamic at the same point of the same trace), the names happen to match across ranks and the problem stays invisible.
A traced CP all_to_all breaks exactly this condition. Its output size is sum(output_split_sizes) — the local chunk plus the other ranks' chunk sizes. That is the one quantity in the graph not derived from local inputs, so dynamo materializes it as an additional symbol mid-trace, and where that symbol lands in each rank's private allocation/deduplication history differs per rank. Observed on wan2.2 (2 ranks): the all_to_all output prints s27 + s82 on rank 0 vs s27 + s74 on rank 1 for structurally identical graphs — the primary (local-seq) symbol matches, the second one diverges; a node-by-node fingerprint diff showed only the all_to_all and its downstream attention nodes differing, everything else identical.
Two cross-rank consistency checks treated these symbol names as part of the graph structure. Both are fail-safe, so instead of crashing they silently degraded, and the weight all-gathers ran fully exposed — nsys showed 82–93% of all-gather time with the compute stream idle.
The two affected checks
Fix: canonicalize s\d+ symbols by first appearance (α-renaming) before hashing. What is structural is the symbols' occurrence pattern, not their names; genuinely different symbolic structure still diverges.
Fix: key symbolic dims by their size hint (("~", hint)) instead — guard-free (no SymInt specialization), rank-identical (same inputs per rank), and isomorphic kernels keep sharing one measurement. If ranks ever see genuinely different hints, the key-set check degrades safely to analytical as before (no deadlock, no misordering).
Verification
wan2.2, 2×H100, 1280×704, caches off:
Tests: new α-equivalence unit test for the fingerprint (test_fingerprint_canonicalizes_shape_symbols); estimator key test updated to assert hint-based keys (test_static_symbolic_dim_keyed_by_hint); reorder (3) / e2e (4) / estimator (16) suites pass.