PyTorch Save and Load Models
Saving and loading PyTorch models lets you keep trained weights, resume interrupted training and deploy a model elsewhere. The recommended approach is to save the model's state_dict, a dictionary mapping each layer name to its weight tensor, rather than pickling the whole model object.
What is a state_dict?
import torch
from torch import nn
model = nn.Sequential(nn.Linear(4, 2), nn.ReLU(), nn.Linear(2, 1))
for k, v in model.state_dict().items():
print(k, tuple(v.shape))0.weight (2, 4) 0.bias (2,) 2.weight (1, 2) 2.bias (1,)
Saving and Loading Weights
torch.save(model.state_dict(), "model.pt")
new_model = nn.Sequential(nn.Linear(4, 2), nn.ReLU(), nn.Linear(2, 1))
new_model.load_state_dict(torch.load("model.pt", weights_only=True))
new_model.eval()
print("loaded")loaded
You must first build a model with the same architecture, then load the weights into it. Call eval() before inference so dropout and batch norm behave correctly.
Since PyTorch 2.6, torch.load defaults to weights_only=True, which refuses to unpickle arbitrary Python objects. That protects you from malicious files; only turn it off for files you fully trust.
Checkpoints for Resuming Training
opt = torch.optim.AdamW(model.parameters(), lr=1e-3)
epoch = 7
torch.save({
"epoch": epoch,
"model": model.state_dict(),
"optimizer": opt.state_dict(),
}, "checkpoint.pt")
ckpt = torch.load("checkpoint.pt", weights_only=True)
model.load_state_dict(ckpt["model"])
opt.load_state_dict(ckpt["optimizer"])
start_epoch = ckpt["epoch"] + 1
print("resume from epoch", start_epoch)resume from epoch 8
Saving the optimizer state matters for Adam-style optimizers, which keep running averages for every parameter.
Loading GPU Weights on a CPU
state = torch.load("model.pt", map_location="cpu", weights_only=True)
new_model.load_state_dict(state)<All keys matched successfully>
Other Formats
- safetensors: a safe, fast format used across Hugging Face; save with safetensors.torch.save_file.
- torch.export: captures a model graph for deployment and ahead-of-time compilation.
- ONNX: export with torch.onnx.export to run in ONNX Runtime and other engines.
- Avoid torch.save(model) of the whole object: it breaks when your code files move or change.
Frequently asked questions
How do I save a PyTorch model?
Use torch.save(model.state_dict(), "model.pt"). To load, build the same architecture and call model.load_state_dict(torch.load("model.pt", weights_only=True)).
What is the difference between .pt and .pth files?
Nothing technical; both are just conventions for files written by torch.save. .pt is the more common choice today.
Why does torch.load fail with weights_only errors?
Since PyTorch 2.6, weights_only=True is the default and blocks arbitrary pickled objects. Save plain state_dicts, or pass weights_only=False only for files you trust.