
Maar wacht eens even
Hoe weet ik eigenlijk of de output, mijn nieuwe database-diagram, wel klopt? AI, of meer specifiek LLM’s, zijn ongelooflijk handig en krachtig, maar ze zijn niet 100% betrouwbaar. Iedereen heeft vast wel inmiddels de term ‘AI-hallucinaties’ gehoord. Dus hoe betrouwbaar is mijn database diagram nu eigenlijk? Kan ik echt een LLM voor dit soort taken gebruiken?
Een hallucinatie verificatie experiment
Ik was nieuwsgierig geworden naar deze vraag: hoe groot is de kans op hallucinaties bij mijn specifieke taak? Dus ik besloot een experiment te gaan coderen (inmiddels was ik qua tijd al ruim over mijn oorspronkelijke database-diagram urenschatting heen natuurlijk).
Via ons Hydrazine Framework genereerde ik snel een Job, waarin ik vanuit de CLI eenvoudig mijn code kon aanroepen. Ik maakte een instance aan van onze ChatGPT-APIClient, vulde een bericht met bovenstaande wizard database-diagrammen en vroeg in mijn query aan ChatGPT om deze om te zetten van snake_case naar PascalCase.
Zoals verwacht, zag dit er (na een korte visuele inspectie) goed uit:

Ik voerde nog wat aanroepen uit, maar bij de vierde aanroep gebeurde er iets onverwachts: Ik zag output die NIET correct was!

Ok, zo dramatisch was het nou ook weer niet
Dat was een hele interessante (en belangrijk) observatie: deze taak kan dus toch fout gaan.
En zelfs veel eerder dan ik had verwacht.
Van Vergissing naar Vergelijking
Ik ontdekte dat deze API-call het inmiddels verouderde gpt-3.5-turbo model aanriep. Dat verklaarde dit onverwachte resultaat!
Ik stond op het punt dit model te veranderen naar hetzelfde model als die van mijn ChatGPT chat-sessie waar ik mijn oorspronkelijke vraag stelde (GPT 4o), maar bedacht me toen dat dit eigenlijk naar een interessanter experiment kan leiden: hoe groot is het verschil tussen de verschillende LLM modellen? En dan niet alleen die van OpenAI, maar bijvoorbeeld ook de open modellen, zoals Llama en Gemma.
Hiervoor is een provider als Groq erg fijn: deze geeft enorm snelle responses terug en biedt een groot aantal verschillende modellen. Ik voegde ook onze APIClient voor Groq toe aan mijn code, en begon met het testen van de modellen.
Let op: Verwar Groq niet met Grok. Grok is een chatbot ontwikkeld door xAI (van Elon Musk), Groq is een bedrijf dat een AI-versnellingschip en een high-speed LLM-inferentieplatform heeft ontwikkeld, gericht op extreem lage latency en hoge prestaties.
Gemma
Vorig jaar in juni (2024) kwam de tweede versie van Gemma uit. Dit is een open-gewichten (open-weights) model, gemaakt door Google.
Een open-weights model houdt in dat je het model als geheel kunt downloaden en precies kunt zien uit welke waardes deze is opgebouwd. Meestal via de website Hugging Face. Na het downloaden van zo'n model is het mogelijk om deze lokaal op je eigen computer (of bijvoorbeeld tablet of telefoon of een eigen server) in te laden en te gebruiken. Hier is dan geen internet verbinding meer voor nodig. Op deze manier een LLM draaien is bijvoorbeeld met de modellen van OpenAI niet mogelijk - omdat deze geheim gehouden worden.
Modellen komen in allerlei maten. Er zijn bijvoorbeeld 2 variaties van het Gemma 2 model, namelijk: 9B en 27B. Deze aanduiding refereert naar het aantal parameters van het model (uitgedrukt in billions, dus miljarden). De parameters van een model bepalen hoe input wordt omgezet naar output - hoe meer het er zijn, hoe 'slimmer' een model over het algemeen is. Maar tegelijkertijd: hoe minder parameters een model heeft, hoe minder geheugen (meestal op een videokaart) het model in beslag neemt en nodig heeft om uitgevoerd te worden.
Gemma 2 werd door Google aangekondigd als een model dat binnen zijn 'grootte/maat' (dus binnen het aantal parameters van het model) als beste naar voren kwam - en het zelfs goed kon concurreren met modellen die 2 keer zo groot waren.
De LLM provider Groq biedt gemma2-9b-it aan. Dit is de kleinste versie van het Gemma2-model, met ongeveer 9 miljard (9 billion) parameters. Hoeveel geheugen het exact nodig heeft is afhankelijk van de 'precisie' van de parameters. Het is mogelijk om deze te reduceren, zodat een model minder geheugen nodig heeft. Dit proces heet kwantisatie (quantization). Hierdoor worden de resultaten die een LLM levert ook slechter, maar de daadwerklijke impact die kwantisatie heeft op de resultaten verschilt per model - het ene model is gevoeliger voor kwantisatie dan het andere. Zoals met veel dingen binnen de ICT is alles weer een afweging. In dit geval vereist deze versie van het model 18.6 GB (V)RAM.
Voor consumenten is deze hoeveelheid VRAM vaak nog net buiten bereik. Er zijn enkele videokaarten (4090, 5090), waar dit in zou passen, maar de meeste videokaarten zitten hier net onder. 16GB VRAM is de hoeveelheid die je terug ziet komen in de meeste videokaarten.
Prompten met Gemma
Ik vond dit een mooi model om mee te beginnen: het model was (toen ik bezig was met het uitvoeren van mijn experiment) alweer 8 maanden oud, en het is een vrij klein (lightweight) model.
Het leek me interessant om te kunnen bepalen vanaf welk punt het mogelijk werd voor LLM's om mijn taak uit te voeren. Een goed startpunt, want zo'n klein (en oud) model als dit gaat natuurlijk keihard falen!
Ik schreef mijn prompt, samen met wat simpele code om te testen of ik de juiste response terugkreeg van OpenAI, en liet toen mijn job draaien vanaf mijn terminal.

