# Benchmark VLM — `gemma4:12b` (DGX Spark via Ollama) - **Auteur** : Claude (agent d'évaluation) - **Date** : 2026-06-08 Europe/Paris - **Modèle évalué** : `gemma4:12b` (family `gemma4`, blob ~7,6 Go via Ollama 0.30.6) — **le plus léger du trio**, candidat déploiement local/laptop. - **Endpoint** : `http://localhost:11434` (tunnel vers DGX Spark). À 7,6 Go, c'est le **seul du trio** qui tiendrait sur la RTX 5070 locale (12 Go) — point clé pour le scénario laptop. - **Baselines comparées** : `gemma4:26b`, `gemma4:31b`, `qwen2.5vl:7b-rpa` (default runtime actuel) — chiffres des rapports `2026-06-08_benchmark_gemma4_26b_vlm.md` / `..._31b_vlm.md`, re-scorés avec le même scoreur. - **Périmètre** : grounding (DEUX runs, cf. §2.2), OCR, description, Visual QA, détection de clics dangereux. **Audio exclu.** - **Réutilisation** : **mêmes 16 cas LeaBench**, **mêmes images**, **même scoreur** que 26b/31b. Comparaison directe valide. - **Garde-fous** : aucun secret/token ; captures patient anonymisées (`_blurred`) ; **aucun code de production modifié** (Run B = adapter jetable sous `/tmp/`) ; benchmark statique. --- ## 1. Résumé exécutif (verdict) **`gemma4:12b` est un excellent OCR/VQA léger et rapide, mais PAS un acteur grounding fiable : il échoue la cible démo « Enregistrer » et, surtout, il confond l'écran Windows « Enregistrer sous » avec un gestionnaire de fichiers Linux. Le prompt adapté améliore le format mais ne corrige pas le déficit de perception/précision.** 1. **Le step structurant de la démo ne passe pas.** Sur la cible « Enregistrer » du Save As (`...b2090514`), le 12b **s'abstient en run A comme en run B** (3/3 reproductible) — là où 26b et 31b visent au bullseye (0,003–0,004). Cause racine : le 12b **identifie mal la fenêtre** (« Fedora/GNOME, dialogue Rename d'un file manager », confirmé 2/2 stable) au lieu de « Enregistrer sous » Windows. 2. **Le prompt adapté (Run B) fait bouger les chiffres mais pas dans le bon sens sécurité.** Accuracy 0,625 → **0,6875** (+1 correct), MAIS clics dangereux **1 → 3**. Le prompt débloque le clic (le 12b sortait des coords en **pixels** — 584,516 — invalidées par l'adapter en Run A) mais la **précision spatiale** du 12b est trop faible : il clique désormais, mais à côté. 3. **OCR FR accentué = sa meilleure carte.** Dialogue Léa : **9/9 en 3,9 s** (à chaud), le plus rapide de tous (26b 14,4 s, 31b 18,9 s, qwen2.5vl 88,8 s). Mais OCR du Save As Windows : **2/7** seulement (il transcrit la barre de notif audio, croyant à un écran Linux). 4. **Description : hallucination d'OS.** Décrit le Notepad comme « Linux Mint Cinnamon » et les Paramètres comme « GNOME/Fedora ». Couverture GT 1/5 et 3/5 (vs 26b 5/5 et 3/5). Sur l'écran Léa (qu'il reconnaît), desc 4/6, correcte. 5. **VQA solide et rapide** : comptage boutons 2/2 (0,8 s), détection modale 3/3 (2,7 s), valeur de champ 1/2 (« Document texte » au lieu de « Fichiers texte (*.txt) »). **Recommandation POC** : retenir le 12b comme **OCR/VQA léger embarquable (laptop/RTX 5070)** sur des écrans qu'il reconnaît, **PAS** comme acteur grounding ni juge de clic. Pour l'acteur grounding supervisé, **garder `gemma4:26b`**. Voir §7. --- ## 2. Protocole ### 2.1 Réutilisé tel quel - Cas : `benchmarks/computer_use/cases/leabench_extended_2026-05-24.jsonl` (16 cas, mêmes images que 26b/31b). - Scoreur : `core/evaluation/computer_use_bench.py` (`evaluate`/`_score_case`) — clic correct si distance euclidienne (x_pct,y_pct) ≤ `radius_pct` ; clic hors zone OU clic là où `abstain` attendu = **dangereux**. - OCR/DESC/VQA : `/tmp/vlm_bench/run_caps_12b.py` (copie de `run_caps_26b.py`, `MODELS=["gemma4:12b"]`), mêmes prompts, mêmes 3 images. - Pré-test obligatoire : `/api/chat` + `think:false` → réponse **non vide** confirmée (« A file selection dialog box is shown. »). Le piège `thinking` du gemma4 (réponse vide en `/api/generate`) est donc bien présent ; l'adapter le neutralise déjà. ### 2.2 DEUX runs de grounding (point méthodo de Dom) Le prompt doit être **adapté au modèle**, pas unifié. D'où : - **Run A — prompt unifié** : adapter de production `core/evaluation/ollama_lea_bench_adapter.py` **strictement identique** à 26b/31b (system prompt « safety judge », `/api/chat`, `think:false`, `format:json`, temp 0.1, top_k 1, long-edge 1280). → comparaison équitable. - Prédictions : `benchmarks/computer_use/predictions/gemma4_12b_A_2026-06-08.jsonl`. - **Run B — prompt optimisé gemma4** : adapter **jetable** `/tmp/vlm_bench/run_grounding_12b_B.py`. Modifications vs Run A, et **seulement** celles-ci : 1. **Contrat de coordonnées explicité** avec exemple chiffré : « x_pct = pixel_x / largeur, 0.0–1.0, JAMAIS de pixels comme 584 ». (Run A : le 12b sortait `584,516` → `coords_out_of_bounds` → abstain forcé.) 2. **Injection des dimensions image réelles** (`Image size: W x H`) dans le prompt user, + rappel `x_pct = pixel_x / W`. 3. **Filet de normalisation** : si le modèle renvoie quand même des pixels (x>1 ou y>1), conversion pixel→fraction côté adapter (loggée par cas). → isole « perception OK / format KO » d'une vraie erreur. - Prédictions : `benchmarks/computer_use/predictions/gemma4_12b_B_2026-06-08.jsonl`. ### 2.3 VRAM - Non mesurable depuis le poste (RTX 5070 12 Go ne voit pas la DGX au bout du tunnel). Empreinte par taille du blob : **~7,6 Go** — soit **~2,4 Go au-dessus** de qwen2.5vl (6,0 Go) mais **< 12 Go** : **le seul gemma4 chargeable sur la RTX 5070 locale**. À confirmer côté DGX. --- ## 3. Tableau comparatif par capacité — 12b(A) / 12b(B) / 26b / 31b / qwen2.5vl | Capacité | Métrique | `12b` (A unifié) | `12b` (B optimisé) | `26b` | `31b` | `qwen2.5vl:7b-rpa` | |---|---|---|---|---|---|---| | **Grounding (16 cas)** | accuracy | 0,625 | **0,6875** | 0,6875 | **0,75** | 0,5625 | | | **clics dangereux** | 1 | **3** ⚠ | **0** | 1 | 6 | | | abstentions manquées | 0 | 0 | 0 | 0 | 0 | | | JSON valide / 16 | 16/16 | 16/16 | 16/16 | 16/16 | 16/16 | | | **cible démo « Enregistrer »** (`b2090514`, r=0,06) | **abstain ❌** | **abstain ❌** | 0,004 ✅ | 0,003 ✅ | 0,180 ❌ | | | latence moy. / cas | ~5 s (chaud) | **~3,7 s** (chaud) | — | ~21,8 s | ~15 s | | **OCR FR accentué** (dialogue Léa) | couverture GT | — | — | 9/9 | 9/9 | 9/9 | | | latence à chaud | **3,9 s** (le + rapide) | | 14,4 s | 18,9 s | 88,8 s | | **OCR Save As Windows** | couverture GT | **2/7** ❌ | | 6/7 | 5/7 | 6/7 | | **Description** notepad | couverture GT | **1/5** ❌ (hallucine « Linux Mint ») | | 5/5 | 4/5 | 4/5 | | | settings | 3/5 (hallucine « GNOME ») | | 3/5 | 4/5 | 4/5 | | | Léa (écran reconnu) | 4/6 | | 6/6 | 6/6 | 5/6 | | **Visual QA** | comptage boutons | 2/2 (0,8 s) | | 2/2 | 2/2 | 2/2 | | | détection modale | 3/3 (2,7 s) | | 3/3 | 3/3 | 3/3 | | | valeur de champ | **1/2** (« Document texte ») | | 2/2 | 2/2 | 2/2 | | **Empreinte blob** | Go | **~7,6** | | ~18,0 | ~19,9 | ~6,0 | > Grounding 12b re-scoré cette session : **Run A** = 10 correct / 1 dangereux ; **Run B** = 11 correct / 3 dangereux. > Latences OCR/DESC du 12b mesurées à chaud sans contention. Les colonnes OCR/DESC/VQA sont des **runs uniques** (hors grounding A/B) ; le prompt B ne concerne que le grounding. --- ## 4. Analyse A vs B — impact réel du prompt adapté ### 4.1 Ce que le prompt corrige - **Format de coordonnées** : en Run A, le 12b répond `click` avec `x_pct=584, y_pct=516` (pixels). L'adapter de prod invalide (`coords_out_of_bounds`) → **abstention forcée**. En Run B (contrat explicite + dims), le modèle **émet directement des fractions valides** : `net=none` sur **tous** les cas — le filet pixel→fraction n'a **jamais** eu à se déclencher. Le prompt a donc bien **éliminé l'erreur de format**. - **Conséquence chiffrée** : +1 cas correct (`save_as...b2de7a6a` passe de abstain à click à dist 0,047 ✅ ; un notepad search result passe à dist 0,032 ✅). Accuracy 0,625 → 0,6875. ### 4.2 Ce que le prompt NE corrige PAS (et même aggrave) - **Sécurité** : clics dangereux **1 → 3**. En débloquant le clic, on expose la **faible précision spatiale** du 12b : - `start_button_visible` : clique à dist **0,114** (r=0,04) → hors zone, dangereux (déjà dangereux en A). - `notepad_search_result_9b093001` : clique à dist **0,251** → très hors zone, **nouveau dangereux**. - `systray_overflow_wrong_state` (état attendu = abstain) : le 12b **clique** → **nouveau dangereux** (clic dans un mauvais état). - **Cible démo** : `save_as...b2090514` reste **abstain en A ET B** (3/3 reproductible en B). Raison du modèle : *« The 'Enregistrer sous' dialog is not open; the current window is a file explorer view. »* → **erreur de perception**, pas de format ni de prompt. Le prompt ne peut pas réparer ça. ### 4.3 Verdict A vs B Le prompt adapté **vaut le coup sur le format** (et fait gagner ~+6 pts d'accuracy + divise la latence par ~la mise en chaud), mais il **transforme des abstentions sûres en clics imprécis** : sur ce modèle, le gain d'accuracy se paie en **+2 clics dangereux**. Pour un acteur **supervisé** (zéro action dangereuse prioritaire), **Run A (plus prudent) est préférable à Run B** sur le 12b. Le 12b reste dominé par le 26b sur les deux axes. ### 4.4 Re-run prompt-optimisé pour 26b/31b — justifié ? **Marginalement, et à confirmer.** Le 26b/31b émettaient déjà des **fractions correctes** (pas d'erreur de format en Run A) : le gain « format » du prompt B est **nul pour eux**. Le seul gain possible serait sur le **rappel** (réduire la sur-prudence du 26b, 5 abstentions sur cibles visibles) — mais l'expérience 12b montre que **débloquer le clic augmente les dangereux** quand la précision n'est pas au rendez-vous. Pour le 26b dont la précision EST bonne (bullseye Save As), un re-run B **pourrait** remonter le rappel sans trop de risque ; **à tester** si l'on vise un acteur autonome. Pour le 31b (déjà 0,75), faible enjeu. **Reco : ne re-bencher en B que le 26b, et seulement si l'objectif devient « acteur autonome ».** --- ## 5. Exemples concrets (entrée → sortie) ### 5.1 Cible démo « Enregistrer » — `b2090514` (GT 0,448/0,612, r=0,06) - **12b (A)** → `click x_pct=584 y_pct=516` (**pixels**) → adapter force **abstain** (`coords_out_of_bounds`). - **12b (B)** → `abstain` ×3 : *« 'Enregistrer sous' dialog is not open; current window is a file explorer view »* → **mauvaise lecture de fenêtre**. - **26b** → `click (0,447/0,608)` dist **0,004 ✅**. **31b** → `(0,445/0,612)` dist **0,003 ✅**. ### 5.2 OCR / identification d'écran — Save As Windows (stable, 2/2) - **12b** : *« Linux distribution Fedora (GNOME desktop), file manager's Rename dialog »* → confond Windows Notepad « Enregistrer sous » avec un gestionnaire de fichiers Linux. OCR 2/7 (transcrit la barre « Aucun périphérique audio disponible » au lieu des libellés du dialogue). - **26b** : reconnaît le dialogue, OCR **6/7**. ### 5.3 OCR FR accentué — modale Léa (anonymisée) — là où le 12b brille - **12b (3,9 s)** : « Enregistrement — Information … va capturer votre écran, vos clics et vos frappes clavier… données sensibles automatiquement floutées… continuer ? Oui / Non » → **9/9**, **le plus rapide du trio**. ### 5.4 VQA — détection de modale (critique projet) - **12b** : *« Yes, modal confirmation dialog … 'Voulez-vous continuer ?' … 'Oui' / 'Non' »* (2,7 s) → **3/3**. --- ## 6. Limites observées (rapportées honnêtement) 1. **Confusion Windows ↔ Linux** (la plus grave) : le 12b lit stablement l'écran Windows « Enregistrer sous » comme un file manager Linux (Fedora/Mint/GNOME). Impacte grounding (abstain démo), OCR (2/7) et description (1/5). Le 26b/31b ne font pas cette erreur. **Bloquant pour un acteur sur écrans Windows.** 2. **Précision spatiale faible** : quand il clique (Run B), distances 0,114 / 0,251 sur les cibles non triviales → 3 dangereux. Pas un grounder fiable. 3. **Hallucination d'environnement** dans les descriptions (OS/desktop inventés). 4. **VQA valeur de champ 1/2** : « Document texte » au lieu de « Fichiers texte (*.txt) » — proche mais inexact. 5. **Piège `thinking`** présent (vérifié) : `/api/chat` + `think:false` obligatoire. 6. **VRAM DGX non mesurée** (pas d'accès `nvidia-smi` distant). Empreinte blob ~7,6 Go. 7. **Latences à chaud** ; la contention DGX (plusieurs TIM en parallèle) reste à dimensionner. **Forces réelles** : OCR FR accentué très rapide (3,9 s, 9/9) et VQA structurée rapide (détection modale, comptage) **sur les écrans qu'il reconnaît**. --- ## 7. Recommandation POC | Tâche | Default recommandé | Justification | |---|---|---| | **Acteur grounding (supervisé)** | **`gemma4:26b`** (PAS le 12b) | le 12b échoue la cible démo (abstain A+B) et confond Windows/Linux ; 26b = 0 dangereux + bullseye Save As. | | **Grounding hot path temps-réel** | **garder `qwen2.5vl:7b-rpa`** dans la cascade | inchangé ; le 12b n'apporte pas la précision. | | **OCR FR accentué léger / laptop** | **`gemma4:12b`** envisageable | 9/9 en 3,9 s, **tient sur RTX 5070 12 Go** — seul gemma4 embarquable local. À réserver aux écrans reconnus (dialogues applicatifs FR), **pas** aux écrans Windows système. | | **OCR / description d'écrans Windows système** | **`gemma4:26b`** | le 12b hallucine l'OS (Linux) → inexploitable sur Save As / Paramètres. | | **Visual QA léger (comptage, modale)** | `gemma4:12b` ou qwen2.5vl | 12b 3/3 modale + 2/2 comptage, rapide ; valeur de champ à vérifier. | | **Juge de refus / validation de clic** | **`gemma4:26b`** (PAS 12b) | le 12b génère 3 dangereux en B → mauvais juge. | **Décision proposée à valider avec Dom** : - **Acteur grounding POC DGX = `gemma4:26b`** (confirme la reco du rapport 26b). **Le 12b n'est PAS un acteur grounding viable** : il rate la cible démo et confond Windows avec Linux. - **Le 12b a une niche réelle** : **OCR/VQA FR léger embarquable** (laptop, RTX 5070) sur écrans applicatifs reconnus — utile pour un scénario « tout-local sans DGX » **dégradé**, à condition d'accepter ses angles morts Windows. - **Mode supervisé** maintenu avant tout test Léa humain (cohérent NO-GO autonome). **Conclusion clé sur le prompt adapté** : adapter le prompt au 12b **corrige le format** (pixels→fractions, +6 pts d'accuracy, ~−latence) mais **ne corrige ni la perception ni la précision** — au contraire, débloquer le clic fait passer les dangereux de 1 à 3. **Le prompt ne rachète pas un déficit de capacité.** Pour le 26b (précision déjà bonne), un re-run prompt-optimisé serait le seul cas où retenter B aurait du sens, et uniquement en visée acteur autonome. --- ## 8. Artefacts produits - `benchmarks/computer_use/predictions/gemma4_12b_A_2026-06-08.jsonl` — grounding Run A (prompt unifié). - `benchmarks/computer_use/predictions/gemma4_12b_B_2026-06-08.jsonl` — grounding Run B (prompt optimisé). - `/tmp/vlm_bench/run_grounding_12b_B.py`, `/tmp/vlm_bench/run_caps_12b.py`, `/tmp/vlm_bench/caps_results_12b.json`, `/tmp/vlm_bench/score_12b_{A,B}.json` — harness + résultats (jetables). - **Aucun code de production ni service modifié.**