Transformer-Architektur verstehen: Theorie und Konzepte (Teil 1 von 3)

Transformer-Architektur verstehen: Theorie und Konzepte (Teil 1 von 3)

Die Transformer-Architektur: Von der Theorie zur Praxis

Einleitung: Eine Revolution in der Sprachverarbeitung

Im Jahr 2017 veröffentlichten Forscher von Google ein Paper mit dem bescheidenen Titel "Attention is All You Need". Was unscheinbar klang, revolutionierte die gesamte Welt der künstlichen Intelligenz. Die Transformer-Architektur, die in diesem Paper vorgestellt wurde, bildet heute das Fundament für nahezu alle modernen Sprachmodelle - von GPT über BERT bis hin zu den neuesten multimodalen Systemen.

Aber was macht Transformer so besonders? Im Kern ist es die elegante Lösung eines fundamentalen Problems: Wie kann ein Computer die komplexen Beziehungen in menschlicher Sprache verstehen, wo doch Wörter ihre Bedeutung oft erst durch den Kontext erhalten?

Dieser Artikel ist der erste Teil einer dreiteiligen Serie über die Transformer-Architektur. In diesem Teil legen wir die theoretischen Grundlagen - von den mathematischen Konzepten bis zu den architektonischen Entscheidungen, die Transformer so erfolgreich machen. Im zweiten zeige ich dir dann, wie du selbst ein Modell trainieren kannst, mit praktischen Anleitungen und Shell-Skripten. Der dritte Teil geht schließlich tief in die Code-Implementierung ein und erklärt jede Zeile des Trainings-Codes.

Das fundamentale Problem: Kontext in der Sprache

Nehmen wir einen einfachen Satz: "Die Bank war zu steil, deshalb rutschte er ab." Das Wort "Bank" hat hier nichts mit Geld zu tun - der Kontext macht klar, dass es um eine Sitzbank oder Böschung geht. Für uns Menschen ist das selbstverständlich, aber für einen Computer ist es eine enorme Herausforderung.

Vor den Transformern versuchten Modelle wie RNNs (Recurrent Neural Networks) dieses Problem zu lösen, indem sie Wörter sequenziell verarbeiteten - eines nach dem anderen, wie beim Lesen. Das funktionierte, hatte aber gravierende Nachteile: Die sequenzielle Verarbeitung war langsam, und bei langen Texten "vergaß" das Modell oft wichtige Informationen vom Anfang.

Transformer lösen dieses Problem radikal anders: Sie betrachten alle Wörter gleichzeitig und lernen, welche Wörter füreinander wichtig sind. Diese Fähigkeit nennt sich "Attention" - Aufmerksamkeit.

Der Attention-Mechanismus im Detail: Das Herzstück der Transformer

Die Intuition hinter Attention

Stell dir vor, du sitzt in einem vollen Café und unterhältst dich mit einem Freund. Obwohl überall Gespräche stattfinden, kannst du dich auf die Stimme deines Gegenübers konzentrieren. Dein Gehirn lenkt seine "Aufmerksamkeit" auf die relevanten Schallwellen und blendet den Rest aus. Genau dieses Prinzip nutzt der Attention-Mechanismus.

Aber Attention in Transformern geht noch weiter. Stell dir vor, du liest einen Krimi: "Der Butler betrat das Zimmer. Die Gräfin schrie. Er hatte das Messer noch in der Hand." Wenn du verstehen willst, wer "er" ist, schaust du automatisch zurück - "er" bezieht sich auf "der Butler", nicht auf "die Gräfin". Dein Gehirn berechnet unbewusst, welche vorherigen Wörter für das Verständnis von "er" relevant sind. Genau das macht der Attention-Mechanismus mathematisch präzise.

Das Query-Key-Value Prinzip: Eine tiefere Betrachtung

Die geniale Idee hinter Attention ist die Aufteilung in drei Komponenten: Query, Key und Value. Lass uns das mit einem ausführlichen Beispiel verstehen:

Beispiel: "Die Katze, die auf dem warmen Dach saß, beobachtete die Vögel."

Nehmen wir an, wir wollen die Bedeutung des Wortes "beobachtete" verstehen. Der Transformer geht wie folgt vor:

1. Query-Erzeugung

Das Wort "beobachtete" wird durch eine lineare Transformation in einen Query-Vektor umgewandelt. Dieser Query repräsentiert die Frage: "Wer führt diese Handlung aus? Was ist das Subjekt dieser Beobachtung?"

Stell dir den Query wie einen Suchvektor vor. Wenn "beobachtete" einen 64-dimensionalen Query-Vektor erzeugt, könnte dieser aussehen wie:

Query("beobachtete") = [0.2, -0.5, 0.8, ..., 0.3]  // 64 Zahlen

Diese Zahlen kodieren abstrakt die "Frage" nach dem Subjekt einer Beobachtungshandlung.

2. Key-Erzeugung für alle Wörter

Gleichzeitig erzeugt jedes Wort im Satz einen Key-Vektor. Der Key ist wie ein "Angebot" - er beschreibt, welche Art von Information dieses Wort bereitstellen kann:

Key("Die") = [0.1, 0.2, -0.3, ..., 0.4]        // Artikel, wenig semantische Info
Key("Katze") = [0.3, -0.4, 0.9, ..., 0.2]      // Subjekt, Lebewesen, Akteur
Key("die") = [0.1, 0.3, -0.2, ..., 0.1]        // Relativpronomen
Key("auf") = [-0.2, 0.1, 0.4, ..., -0.3]       // Präposition, Ortsangabe
Key("saß") = [0.2, -0.3, 0.5, ..., 0.4]        // Verb, Zustand
Key("beobachtete") = [0.4, -0.6, 0.7, ..., 0.5] // Verb, Handlung
Key("Vögel") = [0.2, -0.3, 0.6, ..., 0.3]      // Objekt, Lebewesen

3. Ähnlichkeitsberechnung (Attention Scores)

Jetzt kommt der zentrale Schritt: Wir berechnen, wie ähnlich der Query von "beobachtete" zu jedem Key ist. Diese Ähnlichkeit wird durch das Skalarprodukt (Dot Product) berechnet:

Score("beobachtete" ? "Die") = Query · Key("Die") = 0.2
Score("beobachtete" ? "Katze") = Query · Key("Katze") = 8.5  // Hoch!
Score("beobachtete" ? "die") = Query · Key("die") = 0.3
Score("beobachtete" ? "saß") = Query · Key("saß") = 2.1
Score("beobachtete" ? "Vögel") = Query · Key("Vögel") = 3.2

Die hohe Punktzahl bei "Katze" zeigt: Das Modell hat gelernt, dass "Katze" als Subjekt sehr relevant für das Verb "beobachtete" ist!

