Pular para o conteúdo
mnzes

O que acontece dentro de um LLM entre o prompt e a resposta?

PorDiógenes MenezesAprendendo IA em público

15 min de leitura

Entre o prompt e a resposta o modelo faz sempre a mesma coisa, na mesma ordem: quebra o texto em tokens, transforma cada token em um vetor, passa esses vetores por dezenas de blocos que os reescrevem, converte o resultado em uma pontuação para cada token do vocabulário e sorteia um. Depois repete tudo, com o token sorteado no fim da entrada.

Nada nesse percurso é decisão sobre o que fazer a seguir. A sequência de operações é fixa e vale para qualquer entrada; o que muda são os números que passam por ela. É a arquitetura transformer, descrita em 2017 para tradução automática1, e o esqueleto mudou pouco desde então.

Este artigo percorre o caminho inteiro uma vez, sem matemática. Cada etapa tem um artigo próprio no guia — o residual stream, que costura os blocos, e o bloco de atenção por dentro. Se a pergunta ainda é o que é um modelo de linguagem, comece por lá.

textotokensN blocosatenção + MLPpontuação para cadatoken do vocabuláriopróximo tokentokenizaçãoembeddingunembeddingamostragem
Figura 1A sequência é fixa e vale para qualquer prompt. Só a última etapa, a amostragem, não é determinística — o resto é sempre a mesma conta.

Do texto ao token

O modelo não lê letras. Antes de qualquer conta, um tokenizador quebra o texto em pedaços de um vocabulário fechado, com dezenas a centenas de milhares de entradas, e devolve a posição de cada pedaço nesse vocabulário. É uma tabela de consulta, não uma rede neural: o mesmo texto sai sempre na mesma lista de números.

O vocabulário é construído uma vez, antes do treino, quase sempre por alguma variante de byte pair encoding. A ideia veio da tradução automática, onde as palavras raras quebravam o modelo: em vez de um vocabulário de palavras inteiras com um símbolo genérico para “desconhecido”, junte os pares de caracteres mais frequentes do corpus até chegar ao tamanho desejado2. Palavra comum vira um token só, palavra rara vira três ou quatro pedaços, e nada fica de fora, porque no pior caso sobram os bytes.

Três consequências que aparecem no dia a dia:

  • Contar letra é difícil para o modelo. “Morango” pode chegar como um único símbolo. Perguntar quantos “r” tem é pedir para inspecionar algo que ele nunca recebeu separado.
  • Espaço faz parte do token. “ casa“ e “casa” costumam ser entradas diferentes do vocabulário, e é por isso que um prompt colado com espaçamento estranho às vezes muda o resultado.
  • Português gasta mais tokens que inglês. Os vocabulários mais usados foram ajustados em corpora majoritariamente em inglês, então acento e flexão viram mais pedaços. O mesmo parágrafo traduzido cobra mais caro.

Do token ao vetor

Cada id do tokenizador indexa uma linha de uma tabela grande, e essa linha é um vetor de alguns milhares de números. É o embedding, e é o único ponto do modelo em que um token tem representação fixa: aqui o vetor de “banco” é o mesmo, quer a frase seja sobre dinheiro ou sobre praça.

Falta a posição. A atenção, sozinha, não distingue ordem — para ela um conjunto de vetores é um conjunto. O paper de 2017 resolveu somando ao vetor um padrão de senos e cossenos, um por posição1. Os modelos mais recentes codificam posição de outra forma, dentro do próprio bloco de atenção, mas o efeito é o mesmo: a rede passa a saber quem veio antes de quem.

O bloco: atenção e feed-forward

Daí em diante o modelo aplica o mesmo bloco N vezes. N está na casa das dezenas, de trinta e poucos em modelos pequenos a mais de oitenta nos grandes. Todos os blocos têm a mesma forma e pesos diferentes.

Dentro de cada bloco há duas operações, nesta ordem: atenção, que move informação entre posições, e feed-forward (ou MLP), que trabalha cada posição isolada.

