Transformers verstehen: die Architektur hinter modernem NLP
Was ist ein Transformer?
Die Transformer-Architektur, vorgestellt 2017 im Paper “Attention Is All You Need” von Vaswani et al., ersetzte rekurrente Netze durch ein vollständig aufmerksamkeitsbasiertes Design. Dieser Wechsel ermöglichte massive Parallelisierung beim Training und führte direkt zu Modellen wie BERT, GPT und modernen LLMs.
Das Problem mit RNNs
Rekurrente neuronale Netze verarbeiten Sequenzen Token für Token. Jeder Hidden State hängt vom vorherigen ab. Das bedeutet:
- Training ist inhärent sequenziell und schwer zu parallelisieren
- Gradienten verschwinden oder explodieren bei langen Sequenzen
- Langreichweitige Abhängigkeiten sind schwer zu erfassen
LSTMs und GRUs mildern diese Probleme, beseitigen sie aber nicht vollständig.
Self-Attention
Die zentrale Innovation des Transformers ist Self-Attention: Jedes Token der Eingabe kann direkt jedes andere Token berücksichtigen, unabhängig von dessen Position.
Für eine Eingabesequenz von Embeddings berechnen wir drei Projektionen:
Die Attention-Ausgabe lautet:
Die Skalierung mit verhindert, dass Skalarprodukte in hohen Dimensionen zu groß werden.
Multi-Head Attention
Statt nur eine Attention-Funktion auszuführen, verwendet der Transformer Attention-Heads parallel. Jeder lernt einen anderen Repräsentationsunterraum:
Dadurch kann das Modell gleichzeitig Informationen aus verschiedenen Positionen und Repräsentationsunterräumen berücksichtigen.
Positionskodierung
Da Self-Attention permutationsinvariant ist, muss Positionsinformation explizit hinzugefügt werden. Das ursprüngliche Paper verwendet feste sinusförmige Kodierungen:
Moderne Modelle wie BERT und RoPE-basierte Transformers verwenden stattdessen gelernte oder rotatorische Positions-Embeddings.
Die vollständige Architektur
Der Encoder stapelt identische Schichten, die jeweils enthalten:
- Multi-Head Self-Attention
- Positionsweise Feed-Forward-Netze
- Layer Normalization und Residualverbindungen um beide Blöcke
Der Decoder ergänzt eine dritte Unterschicht: Cross-Attention über die Encoder-Ausgabe.
Ein minimales Beispiel in PyTorch
import torch
import torch.nn as nn
class SelfAttention(nn.Module):
def __init__(self, d_model: int, n_heads: int):
super().__init__()
self.n_heads = n_heads
self.d_k = d_model // n_heads
self.qkv = nn.Linear(d_model, 3 * d_model)
self.out = nn.Linear(d_model, d_model)
def forward(self, x: torch.Tensor) -> torch.Tensor:
B, T, C = x.shape
qkv = self.qkv(x).reshape(B, T, 3, self.n_heads, self.d_k)
q, k, v = qkv.unbind(dim=2) # each (B, T, H, d_k)
q, k, v = [t.transpose(1, 2) for t in (q, k, v)] # (B, H, T, d_k)
scale = self.d_k ** -0.5
attn = (q @ k.transpose(-2, -1)) * scale
attn = attn.softmax(dim=-1)
out = (attn @ v).transpose(1, 2).reshape(B, T, C)
return self.out(out)
Wichtigste Erkenntnisse
- Transformers ersetzen sequenzielle Rekurrenz durch parallele Attention
- Self-Attention erfasst globale Abhängigkeiten in Zeit
- Multi-Head Attention lernt unterschiedliche Repräsentationsunterräume
- Positionskodierungen kompensieren die Permutationsinvarianz der Attention
- Die Architektur skaliert bemerkenswert gut mit Daten und Rechenleistung