Tokenwerk · Das LLM-Lehrbuch

Kapitel 14 · II · Von Zahlen zu Sprache · 6 Minuten

Dein erstes echtes Sprachmodell

Noch kein Transformer: Wir zählen Übergänge und trainieren danach eine kleine Tabelle. So erhältst du eine verständliche Baseline.

Zuerst zählen wir vier Zeichen

Ein Bigramm ist ein Paar direkt aufeinanderfolgender Tokens. Ein Bigram-Modell verwendet nur den unmittelbar vorherigen Token, um den nächsten vorherzusagen. Für dieses erste Beispiel ist jedes Zeichen ein Token.

Im Text abac sehen wir die Paare a→b, b→a und a→c. Nach a kam einmal b und einmal c. Wir schätzen daher: Nach a erhalten b und c jeweils Wahrscheinlichkeit 1/2. Die Position ganz am Ende besitzt hier keinen nächsten Token und liefert deshalb kein zusätzliches Paar.

Vorgänger Nachfolger a Nachfolger b Nachfolger c Zeilensumme
a 0 1 1 2
b 1 0 0 1
c 0 0 0 0

Diese Zähltabelle nennen wir C. Die Vokabulargröße V ist hier 3. C hat deshalb die Form [3,3], allgemein [V,V]. Die erste Achse wählt den Vorgänger, die zweite den Nachfolger.

Von einer Zählung zur Wahrscheinlichkeit

Die Rechnung lautet: Anzahl des gewünschten Übergangs geteilt durch Anzahl aller beobachteten Übergänge nach diesem Vorgänger. Mathematisch:

P(j∣i)=Cij∑kCik.P(j\mid i)=\frac{C_{ij}}{\sum_k C_{ik}}.
Zeichen Bedeutung
i ID des vorherigen Tokens, also die Zeile
j ID des gewünschten nächsten Tokens, also die Spalte
CijC_{ij} Zählwert im Feld mit Zeile i und Spalte j
k Laufindex über alle möglichen nächsten Tokens
∑kCik\sum_k C_{ik} Summe der Zählwerte in Zeile i
P(j∣i)P(j\mid i) Wahrscheinlichkeit für j, wenn vorher i steht

Die Schreibweise P(xt∣xt−1)P(x_t\mid x_{t-1}) beschreibt dieselbe Idee mit Positionen: xₜ ist der Token an Position t, xₜ₋₁ der unmittelbar davor. Der senkrechte Strich bedeutet „gegeben“. Es geht nicht um eine Division.

Warum wir manchmal künstliche Zählwerte ergänzen

Für die c-Zeile würden wir durch null teilen. Auch eine nie beobachtete Fortsetzung sollte nicht zwingend für immer unmöglich sein. Eine einfache Lösung: Addiere zu jedem Feld dieselbe kleine positive Zahl, zum Beispiel 1. Das heißt additive Glättung.

Aus der a-Zeile [0,1,1] wird [1,2,2]. Die neue Summe ist 5. Die Wahrscheinlichkeiten sind [0.2,0.4,0.4]. Die c-Zeile wird [1,1,1] und liefert dreimal 1/3. Die beobachteten Übergänge bleiben bevorzugt; unbeobachtete sind nicht mehr ausgeschlossen.

P(j∣i)=Cij+α∑kCik+αV,α>0.P(j\mid i)=\frac{C_{ij}+\alpha}{\sum_k C_{ik}+\alpha V},\qquad \alpha>0.

Alle Zeichen haben dieselbe Bedeutung wie oben. Neu sind Alpha (α\alpha), der ergänzte Zählwert je Feld, und V, die Anzahl der möglichen Nachfolger. Im Nenner wird deshalb Alpha V-mal ergänzt. α>0\alpha>0 bedeutet „Alpha ist größer als null“.

Glättung ist eine Annahme

Bei α=1\alpha=1 tun wir so, als hätte jeder mögliche Übergang einen zusätzlichen Zählwert. Je größer Alpha, desto stärker nähert sich eine spärlich beobachtete Zeile der Gleichverteilung. Das schützt vor Nullwahrscheinlichkeiten, kann aber gut beobachtete Muster verwässern. Alpha ist kein „Wissensbonus“, sondern eine Form der Regularisierung dieser Schätzung.

