L’IA sur GPU : comment votre carte graphique est devenue un superordinateur domestique

Cet article vous a aidé ?

Entre « pourquoi mon modèle met 45 minutes pour une seule exécution ? » et « pourquoi mon poste a redémarré en plein entraînement ? », on découvre la vérité : l’IA ne veut pas seulement du calcul. Elle veut le bon type de calcul, alimenté par le stockage adéquat, refroidi par un flux d’air correct et encadré par des attentes réalistes.

Les charges de travail modernes en IA ne se mettent pas à l’échelle linéairement avec « plus de cœurs ». Elles dépendent de la bande passante mémoire, du débit en opérations matricielles et de la plomberie peu glamorous autour. C’est pourquoi votre GPU — initialement conçu pour ombrer des pixels — se comporte maintenant comme un petit superordinateur que vous pouvez acheter en boutique et installer à côté de la gamelle du chat.

Pourquoi les GPU ont gagné en IA

L’IA aime trois choses : beaucoup de calcul parallèle, des schémas d’accès mémoire prévisibles (ou du moins que l’on peut forcer à l’être), et un énorme débit. Les CPU sont excellents pour exécuter des systèmes d’exploitation et prendre mille petites décisions par seconde. Les GPU excellent à appliquer la même opération à beaucoup de données en parallèle.

Les réseaux neuronaux — en particulier les transformers — sont essentiellement des pipelines d’algèbre linéaire de haut niveau avec des non-linéarités occasionnelles en guise de garniture. Chaque fois que vous voyez un terme comme « GEMM » (general matrix multiply), c’est l’endroit où le GPU s’épanouit. Le GPU ne « réfléchit » pas. Il manipule des calculs. Rapidement. En parallèle. Encore et encore.

Il y a aussi l’économie. Les GPU sont produits en masse pour le jeu, les graphismes professionnels et les stations de travail. Cela signifie que la chaîne d’approvisionnement, l’échelle de fabrication et la concurrence ont poussé les performances vers le haut et le prix vers le bas (par rapport à des accélérateurs sur mesure). Vous pouvez acheter une quantité ridicule de calcul dans une boîte qui tient encore sous un bureau. « Superordinateur domestique » n’est pas une poésie marketing ; c’est une description maladroitement précise.

Conseil sans compromis : si vous essayez de faire tourner de l’IA en local et que vous dépensez de l’argent, investissez d’abord dans la VRAM et l’alimentation. Le nombre brut de cœurs est un piège si vous ne pouvez pas loger le modèle ou l’alimenter en données.

Ce qu’est vraiment un GPU (et pourquoi l’IA l’adore)

SIMT, warps et pourquoi votre kernel « devrait être ennuyeux »

Les GPU modernes NVIDIA exécutent des threads par groupes (warps). AMD a un concept similaire (wavefronts). Dans un warp, les threads exécutent la même instruction en même temps — juste sur des données différentes. Si votre code diverge (des threads prennent des branches différentes), le GPU sérialise ces branches. C’est le premier précipice de performance. C’est aussi pourquoi de nombreux kernels haute performance semblent avoir été écrits par quelqu’un qui se méfie de la créativité.

Les frameworks d’IA évitent la logique branchée dans le chemin chaud. Ils fusionnent de grosses opérations en kernels uniques : « multiplier, additionner, layernorm, activation », le tout en une passe quand c’est possible. Cela réduit les allers-retours mémoire, améliore le comportement du cache et maintient les SM occupés.

Tensor cores : le matériel qui a « changé les règles »

Les tensor cores (et autres moteurs matriciels similaires) sont des unités spécialisées conçues pour les calculs matriciels en formats de faible précision : FP16, BF16, et maintenant FP8 dans les architectures récentes. Ce n’est pas « bâcler ». C’est de l’ingénierie : les réseaux neuronaux tolèrent souvent la précision réduite, surtout en inférence. Cette tolérance se convertit en débit. Beaucoup de débit.

Mais la faible précision n’est pas gratuite. Elle peut déstabiliser l’entraînement si vous ne gérez pas correctement le scaling et l’accumulation. L’entraînement en précision mixte fonctionne parce que les frameworks conservent soigneusement certaines opérations en précision supérieure (comme les accumulateurs) tout en poussant la majeure partie des calculs en basse précision.

VRAM : la vraie limite de capacité

Sur un poste, la VRAM est la frontière dure. Une fois dépassée, vous plantez, basculez sur le CPU ou commencez à utiliser des chemins mémoire plus lents qui transforment votre « superordinateur » en un chauffage triste. Si vous ne retenez qu’une chose : pour les gros modèles, la VRAM est le budget, pas le nom marketing du GPU.

Petite blague #1 : La VRAM, c’est comme l’espace dans un placard — on ne la remarque pas jusqu’au déménagement et qu’on réalise que votre manteau vit maintenant dans la cuisine.

PCIe et le « problème du bus »

Le GPU n’est pas un univers autonome. Les données doivent y parvenir. Le CPU prépare le travail et lance les kernels. Le sous-système de stockage lit les jeux de données. Le bus PCIe transfère les données. Si vous entraînez ou faites de l’inférence en grands lots, vous pouvez facilement être limité par le bus. C’est pourquoi des systèmes avec le « même GPU » peuvent avoir des performances très différentes.

