Skip to main content
BVDNET
Arnhem · websites & automationBVDNET
Tools & Frameworks

Safetensors

Safetensors is a file format for AI model weights that holds only numbers, so a downloaded model cannot run hidden code on your computer when you open it.

Also known as: safetensors format, safe tensors, .safetensors

Safetensors is a file format for the learned numbers of an AI model, its weights. When you download an open AI model to run on your own computer, the weights arrive as one or more files. The older common format could hide a program that runs the moment the file is opened. A Safetensors file holds only numbers and a description of them, so opening it runs no code.

Why does it exist?

PyTorch saves models with Python's pickle by default, and pickle can run code while loading. Python's own documentation warns: "The pickle module is not secure. Only unpickle data you trust." Hugging Face built Safetensors so that a model file from a stranger can be opened safely. The README defines safe as: "Can I use a file randomly downloaded and expect not to run arbitrary code?"

In May 2023 Hugging Face, EleutherAI and Stability AI had Trail of Bits audit the library. It found "no critical security flaw leading to arbitrary code execution"; some imprecisions in the specification and a gap that allowed polyglot files (files that are valid in two formats at once) were fixed.

PyTorch has narrowed the risk too: since version 2.6 of January 2025, torch.load uses weights_only=True by default. Its documentation says this narrows the attack surface without closing it, and versions before 2.6 could still run code with that setting (CVE-2025-32434).

How does it work?

The README specifies three parts:

  1. 8 bytes that give the size of the header.
  2. A JSON header that lists each tensor with its data type, shape and byte offsets, plus an optional __metadata__ map of strings. The header may be at most 100 MB.
  3. The raw tensor data, without gaps.

Because the header says where each tensor sits, a program can read one tensor without loading the rest (lazy loading) and can map the file straight into memory instead of copying it. The README gives an example: loading the BLOOM model on 8 GPUs took 10 minutes with regular PyTorch weights and 45 seconds with Safetensors. The library is written in Rust and works with PyTorch, TensorFlow, JAX, PaddlePaddle and NumPy.

Who manages it?

On 8 April 2026 Hugging Face moved Safetensors to the PyTorch Foundation. The trademark, repository and governance now sit with the Linux Foundation, and Hugging Face's two core maintainers stay on the technical steering committee. For users nothing changed: same format, same APIs. Hugging Face calls it the default format for model distribution on its Hub, used by tens of thousands of models, and PEFT saves LoRA adapters in it by default. The announcement's roadmap includes loading straight onto GPUs and formal support for FP8 and quantized formats such as GPTQ and AWQ. Hugging Face is also working with the PyTorch team so that Safetensors may be used within PyTorch core.

Where does it go wrong?

  • A safe file is not a safe model. Safetensors prevents code execution while loading weights, and it says nothing about what the model does. Code that ships with a model is a separate risk: the trust_remote_code option in Transformers runs code from the Hub on your machine, and its documentation says to enable it only for repositories you trust and whose code you have read.
  • Tensors only. The format cannot store custom code or other Python objects, so a model's architecture and settings live in other files. The README also notes that tensor values are not checked: a file can contain NaN or infinite values.
  • Old files. The Hugging Face Hub still accepts pickle-based files such as pytorch_model.bin and scans each upload for suspicious imports. Loading such files remains the risky step.

Example

Reading one tensor from a file without loading the rest, as in the README:

Python
1from safetensors import safe_open
2
3with safe_open("model.safetensors", framework="pt", device="cpu") as f:
4 print(list(f.keys())) # tensor names, read from the header
5 weight = f.get_tensor("weight1") # loads only this tensor

Loading the same weights from a pickle-based model.pt goes through torch.load, and the PyTorch documentation warns: "Never load data from an untrusted source."