Skip to content
/ airelien.dev
Go back
Aurélien AMSELLEM

Une semaine de benches sur Olares One : Gemma 4 MTP, Lucebox qui régresse, vLLM no-Genesis qui se cogne au workspace lock

Du 5 au 8 mai 2026, j'ai bench tout ce qui pouvait tenir sur un RTX 5090M 24 Go. Trois trouvailles : Gemma 4 MTP via vLLM passe à 178 t/s 24 h après merge, Lucebox v1.9.0 régresse mystérieusement de 88 à 69 t/s, vLLM no-Genesis valide PR #39931 mais reste bloqué sur P65/P22/P38. Plus le ménage : 8 apps Qwen3.6 27B → 2.

Salut les amis !

Petit rappel pour ceux qui débarquent : sur ce blog, je bench des LLMs en local sur Olares One (un mini-PC avec une RTX 5090M 24 Go, c’est mon labo perso). Trois “stacks” reviennent souvent : Genesis = la stack vLLM custom de Sandermage qui me tient à 88 t/s, Lucebox = un fork de llama.cpp ultra-tuné par sandropuppo, et MTP = le speculative decoding intégré nativement à Qwen3.6 et Gemma 4. Si vous voulez le détail, le post sur le choix de la machine explique le contexte.

Bref, une semaine étrange sur l’Olares One. Côté upstream tout bouge en même temps : Gemma 4 sort ses drafters MTP (le 5), vLLM intègre le support natif (le 6), llama.cpp suit (le 7 via un fork tiers), et pendant ce temps mon Lucebox v1.9.0 régresse de 22 % sans qu’on comprenne pourquoi. Petit récap des trois benches qui ont occupé mes après-midi, plus le ménage des 8 apps Qwen3.6 27B sur l’Olares One Market.

1) Gemma 4 E4B + MTP via vLLM = 178 t/s sur Blackwell consumer mobile

C’est le scoop qui mérite son post séparé (lien à la fin), mais en deux mots : PR #41745 mergée le 6 mai à 14:39 UTC ajoute le support natif des drafters Multi-Token Prediction de Gemma 4 (E2B/E4B/26B-A4B/31B). Le 7 mai à 06:13 UTC, le nightly Docker est publié. À 06:35 UTC, mon Olares One sort :

Run 1 (cold): 800 tok in 6,17 s = 129,73 t/s
Run 2:        800 tok in 4,17 s = 191,73 t/s
Run 3:        800 tok in 3,73 s = 214,38 t/s

AVG = 178,6 t/s, 77,3 % acceptance. Pas de Genesis, pas de fork, pas de patch — juste vllm/vllm-openai:nightly-1acd67a795... + le bon --speculative-config. Je détaille tout ça dans le post court de cet aprèm.

Le truc à retenir ici : 24 heures entre merge upstream et bench validé sur Blackwell consumer mobile. Y a un an cette boucle aurait pris 2-3 semaines.

2) Lucebox v1.9.0 — la régression mystère 88 → 69 t/s

