Aller au contenu
English

L'attention étape par étape

  • Leçon 17
  • 60 min
  • Module 5 : Représenter les séquences et le sens

Ce que vous saurez faire

Construisez l’attention à la main, avec chaque nombre visible, pour suivre les calculs d’un transformeur. Puis lisez les vrais poids d’attention du tout petit transformeur du cours sur des billets de Larkfield. Voyez ce qu’ils expliquent et ce qu’ils n’expliquent pas.

Carnet JupyterL'attention à la main et sur un vrai billet, dans un carnet JupyterColab · Kaggle · GitHub · en anglais

Le carnet (notebook) Jupyter calcule l’exemple détaillé avec PyTorch, vérifie chaque forme et réalise l’exercice du module. Puis il entraîne un petit transformeur pendant quelques époques, soit environ 2 minutes sur un processeur gratuit de Colab. Il lit les poids d’attention d’un billet. Environ 35 minutes.

Le carnet est en anglais. Colab et Kaggle ouvrent votre propre copie. Il faut un compte Google ou Kaggle gratuit. Vous êtes bloqué ? Consultez le carnet de solution.

Avant de commencerCe qu’il faut savoir et avoir sous la mainEnviron 60 minutes

Ce que vous devez savoir

Ce qu’il vous faut sur votre ordinateur

  • Un navigateur et une calculatrice. Le carnet s’ouvre dans Colab ou Kaggle avec PyTorch déjà installé.

Vous participez à une réunion avec une question en tête : « Quand le nouveau stock arrive-t-il? » Cinq collègues parlent. Vous écoutez attentivement la personne de l’entrepôt et un peu la personne responsable des achats. Vous écoutez à peine la personne qui parle de la fête du bureau. Ensuite, votre réponse reprend surtout les propos de la personne de l’entrepôt, avec un peu de ceux de l’autre.

Vous avez fait trois choses. Vous aviez une question. Vous avez évalué à quel point le sujet de chaque personne correspondait à cette question. Et vous avez pris leurs propos, pondérés selon cette correspondance. L’attention fait la même chose pour tous les mots d’un billet à la fois.

Le problème : quels mots « damaged » doit-il lire?

Section intitulée « Le problème : quels mots « damaged » doit-il lire? »

La leçon précédente se terminait par un besoin. Dans « The lamp was damaged on arrival, not after a month of use » (la lampe était endommagée à l’arrivée, pas après un mois d’utilisation), le mot « damaged » (endommagée) a besoin de « arrival » (arrivée), pas de « on » (à). Dans T-64813, « charged » (facturé) compte plus que « refunded » (remboursé). Les mots utiles peuvent être n’importe où dans le billet, et ils changent d’un billet à l’autre.

Une fenêtre fixe, comme des paires de mots, lit toujours les mêmes voisins. Une moyenne lit tous les mots de façon égale. Ni l’une ni l’autre ne peut choisir. Nous voulons que chaque mot choisisse ses propres sources selon leur contenu, avec des poids dont la somme vaut 1.

Chaque mot crée trois vecteurs à partir de son plongement, avec trois matrices de poids apprises :

  • Une requête : ce que ce mot cherche. Dans la réunion, c’est votre question.
  • Une clé : ce que ce mot offre, comme l’étiquette d’un dossier. C’est le sujet de chaque personne.
  • Une valeur : ce que ce mot transmet à un mot qui le lit. C’est ce que chaque personne dit.

Pour mettre à jour un mot, comparez sa requête à la clé de chaque mot, y compris lui-même. Une bonne correspondance donne un score élevé. Softmax transforme les scores en poids dont la somme vaut 1. Le nouveau vecteur du mot est la moyenne pondérée de toutes les valeurs.

C’est l’attention. Les poids indiquent où chaque mot « porte son attention », ce qui donne son nom à la méthode. On appelle souvent le mot qui lit le mot de requête; cette leçon l’appelle le mot lecteur. Tous les mots lisent en même temps, chacun avec sa propre requête.

Prenez trois mots, « damaged on arrival », et seulement 2 nombres par vecteur. Les nombres ci-dessous sont inventés pour que vous puissiez suivre chaque étape. Dans un vrai réseau, ils proviennent des plongements et des matrices apprises.

mot requête q clé k valeur v
damaged (0,5, 1,5) (1, 0) (2, 0)
on (0, 0) (0, 0,5) (0, 0)
arrival (1, 0) (0, 2) (0, 1)

