Self-Attention
L’auto-attention permet à chaque jeton d’une séquence d’accorder un poids à tous les autres, à l’aide de requêtes, de clés et de valeurs issues de la même entrée. Elle est au cœur des Transformers.
L’auto-attention est une forme d’attention dans laquelle les requêtes, les clés et les valeurs proviennent toutes de la même séquence. Ainsi, chaque jeton construit sa nouvelle représentation à partir de tous les autres jetons de cette séquence. Une couche d’auto-attention peut relier en une seule étape les premiers et derniers mots d’un paragraphe, ou les coins opposés d’une image, tandis qu’un réseau neuronal récurrent (RNN) a besoin d’une étape par position et qu’un réseau neuronal convolutif (CNN) nécessite de nombreuses couches empilées pour élargir son champ de perception. Associée à des couches feed-forward, elle forme le Transformer présenté dans l’article de 2017 Attention Is All You Need, qui est à la base des grands modèles de langage (LLM), des Transformers de vision (ViT) et des détecteurs basés sur les Transformers.
Fonctionnement de l’auto-attention#
Chaque jeton d’entrée, représenté par un plongement, est multiplié par trois matrices apprises pour produire une requête, une clé et une valeur. La sortie du jeton i est une moyenne pondérée des vecteurs de valeur de tous les jetons. Les poids sont obtenus en appliquant une fonction softmax aux produits scalaires mis à l’échelle de la requête du jeton i avec toutes les clés ; c’est l’attention par produit scalaire mis à l’échelle décrite sur la page consacrée au mécanisme d’attention. Comme les requêtes, les clés et les valeurs sont des projections des mêmes jetons, une séquence de n jetons produit une matrice de poids n × n. Dans « L’animal n’a pas traversé la rue parce qu’il était trop fatigué », la ligne correspondant à « il » peut attribuer la majeure partie de son poids à « animal » et intégrer le sens de ce mot à sa propre représentation.
L’auto-attention multi-têtes exécute plusieurs de ces calculs en parallèle sur des projections plus petites, puis concatène les résultats. Les différentes têtes peuvent ainsi suivre des relations différentes, comme la syntaxe pour l’une et la coréférence pour une autre. Le Transformer d’origine utilisait 8 têtes de 64 dimensions chacune dans un modèle de 512 dimensions.
L’aveuglement à l’ordre et le masquage causal#
L’auto-attention traite son entrée comme un ensemble. Mélanger les jetons mélange les sorties de la même façon sans rien changer d’autre. Les modèles ajoutent donc des informations de position, par exemple des plongements sinusoïdaux dans le Transformer d’origine ou un plongement positionnel rotatif (RoPE) dans la plupart des LLM actuels. Les encodeurs comme BERT permettent à chaque jeton de prêter attention aux jetons situés dans les deux directions. Les LLM à décodeur seul appliquent un masque causal afin que chaque jeton ne prête attention qu’à lui-même et aux jetons précédents. Un modèle peut ainsi générer du texte de gauche à droite et réutiliser les clés et les valeurs des jetons précédents à partir d’un cache KV. L’MultiheadAttention de PyTorch illustre ces deux propriétés lorsque le même tenseur est passé comme requête, clé et valeur :
import torch
torch.manual_seed(0)
tokens = torch.randn(1, 5, 16) # une séquence de 5 jetons avec 16 caractéristiques chacun
attn = torch.nn.MultiheadAttention(embed_dim=16, num_heads=2, batch_first=True)
# Auto-attention : les requêtes, les clés et les valeurs sont toutes des projections des mêmes jetons
out, weights = attn(tokens, tokens, tokens)
print("Attention weights shape:", tuple(weights.shape))
# Mélanger les jetons ne fait que mélanger les sorties ; sans positions, l’ordre des mots est donc invisible
perm = torch.tensor([3, 0, 4, 1, 2])
out_shuffled, _ = attn(tokens[:, perm], tokens[:, perm], tokens[:, perm])
print("Same outputs after shuffling:", torch.allclose(out_shuffled, out[:, perm], atol=1e-6))
# Un masque causal bloque l’attention portée aux jetons suivants, comme dans un LLM à décodeur seul
mask = torch.triu(torch.ones(5, 5, dtype=torch.bool), diagonal=1)
_, causal_weights = attn(tokens, tokens, tokens, attn_mask=mask)
print(causal_weights[0].detach().round(decimals=2))Le résultat affiche une forme de poids (1, 5, 5), True pour le test de mélange, ainsi qu’une matrice triangulaire inférieure : le premier jeton attribue un poids de 1.00 à lui-même, le deuxième répartit les poids 0.31 et 0.69 entre les deux premiers jetons, et chaque élément au-dessus de la diagonale vaut 0.00.
L’auto-attention et les notions connexes#
- Mécanisme d’attention : opération générale qui pondère les valeurs en fonction de la similarité entre les requêtes et les clés. L’auto-attention est le cas où les trois proviennent d’une même séquence.
- Attention croisée : les requêtes proviennent d’une séquence, et les clés et les valeurs d’une autre. Un décodeur de traduction prête attention à la phrase source encodée, les requêtes d’objet d’un décodeur DETR prêtent attention aux caractéristiques de l’image, et un modèle de diffusion texte-image prête attention à l’invite.
- Convolution : applique le même petit filtre à chaque position. Chaque sortie voit donc une fenêtre locale fixe dont les poids ne dépendent pas du contenu. L’auto-attention calcule ses poids à partir du contenu et couvre l’ensemble de l’entrée.
Le Transformer encodeur-décodeur d’origine combine l’auto-attention bidirectionnelle, l’auto-attention causale et l’attention croisée :
Coût et variantes efficaces#
Le calcul du score de chaque paire de jetons fait croître le temps et la mémoire selon le carré de la longueur de la séquence : 1 000 jetons donnent un million de scores par tête, et 100 000 jetons en donnent dix milliards. FlashAttention calcule l’auto-attention exacte par tuiles sans stocker la matrice complète, l’attention à requêtes groupées (GQA) partage les clés et les valeurs entre les têtes pour réduire la taille du cache KV, et l’attention à fenêtre glissante, clairsemée et linéaire réduit le nombre de paires. En vision, le nombre de jetons dépend de la résolution de l’image, si bien que de nombreux détecteurs n’appliquent l’auto-attention que là où les cartes de caractéristiques sont les plus petites. YOLO26 n’exécute l’auto-attention multi-têtes que dans le bloc C2PSA à la fin de son backbone et dans un bloc C3k2 avec attention dans le neck, tous deux sur la carte de caractéristiques 20 × 20, à stride 32, d’une image de 640 pixels, soit 400 jetons. Son module d’attention calcule les requêtes, les clés et les valeurs à l’aide d’une convolution 1 × 1 sur cette carte et ajoute des informations de position avec une convolution depthwise 3 × 3 appliquée aux valeurs.










