Chapitre 3 : Techniques d'entraînement distribué
Introduction
L'entraînement des LLMs avec des milliards de paramètres nécessite de distribuer le travail sur de nombreux GPU. Ce chapitre couvre les principales stratégies de parallélisme.
Parallélisme de données
L'approche la plus simple
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel
# Chaque GPU traite des données différentes, même modèle
model = DistributedDataParallel(model)
Limitation : Le modèle doit tenir sur un seul GPU
Parallélisme de modèle
Parallélisme de tenseur
Diviser les couches individuelles sur les GPU :
[Matrice de poids de la couche]
↓ Diviser les colonnes
[GPU 0: W[:, :d/2]] [GPU 1: W[:, d/2:]]
Parallélisme de pipeline
Différentes couches sur différents GPU :
GPU 0: Couches 0-11
GPU 1: Couches 12-23
GPU 2: Couches 24-35
GPU 3: Couches 36-47
ZeRO : Optimiseur sans redondance
Trois étapes
| Étape | Ce qui est partitionné | Économies de mémoire |
|---|---|---|
| ZeRO-1 | États de l'optimiseur | 4x |
| ZeRO-2 | + Gradients | 8x |
| ZeRO-3 | + Paramètres | Linéaire avec les GPU |
Implémentation avec DeepSpeed
import deepspeed
model_engine, optimizer, _, _ = deepspeed.initialize(
model=model,
config={
"zero_optimization": {
"stage": 3,
"offload_optimizer": {"device": "cpu"},
"offload_param": {"device": "cpu"}
},
"bf16": {"enabled": True}
}
)
Calcul d'entraînement
Mise à l'échelle de Chinchilla
Entraînement optimal : environ 20 tokens par paramètre
# Taille de modèle optimale en fonction du calcul
def optimal_model_size(compute_budget):
# C ≈ 6 * N * D (N=paramètres, D=tokens)
# Optimal : D ≈ 20N
return compute_budget / (6 * 20)
Points clés à retenir
Résumé
- Parallélisme de données pour les petits modèles
- Parallélisme de modèle lorsque le modèle ne tient pas sur un seul GPU
- ZeRO réduit considérablement les besoins en mémoire
- Précision mixte (bf16) accélère l'entraînement