O modelo devolve uma distribuição. Transformar isso em palavras é decisão sua — e ela muda o resultado mais do que trocar de modelo.
Existe um mal-entendido muito difundido: o de que "o modelo escolhe a próxima palavra". Ele não escolhe. O modelo devolve uma nota para cada um dos 50 257 tokens do vocabulário — e para por aí. Escolher é trabalho de um algoritmo separado, que roda depois e que você controla.
Essas notas cruas se chamam logits. Elas vão de −∞ a +∞ e não somam nada em especial. Para virarem probabilidades, passam pelo softmax:
A partir daqui, tudo é estratégia de decodificação. E a escolha da estratégia é responsável por uma parte enorme da qualidade percebida — trocar de gpt2 para gpt2-xl muitas vezes muda menos o texto do que trocar de greedy para top-p.
Parece a escolha óbvia — se queremos o texto mais provável, escolhemos a palavra mais provável a cada passo, certo?
Errado, e por dois motivos independentes.
A palavra mais provável agora pode levar a um beco onde todas as continuações são ruins. Uma palavra ligeiramente menos provável agora poderia abrir uma sequência muito melhor. O greedy nunca descobre isso, porque nunca volta atrás. É o mesmo problema de qualquer algoritmo guloso.
Este é o motivo profundo, e ele foi demonstrado num artigo importante (Holtzman et al., 2020, "The Curious Case of Neural Text Degeneration"). Os autores mediram a probabilidade que um modelo atribui a texto escrito por humanos, e compararam com o texto que o próprio modelo gera em modo greedy.
Resultado: o texto humano é muito menos provável. Humanos constantemente escolhem palavras surpreendentes. Um texto onde cada palavra é a mais previsível possível não soa humano — soa como um disco riscado.
gpt2, greedy, prompt "The capital of France is": "the capital of the French Republic, and the capital of the French Republic, and the capital of the French Republic..." O loop nao e bug. E o comportamento CORRETO do greedy: uma vez que a sequencia entra num ciclo de alta probabilidade, cada repeticao torna a proxima ainda mais provavel. Ele se prende.
Maximizar a probabilidade produz texto de baixa qualidade. Para soar humano, é preciso deliberadamente não escolher sempre o mais provável. Toda técnica desta apostila é uma forma disciplinada de introduzir surpresa sem introduzir lixo.
O extremo oposto: sortear o token respeitando a distribuição. Se " Paris" tem 40% e " the" tem 12%, sorteia-se com esses pesos.
Isso resolve a repetição, mas cria um problema novo e traiçoeiro: a cauda longa.
São 50 257 tokens. Suponha que os 50 mil tokens irrelevantes tenham, cada um, uma probabilidade minúscula de 0,001%. Individualmente, nada. Somados: 50% de chance de sair um token completamente aleatório.
Na prática a distribuição é mais concentrada que isso, mas o efeito é real: amostragem pura produz texto que caminha bem e de repente despenca numa palavra sem sentido — e, como o modelo é autoregressivo, ele agora precisa continuar a partir daquela palavra fora de lugar. Um erro contamina todo o resto.
Precisamos cortar a cauda. As duas formas de fazer isso são o top-k e o top-p.
Antes do softmax, divida todos os logits por um número
Repare que é a mesma operação do √
| T | Efeito | Distribuição resultante | Quando usar |
|---|---|---|---|
| 0,1 | quase greedy | 0,999 · 0,000 · 0,000 | respostas factuais, código |
| 0,7 | conservador | 0,822 · 0,061 · 0,015 | o padrão sensato |
| 1,0 | distribuição crua | 0,665 · 0,090 · 0,033 | neutro |
| 1,5 | criativo | 0,506 · 0,131 · 0,067 | ficção, brainstorm |
| 3,0 | caótico | 0,332 · 0,171 · 0,122 | quase nunca |
temperature=0 é uma divisão por zero e, matematicamente, indefinido. As bibliotecas tratam isso como um caso especial: T=0 vira greedy puro. No transformers, o jeito correto é do_sample=False. Passar temperature=0 com do_sample=True ou dá erro ou é silenciosamente ignorado, dependendo da versão.
Mantenha apenas os
k = 5, prompt "The capital of France is":
mantidos: ' the' 0.28 | ' Paris' 0.19 | ' a' 0.09 |
' now' 0.06 | ' one' 0.04
descartados: os outros 50 252 tokens
renormaliza para somar 1 e sorteia.
Simples e eficaz. Mas tem uma falha conceitual:
"A capital da França é", a distribuição é muito concentrada — talvez 2 tokens sejam plausíveis. Com "Ele abriu a porta e viu", quase tudo é plausível. Com A solução elegante, disponível como parâmetro nas principais bibliotecas e APIs de geração. Em vez de fixar quantos tokens manter, fixe quanta probabilidade acumulada manter:
gpt2 desta máquina| Contexto | 1º token | P(1º) | Núcleo p=0,9 |
|---|---|---|---|
"The United States of" | " America" | 0,966 | 1 |
"It was the best of" | " times" | 0,597 | 45 |
"The capital of France is" | " the" | 0,085 | 1 503 |
"He opened the door and saw" | " a" | 0,161 | 1 648 |
"Yesterday I went to the" | " store" | 0,023 | 5 548 |
Leia a primeira e a última linha juntas. Em "The United States of" o modelo tem 96,6% de certeza — o núcleo é um único token, e não deveria mesmo haver o que sortear. Em "Yesterday I went to the" ele não faz ideia (o favorito tem 2,3%) — e o núcleo abre para 5 548 tokens, porque qualquer coisa é plausível ali.
Um top_k=50 fixo trataria as duas situações igual: deixaria 49 candidatos ruins na primeira e amputaria a variedade na segunda. O top-p resolve as duas com o mesmo parâmetro, sem ajuste manual. Essa é a sacada inteira.
Repare que "The capital of France is" aparece na faixa de dúvida, com 1 503 tokens de núcleo e o favorito valendo só 8,5%. O gpt2 small genuinamente não é confiante nessa pergunta — o que confirma, por um caminho completamente diferente, o que o logit lens (apostila 05) e o teste de escala (apostila 06) já tinham mostrado. Três medições independentes, a mesma conclusão. É assim que se ganha confiança num resultado.
O repetition_penalty divide o logit de qualquer token já usado, desencorajando repetições. Valores entre 1,1 e 1,2 ajudam bastante em modelos pequenos. Acima de 1,3, o texto fica estranho — o modelo passa a evitar palavras que precisam se repetir, como artigos e preposições.
| Objetivo | Configuração | Por quê |
|---|---|---|
| Factual / código | do_sample=False | determinístico e reproduzível; a repetição é um preço aceitável |
| Uso geral | temperature=0.7, top_p=0.9 | uma combinação comum; equilibra coerência e naturalidade |
| Criativo | temperature=1.0, top_p=0.95 | mais variedade sem abrir a cauda longa |
| GPT-2 pequeno | temperature=0.8, top_p=0.9, | o small repete muito; a penalidade compensa |
| Reproduzir um resultado | qualquer + seed fixo | amostragem com semente fixa é determinística |
Bibliotecas costumam aplicar os dois em sequência (primeiro top-k, depois top-p). Se você deixar top_k=50 ligado junto com top_p=0.95, o top-k já cortou em 50 antes de o top-p ter chance de decidir. Nos contextos abertos, onde o núcleo precisaria de 200 tokens, você nunca chega lá. Se você quer top-p de verdade, desligue o top-k (top_k=0).
O beam search mantém
Por isso beam search é excelente em tradução e sumarização — tarefas onde existe uma resposta certa e você quer encontrá-la — e ruim em geração aberta, onde o objetivo é soar natural. Não use para conversar com o GPT-2.
.venv\Scripts\python.exe lab\07_decoding.py
temperature alta e top_p baixo é uma combinação estranha? O que uma faz que a outra desfaz?As fontes primárias dos conceitos deste capítulo. Os números do texto foram medidos no laboratório; as ideias vêm daqui.
Os termos técnicos têm aqui o sentido de aprendizado de máquina. O glossário do curso mostra esse sentido ao lado dos outros que as mesmas palavras têm na TI.
Já sabemos como o modelo prevê e como escolhemos entre as previsões.
A apostila 08 volta uma etapa: o que exatamente ele aprendeu, e como se mede isso com um número só.