Skip to content

perf(fsdp): SHARD_GRAD_OP for inference (-13.7%, -1855ms, bit-identical) - #52

Open
prashant182 wants to merge 3 commits into
Robbyant:mainfrom
prashant182:feat/e8-fsdp-no-reshard
Open

perf(fsdp): SHARD_GRAD_OP for inference (-13.7%, -1855ms, bit-identical)#52
prashant182 wants to merge 3 commits into
Robbyant:mainfrom
prashant182:feat/e8-fsdp-no-reshard

Conversation

@prashant182

Copy link
Copy Markdown
Contributor

Summary

Switches DiT FSDP from FULL_SHARD to SHARD_GRAD_OP. Parameters stay resident across all 35 DiT forwards in a generate() instead of being re-gathered per-forward. Bit-identical output (MD5 ed2f82628308a3f8acd9b7935bb84401), −13.7% generate().

SHARD_GRAD_OP is FSDP1's equivalent of FSDP2's reshard_after_forward=False (the FSDP2 kwarg isn't accepted by the current PyTorch's FSDP1 constructor).

Measurement (8×H100, 480×832, 81 frames, seed 42)

Stacked on top of #51 (B3) for the canonical chain:

Stage generate() vs unopt vs prior
Unoptimized 22146 ms
+ prewarm() (PR #48) 15564 ms −30%
+ T5 cache (PR #50) 15134 ms −32% −2.8%
+ B3 (PR #51) 13523 ms −39% −10.6%
+ this PR 11668 ms −47% −13.7%

Why

Profiling the post-B3 baseline showed AllGather was 91% of NCCL time — 975 ms over a 2-chunk window. With FULL_SHARD, FSDP shards params after each forward and re-gathers on the next call. Across the 35 forwards in one generate(), that re-gather fires repeatedly. SHARD_GRAD_OP keeps params unsharded after the first all-gather — the per-forward re-gather disappears.

Memory

Unsharded 14B-param DiT at bf16 ≈ 28 GB per rank vs ~3.5 GB sharded across 8 ranks. On 80 GB H100s with VAE + T5 + KV cache + activations resident, there is headroom; no OOM observed across multiple bench runs.

Tradeoffs / scope

  • Purely an inference-mode optimization. If anyone runs this code in a training context, the FULL_SHARD default would need to come back via a flag — happy to add one if requested.
  • Bit-identical (Tier A): MD5 match verified end-to-end at the locked baseline.
  • One file changed (wan/distributed/fsdp.py); ~10 LOC including comment block.

Stack

Stacked on PR #51 (B3). Reported diff will shrink to one line + comment once that lands.

prashant182 and others added 3 commits May 19, 2026 14:03
perf(dit): eliminate ~5600 .item() syncs from DiT forward (-13% generate())
E8 of autoresearch — see /workspace/lingbot-world-artifacts/EXPERIMENTS.md.

Switches DiT FSDP from FULL_SHARD to SHARD_GRAD_OP. Functionally equivalent
to FSDP2's reshard_after_forward=False, which FSDP1 doesn't expose
directly. Effect: parameters are unsharded after the first all-gather
and stay resident across all 35 DiT forwards in a generate(), instead
of being re-gathered per-forward.

Profiling rationale: AllGather was 91% of NCCL time (975 ms / 2-chunk
window) at the post-B3 baseline. The within-forward per-block gathers
still fire, but the outer re-gather between forwards is gone — that's
where the time went.

Memory cost: unsharded 14B-param DiT at bf16 ~ 28GB per rank vs 3.5GB
sharded across 8 ranks. On 80GB H100s with VAE+T5+KV cache + activations,
we have headroom.

Measurement (8×H100, 480×832, 81 frames, seed 42):

   generate()  before  13523 ms (B3 baseline)
   generate()  after   11668 ms
   Δ                  -1855 ms (-13.7%)
   MD5                ed2f82628308a3f8acd9b7935bb84401 (bit-identical, Tier A)
@prashant182

prashant182 commented May 21, 2026

Copy link
Copy Markdown
Contributor Author

Nudge for review when you have a moment Single-line config flip in wan/distributed/fsdp.py (FULL_SHARDSHARD_GRAD_OP). Profile showed AllGather was 91% of NCCL time; this keeps params resident across the 35 forwards per generate(). −13.7%, bit-identical (MD5 match). Lowest-risk PR in the stack: one file, ten lines including comments, independent of #53 and #54.

cc @Robbyant @JingyeChen @qiuyu96

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.

1 participant