Introduction
L’attention causale est le mécanisme à la base de la plupart des avancées en IA depuis 2017. Dans cet article, je vais détailler le calcul et, espérons-le, acquérir une meilleure intuition de son fonctionnement.
À un niveau élevé, cette fonction prend une séquence et la transforme en une autre. Une séquence est une liste d’embeddings de tokens, un tenseur de forme , où est la longueur de la séquence d’entrée et est la dimension de l’embedding. Chaque ligne de cette matrice correspond à un token d’entrée, représenté comme un vecteur de dimension .
Alors pourquoi y a-t-il 3 entrées pour ? C’est parce que, dans l’architecture Transformer, la séquence d’entrée est projetée par 3 couches linéaires différentes de taille . Si est la séquence d’entrée,
où sont de taille . Ainsi, sont simplement des représentations différentes de la même séquence d’entrée.
Calculons étape par étape. D’abord, nous effectuons , qui est un produit scalaire de par , résultant en une sortie de taille . Que fait cette opération ?
Le résultat de est un scalaire ( produit scalaire ), et il représente le produit scalaire entre et . Si nous nous rappelons de la formule
nous voyons que le produit scalaire est positif lorsque , l’angle entre et , est proche de 0º et négatif lorsque l’angle est de 180º, ou lorsqu’ils pointent dans des directions opposées. Nous pouvons interpréter le produit scalaire comme une métrique de similarité, où les valeurs positives indiquent des vecteurs similaires, et les valeurs négatives indiquent le contraire.
Ainsi, notre matrice finale est remplie de scores de similarité entre chaque paire de tokens et . Le résultat est divisé par pour éviter que la variance n’explose pour de grandes dimensions d’embedding. Voir Annexe pour plus de détails.
L’étape suivante consiste à appliquer la fonction , qui définit toutes les valeurs qui ne sont pas dans la section triangulaire inférieure de la matrice d’entrée à .
À cela, nous appliquons , qui convertit chaque ligne de valeurs de la matrice en une distribution de probabilité. La fonction est définie comme une application de , où le ème élément de sortie est donné par
Deux choses à noter ici :
- La somme de tous les éléments de sortie est , comme attendu pour une distribution de probabilité.
- Si un élément d’entrée est , alors .
Après avoir appliqué la fonction aux scores de similarité masqués, nous obtenons :
Où les entrées sont définies comme :
La matrice résultante a des lignes de distribution de probabilité de longueur . La dernière étape consiste à mapper notre matrice de valeurs par ces distributions de probabilité pour obtenir notre nouvelle séquence.
Notez que est un scalaire, et est un vecteur d’embedding de taille . Visuellement, nous observons que SelfAttention combine sélectivement les tokens de valeur, pondérés par une distribution de probabilité générée par la manière dont les requêtes et les clés s’attendent mutuellement, c’est-à-dire ont un grand produit scalaire. Nous voyons également que le poids d’un token de sortie à l’indice ne dépend que des tokens d’entrée avec un indice , en raison du masque causal que nous avons appliqué précédemment. Cela repose sur l’hypothèse causale, selon laquelle un token de sortie ne dépend pas des tokens futurs, ce qui est nécessaire lors de l’entraînement de modèles autoregressifs (c’est-à-dire la prédiction du token suivant).
J’espère que vous avez trouvé cela utile !
Annexe
Pourquoi diviser par ?
Nous faisons cela pour éviter que la variance n’explose lorsque augmente.
Supposons que et i.i.d. Calculons la moyenne et la variance de non divisé.
La moyenne est trivialement nulle :
Et la variance est :
car
qui est pour (puisque et sont i.i.d). Pour ,
puisque .
Ainsi, si nous divisons par , notre nouvelle variance est
comme souhaité.
Attention Multi-Têtes
La plupart des systèmes modernes utilisent l’attention multi-têtes, qui calcule en parallèle sur plusieurs “têtes”. Nous laissons généralement , où est le nombre de têtes.