Vissza a blogra

Gemma4-et néztem, MTP-t találtam

Avagy: a DocAI JSON-KIE workload az MTP architekturális szerelme — 99% draft acceptance, és miért rejti ezt el a 72.5%-os globális szám

12 nappal ezelőtt írtam egy cikket arról, hogy a Qwen3.6 MTP a 16-concurrent stress teszten +24% throughput-ot adott — pont ott, ahol elméletileg semleges vagy negatív kellett volna legyen. Akkor azt mondtam, a magyarázat valószínűleg a GB10 unified memory architektúrája: az MTP draft verification kihasználatlan compute-ot tölt fel a memory-bandwidth-bound batchekben.

Ezúttal megjelent a Gemma4 modellcsalád, és gondoltam, gyorsan átfutok rajta. A DocAI-ban minden új modell-release-t át kell engedjek a candidate eval pipeline-on: méri a magyar KIE pontosságot, leméri a sebességet, és eldönti — leváltja-e a prod modelt vagy nem.

A válasz röviden: nem. A Gemma4 F1=0.890 a 34-dokumentumos KIE corpus-on, a Qwen3.6 ugyanezen F1=1.000. Single-stream decode 30-80%-kal lassabb mindenhol. A prod marad ahol van.

De ezzel még nem lenne cikk. A sztori az, hogy a sebesség-mérés mellékterméke felfedett valamit, ami az előző cikkből hiányzott: az MTP acceptance rate per-workload szinten drasztikusan eltér, és a JSON-KIE workloadon 99%. Az előző cikk 72.53%-os globális rate-je ezt teljesen elrejtette. A DocAI kanonikus workloadja — strukturált JSON kinyerés magyar számlákból — pontosan az a generation pattern, amire a multi-token prediction architekturálisan a legjobban illik.

Aki csak a végét akarja: ez nem szerencse, ez tervezhető. Részletek lent.

A setup

A spark-prod azóta is a Qwen3.6-35B-A3B-FP8-on fut, MTP-vel, ahogy az előző cikkben publikáltam. A production konfig egy apróságban változott: a max-model-len 131072-ről 262144-re emelve, és ezt a 256K kontextust 6.85× concurrency mellett tartja a 20.79 GiB-os KV pool. Egyébként ugyanaz: chunked prefill, prefix caching, fp8_e4m3 KV cache, MTP num_speculative_tokens=2.

A spark-dev — ami egyébként a Qwen3.5-122B-A10B-int4-AutoRound NVFP4 kísérletek otthona — most ad otthont a Gemma4 candidate eval-nek. Ugyanaz a hardver (DGX Spark, GB10 SM 12.1, 128 GB LPDDR5x), ugyanaz a vLLM verzió, ugyanaz a Docker stack. A Gemma4-et out-of-the-box az upstream vLLM build-tel indítottam, alapbeállításokkal — sem MTP, sem speculative decoding nincs hozzá (a model card sem említ ilyet, és nincs is qwen3_next_mtp-szerű draft head architektúra a Gemma4-ben).

Két dolgot kell megnézni:

  1. KIE pontosság — kinyer-e helyesen magyar számlákról adatot? F1 score 34 dokumentumon.
  2. Sebesség — single-stream decode tok/s 6 különböző workloadon (Q&A, Code, JSON-KIE, magyar próza, hosszú RAG 8K és 32K kontextuson).

A KIE eval harness-t most építem fel. Ennek a cikknek a tanulságait meg kell hogy ismételje minden jövőbeli candidate eval — Qwen3.7, Gemma5, vagy ami épp jön. Alapszabály: minden modellt ugyanazon a corpuszon, ugyanazon a sampling configgal, ugyanazon a prompt template-tel mérünk. A különbségeknek a modelltől kell jönnie, nem a környezettől.

A KIE eval harness

A corpus 40 magyar számla-dokumentumból áll, ebből 34 használható (6 stripped multimodal kép — ezeknek külön VL pipeline kellene, ami most nincs scope-ban). A doksik egy része egyszerű header-extraction (kelt, eladó, vevő, adószámok, összegek, fizetési mód), egy része tételesi kinyerés (__items subdir).

Mit mér a harness:

  • JSON validitás — minden modell kimenetét parse-olja, ha nem érvényes JSON, az eleve hiba
  • Field-level F1 — mezőnként összehasonlít GT-vel, számolja TP/FN/FP-t és mismatch-et
  • Latencia — subdir-szintű feldolgozási idő
  • Token számlálás — input és output token átlag