Suivez le mot lecteur « damaged ». Sa requête est (0,5, 1,5).

  1. Score : le produit scalaire de la requête avec chaque clé. damaged : 0,5 × 1 + 1,5 × 0 = 0,5. on : 0,5 × 0 + 1,5 × 0,5 = 0,75. arrival : 0,5 × 0 + 1,5 × 2 = 3,0.
  2. Divisez par √d, où d est le nombre de nombres dans une clé : √2 = 1,414. Les scores deviennent 0,354, 0,530 et 2,121.
  3. Softmax. e^0,354 = 1,424, e^0,530 = 1,699, e^2,121 = 8,342; leur somme vaut 11,466. Divisez chacun par le total : les poids sont 0,124, 0,148 et 0,728. Leur somme vaut 1.
  4. Somme pondérée des valeurs. 0,124 × (2, 0) + 0,148 × (0, 0) + 0,728 × (0, 1) = (0,248, 0,728).

Le nouveau vecteur de « damaged » reprend surtout la valeur de « arrival ». Après l’attention, « damaged » contient de l’information sur le moment où les dommages sont survenus. Le schéma montre les quatre étapes.

Le mot lecteur damaged, requête (0,5, 1,5). Pour les mots damaged, on et arrival : clés (1, 0), (0, 0,5), (0, 2); scores 0,5, 0,75, 3,0; divisés par 1,414 : 0,354, 0,530, 2,121; poids softmax 0,124, 0,148, 0,728; valeurs (2, 0), (0, 0), (0, 1); poids multiplié par la valeur (0,248, 0), (0, 0), (0, 0,728); somme : sortie (0,248, 0,728).
L'attention pour un mot lecteur est une moyenne pondérée. La flèche épaisse porte le poids le plus élevé. Les nombres viennent de l'exemple détaillé inventé.
Description textuelle du diagramme

Le mot lecteur est damaged, avec la requête (0,5, 1,5). Il y a trois colonnes, une par mot : damaged, on et arrival. Leurs clés sont (1, 0), (0, 0,5) et (0, 2). Étape 1, le score est le produit scalaire de la requête avec chaque clé : 0,5, 0,75 et 3,0. Étape 2, chaque score est divisé par la racine carrée de 2, soit 1,414 : 0,354, 0,530 et 2,121. Étape 3, softmax les transforme en poids dont la somme vaut 1 : 0,124, 0,148 et 0,728. Les valeurs des trois mots sont (2, 0), (0, 0) et (0, 1). Chaque valeur est multipliée par son poids : (0,248, 0), (0, 0) et (0, 0,728). Étape 4, on les additionne : la sortie est (0,248, 0,728). La flèche venant de arrival est la plus épaisse, car son poids est le plus élevé.

Pourquoi diviser par √d? Un produit scalaire additionne d produits. Donc, avec plus de nombres par vecteur, les scores augmentent. Des scores élevés rendent softmax extrême : un poids approche 1, tous les autres approchent 0. Le réseau cesse alors presque d’apprendre quels mots lire. Diviser par √d garde les scores dans une plage semblable, peu importe d. Le tout petit transformeur de ce cours utilise d = 16, donc il divise par 4.

Les deux autres mots lisent aussi. « on » a la requête (0, 0) : chaque score vaut 0, donc les poids sont égaux, soit 0,333 chacun. Un mot sans question écoute tout le monde de façon égale. « arrival » a la requête (1, 0), qui correspond à la clé de « damaged » : ses poids sont 0,503, 0,248 et 0,248.

Placez les requêtes des trois mots dans une matrice Q, une ligne par mot. Placez les clés dans K et les valeurs dans V. Un seul produit matriciel calcule alors tous les scores à la fois : Q @ Kᵀ. Ici, Kᵀ est K transposée, pour que chaque requête rencontre chaque clé. Softmax travaille sur chaque ligne, pour que la somme de chaque ligne vaille 1.

attention_by_hand.py
import math
import torch
from torch import nn
Q = torch.tensor([[0.5, 1.5], [0.0, 0.0], [1.0, 0.0]]) # one query per word: damaged, on, arrival
K = torch.tensor([[1.0, 0.0], [0.0, 0.5], [0.0, 2.0]]) # one key per word
V = torch.tensor([[2.0, 0.0], [0.0, 0.0], [0.0, 1.0]]) # one value per word
scores = Q @ K.T # (3, 2) @ (2, 3) -> (3, 3)
weights = torch.softmax(scores / math.sqrt(2), dim=1) # every row adds up to 1
out = weights @ V # (3, 3) @ (3, 2) -> (3, 2)
print(scores)
print(weights.round(decimals=3))
print(out.round(decimals=3))
print(torch.allclose(out, nn.functional.scaled_dot_product_attention(Q, K, V)))

