Transformer-Architekturen: Wie Attention die moderne künstliche Intelligenz neu geprägt hat

In den letzten Jahren haben Transformer-Architekturen das Gebiet der künstlichen Intelligenz grundlegend verändert. Erstmals vorgestellt wurden sie von Vaswani und Kolleg:innen in der wegweisenden Arbeit „Attention Is All You Need“. Transformers brachten dabei einen neuen Ansatz für die Verarbeitung sequenzieller Daten, ohne auf Rekurrenz oder Convolution angewiesen zu sein. Was zunächst als Durchbruch im Bereich Natural Language Processing (NLP) begann, entwickelte sich schnell zu einem breit einsetzbaren Fundament für viele State-of-the-Art-Modelle – unter anderem in Bildklassifikation, Videoanalyse und maschineller Übersetzung.

Im NLP-Bereich ersetzten Transformer-Modelle frühere RNN- und LSTM-basierte Verfahren, da sie weitreichende Abhängigkeiten deutlich besser lernen können und gleichzeitig paralleles Training ermöglichen. Diese Kombination steigerte sowohl die Modellqualität als auch die Trainingseffizienz erheblich. Kurz darauf übertrug die Computer-Vision-Community das Prinzip auf visuelle Aufgaben, wodurch Architekturen wie Vision Transformers (ViTs) entstanden, die heute mit Convolutional Neural Networks (CNNs) konkurrieren – und sie häufig sogar übertreffen. Weil Transformers komplexe Muster in Sprache, Bildern und darüber hinaus modellieren können, sind sie zum Kern vieler leistungsstarker KI-Systeme geworden, darunter GPT, BERT, DALL·E und zahlreiche weitere.

In diesem Artikel entwickelst du nicht nur ein fundiertes Verständnis dafür, wie Transformers funktionieren und warum sie so effektiv sind – du bekommst außerdem praktische Erfahrung, indem du eigene Transformer-basierte Modelle erstellst.

Kernpunkte

  • Transformers wurden 2017 von Vaswani et al. eingeführt und ersetzten rekurrente sowie convolutionale Bausteine durch einen reinen, attention-basierten Mechanismus.
  • Durch Self-Attention haben Transformers die KI – insbesondere NLP und Computer Vision – nachhaltig verändert.
  • Sie integrieren Informationen zur Reihenfolge in Sequenzen, sodass Eingaben ohne Rekurrenz verarbeitet werden können.
  • Mehrere Attention-Heads arbeiten parallel und helfen dem Modell, unterschiedliche Beziehungen zwischen Tokens zu lernen.
  • Der Encoder verarbeitet die Eingabesequenz, während der Decoder die Ausgabesequenz erzeugt – verbunden über Attention-Schichten.
  • Sie vermeiden die sequentiellen Einschränkungen von RNNs und ermöglichen dadurch schnelleres Training auf GPUs.
  • GPU-Beschleunigung ist zentral für effizientes Transformer-Training, da sie die Rechenzeit deutlich reduziert.
  • Die Batch-Size-Optimierung hilft, Speicherverbrauch und Konvergenzgeschwindigkeit auszubalancieren.

Voraussetzungen

Bevor du fortfährst, stelle sicher, dass du Folgendes mitbringst:

  • Grundlegendes Wissen in Python-Programmierung.
  • Vertrautheit mit Deep-Learning-Konzepten wie neuronalen Netzen, Attention und Embeddings.
  • Zugriff auf eine GPU für schnelleres Training.

Was sind Transformers?

Bevor wir in Transformers und ihre Architektur einsteigen, ist es sinnvoll, zunächst Word Embeddings zu verstehen – und warum sie so wichtig sind.

Word Embeddings und ihre Bedeutung

Word Embeddings wandeln jedes Token (Wort oder Subword) in einen Vektor fester Länge um, den ein Modell verarbeiten kann. Das ist notwendig, weil neuronale Netze mit Zahlen arbeiten – nicht mit Rohtext. Außerdem platzieren Embeddings semantisch verwandte Wörter näher zueinander im Vektorraum (zum Beispiel liegen king und queen typischerweise nah beieinander).

