Aller au contenu principal

Module 1 — Les limites des récurrents que l'attention lève

Le cours 11 a construit des LSTM capables de lire une séquence mot par mot et d'en retenir une trace utile. Pour bien des tâches, cela fonctionne. Pour la traduction, la synthèse ou la compréhension de longs documents, cela plafonne, et le plafond est structurel — il ne se casse pas en ajoutant des paramètres. Ce module explique pourquoi, puis pose l'idée qui va tout débloquer : une couche capable de comparer chaque position à toutes les autres en un seul passage.

Le fil rouge du cours

Tout au long de ce cours, nous construisons un petit Transformer en PyTorch d'environ 200 lignes, capable d'apprendre une tâche jouet visible à l'œil nu : traduire une date écrite en français vers son format ISO, par exemple « 3 mars 2026 » vers « 2026-03-03 ». La tâche est assez simple pour tenir sur un portable et assez structurée pour que les cartes d'attention soient lisibles au module 10. À chaque module, une brique du modèle est ajoutée : l'attention seule (module 2), plusieurs têtes (3), l'encodage de position (4), les résidus et la normalisation (5), puis l'assemblage complet (6 à 8 et 10). Les grands modèles réels — BERT, GPT, T5 — sont abordés en contrepoint via la bibliothèque transformers de Hugging Face.

La séquentialité tue le parallélisme

Un LSTM lit ses entrées une position à la fois. Pour calculer l'état caché hth_t, il faut d'abord avoir calculé ht1h_{t-1}. Cette dépendance est irréductible : elle est inscrite dans les équations de la cellule. Sur une séquence de longueur LL, l'entraînement enchaîne donc LL étapes qui ne peuvent pas se recouvrir dans le temps.

Le problème n'est pas tant le nombre d'opérations que leur ordonnancement. Une carte graphique moderne exécute des milliers de multiplications en parallèle ; elle est faite pour être nourrie par des lots massifs de calculs indépendants. Un LSTM qui traite dix mille phrases de 200 mots doit encore attendre 200 fois avant d'avoir fini une seule phrase. Le taux d'occupation du matériel tombe, et la vitesse d'entraînement plafonne bien en dessous de ce que la carte pourrait fournir.

Une couche capable de calculer toutes les positions en même temps, sans dépendre d'un ordre séquentiel, exploiterait pleinement le matériel. C'est exactement ce que l'attention va offrir : une opération dont le coût principal, un produit matriciel, se parallélise trivialement.

Le goulot du vecteur de contexte

Dans un modèle encodeur-décodeur récurrent classique — celui de Sutskever, Vinyals et Le en 2014 — l'encodeur lit toute la phrase source et produit un unique vecteur de dimension fixe, souvent de 512 ou 1024 valeurs. C'est ce vecteur, et lui seul, qui alimente le décodeur.

Le problème saute aux yeux dès qu'on écrit la contrainte : compresser une phrase arbitrairement longue dans un vecteur de taille fixe fait mécaniquement perdre de l'information. Les premiers mots, lus il y a de nombreuses étapes, se diluent au fil du parcours. La courbe de performance décroche typiquement au-delà d'une vingtaine ou d'une trentaine de mots. Les LSTM aident, sans effacer le plafond.

Ce plafond ne se résout pas par la taille

Augmenter la dimension du vecteur de contexte ou empiler des couches améliore les scores à la marge, mais ne change pas la nature du goulot. Toute l'information source passe encore par un tuyau unique. Le seul remède est d'ouvrir plusieurs tuyaux, ce que l'attention fait.

L'attention de Bahdanau, en 2014, sert de pont

Bahdanau, Cho et Bengio proposent en 2014 un remède au goulot : au lieu de résumer la source en un seul vecteur, le décodeur consulte tous les états de l'encodeur à chaque étape, avec une pondération qui varie selon le mot qu'il est en train de produire.

