1 pontos por GN⁺ 2024-05-27 | 1 comentários | Compartilhar no WhatsApp
  • mistral-finetune é uma base de código leve para fazer fine-tuning de modelos Mistral com eficiência de memória e bom desempenho, mas o repositório está atualmente arquivado e não recebe mais manutenção ativa
  • O método de treinamento é baseado em LoRA, que congela a maior parte dos pesos e treina apenas 1~2% de pesos adicionais na forma de perturbações matriciais de baixa dimensão
  • Para máxima eficiência, recomenda-se usar GPUs A100 ou H100; o código é otimizado para treinamento em múltiplas GPUs em um único nó, embora modelos menores como 7B também possam ser treinados em uma única GPU
  • Os modelos compatíveis incluem 7B, Mixtral 8x7B, Mixtral 8x22B, Mistral-Nemo 12B e Mistral Large v2 123B Instruct; Mistral-Nemo e Large v2 têm restrições relacionadas a comprimento de sequência e taxa de aprendizado
  • Os dados devem seguir o formato jsonl e um esquema rígido, e é importante validar o formato e estimar o tempo de treinamento com utils.validate_data antes de iniciar o treinamento

Estado e objetivo do projeto

  • O repositório mistral-finetune está em estado Archived e não recebe mais manutenção ativa
  • Se houver demanda da comunidade ou se for considerado que isso agrega valor ao ecossistema de fine-tuning, uma nova biblioteca ou uma grande atualização pode surgir no futuro
  • O objetivo é fornecer um ponto de entrada simples e guiado para fazer fine-tuning de modelos Mistral
  • Esta base de código é bastante opinativa, especialmente em relação ao formato dos dados, e não busca ser uma ferramenta genérica que cubra várias arquiteturas de modelo ou tipos de hardware
  • Para uma abordagem mais geral, é possível consultar projetos como torchtune

Método de fine-tuning e recomendações de hardware

  • mistral-finetune é baseado em LoRA
    • A maior parte dos pesos do modelo é congelada
    • Apenas 1~2% de pesos adicionais são treinados na forma de perturbações matriciais de baixa dimensão
  • Para máxima eficiência, recomenda-se usar GPUs A100 ou H100
  • O código é otimizado para ambientes de treinamento com múltiplas GPUs em um único nó
  • Modelos menores, como 7B, também funcionam bem em uma única GPU

Atualizações recentes de compatibilidade de modelos

  • Desde 13 de agosto de 2024, Mistral Large v2 é compatível com mistral-finetune
    • É necessário baixar o checkpoint 123B Instruct e definir model_id_or_path para o diretório desse checkpoint
    • Como o modelo é grande, o fine-tuning exige muito mais memória
    • No momento, é preciso definir seq_len como 8192 ou menos
    • Recomenda-se uma taxa de aprendizado mais baixa do que nos outros modelos, e lr=1e-6 tende a funcionar bem na maioria dos casos
  • Desde 19 de julho de 2024, Mistral Nemo é compatível com mistral-finetune
    • É necessário baixar o modelo 12B Base ou Instruct e definir model_id_or_path para o diretório do checkpoint
    • É necessária uma versão de mistral-common com suporte ao Tekkenizer; instale a versão >=1.3.1 com pip install --upgrade mistral-common
    • Devido ao grande tamanho do vocabulário, o pico de memória exigido pela CE loss aumenta, então atualmente é preciso mais memória
    • No momento, é preciso definir seq_len como 16384 ou menos
    • Recomenda-se usar os mesmos hiperparâmetros do 7B v3

Instalação e download de modelos

  • O processo inicial consiste em clonar o repositório e instalar as dependências
  • Recomenda-se fazer fine-tuning dos modelos oficiais da Mistral, e o README fornece os links de download e checksums dos seguintes modelos
  • 8x7B Base V1 e 8x7B Instruct V1 precisam usar o tokenizer v3 e ter o vocabulário expandido para 32768 antes do fine-tuning
  • O caminho da pasta do modelo baixado deve ser definido como caminho absoluto em model_id_or_path no YAML de treinamento

