O projeto inteiro, peça por peça, alinhado aos quatro padrões do modelo de mundo: joint-embedding, energia, regularização e controle preditivo — e o que ainda é híbrido, dito com número.
O slide "Recommendations to my fellow AI scientists" tem quatro linhas, cada uma um abandone X em favor de Y. Esta apostila é uma auditoria: para cada linha, qual peça do nosso código a implementa, qual chave a liga, e se já está medida. Onde o projeto ainda faz X e Y ao mesmo tempo, está escrito — porque a regra da casa é manter e melhorar, sem regressão, e não trocar o que funciona por uma promessa.
| Slide manda | Peça nossa | Chave | Estado |
|---|---|---|---|
| Abandonar generativo → joint-embedding |
O modelo de mundo prevê no espaço latente: Pred( |
--world --sigreg-z |
Híbrido. Rodadas wm* na fila. |
| Abandonar probabilístico → baseado em energia |
Na geração, os candidatos são reordenados por uma energia: guardrail (−log p, acumulado no futuro imaginado) + tarefa (1 − cos ao objetivo). O logit deixa de ser a decisão e vira um dos termos. | compass.mode = energy | gradiente | mpc |
Implementado. Medido só no controle sem WM (apostila 06, §4: o termo aditivo piora). |
| Abandonar contrastivo → regularizado |
Nunca houve par negativo aqui. O anticolapso é todo por regularização: cosseno na tabela, SigReg, VICReg, Barlow. | --reg-cos --sigreg --vicreg --sigreg-z |
Medido (apostila 03 e tabela do §5). |
| Abandonar RL → controle preditivo (MPC) "RL só quando o plano não dá o resultado previsto, para ajustar o modelo de mundo" |
Busca em feixe no latente é MPC em miniatura. E a segunda metade da frase virou um script: mede a surpresa (previsto × real), e corrige só o modelo de mundo, com o encoder congelado. O gerador não é tocado. | _planejar(), correct_world.py, /nosso/trajetoria |
Implementado; teste de fumaça no §4. |
A fala defende que prever símbolos não basta para construir um modelo de mundo. Mesmo assim, o nosso decodificador de tokens faz três coisas que o modelo de mundo sozinho não faz: produz texto (o latente não é legível), dá o guardrail −log p que impede o planejador de sair da distribuição, e é a única régua comparável com tudo que existe (bits/caractere). Tirar a cabeça de tokens hoje seria tirar o instrumento de medida. E há uma razão mais forte, que a entrevista dá (apostila 10, §3): a intratabilidade que motiva a JEPA vale para sinais contínuos; em texto, discreto e finito, o softmax sobre o próximo token é a distribuição sobre os futuros. O plano é invertê-la de papel — de decisão para termo de energia — e é isso que os modos energy e mpc já fazem.
O slide "Outlook" desenha uma JEPA hierárquica: encoders (meio-círculos), preditores condicionados a uma ação (setas verdes com o
abstrair() no nível 2 — média do bloco, opcionalmente corrigida por um encoder aprendido (--world-enc2). Verde = preditores condicionados à ação: no nível 1 a ação é o embedding do token candidato; no nível 2 é a intenção, a média dos embeddings do rumo que você escreveu. Vermelho = onde o previsto encontra o real: no treino é a MSE contra o piso de identidade; na geração é a energia que ordena os candidatos, e a surpresa que fica gravada. A seta tracejada é o planejamento hierárquico: o nível 2 imagina o próximo bloco, e esse ponto vira o alvo de curto alcance do nível 1 — em vez do objetivo final, longe demais para um horizonte de três tokens dizer algo.Um detalhe que custou um bug em potencial: o subobjetivo do planejador tem que passar pelo mesmo encoder de nível 2 que o treino usou. Se o treino aprendeu a prever sobre abstrair(z) e o planejador alimentar o mundo2 com a média crua, ele está planejando num espaço que nunca viu. Por isso abstrair() é um método do modelo, chamado dos dois lados, e não uma linha duplicada em cada script.
Até aqui o estado abstrato era a média do bloco. A média funciona — "níveis mais altos preveem mais longe com menos detalhe" sai de graça, porque a média descarta detalhe. Mas ela descarta sempre o mesmo detalhe. O slide desenha um encoder próprio no nível 2, e a versão nossa é a menor que faz sentido: uma correção residual mundo2 treina
# hierarquia com o encoder de nível 2 aprendido (rodada reg1-wm1n2e-sz1) .venv\Scripts\python.exe model\train.py --size mini --modern --world 1 --world-levels 2 --world-enc2 --sigreg-z 1 --data duelo_200mb --run duelo
Um encoder aprendido sobre um alvo que também é aprendido é a receita do colapso: mundo2 "acerta" sempre. O que segura é o SigReg nos estados de nível 1, que entram em abstrair — e o piso de identidade no relatório: se ganho_mundo2 for grande e a média crua também for, o encoder não fez nada; se o ganho vier com piso_mundo2 despencando, é colapso disfarçado de acerto.
Aconteceu. Na rodada wm1n2e-sz1 o piso do bloco caiu de 0,160 para 0,013 e o ganho do nível 2 de +0,072 para +0,006 — a mesma fração, numa escala treze vezes menor (apostila 11). A primeira correção tentada foi a que a receita prescreve para o nível 1: SigReg também nos estados abstratos (--sigreg-s2). Recuperou parte da escala (piso 0,013 → 0,068) ao preço de blocos consecutivos quase ortogonais e +11,32% no gerador — a receita do nível 1 não serve ao nível 2, que precisa de continuidade entre blocos. A segunda correção, só de escala (--world-enc2-norm), colapsou pela outra porta: com a norma fixada, todos os blocos foram para a mesma direção (cosseno 1,000). Três tentativas, três atalhos; a média crua é a abstração honesta neste orçamento, e o anticolapso certo para o nível 2 fica em aberto (apostila 11).
Da fala: "use DINO as an encoder, then train a world model and do planning". Não é o que o LeWorldModel faz (lá o encoder e o preditor aprendem juntos), e os dois estão certos para perguntas diferentes. O de dois estágios pergunta: o espaço de um encoder auto-destilado é melhor para prever do que um espaço treinado junto com o preditor? Para responder, precisamos treinar o modelo de mundo sobre um encoder congelado — e o nosso encoder DINO é a rodada reg1-lat1o-dino1.
# modelo de mundo sobre o encoder DINO, congelado (rodada wm-sobre-dino) .venv\Scripts\python.exe model\train.py --size mini --modern --world 1 --world-levels 2 --world-enc2 --sigreg-z 1 ^ --base mini-moderno-reg1-lat1o-dino1-duelo --freeze-encoder --data duelo_200mb --run duelo
Com o encoder congelado só sobram 532 mil parâmetros treináveis dos 7,9 milhões (os 7,4 M do mini mais as cabeças do modelo de mundo), e não há retropropagação pelo Transformer — a rodada custa uma fração. A perda de validação dessa rodada é, por construção, a da base: o gerador não mudou. O que se lê é a coluna wm ganho do relatório, contra a mesma coluna da rodada ponta a ponta.
A última linha do slide tem duas metades, e é a segunda que interessa aqui: "use RL only when planning doesn't yield the predicted outcome, to adjust the world model or the critic". Traduzido para o nosso sistema:
A bancada grava a surpresa token a token em toda geração de um modelo -wm, e mostra no painel «Antevisão · leme» da bancada a média, o piso e os picos. O script fecha o laço:
# mede a surpresa em texto real e no que o modelo gerou; --finetune corrige só o WM .venv\Scripts\python.exe model\correct_world.py --model mini-moderno-reg1-wm1n2-sz1-duelo --heading "futebol gol" --finetune
Ele salva o resultado como <modelo>-corrigido, um treino a mais na bancada. O original não é tocado. E mede antes e depois num conjunto separado — porque a armadilha óbvia é o mapa decorar as próprias trajetórias, que é a versão nossa do "overfitting do crítico" que a fala manda vigiar.
Antes de a rodada wm* terminar, o laço foi testado num modelo de mundo de dois passos de treino — quase aleatório, sobre o encoder de reg1-lat1o congelado. Não é um resultado científico; é a prova de que o mecanismo faz o que diz. A razão é surpresa ÷ piso de identidade: abaixo de 1, o mapa prevê melhor do que "copiar o estado".
| Fonte | Razão antes | Razão depois | Leitura |
|---|---|---|---|
| texto gerado pelo modelo (visto na correção) | 1,303 | 0,713 | o mapa era pior que a identidade; deixou de ser |
| teste separado | 0,907 | 0,719 | generalizou: caiu quase o mesmo tanto |
Dois avisos. Primeiro: um WM de dois passos tinha tudo a ganhar — a queda num modelo treinado de verdade será menor, e pode ser zero. Segundo: os picos de surpresa desse teste caíram todos em sequências de dígitos, porque o tokenizador separa dígitos (apostila 01) e um mapa quase aleatório não sabe nada de números. Num modelo treinado, os picos são a informação interessante: eles dizem onde o mapa está errado.
| Rodada | vs controle | O que diz sobre o alinhamento |
|---|---|---|
cosseno + bússola profunda (reg1-lat1o) | −0,90% | prever o estado seguinte no latente ajuda o gerador. Primeira rodada a bater o controle. Uma semente: cautela. |
SigReg na tabela (sig1) | +1,51% | posto efetivo 245,0 contra 244,8 do cosseno: não comprou nada aqui |
VICReg (reg1-vic1) | +2,88% | a melhor geometria da tabela — anisotropia 0,029, decorrelação 0,017 contra 0,061–0,070 das outras, posto 253,0 de 256 — ao maior custo de qualidade de todas. O termo de covariância faz o que promete, e isso não vira perda menor neste orçamento. |
| termo aditivo α na geração | — | pior que a identidade, pior que uma direção aleatória (apostila 06). Foi o que condenou a inferência aditiva e motivou o modo energia. |
wm1-sz1, wm1det, wm1n2-sz1, wm1n2z16-sz1 | na fila | a hipótese central: ganho do WM sobre o piso, e se SigReg-z segura o colapso sem EMA |
wm1n2e-sz1, wm-sobre-dino | na fila | as peças desta apostila: encoder de nível 2 aprendido e o padrão de dois estágios |
O lado direito do slide "Outlook" lista escalas — partículas, átomos, moléculas, materiais, objetos, sistemas — e pergunta se a JEPA hierárquica seria um jeito de construir modelos causais de qualquer sistema complexo. O outro slide dá o exemplo: uma turbina moderna tem mais de mil sensores; um A380, 25 mil, lidos 5 mil vezes por segundo.
Vale dizer com precisão o que isso tem a ver com um modelo de texto de 7,4 milhões de parâmetros. Uma coisa, e é estrutural: no nosso código, a única peça que sabe que a entrada é texto é o tokenizador. O encoder é um Transformer sobre uma sequência de vetores; o modelo de mundo é Pred(abstrair agrupa por blocos; a energia compara vetores. Nenhuma dessas quatro peças muda se a sequência vier de sensores em vez de tokens — a ação seria um comando do controlador em vez de um embedding de palavra, e o objetivo seria um estado desejado em vez de um rumo escrito. É por isso que a hierarquia foi construída como método do modelo, e não como truque do script de geração.
E o que não vale dizer: que o sistema atual faz isso. Ele tem dois níveis, blocos de tamanho fixo, e a ação de nível 2 é uma média — a versão mais simples de "intenção" que dá para medir. Um terceiro nível é um laço a mais sobre abstrair; um bloco de tamanho variável (fronteira de frase, de parágrafo) é a próxima pergunta séria. As duas entram depois que a fila responder se os dois níveis que existem ganham do piso.
Um piloto não planeja um voo em termos de ângulo de aileron milissegundo a milissegundo. Planeja em aeroportos, depois em rotas, depois em altitudes — e só no fim os comandos viram movimento de superfície. Cada nível tem o seu mapa, o seu "onde estou", o seu "para onde vou", e o nível de cima entrega o alvo ao de baixo. Nós temos dois níveis desse mapa: o token e o bloco. O que a apostila mostra é que o mecanismo de entregar o alvo para baixo existe e roda; se ele ajuda, é o número que a fila está produzindo.
--freeze-encoder), o SigReg nos estados não tem o que mover. O colapso dos estados fica impossível — eles são fixos — mas o preditor ainda pode achar a solução trivial de copiar As apostilas 04 e 05 esperam os números da fila. Esta existe para que, quando eles chegarem,
cada um caia numa caixa do diagrama — e não numa tabela solta.