LYCÉE → PRÉPA · L33

Module L33 · Partie K · Ingénierie de l’IA

Les infrastructures de l’IA : ce qui fait tourner les modèles, et ce que ça coûte.

Un modèle est un programme qui multiplie des matrices ; l’infrastructure décide s’il tourne en 10 ms ou 10 s, pour 1 € ou 1 000 €. Ce chapitre explique le matériel (CPU, GPU, TPU, NPU, mémoire, interconnexions), le logiciel (CUDA, noyaux, compilateurs, frameworks), les parallélismes d’entraînement (données, tenseurs, pipeline, ZeRO/FSDP), le service d’inférence (lots, cache KV paginé, quantification, serveurs), le stockage et les pipelines de données, l’observabilité, et l’arbitrage cloud / local / edge — avec les mathématiques du roofline et les coûts réels.

Durée : 3 séances · Prérequis : L18, L22, L25, L27. Objectifs : lire une fiche de GPU et prédire le débit d’un modèle (roofline) ; expliquer les parallélismes et leurs coûts de communication ; dimensionner un service d’inférence ; comparer cloud, on-premise et edge sur un cas chiffré ; mettre en place l’observabilité minimale.

Ce que vous saurez faire à la fin
  • Calculer l’intensité arithmétique d’un calcul et savoir s’il est limité par le calcul ou la mémoire.
  • Choisir et combiner les parallélismes pour entraîner un modèle qui ne tient pas sur un GPU.
  • Dimensionner un serveur d’inférence (débit, latence, lot, mémoire) et chiffrer les alternatives.
  • Décrire une plateforme ML complète : données, entraînement, registre, service, monitoring.

Fiche de cours · Définitions

Définitions

Définition (accélérateur). GPU : milliers de cœurs SIMD, mémoire HBM à haute bande passante (1–5 To/s), unités matricielles (Tensor Cores) pour fp16/bf16/fp8/int8. TPU : matrices systoliques dédiées (Google). NPU/edge : accélérateurs basse consommation (Jetson, Coral, Apple Neural Engine, micro-NPU). CPU : peu de cœurs puissants, latence faible, grande mémoire, flexible.
Définition (hiérarchie mémoire). Registres → SRAM (cache L1/L2, dizaines de Mo, ~10 To/s) → HBM/GDDR (80 Go, ~3 To/s) → RAM hôte (To, ~100 Go/s) → NVMe (~5 Go/s) → réseau (10–400 Gbit/s). Chaque niveau est 10× plus lent et 10× plus grand ; déplacer les données coûte plus que calculer.
Définition (modèle roofline). Un calcul d’intensité arithmétique I = FLOPs / octets transférés est limité par la mémoire si I < pic FLOP/s ÷ bande passante (le « point d’inflexion »), par le calcul sinon. Débit atteignable = min(pic, I × BW).
Définition (précisions). fp32 (référence), tf32, bf16 (même exposant que fp32, 8 bits de mantisse : stable pour l’entraînement), fp16 (nécessite une mise à l’échelle de la perte), fp8 (H100+), int8/int4 (inférence quantifiée). Entraînement en précision mixte : calculs en bf16, accumulation et poids maîtres en fp32.
Définition (parallélismes). Données : chaque GPU a une copie du modèle et un sous-lot ; les gradients sont moyennés (all-reduce). Tenseurs : une couche est découpée entre GPU (une matrice en colonnes/lignes). Pipeline : les couches sont réparties en étages ; les micro-lots s’enchaînent. ZeRO/FSDP : états d’optimiseur, gradients et paramètres partitionnés entre GPU (sharded), rassemblés à la demande. Experts : les experts d’un MoE sur des GPU différents.
Définition (service d’inférence). Serveur qui reçoit des requêtes, les regroupe en lots (continuous batching), gère le cache KV (PagedAttention), applique la quantification et la génération spéculative, et expose une API ; mesuré en débit (tok/s) et latence (temps au premier token TTFT, temps par token TPOT).
Définition (plateforme ML). Stockage objet (données, artefacts), catalogue et versionnage des données, orchestrateur (pipelines), cluster d’entraînement (Kubernetes + GPU), registre de modèles, service, monitoring, gestion des secrets et des accès.

