Pular para o conteúdo
mnzes

Como o modelo converte token em vetor e vetor de volta em token?

PorDiógenes MenezesAprendendo IA em público

14 min de leitura

A camada de embedding é uma tabela de consulta: o id do token endereça uma linha de uma matriz grande, e essa linha é o vetor que entra no primeiro bloco. O unembedding faz o caminho de volta e não é uma tabela — ele compara o vetor que sai do último bloco com todas as linhas, uma a uma, e devolve um número por token do vocabulário. Em muitos modelos as duas pontas usam a mesma matriz.

São as duas fronteiras do modelo. Antes da primeira não existe vetor, só id de token, e o caminho até ali está em do texto ao token. Depois da segunda não existe mais vetor, só uma pontuação por token do vocabulário, e o que se faz com essa pontuação está em logits e logprobs. O percurso inteiro entre uma e outra é o assunto de como um LLM funciona por dentro.

Vale limpar uma confusão de nome antes de seguir. “Embedding” em busca vetorial é outra coisa: um vetor por frase ou por documento, produzido por um modelo treinado para que textos de sentido parecido fiquem perto, o embedding de recuperação. Aqui é um vetor por entrada do vocabulário, aprendido como efeito colateral de treinar o modelo a prever a próxima palavra. Os dois espaços não se substituem, e usar um no lugar do outro é um erro comum e caro.

As duas pontas, com a mesma matriz

id 5615matriz E151.936 linhas× 4.096 númeroslinha 5615= vetor de entradavetor doúltimo bloco151.936 logitsum por tokenindexa uma linhacompara com todasentradasaída
Figura 1Na entrada a matriz é lida por endereço, uma linha só. Na saída ela é percorrida inteira, e cada linha vira um número. Mesma tabela, custos opostos.

A matriz tem uma linha por entrada do vocabulário e uma coluna por dimensão do modelo. No Qwen3-8B são 151.936 linhas de 4.096 números cada, 622 milhões de pesos. É um dos poucos pedaços de um LLM que dá para descrever inteiro em uma frase.

Nos livros a entrada aparece como uma multiplicação de matrizes: o token vira um vetor com um 1 na sua posição e zero em todas as outras, e esse vetor multiplica a matriz. A conta funciona, e o resultado é exatamente a linha correspondente — os zeros anulam todo o resto. Nenhuma implementação faz isso. Seriam 151.936 multiplicações para ler uma linha que está num endereço conhecido. Na prática é um gather: pega a linha, pronto.

Uma sutileza do paper de 2017 sobrevive na maioria dos modelos de hoje. Depois de ler a linha, os valores são multiplicados pela raiz quadrada da dimensão do modelo1. Com 4.096 dimensões isso é um fator de 64. O paper registra a operação sem explicar o motivo; a leitura comum é que a mesma matriz precisa ter escalas diferentes nas duas pontas, e o fator ajusta a magnitude do lado da entrada sem mexer no da saída.

Na saída a lógica se inverte. O vetor que sai do último bloco é multiplicado por cada linha da matriz, e cada produto escalar vira um logit. Um número por token do vocabulário, 151.936 deles, calculados do zero a cada token gerado. Na entrada o custo é de um acesso à memória; na saída é de uma multiplicação contra a matriz inteira.

Essa assimetria explica a intuição geométrica do que o modelo está fazendo. O produto escalar é maior quando o vetor final aponta na direção da linha. Gerar texto, então, é empurrar um vetor até que ele aponte para a região do espaço onde mora o token certo. Todos os blocos do meio existem para isso: mover um ponto num espaço de alguns milhares de dimensões, um empurrão de cada vez.

O que cada bloco escreve, lido no vocabulário

Se a saída é um produto contra a matriz, dá para aplicar esse produto antes da última camada e ver o que o modelo estava prestes a dizer no meio do caminho. Isso funciona porque o vetor não é substituído a cada bloco: ele acumula somas ao longo do residual stream, e o que a matriz de saída lê no fim é a soma de tudo que foi escrito. A técnica ficou conhecida como logit lens, e é a base de boa parte da interpretabilidade prática.

Geva e colegas levaram a ideia a sério em 2022 e reinterpretaram a camada feed-forward inteira nesses termos. Tratando a representação de um token como uma distribuição sobre o vocabulário, cada camada vira uma atualização aditiva sobre essa distribuição, e cada atualização se decompõe em sub-atualizações correspondentes a vetores individuais de parâmetro — muitas delas promovendo conceitos que uma pessoa consegue nomear. Eles usaram isso para duas coisas concretas: reduzir a toxicidade do GPT-2 em cerca de metade e economizar 20% de computação com saída antecipada2.

