Jeff: Fine-tunes van Qwen3.5 en Gemma 4 voor zero-shot classificatie

Met "zero-shot" wordt bedoeld dat de opties alles kunnen zijn: support-wachtrijen, gebruikersintenties, moderatielabels, spraakcommando's of spelzetten. De categorieën hoeven niet in de trainingsdata voor te komen; je beschrijft ze, en Jeff maakt de keuze.

Wat het is, en wat het niet is

Dit zijn zeer kleine modellen. Ze maken extreem snelle, goed gekalibreerde oordelen tussen opties en zijn eenvoudig in lokale code te implementeren. In benchmarks benaderen ze, en verslaan ze soms, Jev. Vanwege hun omvang kan hun redeneervermogen echter niet tippen aan dat van Jev, dat op een veel groter model draait.

Als zero-shot nauwkeurigheid onvoldoende is voor specifieke doeleinden, kan een korte fine-tune op eigen voorbeelden een groot verschil maken. Een fine-tune voor spraaknavigatie verhoogde de held-out nauwkeurigheid bijvoorbeeld van 31,7% naar 95,8% in minder dan een half uur op één GPU.

Ontwikkeling en Hardware

Het project is volledig gebouwd op lokale hardware:

  • Training: Uitgevoerd op één RTX PRO 6000 workstation GPU (de 0.8B-versie traint in ongeveer 2 uur, de 2B-versie in ongeveer 3,5 uur).
  • Data: Alle synthetische trainingsdata zijn geschreven door een open model (Qwen3.8-Flash-Next) op twee DGX Sparks.
  • Testen: Uitgevoerd op een MacBook.

Er zijn geen cloud-GPU's gebruikt en er zit geen output van gesloten modellen in de trainingsdata; een gesloten model is uitsluitend gebruikt om de kwaliteit van een steekproef van de synthetische data te controleren.

Onafhankelijkheid

Jeff is een onafhankelijk project. Hoewel het hetzelfde aanvraagformaat gebruikt als Jev, is het niet gelieerd aan of onderschreven door TypeSafe, de makers van Jev. De trainingscode is gebaseerd op het open-source AutoJev-recept.

Modellen op Hugging Face

  • Jeff-Qwen3.5-0.8B
  • Jeff-Qwen3.5-2B
  • Jeff-Gemma4-E2B

Snelstart

uv sync
uv run hf download mstrasser/Jeff-Qwen3.5-0.8B --local-dir checkpoints/jeff-0.8b

# NVIDIA GPU of CPU (PyTorch)
JEFF_CHECKPOINT=checkpoints/jeff-0.8b PORT=8765 uv run jeff-serve

# Apple silicon (MLX, veel sneller op een Mac; alleen voor Qwen-modellen)
uv sync --extra mac
JEFF_BACKEND=mlx JEFF_CHECKPOINT=checkpoints/jeff-0.8b PORT=8765 uv run jeff-serve

Voorbeeld van een aanvraag via curl:

curl -s localhost:8765/v1/systemone -H 'content-type: application/json' -d '{
"model": "jeff-latest",
"state": "Refund request: the customer says the parcel arrived crushed and wants their money back.",
"questions": {
"route": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"1": "Refunds and payments", "2": "Damaged or lost parcels", "3": "Account and login problems"}},
"angry": {"type": "noul", "instructions": "Is the customer angry?"}
}
}'

Elk antwoord bevat een waarschijnlijkheid per optie, de gekozen optie en een betrouwbaarheidsscore. Er zijn drie vraagtypen:

  1. choice: kies één uit maximaal 255 opties.
  2. noul: ja/nee, teruggegeven als een waarschijnlijkheid.
  3. score: een punt op een schaal die door de gebruiker wordt beschreven.

Verschillende onafhankelijke vragen in één verzoek worden gezamenlijk beantwoord.

Benchmarks

Testresultaten gebaseerd op 4.599 vragen uit vijf publieke benchmarks, plus de publieke hard tier van JevBench (105 items, apart gescoord).