Là c’est plus tordu. Le 4 mai j’avais bench Lucebox v1.4.4 (chemin DFlash custom, target Qwen3.6-27B Q4_K_M, drafter z-lab BF16) à 88,5 t/s sur ce même Olares One. Quand j’ai voulu rebench le 7 mai après le rebuild v1.9.0 (qui inclut PR #94 matched 3.6 SWA draft + PR #99 consumer Blackwell fix), j’obtiens systématiquement 69 t/s — sur exactement le même hardware, le même chart, les mêmes drafters cachés sur disque.

J’ai isolé hypothèse par hypothèse :

Tableau récap :

Configt/s
v1.9.0 (PR #94+#99, TQ3_0, fa_window=2048)68,85
v1.9.0 + fa_window=068,83
v1.6.0 (PR #94 only, TQ3_0)69,05
v1.9.0 + Q4_0 KV68,96
Référence v1.4.4 du 4 mai88,5

Toutes les hypothèses image/config sont éliminées. Reste l’environnement device : update kernel, HAMi runtime, libvgpu state, ou méthodologie de bench (le 4 mai j’ai peut-être bench via un path Open WebUI / public auth URL avec HTTP/2, alors que là je passe par kubectl exec localhost). Le kubectl exec route à travers la stack k8s qui peut ajouter des microsecondes, mais pas 22 % à mon avis.

Conclusion provisoire : régression environnementale qu’on ne peut pas isoler sans accès device-level. J’ai documenté ça dans la mémoire long-terme et désactivé Lucebox de l’app store (voir §4).

3) vLLM no-Genesis avec PR #39931 — la moitié-fix qui pète sur le workspace lock

Côté vLLM, JartX intègre dans le code source officiel le 5 mai à 00:14 UTC la PR #39931 : “[Feature] TurboQuant: support hybrid models and uniform quantization”. C’est gros : ça fixe le crash que TurboQuant lançait dès qu’il croisait une couche Mamba sur Qwen3.5/3.6/Qwen3-Next. Trois des 28 patches Genesis deviennent inutiles d’un coup (P60 ngram pour GDN, P65 baisse de mode CUDA graph en spec-decode, P66 filtre tailles invalides à la capture).

J’ai testé sur l’image vllm/vllm-openai:gemma4-0505-cu130 (build main HEAD post-merge) avec exactement la config de mon vllmqwen36turbo27bone, mais zéro var Genesis.

Premier crash, paradoxal : EagleProposer.__init__ → torch.zeros(...) → CUDA driver error: invalid argument. C’est le bug HAMi 0m que je connaissais déjà côté Lucebox/Driver API. Je pensais que vLLM y échappait (Runtime API). Faux : le drafter MTP allocation passe par un path qu’HAMi-core intercepte. Workaround CUDA_DEVICE_MEMORY_LIMIT_0=24000m → boot.

Deuxième crash, attendu : capture CUDA graph sur query_start_loc.tolist() dans turboquant_attn.py:583. C’est exactement ce que P65 monkey-patche. Workaround : --enforce-eager (skip TOUS les CUDA graphs).

Bench :

Run 1: 800 tok in 11,12 s = 71,97 t/s
Run 2: 800 tok in 10,84 s = 73,81 t/s
Run 3: 800 tok in 11,13 s = 71,87 t/s

AVG = 72,55 t/s−17,5 % vs Genesis baseline (88 t/s). C’est le coût de l’--enforce-eager. Genesis P65 fait plus malin : il downgrade _cudagraph_support seulement quand speculative_config est actif, donc les batches de décode 1-token gardent leur CUDA graph.

J’ai aussi tenté Patch 65 seul (3 lignes inline-patchées sur main HEAD). Boot OK, capture CUDA graph propre, log explicite : “setting cudagraph_mode=PIECEWISE”. Mais à la première inférence : crash.

File ".../vllm/v1/attention/backends/turboquant_attn.py", line 862, in _decode_attention
    current_workspace_manager().get_simultaneous(...)
AssertionError: Workspace is locked but allocation requires 0,76 MB,
current size is 0,00 MB. Workspace growth is not allowed after locking.

C’est le bug du torch.empty invisible au profiler dans la phase de “continuation prefill”, que Sandermage décrit dans le thread #40807 — ses patches P22 (partage du buffer de déquantization + pré-allocation du workspace K/V) et P38 (machine d’états mémoire) sont le vrai fix. P65 seul ne suffit pas. Pour vraiment quitter Genesis, il faut au minimum P22 + P38 + P65.

J’ai posté un comment sur #40807 avec ces deux datapoints (4ème hardware confirmé après Ampere 3090, A5000, et Blackwell 5080). Toujours pas de réponse au 8 mai à 11 h.

Conclusion : on ne peut pas drop Genesis aujourd’hui sans porter ~5 patches upstream non-triviaux. PR #39931 est nécessaire mais pas suffisant. La fix complète demande Sandermage ou un core-team motivé.

4) Le ménage : 8 apps Qwen3.6 27B sur l’Olares One Market → 2

À force d’itérer sur les stacks, mon Olares One Market avait 8 variantes de Qwen3.6 27B :

Trop. J’ai gardé deux apps pour 27B, et pour aider les utilisateurs à choisir, les titres les positionnent directement :

AppTitleStackContext
Qwen36 27B FastvLLM Turbo + Genesis 28 patches + TurboQuant K8V4 + MTP n=3128 K
📜Qwen36 27B Long Contextllama.cpp + PR #22673 (custom image) + froggeric MTP-GGUF128 K (262 K natif)

Supprimés : lucedflashqwen36one, dflashqwen36one, vllmqwen36dense27bone, llamacppqwen36dense27bone. Les apps 35B-A3B (llamacppqwen36a3bone + qwen36a3bvisionone) restent — modèles différents.

Au passage j’ai aussi attrapé 2 bugs sur la version “Fast” pendant le re-test :

Tout ça pour finalement boot v2.5.6 à 128 K context stable.

5) Le bonus : Atomic Chat fork pour Gemma 4 MTP via llama.cpp