La sortie :

tensor([[0.5000, 0.7500, 3.0000],
[0.0000, 0.0000, 0.0000],
[1.0000, 0.0000, 0.0000]])
tensor([[0.1240, 0.1480, 0.7280],
[0.3330, 0.3330, 0.3330],
[0.5030, 0.2480, 0.2480]])
tensor([[0.2480, 0.7280],
[0.6670, 0.3330],
[1.0070, 0.2480]])
True

La première ligne de chaque tenseur correspond au calcul manuel pour « damaged ». dim=1 indique à softmax de travailler sur chaque ligne. La dernière ligne compare le résultat à la fonction de PyTorch, scaled_dot_product_attention (attention par produit scalaire ajusté) : les mêmes nombres. En une seule formule, le calcul complet s’écrit ainsi :

Attention(Q,K,V)=softmax(QK⊤d)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q K^\top}{\sqrt{d}}\right) V

Lisez les formes, comme toujours. Avec n mots et d nombres par vecteur :

Étape Forme dans l’exemple Forme générale
Q, K, V (3, 2) chacune (n, d) chacune
scores Q @ Kᵀ (3, 2) @ (2, 3) → (3, 3) (n, n)
poids, après softmax (3, 3), la somme de chaque ligne vaut 1 (n, n)
sortie, poids @ V (3, 3) @ (3, 2) → (3, 2) (n, d)

Deux points à remarquer. D’abord, l’attention renvoie un nouveau vecteur par mot, de la même taille : des mots entrent, des mots sortent. Ensuite, les poids forment un carré n × n, un poids pour chaque paire de mots. Un billet de 120 jetons a 14 400 poids. Doubler la longueur donne quatre fois plus de poids, donc l’attention devient coûteuse pour les longs textes.

Le tout petit transformeur du cours a 64 nombres par jeton. Il les sépare en 4 têtes de 16 nombres chacune. Chaque tête a ses propres matrices de requêtes, de clés et de valeurs. Elle peut donc chercher quelque chose de différent. Imaginez quatre personnes qui écoutent dans la réunion, chacune avec sa propre question. Chaque tête divise par √16 = 4. Les quatre sorties de 16 nombres sont réunies pour redonner 64 nombres. Le modèle a 2 blocs, chacun avec ses propres 4 têtes. Le module 6 construit le bloc complet. Voici l’attention d’un bloc sur un vrai billet de 30 jetons. Vous n’avez pas encore le fichier tiny_transformer.pt : Les blocs du transformeur entraîne le modèle et l’enregistre. Pour l’instant, lisez le code et sa sortie. Le carnet entraîne lui-même une petite version.

shapes.py
from ticketnet import TEAMS, TinyTransformer
tf = TinyTransformer(len(vocab))
tf.load_state_dict(torch.load("tiny_transformer.pt")) # the course's trained model
tf.eval()
row = next(r for r in valid_rows if r["ticket_id"] == "T-65052")
ids = torch.tensor([vocab.encode(row["text"])])
block = tf.blocks.layers[0]
attn = block.self_attn
print(attn.embed_dim, "numbers per token,", attn.num_heads, "heads of", attn.head_dim)
with torch.no_grad():
h = tf.embed(ids) + tf.position(torch.arange(ids.shape[1]))
x = block.norm1(h)
_, w = attn(x, x, x, need_weights=True, average_attn_weights=False)
print("tokens", ids.shape, "-> vectors", h.shape, "-> weights", w.shape)
print("each row adds up to 1:", torch.allclose(w.sum(-1), torch.ones(1, 4, ids.shape[1])))

La sortie :

64 numbers per token, 4 heads of 16
tokens torch.Size([1, 30]) -> vectors torch.Size([1, 30, 64]) -> weights torch.Size([1, 4, 30, 30])
each row adds up to 1: True

Les poids ont la forme (lot, têtes, jetons, jetons) : pour chacune des 4 têtes, un carré de 30 × 30. Le modèle ajoute aussi un vecteur de position au plongement de chaque jeton. Ainsi, l’ordre des mots peut influencer le résultat; le module 6 l’explique. norm1 est la normalisation de couche que le bloc applique avant l’attention, aussi expliquée au module 6. La couche d’attention de PyTorch ne renvoie pas ses poids sans demande explicite. Le code l’appelle donc à nouveau avec need_weights=True (demander les poids).

