FSDP fails when composed with CPU parameter offloading
Sharding and CPU offloading both move parameters, and each assumes it is the component deciding where a parameter lives. Enabling them together produces a failure during setup or the first step, in a stack that works correctly with either one alone.
Two memory managers are claiming the same parameters. Test each alone to confirm, then recover the memory from the activation side or from wider sharding rather than from offloading.
What this failure is
A composition failure in which parameter sharding and CPU offloading each claim authority over where a parameter resides, producing a setup-time or first-step error in a configuration where either feature alone succeeds.
Why it happens (the mechanism)
Both features exist to reduce resident parameter memory and both work by controlling placement. Sharding splits a parameter and records where each piece lives; offloading moves it to host memory and records that instead. Neither is written to defer to the other, so the composition has no agreed owner for a tensor, and the first thing that resolves placement finds a contradiction.
What you'll observe
- Both features are documented and each works by itself
- The failure appears at setup or on the first step rather than under memory pressure
- Offloading was enabled precisely because memory was already tight, so simply removing it is not free
- The error rarely names offloading, so the interaction is not obvious from the message
Common symptoms and what they mean
| Symptom | Why it happens |
|---|---|
| Setup or the first training step failing with both sharding and CPU offloading enabled | Sharding divides a parameter across ranks and keeps authoritative placement metadata for each piece. Offloading relocates parameters to host memory and restores them on demand, keeping its own view of where each one is. Both are correct in isolation and each expects to be the authority, so composing them leaves two components disagreeing about a single tensor. |
| A device or placement error naming a parameter that offloading has moved to host memory | The disagreement shows up early because placement is resolved during setup and on the first use of a parameter, not when memory runs short. That is why the failure looks unrelated to the memory pressure that motivated enabling offloading. |
| The identical configuration succeeding with offloading disabled | Support for the combination is a property of a specific implementation and version rather than of the idea, so a stack that documents both features separately may not support them together, and a version that works is not evidence a neighbouring one does. |
| The identical configuration succeeding with sharding disabled and offloading kept | Sharding divides a parameter across ranks and keeps authoritative placement metadata for each piece. Offloading relocates parameters to host memory and restores them on demand, keeping its own view of where each one is. Both are correct in isolation and each expects to be the authority, so composing them leaves two components disagreeing about a single tensor. |
Which systems are affected
- Megatron-style FSDP implementations combined with CPU offloading
- Stacks where offloading is configured by a launcher and sharding by the training framework, so neither knows about the other
- Configurations carried over from a single-device memory-saving setup into a sharded one
- Any setup where a parameter's owner is ambiguous between two memory managers
How to confirm this is the problem
Apply the following checklist to a small reproduction: each box below is a positive signal that you are looking at this exact failure rather than a sibling in the same taxonomy.
- ✓Disable CPU offloading and re-run with sharding unchanged. Success isolates the interaction rather than either feature.
- ✓Disable sharding and re-run with offloading unchanged. Success on both single-feature runs confirms the composition is the problem.
- ✓Check whether the failure occurs at setup or on the first step rather than under sustained memory pressure, which distinguishes a placement disagreement from genuine exhaustion.
Example training logs (fingerprint)
Megatron FSDP does not work with CPU_OFFLOADING
RuntimeError raised during setup with both parameter sharding and CPU offloading enabledTimestamps and exact values vary across runs, but the pattern. An info-level start, an early WARN, an ERROR carrying the symptom. Is the actual fingerprint you should alert on. The Denpex platform flags this combination automatically.
Root cause, fix & prevention, signed in
Sign up free to see why this failure really happens, the exact remediation steps, and the production-grade prevention pattern. You also get 3 free full diagnoses for your own training logs.
Sign up free. Unlock the full analysisNo credit card · 3 free diagnoses · Instant access
Why the recommended fix works
Removing one claimant leaves a single authority and the contradiction disappears. Recovering the memory from activations works because activation memory is managed by a different mechanism entirely, so it does not compete for ownership of parameters. Widening sharding reduces the same footprint offloading was targeting, without a second manager.
Code examples
// Typical pattern:
import torch.optim as optim
optimizer = optim.AdamW(model.parameters(), lr=3e-4)
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=num_training_steps)
for step in range(num_training_steps):
optimizer.zero_grad()
loss = model(batch)
loss.backward()
optimizer.step()
scheduler.step()Adapt the snippet to your framework. The same pattern holds for PyTorch Lightning, Hugging Face Trainer, DeepSpeed, Megatron-LM, and vLLM training wrappers. Where the wrapper exposes a config flag (for examplelr_scheduler_type in Trainer), prefer the flag over the imperative API to keep the schedule declarative and reproducible.
Best practices by model family
| Model / Stack | Recommendation | Notes |
|---|---|---|
| Sharding must stay | Widen sharding or shard optimizer state further | Reduces the same footprint without a second memory manager. |
| Memory pressure is from activations | Activation checkpointing or a smaller microbatch | Activation memory does not compete for parameter ownership. |
| Offloading is essential | Pin a version where the pair is supported | Support is a property of the implementation and moves between releases. |
| Diagnosing | Test each feature alone first | Two successful single-feature runs prove it is the composition. |
With the fix vs without the fix
| Dimension | With the fix | Without the fix |
|---|---|---|
| What each feature controls | Both control parameter placement | Assumed to address different resources |
| When the failure appears | At setup or the first step | Expected under sustained memory pressure |
| Whether documentation implies support | Documented separately, not necessarily together | Read as both being supported at once |
Real engineering notes
“The instinct on hitting this is to look for a memory bug, because offloading was enabled under memory pressure and the failure arrives soon after. The timing is the clue that it is not: a genuine exhaustion appears when the workload grows, while a placement disagreement appears at setup or on the very first step regardless of size. Note which, before spending time on allocator settings.”
Visual fingerprint
sharding : parameter split across ranks, placement metadata per shard
offloading : parameter relocated to host memory, restored on demand
both enabled -> who owns the placement of this tensor?
|
resolved at setup / first use -> contradictionRoot cause, fix & prevention
Frequently asked questions
Twelve targeted questions that engineers and on-call staff most commonly ask about this failure.
Both features are documented. Why can I not use both?
Is this an out-of-memory problem?
I enabled offloading because I was out of memory.
How do I confirm it is the combination?
Don't just read the fix, diagnose your run
The encyclopedia tells you what went wrong. Denpex tells you what went wrong in YOUR training run. With your logs, your config, and your stack.