mistral-finetuneest une base de code légère pour fine-tuner les modèles Mistral de manière économe en mémoire et performante ; le dépôt est actuellement archivé et n’est plus activement maintenu- La méthode d’entraînement repose sur LoRA, qui fige la plupart des poids et n’entraîne que 1 à 2 % de poids supplémentaires sous forme de perturbations matricielles de bas rang
- Pour une efficacité maximale, l’utilisation de GPU A100 ou H100 est recommandée ; le code est optimisé pour l’entraînement multi-GPU sur un seul nœud, mais les petits modèles comme les 7B peuvent aussi fonctionner sur un seul GPU
- Les modèles pris en charge incluent 7B, Mixtral 8x7B, Mixtral 8x22B, Mistral-Nemo 12B et Mistral Large v2 123B Instruct ; Mistral-Nemo et Large v2 ont chacun des contraintes liées à la longueur de séquence et au taux d’apprentissage
- Les données doivent respecter le format
jsonlet un schéma strict ; avant l’entraînement, il est important de valider le format avecutils.validate_dataet d’effectuer une estimation du temps d’entraînement
État et objectif du projet
- Le dépôt
mistral-finetuneest archivé et n’est plus activement maintenu - S’il existe une demande de la communauté ou si cela peut apporter de la valeur à l’écosystème du fine-tuning, une nouvelle bibliothèque ou une mise à jour majeure pourrait voir le jour à l’avenir
- L’objectif est de fournir un point d’entrée simple et guidé pour fine-tuner les modèles Mistral
- Cette base de code est particulièrement prescriptive sur le format des données et ne vise pas à être un outil généraliste couvrant plusieurs architectures de modèles ou types de matériel
- Pour une approche plus générale, des projets comme torchtune peuvent servir de référence
Méthode de fine-tuning et recommandations matérielles
mistral-finetunerepose sur LoRA- La plupart des poids du modèle sont figés
- Seuls 1 à 2 % de poids supplémentaires, sous forme de perturbations matricielles de bas rang, sont entraînés
- Pour une efficacité maximale, l’utilisation de GPU A100 ou H100 est recommandée
- Le code est optimisé pour les environnements d’entraînement multi-GPU sur un seul nœud
- Les petits modèles comme les 7B peuvent suffire avec un seul GPU
Mises à jour récentes des modèles compatibles
- Depuis le 13 août 2024, Mistral Large v2 est compatible avec
mistral-finetune- Il faut télécharger le checkpoint 123B Instruct et définir
model_id_or_pathsur le répertoire de ce checkpoint - La grande taille du modèle nécessite beaucoup plus de mémoire pour le fine-tuning
- Pour l’instant,
seq_lendoit être défini à 8192 ou moins - Un taux d’apprentissage plus faible que pour les autres modèles est recommandé ; dans la plupart des cas,
lr=1e-6est indiqué comme fonctionnant bien
- Il faut télécharger le checkpoint 123B Instruct et définir
- Depuis le 19 juillet 2024, Mistral Nemo est compatible avec
mistral-finetune- Il faut télécharger le modèle 12B Base ou Instruct et définir
model_id_or_pathsur le répertoire du checkpoint - Une version de
mistral-commonprenant en charge Tekkenizer est nécessaire ; il faut installer la version>=1.3.1avecpip install --upgrade mistral-common - En raison de la grande taille du vocabulaire, les besoins mémoire en pic de la CE loss augmentent, ce qui nécessite actuellement davantage de mémoire
- Pour l’instant,
seq_lendoit être défini à 16384 ou moins - L’utilisation des mêmes hyperparamètres que pour 7B v3 est recommandée
- Il faut télécharger le modèle 12B Base ou Instruct et définir
Installation et téléchargement des modèles
- La procédure de démarrage consiste à cloner le dépôt et installer les dépendances
git clone https://github.com/mistralai/mistral-finetune.gitpip install -r requirements.txt
- Le fine-tuning des modèles Mistral officiels est recommandé, et le README fournit les liens de téléchargement et checksums suivants
- 7B Base :
0663b293810d7571dad25dae2f2a5806 - 7B Instruct v3 :
80b71fcb6416085bcb4efad86dfb4d52 - 8x7B Base : lien 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 :
- Avant le fine-tuning, 8x7B Base V1 et 8x7B Instruct V1 doivent utiliser le tokenizer v3 et étendre la taille du vocabulaire à 32768
- Le chemin du dossier du modèle téléchargé doit être indiqué comme chemin absolu dans
model_id_or_pathdu YAML d’entraînement
Exigences de format des données
- Tous les fichiers de données doivent être au format jsonl
- Les données de préentraînement stockent le texte brut dans la clé
"text" - Les données d’instruction stockent une liste de conversations dans la clé
"messages"- Chaque entrée contient les clés
"content"et"role" "role"vaut l’un de"user","assistant"ou"system"- La loss n’est calculée que lorsque
"role" == "assistant" - Il est possible d’exclure un message assistant de l’entraînement en définissant
"weight": 0sur ce message
- Chaque entrée contient les clés
- Les données d’appel de fonction stockent aussi une liste de conversations dans la clé
"messages"- Chaque entrée contient la clé
"role"et soit"content", soit"tool_calls" "role"vaut l’un de"user","assistant","system"ou"tool"- La loss n’est calculée que lorsque
"role" == "assistant" - Les champs
"id"et"tool_call_id"de"tool_calls"doivent être des chaînes aléatoires d’exactement 9 caractères - Le README recommande de les générer automatiquement dans le script de préparation des données
- Chaque entrée contient la clé
Validation des données et exemple de workflow
- Avant de lancer l’entraînement, il faut valider le format des données et estimer le temps d’entraînement avec utils.validate_data
- L’exemple d’instruction utilise une partie de Ultachat_200k
- Les données parquet sont chargées avec Pandas
- Elles sont séparées en 95 % pour l’entraînement et 5 % pour l’évaluation
- Elles sont enregistrées en
jsonl - Les chemins sont indiqués dans
data.instruct_dataetdata.eval_instruct_datadeexample/7B.yaml
- Lors de la validation, certaines conversations peuvent être détectées comme se terminant par le rôle
user- Comme seuls les messages assistant sont entraînés, le dernier message
userdevient un élément inutile à traiter - Les données peuvent être corrigées avec utils.reformat_data.py
- Comme seuls les messages assistant sont entraînés, le dernier message
- Après correction, une nouvelle validation affiche un résumé incluant le nombre de tokens de données, le nombre de tokens d’entraînement, le nombre d’epochs,
max_stepset le temps estimé - Dans l’exemple du README,
max_steps=500parcourt le dataset environ 5 fois ; pour une configuration prenant environ 30 minutes sur un cluster 8xH100,max_steps=300est recommandé
Exemple de fine-tuning pour l’appel de fonction
- L’exemple d’appel de fonction utilise le Glaive function calling dataset
- Les données sont chargées avec Pandas, divisées en 95 % pour l’entraînement et 5 % pour l’évaluation, puis enregistrées en
jsonl - Le dataset d’origine ne suit pas le format d’appel de fonction requis et doit donc être reformaté
"from"doit être remplacé par"user"- Les caractères
"\n"inutiles doivent être supprimés
- utils.reformat_data_glaive.py permet de mettre la plupart des échantillons au bon format
- Comme il est impossible d’écrire un script de reformatage fonctionnant pour tous les types de datasets, les datasets qui ne respectent pas le format requis peuvent nécessiter un script de reformatage dédié
utils.validate_data --create_correctedpermet de supprimer les erreurs restantes et de créer un dataset.corrected
Exécution de l’entraînement et exemples de résultats
- Après validation des données, l’entraînement peut être lancé
- Pour un entraînement plus rapide, une configuration avec
max_stepsdéfini à 300 est recommandée run_dirdoit être défini comme dossier d’expérience ; en option,wandb.projectpeut être défini pour utiliser le logging Weights & Biases- L’entraînement s’exécute avec
torchrun, et--nproc-per-nodedoit être défini au nombre de GPU disponibles - L’entraînement UltraChat prend environ 30 minutes sur un nœud 8xH100, et les poids obtenus peuvent produire un score MT Bench d’environ 6,3
- L’entraînement Glaive prend environ 1 heure sur un nœud 8xH100, et les poids obtenus sont présentés comme fonctionnant bien pour l’appel de fonction
Principaux paramètres d’entraînement
model_id_or_path: modèle préentraîné à partir duquel démarrer l’entraînement, ou chemin vers un répertoire de modèle localrun_dir: répertoire où enregistrer les checkpoints et les métriquesseq_len: longueur de séquence d’entraînement ; les échantillons sont packés à la longueurseq_lenpour plus d’efficacitébatch_size: nombre d’exemples d’entraînement par GPU- La taille effective totale du batch en tokens est
num_gpus x batch_size x seq_len
- La taille effective totale du batch en tokens est
max_steps: nombre total d’itérations d’entraînement- Le nombre total de tokens vus pendant l’entraînement est
max_steps x num_gpus x batch_size x seq_len
- Le nombre total de tokens vus pendant l’entraînement est
optim.lr: taux d’apprentissage initial de l’optimiseuroptim.weight_decay: weight decay ; le README recommande de le maintenir à 0,1optim.pct_start: proportion de la phase de warm-up deOneCycleLRde PyTorchlora.rank: taille de l’adapter LoRA ; une valeur inférieure ou égale à 64 est recommandéeseed: graine aléatoire pour la reproductibilité de l’initialisation, du mélange des données et de l’échantillonnagedata.instruct_data: chemin vers les données d’entraînement d’instruction- Il peut s’agir d’un fichier
jsonlunique, d’un répertoire de fichiersjsonlou de plusieurs sources de données avec pondération
- Il peut s’agir d’un fichier
data.data: chemin optionnel vers des données de préentraînement supplémentairesdata.eval_instruct_data: chemin optionnel vers des données d’instruction d’évaluationeval_freq,no_eval,ckpt_freq: contrôlent la fréquence d’évaluation, l’évaluation intermédiaire et l’enregistrement des checkpointssave_adapters: détermine s’il faut enregistrer uniquement les checkpoints LoRA ou fusionner LoRA dans le modèle de base et enregistrer le modèle completsave_adapters=Falsenécessite suffisamment de mémoire CPU et GPU pour enregistrer le modèle complet dans un seul processus, ce qui n’est généralement possible qu’avec les modèles 7B
Inférence et Weights & Biases
- Pour l’inférence avec le modèle entraîné, l’utilisation de mistral-inference est recommandée
- Il peut être installé avec
pip install mistral_inference - Lors de l’exécution de
mistral-chat, le chemin vers lelora.safetensorsenregistré peut être indiqué via--lora_pathpour utiliser les poids LoRA - La prise en charge de Weights and Biases est incluse afin de surveiller les métriques d’entraînement et les expériences
- Installation avec
pip install wandb - Il est recommandé de fournir la clé API via la variable d’environnement
WANDB_API_KEY - Pour des raisons de sécurité, la clé API n’est pas lue depuis la configuration YAML
- La loss d’entraînement, la loss d’évaluation, le taux d’apprentissage, etc., sont enregistrés et visualisés dans le tableau de bord du projet wandb
- Installation avec
- Pour plus de détails d’utilisation, consulter la documentation Weights and Biases
Extension des modèles et FAQ
- Seuls les modèles Mistral compatibles avec le tokenizer v3 peuvent être fine-tunés
- Les modèles compatibles doivent avoir une taille de vocabulaire de 32768, et non 32000
- Les anciens modèles avec un vocabulaire de taille 32000 peuvent être étendus à 32768 avec
utils.extend_model_vocab - Le fine-tuning des modèles MoE présente une variance de performance plus importante
- Il est suggéré d’exécuter plusieurs fois le même fine-tuning MoE avec des seeds différentes et de choisir le meilleur résultat
- Cette forte variance n’a pas été observée sur les modèles denses
- Le nombre de tokens utilisés pour l’entraînement peut être vérifié en fournissant le fichier YAML d’entraînement à utils.validate_data.py
- En cas d’erreur CUDA out-of-memory, il est possible de réduire la taille de batch par GPU
- La taille de batch est
seq_len x batch_size - Il est suggéré de définir
batch_sizeà 1 et de réduireseq_len
- La taille de batch est
- La bibliothèque est distribuée sous licence Apache 2.0
- Cette bibliothèque ou ces modèles ne doivent pas être utilisés d’une manière qui enfreint, détourne ou viole des droits, y compris les droits de propriété intellectuelle de tiers
1 commentaires
Avis sur Hacker News
Avec des modèles qui progressent aussi vite, le fine-tuning a-t-il encore de la valeur ? Je serais curieux de voir des cas d’usage concrets.
Par exemple, l’an dernier Bloomberg a entraîné sur des données financières un LLM du niveau de GPT-3.5, mais peu après, GPT-4-8k l’a dépassé sur presque toutes les tâches financières.
Au final, nous nous sommes concentrés sur des données d’évaluation de haute qualité et sur une architecture permettant de passer facilement à de nouveaux modèles.
Les LLM n’ont jamais vu ce type d’annotations, les LLM non anglophones ne sont pas non plus la priorité absolue des entreprises, et pour des raisons de confidentialité des données nous ne pouvons utiliser que des modèles offline-first.
Dans cette situation, le fine-tuning d’un modèle de langage généraliste convient très bien.
En fine-tunant le modèle sur des messages structurés dans ce format, il le produira automatiquement, ce qui permet d’économiser beaucoup de tokens qui serviraient sinon à décrire le format de sortie dans chaque prompt.
Cela dit, le fine-tuning comble assez bien l’écart entre les deux.
C’est un domaine restreint, mais c’est aussi le cas de la plupart de la programmation. Si l’objectif est de rendre un LLM généraliste plus orienté vers vos propres données, le fine-tuning a probablement peu de rapport.
Mais si vous essayez de résoudre un problème très spécifique tout en restant ambigu, et qu’un LLM n’en résout qu’une partie, le fine-tuning est probablement la meilleure option.
Si votre app contient beaucoup de fonctions personnalisées qui interagissent avec des outils, vous pouvez préférer le fine-tuning à l’utilisation de tokens de contexte.
Quel GPU faudrait-il pour faire ça ? J’ai un portable avec une 3060 Ti, un i9 et 16 Go de RAM.
Je n’ai pas de quotas AWS ou GCP et j’ai entendu parler de Paperspace, mais je prévois d’utiliser une partie des modèles Mistral dans un projet client en cours, donc j’aimerais commencer rapidement le fine-tuning de Mistral.
Un GPU gaming peut dissiper 300 W de chaleur sans problème, alors qu’un GPU de portable fondrait dans ces conditions et sera probablement limité autour de 100 W.
L’évacuation de la chaleur est directement proportionnelle à la vitesse.
En plus, avec un desktop, vous pouvez passer à un GPU plus rapide ou utiliser plusieurs GPU.
Attention toutefois : les configurations multi-GPU en particulier sont bruyantes et dégagent assez de chaleur pour réchauffer rapidement une pièce.
Si, dans les prochaines années, vous ne prévoyez pas de faire tourner vos GPU à pleine charge plus de 10 % du temps, le cloud sera probablement moins cher.
Il récapitule les exigences matérielles par modèle, et permet de filtrer les modèles disponibles en sélectionnant la VRAM et la mémoire système.
Dans notre entreprise, nous avons fine-tuné Mistral et Llama 3 avec les RTX4000 qu’ils proposent.
Avec seulement 20 Go de RAM, c’est un peu limité, mais pour de plus grands nombres de tokens en entrée, réduire le niveau de quantification a aidé.
Ils proposent maintenant aussi de la location à l’heure.
Nous l’utilisons actuellement dans l’entreprise et nous avons obtenu de très bons résultats.
Il est très intéressant de voir quels outils deviendront le standard de facto pour chaque cas d’usage courant des LLM.
L’écosystème est tellement fragmenté qu’on a l’impression de n’avoir même jamais entendu parler de la plupart des outils.
Il y a quelques jours, j’ai découvert Olive de Microsoft, et c’était totalement nouveau pour moi.
Maintenant que beaucoup de LLM open source ont déjà atteint un niveau « utilisable », l’important est de faciliter le développement autour d’eux.
En particulier, les personnes qui sont à la fois utilisatrices et développeuses doivent pouvoir exploiter des données privées, plus précisément des données qui ne figurent pas dans le préentraînement du modèle.
Le dépôt indique qu’il est optimisé pour de grands modèles et nécessite des A100/H100, mais j’ai tout de même l’impression que cela pourrait être encore plus utile pour les petits modèles que pour les grands.
On peut prolonger « si vous le construisez, ils viendront » en « si vous fournissez les outils, ils construiront ».
La partie sur les poids est intéressante.
Le SFTTrainer de HuggingFace permet, si on le souhaite, de n’entraîner que la partie complétion, mais même si cela semble naturel pour les humains, il est généralement préférable d’entraîner un LLM à prédire toute l’entrée.
Avec cette approche, on obtient le meilleur des deux mondes.
Peut-on l’optimiser pour entraîner de plus grandes variantes de modèles avec deux 3090 ou deux 4090 ?
Voici un point de départ qui présente quelques options : https://huggingface.co/blog/trl-peft
Comment pourrais-je entraîner mon modèle de conversations WhatsApp ?
Voulez-vous entraîner un modèle sur vos propres messages WhatsApp ? Quel est l’objectif ? Cela dépend si vous voulez qu’il écrive comme vous, ou si vous voulez faire de la question-réponse basée sur du RAG.