Les vrais poids d’attention sur les billets de Larkfield

Section intitulée « Les vrais poids d’attention sur les billets de Larkfield »

Le tout petit transformeur du cours a été entraîné sur les 4 696 billets d’entraînement pendant 20 époques. Il dirige correctement 94,3 % des billets de validation. L’explorateur montre ses vrais poids d’attention sur six billets de validation. Choisissez un billet, un bloc et une tête, puis cliquez sur un mot pour en faire le mot lecteur. Les mots du billet deviennent plus foncés là où le mot lecteur accorde plus de poids. « Whole matrix » (matrice complète) montre tous les mots lecteurs à la fois.

Explorer

Lire les poids d'attention du tout petit transformeur

Mot lecteur : not (mot 1 sur 30). Plus un mot est foncé, plus il reçoit d’attention.

Équipe de Grace
payment
Petit transformeur
payment, plus de 99,9 %
Sac de mots
payment
Transformeur, mots mélangés
payment, plus de 99,9 %

Dans le bloc 2, tête 1, not donne 0,50 de son attention à twice et 0,07 à “'”. Les autres têtes de ce bloc lisent surtout charge, remove, remove.

  • plus foncé : un poids d’attention plus grand (par rapport au plus grand affiché)
Ce que lit not, bloc 2, tête 1
MotBarrePoids
twice (mot 18)0,50
“'” (mot 7)0,07
duplicate (mot 28)0,05
card (mot 15)0,05
for (mot 19)0,04
les 25 autres mots0,29

La somme des 30 poids est 1,00.

Mots qui reçoivent le plus d’attention dans le bloc 2 (toutes les têtes, tous les mots lecteurs) : remove, twice, charge. Mots dont le retrait affaiblit le plus la réponse : charged, charge, remove.

Les vrais poids d'attention du tout petit transformeur du cours (2 blocs × 4 têtes, 64 nombres par jeton) sur six billets de validation. La somme de chaque ligne de poids vaut 1. La réponse et le test qui masque un mot, sous l'explorateur, viennent du même modèle.
Description textuelle de l’explorateur

L’explorateur montre un billet de validation à la fois, sous forme d’une rangée de boutons de mots. Au départ, le billet est T-65052 : « Not a delivery issue and I’m keeping the leaf blower. My card was charged twice for the same order. Can you remove the duplicate charge? » Cela signifie : « Ce n’est pas un problème de livraison et je garde le souffleur à feuilles. Ma carte a été débitée deux fois pour la même commande. Pouvez-vous supprimer le débit en double? » L’équipe de Grace est payment (paiement), et le tout petit transformeur répond payment avec une probabilité supérieure à 99,9 %. Le mot lecteur est « not », dans le bloc 2, tête 1. Ses cinq poids les plus élevés sont : twice (deux fois) 0,50, l’apostrophe 0,07, duplicate (en double) 0,05, et des poids plus faibles pour le reste. Dans les autres têtes du bloc 2, « not » lit charge (débit) (0,55, tête 2), remove (supprimer) (0,50, tête 3) et remove (0,48, tête 4). Les quatre têtes regardent les mots de la demande de paiement à la fin, pas « delivery » (livraison) juste à côté. Commandes : une liste de six billets (une négation, deux sujets, deux billets à la frontière entre catégories, un billet simple et une négation que le transformeur dirige mal); bloc 1 ou 2; tête 1, 2, 3, 4 ou la moyenne des quatre; vue d’un mot ou de la matrice complète. L’affichage montre l’équipe de Grace, la réponse du transformeur, la réponse du réseau à sac de mots et la réponse du transformeur quand les mots du billet sont mélangés. Une ligne en dessous compare les mots qui reçoivent le plus d’attention dans le bloc 2 à ceux dont le retrait affaiblit le plus la réponse. Pour T-65052, ce sont remove, twice et charge, puis charged, charge et remove.

Dans T-65052, les quatre têtes du bloc 2 envoient « not » vers la fin du billet : « twice », « charge », « remove ». Aucune ne lit « delivery », le mot juste après « not ». Les poids viennent du contenu des mots, pas de leur position. C’est le comportement que la leçon précédente recherchait.