A string_strict típus szigorúan stringben hasonlít, a date_iso ISO formátumra normalizál, a number_strict numerikus toleranciát ad. Ami most még nincs: string_loose (case + whitespace tolerancia), string_normalized (Unicode + diacritic normalizáció). Ezek hiánya pont a Gemma4 hibák egy részénél fog számítani, ahogy mindjárt látjuk.

Két modell, ugyanazon a corpus-on:

qwen36-baseline → http://10.10.0.4:8355  (prod model, MTP-vel)
gemma4          → http://10.10.0.4:8355  (model_override flag)

Sampling: temperature=0.0, max_tokens=8192, enable_thinking=false. A prod konfig nem-thinking módban szolgál ki, a benchmark is így megy.

KIE eredmények

A teljes táblázat:

MetrikaQwen3.6Gemma4
Subdirs sikeres34 / 3434 / 34
JSON validitás100.0%100.0%
Overall F11.0000.890
Precision1.0000.888
Recall1.0000.892
TP / FN / FP / Mismatch214 / 0 / 0 / 0191 / 3 / 4 / 20
Latencia (avg)6687 ms10396 ms
Input tokens (avg)67345293
Output tokens (avg)343342

Egy érdekesség azonnal: a Gemma4 kevesebb input tokent eszik (5293 vs 6734) ugyanazon a corpus-on. Mégis lassabb. Ez azt jelenti, hogy a Gemma tokenizer hatékonyabban kódolja a magyar szöveget — kevesebb tokenre bontja —, de a decode lassabb. A tokenizer hatékonyság vs decode sebesség elkülönülése értékes mérőszám: ha valaki kontextus-méret-bound, a tokenizer-érzékenység egy cég hatása lehet, és ez a Gemma4 javára szól. De ha throughput a metrika, a Qwen3.6 nyer.

A latencia 1.55× — ez sok, de még nem a teljes kép. A latencia csak a single-document feldolgozási idő. Production-ben a 16-concurrent batch ezt teljesen átírná — és a Qwen3.6 ott (ahogy az előző cikkben mértem) kimagaslóan teljesít. Ezt nem futtattam most konkurensen, de a single-stream is bőven elegendő candidate-eval-szempontból: ha single-streamen ennyivel rosszabb, concurrent-ben nem javul majd át.

A 0.890 F1 nem rossz szám abszolút értelemben — a legtöbb publikus KIE benchmarkon ez tisztességes. De a Qwen3.6 1.000-ja ugyanezen a corpus-on. A delta fáj.

A 27 Gemma4 hiba anatómiája

A Gemma4 27 mismatch-et generált. Átfutva őket három kategóriába esnek szét.

Tényleges modell-hibák (~12 db)

Ezek igazán fájdalmasak. Itt a model rosszul olvasta vagy hallucinálta a mezőt:

  • doc77 partner_name: „Baranyai Kéményseprő-ipari Szolgáltató Kft.” → „Baranyai Kéményseprô-ipari Szolgáltató Kft.” A különbség az „ő” → „ô”. Ez magyar karakterkódolási botlás, ami egy magyar SME accounting-rendszerben kínos. NAV invoice-validációnál egy ilyen különbség elutasításhoz vezet.
  • doc84 partner_name: „MVM Next Energiakereskedelmi Zrt.” → „MVM Next Energetikai Zrt.” Két különböző cég. Ez hallucináció.
  • doc84 invoice_number: 846802113701 → 84680211. Csonkolás — a model a számla-számot nem olvasta végig.
  • doc84 total_vat_amount: 1990 → 1990.5. total_gross_amount: 9594 → 9594.5. Decimal-artefakt — a model fél forintokat talált ki.
  • doc109 payment_method: TRANSFER → CARD. Téves kategorizálás.
  • doc77 payment_date: 2025-07-10 → 2025-06-30. Más dátum.
  • doc94 payment_date: 2025-03-12 → null. Mező elveszett.
  • doc94 payment_method: TRANSFER → OTHER.
  • doc71 partner_person_name és partner_bank_account mindkettő nem lett kinyerve (fn).

Ezek a 12 hiba a 27-ből az igazán számító rész. A többi 15 vagy szisztematikus formázási különbség, vagy a comparator gyengesége.

