Média Móvel Exponencial
Uma Média Recente Suavizada
Uma média móvel exponencial (EMA) rastreia um valor ponderando amostras recentes mais que as antigas, com pesos decaíndo exponencialmente. Fórmula:
EMA(t) = (1 - alpha) EMA(t-1) + alpha value(t)
Onde alpha (o fator de suavização) está em (0, 1). ANDREA usa alpha = 0.1 para rastreamento de perda por fonte.
Termo por Termo
- value(t): observação mais recente. Para ANDREA, esta é a perda reportada pelo CUDA após uma passada forward em um documento da fonte k.
- EMA(t-1): valor anterior de EMA para a fonte k. Armazenado no estado proxy.
- alpha = 0.1: cada nova perda contribui 10%; o histórico acumulado contribui 90%.
- (1 - alpha) = 0.9: peso no histórico.
Por que EMA em vez de Média Simples
Uma média móvel simples pondera todos os passos igualmente. O passo 1 tem o mesmo peso que o passo 100.000. Isso funciona se os dados forem estacionários. As perdas da ANDREA NÃO são estacionárias: a capacidade do modelo cresce durante o treinamento, então a perda de uma fonte no passo 5.000 difere da sua perda no passo 50.000.
A EMA resolve isso. Os valores antigos de perda desaparecem exponencialmente. A EMA reflete a realidade recente, não uma média de condições iniciais.
Por Fonte
A ANDREA mantém uma EMA por braço (por fonte). Dezesseis braços = dezesseis EMAs. Cada passo atualiza apenas a EMA da fonte que foi puxada. As outras 15 EMAs permanecem congeladas até o próximo puxão delas.
Calcule um Passo de EMA
A Fórmula de Recompensa
Recompensa = Melhoria, Escalada
ANDREA define a recompensa por passo para o braço k como:
reward_k = max(0, EMA_k(t-1) - loss_k(t)) * 1000
Três partes:
1. EMA_k(t-1) - loss_k(t): melhoria. Se a nova perda vier abaixo da média móvel, a diferença é positiva: a fonte k performou melhor do que o esperado.
2. max(0, ...): corta melhorias negativas para zero. Se a nova perda vier pior que a EMA, nenhuma recompensa (mas também nenhuma penalidade).
3. \* 1000: escala para tornar o sinal comparável ao bônus de exploração UCB.
Por que max(0, ...)
Recompensas negativas empurrariam mean_reward(k) para baixo, enviesando o UCB contra braços cujas perdas flutuaram para cima. Mas flutuação é normal: um único documento difícil eleva a perda sem significar que a fonte é ruim. Cortar para zero trata a flutuação como 'sem informação' em vez de 'penalidade'.
Fontes podem ganhar recompensa zero repetidamente sem afundar. Seu ranking UCB continua impulsionado pelo bônus de exploração (alto quando n_k é pequeno) mais vitórias passadas.
O que o CUDA Relata
Cada passagem forward+backward, o kernel CUDA emite um registro:
{source: 'hermes3-general', doc_index: 4231, loss: 4.520}
O proxy recebe o registro, consulta a EMA para essa fonte, computa a recompensa, atualiza a EMA, alimenta a recompensa no acumulador mean_reward(k) do bandit.
Computar uma Recompensa
Combinando Recompensa com Bônus de Exploração
O Problema de Magnitude
Melhorias de perda por passo são pequenas. A perda cai de 4.521 para 4.520: diferença 0.001. De 4.520 para 4.518: diferença 0.002. Ao longo de uma execução de treinamento inteira, as diferenças brutas vivem aproximadamente em [0, 0.01].
Agora observe o bônus de exploração do UCB em C=0,5, com N=1000 e n_k=20:
0,5 sqrt(ln(1000) / 20) = 0,5 sqrt(6,91 / 20) = 0,5 * 0,588 = 0,294
O bônus opera em 0,294. A recompensa bruta opera em 0,001. O bônus é 300x maior que a recompensa. O argmax do UCB classifica quase inteiramente pelo bônus; mean_reward fornece essencialmente zero sinal.
Resultado sem escalonamento: o bandido da ANDREA escolhe o braço com o menor n_k a cada passo. Mean_reward é ignorado. O bandido se torna uma política de exploração pura.
A Solução: 1000x
Multiplique a recompensa bruta por 1000. Agora a recompensa fica em 1.0 (vs bruta 0.001). Compare com o mesmo bônus de exploração 0.294:
recompensa escalada 1.0 vs bônus 0.294 = recompensa lidera por 3.4x
Agora mean_reward domina o ranking UCB. A exploração adiciona nuances à cauda (braços raros ganham um impulso de 0.3), mas o corpo do ranking vem da recompensa observada.
Por que 1000 (e Não 10, e Não 100.000)
Correspondência de ordem de magnitude. Recompensas brutas ficam em ~10^-3. Bônus de exploração fica em ~10^0. A diferença é 10^3. Multiplique a recompensa bruta por 10^3 para cair na mesma faixa do bônus.
Escalonar por 100x deixa a recompensa em 0.1 (ainda menor que o bônus de 0.294 -> exploração ainda domina). Escalonar por 100.000x eleva a recompensa para 100 (agora a exploração não pode influenciar nada; UCB colapsa para a média gananciosa). 1000x fica na zona funcional onde ambos os termos contribuem.
Calibração, Não Teoria
O fator 1000x é uma calibração de engenharia, não uma constante teórica. Depende de três coisas: escala de perda de treinamento (entropia cruzada em um vocabulário de 8K tokens fica perto de 4.5), taxa de decaimento de perda por passo (lenta) & constante UCB C=0.5. Mude qualquer uma delas, & 1000 pode não ser mais o multiplicador certo.
Raciocinando Sobre o Fator de Escala
Próximo
O Que Você Tem
A atribuição de recompensa converte os relatórios de perda do CUDA em sinal pronto para UCB em três operações: rastreamento EMA por fonte acompanha o histórico de perda (alpha=0.1, lento), reward = max(0, EMA - loss) corta os negativos, & escalonamento 1000x iguala a magnitude da recompensa à magnitude do bônus de exploração UCB.
O Que Resta
Pisos & penalidades de época (atividade 79) operam sobre a saída do UCB. Pisos de fonte garantem amostragem mínima para fontes de prioridade independentemente do rank UCB. Penalidades de época reduzem o peso de fontes que foram puxadas mais vezes do que possuem documentos, prevenindo memorização de conjuntos de dados pequenos enquanto conjuntos de dados grandes permanecem frescos.
Referência
ANDREA whitepaper, seção 3.3.