track
Dacă ai descărcat recent un model de pe Hugging Face, probabil ai observat un fișier .safetensors în loc de .bin sau .pkl. Schimbarea e mai mare decât pare.
Ani la rând, majoritatea frameworkurilor ML s-au bazat pe serializarea cu pickle pentru a stoca checkpointuri de modele. A funcționat suficient de bine, dar a venit cu un cost ascuns: încărcarea unui checkpoint putea executa cod Python arbitrar în timpul deserializării, deschizând calea către atacuri pe lanțul de aprovizionare și payload-uri malițioase ascunse în fișiere de model aparent inofensive.
SafeTensors a fost creat pentru a închide acel gol. Stochează doar greutățile brute ale tensorilor și nu execută niciun cod în timpul încărcării, ceea ce îl face formatul implicit pe Hugging Face Hub. În aprilie 2026, a intrat oficial în Fundația PyTorch sub egida Linux Foundation, alături de proiecte precum PyTorch, vLLM, DeepSpeed și Ray.
Citește în continuare ca să înțelegi cum funcționează formatul „sub capotă” și cum se compară cu celelalte formate.
Ce sunt SafeTensors?
SafeTensors este un format de fișier conceput special pentru a stoca în siguranță greutățile modelelor.
Formatul separă datele numerice brute ale tensorilor de codul executabil și stochează doar greutățile. Aici SafeTensors diferă de formatele bazate pe pickle.
Formatul se potrivește natural și în pipeline-urile ML moderne pentru că se concentrează pe ceea ce conțin deja majoritatea checkpointurilor:
- Tensori
- Forme
- Tipuri de date
- Valori ale greutăților
În loc să acționeze ca un sistem de serializare Python cu scop general, SafeTensors acționează ca un strat de stocare dedicat parametrilor modelului.
Deși Hugging Face a dezvoltat inițial SafeTensors pentru propriul ecosistem, formatul în sine este agnostic față de framework. S-a alăturat recent Fundației PyTorch (în aprilie 2026) și suportă PyTorch, TensorFlow, JAX, Flax, NumPy și alte frameworkuri ML.
Problema Pickle: de ce era nevoie de un nou format
Formatul Pickle din Python a fost construit pentru aplicații Python generale, unde dezvoltatorii au adesea nevoie să salveze și să restaureze obiecte Python întregi împreună cu starea lor internă, metodele și logica de reconstrucție.
Checkpointurile de machine learning nu au de obicei nevoie de acel nivel de stocare. Majoritatea fișierelor de model păstrează în principal tensori: matrice de greutăți, embedding-uri, biase și alți parametri numerici. În practică, asta înseamnă că un checkpoint este în mare parte doar date numerice structurate.
Dar un fișier .pkl face mai mult decât să stocheze date. Poate conține și instrucțiuni pentru Python despre cum să reconstruiască obiectele în timpul încărcării. Asta înseamnă că deserializarea nu este o operațiune pasivă de citire; poate executa cod. Iar dacă acel cod este malițios, devine o problemă serioasă de securitate.
Cum permite pickle executarea de cod arbitrar
Python reconstruiește obiectele în timpul deserializării cu pickle folosind metode speciale precum __reduce__(). Clasele pot defini această metodă pentru a-i spune lui pickle exact cum ar trebui să fie reconstruit obiectul când este readus în memorie.
De exemplu, __reduce__() poate returna o funcție apelabilă împreună cu argumentele pentru acea funcție. În timpul deserializării, Python execută acea funcție pentru a reconstrui obiectul. Cod exemplu:
import pickle
import os
class Demo:
def __reduce__(self):
return (os.system, ("echo 'Code executed during deserialization'",))
payload = pickle.dumps(Demo())
pickle.loads(payload)
Când rulează pickle.loads(), Python execută funcția returnată de __reduce__(). În acest exemplu, deserializarea declanșează o comandă shell prin os.system().
Problema nu este comanda shell în sine. __reduce__() poate returna orice funcție apelabilă împreună cu argumente arbitrare, în funcție de logică. Asta înseamnă că un fișier Pickle poate apela alte funcții, descărca fișiere, modifica mediul sau executa cod malițios în timpul încărcării. De aceea documentația Python avertizează explicit împotriva încărcării datelor pickle din surse neîncrezătoare.
Riscul în era partajării modelelor
Platforme precum Hugging Face Hub găzduiesc acum peste un milion de modele partajate de cercetători, startupuri, pasionați și contribuitori anonimi. Ecosistemul avansează rapid pentru că dezvoltatorii pot descărca și testa instant modele. Dar majoritatea checkpointurilor încărcate nu sunt auditate individual înainte de distribuție.
Multe checkpointuri PyTorch se bazează încă pe serializarea cu pickle prin formate precum .pt sau .bin. Când cineva încarcă unul dintre aceste fișiere, Python poate executa logica de deserializare încorporată în checkpoint. Dacă checkpointul este malițios, acea logică poate fura credențiale, citi variabile de mediu, descărca payload-uri sau executa cod de la distanță în timpul încărcării.