Fiche de cours · Formules

Formules à connaître

Roofline : débit = min(FLOP/spic, I × BW) ; point d’inflexion I* = FLOP/spic/BW — H100 : ≈ 10¹⁵/3,35·10¹² ≈ 300 FLOP/octet (bf16)
Produit matriciel (M×K)(K×N) : FLOPs = 2MKN ; octets ≈ 2(MK + KN + MN) en bf16 ; I ≈ MKN/(MK + KN + MN) — grand si M, N, K grands (≥ 300 chacun)
Décodage LLM en lot B : I ≈ B (chaque poids lu une fois sert B tokens) ⇒ limité par la mémoire tant que B < I* ≈ 300
Mémoire d’entraînement par paramètre (Adam, précision mixte) : 2 (poids bf16) + 4 (poids fp32) + 4 + 4 (moments) + 2 (gradient) = 16 octets ⇒ 7B ≈ 112 Go + activations
ZeRO-3 / FSDP : mémoire par GPU ≈ 16N/nGPU + activations ; communication ≈ 3 × 2N octets par pas (all-gather ×2, reduce-scatter)
All-reduce en anneau de S octets sur n GPU : temps ≈ 2(n − 1)/n × S/BW ; ≈ 2S/BW pour n grand — indépendant de n, mais latence × n
Pipeline à p étages et m micro-lots : bulle = (p − 1)/(m + p − 1) du temps — m ≥ 4p pour une bulle < 20 %
TTFT ≈ tokensprompt × 2N / FLOP/s (calcul) ; TPOT ≈ octetspoids/BW (mémoire, lot 1) ; latence totale = TTFT + nout × TPOT
Coût par million de tokens générés ≈ prix GPU/h ÷ (débit tok/s × 3 600) × 10⁶ ; à 800 tok/s et 2,5 €/h : 0,87 €/M tokens
Loi d’Amdahl (L24) pour le parallélisme ; efficacité = accélération/n ; loi de Gustafson : agrandir le problème avec n

Fiche de cours · Théorèmes et démonstrations

Démonstrations à savoir refaire

