Programa
Se você baixou um modelo no Hugging Face recentemente, provavelmente viu um arquivo .safetensors em vez de .bin ou .pkl. Essa mudança é maior do que parece.
Por anos, a maioria dos frameworks de ML se apoiou em serialização baseada em pickle para armazenar checkpoints de modelos. Funcionava, mas tinha um custo oculto: carregar um checkpoint podia executar código Python arbitrário durante a desserialização, abrindo espaço para ataques na cadeia de suprimentos e cargas maliciosas escondidas em arquivos de modelo aparentemente inofensivos.
O SafeTensors foi criado para fechar essa lacuna. Ele armazena apenas os pesos dos tensores, sem executar nenhum código durante o carregamento, e por isso virou o formato padrão no Hugging Face Hub. Em abril de 2026, passou a fazer parte oficialmente da PyTorch Foundation, sob a Linux Foundation, ao lado de projetos como PyTorch, vLLM, DeepSpeed e Ray.
A seguir, veja como o formato funciona por baixo dos panos e como ele se compara a outros formatos.
O que é o SafeTensors?
SafeTensors é um formato de arquivo criado especificamente para armazenar pesos de modelos com segurança.
O formato separa os dados numéricos brutos dos tensores do código executável e guarda apenas os pesos. É aqui que o SafeTensors difere dos formatos baseados em pickle.
Projetos de aprendizado de máquina
O formato também se encaixa naturalmente nos pipelines modernos de ML porque foca no que a maioria dos checkpoints já contém:
- Tensores
- Formas (shapes)
- Tipos de dados
- Valores de pesos
Em vez de agir como um sistema de serialização Python genérico, o SafeTensors funciona como uma camada dedicada de armazenamento para parâmetros de modelos.
Embora o Hugging Face tenha criado originalmente o SafeTensors para seu ecossistema, o formato em si é agnóstico a frameworks. Ele se juntou recentemente (em abril de 2026) à PyTorch Foundation e oferece suporte a PyTorch, TensorFlow, JAX, Flax, NumPy e outros frameworks de ML.
O problema do pickle: por que era preciso um novo formato
O formato Pickle do Python foi criado para aplicações Python em geral, nas quais muitas vezes é preciso salvar e restaurar objetos completos, junto com seu estado interno, métodos e lógica de reconstrução.
Checkpoints de machine learning normalmente não precisam desse nível de armazenamento. A maioria dos arquivos de modelo guarda principalmente tensores: matrizes de pesos, embeddings, vieses e outros parâmetros numéricos. Na prática, o checkpoint é majoritariamente dados numéricos estruturados.
Mas um arquivo .pkl vai além de armazenar dados. Ele também pode conter instruções para o Python sobre como reconstruir objetos durante o carregamento. Isso significa que a desserialização não é uma leitura passiva; ela pode executar código. E se o código for malicioso, vira um problema sério de segurança.
Como o pickle permite executar código arbitrário
O Python reconstrói objetos durante a desserialização com pickle usando métodos especiais como __reduce__(). Classes podem definir esse método para dizer ao pickle exatamente como o objeto deve ser reconstruído quando for carregado de volta na memória.
Por exemplo, __reduce__() pode retornar uma função chamável junto com os argumentos dessa função. Durante a desserialização, o Python executa essa função para reconstruir o objeto. Exemplo de código:
import pickle
import os
class Demo:
def __reduce__(self):
return (os.system, ("echo 'Code executed during deserialization'",))
payload = pickle.dumps(Demo())
pickle.loads(payload)
Quando pickle.loads() roda, o Python executa a função retornada por __reduce__(). Neste exemplo, a desserialização aciona um comando de shell via os.system().
O problema não é o comando de shell em si. __reduce__() pode retornar qualquer função chamável com argumentos arbitrários conforme a lógica. Isso significa que um arquivo Pickle pode chamar outras funções, baixar arquivos, alterar o ambiente ou executar código malicioso durante o carregamento. Por isso a documentação do Python alerta explicitamente para nunca carregar dados pickle de fontes não confiáveis.
O risco na era do compartilhamento de modelos
Plataformas como o Hugging Face Hub hoje hospedam mais de um milhão de modelos compartilhados por pesquisadores, startups, hobbistas e colaboradores anônimos. O ecossistema avança rápido porque desenvolvedores podem baixar e testar modelos na hora. Mas a maioria dos checkpoints enviados não passa por auditoria individual antes da distribuição.
Muitos checkpoints do PyTorch ainda dependem de serialização baseada em pickle por meio de formatos como .pt ou .bin. Quando alguém carrega um desses arquivos, o Python pode executar a lógica de desserialização embutida no checkpoint. Se o checkpoint for malicioso, essa lógica pode roubar credenciais, ler variáveis de ambiente, baixar payloads ou executar código remoto durante o carregamento.

