What is safetensors? It is a file format from Hugging Face for storing model weights, the large arrays of numbers (tensors) that make up a neural network. A .safetensors file holds only those tensors plus a small text header, so loading one cannot run hidden code the way an old PyTorch pickle file can. It also loads quickly, because a program can map the file straight from disk instead of rebuilding Python objects one by one.

If you download models from the Hugging Face Hub, you will see model.safetensors or a set of numbered model-00001-of-00004.safetensors files in most model repositories. This guide explains what is inside those files, why the format replaced pickle checkpoints, how it compares to GGUF, and how to load, inspect and convert one.

Safetensors in plain words

Think of a safetensors file as a labelled box of numbers. The official safetensors README describes the layout in three parts:

  1. 8 bytes holding one number, the size of the header.
  2. The header, a JSON text block. For every tensor it lists the name, the data type (such as F16, BF16 or F32), the shape, and where its bytes start and end.
  3. The data, one long run of raw bytes holding every tensor back to back.

That is the whole format. There is an optional __metadata__ entry in the header, but it may only hold plain text keys and values. There is no place to put a function, a class or a script.

The library that reads and writes these files is open source under the Apache 2.0 license, written in Rust with Python bindings. Version 0.8.0 is the current stable release on PyPI, published June 9, 2026, with 0.9.0 release candidates out since September. You install it with pip install safetensors.

The data types cover what modern models use: 16 and 32 bit floats, bfloat16, several 8 bit float variants (such as F8_E4M3 and F8_E5M2), newer 4 and 6 bit float types, and signed and unsigned integers. That list comes from the Dtype definition in the library's source code.

Why pickle files are risky

Before safetensors, the usual way to save a PyTorch model was torch.save, which writes a .bin or .pt file using Python's pickle module. Pickle can store almost any Python object, and to rebuild those objects it can call functions while loading. That is the problem. The Python pickle documentation warns that the module is not secure and that you should only unpickle data you trust, because a crafted file can run arbitrary code during loading.

For a site where anyone can upload a model, that is a real risk. Hugging Face said as much when it announced the safetensors security audit on May 23, 2023: a malicious file posing as a model could give an attacker control of the computer that loads it.

PyTorch has since added its own guard. The torch.load source notes that PyTorch 2.6 changed the default of weights_only from False to True, which restricts what the unpickler will accept. The function's docstring still carries the warning to never load data from an untrusted source, and many tutorials pass weights_only=False to silence errors, which removes the guard. Safetensors avoids the question entirely, since the format has no code path to exploit.

What the audit found

Hugging Face, EleutherAI and Stability AI commissioned an external review of the library by Trail of Bits. According to the Hugging Face post, the audit found no critical flaw leading to arbitrary code execution. It did find some gaps in the spec and missing validation that allowed polyglot files (a file that is valid in two formats at once), and both were fixed. The README now requires the data section to be fully indexed with no holes for that reason, and it caps the header at 100 MB so a file cannot exhaust memory with a giant JSON block.

What "safe" does not cover

Safetensors makes the weights file safe to parse. It does not make a model trustworthy in every sense. A model repository can also include Python files, for example custom model code that Transformers runs only when you pass trust_remote_code=True. Read that code before you enable it. And a safe file can still contain a model that gives wrong or harmful answers. The format only protects the act of loading.

Why it loads fast

Speed was the second goal. Because each tensor's position is written in the header, a program can open the file with memory mapping and read just the tensors it needs. The README gives a concrete example: with this format, loading the BLOOM model across 8 GPUs dropped from about 10 minutes with regular PyTorch weights to 45 seconds.

That same layout enables lazy loading. With safe_open you can pull one tensor, or even a slice of one, without reading the rest of the file. Serving engines that split a model across several GPUs use this so each GPU reads only its share.

Safetensors vs GGUF vs PyTorch .bin

You will run into three weight formats when you work with open weight models. They solve different problems.

ItemSafetensorsGGUFPyTorch .bin / .pt
Made byHugging FaceThe llama.cpp projectPyTorch (torch.save)
Can run code when loadedNoNoYes, unless weights_only=True
Typical precisionFull or half (BF16, F16), sometimes FP8Quantized (Q4_K_M, Q8_0 and others)Full or half
Holds tokenizer and configNo, those sit in separate JSON filesYes, in one fileNo
Main usersTransformers, vLLM, Diffusers, ComfyUI, MLX, training toolsllama.cpp, Ollama, LM StudioOlder checkpoints and PyTorch scripts
Best forTraining, fine tuning and GPU servingRunning quantized models locallyLegacy files only