Théorème 1 (roofline). Pour un noyau qui lit/écrit Q octets et effectue W FLOPs sur une machine de pic P FLOP/s et de bande passante β octets/s, le temps est ≥ max(W/P, Q/β), donc le débit ≤ min(P, (W/Q)·β).
Le calcul ne peut pas aller plus vite que P : temps ≥ W/P. Les transferts ne peuvent pas aller plus vite que β : temps ≥ Q/β. Les deux se recouvrent au mieux parfaitement, d’où temps ≥ max. Débit = W/temps ≤ W/max(W/P, Q/β) = min(P, Wβ/Q) = min(P, I·β) avec I = W/Q. Application : décodage LLM en lot 1 — W = 2N, Q = 2N octets (poids bf16) : I = 1 FLOP/octet ≪ 300 : on utilise 0,3 % du calcul du GPU ; la seule façon d’accélérer est de réduire Q (quantification, cache) ou d’augmenter I (lot, spéculatif). Entraînement — produits matriciels avec B×n ≥ 4 096 lignes : I ≈ 1 000 : limité par le calcul, le GPU est utilisé à 40–60 % en pratique (MFU).
Théorème 2 (l’all-reduce en anneau est optimal en bande passante). Réduire S octets sur n nœuds exige que chaque nœud envoie au moins (n − 1)/n × S octets ; l’anneau (reduce-scatter puis all-gather) atteint 2(n − 1)/n × S.
Borne inférieure : chaque nœud détient 1/n des données finales qu’il doit avoir reçues (au moins (n − 1)/n × S octets entrants pour le résultat complet), et pour la réduction, chaque nœud doit exporter sa contribution sur les (n − 1)/n de l’espace qu’il ne réduit pas : ≈ (n − 1)/n × S sortants au minimum pour chaque phase. Anneau : découper S en n tranches ; en n − 1 étapes, chaque nœud envoie une tranche à son successeur qui l’accumule (reduce-scatter : à la fin, chaque nœud a une tranche entièrement réduite) ; puis n − 1 étapes pour diffuser les tranches (all-gather). Chaque étape envoie S/n : total 2(n − 1)S/n par nœud, à un facteur 2 près de la borne — et indépendant de n en asymptote. C’est ce que NCCL fait sur NVLink/InfiniBand ; la limite devient la latence (2(n − 1) étapes) pour de petits messages, d’où le regroupement des gradients en « buckets ».
Théorème 3 (bulle du pipeline). Avec p étages et m micro-lots de durée égale, la fraction de temps où les étages sont oisifs est (p − 1)/(m + p − 1) (schéma GPipe, avant et arrière).
Le premier micro-lot met p unités à traverser les p étages ; les m micro-lots s’enchaînent en tuyau : le dernier finit à l’instant m + p − 1 (temps total). Le travail utile est m·p unités-étages sur p·(m + p − 1) disponibles : utilisation m/(m + p − 1), bulle (p − 1)/(m + p − 1). Pour p = 8 étages et m = 32 micro-lots : 18 % de bulle ; m = 8 : 47 %. Les schémas 1F1B et entrelacés réduisent la mémoire d’activations, pas la bulle ; celle-ci impose de grands lots globaux — d’où la combinaison avec le parallélisme de données et de tenseurs (3D parallelism, Megatron).
Théorème 4 (le lot n’augmente le débit que jusqu’au point d’inflexion). En décodage, le temps par étape est ≈ max(Q/β, 2N·B/P) ; le débit B/temps croît linéairement en B jusqu’à B* = Q·P/(2N·β) ≈ I*, puis plafonne à P/2N tokens/s.
Théorème 1 avec W = 2N·B et Q fixe (poids lus une fois par étape, cache KV mis à part). Pour B < B*, Q/β domine : le temps ne dépend pas de B, le débit est proportionnel à B (« lot gratuit »). Pour B > B*, le calcul domine : le temps croît avec B, le débit sature. En pratique le cache KV ajoute B × (octets par token × n) à Q, ce qui abaisse B* et limite B par la mémoire : PagedAttention (vLLM) sert à remplir la mémoire sans gaspillage pour approcher B*. Ordres de grandeur H100, 7B bf16 : B* ≈ 300 mais mémoire limite B à ~50–100 avec 4k de contexte — le débit maximal est alors ≈ 100/0,005 s ≈ 20 000 tok/s théoriques, 2 000–5 000 mesurés.

01 / Matériel

Lire une fiche technique et prédire les performances avec le roofline

02 / Entraîner à plusieurs

Parallélismes : simuler les coûts de communication et la bulle du pipeline

Retenir : le calcul tient dans le GPU, la communication entre GPU est le goulot ; les collectives s’organisent pour être recouvertes par le calcul ; et un « petit » détail série (lecture des données depuis un stockage lent, un print synchronisé) peut diviser l’efficacité par deux à 64 GPU.

03 / Servir

Dimensionner un service d’inférence : lots, cache KV, latence, coût

04 / Plateforme

Vue informatique : l’architecture d’une plateforme ML complète