Praktisch gesehen beschreibt Word Embedding Wörter als dichte Zahlenvektoren in einem hochdimensionalen Raum (z. B. 300D, 512D oder 1024D), wobei:

  • ähnliche Wörter in diesem Raum nah beieinander liegen,
  • unähnliche Wörter deutlich weiter auseinander liegen,
  • die Geometrie (Abstände und Winkel) semantische und syntaktische Beziehungen widerspiegelt.

Beispiele sind:

“king” → [0.25, -0.88, 0.13, …] “queen” → [0.24, -0.80, 0.11, …] “apple” → [-0.72, 0.13, 0.55, …]

In diesem Beispiel liegen king und queen deutlich näher beieinander als eines der beiden Wörter zu apple. Diese Vektoren sind nicht manuell definiert, sondern werden während des Trainings gelernt.

Zu Beginn erhält jedes Wort zunächst einen zufälligen Vektor. Während des Trainings (etwa bei Language Modeling oder Übersetzung) werden diese Vektoren durch das Netzwerk so angepasst, dass Wörter aus ähnlichen Kontexten ähnliche Repräsentationen erhalten und für die Aufgabe sinnvolle Cluster entstehen.

Um das Zusammenspiel von Word Embeddings besser zu verstehen, wird Leser:innen dringend empfohlen, den ausführlichen Artikel What Are Vector Databases? Why Are They So Important? zu lesen.

In einem Transformer sind Embeddings immer der erste Schritt.

Von Word Embeddings zu kontextuellen Embeddings

Nehmen wir das Wort “bank”. Das Token “bank” hätte bei einem statischen Embedding immer denselben Vektor – egal ob “river bank” oder “money bank” gemeint ist. Dadurch kann ein statisches Embedding hier zu kurz greifen. Deshalb arbeiten Transformer-Modelle mit kontextuellen (dynamischen) Embeddings. Diese Vektoren verändern sich abhängig von den umgebenden Wörtern.

„I sat by the bank of the river“ → embedding shifts toward nature meaning.
„I deposited money at the bank“ → embedding shifts toward finance meaning.

Damit unterscheidet sich ein kontextuelles Embedding je nach Satzumfeld.

Positional Encoding: Wie das Modell Reihenfolgen erkennt

Transformers verarbeiten Tokens parallel. Dadurch benötigen sie explizite Positionsinformationen – im Gegensatz zu RNNs, die Tokens nacheinander abarbeiten. Dieses Problem wird durch Positional Encoding gelöst: Ein positionsabhängiger Vektor wird zum Word Embedding addiert, damit das Modell die Token-Reihenfolge erkennen kann.

Ein häufiger Ansatz ist sinusförmiges Positional Encoding. Für Position pos und Dimension i gilt:

PE(pos, 2i) = sin(pos / 10000^{2i/d})
PE(pos, 2i+1) = cos(pos / 10000^{2i/d})

So entstehen für jede Position eindeutige, kontinuierlich variierende Signale. Alternativ können auch gelernte Position-Embeddings genutzt werden.

Mit diesen Informationen kann das Modell zwischen “das ist das 3. Token” und “das ist das 7. Token” unterscheiden – was entscheidend für Bedeutung ist, etwa wenn Subjekt und Verb in einer bestimmten Reihenfolge stehen.

Transformer-Architektur: Detailliert, Schritt für Schritt

image

Im Diagramm oben besteht die Architektur aus zwei zentralen Teilen: einem Encoder-Stack (links) und einem Decoder-Stack (rechts). Der Encoder wandelt Eingabetokens in reichhaltige kontextuelle Embeddings um, während der Decoder die Ausgabetokens erzeugt. Beide Stacks werden gebildet, indem dieselbe Schicht N-mal wiederholt wird (z. B. 6, 12, 24 usw.), um das Modell tiefer zu machen.

input tokens → input embedding + positional encoding → encoder layers (self-attention + FFN) → encoder outputs decoder receives shifted output embeddings + pos encoding → masked self-attention → encoder–decoder attention → FFN → linear → softmax → token probabilities.

Input Embedding + Positional Encoding

Im Transformer ist das Input Embedding der Mechanismus, der Wörter oder Tokens in Zahlen überführt, sodass das Modell sie verarbeiten kann. Man kann es als Übersetzung in eine Darstellung verstehen, die das Modell „spricht“.