O detalhe que organiza o resto: nenhuma das duas substitui o vetor. Cada uma calcula uma correção e a soma ao que já estava lá. Esse vetor que atravessa o modelo inteiro recebendo somas é o residual stream. Pense nele menos como um cano por onde a informação passa e mais como um quadro branco: cada bloco lê o que está escrito, acrescenta um pedaço e passa adiante. O que o primeiro bloco anotou continua acessível no último.

O que a atenção faz

Em cada posição o modelo monta três vetores a partir do que está no residual stream: uma consulta (query), uma chave (key) e um valor (value). A consulta de uma posição é comparada com a chave de todas as posições anteriores; quanto mais parecidas, mais peso. O resultado é uma média dos valores, ponderada por esses pesos, somada de volta ao stream.

Traduzindo: a posição atual pergunta “o que aqui atrás importa para mim?” e puxa. É o mecanismo que faz um pronome achar seu antecedente trinta palavras antes, e é o único lugar do bloco onde posições diferentes se falam.

Duas restrições valem registrar. A atenção é causal: cada posição só olha para trás. Isso não é economia, é o que permite treinar todas as posições em paralelo e o que torna possível o cache que aparece mais adiante. E ela é dividida em cabeças, dezenas de cópias em paralelo, cada uma com seu subespaço menor, que acabam se especializando em relações diferentes.

O que o feed-forward faz

O feed-forward é onde está a maior parte dos pesos: dois terços dos parâmetros de um transformer, pela contagem de um trabalho de 2021 que foi investigar o que essas camadas guardam3. Ele pega o vetor de uma posição, expande, aplica uma não linearidade e volta ao tamanho original. Nenhuma posição olha para outra.

Esse mesmo trabalho oferece a leitura mais útil que existe do que isso significa. A primeira matriz funciona como um conjunto de chaves, cada uma respondendo a um padrão do texto: nas camadas de baixo, padrões superficiais, tipo uma terminação; nas de cima, padrões semânticos. A segunda funciona como valores, e cada chave que dispara escreve no stream uma inclinação em direção a certos tokens de saída3. O feed-forward é a memória, e a atenção é o roteamento.

Normalização, o detalhe que ninguém desenha

Antes de cada uma das duas operações, o vetor é reescalado. Parece burocracia e não é: sem isso, uma pilha de oitenta blocos não treina.

O trabalho que fechou essa questão mostrou que o lugar da normalização muda o comportamento dos gradientes na inicialização. No desenho original, com a normalização entre os blocos, os gradientes perto da saída começam grandes e o treino só fica estável com um aquecimento cuidadoso da taxa de aprendizado. Movendo a normalização para dentro do ramo residual, eles se comportam desde o início e o aquecimento deixa de ser necessário4. Praticamente todo modelo posterior adotou essa posição.

Quando o feed-forward é um MoE

Se o feed-forward concentra os pesos, é nele que dá para economizar. A ideia do mixture of experts é trocar um feed-forward por vários — os especialistas — e pôr um roteador na frente, que escolhe um subconjunto pequeno deles para cada token.

Duas coisas costumam ser mal entendidas aqui.

O roteamento é por token e por camada, não por pergunta. Não existe “o especialista de código” que atende sua requisição inteira. Dois tokens da mesma frase vão para especialistas diferentes, e o mesmo token pode tomar caminhos diferentes na camada 10 e na camada 40.

O ganho é em contas, não em memória. Os pesos de todos os especialistas precisam estar carregados; só uma fração roda por token. É por isso que a ficha técnica de um modelo MoE traz dois números, parâmetros totais e parâmetros ativos: o segundo prevê a velocidade, o primeiro prevê de quanta GPU você precisa. O Switch Transformer, que fixou a escolha em um especialista por token, mediu até 7 vezes mais velocidade de pré-treino com o mesmo orçamento de computação5.

O preço é instabilidade. Sem uma pressão explícita para distribuir a carga, o roteador colapsa em poucos especialistas e o resto fica sem uso.

