UnpicklingError: Weights only load failed (torch.load)
PyTorch 2.6 made torch.load refuse arbitrary pickled objects by default. For files you trust, pass weights_only=False; for your own pipelines, save plain state_dicts so the safe default works.
Updated
The error
_pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint.
(1) In PyTorch 2.6, we changed the default value of the `weights_only` argument in `torch.load` from `False` to `True`. Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source.
(2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following link. It first offers a way to allowlist the objects being loaded.
WeightsUnpickler error: Unsupported global: GLOBAL numpy.core.multiarray._reconstruct was not an allowed global by default.The "Unsupported global" line names whatever object tripped the check — a NumPy internal, argparse.Namespace, or a custom class.
What it means
Checkpoint files saved by torch.save use pickle, a format that can embed executable code. Loading a malicious checkpoint can therefore run an attacker's code. PyTorch 2.6 (January 2025) flipped torch.load to a safe mode by default: only plain tensors and a small allowlist of types load; everything else is refused. Your file contains an object outside that allowlist. The file is probably fine — the default changed underneath it.
Why it happens
Older training scripts saved rich checkpoint dicts: model weights plus the optimizer, the args namespace, NumPy scalars for the best metric, and so on. Any of those non-tensor objects triggers the refusal under the new default. The error also appears when following pre-2025 tutorials whose code assumed the old behaviour.
How to fix it
1. For a file you created, or fully trust, load with the old behaviour.
ckpt = torch.load("checkpoint.pt", map_location="cpu", weights_only=False)This is exactly as safe as torch.load was for years — meaning: safe for your own files, dangerous for files from the internet. Never do this to a checkpoint downloaded from an untrusted account.
2. Better for shared code: allowlist the specific types.
import numpy as np
torch.serialization.add_safe_globals([np.core.multiarray._reconstruct])
ckpt = torch.load("checkpoint.pt", map_location="cpu")Add whatever the "Unsupported global" line names. The safe mode stays on for everything else.
3. Best long-term: save nothing but tensors.
torch.save({
"model": model.state_dict(),
"optimizer": optimizer.state_dict(),
"epoch": epoch, # plain int — fine
"best_acc": float(best_acc), # convert NumPy scalars to Python floats
}, "checkpoint.pt")State dicts, ints, floats and strings all load under the safe default. This future-proofs your checkpoints.
4. For distributing weights, prefer safetensors. The safetensors format cannot contain code at all, loads faster, and is what Hugging Face uses. No trust decision needed by your users.
How to prevent it
Audit what goes into torch.save — each exotic object is a future loading problem. Treat weights_only=False like allow_pickle=True in NumPy: a deliberate trust statement about a specific file, written next to a comment saying where that file comes from.
Related errors
- Missing key(s) / Unexpected key(s) in state_dict — the next error after loading succeeds
- Object arrays cannot be loaded when allow_pickle=False — NumPy's identical security default
- SafetensorError: error while deserializing header