Pour les gens qui veulent Gemma 4 MTP côté llama.cpp (pas vLLM), AtomicChat a publié les GGUFs MTP compatibles + un fork AtomicBot-ai/atomic-llama-cpp-turboquant qui ajoute :

J’ai built leur fork pour sm_120 → image aamsellem/llamacpp-atomic-mtp:0.1.0 (2,72 GB). Bench AtomicChat sur M5Max : 97 → 138 t/s sur Gemma 4 26B (+40 %).

Validé sur Olares One ce 8 mai après-midi :

Gemma 4 E2B + MTP    : 206,56 t/s, 60,9 % acceptance (3 198 tok in 15,48 s)
Gemma 4 26B-A4B + MTP : 140,03 t/s, 78,1 % acceptance (3 238 tok in 23,12 s)

Le 26B-A4B livre 140 t/s avec 78 % acceptance sur premier run (hors warm-up). On dépasse le bench M5Max d’AtomicChat (138 t/s) — la 5090M sm_120 mobile a ~75 % de la bandwidth d’une 4090 mais le MoE Gemma 4 (3,8 B activés sur 26 B) y tire bien parti. Le E2B à 206 t/s c’est essentiellement la limite “single-stream max” pour un modèle 5 B sur ce hardware.

Charts en prod : gemma4e2bone v1.0.2 (E2B, 128 K ctx) et gemma426ba4bone v1.0.9 (26B-A4B, 64 K ctx, sans vision parce que mmproj n’est pas wired avec MTP dans ce fork).

Ce qui marche, ce qui pète — cheat sheet

StackStatut sur Olares One 5090M
Atomic Chat fork + Gemma 4 E2B MTP via llama.cpp206 t/s, 61 % acceptance — single-stream cap
vLLM nightly + #41745 + Gemma 4 E4B MTP✅ 178 t/s, 77 % acceptance, stack 100 % upstream
Atomic Chat fork + Gemma 4 26B-A4B MTP via llama.cpp140 t/s, 78 % acceptance — bat le bench M5Max ref (138 t/s)
vLLM Turbo (Genesis) + Qwen3.6-27B + MTP n=3 + 88 K✅ 88 t/s steady, validé après fix HAMi + drop xxhash + revert P5B
llama.cpp + PR #22673 + Qwen3.6-27B-MTP + 128 K✅ 65 t/s, stack quasi-upstream (1 PR + 1 GGUF)
Lucebox DFlash v1.9.0 + Qwen3.6-27B⚠️ 69 t/s reproductible vs 88 t/s ref du 4 mai (régression non isolée)
vLLM main HEAD + #39931 + --enforce-eager (no Genesis)⚠️ 72,55 t/s — pas viable pour drop Genesis
vLLM main HEAD + Patch 65 seul❌ Crash workspace lock — il faut aussi P22 + P38

La seule conclusion honnête

L’écosystème inférence local en 2026 a un rythme de release que personne ne peut suivre tous les jours. Sur 7 jours j’ai vu : un drafter Gemma 4 MTP officiel + 2 PR pour le supporter (vLLM + llama.cpp), une PR Genesis-compat dans vLLM main, deux régressions reproduisibles, et un fork TurboQuant porté à llama.cpp. Mon job sur Olares One Market c’est de trier : garder ce qui est validé, supprimer ce qui est cassé, écrire ce qui aide d’autres possesseurs Olares One à éviter mes crashes.

Côté Gemma 4 MTP via vLLM, c’est trop frais pour être généralisé sur autre chose qu’une 5090M. Si vous tournez sur 5070, 5080, 4090 / 3090 desktop, vos chiffres m’intéressent. Et si vous avez résolu la régression Lucebox 88 → 69 t/s d’une façon ou d’une autre, je veux savoir.

À très vite !


Disclosure — Tous les benchmarks de ce post tournent sur mon propre Olares One. Si le contenu vous a été utile et que vous envisagez d’en acheter un, commander via ce lien de parrainage vous donne 400 $ de réduction (3 599 $ au lieu de 3 999 $) et me rapporte 200 $. Je le mentionne par transparence — et oui, accessoirement, ça aide à faire vivre le blog (hébergement, domaine, et le temps que je passe à écrire ici). Lien valable jusqu’à fin juin 2026 environ.

Share this post on:

Commentaires