paint-brush
Ajustei um Llm com meu histórico de bate-papo do Telegram. Aqui está o que aprendipor@furiousteabag
1,512 leituras
1,512 leituras

Ajustei um Llm com meu histórico de bate-papo do Telegram. Aqui está o que aprendi

por Alex7m2024/06/13
Read on Terminal Reader

Muito longo; Para ler

Aperfeiçoei um modelo de linguagem usando minhas mensagens do Telegram para ver se ele poderia replicar meu estilo de escrita e padrões de conversação. Escolhi o modelo Mistral 7B por seu desempenho e experimentei abordagens LoRA (adaptação de baixa classificação) e ajuste fino completo. Extraí todas as minhas mensagens do Telegram, totalizando 15.789 sessões em cinco anos, e inicialmente testei com o modelo Mistral de conversa genérica e ajustado. Para LoRA, o treinamento em um RTX 3090 levou 5,5 horas e custou US$ 2, melhorando a imitação de estilo, mas enfrentando dificuldades com contexto e gramática. O ajuste fino completo, usando oito GPUs A100, melhorou o desempenho da linguagem e a retenção de contexto, mas ainda apresentou alguns erros. No geral, embora o modelo capturasse bem o estilo de conversação e os tópicos comuns, muitas vezes faltava contexto nas respostas.
featured image - Ajustei um Llm com meu histórico de bate-papo do Telegram. Aqui está o que aprendi
Alex HackerNoon profile picture
0-item
1-item

Para a maioria das pessoas com quem interajo, sou apenas mais um programa baseado em texto na maior parte do tempo. Se a entrada e a saída são tão simples, eu poderia ser substituído pelo modelo? Para que isso funcionasse, o modelo precisaria não apenas entender meu estilo de escrita, mas também saber muito sobre mim. A melhor fonte para isso é o meu mensageiro Telegram , pois o uso diariamente e contém quase tudo sobre meus pensamentos e ações na forma de históricos de bate-papo.

Abordagem

A abordagem mais direta seria extrair todas as minhas mensagens, carregá-las no contexto do ChatGPT e instruí-lo a usar essas informações para imitar meu estilo ao responder a novas mensagens. No entanto, esta abordagem é limitada pelo tamanho da janela de contexto, exigindo que eu pré-processe as mensagens para extrair pontos-chave. Como quero evitar esse incômodo, talvez a Geração Aumentada de Recuperação (RAG) possa ser usada para extrair as informações necessárias quando necessário. No entanto, pela minha experiência, a recuperação de dados diversos, como sessões de bate-papo, geralmente precisa de um ajuste supervisionado do modelo de recuperação, e não estou interessado em criar tal conjunto de dados. Portanto, o ajuste fino parece ser a melhor opção. É ideal por vários motivos: deve capturar meu estilo de escrita e potencialmente acumular conhecimento de todas as minhas mensagens sem ter que selecionar o que é importante.


OpenAI oferece recursos de ajuste fino , mas como usarei minhas mensagens privadas, não quero usar nenhum serviço de ajuste fino de terceiros. Então, preciso escolher um modelo básico. De acordo com o Hugging Face Open LLM Leaderboard , um dos principais modelos menores (parâmetros ≤13B) é o Mistral 7B . Ele ainda supera o Llama 2 13B . Agora, a questão é se o LoRA é suficiente ou se é necessário um ajuste fino completo. Várias comparações [1] [2] sugerem que o LoRA é um pouco pior do que o ajuste fino completo, mas ainda assim funciona bem na maioria das vezes. No entanto, para tarefas específicas como a minha (língua russa + bate-papo), encontrei um artigo , onde pesquisadores conduziram o ajuste fino das instruções do Llama em chinês, semelhante em complexidade ao meu objetivo. Eles descobriram que o ajuste baseado em LoRA em um modelo básico sem ajuste prévio de instruções é menos eficaz do que o ajuste fino completo. No entanto, o ajuste baseado em LoRA em um modelo já ajustado para instruções pode produzir resultados comparáveis. No meu caso, isso significa ajuste completo em um modelo básico ou LoRA em um modelo já ajustado para bate-papo em russo. Como não consegui encontrar um modelo ajustado para bate-papo em russo, tentarei o LoRA em um modelo ajustado para bate-papo em inglês, como o modelo Mistral ajustado, Dolphin .


