FSDP preparation fails because activation checkpointing calls a wrapping policy that was never set
Choosing not to auto-wrap is legitimate and leaves the wrapping policy unset. Activation checkpointing then tries to apply that policy to decide which submodules to checkpoint, calls the empty value, and preparation fails with a type error naming nothing that appears in the configuration.
The two settings are not independent. Activation checkpointing calls the wrapping policy, and no-wrap leaves it empty. Set an explicit policy with a layer class, or turn activation checkpointing off.
What this failure is
A preparation-time type error in which activation checkpointing invokes an FSDP wrapping policy that is legitimately unset, because the configuration selected manual wrapping while leaving checkpointing enabled.
Why it happens (the mechanism)
Configuration formats present orthogonal-looking switches, and the code behind them shares state. Selecting manual wrapping correctly produces no policy; activation checkpointing then reuses that policy as its own selector of what to checkpoint, without checking that one exists. The result is a permitted configuration that no code path can serve.
What you'll observe
- The error names a type rather than a setting, so it does not point at the configuration that caused it
- Each of the two options works on its own and only the combination fails
- The traceback lands in framework internals with no application frame to act on
- Turning off the wrong one of the two makes it pass and teaches the wrong lesson
Common symptoms and what they mean
| Symptom | Why it happens |
|---|---|
| TypeError: 'NoneType' object is not callable raised during model preparation | Selecting no automatic wrapping sets the policy to an empty value, which is correct: there is no policy because nothing is to be wrapped automatically. Activation checkpointing, however, reuses that policy to decide which submodules receive checkpointing, and it assumes something callable is there. |
| Traceback through accelerator.prepare into the FSDP2 preparation path and an activation-checkpointing helper | The two settings are presented as independent and are not. One expresses an intent about sharding granularity and the other silently consumes it, so a combination the configuration format permits is one the code path cannot serve. |
| A configuration selecting no automatic wrapping together with activation checkpointing enabled | A neighbouring failure produces the same empty policy from the other direction: a transformer-based policy on a model that exposes no splittable module list, or with a class name that cannot be resolved, also yields nothing to call. |
| Could not find the transformer layer class to wrap in the model, when a class name was supplied instead | Selecting no automatic wrapping sets the policy to an empty value, which is correct: there is no policy because nothing is to be wrapped automatically. Activation checkpointing, however, reuses that policy to decide which submodules receive checkpointing, and it assumes something callable is there. |
Which systems are affected
- Accelerate and similar launchers where wrapping policy and activation checkpointing are independent switches
- Custom models outside a standard architecture library, which expose no default list of splittable modules
- Configurations converted from an older setup where activation checkpointing was enabled for other reasons
- Parameter-efficient tuning stacks that assemble the wrapping policy themselves
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.
- ✓Check whether activation checkpointing is enabled while the wrapping policy is set to no automatic wrapping; that pairing is the failure.
- ✓Disable activation checkpointing alone and re-run. Success identifies it as the consumer of the absent policy.
- ✓Where a transformer-based policy is configured, confirm the named layer class resolves against the model, since an unresolvable name leaves the policy empty too.
Example training logs (fingerprint)
TypeError: 'NoneType' object is not callable
File ".../accelerate/accelerator.py", in _prepare_fsdp2
File ".../accelerate/utils/fsdp_utils.py", in fsdp2_apply_ac
ValueError: Could not find the transformer layer class to wrap in the model.Timestamps 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
An explicit policy gives both consumers something real: sharding gets its granularity and checkpointing gets its selector. Disabling checkpointing works by removing the consumer instead. Either restores the invariant the code assumes, which is that a policy exists whenever something wants to apply one.
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 |
|---|---|---|
| Standard transformer architecture | Transformer-based policy naming the decoder block | Gives sharding and checkpointing the same real unit. |
| Custom model with no module list | Name the layer class explicitly | Defaults derived from the model are absent, so the policy stays empty. |
| No natural layer class | Size-based policy with a minimum parameter count | Produces a real policy without naming an architecture. |
| Wrapping must stay manual | Disable activation checkpointing | It is the component consuming the policy that does not exist. |
With the fix vs without the fix
| Dimension | With the fix | Without the fix |
|---|---|---|
| Are the two settings independent | No, checkpointing consumes the wrapping policy | Presented as separate switches |
| What an empty policy means | A valid expression of manual wrapping | Read as a misconfiguration in itself |
| Which switch to change | The wrapping policy | Whichever one makes the error stop |
Real engineering notes
“The trap is that disabling either option makes the error disappear, so whichever one you try first looks like the culprit. Disabling activation checkpointing is usually the wrong lesson to take away, because it silently costs memory on every subsequent run. Set the wrapping policy properly; it is the setting that was actually incomplete.”
Visual fingerprint
auto_wrap_policy = NO_WRAP -> policy = None (legitimate)
|
+------------------------+------------------------+
v v
sharding: nothing to wrap, fine activation checkpointing: policy(...)
-> None is not callableRelated failures to investigate next
Root cause, fix & prevention
Frequently asked questions
Twelve targeted questions that engineers and on-call staff most commonly ask about this failure.
Both settings are valid on their own. Why does the pair fail?
Should I just turn off activation checkpointing?
I set a transformer policy and still get an empty policy.
Which layer class should I name?
References
- ↗Accelerate issue #3822: no-wrap policy combined with activation checkpointing raising a type error
- ↗Accelerate issue #2947: how layers are checked when wrapping for FSDP
- ↗PEFT issue #2166: the wrapping policy failing when no splittable module list exists
- ↗Transformers documentation on FSDP wrapping policies and layer classes
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.