De vetor a token

Depois do último bloco, o vetor da última posição carrega tudo o que o modelo montou. Falta convertê-lo em palavra.

A conversão é uma multiplicação contra o vocabulário inteiro: sai um número por token possível, o logit. Em muitos modelos essa é a própria tabela de embedding usada ao contrário. Uma normalização depois transforma esses números em uma distribuição de probabilidade.

E então o modelo sorteia. Este é o único passo não determinístico do percurso, e o único que você controla de fora sem mexer no prompt:

  • Temperatura achata ou afia a distribuição antes do sorteio. Perto de zero, o mais provável ganha quase sempre.
  • Top-k descarta tudo fora dos k tokens mais prováveis.
  • Top-p, ou nucleus, corta a cauda por massa acumulada, então o corte fica mais largo quando o modelo está indeciso e mais estreito quando está confiante.

Pegar sempre o token mais provável parece a escolha óbvia e não é. Um trabalho de 2019 mostrou que decodificar por máxima verossimilhança produz texto insosso e estranhamente repetitivo, mesmo em modelos bons, e que truncar a cauda menos confiável antes de sortear chega muito mais perto da distribuição do texto humano6. A qualidade da saída muda com a estratégia de decodificação, com o modelo intacto.

O que é calculado uma vez e o que se repete

Tudo acima descreve uma passada. Gerar uma resposta de 500 tokens são 500 passadas, e elas não custam a mesma coisa: a divisão entre prefill e decode explica quase toda a conta de servir um modelo.

o que entrao que rodao que ficatodo o promptde uma vezuma passadapela redeK e V de todos ostokens no cacheum token:o anterioruma passada por token,todos os pesos de novomais um K e Vno cacheprefill — uma vezdecode — a cada token gerado
Figura 2O prompt inteiro passa uma vez e vira cache. Depois disso, cada token gerado obriga a reler todos os pesos do modelo para produzir um símbolo.

Prefill é a primeira passada. O prompt inteiro entra de uma vez e todas as posições são processadas em paralelo, porque a máscara causal já garante que ninguém olhe para frente. Há muita conta por peso lido, então a GPU trabalha perto do que sabe fazer. O custo cresce com o tamanho do prompt, e é ele que define o tempo até o primeiro token aparecer.

O que sobra do prefill é o cache: as chaves e os valores de cada posição do prompt, guardados.

Decode é todo o resto, um token por vez. Cada token novo calcula sua própria consulta, chave e valor, atende sobre o cache e acrescenta os seus. A aritmética por token é pouca, mas para fazê-la a GPU precisa ler todos os pesos do modelo da memória. O trabalho passa a ser dominado por essa leitura. Um estudo de 2022 sobre inferência em modelos de mais de 500 bilhões de parâmetros chegou a 29 ms por token com lote pequeno, e mostrou que encolher o cache, fazendo várias consultas dividirem a mesma chave, permite contexto até 32 vezes maior7.

Três coisas seguem daí, e explicam quase toda a economia de servir um LLM:

  1. Prompt longo pesa na latência inicial; resposta longa pesa no total. São botões diferentes, e confundir os dois leva a otimizar o lado errado.
  2. Lote grande é quase de graça no decode. Se os pesos vão ser lidos de qualquer jeito, atender 32 requisições naquela leitura sai muito mais barato por token do que atender uma. É a razão principal de servir em escala custar menos por token que rodar o mesmo modelo sozinho.
  3. O cache é o que limita a concorrência. Ele cresce linearmente com o contexto e com o número de requisições simultâneas.

Uma conta de ordem de grandeza para o terceiro ponto, com números redondos em vez de um modelo específico: 80 camadas, 8 grupos de chaves de 128 dimensões, em 16 bits. Cada token guardado ocupa 2 × 80 × 8 × 128 × 2 bytes, algo como 0,33 MB. Cem mil tokens de contexto viram uns 33 GB, só de cache, antes dos pesos.

Onde essa descrição falha

Ela descreve o que é calculado. Não descreve o que aquilo significa.

