CUDA Graphs, modèles de raisonnement et service désagrégé

L'infrastructure d'IA moderne pousse les performances aux limites physiques du silicium et des clusters grâce à l'élimination du surcoût CPU, aux boucles de raisonnement à l'inférence et au routage des clusters GPU spécialisé par phase. Ces trois techniques alimentent les systèmes d'IA en production les plus rapides et les plus intelligents d'aujourd'hui.
1. CUDA Graphs et fusion de noyaux : éliminer le surcoût CPU & mémoire
Les GPU modernes (comme H100 et B200) étant devenus exponentiellement plus rapides, l'exécution d'un seul noyau GPU léger peut ne prendre que 2 à 5 microsecondes. Pourtant, le CPU met souvent 10 à 20 microsecondes simplement pour préparer, valider et lancer ce noyau via le pilote PCIe, laissant le GPU valant plusieurs millions de dollars totalement inactif dans l'attente des instructions CPU.
- Fusion de noyaux (combiner les opérations pour économiser de la mémoire & des lancements).
- Le goulet d'étranglement sans fusion. Une couche Transformer standard exécute séquentiellement des dizaines de petites opérations (par exemple, LayerNorm → Linear → Add Residual → GeLU). Sans fusion, le GPU lance des noyaux séparés pour chaque étape, écrit les tenseurs intermédiaires dans la HBM lente (VRAM) puis les relit immédiatement pour l'étape suivante.
- Exécution fusionnée. Des compilateurs comme torch.compile (TorchInductor) et TensorRT-LLM fusionnent plusieurs opérations élément par élément et de réduction en un seul noyau CUDA/Triton personnalisé. Les valeurs sont chargées une fois depuis la HBM, transformées dans les registres/SRAM ultrarapides sur puce et réécrites en HBM seulement à la toute fin, réduisant fortement le trafic de bande passante mémoire et le nombre de lancements de noyaux.
- CUDA Graphs (rejouer des pipelines d'exécution entiers en une seule fois).
- Enregistrer et rejouer. Même après la fusion de noyaux, une passe avant LLM nécessite encore des centaines de lancements de noyaux par token généré. CUDA Graphs résout ce problème en capturant une séquence complète d'opérations GPU, noyaux, copies mémoire et dépendances, lors d'une exécution de préchauffage, puis en les compilant en un graphe d'exécution statique stocké directement en mémoire GPU.
- Aucune intervention CPU. Pendant l'inférence en temps réel, au lieu de lancer 300 noyaux distincts un par un, le CPU effectue un seul appel API (cudaGraphLaunch) qui déclenche de façon autonome toute la passe avant sur le GPU.
- Gestion des formes dynamiques. Comme CUDA Graphs exige des adresses mémoire et des formes de tenseurs statiques, les moteurs d'inférence complètent les lots entrants jusqu'à des tailles de classes fixes (par exemple, tailles de lot 1, 2, 4, 8, 16) et mettent à jour les pointeurs d'entrée sur place avant de rejouer le graphe capturé auparavant.
2. Calcul au moment du test & modèles de raisonnement (o1/o3 & DeepSeek-R1)
Historiquement, les laboratoires d'IA augmentaient l'intelligence uniquement en consacrant davantage de calcul au préentraînement (modèles plus grands entraînés sur davantage de textes d'Internet). Les modèles de raisonnement comme o1/o3 d'OpenAI et DeepSeek-R1 ont ouvert un second axe de mise à l'échelle : le calcul au moment du test (mise à l'échelle à l'inférence), permettant aux modèles de « réfléchir » plus longtemps avant de répondre.
- Apprentissage par renforcement pour la chaîne de pensée (CoT).
- Au lieu de reposer uniquement sur des exemples de raisonnement pas à pas écrits par des humains, ces modèles sont entraînés par apprentissage par renforcement à grande échelle (RL) (comme GRPO - Group Relative Policy Optimization dans DeepSeek-R1) dans des domaines vérifiables comme les mathématiques, la programmation et la logique formelle.
- Le modèle génère plusieurs chemins de raisonnement candidats, ne reçoit des récompenses objectives que lorsque sa réponse finale passe les tests unitaires ou la vérification mathématique, et découvre de manière autonome des comportements cognitifs émergents, notamment l'autovérification, le retour en arrière lorsqu'une impasse est atteinte et la décomposition des problèmes complexes en sous-objectifs.
- Comment le calcul d'inférence passe à l'échelle.
- Face à un prompt difficile, le modèle génère des milliers de « tokens de réflexion » internes dans un brouillon caché avant de produire une réponse finale. La précision s'améliore logarithmiquement lorsque le modèle consacre davantage de tokens d'inférence à l'exploration d'hypothèses.
- Évolution du compromis de calcul. Dans les LLM traditionnels, l'inférence est peu coûteuse et rapide (générant ~50 tokens de sortie). Dans les modèles de raisonnement, une seule requête peut générer 10 000 à 50 000 tokens de réflexion, transformant l'inférence en une charge massive et soutenue de génération par lots dominée par la croissance du cache KV et l'efficacité de l'attention sur les longs contextes.
3. Préremplissage et décodage désagrégés
Le service d'un LLM comporte deux phases de calcul fondamentalement opposées. Exécuter ces deux phases sur exactement le même GPU crée de graves conflits d'ordonnancement et une sous-utilisation du matériel.
| Phase | Nature de la charge | Goulet d'étranglement matériel | Mesure de latence |
|---|---|---|---|
| Préremplissage (traitement du prompt) | Traite tous les tokens du prompt (par exemple, 10 000 tokens) en parallèle dans une seule passe avant. | Limité par le calcul (sature les Tensor Cores du GPU avec de grandes multiplications matricielles). | TTFT (temps avant le premier token) |
| Décodage (génération de tokens) | Génère séquentiellement les tokens de sortie un par un, en lisant l'ensemble du cache KV à chaque étape. | Limité par la bande passante mémoire (les Tensor Cores restent surtout inactifs en attendant les lectures VRAM). | TPOT (temps par token de sortie) |
- Le problème d'interférence lié à la colocalisation.
- Dans le service unifié traditionnel, si un utilisateur soumet un énorme document de 32 000 tokens au préremplissage alors que 50 autres utilisateurs reçoivent un flux de tokens de décodage, les calculs matriciels massifs du préremplissage monopolisent les Tensor Cores du GPU, provoquant des blocages perceptibles et des pics de latence (« saccades ») pour les 50 utilisateurs en cours de diffusion.
- En outre, le préremplissage exige beaucoup de FLOPs de calcul, tandis que le décodage demande une grande bande passante mémoire HBM et une capacité suffisante pour contenir les caches KV de grands lots.
- Division du cluster (architecture désagrégée).
- Les systèmes d'inférence modernes à très grande échelle (comme Mooncake, DistServe et NVIDIA Dynamo) divisent le cluster GPU en deux groupes dédiés :
- 1. Groupe de préremplissage : optimisé pour le débit de calcul brut (forte utilisation des Tensor Cores, parallélisme de tenseurs plus réduit) afin de traiter rapidement les longs prompts et d'atteindre des objectifs exigeants de temps avant le premier token (TTFT).
- 2. Groupe de décodage : optimisé pour une bande passante mémoire élevée et une grande capacité de cache KV (parallélisme de tenseurs/d'experts plus large, grands lots) afin de diffuser les tokens sans à-coups au débit maximal de tokens par seconde.
- Transfert à haut débit du cache KV. Dès qu'un GPU de préremplissage finit de traiter un prompt et construit son cache KV initial, il transfère ce cache directement via des interconnexions ultrarapides NVLink ou InfiniBand RDMA vers la VRAM d'un GPU de décodage, qui prend immédiatement le relais de la génération des tokens sans aucune interférence.