A apostila 16 mostrou que a busca por energia não achava o mínimo e criou uma busca exata. Esta mede o que a busca exata faz com o texto, e o resultado aponta para outro lugar: a troca entre seguir o rumo e escrever algo plausível é decidida pela energia, não por onde se procura.
O gerador, no modo energia, escolhe cada token em dois passos. Primeiro monta uma lista curta de candidatos. Depois imagina, no espaço latente, para onde cada candidato levaria o texto, e dá a cada um uma energia com dois termos: o quanto o estado previsto se afasta do rumo pedido e o quanto o token é improvável segundo a própria cabeça de tokens.
A apostila 16 mostrou que a lista curta — os 8 tokens mais prováveis — muitas vezes não contém o token de menor energia: com γ = 0 isso acontece em todas as 96 posições medidas. A resposta foi um modo novo, todos, que calcula a energia de cada um dos 16.392 tokens do vocabulário e pega os de menor energia. Ficou uma pergunta, a primeira da lista de perguntas em aberto daquela apostila: achar o mínimo de verdade melhora o texto, ou só abaixa a energia?
A primeira medida saiu estranha. Com γ = 0,1, o modo todos deu afinidade ao rumo de 0,780, bem acima de tudo o que a apostila 12 tinha medido, mas com perplexidade 491; no modo energia sem cabeça de custo a perplexidade chegou a 2.098. A varredura da 16 dizia que, com γ = 0,1, o mínimo verdadeiro já está entre os 8 mais prováveis em 85% das posições. Uma busca que acha o mínimo não deveria produzir texto tão pior que a lista curta.
O motivo estava no código. A função que ordena o vocabulário (_todos_por_energia, em server/ours.py) usava só o termo do rumo e deixava de fora o termo γ · (−log model/inference.py com a energia inteira, não mudam.
A ordenação agora usa a energia inteira, a mesma que o inference.py mede. Todos os números abaixo são depois do conserto.
Para ver se o que importa é onde se procura, comparamos três conjuntos de busca, sempre escolhendo pela mesma energia:
todos);nucleo, com a massa em nucleus_mass.A ideia do núcleo era manter uma restrição de plausibilidade firme, como a da lista curta, e procurar o mínimo exato dentro dela.
| onde procura | γ | energia: afinidade | PPL | cabeça + estado real: afinidade | PPL | guardrail: dígitos | PPL |
|---|---|---|---|---|---|---|---|
| sem leme (livre) | — | 0,256 | 48,5 | 0,256 | 48,5 | 40,6% | 10,7 |
| política, top-8 | 0,1 | 0,200 | 19,8 | 0,355 | 36,7 | 27,6% | 26,1 |
| núcleo, 50% da massa | 0,1 | 0,450 | 694,5 | 0,480 | 84,2 | 0,0% | 75,6 |
| núcleo, 80% da massa | 0,1 | 0,351 | 421,8 | 0,476 | 83,4 | 0,0% | 247,2 |
| vocabulário inteiro | 0,1 | 0,351 | 421,8 | 0,476 | 83,4 | 0,0% | 247,2 |
| política, top-8 | 0 | 0,357 | 293,1 | 0,488 | 82,4 | 0,0% | 144,7 |
| núcleo, 50% da massa | 0 | 0,250 | 1.008,4 | 0,751 | 639,0 | 0,0% | 275,7 |
| vocabulário inteiro | 0 | 0,264 | 5.363,4 | 0,841 | 853,5 | 0,0% | 625,3 |
A coluna do meio, a da melhor configuração do leme (cabeça de custo aplicada ao estado real), é a que responde. As quatro linhas em negrito caem praticamente no mesmo ponto: afinidade entre 0,476 e 0,488, perplexidade entre 82 e 84. Três delas são as três buscas com γ = 0,1; a quarta é a lista curta de sempre com γ = 0. Procurar no núcleo ou no vocabulário inteiro, com γ = 0,1, leva o texto exatamente para onde já se chegava baixando o γ.
Dito de outro jeito: existe uma troca entre seguir o rumo e escrever texto plausível. Baixar o γ anda sobre essa troca; procurar melhor também anda sobre ela, e não a desloca. Nenhuma das buscas comprou mais rumo pelo mesmo preço em perplexidade.
Uma exceção pequena merece registro: no guardrail, o núcleo de 50% zera os dígitos com perplexidade 75,6, contra 144,7 da lista curta com γ = 0 e 247,2 do vocabulário inteiro. É uma medida de 3 sementes num prompt só, e vale como pista para repetir, não como resultado.
As linhas do núcleo de 80% e do vocabulário inteiro não são parecidas: são idênticas, até a terceira casa. Isso não é defeito; é o que duas medidas já feitas preveem juntas.
A primeira é a varredura de γ, feita com o model/inference.py sobre 96 posições do conjunto de validação. Ela diz com que frequência o token de menor energia está entre os
| γ | k = 1 | k = 8 | k = 32 | k = 128 | energia perdida no top-8 | ações a ≤ 5% |
|---|---|---|---|---|---|---|
| 0 | 0,0% | 0,0% | 0,0% | 9,4% | +35,9% | 35,5 |
| 0,01 | 0,0% | 2,1% | 10,4% | 21,9% | +22,4% | 43,0 |
| 0,02 | 1,0% | 9,4% | 24,0% | 47,9% | +13,8% | 40,4 |
| 0,05 | 21,9% | 61,5% | 83,3% | 92,7% | +3,9% | 11,1 |
| 0,1 | 33,3% | 85,4% | 97,9% | 100,0% | +1,2% | 4,1 |
| 0,2 | 56,2% | 96,9% | 100,0% | 100,0% | +0,1% | 2,3 |
| 0,5 | 83,3% | 100,0% | 100,0% | 100,0% | 0,0% | 1,5 |
| 1 | 90,6% | 100,0% | 100,0% | 100,0% | +0,0% | 1,4 |
A segunda é o tamanho do núcleo. A política do mini é plana: a probabilidade se espalha por muitos tokens.
| massa do núcleo | mediana | média | 90% das posições até |
|---|---|---|---|
| 50% | 71 | 198 | 572 |
| 80% | 2.017 | 2.148 | 4.427 |
| 90% | 5.367 | 5.079 | 8.062 |
| 95% | 8.818 | 8.253 | 10.996 |
Juntas, elas explicam o empate. Com γ = 0,1, o token de menor energia está entre os 128 mais prováveis em todas as posições. Um núcleo de 80% tem cerca de 2.000 tokens, e o de 95%, quase 9.000; os dois contêm os mesmos oito tokens de menor energia que o vocabulário inteiro. As buscas são diferentes, os candidatos que elas devolvem não são.
A tabela da §3 tem, então, uma leitura mais precisa do que "a lista curta é melhor". O que faz a lista curta produzir texto plausível é o corte por posição: nenhum token abaixo do oitavo mais provável entra. Os tokens que a energia prefere com γ = 0,1 estão quase sempre entre a 9ª e a 128ª posição da política — dentro de qualquer núcleo razoável, mas fora da lista curta —, e é deles que vem a perplexidade de 83.
O termo γ · (−log
Procurar melhor não desloca a troca entre rumo e plausibilidade. Com três buscas diferentes — a exata no vocabulário, a exata dentro do núcleo e a lista curta com γ menor —, o texto cai no mesmo ponto. O que decide onde o texto cai é a energia: com γ baixo ela considera barato o que a política acha pouco provável. A busca exata continua útil para medir quanto a lista curta deixa de fora (apostila 16); para gerar texto melhor, a peça a mexer é a energia.
| onde | o que mudou |
|---|---|
server/ours.py, _todos_por_energia | conserto: a ordenação do vocabulário usa a energia inteira, com γ · (−log |
server/ours.py, _nucleo_por_energia | modo de candidatos novo, nucleo (nucleus): busca exata só entre os tokens do núcleo da política; massa em nucleus_mass (padrão 0,95); a trajetória registra o tamanho do núcleo em cada passo |
model/modes.py | --candidates nucleo e --nucleus-mass |
mini com modelo de mundo ponta a ponta (wm1-sz1). A política dele é plana; num modelo maior, com política mais concentrada, o núcleo encolhe, e o empate da §4 pode não se repetir.pequeno da escada (15 §5), que tem política menos plana?As fontes das ideias usadas aqui. Os números foram medidos no projeto.
Medido na CPU em 17/09/2026. Dados em out/cpu_1709/.