Szisztematikus items-pattern (~11 db)

Ez érdekes. Minden __items subdir-en a Gemma4 F1=0.000-t kapott, ahol a Qwen 1.000-t. Ennek oka: a Gemma a tétel name mezőbe beletoldja a periódust/időszakot a prompt által nem kért módon:

MezőQwen / GTGemma
name„GitHub Copilot Usage”„GitHub Copilot Usage Feb 01, 2026 - Feb 28, 2026”
name„ChatGPT Plus Subscription”„ChatGPT Plus Subscription Aug 22 - Sep 22, 2025”
name„Premium plan”„Premium plan Core K3 Ipari Szoftverek 2 Year May...”

A string_strict comparator ezt 0-ra húzza. Vitatható, hogy ez „rossz” — információ-szempontból a Gemma többet ad, nem kevesebbet. De a DocAI pipeline-ban a kanonikus tétel-név kell, mert a downstream cikk-pairing erre épül, és NAV invoice szabványban a tétel name legfeljebb a megnevezés, nem a teljes leírás. Tehát production-szempontból ez hiba — csak nem azonos súlyú a „más cégnév” típusúakkal. Egy string_loose field-type bevezetésével a model kapna részleges pontot, de a production-i adatszabvány szempontjából a Qwen kanonikus formája az értékesebb.

GT- és comparator-gyengeségek (~4 db)

Itt a Gemma választása vitatható, de a comparator dönt szigorúan ellene:

  • doc109 partner_taxnumber: GT „13826701-2-41 / HU13826701” — kettő egy cellában! A Gemma az első variánst adta. A comparator nem ismeri az „any of” relációt.
  • doc94 partner_taxnumber: GT „10433748-2-44”, pred „HU10433748” — ugyanaz az adószám, két formátum (HU domestic vs EU VAT).
  • doc70 invoice_number: GT null, pred ch_3Rnky7JFr6CCHwIi1zOC13KU — ez egy Stripe charge ID, ami valid invoice referencia, csak nem ezt vártuk.
  • doc62/63/68 payment_method: GT null, pred „OTHER” — ha a GT szerint ismeretlen, és a model azt mondja „ismeretlen” (= OTHER), ez vitatható hogy fp-e.

Ha a comparator-ben ezt a 4 esetet kezelnénk (alternative format support, multi-value field, null-vs-OTHER tolerancia), a Gemma F1 ~0.92-re emelkedne. Még akkor is jelentősen rosszabb mint a Qwen 1.000. Az igazi 12 model-hiba marad, és ezek szisztematikus jellegűek (magyar karakter, hallucinált cégnév, csonkolt szám).

A Qwen3.6 ezt a 34-doc corpus-t hibátlanul vitte végig. Egyetlen hallucinált mező nincs, egyetlen ő/ô zavar nincs, egyetlen csonkolt szám nincs. Ez erős magyar nyelv-pretraining + erős instruction following.

A KIE-rész végeredménye: a Gemma4 az 1.000-ról 0.890-re viszi le a baseline-t, és ennek nagy része valódi model-pontosság-vesztés, nem csak comparator-zaj. Production-ban erre nem cserélünk.

A sebesség eredmények

Single-stream, decode tok/s, median 3 run:

WorkloadQwen3.6 + MTPGemma4Qwen előny
Q&A54.140.5+34%
Code69.740.1+74%
JSON-KIE69.440.0+74%
Magyar52.040.2+30%
Long-RAG-8K67.038.3+75%
Long-RAG-32K64.435.7+80%

Egy érdekes minta: a Gemma4 rendkívül stabil ~40 tok/s körül a rövid és közepes workloadokon, és csak a 32K kontextuson esik kicsit (35.7 tok/s). A Qwen3.6 viszont kétféle sebességet mutat: 52-54 tok/s a „free prose” workloadokon (Q&A, magyar) és 67-70 tok/s a strukturált workloadokon (Code, JSON-KIE, Long-RAG).

Mi okozza ezt a kettősséget? Erre a választ az MTP acceptance rate adja meg.

Az MTP meglepetés

Az accept= mezőt minden mért runhoz logolja a script — a vLLM /metrics endpointról húzza a vllm:spec_decode_num_accepted_tokens_total és _draft_tokens_total countereket, és a két snapshot közti differenciából számol acceptance rate-et. Ez a futás per-workload-acceptance-e:

