Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Wie Attention in einem Transformer funktioniert

Nach dieser Lektion: Ich kann die Ausgabe von Attention für ein Token von Hand berechnen.

Lektion, 65 Min.2 BefehleJupyterLab-Lab für Data Science: pandas, Matplotlib und scikit-learn im Browser

Welche früheren Wörter zählen für dieses?

Attention ist der Schritt in einem Transformer, in dem jedes Token auf die anderen Tokens schaut und von ihnen übernimmt, was es braucht. Darum kann ein Sprachmodell „er“ dem richtigen Nomen viele Wörter vorher zuordnen.

In „der Zug ist voll“ geht es bei voll um den Zug. Attention ist der Weg, auf dem das Modell das mit Zahlen herausfindet.

Am Ende dieser Lektion

Notiz

Ich kann die Ausgabe von Attention für ein Token von Hand berechnen.

Schlüsselwörter

BegriffWas er bedeutetBeispiel
Queryein Vektor, der sagt, was ein Token sucht
Keyein Vektor, der sagt, was ein Token anbietet
Valueein Vektor mit dem, was ein Token weitergibt
Scorewie gut eine Query zu einem Key passt2
Softmaxmacht aus Scores Anteile, die zusammen 1 ergeben
Gewichtder Anteil eines Values an der Ausgabe0,665

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Jedes Token hat Query, Key und Value

In der linearen Algebra lernen Sie, wie eine Tabelle einen Vektor multipliziert. Attention multipliziert jeden Eingabevektor mit drei gelernten Tabellen. Das ergibt drei neue Vektoren.

Die Query sagt, was dieses Token sucht. Der Key sagt, was es anderen anbietet. Der Value ist das, was es weitergibt, wenn es gewählt wird. Unten beginnen wir mit den drei fertigen Vektoren.

Durchgerechnetes Beispiel: die Query von voll bewerten

TokenKeyQuery von voll mal KeyScore
Zug2, 11x2 + 0x12
ist0, 21x0 + 0x20
voll1, 11x1 + 0x11

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Softmax macht aus Scores Gewichte

Scores können jede Größe haben, sogar unter 0. Softmax macht daraus Gewichte, die alle positiv sind und zusammen 1 ergeben.

Zuerst nimmt man e hoch jeden Score, die exp-Taste auf dem Taschenrechner. Das macht jede Zahl positiv und einen großen Score viel größer. Dann teilt man jede Zahl durch die Summe. Echte Modelle teilen jeden Score vorher noch durch eine feste Zahl. Das lassen wir hier weg.

Durchgerechnetes Beispiel: Softmax von 2, 0 und 1

TokenScoree hoch ScoreGewicht: geteilt durch 11,11
Zug27,390,665
ist01,000,090
voll12,720,245
Summe11,111,000

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Scores und Gewichte mit NumPy

Befehl
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())"

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Die Ausgabe ist eine gewichtete Mischung der Values

Multiplizieren Sie den Value jedes Tokens mit seinem Gewicht und addieren Sie die Ergebnisse. Diese Summe ist der neue Vektor für voll.

Voll hat zwei Drittel seines neuen Vektors von Zug genommen. Damit trägt voll jetzt etwas von dem, was Zug bedeutet. Jedes Token macht gleichzeitig dasselbe mit seiner eigenen Query.

Durchgerechnetes Beispiel: die Values mischen

TokenGewichtValueGewicht mal Value
Zug0,66510, 06,65, 0
ist0,0900, 100, 0,90
voll0,2455, 51,22, 1,22
Ausgabeetwa 7,88, 2,12

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Attention für ein Token in Python

Code: python
import math

keys = [[2, 1], [0, 2], [1, 1]]       # Zug, ist, voll
values = [[10, 0], [0, 10], [5, 5]]
query = [1, 0]                        # die Query von voll

scores = []
for key in keys:
    scores.append(query[0] * key[0] + query[1] * key[1])

potenzen = []
for s in scores:
    potenzen.append(math.exp(s))
summe = sum(potenzen)
gewichte = []
for p in potenzen:
    gewichte.append(p / summe)

mischung = [0, 0]
for i in range(len(values)):
    for j in range(2):
        mischung[j] = mischung[j] + gewichte[i] * values[i][j]

print("Scores:", scores)
print("Gewichte:", [round(g, 3) for g in gewichte])
print("Ausgabe:", [round(m, 2) for m in mischung])
# Ändern Sie die Query in [0, 1] und starten Sie erneut. Welches Token bekommt jetzt das meiste Gewicht?

Ein häufiger Fehler

Warnung

Viele denken, Attention wähle ein Token und ignoriere den Rest. Sie nimmt aber einen Anteil vom Value jedes Tokens. Ein Gewicht ist nur dann nahe 0, wenn der Key schlecht zur Query passt, und die Gewichte ergeben immer zusammen 1.

Attention für alle drei Tokens zugleich

Befehl
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())"

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Über dieses Lab und seinen Quellcode: JupyterLab-Lab für Data Science: pandas, Matplotlib und scikit-learn im Browser

Sie unterrichten eine Gruppe? Weisen Sie dieses Modul Ihren Studierenden zu, mit Handbuch für Lehrende, automatisch geprüften Aufgaben und einem Lab für jede Person.