Por Que os Pisos Existem
Uma Sequência Ruim de Recompensas Pode Famintar uma Fonte de Prioridade
O bandit da ANDREA escolhe braços de foco pela classificação UCB1. A classificação UCB depende de mean_reward(k), que depende de melhorias de perda observadas. Uma sequência de documentos de alta perda de uma fonte de prioridade (digamos dictionary) pode arrastar mean_reward(k) para baixo. Agora dictionary classifica baixo, recebe poucas puxadas de foco, & seu mean_reward(k) não pode se recuperar (sem puxadas = sem observações frescas).
O mesmo risco se aplica a qualquer fonte que o designer de treinamento da ANDREA queira na mistura independentemente do sinal de recompensa de curto prazo.
Pisos como Pesos Mínimos
A configuração de treinamento do ANDREA especifica um piso por fonte: um peso de amostragem mínimo que a fonte recebe independentemente do que a saída UCB diz. Os pisos variam de 0.0 a 1.0. Exemplos:
hermes3-general piso = 0.8 (fonte prioritária conversacional)
chat piso = 0.8
dictionary piso = 0.7 (andaime para recall factual)
gutenberg piso = 0.7 (coerência de prosa)
chat sintético floor = 0.0 (sem floor; bandit decide livremente)
Como os Floors São Aplicados
Após o UCB1 classificar os braços e o controle de dados montar os conjuntos de foco, cada fonte recebe um peso provisório. Então, a aplicação do floor é executada:
final_weight_k = max(tentative_weight_k, floor_k)
Se o bandit atribuiu peso 0.3 a hermes3-general, mas seu floor é 0.8, o floor prevalece: peso final = 0.8. A voz do bandit é sobrescrita apenas para cima; nunca para baixo.
Diferentes Configs, Diferentes Floors
ANDREA envia várias configurações de treinamento: chatbot, tool-caller, bash-commander. Cada config define diferentes floors para suas fontes de prioridade. Chatbot floors hermes3-general & chat alto. Tool-caller floors repo-docstrings mais alto. Bash-commander floors repo-commits mais alto. Mesmo algoritmo, diferentes prioridades.
Aplicar um Floor
O Risco de Memorização
Fontes Pequenas São Memorizadas
As fontes de dados do ANDREA variam muito em tamanho. synthetic-chat tem cerca de 1.400 documentos. gutenberg tem mais de 500.000. Se o bandido puxar uniformemente, synthetic-chat esgota seu pool de documentos rapidamente: após 1.400 puxadas, todo documento foi visto pelo menos uma vez. Puxe 2.800 vezes & todo documento foi visto pelo menos duas vezes em média.
Exposição repetida a um pequeno conjunto de documentos leva à memorização: o modelo para de aprender padrões generalizáveis e começa a recitar sequências específicas de tokens dos dados de treinamento. A memorização é ruim por duas razões: (1) desperdiça capacidade em recall mecânico em vez de generalização, & (2) pode vazar dados de treinamento através da geração.
Épocas Como um Proxy de Memorização
Defina uma época sobre a fonte k como uma passagem completa por todos os documentos de k:
epochs_k = floor(lifetime_pulls_k / n_docs_k)
Se synthetic-chat (n_docs=1400) foi puxado 2.800 vezes, epochs = floor(2800/1400) = 2: a fonte foi vista duas vezes completamente. Se gutenberg (n_docs=500.000) foi puxado 100.000 vezes, epochs = floor(100000/500000) = 0: ainda não uma passagem completa.
A Penalidade 1/(1+epochs)
Quando lifetime_pulls / n_docs > 1.0, ANDREA aplica uma penalidade multiplicativa:
penalty = 1 / (1 + epochs)
final_weight = bandit_weight * penalty
Curva:
| épocas | penalidade | redução de peso |
|---|---|---|
| 0 | 1.000 | nenhuma |
| 1 | 0.500 | metade |
| 2 | 0.333 | um terço |
| 3 | 0.250 | um quarto |
| 5 | 0.167 | um sexto |
| 10 | 0.091 | um décimo primeiro |
A penalidade cresce com cada passagem concluída. Após muitas épocas, o peso da fonte se aproxima de zero & o bandit naturalmente a descansa.
Por Que as Trações Vitalícias Persistem em Reinicializações
As execuções de treinamento da ANDREA duram dias. Crashes acontecem. Servidores reiniciam. Configurações são ajustadas & o treinamento é retomado de um checkpoint. As trações vitalícias persistem em todos esses eventos: o proxy escreve as contagens de trações no disco continuamente.
Se as trações fossem resetadas em cada reinicialização, uma fonte pequena poderia efetivamente resetar para a época 0 toda vez que o treinamento reinicia. A penalidade nunca se acumularia, & a memorização prosseguiria independentemente. Persistir as trações vitalícias torna a penalidade uma restrição real, de crescimento monotônico.
Calcule uma Penalidade de Época
Fechando a Pilha de Currículo Bandit
O Que Você Tem
Os floors garantem amostragem mínima para fontes de prioridade: final_weight = max(bandit_weight, floor_k). As penalidades de época limitam a memorização em fontes pequenas: quando lifetime_pulls/n_docs > 1, o peso é multiplicado por 1/(1+epochs). As puxadas vitalícias persistem entre reinicializações, então a penalidade se torna uma restrição monotônica, não um contador reiniciável.
O Pipeline Completo
Juntando todas as quatro atividades do bandido ANDREA (76-79):
1. Atividade 76 (UCB1). Cada passo calcula UCB(k) = mean_reward(k) + 0.5 * sqrt(ln(N)/n_k). Argmax escolhe um braço.
2. Atividade 77 (fases de dados). Limites de fase (a cada 7 a 42 passos) rolam dados para contagem de braços de foco. Braços aleatórios primeiro, UCB preenche o resto. 25-33% das fases rodam totalmente aleatórias.
3. Atividade 78 (atribuição de recompensa). CUDA reporta perda; EMA por fonte rastreia histórico; recompensa = max(0, EMA - perda) * 1000. Recompensa escalada alimenta mean_reward(k).
4. Atividade 79 (pisos & épocas, esta lição). Após saída UCB, pisos elevam fontes de prioridade; penalidades de época reduzem peso de fontes memorizadas. Puxadas vitalícias persistem.
Juntos: um bandido que se adapta (UCB1), explora de forma confiável (fases de dados), obtém sinais de recompensa honestos (escalonamento 1000x), respeita prioridades de design de treinamento (pisos), & evita memorização (penalidade de época).
Referência
Whitepaper da ANDREA, seções 3.5 & 3.6.