Dans les systèmes multi-GPU, NVLink (lorsqu’il est disponible) peut réduire la douleur. Sans lui, vous payez souvent un prix élevé pour transférer des tenseurs via PCIe.

Faits historiques qui expliquent le bazar actuel

L’IA sur GPU n’est pas apparue parce qu’un ingénieur a eu un moment d’eureka. Elle est née de la collision de plusieurs industries : jeu, calcul scientifique et apprentissage à l’échelle Web. Voici des éléments concrets d’histoire qui rendent le paysage actuel moins mystérieux :

  1. Début des années 2000 : des chercheurs utilisaient les API graphiques (OpenGL/DirectX) pour du calcul général parce que les opérations GPU étaient bon marché et abondantes.
  2. 2006 : CUDA arrive et rend les GPU programmables sans prétendre que votre réseau neuronal est un pixel shader.
  3. 2012 : l’entraînement accéléré sur GPU d’AlexNet devient un tournant pour l’adoption pratique du deep learning.
  4. Milieu des années 2010 : cuDNN transforme le « deep learning GPU » d’un ensemble de kernels héroïques en quelque chose qu’un framework peut raisonnablement abstraire.
  5. 2017 : les transformers montrent que les modèles centrés sur l’attention se mettent bien à l’échelle et ont un appétit pour le débit matriciel — très favorable aux GPU.
  6. 2018–2020 : l’entraînement en précision mixte devient courant, popularisant FP16/BF16 dans les workflows quotidiens.
  7. Depuis 2022 : la demande des consommateurs pour l’inférence locale augmente ; la quantification et les kernels d’attention efficaces deviennent des termes familiers chez les amateurs.
  8. Tout au long : la bande passante mémoire s’est imposée comme un facteur limitant central ; la HBM dans les GPU datacenter devient un différenciateur clé.

Idée paraphrasée (pas mot à mot) : « Tout échoue, tout le temps. » — Werner Vogels, sur l’état d’esprit de fiabilité selon lequel les systèmes doivent être conçus en s’attendant à l’échec.

Les vrais goulets d’étranglement : calcul, VRAM, bande passante, stockage et « oups »

1) Le calcul n’est pas un seul chiffre

Le marketing GPU met en avant les TFLOPS. Utile, mais incomplet. La performance IA dépend de : le débit en basse précision (FP16/BF16/FP8), l’utilisation des tensor cores, l’efficacité des kernels et la fréquence à laquelle vous êtes bloqué par la mémoire.

Deux GPU peuvent afficher des TFLOPS similaires et se comporter différemment parce que l’un a plus de bande passante mémoire, des caches plus grands, un meilleur ordonnancement ou simplement un meilleur support de kernels dans la version du framework que vous utilisez.

2) VRAM et fragmentation

Manquer de VRAM est évident. La fragmentation est plus sournoise : vous pouvez avoir « assez de mémoire libre » au total, mais pas suffisamment de blocs contigus pour satisfaire une grosse allocation. Certains allocateurs peuvent atténuer cela (PyTorch a des réglages), mais la meilleure solution est de concevoir les charges pour éviter les schémas d’allocation pathologiques : réutiliser les tampons, garder des formes stables et ne pas changer la taille des modèles à chaud dans un processus de longue durée.

3) Bande passante mémoire : le limiteur silencieux

Beaucoup d’opérations IA sont limitées par la mémoire : vous déplacez des tenseurs plus que vous ne faites des calculs sur eux. Si votre utilisation est basse mais que le contrôleur mémoire du GPU est occupé, vous êtes probablement limité par la bande passante. Cela suggère : réduire la précision, mieux fusionner, utiliser des implémentations d’attention plus efficaces ou réduire les activations intermédiaires (checkpointing) en entraînement.

4) Stockage et pipeline d’entrée

L’entraînement est souvent limité par le chargement, le décodage et l’augmentation des données. Un GPU rapide peut rester inactif parce que Python décompresse des JPEG comme en 2009. Le NVMe aide, mais ne règle pas le prétraitement mono-thread. Les correctifs incluent : cacher les jeux de données prétraités, loaders de données parallèles, mémoire épinglée et déplacer les augmentations lourdes vers le GPU.

5) Alimentation, thermiques et fréquences

Si votre GPU est « lent », vérifiez s’il est en réalité en train de se brider. Les systèmes grand public sont notoirement sujets aux limites d’alimentation et à la saturation thermique. Un GPU 450W affamé par une alimentation instable ou étouffé par un radiateur poussiéreux n’est pas un problème de calcul ; c’est un problème d’infrastructure en miniature.

6) La catégorie « oups » : pilotes, versions et suppositions

La plupart des incidents de production en IA GPU ne sont pas des pannes matérielles exotiques. Ce sont des incompatibilités : pilote vs version CUDA, runtime de conteneur vs pilote hôte, framework vs capacité de calcul, et des hypothèses comme « ça marchait sur mon laptop ».

