ggml-org/llama.cpp · contributeur

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.

Fusionnées par le mainteneur principal 10 testeurs indépendants CUDA · Metal · Vulkan

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

181,9 s4,7 s

39 fois plus rapide

Tokens relus à cette reprise

58 202516

99 % de lecture évitée

Tour suivant d'un agent, session de 36 044 tokens

tout relire1,7 s

reprise instantanée

Débit de génération, MoE sur CPU

13,7 t/s14,4 t/s

+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.

PR #26004 · fusionnée le 8 octobre 2026

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.

PR #30343 · fusionnée le 14 octobre 2026

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.