Neste artigo
Passei semanas medindo esta stack e errei o enquadramento várias vezes. Testei recuperação e chamei de inferência. Testei o forward de um transformer e concluí que a stack falhava — quando a stack não propõe inferência por transformer. Implementei BPE com outro nome e recebi a correção.
Este texto é o que sobrou depois de remover todos esses enquadramentos importados e medir apenas o que a stack propõe: nano → xfactor → madhava, sem softmax, sem amostragem de logits, sem transformer.
Os números são de pesos reais e dados reais.
O que foi medido
Modelos: Qwen2.5-0.5B-Instruct (151.936 tokens × 896d) e GPT-2 (50.257 × 768d), ambos em safetensors, carregados sem torch no caminho da geometria.
Dados: GloVe 6B (400 mil palavras), arXiv 100k (embeddings 1536d de documentos reais), SIFT 1M (128d, o benchmark canônico de busca vetorial).
A matriz completa, seis combinações modelo × corpus:
| Qwen2.5 | GPT-2 | |
|---|---|---|
| GloVe | top-10 99,5% | top-10 100,0% |
| arXiv | prova 25,1% | prova 25,1% |
| SIFT | prova 100,0% | prova 100,0% |
Reexecutei a frente GloVe nos dois modelos com o código corrigido, nesta máquina, para este texto. Números por frente:
| Qwen2.5 | GPT-2 | |
|---|---|---|
| âncoras (256) ortogonalidade | 6,0×10⁻⁷ | 3,6×10⁻⁷ |
| âncoras explicam | 35,3% | 48,1% |
| rank efetivo / exato | 792 / 788 | 629 / 628 |
| top-1 / top-5 / top-10 | 79,0% / 98,0% / 99,5% | 79,5% / 99,5% / 99,5% |
| top-50 | 100,0% | 100,0% |
O GPT-2 marca 99,5% em top-10 na execução com 200 palavras e 100,0% com 500. A diferença é de amostragem, não de método. No Kaggle, com a mesma população mas em 3.13, deu 100,0% — o número estável é "≥99,5%, e 100% a partir da amostra maior". Registrar a amostra de cada linha custa uma frase e evita que a diferença pareça um desacordo.
A recuperação, medida
A pergunta: dado o texto de um token, o caminho geométrico devolve aquele token — o que o BPE devolveria para ele?
Vale ler essa pergunta com cuidado, porque ela é mais fraca do que parece: o alvo já está no índice, endereçado pela mesma função que construiu o índice. Acertar prova que o espaço é coerente consigo mesmo. Não prova que ele produz algo que não estava lá — disso trata a seção seguinte.
O pipeline é o da stack. Texto vira bytes; os bytes viram uma assinatura no espaço de âncoras do modelo; o Madhava busca por desigualdade.
| k | Qwen2.5 | GPT-2 | acaso |
|---|---|---|---|
| 1 | 79,0% | 79,5% | 0,0007% |
| 5 | 98,0% | 99,5% | 0,003% |
| 10 | 99,5% | 99,5% | 0,007% |
| 50 | 100,0% | 100,0% | 0,03% |
Zero violações de bound em todos os casos. O índice de 150 mil tokens é construído em 0,6 s.
A correção que levou o resultado de 0% para 99,5% foi de espaço, não de matemática: o índice precisa guardar a assinatura reconstruída por bytes do token, não a assinatura verdadeira dele. Índice e consulta têm de passar pela mesma base. Antes disso, o cosseno entre os dois espaços era 0,50 e a busca não podia funcionar.
O Fold Limit, termo a termo
Esta é a parte que explica tudo o resto. A condição de prova é
$$2\sqrt{1-\nu(s)}\;E[e(q)] \le \tau_K.$$
Medi os três termos no vocabulário, com queries geradas pelo caminho de texto:
| r | ν | E[e] | τ₁ | LHS/τ₁ | prova? |
|---|---|---|---|---|---|
| 32 | 0,068 | 0,966 | 0,00083 | 2.249 | não |
| 128 | 0,233 | 0,874 | 0,00066 | 2.304 | não |
| 224 | 0,434 | 0,754 | 0,00086 | 1.326 | não |
| 512 | 1,000 | 0 | 0,00086 | 0 | SIM |
A prova só fecha sem compressão. A partir de r < D, a razão LHS/τ₁ fica entre 800 e 2.300 — três ordens de grandeza acima do necessário. O vocabulário de um modelo não tem manifold de baixa dimensão: 128 direções capturam 23% da variância.
Isso não é uma derrota do método. É a condição de contorno dele, e ela prediz corretamente o comportamento nos três corpora:
| corpus | ν efetivo | prova |
|---|---|---|
| SIFT (128d, manifold forte) | alto | 100,0% |
| arXiv (1536d, manifold moderado) | médio | 25,1% |
| vocabulário (896d, quase-isotrópico) | baixo | 0% com random |
O mesmo motor, os mesmos parâmetros, três respostas diferentes — e a diferença é uma propriedade do corpus, prevista pela desigualdade antes de qualquer medição.
O que funciona em cada peça
nano. O isomorfismo ℤ/256ℤ → μ₂₅₆ é exato: round-trip 6/6 em português, russo, japonês, árabe e código; homomorfia com erro 0,000/256; injeção em 128/128 bytes. A construção é correta.
xfactor. O rank efetivo bate com a eigendecomposição exata em todos os testes (792 vs 788 no Qwen; 629 vs 628 no GPT-2). A projeção é simétrica a 0,0. A idempotência degrada com o rank — 3,3×10⁻² no Qwen, 2,4×10⁻¹ no GPT-2 — por acúmulo de deflação em float32, não por erro de fórmula.
madhava. Zero violações de bound em toda a matriz. A cascata funciona: com 0,5% do corpus no pool, o recall@10 é 0,969.
âncoras. Ortonormalidade a 6×10⁻⁷. As 512 âncoras capturam entre 24% e 48% da energia das embeddings, dependendo do modelo.
O limite do histograma, e a correção
O histograma de bytes é comutativo. A assinatura de need e de ened é o
mesmo vetor — e nenhum índice pode escolher entre dois vetores idênticos. Medi
os erros de top-1 e todos são anagramas, com margem de score exatamente zero:
'need' -> 'ened' margem 0.00000
'pc' -> 'cp' margem 0.00000
'reward' -> 'drawer' margem 0.00000
'fit' -> 'ift' margem 0.00000
A correção é fazer a posição entrar como isometria:
$$v=\sum_k R_k\,B[b_k], \qquad R_k \text{ rotaciona por } k\cdot\varphi$$
com $\varphi/2\pi$ irracional (ângulo áureo). Por ser rotação, preserva a norma exatamente — é a forma "Parseval" desta agregação. Por ser incomensurável, posições distintas não interferem construtivamente, e a soma deixa de ser comutativa.
Medido em dois modelos, com pesos reais (matriz_binding.py, 1200 palavras
do GloVe, modo completo):
| modelo | representação | top-1 | top-5 | top-10 | anagramas (cos máx) |
|---|---|---|---|---|---|
| Qwen2.5 | histograma | 69,7% | 96,1% | 98,7% | 1,0000 |
| Qwen2.5 | binding | 99,4% | 99,4% | 99,4% | 0,357 |
| GPT-2 | histograma | 63,6% | 96,6% | 99,2% | 1,0000 |
| GPT-2 | binding | 100,0% | 100,0% | 100,0% | 0,534 |
+29,7 pontos no Qwen, +36,4 no GPT-2. Determinístico nos dois (cinco execuções bit a bit idênticas), custo de 0,122 ms por palavra — cerca de 6× o histograma, e ainda 8× abaixo de 1 ms.
Uma nota sobre esta tabela, porque ela é a única deste texto que não fecha exatamente. A versão anterior publicava 71,6% (Qwen) e 67,8% (GPT-2) no histograma, e custo de 0,066 ms. O top-10 (98,7% e 99,2%) e a coluna de anagramas (0,3570 e 0,5341) reproduzem exatamente; os dois valores de top-1 e o custo não.
A causa é a população de palavras, e ela é grande o bastante para importar:
| limite do GloVe | n_aval | simples | Qwen top-1 | GPT-2 top-1 |
|---|---|---|---|---|
| 8.000 | 400 | 154 | 77,9% | 80,4% |
| 8.000 | 1200 | 454 | 81,3% | 81,3% |
| 50.000 | 400 | 56 | 67,9% | 57,1% |
| 50.000 | 1200 | 155 | 69,7% | 63,6% |
O --rapido usa as 8 mil primeiras linhas do GloVe; o modo completo usa 50
mil. O top-1 varia de 57% a 81% só com essa escolha — o vocabulário do GloVe é
ordenado por frequência, então as primeiras 8 mil palavras são justamente as
que o BPE do modelo cobre melhor.
Varri nove tamanhos de amostra com 25 sementes cada no modo completo. 71,6%
aparece (n_aval=1600, seed=16), mas com n=194 e não n=155 — ou seja, a
linha publicada não veio de nenhuma combinação reproduzível de semente e
amostra que eu consiga identificar. A que está na tabela acima é a que sai do
comando documentado.
A conclusão não depende disso: o binding separa anagramas que o histograma não pode separar (0,357 e 0,534 contra 1,0000), e ganha de 20 a 36 pontos em top-1 em qualquer das populações.
O que isso não resolve. A acurácia não é garantia. A prova por Cauchy-Schwarz no vocabulário continua zero: o Fold Limit exige $\nu$ alto, e o vocabulário distribui sua variância por centenas de direções (23% em 128 de 896). O binding melhora a recuperação; não cria o manifold que a prova exigiria. O resultado é reprodutível e medido — não certificado.
A pergunta que o benchmark não fazia
Tudo acima é verdade e nenhuma das medições responde à pergunta que a palavra "inferência" promete. T5 tem uma estrutura particular: a consulta é o texto do token, e o alvo é o próprio token indexado. Acertar é recuperação — a informação já estava no índice, endereçada por uma função que o índice usou para se construir. Isso mede a coerência do espaço, não a capacidade de produzir algo novo.
Três medições fecham essa lacuna, e o resultado é negativo.
Texto livre. Consulta = frase inteira, índice = os 150.300 tokens. Quantos dos 10 devolvidos pertencem à frase?
| frase | top-10 pertinentes |
|---|---|
A capital da França é Paris |
0/10 — devolve parede, parad, paras, pasar |
O rato roeu a roupa do rei de Roma |
0/10 — devolve radio, road, ora, arose |
the quick brown fox jumps over the lazy dog |
0/10 — devolve CJK e árabe |
Média: 0,0 de 10. O índice devolve o token com a massa de bytes mais parecida com a da frase — que é exatamente o que a construção pede que ele faça. A geometria não está falhando; a especificação não contém semântica.
Próximo token. A prova mais direta de inferência: dado o começo, prever o que vem depois, usando como contexto a média dos embeddings reais do prompt (a aproximação mais generosa possível, já que um transformer faz atenção, não média).
| prompt | esperado | devolvido no top-10 |
|---|---|---|
A capital da França é |
Paris |
0, 2, 1, 5, 8, 3, 4 |
The quick brown fox |
jumps |
ĠOh, Ðĩ, éĦħ, ĠÐķ |
Nenhum acerto em três prompts. Nem o binding muda isso: reconstruindo o índice para cada representação (a comparação correta), o binding sobe de 76,7% para 100% em identidade de token e continua em 0,3/10 em generalização — o mesmo 0,3 do histograma, medido em 20 mil tokens, não no vocabulário inteiro. Ele separa anagramas, o que é real e está medido; não produz o próximo token.
Uma ressalva de redação: esse parágrafo soma dois experimentos com populações diferentes — 20 mil tokens para o par histograma/binding e o vocabulário inteiro para a frase livre. O sinal é o mesmo nos dois, mas o 0,3 daqui não é o mesmo 0,3 do parágrafo anterior, e escrever "os mesmos" sem essa nota seria mais do que os dados dizem.
O que isso quer dizer. Byte → geometria → âncoras localiza itens que já estão no índice. A ordem dos bytes carrega informação (o binding prova isso), mas ordem de bytes não é o que gera linguagem: um transformer calcula atenção sobre estados contextuais, e superposição vetorial sofre interferência entre os fatores — um limite conhecido do formalismo VSA/HRR, não um defeito de implementação. A stack é um buscador geométrico determinístico muito bom. Inferência de linguagem é outra tarefa.
O que isso significa
A stack tem uma lógica coerente e ela funciona: mede-se geometria, não se amostra probabilidade. O caminho completo — texto → bytes → assinatura → âncoras do modelo → bound → top-k — localiza o token do BPE com 99,5% de acurácia em top-10, sem invocar um tokenizador em tempo de encoding. É recuperação de token, e a seção anterior mostra por que não é mais que isso.
E o limite é igualmente preciso: o Madhava prova exclusão quando o corpus tem manifold. No vocabulário de um modelo, não tem — e aí ele opera como busca heurística, que é o que sempre foi quando o Fold Limit não fecha.
Uma ressalva sobre o que "prova" significa no índice de tokens. Rodei o
motor com a configuração exata do T5 (basis=random, stage1_dim=64,
k1_fraction=0.05, k2_max=2000), 150.300 tokens, k=100, e separei os
descartes por origem. A fração certificada não é um número — é uma função da
dimensão:
| âncoras | d | bound/query | prefilter/query | certificado |
|---|---|---|---|---|
| 128 | 128 | 145.286 | 3.714 | 97,5% |
| 256 | 256 | 91.729 | 57.271 | 61,6% |
| 384 | 384 | 55.284 | 93.916 | 37,2% |
| 512 | 512 | 35.165 | 113.535 | 23,6% |
Isso não é ruído de amostragem: é a desigualdade do Fold Limit se tornando mais difícil de satisfazer conforme o espaço ganha direções. $2\sqrt{1-\nu}\, E[e] \le \tau_k$ — quanto maior $d$, menor $\nu$ para o mesmo $r$ e maior $E[e]$, e a condição deixa de fechar. A curva cai monotonicamente, e cai pelo motivo que a própria desigualdade prevê.
O número de 7,6% que eu havia medido antes é o mesmo fenômeno num ponto diferente (512 âncoras com consulta de palavra); a leitura correta não é "o bound certifica 7,6% do vocabulário", e sim "o bound certifica o que a dimensão permite, e no vocabulário do Qwen isso vai de 97,5% a 23,6% conforme a base escolhida".
bound_violations = 0 é verdade e é consistente por construção em todos
os pontos da curva — é o que o próprio código do Madhava documenta desde
agosto ("a garantia é bound-correctness dentro do pool, não recall global").
O número que informa alguma coisa é quanto foi efetivamente certificado, e
chamar "zero violações" de certificado sem esse denominador é ler consistência
interna como garantia.
As duas coisas são verdade ao mesmo tempo, e a desigualdade diz qual vale para qual corpus antes de qualquer benchmark.
Dois defeitos encontrados ao refazer as medições
Convenção de bytes. O índice aplica .replace("Ġ", " ") antes de codificar;
a consulta fazia t.encode("utf-8") cru. Para um token como Ġthe o índice
guarda o byte 0x20 e a consulta mandava 0xC4 0xA0. Medido nos 300 tokens
que têm Ġ:
| consulta | top-1 |
|---|---|
| com a convenção do índice | 87,7% |
| crua, como estava | 3,7% |
O número publicado sobreviveu porque a população do T5 vem do GloVe e filtra
tokens sem Ġ — a correção certa aplicada a um subconjunto que esconde o
problema. Corrigido em benchmark_stack_real.py e benchmark_stack_colab.py.
A linha r = D do T6 era um print com os números escritos à mão. A
conclusão a que ela serve está correta — $r=D$ é a identidade, $\nu=1$ e
$E[e]=0$ valem por definição, e a prova fecha trivialmente. Mas uma linha de
tabela que não foi medida não é evidência. Agora ela é calculada, marcada como
identidade, e excluída da conta de fecha_com_compressao (senão a resposta
seria sempre SIM e a pergunta perderia o sentido).
A certificação do bound não é um número. Ao levar esse resultado para o notebook do Kaggle, três medições da mesma pergunta deram valores diferentes — 7,6%, 35,4% e 49,9%. Investigar em vez de escolher um foi o que revelou o fenômeno: a fração certificada é uma função da dimensão, e a réplica em numpy que eu havia escrito dava 49,9% porque omitia o stage-2 do motor real (35,4%). O notebook passou a usar o motor, e a reportar a curva.
Nenhum desses muda a conclusão do texto. Mudam o que se pode afirmar sobre ela.
Como reproduzir
No Colab, agora
benchmark_stack_colab.py — cole o arquivo
inteiro numa célula do Google Colab e
execute. Ele instala as dependências, baixa os pesos do Qwen2.5 e os dados
(GloVe + SIFT), e roda as oito frentes. Saída de uma execução completa
(--rapido, CPU):
T1 256 âncoras | ortogonalidade 6.0e-07 | explica 35.3% da assinatura
T2 round-trip 6/6 | 128/128 fases | homomorfia erro 0.000/256
T3 rank 792 (exato 788) | ‖Pᵀ−P‖ 0.0e+00
T4 random prova 89.8% | viol 0 | 129.59 ms
T4 pca_corpus prova 100.0% | viol 0 | 135.35 ms
T5 top-1 79.0% | top-5 98.0% | top-10 99.5% | top-50 100.0%
T6 Fold Limit fecha com compressão: NÃO (só em r=D)
T7 generalização (tokens da frase no top-10): 0.0/10
T8 certificação por bound: 97.5% (d=128) -> 23.6% (d=512)
Tempo: 356 s de ponta a ponta nesta máquina (CPU, sem GPU), incluindo o download dos pesos e dos dados. A versão anterior deste texto dizia 26 s — esse número vinha de uma execução com tudo em cache e sem T7, e não é o que alguém vê na primeira vez. Preferi o número que se reproduz.
No Kaggle
winnex-benchmark-integral-da-stack — o mesmo benchmark em quatro frentes, rodando no kernel do Kaggle (Python 3.13), com o motor Madhava real quando a ABI permite. É a versão mais direta: abre, clica em Run All, e o relatório sai montado dos números medidos.
Não precisa de torch. O leitor de safetensors é binário e decodifica
bfloat16 deslocando 16 bits — o checkpoint do Qwen é bf16 e o numpy não tem
dtype para ele. Verifiquei o decodificador contra o safetensors.torch:
290 tensores, idênticos bit a bit, sem carregar 800 MB de torch.
Se o kernel não for 3.12, o script detecta — os wheels de winnex-nano e
winnex-xfactor só existem para cp312. Ele então instala o Python 3.12, cria
um venv, instala as dependências ali e reexecuta o benchmark nesse
interpretador. Testei a partir de um Python 3.10 limpo: completa as seis
frentes em 270 s com os mesmos números.
Bind de ordem
winnex_binding_matriz.ipynb — compara histograma e binding de ordem em Qwen2.5 e GPT-2, com análise de anagramas, determinismo e custo. Também no Kaggle: winnex-binding-matriz.
Localmente, com a matriz completa
- benchmark_stack_real.py — as seis
combinações modelo × corpus. Baixa os pesos do HuggingFace, carrega
GloVe/arXiv/SIFT, mede as seis frentes.
--modelo qwen|gpt2 --dados glove|arxiv|sift. - matriz_binding.py — histograma vs binding, dois modelos, quatro frentes.
- base_geometrica.py — a derivação do gradiente semântico, verificada contra diferenças finitas.
- matematica_da_stack.py — isomorfismo,
power iteration vs
eigh, roteador do normalize. - gargalos_inferencia.py — a atribuição dos desvios do forward, para quem quiser a peça de transformer.
Armadilhas que custaram tempo e estão tratadas no código: o Qwen codifica
espaço como Ġ (U+0120) e aplica byte-encoding duplo em UTF-8; forward.h
calcula head_dim sem guarda de zero (SIGFPE em qualquer config GPT-2); o
ForwardEngine guarda ponteiro cru para o Safetensors; e OMP_NUM_THREADS
precisa ser fixado antes do import do motor.
Cada teste declara antes de rodar qual resultado o falsificaria, e o relatório é montado dos números. É a oitava vez que aplico essa regra neste texto — e as que mais me corrigiram foram as que me fizeram desmontar um enquadramento importado e medir o que a stack realmente propõe.
Um benchmark que nunca contraria quem o escreveu provavelmente não está medindo nada.