Transformers : l'Architecture qui a Tout Changé
Comprenez le mécanisme d'attention, l'architecture Transformer (encoder/decoder), BERT, GPT et les Vision Transformers avec des implémentations PyTorch.
Avant les Transformers : le Problème des Séquences
Les limites des RNN et LSTM
Avant 2017, le traitement du langage reposait sur les réseaux récurrents (RNN, LSTM, GRU). Ces architectures traitent les mots un par un, dans l''ordre :
Problèmes :
- Séquentiel : impossible de paralléliser → entraînement lent
- Mémoire courte : les premiers mots sont "oubliés" dans les longues phrases
- Vanishing gradient : le gradient s''évanouit en traversant trop d''étapes
La révolution de 2017
Le papier "Attention Is All You Need" (Vaswani et al., 2017) a tout changé en proposant une architecture basée uniquement sur des mécanismes d''attention, sans aucune récurrence.
Ce papier de Google est probablement le plus influent de la dernière décennie en IA. Il a engendré GPT, BERT, Claude, Gemini, Stable Diffusion et presque tous les modèles modernes.
Le Mécanisme d''Attention
L''intuition
Quand vous lisez "Le chat qui était sur le tapis dort", vous savez instinctivement que "dort" se rapporte à "chat" et pas à "tapis". Le mécanisme d''attention fait la même chose : il apprend quels mots sont importants les uns par rapport aux autres.
Self-Attention pas à pas
Pour chaque mot (token), on calcule 3 vecteurs :
- Query (Q) : "Je cherche quoi ?"
- Key (K) : "Qu''est-ce que je contiens ?"
- Value (V) : "Quelle information je transmets ?"
Attention(Q, K, V) = softmax(Q · Kᵀ / √dₖ) · V
Étape par étape :
- Calculer les scores : Q · Kᵀ → chaque mot note sa compatibilité avec tous les autres
- Normaliser : diviser par √dₖ pour éviter les valeurs trop grandes
- Softmax : transformer en probabilités (somme = 1)
- Pondérer : multiplier par V pour obtenir la représentation contextuelle
Exemple concret
Phrase : "Le chat dort"
| Le | chat | dort | |
|---|---|---|---|
| Le | 0.1 | 0.7 | 0.2 |
| chat | 0.1 | 0.3 | 0.6 |
| dort | 0.0 | 0.8 | 0.2 |
"dort" accorde 80% de son attention à "chat" → il comprend que c''est le chat qui dort.
Implémentation simplifiée en PyTorch
import torch
import torch.nn.functional as F
def self_attention(x, d_model=64):
"""
x : tensor de shape (batch, seq_len, d_model)
"""
# Projections linéaires
W_q = torch.nn.Linear(d_model, d_model, bias=False)
W_k = torch.nn.Linear(d_model, d_model, bias=False)
W_v = torch.nn.Linear(d_model, d_model, bias=False)
Q = W_q(x) # (batch, seq_len, d_model)
K = W_k(x)
V = W_v(x)
# Score d''attention
d_k = Q.size(-1)
scores = torch.matmul(Q, K.transpose(-2, -1)) / (d_k ** 0.5)
# Softmax → poids d''attention
attn_weights = F.softmax(scores, dim=-1)
# Sortie pondérée
output = torch.matmul(attn_weights, V)
return output, attn_weights
Multi-Head Attention
Au lieu d''une seule attention, on en exécute plusieurs en parallèle (typiquement 8 ou 12 "têtes"). Chaque tête peut apprendre un type de relation différent :
- Tête 1 : relations sujet-verbe
- Tête 2 : relations adjectif-nom
- Tête 3 : coréférences (pronoms)
class MultiHeadAttention(torch.nn.Module):
def __init__(self, d_model=512, n_heads=8):
super().__init__()
self.n_heads = n_heads
self.d_head = d_model // n_heads
self.W_q = torch.nn.Linear(d_model, d_model)
self.W_k = torch.nn.Linear(d_model, d_model)
self.W_v = torch.nn.Linear(d_model, d_model)
self.W_o = torch.nn.Linear(d_model, d_model)
def forward(self, x):
batch, seq_len, d_model = x.shape
# Projeter et diviser en têtes
Q = self.W_q(x).view(batch, seq_len, self.n_heads, self.d_head).transpose(1, 2)
K = self.W_k(x).view(batch, seq_len, self.n_heads, self.d_head).transpose(1, 2)
V = self.W_v(x).view(batch, seq_len, self.n_heads, self.d_head).transpose(1, 2)
# Attention par tête
scores = torch.matmul(Q, K.transpose(-2, -1)) / (self.d_head ** 0.5)
attn = F.softmax(scores, dim=-1)
context = torch.matmul(attn, V)
# Recombiner les têtes
context = context.transpose(1, 2).contiguous().view(batch, seq_len, d_model)
return self.W_o(context)
L''Architecture Transformer Complète
Encodage Positionnel
L''attention n''a aucune notion d''ordre. "Le chat mange la souris" et "La souris mange le chat" produiraient le même résultat. On ajoute donc un encodage positionnel :
import math
def positional_encoding(seq_len, d_model):
pe = torch.zeros(seq_len, d_model)
position = torch.arange(0, seq_len).unsqueeze(1).float()
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
pe[:, 0::2] = torch.sin(position * div_term) # Dimensions paires
pe[:, 1::2] = torch.cos(position * div_term) # Dimensions impaires
return pe
Pourquoi sin/cos ? Ces fonctions permettent au modèle d''apprendre des positions relatives : la différence entre la position 5 et 10 est la même qu''entre 100 et 105.
Bloc Transformer (Encoder)
Chaque bloc contient :
- Multi-Head Attention + Residual Connection + Layer Norm
- Feed-Forward Network + Residual Connection + Layer Norm
class TransformerBlock(torch.nn.Module):
def __init__(self, d_model=512, n_heads=8, d_ff=2048, dropout=0.1):
super().__init__()
self.attention = MultiHeadAttention(d_model, n_heads)
self.norm1 = torch.nn.LayerNorm(d_model)
self.norm2 = torch.nn.LayerNorm(d_model)
self.ffn = torch.nn.Sequential(
torch.nn.Linear(d_model, d_ff),
torch.nn.ReLU(),
torch.nn.Linear(d_ff, d_model),
)
self.dropout = torch.nn.Dropout(dropout)
def forward(self, x):
# Self-attention + residual
attn_out = self.attention(x)
x = self.norm1(x + self.dropout(attn_out))
# Feed-forward + residual
ffn_out = self.ffn(x)
x = self.norm2(x + self.dropout(ffn_out))
return x
BERT vs GPT : Encoder vs Decoder
Le Transformer original a un encoder ET un decoder. Les modèles modernes n''utilisent souvent qu''un seul des deux.
BERT (Encoder only)
- Attention bidirectionnelle : chaque mot voit tous les autres
- Entraînement : masquer des mots et les prédire (Masked Language Model)
- Usage : classification, NER, question answering
Entrée : "Le [MASK] dort sur le tapis"
BERT : "Le chat dort sur le tapis"
GPT (Decoder only)
- Attention causale : chaque mot ne voit que les précédents
- Entraînement : prédire le mot suivant (autorégressif)
- Usage : génération de texte, chatbots (ChatGPT, Claude)
Entrée : "Le chat dort sur"
GPT : → "le" → "tapis" → "."
| BERT | GPT | |
|---|---|---|
| Architecture | Encoder | Decoder |
| Attention | Bidirectionnelle | Causale (gauche→droite) |
| Tâche | Comprendre | Générer |
| Exemples | BERT, RoBERTa, CamemBERT | GPT-4, Claude, Llama |
CamemBERT est un modèle BERT entraîné spécifiquement sur du texte français. Il est excellent pour les tâches NLP en français.
Exercice : Utiliser un Transformer Pré-entraîné
Classification de sentiment avec Hugging Face
from transformers import pipeline
# Charger un pipeline de classification de sentiment
classifier = pipeline("sentiment-analysis", model="nlptown/bert-base-multilingual-uncased-sentiment")
# Tester sur des phrases françaises
phrases = [
"Ce film est absolument magnifique, je le recommande !",
"Service client horrible, jamais plus.",
"Le repas était correct, sans plus.",
]
for phrase in phrases:
result = classifier(phrase)[0]
print(f"'{phrase[:50]}...' → {result['label']} ({result['score']:.2f})")
Génération de texte avec GPT-2
from transformers import pipeline
generator = pipeline("text-generation", model="gpt2")
prompt = "Deep learning is"
results = generator(prompt, max_length=50, num_return_sequences=3)
for i, result in enumerate(results):
print(f"\n--- Génération {i+1} ---")
print(result["generated_text"])
Vision Transformers (ViT)
Les Transformers ne sont pas limités au texte. Le Vision Transformer (2020) traite les images en les découpant en patches et en les traitant comme une séquence de tokens.
Résultat : ViT atteint des performances comparables ou supérieures aux CNN, surtout avec beaucoup de données d''entraînement.
ViT nécessite beaucoup de données. Avec peu de données, un CNN avec transfer learning reste souvent meilleur. Google a entraîné ViT sur 300 millions d''images (JFT-300M).
Scaling Laws : Plus c''est Gros, Mieux c''est ?
Les recherches de Kaplan et al. (2020) ont montré que les performances des Transformers suivent des lois de puissance prévisibles :
| On augmente... | La performance... |
|---|---|
| Le nombre de paramètres | S''améliore (log-linéaire) |
| La quantité de données | S''améliore (log-linéaire) |
| Le compute (FLOPs) | S''améliore (log-linéaire) |
C''est ce qui a motivé la course aux modèles géants :
| Modèle | Paramètres | Année |
|---|---|---|
| BERT base | 110M | 2018 |
| GPT-2 | 1.5B | 2019 |
| GPT-3 | 175B | 2020 |
| GPT-4 | ~1.7T (estimé) | 2023 |
| Llama 3.1 | 405B | 2024 |
Nuance importante : les scaling laws montrent aussi des rendements décroissants. Doubler les paramètres ne double pas les performances. C''est pourquoi la recherche s''oriente aussi vers des modèles plus efficaces (distillation, quantization, MoE).
Pour Aller Plus Loin
- Exercice avancé : implémentez un Transformer encoder complet de zéro en PyTorch
- Lisez le papier original Attention Is All You Need
- Explorez Hugging Face pour découvrir les milliers de modèles pré-entraînés disponibles
- Testez CamemBERT sur des tâches NLP françaises :
camembert-basesur Hugging Face
Specialiste IA — Master Intelligence Artificielle
Diplome d'un Master en Intelligence Artificielle, je travaille au quotidien sur des projets IA en entreprise. J'ai cree IwanttolearnAI pour rendre l'apprentissage de l'IA accessible a tous, gratuitement.
Continuer a apprendre
RNN et LSTM : Modéliser les Séquences
Maîtrisez les réseaux récurrents : pourquoi les RNN oublient, comment les LSTM résolvent le vanishing gradient avec leurs 3 portes, et quand les utiliser face aux Transformers.
Diffusion Models : l'Architecture de Stable Diffusion
Plongez dans l'architecture des modèles de diffusion : forward process, U-Net débruiteur, guidance CLIP et Latent Diffusion. Comprenez ce qui propulse Stable Diffusion, SDXL et Flux.
Reinforcement Learning : Apprendre par l'Erreur
Maîtrisez le reinforcement learning : paradigme Agent/Environment, Q-Learning, DQN sur CartPole, PPO et le lien avec RLHF pour l'alignement des LLMs.