CoucheRôleOutils (libres / cloud)Point d’attention
Stockage objetDonnées brutes, jeux versionnés, artefacts, checkpointsMinIO, S3, GCS ; formats Parquet/Arrow, WebDataset, ZarrDébit de lecture pour l’entraînement (≥ 1 Go/s par GPU) ; cycle de vie et coût
Versionnage des donnéesReproductibilité, lignageDVC, LakeFS, Delta Lake, catalogues (DataHub)Hash des jeux ; qui a le droit de lire quoi
OrchestrationPipelines (ingestion → features → entraînement → évaluation → déploiement)Airflow, Dagster, Kubeflow, Prefect, ArgoIdempotence, reprise sur erreur, planification
CalculCluster GPU, files d’attente, isolationKubernetes + opérateurs, Slurm (HPC), RayUtilisation réelle des GPU (souvent < 30 %) ; quotas
EntraînementFrameworks, précision mixte, parallélismesPyTorch (FSDP, DDP), DeepSpeed, Megatron, JAX ; HF Accelerate/TRLCheckpoints fréquents ; reprise ; déterminisme
Suivi d’expériencesHyperparamètres, métriques, artefactsMLflow, Weights & Biases, TensorBoardTout journaliser (L24) ; lien commit ↔ modèle
Registre de modèlesVersions, métadonnées, stades (staging/prod), cartes de modèleMLflow Registry, HF Hub, Vertex/SageMaker RegistrySignature des artefacts ; provenance
ServiceAPI, lots, autoscaling, canaryvLLM, TGI, Triton, TorchServe, BentoML, KServe ; ONNX Runtime, TensorRTSLO p95 ; repli ; versions A/B
Compilation / optimisationFusion de noyaux, graphes, quantificationtorch.compile, TensorRT-LLM, ONNX, OpenVINO, TVM ; llama.cpp (edge)Gains 1,5–4× ; vérifier l’exactitude après
ObservabilitéMétriques système et modèle, traces, journauxPrometheus, Grafana, OpenTelemetry ; Evidently, Arize, Langfuse (LLM)Dérive des données et des sorties (L35) ; coût par requête
SécuritéSecrets, accès, réseau, conformitéVault, IAM, VPC ; chiffrement au repos et en transitDonnées personnelles, RGPD ; modèles = actifs à protéger

05 / Choisir

Cloud, on-premise, edge : un arbitrage chiffré

06 / Articles

Les articles et documents à lire

RéférenceContributionÀ retenir
Williams, Waterman & Patterson, Roofline: An Insightful Visual Performance Model, CACM 2009Le modèle rooflineThéorème 1 ; première question à se poser devant un noyau lent
Micikevicius et al., Mixed Precision Training, ICLR 2018 — 1710.03740fp16 avec poids maîtres fp32 et mise à l’échelle de la pertebf16 a rendu la mise à l’échelle inutile ; fp8 est l’étape suivante
Shoeybi et al., Megatron-LM, 2019 — 1909.08053 ; Narayanan et al., Efficient Large-Scale Language Model Training on GPU Clusters, SC 2021 — 2104.04473Parallélisme de tenseurs ; 3D parallelismTenseurs intra-nœud, pipeline/données inter-nœuds
Rajbhandari et al., ZeRO, SC 2020 — 1910.02054 ; Zhao et al., PyTorch FSDP, 2023 — 2304.11277Partitionner états, gradients, paramètres16 octets/paramètre divisés par n GPU
Huang et al., GPipe, NeurIPS 2019 — 1811.06965Pipeline avec micro-lotsThéorème 3 (bulle)
Kwon et al., vLLM / PagedAttention, SOSP 2023 — 2309.06180 ; Yu et al., Orca (continuous batching), OSDI 2022Cache KV paginé ; lots dynamiquesThéorème 4 : remplir la mémoire sans gaspillage
Pope et al., Efficiently Scaling Transformer Inference, 2022 — 2211.05102Analyse complète latence/débit/coût du service de grands modèlesLes formules de TTFT/TPOT et leurs régimes
Dao et al., FlashAttention, 2022 (L25)Noyau IO-awareExemple canonique d’optimisation guidée par le roofline
Patterson et al., Carbon Emissions and Large Neural Network Training, 2021 — 2104.10350Empreinte énergétique et carboneLe mix électrique et l’efficacité matérielle comptent plus que le modèle
Sculley et al., Hidden Technical Debt in Machine Learning Systems, NeurIPS 2015Le modèle est 5 % du systèmeLire avant de construire une plateforme (L38)
Documentation NVIDIA (CUDA, NCCL, TensorRT-LLM), PyTorch (FSDP, torch.compile), vLLMRéférences pratiquesLes chiffres changent chaque année : re-mesurer