O método tem um problema conhecido, e ele importa. Projetar uma camada intermediária com a matriz de saída assume que aquela camada já escreve na mesma base que a última, e isso não é verdade. Belrose e colegas mediram o desvio e propuseram uma correção: uma sonda afim treinada para cada bloco, que converte o estado escondido em distribuição sobre o vocabulário. Em modelos de até 20 bilhões de parâmetros, a versão calibrada ficou mais previsível, mais confiável e menos enviesada que o logit lens simples, e as trajetórias de previsão que ela produz identificam entradas maliciosas com boa precisão3.

Dar e colegas foram um passo além e mostraram que dá para projetar os próprios parâmetros do transformer no espaço do vocabulário, sem rodar o modelo, e ainda assim interpretá-los4. É a mesma ideia levada ao limite: a matriz de saída é o dicionário que traduz qualquer vetor interno em palavras.

Pesos amarrados

uma matriz sóentrada e saídapesos amarrados (tied)Qwen3-0,6B: 156 M de pesos,26% do modelo inteiro.A saída herda a geometriada entrada. Sem escolha.matriz de entrada622 M de pesosmatriz de saída622 M de pesospesos separadosQwen3-8B: 1,25 bi de pesos,15% do modelo inteiro.As duas pontas podemdiscordar. Custa o dobro.
Figura 2Amarrar as duas pontas economiza uma matriz inteira, o que só importa em modelo pequeno. O preço é a saída ficar presa à geometria da entrada.

A ideia de usar a mesma matriz nas duas pontas é de 2016 e vem de dois trabalhos independentes. Press e Wolf estudaram a matriz do topo de modelos de linguagem, mostraram que ela também é um embedding de palavras válido e recomendaram amarrar as duas; o ganho foi redução consistente de perplexidade, e em tradução automática o modelo caiu para menos da metade do tamanho sem perder desempenho5. Inan, Khosravi e Socher chegaram ao mesmo arranjo por outro caminho, partindo de um enquadramento teórico da função de perda em vez de uma observação empírica6. O transformer original já nasceu com os pesos compartilhados, citando o primeiro dos dois1.

O motivo de funcionar é razoável. As duas matrizes descrevem o mesmo conjunto de símbolos; treinar duas versões independentes gasta parâmetros para redescobrir a mesma estrutura duas vezes, e a versão da saída recebe sinal de treino muito mais concentrado nos tokens frequentes.

O que mudou desde então é a escala, e com ela a decisão. A família Qwen3, lançada em 2025, dá o exemplo mais limpo porque usa o mesmo vocabulário de 151.936 entradas em todos os tamanhos. Os modelos de 0,6B, 1,7B e 4B amarram os pesos; os de 8B e 14B não. A conta explica por quê. Com 1.024 dimensões, a matriz tem 156 milhões de pesos, e o modelo de 0,6B tem 0,44 bilhão de parâmetros fora dela. Amarrar economiza 26% do modelo inteiro. Com 4.096 dimensões, cada matriz tem 622 milhões de pesos, e as duas juntas são 1,25 bilhão dos 8,2 bilhões do modelo de 8B: 15%, contra 6,95 bilhões de parâmetros de verdade fazendo o trabalho.

Em modelo pequeno, portanto, amarrar é quase obrigatório: um quarto do orçamento de parâmetros iria para uma tabela de consulta. Em modelo grande a economia deixa de compensar a restrição, porque a geometria que serve para agrupar tokens parecidos na entrada não é a mesma que serve para separá-los na saída. Um exemplo direto: na entrada, interessa que as várias grafias de uma palavra caiam perto umas das outras; na saída, interessa distingui-las, porque só uma está certa naquele contexto.

O custo, em memória e em conta

A matriz de saída é o único lugar do modelo onde o vocabulário aparece na conta, e por isso ela se comporta diferente do resto.

Memória. No Qwen3-8B, 622 milhões de pesos em 16 bits ocupam 1,24 GB. Com as duas matrizes separadas, 2,5 GB antes de qualquer bloco. Não é o que domina a fatura de um modelo desse porte, mas é um número que costuma ser esquecido nas estimativas rápidas.

Computação por token. A passada de saída são 622 milhões de multiplicações acumuladas, cerca de 1,24 GFLOP. Uma passada completa do modelo de 8B fica na casa de 16 GFLOP, então a cabeça de saída sozinha responde por algo perto de 8% do custo de gerar um token. Para um modelo com o mesmo vocabulário e um décimo dos parâmetros, a mesma cabeça vira uma fatia bem maior.

O tensor de logits. Este é o que morde na prática. São 151.936 números por posição; em 32 bits, 594 KB. Uma posição só é irrelevante. Mas se você materializa os logits do prompt inteiro — o que acontece no treino, e em qualquer código que peça logprobs de toda a sequência — um contexto de 4.096 tokens vira um tensor de 2,5 GB, para uma requisição, antes do lote. É a razão de bibliotecas de treino calcularem a perda em fatias e de a maioria das APIs devolver logprobs só dos tokens gerados e só do topo da distribuição.

