Nothing crashes. A teammate loads a downloaded .bin or .pt checkpoint from a
repository nobody recognised, the load succeeds, and the model even produces
plausible output. The damage shows up somewhere else and later: an outbound
connection from a laptop that should only be reading files, a new key or config
file appearing in the home directory, a shell history entry nobody typed, or a
cloud credential used from an address the team has never seen. On a build machine
the first sign is often a CI job that takes longer than usual, or a container
image that grew. The reason the symptom is so quiet is that loading a pickle file
is not reading data — it is running a small program that the file's author wrote,
with your permissions, before your next line of code executes.
Any workflow that pulls weights from an untrusted or unverified source: a
checkpoint linked in a forum post, a mirror on a file-sharing site, a repository
with three downloads and no card, a zip a teammate sent on chat, or a fork of a
known model uploaded by an unknown account. It also appears inside organisations
where an internal artifact store lets anyone publish. The historical reason is
that PyTorch's original save format wraps Python's pickle, which by design can
reconstruct arbitrary objects and therefore call arbitrary code. Modern PyTorch
defends this with weights_only=True by default on torch.load, and the Hub's
safetensors format holds tensors and nothing executable at all — but old
tutorials, old code and old checkpoints keep the unsafe path alive. Linked
modules: 2.10 (Hugging Face ecosystem), 2.9 (checkpoints, where the same file
format is written every few minutes), 3.11 (safety and supply-chain habits),
4.3 (Docker, where the blast radius is decided).
Split the question in two: what format is this file, and who published it. Format
first, because it is cheap. A .safetensors file cannot execute anything on load;
a .bin, .pt, .pth or .ckpt file is a pickle archive unless proven
otherwise, and a .pkl certainly is. Do not open a suspect file to inspect it
with the same call that would execute it. Load with weights_only=True and treat
a failure as evidence rather than an inconvenience: a genuine weights file loads
fine under that flag, and a file that refuses is asking to run something. On the
publisher side, look at the repository the way you would look at an unknown
package on PyPI — is this the organisation that actually produced the model, or a
lookalike name with one character changed, how old is the account, does the card
exist, do the file sizes match the claimed parameter count. If you believe
something already ran, stop treating it as a model problem: the correct next step
is the incident path — disconnect the machine, rotate every credential it held,
and tell whoever owns security, rather than deleting the file and moving on.
Prefer safetensors and make it the only accepted format. On the Hub most
mainstream checkpoints publish a model.safetensors file beside the legacy
pytorch_model.bin, and the loader will take the safe one when it is present; if
a repository offers only the pickle, that is a reason to look for another
repository. Where a library exposes the choice, pass it explicitly rather than
relying on a default that varies with version. Keep weights_only=True on every
torch.load you write, including the ones that load your own checkpoints, so the
habit does not depend on remembering which files came from outside. Pin the
revision you audited, so tomorrow's commit to that repository cannot change what
you load. For anything you are not sure about, do the first load in a container
with no network and no mounted secrets, and inspect the tensor names and shapes
there before the file reaches a real machine. And put the rule where new people
meet it: an approved-publishers list, and one line in the review checklist asking
what format the weights are in.
Treat a model file as executable code from an internet stranger, because in the
pickle case that is exactly what it is. Convert anything you must keep from the
legacy format into safetensors once, in a sandbox, and store only the converted
copy. Never load weights from a link in a chat message, a blog comment or a search
result without checking the publishing account first. Keep model downloads out of
the same environment that holds cloud credentials, and out of CI jobs that hold
deployment keys. Write the reason next to the flag in your own code — one comment
saying that a pickle load runs code — so the next person does not remove it for
being noisy. This is 3.11's supply-chain thinking arriving early, in a place most
courses never mention.
Q: "Why does the industry care whether weights ship as .bin or .safetensors?"
Strong answer: say plainly that the legacy format is a pickle, that unpickling
executes code the file's author chose, and that loading therefore happens before
any of your own safety checks can run. Contrast it with safetensors, which
stores tensor names, shapes and bytes with no executable payload, and which also
happens to load faster and support memory mapping. Name the two defences you use
in practice — weights_only=True on every load, and preferring the safetensors
file when a repository offers both. Then widen it to the supply chain: a model is
a dependency like any package, so publisher identity, a pinned revision and an
approved list matter as much as the format. Finish with the incident answer — if
an untrusted pickle was already loaded, the response is credential rotation and a
report, not a deleted file.