Il coûte des millions de dollars et des mois de temps de calcul pour former un grand modèle de langue depuis le bas. Vous n'avez probablement jamais besoin de le faire. Fine-tuning vous permet d'adapter les modèles de langue pré-entraînés à vos besoins en heures ou en jours, pas en mois, avec une fraction des ressources. Ce tutoriel vous permet de : vous apprendrez les quatre techniques de finition de base, codez un pipeline de formation complet en Python et apprenez les techniques qui séparent les modèles prêts à la production des expériences coûteuses. from theory to practice Qu’est-ce que le LLM Fine-Tuning ? Fine-tuning entraîne un modèle de langue existant sur vos données pour l'améliorer Les modèles pré-entraînés sont de puissants généralistes, mais les exposant à Vous pouvez les transformer en spécialistes pour votre cas d'utilisation. performance on specific tasks focused examples Au lieu de construire un modèle à partir de zéro (qui nécessite des calculs massifs et des données), vous donnez à un modèle déjà capable un cours de crash dans ce qui vous importe, que ce soit le diagnostic médical, l'automatisation du support client, l'analyse des sentiments ou toute autre tâche particulière. Comment fonctionne le LLM Fine-Tuning? Fine-tuning continue le processus de formation sur les modèles de langues pré-entraînés en utilisant votre ensemble de données spécifique. Le modèle traite vos exemples fournis, compare ses propres résultats aux résultats attendus, et adapter et minimiser les pertes. updates internal weights Cette approche peut varier en fonction de votre , à et Certains projets nécessitent un ajustement complet, où vous mettez à jour tous les paramètres du modèle, tandis que d'autres fonctionnent mieux avec des méthodes efficaces en termes de paramètres telles que Cela ne modifie qu’une petite partie. goals available data computational resources Loire LLM méthodes de réglage fin Télécharger Fine-Tuning SFT enseigne au modèle d'apprendre les modèles des bonnes paires de questions-réponses et ajuste les poids du modèle pour correspondre exactement à ces réponses. Utilisez cela lorsque vous voulez des sorties cohérentes, comme faire que le modèle réponde toujours au format JSON, suivre votre script de service à la clientèle ou écrire des e-mails dans le ton de votre entreprise. (Prompt, Ideal Response) Fine-tuning non supervisé Alimente le modèle avec des tonnes de texte brut (pas de questions ou de données étiquetées nécessaires) pour apprendre le vocabulaire et les modèles d'un domaine particulier. Bien que ce soit techniquement un processus de pré-entraînement connu sous le nom de pré-entraînement continu (CPT), cela se fait généralement après la phase de pré-entraînement initiale. Utilisez ceci d'abord lorsque votre modèle a besoin de comprendre le contenu spécialisé sur lequel il n'a pas été initialement formé, comme la terminologie médicale, les contrats juridiques ou une nouvelle langue. Optimisation des préférences directes Le DPO enseigne au modèle à préférer de meilleures réponses en montrant des exemples de bonnes vs. mauvaises réponses à la même question et en l'ajustant pour favoriser les bonnes. Utilisez DPO après une formation de base pour corriger des comportements ennuyeux comme arrêter le modèle de faire les choses, d'être trop verbal ou de donner des réponses dangereuses. (Prompt, Good Response, Bad Response) Renforcement Fine-Tuning Dans RLHF, vous formez d'abord un modèle de récompense sur des prompts avec des réponses multiples classées par les humains, l'enseignant à prédire les réponses que les gens préfèrent. Ensuite, vous utilisez l'apprentissage de renforcement pour optimiser et ajuster un modèle qui génère des réponses, que le modèle de récompense juge. Cela aide le modèle à apprendre au fil du temps pour produire des sorties de score plus élevées. Ce processus nécessite des ensembles de données dans ce format: Il est préférable pour les tâches où le jugement de la qualité est plus facile que la création d'exemples parfaits, tels que les diagnostics médicaux, la recherche juridique et d'autres raisonnements complexes spécifiques au domaine. (Prompt, [Response A, Response B, ...], [Rankings]) Etape par étape Fine-Tuning LLMs tutoriel Nous allons vous guider à travers chaque étape de la finition d'un petit modèle pré-entraîné pour résoudre des problèmes de mathématiques basés sur des mots, quelque chose qu'il lutte avec hors de la boîte. L’approche : enseigner une terminologie spécialisée à un modèle, améliorer les performances du modèle sur des tâches spécifiques ou l’adapter à votre domaine. works for virtually any use case of fine-tuning LLMs Pré-requis Dans un nouveau dossier de projet, créez et activez un environnement virtuel Python, puis installez ces bibliothèques en utilisant ou votre gestionnaire de package préféré : pip pip install requests datasets transformers 'transformers[torch]' Obtenir et charger le dataset Le processus de finition commence par le choix du groupe de données, qui est sans doute la décision la plus importante. . reflect the task you want your model to perform Des tâches simples telles que l'analyse des sentiments nécessitent des paires d'entrée et de sortie de base. Des tâches complexes telles que suivre des instructions ou répondre à des questions nécessitent des ensembles de données plus riches avec des contextes, des exemples et des formats variés. Le point de départ le plus simple est le bibliothèque de datasets, qui héberge des milliers de datasets open source pour différents domaines et tâches. ou données publiquement disponibles. Hugging Face Purchase specialized datasets build your own by scrapé scrapé Par exemple, si vous voulez construire un modèle d'analyse des sentiments pour les critiques de produits Amazon, vous voudrez peut-être collecter des données à partir de critiques réelles à l'aide d'un outil de scraping web. : Le web scraper 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]) Tokeniser les données pour le traitement Les modèles ne comprennent pas directement le texte ; ils travaillent avec La tokenisation convertit votre texte en jetons (représentations numériques) que le modèle peut traiter.Chaque modèle a son propre tokeniser formé à côté de lui, alors utilisez celui qui correspond à votre modèle de base: numbers from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B") tokenizer.pad_token = tokenizer.eos_token Comment nous tokenisons nos formes de données ce que le modèle apprend. Pour les problèmes de mathématiques, nous voulons affiner le modèle pour apprendre à Voici le truc : tokeniser les questions et les réponses séparément, puis utiliser une technique de masquage. Répondre Poser une question à Token indique au processus de formation de les ignorer lors du calcul des pertes.Le modèle n'apprend que des réponses, rendant la formation plus ciblée et efficace. -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, } Appliquez cette fonction de tokenisation à la fois aux ensembles de données de formation et de test. Nous filtrons les exemples plus longs que 512 jetons pour maintenir l'utilisation de la mémoire gérée et assurer que le modèle traite les informations complètes sans truncation. 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: Vous voulez tester rapidement l'ensemble du pipeline avant de vous engager à une course de formation complète? Vous pouvez former le modèle sur un sous-ensemble de données. Donc, au lieu d'utiliser l'ensemble complet de données 8.5K, vous pouvez le minimiser à 3K au total, ce qui rend le processus beaucoup plus rapide: train_dataset = train_dataset.select(range(2000)) eval_dataset = eval_dataset.select(range(1000)) Les plus petits ensembles de données augmentent le risque de suralimentation, où le modèle mémorise les données de formation plutôt que les modèles généraux d’apprentissage. Keep in mind: Initialiser le modèle de base Ensuite, chargez le modèle de base pré-entraîné pour le perfectionner en améliorant ses capacités de résolution de problèmes mathématiques: from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B") model.config.pad_token_id = tokenizer.pad_token_id Fine-Tune en utilisant la méthode de l’entraîneur C'est là que la magie se produit. TrainingArguments contrôle comment votre modèle apprend (pensez-y comme la recette déterminant la qualité de votre résultat final). Ces paramètres et hyperparamètres peuvent faire ou briser votre ajustement, donc expérimenter avec des valeurs différentes pour trouver ce qui fonctionne pour votre cas d'utilisation. Key parameters explained: • Le Plus d’époques équivaut à plus d’opportunités d’apprentissage, mais trop provoquent des suraliments. Epochs: • Le Affecte l'utilisation de la mémoire et la vitesse d'entraînement. Ajustez-les en fonction de votre matériel. Batch size: • Le Contrôle à quelle vitesse le modèle s'ajuste. trop haut et il peut manquer la solution optimale, trop bas et la formation prend toujours. Learning rate: • Le Peut aider à prévenir la surmontage en dissuadant le modèle de s'appuyer trop sur n'importe quel motif. Si la dégradation du poids est trop grande, cela peut conduire à une sous-montage en empêchant le modèle d'apprendre les modèles nécessaires. Weight decay: La configuration optimale ci-dessous est spécialisée dans la formation de la CPU (supprimer use_cpu=True si vous avez une 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 – Évaluer le modèle Après l’ajustement, mesurer à quel point votre modèle fonctionne en utilisant deux mesures communes: • Le Mesure à quel point les prévisions du modèle sont éloignées des résultats cibles, où des valeurs inférieures indiquent une meilleure performance. Loss: • Le Affiche les mêmes informations sur une échelle plus intuitive, où des valeurs plus faibles signifient que le modèle est plus confiant dans ses prédictions. Perplexity (the exponential of loss): Pour les environnements de production, envisagez d'ajouter des métriques comme ou pour mesurer à quel point les réponses générées correspondent aux réponses de référence. 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}") Vous pouvez également inclure d'autres mesures telles que F1, qui mesure à quel point votre modèle est bon à attraper ce qui compte tout en restant précis. est un bon point de départ pour apprendre l'essentiel de l'utilisation de la bibliothèque de transformateurs. La lecture face à face Exemple de code fine-tuning Après ces cinq étapes, vous devriez avoir le code suivant combiné dans un seul fichier 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}") Avant d'exécuter, prenez un moment pour ajuster la configuration de votre entraîneur et les hyperparamètres en fonction de ce que votre machine peut réellement gérer. Pour vous donner une référence dans le monde réel, voici ce qui a fonctionné facilement pour nous sur un MacBook Air avec la puce M4 et 16 Go de RAM. • Le : 7 Batch size for training • Le 7 Batch size for eval: • Le 5 Gradient accumulation: Alors que votre modèle est en train, gardez un œil sur le Si elle augmente tandis que la perte d'entraînement diminue, le modèle est trop adapté. Dans ce cas, ajustez les époques, abaissez le taux d'apprentissage, modifiez la dégradation du poids et d'autres hyperparamètres. Dans l'exemple ci-dessous, nous voyons des résultats sains avec une perte d'évaluation diminuant de deux Une dernière perplexité de . evaluation loss 0.496 0.469 1.60 Testez le modèle Fine-Tuned Maintenant, pour le moment de vérité – notre ajustement a-t-il réellement réussi ? Vous pouvez tester manuellement le modèle ajusté en le demandant avec ce code 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"]) Dans cette comparaison côte à côte, vous pouvez voir comment les modèles avant et après répondent à la même question (la réponse correcte est 10): Avec l'échantillonnage activé, les deux modèles ont occasionnellement raison ou tort en raison du hasard. La fonction révèle leur vraie confiance : le modèle choisit toujours sa réponse la plus probable. Des sorties confiantes (Le ), tandis que le Des sorties confiantes (Le C’est le fine-tuning au travail. do_sample=False in the generator() base model -2 erreur fine-tuned model 10 correctement Fine-Tuning Les meilleures pratiques Modèle Sélection • Le Des modèles spécifiques au domaine et des fenêtres de contexte appropriées vous épargnent de lutter contre les connaissances existantes du modèle. Choose the right base model: • Le Les modèles uniquement encodés (tels que BERT) excellent dans les tâches de classification, les modèles uniquement décodés (tels que GPT) dans la génération de texte et les modèles uniquement décodés (tels que T5) dans les tâches de transformation telles que la traduction ou la résumation. Understand the model architecture: • Le Si votre modèle de base a été entraîné avec des modèles spécifiques, utilisez le même format dans le bon ajustement. Match your model's input format: Préparation des données • Le Des exemples propres et précis battent à chaque fois des ensembles de données massifs et bruyants. Prioritize data quality over quantity: • Le Ne laissez jamais votre modèle voir les données d'évaluation pendant l'entraînement.Cela vous permet d'attraper l'excès avant qu'il ne gâche votre modèle. Split training and evaluation samples: • Le Les métriques automatisées telles que la perplexité ne vous disent pas si le modèle suit réellement les instructions ou simplement prévoit les mots de manière statistique. Establish a "golden set" for evaluation: Stratégie de formation • Le Vous faites des ajustements mineurs, ne l'enseignez pas à partir de zéro, de sorte que les taux agressifs peuvent effacer ce qu'il a appris lors de la pré-entraînement. Start with a lower learning rate: • Le Entraînez seulement 1% des paramètres pour obtenir 90%+ de performance tout en utilisant moins de mémoire et de temps. Use parameter-efficient fine-tuning (LoRA/PEFT): • Le Toutes les catégories ( etc.) donne des modèles qui raisonnent nettement mieux, pas seulement imiter le style. Target all linear layers in LoRA: q_proj, k_proj, v_proj, o_proj, • Le Le bruit aléatoire dans les embeddings agit comme une régularisation, ce qui peut empêcher la mémorisation et améliorer la qualité de la conversation de plus de 35 points de pourcentage. Use NEFTune ( ): Télécharger Fine-Tuning Télécharger Fine-Tuning • Le SFT enseigne comment parler; DPO enseigne ce qui est bon en apprenant des paires de préférence. After SFT, Run DPO: Quelles sont les limites du LLM Fine-Tuning? • Le Fine-tuning surécrit les schémas neuronaux existants, ce qui peut effacer les connaissances générales précieuses apprises par le modèle lors de la pré-entraînement. apprentissage multi-task, où vous formez votre tâche spécialisée aux côtés d'exemples généraux, peut aider à préserver des capacités plus larges. Catastrophic forgetting: • Le Le modèle peut mémoriser vos exemples d'apprentissage au lieu de modèles d'apprentissage, ce qui le fait échouer sur des entrées légèrement différentes. Overfitting on small datasets: • Le La finition de milliards de paramètres nécessite des GPU coûteux, une mémoire importante et des heures à des jours ou des semaines de temps d’entraînement. High computational cost: • Le Les modèles pré-entraînés portent déjà des préjugés à partir de leurs données d'entraînement, et le fine-tuning peut intensifier ces préjugés si votre ensemble de données n'est pas soigneusement curé. Bias amplification: • Le Des connaissances nouvelles et externes peuvent nécessiter la reconversion de l'ensemble du modèle ou la mise en œuvre de la génération augmentée de récupération (RAG), tandis que les ajustements finis répétés dégradent souvent les performances. Manual knowledge update: Conclusion L'ajustement fin fonctionne, mais seulement si vos données sont propres et que vos hyperparamètres sont appuyés.Combinez-le avec l'ingénierie rapide pour obtenir les meilleurs résultats, où l'ajustement fin traite de la spécialisation des tâches, tandis que l'ingénierie rapide guide le comportement du modèle au moment de la conclusion. Continuez par saisir un modèle de Hugging Face qui convient à votre cas d'utilisation pour le fine-tuning spécifique au domaine, balayez ou construisez un ensemble de données de qualité pour votre tâche et exécutez votre première session de fine-tuning sur un petit sous-ensemble. Une fois que vous voyez des résultats prometteurs, évoluez et expérimentez avec LoRA, DPO ou NEFTune pour obtenir de meilleures performances.