4. Skalierung und Softmax

Die Scores werden durch die Wurzel der Dimension geteilt (bei 64 Dimensionen durch 8) und dann durch Softmax in Wahrscheinlichkeiten umgewandelt:

Skalierte Scores: [0.025, 1.06, 0.038, 0.26, 0.4]
Nach Softmax: [0.05, 0.55, 0.05, 0.15, 0.20]  // Summe = 1.0

Das bedeutet: "beobachtete" schenkt 55% seiner Aufmerksamkeit "Katze", 20% "Vögel", 15% "saß", und nur 5% den anderen Wörtern.

5. Value-Aggregation

Jedes Wort hat auch einen Value-Vektor, der die tatsächliche Information enthält, die es weitergibt:

Value("Katze") = [semantische Info über Katze als Subjekt und Lebewesen]
Value("Vögel") = [semantische Info über Vögel als Beobachtungsobjekt]

Die finale Repräsentation von "beobachtete" ist die gewichtete Summe aller Values:

Output("beobachtete") = 0.55 × Value("Katze") + 0.20 × Value("Vögel") + ...

So "versteht" das Modell, dass "beobachtete" hauptsächlich von der Katze ausgeführt wird und sich auf die Vögel bezieht.

flowchart TD
    subgraph "Input: Die Katze beobachtete"
        W1["Die
Token"] W2["Katze
Token"] W3["beobachtete
Token"] end subgraph "Linear Transformationen" W1 --> Q1["Query"] W1 --> K1["Key"] W1 --> V1["Value"] W2 --> Q2["Query"] W2 --> K2["Key"] W2 --> V2["Value"] W3 --> Q3["Query"] W3 --> K3["Key"] W3 --> V3["Value"] end subgraph "Attention für 'beobachtete'" Q3 --> DOT["Dot Product
mit allen Keys"] K1 --> DOT K2 --> DOT K3 --> DOT DOT --> SCORES["Attention Scores
Katze: 8.5
Die: 0.2
beobachtete: 2.1"] SCORES --> SCALE["Skalierung ÷vd"] SCALE --> SOFT["Softmax"] SOFT --> WEIGHTS["Attention Weights
Katze: 55%
Die: 5%
beobachtete: 40%"] end subgraph "Value Aggregation" WEIGHTS --> AGG["Gewichtete Summe"] V1 --> AGG V2 --> AGG V3 --> AGG AGG --> OUT["Output für
'beobachtete'
mit Kontext"] end

Ein komplexeres Beispiel: Mehrdeutigkeit auflösen

Betrachten wir einen mehrdeutigen Satz: "Die Polizei verhaftete den Dieb, weil er gefährlich war."

Für Menschen ist klar: "er" bezieht sich auf "den Dieb". Aber wie lernt das ein Transformer?

Wenn der Attention-Mechanismus die Bedeutung von "er" berechnet:

  1. Query von "er": Sucht nach einem maskulinen Singular-Referenten

  2. Keys:

    • "Polizei" (feminin, Kollektiv) ? niedriger Score
    • "Dieb" (maskulin, Singular) ? hoher Score
    • "gefährlich" (Adjektiv, braucht Bezug) ? mittlerer Score
  3. Attention-Verteilung: "er" könnte 70% Attention auf "Dieb", 20% auf "gefährlich", 10% auf Rest geben

Interessanterweise würde bei dem Satz "Die Polizei verhaftete den Dieb, weil sie effizient war" die Attention von "sie" hauptsächlich auf "Polizei" zeigen - das Modell hat gelernt, Genus und Semantik zu berücksichtigen!

Die Mathematik hinter Attention: Schritt für Schritt

Lass uns die Attention-Berechnung mathematisch durchgehen. Angenommen, wir haben eine Sequenz von 4 Wörtern: "Der Hund bellt laut"

  1. Embedding-Matrix X: Jedes Wort wird zu einem Vektor (sagen wir 512 Dimensionen)

    X = [embedding("Der"), embedding("Hund"), embedding("bellt"), embedding("laut")]
    X hat die Form: 4 × 512
  2. Lineare Transformationen zu Q, K, V:

    Q = X × W_Q  // Query-Matrix (4 × 64 wenn wir auf 64 Dim projizieren)
    K = X × W_K  // Key-Matrix (4 × 64)
    V = X × W_V  // Value-Matrix (4 × 64)
  3. Attention-Score-Matrix:

    Scores = Q × K^T / v64

    Das ergibt eine 4×4 Matrix - jedes Wort hat einen Score zu jedem anderen:

    Scores = [
      [Der?Der, Der?Hund, Der?bellt, Der?laut],
      [Hund?Der, Hund?Hund, Hund?bellt, Hund?laut],
      [bellt?Der, bellt?Hund, bellt?bellt, bellt?laut],
      [laut?Der, laut?Hund, laut?bellt, laut?laut]
    ]
  4. Softmax pro Zeile:

    Attention_Weights = Softmax(Scores)

    Jede Zeile summiert sich zu 1.0

graph TB
    subgraph "Attention Score Matrix"
        subgraph " "
            DER1["Der->Der
2.1"] DER2["Der->Hund
3.5"] DER3["Der->bellt
1.2"] DER4["Der->laut
0.8"] end subgraph " " HUND1["Hund->Der
1.8"] HUND2["Hund->Hund
4.2"] HUND3["Hund->bellt
5.6"] HUND4["Hund->laut
2.1"] end subgraph " " BELLT1["bellt->Der
0.9"] BELLT2["bellt->Hund
6.3"] BELLT3["bellt->bellt
3.1"] BELLT4["bellt->laut
4.5"] end subgraph " " LAUT1["laut->Der
0.5"] LAUT2["laut->Hund
2.8"] LAUT3["laut->bellt
7.2"] LAUT4["laut->laut
2.2"] end end DER4 --> SOFT["Softmax
per row"] HUND4 --> SOFT BELLT4 --> SOFT LAUT4 --> SOFT subgraph "Attention Weights (sum=1.0 per row)" subgraph " " WDER1["Der->Der
0.22"] WDER2["Der->Hund
0.51"] WDER3["Der->bellt
0.17"] WDER4["Der->laut
0.10"] end subgraph " " WHUND1["Hund->Der
0.08"] WHUND2["Hund->Hund
0.24"] WHUND3["Hund->bellt
0.56"] WHUND4["Hund->laut
0.12"] end subgraph " " WBELLT1["bellt->Der
0.04"] WBELLT2["bellt->Hund
0.42"] WBELLT3["bellt->bellt
0.15"] WBELLT4["bellt->laut
0.39"] end subgraph " " WLAUT1["laut->Der
0.03"] WLAUT2["laut->Hund
0.18"] WLAUT3["laut->bellt
0.68"] WLAUT4["laut->laut
0.11"] end end SOFT --> WDER1
  1. Finale Ausgabe:
    Output = Attention_Weights × V
    Jedes Wort bekommt eine neue Repräsentation basierend auf allen anderen!

Selbst-Attention vs. Cross-Attention

Bisher haben wir über Self-Attention gesprochen - die Sequenz "schaut auf sich selbst". Es gibt aber auch Cross-Attention, wo eine Sequenz auf eine andere schaut. Das wird zum Beispiel in Übersetzungsmodellen verwendet:

Beispiel Übersetzung Deutsch ? Englisch:

  • Deutsche Sequenz: "Der Hund schläft"
  • Englische Sequenz (bisher generiert): "The dog"
  • Nächstes Wort: "sleeps"

Bei Cross-Attention:

  • Query kommt von "sleeps" (Englisch)
  • Keys und Values kommen von "Der Hund schläft" (Deutsch)
  • So kann "sleeps" auf "schläft" im Deutschen "schauen" und die korrekte Übersetzung lernen

Warum funktioniert das so gut?

Der Attention-Mechanismus ist aus mehreren Gründen so erfolgreich:

  1. Keine feste Distanz: Im Gegensatz zu CNNs oder RNNs kann Attention beliebig weit entfernte Wörter direkt verbinden. "Er" am Satzende kann problemlos auf "Peter" am Satzanfang referenzieren.

  2. Differenzierbar: Die gesamte Operation ist differenzierbar, also per Backpropagation trainierbar. Das Modell lernt automatisch, welche Verbindungen wichtig sind.

  3. Interpretierbar: Die Attention-Gewichte kann man visualisieren und sehen, worauf das Modell "schaut". Das macht Transformer transparenter als andere Architekturen.

  4. Parallelisierbar: Alle Attention-Berechnungen können gleichzeitig erfolgen, was auf GPUs extrem effizient ist.

Die Rolle der Maskierung

Ein wichtiges Detail bei autoregressiven Modellen wie GPT ist die kausale Maskierung. Das Modell darf nur in die Vergangenheit schauen, nicht in die Zukunft:

Beispiel-Sequenz: "Ich ging nach Hause"

Wenn das Modell "nach" verarbeitet:

  • Es DARF auf "Ich" und "ging" schauen ?
  • Es DARF NICHT auf "Hause" schauen ?

Die Maske sieht so aus:

Maske = [
  [1, 0, 0, 0],  // "Ich" kann nur sich selbst sehen
  [1, 1, 0, 0],  // "ging" kann "Ich" und sich selbst sehen
  [1, 1, 1, 0],  // "nach" kann "Ich", "ging" und sich selbst sehen
  [1, 1, 1, 1]   // "Hause" kann alles sehen
]

Positionen mit 0 werden auf -8 gesetzt, was nach Softmax zu 0 wird - perfekte Blockierung!

Multi-Head Attention: Verschiedene Perspektiven gleichzeitig

Ein einzelner Attention-Mechanismus wäre zu limitiert. Sprache hat viele Dimensionen - grammatikalische Struktur, semantische Bedeutung, stilistische Aspekte. Deshalb nutzen Transformer "Multi-Head Attention" - mehrere Attention-Mechanismen parallel.

Die Intuition hinter Multi-Head Attention

Stell dir vor, du analysierst ein Gemälde. Ein Kunsthistoriker achtet auf die Technik, ein Psychologe auf die emotionale Wirkung, ein Chemiker auf die verwendeten Farben. Jeder hat eine andere Perspektive, aber zusammen ergeben sie ein vollständiges Bild. Genauso arbeiten die verschiedenen Attention-Heads: Jeder lernt, auf andere Aspekte der Sprache zu achten.

Wie Multi-Head Attention funktioniert

Nehmen wir an, wir haben eine Embedding-Dimension von 768 (wie bei GPT-2) und 12 Attention-Heads. So läuft der Prozess ab:

  1. Aufteilung der Dimensionen: Die 768 Dimensionen werden auf 12 Heads aufgeteilt ? jeder Head arbeitet mit 64 Dimensionen.

  2. Parallele Attention-Berechnungen: Jeder Head führt seine eigene Query-Key-Value Attention durch:

    Head 1: Q1, K1, V1 ? Attention1 (64 dim)
    Head 2: Q2, K2, V2 ? Attention2 (64 dim)
    ...
    Head 12: Q12, K12, V12 ? Attention12 (64 dim)
  3. Konkatenation: Die Outputs aller Heads werden zusammengefügt:

    MultiHead_Output = [Attention1; Attention2; ...; Attention12]  // 768 dim total
  4. Finale Projektion: Eine lineare Transformation mischt die Information aller Heads:

    Output = MultiHead_Output × W_O
flowchart TB
    subgraph "Input Embeddings"
        INPUT["Input
768 dim"] end subgraph "Dimension Split (768 -> 12×64)" INPUT --> SPLIT["Split into
12 chunks"] end subgraph "12 Parallel Attention Heads" SPLIT --> H1["Head 1
64 dim
Q1K1V1"] SPLIT --> H2["Head 2
64 dim
Q2K2V2"] SPLIT --> H3["Head 3
64 dim
Q3K3V3"] SPLIT --> HD["..."] SPLIT --> H12["Head 12
64 dim
Q12K12V12"] H1 --> A1["Attention1
64 dim"] H2 --> A2["Attention2
64 dim"] H3 --> A3["Attention3
64 dim"] HD --> AD["..."] H12 --> A12["Attention12
64 dim"] end subgraph "Concatenation" A1 --> CONCAT["Concatenate
12×64 = 768 dim"] A2 --> CONCAT A3 --> CONCAT AD --> CONCAT A12 --> CONCAT end subgraph "Output Projection" CONCAT --> WO["Linear
W_O"] WO --> OUTPUT["Output
768 dim"] end

Ein konkretes Beispiel mit verschiedenen Heads

Betrachten wir den Satz: "Die alte Frau, die im Park spazierte, fütterte die Tauben mit Brotkrumen."

Verschiedene Attention-Heads könnten unterschiedliche Muster lernen:

Head 1 - Subjekt-Verb-Beziehungen:

  • "Frau" ? "fütterte" (starke Attention)
  • "Frau" ? "spazierte" (mittlere Attention)
  • "Tauben" ? "fütterte" (als Objekt, schwächere Attention)

Head 2 - Adjektiv-Nomen-Bindungen:

  • "alte" ? "Frau" (sehr starke Attention)
  • "Die" ? "Frau" (starke Attention)
  • Andere Verbindungen sind schwach

Head 3 - Relativsatz-Struktur:

  • "die" (Relativpronomen) ? "Frau" (starke Attention)
  • "spazierte" ? "die" (Relativpronomen) (starke Attention)
  • "Park" ? "spazierte" (Ortsangabe, mittlere Attention)

Head 4 - Präpositionale Phrasen:

  • "im" ? "Park" (sehr starke Attention)
  • "mit" ? "Brotkrumen" (sehr starke Attention)
  • "fütterte" ? "mit" (Verbindung Verb-Präposition)

Head 5 - Langstrecken-Dependenzen:

  • "Brotkrumen" ? "fütterte" (trotz Distanz starke Attention)
  • "Tauben" ? "Park" (semantische Kohärenz)

Die anderen 7 Heads würden weitere Aspekte abdecken: temporale Beziehungen, semantische Ähnlichkeit, syntaktische Strukturen, etc.

Warum ist Multi-Head so mächtig?

1. Redundanz und Robustheit: Wenn ein Head einen Fehler macht, können andere kompensieren. Es ist wie ein Ensemble-Modell innerhalb des Modells.

2. Spezialisierung: Jeder Head kann sich auf eine spezifische linguistische Aufgabe spezialisieren, ohne mit anderen konkurrieren zu müssen.

3. Verschiedene Repräsentations-Subräume: Die 768-dimensionale Repräsentation wird in 12 verschiedene 64-dimensionale Subräume projiziert. Jeder Subraum kann andere Features kodieren.

Die Mathematik der Dimension-Aufteilung

Ein faszinierendes Detail: Obwohl wir die Dimensionen aufteilen, verlieren wir keine Ausdruckskraft. Hier ist warum:

Für einen einzelnen großen Head:

  • Q, K, V: jeweils 768 × 768 = 589.824 Parameter
  • Total: 3 × 589.824 = 1.769.472 Parameter

Für 12 kleine Heads:

  • Q, K, V pro Head: jeweils 768 × 64 = 49.152 Parameter
  • Pro Head total: 3 × 49.152 = 147.456 Parameter
  • Alle Heads: 12 × 147.456 = 1.769.472 Parameter

Gleiche Anzahl Parameter, aber viel mehr Flexibilität!

Die Transformer-Architektur: Schicht für Schicht zum Verständnis

Ein Transformer besteht nicht nur aus Attention. Die vollständige Architektur ist wie ein mehrstöckiges Gebäude, bei dem jede Etage die Information weiter verfeinert:

Embeddings: Von Wörtern zu Zahlen - Die Grundlage des Verstehens

Computer verstehen keine Wörter, nur Zahlen. Der erste Schritt ist daher, jedes Wort in einen hochdimensionalen Vektor zu übersetzen - eine Liste von Zahlen, die die "Bedeutung" des Wortes kodiert. Diese Vektoren werden während des Trainings gelernt, sodass ähnliche Wörter ähnliche Vektoren bekommen.

Token-Embeddings: Die semantische Repräsentation

Stell dir vor, wir wollen Wörter in einem 768-dimensionalen Raum positionieren. Jede Dimension könnte theoretisch etwas repräsentieren:

  • Dimension 1-50: Grammatikalische Eigenschaften (Verb, Nomen, Adjektiv...)
  • Dimension 51-150: Semantische Kategorien (Lebewesen, Objekt, Abstrakt...)
  • Dimension 151-250: Emotionale Valenz (positiv, negativ, neutral...)
  • ... und so weiter

In der Praxis lernt das Modell diese Zuordnungen selbst. Nach dem Training finden wir faszinierende Muster:

Beispiel semantische Ähnlichkeit:

Cosinus-Ähnlichkeit zwischen Embeddings:
"Katze" ? "Hund": 0.82     // Sehr ähnlich (beide Haustiere)
"Katze" ? "Tiger": 0.75     // Ähnlich (beide Katzen)
"Katze" ? "Auto": 0.12      // Sehr unterschiedlich
"König" ? "Königin": 0.85   // Sehr ähnlich

Beispiel Vektor-Arithmetik: Ein berühmtes Phänomen ist, dass man mit Embeddings rechnen kann:

Embedding("König") - Embedding("Mann") + Embedding("Frau") ˜ Embedding("Königin")
Embedding("Paris") - Embedding("Frankreich") + Embedding("Deutschland") ˜ Embedding("Berlin")

Positions-Embeddings: Die Ordnung im Chaos

Der Transformer verarbeitet alle Wörter parallel, verliert dabei aber die Information über die Reihenfolge. "Der Hund jagt die Katze" wäre ohne Positionsinformation dasselbe wie "Die Katze jagt den Hund". Die Positions-Embeddings kodieren, wo im Satz ein Wort steht.

Zwei Ansätze für Positions-Embeddings:

1. Gelernte Positions-Embeddings (GPT-2 Ansatz):

  • Jede Position von 0 bis 1023 hat ihren eigenen lernbaren 768-dimensionalen Vektor
  • Position 0 lernt "ich bin der Anfang"
  • Position 500 lernt "ich bin ungefähr in der Mitte"
  • Position 1023 lernt "ich bin am Ende der maximalen Sequenz"

2. Sinusoidale Positions-Embeddings (Original Transformer): Verwendet mathematische Funktionen:

PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

Der Vorteil: Funktioniert für beliebige Sequenzlängen, auch länger als im Training gesehen!

Die Kombination: Token + Position

Die finale Eingabe-Repräsentation ist einfach die Summe:

Input_Embedding = Token_Embedding + Position_Embedding

Beispiel mit konkreten (vereinfachten) Zahlen:

Satz: "Die Katze schläft"

Token_Emb("Die", pos=0)    = [0.2, -0.5, 0.8, ...]
Position_Emb(0)             = [0.1,  0.0, -0.2, ...]
Combined(0)                 = [0.3, -0.5, 0.6, ...]

Token_Emb("Katze", pos=1)  = [0.7, 0.3, -0.4, ...]
Position_Emb(1)            = [0.0, 0.1, 0.1, ...]
Combined(1)                = [0.7, 0.4, -0.3, ...]

Token_Emb("schläft", pos=2) = [-0.3, 0.6, 0.2, ...]
Position_Emb(2)             = [-0.1, 0.0, 0.2, ...]
Combined(2)                 = [-0.4, 0.6, 0.4, ...]

Diese kombinierten Vektoren enthalten jetzt sowohl die Information "was" (Token) als auch "wo" (Position)!

flowchart LR
    subgraph "Token Embeddings"
        T1["Die
0.2, -0.5, 0.8"] T2["Katze
0.7, 0.3, -0.4"] T3["schläft
-0.3, 0.6, 0.2"] end subgraph "Position Embeddings" P1["Pos 0
0.1, 0.0, -0.2"] P2["Pos 1
0.0, 0.1, 0.1"] P3["Pos 2
-0.1, 0.0, 0.2"] end T1 --> ADD1((+)) P1 --> ADD1 ADD1 --> C1["Combined 0
0.3, -0.5, 0.6"] T2 --> ADD2((+)) P2 --> ADD2 ADD2 --> C2["Combined 1
0.7, 0.4, -0.3"] T3 --> ADD3((+)) P3 --> ADD3 ADD3 --> C3["Combined 2
-0.4, 0.6, 0.4"]

Transformer-Blöcke: Die Verarbeitungseinheiten im Detail

Das Herzstück der Architektur sind die Transformer-Blöcke, die mehrfach hintereinander geschaltet werden. Jeder Block verfeinert die Repräsentation weiter. Bei GPT-2 durchläuft die Information 12 solcher Blöcke - wie eine Veredelungskette, bei der jeder Schritt das Verständnis vertieft.

Der Aufbau eines Transformer-Blocks

Ein einzelner Transformer-Block besteht aus mehreren Komponenten in einer spezifischen Reihenfolge:

Input ? LayerNorm ? Multi-Head Attention ? Residual Add ? 
        LayerNorm ? Feed-Forward Network ? Residual Add ? Output

Lass uns das an einem Beispiel durchgehen:

Eingabe: Repräsentation des Satzes "Die Sonne scheint hell"

Schritt 1 - Layer Normalization: Normalisiert die Eingabe für stabile Verarbeitung

Schritt 2 - Multi-Head Attention: Die Wörter tauschen Informationen aus

  • "scheint" sammelt Information von "Sonne" (Subjekt)
  • "hell" verstärkt seine Verbindung zu "scheint" (Adverb-Verb)
  • "Sonne" bekommt Kontext von "scheint hell" (was macht die Sonne?)

Schritt 3 - Residual Addition: Die originale Eingabe wird zur Attention-Ausgabe addiert

  • Verhindert, dass Information verloren geht
  • Ermöglicht Gradient Flow beim Training

Schritt 4 - Layer Normalization: Erneute Normalisierung vor FFN

Schritt 5 - Feed-Forward Network: Individuelle Verarbeitung jeder Position

Schritt 6 - Residual Addition: Wieder wird das Original addiert

Ausgabe: Verfeinerte Repräsentation, bereit für den nächsten Block

flowchart LR
    INPUT["Input
768 dim"] --> LN1["Layer
Norm"] LN1 --> MHA["Multi-Head
Attention
12 Heads"] MHA --> ADD1((+)) INPUT --> ADD1 ADD1 --> LN2["Layer
Norm"] LN2 --> FFN["Feed-Forward
Network
768->3072->768"] FFN --> ADD2((+)) ADD1 --> ADD2 ADD2 --> OUTPUT["Output
768 dim"]

Das Feed-Forward-Netzwerk (FFN) - Die individuelle Verarbeitung

Das FFN ist faszinierend, weil es nach der kollektiven Attention-Phase eine individuelle Verarbeitungsphase darstellt. Jede Position wird unabhängig verarbeitet - es gibt keinen Informationsaustausch zwischen Positionen.

Die Architektur des FFN:

Input (768 dim) ? Linear Layer ? (3072 dim) ? GELU Activation ? 
                  Linear Layer ? (768 dim) ? Output

Warum die 4× Expansion?

Die Expansion von 768 auf 3072 Dimensionen hat mehrere Gründe:

  1. Mehr Kapazität für komplexe Funktionen: Mit mehr Dimensionen kann das Netzwerk komplexere Transformationen lernen

  2. Informations-Bottleneck: Die Kompression zurück auf 768 zwingt das Modell, nur die wichtigsten Features zu behalten

  3. Nicht-lineare Transformation: Die GELU-Aktivierung in der Mitte ermöglicht nicht-lineare Mappings

Beispiel einer FFN-Transformation:

Angenommen, das Wort "Bank" kommt aus der Attention-Schicht mit gemischten Signalen (Finanzinstitut vs. Sitzbank). Das FFN könnte lernen:

  • In den ersten 1000 Dimensionen: Finanz-Features verstärken, wenn Kontext-Signale darauf hindeuten
  • In den mittleren 1000 Dimensionen: Physische-Objekt-Features verstärken bei anderen Signalen
  • In den letzten 1072 Dimensionen: Disambiguierungs-Features berechnen

Nach der Kompression hat "Bank" eine klarere Repräsentation basierend auf dem Kontext.

flowchart LR
    subgraph "Feed-Forward Network"
        INPUT["Input
768 dim"] --> L1["Linear Layer
W1: 768×3072"] L1 --> EXP["Expanded
3072 dim
4× larger"] EXP --> GELU["GELU
Activation"] GELU --> L2["Linear Layer
W2: 3072×768"] L2 --> OUTPUT["Output
768 dim"] end

GELU Activation - Die sanfte Nicht-Linearität

GELU (Gaussian Error Linear Unit) ist eine moderne Aktivierungsfunktion:

GELU(x) = x × F(x)

wobei F(x) die kumulative Normalverteilung ist.

Vergleich mit ReLU:

  • ReLU: max(0, x) - harte Grenze bei 0
  • GELU: Sanfter Übergang, kleine negative Werte werden nicht komplett auf 0 gesetzt

Beispielwerte:

GELU(-2.0) ˜ -0.045    // Kleine negative Ausgabe
GELU(-0.5) ˜ -0.154    // Größere negative Ausgabe
GELU(0.0) = 0.0        // Null bleibt Null
GELU(0.5) ˜ 0.346      // Positive Verstärkung
GELU(2.0) ˜ 1.955      // Fast linear für große positive Werte

Die Sanftheit von GELU führt zu besseren Gradienten beim Training und ermöglicht dem Modell, subtilere Muster zu lernen.

Normalisierung und Residual-Verbindungen: Die Stabilisatoren tiefer Netzwerke

Je tiefer ein neuronales Netzwerk, desto schwieriger wird das Training. Zwei Techniken machen Transformer stabil trainierbar, selbst mit 96 oder mehr Schichten:

Layer Normalization - Der Stabilisator

Layer Normalization sorgt dafür, dass die Werte in einem vernünftigen Bereich bleiben. Ohne Normalisierung könnten die Werte nach vielen Schichten explodieren oder gegen Null gehen.

Wie Layer Normalization funktioniert:

  1. Berechne Mittelwert und Varianz für jede Position:

    Eingabe: x = [2.5, -1.0, 8.0, 0.5]  // 4-dim Vektor
    Mittelwert µ = (2.5 - 1.0 + 8.0 + 0.5) / 4 = 2.5
    Varianz s² = ((0)² + (-3.5)² + (5.5)² + (-2)²) / 4 = 11.69
  2. Normalisiere die Werte:

    x_norm = (x - µ) / v(s² + e)
    x_norm = [0, -1.02, 1.61, -0.58]
  3. Skaliere und verschiebe mit lernbaren Parametern:

    output = ? × x_norm + ß

    ? und ß werden gelernt und erlauben dem Modell, die optimale Skalierung zu finden.

Beispiel im Transformer-Kontext:

Stell dir vor, nach 6 Transformer-Blöcken haben die Werte für "Katze" explodiert:

Vor LayerNorm: [1250.5, -890.2, 2100.8, ...]  // Riesige Werte!
Nach LayerNorm: [0.45, -0.82, 1.23, ...]       // Normalisiert

Das verhindert numerische Instabilität und ermöglicht tiefe Netzwerke.

Residual Connections - Die Informations-Autobahn

Residual Connections sind genial einfach: Sie addieren einfach die Eingabe zur Ausgabe.

Die Mathematik:

Ohne Residual: Output = F(Input)
Mit Residual:  Output = F(Input) + Input

Warum ist das so mächtig?

  1. Gradient Flow: Beim Backpropagation fließen Gradienten direkt durch die Addition

    ?Loss/?Input = ?Loss/?Output × (?F/?Input + 1)

    Die "+1" garantiert, dass immer ein Gradient durchkommt!

  2. Identitäts-Mapping: Im Worst Case kann F lernen, 0 auszugeben ? Output = Input

Beispiel mit konkreten Zahlen:

Block 1:
Input:           [0.5, -0.2, 0.8]
Attention-Output: [0.1, 0.3, -0.1]
Nach Residual:    [0.6, 0.1, 0.7]  // Addition!

Block 2:
Input:           [0.6, 0.1, 0.7]
FFN-Output:      [-0.2, 0.4, 0.2]
Nach Residual:    [0.4, 0.5, 0.9]  // Wieder Addition!

Das Ensemble-Effekt:

Mit Residual Connections hat ein 12-Block Transformer theoretisch 2^12 = 4096 verschiedene Pfade durch das Netzwerk! Jeder Pfad ist eine andere Kombination von "Schicht nutzen" vs. "Schicht überspringen".

flowchart TB
    subgraph "Without Residual Connection"
        I1["Input"] --> F1["Function
Layer"] F1 --> O1["Output"] end subgraph "With Residual Connection" I2["Input"] --> F2["Function
Layer"] F2 --> ADD((+)) I2 --> |"Skip
Connection"| ADD ADD --> O2["Output"] end subgraph "Gradient Flow" direction LR GRAD1["?Loss/?Output"] --> |"Through Function
Can vanish!"| GRAD2["?Loss/?Input"] GRAD3["?Loss/?Output"] --> |"Direct Path
Always flows!"| GRAD4["?Loss/?Input"] end

Das Zusammenspiel: Pre-Norm vs. Post-Norm

Es gibt zwei Varianten, wie LayerNorm und Residual kombiniert werden:

Post-Norm (Original Transformer):

Output = LayerNorm(F(Input) + Input)

Pre-Norm (GPT-2 und moderne Transformer):

Output = F(LayerNorm(Input)) + Input

Pre-Norm ist stabiler beim Training sehr tiefer Modelle, weil die Residual-Pfade komplett unnormalisiert bleiben.

Autoregressive Modelle: Die Kunst der sequenziellen Vorhersage

GPT (Generative Pre-trained Transformer) ist eine spezielle Art von Transformer - ein autoregressives Modell. "Autoregressiv" bedeutet, dass es Text Token für Token generiert, wobei jedes neue Token auf allen vorherigen basiert.

Das Prinzip der Autoregression

Stell dir vor, du schreibst eine Geschichte und kannst immer nur das nächste Wort sehen, nachdem du das aktuelle geschrieben hast. Genau so arbeitet GPT:

Start: "Der"
Schritt 1: "Der" ? Modell sagt vorher ? "Himmel"
Schritt 2: "Der Himmel" ? Modell sagt vorher ? "ist"
Schritt 3: "Der Himmel ist" ? Modell sagt vorher ? "blau"
Ergebnis: "Der Himmel ist blau"

Training durch Vorhersage: Teacher Forcing

Das Training funktioniert durch eine elegante Technik namens "Teacher Forcing". Statt das Modell Wort für Wort generieren zu lassen, zeigen wir ihm den kompletten Satz und lassen es an jeder Position das nächste Wort vorhersagen:

Trainingsbeispiel: "Die Katze jagt die Maus"

Position 0: [] ? Vorhersage: "Die"
Position 1: ["Die"] ? Vorhersage: "Katze"
Position 2: ["Die", "Katze"] ? Vorhersage: "jagt"
Position 3: ["Die", "Katze", "jagt"] ? Vorhersage: "die"
Position 4: ["Die", "Katze", "jagt", "die"] ? Vorhersage: "Maus"

Das Geniale: Wir können alle Positionen parallel trainieren! Das macht das Training extrem effizient.

Die kausale Maske: Keine Zeitreisen erlaubt!

Ein kritisches Detail: Das Modell darf nur in die Vergangenheit schauen, nicht in die Zukunft. Das wird durch eine kausale Maske erreicht.

Visualisierung der kausalen Maske für "Ich lese gern":

        Ich  lese  gern
Ich     ?    ?    ?
lese    ?    ?    ?
gern    ?    ?    ?
  • "Ich" kann nur sich selbst sehen
  • "lese" kann "Ich" und sich selbst sehen
  • "gern" kann alle vorherigen Wörter sehen

Implementierung der Maske:

Die Maske wird in der Attention-Berechnung angewendet:

1. Berechne Attention-Scores normal
2. Setze alle "verbotenen" Positionen auf -8
3. Wende Softmax an ? -8 wird zu 0
4. Resultat: Perfekte Blockierung der Zukunft!
graph TB
    subgraph "Causal Mask for 'Ich lese gern'"
        subgraph "Ich kann sehen:"
            I1["Ich: ?"]
            I2["lese: ?"]
            I3["gern: ?"]
        end
        subgraph "lese kann sehen:"
            L1["Ich: ?"]
            L2["lese: ?"]
            L3["gern: ?"]
        end
        subgraph "gern kann sehen:"
            G1["Ich: ?"]
            G2["lese: ?"]
            G3["gern: ?"]
        end
    end
    
    G3 --> APP["Apply to
Attention Scores"] subgraph "Effect on Scores" BEFORE["Before mask:
All positions visible"] AFTER["After mask:
Future = -8"] end APP --> BEFORE APP --> AFTER AFTER --> SOFT["Softmax"] SOFT --> RESULT["Future attention = 0
Past attention preserved"]

Wahrscheinlichkeitsverteilungen und Sampling

Das Modell gibt nicht einfach ein Wort aus, sondern eine Wahrscheinlichkeitsverteilung über alle möglichen nächsten Wörter.

Beispiel Ausgabe für "Der Himmel ist":

Token         Wahrscheinlichkeit
"blau"        35%
"grau"        20%
"bewölkt"     15%
"klar"        10%
"dunkel"      8%
"schön"       5%
... (50.000+ weitere Token)

Verschiedene Sampling-Strategien:

  1. Greedy Decoding: Wähle immer das wahrscheinlichste Wort

    • Deterministisch, aber oft repetitiv
    • "Der Himmel ist" ? "blau" (immer)
  2. Temperature Sampling: Skaliere die Logits vor Softmax

    logits = logits / temperature
    • temperature < 1.0: Schärfere Verteilung (konservativer)
    • temperature > 1.0: Flachere Verteilung (kreativer)
  3. Top-k Sampling: Wähle nur aus den k wahrscheinlichsten Wörtern

    • Top-5: Wähle zufällig aus ["blau", "grau", "bewölkt", "klar", "dunkel"]
  4. Top-p (Nucleus) Sampling: Wähle aus Wörtern, deren kumulative Wahrscheinlichkeit < p

    • p=0.9: Nimm so viele Wörter, bis 90% Wahrscheinlichkeit erreicht

Der Unterschied zu Encoder-Decoder Modellen

GPT ist ein Decoder-only Modell. Es gibt auch andere Architekturen:

Encoder-only (BERT):

  • Kann in beide Richtungen schauen
  • Gut für Verstehen, nicht für Generierung
  • Beispiel: Sentiment-Analyse

Encoder-Decoder (T5, Original Transformer):

  • Encoder liest kompletten Input
  • Decoder generiert Output autoregressiv
  • Beispiel: Übersetzung

Decoder-only (GPT):

  • Nur Autoregression, keine bidirektionale Attention
  • Universell einsetzbar durch cleveres Prompting
  • Beispiel: Alles von Chatbots bis Code-Generierung

Emergente Fähigkeiten durch Skalierung

Ein faszinierendes Phänomen: Obwohl GPT nur trainiert wird, das nächste Wort vorherzusagen, entwickelt es komplexe Fähigkeiten:

Bei kleinen Modellen (100M Parameter):

  • Grundlegende Grammatik
  • Einfache Faktenwiedergabe

Bei mittleren Modellen (1B Parameter):

  • Kontextverständnis
  • Einfache Schlussfolgerungen

Bei großen Modellen (100B+ Parameter):

  • In-Context Learning (lernt aus Beispielen im Prompt)
  • Chain-of-Thought Reasoning
  • Code-Generierung
  • Mathematisches Schließen

Diese Fähigkeiten wurden nie explizit trainiert - sie emergieren aus der simplen Aufgabe der Wortvorhersage!

Skalierung: Warum größer oft besser ist

Ein faszinierendes Phänomen bei Transformern ist, dass sie mit zunehmender Größe nicht nur mehr wissen, sondern qualitativ neue Fähigkeiten entwickeln. Ein kleines Modell kann vielleicht Grammatik und einfache Fakten lernen. Ein mittelgroßes beginnt, logische Zusammenhänge zu verstehen. Und die größten Modelle zeigen emergente Fähigkeiten wie Reasoning, Programmieren oder sogar Kreativität.

Die Skalierung erfolgt in drei Dimensionen:

Tiefe: Mehr Transformer-Blöcke bedeuten mehr Verarbeitungsschritte. Jede zusätzliche Schicht kann komplexere Muster erkennen.

Breite: Größere Hidden-Dimensionen bedeuten reichere Repräsentationen. Statt 768 Dimensionen nutzen große Modelle 4096 oder mehr.

Attention-Heads: Mehr Heads bedeuten mehr verschiedene Perspektiven auf die Daten.

GPT-2 Small, das wir implementieren, hat 12 Schichten, 768 Dimensionen und 12 Heads - insgesamt 124 Millionen Parameter. GPT-3 hat 96 Schichten, 12288 Dimensionen und 96 Heads - 175 Milliarden Parameter. Der Unterschied ist nicht nur quantitativ, sondern führt zu qualitativ neuen Fähigkeiten.

Warum Transformer die Welt eroberten

Der Erfolg der Transformer-Architektur hat mehrere Gründe:

Parallelisierbarkeit: Im Gegensatz zu RNNs können alle Positionen gleichzeitig verarbeitet werden. Das macht das Training auf modernen GPUs extrem effizient.

Skalierbarkeit: Die Architektur funktioniert von kleinen bis zu riesigen Modellen. Die gleichen Prinzipien, die bei 100 Millionen Parametern funktionieren, arbeiten auch bei 100 Milliarden.

Universalität: Transformer funktionieren nicht nur für Text. Mit minimalen Anpassungen verarbeiten sie Bilder (Vision Transformer), Audio (Whisper), und sogar multimodale Daten.

Transferlernen: Ein auf großen Textmengen vortrainierter Transformer kann für spezifische Aufgaben feinabgestimmt werden. Das Grundverständnis von Sprache muss nicht neu gelernt werden.

Die Grenzen und Herausforderungen

Trotz ihres Erfolgs haben Transformer auch Limitierungen:

Quadratische Komplexität: Die Attention-Berechnung skaliert quadratisch mit der Sequenzlänge. Bei 1000 Token sind das eine Million Berechnungen, bei 10000 Token schon 100 Millionen. Das limitiert die maximale Kontextlänge.

Ressourcenhunger: Große Modelle brauchen enorme Mengen an Rechenleistung und Speicher. Das Training von GPT-3 kostete Millionen von Dollar.

Blackbox-Natur: Obwohl wir die Architektur verstehen, ist schwer nachzuvollziehen, was genau in den Milliarden von Parametern kodiert ist.

Halluzinationen: Transformer können überzeugend klingende, aber faktisch falsche Informationen generieren. Sie verstehen nicht wirklich, was sie sagen - sie sind sehr gut darin, plausible Fortsetzungen zu generieren.

Das Gesamtbild: Wie alles zusammenkommt

Lass uns nun Schritt für Schritt durch den kompletten Datenfluss eines Transformers gehen, um zu verstehen, wie all diese Komponenten zusammenarbeiten:

Der vollständige Forward Pass

Eingabe: "Die Katze schläft"

Schritt 1: Tokenisierung

Text: "Die Katze schläft"
Token-IDs: [1245, 8934, 15632]

Schritt 2: Embeddings

Token-Embeddings + Positions-Embeddings = Input-Embeddings
Shape: (3, 768)  // 3 Token, 768 Dimensionen

Schritt 3: Durch 12 Transformer-Blöcke

Block 1:

  • LayerNorm ? Multi-Head Attention (12 Heads parallel)
  • Jeder Head berechnet Q, K, V und Attention
  • Residual Addition
  • LayerNorm ? FFN (768 ? 3072 ? 768)
  • Residual Addition
  • Output: Leicht verfeinerte Repräsentation

Block 2-11:

  • Gleicher Prozess, aber mit immer reicheren Repräsentationen
  • Frühe Blöcke: Syntaktische Muster
  • Mittlere Blöcke: Semantische Beziehungen
  • Späte Blöcke: Abstrakte Konzepte

Block 12:

  • Finale Verfeinerung
  • Output: Hochgradig kontextualisierte Repräsentationen

Schritt 4: Finale Layer Norm

Stabilisiert die Ausgabe der Blöcke

Schritt 5: Output-Projektion

Linear: 768 ? 50.257 (Vokabulargröße)
Für jedes Token: Wahrscheinlichkeit über alle möglichen nächsten Token

Schritt 6: Vorhersage

Nach "schläft" könnte kommen:
"." - 45%
"friedlich" - 15%
"tief" - 10%
...
flowchart TB
    subgraph "1. Tokenization"
        TEXT["Die Katze schläft"] --> TOKENS["Token IDs:
1245, 8934, 15632"] end subgraph "2. Embeddings" TOKENS --> EMB["Token Embeddings
+ Position Embeddings
3×768"] end subgraph "3. Transformer Blocks (×12)" EMB --> B1["Block 1
LN->MHA->Add->LN->FFN->Add"] B1 --> B2["Block 2
Syntactic Patterns"] B2 --> B3["Blocks 3-6
Semantic Relations"] B3 --> B4["Blocks 7-11
Abstract Concepts"] B4 --> B12["Block 12
Final Refinement"] end subgraph "4. Output Processing" B12 --> LNF["Final
Layer Norm"] LNF --> PROJ["Linear Projection
768 -> 50,257
(Vocab Size)"] end subgraph "5. Prediction" PROJ --> SOFT["Softmax"] SOFT --> PRED["Next Token Probabilities:
'.' 45%
'friedlich' 15%
'tief' 10%
..."] end

Ein konkretes Rechenbeispiel

Nehmen wir vereinfachte Zahlen für ein Mini-Transformer mit:

  • 4 Dimensionen
  • 2 Attention Heads
  • 2 Transformer Blöcke

Input: "Katze schläft"

Nach Embeddings:

"Katze": [0.5, -0.2, 0.8, 0.1]
"schläft": [0.3, 0.6, -0.4, 0.7]

Block 1, Head 1 Attention:

Q_Katze = [0.4, -0.1]    K_Katze = [0.3, 0.2]
Q_schläft = [0.2, 0.5]   K_schläft = [-0.1, 0.4]

Score(Katze?Katze) = 0.4×0.3 + (-0.1)×0.2 = 0.10
Score(Katze?schläft) = 0.4×(-0.1) + (-0.1)×0.4 = -0.08
Score(schläft?Katze) = 0.2×0.3 + 0.5×0.2 = 0.16
Score(schläft?schläft) = 0.2×(-0.1) + 0.5×0.4 = 0.18

Nach Softmax:
Attention(Katze) = [0.55, 0.45]  // Schaut auf beide
Attention(schläft) = [0.48, 0.52]  // Schaut leicht mehr auf sich

Nach allen Transformationen:

"Katze": [0.7, -0.3, 0.9, 0.2]  // Angereichert mit Kontext
"schläft": [0.4, 0.7, -0.2, 0.8]  // Weiß jetzt, wer schläft

Von der Theorie zur Praxis

Die Eleganz der Transformer-Architektur liegt in ihrer Einfachheit. Aus wenigen Grundbausteinen - Attention, Feed-Forward-Netzwerken, Normalisierung und Residual-Verbindungen - entsteht ein System, das menschenähnliche Sprachfähigkeiten entwickelt.

Was wir theoretisch besprochen haben:

  • Attention als Mechanismus für flexible Informationsaggregation
  • Multi-Head Attention für verschiedene Perspektiven
  • Feed-Forward Networks für individuelle Verarbeitung
  • Layer Norm und Residuals für stabiles, tiefes Training
  • Autoregression für sequenzielle Generierung
  • Embeddings als Brücke zwischen Symbolen und Vektoren

Im praktischen Teil werden wir diese Konzepte in PyTorch-Code umsetzen. Du wirst sehen, wie:

  • Die Attention-Formel Softmax(QK^T/vd)V zu echtem Code wird
  • Multi-Head Attention durch clevere Tensor-Reshaping implementiert wird
  • Die kausale Maske als einfache Dreiecksmatrix realisiert wird
  • Layer Norm und Residuals nur wenige Zeilen Code benötigen
  • Das Training durch Gradient Descent diese Architektur zum Leben erweckt

Die Transformer-Architektur ist mehr als nur ein technisches Konstrukt - sie ist ein Fenster in die Funktionsweise von Sprache und vielleicht sogar von Intelligenz selbst. Indem wir verstehen, wie Transformer funktionieren, verstehen wir besser, was es bedeutet, Muster zu erkennen, Kontext zu verstehen und Wissen zu repräsentieren.

Zusammenfassung: Die Essenz der Transformer

Die Transformer-Architektur löst das fundamentale Problem der Kontextverarbeitung in Sprache durch einen eleganten Mechanismus: Attention. Statt Wörter sequenziell zu verarbeiten, ermöglicht sie es jedem Wort, direkt mit allen anderen zu interagieren und relevante Informationen zu sammeln.

Die Architektur besteht aus gestapelten Blöcken, die jeweils Attention und Feed-Forward-Verarbeitung kombinieren. Stabilisiert durch Normalisierung und Residual-Verbindungen können diese Blöcke zu tiefen Netzwerken gestapelt werden, die immer komplexere Sprachmuster lernen.

Als autoregressive Modelle lernen Transformer wie GPT durch die simple Aufgabe der Wortvorhersage die gesamte Struktur menschlicher Sprache. Mit zunehmender Größe entwickeln sie emergente Fähigkeiten, die weit über simple Mustererkennung hinausgehen.

Die Kombination aus konzeptioneller Eleganz, praktischer Effizienz und beeindruckenden Ergebnissen hat Transformer zur dominanten Architektur in der KI gemacht. Sie sind der Motor hinter der aktuellen KI-Revolution und werden vermutlich noch lange die Grundlage für Fortschritte in der künstlichen Intelligenz bilden.

Im nächsten Teil werden wir diese theoretischen Konzepte in die Praxis umsetzen und Schritt für Schritt durch den Code gehen, der diese faszinierende Architektur zum Leben erweckt.