Ce que les poids d’attention montrent, et ce qu’ils ne montrent pas

Section intitulée « Ce que les poids d’attention montrent, et ce qu’ils ne montrent pas »

Il est tentant de lire la carte thermique ainsi : « Le modèle a dirigé ce billet vers payment à cause de ces mots. » Faites attention. Les poids montrent quelque chose de réel, mais beaucoup moins que cela.

Ce qu’ils montrent : pour une tête d’un bloc, où chaque mot a pris son information. C’est un fait sur le calcul, utile pour vérifier un modèle ou chercher un bogue.

Ce qu’ils ne montrent pas :

  • Il n’y a pas une seule carte thermique. Ce petit modèle a 2 blocs × 4 têtes = 8 matrices de poids par billet, et elles diffèrent souvent. Dans T-65052, bloc 2, le mot « card » (carte) accorde 0,95 de son poids à « twice » dans la tête 1. Il accorde 0,77 à « remove » dans la tête 4. Dans les têtes 2 et 3, il répartit son poids. Les modèles plus grands ont des centaines de têtes.
  • Les poids ne sont pas des raisons. Un test simple : masquez un mot à la fois (remplacez-le par <unk>, jeton inconnu) et observez combien la réponse s’affaiblit. Prenez le mot qui reçoit le plus d’attention dans le bloc 2 et celui dont le retrait affaiblit le plus la réponse. Sur les 600 billets de validation, c’est le même mot dans seulement 73 billets (12,2 %). Dans T-64917, un billet à la frontière entre catégories, « ? » et « . » reçoivent le plus d’attention. Mais masquer « unpacked » (déballé) affaiblit le plus la réponse delivery.
  • L’attention est une étape parmi plusieurs. Après l’attention, chaque bloc a une couche à propagation avant et ajoute le résultat à son entrée. Viennent ensuite le deuxième bloc, une moyenne sur les mots et la couche de sortie. Les vecteurs de valeurs et toutes ces couches déterminent ce qu’un poids de 0,5 transmet réellement.
  • Ce modèle utilise à peine l’ordre. Quand les mots de chaque billet de validation sont mélangés, il en dirige encore correctement 93,3 %. C’est seulement 1 point de moins qu’avec le bon ordre. Ses motifs d’attention semblent significatifs, mais la plupart de ses décisions pourraient reposer sur les mots seuls.
  • Des poids bien ordonnés peuvent accompagner une mauvaise réponse. Dans T-65198 (« This isn’t about a refund. The courier left my bed linen set with a neighbour … », soit « Il ne s’agit pas d’un remboursement. Le livreur a laissé mon ensemble de literie chez un voisin… »), le transformeur répond warranty (garantie) (80,4 %), ce qui est faux. Avec les mots mélangés, il répond delivery (99,7 %), ce qui est juste. Ses poids dans le bon ordre semblent aussi ordonnés que dans les autres billets.

Et rappelez-vous le résultat global. Après 20 époques, ce transformeur dirige correctement 94,3 % des billets de validation. Le réseau à sac de mots atteint 97,3 % (98,3 % à sa meilleure époque) et le modèle linéaire, 98,8 %. Environ 4 700 billets, c’est trop peu pour apprendre une langue à partir de rien. L’attention est la bonne idée pour un texte dont le sens dépend de l’ordre et du contexte. Un modèle a aussi besoin d’assez de données pour l’apprendre, ou d’un point de départ avec un modèle préentraîné.

Utilisez l’attention quand le sens d’une entrée dépend des relations entre ses parties, comme les mots d’une phrase. Elle lit à n’importe quelle distance en une étape. Elle calcule aussi tous les mots en même temps, ce qui convient au matériel moderne. Elle est au cœur de chaque transformeur, de ce tout petit modèle aux grands modèles de langage.

Ses coûts :

  • La longueur au carré. Chaque mot lit chaque mot, donc le nombre de poids augmente selon n × n : 14 400 par tête et par bloc pour un billet de 120 jetons.
  • Les données. Les matrices de requêtes, de clés et de valeurs sont apprises. Avec peu de données, comme ici, elles apprennent moins que ce qu’un simple comptage sait déjà.
  • Aucun ordre en soi. L’attention compare les contenus, pas les positions. Sans les vecteurs de position du module 6, ce modèle donnerait exactement la même réponse pour des mots mélangés.
  1. Dans l’explorateur, gardez le billet T-65052, le bloc 2, la tête 1 et le mot lecteur « not » (pas). Notez son plus grand poids.
  2. Cliquez sur les têtes 2, 3 et 4, une à la fois. Pour chaque tête, notez le mot que « not » lit le plus.
  3. Cliquez sur « average » (moyenne). Notez le plus grand poids dans la moyenne des quatre têtes.
  4. Passez au bloc 1. Est-ce que « not » lit les mêmes mots?
  5. Lisez la ligne sous l’explorateur : quels mots reçoivent le plus d’attention? Quels mots affaiblissent le plus la réponse quand vous les masquez?
