Contributions à llama.cpp
Deux correctifs fusionnés dans le moteur de référence de l'IA locale
llama.cpp est le moteur qui fait tourner les modèles open-weight sur un portable, un poste de travail ou un serveur sans GPU de datacenter. En octobre 2026, Georgi Gerganov y a fusionné deux correctifs signés Leebr. Ni feature cosmétique ni typo : deux bugs qu'on a subis sur notre banc, mesurés, corrigés, puis défendus en revue publique. Depuis, du code de Leebr tourne chez tous ceux qui mettent llama.cpp à jour.
Impact mesuré
Ce que nos deux correctifs changent, chiffres relevés avant et après, sur notre banc et chez des testeurs qu'on ne connaît pas. Pas des projections.
Reprendre une session de 58 000 tokens
39 fois plus rapide
Tokens relus à cette reprise
99 % de lecture évitée
Tour suivant d'un agent, session de 36 044 tokens
reprise instantanée
Débit de génération, MoE sur CPU
+5 % retrouvés
Reprise de session et tokens relus : relevés d'un testeur indépendant sur la PR #26004 (Radeon 8050S, Qwen3.5-35B-A3B, session de 58 000 tokens). Tour suivant : un autre testeur, RTX 5070 Ti, session d'agent de 36 044 tokens et 31 checkpoints restaurés. Décode : notre banc (i7-10750H, Ornith-1.5-35B Q8_0, experts sur CPU), médiane de plusieurs runs.
Des sessions d'agent qui survivent au redémarrage
« server : preserve context checkpoints across slot save/restore »
Le problème
Sur un portable, on ne tient qu'un modèle et une session à la fois. Pour en mener plusieurs, on sauvegarde la session sur disque et on la restaure plus tard. Sur les modèles hybrides qui dominent l'open-weight en 2026 (Qwen3.5, Qwen3.6, Gemma 4), la restauration repartait à froid : le serveur relisait tout le contexte depuis le premier token. Les checkpoints, ces copies de l'état qui permettent de ne relire que la différence, n'étaient pas dans le fichier, et le code les effaçait au passage. Sur notre banc, un test simple le montre : 210 tokens relus au lieu de 31.
Le correctif
Les checkpoints voyagent avec le fichier. À la suite de l'état existant, un appendice marqué SCKP porte chaque checkpoint et sa position. Un ancien fichier se restaure comme avant, un nouveau fichier se lit sur un ancien serveur. Deux PR avaient tenté la même chose avec un fichier compagnon ; aucune n'avait abouti. On a tout mis dans le même fichier et ajouté le test de régression qui manquait : il échoue sur master sans le correctif.
La revue
Soixante-dix-huit jours, six commits. Un relecteur a trouvé qu'un fichier abîmé pouvait faire allouer de la mémoire avant de vérifier que les octets existaient : corrigé, le serveur refuse proprement. Un autre a apporté lui-même le correctif d'un crash au mélange de types de cache brouillon, crédité en co-auteur. Georgi Gerganov a demandé une dernière clarification sur la gestion d'échec, puis a approuvé et fusionné. Pendant ce temps, dix personnes qu'on ne connaît pas ont fait tourner la branche sur du matériel qu'on n'a pas, d'une Radeon intégrée à un M5 Pro, et des forks l'embarquaient déjà avant le merge.
Mesuré
Radeon 8050S, Qwen3.5-35B-A3B, session de 58 000 tokens : reprise en 4,7 s au lieu de 181,9 s, 516 tokens relus au lieu de 58 202. RTX 5070 Ti, session d'agent de 36 044 tokens : le tour suivant traité en 1,7 s au lieu de relire la session entière. Une sauvegarde faite sur un GB10 restaurée sur un M3 Ultra : sortie identique à l'octet près.
Le débit de décode des MoE sur CPU, retrouvé
« ggml-cpu : keep the FP16->FP32 lookup table on x86 with F16C »
Le problème
Le 11 octobre, une mise à jour du moteur fait passer les conversions FP16 vers FP32 par l'instruction F16C au lieu d'une table. Sur les builds officielles Windows, compilées avec Clang, le décode de notre MoE quotidien perd environ 7 %. Personne ne l'avait vu : la régression n'apparaît qu'avec ce compilateur, dans la boucle des produits scalaires quantifiés.
Le correctif
Diagnostic au llvm-mca : Clang transforme la conversion en une instruction qui fusionne dans l'accumulateur encore en vol, et sérialise la boucle (19,1 cycles par itération au lieu de 4,3). Le correctif tient en une ligne : garder la table pour FP16 vers FP32, laisser F16C pour le sens inverse. Sortie du modèle identique à l'octet près.
La revue
Issue ouverte avec la mesure, PR le même jour. L'auteur de la mise à jour d'origine a expliqué son raisonnement et proposé une condition sur la version du compilateur ; on a vérifié que la dernière version de Clang produisait le même code. Un mainteneur a demandé de commenter la ligne plutôt que de la supprimer, pour garder la trace. Fusionnée par Georgi Gerganov trois jours après l'ouverture.
Mesuré
i7-10750H, Ornith-1.5-35B Q8_0 avec les experts sur CPU : décode de 13,5 à 13,9 t/s avant, 14,2 à 14,6 t/s après. Le noyau en cause (MUL_MAT_ID q8_0) passe de 493 à 332 µs.
Ce que ça change pour vous
Pourquoi un client qui n'a jamais ouvert llama.cpp devrait s'y intéresser.
Un agent local tient sa session
Chez un fournisseur cloud, votre contexte est gardé en mémoire pour vous, et facturé. En local, c'est un fichier sur votre disque. Depuis la #26004, il contient tout : un agent sur un portable ou un petit serveur survit à un redémarrage, une mise à jour, une coupure, et reprend là où il s'était arrêté.
Le matériel modeste reste viable
Les deux bugs touchaient le cas qui nous intéresse : un gros MoE sur une machine ordinaire, experts en RAM, GPU de portable. C'est le terrain de l'IA locale en entreprise, et c'est celui qu'on mesure tous les jours.
On connaît le moteur de l'intérieur
Quand quelque chose ne va pas dans votre déploiement, on ne s'arrête pas à la documentation. On lit le code, on pose une sonde, on mesure, et s'il faut corriger le moteur, on sait comment faire accepter le correctif par ceux qui le maintiennent.
Comment on contribue
La même méthode que sur un projet client : mesurer avant d'affirmer, prouver avant de livrer.
Un bug qu'on subit est un bug qu'on mesure
La sonde, le chiffre avant, le chiffre après. C'est ce qui fait d'une PR autre chose qu'une opinion, et ce qui fait venir les testeurs.
Un test qui échoue sans le correctif
Chaque PR embarque son test de régression, vérifié sur master sans le patch. Les deux tentatives précédentes sur le même sujet n'en avaient pas ; elles n'ont pas abouti.
La revue n'est pas une file d'attente
Les deux cas limites qui auraient fait tomber un serveur en production ont été trouvés par des relecteurs, pas par nous. On répond, on reproduit, on corrige, on crédite.
Et le correctif Vulkan de juillet ?
Notre première note racontait un correctif de six lignes dans le back-end Vulkan : la lecture d'un checkpoint sur iGPU passait de 3,3 s à 25 ms. Le dépôt n'acceptant qu'une PR ouverte à la fois pour un nouveau contributeur, il attendait son tour derrière la #26004. Le 7 octobre, un mainteneur a fusionné le même correctif en amont, limité aux GPU AMD. On a fermé le nôtre : le résultat compte plus que la signature. Reste une mesure à proposer : sur Intel UHD, retirer ce filtre fait passer la sauvegarde d'un slot de 2,2 s à 0,45 s.
Le correctif en amont (#30049)Un agent local chez vous ?
On connaît le moteur de l'intérieur. Parlons d'un pilote sur votre matériel, avec des mesures avant de promettre quoi que ce soit.