Exercises — FSDP and sharded training
Before we start, one shared vocabulary reminder, because every problem below leans on it.
We also fix a "bytes per parameter" table used throughout. This is the standard mixed-precision (Mixed Precision Training) count:
Level 1 — Recognition
Exercise 1.1
Which of these does FSDP shard across GPUs, and which does it not? (a) parameters, (b) activations, (c) optimizer momentum, (d) gradients.
Recall Solution
Sharded: (a) parameters, (c) optimizer momentum, (d) gradients. Not sharded: (b) activations — every GPU still stores its own full activation tensors for backprop. This is the single most-missed fact and the seed of the L5 problem.
Exercise 1.2
Match the collective to its job:
- All-gather :: ?
- Reduce-scatter :: ?
Recall Solution
All-gather ::: each GPU holds one shard ; afterwards every GPU holds the full concatenation . Used to rebuild a full weight matrix just before a layer's matmul. Reduce-scatter ::: each GPU holds a full vector ; afterwards GPU holds only the sum over all GPUs of the -th shard, . Used to combine and split gradients in one step. See Communication Collectives.
Exercise 1.3
FSDP is PyTorch's version of which ZeRO stage, and what does that stage shard?
Recall Solution
FSDP = ZeRO Stage 3. It shards optimizer states and gradients and parameters — all three. (Stage 1 = optimizer only; Stage 2 = optimizer + gradients.) See ZeRO Optimizer.
Level 2 — Application
Exercise 2.1
A model has parameters. Using 16 bytes/param, compute the per-GPU persistent memory (a) with plain data parallelism (no sharding), and (b) with FSDP on GPUs. Ignore the temporary buffer.
Recall Solution
(a) Data parallel replicates all 16 bytes on every GPU: (b) FSDP divides the persistent memory by : So sharding across 8 GPUs turns a 112 GB requirement (impossible on an 80 GB card) into 14 GB (comfortable).
Exercise 2.2
For the same 7B model on , the temporary all-gather buffer for the largest layer is 1.5 GB (fp16). What is the total per-GPU memory, and does it fit an 80 GB A100 (ignoring activations)?
Recall Solution
Yes — , plenty of room (activations still to come, but ignored here).
Exercise 2.3
General formula check. Starting from "16 bytes/param, sharded by , plus a fixed temp buffer ", write the per-GPU memory and evaluate it for , , .
Recall Solution
With : Comfortably under an A100 80 GB — before activations are added.
Level 3 — Analysis
Exercise 3.1
A layer holds 700 MB of parameters (fp16). You will all-gather it over a network. Compute the per-GPU received volume for using the all-gather cost .
Recall Solution
Each GPU already owns its own shard, so it must receive the other shards: Notice: as , , so per-GPU received volume approaches the whole layer size — sharding more does not reduce all-gather traffic per GPU, it only reduces stored memory.
Exercise 3.2
That same 700 MB layer is transferred over a 10 Gbps link. How long does one all-gather take (use full 700 MB for a worst-case single-hop estimate), and if a layer's compute takes 200 ms, is FSDP a good idea here? Also account for the backward pass, which adds a second all-gather plus a reduce-scatter.
Recall Solution
Convert: bits/s bytes/s MB/s (decimal units). One all-gather: Why backward compute forward. The forward pass does one matmul per layer (). The backward pass does two matmuls per layer for the same weight: one for the gradient flowing to the inputs () and one for the gradient of the weights (). Two matmuls of the same size ≈ twice the FLOPs ≈ twice the time. Hence forward compute 200 ms ⇒ backward compute ms. Full per-layer communication. FSDP pays this collective three times per layer per step:
- forward all-gather ≈ 560 ms,
- backward all-gather (weights re-fetched for the gradient) ≈ 560 ms,
- backward reduce-scatter of gradients — same 700 MB volume, so ≈ 560 ms as well.
Compare to compute (forward + backward, ms): (If you only counted the single forward all-gather against forward compute — — you get the same ratio here, which is why the earlier single-collective estimate already flagged the problem. But the honest full-step figure sums three collectives.) Either way the ratio (the overlap threshold defined just above): on a slow 10 Gbps link, do not use FSDP; the network is the bottleneck. (See figure below, which shows the single-collective comparison for clarity.)