Afficher les réponses attendues
  1. Tête 1 : « twice » (deux fois), 0,50.
  2. Tête 2 : « charge » (frais), 0,55. Tête 3 : « remove » (retirer), 0,50. Tête 4 : « remove », 0,48. Chaque tête lit un mot de la demande concernant le paiement, mais pas le même.
  3. Dans la moyenne des quatre têtes, « remove » a le plus grand poids : 0,26. Ce poids est inférieur à celui de chaque tête prise seule, car chaque tête préfère un mot différent.
  4. Non. Dans le bloc 1, « not » répartit davantage son poids. La tête 1 lit surtout « for » (pour), avec 0,27, et la tête 4 lit « charge », avec 0,56. Aucun poids de la tête 3 ne dépasse 0,16. Les deux blocs font un travail différent.
  5. Le plus d’attention : remove, twice, charge. Les mots dont le masquage nuit le plus : charged (facturé), charge, remove. Pour ce billet, les deux listes se recoupent bien. Sur les 600 billets de validation, les mots en tête des listes concordent dans seulement 12,2 % des billets.

Choisissez le billet T-65234 : « La réinitialisation de mon mot de passe a bien fonctionné après mon message de la semaine dernière, merci. Maintenant, j’aimerais retourner les housses de coussin. Comment faire? » L’équipe choisie par Grace est celle des retours. Avant de cliquer, prédisez : dans le bloc 2, tête 4, quel mot « back » (retour) lira-t-il le plus? Vérifiez ensuite, puis comparez avec la ligne de masquage d’un mot à la fois.

Afficher la réponse

« back » donne 0,90 de son poids à « thanks » (merci), un mot du sujet terminé sur le mot de passe. Il ne le donne pas à « send » (envoyer), son partenaire. Pourtant, le modèle achemine le billet vers les retours. Masquer « send », puis « back », affaiblit le plus cette réponse. Un grand poids sur « thanks » ne signifie pas que « thanks » a déterminé l’équipe. Dans le bloc 1, tête 2, « back » se lit surtout lui-même (0,92). Chaque tête et chaque bloc calculent quelque chose de différent. Seul leur ensemble, avec les couches qui suivent, donne la réponse.

Erreur courante

Une carte thermique d'attention présentée comme la raison d'une décision

Symptôme : Omar veut montrer à Grace pourquoi le routeur a choisi l’équipe des paiements pour T-65052. Il prend la carte thermique du bloc 2, tête 1, et écrit : « Le modèle a choisi les paiements parce qu’il s’est concentré sur “twice”. » Grace pose la même question pour T-64917. La carte thermique indique que le modèle s’est « concentré » sur « ? » et « . ».

Cause : une tête d’un bloc montre où un mot a pris son information. Ce n’est pas une liste de raisons. Les 7 autres têtes montrent d’autres mots. D’autres couches suivent l’attention. Le mot qui reçoit le plus d’attention n’est celui dont le retrait affaiblit le plus la réponse que dans 12,2 % des billets de validation.

Correction : pour dire quelles entrées influencent une réponse, modifiez l’entrée et mesurez la sortie. Masquez un mot à la fois ou remplacez un mot, par exemple « arrival » (arrivée) par « use » (utilisation). Comparez ensuite les probabilités. Utilisez les poids d’attention pour examiner le calcul, pas pour expliquer une décision. Précisez aussi ce que le test ne peut pas montrer. Des mots peuvent compter ensemble, ce que le masquage d’un mot à la fois ne détecte pas.

Vérifiez votre compréhension

Dans vos mots : que font la requête, la clé et la valeur d'un mot dans l'attention?

Afficher la réponse

La requête indique ce que le mot lecteur cherche. La clé indique ce que chaque mot offre, comme une étiquette. Le produit scalaire de la requête avec chaque clé donne un score : une bonne correspondance donne un score élevé. Softmax transforme les scores en poids dont la somme est 1. La valeur est ce que chaque mot transmet. Le nouveau vecteur du mot lecteur est la moyenne pondérée des valeurs.

