L’attention et l’auto-attention
Requêtes, clés et valeurs construites depuis la base : pourquoi l’attention existe, comment se calcule l’attention par produit scalaire mis à l’échelle, pourquoi elle est divisée par la racine carrée de la dimension, et comment fonctionne le masquage causal, avec chaque matrice calculée et vérifiée.
Prérequis : La rétropropagation et la descente de gradient
L’auto-attention est le mécanisme qui a rendu possibles les modèles de langue modernes. Elle permet à chaque position d’une séquence de regarder toutes les autres et de décider, par elle-même, lesquelles comptent. Cet article la construit depuis le problème qu’elle résout jusqu’au calcul matriciel complet, en déroulant chaque nombre sur un exemple de trois tokens assez petit pour être vérifié à la main.
A. Le problème que l’attention résout
Pensez à résoudre à quoi renvoie « il » dans une phrase. L’information nécessaire siège ailleurs dans la séquence, et où elle siège dépend entièrement de la phrase. Une approche à fenêtre fixe ne peut pas exprimer « regarde en arrière vers le mot antérieur dont celui-ci dépend réellement ».
L’attention rend cette dépendance apprise et dépendante des données : chaque position calcule, à partir du contenu même des tokens, combien puiser à chaque autre position.
Explorateur des poids d’attention
Une requête portant sur quatre paires clé/valeur.
- Poids le plus élevé
- 29.7%
- Étalement de l’attention
- 0.990
| Jeton | q · k | ÷ √dₖ | Poids | |
|---|---|---|---|---|
| the | 0.40 | 0.20 | 22.0% | |
| cat | 1.00 | 0.50 | 29.7% | |
| sat | 0.92 | 0.46 | 28.5% | |
| down | 0.20 | 0.10 | 19.9% |
Vecteur de requête
Sortie - somme pondérée des vecteurs de valeur
[0.220, 0.297, 0.285, 0.199]
L’attention est une moyenne pondérée, et le softmax en fixe les poids. Baissez la température et elle se concentre sur un seul jeton ; augmentez-la et l’attention se répartit uniformément. Désactiver la mise à l’échelle √dₖ écarte davantage les scores bruts et pousse le softmax vers la saturation : c’est précisément la raison d’être de ce facteur.
B. Requêtes, clés et valeurs
Chaque plongement de token d’entrée est projeté en trois vecteurs par trois matrices de poids apprises :
L’analogie avec une base de données est réellement appropriée :
- la requête est ce que cette position cherche ;
- la clé est ce que chaque position annonce d’elle-même ;
- la valeur est ce que chaque position apporte effectivement si l’on s’y intéresse.
Confronter une requête à une clé mesure la pertinence ; les valeurs sont ce qui se mélange. Séparer « ce qui identifie un token » (clé) de « ce qu’il apporte » (valeur) est ce qui donne au mécanisme sa souplesse - et sont appris par la passe arrière de La rétropropagation et la descente de gradient.
C. L’attention par produit scalaire mise à l’échelle
Le mécanisme entier, pour toutes les positions à la fois :
Lisez-le en quatre étapes : scorer chaque requête contre chaque clé (), mettre à l’échelle par , normaliser chaque ligne pour qu’elle somme à 1 (softmax), puis prendre la moyenne des valeurs pondérée en conséquence.
Raschka note que cela s’appelle l’attention par produit scalaire mise à l’échelle, et que c’est le mécanisme employé dans le transformeur originel et dans la famille GPT.
D. Le dérouler complètement
Trois tokens, . Pour garder l’arithmétique vérifiable, nous prenons et déjà projetés et égaux, avec des valeurs distinctes :
Étape 1 - les scores d’attention. L’entrée vaut :
Vérifions-en une : ligne 3, colonne 3 vaut , le plus grand score de la matrice - la requête du token 3 correspond le mieux à sa propre clé.
Étape 2 - mise à l’échelle. On divise par :
Étape 3 - softmax sur chaque ligne. Pour la ligne 1, l’exponentiation donne , , , de somme . En divisant :
Les trois lignes :
Chaque ligne somme à 1 - ce sont de véritables pondérations. La ligne 3 met sur la position 3, ce qui correspond au score le plus fort de l’étape 1.
Étape 4 - valeurs pondérées. On multiplie par . Ligne 1, première composante :
Chaque ligne de sortie est un mélange des trois vecteurs de valeurs, dosé par une pertinence apprise.
S'exécute dans votre navigateur. La première exécution télécharge l'environnement Python (~10 Mo), puis il est mis en cache.
Son exécution reproduit les deux matrices et affiche matches: True True.
E. Pourquoi diviser par la racine carrée de la dimension
La mise à l’échelle n’est pas cosmétique. Un produit scalaire de deux vecteurs de dimension somme termes : sa magnitude croît donc avec - à peu près comme pour des composantes indépendantes de variance unité.
De grands scores posent problème au softmax. Quand les entrées grandissent, le softmax approche un vecteur one-hot : un poids proche de 1 et le reste proche de 0. Dans ce régime saturé, ses gradients sont minuscules et l’apprentissage cale. Diviser par maintient les scores dans une plage où le softmax reste sensible et où les gradients continuent de circuler.
Avec , les scores non mis à l’échelle seraient environ huit fois plus grands que les scores mis à l’échelle - largement de quoi saturer.
La figure ci-dessous est cette même tête, avec deux réglages. Tourner la requête du jeton trois la fait pivoter dans le plan où vivent ses clés, et seule la troisième ligne de la matrice réagit : les clés et les valeurs ne bougent pas, et c’est précisément ce qui fait d’une requête une requête. Augmentez ensuite la dimension. Avec la division, il ne se passe rien du tout : la matrice en dimension 512 est celle ci-dessus, à la dernière décimale près. Coupez la division et recommencez : la ligne s’effondre sur un seul jeton. Cet effondrement est toute la raison d’être de la racine carrée.
Interactif : orientez une requête, puis changez la dimension
Seule la requête du jeton 3 bouge. Clés et valeurs restent où la leçon les a mises.
Poids d’attention, ligne par ligne
- Diviseur
- 1.4142
- Poids maximal
- 0.5035
- Étalement ligne 3
- 1.496 bits
- Sortie ligne 3
- 1.76, 1.00
Avec la division, la matrice d’attention ne dépend pas du tout de d_k : faites glisser la dimension de 2 à 512, aucun poids ne bouge. Cette invariance est tout le propos de la racine carrée : elle maintient les scores à une taille constante alors que les produits scalaires bruts croissent comme sqrt(d_k), et le softmax reste dans la plage où il a encore un gradient à rendre. La ligne 3 est étalée sur 1.496 bits sur les 1,585 possibles.
F. Le masquage causal
Un modèle qui engendre du texte de gauche à droite ne doit pas voir le futur. Si la position 2 pouvait s’intéresser à la position 3, le modèle serait entraîné avec accès à la réponse et échouerait au moment de la génération, quand le futur n’existe réellement pas.
L’attention causale l’empêche par masquage : avant le softmax, tout score en est mis à , de sorte que et que ces positions reçoivent un poids nul. Les poids restants se renormalisent pour sommer à 1.
En l’appliquant à nos scores mis à l’échelle :
La ligne 1 ne s’intéresse qu’à elle-même, son poids est donc forcé à . La ligne 2 se répartit entre les positions 1 et 2 - notez que ce ne sont pas les valeurs non masquées de la ligne 2, et ; la position 3 étant retirée, les deux restantes sont renormalisées par leur propre somme, , donnant et . (Reporter les valeurs arrondies à la main donne et ; les chiffres ci-dessus viennent du calcul en pleine précision.) La ligne 3, qui n’a jamais eu le droit de voir au-delà de la position 3, est inchangée.
Raschka note aussi qu’un masque de dropout est souvent appliqué aux poids d’attention pendant l’entraînement, afin de réduire le surajustement.
G. Plusieurs têtes
Un calcul d’attention capture un type de relation. L’attention multi-têtes en exécute plusieurs en parallèle avec des distincts, puis concatène les sorties et les reprojette vers le bas. Différentes têtes peuvent se spécialiser - l’une suivant des dépendances syntaxiques, l’autre des liens thématiques à plus longue portée - et le modèle n’est pas contraint de comprimer toutes les relations dans une pondération unique.
À retenir
- L’attention laisse chaque position décider, à partir du contenu, combien puiser à chaque autre position.
- Chaque token est projeté en une requête, une clé et une valeur ; les requêtes se confrontent aux clés, et ce sont les valeurs qui se mélangent.
- Le mécanisme est - scorer, mettre à l’échelle, normaliser, mélanger.
- Le diviseur prévient la saturation du softmax et garde des gradients exploitables.
- Le masquage causal met les scores futurs à , de sorte que les poids se renormalisent sur le seul passé.
- L’attention multi-têtes en exécute plusieurs en parallèle pour capturer différentes relations.
La suite
L’attention est le cœur du transformeur, mais un modèle de langue opérationnel a aussi besoin de tokenisation, de plongements, d’information positionnelle, de blocs à propagation avant et d’un objectif d’entraînement. Ces pièces sont couvertes dans le reste de cette série, et le pendant en IA classique de « fouiller l’espace des possibles » est développé dans La recherche adversariale et le minimax.
Références et lectures complémentaires
- Sebastian Raschka, Build a Large Language Model (From Scratch), Manning, 2025· Bibliothèque de référence Kudos AI
Les œuvres protégées par le droit d’auteur sont citées à titre de référence uniquement et ne sont pas hébergées ici ; veuillez consulter l’éditeur pour y accéder.