Production et pièges courants
Ce que les benchmarks ne montrent jamais : incompatibilités de versions, OOM en production, throttling thermique, partitionnement MIG et observabilité GPU — la checklist go-live d'un déploiement d'inférence à l'échelle.
Table des matières
Pourquoi ce chapitre clôt la formation
Un kernel optimisé, un pipeline multi-GPUGPUIAProcesseur graphique parallélisant massivement les calculs matriciels ; indispensable à l'entraînement et à l'inférence des modèles de deep learning.Voir dans le glossaire avec NCCL qui scale linéairement, un profiling Nsight qui ne montre plus de stalls — tout cela ne garantit rien une fois le code déployé sur un cluster partagé, avec des drivers gérés par une autre équipe, des GPU qui chauffent sous charge continue et des utilisateurs qui envoient des requêtes à des débits imprévisibles. La plupart des incidents GPU en production ne viennent pas d'un mauvais kernel : ils viennent d'un désalignement de versions, d'une VRAM mal budgétée ou d'une absence totale de supervision.
Ce chapitre ferme la formation sur les problèmes que l'on rencontre après le déploiement, pas pendant le développement. Ce sont les pièges qui expliquent pourquoi un service qui fonctionnait parfaitement en local tombe en production trois semaines plus tard, sans qu'aucune ligne de code n'ait changé.
Un déploiement GPU n'est jamais figé. Le firmware, le driver, le kernel Linux et les bibliothèques CUDA évoluent indépendamment. Traiter la stack GPU comme un artefact immuable est l'erreur la plus coûteuse observée en production.
Le mur des versions : driver, CUDA Toolkit, cuDNN
La pile logicielle GPU empile plusieurs couches versionnées séparément : le driver NVIDIA (module noyau), le CUDA Toolkit utilisé à la compilation, les bibliothèques cuDNN/cuBLAS/NCCL liées dynamiquement, et enfin le framework (PyTorch, TensorRT, ONNX Runtime) qui embarque ses propres exigences de version.
La règle de base : le driver installé sur la machine doit être au moins aussi récent que celui exigé par le CUDA Toolkit utilisé pour compiler le binaire. Un driver ancien ne peut pas exécuter un binaire compilé avec un toolkit plus récent — l'inverse fonctionne généralement, grâce à la compatibilité ascendante du driver.
Depuis CUDA 10.x, NVIDIA propose un mécanisme de forward compatibility : un package séparé (cuda-compat) permet d'exécuter des binaires compilés avec un toolkit récent sur un driver plus ancien, sans mise à jour complète du système hôte — utile en environnement conteneurisé où le driver de l'hôte n'est pas sous votre contrôle direct.
En conteneur, l'image de base (nvidia/cuda:12.x-runtime) doit être choisie en fonction du driver de l'hôte Kubernetes ou Docker, pas l'inverse. Le NVIDIA Container Toolkit expose le driver de l'hôte à l'intérieur du conteneur ; une image trop récente par rapport au driver hôte échoue au démarrage avec des erreurs de type CUDA driver version is insufficient for CUDA runtime version.
cuDNN et NCCL ne suivent pas le même cycle de version que CUDA Toolkit. Une mise à jour de framework (PyTorch 2.x → 2.y) peut embarquer une version de cuDNN incompatible avec un kernel personnalisé compilé séparément. Vérifiez systématiquement les matrices de compatibilité avant toute montée de version, y compris pour un simple patch de framework.
Triton Inference Server : servir des modèles à l'échelle
Une fois le modèle entraîné et optimisé (quantification, TensorRT, fusion d'opérateurs), reste la question du service : comment exposer ce modèle en HTTP/gRPC avec un débit et une latence maîtrisés ? Triton Inference Server, développé par NVIDIA, répond à ce besoin en se plaçant entre le client et un ou plusieurs backends d'exécution (TensorRT, ONNX Runtime, PyTorch, Python custom).
Les mécanismes clés de Triton en production :
- Model repository — une arborescence de fichiers où chaque modèle possède sa configuration (
config.pbtxt) décrivant les formes d'entrée/sortie, le backend, les instances GPU et les politiques de batching. - Dynamic batching — Triton regroupe automatiquement les requêtes arrivées dans une fenêtre de temps courte (quelques millisecondes) en un seul batch GPU, ce qui augmente le débit sans pénaliser fortement la latence perçue, à condition de calibrer la fenêtre.
- Instances multiples par modèle — plusieurs copies du même modèle peuvent tourner en parallèle sur le même GPU ou sur des GPU distincts, avec une politique de round-robin gérée par Triton.
- Model ensembles — un pipeline de plusieurs modèles (prétraitement → inférenceinférenceIAUtilisation d'un modèle déjà entraîné sur une donnée nouvelle. Peu coûteuse à l'unité mais répétée à chaque requête, elle constitue le coût récurrent d'exploitation.Voir dans le glossaire → post-traitement) peut être décrit comme un graphe unique, évitant les allers-retours réseau entre étapes.
Un modèle de classification d'images servi avec une fenêtre de dynamic batching de 5 ms et un maximum de 32 requêtes par batch peut faire passer le débit de 220 img/s (requêtes traitées une par une) à plus de 1 800 img/s sur le même GPU, avec une latence P99 qui reste sous 40 ms. Le gain vient du fait que l'inférence GPU est dominée par les coûts fixes de lancement de kernel : amortir ces coûts sur un batch plus large change radicalement le rendement.
Le piège classique avec le dynamic batching : une fenêtre trop longue (par exemple 50 ms) fait exploser la latence individuelle pour des gains de débit marginaux au-delà d'un certain point de saturation. La fenêtre doit être calibrée empiriquement en fonction du SLA de latence, pas fixée arbitrairement.
Out-of-memory GPU : anticiper plutôt que subir
L'erreur CUDA out of memory est probablement l'incident le plus fréquent en production. Elle survient rarement au moment attendu — souvent après plusieurs heures ou jours de fonctionnement stable, ce qui trompe sur sa cause réelle.
Trois origines distinctes méritent d'être distinguées :
- Sous-dimensionnement statique — le modèle plus le batch maximal plus les buffers d'activationfonction d'activationIAOpération non linéaire appliquée en sortie d'un neurone. Sans elle, empiler des couches serait inutile : une succession d'opérations linéaires reste équivalente à une seule.Voir dans le glossaire dépassent la VRAM disponible. Se corrige en réduisant la taille de batch, en activant le checkpointing d'activation, ou en changeant de GPU.
- Fragmentation de l'allocateur — PyTorch et la plupart des frameworks utilisent un allocateur caching qui conserve les blocs libérés pour éviter des appels coûteux à
cudaMalloc. Avec des tailles de requêtes très variables (séquences de longueurs différentes en NLP, par exemple), la mémoire se fragmente : la somme des blocs libres suffirait, mais aucun bloc contigu n'est assez grand. - Fuite lente — des tenseurs restent référencés involontairement (accumulation dans une liste Python, graphe d'autograd non détaché), grossissant l'empreinte mémoire requête après requête jusqu'à l'épuisement.
Pour distinguer fragmentation et fuite réelle, comparez
torch.cuda.memory_allocated()(mémoire réellement utilisée par des tenseurs vivants) ettorch.cuda.memory_reserved()(mémoire retenue par l'allocateur). Un écart important et stable indique de la fragmentation ; une croissance continue des deux indique une fuite.
En production, deux réglages réduisent le risque : fixer PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True (disponible depuis PyTorch 2.1) qui limite la fragmentation en autorisant l'expansion de segments existants plutôt que l'allocation de nouveaux blocs, et instaurer une limite dure de VRAM par processus via MIG ou via des quotas cgroup, pour qu'un service défaillant n'affame pas les autres tenants du GPU.
Thermal throttling : la dérive silencieuse
Un GPU datacenter (A100, H100, L40S) réduit automatiquement ses fréquences d'horloge lorsque sa température de jonction approche une limite de sécurité (typiquement autour de 83-87 °C selon le modèle). Ce mécanisme — le throttling thermique — protège le matériel, mais dégrade silencieusement les performances sans générer d'erreur : le service continue de répondre, simplement plus lentement.
Ce phénomène est particulièrement insidieux car il n'apparaît pas dans les tests de charge courts. Un benchmark de cinq minutes tourne à pleine fréquence ; c'est seulement après vingt ou trente minutes de charge soutenue, une fois l'équilibre thermique atteint, que le throttling se déclenche. Les environnements avec un refroidissement mal dimensionné (racks surchargés, flux d'air insuffisant) ou un power limit mal configuré sont les plus exposés.
Le throttling n'est pas toujours thermique. Un GPU peut aussi réduire ses fréquences par power capping (dépassement du TDP configuré) ou par reliability throttling en cas de dégradation matérielle détectée. Les trois causes se distinguent via les champs
clocks_throttle_reasonsexposés parnvidia-smiet DCGM.
La dérivedériveIADégradation progressive des performances d'un modèle après son déploiement, causée par l'évolution des comportements ou du contexte. Elle impose surveillance et réentraînement.Voir dans le glossaire de performance due au throttling se détecte en comparant le débit observé sur des fenêtres glissantes de 30 minutes à un baseline établi en conditions froides. Une chute de 15 à 20 % sans changement de code ni de charge applicative est un signal quasi certain de throttling thermique.
MIG : partitionner un GPU sans se tirer une balle dans le pied
Le Multi-Instance GPU (MIG), disponible sur les architectures Ampere et Hopper (A100, H100), permet de découper physiquement un GPU en plusieurs instances isolées, chacune avec ses propres unités de calcul (SM), son cache L2 dédié et sa tranche de VRAM. Contrairement au partage de contextefenêtre de contexteIAQuantité de texte qu'un modèle peut prendre en compte simultanément : question, documents fournis et historique. Au-delà, les éléments les plus anciens sortent du champ.Voir dans le glossaire classique où plusieurs processus se disputent librement les ressources, MIG garantit une isolation matérielle réelle : un tenant bruyant ne peut pas dégrader la latence d'un autre.
Ceci est utile pour :
- Héberger plusieurs modèles de petite taille sur un seul GPU physique sans qu'ils interfèrent entre eux.
- Garantir un SLA de latence à un service critique en lui réservant une tranche fixe (par exemple
1g.10gb) pendant qu'un job batch tourne sur une autre tranche du même GPU. - Réduire le coût d'infrastructure en évitant de réserver un GPU entier à un modèle qui n'en utilise qu'une fraction.
Le piège principal : MIG n'est pas dynamique. Le repartitionnement d'un GPU nécessite de vider toutes les instances actives et de relancer la configuration — impossible à faire à chaud sans interruption de service. Le dimensionnement des tranches (profils 1g.5gb, 2g.10gb, 3g.20gb, etc. selon le modèle de GPU) doit donc être décidé à l'avance, en fonction de la charge prévue, pas ajusté au fil de l'eau.
MIG et MPS (Multi-Process Service) répondent à des besoins différents et ne se combinent pas simplement. MPS partage un GPU entre processus sans isolation mémoire stricte, avec un overhead plus faible ; MIG isole physiquement au prix d'un découpageChunkingIADécoupage d'un document en segments de taille fixe ou sémantique avant indexation vectorielle, pour optimiser la récupération RAG.Voir dans le glossaire figé. Confondre les deux mène à des choix d'architecture inadaptés — MPS pour maximiser le débit d'un pool homogène, MIG pour garantir des SLA hétérogènes sur un même GPU.
Observabilité GPU : ce qu'il faut monitorer en continu
Un service GPU sans supervision dédiée se découvre défaillant au moment où l'utilisateur se plaint. Le socle minimal repose sur trois composants : la collecte via DCGM (Data Center GPU Manager) ou nvidia-smi, l'exposition en séries temporelles via un exporter Prometheus, et un tableau de bord avec seuils d'alerte.
Les métriques à suivre en priorité :
| Métrique | Ce qu'elle révèle | Seuil d'alerte typique |
|---|---|---|
| Utilisation SM (%) | Sous-utilisation ou saturation compute | < 30 % en continu = sous-emploi coûteux |
| VRAM utilisée / totale | Marge avant OOM | > 90 % soutenu |
| Température GPU | Risque de throttling imminent | > 80 °C |
clocks_throttle_reasons |
Cause exacte d'un ralentissement | Tout drapeau actif hors idle |
| ECC errors (corrigées/non corrigées) | Dégradation matérielle | Toute erreur non corrigée |
| Latence P50/P95/P99 applicative | Impact utilisateur réel | Dépassement du SLA |
Les erreurs ECC non corrigées sont un signal fort de dégradation matérielle imminente. Un GPU qui accumule ce type d'erreur doit être mis en quarantaine et remplacé, pas simplement redémarré — le problème est physique, pas logiciel.
L'exporter DCGM (dcgm-exporter) expose nativement ces métriques au format Prometheus, ce qui permet de les intégrer directement dans Grafana aux côtés des métriques applicatives (latence, taux d'erreur HTTP). La corrélation entre une chute de débit applicatif et une hausse de température GPU sur le même graphique est souvent le diagnostic le plus rapide pour confirmer un throttling.
Checklist de mise en production
Avant tout déploiement d'un service d'inférence GPU, vérifier :
- La version du driver hôte est documentée et compatible avec le CUDA Toolkit de l'image conteneur (ou le package
cuda-compatest présent). - Un budget VRAM a été calculé pour le pire cas (batch maximal, séquences les plus longues), avec une marge de sécurité d'au moins 15 %.
-
PYTORCH_CUDA_ALLOC_CONFou l'équivalent framework est configuré pour limiter la fragmentation. - Un test de charge soutenue d'au moins 30 minutes a été exécuté pour détecter un éventuel throttling thermique.
- Les métriques DCGM sont collectées et un dashboard expose température, VRAM, utilisation SM et throttle reasons.
- Des seuils d'alerte sont configurés, avec un runbook associé pour chaque type d'alerte.
- La stratégie de partitionnement (MIG, MPS ou GPU dédié) correspond au profil de charge réel, pas à une estimation optimiste.
- Le comportement en cas d'OOM est défini (rejet propre de la requête avec code d'erreur explicite, pas de crash du processus entier).
- Un plan de rollback existe si la nouvelle version du modèle ou du driver dégrade les performances.
Synthèse
La robustesse d'un service GPU en production ne se joue pas dans l'optimisation du kernel mais dans la gestion de ce qui l'entoure : versions cohérentes de bout en bout, budget mémoire réaliste, anticipation du comportement thermique sous charge soutenue, partitionnement adapté au profil réel des tenants, et une boucle d'observabilité qui détecte la dérive avant l'incident. Ces éléments ne s'improvisent pas au moment du déploiement : ils se décident en amont, avec la même rigueur que le choix d'un algorithme ou d'un pattern de kernel.
L'essentiel à retenir
Ce chapitre couvre les pièges opérationnels qui séparent un prototype CUDA fonctionnel d'un service GPU fiable en production : ruptures de compatibilité driver/CUDA/cuDNN, déploiement via Triton Inference Server, gestion des out-of-memory, throttling thermique et partitionnement MIG. Il détaille aussi la boucle d'observabilité GPU (DCGM, Prometheus, alerting) nécessaire pour détecter une dégradation avant qu'elle n'atteigne l'utilisateur. Le chapitre se termine par une checklist de mise en production directement réutilisable.
- Compatibilité driver / CUDA Toolkit / cuDNN et forward compatibility
- Triton Inference Server : model repository, dynamic batching, multi-backend
- Out-of-memory GPU : fragmentation, allocateur caching, OOM killer
- Thermal throttling et dérive de performance (DVFS, power limit)
- MIG (Multi-Instance GPU) et isolation mémoire/compute
- Observabilité GPU : DCGM Exporter, métriques Prometheus, alerting
- Checklist de mise en production d'un service d'inférence GPU
Questions fréquentes
Peut-on faire cohabiter plusieurs versions de CUDA Toolkit sur le même serveur de production ?
Faut-il toujours mettre à jour le driver en même temps que le CUDA Toolkit ?
Quelle est la vraie différence entre MIG et MPS pour partager un GPU ?
Comment détecter un risque d'OOM avant qu'il ne plante le service en production ?
Le throttling thermique touche-t-il aussi les GPU de datacenter comme les A100 ou H100 ?
Quelles métriques mettre en priorité dans un dashboard GPU de production ?
Le dynamic batching de Triton dégrade-t-il toujours la latence individuelle ?
Progression sauvegardée dans votre navigateur.
Quiz de validation
Quiz Player
Quiz de validation
Plusieurs réponses possibles — validez ensuite.
Vrai ou faux.
Quiz indisponible (données invalides).