Embeddings allein verraten jedoch nicht, an welcher Stelle ein Wort im Satz steht. Genau hier setzt Positional Encoding an: Es fügt den Embeddings spezielle numerische Muster hinzu, die Positionen (erstes, zweites, drittes Token usw.) darstellen. In Kombination kennt das Modell sowohl die Bedeutung der Wörter als auch ihre Position – entscheidend für Kontext und Reihenfolgenverständnis.

Zwei verbreitete Methoden sind:

  • Sinusoidal (fest): PE(pos,2i)=sin(pos/10000^{2i/d}), PE(pos,2i+1)=cos(…).
  • Learned: trainable position embeddings.

Der Input für die erste Encoder-Schicht ist die Summe aus Token-Embedding und Positional Encoding.

Encoder-Layer (ein wiederholter Block)

Ein Encoder-Layer ist ein zentrales Bauteil eines Transformers und wird mehrfach gestapelt (z. B. sechs Mal im Original). Jede Encoder-Schicht besitzt zwei wesentliche Komponenten.

Die erste ist Multi-Head Self-Attention. Sie erlaubt es jedem Token, auf alle anderen Tokens zu „schauen“. Dadurch kann das Modell ermitteln, welche Tokens für die Bedeutung des aktuellen Tokens besonders wichtig sind – und Beziehungen wie “wer hat was wem getan” über die gesamte Sequenz hinweg erfassen.

Die zweite Komponente ist ein positionsweises Feed-Forward-Netzwerk, das jede Token-Repräsentation unabhängig verarbeitet, um Merkmale weiter zu transformieren und zu verfeinern. Beide Teile werden durch Residual Connections (Shortcuts, die den ursprünglichen Input zum Output addieren) und Layer Normalization (zur Stabilisierung des Trainings) ergänzt. Durch das Stapeln mehrerer Encoder-Layer entstehen zunehmend reichhaltige, kontextbewusste Repräsentationen des Input-Texts.

Decoder-Layer (ein wiederholter Block)

Auch der Decoder besteht aus mehreren gestapelten Blöcken. Er enthält drei Hauptbestandteile. Zuerst kommt Masked Multi-Head Self-Attention. Dabei darf jedes Token nur auf sich selbst und auf frühere Tokens achten, indem ein Look-Ahead-Mask eingesetzt wird. Das verhindert Zugriff auf zukünftige Tokens und sorgt dafür, dass Text schrittweise generiert wird.

Als Nächstes folgt Encoder–Decoder (Cross) Attention. Dabei stammen die Queries aus der vorherigen Decoder-Schicht, während Keys und Values aus dem Encoder-Output kommen. So kann der Decoder beim Erzeugen jedes Tokens gezielt auf die relevantesten Teile der Eingabe fokussieren.

Zum Schluss gibt es ein positionsweises Feed-Forward-Netzwerk, das die Token-Repräsentationen weiter verfeinert.

Nach jeder Sublayer werden Residual Connections angewendet, indem der Input wieder addiert wird, und LayerNorm stabilisiert das Training. Sobald der letzte Decoder-Layer fertig ist, werden die Outputs über eine lineare Schicht und Softmax in Wahrscheinlichkeitsverteilungen über das Vokabular umgewandelt.

image

Attention: Die Kernmathematik (kompakt)

Lineare Projektionen (pro Head)

Ausgehend von Eingabe-Embeddings X (Form: seq_len × d_model) projiziert das Modell diese in drei unterschiedliche Räume:

eq

wobei WQ, WK, WV gelernte Gewichtsmatrizen mit der Form (dmodel×dk) sind.

Diese Projektionen ermöglichen dem Modell zu lernen, wie es Queries bildet, Vergleiche berechnet und die relevantesten Informationen gezielt abruft.

Scaled Dot-Product Attention

Scaled Dot-Product Attention startet damit, die Ähnlichkeit zwischen jeder Query und allen Keys zu berechnen. Dadurch entsteht eine Score-Matrix, die die Relevanz über die Sequenz hinweg widerspiegelt.

Compute similarity scores between each query and all keys:

eq

Anschließend werden die Scores durch dk skaliert, damit sie nicht zu groß werden. Zu große Werte können Softmax instabil machen.

Scale by dk​​ to avoid extremely large values that can make softmax unstable:

eq

Danach wird Softmax über die Key-Dimension angewendet, um die Scores in Attention-Gewichte zu überführen.

