L'ancien bench ne lisait pas le statut HTTP, inventait un partage 15/85
du temps quand les timings manquaient (et l'enregistrait comme mesuré),
tuilait un petit corpus qu'un brouillon recopiait, et ne disait rien du
prefill à 30k ni du chemin où le cache est repris. Synchrone, il était
coupé par les proxys (60-100 s) pendant que le moteur continuait, et un
simple GET suffisait à le lancer.
- Tâche de fond : POST /api/bench (202, 405 sur GET, 409 si occupé),
/api/bench/status pour la progression, /api/bench/cancel ; chaque
requête au moteur porte le contexte annulable.
- Verrou de génération tenu pendant toute la mesure : chat, tâches et
compaction reçoivent un refus clair ; les clients /v1 un 503 avec
Retry-After ; /slots occupé (client externe, CLI) refuse aussi.
- Mode rapide par défaut : préchauffage jeté + la ligne courte, sur le
chat avec gabarit, raisonnement et échantillonnage du preset, seed fixe.
- Mode complet (bouton « bench complet », loki bench --full) : prefill à
froid à D = min(CTX/2, 32k, ce qui laisse tenir les tours), 16k si des
poids tournent sur CPU, puis 3 tours user → assistant → user de code
jamais vu. Reprise du cache lue dans cache_n, jamais supposée ; note
pour les hybrides (points de contrôle). Pas d'ignore_eos.
- Rien n'est enregistré sans réponses 200 et timings réels, ni pour un
résultat partiel (budget de 6 min par requête, contexte plein).
- Empreinte enregistrée (configuration + CUDA_VISIBLE_DEVICES + protocole) ;
les anciennes mesures retombent sur le nom du modèle. Types de cache KV
et build du moteur affichés, KV quantifié signalé (zone grise).
- Linux : indication « possible thrash » (read_bytes, VmRSS), jamais
enregistrée.
- Effacement du slot en fin de bench inchangé (engineSideJob, différé :
il tourne aussi sur erreur et annulation).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
La relecture du relevé par complétion a trouvé quatre écarts, tous
d'affichage ou de robustesse ; rien ne touche aux requêtes ni au contexte.
- Compaction : la réponse lue d'un bloc passait de Decoder à Unmarshal,
plus strict (un octet parasite après le JSON faisait échouer une
compaction qui passait). Retour au Decoder, et perfWire fait de même.
- API externe : son cache suit ses propres règles, sans slot ni points de
reprise à surveiller ici. Plus de ligne ambre « recalculés » pour elle ;
le relevé reste dans l'anneau.
- Seuil d'alerte : même priorité qu'au lancement — -cms d'EXTRA_ARGS, puis
LLAMA_ARG_CHECKPOINT_MIN_SPACING_NT, puis CKPT_MIN_STEP ; -ub d'EXTRA_ARGS
avant UBATCH.
- UI : « recalculés après sous-agent, client /v1 » au lieu des identifiants
internes (subagent, foreign).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jusqu'ici, impossible de savoir si une ligne volatile s'était glissée dans
le prompt, si une mise à jour du moteur avait cassé les points de reprise
ou si l'acceptation du MTP s'était effondrée : le chunk final de llama.cpp
porte ces chiffres (cache_n, draft_n, cached_tokens), on les jetait.
Lecture seule : aucun champ ajouté aux requêtes, et le comptage du
contexte (usage.prompt_tokens → CtxUsed → compaction) ne change pas.
- perf_log.go : décodage à part et tolérant (perfWire) — un compteur mal
typé ne jette plus le chunk final ni ne fait échouer une compaction ;
cached_tokens, strictement entier dans streamChunk, y déménage aussi.
- Inconnu n'est pas 0 : pointeurs, et l'UI garde « prefill N tok » quand
le moteur ne dit rien de son cache.
- Nature (main, subagent, verify, task, compact, bench, foreign) portée
par le contexte, pas par Caps ; TTFT au premier delta de tout type.
- Perte de cache = total précédent − cache_n, seulement quand les messages
prolongent strictement ceux de la complétion précédente de la même
discussion et de la même nature (empreintes cumulées) ; jamais sur un
flux coupé. Ce qui s'est intercalé (sous-agent, client /v1, bench) est
nommé.
- Anneau de 5000 entrées en mémoire, sans texte ; GET /api/perf/summary
(derrière la clé) : taux de cache, recalcul par tour et par nature,
médianes pp/tg par profondeur, acceptation du brouillon.
- Ligne [perf] sur stderr seulement avec LOKI_PERF_LOG.
- UI : « prefill X nouveaux / Y en cache », ambre au-delà d'un seuil
relevé sur un modèle hybride (espacement des points de reprise).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>