BenchmarkQwen3.5-0.8B (ontraind)Jeff-Qwen3.5-0.8BQwen3.5-2B (ontraind)Jeff-Qwen3.5-2BGemma 4 E2B (ontraind)Jeff-Gemma4-E2BJev (gepubliceerd)AutoJev-27B (gepubliceerd)
Overall (5 benchmarks)45.379.146.583.162.581.683.084.9
BBH39.564.046.068.051.366.494.382.8
Financial PhraseBank36.096.453.496.386.096.177.084.2
JudgeBench56.662.657.464.646.960.678.678.9
RAGTruth49.186.135.988.963.887.477.388.9
WinoGrande49.268.652.279.051.077.490.783.3
JevBench hard (apart)36.247.645.753.341.048.673.370.3
  • Vetgedrukt: De winnaar tussen Jeff en Jev per rij.
  • Vetcursief: AutoJev-27B wanneer dit het beste model in de rij is (op RAGTruth gelijk aan Jeff-Qwen3.5-2B).
  • De gepubliceerde Jev- en AutoJev-cijfers zijn gemeten op een andere steekproef van dezelfde benchmarks.
  • Jeff's totale score komt voort uit classificatie en grounding, waar het grote modellen matcht of verslaat. Bij benchmarks die zwaar leunen op redeneren (BBH, JudgeBench, JevBench) blijft Jeff, zoals verwacht bij deze omvang, ruim onder deze modellen.

Games: Een zero-shot test

Om de zero-shot prestaties te testen op taken die niet in de benchmarks voorkomen, heeft Jeff drie spellen gespeeld. Hoewel spelstaten geen typische ongestructureerde data zijn, is dit een veelgebruikte manier om een "Systeem 1"-model te testen. Per beurt beschrijft de code de situatie en de legale zetten in woorden, waarna het model een keuze maakt. De opties beschrijven waar een zet toe leidt (bijv. Frogger: "je wordt geraakt door een auto en verliest een leven"), maar nooit welke zet correct is. Resultaten zijn gebaseerd op 20 episodes (seed 1234).

Prestaties van Jeff-Qwen3.5-0.8B (zero-shot):

ModelDoom (kills)Frogger (oversteken)Pac-Man (pellets van 98)
Willekeurige zetten−0.05011.2
Hand-coded rule bot6.5510.2594.1
Qwen3.5-0.8B (ontraind)5.01.025.8
Jeff-Qwen3.5-0.8B6.5510.357.0
Qwen3.5-2B (ontraind)0.550.0572.1
Jeff-Qwen3.5-2B−0.96.041.2
Gemma 4 E2B (ontraind)−0.5503.2
Jeff-Gemma4-E2B0.550.1553.2
Jev (gepubliceerd, Doom)6.55 (met regel) / −0.60 (zonder)——

Jeff-0.8B beslist in 29–49 ms per zet op een M4 Max; de gepubliceerde Doom-run van Jev duurde 212 ms per aanroep via de API.

Om zelf te spelen:

uv sync --extra games
uv run python -m jeff.games --game doom --player jeff --criteria situation --url http://127.0.0.1:8765 --video --out runs/games/doom.json
uv run python -m jeff.games --game frogger --player jeff --criteria outcomes --url http://127.0.0.1:8765 --out runs/games/frogger.json
uv run python -m jeff.games --game pacman --player rule --out runs/games/pacman-rule.json

Snelheid en omvang

Mediane tijd per beslissing over 200 benchmarkvragen (ongeveer 200 input-tokens per stuk), één vraag per keer, van ruwe tekst naar waarschijnlijkheden:

ModelParametersGewichten (16-bit)NVIDIA RTX PRO 6000Apple M4 Max (MLX)CPU (32 threads)
Jeff-Qwen3.5-0.8B0.8B1.7 GB22 ms28 ms463 ms
Jeff-Qwen3.5-2B2B4.2 GB24 ms60 ms708 ms
Jeff-Gemma4-E2B2B eff. (4.6B opgeslagen)9.3 GB29 ms— (alleen Qwen)1.0 s
AutoJev-27B27B~54 GBniet gepubliceerd——
Jevniet bekendAPI only114–212 ms (incl. netwerk)——