WorkloadMTP AcceptanceDecode tok/sMegjegyzés
Q&A60.81%54.1Magyar nyitott kérdés
Code97.66%69.7Python függvény írása
JSON-KIE99.01%69.4Strukturált kinyerés
Magyar56.06%52.0Számviteli definíció próza
Long-RAG-8K90.71%67.0Kontextus-bound válasz
Long-RAG-32K89.33%64.4Kontextus-bound, hosszabb

És itt a sztori. A 99% acceptance a JSON-KIE-n nem mérési hiba — a Code 97.7%-a, a Long-RAG ~90%-a ugyanezt a mintázatot erősíti. A strukturált, determinisztikus output workloadokon a draft head szinte mindig eltalálja a következő tokent.

Az előző cikkben publikált 72.53%-os globális acceptance rate egy átlag, ami elrejti, hogy a workload pattern-je drasztikusan számít:

  • Szabad magyar/angol próza (Q&A, Magyar): 56-61%. Magas entrópia, sok valid folytatás. A draft head gyakran téved.
  • Strukturált programkód (Code): 97.7%. A szintaxis annyira korlátozza a következő token-teret (def , :, indent, return...), hogy a draft head szinte mindig eltalálja.
  • JSON kinyerés (JSON-KIE): 99.01%. Még inkább korlátozott. {"name": után string. , után key. A grammar szinte minden tokent kényszerít.
  • Long-context RAG (Long-RAG): 89-91%. A válasz a kontextusból derivál, ami magas előrejelezhetőséget ad — még szabadszövegben is a háttér-anyag korlátozza a generálást.

Ez azt jelenti, hogy a DocAI elsődleges workloadja — strukturált JSON kinyerés magyar számlákból — nem véletlenül érzi jól magát az MTP-vel. Ez az elméleti best case.

Mit jelent ez

Az előző cikkben a 16-concurrent stress teszt +24% throughput-ja meglepetés volt. Akkor azt írtam: „a memory-bandwidth-bound batchekben az MTP draft verification kihasználatlan compute-ot tölt ki”. Ez igaz — de hiányos. A teljes kép:

A vllm bench serve random promptok alapján méri, ami egy vegyes workload. A 72.5%-os acceptance erre jött ki. Egy igazi production DocAI workload-on, ahol a kérések 90%-a JSON kinyerés strukturált sémából, a tényleges acceptance 95%+ tartományban lesz. Ez azt jelenti, hogy a 16-concurrent +24% alulbecsülése a real-world DocAI gain-nek.

Mennyivel jobb? Nehéz pontosan kalkulálni a bench számokból, de egy back-of-envelope: ha a benchen 72.5% acceptance hozott +24%-ot, és a real workloadon 95%+ acceptance lenne, akkor a tényleges gain 30-35% felé csúszik. Ezt egyszer egy dedikált production-trace replay-jel le kell mérni — most nincs setup hozzá, jövő hónap, valószínűleg cikk lesz belőle.

A másik konklúzió: az MTP nem általános win. Ha a workloadod az itteni „Magyar próza” típus (chat-bot szabad magyar válaszokra), akkor a 56% acceptance-szel a nyereség sokkal kisebb. A Qwen3.6 vanilla és MTP között az 52 tok/s-os Q&A-n nincs nagy különbség (talán 5-7%-os edge). Ott más optimalizációk hoznak többet.

Egy döntési heurisztika cikkbe-anyagnak:

Workload típusVárható MTP acceptanceMTP érdemes
Strukturált output (JSON, XML, kód)95-99%Igen, nagy nyereség
Long-context RAG (válasz kontextusból)85-92%Igen, jó nyereség
Free Q&A, prose generation55-65%Marginális, érdemes mérni
Multi-turn dialog (sok variancia)?Mérés-függő

A DocAI workload az első kategóriában van. A prod konfig optimális, ezt erősíti meg ez a candidate eval. A Gemma4 nem váltja le, mert nincs MTP-ekvivalense, és a baseline decode-on is lassabb.

Egyéb megfigyelések

A Gemma4 sokkal bőbeszédűbb a Qwen3.6-nál ugyanazon promptra:

WorkloadQwen3.6 out_tokGemma4 out_tokMegjegyzés
Q&A164256Gemma a max-token-ig megy
Code190512Gemma a teljes max-tokent kihasználja
JSON-KIE301303itt egybe esnek
Magyar490381Qwen hosszabb
Long-RAG-8K196177hasonló
Long-RAG-32K208185hasonló

A „Code” feladat — Write a Python function that performs binary search — Qwen-en 190 tokenes válaszhoz vezet. Gemma4 a teljes 512 tokent kihasználja. Vagy dupla példákat ad, vagy hosszabb magyarázatot, vagy bóbiskoló önmagát produkál. Ez instruction-following kvalitás — a Qwen tudja, mikor kész egy feladat. A Gemma „amíg jut max-token, megyek tovább” mintát mutat.

A throughput számok ezért enyhén szólva nem 1:1 hasonlíthatók — egy hosszabb output több időt vesz, és a Gemma4 itt stagger fix sebességet tart, miközben a Qwen3.6 hamarabb leáll. Production-szempontból a rövidebb-de-pontos preferált, mert a downstream pipeline így kevesebb tokenből dolgozik.

A Gemma4 input tokenizer-hatékonysága viszont jobb: a 34-doc corpus átlag input 5293 vs 6734 token. Ez ~21% kevesebb token ugyanahhoz a tartalomhoz. Ha kontextus-méret-bound vagy (hosszú dokumentum, KV cache nyomás), a Gemma tokenizer kedvezőbb. Ezt érdemes beletenni a „tokenizer efficiency” tab-ba a következő eval körre.

A TTFT, ahol fair

Csak Qwen3.6, friss cold prefill (nonce-szal):

WorkloadTTFTMegjegyzés
Q&A (~50 in)0.13srövid prompt, MTP overhead
Code (~50 in)0.13sugyanaz
JSON-KIE (~150 in)0.20sstructured prompt
Magyar (~30 in)0.14srövid magyar prompt
Long-RAG-8K0.55s8K context cold prefill
Long-RAG-32K1.18s32K context cold prefill

A 32K cold prefill 1.18s-os mérése a GB10-en konzisztens a korábbi production benchmarkkal — kb. 27K tok/s prefill throughput. A 8K-n az effektív arány hasonló. Ezek a számok jövőbeli candidate eval-ek baseline-ja lesznek.

Tanulságok

Hét tanulság, fontossági sorrendben:

1. Az MTP acceptance rate workload-szinten gondolkodj

A globális 72.5%-os átlag elrejti, hogy strukturált output workloadon 99%, magyar prózán 56%. Az MTP-t a workloadod legfontosabb mintázatára kell mérni, nem egy benchmark-mixen. Ha JSON-t generálsz, az MTP majdnem ingyen extra throughput. Ha magyar chat-bot vagy, marginális.

2. A DocAI workload az MTP best case-e

Ez nem véletlen, és nem szerencse. A strukturált JSON kinyerés a draft head számára a leginkább predikálható mintázat — minden token a grammar által korlátozott. A Qwen3.6 + MTP + DocAI workload kombináció architekturális szimbiózis.

3. A prefix caching benchmarkot megöli — kapcsold ki vagy busteld

A vLLM --enable-prefix-caching production-ben jó dolog, de benchmarken minden ismétlődő prompt cache hit lesz, és a TTFT mérés értelmét veszti. Vagy állítsd le a szervert és indítsd újra --no-enable-prefix-caching-gal, vagy adj egy 8-hex-karakteres nonce-ot a system message elejére. A 32K Long-RAG TTFT-m 0.19s-ról 1.18s-re ugrott a fix után. A 0.19s nem létező sebesség volt.

4. A magyar karakterkódolás új modellnél default-ban tesztelendő

A Gemma4 „ő” → „ô” váltása egyetlen mező-értéken eldönti egy Hungarian invoice processing pipeline acceptability-jét. A NAV invoice validáció szigorúan checksum-ol, és egy diakritikus jel változás elutasításhoz vezet. Magyar use case-re minden új modellt magyar GT-vel kell tesztelni, nem mehetünk csak „az M-Bench szám jó” alapján.

5. A KIE F1 + decode tok/s két orthogonal metrika

A pontosság és a sebesség külön-külön bukik vagy nyer. A Gemma4 itt mindkettőben rosszabb mint a Qwen3.6 — ami egyszerűsíti a döntést. De más esetekben (pl. egy lassabb-de-pontosabb modell) a trade-off explicit. Az eval harness mindkettőt méri, és a riport mindkettőt mutatja.

6. A string_strict comparator szabad-szövegre durva

A 11 items-mismatch a Gemma4-en azt mutatja, hogy az exact string match nem mindig hasznos. Field-type rendszert érdemes építeni: string_strict (ID-k, számok), string_loose (case+whitespace tolerancia), string_normalized (Unicode normalizáció), enum_set (kategorikus mezők). Ez a következő iteráció a harness-en, és ennek hiányában a „Gemma 0.890” szám is részben comparator-artefakt. De a 12 valódi modell-hiba marad, és ezek nem mennek el.

7. A modell candidate-eljárás működik, és ennek meg kell maradnia

Egy év múlva ez a cikk számokkal alá fogja támasztani azt, hogy a következő candidate is így kerül megmérésre — Qwen3.7, Gemma5, Llama5, vagy ami épp jön. Ugyanaz a corpus, ugyanaz a benchmark, ugyanaz a methodology. A delta-számok így meaningful-ek lesznek, és nem keveredik a methodológia változással. Ezt a discipline-t nem lehet utólag visszaszerezni — most kell kiépíteni.

Mit lehet még csinálni

Pár ötlet, ami felmerült, de nem fért bele ebbe a körbe:

  • Concurrent benchmark Gemma4-en is: a benchmark.py-t be kell bővíteni --concurrency N flaggel, és lefuttatni 1, 4, 8, 16-on mindkét modellre. Ez mutatná meg, hogy a Gemma4 hogyan skálázódik concurrent batch-ben — sejtem, hogy rosszabbul mint a Qwen + MTP, de a számok kellenek.
  • MTP num_speculative_tokens=1 vs =2 vs =3: az előző cikkből függőben maradt. A 99%-os position-0 acceptance-szel egy =3 config kíváncsi vagyok hogyan teljesít a JSON-KIE-n.
  • Production-trace replay: 24 óra valódi DocAI traffic visszajátszása MTP-vel és vanilla-val. Ez adná meg a valódi MTP-gain-t a production workload-on, nem a synthetic benchmark-mixen. Aug-ra tervezve.
  • String-type rendszer a comparator-ben: string_loose, string_normalized, enum_set. Ezzel a Gemma4 F1 ~0.92-re menne, ami az igazságosabb szám. De a Qwen továbbra is 1.000.
  • Multimodal corpus extension: a 6 stripped multimodal képet most kihagyjuk. A Qwen3-VL-Embedding-2B classifier + Qwen3.6 chain-t lefuttatva ezeknek is bekerül a corpusba. Ez egy következő harness-iteráció.

Production döntés

A spark-prod marad a Qwen3.6-35B-A3B-FP8 + MTP konfigon. A Gemma4 nem váltja le:

  • KIE F1 0.890 vs 1.000 — bukás
  • Decode tok/s 30-80%-kal lassabb minden workloadon — bukás
  • Nincs MTP-ekvivalens spec decoding — strukturális hátrány a DocAI workload-on
  • Magyar karakterkódolási hibák — kockázat

A Gemma4 esetleg érdekes lehet egy másik use case-re (rövidebb input tokenek, jobb tokenizer-hatékonyság), de a DocAI candidate-roleban nem teljesít.

A jövőre nézve: a most lefuttatott eval pipeline reprodukálható, és minden új release ezen fog átmenni. A következő candidate Qwen3.7 lesz, ha ez év végéig megjelenik, vagy Gemma5, vagy valami új. A pipeline ugyanaz marad, és a számok év-évre összevethetők lesznek.


Rendszer: NVIDIA DGX Spark, GB10 (SM 12.1), 128 GB LPDDR5x unified memory
Driver: NVIDIA 580.142, CUDA 13.0
Modellek: Qwen/Qwen3.6-35B-A3B-FP8 (prod, MTP num_speculative_tokens=2) vs Gemma4 (out-of-the-box, no spec decoding)
vLLM: 0.19.1rc1.dev328+ (cu130-nightly image)
Benchmark eszköz: saját benchmark.py (chat completions streaming, nonce prefix-cache busting)
KIE corpus: 34 magyar számla-dokumentum (40-ből, 6 stripped multimodal kihagyva)

Minden JSON eredmény, eval harness output, benchmark log, és a benchmark.py patchelt verziója elérhető. Ha érdekel a reprodukció, írj.