← retour
Ne ratez plus rien.
Un email à chaque nouvel article, les annonces des formations à venir, rien d'autre. Les news complètes de la veille, les chiffres et les cadeaux sont réservés aux inscrits à l'Espace Abonnés.
Discutez de cet article avec votre IA
Le bouton copie l'article avec une courte introduction pour le modèle. Collez le tout dans Claude, ChatGPT, Le Chat ou une autre IA, puis posez-lui vos questions.

On descend d'un cran : #002.1 complément, l'Arc en f16

Ce complément prolonge l'article #002 le même compilateur sur un GPU, publié le 18 octobre, que je ne modifie pas. Il y avait un cas où Herbert perdait nettement : le GPU Arc 140V d'un portable Core Ultra 7 258V, en f16 contre f16. Au prefill sur 759 tokens, Herbert faisait ×0,89 de llama.cpp Vulkan sur Qwen3.5-0.8B et ×0,57 sur le 4B. J'écrivais que ses multiplications de matrices ne tiraient pas tout de la carte, que je n'avais pas encore eu le temps de chercher pourquoi, mais que ça allait me plaire.

Ça m'a plu.

Ce qui a changé

Trois choses, toutes propres à cette carte.

Les matrices que la carte sait faire. Sous le pilote Mesa ANV, les unités matricielles de l'Arc 140V ne proposent qu'une forme : des tuiles de 8 × 16 × 16 en f16, sur des sous-groupes de 16 invocations. Les noyaux d'Herbert attendaient les tuiles de 16 × 16 × 16 sur 32 invocations des cartes NVIDIA et AMD. Faute de les trouver, l'attention du prefill retombait ici sur des noyaux qui n'utilisaient pas du tout les unités matricielles. Elle travaille maintenant sur des tuiles de 8 lignes, la forme que la carte offre.

La taille des tuiles. C'est le gros du gain. Une multiplication de matrices se découpe en blocs : chaque groupe de travail calcule un bloc de la sortie, et charge pour cela une bande de chacune des deux matrices d'entrée. Plus le bloc est grand, plus chaque valeur chargée sert à de calculs. Sur cette carte, Herbert calculait des blocs de 32 × 64 sorties par groupe de 64 invocations : 2 048 sorties pour 96 lignes et colonnes lues à chaque pas. Il calcule maintenant des blocs de 128 × 128 par groupe de 512 invocations : 16 384 sorties pour 256 lignes et colonnes lues, soit trois fois plus de calcul par valeur lue. Le bloc de sortie ne tient plus dans les 48 Kio de mémoire partagée du groupe, alors les résultats s'écrivent directement depuis les accumulateurs.

J'ai mesuré 31 découpages sur la carte avant de retenir celui-là. Chacun des 32 sous-groupes y porte 2 × 2 matrices. Au-delà, le débit tombe à moins de la moitié. Un bloc encore plus grand, 256 × 128, gagne 6 % sur un modèle et en perd 6 sur un autre. Le découpage retenu a la même forme que celui de llama.cpp sur cette carte.

Un défaut trouvé en route. Le chemin qui écrit directement depuis les accumulateurs existait déjà, mais il n'était pas utilisé par défaut. Il cachait un défaut : la projection du Gated DeltaNet de Qwen3.5 fait 8 224 colonnes, ce qui n'est pas un multiple de 128, et les dernières matrices de chaque ligne atterrissaient sur la ligne suivante. C'est corrigé : Qwen redonne exactement les mêmes tokens qu'avec l'ancienne écriture.

Les chiffres

Même carte, mêmes prompts, même protocole que la campagne d'octobre, cinq tours alternés, f16 contre f16. En face, le llama.cpp de l'article, 08ffba21e, à son meilleur réglage, et celui du 2 novembre, 4e910a86e, à son réglage par défaut.

prefill sur 759 tokens, f16 contre f16, tokens par secondeHerbert, 2 novembrellama.cpp du 2 novembreHerbert / llama.cpp du 2 novembrellama.cpp de l'articleHerbert / llama.cpp de l'articleHerbert / llama.cpp, le 18 octobre
Arc 140V, 0.8B4 1132 629×1,562 216×1,86×0,89
Arc 140V, 4B804619×1,30594×1,35×0,57

Sur le 4B, Herbert passe de 328 à 804 tokens par seconde. Le llama.cpp de l'article redonne ses vitesses d'octobre, 573 tokens par seconde à son réglage par défaut. Celui du 2 novembre a gagné de 8 à 19 % : Herbert reste devant.

Au client commun, sur le 4B à 4 105 tokens, en f16, Herbert donne maintenant son premier token en 7,75 s, contre 17,5 s le 18 octobre. llama.cpp du 2 novembre le donne en 10,70 s, celui de l'article en 11,14 s. Ce sont des médianes de 15 requêtes. Au décodage, rien ne change.

Une précision que je n'avais pas écrite

Sur cette carte, pour des poids en f16, llama.cpp accumule ses produits de matrices en f16 (matmul_f16_f16acc). Herbert accumule en f32. « f16 contre f16 » veut donc dire les mêmes poids et les mêmes activations, avec un accumulateur plus précis du côté d'Herbert. Les deux fichiers GGUF sont en F16, sans aucun tenseur quantifié.

Les limites

Cette mesure ne vaut que pour l'Arc 140V, sous Mesa 26.0.8 et le noyau Linux 7.0.0. Le code mesuré est la version 0.2.0 de herbert-vk-f16 (tag v0.2.0), publiée avec ce complément. Avant de la publier, je l'ai repassée en non-régression : sur la RTX 4080 et les deux GPU intégrés AMD, elle donne les mêmes tokens que la version de l'article, partout où le chemin de calcul n'a pas changé. Le reste de l'article #002 tient tel qu'il est publié, y compris les cas où Herbert est à égalité ou plus lent : le 4B sur la RTX 4080 face au meilleur réglage de llama.cpp, et le 4B sur les GPU intégrés AMD.

On descend d'un cran, ou plusieurs...

  1. On descend d'un cran : #000 un moteur d'inférence qui écrit son propre code · 03-oct-2026
  2. On descend d'un cran : #001 un compilateur pour moteur de LLM · 11-oct-2026
  3. On descend d'un cran : #002 le même compilateur sur un GPU · 18-oct-2026
    1. On descend d'un cran : #002.1 complément, l'Arc en f16 · 02-nov-2026
  4. On descend d'un cran : #003 ce que CUDA a et que Vulkan n'a pas · 25-oct-2026
  5. On descend d'un cran : #004 le même compilateur sur les puces d'Apple · 01-nov-2026