Requisitos de formato dos dados

  • Todos os arquivos de dados devem estar no formato jsonl
  • Dados de pré-treinamento armazenam texto puro na chave "text"
  • Dados de instrução armazenam uma lista de conversas na chave "messages"
    • Cada item inclui as chaves "content" e "role"
    • "role" deve ser um de "user", "assistant" ou "system"
    • A loss é calculada apenas quando "role" == "assistant"
    • É possível excluir uma mensagem do assistant do treinamento definindo "weight": 0
  • Dados de function calling também armazenam uma lista de conversas na chave "messages"
    • Cada item inclui "role" e "content" ou "tool_calls"
    • "role" deve ser um de "user", "assistant", "system" ou "tool"
    • A loss é calculada apenas quando "role" == "assistant"
    • "id" de "tool_calls" e "tool_call_id" devem ser strings aleatórias com exatamente 9 caracteres
    • O README recomenda gerar isso automaticamente no script de preparação dos dados

Validação de dados e fluxo de trabalho de exemplo

  • Antes de iniciar o treinamento, é preciso validar o formato dos dados e estimar o tempo de treinamento com utils.validate_data
  • O exemplo de instrução usa parte do dataset Ultachat_200k
    • Os dados parquet são carregados com Pandas
    • A divisão é feita em 95% para treino e 5% para avaliação
    • Os arquivos são salvos em jsonl
    • Os caminhos devem ser definidos em data.instruct_data e data.eval_instruct_data de example/7B.yaml
  • Durante a validação, pode-se descobrir que algumas conversas terminam com papel user
    • Como apenas mensagens do assistant são usadas no treinamento, a última mensagem user acaba sendo um processamento desnecessário
    • Os dados podem ser corrigidos com utils.reformat_data.py
  • Após a correção, uma nova validação mostra um resumo com número de tokens dos dados, número de tokens de treinamento, número de épocas, max_steps e tempo estimado
  • No exemplo do README, max_steps=500 percorre o dataset cerca de 5 vezes; por isso, recomenda-se max_steps=300, o que leva cerca de 30 minutos em um cluster com 8xH100

Exemplo de fine-tuning para function calling

  • O exemplo de function calling usa o Glaive function calling dataset
  • Os dados são carregados com Pandas, divididos em 95% para treino e 5% para avaliação e depois salvos em jsonl
  • Como o dataset original não segue o formato exigido para function calling, é necessário reformatá-lo
    • "from" deve ser trocado por "user"
    • Caracteres "\n" desnecessários devem ser removidos
  • Com utils.reformat_data_glaive.py, a maioria das amostras pode ser convertida para o formato correto
  • Como é impossível escrever um script de reformatação que funcione para todo tipo de dataset, datasets fora do formato exigido podem precisar de scripts específicos
  • Usando utils.validate_data --create_corrected, é possível remover os erros restantes e gerar um dataset .corrected

Execução do treinamento e exemplos de resultado

  • Após validar os dados, o treinamento pode ser iniciado
  • Para treinar mais rápido, recomenda-se uma configuração com max_steps em 300
  • run_dir deve ser definido como a pasta do experimento e, opcionalmente, wandb.project pode ser configurado para usar logging com Weights & Biases
  • A execução usa torchrun, e --nproc-per-node deve ser definido conforme o número de GPUs disponíveis
  • O treinamento com UltraChat leva cerca de 30 minutos em um nó com 8xH100, e os pesos resultantes podem atingir cerca de 6.3 no MT Bench
  • O treinamento com Glaive leva cerca de 1 hora em um nó com 8xH100, e os pesos resultantes são descritos como funcionando bem para function calling

Principais itens da configuração de treinamento

  • model_id_or_path: modelo pré-treinado ou caminho do diretório local do modelo a partir do qual iniciar o treinamento
  • run_dir: diretório para salvar checkpoints e métricas
  • seq_len: comprimento da sequência de treinamento; as amostras são empacotadas até esse tamanho para maior eficiência
  • batch_size: número de exemplos de treino por GPU
    • O batch efetivo total em tokens é num_gpus x batch_size x seq_len
  • max_steps: número total de iterações de treinamento
    • O total de tokens vistos durante o treinamento é max_steps x num_gpus x batch_size x seq_len
  • optim.lr: taxa de aprendizado inicial do otimizador
  • optim.weight_decay: weight decay; o README recomenda manter em 0.1
  • optim.pct_start: proporção da fase de warm-up do OneCycleLR do PyTorch
  • lora.rank: tamanho do adaptador LoRA; recomenda-se 64 ou menos
  • seed: seed aleatória para reprodutibilidade da inicialização, embaralhamento e amostragem dos dados
  • data.instruct_data: caminho dos dados de treino instruction
    • Pode ser um único arquivo jsonl, um diretório de jsonl ou várias fontes de dados com pesos
  • data.data: caminho opcional para dados adicionais de pré-treinamento
  • data.eval_instruct_data: caminho opcional para dados de avaliação instruction
  • eval_freq, no_eval, ckpt_freq: controlam a frequência de avaliação, avaliação intermediária e salvamento de checkpoints
  • save_adapters: define se serão salvos apenas os checkpoints LoRA ou o modelo completo com o LoRA mesclado ao modelo base
    • save_adapters=False exige CPU e memória de GPU suficientes para salvar o modelo completo em um único processo, o que normalmente só é viável para modelos 7B