Apply softmax across the key dimension to turn scores into attention weights:

eq

Zum Schluss werden die Attention-Gewichte mit V multipliziert, wodurch eine gewichtete Summe der Value-Vektoren entsteht.

Multiply by V to get a weighted sum of value vectors.

Multi-Head Attention (MHA)

Multi-Head Attention erweitert Scaled Dot-Product Attention, indem derselbe Prozess mehrfach parallel ausgeführt wird. Jede Wiederholung nutzt dabei eigene Parameter, sodass das Modell gleichzeitig unterschiedliche Beziehungstypen lernen kann.

Repeat the above process h times in parallel with different parameter sets,

eq

Jeder Head konzentriert sich auf andere Beziehungen oder Merkmale innerhalb der Sequenz.

Each head focuses on different relationships or features in the sequence.

Nachdem alle Heads berechnet wurden, werden deren Outputs zusammengeführt (concat) und anschließend mit WO zurück in den dmodel-Raum projiziert.

Concatenate all heads’ outputs and project them back to dmodel space with WO​.

Masked Attention

Masked Attention wird verwendet, um das Modell daran zu hindern, auf bestimmte Positionen zu achten. Ziel ist es, die Nutzung von Informationen zu verhindern, die in einer bestimmten Situation nicht zugänglich sein sollen.

Purpose: Prevent the model from looking at certain positions.

  • Causal mask (future masking): In autoregressive settings, this blocks attention to tokens that appear after the current position.
  • Padding mask: This ensures padded tokens in variable-length batches are ignored.

Die Maske wird vor dem Softmax angewendet, indem ein sehr großer negativer Wert (z. B. −∞) zu den nicht erlaubten Positionen in der Score-Matrix addiert wird.

How: Before softmax, add a large negative number (e.g., −∞) to the unwanted positions in the score matrix:

eq

Hier enthält M den Wert 0 für erlaubte Positionen und −∞ für blockierte Positionen.

where M has 0s for allowed positions and −∞ for blocked ones.

Nach dem Softmax haben diese blockierten Positionen nahezu Null-Wahrscheinlichkeit.

After softmax, these positions have near-zero probability.

Residuals, LayerNorm und Stabilität

In einem Transformer sind Residual Connections und Layer Normalization entscheidend, um Training stabil und effizient zu halten. Eine Residual Connection addiert den Input einer Sublayer wieder zum Output. Dadurch bleiben ursprüngliche Informationen erhalten und Gradienten können leichter rückwärts durch das Netzwerk fließen, was das Risiko von verschwindenden oder explodierenden Gradienten reduziert.

Layer Normalization passt anschließend den kombinierten Output an, indem Werte so skaliert und verschoben werden, dass ihre Verteilung stabil bleibt. Das macht das Lernen in der Regel gleichmäßiger und schneller.

Im ursprünglichen Transformer erfolgt die Reihenfolge Add → LayerNorm (post-norm), also Normalisierung nach der Residual-Addition. Viele moderne Modelle nutzen dagegen pre-norm (LayerNorm → sublayer → Add), was besonders bei sehr tiefen Transformers oft zuverlässiger ist, weil es instabile Gradienten verringern kann.

Zusammen verhindern diese Techniken, dass das Netzwerk nützliche Inputs „vergisst“, und sorgen gleichzeitig für konsistente Aktivierungen über die Schichten hinweg.

Output Projection und Loss

Die finalen Decoder-Vektoren werden über eine lineare Projektion der Form (d_model, vocab_size) transformiert und anschließend durch Softmax in Token-Wahrscheinlichkeiten umgewandelt.

Beim Training wird häufig Teacher Forcing verwendet: Das echte vorherige Token wird dem Decoder zugeführt, während der Cross-Entropy-Loss zwischen der vorhergesagten Verteilung und dem korrekten nächsten Token berechnet wird.

Eine weitere verbreitete Technik ist Weight Tying, bei der die Input-Embedding-Matrix und die Output-Projektionsgewichte (transponiert) geteilt werden. Das reduziert die Anzahl der Parameter und kann die Konvergenz verbessern.

Masks in der Praxis

