Antevisão · Latent Rehearsal
14

Memória
consultada

A apostila 11 mediu que um vetor de memória persiste, mas dilui: o passado inteiro vale menos que cada metade. LeCun pede outra coisa — uma memória consultada, que sobrevive à janela e à sessão. Aqui ela vira um banco de estados abstratos lido por atenção, com um índice vetorial quantizado (turbovec) guardando o banco em disco.

Apostila 14 Pré-requisito: 11 (a memória somada) e 13 (memória-dropout)

1 O que a memória somada não faz

A memória da apostila 11 é um vetor m por sequência, atualizado a cada bloco que sai da janela: m ← m + f([m ; sbloco]). Ela persiste — a predição com a memória do texto certo ganha +0,019 sobre a memória de outro texto, mesmo uma janela inteira depois. Mas a mesma tabela mostrou o limite: "longa" (A+B) erra 0,181, pior que "recente" (só B, 0,173) e que "só antiga" (só A, 0,174). Um vetor de capacidade fixa não acumula: cada bloco novo sobrescreve parte do anterior. Quanto mais passado, menos de cada pedaço.

LeCun descreve outra peça. A palestra: "você pode ter de combinar a percepção com o conteúdo de uma memória para ter o estado completo do mundo". A entrevista: sistemas com "memória persistente, do tipo que nós temos". E o slide da arquitetura tem a memória como um módulo consultado pelo modelo de mundo, não como um somatório. A apostila 11 deixou isso escrito como pergunta em aberto: "a memória consultada, não só somada, exige atenção sobre um banco de estados abstratos, e é outra peça". Esta é a peça.

2 A peça: banco + atenção

Cada bloco de 8 tokens que sai da janela é abstraído pelo mesmo encoder de nível 2 (abstrair()) e guardado, não somado. O banco é o conjunto S = {s1, …, sn} desses estados. O modelo de mundo consulta o banco com uma chave projetada do estado atual, e lê o resultado por atenção:

q = Wq zt / √d   rt = softmax(q · ST) S   Pred(zt, at[, ζ][, m], rt) → zt+1

Três decisões, todas herdadas do que já foi medido. O encoder não recebe gradiente pelo banco (só Wq e o modelo de mundo aprendem a consultá-lo; a mesma regra da memória somada, pelo mesmo motivo: senão o encoder esconde o alvo no banco). O treino usa as janelas duplas da apostila 11: o banco de treino são os blocos do passado contíguo, e a atenção é exata sobre eles (no máximo 32 estados). E o banco-dropout de 0,5 já vem embutido — a lição da apostila 13: metade dos lotes com r = 0, para o preditor funcionar quando o banco está vazio, que é o caso de todo prompt curto.

A medida é a da apostila 11, transposta: ganho_banco = MSE(banco de outro texto) − MSE(banco certo), com a MSE do banco vazio ao lado. Zero quer dizer que a atenção não encontra nada útil no passado.

3 Por que um índice vetorial, e por que o turbovec

No treino o banco cabe numa multiplicação de matrizes. Na bancada, não: o banco cresce a cada bloco gerado ou lido, sessão após sessão, e a promessa da entrevista é que ele não seja apagado. Um milhão de blocos (oito milhões de tokens lidos) são 256 milhões de floats — um giga em fp32, e uma atenção exata sobre um milhão de estados a cada token. O que a atenção precisa de fato são os k maiores logits q · sj; o resto do softmax é desprezível. E "os k maiores produtos internos com uma consulta" é exatamente o que um índice vetorial devolve.

O turbovec é um índice em Rust com ligação Python que implementa o TurboQuant (Google Research, 2025): cada vetor é normalizado, passa por uma rotação aleatória fixa (que torna cada coordenada aproximadamente Beta, com a mesma distribuição em todas as dimensões), é quantizado por coordenada com um codebook Lloyd-Max de 4 bits (16 níveis) e empacotado — 256 dimensões viram 128 bytes, oito vezes menos que fp32 — e um escalar por vetor corrige o viés do produto interno estimado. A busca roda em SIMD sobre os códigos, sem etapa de treino nem ajuste de parâmetros: o banco ingere online, um bloco de cada vez, que é o regime da bancada. A gravação é incremental (sync escreve só o que mudou desde a última vez), o que faz a persistência custar milissegundos por geração. O que ele não devolve são os vetores — só ids e pontuações —, então os estados em fp32 ficam num arquivo ao lado, e a atenção é feita sobre os k recuperados de verdade.

