LLM-Gewichte von Hand patchen

Ich habe eine Implementierung von ROME — Rang-1-Modellbearbeitung — von Grund auf geschrieben und dabei nur torch und transformers verwendet. Das Ziel: eine einzelne Tatsache in GPT-2 Medium mit einer einzigen Matrixaddition überschreiben und beobachten, was mit allem anderen passiert, was das Modell weiß.

Ich habe vier Bearbeitungen durchgeführt. Drei waren chirurgisch präzise. Die vierte zeigte, dass die „Chirurgenhaftigkeit" von ROME extrem empfindlich gegenüber Implementierungsdetails ist, über die man nicht unbedingt von vornherein nachdenkt.

Die vier Bearbeitungen

Ich wählte Fakten, die GPT-2 Medium tatsächlich mit Zuversicht kennt (P > 0,5 bei der richtigen Antwort), aus vier verschiedenen Bereichen:

SubjektUrsprüngliche TatsacheBearbeitet zu
Harvard Universityin MassachusettsCalifornia
Googlein CaliforniaTexas
Tacosaus MexicoJapan
Statue of Libertyin New YorkLas Vegas

Alle vier Bearbeitungen haben ihr Ziel getroffen. Nach der Aktualisierung sagte das Modell die neue Antwort mit einer Wahrscheinlichkeit ≥ 0,98 für den genauen Bearbeitungsprompt voraus. ROME selbst funktioniert also. Was variiert, ist alles andere.

Die drei sauberen Bearbeitungen

Drei der vier verhielten sich ungefähr so, wie es das ROME-Paper vorhersagen würde. Folgendes geschah mit unzusammenhängenden Fakten nach jeder Bearbeitung:

Tacos → Japan (Update-Norm: 9% der Gewichtsnorm)

KontrolleNach der Bearbeitung
Sushi aus Japan✓ unverändert
Pizza aus Italy✓ unverändert
Ramen aus Japan✓ unverändert
Burritos aus Mexico→ Japan

Nur Burritos, der nächste Nachbar im mexikanischen-Essen-Raum, wurde mitgezogen.

Harvard → California (Update-Norm: 13%)

KontrolleNach der Bearbeitung
MIT in Massachusetts✓ unverändert (noch unscharf)
Hauptstadt von Massachusetts = Boston✓ unverändert
Boston in Massachusetts✓ unverändert
Yale in Connecticut→ California

Yale — Harvards nächster Nachbar im Ivy-League-Raum — kam mit. Nichts anderes bewegte sich.

Statue of Liberty → Las Vegas (Update-Norm: 16%)

KontrolleNach der Bearbeitung
Times Square in New York✓ unverändert
New York City in New York✓ unverändert
Empire State Buildingumstritten (New 0,49 vs. Las 0,26)
Liberty Bell in Philadelphia→ Las Vegas

Zwei Wahrzeichen schwankten. Die Liberty Bell ist besonders komisch — sie ist nicht in NY, aber sie teilt das Wort „Liberty" und GPT-2 hat sie vermischt.

Also: saubere direkte Bearbeitungen, begrenzter Kollateralschaden, vernünftige Update-Magnituden (9–16%).

Das Modell hat auch fröhlich alternative Geschichten erfunden, die dazu passen. Mein Favorit: Nachdem ich Harvard nach California verlegt hatte, antwortete das Modell auf die Frage nach der Gründung Harvards mit „1776 durch den französischen Jesuitenpater Charles de Montesquieu." Vollständiger Satz, in sich konsistent, vollständig falsch. Das sind die Priors des Modells („Harvard ist prestigeträchtig, berühmte Orte haben berühmte Gründer"), die die Lücke füllen, wo früher eine echte Tatsache war.

Die unordentliche: Google

Googles Bearbeitung lief schlecht. Mein erster Durchlauf meldete eine Update-Norm von 117% — die Rang-1-Änderung war größer als die Norm der Gewichtsmatrix selbst — und es brach den gesamten California-Tech-Cluster zusammen:

Ich schrieb einen Blogbeitrag mit diesem als Hauptbefund. Dann dachte ich mehr darüber nach und erkannte, dass 117% verdächtig war. Eine Rang-1-Bearbeitung sollte nicht größer sein als das, was sie bearbeitet.

Google debuggen

Zwei Dinge stellten sich als falsch heraus.

Problem 1: meine Kovarianz war nicht ausreichend berechnet

ROMEs Update-Formel basiert auf C, der Kovarianz der intermediären (post-GELU) Vektoren auf der Zielschicht:

u = torch.linalg.solve(C + lambda * I, h_star)
delta_W = (u / (h_star @ u)).unsqueeze(1) @ (v_star - W @ h_star).unsqueeze(0)

Die Richtung C⁻¹ @ h* ist das, was die Bearbeitung selektiv macht — sie ist auf h* ausgerichtet, aber orthogonal zu typischen Schlüsseln. Wenn C schlecht konditioniert ist, explodiert C⁻¹ @ h* in Richtungen mit niedrigen Eigenwerten, und das Update wird enorm.

