O ajuste fino de modelos de linguagem grandes (LLMs) como o Llama 3 envolve a adaptação de um modelo pré-treinado para tarefas específicas usando um conjunto de dados específico do domínio. Esse processo aproveita o conhecimento pré-existente do modelo, tornando-o eficiente e econômico em comparação ao treinamento do zero. Neste guia, percorreremos as etapas para ajustar o Llama 3 usando QLoRA (Quantized LoRA), um método com eficiência de parâmetros que minimiza o uso de memória e os custos computacionais.
Visão geral do ajuste fino
O ajuste fino envolve várias etapas importantes:
- Selecionando um modelo pré-treinado: Escolha um modelo base que esteja alinhado com a arquitetura desejada.
- Reunindo um conjunto de dados relevantes: Colete e pré-processe um conjunto de dados específico para sua tarefa.
- Afinação: Adapte o modelo usando o conjunto de dados para melhorar seu desempenho em tarefas específicas.
- Avaliação: Avalie o modelo ajustado usando métricas qualitativas e quantitativas.
Conceitos e Técnicas
Ajuste fino de grandes modelos de linguagem
Ajuste fino completo
O ajuste fino completo atualiza todos os parâmetros do modelo, tornando-o específico para a nova tarefa. Este método requer recursos computacionais significativos e geralmente é impraticável para modelos muito grandes.
Ajuste fino com eficiência de parâmetros (PEFT)
PEFT atualiza apenas um subconjunto dos parâmetros do modelo, reduzindo os requisitos de memória e o custo computacional. Essa técnica previne esquecimento catastrófico e mantém o conhecimento geral do modelo.
Adaptação de baixa classificação (LoRA) e LoRA quantizado (QLoRA)
O LoRA ajusta apenas algumas matrizes de baixa classificação, enquanto o QLoRA quantiza essas matrizes para reduzir ainda mais o consumo de memória.
Métodos de ajuste fino
- Ajuste fino completo: Isso envolve treinar todos os parâmetros do modelo no conjunto de dados específico da tarefa. Embora esse método possa ser muito eficaz, ele também é computacionalmente caro e requer memória significativa.
- Ajuste fino eficiente de parâmetros (PEFT): PEFT atualiza apenas um subconjunto dos parâmetros do modelo, tornando-o mais eficiente em termos de memória. Técnicas como Low-Rank Adaptation (LoRA) e Quantized LoRA (QLoRA) se enquadram nessa categoria.
O que é LoRA?
![Comparando métodos de ajuste fino: QLORA aprimora LoRA com quantização de precisão de 4 bits e otimizadores paginados para gerenciamento de picos de memória](https://i0.wp.com/www.unite.ai/wp-content/uploads/2023/09/Screenshot-2023-09-10-163359.png?resize=662%2C293&ssl=1)
Comparando métodos de ajuste fino: QLORA aprimora LoRA com quantização de precisão de 4 bits e otimizadores paginados para gerenciamento de picos de memória
LoRA é um método de ajuste fino aprimorado onde, em vez de ajustar todos os pesos do modelo pré-treinado, duas matrizes menores que se aproximam da matriz maior são ajustadas. Essas matrizes constituem o adaptador LoRA. Esse adaptador ajustado fino é então carregado no modelo pré-treinado e usado para inferência.
Principais vantagens do LoRA:
- Eficiência de memória: O LoRA reduz o consumo de memória ajustando apenas pequenas matrizes em vez do modelo inteiro.
- Reutilização: O modelo unique permanece inalterado, e vários adaptadores LoRA podem ser usados com ele, facilitando o manuseio de múltiplas tarefas com menores requisitos de memória.
O que é LoRA Quantizado (QLoRA)?
QLoRA leva LoRA um passo adiante ao quantizar os pesos dos adaptadores LoRA para menor precisão (por exemplo, 4 bits em vez de 8 bits). Isso reduz ainda mais o uso de memória e os requisitos de armazenamento, mantendo um nível comparável de eficácia.
Principais vantagens do QLoRA:
- Eficiência de memória ainda maior:Ao quantizar os pesos, o QLoRA reduz significativamente os requisitos de memória e armazenamento do modelo.
- Mantém o desempenho:Apesar da precisão reduzida, o QLoRA mantém níveis de desempenho próximos aos dos modelos de precisão complete.
Adaptação específica da tarefa
Durante o ajuste fino, os parâmetros do modelo são ajustados com base no novo conjunto de dados, ajudando-o a entender melhor e gerar conteúdo relevante para a tarefa específica. Esse processo retém o conhecimento geral da linguagem obtido durante o pré-treinamento, ao mesmo tempo em que adapta o modelo às nuances do domínio de destino.
Ajuste fino na prática
Ajuste fino completo vs. PEFT
- Ajuste fino completo: Envolve o treinamento de todo o modelo, o que pode ser computacionalmente caro e requer memória significativa.
- PEFT (LoRA e QLoRA): Ajusta apenas um subconjunto de parâmetros, reduzindo os requisitos de memória e evitando esquecimentos catastróficos, tornando-se uma alternativa mais eficiente.
Etapas de implementação
- Ambiente de configuração: Instale as bibliotecas necessárias e configure o ambiente de computação.
- Carregar e pré-processar conjunto de dados: Carregue o conjunto de dados e pré-processe-o em um formato adequado para o modelo.
- Carregar modelo pré-treinado: Carregue o modelo base com configurações de quantização se estiver usando QLoRA.
- Tokenização: Tokenize o conjunto de dados para prepará-lo para treinamento.
- Treinamento: Ajuste o modelo usando o conjunto de dados preparado.
- Avaliação: Avalie o desempenho do modelo em tarefas específicas usando métricas qualitativas e quantitativas.
Guia Steo by Step para ajuste fino do LLM
Configurando o ambiente
Usaremos um pocket book Jupyter para este tutorial. Plataformas como Kaggle, que oferecem uso gratuito de GPU, ou Google Colab são ideais para executar esses experimentos.
1. Instale as bibliotecas necessárias
Primeiro, certifique-se de ter as bibliotecas necessárias instaladas:
!pip set up -qqq -U bitsandbytes transformers peft speed up datasets scipy einops consider trl rouge_score</div>
2. Importar bibliotecas e configurar o ambiente
import os import torch from datasets import load_dataset from transformers import ( AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments, pipeline, HfArgumentParser ) from trl import ORPOConfig, ORPOTrainer, setup_chat_format, SFTTrainer from tqdm import tqdm import gc import pandas as pd import numpy as np from huggingface_hub import interpreter_login # Disable Weights and Biases logging os.environ('WANDB_DISABLED') = "true" interpreter_login()
3. Carregue o conjunto de dados
Usaremos o conjunto de dados DialogSum para este tutorial:
Pré-processar o conjunto de dados de acordo com os requisitos do modelo, incluindo a aplicação de modelos apropriados e a garantia de que o formato dos dados seja adequado para ajuste fino. (Abraçando o Rosto) (Acampamento de Dados).
dataset_name = "neil-code/dialogsum-test" dataset = load_dataset(dataset_name)
Inspecione a estrutura do conjunto de dados:
print(dataset('check')(0))
4. Crie a configuração BitsAndBytes
Para carregar o modelo no formato de 4 bits:
compute_dtype = getattr(torch, "float16") bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type='nf4', bnb_4bit_compute_dtype=compute_dtype, bnb_4bit_use_double_quant=False, )
5. Carregue o modelo pré-treinado
Usando o modelo Phi-2 da Microsoft para este tutorial:
model_name = 'microsoft/phi-2' device_map = {"": 0} original_model = AutoModelForCausalLM.from_pretrained( model_name, device_map=device_map, quantization_config=bnb_config, trust_remote_code=True, use_auth_token=True )
6. Tokenização
Configurar o tokenizador:
tokenizer = AutoTokenizer.from_pretrained( model_name, trust_remote_code=True, padding_side="left", add_eos_token=True, add_bos_token=True, use_fast=False ) tokenizer.pad_token = tokenizer.eos_token
Ajuste fino do Llama 3 ou outros modelos
Ao ajustar modelos como o Llama 3 ou qualquer outro LLM de código aberto de última geração, há considerações e ajustes específicos necessários para garantir o desempenho splendid. Aqui estão as etapas detalhadas e os insights sobre como abordar isso para diferentes modelos, incluindo Llama 3, GPT-3 e Mistral.
5.1 Usando o Llama 3
Seleção de modelo:
- Certifique-se de ter o identificador de modelo correto do hub de modelos Hugging Face. Por exemplo, o modelo Llama 3 pode ser identificado como
meta-llama/Meta-Llama-3-8B
em Abraçar o Rosto. - Certifique-se de solicitar acesso e fazer login na sua conta Hugging Face, se necessário, para modelos como o Llama 3. (Abraçando o Rosto)
Tokenização:
- Use o tokenizador apropriado para o Llama 3, garantindo que ele seja compatível com o modelo e suporte os recursos necessários, como preenchimento e tokens especiais.
Memória e Computação:
- O ajuste fino de modelos grandes como o Llama 3 requer recursos computacionais significativos. Garanta que seu ambiente, como uma configuração de GPU poderosa, possa lidar com os requisitos de memória e processamento. Garanta que o ambiente possa lidar com os requisitos de memória, que podem ser mitigados usando técnicas como QLoRA para reduzir a pegada de memória (Fóruns de abraços)
Exemplo:
model_name = 'meta-llama/Meta-Llama-3-8B' device_map = {"": 0} bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.float16, bnb_4bit_use_double_quant=True, ) original_model = AutoModelForCausalLM.from_pretrained( model_name, device_map=device_map, quantization_config=bnb_config, trust_remote_code=True, use_auth_token=True )
Tokenização:
Dependendo do caso de uso específico e dos requisitos do modelo, garanta a configuração correta do tokenizer sem configurações redundantes. Por exemplo, use_fast=True
é recomendado para melhor desempenho (Abraçando o Rosto) (Pesos e Vieses).
tokenizer = AutoTokenizer.from_pretrained( model_name, trust_remote_code=True, padding_side="left", add_eos_token=True, add_bos_token=True, use_fast=False ) tokenizer.pad_token = tokenizer.eos_token
5.2 Usando outros modelos populares (por exemplo, GPT-3, Mistral)
Seleção de modelo:
- Para modelos como GPT-3 e Mistral, certifique-se de usar o nome e o identificador corretos do modelo do hub de modelos Hugging Face ou de outras fontes.
Tokenização:
- Semelhante ao Llama 3, certifique-se de que o tokenizador esteja configurado corretamente e seja compatível com o modelo.
Memória e Computação:
- Cada modelo pode ter requisitos de memória diferentes. Ajuste a configuração do seu ambiente de acordo.
Exemplo para GPT-3:
model_name = 'openai/gpt-3' device_map = {"": 0} bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.float16, bnb_4bit_use_double_quant=True, ) original_model = AutoModelForCausalLM.from_pretrained( model_name, device_map=device_map, quantization_config=bnb_config, trust_remote_code=True, use_auth_token=True )
Exemplo para Mistral:
model_name = 'mistral-7B' device_map = {"": 0} bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.float16, bnb_4bit_use_double_quant=True, ) original_model = AutoModelForCausalLM.from_pretrained( model_name, device_map=device_map, quantization_config=bnb_config, trust_remote_code=True, use_auth_token=True )
Considerações sobre tokenização: Cada modelo pode ter requisitos de tokenização exclusivos. Garanta que o tokenizador corresponda ao modelo e esteja configurado corretamente.
Exemplo de Tokenizador Llama 3:
tokenizer = AutoTokenizer.from_pretrained( model_name, trust_remote_code=True, padding_side="left", add_eos_token=True, add_bos_token=True, use_fast=False ) tokenizer.pad_token = tokenizer.eos_token
Exemplo de Tokenizador GPT-3 e Mistral:
tokenizer = AutoTokenizer.from_pretrained( model_name, use_fast=True )
7. Teste o modelo com inferência de tiro zero
Avalie o modelo base com uma entrada de amostra:
from transformers import set_seed set_seed(42) index = 10 immediate = dataset('check')(index)('dialogue') formatted_prompt = f"Instruct: Summarize the next dialog.n{immediate}nOutput:n" # Generate output def gen(mannequin, immediate, max_length): inputs = tokenizer(immediate, return_tensors="pt").to(mannequin.machine) outputs = mannequin.generate(**inputs, max_length=max_length) return tokenizer.batch_decode(outputs, skip_special_tokens=True) res = gen(original_model, formatted_prompt, 100) output = res(0).break up('Output:n')(1) print(f'INPUT PROMPT:n{formatted_prompt}') print(f'MODEL GENERATION - ZERO SHOT:n{output}')
8. Pré-processe o conjunto de dados
Converta pares de diálogo-resumo em prompts:
def create_prompt_formats(pattern): blurb = "Under is an instruction that describes a process. Write a response that appropriately completes the request." instruction = "### Instruct: Summarize the beneath dialog." input_context = pattern('dialogue') response = f"### Output:n{pattern('abstract')}" finish = "### Finish" components = (blurb, instruction, input_context, response, finish) formatted_prompt = "nn".be part of(components) pattern("textual content") = formatted_prompt return pattern dataset = dataset.map(create_prompt_formats)
Tokenize o conjunto de dados formatado:
def preprocess_batch(batch, tokenizer, max_length): return tokenizer(batch("textual content"), max_length=max_length, truncation=True) max_length = 1024 train_dataset = dataset("practice").map(lambda batch: preprocess_batch(batch, tokenizer, max_length), batched=True) eval_dataset = dataset("validation").map(lambda batch: preprocess_batch(batch, tokenizer, max_length), batched=True)
9. Put together o modelo para QLoRA
Put together o modelo para ajuste fino com eficiência de parâmetros:
original_model = prepare_model_for_kbit_training(original_model)
Hiperparâmetros e seu impacto
Os hiperparâmetros desempenham um papel essential na otimização do desempenho do seu modelo. Aqui estão alguns hiperparâmetros importantes a serem considerados:
- Taxa de Aprendizagem: Controla a velocidade na qual o modelo atualiza seus parâmetros. Uma alta taxa de aprendizado pode levar a uma convergência mais rápida, mas pode ultrapassar a solução ótima. Uma baixa taxa de aprendizado garante uma convergência estável, mas pode exigir mais épocas.
- Tamanho do batch: O número de amostras processadas antes que o modelo atualize seus parâmetros. Tamanhos de lote maiores podem melhorar a estabilidade, mas exigem mais memória. Tamanhos de lote menores podem levar a mais ruído no processo de treinamento.
- Etapas de acumulação de gradiente: Este parâmetro ajuda a simular tamanhos de lote maiores acumulando gradientes em várias etapas antes de executar uma atualização de parâmetro.
- Número de Épocas: O número de vezes que todo o conjunto de dados é passado pelo modelo. Mais épocas podem melhorar o desempenho, mas podem levar a overfitting se não forem gerenciadas corretamente.
- Decadência de peso: Técnica de regularização para evitar overfitting penalizando pesos grandes.
- Agendador de Taxas de Aprendizagem: Ajusta a taxa de aprendizado durante o treinamento para melhorar o desempenho e a convergência.
Personalize a configuração de treinamento ajustando hiperparâmetros como taxa de aprendizado, tamanho do lote e etapas de acumulação de gradiente com base no modelo específico e nos requisitos da tarefa. Por exemplo, os modelos Llama 3 podem exigir taxas de aprendizado diferentes em comparação com modelos menores. (Pesos e Vieses) (GitHub)
Exemplo de configuração de treinamento
orpo_args = ORPOConfig( learning_rate=8e-6, lr_scheduler_type="linear",max_length=1024,max_prompt_length=512, beta=0.1,per_device_train_batch_size=2,per_device_eval_batch_size=2, gradient_accumulation_steps=4,optim="paged_adamw_8bit",num_train_epochs=1, evaluation_strategy="steps",eval_steps=0.2,logging_steps=1,warmup_steps=10, report_to="wandb",output_dir="./outcomes/",)
10. Treine o modelo
Configure o treinador e comece a treinar:
coach = ORPOTrainer( mannequin=original_model, args=orpo_args, train_dataset=train_dataset, eval_dataset=eval_dataset, tokenizer=tokenizer,) coach.practice() coach.save_model("fine-tuned-llama-3")
Avaliando o modelo ajustado
Após o treinamento, avalie o desempenho do modelo usando métodos qualitativos e quantitativos.
1. Avaliação Humana
Examine os resumos gerados com os escritos por humanos para avaliar a qualidade.
2. Avaliação quantitativa
Use métricas como ROUGE para avaliar o desempenho:
from rouge_score import rouge_scorer scorer = rouge_scorer.RougeScorer(('rouge1', 'rouge2', 'rougeL'), use_stemmer=True) scores = scorer.rating(reference_summary, generated_summary) print(scores)
Desafios e soluções comuns
1. Limitações de memória
Usar QLoRA ajuda a mitigar problemas de memória ao quantizar pesos de modelos para 4 bits. Certifique-se de ter memória de GPU suficiente para lidar com o tamanho do lote e do modelo.
2. Sobreajuste
Monitore métricas de validação para evitar overfitting. Use técnicas como early stops e weight decay.
3. Treinamento lento
Otimize a velocidade do treinamento ajustando o tamanho do lote, a taxa de aprendizado e usando o acúmulo de gradiente.
4. Qualidade de dados
Garanta que seu conjunto de dados esteja limpo e bem pré-processado. Dados de baixa qualidade podem impactar significativamente o desempenho do modelo.
Conclusão
O ajuste fino de LLMs usando QLoRA é uma maneira eficiente de adaptar grandes modelos pré-treinados a tarefas específicas com custos computacionais reduzidos. Seguindo este guia, você pode ajustar o PHI, o Llama 3 ou qualquer outro modelo de código aberto para atingir alto desempenho em suas tarefas específicas.