In Transformer-Systemen steuern Masks, welche Tokens einander in der Attention „sehen“ dürfen. Eine Padding Mask wird eingesetzt, wenn Sequenzen in einem Batch unterschiedliche Längen haben. Sie verhindert, dass das Modell auf Padding-Tokens achtet, die nur zur Vereinheitlichung eingefügt wurden. Eine Causal Mask (auch Look-Ahead Mask) wird im Decoder genutzt, damit Tokens nicht auf zukünftige Tokens schauen können. Dadurch wird Schritt-für-Schritt-Vorhersage erzwungen und verhindert, dass das Modell „schummelt“, indem es vorausblickt.

Wichtige Hyperparameter und typische Größen

Mehrere Hyperparameter bestimmen Aufbau und Kapazität eines Transformers. Diese Einstellungen beeinflussen direkt Rechenaufwand, Speicherverbrauch und die Repräsentationsfähigkeit.

  • d_model (Embedding + Hidden Dim): zum Beispiel 512, 768, 1024, 2048…
  • num_heads h: oft 8 oder 16; die Dimension pro Head = d_model / h.
  • d_ff (FFN Hidden Dim): typischerweise 4 × d_model (z. B. 2048 bei d_model=512).
  • Depth N: Anzahl gestapelter Layer (6, 12, 24 usw.).

Diese Entscheidungen wirken sich auf Compute, Memory und Representational Power aus.

Warum GPUs für Transformer-Training verwenden?

Das Training von Transformer-Modellen – ob für NLP, Computer Vision oder multimodale Systeme – erfordert enorme Rechenleistung. Transformers nutzen Multi-Head Attention, große Matrixmultiplikationen und tiefe Layer-Stacks, die Millionen oder sogar Milliarden von Parametern gleichzeitig verarbeiten müssen. Auf CPUs können solche Berechnungen Tage oder sogar Wochen dauern, was Entwicklung und Iteration extrem verlangsamt.

GPUs (Graphics Processing Units) sind für parallele Hochdurchsatzberechnungen optimiert und damit ideal zur Beschleunigung von Transformer-Training. Während CPUs primär für sequentielle Verarbeitung ausgelegt sind, verfügen GPUs über tausende kleinere Kerne, die viele Operationen gleichzeitig ausführen können. Dadurch verkürzt sich die Trainingszeit massiv: Aufgaben, die auf einer CPU Wochen dauern könnten, sind auf GPUs oft in Stunden oder wenigen Tagen machbar. Für Entwickler:innen und Forschende bedeutet das schnellere Experimente, kürzere Iterationszyklen und die Möglichkeit, größere Modelle ohne große Verzögerungen zu trainieren.

GPU Virtual Machines vereinfachen den Zugang zu GPU-Compute, weil sie On-Demand-Instanzen bereitstellen, ohne dass komplexe Infrastruktur betrieben werden muss. So lässt sich eine AI/ML-Umgebung in kurzer Zeit aufsetzen und man zahlt nur für die tatsächlich genutzten Ressourcen.

Hands-On: Ein Transformer-Modell trainieren

Als nächstes erstellen wir einen leichten Transformer-Textklassifikator mit dem Kaggle-Datensatz “Disaster Tweets”. Dieses Beispiel verwendet das Dataset “Real or Not? NLP with Disaster Tweets” (leicht auf Kaggle zu finden). Der Datensatz enthält eine Textspalte sowie ein binäres Target (0/1). Du kannst stattdessen auch ein ähnliches CSV verwenden.

Bevor du startest

  • Download train.csv from the Kaggle dataset and place it in your working directory.
  • This script automatically splits train/val.
  • Run the script (or paste it into Jupyter).
  • Here we are using Python’s built-in re for tokenization.

Minimale Abhängigkeiten

pip install torch pandas scikit-learn numpy

Transformer-Training-Code

import re
import math
import random
import time
import os
import numpy as np
import pandas as pd
from collections import Counter
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, f1_score

import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader

# ====== Config ======
DATA_PATH = "./train.csv"  # Kaggle "Real or Not? NLP with Disaster Tweets"
MAX_LEN = 50
MIN_FREQ = 2
BATCH_SIZE = 64
EMBED_DIM = 128
FF_DIM = 256
N_HEADS = 4
N_LAYERS = 2
DROPOUT = 0.1
LR = 3e-4
EPOCHS = 5
SEED = 42
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

