Intelligence artificielle
Le seul guide dont vous avez besoin pour affiner Llama 3 ou tout autre modèle open source
L’affinage de grands modèles de langage (LLM) comme Llama 3 implique l’adaptation d’un modèle pré-entraîné à des tâches spécifiques en utilisant un ensemble de données spécifique à un domaine. Ce processus exploite les connaissances préexistantes du modèle, ce qui le rend efficace et rentable par rapport à une formation à partir de zéro. Dans ce guide, nous allons passer en revue les étapes pour affiner Llama 3 en utilisant QLoRA (Quantized LoRA), une méthode efficiente en termes de paramètres qui minimise l’utilisation de la mémoire et les coûts de calcul.
Vue d’ensemble de l’affinage
L’affinage implique plusieurs étapes clés :
- Sélection d’un modèle pré-entraîné : Choisissez un modèle de base qui correspond à votre architecture souhaitée.
- Collecte d’un ensemble de données pertinent : Collectez et prétraitez un ensemble de données spécifique à votre tâche.
- Affinage : Adaptez le modèle en utilisant l’ensemble de données pour améliorer ses performances sur des tâches spécifiques.
- Évaluation : Évaluez les performances du modèle affiné en utilisant à la fois des métriques qualitatives et quantitatives.
Concepts et techniques
Affinage complet
L’affinage complet met à jour tous les paramètres du modèle, le rendant spécifique à la nouvelle tâche. Cette méthode nécessite des ressources computationnelles importantes et est souvent impraticable pour les très grands modèles.
Affinage efficient en termes de paramètres (PEFT)
PEFT met à jour uniquement un sous-ensemble des paramètres du modèle, réduisant ainsi les exigences de mémoire et les coûts de calcul. Cette technique empêche l’oubli catastrophique et maintient les connaissances générales du modèle.
Adaptation de bas rang (LoRA) et Quantized LoRA (QLoRA)
LoRA affine uniquement quelques matrices de bas rang, tandis que QLoRA quantifie ces matrices pour réduire encore l’empreinte mémoire.
Méthodes d’affinage
- Affinage complet : Cela implique la formation de l’ensemble du modèle sur l’ensemble de données spécifique à la tâche. Bien que cette méthode puisse être très efficace, elle est également coûteuse en termes de calcul et nécessite une grande quantité de mémoire.
- Affinage efficient en termes de paramètres (PEFT) : PEFT met à jour uniquement un sous-ensemble des paramètres du modèle, ce qui le rend plus efficient en termes de mémoire. Des techniques comme LoRA et QLoRA entrent dans cette catégorie.
Qu’est-ce que LoRA ?

