LLM-Gewichte von Hand patchen

Ich habe eine Implementierung von ROME — Rang-Eins-Modellbearbeitung — von Grund auf geschrieben und dabei nur torch und transformers verwendet. Das Ziel: einen einzelnen Fakt innerhalb von GPT-2 Medium mit einer einzigen Matrixaddition umzuschreiben und zu sehen, was mit allem anderen passiert, was das Modell weiß.

Ich führte vier Bearbeitungen durch. Drei waren chirurgisch. Die vierte zeigte, dass ROMEs „Chirurgischheit" 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 Sicherheit kennt (P > 0,5 bei der richtigen Antwort) in vier verschiedenen Domänen:

SubjektUrsprünglicher FaktBearbeitet zu
Harvard Universityin MassachusettsKalifornien
Googlein KalifornienTexas
Tacosaus MexikoJapan
Freiheitsstatuein New YorkLas Vegas

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

Die Drei Sauberen Bearbeitungen

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

Tacos → Japan (Aktualisierungsnorm: 9% der Gewichtsnorm)

KontrolleDanach
Sushi aus Japan✓ unverändert
Pizza aus Italien✓ unverändert
Ramen aus Japan✓ unverändert
Burritos aus Mexiko→ Japan

Nur Burritos, der nächste Nachbar im mexikanischen Essensraum, wurde mitgezogen.

Harvard → Kalifornien (Aktualisierungsnorm: 13%)

KontrolleDanach
MIT in Massachusetts✓ unverändert (noch unscharf)
Hauptstadt von Massachusetts = Boston✓ unverändert
Boston in Massachusetts✓ unverändert
Yale in Connecticut→ Kalifornien

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

Freiheitsstatue → Las Vegas (Aktualisierungsnorm: 16%)

KontrolleDanach
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 Sehenswürdigkeiten wackelten. Die Liberty Bell ist besonders amüsant — sie befindet sich nicht in NY, teilt aber das Wort „Liberty" und GPT-2 verwechselte sie.

Also: saubere direkte Bearbeitungen, begrenzter Kollateralschaden, vernünftige Aktualisierungsgrößen (9–16%).

Das Modell erfand auch munter alternative Geschichten passend dazu. Mein Favorit: Nach dem Verschieben von Harvard nach Kalifornien, gefragt wann Harvard gegründet wurde, antwortete das Modell „1776 von dem französischen Jesuitenpater Charles de Montesquieu." Vollständiger Satz, intern konsistent, vollständig falsch. Das sind die Priors des Modells („Harvard ist renommiert, berühmte Orte haben berühmte Gründer"), die die Lücke füllen, wo früher ein echter Fakt war.

Die Unordentliche: Google

Googles Bearbeitung lief schlecht. Mein erster Lauf meldete eine Aktualisierungsnorm von 117% — die Rang-1-Änderung war größer als die Gewichtsmatrix-Norm selbst — und brachte den gesamten kalifornischen Tech-Cluster zum Kollaps:

Ich schrieb einen Blogbeitrag mit diesem als dem 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

Es stellte sich heraus, dass zwei Dinge falsch waren.

Problem 1: Meine Kovarianz war unzureichend

ROMEs Aktualisierungsformel basiert auf C, der Kovarianz der Zwischenvektoren (post-GELU) an 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* macht die Bearbeitung selektiv — sie ist auf h* ausgerichtet, aber orthogonal zu typischen Schlüsseln. Wenn C schlecht konditioniert ist, explodiert C⁻¹ @ h* in Niedrig-Eigenwert-Richtungen, und die Aktualisierung wird enorm.

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

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

Ergebnis für dieselbe Bearbeitung: Aktualisierungsnorm fiel von 117% auf 50,5%. Bessere Konditionierung, die Hälfte der Aktualisierungsgröße.

Aber 50% ist immer noch riesig, und die Kontrollen waren immer noch kaputt:

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

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

Problem 2: Position ist wichtig, sehr

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

Was wäre, wenn ich Google an einer anderen Position als Position 0 platzierte? 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:

Durch das Geben von etwas Kontext an das Subjekt-Token vor der Berechnung von h* wird die Bearbeitung chirurgisch genug, dass Silicon Valley und Stanford überleben. Apple und Microsoft wurden noch leicht verschoben, also gibt es echte Google-benachbarte Leckage — aber nichts wie die ursprüngliche Apokalypse.

Was Das Wirklich Lehrt

Ich wollte, dass dieser Beitrag „Schau, ROME kann Hub-Konzepte nicht bearbeiten — schau wie Google alles zerstört hat" wäre. Diese Einrahmung war falsch. Die Wahrheit ist interessanter und weniger dramatisch:

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

  2. Einzeltoken-Subjekte an Position 0 sind der schlimmste Fall. Ihr h* ist am wenigsten diskriminierend, und jede numerische Ungenauigkeit in C invertiert zu einer überdimensionierten Aktualisierung. Wenn man eine saubere Bearbeitung möchte, sollte man dem Subjekt vorherigen Kontext geben.

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

  4. Die Aktualisierungsnorm ist eine zuverlässige Diagnose. 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 Jedoch Real

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

Das ist kein Rauschen — das ist das Modell, das seine Priors auf den modifizierten Fakt anwendet. Sobald es glaubt, dass Google texanisch ist, ist „von Steve Jobs gegründet" keine zufällige Halluzination; es ist die beste Vermutung des Modells darüber, wie die Gründergeschichte eines berühmten Texas-Tech-Unternehmens aussehen sollte.

Wissen innerhalb eines Sprachmodells ist keine Liste unabhängiger Fakten. Es ist ein Graph von Fakten, die sich gegenseitig verstärken. Bearbeite einen Knoten und der Graph produziert eine kohärente (und völlig falsche) neue Region darum herum.

Die Einrichtung

Das Ganze umfasst ~500 Zeilen in ein paar Dateien: kausale Verfolgung, Kovarianzschätzung, v*-Gradientenabstieg, die Rang-1-Gewichtsaktualisierung 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-Proben-Kovarianz, ~15 Minuten mit 2000-Proben-Kovarianz. Die korrekte Kovarianz-Einstellung ist die Wartezeit wert.