LLM Engineering Avancé

Optimisation Avancée des LLM : Architecture Interne et Stratégies de Performance en Production

Plongez dans les mécanismes internes des transformers et maîtrisez les techniques d'optimisation critiques pour déployer des LLM performants en production. Ce cours décortique l'architecture, révèle les goulots d'étranglement et fournit des stratégies éprouvées pour maximiser l'efficacité.

Preparetoi.academy 30 min

1. Anatomie Interne des Transformers : De l'Embedding à la Génération

Définition

L'architecture transformer repose sur un mécanisme d'attention auto-régressive qui traite les séquences de tokens en parallèle pendant l'entraînement, puis de façon autorisatrice durant l'inférence. Chaque couche contient des têtes d'attention multi-heads, des réseaux feed-forward avec activations non-linéaires, et des mécanismes de normalisation critiques pour la stabilité.

Analogie Pédagogique

Imaginez une équipe de traducteurs simultanés (heads d'attention) dans une salle. Chacun se concentre sur certains mots et leurs relations (queries, keys, values). Ils travaillent en parallèle, puis un superviseur (feed-forward) reformule les insights combinés avant de passer à l'équipe suivante. La chaîne complète crée progressivement une compréhension nuancée du texte.

Tableau Comparatif : Composants et Responsabilités

Composant Fonction Primaire Coût Mémoire Coût Computationnel Optimisabilité
Embedding Layer Conversion token→vecteur O(V×d) O(1) par token Basse (fixe)
Multi-Head Attention Modélisation des dépendances O(n×d) O(n²×d) Très haute
Feed-Forward Networks Non-linéarité et expansion O(d×d_ff) O(n×d×d_ff) Haute
Layer Normalization Stabilité numérique O(d) O(n×d) Faible
Positional Encoding Information positionnelle O(n×d) O(1) Moyenne

Astuce d'Expert

Exploitez la détection des "attention heads mortes" - certaines têtes convergent vers des patterns statiques. Identifier et analyser ces têtes révèle souvent des optimisations possibles : vous pouvez les supprimer (pruning) ou les recycler pour d'autres tâches. Utilisez les statistiques d'entropie des distributions d'attention pour quantifier ce phénomène.

⚠️ Attention Critique

Le coût quadratique de l'attention O(n²) n'est jamais vraiment éliminé - seul le contexte de la fenêtre peut être réduit. Les variantes "linéarisant" l'attention (linear attention, kernel-based) modifient les propriétés mathématiques de la convergence. Vérifiez toujours la capacité d'expressivité avant d'optimiser agressivement.


2. Quantization et Compression : Réduire Sans Casser

Définition

La quantization convertit les poids et activations de précision flottante (float32, float16) vers des représentations entières de plus basse précision (int8, int4, bfloat16). La post-training quantization (PTQ) s'applique après entraînement, tandis que la quantization-aware training (QAT) intègre les effets de la quantization durant l'apprentissage pour une plus grande fidélité.

Analogie Pédagogique

Pensez à la quantization comme la compression d'une image haute résolution en JPEG. Vous réduisez les données brutes, mais les détails critiques doivent survivre. Un JPEG agressif crée des artefacts visibles ; une compression intelligente préserve les contours importants. De même, quantizer intelligemment préserve les "contours" décisionnels du modèle.

Tableau Détaillé : Schémas de Quantization

Schéma Précision Perte Typique (Accuracy) Compression Use Case Complexité
PTQ Int8 Asymétrique int8 0.5-2% Inférence CPU/edge Basse
PTQ Int4 Groupwise int4 1-3% Mobile, embeddings Moyenne
QAT Mixed-Precision int8/int4 0.1-0.5% Critique performance Haute
GPTQ (Quantization-aware) int4 (groupé) 0.2-0.8% LLM 7B-13B Haute
Activation Quantization int8 activations 1-5% Réduction mémoire Moyenne

Astuce d'Expert

Utilisez la "calibration par percentile" plutôt que par min-max pour les outliers. Identifiez les activations qui ont des queues de distribution longues (tokens rares, gradients expliquant) ; quantizez-les séparément. Pour GPTQ spécifiquement, calculez l'ordre de Hessian Schur pour prioriser les poids critiques lors de la quantization groupe par groupe.

⚠️ Attention Critique

Les couches early (embedding, premières couches d'attention) sont souvent plus sensibles à la quantization que les couches finales. Ne compressez jamais uniformément. Les activations sont plus difficiles à quantizer que les poids ; les approches dynamiques (per-batch) augmentent la latence d'inférence. Testez systématiquement sur des benchmarks représentatifs de votre domaine applicatif.


3. KV-Cache, Paging et Optimisation Mémoire en Inférence

Définition

Le KV-cache (Key-Value cache) stocke les clés et valeurs pré-calculées des tokens précédents pour éviter de les recalculer durant l'inférence autoégressive. Cela réduit le coût de chaque pas de décodage de O(n²×d) à O(1×d) asymptotiquement, mais introduit une pression mémoire croissante O(n×d×num_layers×batch_size). Le paging (comme dans vLLM) traite le KV-cache comme de la mémoire virtuelle paginée pour fragmenter et réutiliser efficacement l'espace.

Analogie Pédagogique

Imaginez un scénario de restaurant : lors du premier appel (requête initiale), le serveur écoute chaque client entièrement (attention complète). Ensuite, il prend note (KV-cache) des commandes précédentes. Pour les appels suivants, il ne consulte que ses notes au lieu de réécouter. Le paging est comme utiliser un cahier au lieu de mémoriser : vous pouvez utiliser un cahier partagé par plusieurs tables (batch), paginé sur le disque si nécessaire.

Tableau Comparatif : Stratégies de Gestion Mémoire

Stratégie Pic Mémoire Latence Token Utilisation GPU Fragmentation Scalabilité Batch
KV-Cache Standard O(n×d×L×B) Basse (très) Très haute Moyenne Faible (OOM rapide)
KV-Cache avec Recompute O(√(n)×d×L×B) Moyenne Haute Basse Moyenne
Paging (vLLM) O(n×d×L×B/page_size) Basse+ Très haute Très basse Très élevée
Ring Buffer KV O(context_window×d×L×B) Basse Très haute Nulle Très élevée
Sparse Attention KV O(sparse_ratio×n²×d×L) Basse/Moyenne Moyenne Faible Élevée

Astuce d'Expert

Implémentez un "scheduler de paging" adaptatif : au lieu d'utiliser une taille de page fixe, ajustez dynamiquement la granularité du paging en fonction du ratio hit-rate du cache. Si vous générez des batches hétérogènes (longueurs d'entrée/sortie variées), utilisez le "continuous batching" avec préemption : les séquences courtes terminent rapidement et libèrent la mémoire pour les longues. Mesurez le "effective batch size" (tokens/seconde) plutôt que le nombre brut de séquences.

⚠️ Attention Critique

Le paging introduit des accès mémoire non-contiguës, réduisant potentiellement la bande passante effective. Les latences de swap disque (si débordement GPU→CPU) peuvent devenir dominantes. Le "batch reordering" (traiter d'abord les courtes séquences) crée une variance importante en latence pour les utilisateurs. Documentez toujours le "latency SLA" vs "throughput trade-off" que votre architecture impose.


4. Fine-tuning Efficace : LoRA, Adapters et Mixing of Experts Dynamiques

Définition

Le fine-tuning pleine dimension met à jour tous les paramètres du LLM, consommant énormément de mémoire et de temps. Les méthodes efficaces (LoRA, adapters) introduisent des modules paramétrés supplémentaires de dimension réduite. LoRA (Low-Rank Adaptation) décompose les mises à jour de poids en produits de deux matrices de rang faible : ΔW = AB^T où A∈ℝ^(d×r) et B∈ℝ^(d×r) avec r << d. Les Mixture-of-Experts dynamiques ajoutent une couche de routage pour activer sélectivement des experts spécialisés.

Analogie Pédagogique

Imaginez un système de tuteurs spécialisés. Au lieu de réentraîner chaque tuteur (fine-tuning complet), vous envoyez des "instructions de correction" minimalistes (LoRA) à leurs notes existantes. Ces corrections capturent les principes essentiels de votre domaine sans reécrire les manuels entiers. Pour les Mixture-of-Experts, certains tuteurs se spécialisent en mathématiques, d'autres en langues ; un superviseur (router) dirige chaque étudiant vers l'expert approprié.

Tableau Comparatif : Méthodes de Fine-tuning

Méthode Params Trainables Mémoire GPU Vitesse Training Flexibilité Qualité Finale
Full Fine-tuning 100% Très haute Basse Très haute Excellente
LoRA (r=8) 0.1-0.5% Basse Très haute Haute Très bonne
LoRA (r=64) 1-2% Basse-Moyenne Très haute Très haute Excellente
Adapter Modules 1-5% Basse Haute Moyenne Bonne
Prefix-tuning 0.1-1% Basse Très haute Basse Acceptable
MoE Dynamique 10-30% (selon routing) Haute Moyenne Très haute Excellente (tâches mixtes)

Astuce d'Expert

Pour LoRA, le rang r = 8 est souvent un sweet spot, mais mesurez la "intrinsic dimensionality" du fine-tuning en calculant les valeurs singulières des mises à jour de poids sur un petit subset. Utilisez des "LoRA blocks" spécialisés : applicatifs seulement à certaines couches (attention + dernière couche feed-forward typiquement). Pour les MoE dynamiques, implémentez l'"expert load balancing" via une perte auxiliaire qui pénalise les déséquilibres de routage, sinon tous les tokens convergent vers 1-2 experts.

⚠️ Attention Critique

LoRA suppose une faible intrinsèque dimensionnalité des mises à jour - faux pour les changements de domaine drastiques. Un adapter avec 5% de paramètres peut dépasser LoRA à rang 8 sur certaines tâches. Les MoE introduisent une variance importante (dropout stochastique du routage) ; nécessitent une regularization délicate. Le "catastrophic forgetting" revient même avec ces méthodes - utilisez systématiquement des techniques de replay ou continual learning si fine-tunez séquentiellement sur plusieurs tâches.


5. Debugging et Profiling : Identifier les Bottlenecks en Production

Définition

Le debugging de LLM en production requiert une instrumentation profonde des trois dimensions : computationnelle (où le temps CPU/GPU est dépensé), mémoire (pics et fuites), et comportementale (sorties dégradées, mode collapse). Le profiling collecte des traces exécution précises ; l'analyse révèle les goulots. Les outils modernes (PyTorch Profiler, TensorRT, Triton Inference Server) exposent les kernels GPU critiques et les stalls de mémoire.

Analogie Pédagogique

Déboguer un LLM est comme diagnostiquer un patient compliqué. Vous ne voyez que les symptômes (latence élevée, mémoire saturée, outputs bizarres). Vous devez tester systématiquement : scanner (profiling) révèle où les problèmes se concentrent. Une latence élevée vient-elle de l'I/O réseau, du compute GPU, ou de la congestion mémoire ? Chaque cause exige un traitement différent.

Tableau de Diagnostic : Symptômes et Root Causes

Symptôme Observé Root Causes Probables Outils de Debug Solution Typique
Latence élevée (p99) Queuing batch, TTFT > 500ms Triton metrics, vLLM logs Augmenter batch_size ou ajouter instances
Crête GPU mémoire soudaine KV-cache non-libéré, mémoire fragment nvidia-smi, torch.cuda.memory_allocated() Réduire max_tokens_per_batch ou impl streaming
Throughput réduisant (>24h) Fuite mémoire, accumulateurs de gradients Memory Profiler, torch.utils.checkpoint Vérifier delete() explicite des tensors
Mode Collapse (rép. répétées) Temperature=0, beam_search défectueux Logits histogrammes, sequence analysis Augmenter temperature, ajouter penalties
Divergence output vs baseline Quantization non-calibrée, opérateurs fondus Layer-wise activation comparison Recalibrer quantization sur données réelles
Variance inter-infos (même prompt) Seed non-controllé, ordre d'exécution GPU Fixer seed + redémarrer GPU state torch.manual_seed() + gpu memset

Astuce d'Expert

Implémentez un "heartbeat profiler" : collectez toutes les 1000 tokens générés les métriques clés (peak_memory, compute_time, memory_allocated). Plottez les timeline pour identifier les patterns. Utilisez "activation checkpointing" (recompute) sur les couches suspectes une à une pour isoler les outliers. Enfin, profilez avec des données réelles en production (shadowing) : les benchmark synthétiques masquent souvent des patterns pathologiques d'utilisation réelle.

⚠️ Attention Critique

Le profiling introduit un overhead non négligeable (5-20% en général). N'activez jamais le profiling complet sur 100% du trafic production ; échantillonnez (ex: 1% des requêtes). Les outils GPU (nvprof, nsys) génèrent des fichiers énormes ; comprimez et streamez vers stockage distant. Les problèmes mémoire sont souvent "intermittents" (ex: OOM seulement après N heures) ; testez les scenarios de long-running avec des boucles synthétiques. Enfin, distinguez clairement : latency variance due aux ressources partagées (réseau, CPU) vs latency dus au modèle lui-même.

Accédez à des centaines d'examens QCM — Découvrir les offres Premium