Cloud

143 milliards par trimestre et toujours pas de GPU : architecturer l'inférence quand le cloud n'est plus élastique

Les dépenses en infrastructures cloud ont atteint 143,4 milliards de dollars au deuxième trimestre 2026, mais la capacité accélérée reste rationnée : le goulot d'étranglement s'est déplacé des GPU vers l'électricité et le foncier. Cet article détaille les patrons d'architecture, l'ordonnancement Kubernetes et les métriques FinOps qui permettent de traiter la capacité comme une dépendance de conception plutôt que comme un acquis.

| | | 10 min read · by
Rangée de racks GPU dans un datacenter avec des voyants d'alimentation, illustrant la contrainte de capacité électrique

Pendant quinze ans, le cloud a fonctionné sur un contrat implicite : la capacité est infinie, elle est immédiate, et son prix baisse. Ce contrat vient d’être rompu pour une catégorie précise de charges — celles qui ont besoin d’accélérateurs. Les équipes le constatent au quotidien : erreurs d’InsufficientInstanceCapacity sur les familles GPU, réservations qui s’étendent jusqu’à fin 2026, arbitrages multi-région imposés par le sourcing plutôt que par la latence utilisateur.

La conséquence est architecturale, pas seulement contractuelle. Il faut désormais concevoir des systèmes d’inférence dont le comportement reste défini lorsque la capacité manque.

L’état du marché en trois chiffres

Les dépenses mondiales en infrastructures cloud ont atteint un record de 143,4 milliards de dollars au deuxième trimestre 2026, en hausse de 43 % sur un an — le rythme de croissance le plus élevé depuis huit ans. Cette accélération est tirée par l’IA, et plus précisément par un déplacement de la charge : l’inférence absorbe désormais 55 % des dépenses d’infrastructure IA en 2026, dépassant l’entraînement.

Ce dernier chiffre est le plus important pour un ingénieur. L’entraînement est une charge planifiable : elle tolère la file d’attente, elle s’exécute dans une région choisie à l’avance, elle peut redémarrer sur checkpoint. L’inférence, elle, est une charge de production avec un SLO, un trafic diurne et des utilisateurs qui n’attendent pas. Le poste budgétaire dominant est donc devenu celui qui supporte le moins bien la pénurie.

Le goulot d’étranglement a changé de nature

En 2023-2024, la contrainte était l’approvisionnement en accélérateurs. Aujourd’hui, les acteurs de l’infrastructure décrivent une contrainte différente et plus rigide : la puissance électrique livrable et les emplacements raccordables. Un rack d’accélérateurs modernes consomme un ordre de grandeur de plus qu’un rack de serveurs généralistes, avec une densité thermique qui impose souvent du refroidissement liquide. On ne pose pas des mégawatts supplémentaires sur une zone de disponibilité en un trimestre : les délais de raccordement au réseau, les autorisations et la construction se comptent en années.

Trois implications concrètes pour l’architecture :

  1. La capacité est régionalisée de façon durable. Le déficit ne se rattrape pas par un simple scale-up du fournisseur. Certaines régions historiques resteront structurellement pauvres en accélérateurs récents.
  2. La disponibilité devient discontinue. Les instances GPU ne sont pas fongibles : H100, H200, L4, TPU, MI300X ont des profils mémoire et logiciels différents. Un repli n’est pas un simple changement de type d’instance.
  3. L’hypothèse de baisse continue des prix ne tient plus sur ce segment. Le raisonnement FinOps « attendons la prochaine génération, elle sera moins chère au token » n’est plus un plan.

Conséquence n°1 : la capacité devient une contrainte de conception

Traitez la capacité accélérée comme vous traitez une dépendance externe : avec un budget d’erreur, un mode dégradé et un test de bascule. Concrètement, cela signifie documenter pour chaque service d’inférence :

  • le quantum de capacité minimal viable (combien de replicas, sur quel type d’accélérateur, avec quelle mémoire) ;
  • la source de capacité (réservation, on-demand, spot, neocloud) et son horizon d’engagement ;
  • le comportement attendu à capacité zéro — c’est la question que la plupart des architectures n’ont pas encore tranchée.

Patrons d’architecture pour capacité contrainte

Quatre patrons couvrent l’essentiel des situations.

Dégradation progressive par paliers de qualité. Définissez explicitement des niveaux de service : modèle principal, modèle plus petit quantifié, réponse depuis un cache sémantique, réponse non générative (recherche lexicale, template), refus explicite. Chaque palier doit être testé en production, pas seulement décrit dans un document.

Routage entre modèles piloté par la charge. Le routeur ne choisit pas uniquement selon la complexité de la requête, mais aussi selon la pression sur les pools disponibles.

