Clone do ChatGPT implementado em C com 3000 bytes baseado em GPT-2 (2023)
(nicholas.carlini.com)-
Implementação de um clone do ChatGPT
- Este programa é uma implementação sem dependências do GPT-2.
- Ele carrega as matrizes de pesos de arquivos TensorFlow e o arquivo BPE, e tokeniza a entrada com um codificador simples de pares de bytes.
- Implementa um pacote básico de álgebra linear, define a arquitetura do transformer, executa a inferência do transformer e destokeniza a saída com um decodificador BPE.
- Foi escrito em cerca de 3000 bytes de C.
- É otimizado de forma eficiente para que o modelo GPT-2 Small possa responder em poucos segundos em dispositivos modernos.
- Implementa cache KV e algoritmos eficientes de multiplicação de matrizes.
-
Estrutura do programa
- Biblioteca básica de matemática de matrizes (700 bytes)
- Multiplicação rápida de matrizes (300 bytes)
- Camadas de rede neural (300 bytes)
- Modelo transformer (600 bytes)
- Codificação de pares de bytes (400 bytes)
- Entrada e saída (200 bytes)
- Carregamento de pesos (300 bytes)
- Carregamento da codificação de pares de bytes (300 bytes)
-
Contexto sobre ChatGPT e transformers
- O ChatGPT é uma aplicação para conversar com um modelo de linguagem.
- O GPT-4 é o modelo mais recente e é muito impressionante.
- Este programa em C implementa o funcionamento do ChatGPT usando o GPT-2, um modelo mais fraco de 2019.
- O GPT-2 é um transformer que recebe como entrada uma sequência de palavras de tamanho fixo e prevê a próxima palavra.
-
Explicação do código em C
-
Começando pela matemática de matrizes (700 bytes)
- Redes neurais são compostas por operações com matrizes.
- A biblioteca de matrizes é construída usando uma definição mínima de matriz.
- Macros são usadas para extrair a lógica comum em meta-rotinas.
-
Multiplicação rápida de matrizes (300 bytes)
- A multiplicação básica de matrizes é implementada com três loops.
- Graças à forma como memória e cache funcionam, ler e escrever repetidamente na mesma memória é mais rápido.
-
Camadas de rede neural (300 bytes)
- Para escrever o transformer, são definidas algumas camadas especiais de rede neural.
- São implementadas a função de ativação GELU e funções como a que configura a subdiagonal necessária para a atenção causal.
-
Arquitetura do transformer (600 bytes)
- O transformer é implementado em 600 bytes.
- Em cada camada, são calculados chave, consulta e valor, a matriz de atenção é gerada e os resultados são combinados.
-
Codificação de pares de bytes (400 bytes)
- Como modelos de linguagem precisam de entrada de tamanho fixo, tokens são gerados usando fragmentos de palavras.
- Uma palavra dada é dividida em caracteres individuais, e pares de tokens adjacentes são mesclados.
-
Carregamento de pesos (300 bytes)
- Os pesos da rede neural são carregados do disco.
- Os pesos são serializados como números de ponto flutuante de 32 bits.
-
Carregamento da codificação de pares de bytes (300 bytes)
- O vocabulário da codificação de pares de bytes é carregado do disco.
- O formato do arquivo é composto por uma lista de codificações de pares de bytes.
-
-
Conclusão
- É possível comprimir décadas de avanços em machine learning em alguns milhares de bytes.
- Como exemplo de uma rede neural simples, inclui tudo, exceto os pesos reais do modelo.
1 comentários
Comentários do Hacker News
Quando usei o GPT-2 para simular uma conversa com um amigo, foi divertido e às vezes surpreendentemente preciso. Fico curioso se o grande salto entre GPT-2 e GPT-3 aconteceu por causa de modelos maiores, mais dados, ou ambos. O RLHF faz uma grande diferença, mas o modelo base do GPT-3 também era muito útil quando recebia exemplos suficientes
Um bom exemplo de como redes neurais simples podem ser realmente simples. IA é a magia negra que usamos para ganhar dinheiro
Não executei o código, mas fiquei impressionado com o tamanho reduzido. Os primeiros programas de ELISA eram maiores. Ao longo dos últimos 4 anos, isso passou a caber nesse número de bytes. Se alguém tiver uma pista de onde está a mágica, gostaria que explicasse. Fico me perguntando se está na função GELU ou no modelo baixado via script bash
O GPT-2 escreveu um conto de fadas de que gostei. Link: The Princess, the Fairy Godmother, and the Chest
Fico curioso se o GPT-2 foi realmente ajustado para poder ser usado em chat. Se não foi, acho forçado chamar isso de um clone do ChatGPT
LISP nem sempre é melhor que C. Desta vez, está liberado. Se você perdeu o link do código, aqui está: C-Chat-GPT-2
Fico curioso sobre em que tipo de hardware isso pode rodar. Também queria saber se dá para usar os pesos quantizados do Hugging Face e para que tipos de problemas ou consultas isso é especialmente adequado
Hoje em dia, é fácil implementar seu próprio ChatGPT usando gptscript. Link: gptscript
Não entendo como macros de C se parecem com expressões regulares. Macros de C fazem correspondência de palavras e substituem por outro texto. Expressões regulares fazem correspondência de texto com padrões relativamente complexos e, por si só, não fazem substituição de texto
Fico curioso se alguém rodou isso localmente para ver como é a saída gerada por esse GPT-2