Custa milhões de dólares e meses de tempo de computação para treinar um grande modelo de idioma do zero.Você provavelmente nunca precisa fazê-lo.Fine-tuning permite que você adapte modelos de idioma pré-treinados às suas necessidades em horas ou dias, não meses, com uma fração dos recursos. Este tutorial vai te levar Você aprenderá as quatro técnicas básicas de ajuste fino, codificará um pipeline de treinamento completo em Python e aprenderá as técnicas que separam modelos prontos para produção de experimentos caros. from theory to practice O que é o LLM Fine-Tuning? Fine-tuning treina um modelo de idioma existente em seus dados para melhorar sua Modelos pré-treinados são poderosos generalistas, mas expondo-os a Você pode transformá-los em especialistas para o seu caso de uso. performance on specific tasks focused examples Em vez de construir um modelo do zero (que requer computação e dados maciços), você está dando a um modelo já capaz de um curso de colisão no que importa para você, seja diagnóstico médico, automação de suporte ao cliente, análise de sentimentos ou qualquer outra tarefa específica. Como funciona o LLM Fine-Tuning? Fine-tuning continua o processo de treinamento em modelos de linguagem pré-treinados usando seu conjunto de dados específico. O modelo processa seus exemplos fornecidos, compara suas próprias saídas com os resultados esperados, e adaptar e minimizar as perdas. updates internal weights Esta abordagem pode variar com base no seu , em e Alguns projetos exigem ajuste completo, onde você atualiza todos os parâmetros do modelo, enquanto outros funcionam melhor com métodos eficientes em parâmetros, como Isso altera apenas uma pequena parte. goals available data computational resources Loira LLM Métodos de Fine-Tuning Supervisão de Fine-Tuning SFT ensina o modelo a aprender os padrões dos pares de perguntas e respostas corretas e ajusta os pesos do modelo para corresponder exatamente a essas respostas. Use isso quando você quer saídas consistentes, como fazer com que o modelo sempre responda no formato JSON, seguindo seu script de atendimento ao cliente ou escrevendo e-mails no tom da sua empresa. (Prompt, Ideal Response) Fine-Tuning sem supervisão Alimenta o modelo com toneladas de texto bruto (sem perguntas ou dados rotulados necessários) para que ele aprenda o vocabulário e padrões de um domínio específico. Embora este seja tecnicamente um processo de pré-treinamento conhecido como Pre-treinamento Continuado (CPT), isso geralmente é feito após a fase inicial de pré-treinamento. Use isso primeiro quando seu modelo precisa entender conteúdo especializado em que não foi originalmente treinado, como terminologia médica, contratos legais ou uma nova língua. Otimização de preferência direta O DPO ensina o modelo a preferir respostas melhores, mostrando exemplos de respostas boas versus ruins para a mesma pergunta e ajustando-a para favorecer as boas. Use DPO após o treinamento básico para corrigir comportamentos irritantes, como parar o modelo de fazer as coisas, ser muito verboso ou dar respostas inseguras. (Prompt, Good Response, Bad Response) Reforço Fine-Tuning No RLHF, você primeiro treina um modelo de recompensa em prompts com múltiplas respostas classificadas por seres humanos, ensinando-o a prever quais respostas as pessoas preferem. Em seguida, você usa o aprendizado de reforço para otimizar e ajustar um modelo que gera respostas, que o modelo de recompensa julga. Isso ajuda o modelo a aprender ao longo do tempo para produzir saídas com maior pontuação. É melhor para tarefas onde julgar a qualidade é mais fácil do que criar exemplos perfeitos, como diagnósticos médicos, pesquisa jurídica e outro raciocínio complexo específico do domínio. (Prompt, [Response A, Response B, ...], [Rankings]) Passo a passo Fine-Tuning LLMs Tutorial Vamos percorrer todos os passos de ajustar um pequeno modelo pré-treinado para resolver problemas de matemática baseados em palavras, algo que ele luta com fora da caixa. A abordagem Ensinar uma terminologia especializada para um modelo, melhorar o desempenho do modelo em tarefas específicas ou adaptá-lo ao seu domínio. works for virtually any use case of fine-tuning LLMs pré-requisitos Instale alguns pacotes de Python que usaremos ao longo deste tutorial.Em uma nova pasta de projeto, crie e ative um ambiente virtual de Python e, em seguida, instale essas bibliotecas usando Ou o seu gerenciador de pacotes preferido: pip pip install requests datasets transformers 'transformers[torch]' Obter e carregar o conjunto de dados O processo de ajuste começa com a escolha do conjunto de dados, que é provavelmente a decisão mais importante. . reflect the task you want your model to perform Tarefas simples, como análise de sentimentos, precisam de pares básicos de entrada e saída.Tarefas complexas, como seguir instruções ou responder perguntas, exigem conjuntos de dados mais ricos com contexto, exemplos e formatos variados. O ponto de partida mais fácil é o biblioteca de conjuntos de dados, que hospeda milhares de conjuntos de dados de código aberto para diferentes domínios e tarefas. ou dados disponíveis publicamente. Hugging Face Purchase specialized datasets build your own by Scraping Scraping Por exemplo, se você quiser construir um modelo de análise de sentimentos para comentários de produtos da Amazon, você pode querer coletar dados de comentários reais usando uma ferramenta de rascunho da web. : Web Scraper com API import json import requests # Web Scraper API parameters. payload = { "source": "amazon_product", # Query is the ASIN of a product. "query": "B0DZDBWM5B", "parse": True, } # Send a request to the API and get the response. response = requests.post( "https://realtime.oxylabs.io/v1/queries", # Visit https://dashboard.oxylabs.io to claim FREE API tokens. auth=("USERNAME", "PASSWORD"), json=payload, ) print(response.text) # Extract the reviews from the response. reviews = response.json()["results"][0]["content"]["reviews"] print(f"Found {len(reviews)} reviews") # Save the reviews to a JSON file. with open("reviews.json", "w") as f: json.dump(reviews, f, indent=2) For this tutorial, let’s keep it simple without building a custom data collection pipeline. Since we're teaching the base model to solve word-based math problems, we can use the openai/gsm8k dataset. It’s a collection of grade-school math problems with step-by-step solutions. Load it in your Python file: from datasets import load_dataset dataset = load_dataset("openai/gsm8k", "main") print(dataset["train"][0]) Tokenize os dados para processamento Os modelos não entendem o texto diretamente; eles trabalham com A tokenização converte seu texto em tokens (representações numéricas) que o modelo pode processar. Cada modelo tem seu próprio tokenizador treinado ao lado dele, então use o que corresponde ao seu modelo de base: numbers from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B") tokenizer.pad_token = tokenizer.eos_token Como tokenizamos nossas formas de dados o que o modelo aprende.Para problemas de matemática, queremos ajustar o modelo para aprender como Aqui está o truque: tokenize perguntas e respostas separadamente, em seguida, use uma técnica de mascaramento. Resposta Responder a perguntas tokens O modelo só aprende com as respostas, tornando o treinamento mais focado e eficiente. -100 def tokenize_function(examples): input_ids_list = [] labels_list = [] for question, answer in zip(examples["question"], examples["answer"]): # Tokenize question and answer separately question_tokens = tokenizer(question, add_special_tokens=False)["input_ids"] answer_tokens = tokenizer(answer, add_special_tokens=False)["input_ids"] + [tokenizer.eos_token_id] # Combine question + answer for input input_ids = question_tokens + answer_tokens # Mask question tokens with -100 so loss is only computed on the answer labels = [-100] * len(question_tokens) + answer_tokens input_ids_list.append(input_ids) labels_list.append(labels) return { "input_ids": input_ids_list, "labels": labels_list, } Aplique esta função de tokenização a conjuntos de dados de treinamento e teste. filtramos exemplos com mais de 512 tokens para manter o uso da memória gerenciável e garantir que o modelo processe informações completas sem truncação. train_dataset = dataset["train"].map( tokenize_function, batched=True, remove_columns=dataset["train"].column_names, ).filter(lambda x: len(x["input_ids"]) <= 512) .shuffle(seed=42) eval_dataset = dataset["test"].map( tokenize_function, batched=True, remove_columns=dataset["test"].column_names, ).filter(lambda x: len(x["input_ids"]) <= 512) print(f"Samples: {len(dataset['train'])} → {len(train_dataset)} (after filtering)") print(f"Samples: {len(dataset['test'])} → {len(eval_dataset)} (after filtering)") Optional: Você pode treinar o modelo em um subconjunto de dados.Então, em vez de usar o conjunto de dados completo de 8.5K, você pode minimizá-lo para 3K no total, tornando o processo muito mais rápido: train_dataset = train_dataset.select(range(2000)) eval_dataset = eval_dataset.select(range(1000)) Os conjuntos de dados menores aumentam o risco de sobreposição, onde o modelo memoriza dados de treinamento em vez de padrões gerais de aprendizagem.Para a produção, tente pelo menos amostras de treinamento 5K+ e ajuste cuidadosamente seus hiperparâmetros. Keep in mind: Inicialização do modelo de base Em seguida, carregue o modelo de base pré-treinado para ajustá-lo melhorando suas habilidades de resolução de problemas matemáticos: from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B") model.config.pad_token_id = tokenizer.pad_token_id Fine-Tune usando o Método do Treinador É aqui que a magia acontece. TrainingArguments controla como o seu modelo aprende (pense nisso como a receita que determina a qualidade do seu resultado final). Essas configurações e hiperparâmetros podem fazer ou quebrar o seu ajuste, então experimente com valores diferentes para encontrar o que funciona para o seu caso de uso. Key parameters explained: · Mais épocas equivale a mais oportunidades de aprendizagem, mas muitos causam overfitting. Epochs: · Afeta o uso da memória e a velocidade de treinamento. Ajuste-os com base no seu hardware. Batch size: · Controla a rapidez com que o modelo se ajusta.Muito alto e pode perder a solução ideal, muito baixo e o treinamento leva para sempre. Learning rate: · Pode ajudar a prevenir o overfitting, impedindo que o modelo se incline demais em qualquer padrão único.Se a quebra de peso for muito grande, pode levar ao underfitting, impedindo que o modelo aprenda os padrões necessários. Weight decay: A configuração ideal abaixo é especializada para treinamento de CPU (remove use_cpu=True se você tiver uma GPU): from transformers import TrainingArguments, Trainer, DataCollatorForSeq2Seq training_args = TrainingArguments( output_dir="./qwen-math", # Custom output directory for the fine-tuned model use_cpu=True, # Set to False or remove to use GPU if available # Training duration num_train_epochs=2, # 3 may improve reasoning at the expense of overfitting # Batch size and memory management per_device_train_batch_size=5, # Adjust depending on your PC capacity per_device_eval_batch_size=5, # Adjust depending on your PC capacity gradient_accumulation_steps=4, # Decreases memory usage, adjust if needed # Learning rate and regularization learning_rate=2e-5, # Affects learning speed and overfitting weight_decay=0.01, # Prevents overfitting by penalizing large weights max_grad_norm=1.0, # Prevents exploding gradients warmup_ratio=0.1, # Gradually increases learning rate to stabilize training lr_scheduler_type="cosine", # Smoother decay than linear # Evaluation and checkpointing eval_strategy="steps", eval_steps=100, save_strategy="steps", save_steps=100, save_total_limit=3, # Keep only the best 3 checkpoints load_best_model_at_end=True, # Load the best checkpoint at the end of training metric_for_best_model="eval_loss", greater_is_better=False, # Logging logging_steps=25, logging_first_step=True, ) # Data collator handles padding and batching data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model) # Initialize trainer trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset, data_collator=data_collator, ) # Fine-tune the base model print("Fine-tuning started...") trainer.train() Once training completes, save your fine-tuned model: trainer.save_model("./qwen-math/final") tokenizer.save_pretrained("./qwen-math/final") 5 – Avaliar o modelo Após o ajuste, medir o quão bem o seu modelo desempenha usando duas métricas comuns: · Medir o quão longe as previsões do modelo estão das saídas-alvo, onde valores mais baixos indicam um melhor desempenho. Loss: · Mostra as mesmas informações em uma escala mais intuitiva, onde valores mais baixos significam que o modelo é mais confiante em suas previsões. Perplexity (the exponential of loss): Para ambientes de produção, considere adicionar métricas como ou para medir o quão perto as respostas geradas correspondem às respostas de referência. BLEU ROUGE import math eval_results = trainer.evaluate() print(f"Final Evaluation Loss: {eval_results['eval_loss']:.4f}") print(f"Perplexity: {math.exp(eval_results['eval_loss']):.2f}") Você também pode incluir outras métricas, como F1, que mede o quão bom seu modelo é em pegar o que importa, enquanto permanece preciso. É um bom ponto de partida para aprender o essencial de usar a biblioteca de transformadores. Coloque o rosto na leitura Exemplo de código de ajuste completo Após estes cinco passos, você deve ter o seguinte código combinado em um único arquivo Python: import math from datasets import load_dataset from transformers import ( AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer, DataCollatorForSeq2Seq, ) dataset = load_dataset("openai/gsm8k", "main") tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B") tokenizer.pad_token = tokenizer.eos_token # Tokenization function adjusted for the specific dataset format def tokenize_function(examples): input_ids_list = [] labels_list = [] for question, answer in zip(examples["question"], examples["answer"]): question_tokens = tokenizer(question, add_special_tokens=False)["input_ids"] answer_tokens = tokenizer(answer, add_special_tokens=False)["input_ids"] + [tokenizer.eos_token_id] input_ids = question_tokens + answer_tokens labels = [-100] * len(question_tokens) + answer_tokens input_ids_list.append(input_ids) labels_list.append(labels) return { "input_ids": input_ids_list, "labels": labels_list, } # Tokenize the data train_dataset = dataset["train"].map( tokenize_function, batched=True, remove_columns=dataset["train"].column_names, ).filter(lambda x: len(x["input_ids"]) <= 512) .shuffle(seed=42) eval_dataset = dataset["test"].map( tokenize_function, batched=True, remove_columns=dataset["test"].column_names, ).filter(lambda x: len(x["input_ids"]) <= 512) print(f"Samples: {len(dataset['train'])} → {len(train_dataset)} (after filtering)") print(f"Samples: {len(dataset['test'])} → {len(eval_dataset)} (after filtering)") # Optional: Use a smaller subset for faster testing # train_dataset = train_dataset.select(range(2000)) # eval_dataset = eval_dataset.select(range(1000)) model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B") model.config.pad_token_id = tokenizer.pad_token_id # Configuration settings and hyperparameters for fine-tuning training_args = TrainingArguments( output_dir="./qwen-math", use_cpu=True, # Training duration num_train_epochs=2, # Batch size and memory management per_device_train_batch_size=5, per_device_eval_batch_size=5, gradient_accumulation_steps=4, # Learning rate and regularization learning_rate=2e-5, weight_decay=0.01, max_grad_norm=1.0, warmup_ratio=0.1, lr_scheduler_type="cosine", # Evaluation and checkpointing eval_strategy="steps", eval_steps=100, save_strategy="steps", save_steps=100, save_total_limit=3, load_best_model_at_end=True, metric_for_best_model="eval_loss", greater_is_better=False, # Logging logging_steps=25, logging_first_step=True, ) data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model) trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset, data_collator=data_collator, ) # Fine-tune the base model print("Fine-tuning started...") trainer.train() # Save the final model trainer.save_model("./qwen-math/final") tokenizer.save_pretrained("./qwen-math/final") # Evaluate after fine-tuning eval_results = trainer.evaluate() print(f"Final Evaluation Loss: {eval_results['eval_loss']:.4f}") print(f"Perplexity: {math.exp(eval_results['eval_loss']):.2f}") Antes de executar, tome um momento para ajustar a configuração do seu treinador e os hiperparâmetros com base no que sua máquina pode realmente lidar. Para lhe dar uma referência do mundo real, aqui está o que funcionou suavemente para nós em um MacBook Air com o chip M4 e 16 GB de RAM. · : 7 Batch size for training · 7 Batch size for eval: · 5 Gradient accumulation: Enquanto seu modelo treina, fique de olho no Se ele aumenta enquanto a perda de treinamento diminui, o modelo é excessivo.Nesse caso, ajuste as épocas, reduza a taxa de aprendizagem, modifique a perda de peso e outros hiperparâmetros.No exemplo abaixo, vemos resultados saudáveis com a perda de eval diminuindo de Dois Uma perplexidade final de . evaluation loss 0.496 0.469 1.60 Teste o modelo finamente ajustado Agora, para o momento da verdade – foi o nosso ajuste fino realmente bem sucedido? Você pode testar manualmente o modelo ajustado fino, solicitando-o com este código Python: from transformers import pipeline generator = pipeline( "text-generation", # Use `Qwen/Qwen2.5-0.5B` for testing the base model model="./qwen-math/final" ) output = generator( "James has 5 apples. He buys 3 times as many. Then gives half away. How many does he have?", return_full_text=False ) print(output[0]["generated_text"]) Nesta comparação lado a lado, você pode ver como os modelos antes e depois respondem à mesma pergunta (a resposta correta é 10): Com a amostragem habilitada, ambos os modelos ocasionalmente ficam certos ou errados devido à aleatoriedade. A função revela sua verdadeira confiança: o modelo sempre escolhe sua resposta de maior probabilidade. Saídas confiantes (em inglês ), enquanto o Saídas confiantes (em inglês Isso é o fine-tuning no trabalho. do_sample=False in the generator() base model -2 errado fine-tuned model 10 Correto Fine-Tuning Melhores Práticas Modelo Selecção · Modelos específicos de domínio e janelas de contexto apropriadas poupam você de lutar contra o conhecimento existente do modelo. Choose the right base model: · Modelos apenas de codificador (como BERT) excelem em tarefas de classificação, modelos apenas de decodificador (como GPT) na geração de texto e modelos de codificador-decodificador (como T5) em tarefas de transformação, como tradução ou resumo. Understand the model architecture: · Se o seu modelo de base foi treinado com modelos de prompt específicos, use o mesmo formato no ajuste fino. Formatos incompatíveis confundem o modelo e o desempenho do tanque. Match your model's input format: Preparação de dados · Exemplos limpos e precisos batem conjuntos de dados maciços e barulhentos a cada vez. Prioritize data quality over quantity: · Nunca deixe seu modelo ver os dados de avaliação durante o treinamento.Isso permite que você pegue o overfitting antes que ele arruine seu modelo. Split training and evaluation samples: · As métricas automatizadas, como a perplexidade, não lhe dizem se o modelo realmente segue instruções ou apenas prevê palavras de forma estatística. Establish a "golden set" for evaluation: Estratégia de treinamento · Você está fazendo ajustes menores, não ensinando a partir do zero, então taxas agressivas podem apagar o que ele aprendeu durante o pré-treino. Start with a lower learning rate: · Treine apenas 1% dos parâmetros para obter 90% + desempenho enquanto usa menos memória e tempo. Use parameter-efficient fine-tuning (LoRA/PEFT): · Todos os tipos de alvo ( etc.) produz modelos que raciocinam significativamente melhor, não apenas imitam o estilo. Target all linear layers in LoRA: q_proj, k_proj, v_proj, o_proj, · O ruído aleatório em embeddings atua como regularização, o que pode impedir a memorização e aumentar a qualidade da conversação em mais de 35 pontos percentuais. Use NEFTune ( ): Acessórios em Fine-Tuning Acessórios em Fine-Tuning · SFT ensina como falar; DPO ensina o que é bom aprendendo de pares de preferência. After SFT, Run DPO: Quais são as limitações do LLM Fine-Tuning? · Fine-tuning sobrepõe padrões neurais existentes, o que pode apagar valiosos conhecimentos gerais aprendidos durante o modelo de pré-treinamento. aprendizagem multi-tarefa, onde você treina em sua tarefa especializada ao lado de exemplos gerais, pode ajudar a preservar capacidades mais amplas. Catastrophic forgetting: · O modelo pode memorizar seus exemplos de treinamento em vez de padrões de aprendizagem, fazendo com que ele falhe em entradas ligeiramente diferentes. Overfitting on small datasets: · O ajuste fino de bilhões de parâmetros requer GPUs caros, memória significativa e horas a dias ou semanas de tempo de treinamento. High computational cost: · Modelos pré-treinados já carregam preconceitos de seus dados de treinamento, e o ajuste fino pode intensificar esses preconceitos se o seu conjunto de dados não for cuidadosamente curado. Bias amplification: · Conhecimento novo e externo pode exigir o treinamento de todo o modelo ou a implementação de Retrieval-Augmented Generation (RAG), enquanto o ajuste repetido muitas vezes degrada o desempenho. Manual knowledge update: CONCLUSÃO O ajuste fino funciona, mas apenas se os seus dados estiverem limpos e os seus hiperparâmetros estiverem conectados.Combine-o com engenharia rápida para obter os melhores resultados, onde o ajuste fino lida com a especialização da tarefa, enquanto a engenharia rápida guia o comportamento do modelo no momento da inferência. Continue pegando um modelo da Hugging Face que se encaixa no seu caso de uso para o ajuste fino específico do domínio, raspe ou construa um conjunto de dados de qualidade para a sua tarefa e execute sua primeira sessão de ajuste fino em um subconjunto pequeno. Uma vez que você veja resultados promissores, escala e experimente com LoRA, DPO ou NEFTune para espremer um melhor desempenho.