Quels mots d’avant comptent pour celui-ci ?
L’attention est l’étape d’un transformeur où chaque jeton regarde les autres jetons et leur prend ce dont il a besoin. C’est grâce à elle qu’un modèle de langage relie « il » au bon nom, plusieurs mots en arrière.
Dans « le train est bondé », le mot bondé parle du train. L’attention est la façon dont le modèle le trouve avec des nombres.
À la fin de cette leçon
Remarque
Je peux calculer à la main la sortie de l’attention pour un jeton.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Requête | un vecteur qui dit ce qu’un jeton cherche | |
| Clé | un vecteur qui dit ce qu’un jeton offre | |
| Valeur | un vecteur qui porte ce qu’un jeton transmet | |
| Score | à quel point une requête correspond à une clé | 2 |
| Softmax | change des scores en parts dont la somme vaut 1 | |
| Poids | la part d’une valeur qui entre dans la sortie | 0,665 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Requête, clé et valeur pour chaque jeton
Le module d’algèbre linéaire montre comment une table multiplie un vecteur. L’attention multiplie chaque vecteur d’entrée par trois tables apprises, ce qui donne trois nouveaux vecteurs.
La requête dit ce que ce jeton cherche. La clé dit ce qu’il offre aux autres. La valeur est ce qu’il transmet s’il est choisi. Ci-dessous, nous partons des trois vecteurs déjà calculés.
Exemple travaillé : noter la requête de bondé
| Jeton | Clé | Requête de bondé fois clé | Score |
|---|---|---|---|
| train | 2, 1 | 1x2 + 0x1 | 2 |
| est | 0, 2 | 1x0 + 0x2 | 0 |
| bondé | 1, 1 | 1x1 + 0x1 | 1 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Softmax change les scores en poids
Les scores peuvent avoir n’importe quelle taille, même sous 0. Le softmax les change en poids tous positifs, dont la somme vaut 1.
On prend d’abord e puissance chaque score, la touche exp d’une calculatrice. Chaque nombre devient positif, et un grand score devient bien plus grand. Puis on divise chacun par le total. Les vrais modèles divisent aussi chaque score par un nombre fixe avant. Nous sautons cette étape ici.
Exemple travaillé : softmax de 2, 0 et 1
| Jeton | Score | e puissance le score | Poids : diviser par 11,11 |
|---|---|---|---|
| train | 2 | 7,39 | 0,665 |
| est | 0 | 1,00 | 0,090 |
| bondé | 1 | 2,72 | 0,245 |
| Total | 11,11 | 1,000 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Scores et poids avec NumPy
docker exec jupyter python3 -c "import numpy as np; K = np.array([[2, 1], [0, 2], [1, 1]]); s = K @ np.array([1, 0]); w = np.exp(s) / np.exp(s).sum(); print(s.tolist(), w.round(3).tolist())"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
La sortie est un mélange pondéré des valeurs
On multiplie la valeur de chaque jeton par son poids, puis on additionne les résultats. Cette somme est le nouveau vecteur de bondé.
Bondé a pris les deux tiers de son nouveau vecteur chez train, donc bondé porte maintenant une part du sens de train. Chaque jeton fait de même avec sa propre requête, au même moment.
Exemple travaillé : mélanger les valeurs
| Jeton | Poids | Valeur | Poids fois valeur |
|---|---|---|---|
| train | 0,665 | 10, 0 | 6,65, 0 |
| est | 0,090 | 0, 10 | 0, 0,90 |
| bondé | 0,245 | 5, 5 | 1,22, 1,22 |
| Sortie | environ 7,88, 2,12 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
L’attention pour un jeton en Python
import math
cles = [[2, 1], [0, 2], [1, 1]] # train, est, bondé
valeurs = [[10, 0], [0, 10], [5, 5]]
requete = [1, 0] # la requête de bondé
scores = []
for cle in cles:
scores.append(requete[0] * cle[0] + requete[1] * cle[1])
puissances = []
for s in scores:
puissances.append(math.exp(s))
total = sum(puissances)
poids = []
for p in puissances:
poids.append(p / total)
melange = [0, 0]
for i in range(len(valeurs)):
for j in range(2):
melange[j] = melange[j] + poids[i] * valeurs[i][j]
print("scores :", scores)
print("poids :", [round(w, 3) for w in poids])
print("sortie :", [round(m, 2) for m in melange])
# Remplacez la requête par [0, 1], puis cliquez sur Exécuter.
# Quel jeton reçoit le plus de poids maintenant ?
Une erreur fréquente
Attention
Beaucoup pensent que l’attention choisit un jeton et ignore les autres. Elle prend une part de la valeur de chaque jeton. Un poids est proche de 0 seulement quand la clé correspond mal à la requête, et les poids font toujours 1 au total.
L’attention pour les trois jetons à la fois
docker exec jupyter python3 -c "import numpy as np; Q = np.array([[0, 1], [1, 1], [1, 0]]); K = np.array([[2, 1], [0, 2], [1, 1]]); V = np.array([[10, 0], [0, 10], [5, 5]]); S = Q @ K.T; W = np.exp(S) / np.exp(S).sum(axis=1, keepdims=True); print(W.round(3).tolist()); print((W @ V).round(2).tolist())"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.