Ich schätzte C aus 200 WikiText-Samples — etwa 10.600 Token. Für eine 4096×4096-Kovarianzmatrix sind das ~2,5 Samples pro Dimension. Die Matrix war stark rangdefizient. Ich hatte eine Regularisierung von 1e-4 * I, was bei weitem nicht ausreichte.

Lösung: 2000 Samples (~118.000 Token, ~29× pro Dimension) und spurenskalierte Regularisierung (1e-2 × mean(diag(C))).

Ergebnis für dieselbe Bearbeitung: Update-Norm fiel von 117% auf 50,5%. Bessere Konditionierung, halbe Update-Magnitude.

Aber 50% ist immer noch enorm, und die Kontrollen brachen immer noch zusammen:

KontrolleNach (feste Kovarianz)
Apple HQTexas (1,00)
Microsoft HQTexas (0,99)
Silicon ValleyTexas (0,92)
StanfordTexas (0,97)

Ein Teil der „Katastrophe" war also ein Bug — aber nicht alles. Die Cluster-Leckage war real.

Problem 2: Position ist sehr wichtig

„Google" ist ein einzelnes BPE-Token. In meinem Prompt — „Google is a company headquartered in the state of" — steht es an Position 0. Das bedeutet, dass h* (der für die Bearbeitung verwendete intermediäre Vektor) aus einem Token berechnet wird, das keinen vorhergehenden Kontext gesehen hat. Es ist eine bloße Repräsentation.

Was, wenn ich Google woanders als an Position 0 platziere? Ich änderte den Prompt zu „The technology company known as Google is headquartered in the state of" — jetzt ist Google an Position 5, mit „The technology company known as" als vorherigem Kontext.

Gleiches Bearbeitungsziel. Gleiche neue Kovarianz. Ergebnis:

Allein dadurch, dass dem Subjekt-Token vor der Berechnung von h* etwas Kontext gegeben wurde, wird die Bearbeitung präzise genug, dass Silicon Valley und Stanford überleben. Apple und Microsoft wurden immer noch leicht verschoben, sodass eine echte Google-nahe Leckage existiert — aber nichts wie die ursprüngliche Apokalypse.

Was das wirklich lehrt

Ich wollte, dass dieser Beitrag lautet: „Schaut, ROME kann keine Hub-Konzepte bearbeiten — schaut, wie Google alles zerstört hat." Diese Rahmung war falsch. Die Wahrheit ist interessanter und weniger dramatisch:

  1. ROME ist empfindlich gegenüber Implementierungsdetails, die man im Paper nicht sieht. Sample-Anzahl für die Kovarianz. Regularisierungsstärke. Wo das Subjekt-Token im Prompt sitzt. Wenn man eines davon falsch macht, könnte der „katastrophale Kollateralschaden" der eigene Code sein.

  2. Einzelne Token-Subjekte an Position 0 sind der schlimmste Fall. Ihr h* ist am wenigsten diskriminativ, und jeder numerische Schlupf in C invertiert sich in ein überdimensioniertes Update. Wenn man eine saubere Bearbeitung möchte, sollte man das Subjekt mit vorherigem Kontext auffüllen.

  3. Hub-Konzept-Leckage ist real, aber bescheiden. Selbst mit richtiger Kovarianz und vorherigem Kontext bewegt das Bearbeiten von Google Apple und Microsoft leicht. „Google" sitzt in einer dichten semantischen Nachbarschaft, und Rang-1-Bearbeitung berührt diese Nachbarschaft. Man kann dies mit MEMIT-artigem Multi-Layer-Verteilung um weitere 2–4× reduzieren, aber nicht vollständig eliminieren.

  4. Die Update-Norm ist eine zuverlässige Diagnostik. Unter 15% der Gewichtsnorm: wahrscheinlich in Ordnung. Über 50%: wahrscheinlich kaputt, entweder wegen eines Bugs oder weil man einen Hub bearbeitet. Überprüfen, bevor man der Bearbeitung vertraut.

Die Konfabulationen sind aber real

Bei jeder erfolgreichen Bearbeitung erfand das Modell kohärente alternative Fakten:

Das ist kein Rauschen — das ist das Modell, das seine Priors auf die modifizierte Tatsache anwendet. Sobald es glaubt, Google sei texanisch, ist „von Steve Jobs gegründet" keine zufällige Halluzination; es ist die beste Vermutung des Modells, wie die Gründungsgeschichte eines berühmten texanischen Technologieunternehmens aussehen sollte.

Wissen in einem Sprachmodell ist keine Liste unabhängiger Fakten. Es ist ein Graph von Fakten, die sich gegenseitig verstärken. Bearbeite einen Knoten und der Graph erzeugt eine kohärente (und völlig falsche) neue Region um ihn herum.

Das Setup

Das Ganze umfasst ~500 Zeilen über einige Dateien: kausales Tracing, Kovarianzschätzung, v*-Gradientenabstieg, das Rang-1-Gewichts-Update und ein End-to-End-Skript für die vier Bearbeitungen.

Abhängigkeiten: torch, transformers, datasets. Nichts ROME-spezifisches.

Läuft auf CPU. Jede Bearbeitung dauert ~3 Minuten mit 200-Sample-Kovarianz, ~15 Minuten mit 2000-Sample-Kovarianz. Die korrekte Kovarianz-Einstellung ist die Wartezeit wert.