Exponentiellt glidande medelvärde
Ett utjämnat nyligt medelvärde
Ett exponentiellt glidande medelvärde (EMA) spårar ett värde genom att väga nyliga prover tyngre än gamla, med vikter som avtar exponentiellt. Formel:
EMA(t) = (1 - alpha) EMA(t-1) + alpha value(t)
Där alpha (utjämningsfaktorn) ligger i (0, 1). ANDREA använder alpha = 0.1 för spårning av förlust per källa.
Term för term
- value(t): senaste observationen. För ANDREA är detta förlust rapporterad av CUDA efter en framåtpassning på ett dokument från källa k.
- EMA(t-1): tidigare EMA-värde för källa k. Sparad i proxy-tillstånd.
- alpha = 0.1: varje ny förlust bidrar med 10 %; den rullande historiken bidrar med 90 %.
- (1 - alpha) = 0.9: vikt på historiken.
Varför EMA istället för enkel medelvärde
Ett enkelt glidande medelvärde ger varje steg lika stor vikt. Steg 1 har samma vikt som steg 100 000. Det fungerar om datan är stationär. ANDREA:s förluster är INTE stationära: modellkapaciteten växer under träningen, så en källas förlust vid steg 5 000 skiljer sig från dess förlust vid steg 50 000.
EMA löser detta. Gamla förlustvärden bleknar exponentiellt. EMA:n speglar den senaste verkligheten, inte ett genomsnitt av initiala förhållanden.
Per källa
ANDREA underhåller en EMA per arm (per källa). Sexton armar = sexton EMAs. Varje steg uppdaterar endast EMA:n för den källa som drogs. De andra 15 EMAs förblir frysta tills deras nästa drag.
Beräkna en EMA-steget
Belöningsformeln
Belöning = Förbättring, Skalad
ANDREA definierar perstegsbelöning för arm k som:
reward_k = max(0, EMA_k(t-1) - loss_k(t)) * 1000
Tre delar:
1. EMA_k(t-1) - loss_k(t): förbättring. Om den nya förlusten kommer in under det glidande genomsnittet är skillnaden positiv: källan k presterade bättre än förväntat.
2. max(0, ...): klipp negativa förbättringar till noll. Om den nya förlusten kommer in sämre än EMA, ingen belöning (men ingen straff heller).
3. \* 1000: skala upp för att göra signalen jämförbar med UCB-utforskningsbonusen.
Varför max(0, ...)
Negativa belöningar skulle sänka mean_reward(k), vilket skulle biasa UCB mot armar vars förluster fluktuerade uppåt. Men fluktuation är normalt: ett enskilt svårt dokument höjer förlusten utan att det betyder att källan är dålig. Klippning till noll behandlar fluktuation som 'ingen information' snarare än 'straff'.
Källor kan tjäna noll belöning upprepade gånger utan att sjunka. Deras UCB-rankning drivs fortfarande av utforskningsbonusen (hög när n_k är liten) plus tidigare vinster.
Vad CUDA rapporterar
Varje framåt+bakåt-pass emiteterar CUDA-kärnan en post:
{source: 'hermes3-general', doc_index: 4231, loss: 4.520}
Proxy tar emot posten, slår upp EMA för den källan, beräknar belöning, uppdaterar EMA, matar in belöningen i banditens mean_reward(k)-ackumulator.
Beräkna en belöning
Matcha belöning till explorationsbonus
Magnitudproblemet
Förbättringar i loss per steg är små. Loss sjunker från 4.521 till 4.520: skillnad 0.001. Från 4.520 till 4.518: skillnad 0.002. Över hela en träningskörning lever råa skillnader ungefär i [0, 0.01].
Titta nu på UCB:s explorationsbonus vid C=0.5, med N=1000 & n_k=20:
0.5 sqrt(ln(1000) / 20) = 0.5 sqrt(6.91 / 20) = 0.5 * 0.588 = 0.294
Bonusen ligger på 0.294. Den råa belöningen ligger på 0.001. Bonusen är 300x större än belöningen. UCB:s argmax sorterar nästan helt efter bonusen; mean_reward ger i princip noll signal.
Resultat utan skalning: ANDREA:s bandit väljer armen med minsta n_k varje steg. Mean_reward ignoreras. Banditen blir en ren explorationspolicy.
Lösningen: 1000x
Multiplicera rå belöning med 1000. Nu ligger belöningen på 1.0 (mot rå 0.001). Jämför med samma explorationsbonus 0.294:
skalad belöning 1.0 mot bonus 0.294 = belöning leder med 3.4x
Nu dominerar mean_reward UCB-rankningen. Utforskning lägger till nyanser i svansen (sällsynta armar får en boost på 0.3), men kroppens rankning kommer från observerad belöning.
Varför 1000 (och inte 10, och inte 100 000)
Magnitudsordning som matchar. Rå belöningar ligger runt ~10^-3. Explorationsbonusen ligger runt ~10^0. Skillnaden är 10^3. Multiplicera rå belöning med 10^3 för att hamna i samma intervall som bonusen.
Skalning med 100x lämnar belöningen på 0,1 (fortfarande mindre än 0,294 bonus -> exploration dominerar fortfarande). Skalning med 100 000x höjer belöningen till 100 (nu kan exploration inte påverka något; UCB kollapsar till girig medelbelöning). 1000x ligger i det fungerande området där båda termerna bidrar.
Kalibrering, inte teori
1000x-faktorn är ingenjörskalibrering, inte en teoretisk konstant. Den beror på tre saker: träningsförlustskala (korsentropi på ett ordförråd med 8K tokens ligger nära 4,5), förlustnedbrytningshastighet per steg (långsam) & UCB-konstant C=0,5. Ändra någon av dessa, & 1000 kanske inte längre är rätt multiplikator.
Resonemang om skalningsfaktorn
Vad kommer härnäst
Vad du har
Belöningsattribution omvandlar CUDA:s förlustrapporter till UCB-redo signal i tre operationer: per-källans EMA spårar förlusthistorik (alpha=0.1, långsam), belöning = max(0, EMA - förlust) klipper negativa, & 1000x skalning matchar belöningsmagnitud till UCB explorationsbonus magnitud.
Vad som återstår
Golv & epokstraff (aktivitet 79) fungerar ovanpå UCB-utdata. Källgolv garanterar minimalsampling för prioriterade källor oavsett UCB-rankning. Epokstraff nedväger källor som har dragits fler gånger än de har dokument, vilket förhindrar memorering av små datamängder samtidigt som stora datamängder hålls färska.
Referens
ANDREA whitepaper, avsnitt 3.3.