As asked
Walk me through the three sharding strategies in PyTorch FSDP: FULL_SHARD, SHARD_GRAD_OP, and NO_SHARD. When would you pick each one, and what are the memory and communication tradeoffs at scale?
Sample answer outline
FULL_SHARD shards parameters, gradients, and optimizer state across all ranks, giving the lowest peak memory but requiring two all-gather passes per forward and one reduce-scatter per backward. SHARD_GRAD_OP keeps parameters unsharded during the forward pass, trading memory for fewer collective calls. NO_SHARD is DDP. A strong answer covers the tradeoff between peak GPU memory and all-reduce/all-gather volume, and explains when gradient checkpointing interacts with FSDP prefetching.
Expect these follow-ups
- How does FSDP's auto_wrap_policy interact with transformer layer boundaries, and what happens if you wrap at the wrong granularity?
- How do you profile the all-gather overhead in FSDP and what tools do you use?