Aceasta este problema exactă pe care SafeTensors a fost construit să o rezolve. În loc să serializeze obiecte Python arbitrare, stochează doar datele tensorilor și metadatele necesare pentru a le încărca corect. Încărcarea unui fișier .safetensors nu necesită execuția logicii de reconstrucție Python, ceea ce reduce semnificativ suprafața de atac.
Cum funcționează formatul SafeTensors
Acum că știm ce sunt SafeTensors și de ce există, să aruncăm o privire la structura lor și la modul în care funcționează.
Structura header–date
Un fișier SafeTensors are două părți: un header JSON urmat de datele brute ale tensorilor.
Headerul stochează metadate pentru fiecare tensor, inclusiv
- Numele tensorilor
- Formele
- Tipurile de date
- Dezvoltările de bytes (offseturi)
După header, fișierul stochează consecutiv bytes-ii bruti ai tensorilor.
Headerul funcționează ca un cuprins. Îi spune loaderului ce tensori există și unde sunt localizați în fișier, similar cu modul în care un index de bază de date indică înregistrările stocate. SafeTensors limitează dimensiunea acestui header la 100 MB pentru a preveni payload-uri de metadate supradimensionate.
Încărcare zero-copy și memory-mapped
SafeTensors îmbunătățește viteza de încărcare prin încărcare memory-mapped. În loc să reconstruiască obiecte Python în timpul deserializării, frameworkurile pot mapa direct datele tensorilor din disc în memorie. Asta reduce copiile inutile în memorie și scade încărcarea pe CPU în timpul încărcării.
Conform benchmarkurilor Hugging Face, SafeTensors a încărcat greutăți de aproximativ 76x mai rapid decât PyTorch pe CPU și cam de 2x mai rapid pe sarcini GPU. Desigur, accelerarea exactă depinde de hardware și de dimensiunea checkpointului, dar evitarea deserializării Python îmbunătățește constant performanța de încărcare.
Încărcare „lazy” și deserializare parțială
SafeTensors încarcă anumiți tensori după nume, în loc să citească întregul checkpoint în memorie dintr-odată.
Asta e util pentru modele mari distribuite care rulează pe mai multe GPU-uri. Ia ca exemplu modelul BLOOM cu 176B de parametri. Cu checkpointurile standard PyTorch, sistemul trebuia întâi să deserializaze greutățile complete ale modelului înainte de a le împărți între dispozitive, ceea ce dura în jur de 10 minute.
Cu SafeTensors, fiecare GPU a încărcat doar shardurile de tensori de care avea efectiv nevoie. Asta a reducț timpul de pornire a modelului la aproximativ 45 de secunde pe 8 GPU-uri.
SafeTensors vs alte formate de serializare
SafeTensors funcționează foarte bine pentru a stoca și încărca greutăți de model în siguranță și eficient, dar asta nu îl face un înlocuitor universal pentru orice format. Alegerea corectă depinde de ceea ce stochezi și de locul în care se află modelul în pipeline.
Am vorbit deja mult despre pickle, așa că mă voi concentra pe alte formate.
SafeTensors vs GGUF
SafeTensors și GGUF rezolvă probleme diferite.
GGUF, prescurtare de la GGML Unified Format, a fost construit pentru workload-uri de inferență cuantizată în runtime-uri precum llama.cpp. Formatul se concentrează pe distribuirea eficientă a modelelor comprimate, în special pentru inferență pe CPU și pe dispozitive edge.
SafeTensors se află mai devreme în pipeline. Majoritatea checkpointurilor SafeTensors stochează tensori în precizie completă sau gata de antrenare, folosiți pentru antrenare, fine-tuning, îmbinare sau workflow-uri de inferență distribuită. Formatul prioritizează încărcarea sigură, compatibilitatea cu frameworkuri precum PyTorch și accesul eficient la tensori în timpul antrenării și servirii.
Se pot completa reciproc în loc să concureze direct. Flux de lucru exemplu:
- Antrenează sau fine-tunează modelul folosind PyTorch și checkpointuri SafeTensors
- Cuantizează modelul final
- Exportă-l în GGUF pentru distribuire în llama.cpp sau în runtime-uri de inferență la edge
SafeTensors vs ONNX
SafeTensors se concentrează pe stocarea în siguranță a greutăților modelului și încărcarea lor eficientă în cadrul frameworkurilor precum PyTorch. Stochează doar tensori și metadate, ceea ce îl face ușor și rapid pentru partajarea checkpointurilor, fine-tuning și workflow-uri de antrenare.
ONNX abordează problema mai larg. Stochează graful de calcul complet împreună cu parametrii modelului. Asta face ONNX util când vrei să exporți un model dintr-un framework și să-l rulezi în altă parte cu totul.
De exemplu, echipele care antrenează și fac fine-tuning pe LLM-uri folosind PyTorch vor prefera de obicei checkpointuri SafeTensors pentru că se încarcă rapid și se integrează direct în workflow-urile existente. Dar dacă aceeași echipă trebuie să distribuie modelul în TensorRT, ONNX Runtime sau un engine de inferență la edge, are mai mult sens exportul modelului în ONNX.
Utilizarea SafeTensors în practică
Un motiv pentru care SafeTensors s-a răspândit rapid în ecosistemul PyTorch este că API-ul se simte familiar. Lucrezi în continuare cu dicționare de stare și tensori la fel ca de obicei.
Salvarea și încărcarea tensorilor
Fluxul de bază arată identic cu gestionarea standard a checkpointurilor PyTorch. Iată exemplul:
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() scrie tensorii în formatul .safetensors, în timp ce load_file() îi încarcă înapoi în memorie.
SafeTensors suportă și încărcarea selectivă prin safe_open(), care devine utilă la checkpointuri mari când ai nevoie doar de câțiva tensori.
from safetensors import safe_open
with safe_open("model.safetensors", framework="pt") as f:
weights = f.get_tensor("weights")
print(weights)
În loc să încarci întregul checkpoint, get_tensor() citește doar tensorul pe care îl ceri.
Conversia modelelor existente la safetensors
Modelul standard este:
- Încarcă modelul existent
- Extrage dicționarul de stare
- Salvează-l cu
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() returnează greutățile modelului ca tensori, pe care SafeTensors îi poate stoca direct.
Dacă modelul există deja pe Hugging Face Hub, s-ar putea nici să nu ai nevoie de cod local de conversie. Hugging Face oferă suport încorporat pentru conversia checkpointurilor pentru modele găzduite prin interfața Hub.
Formate de serializare: tabel comparativ
| Funcție | SafeTensors | Pickle (.pkl/.bin/.pt) |
GGUF | ONNX |
|---|---|---|---|---|
| Executare de cod arbitrar | Nu | Da | Nu | Nu |
| Caz principal de utilizare | Antrenare, fine-tuning, partajare de checkpointuri | Serializare Python generală | Inferență cuantizată pe edge/CPU | Distribuire cross-framework |
| Stochează graful de calcul | Nu | Nu | Nu | Da |
| Încărcare memory-mapped | Da | Nu | Da | Nu |
| Încărcare „lazy”/parțială a tensorilor | Da | Nu | Da | Nu |
| Suport pentru frameworkuri | PyTorch, TF, JAX, Flax, NumPy | Python (toate frameworkurile) | llama.cpp, runtime-uri edge | ONNX Runtime, TensorRT, edge |
| Suport pentru cuantizare | În extindere (FP8, GPTQ, AWQ) | Nu | Da (nativ) | Da |
| Implicit pe Hugging Face Hub | Da | Nu | Nu | Nu |
SafeTensors în 2026: Fundația PyTorch și ce urmează
În aprilie 2026, Hugging Face a contribuit SafeTensors către Fundația PyTorch, sub Linux Foundation. Proiectul se află acum alături de PyTorch, vLLM, DeepSpeed și Ray, sub guvernanța fundației.
Această mișcare arată că SafeTensors nu mai este doar un proiect Hugging Face. Devine infrastructură comună pentru ecosistemul ML.
Anunțul atinge și direcțiile în care se îndreaptă formatul.
Încărcare conștientă de dispozitiv
Un accent major este pe încărcarea conștientă de dispozitiv. Astăzi, multe fluxuri încă încarcă tensorii în memoria CPU înainte de a-i transfera pe dispozitive CUDA sau ROCm. Acel pas intermediar crește latența de pornire, mai ales pentru sisteme distribuite mari.
Mentinerii SafeTensors lucrează la căi de încărcare direct pe dispozitiv care reduc copiile inutile pe CPU și mută tensorii direct pe acceleratoare.
Încărcare distribuită
Suportul pentru încărcare distribuită evoluează și el. Sistemele moderne de inferență rareori mai rulează modele pe un singur GPU. Paralelismul pe tensori și paralelismul pe pipeline sunt acum modele standard de distribuire pentru modele mari, dar API-urile de încărcare a checkpointurilor între frameworkuri sunt încă fragmentate.
SafeTensors își extinde suportul pentru încărcare conștientă de sharduri și layouturi distribuite ale tensorilor, astfel încât frameworkurile să poată coordona mai eficient încărcarea checkpointurilor între dispozitive.
Workflow-uri moderne de cuantizare
Formatul se adaptează și la workflow-uri de cuantizare mai noi. Sistemele de inferență se bazează din ce în ce mai mult pe formate FP8, GPTQ și AWQ pentru a reduce utilizarea memoriei și costurile de servire.
În loc să forțeze frameworkurile să gestioneze acestea prin logică de serializare personalizată, SafeTensors adaugă suport formal pentru formate de tensori cu precizie redusă și cuantizare pe bloc direct în format.
Acum, dezvoltatorii trebuie încă să opteze manual pentru SafeTensors, comutând între fluxuri de salvare și încărcare. Dar există lucru în desfășurare pentru o integrare mai profundă cu sistemul nativ de serializare al PyTorch. Dacă asta se va concretiza, SafeTensors ar putea înceta să fie un format alternativ de checkpoint și să devină modul implicit în care PyTorch stochează modele.
Gânduri finale
Ani la rând, dezvoltatorii au partajat checkpointuri de modele folosind sisteme de serializare care puteau executa cod Python arbitrar în timpul încărcării. Odată ce huburile publice de modele au început să găzduiască milioane de checkpointuri, riscurile de securitate au devenit mult mai greu de ignorat.
SafeTensors a schimbat asta restrângând scopul formatului. În loc să încerce să serializeze obiecte Python întregi, se concentrează doar pe stocarea tensorilor și a metadatelor necesare pentru a-i încărca. Acest design mai simplu elimină riscurile de deserializare care veneau cu checkpointurile bazate pe pickle și, în același timp, îmbunătățește viteza de încărcare și eficiența memoriei.
Așadar, când ai nevoie doar de greutățile modelului, nu are rost să execuți cod arbitrar în timpul deserializării — mai bine folosești SafeTensors în astfel de cazuri.
Dacă vrei să lucrezi mai în profunzime cu tool-urile ML moderne, formatele de model și workflow-urile Hugging Face, cursurile noastre Deep Learning in Python și Working with Hugging Face sunt un pas bun înainte. Acoperă fluxuri de lucru practice pentru antrenarea, fine-tuningul și distribuirea modelelor cu instrumentele folosite în ecosistemul AI de astăzi.
Întrebări frecvente despre SafeTensors
Pot converti modelele .bin sau .pt existente în SafeTensors?
Da. Poți încărca modelul normal în PyTorch sau Transformers, extrage state_dict() și îl poți salva folosind save_file() din biblioteca safetensors. Hugging Face Hub suportă și conversia automată pentru multe modele găzduite.
Poate SafeTensors să stocheze modele cuantizate?
Da. SafeTensors suportă deja mai multe tipuri de tensori cu precizie redusă, iar suportul pentru formate precum FP8, GPTQ și AWQ se extinde pe măsură ce inferența cuantizată devine mai comună.
Pot să inspectez conținutul unui fișier SafeTensors fără să încarc modelul complet?
Da. Formatul stochează metadatele tensorilor separat, în header, astfel încât poți inspecta numele tensorilor, formele și tipurile de date fără a încărca complet checkpointul în memorie.
Afectează SafeTensors acuratețea modelului?
Nu. SafeTensors schimbă modul în care sunt stocate și încărcate greutățile, nu valorile numerice în sine. Modelul se comportă la fel după încărcare.
Este SafeTensors util doar pentru workload-uri de inferență?
Dezvoltatorii îl folosesc și în timpul antrenării, fine-tuningului, partajării de checkpointuri și în fluxuri de încărcare distribuită.
