# Mécanismes d'attention dans les Transformers : Self-Attention, Cross-Attention et Multi-Head
Les mécanismes d'attention permettent aux modèles d'IA de pondérer dynamiquement l'importance des éléments d'une séquence d'entrée. Pour chaque token, des poids sont calculés à l'aide des matrices Query, Key et Value, créant des représentations contextualisées. La self-attention examine les connexions au sein d'une même séquence, la cross-attention relie l'encodeur et le décodeur, et la multi-head attention parallélise le processus pour capturer différents aspects des données.
Théorie de la Self-Attention
La séquence d'entrée est représentée par la matrice $X \in \mathbb{R}^{n \times d}$, où $n$ est le nombre de tokens et $d$ la dimension d'embedding. À partir de $X$, on projette les matrices $Q = XW^Q$, $K = XW^K$, $V = XW^V$ avec des poids $W^{Q,K,V} \in \mathbb{R}^{d \times d_k}$.
La matrice des scores d'attention $A_{ij} = \frac{Q_i K_j^T}{\sqrt{d_k}}$ mesure la pertinence du $j$-ième token pour le $i$-ième. L'échelle par $\sqrt{d_k}$ stabilise les gradients, évitant leur disparition dans le softmax.
La matrice normalisée $N = \mathrm{softmax}(A)$ sur les lignes fournit une distribution probabiliste. Sortie : $\mathrm{Attention}(Q, K, V) = N V$.
Exemple de Self-Attention
Considérons la phrase « Karina va au magasin », tokenisée en ["karina", "va", "au", "le", "magasin"] avec $n=5$. Embeddings (simplifiés) :
| Token | Embedding |
|---------|-----------|
| karina | [1, 0] |
| va | [0, 1] |
| au | [1, 1] |
| le | [1, 1] |
| magasin | [0.5, 1] |
Matrice $X_{5\times2} = \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 1 & 1 \\ 1 & 1 \\ 0.5 & 1 \end{bmatrix}$. Pour simplifier, $W^Q = W^K = W^V = I$, donc $Q=K=V=X$.
$QK^T = \begin{bmatrix} 1 & 0 & 1 & 1 & 0.5 \\ 0 & 1 & 1 & 1 & 1 \\ 1 & 1 & 2 & 2 & 1.5 \\ 1 & 1 & 2 & 2 & 1.5 \\ 0.5 & 1 & 1.5 & 1.5 & 1.25 \end{bmatrix}$, divisée par $\sqrt{2} \approx 1.41$ :
$A \approx \begin{bmatrix} 0.71 & 0 & 0.71 & 0.71 & 0.35 \\ 0 & 0.71 & 0.71 & 0.71 & 0.71 \\ 0.71 & 0.71 & 1.42 & 1.42 & 1.06 \\ 0.71 & 0.71 & 1.42 & 1.42 & 1.06 \\ 0.35 & 0.71 & 1.06 & 1.06 & 0.89 \end{bmatrix}$.
Après softmax par ligne : $N \approx \begin{bmatrix} 0.25 & 0.15 & 0.25 & 0.25 & 0.10 \\ 0.17 & 0.23 & 0.23 & 0.23 & 0.23 \\ 0.15 & 0.15 & 0.30 & 0.30 & 0.10 \\ 0.15 & 0.15 & 0.30 & 0.30 & 0.10 \\ 0.14 & 0.23 & 0.28 & 0.28 & 0.07 \end{bmatrix}$.
Sortie $N \times V = \begin{bmatrix} 0.73 & 0.68 \\ 0.57 & 0.87 \\ 0.68 & 0.81 \\ 0.68 & 0.81 \\ 0.63 & 0.84 \end{bmatrix}$. Les nouveaux embeddings intègrent désormais le contexte : le vecteur pour « va » reflète un mouvement humain plutôt qu'un temps abstrait.
import torch
import torch.nn as nn
class SelfAttention(nn.Module):
def __init__(self, embed_dim):
super().__init__()
self.embed_dim = embed_dim
self.q_linear = nn.Linear(embed_dim, embed_dim)
self.k_linear = nn.Linear(embed_dim, embed_dim)
self.v_linear = nn.Linear(embed_dim, embed_dim)
self.scale = embed_dim ** 0.5
def forward(self, x):
Q = self.q_linear(x)
K = self.k_linear(x)
V = self.v_linear(x)
scores = torch.bmm(Q, K.transpose(1, 2)) / self.scale
attn = torch.softmax(scores, dim=-1)
out = torch.bmm(attn, V)
return out
Cross-Attention : Relier les Séquences
En cross-attention, Query provient du décodeur ($Q = X_{dec}W^Q$), tandis que Key et Value viennent de l'encodeur ($K = X_{enc}W^K$, $V = X_{enc}W^V$). Le calcul est identique : $\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\left( \frac{QK^T}{\sqrt{d_k}} \right) V$.
Différences clés :
| Composant | Self-Attention | Cross-Attention |
|-----------|----------------|-----------------|
| Q | X | X_dec |
| K | X | X_enc |
| V | X | X_enc |
Cela permet au décodeur de se concentrer sur les parties pertinentes du contexte de l'encodeur.
import torch
import torch.nn as nn
class CrossAttention(nn.Module):
def __init__(self, embed_dim):
super().__init__()
self.embed_dim = embed_dim
self.q_linear = nn.Linear(embed_dim, embed_dim)
self.k_linear = nn.Linear(embed_dim, embed_dim)
self.v_linear = nn.Linear(embed_dim, embed_dim)
self.scale = embed_dim ** 0.5
def forward(self, x_dec, x_enc):
Q = self.q_linear(x_dec)
K = self.k_linear(x_enc)
V = self.v_linear(x_enc)
scores = torch.bmm(Q, K.transpose(1, 2)) / self.scale
attn = torch.softmax(scores, dim=-1)
out = torch.bmm(attn, V)
return out
Multi-Head Attention : Perspectives Parallèles
La multi-head attention exécute $h$ calculs d'attention indépendants avec des projections $Q^{(i)} = X W_Q^{(i)}$, $K^{(i)} = X W_K^{(i)}$, $V^{(i)} = X W_V^{(i)}$. Chaque tête : $\mathrm{head}_i = \mathrm{Attention}(Q^{(i)}, K^{(i)}, V^{(i)})$.
Les résultats sont concaténés et projetés : $\mathrm{MultiHead}(X) = \mathrm{Concat}(head_1, \dots, head_h) W^O$. Taille de tête $d_k = d / h$, où $d$ est embed_dim.
import torch
import torch.nn as nn
class MultiHeadSelfAttention(nn.Module):
def __init__(self, embed_dim, num_heads):
super().__init__()
assert embed_dim % num_heads == 0
self.embed_dim = embed_dim
self.num_heads = num_heads
self.head_dim = embed_dim // num_heads
self.q = nn.Linear(embed_dim, embed_dim)
self.k = nn.Linear(embed_dim, embed_dim)
self.v = nn.Linear(embed_dim, embed_dim)
self.out = nn.Linear(embed_dim, embed_dim)
def forward(self, x):
B, T, D = x.shape
Q = self.q(x).view(B, T, self.num_heads, self.head_dim).transpose(1, 2)
K = self.k(x).view(B, T, self.num_heads, self.head_dim).transpose(1, 2)
V = self.v(x).view(B, T, self.num_heads, self.head_dim).transpose(1, 2)
scores = torch.matmul(Q, K.transpose(-2, -1)) / (self.head_dim ** 0.5)
attn = torch.softmax(scores, dim=-1)
out = torch.matmul(attn, V).transpose(1, 2).contiguous().view(B, T, D)
return self.out(out)
Points Clés
- Self-attention contextualise les tokens : Chaque vecteur de sortie dépend de la séquence entière.
- L'échelle par $\sqrt{d_k}$ est essentielle : Elle stabilise softmax et gradients.
- Cross-attention pour seq2seq : Relie encodeur et décodeur dans les transformers.
- Multi-head capture des aspects divers : Grammaire, sémantique, dépendances à longue portée.
- Implémentations PyTorch utilisent Linear et bmm : Pour l'efficacité par lots.
— Editorial Team
Aucun commentaire pour le moment.