Maar er gebeurde iets vreemds: Mijn eerste 4 runs gaven geen melding. Dit betekent dat mijn test-framework vond dat de output van Gemma2 overeen kwam met wat correct was. Dit resultaat was voor mij dusdanig onverwacht dat ik ging controleren of mijn test-code wel echt correct was, en ik deed nog een visuele inspectie:

Maar het klopte echt! Dit enorm kleine modelletje (zeker vergeleken met een OpenAI model; ik vermoed dat dit model wel 40 keer 'past' in een OpenAI-model) was al in staat om mijn verzoek correct af te handelen.
Gelukkig ging het de 5de keer eindelijk fout. De output was niet helemaal zoals verwacht. Wat had Gemma fout gedaan? Het model had een fout gemaakt die ik hierna regelmatig terug zag komen:
Id Integer [primary key]
WizardId Integer
Zie je de fout? Alle integers waren omgezet naar Integers. Dat was natuurlijk niet de bedoeling, want een integer is geen veldnaam!
Niet bepaald een Gemmatigd succes
Vanwege dit onverwachte succesgehalte van Gemma, besloot ik nog niet direct door te gaan naar het volgende model. Ik wou eerst gaan uitzoeken of het mogelijk was om de output van Gemma te verbeteren (een mooi voorbeeld van scope creep).
LLMs zijn vreemde technologie. Misschien heeft dit te maken met de fase waarin deze technologie zich bevindt, maar vaak moeten we dingen doen die je niet verwacht. Een bekende variant hiervan is om tegen de LLM te zeggen: 'doe meer je best!', of 'dit is belangrijk!'.
Om diezelfde reden ging ik er eigenlijk wel vanuit dat met wat 'sleutelen' aan de prompt die ik naar Gemma stuurde de output waarschijnlijk ook wel verbeterd kan worden. Maar net als dat je niet verwacht dat 'doe beter je best!' zou werken, verwacht je niet dat 'geef integer geen hoofdletter' totaal geen effect lijkt te hebben. LLM's zijn mysterieus.
Uiteindelijk eindigde ik met dit als prompt:

Ik voerde daarna 100 keer mijn prompt uit. En de resultaten waren:
We passen een prompting techniek toe
Na wat sleutelen aan de prompt, besloot ik een 'example' mee te geven, omdat ik vaker had gelezen dat dit de output van LLM's kon verbeteren. Deze techniek noemen ze ook wel few-shot prompting (waarbij het niet meegeven van een voorbeeld zero-shot prompting is).
In de code 'simuleer' ik dit door een bericht van de LLM in de lijst van berichten toe te voegen, met daarin een 'juist' antwoord. Ik doe dus net alsof de LLM al een antwoord heeft gegeven, en vraag daarna om dit nog een keer te doen, met een ander diagram. Vanuit het 'perspectief' van de LLM geeft dit een hele sterke hint die invloed heeft op zijn 'next token prediction'. Je geeft het model een in-context leermoment.
Dat ziet er als volgt uit:
- Bericht 1: Mijn prompt, met instructies over het omzetten van een diagram.
- Bericht 2: Een voorbeeld diagram
- Bericht 3: Het 'gesimuleerde' bericht van de LLM, met het omgezette diagram
- Bericht 4: Mijn echte diagram
In de code zag dat er zo uit:

Na het toevoegen van dit voorbeeld aan mijn prompt was dit het nieuwe succes percentage:
En dat was het...? Doel bereikt?
Ja, eigenlijk had ik nu dus mijn doel al bereikt. Ik had een heel klein model gevonden, dat in staat is om deze taak te voldoen. Het laat ook zien dat het gebruiken van een ChatGPT-model dus waanzinnige 'overkill' is voor een taak als dit.
Ondanks dat ik mijn doel bereikt had, was ik eigenlijk nog niet klaar om hiermee te stoppen. Ik had nog meer modellen die ik wilde gaan testen. In het volgende artikel in deze reeks ga ik daarmee verder.