Petite blague #2 : Le moyen le plus rapide de réduire la latence d’un modèle est de mettre à jour la présentation — rien ne bat l’inférence à 0 milliseconde.

Tâches pratiques : commandes, sorties, décisions

Voici des tâches concrètes que j’utilise réellement pour diagnostiquer les performances et la fiabilité GPU en IA. Chacune inclut une commande, un exemple réaliste de sortie, ce que cela signifie et la décision à prendre ensuite. Elles sont centrées sur Linux parce que c’est là que vit la plupart du travail GPU sérieux, même lorsqu’il a commencé sur un poste.

Task 1: Verify the driver sees your GPU (and which one)

cr0x@server:~$ nvidia-smi -L
GPU 0: NVIDIA GeForce RTX 4090 (UUID: GPU-3a6b1c2d-xxxx-xxxx-xxxx-9c2e4b2f1a7d)

Ce que cela signifie : Le pilote noyau est chargé et énumère le périphérique. Si cette commande échoue, rien de ce qui précède ne compte.

Décision : Si absent, corrigez l’installation du pilote, les paramètres de secure boot ou les modules du noyau avant de toucher aux frameworks.

Task 2: Check driver version and CUDA compatibility surface

cr0x@server:~$ nvidia-smi
+---------------------------------------------------------------------------------------+
| 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  RTX 4090              Off | 00000000:01:00.0  On |                  N/A             |
| 30%   54C    P2   120W / 450W |   8200MiB / 24564MiB |     78%      Default             |
+-------------------------------+----------------------+----------------------------------+

Ce que cela signifie : Vous avez un pilote installé ; il indique une « CUDA Version » prise en charge par l’API du pilote. Cela ne garantit pas que votre toolkit dans un conteneur correspond, mais c’est la base.

Décision : Si votre framework se plaint de CUDA, alignez l’image du conteneur / la version du toolkit avec la capacité du pilote hôte.

Task 3: Confirm PCIe link width and speed (common hidden limiter)

cr0x@server:~$ nvidia-smi -q | sed -n '/PCI/,/Clocks/p'
    PCI
        Bus                               : 0x01
        Device                            : 0x00
        Domain                            : 0x0000
        Bus Id                            : 00000000:01:00.0
        PCIe Generation
            Max                           : 4
            Current                       : 4
        Link Width
            Max                           : 16x
            Current                       : 8x
    Clocks
        Graphics                          : 2520 MHz

Ce que cela signifie : Le GPU fonctionne en Gen4 mais seulement sur x8 lanes. Cela peut être acceptable pour du calcul pur, mais cela peut créer un goulet d’étranglement pour des workloads lourds en transferts ou des communications multi-GPU.

Décision : Si le workload est lié aux transferts, reposez la carte, vérifiez la bifurcation PCIe dans le BIOS ou déplacez-la vers un slot x16 complet.

Task 4: Watch utilization and memory pressure live

cr0x@server:~$ nvidia-smi dmon -s pucm -d 1
# gpu   pwr gtemp mtemp    sm   mem   enc   dec  mclk  pclk
# Idx     W     C     C     %     %     %     %   MHz   MHz
    0   330    71     -    92    78     0     0 10501  2520
    0   338    72     -    94    81     0     0 10501  2520

Ce que cela signifie : SM élevé et forte utilisation mémoire suggèrent que le calcul est utilisé. Si SM est bas mais la puissance élevée, vous pouvez être limité par la bande passante ou en attente d’autre chose.

Décision : Si SM est bas, regardez le pipeline CPU, l’IO disque ou le surcoût de lancement des kernels plutôt que d’acheter un GPU plus gros.

Task 5: Identify which process is hogging VRAM

cr0x@server:~$ nvidia-smi --query-compute-apps=pid,process_name,used_gpu_memory --format=csv
pid, process_name, used_gpu_memory [MiB]
18422, python, 17340 MiB
19107, python, 6200 MiB

Ce que cela signifie : Vous avez plusieurs processus consommant la VRAM. Cela compte parce que même des modèles « inactifs » peuvent réserver de la mémoire.

Décision : Décidez de consolider en un seul processus (serveur de modèle partagé) ou d’appliquer l’isolation avec des GPUs séparés / MIG / ordonnancement.

Task 6: Check CPU bottlenecks and load distribution

cr0x@server:~$ mpstat -P ALL 1 2
Linux 6.5.0 (server)  01/13/2026  _x86_64_  (32 CPU)

01:10:54 PM  CPU   %usr  %nice   %sys %iowait  %irq  %soft  %idle
01:10:55 PM  all  120.0    0.0   12.0    1.0   0.0    2.0  865.0
01:10:55 PM   7   98.0    0.0    1.0    0.0   0.0    0.0    1.0
01:10:55 PM  12   97.0    0.0    1.0    0.0   0.0    0.0    2.0

Ce que cela signifie : Quelques cœurs CPU sont saturés tandis que beaucoup sont inactifs. C’est typique des data loaders Python ou des goulots de tokenization.

Décision : Parallélisez le prétraitement, augmentez les workers du dataloader, dégagez la tokenization du chemin critique ou utilisez un backend de tokenisation compilé.

