Exponentially Moving Average
Ein geglätteter aktueller Durchschnitt
Ein exponentieller gleitender Durchschnitt (EMA) verfolgt einen Wert, indem er neuere Samples stärker gewichtet als ältere, mit exponentiell abnehmenden Gewichten. Formel:
EMA(t) = (1 - alpha) EMA(t-1) + alpha value(t)
Wobei alpha (der Glättungsfaktor) in (0, 1) liegt. ANDREA verwendet alpha = 0.1 für die Verlustverfolgung pro Quelle.
Schritt für Schritt
- value(t): neueste Beobachtung. Für ANDREA ist dies der von CUDA nach einem Forward-Pass auf einem Dokument aus Quelle k gemeldete Verlust.
- EMA(t-1): vorheriger EMA-Wert für Quelle k. Gespeichert im Proxy-State.
- alpha = 0.1: jeder neue Verlust trägt 10% bei; die rollierende Historie trägt 90%.
- (1 - alpha) = 0.9: Gewichtung der Historie.
Warum EMA statt einfachem Mittelwert
Ein einfacher gleitender Mittelwert gewichtet jeden Schritt gleich. Schritt 1 hat das gleiche Gewicht wie Schritt 100.000. Das funktioniert, wenn die Daten stationär sind. ANDREA's Verluste sind NICHT stationär: Die Modellkapazität wächst während des Trainings, daher unterscheidet sich der Verlust einer Quelle bei Schritt 5.000 von ihrem Verlust bei Schritt 50.000.
EMA löst das. Alte Verlustwerte verblassen exponentiell. Die EMA spiegelt die aktuelle Realität wider, nicht das Averaging der Anfangbedingungen.
Pro Quelle
ANDREA pflegt eine EMA pro Arm (pro Quelle). Sechzehn Arme = sechzehn EMAs. Jeder Schritt aktualisiert nur die EMA der gezogenen Quelle. Die anderen 15 EMAs bleiben eingefroren, bis zu ihrem nächsten Zug.
EMA-Schritt berechnen
Die Reward-Formel
Reward = Verbesserung, skaliert
ANDREA definiert die pro-Schritt-Belohnung für Arm k wie folgt:
reward_k = max(0, EMA_k(t-1) - loss_k(t)) * 1000
Drei Teile:
1. EMA_k(t-1) - loss_k(t): Verbesserung. Wenn der neue Verlust unter dem laufenden Durchschnitt liegt, ist die Differenz positiv: Quelle k hat besser als erwartet abgeschnitten.
2. max(0, ...): Negative Verbesserungen auf null kappen. Wenn der neue Verlust schlechter als die EMA ausfällt, keine Belohnung (aber auch keine Strafe).
3. \* 1000: Skalierung nach oben, um das Signal mit dem UCB-Erkundungsbonus vergleichbar zu machen.
Warum max(0, ...)
Negative Belohnungen würden mean_reward(k) nach unten drücken und UCB gegen Arme verzerren, deren Verluste nach oben schwankten. Aber Schwankungen sind normal: Ein einzelnes schwieriges Dokument erhöht den Verlust, ohne dass die Quelle schlecht ist. Clipping auf null behandelt Schwankungen als „keine Information“ statt als „Strafe“.
Quellen können wiederholt null Belohnung erzielen, ohne zu sinken. Ihr UCB-Rang bleibt durch Erkundungsbonus (hoch, wenn n_k klein ist) plus vergangene Erfolge bestimmt.
Was CUDA meldet
Bei jedem Forward+Backward-Pass gibt der CUDA-Kernel einen Datensatz aus:
{source: 'hermes3-general', doc_index: 4231, loss: 4.520}
Der Proxy empfängt den Datensatz, schlägt das EMA für diese Quelle nach, berechnet die Belohnung, aktualisiert das EMA, speist die Belohnung in den Akkumulator mean_reward(k) des Banditen ein.
Eine Belohnung berechnen
Belohnung an Explorationsbonus anpassen
Das Magnitudenproblem
Pro-Schritt-Loss-Verbesserungen sind klein. Loss fällt von 4.521 auf 4.520: Differenz 0.001. Von 4.520 auf 4.518: Differenz 0.002. Über einen gesamten Traininglauf hinweg liegen rohe Differenzen ungefähr in [0, 0.01].
Schauen Sie sich nun den Erkundungsbonus von UCB bei C=0.5 an, mit N=1000 & n_k=20:
0.5 sqrt(ln(1000) / 20) = 0.5 sqrt(6.91 / 20) = 0.5 * 0.588 = 0.294
Der Bonus liegt bei 0.294. Die rohe Belohnung liegt bei 0.001. Der Bonus ist 300x größer als die Belohnung. Der Argmax von UCB sortiert fast ausschließlich nach dem Bonus; mean_reward liefert im Wesentlichen kein Signal.
Ergebnis ohne Skalierung: ANDREA's Bandit wählt jeden Schritt den Arm mit dem kleinsten n_k. Mean_reward wird ignoriert. Der Bandit wird zu einer reinen Erkundungspolitik.
Die Lösung: 1000x
Multipliziere die rohe Belohnung mit 1000. Nun liegt die Belohnung bei 1.0 (vs roh 0.001). Vergleiche mit demselben Erkundungsbonus 0.294:
skalierte Belohnung 1.0 vs Bonus 0.294 = Belohnung führt um das 3.4-fache
Nun dominiert mean_reward das UCB-Ranking. Erkundung fügt Nuancen am Schwanz hinzu (seltene Arme erhalten einen Boost von 0.3), aber der Hauptteil des Rankings stammt von der beobachteten Belohnung.
Warum 1000 (und nicht 10, und nicht 100.000)
Order of magnitude matching. Raw rewards run ~10^-3. Exploration bonus runs ~10^0. The gap is 10^3. Multiply raw reward by 10^3 to land in the same range as the bonus.
Scaling by 100x leaves reward at 0.1 (still less than 0.294 bonus -> exploration still dominates). Scaling by 100,000x lifts reward to 100 (now exploration cannot influence anything; UCB collapses to greedy mean_reward). 1000x sits in the working zone where both terms contribute.
Kalibrierung, nicht Theorie
The 1000x factor is engineering calibration, not a theoretical constant. It depends on three things: training loss scale (cross-entropy on a vocabulary of 8K tokens runs near 4.5), per-step loss decay rate (slow), & UCB constant C=0.5. Change any of those, & 1000 might no longer be the right multiplier.
Über das Skalierungsfaktor nachdenken
Als Nächstes
Was Sie haben
Reward Attribution wandelt CUDA's Loss-Berichte in ein UCB-fähiges Signal in drei Operationen um: per-source EMA trackt Loss-Historie (alpha=0.1, langsam), reward = max(0, EMA - loss) clippt Negatives, & 1000x-Skalierung passt Belohnungsgröße an UCB-Explorationsbonus-Größe an.
Was bleibt
Böden & Epochenstrafen (Aktivität 79) wirken auf dem UCB-Output auf. Quellenböden garantieren minimale Abtastung für Prioritätsquellen unabhängig vom UCB-Rang. Epochenstrafen gewichten Quellen ab, die öfter gezogen wurden als sie Dokumente haben, und verhindern die Memorierung kleiner Datensätze, während große Datensätze frisch bleiben.
Referenz
ANDREA whitepaper, Abschnitt 3.3.