Inferência e Weights & Biases

  • Para inferência com o modelo treinado, recomenda-se usar mistral-inference
  • A instalação pode ser feita com pip install mistral_inference
  • Ao executar mistral-chat, é possível usar os pesos LoRA informando o caminho de lora.safetensors salvo em --lora_path
  • Há suporte integrado a Weights and Biases para monitorar métricas e experimentos de treinamento
    • Instalação com pip install wandb
    • Recomenda-se fornecer a chave de API pela variável de ambiente WANDB_API_KEY
    • Por segurança, a chave de API não é lida a partir do YAML de configuração
    • Loss de treinamento, loss de avaliação, taxa de aprendizado e outras métricas são registradas e visualizadas no dashboard do projeto wandb
  • Para mais detalhes de uso, consulte a documentação do Weights and Biases

Escalonamento de modelos e FAQ

  • Só é possível fazer fine-tuning de modelos Mistral compatíveis com o tokenizer v3
  • Os modelos compatíveis devem ter vocabulário de 32768, e não 32000
  • Modelos antigos com vocabulário 32000 podem ser expandidos para 32768 com utils.extend_model_vocab
  • O fine-tuning de modelos MoE apresenta maior variância de desempenho
    • Sugere-se executar o mesmo fine-tuning MoE várias vezes com seeds diferentes e escolher o melhor resultado
    • Essa alta variância não foi observada em modelos dense
  • O número de tokens usados no treinamento pode ser verificado passando o arquivo YAML de treinamento para utils.validate_data.py
  • Em caso de erro de CUDA out-of-memory, é possível reduzir o batch size por GPU
    • O tamanho do batch é seq_len x batch_size
    • Recomenda-se definir batch_size como 1 e reduzir seq_len
  • A biblioteca é distribuída sob a Apache 2.0 License
  • Esta biblioteca e estes modelos não devem ser usados de forma que infrinja, se aproprie indevidamente ou viole direitos, incluindo propriedade intelectual de terceiros