Task 7: Measure disk throughput for datasets/checkpoints

cr0x@server:~$ fio --name=seqread --filename=/mnt/nvme/testfile --size=4G --rw=read --bs=1M --iodepth=16 --numjobs=1 --direct=1
seqread: (g=0): rw=read, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=libaio, iodepth=16
fio-3.35
seqread: (groupid=0, jobs=1): err= 0: pid=22144: Thu Jan 13 13:12:01 2026
  read: IOPS=3150, BW=3076MiB/s (3224MB/s)(4096MiB/1332msec)

Ce que cela signifie : Vous pouvez lire ~3 Go/s en séquentiel. Parfait pour de grands jeux de données contigus, moins informatif pour de petits fichiers.

Décision : Si votre pipeline lit beaucoup de petits fichiers, passez à des formats sharded plus gros ou ajoutez du cache ; la bande passante NVMe brute ne vous protège pas des tempêtes de métadonnées.

Task 8: Detect small-file pain (metadata and random IO)

cr0x@server:~$ fio --name=randread4k --filename=/mnt/nvme/testfile --size=4G --rw=randread --bs=4k --iodepth=64 --numjobs=1 --direct=1
randread4k: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.35
randread4k: (groupid=0, jobs=1): err= 0: pid=22401: Thu Jan 13 13:13:12 2026
  read: IOPS=420k, BW=1641MiB/s (1720MB/s)(4096MiB/2494msec)

Ce que cela signifie : Les performances de lecture aléatoire sont solides. Si votre entraînement stagne encore, le goulet peut être le décodage CPU ou le surcoût du framework, pas le stockage.

Décision : Profilez le prétraitement et le dataloader. N’achetez pas de disques pour régler du code Python.

Task 9: Check memory pressure and swap (slow-motion catastrophe)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           125Gi        96Gi        2.1Gi       1.4Gi        27Gi        18Gi
Swap:           32Gi        14Gi         18Gi

Ce que cela signifie : Vous êtes en swap. Cela peut détruire le débit et provoquer une faible utilisation GPU parce que le CPU pagine.

Décision : Réduisez la taille de batch, diminuez la mémoire du dataloader, préfetch moins ou ajoutez de la RAM. Si vous swappez pendant l’entraînement, vous n’entraînez pas ; vous négociez avec le noyau.

Task 10: Validate Docker GPU pass-through

cr0x@server:~$ docker run --rm --gpus all nvidia/cuda:12.3.2-base-ubuntu22.04 nvidia-smi -L
GPU 0: NVIDIA GeForce RTX 4090 (UUID: GPU-3a6b1c2d-xxxx-xxxx-xxxx-9c2e4b2f1a7d)

Ce que cela signifie : Le runtime conteneur est connecté et peut accéder au GPU via le pilote hôte.

Décision : Si cela échoue, corrigez la configuration de NVIDIA Container Toolkit / runtime avant d’accuser PyTorch.

Task 11: Confirm PyTorch can see CUDA (and which version it built against)

cr0x@server:~$ python -c "import torch; print(torch.cuda.is_available()); print(torch.version.cuda); print(torch.cuda.get_device_name(0))"
True
12.1
NVIDIA GeForce RTX 4090

Ce que cela signifie : CUDA est utilisable dans votre environnement Python. La version CUDA affichée est celle contre laquelle le build PyTorch a été compilé, pas nécessairement celle de l’outil hôte.

Décision : Si False, vous avez un décalage de dépendances ou des bibliothèques manquantes ; corrigez cela avant d’optimiser quoi que ce soit.

Task 12: Catch ECC/Xid errors in logs (hardware/software blame separator)

cr0x@server:~$ sudo dmesg -T | egrep -i 'nvrm|xid|cuda|pcie' | tail -n 8
[Tue Jan 13 13:02:44 2026] NVRM: Xid (PCI:0000:01:00): 31, pid=18422, name=python, Ch 0000003a
[Tue Jan 13 13:02:44 2026] NVRM: Xid (PCI:0000:01:00): 31, GPU has fallen off the bus.

Ce que cela signifie : « Fallen off the bus » est souvent une question d’alimentation/PCIe, parfois des bugs de pilote, parfois une surchauffe. C’est rarement « votre code de modèle ».

Décision : Vérifiez l’alimentation, le câblage, les risers, le slot PCIe, les thermiques et essayez un changement de pilote. Réduisez aussi la limite de puissance pour tester la stabilité.

Task 13: Check GPU power limit and set a stability cap

cr0x@server:~$ nvidia-smi -q | sed -n '/Power Readings/,/Clocks/p'
    Power Readings
        Power Management                  : Supported
        Power Draw                        : 438.12 W
        Power Limit                       : 450.00 W
        Default Power Limit               : 450.00 W
cr0x@server:~$ sudo nvidia-smi -pl 380
Power limit for GPU 00000000:01:00.0 was set to 380.00 W from 450.00 W.

Ce que cela signifie : Vous pouvez limiter la puissance pour réduire les pics transitoires et améliorer la stabilité, souvent avec une petite perte de performance.