Reading the figure. The horizontal axis lists two activities; the vertical axis is time in milliseconds. The blue bar (left) is one layer's forward compute = 200 ms; the pale-yellow bar (right) is one all-gather over the 10 Gbps link = 560 ms. The pink dashed line marks the 200 ms compute level so you can see how far the yellow comm bar overshoots it — the yellow arrow points to that overshoot, the "wasted GPU time" spent waiting on the wire that cannot be hidden behind compute. The bar values are printed above each bar. Remember: a real training step pays this collective three times (two all-gathers + one reduce-scatter), so the true comm burden is even larger than the single yellow bar shown.
Exercise 3.3
The 1.3B-model case from the parent note: it fits in memory under plain DP ( GB on an 80 GB A100). Why does adding FSDP here slow you down, and what is the one-line decision rule?
Recall Solution
FSDP's memory saving is useless here — the model already fits — but its costs stay: every layer now pays an all-gather (forward), a second all-gather (backward), and a reduce-scatter (backward). You bought communication overhead and got no memory benefit in return, hence the parent's "15–20 % slower." Decision rule: use FSDP only when required memory available GPU memory. If it fits under plain DP, stay on DP.
Level 4 — Synthesis
Exercise 4.1
You have 512 GPUs and want (FSDP), (Pipeline Parallelism), and some tensor parallelism (Model Parallelism). What is ?
Recall Solution
The parent's identity: . A neat cube.
Exercise 4.2
In a hybrid FSDP + Pipeline setup, the model is split into 4 pipeline stages, each stage sharded by FSDP across 4 GPUs (16 GPUs total). A stage's parameters are 40 GB (16 bytes/param already folded in). What is the persistent per-GPU parameter memory, and why is the all-gather cheaper than pure FSDP over all 16?
Recall Solution
Each stage's 40 GB is sharded only within its 4 GPUs: Why cheaper communication: all-gather now happens inside a 4-GPU group, not across all 16. Fewer participants and (usually) intra-node NVLink instead of cross-node InfiniBand → smaller, faster collectives. Pipeline splits the model depth-wise so FSDP's expensive all-gather scope shrinks. Trade-off: pipeline introduces bubble/idle time you must hide with micro-batching.
Exercise 4.3
Design task: a 30B model, 8 nodes × 8 GPUs = 64 GPUs, NVLink inside a node (fast), slower InfiniBand across nodes. Where should tensor parallelism go, and where should FSDP go, and why?
Recall Solution
Put tensor parallelism inside a node (, over NVLink): tensor parallelism does frequent, latency-sensitive all-reduces every layer, so it needs the fastest link. Put FSDP across nodes (, over InfiniBand): FSDP's all-gather can be prefetched (overlapped with compute) and happens per-FSDP-unit, tolerating higher latency better. Result: GPUs, fast link for the chatty collective, slower link for the overlappable one. This is exactly why the parent recommends "tensor parallelism for computation within a node, FSDP for memory across nodes."
Level 5 — Mastery
Exercise 5.1
GPT-3-scale layer: batch size , sequence length , hidden dim , fp16 (2 bytes). Compute the activation memory for one layer's main tensor, and explain why FSDP does not reduce it. Then estimate the activation total across ~96 transformer layers.
Recall Solution
Step: ; ; bytes (decimal units). Across ~96 layers (one such tensor each, no safety factor): (Real transformers store several activation tensors per layer — attention scores, MLP intermediates — so the practical number is a few times higher, which is why one reaches into the tens-of-GB range and why checkpointing matters.) Why FSDP does not reduce it: FSDP shards params, grads, optimizer — not activations. Activations are produced during the forward pass by each GPU for its own micro-batch, and each GPU must keep them until its own backward pass consumes them. There is no shard to fetch from a neighbour — the data is local, per-GPU, and unique. So this 38.6 GB figure is unchanged by any value of : doubling the GPU count halves the param/grad/optimizer footprint but leaves the activation footprint exactly where it was. That is precisely why FSDP alone cannot make an arbitrarily large model fit, and why you must pair it with Activation Checkpointing.
Exercise 5.2
Activation checkpointing recomputes activations in the backward pass instead of storing them, cutting activation memory ~10× at the cost of ~33 % more compute. If a layer's forward compute is 200 ms and a step is forward + backward, estimate the new backward compute (backward ≈ 2× forward without checkpointing) and the total step time with checkpointing.
Recall Solution
Baseline: forward ms, backward ms (see Ex 3.2 for why backward is twice forward), step ms. Checkpointing adds a recompute of the forward inside backward: the extra is applied to the step ⇒ extra ms. You pay ~33 % more time to buy ~10× less activation memory — usually worth it when activations are what blocks you. Pair FSDP (params) with Activation Checkpointing (activations) to attack both memory sources.
Exercise 5.3
Full budget synthesis. GPT-3, 175B params, GPUs, mixed precision (16 bytes/param). Compute the persistent sharded memory. Then, with a temp all-gather buffer of GB and activations with checkpointing of GB, does the total fit an 80 GB A100? What is the largest single contributor, and what does that tell you about where to optimise next?
Recall Solution
Persistent sharded memory: Total budget: — fits, with comfortable headroom. Largest contributor: activations (30 GB), dwarfing sharded params (2.73 GB) and the temp buffer (1.5 GB). Lesson: once FSDP has crushed the param/grad/optimizer footprint, activations become the dominant term. The next optimisation lever is activation memory (more aggressive checkpointing, smaller micro-batch, shorter sequences) — not more param sharding.
Recall One-line summary you should now be able to say
FSDP replaces full copies of params/grads/optimizer with shards (memory , at 16 bytes/param in mixed precision), paying all-gather + reduce-scatter communication that scales as per GPU; use it only when the model won't fit under DP, and always budget the un-sharded activations separately with Activation Checkpointing.