random.seed(SEED)
np.random.seed(SEED)
torch.manual_seed(SEED)

# ====== Load Dataset ======
df = pd.read_csv(DATA_PATH)[["text", "target"]].dropna()
train_df, val_df = train_test_split(df, test_size=0.15, stratify=df["target"], random_state=SEED)

# ====== Tokenizer & Vocab ======
def simple_tokenizer(text):
    text = text.lower()
    return re.findall(r"\b\w+\b", text)

counter = Counter()
for text in train_df["text"]:
    counter.update(simple_tokenizer(text))

# Special tokens
PAD_TOKEN = ""
UNK_TOKEN = ""
BOS_TOKEN = ""
EOS_TOKEN = ""

itos = [PAD_TOKEN, UNK_TOKEN, BOS_TOKEN, EOS_TOKEN] + [w for w, c in counter.items() if c >= MIN_FREQ]
stoi = {tok: i for i, tok in enumerate(itos)}

PAD_IDX = stoi[PAD_TOKEN]
BOS_IDX = stoi[BOS_TOKEN]
EOS_IDX = stoi[EOS_TOKEN]

def text_to_ids(text):
    tokens = [BOS_TOKEN] + simple_tokenizer(text)[:MAX_LEN-2] + [EOS_TOKEN]
    ids = [stoi.get(tok, stoi[UNK_TOKEN]) for tok in tokens]
    ids = ids + [PAD_IDX] * (MAX_LEN - len(ids)) if len(ids) < MAX_LEN else ids[:MAX_LEN]
    return ids

# ====== Dataset Class ======
class TextDataset(Dataset):
    def __init__(self, df):
        self.texts = df["text"].tolist()
        self.labels = df["target"].astype(int).tolist()
    def __len__(self):
        return len(self.texts)
    def __getitem__(self, idx):
        ids = torch.tensor(text_to_ids(self.texts[idx]), dtype=torch.long)
        label = torch.tensor(self.labels[idx], dtype=torch.long)
        return ids, label

train_ds = TextDataset(train_df)
val_ds = TextDataset(val_df)
train_loader = DataLoader(train_ds, batch_size=BATCH_SIZE, shuffle=True)
val_loader = DataLoader(val_ds, batch_size=BATCH_SIZE)

# ====== Positional Encoding ======
class PositionalEncoding(nn.Module):
    def __init__(self, d_model, max_len=5000):
        super().__init__()
        pe = torch.zeros(max_len, d_model)
        position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
        div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
        pe[:, 0::2] = torch.sin(position * div_term)
        pe[:, 1::2] = torch.cos(position * div_term)
        self.register_buffer("pe", pe.unsqueeze(0))
    def forward(self, x):
        return x + self.pe[:, :x.size(1), :]

# ====== Model ======
class TransformerClassifier(nn.Module):
    def __init__(self, vocab_size, embed_dim, num_heads, ff_dim, num_layers, num_classes, pad_idx, dropout=0.1):
        super().__init__()
        self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=pad_idx)
        self.pos_encoding = PositionalEncoding(embed_dim)
        encoder_layer = nn.TransformerEncoderLayer(d_model=embed_dim, nhead=num_heads, dim_feedforward=ff_dim, dropout=dropout, batch_first=True)
        self.encoder = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
        self.fc = nn.Linear(embed_dim, num_classes)
    def forward(self, ids):
        mask = (ids == PAD_IDX)
        x = self.embedding(ids)
        x = self.pos_encoding(x)
        x = self.encoder(x, src_key_padding_mask=mask)
        x = x[:, 0, :]  # take BOS token
        return self.fc(x)

model = TransformerClassifier(len(itos), EMBED_DIM, N_HEADS, FF_DIM, N_LAYERS, 2, PAD_IDX, DROPOUT).to(DEVICE)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.AdamW(model.parameters(), lr=LR)