Décision : Si vous voyez des réinitialisations aléatoires ou des erreurs Xid, limitez la puissance pendant l’investigation ; en production, on préfère « un peu plus lent » à « mort de temps en temps ».

Task 14: Verify thermals and throttling state

cr0x@server:~$ nvidia-smi --query-gpu=temperature.gpu,clocks.sm,clocks_throttle_reasons.active --format=csv
temperature.gpu, clocks.sm [MHz], clocks_throttle_reasons.active
83, 2100, Active

Ce que cela signifie : Des raisons de throttling sont actives ; à 83°C vous pouvez atteindre des limites thermiques ou de puissance selon la carte et le refroidissement.

Décision : Améliorez le flux d’air, reposez le refroidissement, ajustez les courbes de ventilateurs ou réduisez la limite de puissance. N’« optimisez pas les kernels » pendant que votre GPU réduit ses fréquences.

Task 15: Spot kernel launch overhead and CPU-side stalls (quick-and-dirty)

cr0x@server:~$ python -m torch.utils.bottleneck train.py
...
CPU time total: 312.45s
CUDA time total: 128.77s
Top CPU ops: DataLoader, tokenizer_encode, python overhead
Top CUDA ops: aten::matmul, aten::scaled_dot_product_attention

Ce que cela signifie : Vous passez plus de temps sur le CPU que sur le GPU. Votre GPU n’est pas le goulet ; il attend.

Décision : Corrigez le pipeline d’entrée, la tokenization en batch, ou utilisez un dataloader plus rapide au lieu de courir après des « réglages GPU ».

Task 16: Confirm NUMA locality (quiet performance killer in dual-socket boxes)

cr0x@server:~$ nvidia-smi topo -m
        GPU0    CPU Affinity    NUMA Affinity
GPU0     X     0-15,32-47          0

Ce que cela signifie : Le GPU est plus proche d’un sous-ensemble de cœurs CPU / d’un nœud NUMA. Si votre processus tourne sur le mauvais nœud NUMA, le trafic PCIe traverse les sockets.

Décision : Pincez votre processus / threads du dataloader aux bons cœurs CPU avec taskset ou systemd CPUAffinity pour des performances cohérentes.

Task 17: Check network as the bottleneck (for remote datasets or object storage)

cr0x@server:~$ ip -s link show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    RX:  bytes  packets  errors  dropped  missed   mcast
    9876543210  6543210       0      421       0       0
    TX:  bytes  packets  errors  dropped  carrier collsns
    8765432109  5432109       0        0       0       0

Ce que cela signifie : Des paquets perdus en réception peuvent se traduire par des transferts retentés et un chargement de données en rafales, surtout si vous streammez des données.

Décision : Réparez la santé du réseau ou mettez les données en cache local ; ne laissez pas l’« entraînement » devenir un test d’endurance réseau.

Mode opératoire de diagnostic rapide

Quand les performances s’effondrent ou que la latence d’inférence devient étrange, il vous faut un chemin court vers la vérité. Voici l’ordre qui trouve rapidement les goulets d’étranglement dans le monde réel.

First: is the GPU actually being used?

  • Exécutez nvidia-smi et vérifiez GPU-Util et Memory-Usage.
  • Si GPU-Util est près de 0% pendant ce qui devrait être une charge GPU, vous êtes sur le CPU, bloqué par les données, ou en train de planter / redémarrer.
  • Décision : corrigez la disponibilité CUDA, le placement des devices dans le framework, ou les blocages du dataloader avant de toucher à l’architecture du modèle.

Second: is the GPU starved or choking?

  • Utilisez nvidia-smi dmon -s pucm -d 1 pour puissance/temp/SM/mem.
  • SM bas avec mémoire élevée ou puissance élevée suggère des stalls de bande passante ou des kernels inefficaces.
  • SM élevé mais faible débit suggère des fréquences bridées ou que la charge est trop petite (taille de batch, longueur de séquence).
  • Décision : choisissez le bon levier — batch size, kernels d’attention fusionnés, précision, ou refroidissement / puissance.

Third: check VRAM and allocator behavior

  • Cherchez les erreurs OOM, mais surveillez aussi le comportement « presque OOM » où la performance se dégrade à cause d’allocations fréquentes.
  • Décision : réduisez le batch, activez la quantification en inférence, utilisez le gradient checkpointing en entraînement, ou choisissez un modèle plus petit.

Fourth: measure the input pipeline

  • Utilisation CPU et iowait : mpstat, iostat, pidstat si installé.
  • Disque : baseline fio, puis profiler le format de fichier et le temps de décodage.
  • Décision : sharder les datasets, cacher les sorties prétraitées ou déplacer le prétraitement sur le GPU.

Fifth: confirm platform integrity

  • Vérifiez dmesg pour Xid et erreurs PCIe.
  • Vérifiez le throttling de puissance et thermique.
  • Décision : traitez la stabilité comme une fonctionnalité. Limitez la puissance, améliorez le refroidissement et arrêtez d’utiliser des alimentations limites « parce que ça boot ».

Trois mini-récits d’entreprise tirés du terrain

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Ils avaient un plan « simple » : prendre un modèle qui fonctionnait en staging, le déployer en production sur une machine GPU et considérer le travail terminé. L’équipe a supposé que si torch.cuda.is_available() renvoyait True, le chemin GPU était « actif et rapide ». Ce n’est pas un test ; c’est un salut.

