Leerpad
Als je onlangs een model van Hugging Face hebt gedownload, heb je waarschijnlijk een .safetensors-bestand gezien in plaats van een .bin of .pkl. Dat is een grotere verandering dan het lijkt.
Jarenlang vertrouwden de meeste ML-frameworks op pickle-gebaseerde serialisatie om modelcheckpoints op te slaan. Dat werkte redelijk, maar had een verborgen prijs: het laden van een checkpoint kon tijdens deserialisatie willekeurige Python-code uitvoeren, waardoor de deur werd geopend voor supplychain-aanvallen en kwaadaardige payloads die verstopt zitten in ogenschijnlijk onschuldige modelbestanden.
SafeTensors is gebouwd om dat gat te dichten. Het slaat alleen ruwe tensorgewichten op en voert tijdens het laden geen code uit, waardoor het het standaardformaat is op de Hugging Face Hub. In april 2026 trad het officieel toe tot de PyTorch Foundation onder de Linux Foundation, naast projecten als PyTorch, vLLM, DeepSpeed en Ray.
Lees verder om te begrijpen hoe het formaat onder de motorkap werkt en hoe het zich verhoudt tot andere formaten.
Wat zijn SafeTensors?
SafeTensors is een bestandsformaat dat speciaal is ontworpen voor het veilig opslaan van modelgewichten.
Het formaat scheidt ruwe numerieke tensordata van uitvoerbare code en slaat alleen de gewichten op. Hierin verschilt SafeTensors van pickle-gebaseerde formaten.
Het formaat past ook natuurlijk in moderne ML-pijplijnen, omdat het focust op wat de meeste checkpoints al bevatten:
- Tensors
- Vormen
- Datatypes
- Gewichtswaarden
In plaats van te fungeren als een general-purpose Python-serialisatiesysteem, werkt SafeTensors als een toegewijde opslaglaag voor modelparameters.
Hoewel Hugging Face oorspankelijk SafeTensors voor zijn ecosysteem ontwikkelde, is het formaat zelf framework-agnostisch. Het is onlangs (in april 2026) toegetreden tot de PyTorch Foundation en ondersteunt PyTorch, TensorFlow, JAX, Flax, NumPy en andere ML-frameworks.
Het Pickle-probleem: waarom een nieuw formaat nodig was
Pythons Pickle-formaat is gebouwd voor algemene Python-toepassingen, waar ontwikkelaars vaak complete Python-objecten willen opslaan en herstellen, inclusief hun interne staat, methoden en logica voor wederopbouw.
Machinelearning-checkpoints hebben die mate van opslag meestal niet nodig. De meeste modelbestanden slaan voornamelijk tensors op: gewichtsmatrices, embeddings, biases en andere numerieke parameters. In de praktijk betekent dat dat het checkpoint grotendeels uit gestructureerde numerieke data bestaat.
Maar een .pkl-bestand doet meer dan alleen data opslaan. Het kan ook instructies bevatten voor Python over hoe objecten tijdens het laden moeten worden herbouwd. Dat betekent dat deserialisatie geen passieve leesoperatie is; het kan code uitvoeren. En als die code kwaadaardig is, wordt dat een serieus beveiligingsprobleem.
Hoe pickle willekeurige code-executie mogelijk maakt
Python reconstrueert objecten tijdens pickle-deserialisatie met speciale methoden zoals __reduce__(). Klassen kunnen deze methode definiëren om pickle precies te vertellen hoe het object moet worden herbouwd wanneer iemand het terug in het geheugen laadt.
Zo kan __reduce__() een aanroepbare functie teruggeven met argumenten voor die functie. Tijdens deserialisatie voert Python die callable uit om het object te reconstrueren. Voorbeeldcode:
import pickle
import os
class Demo:
def __reduce__(self):
return (os.system, ("echo 'Code executed during deserialization'",))
payload = pickle.dumps(Demo())
pickle.loads(payload)
Wanneer pickle.loads() draait, voert Python de functie uit die door __reduce__() is teruggegeven. In dit voorbeeld triggert deserialisatie een shell-commando via os.system().
Het probleem is niet het shell-commando zelf. __reduce__() kan elke callable teruggeven met willekeurige argumenten op basis van de logica. Dat betekent dat een Pickle-bestand andere functies kan aanroepen, bestanden kan downloaden, de omgeving kan wijzigen of kwaadaardige code kan uitvoeren tijdens het laden. Daarom waarschuwt de Python-documentatie expliciet tegen het laden van pickle-data uit onbetrouwbare bronnen.
Het risico in het tijdperk van modeldeling
Platforms zoals Hugging Face Hub hosten inmiddels meer dan een miljoen modellen die worden gedeeld door onderzoekers, startups, hobbyisten en anonieme bijdragers. Het ecosysteem beweegt snel omdat ontwikkelaars modellen direct kunnen downloaden en testen. Maar de meeste geüploade checkpoints worden niet individueel geaudit voordat ze worden verspreid.
Veel PyTorch-checkpoints vertrouwen nog steeds op pickle-gebaseerde serialisatie via formaten zoals .pt of .bin. Wanneer iemand een van die bestanden laadt, kan Python deserialisatielogica uitvoeren die in het checkpoint is ingebed. Als het checkpoint kwaadaardig is, kan die logica inloggegevens stelen, omgevingsvariabelen lezen, payloads downloaden of tijdens het laden op afstand code uitvoeren.