Vérifiez votre compréhension

Prédisez : les trois scores d'un mot lecteur sont 2, 2 et 2. Quels sont ses poids d'attention et sa sortie si les valeurs sont (3, 0), (0, 3) et (0, 0)?

Afficher la réponse

Des scores égaux donnent des poids égaux après la division par √d et softmax : 1/3 chacun, soit 0,333. La sortie est la moyenne simple des valeurs : (3 + 0 + 0) ÷ 3 = 1 et (0 + 3 + 0) ÷ 3 = 1, donc (1, 1). Quand tous les scores sont égaux, l’attention équivaut à la moyenne du réseau qui utilise la moyenne des plongements.

L’exercice du module réunit les trois leçons. Suivez un calcul d’attention à la main et vérifiez chaque dimension.

Vous l’avez fait plus haut : le mot lecteur « damaged » (endommagé), les scores 0,5, 0,75 et 3,0. Après division par √2 : 0,354, 0,530 et 2,121. Les poids : 0,124, 0,148 et 0,728. La sortie : (0,248, 0,728). Les formes étaient (3, 2) pour Q, K et V, (3, 3) pour les poids et (3, 2) pour la sortie.

Trois mots, deux nombres chacun. Les nombres sont inventés.

mot requête q clé k valeur v
mot 1 (1, 0) (2, 0) (1, 0)
mot 2 (0, 1) (0, 2) (0, 1)
mot 3 (1, 1) (1, 1) (1, 1)
  1. Pour le mot lecteur mot 1, calculez les trois scores, les scores ajustés (÷ √2), les poids softmax et la sortie.
  2. Écrivez la forme de Q, de Q @ Kᵀ, des poids et de la sortie.
  3. Prédisez les poids du mot 3 sans calculer chaque étape. Expliquez pourquoi.
  4. Le tout petit transformeur lit un lot de 8 billets, complétés à 50 jetons, avec 4 têtes. Donnez la forme de ses poids d’attention et celle de la sortie d’un bloc.
Afficher la réponse modèle

1. Mot 1. Scores : q · k = 1 × 2 + 0 × 0 = 2, 1 × 0 + 0 × 2 = 0, 1 × 1 + 0 × 1 = 1. Scores ajustés : 2 ÷ 1,414 = 1,414, 0, 1 ÷ 1,414 = 0,707. Softmax : e^1,414 = 4,113, e^0 = 1, e^0,707 = 2,028; total 7,141. Poids : 0,576, 0,140, 0,284 (leur somme est 1). Sortie : 0,576 × (1, 0) + 0,140 × (0, 1) + 0,284 × (1, 1) = (0,860, 0,424).

2. Formes. Q a la forme (3, 2). Q @ Kᵀ donne (3, 2) @ (2, 3) → (3, 3). Les poids ont la forme (3, 3), et la somme de chaque ligne est 1. La sortie est (3, 3) @ (3, 2) → (3, 2) : un nouveau vecteur de 2 nombres par mot.

3. Mot 3. Sa requête (1, 1) donne les scores 2, 2 et 2 : le même pour chaque clé. Ses poids sont donc égaux, 0,333 chacun. Sa sortie est la moyenne des valeurs, (0,667, 0,667).

4. Le tout petit transformeur. Les poids ont la forme (lot, têtes, jetons, jetons) = (8, 4, 50, 50). Un bloc renvoie un vecteur de 64 nombres par jeton : (8, 50, 64), la même forme que son entrée.

Le carnet Jupyter vérifie les quatre réponses avec PyTorch. Une réponse complète montre chaque nombre intermédiaire et vérifie que la somme de chaque ligne de poids est 1.

Vérifiez votre compréhension

Rappel : quelle est la forme des poids d'attention pour une tête et un billet de n jetons? Quelle doit être la somme de chaque ligne?

Afficher la réponse

Une tête donne une matrice n × n : une ligne par mot lecteur, une colonne par mot qu’il lit. Softmax agit sur chaque ligne, donc la somme de chaque ligne est 1. Avec un lot et plusieurs têtes, la forme est (lot, têtes, n, n).

Vérifiez votre compréhension

Expliquez ou prédisez : Tomás mélange les mots de chaque billet de validation. Le réseau à sac de mots en achemine correctement 98,0 % (97,3 % avant, dans les deux cas après 20 époques). Le tout petit transformeur passe de 94,3 % à 93,3 %. Que vous indique chaque résultat?