En production, la latence a dérivé à la hausse sur une semaine. Puis elle a commencé à expirer sous charge. Les graphiques étaient confus : l’utilisation CPU était élevée, l’utilisation GPU faible. Quelqu’un a insisté pour dire que c’était « juste du trafic » et a proposé d’ajouter plus d’instances GPU. Ils l’ont fait, et le problème a persisté. De manière coûteuse.

Le vrai mode de défaillance : le service d’inférence exécutait plusieurs processus workers, chacun chargeant le modèle séparément. La VRAM était presque pleine, ne laissant aucune marge pour les pics d’activations. Le framework a commencé à basculer sur des chemins plus lents, et dans certains cas le processus OOMait et redémarrait. Le load balancer a vu des instances instables. La latence ressemblait à « charge normale » alors que c’était du churn.

La correction a été ennuyeuse : un seul processus chargeant le modèle par GPU, batching des requêtes avec un plafond strict et un budget VRAM appliqué par configuration. Ils ont aussi ajouté une alerte sur « GPU memory used > 90% for 10 minutes » et une autre sur « GPU-Util < 20% while QPS high ». L’incident s’est terminé sans héroïsme, mais avec moins de processus.

Mini-récit 2 : L’optimisation qui a mal tourné

Une autre équipe voulait réduire le coût d’inférence. Ils ont activé une quantification agressive et remplacé le kernel d’attention par un plus rapide. Les benchmarks sur une seule requête semblaient excellents. Le CFO a eu son tableau. Le déploiement est allé à la moitié de la flotte.

Deux jours plus tard, des plaintes clients sont arrivées : les réponses comportaient des erreurs subtiles, surtout sur de longs contextes. Pire, le service est devenu instable sous des mixes de requêtes spécifiques. Les métriques GPU n’affichaient rien d’évident. C’était le genre d’échec qui vous fait douter de votre santé mentale.

La cause racine était double. D’abord, le schéma de quantification interagissait mal avec certaines couches, dégradant la qualité sur des cas limites — ce que le micro-benchmark n’avait pas couvert. Ensuite, le kernel « plus rapide » utilisait plus de mémoire temporaire sur de longues séquences. Sous trafic mixte, cela provoquait des pics transitoires de VRAM qui entraînaient la fragmentation de l’allocateur et des OOM occasionnels.

Le rollback a restauré la stabilité. La correction ultérieure : quantification sélective (pas globale), classification des requêtes par longueur et politique d’espace libre VRAM. Ils ont aussi modifié les tests de performance : plus de démos à une seule requête. Les benchmarks incluent désormais longs contextes, tailles de batch mixtes et scénarios mémoire pires cas. L’optimisation, c’est de l’ingénierie, pas un sport extrême.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la journée

Une entreprise exécutant des jobs d’entraînement internes avait une règle : chaque nœud GPU lançait une tâche de « balayage santé » nocturne. Elle ne faisait rien d’excitant — validait la santé du pilote, exécutait un petit stress test, vérifiait dmesg pour de nouveaux Xid, validait le statut SMART du NVMe et enregistrait le débit de base pour une petite boucle d’entraînement.

Une semaine, un nœud a commencé à montrer des erreurs PCIe corrigeables occasionnelles. Personne ne l’a remarqué d’abord car les jobs d’entraînement retentaient souvent et continuaient. Mais le balayage a signalé un changement : la boucle d’entraînement de base du nœud est devenue instable, et dmesg montrait de nouveaux messages AER PCIe.

Ils ont drainé le nœud du scheduler et ouvert le châssis. Un câble d’alimentation du connecteur GPU était légèrement desserré — suffisamment pour être « correct » jusqu’à ce qu’une charge particulière consomme un pic transitoire. En entraînement réel, le GPU tombait parfois du bus, provoquant des échecs de job qui ressemblaient à des crashs logiciels aléatoires.

Parce qu’ils traitaient les signaux matériels comme de la télémétrie de première classe, ils l’ont trouvé tôt, réparé en 15 minutes et évité une semaine d’ingénieurs à blâmer les bibliothèques. La maintenance préventive est impopulaire parce qu’elle est terne ; elle est efficace parce que la réalité est terne aussi.

Erreurs courantes : symptômes → cause profonde → correction

1) Symptôme : GPU-Util bas, CPU haut, les jobs sont lents

Cause profonde : Goulot du pipeline d’entrée (tokenization, décodage, augmentation) ou prétraitement synchrone sur le CPU.

Correction : Augmentez les workers du dataloader, shardez / mettez en cache le dataset, utilisez des tokenizers plus rapides, pré-tokenisez ou déplacez le prétraitement sur le GPU. Confirmez avec un profiler et mpstat.

2) Symptôme : « CUDA out of memory » aléatoire malgré une VRAM « suffisante »

Cause profonde : Fragmentation due à des formes variables ou de nombreuses allocations, plus des pics transitoires sur de longues séquences ou de gros batches.

