← Blog

AI agents

Model-provenance audits: als 'eigen LLM' een LoRA blijkt

Een junior pushte dinsdagochtend ongemerged base-gewichten naar een publieke Hugging Face repo. Tegen lunchtijd was de 'eigen LLM' van een Apeldoornse vendor ontmaskerd als LoRA op Llama 3.1.

Jacob Molkenboer· Oprichter · A Brand New Company· 27 aug 2025· 9 min
Messing relais en crème indexkaart met doorgesneden lakzegel, groen lint over botkleurig papier.

De CTO belde om 09:14 op een dinsdag. Om 09:30 was de 'eigen Nederlandse juridische LLM' van de vendor ontmaskerd op een subreddit voor AI-tinkeraars, had de diff 180 upvotes en had iemand in München al een how-to-reproduce gepubliceerd. De vendor is een bedrijf van 29 mensen in Apeldoorn. Vier van de twintig grootste Nederlandse advocatenkantoren hebben betaalde licenties.

Om 02:11 die ochtend pushte een junior engineer een feature branch naar wat hij dacht dat de private Hugging Face-organisatie van de vendor was. Hij was publiek. De push bevatte de ongemerged base-gewichten checkpoint, niet alleen de fine-tuned adapter waarvan de publieke docs suggereerden dat hij los bestond. Binnen anderhalf uur had een developer met safetensors geïnstalleerd SHA-256-hashes vergeleken met de publiek gedistribueerde Meta-release. Ze kwamen overeen. Het 'in-house, vanaf nul opgebouwde' model dat de vendor pitchte, was technisch gezien een LoRA-adapter van zo'n 180 miljoen parameters bovenop een ongewijzigde Llama 3.1 70B base.

We zagen hetzelfde patroon de afgelopen zes maanden tweemaal bij andere vendors die een klant ons vroeg te evalueren: een geclaimd 'eigen' model dat bij inspectie een open base bleek met een dunne adapter erbovenop. Het komt vaak genoeg voor dat we de model-provenance audit die we nu draaien op elk model dat een klant zegt getraind te hebben, en op elk model dat een klant wordt geadviseerd te kopen, hebben opgeschreven.

Wat de vendor verkocht

De pitch deck beschreef een 'op maat gebouwd Nederlands juridisch taalmodel, getraind op 40 jaar gecureerde Hoge Raad-uitspraken en een privé-corpus van contracten van partner-kantoren'. Het architectuurdiagram toonde één grijs rechthoek met het label 'Vendor LLM'. Geen vermelding van een base model, geen erkenning van upstream-provenance, nergens in de docs een 'Built with Llama'-notice.

De technische werkelijkheid, zodra je de audit draaide: een ongewijzigde Meta Llama 3.1 70B base, plus een LoRA-adapter getraind op ongeveer 8.400 zaaksamenvattingen en een Nederlands contractencorpus. Het totaal aantal trainbare parameters lag rond 0,26% van het model. De compute-kosten waren misschien €4.200 aan H100-tijd. Niet niks, maar ook geen 'we hebben een foundation model gebouwd'.

Dat onderscheid doet ertoe, en niet alleen als marketingvraag. Meta's Llama 3.1 Community License vereist dat elk product of dienst dat het model gebruikt prominent 'Built with Llama' toont. Het verbiedt ook dat je Llama-outputs gebruikt om andere LLM's te trainen die met Llama concurreren, en voegt een 700M-MAU-clausule toe. Als je een wrapped Llama als eigen product uitbrengt zonder hem te noemen, voldoe je niet aan de licentie die je accepteerde toen je de gewichten downloadde.

Waarschuwing

Een Llama-checkpoint pakken en als eigen product uitbrengen zonder de vereiste attributie is geen grijs gebied. Het is een licentiebreuk. De juridische teams van je enterprise-klanten weten dat, en zullen er uiteindelijk naar vragen.

Het eerste uur

We kwamen erin als hun fractional ML lead. Het telefoongesprek zat ergens tussen een bekentenis en een verzoek om dekking. Drie dingen moesten parallel gebeuren vóór de lunch.

Eén: de publieke repo privé maken en het Hugging Face-token dat de junior had gebruikt intrekken. Twee: een klantbericht schrijven, kort, feitelijk, zonder spin. Drie: bepalen welke architecturale waarheid het bedrijf vanaf nu schriftelijk zou verdedigen. Nummer drie was de moeilijke.

De eerste reactie van de CTO was dat de LoRA 'nog steeds eigen is, omdat de adapter-gewichten van ons zijn'. Dat argument is technisch correct en commercieel waardeloos. Een klant die €78.000 per jaar betaalt voor een 'Nederlandse juridische LLM' geeft er niet om of de 180M-parameter adapter origineel is. Hij geeft erom of hij kreeg wat beloofd was. Dat kreeg hij niet.