Esse é exatamente o problema que o SafeTensors veio resolver. Em vez de serializar objetos Python arbitrários, ele salva apenas os dados dos tensores e os metadados necessários para carregá-los corretamente. Carregar um arquivo .safetensors não exige executar lógica de reconstrução em Python, o que reduz significativamente a superfície de ataque.
Como funciona o formato SafeTensors
Agora que você já sabe o que é o SafeTensors e por que ele existe, vamos ver sua estrutura e como ele opera.
A estrutura de cabeçalho e dados
Um arquivo SafeTensors tem duas partes: um cabeçalho JSON seguido pelos dados brutos dos tensores.
O cabeçalho armazena metadados de cada tensor, incluindo
- Nomes dos tensores
- Formas (shapes)
- Tipos de dados
- Offsets em bytes
Após o cabeçalho, o arquivo armazena os bytes brutos dos tensores de forma contígua.
O cabeçalho funciona como um índice. Ele diz ao loader quais tensores existem e onde estão localizados no arquivo, de modo semelhante a como um índice de banco de dados aponta para registros armazenados. O SafeTensors limita o tamanho desse cabeçalho a 100 MB para evitar cargas de metadados desproporcionais.
Carregamento zero-copy e via mapeamento de memória
O SafeTensors acelera o carregamento usando mapeamento de memória. Em vez de reconstruir objetos Python durante a desserialização, os frameworks podem mapear os dados dos tensores diretamente do disco para a memória. Isso reduz cópias desnecessárias e diminui a sobrecarga de CPU no carregamento.
Segundo os benchmarks do Hugging Face, o SafeTensors carregou pesos cerca de 76x mais rápido que o PyTorch na CPU e cerca de 2x mais rápido em cargas de trabalho na GPU. Claro, o ganho exato depende do hardware e do tamanho do checkpoint, mas evitar a desserialização em Python melhora o desempenho de forma consistente.
Carregamento sob demanda e desserialização parcial
O SafeTensors carrega tensores específicos pelo nome, em vez de ler o checkpoint inteiro de uma vez para a memória.
Isso é útil em modelos grandes e distribuídos em várias GPUs. Pegue como exemplo o BLOOM com 176B parâmetros. Com checkpoints padrão do PyTorch, o sistema primeiro precisava desserializar todos os pesos do modelo para depois dividir entre os dispositivos, o que levava cerca de 10 minutos.
Com SafeTensors, cada GPU carrega apenas os shards de tensores de que realmente precisa. Isso reduziu o tempo de inicialização do modelo para cerca de 45 segundos em 8 GPUs.
SafeTensors vs. outros formatos de serialização
O SafeTensors é ótimo para armazenar e carregar pesos de modelos com segurança e eficiência, mas isso não o torna um substituto universal para todos os formatos. A escolha certa depende do que você está armazenando e de onde o modelo se encontra no pipeline.
Já falamos bastante sobre pickle, então vamos nos concentrar em formatos diferentes.
SafeTensors vs. GGUF
SafeTensors e GGUF resolvem problemas diferentes.
GGUF, sigla para GGML Unified Format, foi criado para inferência quantizada em runtimes como o llama.cpp. O formato foca no deployment eficiente de modelos comprimidos, especialmente para inferência em CPU e dispositivos de borda.
O SafeTensors atua mais cedo no pipeline. A maioria dos checkpoints em SafeTensors armazena tensores em precisão total ou prontos para treinamento, usados em treino, fine-tuning, merging ou fluxos de inferência distribuída. O formato prioriza carregamento seguro, compatibilidade com frameworks como PyTorch e acesso eficiente aos tensores durante treino e serving.
Eles podem se complementar, e não competir diretamente. Exemplo de fluxo:
- Treine ou faça fine-tuning do modelo usando PyTorch e checkpoints em SafeTensors
- Quantize o modelo final
- Exporte para GGUF para deployment no llama.cpp ou em runtimes de inferência na borda
SafeTensors vs. ONNX
O SafeTensors foca em armazenar pesos de modelos com segurança e carregá-los com eficiência em frameworks como o PyTorch. Ele guarda apenas tensores e metadados, o que o torna leve e rápido para compartilhamento de checkpoints, fine-tuning e fluxos de treinamento.
O ONNX tem um escopo mais amplo. Ele armazena o grafo computacional completo junto com os parâmetros do modelo. Isso torna o ONNX útil quando você quer exportar um modelo de um framework e rodá-lo em outro ambiente totalmente diferente.
Por exemplo, times que treinam e fazem fine-tuning de LLMs com PyTorch geralmente preferem checkpoints em SafeTensors porque carregam rápido e se encaixam direto nos fluxos existentes. Mas se esse mesmo time precisar fazer deploy no TensorRT, ONNX Runtime ou em um engine de inferência na borda, exportar o modelo para ONNX faz mais sentido.
Usando SafeTensors na prática
Um dos motivos de o SafeTensors ter se espalhado rápido no ecossistema PyTorch é que a API é familiar. Você continua trabalhando com state dicts e tensores como de costume.
Salvando e carregando tensores
O fluxo básico é idêntico ao manuseio de checkpoints padrão do PyTorch. Veja o exemplo:
import torch
from safetensors.torch import save_file, load_file
tensors = {
"weights": torch.randn(2, 2),
"bias": torch.zeros(2)
}
save_file(tensors, "model.safetensors")
loaded_tensors = load_file("model.safetensors")
print(loaded_tensors["weights"])
save_file() grava os tensores no formato .safetensors, enquanto load_file() os carrega de volta para a memória.
O SafeTensors também oferece carregamento seletivo via safe_open(), muito útil quando o checkpoint é grande e você só precisa de alguns tensores.
from safetensors import safe_open
with safe_open("model.safetensors", framework="pt") as f:
weights = f.get_tensor("weights")
print(weights)
Em vez de carregar o checkpoint completo, get_tensor() lê apenas o tensor solicitado.
Convertendo modelos existentes para safetensors
O padrão é:
- Carregue o modelo existente
- Extraia o state dict
- Salve com
save_file()
from transformers import AutoModel
from safetensors.torch import save_file
model = AutoModel.from_pretrained("bert-base-uncased")
save_file(model.state_dict(), "model.safetensors")
state_dict() retorna os pesos do modelo como tensores, que o SafeTensors pode armazenar diretamente.
Se o modelo já estiver no Hugging Face Hub, talvez você nem precise converter localmente. O Hugging Face oferece suporte integrado para conversão de checkpoints de modelos hospedados pela interface do Hub.
Formatos de serialização: tabela comparativa
| Recurso | SafeTensors | Pickle (.pkl/.bin/.pt) |
GGUF | ONNX |
|---|---|---|---|---|
| Execução de código arbitrário | Não | Sim | Não | Não |
| Caso de uso principal | Treinamento, fine-tuning, compartilhamento de checkpoints | Serialização geral em Python | Inferência quantizada em CPU/borda | Deployment entre frameworks |
| Armazena o grafo computacional | Não | Não | Não | Sim |
| Carregamento via mapeamento de memória | Sim | Não | Sim | Não |
| Carregamento parcial/sob demanda | Sim | Não | Sim | Não |
| Suporte de frameworks | PyTorch, TF, JAX, Flax, NumPy | Python (todos os frameworks) | llama.cpp, runtimes de borda | ONNX Runtime, TensorRT, borda |
| Suporte a quantização | Em expansão (FP8, GPTQ, AWQ) | Não | Sim (nativo) | Sim |
| Padrão no Hugging Face Hub | Sim | Não | Não | Não |
SafeTensors em 2026: PyTorch Foundation e os próximos passos
Em abril de 2026, o Hugging Face contribuiu o SafeTensors para a PyTorch Foundation, sob a Linux Foundation. O projeto agora está ao lado do PyTorch, vLLM, DeepSpeed e Ray sob a governança da fundação.
Esse movimento sinaliza que o SafeTensors não é mais apenas um projeto do Hugging Face. Ele está se tornando infraestrutura compartilhada para o ecossistema de ML.
O anúncio também indica para onde o formato está caminhando.
Carregamento ciente do dispositivo
Um foco importante é o carregamento ciente do dispositivo. Hoje, muitos fluxos ainda carregam tensores na memória da CPU antes de transferi-los para dispositivos CUDA ou ROCm. Essa etapa extra aumenta a latência de inicialização, especialmente em sistemas distribuídos grandes.
Os mantenedores do SafeTensors estão trabalhando em caminhos de carregamento direto para o dispositivo, reduzindo cópias desnecessárias na CPU e movendo os tensores diretamente para os aceleradores.
Carregamento distribuído
O suporte a carregamento distribuído também está evoluindo. Sistemas modernos de inferência raramente rodam modelos em uma única GPU. Paralelismo de tensores e de pipeline já são padrões de deployment para modelos grandes, mas as APIs de carregamento de checkpoints entre frameworks ainda são fragmentadas.
O SafeTensors está ampliando o suporte a carregamento ciente de shards e a layouts distribuídos de tensores, para que os frameworks coordenem o carregamento de checkpoints de forma mais eficiente entre dispositivos.
Workflows modernos de quantização
O formato também está se adaptando a workflows de quantização mais recentes. Sistemas de inferência dependem cada vez mais de FP8, GPTQ e AWQ para reduzir o uso de memória e cortar custos de serving.
Em vez de forçar os frameworks a tratar isso por lógica de serialização customizada, o SafeTensors está adicionando suporte formal a formatos de tensores de menor precisão e quantização em blocos diretamente no próprio formato.
Hoje, desenvolvedores ainda precisam optar manualmente pelo SafeTensors alternando entre fluxos de salvar e carregar. Mas há trabalhos em andamento para uma integração mais profunda com o sistema nativo de serialização do PyTorch. Se isso avançar, o SafeTensors pode deixar de ser um formato alternativo de checkpoint e virar a forma padrão de armazenamento de modelos no PyTorch.
Considerações finais
Por anos, desenvolvedores compartilharam checkpoints usando sistemas de serialização que podiam executar código Python arbitrário durante o carregamento. Quando hubs públicos de modelos passaram a hospedar milhões de checkpoints, os riscos de segurança ficaram impossíveis de ignorar.
O SafeTensors mudou esse jogo ao reduzir o escopo do formato. Em vez de tentar serializar objetos Python inteiros, ele foca em armazenar apenas tensores e os metadados necessários para carregá-los. Esse design mais simples elimina os riscos de desserialização dos checkpoints baseados em pickle e ainda melhora a velocidade de carregamento e a eficiência de memória.
Quando você só precisa dos pesos do modelo, não faz sentido executar código arbitrário durante a desserialização — melhor usar SafeTensors nesses casos.
Se você quiser se aprofundar nas ferramentas modernas de ML, formatos de modelo e fluxos de trabalho no Hugging Face, nossos cursos Deep Learning in Python e Working with Hugging Face são um ótimo próximo passo. Eles cobrem fluxos práticos para treinar, fazer fine-tuning e implantar modelos com as ferramentas usadas no ecossistema de IA atual.
Perguntas frequentes sobre SafeTensors
Posso converter modelos .bin ou .pt existentes para SafeTensors?
Sim. Você pode carregar o modelo normalmente no PyTorch ou Transformers, extrair o state_dict() e salvá-lo usando save_file() da biblioteca safetensors. O Hugging Face Hub também dá suporte a conversão automática para muitos modelos hospedados.
O SafeTensors consegue armazenar modelos quantizados?
Sim. O SafeTensors já oferece suporte a vários tipos de tensores de menor precisão, e o suporte a formatos como FP8, GPTQ e AWQ está se expandindo conforme a inferência quantizada se populariza.
Posso inspecionar o conteúdo de um arquivo SafeTensors sem carregar o modelo completo?
Sim. O formato armazena metadados dos tensores separadamente no cabeçalho, então você pode inspecionar nomes, formas e tipos de dados sem carregar o checkpoint inteiro na memória.
Usar SafeTensors afeta a acurácia do modelo?
Não. O SafeTensors muda como os pesos são armazenados e carregados, não os valores numéricos em si. O modelo se comporta da mesma forma após o carregamento.
SafeTensors é útil apenas para workloads de inferência?
Ele também é usado durante treinamento, fine-tuning, compartilhamento de checkpoints e em fluxos de carregamento distribuído.
Srujana é redatora freelancer de tecnologia e tem um diploma de quatro anos em Ciência da Computação. Escrever sobre vários tópicos, incluindo ciência de dados, computação em nuvem, desenvolvimento, programação, segurança e muitos outros, é algo natural para ela. Ela gosta de literatura clássica e de explorar novos destinos.