Onde isso falha

O posto da matriz limita o que pode ser dito. Os logits de todos os contextos possíveis formam uma matriz cujo posto não passa da dimensão do modelo, porque ela é o produto de dois fatores dessa largura. Yang e colegas formalizaram isso em 2017 como softmax bottleneck: se a distribuição verdadeira da linguagem exige posto maior, nenhum treino resolve, e a saída fica limitada por construção. Eles propuseram uma mistura de softmaxes e melhoraram o estado da arte em Penn Treebank e WikiText-2, para 47,69 e 40,68 de perplexidade7. O escopo é de modelos recorrentes de 2017, e a dimensão de hoje é muito maior; o argumento estrutural, porém, continua valendo.

Algumas palavras não conseguem ganhar. Demeter, Kimmel e Downey mostraram um efeito mais concreto do mesmo mecanismo. Como o logit é um produto escalar e a probabilidade sai de um softmax sobre esses produtos, palavras cujo vetor cai no interior do fecho convexo do espaço de embedding têm a probabilidade limitada superiormente pelas palavras que estão na casca8. Elas nunca podem ser a previsão mais provável, em contexto nenhum. Não é falta de treino: é geometria.

A ida e a volta não são inversas. É tentador ler a simetria da figura como “desfazer o embedding”, e não é. A ida é um endereçamento exato; a volta é uma comparação com todas as linhas, que devolve uma distribuição. Nada garante que passar um vetor de embedding pela saída recupere o token de origem, e a proximidade entre duas linhas não diz que o modelo confunde os dois tokens — só que os vetores apontam para direções parecidas.

A linha do embedding não sabe de contexto. No ponto em que a matriz é lida, o vetor de “banco” é o mesmo na frase sobre dinheiro e na frase sobre praça. Isso é por construção, e é o que distingue esse vetor daquilo que se chama de embedding em recuperação. Tratar as linhas da matriz de um LLM como representações semânticas de palavra é aplicar a elas uma expectativa que vem de word2vec e de trabalhos da mesma linhagem, que treinavam vetores especificamente com esse objetivo e mediam a qualidade em testes de similaridade sintática e semântica9. A matriz de um LLM foi otimizada para outra coisa.

Trocar o vocabulário quebra as duas pontas. Adicionar tokens exige redimensionar a matriz, e num modelo com pesos amarrados a linha nova entra na entrada e na saída ao mesmo tempo. Inicializar as linhas novas com ruído costuma degradar o modelo de imediato; a prática que funciona é partir da média das linhas existentes ou da média dos subtokens que compunham o termo antes.

O que fazer com isso

  1. Compare modelos por parâmetros não-embedding. É o número que prevê capacidade. Dois modelos de “0,6B” com vocabulários diferentes podem ter 30% de diferença no que de fato computa.
  2. Não use a matriz de um LLM como embedding de busca. Para recuperação, use um modelo treinado para isso. A distinção está em o que é um embedding.
  3. Peça logprobs só do que você vai usar. O tensor completo é de centenas de KB por posição, e quase toda API devolve apenas o topo da distribuição por padrão.
  4. Conte a matriz separadamente ao dimensionar memória de modelo pequeno. Em modelo de menos de 2 bilhões de parâmetros ela é uma fatia grande e some das estimativas feitas por regra de três.
  5. Ao expandir o vocabulário, inicialize a partir do que já existe. Média das linhas dos subtokens antigos, não ruído. E confira se o modelo amarra os pesos antes de mexer em uma das pontas.
  6. Ao ler logit lens de camada intermediária, desconfie. A projeção crua é enviesada; se a conclusão importa, use uma sonda calibrada por camada.

