Aller au contenu
Sylvain Joffraud l4w
Retour

Banc LLM : un seul passage varie de ±12 points

La variance d’un benchmark LLM entre deux runs n’est pas un détail : sur le banc d’essai de l’assistant du Journal des Nuisances, le même adaptateur LoRA a obtenu 51,4 % puis 39,8 % de réussite, à trois heures d’écart, sur les mêmes 22 cas et avec le même juge. Soit ±12 points de bruit, plus que l’écart entre la plupart des candidats. La règle depuis : on ne compare que des moyennes sur 3 passages, détail affiché. Rejouée trois fois, la référence de production est d’ailleurs passée de 57 % à 54,5 % : son unique passage était un bon jour.

Le banc : 22 cas, des contrôles et un LLM-juge

L’assistant du Journal des Nuisances, une application de suivi de nuisances que j’ai co-fondée, tourne sur un modèle local. Je cherche un modèle plus léger que la référence de production, assistant-gemma4 (dérivé de gemma4:26b, servi par Ollama 0.34.2 sur pc-llm).

Le banc d’essai rejoue 22 cas pilotes contre chaque candidat. Chaque réponse passe des contrôles déterministes (D-…), puis un LLM-juge, qwen3.6:35b-a3b, d’une autre famille que les modèles jugés. Les pièges de ce juge sont détaillés dans l’article sur le time-out fetch failed du LLM-juge.

Deux mesures sortent d’un passage :

Un passage = les 22 cas une fois, soit près de 40 minutes (rapports de la référence horodatés 15h11, 15h50, 16h27).

Variance d’un benchmark LLM entre deux runs : les chiffres

Le bruit est apparu le 13 octobre, en rejouant un adaptateur de Gemma 4 E4B, et s’est confirmé ensuite :

Modèle (même banc, même juge)Réussite par passageMoyenneBloquants par passage
Gemma 4 E4B affiné, lr 3e-5 (13/10)51,4 / 39,8 %45,6 %1,5 en moyenne
Ministral 3 8B, non entraîné61,6 / 69,6 / 56,1 %62,4 %8 / 10 / 7
Ministral 3 8B + DPO, point 11656,4 / 62,2 / 72,6 %63,7 %11 / 10 / 4
Gemma 4 12B QAT, non entraîné (16/10)65,2 / 62,1 / 57,8 %61,7 %0 / 0 / 3
Référence assistant-gemma4 (17/10)53,9 / 55,4 / 54,3 %54,5 %1 / 1 / 1

Ministral 8B couvre 13,5 points entre son pire et son meilleur passage ; après DPO, 16,2 points. Les bloquants bougent autant : Gemma 4 12B QAT fait 0, 0, puis 3. Un passage unique à 0 aurait suffi à le déclarer « sans bloquant ».

La référence, elle, tient en 1,5 point : le bruit dépend du modèle, et on ne le connaît qu’après plusieurs passages.

Sur un banc jugé par un LLM, un écart entre deux modèles plus petit que l’écart entre deux passages du même modèle n’est pas un résultat.

C’est ce qui a tranché entre Gemma 4 12B QAT et non QAT : 62,2 % contre 61,9 %, écart dans le bruit, donc le plus léger des deux.

Pourquoi un juge à temperature: 0 n’empêche pas le bruit ?

Le juge est appelé à température nulle :

options: { temperature: 0 },
messages: [{ role: "user", content: prompt }],

Mais il ne juge pas un texte fixe. Les candidats sont servis par mlx_lm.server sur mac-train, avec un échantillonnage :

.venv/bin/python servir_socle.py --model "$1" --host 10.66.0.21 --port 8080 \
  --temp 0.8 --top-p 0.95 --top-k 40 --min-p 0.05 --max-tokens 1024

Et la référence, côté Ollama, est échantillonnée elle aussi : le générateur du jeu d’entraînement le note en commentaire, « le modèle de référence étant échantillonné (température 1), un essai raté n’est pas rejoué à l’identique ».

Le bruit vient donc de la génération, pas du jugement. Chaque passage produit 22 nouvelles conversations : il suffit qu’une réponse oublie le syndic ou invente un fait pour que des critères basculent, parfois un cas entier.

Mettre les candidats à température 0 ? Le script de service répond : « mêmes réglages que le banc : ce qui est servi est ce qui a été mesuré ». Un banc à température nulle mesurerait un modèle que personne n’utilise.

La référence rejouée : 57 % sur un passage, 54,5 % sur trois

La référence n’avait qu’un passage, le 10 octobre : 57 %, 0 bloquant. Rejouée trois fois le 17 octobre, sur la même machine et avec le même juge : 54,5 % (53,9 / 55,4 / 54,3), 1 bloquant à chaque passage, premier mot en 8,8 s, réponse complète en 14,2 s. Le passage unique du 10/10 était au-dessus de sa moyenne.

Or les seuils d’acceptation des candidats avaient été posés à partir de ce passage :

CritèreSeuil
Cas bloquants0 (moyenne de 3 passages)
Réussite≥ 57 % (« la référence »)
Mémoire en service≤ ~8 Go
Premier motquelques secondes
LicenceApache 2.0 ou équivalente

Ironie du sort, la référence ne passe plus ses propres seuils : 54,5 % de réussite, 1 bloquant. J’ai laissé le seuil de 57 % tel quel, puisque tous les candidats retenus le dépassent : Gemma 4 12B fait 61,9 %, 7 points de mieux que la référence. En revanche, aucun ne tient les deux seuils à la fois : Gemma 4 12B affiné par LoRA fait 0 bloquant sur trois passages, mais 55,8 % de réussite, et Gemma 4 12B non affiné, le meilleur compromis, en est à 0,7 bloquant.

Lessons learned

Questions fréquentes

Pourquoi un benchmark LLM donne-t-il un score différent à chaque run ?
Parce que le modèle évalué est échantillonné : servi avec --temp 0.8 --top-p 0.95, il n’écrit jamais deux fois la même réponse, et le juge lit donc un texte différent à chaque passage. Sur le banc d’essai de l’assistant du Journal des Nuisances, le même adaptateur LoRA a obtenu 51,4 % puis 39,8 % de réussite sur les mêmes 22 cas, avec le même juge.
Combien de passages faut-il pour comparer deux modèles sur un banc LLM ?
Sur un banc de 22 cas jugé par un LLM, trois passages par modèle sont un minimum : on compare les moyennes et on garde le détail des passages. Un écart entre deux modèles plus petit que l’écart entre les passages d’un même modèle est du bruit. Gemma 4 12B QAT à 62,2 % et Gemma 4 12B à 61,9 % se valent, par exemple.
Un LLM-juge à temperature 0 rend-il le banc déterministe ?
Non. Un LLM-juge appelé avec temperature: 0 limite son propre hasard, mais il juge la réponse du modèle candidat, qui change à chaque passage. Le bruit vient surtout de cette génération échantillonnée. Mettre aussi le candidat à température nulle mesurerait un modèle différent de celui qui sera servi en production.
Peut-on fixer un seuil d’acceptation à partir d’un seul passage de la référence ?
C’est risqué : un passage unique peut tomber au-dessus ou au-dessous de la moyenne. La référence de l’assistant du Journal des Nuisances avait obtenu 57 % et 0 bloquant sur un passage ; rejouée trois fois, elle fait 54,5 % et 1 bloquant en moyenne. Le seuil de 57 % tiré du passage unique est donc plus exigeant que la référence elle-même.

Partager cet article :

Article précédent
Astro + Svelte : des styles perdus sans erreur de build
Article suivant
rsync `--link-dest` sans `-H` : les snapshots explosent