- Depois de treinar um Transformer decoder-only com cerca de 10 milhões de parâmetros em TinyShakespeare, o autor rastreou, por meio de estados internos e experimentos, como o resultado do cálculo após a autoatenção se transforma em probabilidades do próximo token
- A hipótese central é que cada bloco do Transformer conecta o prompt a um conjunto específico de strings do corpus de treino, e que a distribuição de frequência dos tokens que realmente aparecem após essas strings se aproxima da previsão de próximo token do bloco
- O procedimento de aproximação implementado encontra strings de treino semelhantes à saída da feed-forward network de cada bloco, soma a distribuição dos caracteres que vieram em seguida e então reconstrói a saída do modelo com uma soma ponderada por bloco
- Em 20.000 prompts de comprimento 10, a distância de Hellinger média entre a saída aproximada e a saída real do Transformer foi de cerca de 0,17; a distância entre o modelo original e modelos alternativos treinados com a mesma arquitetura, mas seeds diferentes, foi de cerca de 0,11 ± 0,08
- A análise sustenta a interpretação de que a saída da feed-forward tem grande peso na transformação do bloco e que a attention mapeia o prompt para a classe correta de strings de treino, mas não está claro se isso se generaliza além de modelos pequenos
Modelo analisado e a pergunta
- Foi implementado e treinado um Transformer com cerca de 10 milhões de parâmetros seguindo Andrej Karpathy em Let’s build GPT: from scratch, in code, spelled out
- O código principal do modelo de linguagem é trabalho de Karpathy; a análise interna e o código auxiliar são contribuições separadas
- O código relacionado está em transformer-experiments
- O modelo é um Transformer decoder-only composto por 6 blocos
- Os dados de treino são TinyShakespeare, com 40.000 linhas de peças de Shakespeare
- Após cerca de 1 hora de treino em uma GPU RTX 4000, ele gera texto falso no estilo Shakespeare que parece estruturalmente plausível
- Os tokens são caracteres, não palavras
- O vocabulário tem 65 itens, e o modelo prevê a distribuição de probabilidade do caractere que vem depois do prompt de entrada
- Por exemplo, após
'my most gr', ele prevê o próximo caractere comoacom 0,819,ecom 0,081 eicom 0,059
- A pergunta central não é sobre a autoatenção em si, mas sobre como o resultado após a attention se transforma na probabilidade final do próximo token
Estrutura dos blocos e o peso da feed-forward network
- Cada bloco do Transformer inclui multi-head self-attention e uma feed-forward network
- Na estrutura em PyTorch, a saída do bloco tem a forma
x + self.sa(self.ln1(x)), seguida porx + self.ffwd(self.ln2(x)) - Em variáveis intermediárias, a saída do bloco pode ser vista como
x + sa_out + ffwd_out
- Na estrutura em PyTorch, a saída do bloco tem a forma
- No modelo analisado, a feed-forward network responde por 65,71% de todos os parâmetros treináveis
- Parâmetros da feed-forward: 7.089.408
- Total de parâmetros treináveis: 10.788.929
- A saída da feed-forward network parece ser o principal fator na conversão da entrada do bloco em sua saída
- Nos experimentos posteriores também, a saída da feed-forward mostrou mais influência na distribuição final de probabilidade do que a saída da self-attention isoladamente
Encontrando strings por saídas feed-forward semelhantes
- O procedimento de aproximação usa a similaridade da saída feed-forward entre o prompt e strings do corpus de treino
- O prompt é inserido no modelo e a saída da feed-forward network de cada bloco é armazenada
- Para cada bloco, busca-se no corpus de treino strings com saída feed-forward semelhante
- Soma-se a distribuição de frequência dos tokens que vieram depois dessas strings
- As distribuições por bloco são combinadas com pesos e normalizadas para formar uma distribuição de probabilidade
- No prompt de demonstração
'And only l', foram encontradas 94 strings de comprimento 10 com similaridade de cosseno acima de 0,95 com a saída da feed-forward do bloco 1- As strings encontradas geralmente terminavam em
y louly l, comohat only l,\nMy only l,I dearly l,ng Henry l,And only l - A distribuição de frequência normalizada dos caracteres que vinham depois dessas strings foi muito semelhante à previsão real do modelo para o próximo caractere
- As strings encontradas geralmente terminavam em
- No exemplo
'And only l', a aproximação e a previsão do modelo real ficaram próximas- Modelo:
i0,437,o0,204,a0,195,e0,160 - Aproximação:
i0,389,o0,250,a0,222,e0,139 - A distância de Hellinger foi 0,0711
- Modelo:
- Há casos em que um único bloco falha
- No prompt
'hing tremb', usando apenas o bloco 1, o modelo prevêlcom 0,999, mas a aproximação dáe0,543 el0,343, produzindo uma distância de Hellinger de 0,6305 - Quando todos os blocos são considerados, no mesmo exemplo a aproximação prevê
lcom 0,997 e a distância de Hellinger cai para 0,0233
- No prompt
Escala computacional e ajuste manual
- Por eficiência, toda a análise foi feita principalmente com strings de comprimento 10
- O corpus de treino tem 1.115.394 caracteres, e há 858.923 substrings únicas de comprimento 10
- A saída feed-forward é um vetor
float32de 384 dimensões, um por cada um dos 6 blocos
- 20.000 strings de comprimento 10 foram escolhidas aleatoriamente e usadas como prompts de teste
- A similaridade de cosseno por bloco entre cada prompt e as 858.923 substrings únicas foi pré-calculada e salva em disco
- Como não apareceram correspondências relevantes abaixo de similaridade 0,7, foi aplicado um pré-filtro mantendo apenas valores de 0,7 ou mais
- O threshold de similaridade por bloco foi definido por ajuste manual
- Bloco 0: 0,95
- Bloco 1: 0,94
- Bloco 2: 0,85
- Bloco 3: 0,76
- Bloco 4: 0,81
- Bloco 5: 0,89
- Também foram usados pesos manuais ao combinar as distribuições de frequência por bloco
- Os pesos utilizados foram
[0.01, 0.01, 0.1, 1.5, 6, 0.01] - Também foi tentada uma busca de pesos via deep learning, mas o resultado não superou o ajuste manual
- Os pesos utilizados foram
Avaliação com 20.000 prompts
- Para os 20.000 prompts completos, foi calculada a distância de Hellinger entre a distribuição aproximada e a distribuição de saída do modelo
- Média: 0,1677
- Desvio padrão: 0,1215
- Mínimo: 0,0013
- Máximo: 0,9994
- A distância de Hellinger mede a sobreposição entre distribuições de probabilidade: 0 significa idênticas, 1 significa sem sobreposição
- Para comparar a qualidade da aproximação, a mesma arquitetura foi treinada mais 3 vezes com random seeds diferentes
- Seed do modelo original: 1337, training loss estimada 0,9334, validation loss 1,5063
- Alternate 1 seed: 1442, training loss 0,9293, validation loss 1,5038
- Alternate 2 seed: 88, training loss 0,9294, validation loss 1,4991
- Alternate 3 seed: 99999, training loss 0,9339, validation loss 1,4941
- A distância de Hellinger média entre o modelo original e os modelos alternativos foi de cerca de 0,11 ± 0,08
- Original vs Alternate 1: 0,1064 ± 0,0823
- Original vs Alternate 2: 0,1057 ± 0,0817
- Original vs Alternate 3: 0,1053 ± 0,0828
- A distância média de 0,17 entre a aproximação e o modelo é maior que os 0,11 entre modelos alternativos, mas está dentro da faixa do desvio padrão, o que sustenta a avaliação de que a aproximação é bastante boa
Interpretando o funcionamento interno do Transformer
- O modelo pode ser visto, após os embeddings, como várias etapas de transformação no espaço
- Os 6 blocos do Transformer transformam embeddings de entrada em embeddings de saída dentro de um espaço de embeddings de 384 dimensões
- O LayerNorm final e a camada linear convertem esse espaço de embeddings em um espaço de logits de 65 dimensões, e o softmax gera as probabilidades do próximo token
- As transformações internas de cada bloco podem ser vistas como soma de vetores
- A saída do bloco é a soma da entrada
x, da saída da self-attentionsa_oute da saída da feed-forwardffwd_out - Na análise, observou-se um padrão em que os vetores de saída da feed-forward geralmente têm norma maior que os vetores de saída da self-attention, e em que as duas saídas costumam apontar em direções semelhantes em cada bloco
- A saída do bloco é a soma da entrada
- Mesmo somando apenas as saídas da feed-forward, o vetor final de saída costuma apontar em direção parecida com a saída final completa
- A saída usando só feed-forward tem norma menor, mas direção próxima da saída original
- Por causa do LayerNorm final, a diferença de norma não é tão importante na entrada da camada linear final
- Isso não significa que o cálculo de self-attention possa ser removido
- A feed-forward network recebe a saída da self-attention em sua entrada, como em
ffwd_out = self.ffwd(self.ln2(x + sa_out)); portanto, remover a self-attention mudaria a própria saída da feed-forward
- A feed-forward network recebe a saída da self-attention em sua entrada, como em
Hipótese do subespaço de tokens
- Certos embeddings podem fazer o modelo prever um token específico com probabilidade quase certa
- Por exemplo, é possível aprender um embedding que, ao ser passado pelo LayerNorm e pela camada linear após o bloco final, faça a probabilidade do token
aficar quase em 1 - Os pesos do Transformer ficam fixos e apenas o tensor de embedding é otimizado
- Por exemplo, é possível aprender um embedding que, ao ser passado pelo LayerNorm e pela camada linear após o bloco final, faça a probabilidade do token
- Cada token não corresponde a um único embedding, mas a vários embeddings
- Isso é interpretado como um subespaço de embeddings complexo e não linear correspondente a cada token
- Foi possível aprender facilmente milhares de embeddings únicos para cada token
- Embora não tenha sido possível determinar matematicamente esse subespaço com precisão, na etapa final uma aproximação linear funcionou bem
- Os embeddings aprendidos para cada token foram empilhados e submetidos a SVD
- Um único primeiro right singular vector funcionou bem como aproximação linear unidimensional do subespaço daquele token
- Ao combinar linearmente vetores de aproximação de subespaços de vários tokens, é possível criar embeddings que distribuem probabilidade entre vários tokens
- Somar os vetores aproximados de
aebproduz uma distribuição que reparte probabilidade entre os dois tokens - Porém, por causa do erro de aproximação, da não ortogonalidade entre os vetores de subespaço e de diferenças na magnitude dos logits por token, o resultado não é exatamente uma distribuição 50:50
- Somar os vetores aproximados de
Correspondência entre saídas feed-forward e subespaços de tokens
- A saída feed-forward pode ser interpretada como um ajuste da saída do bloco em direção ao subespaço de certos tokens
- Esses tokens coincidem com os tokens previstos pelo procedimento de aproximação, isto é, os que aparecem após strings de treino que produzem saídas feed-forward semelhantes
- No exemplo
med me Aut, olhando apenas o bloco final, a aproximação prevêocomo token seguinte mais provável, seguido deh- Ao projetar o mesmo vetor de saída feed-forward na aproximação de subespaços de tokens, os tokens mais semelhantes também foram
o,h,i,u,y, nessa ordem
- Ao projetar o mesmo vetor de saída feed-forward na aproximação de subespaços de tokens, os tokens mais semelhantes também foram
- No exemplo
if and thy, aparece uma correspondência semelhante- A aproximação aponta espaço,
se newline como principais tokens previstos - Os subespaços mais alinhados com a saída feed-forward também ficaram próximos de espaço,
se newline nessa ordem
- A aproximação aponta espaço,
- Em todos os 20.000 prompts, foi definido um critério arbitrário para agregação
- O critério foi: “os subespaços dos tokens que respondem por 90% da massa de probabilidade na previsão aproximada aparecem na metade superior do ranking de similaridade de cosseno com a saída feed-forward?”
- No bloco final, 16.357 casos, ou 81,78%, satisfizeram esse critério
Resultados agregados por bloco e comparação com acaso
- Ao usar as aproximações de subespaço aprendidas em cada posição de bloco, a taxa de atendimento do critério cresce nos blocos mais tardios
- Bloco 6: 16.357 casos, 81,78%
- Bloco 5: 10.142 casos, 50,71%
- Bloco 4: 7.760 casos, 38,80%
- Aplicar a aproximação de subespaço da etapa final a todos os blocos produz resultados ainda melhores
- Bloco 6: 81,78%
- Bloco 5: 68,26%
- Bloco 4: 58,15%
- Bloco 3: 57,34%
- Bloco 2: 52,02%
- Bloco 1: 49,71%
- Também foi simulada a probabilidade de o critério ser satisfeito por acaso, com similaridades de cosseno aleatórias
- Bloco 6: 20,76% ± 0,25%
- Bloco 5: 20,55% ± 0,26%
- Bloco 4: 18,37% ± 0,24%
- Bloco 3: 18,20% ± 0,24%
- Bloco 2: 17,04% ± 0,23%
- Bloco 1: 16,31% ± 0,23%
- Os resultados ficam muito acima do acaso, mas, por causa do ruído de medição e das limitações da aproximação de subespaço, é difícil tratar isso como evidência conclusiva
O papel da self-attention
- Nessa interpretação, boas previsões dependem de mapear o prompt para a classe correta de strings do corpus de treino
- O eixo responsável por esse mapeamento é a self-attention
- A camada de attention identifica padrões entre os tokens do prompt
- Esses padrões podem ser algo simples, como o padrão final
y l, ou tipos de token mais gerais, como vogais ou letras maiúsculas em posições específicas
- Os pesos aprendidos dos attention heads determinam a quais padrões eles respondem
- Quando a saída do attention head passa pela feed-forward network, ela se torna uma representação no espaço de embeddings que carrega informação sobre a distribuição dos tokens que apareceram após strings de treino semelhantes
- O modelo analisado tem 6 blocos e 6 attention heads por bloco, então um mesmo prompt pode ser avaliado em relação a vários padrões latentes
Conclusão e limitações
- A evidência de que o procedimento de aproximação e a saída real do Transformer são semelhantes é forte
- A evidência de que o procedimento de aproximação corresponde ao cálculo interno real do Transformer é menos clara, mas sugere que a ideia pode estar parcialmente correta
- Não está claro se os resultados obtidos em um único Transformer pequeno se generalizam para modelos maiores ou outros datasets
- Este projeto é um processo de fazer perguntas ao interior do modelo e desenhar experimentos, e ajuda mais a enxergar a complexidade dos modelos de linguagem do que a reduzir sua “mágica” a um mecanismo simples
1 comentários
Opiniões do Hacker News
Alguns dos temas do post pai não deveriam ser uma grande surpresa para quem leu https://people.math.harvard.edu/~ctm/home/text/others/shanno...
Se você não lê a literatura fundamental da sua área, até fenômenos que surgem como consequência natural de trabalhos já estabelecidos acabam parecendo mistérios inexplicáveis
Ainda assim, os experimentos parecem bastante completos à primeira vista, e valorizo muito a quantidade de trabalho detalhado envolvida
Há um trade-off difícil entre aprender a teoria existente e tentar derivar tudo de novo do zero. Sem uma base tradicional, novas descobertas são possíveis; com essa base, dá para entender certos fenômenos mais profundamente
Nos comentários aqui, vejo várias pessoas surpresas que um modelo que maximiza a log-verossimilhança de uma sequência, dados os dados, não se afaste magicamente desse comportamento durante a inferência. Trata-se de um modelo de estimação de densidade; esperavam que ele recitasse Shakespeare do nada?
Voltar ao básico faz com que esses experimentos sejam entendidos muito melhor. Já existe uma base matemática muito clara que explica isso, bem como os chamados fenômenos emergentes
Mais especificamente, há várias camadas, e o tratamento de Shannon para sistemas ergódicos é um bom ponto de partida. Há alguns desalinhamentos aqui, mas parece uma correspondência próxima o suficiente para entender a dinâmica geral
Não é raro pessoas inteligentes dizerem: “esta estrutura matemática se parece com aquela ideia; se adicionarmos ou removermos algumas estruturas, tudo fica explicado”. Mas, na prática, há muita coisa que não sabemos
Nunca vi teóricos desta área chegarem com uma teoria e, a partir dela, criarem algo novo ou fazerem previsões úteis. Normalmente, tenta-se uma coisa aqui e outra ali; se funcionar, depois se acrescenta uma explicação plausível para por que funcionou; se não funcionar, fica esquecido
Também houve recentemente um texto vendo transformers como suavização por kernel: https://arxiv.org/abs/1908.11775
Redescobertas repetidas não são necessariamente desperdício; podem ser um processo de confirmar e validar uma verdade profunda à qual se chega por várias rotas
Muitos livros-texto de teoria da informação já apontam a natureza endereçável por conteúdo (content-addressable) dessas redes[1], e elas também são usadas em aplicações como compressão por esse motivo[2][3]
Portanto, não surpreende que, quando o NYT inseriu alguns parágrafos de seus próprios artigos como prompt em um modelo da OpenAI, eles tenham sido reproduzidos quase literalmente
[1] https://www.inference.org.uk/itprnn/book.pdf
[2] https://bellard.org/nncp/
[3] https://pub.towardsai.net/stable-diffusion-based-image-compr...
Quando vi a observação de que, se o Google mandar repetir a mesma palavra continuamente, isso pode fazer o ChatGPT regurgitar os dados de treinamento literalmente[0][1], pensei exatamente na mesma ideia. Fico feliz que alguém tenha de fato implementado
Isso levanta duas perguntas adicionais
[0] Antes era possível. Agora a OpenAI bloqueia a geração se você preencher a janela de contexto com uma única palavra
[1] https://arxiv.org/abs/2311.17035
Não há muitas etapas sendo puladas; pelo contrário, muito trabalho extra é acrescentado
Acho que, mesmo separando completamente o corpus de treinamento do modelo e o corpus usado para buscar strings com ativações semelhantes, o resultado seria quase o mesmo. A parte difícil, afinal, é fazer com que strings com estatísticas de próximo token parecidas produzam ativações parecidas
Nos pesos por camada [0.01, 0.01, 0.1, 1.5, 6, 0.01], o mais importante é a penúltima camada, e nesse ponto a entrada já foi bastante transformada. Portanto, não se deve esperar substituir o transformer por um simples grep sobre os dados de treinamento com base nisso
O motivo de o peso da penúltima camada ser muito maior que o da camada final provavelmente são as cabeças de indução. Como em https://transformer-circuits.pub/2021/framework/index.html, pode ser uma estrutura que implementa a função de copiar strings repetidas da entrada, em que a penúltima camada decide o que procurar e a camada final realiza a cópia
A contribuição deste texto, como o próprio autor diz, é mostrar isso a leitores técnicos que estão criando seu próprio GPT, ao contrário de textos focados no próprio transformer e em “como isso é implementado?”
Olhando de perto, eram READMEs do GitHub inexistentes e incoerentes, folhetos informativos sem conteúdo, conversas aleatórias e coisas do tipo
Mas raspar a internet inteira para treinar esses modelos nunca é chamado de ataque
Então por que não deveríamos considerar que ela também tem direitos sobre a distribuição de probabilidade dos caracteres dentro dessa obra?
Assim que conheci o NanoGPT do Andrej Karpathy, treinei-o com a versão russa de War and Peace, e achei interessante que, mesmo sendo um modelo de apenas 3 MB, ele captou quase toda a gramática russa
O russo tem uma estrutura sintética e flexional complexa. Por exemplo, depois da preposição “na” (“upon”), deve vir um substantivo no acusativo, o que aparece como -a para substantivos masculinos animados, ausência de terminação para substantivos inanimados, -ia para substantivos terminados em “consoante suave”, -u para substantivos femininos, e assim por diante
Além disso, o verbo “usar” exige o caso instrumental quando vem seguido de um substantivo usado como ferramenta
Não era perfeito e havia erros, mas foi interessante que o NanoGPT inferiu regras específicas e complexas com apenas 3 minutos de treinamento. Procurei no texto original as frases exatas que ele gerou, mas não encontrei nenhuma correspondência literal
Ainda assim, embora entendesse a gramática em certa medida, semanticamente era um completo absurdo
Havia uma boa visualização 3D mostrando o mesmo sistema, e acho que funcionaria bem ler junto
LLM Visualization (https://bbycroft.net/llm)
https://news.ycombinator.com/item?id=38505211
Acho que foi por tentar mostrar tudo de uma vez e por não empurrar as coisas para conceitos abstratos, mas não tenho certeza
É um bom projeto, mas o modelo analisado é, na prática, um modelo de brinquedo, tanto em tamanho quanto na quantidade de dados de treinamento
Por isso, esse modelo talvez possa ser aproximado por um modelo mais simples, provavelmente um modelo de linguagem n-gram, mas é difícil vê-lo como representativo de como modelos de linguagem maiores funcionam
Fico me perguntando se o autor está afirmando que LLMs são geradores de texto de cadeia de Markov.
Ou seja, isso quer dizer que a distribuição de probabilidade do próximo token gerado é igual à probabilidade daquela sequência de tokens nos dados de treinamento?
Se for assim, será que criar “simplesmente” uma cadeia de Markov a partir dos dados de treinamento originais daria um desempenho parecido com o de um LLM?
o estado é um vetor de tokens do tamanho do comprimento de contexto, e o modelo descreve a matriz de transição. Para um dado vetor de tokens do tamanho do comprimento de contexto, ele produz as probabilidades do próximo vetor de tokens com o mesmo tamanho de contexto.
A parte difícil é a classificação: saber quais textos dos dados de treinamento são “parecidos” com o texto do prompt.
Usando o exemplo do post do blog, fica assim:
Original string: 'And only l'
Similar strings: 'hat only l' 's sickly l' ' as\nthey l' 'r kingly l'
Isso sugere que pode haver uma forma de contornar o transformer e obter o mesmo resultado. Fico curioso se seria mais eficiente.
Por exemplo, dado um modelo-base, talvez fosse possível treinar outra coisa e executá-la em um dispositivo muito menor.
É bem difícil entender exatamente o que o autor afirma ter demonstrado.
Li algumas vezes a seção “Interpretation: Why Does the Approximation Work?”, mas ela me parece uma explicação mecânica das etapas do transformer. Não sei qual é a tese central.
Fico me perguntando se já é conhecido o fenômeno de o deslocamento de attention e FF apontarem, em geral, na mesma direção.
Já acho um pouco surpreendente que eles estejam no mesmo espaço latente ao longo das camadas. Uma rede FF não poderia fazer uma rotação arbitrária? Acho que entendi algo errado.
Inevitavelmente algo fica de fora, e uma das coisas que fica de fora é descrever com precisão uma rotação arbitrária em um espaço de alta dimensão.