Peso de atenção não é explicação. É tentador ler o mapa de atenção como “o modelo olhou para esta palavra e por isso respondeu aquilo”. Um trabalho de 2019 testou isso e achou o contrário: os pesos de atenção com frequência não se correlacionam com medidas de importância baseadas em gradiente, e dá para construir distribuições de atenção bem diferentes que produzem a mesma previsão8. O escopo importa, porque foram classificadores com atenção e não LLM de hoje, mas o alerta vale e o debate seguiu sem conclusão limpa.

O esqueleto é estável, os detalhes não. Tokenizador, embedding, blocos, unembedding e amostragem estão em todo modelo decoder-only servido em produção em 2026. Já a variante de normalização, a forma de codificar posição, quantos grupos de chave a atenção compartilha e se o feed-forward é denso ou MoE mudam de modelo para modelo. Ler o card do modelo continua necessário.

Temperatura zero não garante saída idêntica. Ela remove o sorteio, não a variação numérica: a mesma requisição em um lote diferente pode somar as mesmas parcelas em outra ordem, e um empate apertado entre dois tokens vira uma resposta diferente. Determinismo é coisa a testar, não a assumir.

Isto é inferência, não treino. Nada aqui explica de onde vieram os pesos, e a resposta para “por que o modelo respondeu isso” mora no treino muito mais do que na arquitetura.

O que fazer com isso

  1. Meça em tokens, não em caracteres. Orçamento, custo e limite de janela são todos contados na saída do tokenizador, não no seu editor de texto.
  2. Separe os dois tempos. Se o problema é demorar a começar, mexa no prompt. Se é demorar a terminar, mexa no tamanho da resposta ou no modelo.
  3. Estabilize o prefixo. Prompt caching reaproveita o prefill de um prefixo idêntico, o que só funciona se a parte fixa vier antes da parte variável.
  4. Escolha a decodificação pela tarefa. Extração e classificação querem temperatura baixa. Texto que não pode se repetir quer nucleus.
  5. Leia os dois números de um MoE. Ativos para estimar velocidade, totais para estimar memória.
  6. Conte a memória do cache, não só a janela. Contexto grande com muita concorrência esbarra em GPU antes de esbarrar no limite anunciado.

Daqui o guia se divide assim:

do textoao tokeno residualstreamo blocode atençãoroteamentoem MoEprefille decodeinterpretabilidadeo caminho do tokenolhar o modelo rodando
Figura 3Os quatro primeiros temas seguem o caminho do token, na ordem. Os dois últimos olham o mesmo processo de fora: um mede, o outro tenta ler.

Se você for ler só mais um, leia o do residual stream. É o que faz os outros quatro fazerem sentido juntos.

Footnotes

  1. O paper que apresentou o transformer, com atenção multi-cabeça, conexões residuais e codificação de posição por senos e cossenos. O alvo era tradução automática; o decoder isolado virou a base dos LLMs depois. 2

  2. Sennrich et al. (2016) propuseram representar palavra rara como sequência de unidades menores em vez de recorrer a um símbolo de “desconhecido”, e mediram ganho de 1,1 e 1,3 BLEU nas tarefas inglês-alemão e inglês-russo do WMT 15.

  3. Geva et al. (2021) mostraram que as camadas feed-forward, que somam dois terços dos parâmetros, operam como memórias de chave e valor: as chaves casam com padrões do texto, e os valores induzem distribuições sobre o vocabulário de saída. 2

  4. Xiong et al. (2020) mostraram que, com a normalização entre os blocos, os gradientes perto da saída são grandes na inicialização e exigem aquecimento da taxa de aprendizado; dentro do ramo residual, ficam bem comportados e o aquecimento pode ser removido.

  5. Fedus et al. (2021) simplificaram o roteamento para um especialista por token e mediram até 7 vezes mais velocidade de pré-treino com o mesmo orçamento de computação, sobre modelos derivados do T5.

  6. Holtzman et al. (2019) mostraram que decodificar maximizando verossimilhança degenera em texto repetitivo e propuseram amostrar de um núcleo dinâmico da distribuição, truncando a cauda menos confiável.

  7. Pope et al. (2022) montaram um modelo analítico de custo de inferência para transformers grandes, chegaram a 29 ms por token com lote pequeno em modelos de 500B+ e mostraram que a atenção multi-query, por guardar menos cache, permite contexto até 32 vezes maior.

  8. Jain e Wallace (2019) testaram se pesos de atenção explicam previsões e concluíram que não: eles frequentemente não se correlacionam com medidas de importância por gradiente, e distribuições bem diferentes produzem a mesma saída.