Afficher la réponse

Le réseau à sac de mots ne peut pas détecter le mélange : les comptes restent identiques, donc ses entrées et ses réponses aussi. (Son résultat passe de 97,3 % à 98,0 % uniquement parce que le cours coupe les billets après 120 jetons. Dans quelques longs billets, le mélange change les mots conservés. Sans cette coupure, le résultat est de 98,0 % dans les deux ordres.) Le transformeur peut voir l’ordre grâce à ses vecteurs de position et à l’attention. Mais la perte de l’ordre lui coûte seulement 1 point. Sur ces billets, il utilise donc à peine l’ordre; il décide surtout à partir des mots. L’attention permet à un modèle d’utiliser l’ordre et le contexte. Mais le modèle ne le fait que dans la mesure où les données le lui apprennent.

Vérifiez votre compréhension

Vérification finale : pour T-65052 (« Ce n'est pas un problème de livraison… Ma carte a été débitée deux fois… Pouvez-vous retirer les frais en double? »), expliquez quelles entrées influencent la réponse « paiements », sans traiter l'attention comme une explication complète.

Afficher la réponse

Mesurez l’influence en modifiant l’entrée. Quand vous masquez un mot à la fois, la réponse « paiements » s’affaiblit le plus sans « charged », puis « charge » et « remove ». Ces mots influencent la réponse. Les poids d’attention concordent pour ce billet. Dans le bloc 2, les mots qui reçoivent le plus d’attention sont « remove », « twice » et « charge ». Chaque tête dirige « not » vers la demande concernant le paiement.

Mais les poids ne sont pas l’explication. Ils proviennent de 8 têtes dans 2 blocs qui sont souvent en désaccord, et d’autres couches les suivent. Sur les 600 billets de validation, le mot qui reçoit le plus d’attention est le plus influent dans seulement 12,2 % des billets. Masquer un mot à la fois ne détecte pas non plus les mots qui comptent seulement ensemble. Voici donc une formulation prudente : « Masquer “charged” ou “charge” affaiblit le plus la réponse “paiements”. Les poids d’attention concordent avec ce résultat, mais ils ne le prouvent pas. »

Récapitulatif

Récapitulatif du module 5

  • Le texte devient des jetons et des identifiants de jetons. Chaque identifiant sélectionne une ligne apprise dans la table de plongements : (lot, jetons) → (lot, jetons, 64). Les plongements apprennent « utilisés de façon semblable pour cette tâche », avec une part de sens et une part de bruit.
  • Un sac de mots et une moyenne de plongements oublient l’ordre. Deux billets inventés contenant les mêmes mots reçoivent la même entrée. L’un des deux est donc toujours mal acheminé. Les n-grammes aident un peu et coûtent beaucoup.
  • Attention : chaque mot compare sa requête à chaque clé et divise les scores par √d. Softmax transforme les scores en poids, et la sortie est la moyenne pondérée des valeurs. Formes : entrée (n, d), poids (n, n), sortie (n, d).
  • Les poids réels du tout petit transformeur montrent où chaque mot a pris son information, dans 8 têtes en désaccord. Ce ne sont pas des raisons. Le mot qui reçoit le plus d’attention est le plus influent dans seulement 12,2 % des billets de validation. Ce modèle utilise à peine l’ordre (mots mélangés : −1 point). Il achemine correctement moins de billets que le sac de mots. Larkfield garde son routeur linéaire.

Réinitialisation : ce module n’installe rien sur votre ordinateur. Pour recommencer un explorateur, rechargez la page. Si vous avez utilisé un carnet Jupyter, redémarrez-le. Dans Colab, choisissez Runtime › Restart session (exécution › redémarrer la session). Dans Kaggle, choisissez Run › Restart & clear cell outputs (exécuter › redémarrer et effacer les sorties des cellules). Exécutez ensuite toutes les cellules de nouveau. Les carnets enregistrent leurs fichiers uniquement dans le dossier ticket-router; supprimez ce dossier pour repartir complètement à zéro.

Ensuite, le module 6 assemble un bloc de transformeur complet autour de l’attention : plusieurs têtes, une couche à propagation avant, des connexions résiduelles et une normalisation. Il entraîne ensuite le tout petit transformeur et le compare honnêtement au sac de mots.

Leçon suivante : Les blocs du transformeur