Footnotes

  1. Vaswani et al. (2017) descrevem, na seção 3.4, o compartilhamento da mesma matriz de pesos entre as duas camadas de embedding e a transformação linear anterior ao softmax, com os pesos da entrada multiplicados pela raiz quadrada da dimensão do modelo. 2

  2. Geva et al. (2022) trataram a representação de um token como distribuição sobre o vocabulário e mostraram que cada camada feed-forward é uma atualização aditiva decomponível em sub-atualizações interpretáveis; aplicaram o resultado para cortar cerca de metade da toxicidade do GPT-2 e economizar 20% de computação com saída antecipada.

  3. Belrose et al. (2023) treinaram uma sonda afim por bloco para converter estados escondidos em distribuição sobre o vocabulário e mostraram que ela é mais previsível, confiável e menos enviesada que o logit lens, em modelos de até 20 bilhões de parâmetros.

  4. Dar et al. (2022) propuseram interpretar os parâmetros do transformer projetando-os no espaço do vocabulário, sem passada para frente nem para trás, e aplicaram isso a alinhamento de parâmetros entre modelos que compartilham vocabulário.

  5. Press e Wolf (2016) mostraram que a matriz do topo de um modelo de linguagem é um embedding de palavras válido e que amarrá-la à matriz de entrada reduz perplexidade; em tradução automática, o modelo cai para menos da metade do tamanho sem perda de desempenho.

  6. Inan et al. (2016) chegaram ao mesmo compartilhamento por um enquadramento teórico da função de perda, argumentando que treinar contra alvos one-hot desperdiça informação e parâmetros.

  7. Yang et al. (2017) formularam modelagem de linguagem como fatoração de matriz e mostraram que o softmax sobre embeddings distribuídos limita o posto da matriz de logits, propondo uma mistura de softmaxes que levou a perplexidade a 47,69 no Penn Treebank e 40,68 no WikiText-2.

  8. Demeter et al. (2020) mostraram, por análise numérica, teórica e empírica, que palavras no interior do fecho convexo do espaço de embedding têm a probabilidade limitada pelas palavras da casca, o que as impede estruturalmente de serem a previsão mais provável.

  9. Mikolov et al. (2013) propuseram duas arquiteturas para aprender vetores contínuos de palavra a partir de corpora muito grandes, com ganho de qualidade a custo computacional bem menor, medido em um conjunto de teste de similaridade sintática e semântica.

Perguntas frequentes

O que é a matriz de embedding de um LLM?
É uma tabela com uma linha por entrada do vocabulário e uma coluna por dimensão do modelo. O id que sai do tokenizador é o número da linha, e essa linha é o vetor que entra no primeiro bloco. Ela é aprendida no pré-treino junto com o resto dos pesos.
O que são tied embeddings?
É usar a mesma matriz na entrada e na saída, em vez de duas independentes. Economiza vocabulário vezes dimensão pesos, o que em modelo pequeno é um quarto do total. O custo é que a geometria boa para agrupar tokens na entrada nem sempre é a boa para separá-los na saída.
A cabeça de saída de um LLM é uma tabela de consulta?
Não. Na entrada há endereçamento: um id, uma linha. Na saída há comparação: o vetor final é multiplicado por todas as linhas do vocabulário e cada produto vira um logit. É a diferença entre ler uma posição da memória e varrer a matriz inteira a cada token gerado.
O embedding de um LLM serve para busca vetorial?
Mal. As linhas da matriz representam tokens isolados e sem contexto, e foram otimizadas para prever a próxima palavra. Modelos de recuperação produzem um vetor por trecho de texto, treinados para que trechos com sentido parecido fiquem perto. São espaços diferentes com objetivos diferentes.
Por que o vetor de entrada de um token é sempre o mesmo?
Porque nesse ponto o modelo ainda não olhou para o resto da frase. A matriz é indexada por id, e o id de "banco" é o mesmo em qualquer frase. A diferenciação por contexto acontece depois, nos blocos de atenção, que somam ao vetor informação vinda das outras posições.
Quanto de um modelo é matriz de embedding?
Depende do tamanho. No Qwen3-0,6B a matriz amarrada tem 156 milhões de pesos, 26% do modelo. No Qwen3-8B, com as duas matrizes separadas, são 1,25 bilhão de pesos, 15% do total. Em modelo pequeno a tabela de consulta é uma fatia grande do orçamento.

Referências

  1. Vaswani, A. et al.. Attention Is All You Need (2017)arXiv:1706.03762
  2. Mikolov, T.; Chen, K.; Corrado, G.; Dean, J.. Efficient Estimation of Word Representations in Vector Space (2013)arXiv:1301.3781
  3. Press, O. e Wolf, L.. Using the Output Embedding to Improve Language Models (2016)arXiv:1608.05859
  4. Inan, H.; Khosravi, K.; Socher, R.. Tying Word Vectors and Word Classifiers: A Loss Framework for Language Modeling (2016)arXiv:1611.01462
  5. Geva, M.; Caciularu, A.; Wang, K. R.; Goldberg, Y.. Transformer Feed-Forward Layers Build Predictions by Promoting Concepts in the Vocabulary Space (2022)arXiv:2203.14680
  6. Belrose, N. et al.. Eliciting Latent Predictions from Transformers with the Tuned Lens (2023)arXiv:2303.08112
  7. Yang, Z.; Dai, Z.; Salakhutdinov, R.; Cohen, W. W.. Breaking the Softmax Bottleneck: A High-Rank RNN Language Model (2017)arXiv:1711.03953
  8. Demeter, D.; Kimmel, G.; Downey, D.. Stolen Probability: A Structural Weakness of Neural Language Models (2020)arXiv:2005.02433
  9. Dar, G.; Geva, M.; Gupta, A.; Berant, J.. Analyzing Transformers in Embedding Space (2022)arXiv:2209.02535