Comparaison des méthodes d’affinage : QLORA améliore LoRA avec une quantification à 4 bits et des optimiseurs paginés pour la gestion des pics de mémoire
LoRA est une méthode d’affinage améliorée où, au lieu d’affiner tous les poids du modèle pré-entraîné, deux petites matrices qui approximent la matrice plus grande sont affinées. Ces matrices constituent l’adaptateur LoRA. Cet adaptateur affiné est ensuite chargé dans le modèle pré-entraîné et utilisé pour l’inférence.
Avantages clés de LoRA :
- Efficacité de la mémoire : LoRA réduit l’empreinte mémoire en n’affinant que de petites matrices au lieu de l’ensemble du modèle.
- Réutilisation : Le modèle original reste inchangé, et plusieurs adaptateurs LoRA peuvent être utilisés avec lui, facilitant la gestion de plusieurs tâches avec des exigences de mémoire plus faibles.
Qu’est-ce que Quantized LoRA (QLoRA) ?
QLoRA va plus loin en quantifiant les poids de l’adaptateur LoRA à une précision plus faible (par exemple, 4 bits au lieu de 8 bits). Cela réduit encore l’utilisation de la mémoire et les exigences de stockage tout en maintenant un niveau de performance comparable.
Avantages clés de QLoRA :
- Efficacité de la mémoire encore plus grande : En quantifiant les poids, QLoRA réduit considérablement les exigences de mémoire et de stockage du modèle.
- Maintien des performances : Malgré la précision réduite, QLoRA maintient des niveaux de performance proches de ceux des modèles à précision complète.
Adaptation spécifique à la tâche
Pendant l’affinage, les paramètres du modèle sont ajustés en fonction du nouvel ensemble de données, l’aidant à mieux comprendre et générer du contenu pertinent pour la tâche spécifique. Ce processus conserve les connaissances générales de langage acquises pendant la formation préalable tout en adaptant le modèle aux nuances du domaine cible.
Affinage en pratique
Affinage complet vs PEFT
- Affinage complet : Cela implique la formation de l’ensemble du modèle, ce qui peut être coûteux en termes de calcul et nécessite une grande quantité de mémoire.
- Affinage efficient en termes de paramètres (PEFT) : PEFT affine uniquement un sous-ensemble des paramètres du modèle, ce qui le rend plus efficient en termes de mémoire et empêche l’oubli catastrophique, ce qui en fait une alternative plus efficiente.
Étapes de mise en œuvre
- Configuration de l’environnement : Installez les bibliothèques nécessaires et configurez l’environnement de calcul.
- Chargement et prétraitement de l’ensemble de données : Chargez l’ensemble de données et prétraitez-le dans un format adapté au modèle.
- Chargement du modèle pré-entraîné : Chargez le modèle de base avec les configurations de quantification si vous utilisez QLoRA.
- Tokenisation : Tokenisez l’ensemble de données pour le préparer à la formation.
- Formation : Affinez le modèle en utilisant l’ensemble de données préparé.
- Évaluation : Évaluez les performances du modèle en utilisant à la fois des métriques qualitatives et quantitatives.
Guide étape par étape pour affiner LLM
Configuration de l’environnement
Nous allons utiliser un notebook Jupyter pour ce tutoriel. Des plateformes comme Kaggle, qui offrent une utilisation gratuite de GPU, ou Google Colab sont idéales pour exécuter ces expériences.
1. Installation des bibliothèques requises
Tout d’abord, assurez-vous d’avoir les bibliothèques nécessaires installées :
!pip install -qqq -U bitsandbytes transformers peft accelerate datasets scipy einops evaluate trl rouge_score
2. Importation des bibliothèques et configuration de l’environnement
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 # Désactivez la journalisation Weights and Biases os.environ['WANDB_DISABLED'] = "true" interpreter_login()
3. Chargement de l’ensemble de données
Nous allons utiliser l’ensemble de données DialogSum pour ce tutoriel :
Prétraitez l’ensemble de données selon les exigences du modèle, y compris l’application de modèles appropriés et en vous assurant que le format des données est adapté à l’affinage (Hugging Face) (DataCamp).
dataset_name = "neil-code/dialogsum-test" dataset = load_dataset(dataset_name)
Inspectez la structure de l’ensemble de données :
print(dataset['test'][0])
4. Création d’une configuration BitsAndBytes
Pour charger le modèle en format 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. Chargement du modèle pré-entraîné
En utilisant le modèle Phi-2 de Microsoft pour ce tutoriel :
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. Tokenisation
Configurez le tokeniseur :
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
Affinage de Llama 3 ou d’autres modèles
Lors de l’affinage de modèles comme Llama 3 ou tout autre modèle open source de pointe, il existe des considérations et des ajustements spécifiques nécessaires pour assurer des performances optimales. Voici les étapes détaillées et les insights sur la façon d’aborder cela pour différents modèles, y compris Llama 3, GPT-3 et Mistral.
5.1 Utilisation de Llama 3
Sélection du modèle :
- Assurez-vous d’avoir l’identifiant de modèle correct à partir du hub de modèles Hugging Face. Par exemple, le modèle Llama 3 peut être identifié comme
meta-llama/Meta-Llama-3-8Bsur Hugging Face. - Assurez-vous de demander l’accès et de vous connecter à votre compte Hugging Face si nécessaire pour des modèles comme Llama 3 (Hugging Face)
Tokenisation :
- Utilisez le tokeniseur approprié pour Llama 3, en vous assurant qu’il est compatible avec le modèle et prend en charge les fonctionnalités requises comme le padding et les jetons spéciaux.
Mémoire et calcul :
- L’affinage de grands modèles comme Llama 3 nécessite des ressources computationnelles importantes. Assurez-vous que votre environnement, tel qu’une configuration GPU puissante, peut gérer les exigences de mémoire et de traitement. Assurez-vous que l’environnement peut gérer les exigences de mémoire, qui peuvent être atténuées en utilisant des techniques comme QLoRA pour réduire l’empreinte mémoire (Hugging Face Forums)
Exemple :
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
)
Tokenisation :
En fonction de l’utilisation spécifique et des exigences du modèle, assurez-vous que la configuration du tokeniseur est correcte sans paramètres redondants. Par exemple, use_fast=True est recommandé pour de meilleures performances (Hugging Face) (GitHub)
5.2 Utilisation d’autres modèles populaires (par exemple, GPT-3, Mistral)
Sélection du modèle :
- Pour des modèles comme GPT-3 et Mistral, assurez-vous d’utiliser l’identifiant de modèle correct à partir du hub de modèles Hugging Face ou d’autres sources.
Tokenisation :
- De même que pour Llama 3, assurez-vous que le tokeniseur est correctement configuré et compatible avec le modèle.
Mémoire et calcul :
- Chaque modèle peut avoir des exigences de mémoire différentes. Ajustez votre configuration d’environnement en conséquence.
Exemple pour 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
)
Exemple pour 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
)
Considérations de tokenisation : Chaque modèle peut avoir des exigences de tokenisation uniques. Assurez-vous que le tokeniseur correspond au modèle et est configuré correctement.
Exemple de tokeniseur 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
Exemple de tokeniseur GPT-3 et Mistral :
tokenizer = AutoTokenizer.from_pretrained( model_name, use_fast=True )
7. Testez le modèle avec une inférence à zéro tir
Évaluez le modèle de base avec une entrée d’exemple :
from transformers import set_seed
set_seed(42)
index = 10
prompt = dataset['test'][index]['dialogue']
formatted_prompt = f"Instruct: Summarize the following conversation.\n{prompt}\nOutput:\n"
# Générez la sortie
def gen(model, prompt, max_length):
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.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].split('Output:\n')[1]
print(f'ENTRÉE PROMPT:\n{formatted_prompt}')
print(f'GÉNÉRATION DU MODÈLE - ZÉRO TIR:\n{output}')
8. Prétraitez l’ensemble de données
Convertissez les paires de dialogue-résumé en invites :
def create_prompt_formats(sample):
blurb = "Below is an instruction that describes a task. Write a response that appropriately completes the request."
instruction = "### Instruct: Summarize the below conversation."
input_context = sample['dialogue']
response = f"### Output:\n{sample['summary']}"
end = "### End"
parts = [blurb, instruction, input_context, response, end]
formatted_prompt = "\n\n".join(parts)
sample["text"] = formatted_prompt
return sample
dataset = dataset.map(create_prompt_formats)
Tokenisez l’ensemble de données formaté :
def preprocess_batch(batch, tokenizer, max_length): return tokenizer(batch["text"], max_length=max_length, truncation=True) max_length = 1024 train_dataset = dataset["train"].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. Préparez le modèle pour QLoRA
Préparez le modèle pour l’affinage efficient en termes de paramètres :
original_model = prepare_model_for_kbit_training(original_model)
Hyperparamètres et leur impact
Les hyperparamètres jouent un rôle crucial dans l’optimisation des performances de votre modèle. Voici quelques hyperparamètres clés à considérer :
- Taux d’apprentissage : Contrôle la vitesse à laquelle le modèle met à jour ses paramètres. Un taux d’apprentissage élevé peut conduire à une convergence plus rapide, mais peut dépasser la solution optimale. Un taux d’apprentissage faible garantit une convergence stable, mais peut nécessiter plus d’époques.
- Taille du lot : Le nombre d’échantillons traités avant que le modèle mette à jour ses paramètres. Des tailles de lot plus grandes peuvent améliorer la stabilité, mais nécessitent plus de mémoire. Des tailles de lot plus petites peuvent conduire à plus de bruit dans le processus de formation.
- Étapes d’accumulation de gradient : Ce paramètre aide à simuler des tailles de lot plus grandes en accumulant les gradients sur plusieurs étapes avant de mettre à jour les paramètres.
- Nombre d’époques : Le nombre de fois que l’ensemble de données complet est passé à travers le modèle. Plus d’époques peuvent améliorer les performances, mais peuvent également conduire à un surapprentissage si cela n’est pas géré correctement.
- Décroissance de poids : Technique de régularisation pour prévenir le surapprentissage en pénalisant les poids importants.
- Planificateur de taux d’apprentissage : Ajuste le taux d’apprentissage pendant la formation pour améliorer les performances et la convergence.
Personnalisez la configuration de formation en ajustant les hyperparamètres comme le taux d’apprentissage, la taille du lot et les étapes d’accumulation de gradient en fonction des exigences spécifiques du modèle et de la tâche. Par exemple, les modèles Llama 3 peuvent nécessiter des taux d’apprentissage différents par rapport aux modèles plus petits (Weights & Biases) (GitHub)
Exemple de configuration de formation
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="./results/", )
10. Formez le modèle
Configurez le formateur et commencez la formation :
trainer = ORPOTrainer(
model=original_model,
args=orpo_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
tokenizer=tokenizer,
)
trainer.train()
trainer.save_model("fine-tuned-llama-3")
Évaluation du modèle affiné
Après la formation, évaluez les performances du modèle en utilisant à la fois des méthodes qualitatives et quantitatives.
1. Évaluation humaine
Comparez les résumés générés avec des résumés écrits par des humains pour évaluer la qualité.
2. Évaluation quantitative
Utilisez des métriques comme ROUGE pour évaluer les performances :
from rouge_score import rouge_scorer scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'], use_stemmer=True) scores = scorer.score(reference_summary, generated_summary) print(scores)
Défis courants et solutions
1. Limitations de mémoire
L’utilisation de QLoRA aide à atténuer les problèmes de mémoire en quantifiant les poids du modèle à 4 bits. Assurez-vous d’avoir suffisamment de mémoire GPU pour gérer votre taille de lot et la taille de votre modèle.
2. Surapprentissage
Surveillez les métriques de validation pour prévenir le surapprentissage. Utilisez des techniques comme l’arrêt précoce et la décroissance de poids.
3. Formation lente
Optimisez la vitesse de formation en ajustant la taille du lot, le taux d’apprentissage et en utilisant l’accumulation de gradient.
4. Qualité des données
Assurez-vous que votre ensemble de données est propre et bien prétraité. Une mauvaise qualité des données peut avoir un impact significatif sur les performances du modèle.
Conclusion
L’affinage de LLM en utilisant QLoRA est une méthode efficace pour adapter de grands modèles pré-entraînés à des tâches spécifiques avec des coûts de calcul réduits. En suivant ce guide, vous pouvez affiner PHI, Llama 3 ou tout autre modèle open source pour atteindre de hautes performances sur vos tâches spécifiques.