Safetensors vs GGUF: both are safe to load, so the choice comes down to the job. Safetensors is the source format most labs publish, usually at full or half precision, and it is what you fine tune from. GGUF is a packaging format for local inference that bundles quantized weights, tokenizer and settings into one file. Our GGUF quantization explained guide covers the quant names and which file to pick.

Safetensors vs .bin: for the same weights, a converted safetensors file holds the same numbers without the pickle wrapper. If a repository offers both, take the safetensors file.

How to load a safetensors file

With the safetensors library

from safetensors import safe_open

tensors = {}
with safe_open("model.safetensors", framework="pt", device="cpu") as f:
    for name in f.keys():
        tensors[name] = f.get_tensor(name)

The framework argument picks the output type. PyTorch ("pt") is the common choice, and the library also has helpers for NumPy, TensorFlow, Flax, PaddlePaddle and MLX. To save, call save_file(tensors, "model.safetensors") from safetensors.torch.

If your model ties two layers to the same tensor (many language models share the embedding matrix with the output layer), save_file on the raw state dict will complain. The shared tensors doc recommends save_model(model, "model.safetensors") and load_model(model, "model.safetensors") instead.

With Transformers

Transformers loads safetensors automatically. AutoModelForCausalLM.from_pretrained("org/model") looks for model.safetensors (or the sharded index) first and falls back to pytorch_model.bin only if no safetensors weights exist, per the loading logic in modeling_utils.py. Calling save_pretrained writes safetensors by default.

With local tools

Inspect a file without loading it

Because the header sits at the front, you can read a file's tensor list without downloading the weights. The metadata parsing doc shows how: fetch the first 8 bytes, read the header length, then fetch only the header with an HTTP range request. The Hub uses this to show parameter counts and tensor types on model pages. In Python, huggingface_hub offers HfApi().get_safetensors_metadata("org/model") for the same job.

Why models are split into several files

A large model often ships as model-00001-of-00004.safetensors and so on, plus model.safetensors.index.json. The index maps each tensor name to the file that holds it. Splitting keeps single files at a manageable size for uploads, downloads and file systems, and lets a loader fetch shards in parallel. Transformers decides the split with the max_shard_size argument of save_pretrained; in the 4.x releases the default was 5 GB per shard. You do not need to merge the shards. Point your tool at the folder and it reads the index.

Converting older checkpoints

If you have a pytorch_model.bin, converting is a short script:

import torch
from safetensors.torch import save_file

state = torch.load("pytorch_model.bin", map_location="cpu", weights_only=True)
save_file(state, "model.safetensors")

Two cautions. First, converting means loading the pickle file once, so do it only for files you trust, or in a throwaway container. The official convert.py in the safetensors repository prints exactly that warning before it runs. Second, if the model has tied weights, use save_model as described above.

For a model that already lives on the Hub, the safetensors convert Space runs the conversion on Hugging Face's machines and opens a pull request on the repository with the new files, so the pickle never touches your computer.

Who should care

If you only run models through Ollama, you rarely handle safetensors directly, because Ollama manages the model files for you. If you fine tune, serve with vLLM, train with PyTorch, or build image workflows, safetensors is the format you work in every day. Prefer it over .bin and .pt files whenever a repository offers both, and treat any pickle file from an unknown uploader as code, not data. For more on what open weight releases include, see open weight vs open source.

FAQ

Is safetensors safe to download?

Loading the file is safe in the sense that it cannot execute code: the format holds only a JSON header and raw numbers, and an external audit by Trail of Bits found no flaw allowing code execution. It does not vouch for the model's behaviour or for any separate Python files in the same repository.

Can Ollama use safetensors files?

Yes. Ollama can import a folder of safetensors weights with a Modelfile that points FROM at the directory, followed by ollama create. Models you pull from the Ollama library itself come in Ollama's own packaging.

What is the difference between safetensors and GGUF?

Safetensors stores tensors only, usually at full or half precision, and is the standard for training and GPU serving. GGUF packs quantized weights, tokenizer and settings into one file for llama.cpp based local inference. Both are safe to load.

How do I open a safetensors file?

In Python, use safe_open from the safetensors library to list tensor names and read them, or load the whole model with Transformers. To see what is inside without loading the weights, read just the header, which the Hub shows on the model page.

Why are models split into several safetensors files?

Large checkpoints are sharded so each file stays a manageable size. A model.safetensors.index.json file tells the loader which shard holds each tensor, and tools read the shards together automatically.

Is safetensors only for PyTorch?

No. The library reads and writes tensors for PyTorch, TensorFlow, Flax (JAX), NumPy, PaddlePaddle and MLX, and the format itself is framework neutral, so the same file can feed different libraries.