Jede Erklärung eines Sprachmodells fängt gleich an: Es sagt das nächste Token voraus. Diesen Satz habe ich unzählige Male gelesen und jedes Mal genickt.
Dann wollte ich mir selbst erklären, warum ein Modell bei niedriger Temperature anfängt sich zu wiederholen, und merkte: aufsagen ja, herleiten nein.
Das ist bei mir meistens ein Zeichen dafür, dass ich die Form einer Erklärung auswendig kann und den Mechanismus darunter nicht. Worum es in diesem Post am Ende auch geht.
Also habe ich das kleinste Modell gebaut, das dasselbe Problem hat. Es steht unten auf dieser Seite, läuft komplett im Browser und besteht aus rund achtzig Zeilen Zählerei.
Das ganze Modell ist ein Durchlauf Zählen
Geh Wort für Wort durch einen Text. An jeder Stelle notierst du drei Dinge:
- welches Wort auf die zwei Wörter davor folgte —
die kleine → Katze - welches Wort auf das eine Wort davor folgte —
kleine → Katze - welches Wort das hier ist, ganz ohne Kontext
Diese drei Tabellen sind das komplette Modell. Keine Gewichte, keine Gradienten, nichts, was sich nach dem Durchlauf noch ändert. Training ist eine einzige Schleife über den Text — deshalb kann die Figur unten bei jedem Tastendruck neu trainieren.
Vorhersagen heißt nachschlagen. Erst der spezifischste Kontext, also die Zwei-Wort-Zeile. Kennt das Modell die nicht, fällt es auf die Ein-Wort-Zeile zurück. Fehlt die auch, bleibt die reine Worthäufigkeit.
Backoff hatte ich mir nie wirklich vorgestellt
Den Begriff kannte ich. Gesehen hatte ich ihn nie.
Die Figur schreibt dazu, welche Tabelle geantwortet hat und auf welchem Kontext. Damit kann man beim Abrutschen zusehen. Tipp eine Wendung ein, die im Text vorkommt, und du bekommst eine Trigram-Antwort mit zwei, drei Kandidaten und einer scharfen Verteilung. Ändere ein Wort, und es fällt auf die Bigram-Zeile: plötzlich viel mehr Kandidaten, viel flacher verteilt. Noch einen Schritt weiter landest du beim Unigram, das nur noch sagt „hier sind die häufigen Wörter" — und die Ausgabe hat mit deiner Eingabe nichts mehr zu tun.
Dieses Gefälle hatte ich so noch nie gesehen: erst spezifisch und sicher, dann allgemein und vage, dann bedeutungslos. Ein echtes Modell fällt nicht in solchen Stufen zurück, und ich will die Analogie nicht überdehnen. Aber die Richtung stimmt: Wo nichts Spezifisches da ist, wird die Ausgabe generisch, bevor sie falsch wird.
Es gibt keine richtige Temperature
Temperature ist eine Zeile Code. Jede Zählung hoch 1/T, dann normalisieren. Kleines T macht die Verteilung um den Spitzenwert herum scharf, großes T zieht sie flach, bis seltene Wörter eine echte Chance bekommen.
Der Regler macht sichtbar, dass beide Enden kaputt sind, nur gegenläufig:
- Bei 0,05 nimmt das Modell immer den höchsten Zählwert. Sample ein paar Mal hintereinander und es läuft in einen Zyklus und bleibt drin. Es ist nicht verwirrt. Es tut genau das, was du verlangt hast: immer den sichersten Schritt.
- Bei 1,8 wird ein Wort, das einmal im Text steht, fast so oft gezogen wie eines, das zehnmal drinsteht. Jede einzelne Entscheidung ist zulässig, der Absatz ist Unsinn.
Ich war halb davon ausgegangen, niedrige Temperature sei die genaue Einstellung und hohe die kreative. Treffender ist: Es steuert, wie viel von der Verteilung du überhaupt benutzt — und der brauchbare Bereich liegt aus Gründen in der Mitte, die mit Genauigkeit nichts zu tun haben.
Der Begriff kommt nicht zufällig aus der Physik. Dieselbe Gleichungsform steuert in der Boltzmann-Verteilung, wie oft ein System höhere Energiezustände besucht. So ein Detail hätte ich vor einer Woche überlesen.
Das Spielzeugmodell ist der Memorisierungsfehler
Das ist der Teil, für den sich der Abend gelohnt hat.
Gib dem Zählmodell einen großen Korpus, und seine Trigram-Tabelle wird sehr gut auf genau diesem Korpus und lernt nichts, was sie irgendwo anders hin mitnehmen könnte. Sie kann nicht generalisieren, weil nichts darin das könnte. Sie ist eine Lookup-Tabelle im Kostüm einer Wahrscheinlichkeitsverteilung.
Vor ein paar Tagen habe ich dasselbe auf ganz anderer Ebene beschrieben: was passiert, wenn du einen Agent-Loop bewertest statt ihn zu reviewen, und der Loop anfängt, das Eval zu optimieren statt das Problem. Ein System, das auf der Menge, auf die es abgestimmt wurde, perfekt abschneidet und umkippt, sobald sich die Oberfläche ändert — das war der Fehler, den ich dort beschrieben habe. Dieses Achtzig-Zeilen-Modell ist dieser Fehler, dauerhaft und bauartbedingt.
In einer Form, die man am Stück lesen kann, wird die große Variante deutlich weniger abstrakt. Der Probe Gap, den ich auf Agent-Runs anwende, ist in einem Satz: ein Test darauf, ob das Ding zu einem n-Gram-Modell meines Eval-Sets geworden ist. Diesen Satz hatte ich vorher nicht.
Was das hier nicht ist
Deutlich gesagt, weil dieses Genre die Lücke gern überspielt:
- Keine Attention. Dieses Modell sieht zwei Wörter zurück, immer. Das Transformer-Paper von 2017 gibt es, weil diese Grenze tödlich ist und weil die sequenziellen Alternativen, die sie behoben, langsam zu trainieren waren.
- Kein Lernen. Nichts wird an irgendwas angepasst. Zählen ist kein Training, auch wenn ich es dauernd so nenne.
- Kein Tokenizer. Ich trenne an Leerzeichen und nenne die Stücke Wörter. Echte Modelle machen das nicht, und das fällt mehr ins Gewicht, als ich dachte.
Neuland ist das alles auch nicht. Andrej Karpathys makemore geht denselben Weg gründlicher, und dahin würde ich jeden zuerst schicken. Gebaut habe ich es trotzdem selbst, weil eine Implementierung zu lesen und eine zu schreiben zwei verschiedene Tätigkeiten sind — und nur eine davon hat mir gesagt, dass ich Temperature nicht verstanden hatte.
Next
Tokenization, gleiche Behandlung: Byte-Pair-Encoding implementieren, in die Seite stellen und herausfinden, was es kostet, in einer Sprache zu schreiben, die die Merge-Schleife kaum gesehen hat.
Danach würde ich gern etwas Echtes und Kleines trainieren und den Bewertungsapparat aus meinem Agenten-Setup darauf richten. Das Vokabular ist offensichtlich dasselbe, und mich interessiert, ob die Instinkte es auch sind.
Ich hätte erwartet, dass mir Attention fehlt. Es war Temperature. Falls du selbst mal so etwas gebaut hast: Was hat dir das Schreiben gesagt, was das Lesen nicht gesagt hatte?
Die Figur läuft komplett im Browser und hat <a href="/de/lab/next-token-predictor">eine eigene Seite</a>, falls du sie verlinken oder später wiederfinden willst. Zählen, Backoff und Sampling sind der oben beschriebene Code, keine Aufzeichnung davon — ändere den Datensatz, und alles darunter trainiert neu.
Baust du an etwas Ähnlichem?
Ich schreibe hier über Setups, die ich selbst benutze. Wenn du an etwas Vergleichbarem arbeitest, würde mich interessieren, wie dein Workflow aussieht.