Skip to content

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.

Quick answer

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.

Distributed Training#fsdp#auto-wrap-policy#no-wrap#activation-checkpointing#typeerror#accelerate

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

SymptomWhy it happens
TypeError: 'NoneType' object is not callable raised during model preparationSelecting 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 helperThe 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 enabledA 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 insteadSelecting 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)

training.log (synthetic 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 analysis

No 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 reference pattern
// 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 / StackRecommendationNotes
Standard transformer architectureTransformer-based policy naming the decoder blockGives sharding and checkpointing the same real unit.
Custom model with no module listName the layer class explicitlyDefaults derived from the model are absent, so the policy stays empty.
No natural layer classSize-based policy with a minimum parameter countProduces a real policy without naming an architecture.
Wrapping must stay manualDisable activation checkpointingIt is the component consuming the policy that does not exist.

With the fix vs without the fix

DimensionWith the fixWithout the fix
Are the two settings independentNo, checkpointing consumes the wrapping policyPresented as separate switches
What an empty policy meansA valid expression of manual wrappingRead as a misconfiguration in itself
Which switch to changeThe wrapping policyWhichever 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

One setting, two consumers
  auto_wrap_policy = NO_WRAP   ->   policy = None      (legitimate)
                                       |
              +------------------------+------------------------+
              v                                                 v
     sharding: nothing to wrap, fine        activation checkpointing: policy(...)
                                                                 -> None is not callable
Selecting manual wrapping leaves the policy empty, which sharding handles correctly. Activation checkpointing reuses the same policy to choose what to checkpoint and calls it, which is where the type error is raised.

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?
They are not independent. Activation checkpointing reuses the wrapping policy to decide what to checkpoint, and manual wrapping legitimately leaves that policy empty.
Should I just turn off activation checkpointing?
It clears the error and gives back the memory saving it existed to provide. Setting the wrapping policy properly is usually the better fix.
I set a transformer policy and still get an empty policy.
The named layer class probably does not resolve against your model, or the model exposes no default list to derive one from. Name a class that exists.
Which layer class should I name?
The block containing attention followed by the feed-forward network, keeping weight-sharing submodules inside a single unit.

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.