Então, o plano é:

  1. Comece com LoRA em cima do Dolphin, o bate-papo em inglês Mistral aprimorado
  2. Se a qualidade não for suficiente, tente o ajuste fino completo no Mistral

Preparação de dados

Um aspecto único das mensagens em aplicativos como o Telegram, em comparação com os e-mails, é o fluxo da conversa. As mensagens geralmente não se alternam entre você e seu contato. Em vez disso, muitas vezes você envia algumas mensagens seguidas, seguidas de várias respostas da outra pessoa. Essas mensagens geralmente também são curtas. Eu queria preservar esse estilo de conversação natural em meus dados.


O Telegram oferece um recurso integrado para exportar todos os bate-papos para JSON. Depois de filtrar e agrupar mensagens em sessões, compilei dados dos últimos cinco anos de uso do Telegram. Isso resultou em 15.789 sessões de 466 chats, com duração média de sessão de 8,51 mensagens. Para estruturar os dados, escolhi o formato de prompt ChatML . Aqui está um exemplo de sessão (traduzido do russo):


<|im_start|>João Smith
>>> caramba, não consigo contornar o limite de tempo de 135

>>> tentando fazer tudo de maneira super otimizada, mas sem sorte<|im_end|>

<|im_start|>Alexandre Smirnov
>>> sim, mesmo

>>> você ainda segue com a mesma ideia?<|im_end|>

<|im_start|>João Smith
>>> não sei, acho que estamos na mesma página

>>> como você disse

>>> indo com a string invertida em uma tentativa e tentando encontrar algo lá

>>> parece uma merda porque a função z estraga tudo…………………<|im_end|>

<|im_start|>Alexandre Smirnov
>>> não entenda onde z entra nisso<|im_end|>

<|im_start|>João Smith
>>> não sei, parece que estou fazendo tudo iterativamente de qualquer maneira, mas sim, preciso reverter algumas strings para construir a função z

>>> e é apenas uma solução aleatória

>>> das discussões<|im_end|>

<|im_start|>Alexandre Smirnov
>>> entendi<|im_end|>


Meu coletor de dados garante que a perda seja calculada apenas com base na resposta de alguém. Prever quem falará a seguir é relativamente simples e não queremos que o modelo se concentre em aprender isso. Portanto, as partes da conversa onde a perda é calculada são destacadas em negrito.


Você pode notar que não apenas minhas respostas, mas também as de outras pessoas são usadas para cálculo de perdas. Isso é deliberado. Ao fazer isso, o modelo será capaz de representar não apenas como eu, mas também como meus parceiros de conversa frequentes!

Plano de avaliação

Testarei modelos conversando de duas maneiras. Primeiro, a modelo vai fingir ser eu e eu estarei conversando comigo mesmo da perspectiva de meus diferentes amigos. Então, vou conversar como eu mesmo enquanto a modelo atua como minha amiga. Meu início de conversa será sempre as mesmas 2 mensagens: “ei” e “e aí?” (em russo, “прив” e “как дела?”). Frases e pessoas geradas à medida que o modelo atua serão destacadas . Para testes, usarei oobabooga/text-Generation-webui .


No início, quero explorar como o modelo Mistral de conversação genérica e ajustado lida com essa tarefa sem qualquer treinamento prévio de minha parte.


Amigo 1 vs Alexander Smirnov


Alexander Smirnov vs Amigo 1


Ok, é capaz de formar frases coerentes. O problema mais notável é a falta de consciência do contexto das conversas, o que leva a respostas brandas e genéricas. As mensagens não tinham nenhum estilo distinto, parecendo bastante básicas. Outra questão é que o russo do modelo é ruim. Isto é esperado, uma vez que o modelo é demasiado pequeno para ser bem generalizado para outras línguas que não a sua principal, o inglês. Além disso, o modelo tendia a ser excessivamente proativo, terminando quase todas as frases com uma pergunta, o que não é a forma como as pessoas reais normalmente se comunicam nos mensageiros.


Vamos tentar consertar tudo isso!