Tips voor optimaal gebruik

  • Redeneer in code, beslis met Jeff. Het is een classifier, geen planner. Beschrijf waar een optie toe leidt ("deze zet zorgt dat je geraakt wordt door een auto"). Als het model gevraagd wordt om te voorspellen ("er komt over 2 beurten een auto"), presteert het niet beter dan willekeurig.
  • Woordkeuze is cruciaal. Beschrijf opties consistent. Bij Frogger zorgde het consistent maken van de doeloptie ten opzichte van andere voorwaartse opties ervoor dat het aantal oversteken steeg van 15 naar 23 in één episode.
  • Gebruik korte optiesleutels en beschrijvende tekst: Gebruik {"1": "Engagement letter"} in plaats van lange ID's, die tijd kosten en niets toevoegen.
  • Bundel vragen. Stel meerdere onafhankelijke vragen in één verzoek.
  • Fine-tune indien zero-shot onvoldoende is. Een fine-tune voor spraaknavigatie op ~11k app-specifieke voorbeelden duurde ongeveer een half uur op één GPU en verhoogde de nauwkeurigheid van 31,7% naar 95,8%.
  • Kies de juiste omvang. Voor snel kiezen is de 0.8B-versie het meest optimaal. De 2B-versie is voorzichtiger en presteert in de spellen slechter, ondanks hogere benchmarkscores.

Zelf trainen

uv run autojev-mix ...          # bouw de trainingsset (publieke data, synthetische data, lekfilter)
scripts/train.sh RUN data/mix/public.jsonl data/mix 5e-6 40 Qwen/Qwen3.5-0.8B <revision> --epochs 1
uv run autojev-evaluate --data data/panel.jsonl --local --checkpoint checkpoints/RUN/selected --output runs/eval/RUN.json

De volledige pijplijn (synthetische data van een lokale teacher, lekfilter, learning-rate sweeps, dashboard) staat beschreven in scripts/train_all.sh, en elke trainingsbron met licentie in docs/data-sources.md.

Trainingsrecept: Full-weight fine-tuning, één epoch, batches van 256, cross-entropy over de optieletters, gevolgd door één passende temperatuur voor kalibratie. Checkpoints worden gekozen op een ontwikkelset, nooit op het benchmarkpanel. Minstens de helft van elke trainingsfamilie volgt de layout-conventies van het panel (alleen formaten; geen enkel panel-item is ooit gebruikt voor training).

Kanttekeningen

  • Kleine modellen redeneren niet. Verwacht snelle, gekalibreerde keuzes tussen beschreven opties, geen multi-step redenering. Dit geldt voor elk model van 0.8B–2B parameters, niet alleen voor Jeff.
  • Jeff-2B is een zwakkere speler. De ongetrainde 2B-versie lijkt al risico-averser dan de 0.8B-versie, en training lijkt dit te hebben verergerd. Dit vereist verder onderzoek.
  • Benchmarks voorspellen geen gameplay. De ongetrainde Gemma 4 E2B verslaat de ongetrainde Qwen-modellen in benchmarks, maar presteert het slechtst in spellen: vaak correct, maar niet betrouwbaar. Training verbeterde Pac-Man (3.2 → 53.2 pellets), maar niet Doom of Frogger.
  • Prompts zijn bepalend. De eigen Doom-prompt van Jev (een ruw peilgetal plus een richtregel) werkt niet voor onze modellen; opties die gevolgen in woorden beschrijven wel.
  • Alleen Engels en tekst.

Geschiedenis

Jeff begon als een fork van AutoJev door Denis Yarats (MIT-licentie), een open recept dat Qwen3.8-27B fine-tunt om Jev-stijl beslissingen terug te geven. Het kernontwerp is behouden (één forward pass per beslissing, een getrainde antwoord-readout, een passende temperatuur voor kalibratie), maar uitgebreid met: kleine student-modellen (0.8B en 2B Qwen, Gemma 4 E2B), een lokale synthetische-data pijplijn met lekfilter, prompt-layouts voor domein-fine-tunes, MLX-serving op Apple silicon, game-tests en een trainingsdashboard.

Licenties

  • Code: MIT (inclusief AutoJev).
  • Modelgewichten: Apache 2.0.
  • Doom harness: Aangepast van jev-plays-doom (MIT).
  • Trainingsdata: Zie de dataset card; elke bron behoudt zijn eigen licentie en is vermeld in docs/data-sources.md. De gewichten en code worden vrijgegeven, niet de trainingsdata (sommige bronnen zijn share-alike CC BY-SA).