~/teaching · machine learning
Aufmerksamkeitsmechanismus und Transformer, Schritt für Schritt
Ein einfacher Satz, dann die Mathematik, dann die Zahlen von Hand: Einbettungen, Abfragen, Schlüssel, Werte, Köpfe, Positionen, Encoder, Decoder
Zusammenfassung
Ein Sprachmodell braucht die Bedeutung eines Wortes, und die Bedeutung eines Wortes hängt von den Wörtern ab, die es umgeben. Aufmerksamkeit (Attention) ist die Operation, mit der jedes Wort eines Satzes etwas von den anderen übernehmen kann, in Anteilen, die das Modell lernt. Dieser Artikel baut sie von der ersten Idee bis zum vollständigen Transformer auf, in der Reihenfolge, die Studierende brauchen: Einbettungen (Embeddings), der gewichtete Mittelwert, Abfragen, Schlüssel und Werte, mehrere Köpfe, die Position der Wörter, dann Encoder, Decoder und die Vorhersage des nächsten Tokens.
Jeder Abschnitt beginnt mit einem einfachen Satz, bringt dann die Mathematik und rechnet anschließend alles an einem Satz aus vier Wörtern in zwei Dimensionen nach, klein genug, um ihn mit dem Bleistift zu prüfen. Nichts verschwindet hinter einem Bibliotheksaufruf: Die zwölf Zeilen NumPy am Ende reproduzieren jede Zahl im Text.
Lesehinweise
- Wenn Sie nur zehn Minuten haben, lesen Sie die einfachen Sätze und sehen Sie sich die Abbildungen an: Zusammen erzählen sie die ganze Geschichte.
- Wenn Sie sich auf eine Prüfung oder ein Vorstellungsgespräch vorbereiten, folgen Sie den Schritt-für-Schritt-Listen und rechnen Sie das Beispiel auf Papier nach; die Tabellen liefern die Zahlen zum Vergleich.
- Wenn Sie es implementieren wollen, springen Sie zum Code am Ende und kehren Sie dann zu den Abschnitten zurück, um die Gründe hinter jeder Zeile zu verstehen.
Dieser Artikel begleitet den Machine-Learning-Kurs an der Centrale Méditerranée.
Teil I
Wörter als Vektoren
Einbettungen: Ein Wort ist ein Punkt im Raum
Eine Einbettung verwandelt ein Wort in eine Liste von Zahlen, so angeordnet, dass Wörter mit ähnlicher Bedeutung nahe beieinander liegen.
Ein Computer kann die Wörter Pferd und Gaul nicht als Text vergleichen: Die beiden Zeichenketten haben keinen Buchstaben gemeinsam. Zwei Listen von Zahlen kann er dagegen vergleichen. Eine Einbettung (Embedding) ist eine Funktion, die jedem Token (einem Wort oder einem Wortteil) einen Vektor in zuordnet, mit typischerweise zwischen einigen Hundert und einigen Tausend, und die so trainiert wird, dass die Geometrie die Bedeutung widerspiegelt: nahe Vektoren für verwandte Wörter, weit entfernte für Wörter ohne Bezug zueinander.
Schritt für Schritt
- Tokenisieren. Den Text in Tokens zerlegen. In diesem Artikel ist ein Token ein Wort; echte Modelle zerlegen in Teilwörter, damit auch seltene Wörter abgedeckt sind.
- Nachschlagen. Jedes Token ist eine Zeile einer großen Tabelle , wobei die Größe des Vokabulars ist. Die Einbettung von Token ist einfach die Zeile .
- Vergleichen. Zwei Vektoren vergleicht man über den Kosinus des Winkels zwischen ihnen, der ihre Länge ignoriert: . Ein Wert nahe 1 bedeutet dieselbe Richtung, nahe 0 keinen Zusammenhang, nahe die entgegengesetzte Richtung.
Die Tabelle wird gelernt, nicht von Hand geschrieben: Man trainiert ein Modell auf einem großen Korpus darauf, Wörter aus ihren Nachbarn vorherzusagen, und die Zeilen von pendeln sich dort ein, wo die Vorhersage am besten funktioniert. Die berühmten Regelmäßigkeiten folgen aus diesem Training: In einem guten Raum ist der Vektor von König zu Königin fast derselbe wie der Vektor von Mann zu Frau.
Das Beispiel, das sich durch den ganzen Artikel zieht
Nehmen wir den Satz Apple shares fell sharply („Die Apple-Aktien fielen stark“), vier Tokens, und einen Spielzeugraum der Dimension . Achse 1 lesen wir als „Nahrung“, Achse 2 als „Finanzen“. Die Einbettungstabelle, auf allgemeinem Text trainiert, hat Apple in die Nähe der Frucht gelegt, weil das Wort meistens genau das bedeutet:
Der Kosinus zwischen Apple und shares beträgt 0,29: Die bloßen Einbettungen sagen, dass die beiden Wörter wenig miteinander zu tun haben. In diesem Satz haben sie alles miteinander zu tun. Diese Lücke ist das Problem, das die Aufmerksamkeit löst.
Das Problem: ein Vektor pro Wort, egal in welchem Satz
Eine feste Einbettung gibt einem Wort in jedem Satz denselben Vektor und kann deshalb eine Frucht nicht von einem Unternehmen unterscheiden.
Die Tabelle hat eine Zeile pro Token. Apple erhält denselben Vektor in an apple a day und in Apple shares fell sharply; Bank erhält denselben Vektor, ob sie ein Geldinstitut oder eine Sitzgelegenheit ist; Kurs, ob er ein Börsenkurs, eine Fahrtrichtung oder ein Lehrgang ist. Linguisten nennen solche Wörter polysem; für ein Modell sind sie ein einziger Punkt, der eigentlich zwei sein müsste.
Was wir wollen, ist eine zweite Folge , ein Vektor pro Token, wobei der Vektor von Token in diesem Satz ist: dasselbe Wort, von seinen Nachbarn neu verortet. Diese Darstellung muss aus dem Satz selbst aufgebaut werden, in dem Moment, in dem der Satz gelesen wird, statt in einer Tabelle nachgeschlagen zu werden.
Bemerkung (Warum ein gewichteter Mittelwert). Der einfachste Weg für ein Token, seinen Kontext zu berücksichtigen, besteht darin, ein wenig von jedem anderen Token beizumischen. Eine Mischung ist ein gewichteter Mittelwert, und die ganze Frage lautet dann: wie viel von jedem Nachbarn, und wer entscheidet das.
Teil II
Der Aufmerksamkeitsmechanismus
Aufmerksamkeit als gewichteter Mittelwert
Jedes Wort wird zu einem gewichteten Mittelwert aller Wörter des Satzes, wobei die Wörter, die für dieses Wort zählen, mehr Gewicht erhalten.
Der Satz sei die Folge von Einbettungen, Tokens der Dimension . Der kontextuelle Vektor von Token ist eine gewichtete Summe aller Tokens:
Das Gewicht gibt an, wie stark Token in der neuen Fassung von Token zählt. Die Nebenbedingungen machen die Gewichte zu einer Wahrscheinlichkeitsverteilung über den Satz, sodass in derselben Region des Raums bleibt wie die Eingaben: ein echter Mittelwert, keine Explosion.
Schritt für Schritt
- Bewerten. Messen, wie relevant für ist. Das rechnerisch günstigste Maß ist das Skalarprodukt (Dot Product) : groß, wenn die beiden Vektoren in dieselbe Richtung zeigen, null, wenn sie senkrecht aufeinander stehen.
- Normieren. Die Scores der Zeile mit der Softmax-Funktion in Gewichte umwandeln, die positiv sind und sich zu 1 addieren: .
- Mischen. als gewichtete Summe aus Gleichung (3) berechnen.
- Für jedes Token wiederholen. Die Zeilen beeinflussen sich nicht gegenseitig: Die Berechnungen sind unabhängig und laufen parallel, weshalb diese Operation so gut zu GPUs passt.
Stapelt man die Zeilen, erhält man die Matrixform. Mit ist die Score-Matrix (Eintrag ist ), die Softmax wird Zeile für Zeile angewendet, und die neue Folge ist das Produkt der Gewichte mit den Eingaben:
Von Hand, am Beispiel
Zeile 1 ist Apple. Die Skalarprodukte von Apple mit den vier Tokens betragen , dann 0,30 mit shares, 0,42 mit fell und 0,30 mit sharply. Die Exponentialwerte, geteilt durch ihre Summe, ergeben die Gewichte der ersten Zeile von Tabelle 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 |
Der neue Vektor von Apple ist . Er hat sich von in Richtung der Finanzachse bewegt, was die richtige Richtung ist, aber vor allem, weil drei der vier Wörter zufällig dort liegen. Nichts in der Rechnung wusste, dass shares das Wort war, auf das es ankam.
Bemerkung (Wo die Methode an ihre Grenzen stößt). Das Skalarprodukt belohnt Vektoren, die bereits in dieselbe Richtung zeigen. Stünden Apple und shares im Einbettungsraum senkrecht aufeinander, wäre ihr Score 0, und shares bekäme das kleinste Gewicht, genau dann, wenn es das größte bekommen sollte. Die Gewichte müssen in einem Raum berechnet werden, in dem die relevanten Paare gleich ausgerichtet sind, und dieser Raum muss gelernt werden. Das ist die Aufgabe des nächsten Abschnitts.
Abfragen, Schlüssel und Werte
Vor dem Vergleich wird jedes Wort dreimal projiziert: auf eine Frage, die es stellt, auf ein Etikett, auf das es hört, und auf den Inhalt, den es weitergibt.
Im gewichteten Mittelwert spielte ein einziger Vektor drei Rollen zugleich: Er fragte nach Kontext, er diente als Vergleichspunkt, und er wurde eingemischt. Trennt man die drei Rollen, kann das Modell jede einzeln lernen. Stellen Sie sich einen Lesesaal vor: Ein Leser gibt eine Abfrage (Query) ab („wonach ich suche“), jedes Buch trägt auf dem Rücken einen Schlüssel (Key) („wovon ich handle“), und das Buch selbst ist der Wert (Value) („was Sie bekommen, wenn Sie mich aufschlagen“). Die Relevanz wird zwischen der Abfrage und den Schlüsseln gemessen; zurückgegeben wird eine Mischung der Werte.
Schritt für Schritt
- Projizieren. Drei gelernte Matrizen verwandeln die Eingabe in Abfragen, Schlüssel und Werte: , , , mit und .
- Bewerten. Der Score von Token für Token ist das Skalarprodukt der Abfrage von mit dem Schlüssel von : , also .
- Skalieren. Die Scores durch teilen, damit sie in dem Bereich bleiben, in dem die Softmax noch einen Gradienten hat (siehe Bemerkung unten).
- Normieren und mischen. Softmax auf jede Zeile, dann mit den Werten multiplizieren.
Das ist die skalierte Skalarprodukt-Aufmerksamkeit (Scaled Dot-Product Attention) aus dem Paper von 2017, und sie ist der ganze Mechanismus. Alles Weitere (Köpfe, Positionen, Encoder, Decoder) baut auf dieser einen Zeile auf. Die Matrizen , , sind die Parameter, die das Training anpasst: Der Verlust bei der Vorhersage des nächsten Tokens verschiebt sie so, dass sich die Abfragen eines Tokens an den Schlüsseln der Tokens ausrichten, die helfen, das Folgende vorherzusagen.
Bemerkung (Warum durch die Wurzel der Schlüsseldimension teilen). Sind die Koordinaten von und unabhängig mit Mittelwert 0 und Varianz 1, so ist ihr Skalarprodukt eine Summe von Termen der Varianz 1; es hat also die Varianz und die typische Größe . Bei streuen die rohen Scores über Dutzende Einheiten, die Softmax legt ihre gesamte Masse auf ein einziges Token, und ihr Gradient verschwindet. Die Division durch bringt die Varianz unabhängig von der Dimension auf 1 zurück.
Von Hand, am Beispiel
Zuerst nur die Skalierung. Mit werden die Scores von Zeile 1 durch geteilt: 0,735; 0,212; 0,297; 0,212, und die Gewichte werden zu 0,353; 0,209; 0,228; 0,209: flacher, wie erwartet, denn die Softmax kleinerer Zahlen liegt näher an der Gleichverteilung.
Nun eine Projektion. Wir wählen von Hand, um zu zeigen, was das Training entdecken könnte: eine Matrix, die die beiden Achsen vertauscht. Die Abfrage eines Tokens fragt dann nach der anderen Lesart seiner selbst. Apple, das auf der Nahrungsachse liegt, fragt nach Finanzen. und bleiben die Identität.
Die Abfrage von Apple ist jetzt . Die skalierten Scores dieser Abfrage gegen die vier Schlüssel betragen 0,283; 0,721; 0,467; 0,382: shares passt jetzt am besten, wie Tabelle 2 zeigt.
| 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 |
Die Ausgabe für Apple wird zu , weiter entlang der Finanzachse als zuvor, und diesmal, weil das richtige Wort sie gezogen hat. Eine einzige, absichtlich gewählte Matrix der Größe hat geschafft, was kein Skalarprodukt auf den rohen Einbettungen konnte. Ein trainiertes Modell hat Tausende solcher Matrizen und wählt sie anhand der Daten.
Mehrkopf-Aufmerksamkeit
Mehrere Aufmerksamkeitsberechnungen laufen nebeneinander, jede mit eigenen Projektionen, sodass eine die Bedeutung verfolgen kann, während eine andere die Grammatik verfolgt.
Ein einzelnes Tripel von Projektionen erfasst eine einzige Art von Beziehung. Die Vertauschungsmatrix oben klärt den Fall Apple; sie sagt nichts darüber, welches Verb zu welchem Subjekt gehört oder welches Wort zwei Stellen weiter links steht. Statt eine einzige Projektion alles erledigen zu lassen, führt der Transformer in der Mehrkopf-Aufmerksamkeit (Multi-Head Attention) Aufmerksamkeitsberechnungen parallel aus, die Köpfe (Heads), jede mit eigenen , , der reduzierten Dimension , und fügt ihre Ausgaben anschließend zusammen.
Schritt für Schritt
- Aufteilen. Kopf projiziert die Eingabe in seinen eigenen kleinen Raum: , jede Ausgabe in .
- Verketten. Die Ausgaben werden nebeneinandergelegt, was eine Matrix in ergibt.
- Zurückprojizieren. Eine letzte Matrix mischt die Köpfe zu einer Darstellung pro Token.
Die Kosten sind dieselben wie bei einem einzigen Kopf voller Dimension: Köpfe der Dimension erfordern genauso viel Rechenarbeit wie ein Kopf der Dimension . Gewonnen wird Vielfalt. In trainierten Modellen finden Sondierungsanalysen (Probes) Köpfe, die der Syntax folgen (ein Verb achtet auf sein Subjekt), Köpfe, die auf das vorherige Token achten, Köpfe, die ein seltenes Wort von weiter vorne im Text kopieren, und Köpfe, deren Rolle noch niemand benannt hat.
Von Hand, am Beispiel
Nehmen wir Köpfe der Dimension . Kopf 1 behält nur die Finanzkoordinate jedes Tokens (), Kopf 2 nur die Nahrungskoordinate (). In Kopf 2 lautet die Zeile von Apple 0,425; 0,173; 0,211; 0,191: Apple, das einzige Wort aus dem Bereich Nahrung, achtet vor allem auf sich selbst. In Kopf 1 lautet sie 0,232; 0,272; 0,251; 0,246: Auf der Finanzachse ähneln sich die vier Tokens, und die Gewichte sind nahezu gleich verteilt. Die Verkettung der beiden Ausgaben für Apple ergibt ; mit als Identität ist das die Ausgabe der Mehrkopf-Aufmerksamkeit.
Bemerkung (Was die beiden Köpfe sagen). Kopf 2 beantwortet die Frage Wer bin ich?, Kopf 1 die Frage Wie sieht der Markt um mich herum aus? Ein einziger Kopf der Dimension 2 hätte beide Fragen zu einem einzigen Score verschmelzen müssen. Genau darum geht es bei den Köpfen: getrennte Fragen, getrennte Gewichte, eine gemeinsame Antwort.
Positionskodierung: den Wörtern eine Reihenfolge geben
Die Aufmerksamkeit behandelt den Satz als ungeordnete Wortmenge (Bag of Words), deshalb wird zu jedem Token ein Vektor addiert, der seine Position beschreibt, bevor irgendetwas anderes geschieht.
Sehen Sie sich noch einmal Gleichung (6) an: Nichts darin hängt vom Index ab, außer über . Vertauscht man die Tokens, werden die Ausgaben auf dieselbe Weise vertauscht, sonst aber nicht verändert. Die Bank kaufte die Firma und Die Firma kaufte die Bank ergeben dieselbe Menge von Vektoren. Die Reihenfolge trägt Bedeutung, und der Mechanismus wirft sie weg.
Die Abhilfe, die Positionskodierung (Positional Encoding), besteht darin, zu jeder Einbettung vor der ersten Aufmerksamkeitsschicht einen Vektor zu addieren, der nur von der Position des Tokens in der Folge abhängt:
Schritt für Schritt
- Für jede Position einen Code wählen. Das Paper von 2017 verwendet Sinus und Kosinus mit geometrisch gestaffelten Frequenzen: Koordinate von ist , Koordinate ist . Niedrige Koordinaten schwingen schnell und unterscheiden benachbarte Positionen; hohe Koordinaten schwingen langsam und ordnen die ganze Folge.
- Addieren, nicht verketten. Die Addition behält die Dimension bei und lässt die Projektionen , Position und Inhalt gemeinsam lesen; so kann ein Kopf lernen, auf das Token direkt vor mir zu achten.
- Die Schichten davon Gebrauch machen lassen. Von da an tragen jede Abfrage und jeder Schlüssel die Position, sodass die Scores vom Abstand ebenso abhängen können wie von der Bedeutung.
Bemerkung (Warum Sinus und Kosinus). Für einen festen Versatz ist das Paar an Position eine Drehung des Paars an Position um den Winkel : eine lineare Funktion, unabhängig von . Ein Kopf kann daher k Positionen nach links als feste lineare Abbildung lernen, unabhängig von der absoluten Position. Die Kodierungen sind außerdem beschränkt, und sie lassen sich auf Längen ausdehnen, die im Training nie vorkamen. Viele neuere Modelle verwenden eine rotationsbasierte Variante, die dieselbe Drehidee innerhalb der Abfragen und Schlüssel anwendet, statt sie zur Eingabe zu addieren.
Von Hand, am Beispiel
Bei gibt es nur eine Frequenz, , also im Bogenmaß. Tabelle 3 addiert sie zu den vier Einbettungen. Die beiden Sätze Apple shares fell sharply und Shares fell sharply, Apple geben Apple jetzt zwei verschiedene Eingaben, an Position 0 und an Position 3, und alle Aufmerksamkeitsgewichte ändern sich mit ihnen.
| Token | |||||
|---|---|---|---|---|---|
| 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 |
Der Encoder-Block
Ein Encoder-Block lässt die Wörter miteinander reden (Aufmerksamkeit) und dann jedes Wort für sich nachdenken (ein kleines neuronales Netz), mit Umgehungspfaden, damit das Training stabil bleibt.
Der Transformer von Vaswani et al. (2017) wurde gebaut, um eine Folge in eine andere zu überführen, einen französischen Satz in einen englischen. Sein Encoder liest die gesamte Eingabe und erzeugt pro Eingabetoken einen kontextreichen Vektor. Er ist ein Stapel aus identischen Blöcken (6 im Paper), und jeder Block besteht aus zwei Teilschichten, die beide mit denselben zwei Kniffen versehen sind.
Ein Encoder-Block, Eingabe
- Mehrkopf-Selbstaufmerksamkeit. : Abfragen, Schlüssel und Werte stammen alle aus , deshalb heißt sie Selbstaufmerksamkeit (Self-Attention). Hier, und nur hier, fließt Information zwischen den Tokens.
- Residualverbindung und Normalisierung. . Die Eingabe wieder zu addieren (das Residuum) bedeutet, dass ein Block nur eine Korrektur lernen muss und die Gradienten geradewegs durch den Stapel fließen; jeden Token-Vektor auf Mittelwert 0 und Varianz 1 zu normalisieren, hält die Skala von Block zu Block stabil.
- Feedforward-Netz. , dasselbe zweischichtige Netz (Feed-Forward Network), unabhängig auf jedes Token angewendet: , mit einer verborgenen Schicht der Breite im Paper. Hier fließt keine Information zwischen den Tokens; jeder Vektor wird für sich transformiert.
- Noch einmal Residuum und Normalisierung. ist die Ausgabe des Blocks und die Eingabe des nächsten.
Die Aufmerksamkeit mischt über den Satz hinweg; das Feedforward-Netz arbeitet innerhalb jedes Tokens. Diese Arbeitsteilung ist gewollt: Die Aufmerksamkeit entscheidet, wohin geschaut wird, das Feedforward-Netz entscheidet, was daraus gemacht wird. Durch das Stapeln von Blöcken kann ein Token Kontext über den Kontext sammeln: Nach zwei Blöcken kann Apple nutzen, was shares selbst von fell gelernt hat.
Der Decoder-Block
Der Decoder schreibt die Ausgabe Token für Token und schaut dabei auf das, was er schon geschrieben hat, und auf die Lesart der Eingabe, die der Encoder geliefert hat.
Der Decoder erzeugt die Ausgabefolge Token für Token. In Schritt hat er bereits Tokens erzeugt, die eingebettet, mit Positionskodierung versehen und in zusammengefasst sind, und er verfügt über die Encoder-Ausgabe . Jeder seiner Blöcke hat drei Teilschichten, jede wie im Encoder mit Residualverbindung und Normalisierung versehen.
Ein Decoder-Block
- Maskierte Selbstaufmerksamkeit. Mehrkopf-Aufmerksamkeit über die bereits geschriebenen Tokens, mit einer Änderung: Ein Token darf nur auf die Positionen vor ihm achten. In der Score-Matrix wird jeder Eintrag mit vor der Softmax auf gesetzt, sodass sein Gewicht genau 0 wird. Ohne die Maske ließe das Training das Modell die Antwort lesen, die es vorhersagen soll.
- Kreuzaufmerksamkeit (Cross-Attention). Die Abfragen stammen aus den eigenen Vektoren des Decoders; die Schlüssel und Werte stammen aus der Encoder-Ausgabe . Hier schaut die Ausgabe auf die Eingabe: Beim Schreiben des dritten englischen Wortes fragt der Decoder, welche französischen Wörter dafür relevant sind. Es ist die einzige Stelle, an der sich die beiden Hälften des Modells treffen.
- Feedforward-Netz. Dasselbe Netz pro Token wie im Encoder.
Bemerkung (Encoder-Decoder, nur Encoder, nur Decoder). Das Modell von 2017 hat beide Hälften, weil es übersetzt. Modelle, die Text klassifizieren oder einbetten, behalten nur den Encoder (BERT ist eines davon). Die großen Sprachmodelle, die Text schreiben, behalten nur den Decoder: Es gibt keine separate Eingabe, auf die geachtet werden müsste, Prompt und Antwort bilden eine einzige Folge, und die Maske sorgt dafür, dass die Generierung von links nach rechts verläuft.
Das nächste Token vorhersagen
Der letzte Vektor des Decoders wird in einen Score für jedes Wort des Vokabulars umgewandelt, die Scores werden zu Wahrscheinlichkeiten, und ein Wort wird ausgewählt.
Nach dem letzten Decoder-Block fasst der Vektor an der letzten Position, , alles zusammen, was bisher geschrieben und was in der Eingabe gelesen wurde. Eine lineare Schicht bildet ihn auf einen Score pro Eintrag des Vokabulars ab, und eine Softmax verwandelt die Scores in eine Wahrscheinlichkeitsverteilung:
Die Generierungsschleife
- Das Vokabular bewerten. Die obige Verteilung für das aktuelle Präfix berechnen.
- Ein Token wählen. Das wahrscheinlichste (gierige Dekodierung, Greedy Decoding) oder eine Stichprobe aus der Verteilung, oft nachdem sie mit einer Temperatur geschärft oder abgeflacht wurde, oder unter Beschränkung auf die besten Kandidaten.
- Anhängen und wiederholen. Das gewählte Token wird an das Präfix angehängt, erhält seine Einbettung und seine Position, und der Decoder läuft erneut. Die Schleife endet beim Sequenzende-Token oder bei einer Maximallänge.
Beim Training gibt es keine Schleife: Der gesamte Zielsatz wird dem Decoder auf einmal zugeführt, die Maske verbirgt die Zukunft, und der Verlust ist die Kreuzentropie zwischen der vorhergesagten Verteilung an jeder Position und dem tatsächlichen nächsten Token, summiert über den Satz. Das nennt man Teacher Forcing, und deshalb lässt sich das Training eines Transformers über die Sequenz parallelisieren, die Generierung dagegen nicht.
Bemerkung (Kosten). Die Selbstaufmerksamkeit vergleicht jedes Token mit jedem anderen: Scores aus je Multiplikationen, also Zeit und Speicher pro Kopf und pro Schicht. Dieser quadratische Term ist der Grund, warum lange Kontexte teuer sind, und der Grund, warum es eine ganze Fachliteratur zu dünn besetzter oder approximativer Aufmerksamkeit gibt.
Der gesamte Vorwärtsdurchlauf, der Reihe nach
- Tokenisieren und einbetten. Den Text in Tokens zerlegen; jedes in der Tabelle nachschlagen, um zu erhalten.
- Positionen addieren. , damit die Reihenfolge der Wörter den nächsten Schritt übersteht.
- Projizieren. Für jeden Kopf , , .
- Bewerten, skalieren, maskieren. , plus oberhalb der Diagonale in einem Decoder.
- Normieren. Softmax auf jede Zeile: Jedes Token erhält eine Verteilung über den Satz.
- Mischen. Die Gewichte mit multiplizieren; die Köpfe verketten; mit projizieren.
- Residuum, Normalisierung, Feedforward, Residuum, Normalisierung. Ein Block ist fertig; -mal wiederholen.
- Den letzten Vektor lesen. Lineare Schicht auf das Vokabular, Softmax, ein Token wählen, anhängen, für das neue Präfix zurück zu Schritt 1.
Dieselbe Rechnung in zwölf Zeilen NumPy
Zwölf Zeilen, die Abschnitt 4 an der Beispielmatrix nachrechnen, mit der Projektion , die die Achsen vertauscht. Die beiden ausgegebenen Zeilen sind die erste Zeile von Tabelle 2 und die Ausgabe für 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]
Glossar
- Einbettung (Embedding)
- Eine gelernte Abbildung von Tokens auf Vektoren, so trainiert, dass der Abstand die Bedeutung widerspiegelt. Eine Zeile pro Token in einer Tabelle .
- Token
- Die Einheit, die das Modell liest: ein Wort, ein Teilwort oder ein Zeichen, je nach Tokenizer.
- Aufmerksamkeit (Attention)
- Ein gewichteter Mittelwert der Werte einer Folge, mit Gewichten, die aus der Übereinstimmung zwischen einer Abfrage und allen Schlüsseln berechnet werden.
- Abfrage, Schlüssel, Wert (Query, Key, Value)
- Drei Projektionen desselben Tokens: wonach es sucht, worauf es hört, was es weitergibt.
- Kopf (Head)
- Eine Aufmerksamkeitsberechnung mit eigenen Projektionen; mehrere laufen parallel und werden verkettet.
- Positionskodierung (Positional Encoding)
- Ein zu jeder Einbettung addierter Vektor, der die Position des Tokens kodiert, damit die Reihenfolge nicht verloren geht.
- Residualverbindung (Residual Connection)
- Die Eingabe einer Teilschicht wird zu ihrer Ausgabe addiert, sodass die Teilschicht eine Korrektur lernt und die Gradienten durchfließen.
- Schichtnormalisierung (Layer Normalization)
- Jeden Token-Vektor auf Mittelwert 0 und Varianz 1 bringen, danach eine gelernte Skalierung und Verschiebung anwenden.
- Encoder
- Der Stapel von Blöcken, der die Eingabefolge liest und pro Token einen Kontextvektor ausgibt.
- Decoder
- Der Stapel von Blöcken, der die Ausgabe Token für Token schreibt, mit einer kausalen Maske und Kreuzaufmerksamkeit auf den Encoder.
- Softmax
- Die Funktion, die eine Liste von Scores in positive Gewichte mit der Summe 1 verwandelt, indem sie die Exponentialfunktion anwendet und durch die Gesamtsumme teilt.
Literatur
- 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. Der erste Aufmerksamkeitsmechanismus, additiv statt über das Skalarprodukt.
- 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. Die in Abschnitt 6 erwähnte rotationsbasierte Variante.
- 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. Der Artikel, dessen Weg dieser hier folgt, mit einer Implementierung in PyTorch.
- A. Rush et al., The Annotated Transformer, Harvard NLP, 2018, überarbeitet 2022. nlp.seas.harvard.edu. Das Paper Zeile für Zeile neu implementiert.
Die Notizen des Machine-Learning-Kurses
Dieser Artikel erweitert einen Kurs. Zu jedem Foliensatz des Kurses gibt es außerdem öffentliche Notizen mit den Kernideen, den Formeln und einem durchgerechneten Beispiel:
- Einführung · KI-Winter, Arbeitsmarkt und Methode
- Werkzeuge · Kaggle, GitHub, Python: die Werkzeuge
- Sitzung 1 · Projektrahmen und kleinste Quadrate
- Sitzung 2 · Maximum Likelihood und logistische Regression
- Sitzung 3 · Gradientenabstieg, Ridge und Lasso
- Sitzung 4 · Entscheidungsschwelle und reproduzierbares ML
- Hausaufgabe · ML-Projekt abstecken: der Projektsteckbrief
- Sitzung 5 · Kernel, SVM und Entscheidungsbäume
- Sitzung 6 · Random Forests, Boosting, ehrlicher Vergleich
- Sitzung 7 · SHAP, Fairness, PCA und Clustering
- Hausaufgabe · Ein einfaches Modell mit vollständiger Methode
- Sitzung 8 · Neuronale Netze, Drift, konforme Vorhersage
- Hausaufgabe · Ein ausgeliefertes Machine-Learning-Projekt
- Sitzung 9 · Ein Machine-Learning-Projekt verteidigen
- Referenz · Projekt zum Kreditausfallscore
- Referenz · Aktienrenditen: XGBoost und Sentiment
- Referenz · Python-Code für jedes ML-Modell
- Referenz · Deep Learning, das Wesentliche
- Referenz · ML-Projekte mit offenen Daten nach Branche
- Referenz · Handbuch für Daten- und KI-Fachleute
- Referenz · Data Engineering, SRE und Cloud
- Referenz · Panorama der Machine-Learning-Modelle
Über diesen Artikel
Geschrieben für die Studierenden des Schwerpunkts Machine Learning an der Centrale Méditerranée und für alle, die ein Transformer-Tutorial gelesen haben und die Zahlen trotzdem nicht nachrechnen konnten. Der Weg von den Einbettungen zum vollständigen Modell ist der klassische; der Satz, das zweidimensionale Beispiel, die von Hand gewählte Projektion und der Code sind eigens für diesen Artikel entstanden. Die Mathematik ist die von Vaswani et al. (2017), mit der Schichtnormalisierung von Ba et al. (2016).
Mit Unterstützung von Claude Code verfasst, einem Produkt von Anthropic; jede Formel wurde anhand der Originalarbeiten geprüft, und jede Zahl wird bei jedem Build vom Code der Seite selbst neu berechnet.
Stand: . Erstveröffentlichung am selben Tag.