TP guidé

TP — Mesurer, puis optimiser un service (5 h)

Exercices

Exercices auto-corrigés

Exercice 1 — Roofline

Écrivez temps_noyau(flops, octets, pic, bw) (borne du Théorème 1) et regime(flops, octets, pic, bw) renvoyant "mémoire" ou "calcul". Vérifiez sur : décodage lot 1 d’un 7B, produit 4096³, et une convolution 3×3 sur 224×224×64→64.

Correction
def temps_noyau(flops, octets, pic, bw): return max(flops / pic, octets / bw)
def regime(flops, octets, pic, bw): return "mémoire" if octets / bw > flops / pic else "calcul"

Exercice 2 — Mémoire d’entraînement et nombre de GPU

Écrivez memoire_entrainement(N, n_gpu, strategie, activ_go) renvoyant la mémoire par GPU en Go : "ddp" (16N octets par GPU + activations), "fsdp" (16N/n_gpu + activations), "lora" (2N poids gelés en bf16 + 16·r_params pour les adaptateurs, r_params = 1 % de N, + activations). Puis gpus_necessaires(N, strategie, mem_gpu, activ_go) (plus petit n_gpu ∈ {1, 2, 4, 8, 16, 32, 64} qui tient, ou None).

Correction
def memoire_entrainement(N, n_gpu, strategie, activ_go=10):
    if strategie == "ddp": return 16 * N / 1e9 + activ_go
    if strategie == "fsdp": return 16 * N / n_gpu / 1e9 + activ_go
    if strategie == "lora": return 2 * N / 1e9 + 16 * 0.01 * N / 1e9 + activ_go
def gpus_necessaires(N, strategie, mem_gpu=80, activ_go=10):
    for n in (1, 2, 4, 8, 16, 32, 64):
        if memoire_entrainement(N, n, strategie, activ_go) <= mem_gpu: return n
    return None

Exercices

Exercices auto-corrigés (suite)

Exercice 3 — All-reduce en anneau et bulle de pipeline

Écrivez temps_allreduce(S, n, bw, latence) = 2(n−1)·(S/n/bw + latence) et bulle(p, m) ; vérifiez la borne asymptotique 2S/bw, l’effet de la latence sur les petits messages, et trouvez le plus petit m tel que bulle(8, m) < 0,1.

Correction
def temps_allreduce(S, n, bw, latence=10e-6): return 2 * (n - 1) * (S / n / bw + latence)
def bulle(p, m): return (p - 1) / (m + p - 1)

Exercice 4 — Capacité d’un service sous SLO

Écrivez capacite(B, ttft, tpot, n_out) = requêtes/s servies par un GPU à lot B (latence = ttft + n_out·tpot) et gpus_pour(req_s, slo_s, options) qui, parmi une liste d’options (B, ttft, tpot), choisit celle qui respecte latence ≤ slo et minimise le nombre de GPU (arrondi supérieur, marge 30 %) ; renvoie (n_gpu, B) ou None.

Correction
def capacite(B, ttft, tpot, n_out=300): return B / (ttft + n_out * tpot)
def gpus_pour(req_s, slo_s, options, n_out=300):
    ok = [(math.ceil(req_s * 1.3 / capacite(B, t1, t2, n_out)), B) for B, t1, t2 in options if t1 + n_out * t2 <= slo_s]
    return min(ok) if ok else None

Fiche de cours · Exercices corrigés

Exercices corrigés (rédaction)

