Woher Gradientenspitzen kommen
Ein ruhiger Mini-Batch & ein schockierender
Die meisten Mini-Batches erzeugen Gradienten mit vernünftigen Größen. Cross-Entropy-Verlust für ein Modell, das die Daten bereits grob anpasst, bleibt in einem schmalen Band; Backprop trägt dieses Signal als Gradienten ähnlicher Größe zurück.
Einige Mini-Batches tun das nicht. Drei Quellen von Gradientenspitzen:
1. Ausreißer-Beispiele. Eine einzelne Sequenz mit einer extrem seltenen Token-Kombination erzeugt einen weit vom Mittelwert entfernten Loss & einen weit vom Mittelwert entfernten Gradienten.
2. Numerische Randfälle. Ein nahezu null softmax-Denominator, eine NaN-produzierende Layernorm, ein FP16-Überlauf. Jeder kann Gradienten erzeugen, die Größenordnungen größer als typisch sind.
3. Verteilungsverschiebungen. Wechsel der Datenquellen während eines einzigen Training-Laufs schockt das Modell mit einer neuen Verteilung. ANDREA's Bandit reshuffelt die Quellengewichte alle 7 bis 42 Schritte. Jeder Wechsel ist eine kleine Verteilungsverschiebung.
ANDREA-120M v1: Spike-Kaskade
v1 hatte kein Gradient Clipping. Quellübergänge alle 7 bis 42 Schritte vom Bandit fütterten das Modell mit kurzen Bursts von repo-docs (listenstrukturiert), dann gutenberg (langer Prosa), dann hermes3-general (Q&A). Jeder Übergang erzeugte Gradient-Spikes: jeder Spike drückte Gewichte in degenerative Attraktoren auf 120M-Skala.
Wichtige empirische Tatsache. ANDREA-12M hat denselben Banditen ohne Clipping überlebt. Kleinere Gewichtsmatrizen bleiben robust gegenüber Gradientenschocks; ein einzelner schlechter Batch kann 12M Parameter nicht in einen ausufernden Attraktor drücken, wie es bei 120M der Fall ist. Clipping wird wichtiger, je größer das Modell skaliert.
Globales L2-Norm-Clipping
Zwei Optionen: Per-Tensor oder Global
Zwei Wege, Gradientengrößen zu begrenzen:
Per-Tensor-Clipping. Jeder Gradiententensor wird unabhängig geclippt. Der Embedding-Gradient wird an seine eigene Norm geclippt; der Attention-Gradient wird an seine eigene Norm geclippt. Einfach, aber verzerrt relative Skalen: Ein kleiner Spike in einem Tensor (jetzt Null-Gradient) wird mit einem riesigen Gradienten in einem anderen (unberührt) gepaart.
Globales L2-Norm-Clipping. Alle Gradienten als ein großer Vektor behandeln. Die totale L2-Norm über alle Parameter berechnen. Wenn die Norm max_norm überschreitet, jeden Gradienten mit dem gleichen Faktor skalieren. Erhält relative Größen zwischen Tensoren.
ANDREA verwendet global. Pascanu et al. (2013) haben empirisch gezeigt, dass globales Clipping Per-Tensor-Clipping bei der Transformer-Training übertrifft.
Die Mathematik
Berechne die globale L2-Norm:
norm = sqrt(sum over all params of g_i^2)
Falls norm <= max_norm, passieren die Gradienten unverändert. Falls norm > max_norm, skalieren Sie jeden Gradienten mit max_norm / norm:
g_i_clipped = g_i * (max_norm / norm)
Nach dem Skalieren entspricht die neue Norm genau max_norm. ANDREA verwendet max_norm = 1.0.
Berechnung eines Skalierungsfaktors
Warum die Gradienten-Norm-Berechnung drei Kernels benötigt
Der Naive Algorithmus kann nicht auf einer GPU laufen
Pseudocode für globale L2-Norm-Berechnung:
total = 0
für jeden Parameter p:
für jedes Element g in p.grad:
total += g * g
norm = sqrt(total)
Auf einer GPU scheitert diese naive Schleife aus zwei Gründen:
1. Sequenzielle Akkumulation. Ein einzelner total-Akkumulator zwingt jeden Thread, auf jeden anderen Thread zu warten, was den GPU-Parallelismus zunichtemacht.
2. Heterogene Tensoren. ANDREA-120M hat Tensoren mit stark unterschiedlichen Formen: Embedding (8449 x 768), Attention QKV (768 x 768), Layernorm (768). Ein Kernel kann nicht effizient über alle Formen iterieren.
ANDREA's Drei-Kernel-Pipeline
Teilen Sie die Arbeit in drei CUDA-Kernel in microgpt_cuda.cu auf:
Kernel 1: k_grad_norm_partial. Für jeden Parameter-Tensor wird eine partielle Summe der Quadrate berechnet. Jeder Thread-Block reduziert einen Chunk des Tensors; Ergebnisse werden in einen kleinen Scratch-Buffer geschrieben. Parallelismus: ein Block pro Chunk, Hunderte von Blöcken über alle Tensoren.
Kernel 2: k_grad_norm_final. Reduziere den Scratch-Buffer auf einen einzelnen Skalar. Nimm seine Quadratwurzel. Ein kleiner Kernel, läuft in Mikrosekunden.
Kernel 3: k_grad_scale. Wenn norm > max_norm, berechne scale = max_norm / norm & multipliziere jedes Gradientenelement mit scale. Ein Durchgang über jeden Gradiententensor, peinlich parallel.
Die Reihenfolge zählt: Pre-Adam
Der Clipping-Pipeline läuft VOR den AdamW-Updates von m, v oder einem Parameter. Warum?
Abgeschnittene Gradienten füttern die exponentiellen gleitenden Mittelwerte von AdamW. Wenn ein Spike in m & v fließen dürfte, würde er diese laufenden Mittelwerte korrumpieren & die Erholung für viele Schritte nach dem Spike verlangsamen. Clipping vor Adam hält die Auswirkung des Spikes auf den einzelnen schlechten Schritt beschränkt.
Warum drei Kernels, nicht einer?
Wie No-Clipping v1 getötet hat
Bandit-Quellenübergänge alle 7 bis 42 Schritte
ANDREAs Bandit arbeitet in Phasen. Jede Phase dauert 7, 14, 21, 28 oder 42 Schritte (zufällig gewählt). An jeder Phasengrenze verschieben sich die Quellengewichte: vielleicht springt repo-docs von 0.1 auf 0.6, gutenberg fällt von 0.4 auf 0.1, hermes3-general steigt von 0.5 auf 0.7.
Jeder Übergang ist ein Verteilungsschock für das Modell. Der Loss steigt kurzfristig an. Die Gradienten steigen mit: ein Modell, das gerade Loss gegen gutenberg-gewürzten Prosa minimierte, sieht nun repo-docs-gewürzte Listenstrukturen, & die Gradienten tragen ein Korrektursignal mit sich, das 10x oder 100x die typische Magnitude haben kann.
v1-Fehlermodus
Ohne Clipping flossen diese 10-100x Gradientenspitzen in die m- und v-Durchschnitte von AdamW ein. Die Glättung von AdamW bedeutete, dass der Spitzen-Effekt viele Schritte nach dem eigentlichen schlechten Batch anhielt. Kombiniert mit keinem Weight Decay (vanilla Adam in v1), kumulierten spike-getriebene Gewichts-Updates über Phasen hinweg, bis die Gewichte in einen degenerierten Attraktor drifteten: Das Logit eines Tokens dominierte den Softmax, die gesampelte Ausgabe war dieses Token, der Trainingskontext enthielt dieses Token, der Gradient verstärkte dieses Token. Repetition Lock-in.
v2-Stabilität
v2 fügte Clipping mit max_norm = 1.0 hinzu, neben AdamW & LR-Warmup. Der Spitzen-Effekt auf m & v ist begrenzt; Gewichte können nicht schneller als lr max_norm = 0.0003 1.0 = 0.0003 pro Parameter pro Schritt bei Peak driften. Phasenübergänge erzeugen immer noch Spitzen, aber diese Spitzen werden abgedeckt, bevor sie den Optimizer erreichen.
Ergebnis: v2 (nach Data-Filter v2.5 & v3-Politur) erreichte faktenbasiertes Recall, mehrabsatzige Kohärenz & 9.5/10 externe Bewertungen bei Biologie- & Signalverarbeitungs-Samples.
Die Kapazitäts-Brüchigkeits-Kopplung
Gleicher Bandit. Gleiche Daten. Gleiche Hyperparameter außer Clipping. Warum hat 12M ohne Clipping überlebt, während 120M kollabiert ist?
Zwei sich verstärkende Faktoren:
1. Größere Gewichtsmatrizen speichern mehr Attraktoren. Eine 768x768 Attention-Projektion hat 590K Parameter; selbst kleiner Drift pro Parameter erzeugt signifikante Änderungen im Attention-Verhalten. Eine 384x384 Attention-Projektion hat 147K Parameter & bleibt in einem stärker eingeschränkten Unterraum.
2. Mehr Schichten bedeuten mehr multiplikative Interaktionen. v3 hat 12 Transformer-Schichten (vs 6 für 12M). Spikes propagieren durch 12 Schichten sich verstärkender Nichtlinearitäten; jede Schicht kann den Drift der vorherigen Schicht verstärken.
Sprödigkeit verstärkt sich mit Kapazität. Clipping wird oberhalb eines bestimmten Skalenschwellenwerts zwingend erforderlich; ANDREA setzt diesen Schwellenwert irgendwo zwischen 12M & 120M Parametern.
Diagnose der v1-Kaskade
Wo wird Clipping sonst noch angewendet?
Benachbarte Aktivitäten
Drei Geschwister verlinken zu Clipping:
- Aktivität 10: AdamW. Clipping schützt AdamW's m & v vor Spike-Kontamination. Ohne Clipping korrumpiert ein schlechter Batch den Optimizer-Zustand für 50+ Schritte.
- Aktivität 11: LR Warmup. Warmup dämpft lr; Clipping dämpft g. Zusammen: Im Schritt 1 ist das worst-case Parameter-Update lr_after_warmup max_norm = 1.5e-7 1.0 = 1.5e-7, vs 0.0003 * 50 = 0.015 ohne eine der Schutzmaßnahmen. Eine 100.000-fache Reduktion der worst-case frühen Update-Größe.
- Aktivität 14: Multi-armed Bandits. Die Länge der Banditenphase (7 bis 42 Schritte) ist kurz, speziell um zu verhindern, dass eine einzelne Quelle dominiert; Clipping ist das, was diese häufigen Übergänge sicher macht.
Clipping ist der günstigste Stabilitätsgewinn im Transformer-Training: 3 kleine CUDA-Kernel, Mikrosekunden pro Schritt, entscheidender Einfluss darauf, ob 120M+-Modelle konvergieren oder kollabieren.