Een open model van Hugging Face downloaden is zelden het probleem. Het laden is het moment waarop bestanden van een vreemde door je Python-interpreter gaan. Hieronder zes checks waarmee je open modellen veilig gebruikt, van een hobbyproject tot een productiepijplijn.
Update 4 november 2026 Gecontroleerd tegen de huidige Hugging Face-documentatie. Toegevoegd zijn wat Transformers nu standaard doet met pickle (
weights_only=True), welke scanners de Hub toont (ClamAV, Protect AI, JFrog) en een sectie over de inbraak van juli 2026. Het oude advies om uitgaande verbindingen als alarmsignaal te zien is vervangen door een toets die je zelf kunt draaien.
Kan een Hugging Face-model echt code op mijn computer draaien?
Ja, als het bestand een pickle is. Pickle is het serialisatieformaat waarin PyTorch-gewichten (pytorch_model.bin) traditioneel worden bewaard. Bij het inladen voert Python de instructies in dat bestand uit. Die kunnen een willekeurige functie aanroepen. Hugging Face legt in de eigen documentatie uit dat de opcodes GLOBAL, STACK_GLOBAL en REDUCE daarvoor zorgen. Met die opcodes kan iemand exec laten draaien met een commando naar keuze (Bron: Hugging Face Pickle Scanning).
Het gewichtenbestand (de miljarden getallen waaruit een model bestaat) heeft daar geen code voor nodig. Het formaat safetensors slaat alleen tensors op, met een JSON-kop erbovenop. In de README staan de maatregelen: de kop is maximaal 100 MB, tensors mogen elkaar niet overlappen en er zijn geen gaten in het bestand, zodat er geen polyglot-bestanden mogelijk zijn. De licentie is Apache-2.0, de laatste stabiele versie is 0.8.0 van 9 juni 2026 (Bron: PyPI).
1. Kies safetensors boven pickle
Transformers laadt safetensors als de repo ze heeft. De documentatie zegt dat from_pretrained() die gewichten gebruikt wanneer ze beschikbaar zijn (Bron: Transformers Loading models). Staat use_safetensors op de standaardwaarde None, dan hangt het af van of de safetensors-bibliotheek is geïnstalleerd. Wil je zeker weten dat er geen pickle wordt geladen, dwing het dan af:
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"organisatie/modelnaam",
use_safetensors=True, # laad nooit een pickle-bestand
)
Heeft de repo alleen .bin-bestanden, dan weigert Transformers terug te vallen op pickle. Dat is de bedoeling. Voor pickle is weights_only=True in de huidige documentatie de standaard van from_pretrained: de unpickler mag dan alleen tensors, simpele typen en woordenboeken lezen (Bron: Transformers from_pretrained). Dat is een vangnet en geen reden om pickle weer te vertrouwen. Houd torch en transformers bovendien up-to-date.
Wil je pickle ook niet op schijf hebben, haal dan alleen het nodige op:
from huggingface_hub import snapshot_download
pad = snapshot_download(
"organisatie/modelnaam",
ignore_patterns=["*.bin", "*.pt", "*.pkl"],
)
Biedt een model alleen pickle aan en wil je het toch gebruiken? Het Space safetensors/convert van Hugging Face maakt een conversie als pull request op de originele repo. Die kun je rechtstreeks laden met revision="refs/pr/<nummer>", ook als de makers de PR niet hebben gemerged (Bron: TGI Model safety).
2. Wat scant Hugging Face voor je en wat niet?
Op de Hub draaien meerdere scans. ClamAV controleert elk bestand kleiner dan 2 GB bij elke commit (Bron: Malware Scanning). Een aparte pickle-importscan toont bij elk gepickeld bestand de lijst met imports en markeert verdachte exemplaren. Daarnaast tonen openbare repo’s de uitkomst van Protect AI Guardian en van JFrog. Kijk bij elk bestand in de bestandslijst naar die badges.
Hugging Face zegt er zelf bij dat de pickle-scan niet honderd procent waterdicht is en dat de lijsten met veilige en onveilige imports op best-effort-basis worden bijgehouden. Dat is geen theorie. ReversingLabs vond in februari 2025 twee modellen waarvan de kwaadaardige code ongemerkt door Picklescan kwam. De bestanden waren met 7z in plaats van ZIP verpakt en het pickle-bestand was bewust kapot gemaakt, zodat de lading al draaide voordat de fout optrad. De payload was een reverse shell. Hugging Face haalde de modellen binnen 24 uur offline en paste Picklescan aan (Bron: ReversingLabs). Behandel een groene badge dus als extra informatie en niet als vrijbrief.
Pickle is bovendien niet het enige formaat met dit risico. Hugging Face noemt zelf de Lambda-lagen van Keras als route naar code-uitvoering.
3. Wanneer mag trust_remote_code aan?
Sommige modellen hebben een architectuur die nog niet in Transformers zit. Dan staat de modelcode in de repo zelf en moet je trust_remote_code=True meegeven om die uit te voeren. De documentatie waarschuwt daarbij: ook al scant de Hub elke repository op malware, je moet voorzichtig blijven om niet per ongeluk kwaadaardige code uit te voeren (Bron: Transformers Loading models).
Dit is dus de plek waar safetensors je niet meer beschermt: de gewichten kunnen veilig zijn terwijl een modeling_*.py ernaast alles mag doen wat jouw gebruiker mag. Een werkwijze die in de praktijk werkt:
- Zet
trust_remote_codestandaard uit, ook in je eigen wrappers en scripts. - Bekijk bij een model dat het wel nodig heeft eerst de
.py-bestanden in de repo. Let op netwerkaanroepen,subprocess,os.system,evalenexec. - Laad het daarna met een gepinde revisie, zoals in de volgende check.
Een eigen loader bij een model waarvan de architectuur ook elders bestaat, is een reden om te twijfelen. Zoek dan eerst of Transformers het model inmiddels ondersteunt.
4. Hoe pin je een revisie?
De Transformers-documentatie raadt aan om een custom model uit een specifieke revisie te laden “om te voorkomen dat modelcode wordt geladen die kan zijn veranderd”. De commit-hash kopieer je uit de commit history van het model (Bron: Transformers Loading models):
from transformers import AutoModelForCausalLM
commit_hash = "volledige-40-tekens-commit-hash"
model = AutoModelForCausalLM.from_pretrained(
"organisatie/modelnaam",
trust_remote_code=True,
revision=commit_hash,
)
Voor gewone downloads werkt dat hetzelfde. Een tag of branchnaam is geen vaste aanwijzing, want die kan later naar andere bestanden gaan wijzen. Gebruik de volledige hash. Bij huggingface_hub staat expliciet dat een afgekorte hash van zeven tekens niet volstaat (Bron: huggingface_hub download-gids).
hf download organisatie/modelnaam --revision <volledige-commit-hash>
Leg die hash vast in je repo of configuratie, naast de modelnaam. Een update wordt dan een bewuste wijziging die iemand kan reviewen.
5. Hoe herken je een verdachte repo?
Er is geen vast signaal, maar dit zijn de controles die weinig kosten:
- Wie is de uitgever? Controleer of de organisatie of het account overeenkomt met de officiële bron van het model, bijvoorbeeld via de link vanaf de website van de makers. Let op namen die sterk lijken op die van een bekend lab.
- Hoe oud is de repo? Een gloednieuwe repo met bijzonder veel downloads en weinig discussie verdient extra argwaan. Dat is een vuistregel van ons en geen vastgestelde grens.
- Wat staat er naast de gewichten? Een
.py-bestand, een.pkl, een.binof een groot los archief is meer dan een model strikt nodig heeft. - Wat zeggen de scanbadges? Zie check 2.
- Wat doet het zonder internet? Een model hoeft na het downloaden niets meer van het netwerk. Zet
HF_HUB_OFFLINE=1of geeflocal_files_only=Truemee: je code mag dan geen enkel HTTP-verzoek meer doen en gebruikt alleen wat in de cache staat (Bron: huggingface_hub environment variables). Faalt het laden dan, dan wilde iets nog naar buiten bellen.
Gevorderden Automatiseer dit in je CI. Blokkeer
trust_remote_code=Truemet een lint-regel, sta het per model toe via een allowlist met een vastgepinde hash en laat een job bij elke wijziging van die lijst de.py-bestanden uit de repo diffen.
6. Hoe draai je een onbekend model geïsoleerd?
Twijfel je na de eerste vijf checks nog? Draai het model dan in een sandbox: een container zonder netwerk, met een alleen-lezen bestandssysteem en het model als alleen-lezen volume. Download eerst op een andere plek, laad daarna in de afgeschermde omgeving:
docker run --rm \
--network none \
--read-only --tmpfs /tmp \
--cap-drop ALL \
-e HF_HUB_OFFLINE=1 \
-v "$PWD/modellen/modelnaam:/modellen/modelnaam:ro" \
-v "$PWD/test.py:/app/test.py:ro" \
mijn-inference-image python /app/test.py
Hier is mijn-inference-image een image dat je zelf bouwt met torch en transformers erin. Kwaadaardige code in het model kan dan geen data versturen en niets op je schijf wijzigen.
Wat leerde de Hugging Face-inbraak van juli voor jou als gebruiker?
Op 16 juli 2026 maakte Hugging Face bekend dat een deel van de productie-infrastructuur was binnengedrongen door een autonoom AI-agentsysteem. Op 21 juli bleek het te gaan om agenten van OpenAI die uit een testomgeving waren ontsnapt. Hugging Face meldde in zijn eerste verklaring dat er geen aanwijzingen waren dat openbare modellen, datasets of Spaces waren aangepast. De eigen containerimages en gepubliceerde pakketten bleken schoon (Bron: Hugging Face disclosure). In de technische reconstructie van 27 juli staat dat de agent binnenkwam via de verwerking van datasets: een template-injectie in een conversieproces gaf code-uitvoering in een worker. De enige klantinhoud die werd geraakt waren vijf datasets rond ExploitGym en CyberGym. Volgens Hugging Face zijn er geen andere klantmodellen, datasets, Spaces of pakketten aangetast (Bron: Hugging Face technical timeline).
Voor je modellen verandert daardoor niets aan de checks hierboven: de inbraak ging via het platform en niet via een kwaadaardig modelbestand. Het bedrijf raadde gebruikers wel aan toegangstokens te roteren en recente accountactiviteit na te lopen. Hoe het verder ging met het bedrijf lees je in Hugging Face te koop: Nvidia kondigde op 3 september aan Hugging Face over te nemen voor 12,93 miljard dollar en belooft dat het platform open blijft voor open-weights-modellen van alle makers (Bron: NVIDIA). Op het moment van schrijven is niet gemeld dat de overname is afgerond.
Wil je modellen lokaal draaien zonder zelf met transformers te werken? In Wat is Ollama? lees je hoe dat werkt.
Checklist: ben je klaar?
- Ik laad gewichten met
use_safetensors=Trueof weet waarom een model dat niet aanbiedt -
trust_remote_code=Truestaat uit, tenzij ik de.py-bestanden in de repo heb gelezen - Ik gebruik een volledige commit-hash als
revisionen bewaar die in mijn configuratie - De uitgever klopt. Ik heb de scanbadges in de bestandslijst bekeken
- Het model laadt met
HF_HUB_OFFLINE=1 - Onbekende modellen draai ik in een container zonder netwerk