De vierstappen provenance-audit

We schreven dit de week erna uit als checklist voor ons eigen due-diligence-proces. We draaien hem nu op elk model waarvan een klant zegt dat hij het heeft getraind, en op elk model dat een klant overweegt te kopen. Eén engineer is er ongeveer drie uur mee bezig.

1. Hash de base-gewichten

Als een vendor je de modelbestanden geeft, is de goedkoopste check het SHA-256-hashen van de safetensors-shards en die vergelijken met de publieke Meta-, Mistral-, Qwen- en DeepSeek-releases. Als één shard matcht, kijk je naar een ongewijzigde base. Zo werd de Apeldoornse vendor ontmaskerd: niet door slimme interpretatie, maar door file hashing.

#!/usr/bin/env bash
# hash-shards.sh - dump SHA-256 for every safetensors shard
set -euo pipefail

MODEL_DIR="${1:?usage: hash-shards.sh /path/to/model}"

cd "$MODEL_DIR"
for f in *.safetensors; do
  sha256sum "$f"
done | sort

Draai dat tegen de release van de vendor, draai het dan tegen het publieke base model, en vergelijk. Als ze ook maar één shard delen, klopt de 'vanaf nul'-claim niet. De techniek werkt omdat de meeste teams die via LoRA fine-tunen, de base-shards helemaal niet wijzigen. De adapter is een apart bestand, by design.

2. Controleer de tokenizer

Tokenizers zijn de goedkoopste fingerprint. Een team dat een model vanaf nul trainde koos een tokenizer. Ze kunnen die keuze technisch uitleggen en je de statistieken van het training-corpus achter de vocabulaire laten zien. Een team dat een open base fine-tunede levert de upstream-tokenizer ongewijzigd mee. De hash van het tokenizer.json-bestand matcht exact die van de upstream-release.

from transformers import AutoTokenizer
import hashlib, json

def fingerprint(path: str) -> str:
    vocab = AutoTokenizer.from_pretrained(path).get_vocab()
    sorted_pairs = sorted(vocab.items(), key=lambda kv: kv[1])
    blob = json.dumps(sorted_pairs, ensure_ascii=False).encode()
    return hashlib.sha256(blob).hexdigest()

print("vendor:", fingerprint("./vendor-model"))
print("llama :", fingerprint("meta-llama/Llama-3.1-70B"))

Als die hashes matchen, trainde de vendor geen tokenizer. Dat alleen bewijst nog niet dat het model een derivaat is (sommige teams hergebruiken tokenizers bewust), maar samen met shard-hashes is het beslissend.

3. Vergelijk op een held-out evaluatie

Kies vijf prompts die obscuur genoeg zijn dat een ongewijzigde base ze op een herkenbaar 'Llama'- of 'Mistral'-manier zou beantwoorden: lang, voorzichtig, met dezelfde karakteristieke refusal-formuleringen. Draai daarna het model van de vendor op dezelfde prompts bij temperature 0. Als de antwoorden de stilistische vingerafdrukken van het upstream-model dragen (dezelfde openingsclausules, dezelfde safety-disclaimers, dezelfde hallucinatiepatronen op Nederlandse zaaknamen), heb je je tweede bewijsstuk. Een LoRA-adapter getraind op 8.000 documenten wist de stem van de base niet uit.

4. Lees de licentie-tree

Elk transitief opgenomen gewicht in een vendor-model heeft een licentie. Llama 3.1 valt onder de Meta Community License, met attributie, acceptable-use-regels en de MAU-clausule. Mistral heeft Apache 2.0 op de oudere releases en de Mistral Research License op andere. Qwen heeft eigen voorwaarden. De licensing van DeepSeek veranderde tweemaal in 2025. Als de vendor je niet schriftelijk kan vertellen welke licenties op welke delen van hun stack van toepassing zijn, hebben ze het werk niet gedaan.

Voor onze enterprise-klanten eisen we nu een ondertekende Model Bill of Materials bij elke inkoop: base model en versie, fine-tuning-methode, dataset-provenance en de exacte licentie-clausules waarop de vendor zich baseert. Het is één pagina. Het feit dat erom vragen de kandidaten-shortlist halveert, is op zich al informatief.

Wat de vendor daarna deed

Ze schreven het bericht. Het ging dezelfde middag de deur uit. De versie die we na twee herwerkingen verstuurden zei: 'Het base model in ons product is Meta Llama 3.1 70B, gebruikt onder de Llama 3.1 Community License. Onze fine-tuning-adapter en Nederlands juridisch trainingscorpus zijn ons eigendom. We hebben onze productpagina en documentatie aangepast om dit te weerspiegelen.'