# ====== Training Loop ======
for epoch in range(1, EPOCHS+1):
    model.train()
    train_loss = 0
    for ids, labels in train_loader:
        ids, labels = ids.to(DEVICE), labels.to(DEVICE)
        optimizer.zero_grad()
        output = model(ids)
        loss = criterion(output, labels)
        loss.backward()
        optimizer.step()
        train_loss += loss.item()
    
    # Validation
    model.eval()
    val_loss, preds_all, labels_all = 0, [], []
    with torch.no_grad():
        for ids, labels in val_loader:
            ids, labels = ids.to(DEVICE), labels.to(DEVICE)
            output = model(ids)
            loss = criterion(output, labels)
            val_loss += loss.item()
            preds_all.extend(torch.argmax(output, dim=1).cpu().numpy())
            labels_all.extend(labels.cpu().numpy())
    
    acc = accuracy_score(labels_all, preds_all)
    f1 = f1_score(labels_all, preds_all, average="macro")
    print(f"Epoch {epoch}: Train Loss={train_loss/len(train_loader):.4f}, Val Loss={val_loss/len(val_loader):.4f}, Acc={acc:.4f}, F1={f1:.4f}")

print("Training complete.")

# ====== Predict for a few random samples ======
model.eval()
sample_indices = random.sample(range(len(val_df)), 5)
for idx in sample_indices:
    text = val_df.iloc[idx]["text"]
    true_label = val_df.iloc[idx]["target"]
    ids = torch.tensor(text_to_ids(text), dtype=torch.long).unsqueeze(0).to(DEVICE)
    with torch.no_grad():
        pred = torch.argmax(model(ids), dim=1).item()
    print(f"Text: {text[:80]}...")  # print first 80 chars
    print(f"True: {true_label}, Pred: {pred}")
    print("-" * 50)

# ====== Save all validation predictions ======
all_preds = []
model.eval()
with torch.no_grad():
    for text in val_df["text"]:
        ids = torch.tensor(text_to_ids(text), dtype=torch.long).unsqueeze(0).to(DEVICE)
        pred = torch.argmax(model(ids), dim=1).item()
        all_preds.append(pred)

val_df_with_preds = val_df.copy()
val_df_with_preds["predicted"] = all_preds
val_df_with_preds.to_csv("validation_predictions.csv", index=False)
print("Saved validation predictions to validation_predictions.csv")

Wichtige Erkenntnisse aus dem Transformer-Training-Code

Schauen wir uns einige zentrale Punkte aus dem Transformer-Training-Code an:

  • Datensatzwahl – Wenn du gerade erst anfängst, empfiehlt es sich, ein leichtes und einfach herunterladbares Dataset zu verwenden (z. B. von Kaggle oder Hugging Face Datasets), um Konflikte durch Abhängigkeiten zu vermeiden.
  • Tokenisierung – Nutze einen Tokenizer (z. B. aus der transformers-Bibliothek), um Text in numerische Tokens umzuwandeln, die das Modell verarbeiten kann.
  • Modellauswahl – Du kannst ein kleines, vortrainiertes Transformer-Modell wie distilbert/distilbert-base-uncased auswählen, um Trainingszeit zu reduzieren und geringere Ressourcenanforderungen zu haben.
  • DataLoader-Setup – Der DataLoader sorgt für effizientes Batching und Shuffling und unterstützt sowohl Training als auch Evaluation.
  • Trainingsschleife – Eine typische Schleife umfasst Forward Pass, Loss-Berechnung (z. B. Cross-Entropy), Backpropagation und den Optimizer-Step.
  • GPU-Nutzung – Wenn du Modell und Daten per .to(device) auf die GPU verschiebst, wird das Training deutlich schneller.
  • Early Stopping – Early Stopping kann Overfitting verhindern, indem das Training abgebrochen wird, sobald sich der Validation-Loss nicht mehr verbessert.
  • Logging – Tools wie tqdm liefern Fortschrittsbalken, während wandb oder tensorboard detailliertes Experiment-Tracking ermöglichen.

FAQs

1. Was sind Transformers, und warum sind sie so populär?

Transformers sind Deep-Learning-Architekturen, die Self-Attention verwenden, um Eingaben parallel zu verarbeiten, statt sie wie RNNs sequenziell abzuarbeiten. Dadurch sind sie effizient und gut skalierbar, was große Fortschritte in Aufgaben wie Übersetzung, Zusammenfassung und Bildklassifikation ermöglicht hat. Ihre Fähigkeit, lange Abhängigkeiten zu lernen und große Datensätze zu verarbeiten, hat sie zu einem Standardansatz in der modernen KI-Forschung gemacht.

2. Was ist Mixed-Precision-Training, und wie hilft es?