LoRA

LoRA oferece uma abordagem de baixo esforço em termos de pipeline de treinamento e requisitos de hardware. Treina cerca de 1% dos pesos totais. Escolhi um comprimento de sequência de 1.024 e um tamanho de lote de 8. O treinamento, que consumiu 20 GB de VRAM em um RTX 3090, durou três épocas e durou 5,5 horas. Para isso, utilizei o vasto.ai , onde o custo da GPU foi de US$ 0,362 por hora, totalizando US$ 2 para todo o treinamento, excluindo o tempo gasto em experimentos e correções de bugs.


Aqui estão os resultados:


Amigo 1 vs Alexander Smirnov


Amigo 2 vs Alexander Smirnov


Alexander Smirnov vs Amigo 1


Alexander Smirnov vs Amigo 2


Isto é muito melhor. Definitivamente captura o estilo da pessoa por quem está respondendo. Também identifica os tópicos mais comuns discutidos entre pares específicos de pessoas. Por exemplo, com o amigo 2, o foco está claramente mais no trabalho. Porém, a gramática ainda está errada e perde rapidamente o contexto da conversa. Estou bastante confiante de que o LoRA funcionaria com qualidade razoável em inglês e talvez não seja necessário um ajuste fino completo. Mas, como o russo não é o idioma nativo do modelo, vamos tentar o ajuste fino completo.

Ajuste fino completo

O ajuste fino completo é mais desafiador devido à necessidade de treinamento multi-GPU. Os métodos populares incluem ZeRO & DeepSpeed [3] ou FSDP [4] , com FSDP sendo essencialmente um ZeRO3 [5] . Decidi ir com o FSDP.


Ao implementar o pipeline de treinamento, referi-me ao código de ajuste fino Stanford Alpaca e ao código de ajuste fino Mistral de Anton Bacaj .


Usar um fragmento completo FSDP de meia precisão com comprimento de sequência de 1.024 e tamanho de microlote de 2 exigiu 63 GB de VRAM em cada uma das oito GPUs A100 de 80 GB. O treinamento, que durou três épocas, durou apenas 20 minutos. O custo total da VM foi de US$ 8,88 por hora, resultando em US$ 3, sem incluir o tempo para experimentos e correções de bugs.


Conversas:


Amigo 1 vs Alexander Smirnov


Amigo 2 vs Alexander Smirnov


Alexander Smirnov vs Amigo 1


Alexander Smirnov vs Amigo 2


As conversas tornaram-se mais interessantes e envolventes, embora ainda exista o risco de perder o contexto. O desempenho do idioma russo melhorou, mas ainda ocorrem erros. Acredito que antes de fazer o ajuste fino para uma tarefa específica com dados limitados, como o meu, seria benéfico primeiro ajustar o modelo sem supervisão em um grande corpus de textos russos. Além disso, incorporar nomes de interlocutores comuns como tokens separados pode melhorar a qualidade.


Eu não diria que acabou sendo significativamente melhor que o LoRA. Pode ser mais eficaz focar apenas em uma única pessoa e calcular a perda com base apenas nas minhas respostas (ou nas de outra pessoa), em vez de tentar aprender sobre cada um dos interlocutores.

Pensamentos finais

Certamente, tive que escolher os resultados, não porque a maioria das respostas do modelo fosse inadequada, mas porque muitas eram respostas simples como “te ligo mais tarde”, “ocupado” e “ok”, que são naturalmente frequentes. em conversas. Apesar disso, fica claro que o modelo se destaca por imitar o estilo da pessoa que representa. Ele também captura os tópicos comumente discutidos entre duas pessoas. No entanto, falta significativamente contexto nas conversas. Responder a perguntas como “ei, e daí?” ou “quais são seus planos para o fim de semana” é um desafio sem ter um contexto completo. Talvez utilizar um sistema como o Rewind , que captura tudo o que o usuário faz no computador, possa ser benéfico.

Código

Você pode encontrar o código para este projeto, bem como instruções sobre como replicá-lo sozinho em seu próprio despejo do Telegram em meu repositório do GitHub . Os registros de treinamento podem ser acessados no WandB .


Imagem principal de Christian Wiediger no Unsplash