Dit is precies het probleem dat SafeTensors moest oplossen. In plaats van willekeurige Python-objecten te serialiseren, slaat het alleen tensordata op en de metadata die nodig is om die tensors correct te laden. Het laden van een .safetensors-bestand vereist geen uitvoering van Python-wederopbouwlogica, wat het aanvalsoppervlak aanzienlijk verkleint.
Hoe het SafeTensors-formaat werkt
Nu we weten wat SafeTensors zijn en waarom ze bestaan, kijken we naar de structuur en werking.
De header-data-structuur
Een SafeTensors-bestand heeft twee delen: een JSON-header gevolgd door de ruwe tensordata.
De header slaat metadata op voor elke tensor, waaronder
- Tensornamen
- Vormen
- Datatypes
- Byte-offsets
Na de header slaat het bestand de ruwe tensorbytes aaneengesloten op.
De header werkt als een inhoudsopgave. Hij vertelt de loader welke tensors er zijn en waar ze zich in het bestand bevinden, vergelijkbaar met hoe een database-index naar opgeslagen records verwijst. SafeTensors beperkt de grootte van deze header tot 100 MB om te grote metadatapayloads te voorkomen.
Zero-copy en memory-mapped laden
SafeTensors versnelt het laden via memory-mapped loading. In plaats van Python-objecten te herbouwen tijdens deserialisatie, kunnen frameworks tensordata direct van schijf naar geheugen mappen. Dat vermindert onnodige geheugenkopieën en verlaagt de CPU-overhead tijdens het laden.
Volgens benchmarks van Hugging Face laadde SafeTensors gewichten ongeveer 76x sneller dan PyTorch op CPU en ongeveer 2x sneller bij GPU-workloads. De exacte snelheidswinst hangt natuurlijk af van de hardware en de checkpointgrootte, maar het vermijden van Python-deserialisatie verbetert de laadtijd consequent.
Lazy loading en gedeeltelijke deserialisatie
SafeTensors laadt specifieke tensors op naam in plaats van het hele checkpoint in één keer in het geheugen te lezen.
Dat is handig bij grote gedistribueerde modellen die over meerdere GPU’s draaien. Neem bijvoorbeeld BLOOM’s model met 176B parameters. Met standaard PyTorch-checkpoints moest het systeem eerst de volledige modelgewichten deserialiseren voordat ze over apparaten werden verdeeld, wat ongeveer 10 minuten duurde.
Met SafeTensors laadde elke GPU alleen de tensorscherven die het daadwerkelijk nodig had. Dat verminderde de opstarttijd van het model tot ongeveer 45 seconden over 8 GPU’s.
SafeTensors vs andere serialisatieformaten
SafeTensors werkt goed voor het veilig en efficiënt opslaan en laden van modelgewichten, maar dat maakt het nog geen universele vervanger voor elk formaat. De juiste keuze hangt af van wat je opslaat en waar het model in de pijplijn staat.
We hebben het al veel over pickle gehad, dus ik focus nu op andere formaten.
SafeTensors vs GGUF
SafeTensors en GGUF lossen verschillende problemen op.
GGUF, kort voor GGML Unified Format, is gebouwd voor gequantiseerde inference-workloads in runtimes zoals llama.cpp. Het formaat richt zich op efficiënte uitrol van gecomprimeerde modellen, vooral voor CPU-inference en edge-apparaten.
SafeTensors zit eerder in de pijplijn. De meeste SafeTensors-checkpoints slaan tensoren met volledige precisie of trainingsklare tensoren op die worden gebruikt voor training, fine-tuning, merging of gedistribueerde inference-workflows. Het formaat geeft prioriteit aan veilig laden, compatibiliteit met frameworks zoals PyTorch en efficiënte tensor-toegang tijdens training en serving.
Ze kunnen elkaar aanvullen in plaats van rechtstreeks te concurreren. Voorbeeldworkflow:
- Train of fine-tune het model met PyTorch en SafeTensors-checkpoints
- Quantiseer het uiteindelijke model
- Exporteer het naar GGUF voor deployment in llama.cpp of edge-inference-runtimes
SafeTensors vs ONNX
SafeTensors richt zich op het veilig opslaan van modelgewichten en het efficiënt laden ervan binnen frameworks zoals PyTorch. Het slaat alleen tensors en metadata op, wat het lichtgewicht en snel maakt voor het delen van checkpoints, fine-tuning en trainingsworkflows.
ONNX pakt het breder aan. Het slaat de volledige rekengrafiek op samen met de modelparameters. Dat maakt ONNX nuttig wanneer je een model uit het ene framework wilt exporteren en het ergens anders volledig wilt draaien.
Teams die bijvoorbeeld LLM’s trainen en fine-tunen met PyTorch, geven meestal de voorkeur aan SafeTensors-checkpoints omdat ze snel laden en direct integreren in bestaande workflows. Maar als hetzelfde team het model moet uitrollen naar TensorRT, ONNX Runtime of een edge-inference-engine, is exporteren naar ONNX logischer.
SafeTensors in de praktijk gebruiken
Een reden waarom SafeTensors zich snel verspreidde in het PyTorch-ecosysteem is dat de API vertrouwd aanvoelt. Je werkt nog steeds met state-dicts en tensors zoals je gewend bent.
Tensors opslaan en laden
De basisworkflow lijkt identiek aan standaard PyTorch-checkpointafhandeling. Hier is het voorbeeld:
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() schrijft de tensors naar het .safetensors-formaat, terwijl load_file() ze terug in het geheugen laadt.
SafeTensors ondersteunt ook selectief laden via safe_open(), wat handig is bij grote checkpoints waar je maar een paar tensors nodig hebt.
from safetensors import safe_open
with safe_open("model.safetensors", framework="pt") as f:
weights = f.get_tensor("weights")
print(weights)
In plaats van het volledige checkpoint te laden, leest get_tensor() alleen de tensor die je opvraagt.
Bestaande modellen converteren naar safetensors
Het standaardpatroon is:
- Laad het bestaande model
- Extraheer de state-dictionary
- Sla die op met
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() geeft de modelgewichten terug als tensors, die SafeTensors direct kan opslaan.
Als het model al op Hugging Face Hub staat, heb je mogelijk niet eens lokale conversiecode nodig. Hugging Face biedt ingebouwde checkpointconversie voor gehoste modellen via de Hub-interface.
Serialisatieformaten: vergelijktabel
| Functie | SafeTensors | Pickle (.pkl/.bin/.pt) |
GGUF | ONNX |
|---|---|---|---|---|
| Willekeurige code-executie | Nee | Ja | Nee | Nee |
| Primaire usecase | Training, fine-tuning, checkpoints delen | Algemene Python-serialisatie | Gequantiseerde edge/CPU-inference | Cross-framework deployment |
| Slaat rekengrafiek op | Nee | Nee | Nee | Ja |
| Memory-mapped laden | Ja | Nee | Ja | Nee |
| Lazy/gedeeltelijk tensorladen | Ja | Nee | Ja | Nee |
| Framework-ondersteuning | PyTorch, TF, JAX, Flax, NumPy | Python (alle frameworks) | llama.cpp, edge-runtimes | ONNX Runtime, TensorRT, edge |
| Quantisatie-ondersteuning | Uitbreidend (FP8, GPTQ, AWQ) | Nee | Ja (native) | Ja |
| Standaard op Hugging Face Hub | Ja | Nee | Nee | Nee |
SafeTensors in 2026: de PyTorch Foundation en wat volgt
In april 2026 droeg Hugging Face SafeTensors over aan de PyTorch Foundation onder de Linux Foundation. Het project staat nu naast PyTorch, vLLM, DeepSpeed en Ray onder bestuur van de foundation.
Die stap geeft aan dat SafeTensors niet langer alleen een Hugging Face-project is. Het groeit uit tot gedeelde infrastructuur voor het ML-ecosysteem.
De aankondiging gaat ook in op de richting waarin het formaat verder evolueert.
Device-aware laden
Een belangrijk speerpunt is device-aware laden. Vandaag de dag laden veel workflows tensoren nog in CPU-geheugen voordat ze naar CUDA- of ROCm-apparaten worden overgezet. Die extra tussenstap verhoogt de opstartlatentie, vooral bij grote gedistribueerde systemen.
De maintainers van SafeTensors werken aan directe device-laadpaden die onnodige CPU-kopieën verminderen en tensoren rechtstreeks naar accelerators verplaatsen.
Gedistribueerd laden
Ondersteuning voor gedistribueerd laden ontwikkelt zich ook verder. Moderne inference-systemen draaien modellen zelden nog op één enkele GPU. Tensor- en pipeline-parallelisme zijn nu standaardpatronen voor grote modellen, maar checkpoint-API’s voor laden zijn nog gefragmenteerd over frameworks heen.
SafeTensors breidt ondersteuning uit voor shard-aware laden en gedistribueerde tensorlay-outs, zodat frameworks het laden van checkpoints efficiënter over apparaten kunnen coördineren.
Moderne quantisatieworkflows
Het formaat past zich ook aan nieuwere quantisatieworkflows aan. Inference-systemen vertrouwen steeds vaker op FP8, GPTQ en AWQ om het geheugenverbruik te verminderen en de serveerkosten te verlagen.
In plaats van frameworks te dwingen dit via aangepaste serialisatielogica af te handelen, voegt SafeTensors formele ondersteuning toe voor lagere-precisie- en block-gequantiseerde tensorformaten, rechtstreeks in het formaat zelf.
Op dit moment moeten ontwikkelaars nog handmatig voor SafeTensors kiezen door tussen save- en load-workflows te wisselen. Maar er loopt werk aan diepere integratie met het native serialisatiesysteem van PyTorch. Als dat uiteindelijk landt, kan SafeTensors ophouden een alternatief checkpointformaat te zijn en de standaard worden waarmee PyTorch modellen opslaat.
Tot slot
Jarenlang deelden ontwikkelaars modelcheckpoints met serialisatiesystemen die tijdens het laden willekeurige Python-code konden uitvoeren. Toen publieke modelhubs miljoenen checkpoints begonnen te hosten, werden de beveiligingsrisico’s veel moeilijker te negeren.
SafeTensors veranderde dat door de scope van het formaat te versmallen. In plaats van te proberen complete Python-objecten te serialiseren, focust het alleen op het opslaan van tensors en de metadata die nodig is om ze te laden. Dat eenvoudigere ontwerp verwijdert de deserialisatierisico’s die bij pickle-gebaseerde checkpoints hoorden, en verbetert tegelijk laadsnelheid en geheugenefficiëntie.
Dus als je alleen modelgewichten nodig hebt, is er geen reden om willekeurige code uit te voeren tijdens deserialisatie, en kun je in die gevallen beter SafeTensors gebruiken.
Als je je dieper wilt verdiepen in moderne ML-tools, modelformaten en Hugging Face-workflows, dan zijn onze cursussen Deep Learning in Python en Working with Hugging Face een goede volgende stap. Ze behandelen praktische workflows voor het trainen, fine-tunen en uitrollen van modellen met de tools die in het AI-ecosysteem van vandaag worden gebruikt.
SafeTensors-veelgestelde vragen
Kan ik bestaande .bin- of .pt-modellen converteren naar SafeTensors?
Ja. Je kunt het model normaal in PyTorch of Transformers laden, de state_dict() extraheren en het opslaan met save_file() uit de safetensors-bibliotheek. Hugging Face Hub ondersteunt ook automatische conversie voor veel gehoste modellen.
Kan SafeTensors gequantiseerde modellen opslaan?
Ja. SafeTensors ondersteunt al verschillende tensortypen met lagere precisie, en ondersteuning voor formaten als FP8, GPTQ en AWQ wordt uitgebreid naarmate gequantiseerde inference gebruikelijker wordt.
Kan ik de inhoud van een SafeTensors-bestand inspecteren zonder het volledige model te laden?
Ja. Het formaat slaat tensormetadata apart op in de header, zodat je tensornamen, vormen en datatypes kunt inspecteren zonder het volledige checkpoint in het geheugen te laden.
Beïnvloedt het gebruik van SafeTensors de modelnauwkeurigheid?
Nee. SafeTensors verandert hoe gewichten worden opgeslagen en geladen, niet de numerieke waarden zelf. Het model gedraagt zich hetzelfde na het laden.
Is SafeTensors alleen nuttig voor inference-workloads?
Ontwikkelaars gebruiken het ook tijdens training, fine-tuning, het delen van checkpoints en gedistribueerde laadworkflows.
Srujana is een freelance techschrijver met een vierjarige opleiding in Computer Science. Schrijven over uiteenlopende onderwerpen, waaronder data science, cloud computing, development, programmeren, security en veel meer, gaat haar vanzelf af. Ze houdt van klassieke literatuur en het ontdekken van nieuwe bestemmingen.