1 comentários

 
GN⁺ 2024-05-27
Comentários no Hacker News
  • Com os modelos evoluindo tão rápido, fine-tuning ainda vale a pena? Tenho curiosidade sobre casos de uso reais.
    Por exemplo, no ano passado a Bloomberg treinou um LLM no nível do GPT-3.5 com dados financeiros, mas pouco depois o GPT-4-8k o superou em quase todas as tarefas financeiras.
    No fim, acabamos focando em dados de avaliação de alta qualidade e em uma arquitetura que permita trocar facilmente para modelos novos.

    • Sim. Há dados de pessoas que não estão em inglês, anotados em um formato projetado para uma pesquisa específica relacionada à saúde.
      O LLM nunca viu essas anotações, LLMs fora do inglês não são a prioridade máxima das empresas, e por causa da privacidade dos dados só podemos usar modelos offline-first.
      Nesse cenário, fazer fine-tuning de um modelo de linguagem geral se encaixa muito bem.
    • Se você precisa gerar um grande volume de saídas em um formato específico, fine-tuning pode ser útil.
      Ao fazer fine-tuning com mensagens formatadas, o modelo passa a gerar esse formato automaticamente, economizando muitos tokens que seriam usados em cada prompt para explicar o formato de saída.
    • E se forem dados corporativos internos que o GPT-4 nunca viu?
    • Em tarefas tradicionais de processamento de linguagem natural, LLMs ainda ficam bem abaixo de pipelines de PLN dedicados, como tagging de classe gramatical ou tagging de atributos.
      Ainda assim, o fine-tuning fecha bastante essa lacuna.
      É um domínio estreito, mas isso também vale para grande parte da programação. Se o objetivo é fazer um LLM geral pender mais para os seus dados, provavelmente o fine-tuning não é muito relevante.
      Mas, se você está tentando resolver um problema muito específico e ambíguo, e o LLM só resolve parte dele, o fine-tuning provavelmente é a melhor opção.
    • Chamadas de função também podem ser um motivo.
      Se o seu app tem muitas funções customizadas que interagem com ferramentas, você pode preferir fine-tuning em vez de gastar tokens de contexto.
  • Que GPU seria necessária para fazer isso? Tenho um notebook com 3060 Ti, i9 e 16 GB de RAM.
    Não tenho cota na AWS ou no GCP e já ouvi falar da Paperspace, mas quero começar logo com fine-tuning do Mistral porque pretendo usar alguns modelos Mistral em um projeto de cliente em andamento.

    • Se o orçamento não for literalmente zero, recomendo fortemente ir de desktop gamer.
      GPUs gamer conseguem dissipar 300 W de calor sem problemas; uma GPU de notebook derreteria se fizesse isso e provavelmente fica limitada a algo em torno de 100 W.
      Dissipação de calor é diretamente proporcional à velocidade.
      Além disso, em um desktop é possível fazer upgrade para uma GPU mais rápida ou usar várias GPUs.
      Dito isso, especialmente configurações multi-GPU são barulhentas e geram calor suficiente para aquecer rapidamente um cômodo.
      Se, nos próximos anos, você não for deixar a GPU em carga máxima por mais de 10% do tempo, a nuvem provavelmente sai mais barata.
    • Vale conferir este site: https://www.hardware-corner.net/llm-database/Mistral/
      Ele reúne os requisitos de hardware por modelo e permite filtrar os modelos disponíveis escolhendo VRAM e memória do sistema.
    • Dá para usar um servidor com GPU na Hetzner por 184 euros por mês.
      Na nossa empresa, fizemos fine-tuning de Mistral e Llama 3 com a RTX4000 de lá.
      É um pouco limitado porque tem só 20 GB de RAM, mas para números maiores de tokens de entrada, reduzir o nível de quantização ajudou.
      Agora eles também oferecem aluguel por hora.
    • Vale experimentar o openpipe.
      Estamos usando na empresa atualmente e tivemos resultados bem bons.
  • É muito interessante ver quais ferramentas vão se tornar o padrão de fato para cada caso de uso comum de LLM.
    O ecossistema é tão fragmentado que sinto que nem ouvi falar da maioria das ferramentas.
    Há alguns dias vi o Olive, da Microsoft, e era uma ferramenta completamente nova para mim.

  • Agora que muitos LLMs open source já chegaram a um nível “usável”, o importante é facilitar o desenvolvimento ao redor deles.
    Em especial, pessoas que são ao mesmo tempo usuárias e desenvolvedoras precisam conseguir usar dados privados, mais precisamente dados que não estavam no pré-treinamento do modelo.
    O repositório diz que ele é otimizado para modelos grandes e exige A100/H100, mas ainda assim sinto que isso pode ajudar mais modelos menores do que modelos grandes.
    Dá para estender “se você construir, eles virão” para “se você fornecer as ferramentas, eles construirão”.

    • “Se você fornecer as ferramentas, eles construirão” só vale quando o incentivo para aprender aquela tecnologia faz esperar ganhos futuros.
  • A parte dos pesos é interessante.
    O SFTTrainer da HuggingFace permite treinar só a parte de completions, se você quiser, mas, embora isso pareça natural para humanos, em geral é melhor treinar LLMs para prever a entrada inteira.
    Com essa abordagem, dá para obter o melhor dos dois mundos.

  • Será que dá para otimizar para treinar variantes maiores com duas 3090 ou duas 4090?

  • Como eu poderia treinar meu modelo de conversas do WhatsApp?

    • Você precisa deixar mais claro o que quer dizer.
      Você quer treinar um modelo com suas mensagens do WhatsApp? Qual é o objetivo? Depende se você quer que ele escreva como você ou se quer perguntas e respostas baseadas em RAG.