- Safetensors es un formato de archivo para almacenar los pesos de modelos de aprendizaje automático que evita las vulnerabilidades de ejecución arbitraria de código presentes en formatos basados en pickle
- Se carga de 2 a 10 veces más rápido que los archivos .bin de PyTorch gracias al mapeo de memoria sin copia y admite la carga diferida (lazy loading) para modelos de varios gigabytes
- Instale con
pip install safetensorsy utilizasafe_open()para cargar osave_file()para guardar tensores - Ampliamente compatible con Hugging Face, Ollama, LM Studio, ComfyUI y todos los principales frameworks de aprendizaje automático
Safetensors es un formato binario para almacenar y cargar los pesos de modelos de aprendizaje automático, desarrollado por Hugging Face. Resuelve vulnerabilidades críticas de seguridad presentes en formatos basados en pickle (archivos .bin y .pt de PyTorch) mediante una estructura simple y analizable estáticamente que no permite la ejecución de código arbitrario durante la deserialización. El formato logra tiempos de carga significativamente más rápidos gracias al mapeo de memoria y operaciones sin copia, convirtiéndolo en el formato preferido para distribuir y cargar modelos de IA en 2026.
- ¿Qué es Safetensors?
- ¿Por qué se creó Safetensors?
- Instalación y uso de Safetensors
- Conversión entre formatos
- Detalles técnicos del formato de archivo
- Compatibilidad en el ecosistema
- Características de rendimiento
- Modelos fragmentados (sharded)
- Enlaces con lenguajes de programación (language bindings)
- Preguntas frecuentes
¿Qué es Safetensors?
Safetensors almacena tensores (matrices multidimensionales de números que representan los pesos de redes neuronales) en un formato binario plano con un encabezado JSON. A diferencia de los formatos basados en pickle utilizados históricamente en PyTorch, safetensors contiene únicamente datos brutos de tensores y metadatos: sin código Python, sin definiciones de clases ni instrucciones ejecutables.
La estructura del archivo consta de:
- Un encabezado de 8 bytes que contiene la longitud de los metadatos
- Una sección JSON de metadatos que describe los nombres de los tensores, sus formas, tipos de datos y desplazamientos en bytes
- Datos brutos de tensores almacenados contiguamente en bloques alineados en memoria
Esta simplicidad permite la carga mediante mapeo de memoria: el sistema operativo mapea directamente el archivo en la memoria del proceso, lo que permite acceder instantáneamente a los datos de los tensores sin copiar gigabytes a la RAM. Cuando se carga un modelo de 7 mil millones de parámetros almacenado como safetensors, el tiempo de carga se mide en milisegundos, no en segundos.
¿Por qué se creó Safetensors?
El formato pickle de Python, utilizado de forma predeterminada en las funciones torch.save() y torch.load()de PyTorch, puede ejecutar código Python arbitrario durante la deserialización. Un atacante malicioso puede crear un archivo .bin o .pt que ejecute malware al llamar a torch.load(). Esta no es una vulnerabilidad teórica: ya se han documentado múltiples incidentes reales con archivos de modelos comprometidos.
Más allá de la seguridad, los formatos basados en pickle presentan problemas de rendimiento:
| Problema | Basados en pickle (.bin, .pt) | Safetensors |
|---|---|---|
| Ejecución arbitraria de código | Sí, inherente a pickle | No, formato estático |
| Tiempo de carga para un modelo de 7B | 5-15 segundos | 0,5-2 segundos |
| Sobrecarga de memoria durante la carga | 2× el tamaño del modelo (se requiere copia) | ~1× (mapeo de memoria) |
| Portabilidad entre frameworks | Específico de Python/PyTorch | Cualquier lenguaje con enlaces disponibles (bindings) |
| Soporte para carga diferida (lazy loading): al cargar un archivo pickle, Python debe deserializar toda la estructura en memoria, reconstruir los objetos de Python y luego copiar los datos de los tensores al formato nativo del framework. Safetensors elimina estos pasos al mapear directamente los datos binarios de los tensores. | No | Sí |
Al cargar un archivo pickle, Python debe deserializar toda la estructura en la memoria, reconstruir los objetos de Python y luego copiar los datos de los tensores al formato nativo del marco de trabajo. Safetensors elimina estos pasos mediante la asignación directa de los datos binarios de los tensores.
Instalación y uso de Safetensors
Instala la biblioteca de Python:
pip install safetensorsCarga de archivos Safetensors
Usa safe_open() para carga diferida con mapeo de memoria:
from safetensors import safe_open
with safe_open("model.safetensors", framework="pt", device="cpu") as f:
# Obtener lista de nombres de tensores
tensor_names = f.keys()
# Cargar un tensor específico (diferida: solo se carga este tensor)
embedding_weights = f.get_tensor("model.embed_tokens.weight")
# Obtener metadatos del tensor sin cargarlo
metadata = f.metadata()El framework especifica el framework objetivo: "pt" para PyTorch, "tf" para TensorFlow, "np" para NumPy, o "jax" para JAX. El parámetro device controla dónde se colocan los tensores: "cpu", "cuda:0", u otros identificadores de dispositivo.
Para cargar todos los tensores a la vez:
from safetensors.torch import load_file
tensors = load_file("model.safetensors")
# Devuelve un diccionario: {"layer.weight": tensor, "layer.bias": tensor, ...}Guardar archivos Safetensors
Guarde un diccionario de tensores:
from safetensors.torch import save_file
import torch
tensors = {
"embedding.weight": torch.randn(50000, 768),
"layer1.weight": torch.randn(768, 768),
"layer1.bias": torch.randn(768)
}
save_file(tensors, "model.safetensors")Incluya metadatos personalizados:
save_file(
tensors,
"model.safetensors",
metadata={"model_type": "bert", "vocab_size": "50000"}
)Cargar modelos desde Hugging Face
La biblioteca transformers de Hugging Face utiliza safetensors automáticamente cuando está disponible:
from transformers import AutoModel
# Descarga y carga automáticamente el archivo .safetensors si está disponible
model = AutoModel.from_pretrained("bert-base-uncased")Forzar el formato safetensors:
model = AutoModel.from_pretrained(
"bert-base-uncased",
use_safetensors=True # Falla si safetensors no está disponible
)La mayoría de los modelos en Hugging Face Hub incluyen ahora tanto model.safetensors y como pytorch_model.bin Los archivos. La biblioteca prefiere safetensors cuando ambos existen.
Conversión entre formatos
Conversión de PyTorch .bin a Safetensors
from safetensors.torch import save_file
import torch
# Cargar el punto de control de PyTorch
state_dict = torch.load("pytorch_model.bin", map_location="cpu")
# Guardarlo como safetensors
save_file(state_dict, "model.safetensors")Conversión de Safetensors a PyTorch .bin
from safetensors.torch import load_file
import torch
tensors = load_file("model.safetensors")
torch.save(tensors, "pytorch_model.bin")Script de conversión de Hugging Face
El transformers La biblioteca incluye una herramienta de conversión:
python -m transformers.convert_safetensors_to_pytorch
--model_name_or_path ./model_folder
--output_dir ./convertedDetalles técnicos del formato de archivo
Un archivo safetensors tiene esta estructura:
- Encabezado (8 bytes): Entero sin signo de 64 bits en orden little-endian que contiene la longitud, en bytes, del metadato JSON
- Metadatos (variable): Objeto JSON con este esquema:
{ "layer_name": { "dtype": "F32", // Tipo de dato: F32, F16, BF16, I64, I32, etc. "shape": [768, 768], // Dimensiones del tensor "data_offsets": [0, 2359296] // Byte de inicio y fin en la sección de datos }, "__metadata__": { // Metadatos personalizados opcionales "key": "value" } } - Sección de datos: Bytes brutos del tensor, almacenados en orden contiguo C (row-major) y alineados a límites de 8 bytes
El formato admite estos tipos de datos: F64, F32, F16, BF16, I64, U64, I32, U32, I16, U16, I8, U8, BOOL. El rango de bytes de cada tensor se especifica en los metadatos, lo que permite su carga selectiva sin necesidad de analizar todo el archivo.
Compatibilidad en el ecosistema
Safetensors cuenta con soporte en todo el ecosistema de IA:
| Herramienta/Framework | Nivel de soporte | Notas |
|---|---|---|
| Hugging Face Transformers | Nativo | Formato predeterminado desde la versión v4.30 |
| Hugging Face Diffusers | Nativo | Utilizado para modelos de Stable Diffusion |
| PyTorch | Mediante biblioteca | Requiere el paquete safetensors safetensors |
| TensorFlow | Mediante biblioteca | Soportado mediante enlaces |
| JAX | Mediante biblioteca | Soportado mediante enlaces |
| Ollama | Nativo | Lo convierte internamente a GGUF |
| LM Studio | Nativo | Carga safetensors directamente |
| ComfyUI | Nativo | Formato principal para modelos personalizados |
| AUTOMATIC1111 | Nativo | Soporte para Stable Diffusion WebUI |
| llama.cpp | Mediante conversión | Convertir al formato GGUF |
| vLLM | Nativo | Compatibilidad con servidores de inferencia |
| TGI | Nativo | Compatibilidad con Text Generation Inference |
Al evaluar si un modelo cabrá en la memoria de su GPU, use el Calculadora de VRAM para estimar los requisitos según el número de parámetros y el nivel de cuantización. El propio formato de archivo no afecta el uso de VRAM: los archivos safetensors y pickle del mismo modelo consumen idéntica memoria GPU una vez cargados.
Características de rendimiento
Benchmarks en un sistema con SSD NVMe y 64 GB de RAM al cargar un modelo de 7 mil millones de parámetros:
| Formato | Tiempo de carga | Uso máximo de RAM | Tamaño del archivo |
|---|---|---|---|
| PyTorch .bin | 8,2 s | 28 GB | 13,5 GB |
| Safetensors (load_file) | 1,1 s | 14 GB | 13,5 GB |
| Safetensors (safe_open lazy) | 0,08 s | 0,5 GB | 13,5 GB |
El enfoque de carga diferida con safe_open() es especialmente valioso cuando necesita inspeccionar la arquitectura del modelo, extraer capas específicas o cargar modelos que superan la RAM disponible mediante la carga selectiva de tensores.
Para modelos cuantizados, safetensors admite todos los tipos de datos estándar, incluidos FP16, BF16, INT8 e INT4. La Base de datos de modelos de IA incluye los tamaños de los archivos safetensors y los requisitos de VRAM para 37 modelos populares en distintos niveles de cuantización.
Modelos fragmentados (sharded)
Los modelos mayores de varios gigabytes suelen distribuirse como múltiples archivos safetensors (sharding). Un modelo de 70 mil millones de parámetros podría dividirse en 8 fragmentos:
model-00001-of-00008.safetensors
model-00002-of-00008.safetensors
...
model-00008-of-00008.safetensors
model.safetensors.index.jsonEl archivo de índice asigna los nombres de los tensores a los archivos de fragmentos:
{
"metadata": {"total_size": 141123453952},
"weight_map": {
"model.embed_tokens.weight": "model-00001-of-00008.safetensors",
"model.layers.0.self_attn.q_proj.weight": "model-00001-of-00008.safetensors",
"model.layers.40.mlp.gate_proj.weight": "model-00005-of-00008.safetensors"
}
}Las bibliotecas de Hugging Face gestionan automáticamente la carga fragmentada. Carga manual:
import json
from safetensors import safe_open
with open("model.safetensors.index.json") as f:
index = json.load(f)
weight_map = index["weight_map"]
# Cargar un tensor específico buscando su fragmento
tensor_name = "model.layers.20.mlp.down_proj.weight"
shard_file = weight_map[tensor_name]
with safe_open(shard_file, framework="pt", device="cpu") as f:
tensor = f.get_tensor(tensor_name)Enlaces con lenguajes de programación (language bindings)
Aunque la implementación de referencia es en Python, safetensors dispone de enlaces para múltiples lenguajes:
- Rust: Implementación principal en Rust para rendimiento y seguridad
- Python: Enlaces oficiales mediante PyPI
- JavaScript/Node.js:
@huggingface/safetensorsPaquete npm - C/C++: Disponible mediante FFI a la biblioteca en Rust
- Go: Existen implementaciones comunitarias
La implementación en Rust es la referencia canónica. Los enlaces de Python envuelven esta implementación, heredando sus características de rendimiento.
Preguntas frecuentes
¿Puedo usar safetensors con modelos existentes de PyTorch sin modificar el código?
Sí, si utiliza las bibliotecas de Hugging Face. Para modelos personalizados, debe modificar torch.load() a load_file() de safetensors y torch.save() a save_file(). Los datos de los tensores y la arquitectura del modelo permanecen idénticos: solo cambia el formato de serialización. Convertir puntos de control existentes es una operación única que tarda segundos.
¿Funcionan los archivos safetensors entre distintas versiones de PyTorch?
Sí. A diferencia de los archivos pickle, que pueden dejar de funcionar al cambiar la versión de Python o PyTorch, safetensors almacena datos binarios sin serialización específica de versión. Un archivo safetensors creado con PyTorch 1.12 se carga correctamente en PyTorch 2.x, y viceversa. Esto hace que safetensors sea superior para el archivo a largo plazo y la distribución de modelos.
¿Por qué algunos modelos en Hugging Face Hub siguen distribuyéndose como archivos .bin?
Los modelos más antiguos, subidos antes de 2023, pueden contener únicamente archivos basados en pickle. Hugging Face está convirtiendo gradualmente el modelo hub, pero algunos modelos siguen siendo exclusivamente pickle si el autor original no ha proporcionado versiones en safetensors. Cuando ambos formatos están disponibles, safetensors se prefiere automáticamente. Puede convertir localmente usando el método mostrado en la sección de conversión anterior.
¿Aumenta safetensors el tamaño del archivo comparado con el .bin de PyTorch?
No. Los tamaños de archivo suelen ser idénticos o diferir en un 1-2 %, ya que ambos formatos almacenan los mismos datos binarios de los tensores. Safetensors añade una sobrecarga mínima (una cabecera JSON de unos pocos kilobytes), mientras que pickle incorpora una sobrecarga por serialización de objetos Python. Para un modelo de 7B, ambos formatos generan archivos de aproximadamente 13-14 GB. La diferencia radica en la velocidad de carga y la seguridad, no en la eficiencia de almacenamiento.
¿Puedo inspeccionar archivos safetensors sin cargar el modelo completo en memoria?
Sí, esta es una de las principales ventajas de safetensors. Use safe_open() para leer los metadatos y cargar selectivamente tensores específicos. Puede enumerar todos los nombres de tensores, verificar sus formas y tipos de datos, y extraer capas individuales sin cargar todo el archivo de varios gigabytes. Esto resulta especialmente útil para el análisis, depuración y extracción de componentes del modelo.
¿Son GGUF y safetensors lo mismo?
No. GGUF (GPT-Generated Unified Format) es un formato distinto utilizado principalmente por llama.cpp para inferencia cuantizada. GGUF incluye esquemas de cuantización optimizados para inferencia en CPU que safetensors no soporta. Safetensors está diseñado para entrenamiento y distribución general de modelos, mientras que GGUF está optimizado para inferencia eficiente en hardware de consumo. Muchas herramientas como Ollama aceptan safetensors como entrada y las convierten internamente a GGUF para la inferencia.

