À 02:17, le pager sonne parce que « les nœuds GPU sont lents ». Ce n’est pas un message d’erreur. C’est un mode de vie. En production moderne, la différence entre un cluster sain et un radiateur très coûteux est souvent une révision de pilote, un lien PCIe qui fonctionne à la mauvaise largeur, ou une équipe qui croit les slides marketing plutôt que les compteurs.
Le marché des GPU n’est pas juste un match à trois logos. C’est une chaîne d’approvisionnement, un écosystème logiciel et un profil de risque opérationnel. Si vous achetez de l’accélération à grande échelle — entraînement AI, inférence, HPC, vidéo, analytics — la concurrence n’est pas un luxe. C’est la seule chose qui empêche les prix, la consommation électrique et le verrouillage de transformer votre feuille de route en lettre de rançon.
Ce que la concurrence doit apporter (et ce qu’elle doit arrêter de faire)
« NVIDIA vs AMD vs Intel » est généralement cadré comme une affaire de performance, et la performance est réelle. Mais en production, la performance est la troisième question. La première est pouvons-nous l’exécuter de façon fiable ? La deuxième est pouvons-nous l’acheter de façon prévisible ? La troisième est pouvons-nous changer d’avis plus tard ?
1) La concurrence doit maintenir l’honnêteté des écosystèmes logiciels
Si la pile propriétaire d’un fournisseur devient l’API de facto d’une industrie, ce fournisseur n’a plus besoin de se soucier de vos coûts de migration. La soupape de sécurité, ce sont des alternatives crédibles : pas seulement « ça compile », mais « ça se déploie ». La concurrence force :
- Des kernels et pilotes stables et documentés qui ne cassent pas l’espace utilisateur à chaque point release.
- Parité d’outillage (profilers, débogueurs, télémétrie) pour que les SRE puissent diagnostiquer sans doctorat en folklore fournisseur.
- De meilleurs standards (IR de compilateur, APIs runtime, schémas de distribution de conteneurs) parce que les clients exigent la portabilité quand ils ont le choix.
2) La concurrence doit rendre les chaînes d’approvisionnement moins ridicules
Les feuilles de route matérielles sont désormais des feuilles de route business. Si votre run d’entraînement dépend d’un seul SKU que seul un fournisseur peut livrer, vous n’avez pas un plan d’infrastructure. Vous avez une prévision météo.
3) La concurrence doit promouvoir l’efficacité énergétique comme métrique de premier ordre
En 2026, le « coût » du calcul est dominé par l’énergie, le refroidissement, les limites de densité en rack et les humains qui maintiennent l’ensemble en vie. Le meilleur accélérateur est celui qui atteint vos objectifs de latence/débit sans vous forcer à redessiner le datacenter pour l’accueillir.
Une citation à agrafer au dossier des achats : « L’espoir n’est pas une stratégie. » — Général Gordon R. Sullivan. En ops, c’est pratiquement une philosophie de monitoring.
Petite blague #1 : Le marché des GPU est le seul endroit où « disponible » est considéré comme une fonctionnalité avancée.
Quelques faits et une histoire qui comptent encore
Six à dix faits concrets ne résoudront pas votre architecture, mais ils vous immuniseront contre le discours « c’est tout nouveau ». En voici neuf qui reviennent encore dans la prise de décision :
- CUDA (introduit en 2006) a transformé les GPU en plateforme de calcul généraliste grand public, pas seulement en matériel graphique. Cela a créé un puits de gravité de bibliothèques et d’habitudes développeur.
- AMD a racheté ATI en 2006, héritant des talents GPU et des gammes produits, puis a passé des années à concilier priorités graphiques et priorités compute.
- OpenCL (Khronos, 2009) promettait le calcul GPU inter-fournisseurs. Il a offert la portabilité en théorie, et la « douleur de performance portable » en pratique pour beaucoup de workloads.
- HBM (High Bandwidth Memory) est devenu un avantage déterminant pour les accélérateurs data-parallèles : ce n’est pas que les FLOPS, c’est nourrir les cœurs sans les affamer.
- PCIe a été le goulot d’étranglement perpétuel pour les mouvements de données GPU→CPU ; les montées de génération aident, mais une topologie négligée tue toujours la performance.
- NVLink a mis en avant la communication GPU→GPU à haute bande passante comme différenciateur produit, surtout pour l’entraînement qui nécessite un all-reduce rapide.
- ROCm a mûri de façon inégale selon les générations de GPU et les distributions Linux ; l’histoire s’est améliorée, mais la « matrice supportée » reste une vraie contrainte opérationnelle.
- oneAPI d’Intel est une tentative stratégique d’unifier la programmation CPU/GPU/accélérateurs — utile quand ça marche, frustrant quand l’écosystème autour ne suit pas.
- L’inférence a changé l’économie : l’entraînement fait la une, mais l’inférence en régime permanent à grande échelle est là où coût par token, consommation électrique et simplicité opérationnelle décident des gagnants.
Ces faits ne sont pas des anecdotes. Ils expliquent pourquoi le fossé logiciel de NVIDIA existe, pourquoi l’opportunité d’AMD réapparaît, et pourquoi l’histoire d’Intel est indissociable de la plateforme CPU et des relations enterprise.
Comment penser NVIDIA vs AMD vs Intel sans se mentir
La plupart des comparaisons sont soit des guerres de fans, soit du théâtre d’achats. Voici la vue production : traitez chaque fournisseur comme un paquet de silicium + pilote + runtime + bibliothèques + outillage + comportement de support + chaîne d’approvisionnement. Le GPU est le moindre de ces éléments.
NVIDIA : le choix par défaut, pour des raisons pas purement techniques
Le plus grand avantage de NVIDIA n’est pas la performance brute. C’est que CUDA est devenu le centre de gravité des outils ML, plus un long historique d’expérience développeur qui fonctionne « out of the box » plus souvent qu’autrement. En production, cela se traduit par :
- Un temps plus court pour atteindre le premier succès pour des équipes sans expertise profonde en compilateur/runtime.
- Une meilleure couverture d’écosystème : kernels, implémentations d’attention, runtimes d’inférence, outils de quantification, profilers.
- Un support plus prévisible dans les environnements Linux courants (toujours pas parfait ; rien ne l’est).
Le risque est clair : plus votre activité dépend de chemins de code exclusifs à CUDA, moins vous avez de pouvoir de négociation sur le prix, les délais de livraison et les priorités de feuille de route.
AMD : silicium crédible, maturité logicielle comme enjeu décisif
La proposition de valeur d’AMD est simple : fort potentiel de performance et chance de briser la monoculture. Mais en production, ROCm ne se juge pas sur des slides ; il se juge sur :
- Si votre combinaison exacte distro/kernel est supportée et stable.
- Si vos frameworks et kernels clés atteignent les performances attendues sans tuning héroïque.
- Si votre équipe peut déboguer et profiler les problèmes aussi rapidement que sur CUDA.
AMD peut gagner gros là où les clients standardisent leur environnement, valident soigneusement et exigent la responsabilité du fournisseur. Il perd là où les équipes attendent « installer et prier ».
Intel : le cheval noir qui compte parce que les entreprises existent
La position d’Intel est unique : il possède déjà une grande partie de la plateforme CPU, des relations d’achat et des canaux enterprise « ennuyeux mais critiques ». Le pari est que oneAPI et les GPU Intel peuvent offrir une voie d’accélération qui s’intègre aux flottes existantes.
En pratique, Intel est le plus intéressant quand :
- Vos workloads bénéficient déjà des CPU Intel et vous voulez une intégration plus étroite.
- Vous tenez à la stabilité fournisseur à long terme et aux modèles de support enterprise.
- Vous acceptez que certaines parties de l’écosystème soient moins matures que les chemins centrés CUDA.
À quoi ressemble une concurrence saine
Ce n’est pas « trois fournisseurs égaux sur tout ». Ça n’arrive jamais. Une concurrence saine, c’est :
- Au moins deux choix viables pour vos workloads principaux.
- Des architectures portables où votre logique métier ne se marie pas à une API fournisseur.
- Des benchmarks que vous exécutez vous-même, liés à vos données, vos tailles de batch, vos SLO de latence.
Piles logicielles : CUDA, ROCm, oneAPI et le vrai coût du « portable »
La portabilité n’est pas une case à cocher. La portabilité est un budget d’ingénierie. La bonne question n’est pas « est-ce que ça tourne sur plusieurs fournisseurs ? » mais « combien ça coûte de le maintenir sur plusieurs fournisseurs dans le temps ? »
Les trois couches que vous devriez séparer
Si vous voulez de l’optionnalité, concevez comme si vous alliez changer. Séparez :
- Couche framework : PyTorch, TensorFlow, JAX, XGBoost, piles de serving type Triton Inference Server.
- Couche kernel/bibliothèque : analogues cuDNN/hipDNN, BLAS, kernels d’attention, quantification, communication collective.
- Couche runtime/driver : runtime/driver CUDA, stack ROCm, runtimes Level Zero/oneAPI.
Votre portabilité vit et meurt dans la couche du milieu. C’est là que se cachent les kernels critiques pour la performance. Vous pouvez écrire du code modèle indépendant du fournisseur et être pourtant verrouillé par les implémentations de kernels que votre framework choisit au runtime.
Que faire en production
- Privilégiez les frameworks qui supportent déjà plusieurs backends pour votre classe de workload, même si vous déployez sur un fournisseur aujourd’hui.
- Évitez les extensions CUDA custom sauf obligation. Si vous devez en avoir, isolez-les derrière une interface propre et maintenez un fallback CPU pour les tests de correction.
- Construisez une « lane CI de portabilité » : exécutez un job hebdomadaire sur un fournisseur non-primaire pour garder l’option vivante.
Petite blague #2 : « On rendra ça portable plus tard » est la version logicielle de « Je commencerai les sauvegardes après ce déploiement ».
Réalité opérationnelle : les pilotes font partie de votre application
Dans le monde GPU, « l’app » inclut :
- Version du kernel
- Version du pilote GPU
- Firmware (GPU, NIC, parfois carte mère)
- Versions du runtime de conteneur et du device plugin
- Options de build des frameworks
Si vous ne pointez pas et ne validez pas ces éléments comme vous pointez et validez des changements de schéma de base de données, vous choisissez des pannes aléatoires.
Réalités matérielles : mémoire, interconnexions et pourquoi PCIe est toujours suspect
Quand la performance est mauvaise, on blâme « le GPU ». En pratique, c’est souvent la bande passante mémoire, la topologie ou une famine côté CPU. Voici les boutons qui font vraiment bouger l’aiguille.
Capacité et bande passante HBM : la contrainte silencieuse
Pour l’entraînement et l’inférence en gros batch, la capacité HBM détermine si vous pouvez garder activations et cache KV résidents. La bande passante HBM détermine si vos unités de calcul passent leur vie à attendre.
Règle décisionnelle : si vous voyez une faible utilisation compute mais une forte pression sur le contrôleur mémoire, vous n’avez pas besoin de « plus de TFLOPS ». Vous avez besoin d’un meilleur comportement mémoire : kernels fusionnés, meilleure taille de batch, quantification, ou un SKU différent avec plus de bande passante.
Liens GPU→GPU et GPU→CPU : la topologie compte plus que la marque
L’interconnect est l’endroit où l’entraînement multi-GPU vit ou meurt. Si votre all-reduce est lent, vous pouvez avoir le meilleur GPU sur le papier et perdre face à une machine moins chère avec une meilleure topologie. Vous devez savoir :
- Le trafic GPU–GPU passe-t-il sur un tissu de type NVLink ou rebondit-il sur PCIe ?
- Les GPU sont-ils répartis sur des sockets CPU avec un mauvais alignement NUMA ?
- La NIC est-elle placée sur le « mauvais » root complex, forçant des sauts cross-socket ?
Puissance et thermique : des falaises de performance invisibles dans les benchmarks
Le throttle thermique est un tueur silencieux dans les racks denses. Vous pouvez être « sain » et quand même manquer vos SLO parce que les fréquences s’effondrent sous charge soutenue. Votre monitoring devrait traiter les fréquences GPU et la consommation comme des métriques de première classe, pas des détails.
Achats pour SRE : les questions que votre fournisseur ne vous posera pas
Les conversations d’achat sont généralement dominées par le prix et le throughput de pointe. En ops, vous devez vous soucier de : mean time to recover, change management, et hétérogénéité de la flotte.
Ce que vous devez exiger avant d’acheter
- Une matrice logicielle supportée : versions exactes d’OS, plages de kernel, versions de pilote, et attentes sur le runtime de conteneur.
- Une stratégie de mise à jour firmware : comment patcher à grande échelle, à quelle fréquence, et ce qui casse ?
- Attentes RMA et de pièces de rechange : délais, cross-ship, et à quoi ressemble une « panne » dans leurs logs.
- Compatibilité télémétrie : pouvez-vous extraire les métriques nécessaires sans agents propriétaires qui se battent avec votre environnement ?
- Docs claires de topologie d’interconnect pour le SKU serveur que vous achetez réellement, pas un design de référence.
Ce que vous devez construire en interne
- Une image golden par pile fournisseur avec versions épinglées.
- Une lane de canary pour les upgrades qui exécute des workloads représentatifs d’entraînement et d’inférence.
- Un harness de benchmark qui mesure non seulement le throughput, mais la latence tail, le comportement de warmup et la récupération sur panne.
Playbook de diagnostic rapide : quoi vérifier en premier/deuxième/troisième pour trouver le goulot d’étranglement rapidement
Voici la séquence « arrêtez de discuter, commencez à mesurer ». Elle fonctionne entre fournisseurs car elle se base sur la physique et les systèmes d’exploitation, pas sur l’identité d’une marque.
Premier : le GPU est-il réellement utilisé ?
- Vérifiez l’utilisation, les fréquences, la consommation, et l’utilisation mémoire.
- Si l’utilisation est faible mais que le job est « lent », vous êtes probablement lié au CPU, à l’I/O, ou bloqué sur une synchronisation.
Second : le mouvement de données est-il le vrai goulot ?
- Recherchez un RX/TX PCIe élevé avec peu de compute.
- Vérifiez la largeur/vitesse du lien PCIe (x16 vs x8 ; Gen5 vs Gen4) et la localité NUMA.
- Pour le multi-GPU, validez la bande passante peer-to-peer et collective.
Troisième : le framework ne tombe-t-il pas sur un chemin lent ?
- Confirmez que le backend prévu est actif (CUDA/ROCm/oneAPI) et que les ops clés utilisent des kernels accélérés.
- Surveillez les logs pour des avertissements de « fallback » et des placements de device inattendus.
Quatrième : le nœud est-il stable sous charge soutenue ?
- Vérifiez le throttling (thermique/puissance), les erreurs ECC, et les resets de pilote.
- Consultez les logs kernel pour des erreurs PCIe/AER et des événements de type Xid GPU.
Cinquième : l’ordonnanceur du cluster vous ment-il ?
- Validez la santé du device plugin, les contraintes cgroup, la configuration MIG/partitioning, et l’intégration du runtime de conteneur.
- Confirmez que vous ne sur-allouez pas CPU/mémoire pour les jobs GPU (commun dans Kubernetes).
Tâches pratiques : commandes, signification des sorties, et décision à prendre
Ce sont des vérifications réelles et exécutables. Utilisez-les lors d’incidents, de planification de capacité et d’évaluations fournisseurs. Le but n’est pas de collectionner des trivia ; c’est de prendre des décisions.
Task 1: Identify GPUs and the driver in use
cr0x@server:~$ lspci -nn | egrep -i 'vga|3d|display'
01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2330] (rev a1)
21:00.0 Display controller [0380]: Advanced Micro Devices, Inc. [AMD/ATI] Device [1002:74a1] (rev c1)
Ce que cela signifie : Vous voyez quels périphériques fournisseur sont présents et leurs PCI IDs. Les flottes mixtes sont normales ; des pilotes mixtes sur un même nœud le sont généralement moins.
Décision : Si le périphérique ne correspond pas à ce que vous pensez avoir déployé, arrêtez. Corrigez l’inventaire et l’ordonnancement avant d’optimiser quoi que ce soit.
Task 2: Check kernel and OS details (driver compatibility starts here)
cr0x@server:~$ uname -r
6.5.0-17-generic
Ce que cela signifie : La version du kernel affecte les modules DKMS, le comportement IOMMU et les matrices de support des fournisseurs.
Décision : Si vous êtes en dehors de la plage de kernels supportée par le fournisseur, vous débrouillez un projet scientifique. Passez à un kernel supporté.
Task 3: NVIDIA quick health view (utilization, power, clocks)
cr0x@server:~$ nvidia-smi
Tue Jan 21 02:31:09 2026
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.14 Driver Version: 550.54.14 CUDA Version: 12.4 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA H100 PCIe On | 00000000:01:00.0 Off | 0 |
| N/A 61C P0 280W / 350W| 62480MiB / 81559MiB | 92% Default |
+-----------------------------------------+----------------------+----------------------+
Ce que cela signifie : Une forte GPU-Util avec une puissance élevée et un état P0 stable suggère que le GPU travaille. Une faible utilisation avec une mémoire élevée signifie souvent mémoire résidente mais compute inactif (pipeline de données, sync, ou inefficacité des kernels).
Décision : Si GPU-Util est faible, concentrez-vous sur CPU/I/O/ordonnancement et les fallback du framework.
Task 4: AMD ROCm health view (if ROCm is installed)
cr0x@server:~$ rocm-smi
========================ROCm System Management Interface========================
GPU[0] : GPU ID: 0x74a1
GPU[0] : Temp (Sensor edge) (C): 58.0
GPU[0] : Average Graphics Package Power (W): 240.0
GPU[0] : VRAM Total (B): 68719476736
GPU[0] : VRAM Used (B): 42949672960
GPU[0] : GPU use (%): 88
Ce que cela signifie : Même logique que pour NVIDIA : utilisation/power/temp vous indiquent si l’accélérateur est engagé et s’il est thermiquement stressé.
Décision : Si l’utilisation est élevée mais le throughput faible, suspectez la bande passante mémoire ou le choix de kernel ; passez au profiler et aux logs du framework.
Task 5: Intel GPU enumeration (Level Zero)
cr0x@server:~$ /usr/bin/zeinfo | head
Level Zero API version: 1.13
Driver version: 1.3.29735
Devices:
Device 0: Intel(R) Data Center GPU
Ce que cela signifie : Confirme que le runtime Level Zero voit le périphérique et qu’un pilote est chargé.
Décision : Si le runtime n’énumère pas les appareils, corrigez l’installation pilote/runtime avant de toucher les configs applicatives.
Task 6: Check PCIe link speed/width (common silent failure)
cr0x@server:~$ sudo lspci -s 01:00.0 -vv | egrep -i 'LnkCap|LnkSta'
LnkCap: Port #0, Speed 32GT/s, Width x16
LnkSta: Speed 16GT/s (downgraded), Width x8 (downgraded)
Ce que cela signifie : La carte peut fonctionner en PCIe Gen5 x16, mais elle tourne actuellement en Gen4 x8. C’est une taxe de performance, parfois un désastre.
Décision : Traitez cela comme un incident hardware/BIOS/topologie : reseat, vérifiez les risers, les réglages BIOS, le partage de lanes et la disposition de la carte mère.
Task 7: Check NUMA topology (GPU placed far from your CPU threads)
cr0x@server:~$ numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0-31
node 1 cpus: 32-63
node 0 size: 256000 MB
node 1 size: 256000 MB
Ce que cela signifie : Système dual-socket. Si votre GPU est attaché au nœud 1 mais que votre dataloader tourne sur le nœud 0, vous payez la latence et le coût en bande passante cross-socket.
Décision : Épinglez les threads CPU et l’allocation mémoire au nœud NUMA local au GPU pour le throughput et la stabilité de la latence tail.
Task 8: Map PCI devices to NUMA nodes
cr0x@server:~$ cat /sys/bus/pci/devices/0000:01:00.0/numa_node
1
Ce que cela signifie : Ce GPU est local au nœud NUMA 1.
Décision : Exécutez votre pipeline d’entrée et le prétraitement CPU sur le nœud 1 (ou acceptez le coût en connaissance de cause).
Task 9: Check IOMMU settings (can hurt latency and peer-to-peer)
cr0x@server:~$ dmesg | egrep -i 'iommu|dmari' | head
[ 0.112345] DMAR: IOMMU enabled
[ 0.112900] DMAR: Intel(R) Virtualization Technology for Directed I/O
Ce que cela signifie : IOMMU est activé. C’est souvent nécessaire pour la virtualisation et l’isolation, mais des configurations erronées peuvent casser le P2P ou réduire la performance.
Décision : Si vous avez besoin de peer-to-peer GPU ou du maximum de débit, validez le mode IOMMU recommandé par le fournisseur (activé, passthrough, ou paramètres kernel spécifiques) et testez.
Task 10: Find GPU-related kernel errors (AER, resets, Xid-like events)
cr0x@server:~$ sudo journalctl -k -S -2h | egrep -i 'nvrm|xid|amdgpu|pcie|aer|gpu reset' | tail
Jan 21 01:44:10 server kernel: pcieport 0000:00:01.0: AER: Corrected error received: id=00e0
Jan 21 01:44:10 server kernel: amdgpu 0000:21:00.0: GPU reset begin!
Jan 21 01:44:14 server kernel: amdgpu 0000:21:00.0: GPU reset succeeded
Ce que cela signifie : Erreurs PCIe corrigées et un reset GPU. Même les erreurs « corrigées » corrèlent avec des risers instables, une alimentation marginale ou des lanes dégradées.
Décision : Si vous voyez des resets sous charge, cessez de blâmer le modèle. Quarantainez le nœud, lancez des diagnostics hardware et engagez le fournisseur.
Task 11: Confirm container runtime sees GPUs (Kubernetes or standalone)
cr0x@server:~$ docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.14 Driver Version: 550.54.14 CUDA Version: 12.4 |
+---------------------------------------------------------------------------------------+
Ce que cela signifie : Le conteneur peut accéder au GPU et la pile pilote est correctement acheminée via le runtime.
Décision : Si cela échoue, corrigez le runtime de conteneur/device plugin/permissions avant de toucher le code applicatif.
Task 12: Check Kubernetes GPU allocation (are you actually scheduled on a GPU?)
cr0x@server:~$ kubectl describe pod infer-7c9b6d6c6f-2kqnx | egrep -i 'node:|nvidia.com/gpu|amd.com/gpu|intel.com/gpu|limits|requests'
Node: gpu-node-12/10.10.12.34
Limits:
nvidia.com/gpu: 1
Requests:
nvidia.com/gpu: 1
Ce que cela signifie : Le pod est planifié avec une ressource GPU en limits/requests, et vous voyez quel nœud il utilise.
Décision : Si requests/limits manquent, vous êtes sur CPU et votre « lenteur GPU » est en réalité « pas de GPU ». Corrigez le manifest et les admission controls.
Task 13: Check CPU throttling and steal time (GPU jobs can be CPU-starved)
cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0-17-generic (server) 01/21/2026 _x86_64_ (64 CPU)
02:32:01 AM CPU %usr %sys %iowait %steal %idle
02:32:02 AM all 85.1 8.2 1.3 0.0 5.4
02:32:03 AM all 88.0 9.1 0.7 0.0 2.2
Ce que cela signifie : Le CPU est fortement chargé ; si votre dataloader et le networking tournent sur le CPU, l’utilisation GPU peut chuter en attendant l’entrée.
Décision : Augmentez l’allocation CPU pour les pods GPU, ajustez les workers du dataloader, ou déplacez le prétraitement en dehors des nœuds critiques.
Task 14: Check disk I/O saturation (training input pipeline)
cr0x@server:~$ iostat -xz 1 3
Device r/s rkB/s await %util
nvme0n1 120.0 98000.0 18.2 99.5
Ce que cela signifie : NVMe est saturé à ~100% d’utilisation et await élevé. Votre GPU attend probablement les données.
Décision : Mettez en cache local les datasets, améliorez le sharding, augmentez le read-ahead, ou passez à un stockage plus performant. N’achetez pas plus de GPU pour résoudre un goulot disque.
Task 15: Check network health (distributed training all-reduce, remote storage)
cr0x@server:~$ ip -s link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
RX: bytes packets errors dropped missed mcast
9834212345 8123456 0 0 0 0
TX: bytes packets errors dropped carrier collsns
11233455667 9234567 0 0 0 0
Ce que cela signifie : Les erreurs et drops sont à zéro (bon signe). Si vous voyez erreurs/drops en hausse, l’entraînement distribué paraîtra comme une « lenteur GPU » mais sera en réalité des retransmissions et de la congestion.
Décision : Corrigez le firmware NIC, le câblage, la config du switch, ou isolez les collectives sur un tissu dédié.
Task 16: Verify hugepages and memory pressure (page faults hurt)
cr0x@server:~$ grep -E 'HugePages_Total|HugePages_Free|MemAvailable' /proc/meminfo
MemAvailable: 182345672 kB
HugePages_Total: 4096
HugePages_Free: 3900
Ce que cela signifie : Les hugepages sont majoritairement libres et la mémoire est disponible ; bon état. Si MemAvailable est faible, le paging côté CPU peut bloquer les pipelines de données et augmenter la latence.
Décision : Empêchez la sur-allocation mémoire sur les nœuds GPU ; définissez des limites de pod appropriées ; isolez des nœuds pour les workloads GPU.
Trois mini-histoires d’entreprise (comment ça foire dans des sociétés réelles)
Mini-histoire 1 : L’incident causé par une mauvaise hypothèse
L’entreprise avait un cluster d’inférence tout neuf. Même modèle, même image conteneur, mêmes manifests Kubernetes. Le plan de déploiement était propre : ajouter des nœuds progressivement, laisser l’autoscaler faire le reste. Le dashboard semblait correct — les pods tournaient, les GPU étaient « alloués » et le service répondait.
Puis la latence tail a doublé. Rien d’évident n’était cassé. L’utilisation GPU était faible, l’utilisation CPU élevée, et les logs applicatifs étaient remplis d’avertissements innocents que personne n’avait jamais lus.
La mauvaise hypothèse : « Si le pod demande un GPU, il utilisera le GPU. » En réalité, le runtime modèle dans le conteneur ne correspondait pas à la pile pilote sur les nouveaux nœuds. Le framework a détecté une incompatibilité et est silencieusement retombé sur le CPU pour plusieurs ops clés. Pas tous les ops — juste assez pour que le service « fonctionne », mais trop lent pour respecter les SLO.
La correction a été ennuyeuse : aligner la version du pilote avec le runtime attendu par le conteneur, ajouter un check de démarrage qui fait échouer le pod si le backend n’est pas actif, et imposer un labeling des nœuds pour que les nœuds incompatibles ne soient pas sélectionnés. Le postmortem a été encore plus ennuyeux : « Nous aurions dû tester l’image exacte du nœud en canary. » Exact. Et douloureux.
Mini-histoire 2 : L’optimisation qui a échoué
Une équipe d’entraînement voulait accélérer les époques. Ils avaient une nouvelle machine multi-GPU avec un interconnect rapide et ont décidé d’augmenter les workers du dataloader et le prefetching. Ça a marché dans un petit test : l’utilisation GPU a augmenté et les steps se sont accélérés.
En exécution complète, la performance a décliné sur plusieurs heures. Pas immédiatement, ce qui en a fait un grand mystère et une grande perte de temps. Les GPU ont commencé à osciller : des pics d’utilisation suivis de plages inactives. Finalement, les nœuds ont commencé à rapporter des erreurs PCIe corrigées, puis des resets GPU occasionnels.
L’« optimisation » a augmenté la charge CPU et le churn mémoire, ce qui a augmenté la température du châssis et poussé la plateforme vers une stabilité marginale. Les GPU allaient bien ; le serveur non. Sous charge soutenue, une combinaison de thermique et d’intégrité de signal PCIe limite a provoqué des resets. Le cluster ressemblait à un problème logiciel parce que le job redémarrait et continuait — juste plus lent, plus bruyant, et avec un backlog croissant.
La solution a été de réduire la pression côté CPU, d’améliorer la gestion du flux d’air, et de définir des limites de puissance/fréquence pour éviter les falaises thermiques. La leçon : si un tweak de performance change la consommation, vous avez aussi changé la fiabilité. Traitez-le comme un changement de production, pas comme une expérience de notebook.
Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une équipe infra gérait une flotte multi-fournisseurs : certains nœuds pour l’entraînement sur un fournisseur, d’autres pour des expérimentations d’inférence sur un autre. Ils étaient constamment tentés de « standardiser plus tard », mais faisaient une chose de façon constante : ils épinglaient une image golden par classe de nœud, avec un ensemble pilote/kernel/conteneur validé. Pas de snowflakes, pas de hotfixs manuels.
Pendant un cycle de patch de sécurité, une mise à jour du kernel a traversé la flotte compute générale. Les nœuds GPU ont été exclus par politique. Quelqu’un s’est plaint — « pourquoi les nœuds GPU sont spéciaux ? » — et la réponse a été la même que toujours : parce que les mismatches kernel/driver ne sont pas une façon agréable de passer les weekends.
Deux semaines plus tard, une mise à jour de pilote fournisseur a été publiée pour adresser une stabilité sous un certain pattern de workload. L’équipe l’a déployée sur une petite pool canary, a exécuté une suite complète de benchmarks d’entraînement et d’inférence, et a surveillé les logs pour erreurs PCIe corrigées et throttling. Ce n’est qu’ensuite qu’ils l’ont déployée largement.
Le gain est arrivé silencieusement : tandis que d’autres équipes géraient des régressions mystérieuses après la mise à jour du kernel, cette équipe avait des baselines propres et un chemin de mise à jour contrôlé. L’incident ne leur est jamais arrivé. Voilà le but de la correction ennuyeuse — elle empêche l’existence des histoires au départ.
Erreurs courantes : symptôme → cause racine → correction
1) Symptom: GPU utilization is low, but the job is slow
Cause racine : Pipeline d’entrée lié au CPU, goulot disque, ou fallback du framework sur le CPU pour des ops clés.
Correction : Vérifiez CPU (mpstat), disque (iostat) et logs d’activation du backend. Échouez rapidement si le backend n’est pas actif. Épinglez CPU/mémoire au nœud NUMA local au GPU.
2) Symptom: Multi-GPU training is slower than single GPU scaling math
Cause racine : Goulot de communication collective (placement NIC, topologie, mauvaise utilisation de l’interconnect), ou tailles de batch petites provoquant la dominance de la surcharge de sync.
Correction : Vérifiez la topologie (PCIe/links de type NVLink), assurez la localité NIC, ajustez tailles de batch et accumulation de gradient, et isolez le réseau pour les collectives.
3) Symptom: Great performance in a benchmark, mediocre in production
Cause racine : Le benchmark tient en cache/HBM et ne modélise pas l’I/O réel, les patterns de requêtes ou la latence tail. Throttling thermique sous charge soutenue.
Correction : Benchmarquez avec des séquences réalistes, de la concurrence et des durées soutenues. Surveillez fréquences et puissance sous charge prolongée. Définissez des power caps stables si nécessaire.
4) Symptom: Random “device disappeared” / GPU resets
Cause racine : Erreurs PCIe/AER, risers marginaux, alimentation insuffisante, ou bugs pilote/firmware déclenchés sous charge.
Correction : Quarantainez le nœud. Vérifiez journalctl -k pour AER/logs de reset GPU. Validez largeur/vitesse du lien PCIe. Mettez à jour firmware/driver en canary, puis déployez.
5) Symptom: Inference latency spikes every few minutes
Cause racine : Compaction en arrière-plan, lectures de dataset, churn de l’autoscaler, garbage collection CPU, ou changements d’horloge GPU dus à la gestion de puissance.
Correction : Chauffez les modèles, pré-allouez des pools mémoire, épinglez les fréquences/puissance si approprié, et éliminez les voisins bruyants (isolation CPU et I/O).
6) Symptom: Porting from CUDA to “portable” backend compiles but is much slower
Cause racine : Kernels optimisés manquants (attention, layernorm, variantes GEMM), comportement de fusion différent, ou fallback vers des implémentations génériques.
Correction : Profilez et identifiez les ops chauds, puis choisissez des bibliothèques qui fournissent des kernels optimisés pour le backend cible. Gardez l’architecture du modèle flexible quand c’est possible.
7) Symptom: Kubernetes shows GPUs allocated, but inside container no GPU is visible
Cause racine : Mismatch device plugin, mauvaise config du runtime conteneur, permissions insuffisantes, ou hooks conteneur fournisseur manquants.
Correction : Validez avec un test conteneur GPU minimal, vérifiez les logs du device plugin, et standardisez la configuration runtime à travers les pools de nœuds.
Listes de contrôle / plan pas-à-pas
Step-by-step: selecting a vendor (or mixing vendors) without regrets
- Écrivez votre vraie mixité de workloads. Entraînement vs inférence, tailles de batch, modes de précision, longueurs de séquence, empreinte mémoire et patterns de communication.
- Définissez deux métriques par workload : une performance (throughput ou time-to-train) et une métrique business (coût par token, coût par époque, puissance par requête).
- Choisissez trois tests représentatifs que vous pouvez exécuter sur chaque plateforme candidate : (a) inférence en régime permanent, (b) run d’entraînement long, (c) test de récupération sur panne (drain de nœud + reschedule).
- Construisez une image golden par plateforme avec kernel/pilote/runtime épinglés et une chaîne de build reproductible.
- Validez la topologie (vitesse/largeur PCIe, localité NUMA, placement NIC) avant d’exécuter un benchmark. Sinon vous benchmarkez vos erreurs.
- Exécutez des tests soutenus (heures, pas minutes). Surveillez fréquences, températures, erreurs PCIe corrigées et resets.
- Décidez explicitement votre posture de portabilité : « CUDA-first mais architecture portable », ou « CI multi-backend », ou « fournisseur unique pour l’instant ». Prétendre faire les trois tue les budgets.
- Operationalisez les upgrades : lane canary, plan de rollback, et checks health automatisés qui échouent vite sur les chemins de fallback.
- Négociez le support comme un SRE : exigez des chemins d’escalade clairs pour les problèmes de pilote, et définissez les logs/télémétrie requis pour ouvrir un dossier.
Checklist: before you blame the GPU vendor
- Le lien PCIe n’est pas dégradé (vitesse et largeur correspondent aux attentes).
- L’alignement NUMA est correct pour les threads CPU et allocations mémoire.
- Pas d’erreurs PCIe corrigées dans les logs kernel sous charge.
- Le pipeline de stockage n’est pas saturé.
- Les erreurs/drops réseau sont à zéro pour les jobs distribués.
- Le framework utilise le backend prévu et ne retombe pas silencieusement.
- Thermiques et puissance stables ; pas de throttling soutenu.
Checklist: how to keep competition alive inside your org
- Gardez au moins un pool de nœuds d’un fournisseur non-primaire, même petit.
- Exécutez un job de portabilité hebdomadaire : compiler, exécuter les tests de correction, enregistrer les deltas de perf.
- Interdisez les extensions spécifiques fournisseur sauf si ROI mesuré et plan de sortie.
- Suivez les « blockers de migration » comme dette technique : assignez des propriétaires et des budgets.
FAQ
1) Should we standardize on one vendor to reduce operational complexity?
Standardisez votre processus, pas votre fournisseur. Une flotte mono-fournisseur est plus simple jusqu’à ce qu’elle ne le soit plus — prix, délais et surprises de roadmap sont aussi de la complexité opérationnelle. Si vous le pouvez, gardez un petit pool second-fournisseur pour préserver du levier et la « muscle » de portabilité.
2) Is CUDA lock-in always bad?
Non. CUDA peut être le chemin le plus rapide vers la production et souvent le mieux supporté. Le verrouillage devient mauvais quand vous construisez des kernels custom uniquement CUDA partout et ne pouvez pas négocier le prix ou pivoter quand l’approvisionnement se tarit. Utilisez CUDA, mais architectez pour l’optionnalité.
3) What’s the number one hidden performance killer?
PCIe et les problèmes de topologie. Un lien dégradé (Gen5 x16 tournant en Gen4 x8) ou du trafic cross-socket peut effacer l’avantage d’un GPU plus cher.
4) For inference, what matters more: compute or memory?
Souvent la mémoire — capacité et bande passante — parce que le KV cache et les activations dominent. Le compute compte aussi, mais beaucoup de workloads d’inférence sont limités par le déplacement des données, pas par les calculs.
5) Can we rely on “portable” APIs and expect near-equal performance?
Attendez-vous à la portabilité fonctionnelle, pas à la parité de performance. La performance vient des kernels tunés, des stratégies de fusion et des bibliothèques matures. La portabilité vaut le coup ; prévoyez juste du tuning spécifique au backend.
6) How do we prevent silent CPU fallback?
Ajoutez des checks explicites au démarrage de votre service/job qui vérifient que le backend est actif et qu’une petite opération tensorielle s’exécute sur le device. Sinon, crasher tôt et fort. « Ça fonctionne mais c’est lent » est le pire mode de défaillance.
7) Do we need separate golden images per vendor?
Oui, si vous voulez garder la raison. Traitez le combo pilote/runtime/kernel comme faisant partie de l’application. Épinglez-le, testez-le, et déployez-le comme des migrations de base de données.
8) What’s a sane way to benchmark vendors?
Utilisez vos vrais modèles et vos vrais patterns de requêtes. Exécutez des tests soutenus. Mesurez la latence tail, la stabilité (resets, erreurs corrigées) et la friction opérationnelle (outillage, facilité de mise à jour). Si vous ne mesurez que le throughput de pointe pendant cinq minutes, vous benchmarquez l’optimisme.
9) Are power caps a hack or a best practice?
C’est une bonne pratique quand vous touchez des falaises thermiques ou d’alimentation. Une fréquence de pointe légèrement inférieure avec une performance soutenue stable vaut mieux qu’un nœud instable qui reset sous charge.
10) What’s the simplest way to keep multi-vendor optionality?
Gardez votre code modèle propre d’extensions propres au fournisseur, exécutez périodiquement un job sur un second backend, et évitez de construire votre stack de serving autour des fonctionnalités propriétaires d’un fournisseur sauf si vous avez un besoin business mesuré.
Prochaines étapes que vous pouvez réellement exécuter
Si vous voulez que la concurrence maintienne le marché sain, vous devez garder votre propre architecture saine. Cela signifie que vous pouvez changer, ou au moins menacer crédiblement de le faire. Voici le chemin pratique :
- Instrumentez d’abord : ajoutez utilisation GPU, fréquences, puissance, mémoire, erreurs PCIe et signaux de sélection de backend à votre monitoring. Si vous ne le voyez pas, vous ne pouvez pas le négocier.
- Construisez une lane de portabilité : un run CI hebdomadaire sur un nœud fournisseur non-primaire. Il n’a pas besoin d’être rapide. Il doit être réel.
- Renforcez votre flotte : images golden, versions épinglées, rollouts canary et health checks automatisés qui échouent vite sur les chemins de fallback.
- Benchmarquez comme un opérateur : runs soutenus, données réelles, concurrence réelle, et injection de panne (drain de nœud, restart, reschedule) pour mesurer le comportement de récupération.
- Procurez-vous comme un SRE : docs de topologie, matrices supportées, stratégie firmware et chemins d’escalade support ne sont pas « agréables à avoir ». Ce sont la différence entre livrer et éteindre des incendies.
Le marché continuera à faire ce que font les marchés : se concentrer, extraire une rente, et appeler ça de « l’innovation ». Votre travail est de maintenir des options — techniquement et commercialement — pour que vos systèmes de production ne deviennent pas un monument aux marges de quelqu’un d’autre.