O que o índice muda, para o banco de estados de 256 dimensões desta rodada. A busca exata é o que a atenção faria sem índice.
busca exata (numpy)turbovec, 4 bits
bytes por estado no índice1.024128
um milhão de blocos1,0 GB128 MB (+ 1,0 GB de estados em disco, lidos só os k)
custo por consultaproduto com o banco inteirobusca SIMD sobre códigos; top-k
etapa de treino do índice—nenhuma (rotação fixa + codebook pré-computado)
persistênciarescrever tudoincremental, durável a qualquer byte
a atenção usatodos os estadosos k recuperados, em fp32

A alternativa mais simples seria manter tudo em RAM e fazer a busca exata; ela fica disponível como fallback (mesma API, sem o turbovec instalado) e é a referência para medir o que a quantização custa em recall — a pergunta que a seção 5 deixa aberta.

4 A rodada

Rodada wm1n2bco-sz1, na mesma verba das outras: hierarquia com média crua (a abstração honesta da apostila 11), SigReg-z, banco com dropout 0,5, sem a memória somada (para medir a peça sozinha). Três perguntas: o banco carrega passado (ganho > 0)? o passado inteiro vale mais que cada metade (o que o vetor não conseguia)? e o leme governa nesse mapa, com o banco vazio — que é a condição da apostila 12?

Persistência, model/memory.py: 32 sequências de 3 × 256 tokens, predição na terceira janela, o banco montado de A, B ou A+B. Ao lado, a memória somada (rodada wm1n2mem-sz1, apostila 11) para comparação.
Fonte do passadomemória somada (mem)banco consultado (bco)ganho vs outra (bco)
zero / vazio0,2200,1748+0,0023
outra (A+B de outro texto)0,1930,17710
recente (só B)0,1730,1736+0,0035
longa (A+B)0,1810,1736+0,0036
só antiga (só A)0,1740,1738+0,0033
O custo, o ganho e o leme (report.py, modes.py γ = 0,1, cabeça "futebol10" + estado real, juiz reg1-lat1o).
Rodadavalidaçãocustoganho do mapaganho de memória / bancolivrecabeça + estado realgoverna?
wm1n2mem-sz1 (somada)5,6801+7,77%+0,93+0,0140,3430,258não
wm1n2mem-sz1-md0.5 (somada + dropout)5,6109+6,46%+0,92+0,0020,2240,301sim
wm1n2bco-sz1 (consultada)5,7695+9,73%+0,87+0,00360,3600,272não

O banco resolve a diluição, que era o defeito da memória somada. Na apostila 11, "longa" (A+B) errava 0,181, pior que "recente" (só B, 0,173): quanto mais passado, menos de cada pedaço, porque um vetor de capacidade fixa sobrescreve a si mesmo. No banco consultado, "longa" erra 0,1736 — exatamente igual a "recente", e ligeiramente melhor que "só antiga" (0,1738). Guardar em vez de somar elimina a diluição por construção: o bloco antigo continua lá, intacto, e a atenção escolhe. É o que a arquitetura do slide previa e o somatório não entregava.

E o banco carrega pouco. O ganho sobre a memória de outro texto é +0,0036, contra os +0,014 da memória somada da apostila 11 e os +0,002 da somada com dropout. A causa é a mesma dos dois casos anteriores, e está na receita: o banco-dropout de 0,5 ensina o preditor a funcionar sem banco, e ele aprende a não depender dele. A diferença é que aqui o dropout era obrigatório — todo prompt curto começa com o banco vazio —, então o compromisso não é um erro de calibração e sim a forma do problema. A rodada com dropout menor é o teste que falta.

O leme não governa neste mapa (0,272 com cabeça e estado real contra 0,360 livre), e o custo ao gerador é o mais alto da família, +9,73%. Somando: a memória consultada entrega o que prometeu na persistência — não dilui — e não entrega no resto. Pela régua de ruído da apostila 13 §12.3, o +9,73% é indistinguível dos +9,55% do mesmo mapa sem banco: o banco é de graça e quase não carrega. Fica na bancada como peça de infraestrutura, com o índice quantizado em disco pronto para um banco grande, e a pergunta sobre o dropout em aberto.

Como ler

O banco passa se "longa" ganha de "recente" e de "só antiga" — a atenção escolhe no passado inteiro em vez de diluí-lo — e se "vazio" fica neutro (o dropout fez o seu trabalho). Se o ganho do banco for zero, a atenção não achou estrutura no passado a 256 tokens de distância; a próxima régua é o mesmo experimento com passado mais longo (a bancada já o monta). Se o custo ao gerador for maior que o da memória somada, a atenção está cobrando; o que se compara então é ganho por ponto de custo.

5 Na bancada

Perguntas em aberto