Correction : Stabilisez les formes (bucketing), réduisez batch/longueur de séquence, imposez une marge de sécurité, réutilisez les buffers, redémarrez les processus de longue durée ou ajustez les paramètres de l’allocateur dans votre framework.

3) Symptôme : La vitesse d’entraînement est incohérente entre les runs

Cause profonde : Throttling thermique/power, processus en arrière-plan utilisant le GPU, ou différences de localité NUMA.

Correction : Vérifiez l’état de throttling, limitez la puissance, améliorez le refroidissement, isolez le GPU et pincez les threads CPU vers le nœud NUMA du GPU.

4) Symptôme : « GPU has fallen off the bus » / erreurs Xid

Cause profonde : Problèmes d’alimentation, lien PCIe instable, risers, surchauffe ou problèmes de pilote.

Correction : Inspectez câblage / PSU, reposez le GPU, mettez à jour ou changez de branche de pilote, réduisez la limite de puissance pour stabiliser pendant le debug, vérifiez les paramètres BIOS.

5) Symptôme : Les performances sont pires dans Docker que sur l’hôte

Cause profonde : Stack runtime/pilote non aligné, limites CPU, mémoire partagée manquante ou surcharge du système de fichiers.

Correction : Validez docker run --gpus all ... nvidia-smi, définissez un --shm-size adéquat, évitez overlayfs pour de l’IO intensif et assurez-vous que le conteneur a le bon build CUDA-enabled.

6) Symptôme : L’échelle multi-GPU est catastrophique

Cause profonde : Surcharge de communication (PCIe), stratégie de parallélisme inadaptée, tailles de batch trop petites ou goulots CPU par rang.

Correction : Augmentez le batch global, utilisez l’accumulation de gradients, assurez une interconnexion rapide si disponible et profilez la communication. Ne supposez pas que rajouter des GPU coupe le temps par deux.

7) Symptôme : NVMe est rapide mais le dataloader est lent

Cause profonde : Petits fichiers + surcoût Python + décompression dominent, pas le débit disque brut.

Correction : Utilisez des formats sharded, lectures séquentielles, memory-mapping, cache ou datasets pré-décompressés. Mesurez l’IO aléatoire et le temps CPU.

8) Symptôme : Les pics de latence d’inférence sous trafic mixte

Cause profonde : Longueurs de séquence non bornées, batching dynamique incontrôlé, pics VRAM ou contention CPU pour la tokenization.

Correction : Imposer des limites de requête, classifier par longueur, limiter batch/kv-cache, réserver de la marge VRAM et mesurer la latence en paliers (tail) séparément.

Listes de contrôle / plan étape par étape

Étape par étape : construire une machine GPU IA « sensée » de type superordinateur domestique

  1. Choisissez le GPU selon la VRAM en priorité. Si votre modèle cible tient juste, il ne tient pas. Prévoyez de la marge.
  2. Achetez une alimentation que vous aurez honte de rendre. De bonnes unités gèrent mieux les transitoires. La stabilité bat le pic théorique.
  3. Le refroidissement n’est pas optionnel. Assurez un flux d’air et des filtres propres. Les GPU chauds se brident ; les GPU bridés mentent sur les performances.
  4. Utilisez NVMe pour les datasets et checkpoints. Mais n’attendez pas que cela répare le prétraitement CPU.
  5. Installez une branche de pilote connue et saine. Puis ne la mettez pas à jour à la légère sur une machine proche de la production.
  6. Validez la chaîne de bout en bout. Lancez nvidia-smi, puis la pass-through GPU du conteneur, puis la détection GPU du framework.
  7. Verrouillez les versions. Sauvegardez pip freeze ou utilisez un lockfile. La reproductibilité est la sœur discrète de l’ingénierie des performances.

Étape par étape : obtenir une inférence stable sur un GPU unique

  1. Fixez un budget VRAM. Réservez de la marge pour les pics. Traitez 90–95% d’utilisation VRAM comme « dangereusement plein ».
  2. Bornes la taille des requêtes. Imposer une longueur de contexte et un plafond sur les tokens de sortie. La latence tail vous remerciera.
  3. Batcher délibérément. Le micro-batching peut améliorer le débit, mais le batching dynamique non borné peut exploser la VRAM.
  4. Quantifiez stratégiquement. Utilisez la quantification pour faire tenir les modèles et augmenter le débit, mais testez les longs contextes et les cas limites.
  5. Surveillez les métriques tail. Les moyennes cachent la douleur. Suivez p95/p99 et corrélez avec la VRAM et la longueur des séquences.

Étape par étape : obtenir un entraînement fiable sur un GPU unique

  1. Commencez par un run minuscule. Validez que la loss décroît, que les checkpoints s’écrivent et que le dataloader ne se bloque pas.
  2. Utilisez la précision mixte correctement. Si vous voyez des NaN, corrigez le scaling et la stabilité avant d’accuser le GPU.
  3. Contrôlez la mémoire. Réduisez la taille de batch, utilisez l’accumulation de gradients et envisagez le checkpointing pour réduire les activations.
  4. Rendez l’IO ennuyeux. Mettez les datasets sur un stockage local rapide, réduisez les petits fichiers et pré-tokenisez si possible.
  5. Capturez des baselines. Mesurez images/sec ou tokens/sec sur un échantillon connu. Re-lancez après chaque changement. Pas de baseline, pas de diagnostic.

