veilletech.fr
26 août Feed du jour
#07 LLM Article

Quatre GPU, et le goulot était dans le BIOS

Avant d'accuser le modèle, mesurez ce qui circule entre vos cartes.

Deuxième volet d'un montage de serveur d'inférence maison à quatre GPU AMD. L'auteur y traque la lenteur du multi-GPU sous llama.cpp et découvre que les transferts directs entre cartes ne fonctionnaient pas du tout : tout passait par le processeur. Deux réglages, un dans le BIOS et un dans le noyau, multiplient les débits.

4 min de lecturevidéo 1:18
Partager
Sommaire6 sections
  1. Ce qui se passe
  2. Le décodage spéculatif ne suffit pas
  3. La vraie cause : pas le logiciel, le BIOS
  4. Les gains
  5. Deux détails qui servent
  6. À retenir

Ce qui se passe

Deuxième volet d'une série où l'auteur monte un serveur d'inférence maison avec quatre cartes AMD Radeon PRO V620 de récupération, et cherche à en tirer une vitesse utilisable. Tout se fait avec llama.cpp et des réglages existants — aucun noyau ROCm réécrit.

Le point de départ est décevant. En répartissant les couches du modèle sur plusieurs cartes (layer parallel), on obtient une vingtaine de tokens par seconde, et surtout rocm-smi montre que la plupart du matériel est inactif : les couches s'exécutent en série, donc les cartes qui ne traitent pas la couche courante attendent leur tour.

Rappel utile pour la suite : la génération de tokens est limitée par la bande passante mémoire, pas par le calcul. Il faut relire tous les poids du modèle à chaque token généré, et les faire arriver au GPU coûte plus cher que la multiplication de matrices elle-même.

Le décodage spéculatif ne suffit pas

L'auteur active un modèle brouillon (draft model) : un petit modèle propose plusieurs tokens, le gros les vérifie en parallèle. Sur un modèle de 31 milliards de paramètres avec son modèle brouillon dédié, le résultat est net et contre-intuitif :

Tout mettre sur une carte est plus rapide que de répartir, parce que llama.cpp traite très bien plusieurs tokens par lot sur un seul GPU — l'inférence étant limitée par la mémoire, il reste du calcul disponible. Répartir n'a d'intérêt que si le modèle, ou le contexte voulu, ne tient pas sur une carte.

Sur un modèle plus gros étalé sur les quatre cartes, avec son propre modèle brouillon, il plafonne à 13 puis 15-16 tokens/s, avec des performances qui varient fortement au fil d'une même invite — signe que quelque chose cloche.

La vraie cause : pas le logiciel, le BIOS

Plutôt que de continuer à deviner, il mesure, avec un outil livré avec ROCm :

Terminal
/opt/rocm-6.4.0/bin/rocm-bandwidth-test

Le tableau de connectivité inter-périphériques est sans appel : aucun accès direct entre les cartes. Chaque transfert GPU→GPU faisait un détour par le processeur, à environ 7 Go/s, quand la mémoire d'une carte tourne à plus de 400 Go/s.

Deux causes, aucune dans le logiciel d'inférence :

  1. Un réglage de BIOS. La base des adresses mémoire haute (MMIO High Base) avait été placée très haut pour que la carte mère accepte de démarrer avec quatre cartes de 32 Go. Or certains GPU n'adressent que 44 bits, ce qui impose de rester sous 16 To. Valeurs retenues après essais : base à 4 To, granularité 1024 Go.
  2. Le noyau. Sans iommu=pt au démarrage, l'inférence produit du texte corrompu — « le modèle fait un AVC », écrit l'auteur — puis le noyau panique.

Les gains

Une fois les transferts directs rétablis, en parallélisme de tenseurs (tensor parallel, où chaque couche est découpée entre les cartes) :

Configuration Avant Après
Deux cartes 20 tokens/s 47 tokens/s
Quatre cartes 0,5 token/s 37 tokens/s

Pour référence, une seule carte donne 40 tokens/s. Deux cartes en tensor parallel passent donc au-dessus de la carte unique ; quatre restent en dessous, la synchronisation entre pairs coûtant plus qu'elle ne rapporte sur ce matériel.

À noter : avant correction, quatre cartes donnaient 0,5 token/s. Ce n'est plus de la lenteur, c'est une panne — mais une panne qui ne dit pas son nom.

Deux détails qui servent

L'auteur a balayé les réglages par script plutôt qu'à la main, en comparant contre une invite de référence. Deux résultats valent d'être notés :

À retenir

Avant d'accuser le modèle, la quantification ou llama.cpp, mesurez ce qui circule entre vos cartes. Un rocm-bandwidth-test — ou son équivalent NVIDIA, p2pBandwidthLatencyTest — coûte deux minutes, et aucune couche logicielle ne vous signalera que le pair-à-pair PCIe est mort.

Source : No, We Have AI At Home