Mistral-finetune - Como fazer fine-tuning de modelos Mistral
(github.com/mistralai)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
jsonle um esquema rígido, e é importante validar o formato e estimar o tempo de treinamento comutils.validate_dataantes de iniciar o treinamento
Estado e objetivo do projeto
- O repositório
mistral-finetuneestá 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_pathpara o diretório desse checkpoint - Como o modelo é grande, o fine-tuning exige muito mais memória
- No momento, é preciso definir
seq_lencomo 8192 ou menos - Recomenda-se uma taxa de aprendizado mais baixa do que nos outros modelos, e
lr=1e-6tende a funcionar bem na maioria dos casos
- É necessário baixar o checkpoint 123B Instruct e definir
- 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_pathpara o diretório do checkpoint - É necessária uma versão de
mistral-commoncom suporte ao Tekkenizer; instale a versão>=1.3.1compip 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_lencomo 16384 ou menos - Recomenda-se usar os mesmos hiperparâmetros do 7B v3
- É necessário baixar o modelo 12B Base ou Instruct e definir
Instalação e download de modelos
- O processo inicial consiste em clonar o repositório e instalar as dependências
git clone https://github.com/mistralai/mistral-finetune.gitpip install -r requirements.txt
- Recomenda-se fazer fine-tuning dos modelos oficiais da Mistral, e o README fornece os links de download e checksums dos seguintes modelos
- 7B Base:
0663b293810d7571dad25dae2f2a5806 - 7B Instruct v3:
80b71fcb6416085bcb4efad86dfb4d52 - 8x7B Base: link do Hugging Face
- 8x7B Instruct:
8e2d3930145dc43d3084396f49d38a3f - 8x22 Instruct:
471a02a6902706a2f1e44a693813855b - 8x22B Base:
a2fa75117174f87d1197e3a4eb50371a - 12B Instruct (Mistral-Nemo):
296fbdf911cb88e6f0be74cd04827fe7 - 12 Base (Mistral-Nemo):
c5d079ac4b55fc1ae35f51f0a3c0eb83 - 123B Instruct (Large v2):
fc602155f9e39151fba81fcaab2fa7c4
- 7B Base:
- 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_pathno 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
- Cada item inclui as chaves
- 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
- Cada item inclui
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_dataedata.eval_instruct_datadeexample/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
useracaba sendo um processamento desnecessário - Os dados podem ser corrigidos com utils.reformat_data.py
- Como apenas mensagens do assistant são usadas no treinamento, a última mensagem
- 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_stepse tempo estimado - No exemplo do README,
max_steps=500percorre o dataset cerca de 5 vezes; por isso, recomenda-semax_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_stepsem 300 run_dirdeve ser definido como a pasta do experimento e, opcionalmente,wandb.projectpode ser configurado para usar logging com Weights & Biases- A execução usa
torchrun, e--nproc-per-nodedeve 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 treinamentorun_dir: diretório para salvar checkpoints e métricasseq_len: comprimento da sequência de treinamento; as amostras são empacotadas até esse tamanho para maior eficiênciabatch_size: número de exemplos de treino por GPU- O batch efetivo total em tokens é
num_gpus x batch_size x seq_len
- O batch efetivo total em tokens é
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
- O total de tokens vistos durante o treinamento é
optim.lr: taxa de aprendizado inicial do otimizadoroptim.weight_decay: weight decay; o README recomenda manter em 0.1optim.pct_start: proporção da fase de warm-up doOneCycleLRdo PyTorchlora.rank: tamanho do adaptador LoRA; recomenda-se 64 ou menosseed: seed aleatória para reprodutibilidade da inicialização, embaralhamento e amostragem dos dadosdata.instruct_data: caminho dos dados de treino instruction- Pode ser um único arquivo
jsonl, um diretório dejsonlou várias fontes de dados com pesos
- Pode ser um único arquivo
data.data: caminho opcional para dados adicionais de pré-treinamentodata.eval_instruct_data: caminho opcional para dados de avaliação instructioneval_freq,no_eval,ckpt_freq: controlam a frequência de avaliação, avaliação intermediária e salvamento de checkpointssave_adapters: define se serão salvos apenas os checkpoints LoRA ou o modelo completo com o LoRA mesclado ao modelo basesave_adapters=Falseexige 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 delora.safetensorssalvo 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
- Instalação com
- 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_sizecomo 1 e reduzirseq_len
- O tamanho do batch é
- 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
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.
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.
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.
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.
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.
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.
Ele reúne os requisitos de hardware por modelo e permite filtrar os modelos disponíveis escolhendo VRAM e memória do sistema.
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.
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”.
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?
Um ponto de partida que cobre algumas opções está aqui: https://huggingface.co/blog/trl-peft
Como eu poderia treinar meu modelo de conversas do WhatsApp?
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.