~/teaching · machine learning
Le mécanisme d'attention et le transformer, pas à pas
Une phrase simple, puis les maths, puis les chiffres à la main : plongements, requêtes, clés, valeurs, têtes, positions, encodeur, décodeur
Résumé
Un modèle de langue a besoin du sens d'un mot, et le sens d'un mot dépend des mots qui l'entourent. L'attention est l'opération qui permet à chaque mot d'une phrase d'emprunter aux autres, dans des proportions que le modèle apprend. Cet article la construit depuis la première idée jusqu'au transformer complet, dans l'ordre dont un étudiant a besoin : les plongements (embeddings), la moyenne pondérée, les requêtes, clés et valeurs, les têtes multiples, la position des mots, puis l'encodeur, le décodeur et la prédiction du mot suivant.
Chaque section s'ouvre par une phrase simple, donne ensuite les mathématiques, puis refait le calcul sur une phrase de quatre mots en deux dimensions, assez petite pour être vérifiée au crayon. Rien n'est caché derrière une bibliothèque : les douze lignes de NumPy de la fin reproduisent chaque nombre du texte.
Comment lire
- Vous avez dix minutes : lisez les phrases simples et regardez les figures, elles racontent toute l'histoire.
- Vous préparez un examen ou un entretien : suivez les listes « pas à pas » et refaites l'exemple sur papier ; les tableaux donnent les nombres à retrouver.
- Vous voulez l'implémenter : allez au code de la fin, puis revenez aux sections pour les raisons de chaque ligne.
Cet article accompagne le cours de machine learning de Centrale Méditerranée.
Partie I
Les mots comme vecteurs
Les plongements : un mot est un point dans l'espace
Un plongement transforme un mot en une liste de nombres, placée de sorte que les mots de sens proche soient voisins.
Un ordinateur ne peut pas comparer les mots actions et titres comme du texte : les deux chaînes n'ont aucune lettre commune. Il peut comparer deux listes de nombres. Un plongement (embedding) est une fonction qui donne à chaque jeton (token), un mot ou un morceau de mot, un vecteur de , avec de quelques centaines à quelques milliers, entraînée pour que la géométrie reflète le sens : vecteurs proches pour des mots liés, éloignés pour des mots sans rapport.
Pas à pas
- Découper. Couper le texte en jetons. Dans cet article un jeton est un mot ; les vrais modèles coupent en sous-mots, pour que les mots rares soient couverts aussi.
- Chercher dans la table. Chaque jeton est une ligne d'une grande table , où est la taille du vocabulaire. Le plongement du jeton est simplement la ligne .
- Comparer. Deux vecteurs se comparent par le cosinus de leur angle, qui ignore leur longueur : . Proche de 1, même direction ; proche de 0, sans rapport ; proche de , opposés.
La table est apprise, pas écrite à la main : on entraîne un modèle sur un grand corpus à prédire les mots à partir de leurs voisins, et les lignes de se placent là où la prédiction marche le mieux. Les régularités célèbres en découlent : dans un bon espace, le vecteur qui va de roi à reine est presque le même que celui qui va d'homme à femme.
L'exemple suivi dans tout l'article
Prenons la phrase Apple shares fell sharply (« les actions Apple ont chuté »), quatre jetons, et un espace jouet de dimension . Lisons l'axe 1 comme « nourriture » et l'axe 2 comme « finance ». La table de plongements, entraînée sur du texte général, a placé Apple près du fruit, parce que c'est ce que le mot veut dire le plus souvent :
Le cosinus entre Apple et shares vaut 0,29 : les plongements bruts disent que les deux mots ont peu à voir. Dans cette phrase, ils ont tout à voir. Cet écart est le problème que l'attention résout.
Le problème : un vecteur par mot, quelle que soit la phrase
Un plongement fixe donne le même vecteur à un mot dans toutes les phrases : il ne distingue pas un fruit d'une entreprise.
La table a une ligne par jeton. Apple reçoit le même vecteur dans an apple a day et dans Apple shares fell sharply ; intérêt reçoit le même vecteur qu'il soit un sentiment ou un taux ; obligation qu'elle soit morale ou financière. Les linguistes parlent de mots polysémiques ; pour un modèle, c'est un seul point qui devrait en être deux.
Ce que nous voulons, c'est une seconde suite , un vecteur par jeton, où est le vecteur du jeton dans cette phrase : le même mot, repositionné par ses voisins. Cette représentation doit se construire à partir de la phrase elle-même, au moment où on la lit, pas se lire dans une table.
Remarque (Pourquoi une moyenne pondérée). La façon la plus simple, pour un jeton, de tenir compte de son contexte est de se mélanger un peu de chacun des autres. Un mélange est une moyenne pondérée, et toute la question devient : combien de chaque voisin, et qui décide.
Partie II
Le mécanisme d'attention
L'attention comme moyenne pondérée
Chaque mot devient une moyenne pondérée de tous les mots de la phrase, avec plus de poids sur les mots qui comptent pour lui.
Soit la phrase, suite de plongements, jetons de dimension . Le vecteur contextuel du jeton est une somme pondérée de tous les jetons :
Le poids dit combien le jeton compte dans la nouvelle version du jeton . Les contraintes font des poids une distribution de probabilité sur la phrase, donc reste dans la même région de l'espace que les entrées : une vraie moyenne, pas une explosion.
Pas à pas
- Noter. Mesurer la pertinence de pour . La mesure la moins chère est le produit scalaire (dot product) : grand quand les deux vecteurs pointent dans la même direction, nul quand ils sont perpendiculaires.
- Normaliser. Transformer les notes de la ligne en poids positifs de somme 1 avec la fonction softmax : .
- Mélanger. Calculer par la somme pondérée de l'équation (3).
- Recommencer pour chaque jeton. Les lignes n'interagissent pas : les calculs sont indépendants et se font en parallèle, ce qui explique pourquoi cette opération convient si bien aux GPU.
En empilant les lignes, on obtient la forme matricielle. Avec , la matrice des notes est (l'entrée vaut ), le softmax s'applique ligne par ligne, et la nouvelle suite est le produit des poids par les entrées :
À la main, sur l'exemple
La ligne 1 est Apple. Ses produits scalaires avec les quatre jetons valent , puis 0,30 avec shares, 0,42 avec fell et 0,30 avec sharply. Les exponentielles, divisées par leur somme, donnent les poids de la première ligne du tableau 1.
| Apple | shares | fell | sharply | |
|---|---|---|---|---|
| Apple | 0,401 | 0,191 | 0,216 | 0,191 |
| shares | 0,176 | 0,359 | 0,245 | 0,220 |
| fell | 0,238 | 0,293 | 0,245 | 0,224 |
| sharply | 0,233 | 0,290 | 0,247 | 0,230 |
Le nouveau vecteur d'Apple est . Il a quitté vers l'axe finance, ce qui est la bonne direction, mais surtout parce que trois mots sur quatre s'y trouvent. Rien dans le calcul ne savait que shares était le mot qui comptait.
Remarque (Où la méthode cale). Le produit scalaire récompense les vecteurs qui pointent déjà dans la même direction. Si Apple et shares étaient perpendiculaires dans l'espace des plongements, leur note vaudrait 0 et shares recevrait le plus petit poids, exactement quand il devrait recevoir le plus grand. Les poids doivent être calculés dans un espace où les bonnes paires sont alignées, et cet espace doit être appris. C'est le travail de la section suivante.
Requêtes, clés et valeurs
Avant la comparaison, chaque mot est projeté trois fois : en une question qu'il pose, une étiquette à laquelle il répond, et un contenu qu'il transmet.
Dans la moyenne pondérée, un seul vecteur jouait trois rôles à la fois : il demandait du contexte, il servait de point de comparaison, et il entrait dans le mélange. Séparer les trois rôles donne au modèle la liberté d'apprendre chacun. Imaginez une salle de lecture : un lecteur dépose une requête (query), ce que je cherche ; chaque livre porte une clé (key) sur sa tranche, ce dont je parle ; et le livre lui-même est la valeur (value), ce que vous obtenez en l'ouvrant. La pertinence se mesure entre la requête et les clés ; ce qui est rendu est un mélange des valeurs.
Pas à pas
- Projeter. Trois matrices apprises transforment l'entrée en requêtes, clés et valeurs : , , , avec et .
- Noter. La note du jeton pour le jeton est le produit scalaire de la requête de avec la clé de : , soit .
- Mettre à l'échelle. Diviser les notes par pour qu'elles restent dans la plage où le softmax a encore un gradient (remarque ci-dessous).
- Normaliser et mélanger. Softmax sur chaque ligne, puis produit par les valeurs.
C'est l'attention par produit scalaire mis à l'échelle (scaled dot-product attention) de l'article de 2017, et c'est tout le mécanisme. Tout ce qui suit (têtes, positions, encodeur, décodeur) se construit autour de cette ligne. Les matrices , , sont les paramètres que l'entraînement ajuste : la perte sur la prédiction du jeton suivant les pousse pour que les requêtes d'un jeton s'alignent sur les clés des jetons qui aident à prédire la suite.
Remarque (Pourquoi diviser par la racine de la dimension des clés). Si les coordonnées de et sont indépendantes, de moyenne 0 et de variance 1, leur produit scalaire est une somme de termes de variance 1 : sa variance vaut et sa taille typique . Avec , les notes brutes s'étalent sur des dizaines d'unités, le softmax met toute sa masse sur un seul jeton, et son gradient s'évanouit. Diviser par ramène la variance à 1 quelle que soit la dimension.
À la main, sur l'exemple
D'abord la mise à l'échelle seule. Avec , les notes de la ligne 1 sont divisées par : 0,735, 0,212, 0,297, 0,212, et les poids deviennent 0,353, 0,209, 0,228, 0,209 : plus plats, comme attendu, puisque le softmax de nombres plus petits est plus proche de l'uniforme.
Puis une projection. Nous choisissons à la main pour montrer ce que l'entraînement pourrait découvrir : une matrice qui échange les deux axes. La requête d'un jeton demande alors l'autre lecture de lui-même. Apple, qui vit sur l'axe nourriture, demande la finance. et restent l'identité.
La requête d'Apple vaut maintenant . Ses notes mises à l'échelle contre les quatre clés sont 0,283, 0,721, 0,467, 0,382 : shares est désormais la meilleure correspondance, comme le montre le tableau 2.
| Apple | shares | fell | sharply | |
|---|---|---|---|---|
| Apple | 0,206 | 0,319 | 0,247 | 0,227 |
| shares | 0,361 | 0,202 | 0,227 | 0,210 |
| fell | 0,296 | 0,240 | 0,240 | 0,225 |
| sharply | 0,292 | 0,238 | 0,241 | 0,229 |
La sortie pour Apple devient , plus loin sur l'axe finance qu'avant, et cette fois parce que le bon mot l'a tirée. Une matrice , choisie exprès, a fait ce qu'aucun produit scalaire sur les plongements bruts ne pouvait faire. Un modèle entraîné possède des milliers de telles matrices et les choisit à partir des données.
L'attention multi-têtes
Plusieurs attentions tournent côte à côte, chacune avec ses projections, pour que l'une suive le sens pendant qu'une autre suit la grammaire.
Un jeu de projections capte une sorte de relation. La matrice d'échange ci-dessus règle Apple ; elle ne dit rien sur le verbe qui va avec quel sujet, ni sur le mot situé deux places à gauche. Plutôt que de demander tout à une projection, le transformer fait tourner attentions en parallèle, les têtes (heads), chacune avec ses , , de dimension réduite , puis recolle leurs sorties.
Pas à pas
- Séparer. La tête projette l'entrée dans son petit espace : , chaque sortie dans .
- Concaténer. Les sorties sont placées côte à côte, ce qui donne une matrice de .
- Reprojeter. Une dernière matrice mélange les têtes en une représentation par jeton.
Le coût est celui d'une seule tête de dimension pleine : têtes de dimension font autant d'arithmétique qu'une tête de dimension . Ce qu'on gagne, c'est la diversité. Dans les modèles entraînés, les sondes trouvent des têtes qui suivent la syntaxe (un verbe regarde son sujet), des têtes qui regardent le jeton précédent, des têtes qui recopient un mot rare vu plus tôt, et des têtes dont personne n'a nommé le rôle.
À la main, sur l'exemple
Prenons têtes de dimension . La tête 1 ne garde que la coordonnée finance de chaque jeton (), la tête 2 que la coordonnée nourriture (). Dans la tête 2, la ligne d'Apple vaut 0,425, 0,173, 0,211, 0,191 : Apple, seul mot de nourriture, se regarde surtout lui-même. Dans la tête 1, elle vaut 0,232, 0,272, 0,251, 0,246 : sur l'axe finance, les quatre jetons se ressemblent et les poids sont presque uniformes. La concaténation des deux sorties pour Apple donne ; avec l'identité, c'est la sortie multi-têtes.
Remarque (Ce que disent les deux têtes). La tête 2 répond à qui suis-je, la tête 1 à quel est le marché autour de moi. Une seule tête de dimension 2 aurait dû fondre les deux questions en une seule note. C'est tout l'intérêt des têtes : des questions séparées, des poids séparés, une réponse combinée.
L'encodage de position : donner un ordre aux mots
L'attention traite la phrase comme un sac de mots : on ajoute donc à chaque jeton un vecteur qui décrit sa position, avant toute autre chose.
Regardez à nouveau l'équation (6) : rien n'y dépend de l'indice sauf à travers . Permutez les jetons, les sorties sont permutées de la même façon, inchangées. Le fonds a racheté la banque et La banque a racheté le fonds donnent le même ensemble de vecteurs. L'ordre porte du sens et le mécanisme le jette.
Le remède consiste à ajouter à chaque plongement un vecteur qui ne dépend que de la position du jeton dans la suite, avant la première couche d'attention :
Pas à pas
- Choisir un code par position. L'article de 2017 utilise des sinus et cosinus de fréquences espacées géométriquement : la coordonnée de vaut , la coordonnée vaut . Les coordonnées basses oscillent vite et distinguent les positions voisines ; les hautes oscillent lentement et ordonnent toute la suite.
- Ajouter, pas concaténer. L'addition conserve la dimension et laisse les projections , lire position et contenu ensemble, ce qui permet à une tête d'apprendre à regarder le jeton juste avant moi.
- Laisser les couches s'en servir. À partir de là, chaque requête et chaque clé porte la position, et les notes peuvent dépendre de la distance autant que du sens.
Remarque (Pourquoi des sinus et des cosinus). Pour un décalage fixé, le couple à la position est une rotation du couple à la position d'un angle : une fonction linéaire, indépendante de . Une tête peut donc apprendre k positions à gauche comme une application linéaire fixe, quelle que soit la position absolue. Les encodages sont aussi bornés, et ils s'étendent à des longueurs jamais vues à l'entraînement. Beaucoup de modèles récents utilisent une variante rotative qui applique la même idée de rotation à l'intérieur des requêtes et des clés plutôt que de l'ajouter à l'entrée.
À la main, sur l'exemple
Avec il n'y a qu'une fréquence, , donc en radians. Le tableau 3 l'ajoute aux quatre plongements. Les deux phrases Apple shares fell sharply et Shares fell sharply, Apple donnent maintenant à Apple deux entrées différentes, en position 0 et en position 3, et tous les poids d'attention changent avec elles.
| jeton | |||||
|---|---|---|---|---|---|
| Apple | 0 | 0,000 | 1,000 | 1,000 | 1,200 |
| shares | 1 | 0,841 | 0,540 | 0,941 | 1,540 |
| fell | 2 | 0,909 | −0,416 | 1,209 | 0,184 |
| sharply | 3 | 0,141 | −0,990 | 0,341 | −0,490 |
Le bloc encodeur
Un bloc encodeur laisse les mots se parler (l'attention), puis laisse chaque mot réfléchir seul (un petit réseau de neurones), avec des raccourcis pour que l'entraînement reste stable.
Le transformer de Vaswani et al. (2017) a été construit pour transformer une suite en une autre, une phrase française en une phrase anglaise. Son encodeur (encoder) lit toute l'entrée et produit un vecteur riche en contexte par jeton d'entrée. C'est une pile de blocs identiques (6 dans l'article), et chaque bloc est fait de deux sous-couches enveloppées des deux mêmes astuces.
Un bloc encodeur, entrée
- Auto-attention multi-têtes. : requêtes, clés et valeurs viennent toutes de , d'où le nom d'auto-attention (self-attention). L'information passe entre les jetons ici, et seulement ici.
- Connexion résiduelle et normalisation. . Rajouter l'entrée (le résidu) signifie qu'un bloc n'a qu'une correction à apprendre, et que les gradients traversent la pile tout droit ; normaliser chaque vecteur de jeton à moyenne 0 et variance 1 garde l'échelle stable de bloc en bloc.
- Réseau à propagation avant. , le même réseau à deux couches (feed-forward network) appliqué à chaque jeton indépendamment : , avec une largeur cachée de dans l'article. Aucune information ne passe entre les jetons ici ; chaque vecteur est transformé seul.
- Résidu et normalisation à nouveau. est la sortie du bloc et l'entrée du suivant.
L'attention mélange à travers la phrase ; le réseau à propagation avant travaille à l'intérieur de chaque jeton. La répartition est voulue : l'attention décide où regarder, le réseau décide quoi en faire. Empiler blocs permet à un jeton de rassembler du contexte sur le contexte : après deux blocs, Apple peut utiliser ce que shares a lui-même appris de fell.
Le bloc décodeur
Le décodeur écrit la sortie un jeton à la fois, en regardant ce qu'il a déjà écrit et la lecture de l'entrée faite par l'encodeur.
Le décodeur (decoder) produit la suite de sortie jeton par jeton. À l'étape , il a déjà produit jetons, plongés et positionnés dans , et il dispose de la sortie de l'encodeur . Chacun de ses blocs a trois sous-couches, chacune enveloppée de la connexion résiduelle et de la normalisation de l'encodeur.
Un bloc décodeur
- Auto-attention masquée. Attention multi-têtes sur les jetons déjà écrits, avec un changement : un jeton ne peut regarder que les positions avant lui. Dans la matrice des notes, chaque entrée avec est mise à avant le softmax, et son poids devient exactement 0. Sans ce masque, l'entraînement laisserait le modèle lire la réponse qu'il est censé prédire.
- Attention croisée. Les requêtes viennent des vecteurs du décodeur ; les clés et les valeurs viennent de la sortie de l'encodeur . C'est là que la sortie regarde l'entrée : en écrivant le troisième mot anglais, le décodeur demande quels mots français lui sont pertinents. C'est le seul endroit où les deux moitiés du modèle se rencontrent.
- Réseau à propagation avant. Le même réseau par jeton que dans l'encodeur.
Remarque (Encodeur-décodeur, encodeur seul, décodeur seul). Le modèle de 2017 a les deux moitiés parce qu'il traduit. Les modèles qui classent ou plongent du texte ne gardent que l'encodeur (BERT en est un). Les grands modèles de langue qui écrivent du texte ne gardent que le décodeur : il n'y a pas d'entrée séparée à regarder, la consigne et la réponse forment une seule suite, et le masque est ce qui rend la génération de gauche à droite.
Prédire le jeton suivant
Le dernier vecteur du décodeur est transformé en une note pour chaque mot du vocabulaire, les notes deviennent des probabilités, et un mot est choisi.
Après le dernier bloc du décodeur, le vecteur à la dernière position, , résume tout ce qui a été écrit et tout ce qui a été lu dans l'entrée. Une couche linéaire le transforme en une note par entrée du vocabulaire, et un softmax transforme les notes en une distribution de probabilité :
La boucle de génération
- Noter le vocabulaire. Calculer la distribution ci-dessus pour le préfixe courant.
- Choisir un jeton. Le plus probable (décodage glouton), ou un tirage selon la distribution, souvent après l'avoir accentuée ou aplatie par une température, ou en ne gardant que les meilleurs candidats.
- Ajouter et recommencer. Le jeton choisi rejoint le préfixe, reçoit son plongement et sa position, et le décodeur tourne à nouveau. On s'arrête au jeton de fin de séquence ou à une longueur maximale.
À l'entraînement, il n'y a pas de boucle : toute la phrase cible est donnée au décodeur d'un coup, le masque cache l'avenir, et la perte est l'entropie croisée entre la distribution prédite à chaque position et le vrai jeton suivant, sommée sur la phrase. On appelle cela le forçage par l'enseignant (teacher forcing), et c'est pourquoi l'entraînement d'un transformer se parallélise sur la séquence alors que la génération ne le peut pas.
Remarque (Coût). L'auto-attention compare chaque jeton à tous les autres : notes de multiplications chacune, soit un temps en et une mémoire en par tête et par couche. Ce terme quadratique est la raison pour laquelle les longs contextes coûtent cher, et la raison d'être de toute une littérature sur les attentions creuses ou approchées.
Toute la passe avant, dans l'ordre
- Découper et plonger. Couper le texte en jetons ; chercher chacun dans la table pour obtenir .
- Ajouter les positions. , pour que l'ordre des mots survive à l'étape suivante.
- Projeter. Pour chaque tête, , , .
- Noter, mettre à l'échelle, masquer. , plus au-dessus de la diagonale dans un décodeur.
- Normaliser. Softmax sur chaque ligne : chaque jeton obtient une distribution sur la phrase.
- Mélanger. Multiplier les poids par ; concaténer les têtes ; projeter par .
- Résidu, normalisation, réseau avant, résidu, normalisation. Un bloc est fini ; répéter fois.
- Lire le dernier vecteur. Couche linéaire vers le vocabulaire, softmax, choisir un jeton, l'ajouter, revenir à l'étape 1 pour le nouveau préfixe.
La même arithmétique en douze lignes de NumPy
Douze lignes qui refont la section 4 sur la matrice de l'exemple, avec la projection qui échange les axes. Les deux lignes imprimées sont la première ligne du tableau 2 et la sortie d'Apple.
import numpy as np def attention(Q, K, V, mask=None): """Scaled dot-product attention, one line per step of section 4.""" d_k = K.shape[-1] S = Q @ K.T / np.sqrt(d_k) # scores, scaled if mask is not None: S = S + mask # -inf above the diagonal W = np.exp(S - S.max(axis=-1, keepdims=True)) W = W / W.sum(axis=-1, keepdims=True) # softmax, row by row return W @ V, W # mix of the values, and the weights # Apple, shares, fell, sharply X = np.array([[1.0, 0.2], [0.1, 1.0], [0.3, 0.6], [0.2, 0.5]]) W_Q = np.array([[0.0, 1.0], [1.0, 0.0]]) # the axis swap of section 4 Y, W = attention(X @ W_Q, X, X) print(W[0].round(3)) # [0.206 0.319 0.247 0.227]: Apple looks at shares print(Y[0].round(3)) # [0.358 0.623]
Glossaire
- Plongement (embedding)
- Une application apprise des jetons vers des vecteurs, entraînée pour que la distance reflète le sens. Une ligne par jeton dans une table .
- Jeton (token)
- L'unité que lit le modèle : un mot, un sous-mot ou un caractère, selon le découpeur.
- Attention
- Une moyenne pondérée des valeurs d'une suite, avec des poids calculés d'après l'accord entre une requête et toutes les clés.
- Requête, clé, valeur (query, key, value)
- Trois projections du même jeton : ce qu'il cherche, ce à quoi il répond, ce qu'il transmet.
- Tête (head)
- Une attention avec ses propres projections ; plusieurs tournent en parallèle et sont concaténées.
- Encodage de position (positional encoding)
- Un vecteur ajouté à chaque plongement, qui code la position du jeton pour que l'ordre ne soit pas perdu.
- Connexion résiduelle (residual connection)
- Ajouter l'entrée d'une sous-couche à sa sortie, pour que la sous-couche apprenne une correction et que les gradients passent.
- Normalisation de couche (layer normalisation)
- Ramener chaque vecteur de jeton à moyenne 0 et variance 1, puis une échelle et un décalage appris.
- Encodeur (encoder)
- La pile de blocs qui lit la suite d'entrée et produit un vecteur contextuel par jeton.
- Décodeur (decoder)
- La pile de blocs qui écrit la sortie un jeton à la fois, avec un masque causal et une attention croisée vers l'encodeur.
- Softmax
- La fonction qui transforme une liste de notes en poids positifs de somme 1, par exponentielle puis division par le total.
Références
- A. Vaswani, N. Shazeer, N. Parmar, J. Uszkoreit, L. Jones, A. N. Gomez, Ł. Kaiser, I. Polosukhin, Attention Is All You Need, NeurIPS 2017. arXiv:1706.03762.
- D. Bahdanau, K. Cho, Y. Bengio, Neural Machine Translation by Jointly Learning to Align and Translate, ICLR 2015. arXiv:1409.0473. Le premier mécanisme d'attention, additif plutôt que par produit scalaire.
- J. L. Ba, J. R. Kiros, G. E. Hinton, Layer Normalization, 2016. arXiv:1607.06450.
- J. Su, Y. Lu, S. Pan, A. Murtadha, B. Wen, Y. Liu, RoFormer: Enhanced Transformer with Rotary Position Embedding, 2021. arXiv:2104.09864. La variante rotative citée à la section 6.
- J. Alammar, The Illustrated Transformer, 2018. jalammar.github.io.
- P. Moskwa, Attention, please! Demystifying the math behind the attention mechanism and the transformer model, 2025. paulinamoskwa.github.io. L'article dont celui-ci suit le chemin, avec une implémentation PyTorch.
- A. Rush et al., The Annotated Transformer, Harvard NLP, 2018, révisé 2022. nlp.seas.harvard.edu. L'article de 2017 réimplémenté ligne par ligne.
À propos de cet article
Écrit pour les élèves de l'option machine learning de Centrale Méditerranée, et pour quiconque a lu un tutoriel sur les transformers sans parvenir à refaire les chiffres. Le chemin des plongements au modèle complet est le chemin classique ; la phrase, l'exemple en deux dimensions, la projection choisie à la main et le code sont propres à cet article. Les mathématiques sont celles de Vaswani et al. (2017), avec la normalisation de couche de Ba et al. (2016).
Rédigé avec l'aide de Claude Code, un produit d'Anthropic ; chaque formule a été vérifiée sur les articles cités et chaque nombre est recalculé par le code de la page à chaque construction.
Révision : . Première publication le même jour.