Ir para o conteúdo

Output

O caminho do texto ao próximo token em sete passos: tokens, embeddings, query/key/value, máscara e cabeças, o bloco, a saída e a geração. O passo atual é Saída. ATENÇÃO TRANSFORMERS Tokenstexto → ids Embeddingsids → X Q · K · Vuma cabeça Máscaraduas cabeças BlocoLN · MLP Saídalogits → p ▲ você está aqui Geraçãoescolher texto → → próximo token

Passo 6 de 7. Entra: \(y\) do bloco, \(5 \times 4\). Sai: para cada posição, uma probabilidade para cada um dos 12 tokens do vocabulário; a última linha diz o que vem depois de "o gato subiu no". ← O bloco · próximo passo: Geração →

Uma pilha de blocos

O brinquedo tem um bloco. Um modelo de verdade empilha \(L\) deles, a saída de cada um sendo a entrada do seguinte, cada um recebendo \(n \times d\) e devolvendo \(n \times d\): o GPT-2 small tem \(L = 12\) com \(d = 768\); o Llama 3 8B tem 32 com \(d = 4096\). Nada nesta página muda quando \(L\) cresce — ela só lê a saída do último bloco, que no brinquedo é o \(y\) da página anterior.

A norma final

Antes da camada de saída, mais uma LayerNorm, igual à de dentro do bloco (o GPT-2 a chama de ln_f): \(f = \text{LN}(y)\), linha a linha. Para o último token, ␣no, \(y_5 = [-0{,}436; 1{,}551; -0{,}461; 1{,}698]\): média \(\mu = 2{,}352/4 = 0{,}588\), desvio-padrão \(\sigma = 1{,}038\), então

\[ f_5 = \frac{y_5 - \mu}{\sigma} = [-0{,}987;\ 0{,}928;\ -1{,}011;\ 1{,}069] \]

Unembedding: um score por token do vocabulário

A camada de saída é uma matriz \(W_U\) de \(d \times V\) números, \(4 \times 12\) no brinquedo: a coluna \(j\) é uma direção no espaço de \(d\) dimensões que favorece o token \(j\). Cada score — um logit — é um produto escalar:

\[ z = f\,W_U \qquad\qquad z_j = f \cdot W_U[:, j] \]
\(W_U\) o ␣no ␣gato ␣cão ␣sub iu ␣telhado ␣muro ␣sofá ␣chão . <|endoftext|>
linha 1 0 1 −0,5 −0,5 1 −0,5 −0,5 0 0 0 1 −0,5
linha 2 0 1 −1 −0,5 −0,5 1 1 1 0,5 0,5 0 0
linha 3 0 −1 0 0 −0,5 1 0 0 0 −0,5 0 1
linha 4 0 −0,5 1 0,5 0 0 1 0,5 0,5 0 −1 0

Para ␣telhado, coluna \([-0{,}5; 1; 0; 1]\):

\[ z_{\texttt{telhado}} = (-0{,}987)(-0{,}5) + 0{,}928 \cdot 1 + (-1{,}011) \cdot 0 + 1{,}069 \cdot 1 = 0{,}494 + 0{,}928 + 1{,}069 = 2{,}491 \]

A camada de saída do GPT-2 é \(768 \times 50.257\) e não é uma matriz à parte: é a tabela de embeddings \(E\) transposta (pesos amarrados), os mesmos 38,6 milhões de números lidos nos dois sentidos. O brinquedo tem a sua própria \(W_U\) por um motivo que dá para conferir: com \(d = 4\) e um bloco só, o último vetor ainda se parece tanto com o token que ele guarda que a versão amarrada, \(z = fE^\top\), poria a maior probabilidade no próprio ␣no. Um modelo treinado e mais fundo já se afastou o bastante da entrada para a amarração funcionar.

Softmax: dos scores às probabilidades

\[ p_j = \frac{e^{z_j}}{\sum_k e^{z_k}} \]
token \(z\) \(e^{z}\) \(p\)
␣telhado 2,491 12,069 0,395
␣muro 1,463 4,318 0,141
␣sofá 0,999 2,715 0,089
␣chão 0,970 2,637 0,086
␣gato 0,634 1,886 0,062
␣cão 0,564 1,757 0,058
␣no 0,418 1,519 0,050
iu 0,410 1,507 0,049
o 0 1 0,033
<|endoftext|> −0,518 0,596 0,020
␣sub −0,945 0,389 0,013
. −2,056 0,128 0,004
soma 30,521 1

Depois de "o gato subiu no", ␣telhado lidera com 0,395 e os quatro lugares a que um gato sobe dividem 0,71. O modelo ainda não escreveu nada: ele produziu uma distribuição e escolher a partir dela é o próximo passo.

Toda posição prevê

As duas contas acima rodam em todas as linhas e cada linha prevê o token depois da sua própria posição — a máscara causal garante que ela não viu esse token. O treino compara cada linha com o token que veio de fato depois e faz a média de \(-\ln p\) desse token, a perda de entropia cruzada:

posição depois de alvo \(p\)(alvo) \(-\ln p\) mais provável
1 o ␣gato 0,500 0,693 ␣gato
2 ␣gato ␣sub 0,444 0,811 ␣sub
3 ␣sub iu 0,274 1,295 iu
4 iu ␣no 0,311 1,169 ␣no
5 ␣no ␣telhado 0,395 0,928 ␣telhado

Média: 0,979 nats, contra \(\ln 12 = 2{,}485\) de um chute uniforme. Treinar é fazer descida de gradiente nesse número, em todas as linhas de todas as sequências ao mesmo tempo; a geração lê só a última linha.

O que a atenção comprou

Desligue o ramo de atenção (\(h = x\) no bloco) e a última linha só sabe que guarda ␣no na posição 5: ␣gato 0,455, ␣cão 0,143, ␣telhado 0,143 — o que vem depois de qualquer artigo. As palavras "gato subiu" é que levaram ␣telhado de 0,143 para 0,395; a atenção é o único caminho pelo qual elas chegaram à última linha. O laboratório faz o mesmo com o GPT-2 e chega ao mesmo veredito.

Verifique você mesmo — o modelo devolve uma palavra?

Não: ele devolve 12 probabilidades (50.257 no GPT-2) que somam 1, uma por token do vocabulário. Uma palavra só aparece depois que um token é escolhido entre elas e o seu id volta a ser texto — a próxima página.

Verifique você mesmo — some 10 a todos os logits da última linha. O que muda?

Nada: \(e^{z_j + 10} = e^{10} e^{z_j}\) e o \(e^{10}\) se cancela entre o numerador e a soma. Só as diferenças entre logits importam; por isso um logit sozinho não significa nada.


← O bloco · próximo passo: Geração →