Concrètement, pour chaque mot cible à générer, le modèle calcule un score d'alignement entre l'état courant du décodeur et chacun des états de l'encodeur, puis passe ces scores par un softmax pour obtenir des poids. Le contexte utilisé est la somme pondérée des états de l'encodeur. Autrement dit, le décodeur regarde ce qui l'intéresse dans la phrase source, sans être obligé de tout faire tenir dans un vecteur unique.

Cette idée transforme la traduction automatique : les scores de BLEU montent, et surtout les longues phrases cessent de s'effondrer. Les cartes d'alignement obtenues sont interprétables — on y voit le mot cible qui pointe vers le mot source correspondant, ce qui donne à l'attention son intuition durable de « regarder au bon endroit ».

Mais le modèle reste récurrent en son cœur. L'encodeur et le décodeur sont des LSTM ; l'attention n'est qu'une couche additionnelle. La séquentialité subsiste, et avec elle la limite matérielle.

De 2014 à 2017 : « Attention is all you need »

Trois ans plus tard, huit chercheurs de Google signent un article au titre volontairement provocant : Attention is all you need. Leur idée tient en une phrase : puisque l'attention règle le goulot, pourquoi ne pas la garder seule, sans récurrence du tout ?

Le Transformer résultant remplace complètement les LSTM par des piles de couches d'attention et de simples réseaux à propagation avant, appliqués à toutes les positions en parallèle. La séquentialité n'est plus dans le modèle ; l'ordre des mots est réintroduit par un encodage de position ajouté aux entrées (module 4). Sur la traduction anglais-allemand, l'architecture bat l'état de l'art précédent tout en s'entraînant plusieurs fois plus vite, parce qu'elle sature enfin les cartes graphiques.

La chronologie mérite d'être retenue, car elle explique la structure du domaine aujourd'hui :

AnnéeÉtapeModèleCe qui change
2014Encodeur-décodeur RNNSutskever et al.Traduction en apprentissage de bout en bout
2014Attention additiveBahdanau et al.Le goulot du vecteur unique disparaît
2017TransformerVaswani et al.La récurrence disparaît à son tour
2018BERT et GPT-1Devlin, RadfordLe Transformer se préentraîne à grande échelle
2020+T5, GPT-3, ...Raffel, Brown, ...La même architecture monte à des centaines de milliards de paramètres
# Illustration : le coût séquentiel d'un LSTM contre le coût "aplati" d'une attention.
# On mesure des temps CPU, l'important est le rapport.
import time
import torch
import torch.nn as nn

L, B, D = 256, 32, 128
x = torch.randn(B, L, D)

lstm = nn.LSTM(input_size=D, hidden_size=D, batch_first=True)
attn = nn.MultiheadAttention(embed_dim=D, num_heads=4, batch_first=True)

t0 = time.perf_counter(); _ = lstm(x); t_lstm = time.perf_counter() - t0
t0 = time.perf_counter(); _ = attn(x, x, x); t_attn = time.perf_counter() - t0
print(f"LSTM : {t_lstm:.3f} s attention : {t_attn:.3f} s")
Ce que l'on mesure et ce que l'on ne mesure pas

Ce script compare deux couches sur CPU, à séquence courte. Sur GPU et sur des séquences longues, l'écart en faveur de l'attention se creuse encore, jusqu'à un ordre de grandeur. En revanche, à séquence très longue, l'attention paie son coût quadratique en mémoire — c'est l'objet du module 9.

En résumé

  • La séquentialité des LSTM empêche le parallélisme et laisse le matériel graphique sous-utilisé, ce qui plafonne la vitesse d'entraînement quelle que soit la taille du modèle.
  • Le goulot du vecteur de contexte unique fait perdre de l'information sur les longues séquences et ne se résout pas en agrandissant ce vecteur.
  • L'attention de Bahdanau (2014) ouvre un accès direct à tous les états sources, mais laisse la récurrence en place et ses limites avec.
  • Le Transformer (2017) supprime la récurrence et pose l'attention comme opération centrale, ce qui parallélise entièrement le calcul et débloque l'échelle.

Module suivant : ouvrir la boîte noire de l'attention et calculer sa sortie à la main sur trois jetons, avec les projections requête, clé et valeur.