Perguntas frequentes

O que acontece dentro do modelo quando eu mando um prompt?
O texto é quebrado em tokens, cada token vira um vetor, esses vetores passam por dezenas de blocos que somam correções a eles, e o vetor da última posição é convertido em uma pontuação para cada token do vocabulário. Um token é sorteado dessa distribuição e o ciclo recomeça.
Qual é a arquitetura interna de um LLM?
Um transformer decoder-only: uma pilha de blocos idênticos em forma e diferentes em pesos. Cada bloco tem atenção, que move informação entre posições, e um feed-forward, que trabalha cada posição isolada. As duas somam ao mesmo vetor em vez de substituí-lo, e é essa soma acumulada que atravessa o modelo.
O que a atenção faz, exatamente?
Cada posição monta uma consulta e a compara com as chaves de todas as posições anteriores. Quanto mais parecidas, mais peso aquela posição recebe. O resultado é uma média dos valores das posições passadas, somada de volta ao vetor atual. É o único ponto do bloco onde posições diferentes trocam informação.
Por que a primeira palavra demora e o resto sai rápido?
São duas fases com custos diferentes. No prefill o prompt inteiro é processado de uma vez, e esse tempo cresce com o tamanho do prompt. No decode cada token exige uma passada nova, mas o custo por token quase não depende do prompt: depende do tamanho do modelo e da memória.
Um modelo MoE usa todos os parâmetros a cada token?
Não. Um roteador escolhe um subconjunto pequeno de especialistas por token e por camada, então só uma fração dos pesos participa da conta. Os outros continuam carregados na memória. Por isso a ficha técnica traz dois números: parâmetros ativos preveem a velocidade, parâmetros totais preveem de quanta GPU você precisa.
A resposta é sempre a mesma para o mesmo prompt?
Não por padrão. O último passo sorteia um token da distribuição, e o sorteio muda a cada chamada. Temperatura zero remove o sorteio, mas não garante saída idêntica: variações de arredondamento conforme o lote em que sua requisição caiu podem desempatar dois tokens de outro jeito.
O modelo pensa antes de responder?
Na arquitetura não existe etapa de deliberação: são as mesmas operações, na mesma ordem, para qualquer entrada. O que existe é o texto gerado entrar no contexto do que vem depois. Modelos de raciocínio exploram isso gastando tokens em rascunho antes de escrever a resposta final.

Referências

  1. Vaswani, A. et al.. Attention Is All You Need (2017)arXiv:1706.03762
  2. Sennrich, R.; Haddow, B.; Birch, A.. Neural Machine Translation of Rare Words with Subword Units (2016)arXiv:1508.07909
  3. Geva, M. et al.. Transformer Feed-Forward Layers Are Key-Value Memories (2021)arXiv:2012.14913
  4. Xiong, R. et al.. On Layer Normalization in the Transformer Architecture (2020)arXiv:2002.04745
  5. Fedus, W.; Zoph, B.; Shazeer, N.. Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity (2021)arXiv:2101.03961
  6. Holtzman, A. et al.. The Curious Case of Neural Text Degeneration (2019)arXiv:1904.09751
  7. Pope, R. et al.. Efficiently Scaling Transformer Inference (2022)arXiv:2211.05102
  8. Jain, S.; Wallace, B.. Attention is not Explanation (2019)arXiv:1902.10186