Règle : Si vous ne pouvez pas expliquer votre goulet d’étranglement en une phrase, vous n’avez pas fini de mesurer.

FAQ

1) Ai-je vraiment besoin d’un GPU pour faire de l’IA à la maison ?

Pour de petits modèles, non. Pour les LLM modernes, la génération d’images et tout ce qui n’est pas un jouet, oui — sauf si vous aimez attendre. Les GPU transforment des « minutes » en « secondes » en accélérant l’algèbre linéaire dense au cœur de ces modèles.

2) Plus de VRAM vaut-il toujours mieux qu’un GPU plus rapide ?

Pour l’inférence locale, la VRAM est généralement le facteur limitant. Un GPU un peu plus lent qui permet au modèle de tenir confortablement bat souvent un GPU plus rapide qui vous force à décharger sur le CPU ou à faire des compromis agressifs.

3) Pourquoi mon GPU reste-t-il à 10% d’utilisation pendant l’entraînement ?

Le plus souvent : dataloading lié au CPU, tokenization, augmentation ou un système de fichiers lent. Confirmez avec les métriques CPU et un profiler. Corrigez le pipeline et l’utilisation GPU remontera souvent « gratuitement ».

4) Quelle est la manière la plus rapide d’améliorer les performances locales d’un LLM ?

La quantification (pour faire tenir le modèle en VRAM et augmenter le débit), des kernels d’attention efficaces et un batching sensé. Aussi : arrêtez de swapper sur l’hôte ; le paging rend tout cassé.

5) Pourquoi ai-je « CUDA out of memory » quand l’utilisation VRAM ne semble pas maximale ?

Fragmentation de l’allocateur et pics transitoires. Votre monitoring peut montrer « mémoire libre », mais l’allocateur peut ne pas avoir de bloc contigu assez grand, ou un workspace temporaire vous fait dépasser la limite.

6) La vitesse PCIe est-elle importante pour l’inférence ?

Pour un serveur d’inférence mono-GPU où le modèle et le cache KV vivent en VRAM, le PCIe n’est souvent pas le principal limiteur. Il compte davantage lorsque vous streamez de gros tenseurs fréquemment, effectuez du CPU-offload ou utilisez du model parallelisme multi-GPU.

7) Dois-je exécuter l’IA dans Docker ou directement sur l’hôte ?

Docker va bien et est souvent meilleur pour la reproductibilité — si vous validez la pass-through GPU et gérez la mémoire partagée et le choix du système de fichiers. Le mythe « le conteneur est plus lent » est généralement « mon conteneur est mal configuré ».

8) Quelle est la différence pratique entre « GPU compute » et « tensor cores » ?

Les tensor cores accélèrent massivement les opérations matricielles en basse précision. Si votre framework les utilise efficacement, vous verrez de grandes accélérations avec FP16/BF16/FP8. Sinon, votre « GPU rapide » se comportera étrangement moyen.

9) Puis-je entraîner de grands modèles sur un GPU grand public ?

Vous pouvez entraîner quelque chose, mais « grand » est relatif. Des techniques comme la précision mixte, l’accumulation de gradients et le checkpointing étirent la capacité. Cependant, la VRAM est le mur, et le temps d’entraînement peut être le deuxième mur juste derrière.

10) Comment savoir si mon GPU se bride ?

Vérifiez la température, la consommation et les raisons de throttling dans nvidia-smi. Si les fréquences chutent sous charge ou si le throttling est actif, améliorez le refroidissement ou limitez la puissance. Ne basez pas un benchmark sur un GPU bridé et appelez ça « science ».

Prochaines étapes pratiques

Si vous voulez que votre GPU se comporte comme un superordinateur domestique plutôt que comme un appareil capricieux, faites trois choses cette semaine :

  1. Établissez une baseline. Choisissez un prompt d’inférence représentatif et un mini-run d’entraînement, enregistrez tokens/sec ou steps/sec et conservez-le quelque part versionné.
  2. Instrumentez votre réalité. Surveillez ensemble l’utilisation GPU, la VRAM, la charge CPU et l’IO disque. La corrélation bat la supposition.
  3. Appliquez des budgets. Tête de VRAM, limites de taille de requête, limites de puissance si nécessaire. Vous ne pouvez pas « optimiser » votre sortie de la physique.

La révolution GPU en IA n’est pas magique. C’est un type très précis de calcul parallèle exécuté sur un matériel devenu incroyablement performant parce que les joueurs exigeaient de plus belles explosions. Votre travail consiste à lui fournir des données propres, à le garder au frais et à arrêter de croire aux mythes de performance qui s’effondrent dès que vous lancez nvidia-smi.

← Précédent
WireGuard contre IPsec pour les bureaux : ce qui est plus facile à maintenir et pièges courants
Suivant →
Debian 13 : NFS plus lent que prévu — prouvez que c’est sync/rsize/wsize et corrigez-le (cas n°23)

Laisser un commentaire