Duiding7 minGevorderd

Hugging Face-modellen veilig downloaden: 6 checks

Een model laden kan code op je machine draaien. Kies safetensors, laat trust_remote_code uit en pin een revisie. Zo download je veilig van Hugging Face.

Conceptueel stilleven bij artikel 'Hugging Face-modellen veilig downloaden: 6 checks'AI-beeld

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:

  1. Zet trust_remote_code standaard uit, ook in je eigen wrappers en scripts.
  2. Bekijk bij een model dat het wel nodig heeft eerst de .py-bestanden in de repo. Let op netwerkaanroepen, subprocess, os.system, eval en exec.
  3. 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 .bin of 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=1 of geef local_files_only=True mee: 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=True met 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=True of weet waarom een model dat niet aanbiedt
  • trust_remote_code=True staat uit, tenzij ik de .py-bestanden in de repo heb gelezen
  • Ik gebruik een volledige commit-hash als revision en 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

Lees verder

Veelgestelde vragen

Is het gevaarlijk om modellen van Hugging Face te downloaden?

Downloaden zelf niet, laden en draaien wel. Een model in het oude pickle-formaat kan bij het inladen code uitvoeren. Een repo met trust_remote_code=True laat bovendien Python uit de repo draaien. Bij een model in safetensors-formaat zonder eigen Python-code is dat risico er niet. Hugging Face scant uploads, maar noemt dat zelf niet waterdicht.

Wat is safetensors en waarom is het veiliger dan pickle?

Safetensors is een bestandsformaat van Hugging Face dat alleen tensors (de getallen van het model) en een JSON-kop opslaat. Er zit geen uitvoerbare code in, anders dan bij pickle waar het inladen willekeurige Python kan starten. Het is open source onder Apache-2.0 en je installeert het met pip install safetensors. Het beschermt alleen het gewichtenbestand, niet de andere bestanden in een repo.

Wat doet trust_remote_code=True precies?

Het laat Transformers Python-code uit de model-repo uitvoeren, meestal een modeling.py en een configuration.py. Dat is nodig voor modellen met een architectuur die nog niet in Transformers zit. De docs raden aan zo'n model te laden met revision=<commit-hash>, zodat de code niet ongemerkt verandert. Lees de bestanden eerst door.

Hoe pin ik een revisie van een Hugging Face-model?

Geef bij from_pretrained, hf_hub_download of snapshot_download het argument revision mee met de volledige commit-hash van de repo, te vinden onder Commit history op de modelpagina. Een afgekorte hash van zeven tekens werkt niet. Een tag of branchnaam kan later naar andere bestanden gaan wijzen, een commit-hash niet.

Hoe draai ik een onbekend model veilig?

Download het vooraf, laad het daarna in een container zonder netwerk, met een alleen-lezen bestandssysteem en het model als read-only volume. Zet ook HF_HUB_OFFLINE=1 zodat je code niets meer van de Hub ophaalt. Zo kan zelfs kwaadaardige code geen data wegsturen.

Bronnen

Waar deze informatie vandaan komt.

  1. ReversingLabs: Malicious ML models on Hugging Face (nullifAI)reversinglabs.comReversingLabs
  2. Hugging Face: Security incident disclosure, July 2026huggingface.coHugging Face