Exercice 1. Un serveur d’inférence affiche 8 % d’utilisation GPU alors que la latence est déjà de 2 s par requête. Diagnostic ?
Correction. Utilisation faible + latence élevée = régime mémoire-limité en petit lot (Théorème 1) ou goulot hors GPU. Vérifier dans l’ordre : (1) taille de lot effective — si les requêtes sont servies une à une, le GPU passe son temps à relire les poids : activer le continuous batching (vLLM) ; (2) la tokenisation, le prétraitement ou la recherche RAG sur CPU dans le chemin critique (profiler par étape) ; (3) transferts hôte↔GPU (données non pré-chargées) ; (4) précision : un modèle en fp32 double les octets ; (5) le cache KV fragmenté qui limite le lot. Attendu après correction : utilisation 40–70 %, latence stable, débit ×5–10.
Exercice 2. Pourquoi le parallélisme de tenseurs reste-t-il à l’intérieur d’un nœud, alors que le parallélisme de données s’étend à des milliers de GPU ?
Correction. Le parallélisme de tenseurs découpe chaque couche : il exige une communication (all-reduce des activations partielles) à chaque couche, à chaque passage, soit des centaines de collectives par pas, de taille modérée mais à latence critique ; seul NVLink (~900 Go/s, latence de quelques µs) le supporte sans dominer le calcul. Le parallélisme de données ne communique qu’une fois par pas (les gradients, 2N octets), en une collective de grande taille, recouvrable par le calcul de l’arrière (Théorème 2 : coût indépendant de n en bande passante) ; il tolère InfiniBand (50 Go/s). D’où le schéma 3D : tenseurs dans le nœud (8 GPU), pipeline entre quelques nœuds, données sur le reste.
Exercice 3. Un robot embarque un Jetson Orin (25 TFLOP/s, 200 Go/s, 32 Go). Peut-il exécuter un LLM 8B en int4 pour le dialogue, et un détecteur d’objets à 30 images/s ? Chiffrer.
Correction. LLM 8B int4 : 4 Go de poids ; TPOT ≈ 4·10⁹/2·10¹¹ = 20 ms/token → 50 tok/s en lot 1 : suffisant pour un dialogue (une phrase de 30 tokens en 0,6 s) ; TTFT pour 500 tokens de prompt ≈ 2·8·10⁹·500/(25·10¹²·0,5) ≈ 0,6 s. Détecteur (YOLO-type, ~10 GFLOP/image) : 30 images/s = 300 GFLOP/s, soit 1,2 % du pic — largement faisable en fp16/int8 avec TensorRT, mais il partage la mémoire et le calcul avec le LLM : ordonnancer (priorité temps réel au détecteur, L18), et vérifier la dissipation thermique (le Jetson bride sa fréquence à chaud). Conclusion : oui, avec quantification, TensorRT, et une gestion explicite des ressources ; le LLM en cloud reste une option si la connectivité et la latence (≈ 1 s) sont acceptables.

Vérification

Un GPU de 1 PFLOP/s décode un LLM 7B en bf16 à ~240 tokens/s en lot 1. Quelle est la ressource saturée ?

Deux questions supplémentaires

1. Pourquoi le lot est-il « gratuit » jusqu’à un certain point ? Les poids sont lus une fois par étape quel que soit B ; le temps ne change pas tant que le calcul 2NB reste sous le temps de lecture (Théorème 4).

2. Pourquoi 16 octets par paramètre à l’entraînement ? Poids bf16 + copie fp32 + deux moments d’Adam fp32 + gradient bf16.

Référence

Les mots à retenir

MotDéfinition
RooflineDébit ≤ min(pic, intensité × bande passante).
Intensité arithmétiqueFLOPs par octet transféré ; décodage ≈ 1, matmul ≈ 1 000.
Précision mixtebf16 pour le calcul, fp32 pour les poids maîtres et l’accumulation.
DDP / FSDP / tenseurs / pipelineRépliquer / partitionner / découper les couches / étager les couches.
All-reduce en anneau2(n−1)/n × S octets par nœud ; optimal en bande passante.
TTFT / TPOTTemps au premier token (calcul) / par token (mémoire).
Continuous batching, PagedAttentionLots dynamiques ; cache KV paginé.
MFUFraction du pic réellement utilisée (40–60 % en bon entraînement).

Suite

Vous savez ce que coûte un modèle. Lequel choisir ?

Chapitre suivant : la méthode de sélection d’un modèle — besoins, contraintes, candidats, évaluation comparative, coût total, et les pièges.

← L32SommaireL34 : choisir un modèle →