Twee van de vier advocatenkantoren accepteerden dat bericht als voldoende. Eén vroeg om een korting en kreeg 30%. Eén beëindigde het contract binnen negentig dagen. De totale commerciële schade lag rond €310.000 aan misgelopen ARR plus juridische kosten, tegenover een product dat technisch werkte. De schade kwam bijna volledig uit het gat tussen wat was beloofd en wat er werd geleverd, niet uit de LoRA-op-Llama-architectuur zelf. Een vendor die vanaf dag één zegt 'we fine-tunen Llama 3.1 voor Nederlands juridisch werk en dit is het corpus dat we gebruiken' heeft een verdedigbaar bedrijf. Een vendor die het verbergt heeft een perscyclus.

Wat we in ons eigen proces wijzigden

We doen modelwerk voor klanten in twee modi: we bouwen agents bovenop het foundation model van iemand anders, en we evalueren vendors waarvan de klant overweegt te kopen. Na dit incident voerden we drie wijzigingen door.

Eén: de vierstappen-audit hierboven is nu onderdeel van elke vendor-evaluatie die we doen. Hij is ook onderdeel van onze eigen interne pre-flight voordat we een modelclaim in klantdocumentatie zetten. Als we 'getraind op' opschrijven, moeten we het onder hash-inspectie kunnen verdedigen.

Twee: we eisen een schriftelijke Model Bill of Materials van elke sub-vendor voordat we hun model in een klantproduct integreren. Het template is kort. Als een vendor er geen kan leveren, is dat op zich al een antwoord.

Drie: op Hugging Face behandelen we elke push naar een publieke organisatie als een deploy. Protected branches, verplichte reviewers, geen service tokens met schrijfrechten op een developer-laptop. Het Apeldoornse incident was, in de kern, een deploy-to-prod-ongeluk waarbij modelgewichten de rol van credentials speelden. De fix is saai: branch protection, scoped tokens, een CI-check die weigert iets boven 1 GB te pushen zonder expliciete flag.

De korte versie

Als een vendor claimt een model getraind te hebben, is de goedkoopste manier om dat te verifiëren het hashen van de gewichten. De op één na goedkoopste is het hashen van de tokenizer. De derde is het licentiebestand lezen. De vierde is hen schriftelijk vragen welk base model en welke versie ze fine-tunede. Samen kosten ze een middag. Ze vangen het meeste op van wat momenteel als 'eigen' wordt verkocht in de Europese AI-vendormarkt.

Toen we het terugdraaiwerk voor de Apeldoornse vendor deden, herschreven we hun klantgerichte modeldocumentatie en bouwden we het inkoopverhaal opnieuw op dat ze eerlijk konden verdedigen tegenover de general counsel van een advocatenkantoor. Die herschrijving is het soort werk dat we doen als onderdeel van onze AI-agents en modelwerk: geen modellen verkopen, maar zorgen dat de modellen waarvan een bedrijf afhankelijk is, accuraat genoeg worden beschreven om een auditor met een hash-commando te overleven.

Het kleinste dat je vandaag kunt doen: draai sha256sum op de grootste safetensors-shard die je interne of vendor-geleverde model meelevert, en vergelijk hem met de upstream open releases op Hugging Face. Als hij matcht, heb je een gesprek te voeren voordat iemand anders het voor je voert.

Kern

Als een vendor zegt een LLM getraind te hebben, hash de safetensors-shards voordat je het contract tekent. Het vangt het meeste op van wat vandaag als 'eigen' wordt verkocht.

FAQ

Wat is een LoRA-adapter?

Een kleine set trainbare gewichten, vaak 0,1 tot 1% van het base model, die het gedrag aanpast zonder de base te wijzigen. Goedkoop te trainen, goedkoop te leveren, makkelijk verkeerd als 'eigen' te verkopen als je de base verbergt.

Mag je Llama 3.1 fine-tunen en het resultaat verkopen?

Ja, onder de Meta Community License, maar je moet de 'Built with Llama'-attributie tonen en het acceptable-use-beleid volgen. Het base model verbergen is een breuk van de licentie die je hebt geaccepteerd.

Kan hashen écht bewijzen dat een model afgeleid is?

Het kan bewijzen dat de base-gewichten ongewijzigde kopieën zijn van een publieke release. Samen met een matchende tokenizer-hash is het beslissend bewijs dat er niet vanaf nul is getraind.

Hoe lang duurt de provenance-audit?

Voor één engineer met shard-toegang ongeveer drie uur. Zonder shard-toegang (API-only vendor) leunt het op tokenizer-fingerprints en gedragstests, en duurt het dichter bij een dag.

ai agentsarchitecturestrategyoperationscase studybusiness

Iets bouwen?

Start een project