Mixed-Precision-Training nutzt sowohl 16-Bit- als auch 32-Bit-Fließkommazahlen während des Trainings. Dadurch sinkt der Speicherbedarf und Berechnungen laufen schneller ab, während die Genauigkeit meist hoch bleibt – insbesondere auf GPUs mit Tensor Cores, die für FP16 optimiert sind.

3. Wie wähle ich die passende Batch Size für Transformer-Training?

Die Batch Size beeinflusst Trainingsgeschwindigkeit, Stabilität, Konvergenzverhalten und Speicherverbrauch. Kleinere Batches benötigen weniger Speicher, können aber zu stärkerem Rauschen in der Optimierung führen. Größere Batches sind stabiler, benötigen jedoch mehr Speicher. In der Praxis ist es oft sinnvoll, verschiedene Größen auf der eigenen Hardware zu testen.

4. Kann ich einen Transformer von Grund auf trainieren, oder sollte ich vortrainierte Modelle nutzen?

Training von Grund auf erfordert in der Regel große Datensätze und erhebliche Ressourcen. Die meisten Anwender:innen starten mit einem vortrainierten Transformer und fine-tunen ihn für den eigenen Anwendungsfall. Frameworks wie Hugging Face transformers vereinfachen diesen Prozess erheblich.

Fazit und nächste Schritte

In dieser guid haben wir die zentralen Konzepte eines Transformer-Modells betrachtet, die Architektur verstanden und einige der wichtigsten Grundideen beleuchtet. Zusätzlich haben wir die Kernschritte kennengelernt, um ein Modell von Grund auf zu trainieren – inklusive Datenvorverarbeitung, Definition der Modellarchitektur und Inferenz mit dem Modell.

Auch wenn wir für die Demonstration einen relativ kleinen und gut handhabbaren Datensatz genutzt haben, lassen sich dieselben Prinzipien ebenso auf deutlich größere Aufgaben übertragen. Für produktive Workloads wird effizientes Skalieren des Trainings entscheidend, und Cloud-GPU-Plattformen können den Prozess deutlich beschleunigen.

Nächste Schritte

  • Experimentiere mit größeren Datensätzen von Kaggle oder Hugging Face Datasets.
  • Teste das Fine-Tuning eines vortrainierten Transformers für eine domänenspezifische Aufgabe.
  • Implementiere fortgeschrittene Optimierungen wie Learning-Rate-Warm-up, Weight Decay oder Gradient Clipping.
  • Wende zusätzliche Optimierungen wie Learning-Rate-Warm-up, Weight Decay oder Gradient Clipping an.

Wenn du solides Modelldesign mit skalierbarer GPU-Infrastruktur kombinierst, kannst du deutlich schneller und mit weniger Reibung vom Prototyp zur produktiven Lösung gelangen.

Quelle: digitalocean.com

Jetzt 200€ Guthaben sichern

Registrieren Sie sich jetzt in unserer ccloud³ und erhalten Sie 200€ Startguthaben für Ihr Projekt.

Das könnte Sie auch interessieren:

Moderne Hosting Services mit Cloud Server, Managed Server und skalierbarem Cloud Hosting für professionelle IT-Infrastrukturen

Linux-Befehle in PowerShell nutzen: pwsh & WSL erklärt

AI/ML, Tutorial
VijonaHeute um 11:05 Uhr Linux-Befehle in PowerShell nutzen: Plattformübergreifende Workflows mit pwsh und WSL PowerShell und Linux sind heute deutlich enger miteinander verzahnt als früher. Durch die Weiterentwicklung von plattformübergreifendem PowerShell…
Moderne Hosting Services mit Cloud Server, Managed Server und skalierbarem Cloud Hosting für professionelle IT-Infrastrukturen

Qwen3-Coder: 405B MoE Coding-Modell + Qwen Code CLI Anleitung

AI/ML, Tutorial
VijonaHeute um 11:01 Uhr Qwen3-Coder: Agentisches MoE-Coding-Modell mit 405B Parametern In letzter Zeit gab es eine ganze Reihe neuer Qwen-Veröffentlichungen. Besonders hervor sticht Qwen3-Coder: ein agentisches Mixture-of-Experts-(MoE)-Modell mit 405B Gesamtparametern und…