# Routage à deux dimensions : criticité de la requête × capacité disponible
PALIERS = [
    ("llm-70b-h100",  {"min_free_slots": 2}),
    ("llm-8b-l4-int8", {"min_free_slots": 1}),
    ("cache-semantique", {}),
]

def router(requete, pools):
    if requete.priorite == "batch":
        return enfiler(requete, deadline="+15m")   # découplage temporel

    for cible, contrainte in PALIERS:
        pool = pools[cible]
        if pool.disponible and pool.slots_libres >= contrainte.get("min_free_slots", 0):
            return pool.soumettre(requete)

    # Aucun palier : réponse explicite, jamais un timeout silencieux
    raise CapaciteIndisponible(retry_after=30)

Le point non négociable est la dernière ligne : sous contrainte, un système doit refuser vite et clairement plutôt que saturer ses files et propager la latence à l’ensemble des appelants.

Découplage temporel par files et batching. Toute requête qui n’est pas synchrone du point de vue de l’utilisateur doit passer par une file avec deadline. C’est le levier le plus rentable en capacité contrainte : le batching augmente le débit par accélérateur, et lisser le trafic diurne réduit le pic de capacité à réserver. Distinguez le batching de serveur (continuous batching de type vLLM/TGI, transparent) du batching applicatif (regroupement de tâches asynchrones, à votre charge).

Repli sur CPU ou modèle réduit. Un modèle de 3 à 8 milliards de paramètres quantifié en int8/int4 tourne sur CPU avec une latence acceptable pour des tâches de classification, extraction ou reformulation courte. Ce n’est pas un substitut pour de la génération longue, mais c’est la différence entre un service dégradé et un service indisponible.

Multi-région et multi-cloud : ce qui marche, ce qui coûte

Le multi-cloud pour les charges accélérées n’est plus un discours de résilience, c’est du sourcing de capacité. Ce qui fonctionne :

  • des clusters gérés indépendants par fournisseur (EKS/GKE/AKS) avec un plan de contrôle applicatif commun (GitOps, même image de serveur d’inférence, même contrat d’API) ;
  • une abstraction de placement stricte : le code d’inférence ne connaît que « un pool qui expose le modèle X avec Y Go de VRAM » ;
  • des poids de modèles traités comme des artefacts versionnés, répliqués à l’avance dans chaque région.

Ce qui coûte cher, et qu’il faut budgéter explicitement :

  • le transfert de données inter-région et sortant — c’est le poste qui transforme un failover élégant en dérive budgétaire ;
  • la duplication des poids : quelques centaines de gigaoctets par région et par version, plus les caches locaux sur NVMe pour éviter des cold starts de plusieurs minutes ;
  • la latence : un repli transatlantique ajoute typiquement plus de latence réseau que le gain apporté par un accélérateur plus rapide ;
  • le coût cognitif : deux écosystèmes d’observabilité, deux modèles IAM, deux jeux de quotas.

Règle pragmatique : multi-région pour la capacité et la continuité, multi-cloud uniquement si le second fournisseur vous apporte une capacité que le premier ne peut pas garantir contractuellement.

Ordonnancement sur Kubernetes : arbitrer entre production et R&D

Quand les accélérateurs sont rares, la question n’est plus « comment scaler » mais « qui perd son GPU ». Cela s’exprime dans l’ordonnanceur.

# 1. Un quota par namespace : la R&D ne peut pas absorber le pool de prod
apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-gpu
  namespace: ml-recherche
spec:
  hard:
    requests.nvidia.com/gpu: "8"
---
# 2. Deux niveaux de priorité, avec un écart franc
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: inference-prod
value: 100000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: recherche-batch
value: 1000
preemptionPolicy: Never   # ne préempte jamais, se fait préempter
---
# 3. Les nœuds accélérés sont réservés par taint
# kubectl taint nodes gpu-node-01 accelerator=h100:NoSchedule
apiVersion: apps/v1
kind: Deployment
metadata:
  name: serveur-inference
spec:
  template:
    spec:
      priorityClassName: inference-prod
      tolerations:
        - key: accelerator
          operator: Equal
          value: h100
          effect: NoSchedule
      containers:
        - name: vllm
          resources:
            limits:
              nvidia.com/gpu: "1"   # ressource étendue : requests = limits, pas de surengagement

Trois pièges méritent d’être connus avant l’incident :

  • La préemption ne respecte pas les PodDisruptionBudgets de façon garantie. L’ordonnanceur tente de choisir des victimes qui minimisent les violations de PDB, mais il violera un PDB s’il n’existe pas d’autre option pour placer le pod prioritaire. Un PDB n’est donc pas un bouclier contre la préemption.
  • La préemption ne crée pas de capacité. Elle redistribue. Si l’autoscaler ne peut pas provisionner de nœud faute de stock chez le fournisseur, la préemption ne fait que déplacer l’interruption vers une autre équipe. Mesurez le taux d’échec de provisionnement, pas seulement le taux de pods Pending.
  • Les accélérateurs ne sont pas surengageables comme le CPU. Le partage passe par MIG, le time-slicing ou MPS, chacun avec un compromis distinct entre isolation, latence et densité. Un time-slicing naïf sur un service à SLO strict produit des queues de latence désastreuses.

