Data Woordenboek

Non-determinisme (LLM-output)

Wat is non-determinisme bij LLM-output?

Non-determinisme wil zeggen dat dezelfde input niet betrouwbaar dezelfde output geeft. Stuur twee keer exact dezelfde prompt naar een large language model, met exact dezelfde instellingen, en je krijgt perfect twee verschillende antwoorden terug. Er is niets stuk. Zo werkt het systeem gewoon.

Een deel van die variatie is bewust ingebouwd. Het model geeft elke mogelijke volgende token een score, en een sampling-stap kiest er eentje uit die verdeling. Twee instellingen sturen die keuze: temperature, dat de verdeling scherper of vlakker maakt, en top_p, dat de staart afknipt. Zet je de willekeur lager, dan krijg je minder variatie.

Het andere deel is helemaal niet bewust, en net dat verrast de meeste teams. Het komt van de hardware waarop het model draait en niet van je instellingen, en er bestaat geen parameter om het af te zetten.

Waarom temperature 0 geen garantie is

Bij temperature 0 valt sampling terug op greedy decoding: bij elke stap neemt het model de token met de hoogste score. Er wordt niet meer gedobbeld, dus in theorie ligt het antwoord vast. De leveranciers zeggen zelf van niet. In de API-documentatie van Anthropic staat dat de resultaten ook bij een temperature van 0.0 niet volledig deterministisch zijn.

De eerste reden is rekenwerk. Optellen in floating point is niet associatief: (a + b) + c en a + (b + c) verschillen soms in de laatste bits. Een GPU verdeelt zo'n grote som over veel threads tegelijk, en de volgorde waarin die deelresultaten samenkomen bepaalt die laatste bits. Meestal merk je daar niets van. Maar liggen twee kandidaat-tokens qua score dicht bij elkaar, dan kantelt het welke van de twee wint, en vanaf die token lopen de twee antwoorden uit elkaar.

De tweede reden zit daaronder: de batch. Een gehost model bedient veel klanten tegelijk, en jouw call wordt samen verwerkt met wat er op dat moment toevallig binnenkomt. Onderzoek van Thinking Machines Lab legt de vinger daar op de wonde. De kernels voor matrixvermenigvuldiging, normalisatie en attention zijn niet batch-invariant, waardoor dezelfde call in een batch van vier andere getallen oplevert dan in een batch van veertig. Hoe druk de server het heeft, staat nergens in jouw request, en toch bepaalt het mee wat je terugkrijgt.

Hun meting blijft goed hangen. Duizend keer dezelfde vraag aan één open model, op temperature 0, gaf 80 verschillende antwoorden, en het eerste verschil dook op rond de honderdste token. Korte antwoorden ogen dus vaak stabiel. Lange antwoorden lopen weg.

Wat een seed wel en niet oplost

OpenAI en Azure OpenAI kennen een seed-parameter. Geef hetzelfde getal mee bij dezelfde prompt en dezelfde instellingen, en de dienst doet een best effort om deterministisch te samplen. Niet elke leverancier heeft er een: de Messages-API van Anthropic werkt zonder seed.

Best effort is het sleutelwoord, en de leveranciers zijn daar eerlijk over. Microsoft schrijft in de documentatie van Azure OpenAI dat determinisme niet gegarandeerd is, dat je nog altijd variatie ziet zelfs als de seed en de system_fingerprint gelijk blijven, en dat langere antwoorden doorgaans minder stabiel zijn dan korte. Dat veld system_fingerprint bestaat net om te zien wanneer de configuratie achter de schermen veranderd is.

Het voorbeeld in die documentatie toont meteen de grens. Drie calls met seed=42, temperature 0,7 en een limiet van 50 tokens gaven twee identieke verhaaltjes en een derde dat één zin lang meeliep en daarna zijn eigen weg ging.

Een LLM-call naast een SQL-query

Dit is de kantelbeweging die telt voor iedereen die uit de rapporteringswereld komt. Draai een SQL-query op een tabel die niet veranderd is en je krijgt dezelfde rijen terug, vandaag en volgende week dinsdag. Net die eigenschap maakt een reconciliatie mogelijk: verschuift het cijfer, dan is ofwel de data veranderd ofwel de query, en allebei kan je nakijken.

Een LLM-call gooit die zekerheid overboord. De output kan verschuiven terwijl de prompt, het model en de data alle drie stilstonden. De vraag "waarom staat hier iets anders dan vorige week?" heeft dan geen proper antwoord meer, en "kan je aantonen wat het systeem op 3 maart heeft gezegd?" evenmin.

Het breekt ook je gewone test. Een test die de output letterlijk vergelijkt met één juist antwoord slaagt bij de eerste run en faalt bij de vijfde, zonder dat die fout je iets leert. Daarom scoren evals een band van aanvaardbaar gedrag in plaats van te controleren op één exacte tekst.

Waar moet je op letten als een LLM in je pipeline zit

  • Hou het model weg van het cijfer zelf. Laat een LLM classificeren, extraheren of een tekst voorstellen, en laat gewone code optellen en groeperen. Een totaal dat bij elke refresh opnieuw door een model berekend wordt, valt niet te reconciliëren.

  • Log de volledige call, niet enkel het antwoord. Prompt, modelversie, parameters, de seed als je er een meegaf, de system_fingerprint als je die terugkrijgt, en de ruwe respons. Zonder dat logboek kan je achteraf niets reconstrueren, en een audit trail die stopt bij het antwoord houdt geen ernstige vraag tegen.

  • Leg de vorm van de output vast. Vraag een waarde uit een vaste lijst, of JSON tegen een schema. Verschillen in formulering wegen veel minder zwaar zodra het veld dat in je warehouse belandt maar zes waarden kan aannemen.

  • Test op verdelingen in plaats van op één run. Draai dezelfde casus vijftig keer en kijk in hoeveel procent van de gevallen het antwoord bruikbaar is. Eén groene run bewijst weinig.

  • Verwacht stille wijzigingen aan de kant van de leverancier. Een provider kan zijn serving-stack aanpassen zonder de modelnaam te wijzigen. Pin versies waar de API dat toelaat, en draai je evals opnieuw zodra de fingerprint verandert.

Laatst Bijgewerkt: July 20, 2026 Terug naar Woordenboek
Trefwoorden
non-determinisme reproduceerbaarheid temperature seed sampling large language model llm tokens gpu evals sql generatieve ai