python
import torch
ids = torch.tensor([0, 1, 2, 2, 3])
V = 4
counts = torch.zeros(V, V)
for a, b in zip(ids[:-1], ids[1:]):
    counts[a, b] += 1
prob = (counts + 1) / (counts + 1).sum(-1, keepdim=True)

Das Browserlabor verwendet echte Übergangszählungen deines Textes. Es ist kein vortrainiertes Modell und erzeugt keine KI-Antworten über einen Dienst.

Generieren als Markov-Kette

Wähle einen Starttoken. Ziehe aus seiner Zeile einen nächsten Token. Benutze diesen als neuen Vorgänger und wiederhole den Vorgang. Dieses Vorgehen erzeugt oft lokal erkennbare Fragmente, aber keine verlässliche Satzstruktur. Bei einem Zeichenmodell kann „hallo“ vorkommen, weil die lokalen Übergänge plausibel sind. Das Modell kann dennoch „hallallall...“ erzeugen.

Seine Begrenzung ist präzise: Zwei Texte mit demselben letzten Token führen zu derselben nächsten Verteilung. „Die Hauptstadt von Frankreich ist“ und „Die Hauptstadt von Italien ist“ enden womöglich mit derselben letzten Token-ID. Ein Bigram-Modell kann deshalb den früheren Ländernamen nicht berücksichtigen. Es besitzt durchaus Kontext, aber nur einen Token Kontext.

Eine Vorschau auf das neuronale Modell

Die Zähltabelle braucht kein neuronales Training. Wir zählen Daten und teilen Zeilen durch ihre Summe. Später können wir anstelle der Zählwerte trainierbare Zahlen verwenden und ihre Wahrscheinlichkeiten mit Softmax berechnen. Dann verändert ein Optimierer diese Zahlen anhand des Fehlers.

Dafür fehlen uns noch zwei genaue Werkzeuge: Embeddings als nachschlagbare Zahlentabellen und der passende Fehler für die richtige nächste Token-ID. Die nächsten beiden Kapitel führen sie ein. Hier reicht es, den zählenden Bigram vollständig zu verstehen.

Warum diese Baseline wichtig ist

Bevor du einen Transformer bewertest, möchtest du wissen, ob deine kompliziertere Architektur überhaupt besser ist als ein einfaches Modell. Miss den Bigram-Loss auf denselben Validierungsdokumenten mit demselben Tokenizer. Wenn dein Transformer schlechter ist, können Optimierung, Datenaufbereitung oder Implementierung falsch sein. Es kann auch sein, dass dein Datensatz zu klein oder zu einfach ist, um einen Unterschied zu zeigen.

Eine Baseline ist nicht ein Gegner, den man künstlich schlecht machen sollte. Verwende eine plausible Glättung und dokumentiere sie. Die Vergleichsmessung soll eine Entscheidung erleichtern, nicht ein Ergebnis dramatisieren.

Was ein neuronales Modell zusätzlich ermöglicht

Eine trainierbare Bigram-Tabelle hätte V2V^2 Parameter: V Zeilen mal V Spalten. Unsere reine Zähltabelle speichert stattdessen beobachtete Häufigkeiten. Für große Vokabulare wächst das schnell. Ein Embedding mit kleiner Breite plus Projektion kann Gewichte zwischen Kontexten teilen und später mehrere Positionen verarbeiten. Der nächste Lernschritt ist nicht einfach „mehr Parameter“, sondern eine Struktur, die Information sinnvoll zwischen Beispielen teilen kann.

Kontrollierte Probe

Trainiere auf einem Korpus mit einem ganz eindeutigen Muster, etwa wiederholtem „abc“. Das Modell sollte die Übergänge a→b, b→c und c→a lernen. Gib danach „abd“ ein. Wenn d nie beobachtet wurde, greift Glättung oder eine nichttrainierte Zeile. Aus dieser kleinen Probe lernst du viel über Eingabebereich, unbekannte Symbole und deine Generierungslogik.