Pour les charges de type batch et entraînement, un ordonnanceur par lots (Kueue, Volcano, Yunikorn) apporte la file d’attente, le partage équitable et le gang scheduling que le kube-scheduler seul ne fournit pas.

FinOps de l’inférence : du coût horaire au coût par réponse utile

Le coût par heure de GPU est une métrique de fournisseur, pas une métrique de produit. La seule qui pilote des décisions est le coût par réponse utile : le coût total de la plateforme divisé par le nombre de réponses effectivement consommées par un utilisateur ou un système en aval.

coût_par_réponse_utile =
    (coût_compute + coût_stockage_poids + coût_transfert) /
    (réponses_servies − réponses_annulées − réponses_rejetées_par_le_produit)

Les leviers, du plus rentable au moins rentable dans la plupart des déploiements :

  1. Cache de préfixes / KV cache réutilisé. Les prompts système longs et les conversations à contexte partagé sont massivement redondants ; le prefix caching supprime le recalcul de préremplissage correspondant. À activer avant toute autre optimisation.
  2. Cache de réponses exact ou sémantique en amont du modèle, avec une politique d’invalidation explicite.
  3. Quantification (int8, fp8, int4 selon l’accélérateur) : gain en empreinte mémoire et en débit, à valider par une évaluation de qualité sur vos propres jeux de tests, jamais sur un benchmark générique.
  4. Taille de lot et concurrence : ajuster jusqu’au point où le P95 de latence commence à se dégrader, puis reculer d’un cran.
  5. Taux d’utilisation réel des accélérateurs réservés. Un GPU réservé et utilisé à 20 % coûte cinq fois son prix affiché.

Négociation et engagement : les questions à poser avant de signer

La capacité réservée est devenue un instrument d’ingénierie autant que d’achat. Avant de vous engager sur douze ou trente-six mois, exigez des réponses écrites sur :

  • Quelle est la garantie exacte ? Réservation de capacité dans une zone précise, ou simple remise tarifaire sans priorité d’accès ? La différence est totale en période de pénurie.
  • La réservation est-elle transférable entre régions, familles d’instances ou générations d’accélérateurs ?
  • Que se passe-t-il à la génération suivante ? Un engagement long sur une génération sortante peut vous enfermer.
  • Pour les neoclouds spécialisés : quelle est la maturité du réseau (InfiniBand/RoCE), du stockage à haut débit, de l’IAM, de la conformité et de l’observabilité ? Le prix au GPU-heure y est souvent attractif ; le coût d’intégration et l’absence de services managés adjacents le sont moins.
  • Quel est le plan de sortie ? Volume de poids à rapatrier, frais de sortie, délai de démantèlement.

Ce qu’il faut mettre en place cette semaine

Trois métriques, exposées sur le même dashboard que vos SLO :

  1. Marge de capacité : accélérateurs disponibles moins accélérateurs nécessaires au pic P95 observé, par région et par type. Une valeur négative est un incident latent.
  2. Taux d’échec de provisionnement : proportion de demandes de nœuds accélérés refusées par le fournisseur. C’est votre indicateur avancé de pénurie, bien plus fiable que le discours commercial.
  3. Coût par réponse utile, segmenté par palier de qualité. Il rend visible ce que coûte réellement le maintien du modèle le plus lourd sur des requêtes triviales.

Et un exercice : un test de bascule en conditions réelles. Coupez délibérément le pool d’accélérateurs principal d’une région en heures ouvrées, avec les équipes présentes, et vérifiez trois choses — le routeur descend d’un palier sans erreur 5xx, le temps de chargement des poids sur le pool de secours est conforme à ce que vous avez annoncé, et la facture de transfert de données générée par l’exercice correspond à votre estimation. Si l’un des trois écarts dépasse ce que vous attendiez, vous venez d’apprendre quelque chose que la prochaine pénurie vous aurait appris plus cher.

Le changement de fond n’est pas que le cloud soit devenu plus coûteux : c’est qu’il est redevenu fini, au moins pour les charges accélérées. Les équipes qui traitent la capacité comme une ressource négociée, mesurée et budgétée — au même titre que la latence ou la disponibilité — n’attendront pas la fin de la contrainte pour livrer. Les autres continueront à écrire des tickets de support en espérant qu’une zone de disponibilité leur réponde.

Comments (0)

Please log in to leave a comment.

Log In

No comments yet. Be the first to comment!