[!NOTE] Traduction automatique Cet article a été traduit automatiquement depuis la version originale en anglais.

LLM Fine-Tuning Guide : LoRA, QLoRA, DoRA, Unsloth, Axolotl et déploiement

La plupart des échecs fine-tuning relèvent d’échecs de décision. Une équipe effectue d’abord un entraînement avant de démontrer que les techniques de prompting, de récupération d’informations ou constrained decoding ne permettent pas de résoudre le problème ; elle évalue ensuite les résultats sur la distribution d’entraînement ; ou bien elle découvre, une fois l’entraînement terminé, que l’artefact généré est difficile à mettre en œuvre.

Ce guide considère l’adaptation comme une expérience disposant d’une issue opérationnelle définie. Il commence par la frontière de décision, puis suit une séquence allant des données, LoRA ou QLoRA, jusqu’à l’évaluation spécifique à la tâche, à l’export, et enfin à serving.

TL;DR : Effectuez un affinage uniquement lorsque la valeur de référence mesurée montre qu’une modification du comportement du modèle justifie une mise à jour des poids. Utilisez la récupération de connaissances pour mettre à jour les faits et constrained decoding pour gérer la syntaxe. Commencez par LoRA lorsque le modèle de base s’adapte sans difficulté ; recourez à QLoRA lorsque la mémoire aux poids figés constitue la contrainte principale. Conservez un ensemble d’évaluation avant l’entraînement, comparez les résultats avec la version non affinée, puis choisissez l’artefact à déployer avant de valider définitivement une méthode.

Faut-il effectuer du fine-tuning ?

Avant de consacrer des heures à GPU, déterminez d’abord si fine-tuning constitue l’outil adapté pour résoudre le problème qui se pose à vous.

Diagramme de flux de décision

Fine-tuning contre RAG

Fine-tuning peut modifier la manière dont un modèle utilise le langage du domaine, mais c’est un mécanisme de mise à jour insuffisant pour les faits qui évoluent ou doivent être cités. La récupération et fine-tuning traitent des aspects différents du problème et font souvent partie d’un même système.

FonctionnalitéFine-TuningRAG (Génération augmentée par récupération d’informations)
Fonction principaleModifie les poids internes afin d’enseigner des compétences, des styles ou des comportements.Fournit un contexte externe à jour au moment de l’inférence
Meilleur usage pour• Styles de conversation spécifiques
• Suivi d’instructions complexes
• Raisonnement sectoriel
• Données en évolution rapide (actualités, cours boursiers)
• Réduction des hallucinations (ancrage)
• Citation des sources
Gestion des connaissancesModifications du comportement statistique des poids ; un taux de rappel exact n’est pas garanti.Récupère les enregistrements ou les extraits pouvant être mis à jour et cités
Fréquence de mise à jourExige un réentraînement pour intégrer les mises à jourMises à jour immédiates grâce aux nouveaux documents

Fine-tuning contre prompt engineering

Les agents modernes LLMs fonctionnent de manière optimale lorsqu’ils disposent de spécifications claires prompts ainsi que d’exemples concrets. Il est donc recommandé de tester ces différentes approches avant d’investir dans des solutions fine-tuning.

AspectFine-TuningPrompt Engineering
Coût de mise en placeÉlevé (curation des données, calcul GPU, itération)Faible (affinage itératif prompt)
FlexibilitéExige un autre cycle d’entraînement et de déploiement.Changements apportés au prompt
Format/StylePermet de rendre plus probable l’apparition d’un comportement répétitif.Cela suffit souvent pour les styles et les formats simples.
LatenceIl est possible de raccourcir les instructions répétées.Cela dépend de la longueur de prompt ainsi que du mécanisme de mise en cache du fournisseur.
Meilleur usage pourComportements complexes, distillation, coût à grande échelleItération rapide et évolutions continues des exigences

[!TIP] Essayez d’abord des prompts Commencez par un prompt ainsi que par des exemples représentatifs. Si seule la syntaxe de la sortie est peu fiable, ajoutez constrained decoding avant de modifier les poids.

Fine-tuning contre constrained decoding

Des bibliothèques telles que xgrammar et outlines Restreindre la génération à un JSON schema, une expression régulière ou une grammaire. En fonction de cette contrainte et de backend, ils compilent un automate ou une grammaire afin de masquer les tokens suivants non valides. Aucune mise à jour de poids n’est nécessaire.

Cela garantit l’appartenance à la langue de sortie prise en charge, mais cela ne signifie pas pour autant que les valeurs soient vraies, complètes ou sémantiquement appropriées. Une appel de fonction syntaxiquement valide peut tout de même contenir un identifiant de client incorrect.

AspectConstrained DecodingFine-Tuning
ConfigurationImmédiat — définir le schéma, déployerExige une curation des données, ainsi que des calculs GPU et des itérations.
GarantieSyntaxe valide pour la contrainte prise en chargeComportement appris ; le degré de conformité aux schémas peut varier.
FlexibilitéModifier le schéma à tout moment sans avoir à réentraîner le modèleVerrouillé après l’entraînement
LatenceUne légère surcharge opérationnelle (le modèle peut entrer en conflit avec le schéma)
Meilleur usage pourJSON, choix, grammaires, syntaxe de appel d’outilsComportement répétitif des tâches, caractéristique absente du modèle de base

Une commande pratique :

  1. Commencez par des prompts ainsi que des exemples de type few-shot pour le formatage de base.
  2. Ajoutez constrained decoding (xgrammar ou outlines) en cas d’incohérence syntaxique.
  3. Ne procédez au fine-tuning que lorsque vous avez besoin de modifications comportementales que le schéma ne peut pas imposer.

Référence rapide : correspondance entre problèmes et solutions

DéfiPremier mécanisme à testerPourquoi ?
Connaissances manquantesRAGLes modèles génèrent des fausses informations. La récupération de données fournit un contexte fiable et à jour.
Format ou ton incorrectPrompt EngineeringLes modèles modernes suivent efficacement les instructions de style à l’aide d’exemples en few-shot.
Syntaxe de sortie invalideConstrained decodingImpose un schéma ou une grammaire pris en charge lors de la génération
Échec répété de la tâcheFine-tuning (SFT)Apprend à partir d’exemples d’entrée/sortie soigneusement sélectionnés
Désaccord de préférence par pairesOptimisation des préférencesUtilise des exemples sélectionnés ou rejetés une fois que le comportement de la tâche est mesurable
Latence et coût à grande échelleDistillation (SFT)Entraîner un modèle étudiant plus petit à partir des sorties du modèle enseignant de taille supérieure
Réduire la taille du modèleQuantificationPas de formation : compression des poids (FP16→INT4) afin d’accélérer l’inférence

Rendre le cas d’affaires mesurable

Fine-tuning peut réduire le nombre de tokens prompt récurrents ou permettre à un modèle plus petit d’atteindre les objectifs fixés, mais aucune de ces économies n’est automatique. Calculez le point d’équilibre en fonction de votre propre volume de trafic et de vos tarifs :

[ \text{demandes d’équilibre} = \frac{\text{coût d’entraînement + d’évaluation + de déploiement}} {\text{coût de référence/demande} - \text{coût ajusté/demande}} ]

Lorsque le dénominateur est faible, négatif, ou fondé sur une hypothèse de qualité non validée, le projet ne présente pas encore de viabilité économique.

[!TIP] La configuration hybride Une architecture courante consiste en un modèle plus petit adapté à la tâche, complété par un système de récupération d’informations pour les faits changeants. Considérez le modèle plus grand activé par des prompts comme référence de base, et ne conservez le modèle plus petit que s’il respecte les mêmes seuils de qualité et de sécurité spécifiques à la tâche.


Types de fine-tuning

Il existe trois formes principales que fine-tuning peut adopter. Elles diffèrent selon le type de données dont elles ont besoin et ce qu’elles enseignent au modèle.

Fine-Tuning Types

1. Pré-apprentissage continu (non supervisé)

Vous entraînez le modèle de base sur davantage de texte brut, sans étiquettes. Il continue à effectuer des prédictions de token suivant, exactement comme lors de la phase d’entraînement préliminaire initiale.

Quand l’utiliser :

Exemple : entraînement sur des millions de notes cliniques afin que le modèle apprenne les abréviations médicales, les noms de médicaments et les flux de travail cliniques.

2. Apprentissage supervisé fine-tuning (SFT)

SFT s’entraîne à l’aide de paires étiquetées (entrée, sortie). Vous montrez au modèle la sortie exacte que vous souhaitez obtenir pour chaque entrée.

Quand l’utiliser :

Exemple : entraînement sur des paires (description de la requête SQL, code SQL) pour le texte vers SQL.

{
    "input": "Get all users who signed up last month",
    "output": "SELECT * FROM users WHERE signup_date >= DATE_SUB(NOW(), INTERVAL 1 MONTH)"
}

3. Ajustement des instructions

Le réglage par instruction constitue un cas particulier de SFT, conçu pour amener les modèles à respecter une grande variété d’instructions en langue naturelle. Les données d’entraînement sont des paires (instruction, réponse) provenant de nombreuses tâches différentes.

Quand l’utiliser :

Exemple : entraînement sur des milliers d’instructions diverses telles que « Résumer cet article », « Écrire un poème sur X », « Expliquer Y en termes simples ».

Comparaison

AspectPré‑entraînement continuSFTAjustement des instructions
DonnéesTexte brutpaires (entrée, sortie)paires (instruction, réponse)
ÉtiquettesAucun (non supervisé)Spécifique à la tâcheTâches diverses
ObjectifConnaissances du domaineComportement spécifique de la tâcheSuivre toute instruction donnée
Volume de donnéesGénéralement, il s’agit du plus grand corpus.Déterminé par la couverture des tâches et la diversité des erreurs.Généralement plus large que les spécifications propres à une tâche donnée SFT

[!NOTE] Ce que font réellement les chercheurs SFT ainsi que le fine-tuning par instructions utilisent le même objectif basé sur le token suivant ; la différence réside dans l’ampleur et la conception des dataset. Le pré-apprentissage continu constitue une expérience distincte, qui doit être suivie de tests visant à évaluer à la fois les améliorations dans le domaine cible et toute dégradation des capacités générales.


Le processus en 7 étapes fine-tuning pipeline

Fine-tuning est un pipeline, et non une commande unique. Chaque étape présente ses propres modes de défaillance, et le saut d’une d’entre elles se traduit généralement par un modèle de mauvaise qualité par la suite.

7 étapes Pipeline

Chaque étape s’appuie sur la précédente :

  1. Préparation des données — Définir l’unité d’évaluation, diviser les données, puis les nettoyer et les formater
  2. Sélection du modèle — Choisir le modèle de base approprié et charger ses poids
  3. Configuration de l’entraînement — Configurer le matériel, les hyperparamètres ainsi que la stratégie d’optimisation
  4. Fine-tuning — Lancer l’entraînement avec SFT, DPO, ou ORPO
  5. Évaluation — Évaluer les performances via Benchmark et valider la qualité
  6. Déploiement — Exporter et mettre à disposition votre modèle
  7. Surveillance — Suivre les performances, assurer la maintenance et itérer

[!Avertissement] Les données constituent la base fondamentale L’entraînement reproduit des défauts systématiques au sein des exemples. Vérifiez les étiquettes, les fuites de données, le niveau de couverture ainsi que le respect des politiques avant de consacrer du temps à l’optimisation des paramètres d’entraînement.


Étape 1 : Préparation des données

La plupart des projets fine-tuning échouent à cet étape, et non lors de l’entraînement. La préparation moderne des données va bien au-delà du simple application de régularisations sur des fichiers CSV.

Données Pipeline

Le processus de traitement des données en 5 étapes pipeline

Des outils tels que DataTrove et Distilabel peuvent être utiles à grande échelle, mais le pipeline doit être déterminé en fonction de la taxonomie des pannes et du contrat de données, et non en fonction d’un outil préféré.

1. Ingestion et filtrage

2. Politique de gestion des données sensibles

3. Déduplication (MinHash LSH)

4. Augmentation synthétique, le cas échéant

5. Formatage

Exemples de formats de données

Format Alpaca (suivi d’instructions) :

{
    "instruction": "Summarize the following text.",
    "input": "The text to be summarized...",
    "output": "This is the summary."
}

Format ShareGPT/ChatML (conversationnel) :

{
    "conversations": [
        { "from": "user", "value": "Hello, who are you?" },
        { "from": "assistant", "value": "I am a helpful AI assistant." }
    ]
}

Ce qui compte réellement


Étape 2 : Sélection du modèle et matériel

Le choix du modèle de base ainsi que la compréhension du plafond GPU déterminent ce que vous pouvez réellement entraîner.

Commencez par le modèle de base le plus petit qui satisfait déjà aux vérifications de base incontournables. Vérifiez :

Fine-tuning représente une étape d’adaptation et non une correction d’une base inadaptée. Lorsque le modèle ne possède pas les capacités couvertes par dataset, il convient de sélectionner une autre base avant de poursuivre l’entraînement sur davantage d’epochs.

Définissez la taille de l’exécution, pas le niveau de marketing

Il n’existe pas de tableau fiable reliant la taille du modèle à GPU. La consommation maximale en mémoire dépend de la précision des poids, du choix de l’optimiseur, du nombre de paramètres trainables, de la longueur des séquences, de la taille des micro-batches, du mécanisme de sauvegarde des activations, de l’implémentation de l’attention, ainsi que des coûts supplémentaires générés par framework. Commencez par estimer la mémoire nécessaire, puis effectuez un bref test de charge sur une séquence de longueur maximale en utilisant exactement cette pile technique.

Composant mémoireFull fine-tuningLoRAQLoRA
Poids de basePrécision de l’entraînementGelé, généralement BF16/FP16Congelé, généralement en NF4 à 4 bits
GradientsTous les poids entraînablesAdapter les poidsAdapter les poids
États de l’optimiseurTous les poids entraînablesAdapter les poidsAdapter les poids
ActivationsCela dépend de la taille du lot ainsi que de la longueur de la séquence dans chaque méthode.Même dépendanceMême dépendance

L’article original QLoRA montre que, dans son cadre spécifique, un modèle LLaMA de 65 G est compatible avec une mémoire GPU de 48 GB. Ce résultat constitue une borne utile, mais il ne garantit pas que toute architecture actuelle de 70 G, quel que soit le débit de contexte, le noyau ou l’outil d’entraînement, pourra être intégrée sur ce même dispositif.

Mathématiques de la mémoire

Pour un modèle doté de (P) paramètres, les seuls poids nécessitent environ (2P) octets en BF16/FP16 ou (0{,}5P) octets avec quatre bits, sans compter les métadonnées de quantification ni les buffers runtime. Une formation de type Adam complet ajoute des gradients, des états d’optimiseur, ainsi que des poids principaux à plus haute précision. LoRA permet d’éviter l’utilisation de la majeure partie de la mémoire réservée aux états entraînables ; QLoRA réduit en outre l’espace occupé par les poids de base figés. Les activations peuvent toutefois rester prédominantes pour des longueurs de séquence importantes.

Utilisez ce flux de travail :

  1. Sélectionnez la séquence la plus longue ainsi que la taille de micro-lot que vous devez prendre en charge.
  2. Estimez les poids et les états entraînables, en réservant de la marge pour les activations et les noyaux.
  3. Exécutez une étape avant/arrière sur la longueur maximale autorisée.
  4. Enregistrez la mémoire allouée et réservée à son niveau maximal.
  5. Ce n’est qu’alors que vous ajustez la taille du lot, le nombre de processeurs, la longueur de la séquence ou le compteur GPU.

Étape 3 : Méthodes d’entraînement (PEFT et LoRA)

fine-tuning complet vs PEFT

La mise à jour complète fine-tuning (FFT) affecte chaque poids individuellement, ce qui fait que les gradients ainsi que l’état de l’optimiseur évoluent en proportion de la taille totale du modèle. Il n’est pas possible d’estimer la consommation maximale en se basant uniquement sur le nombre de paramètres, mais elle dépasse de loin la mémoire nécessaire pour charger ces poids lors des inférences.

Le fine-tuning (PEFT) à efficacité paramétrique ne traite qu’un petit sous-ensemble de paramètres, en gelant le reste. Cela rend les calculs mathématiques bien plus simples.

LoRA : le point de départ

LoRA (Adaptation à rang faible) consiste à figer une matrice pré-entraînée et à représenter son mise à jour apprise à l’aide de deux matrices plus petites. L’article original justifie cette approche en émettant l’hypothèse selon laquelle les mises à jour d’adaptation utiles possèdent un rang intrinsèque faible.

LoRA Architecture

Pour une matrice figée (W0 \in \mathbb{R}^{d{out} \times d_{in}}), LoRA apprend :

La couche adaptée est :

[W’ = W_0 + \frac{\alpha}{r}BA]

Cet adaptateur dispose de (r(d*{in}+d*{out})) paramètres entraînables au lieu de (d*{in}d*{out}) pour cette matrice. Pour une matrice carrée de 4 096 de largeur et de rang 16, cela correspond à une réduction de 128 fois — et non à 10 000 fois comme le prétendait un modèle arbitraire. L’affirmation selon laquelle il s’agirait d’une réduction de 10 000 fois mentionnée dans l’article LoRA faisait référence à une configuration spécifique de GPT-3 de 175 M paramètres qui adaptait certaines matrices.

Méthodes PEFT comparées

MéthodeQuelles modificationsChoisissez-le lorsque
LoRABase figée associée à des mises à jour entraînables de rang faibleLe modèle de base s’adapte parfaitement et vous souhaitez des artefacts de tâche de petite taille.
QLoRALoRA avec la base figée stockée sous forme de 4 bitsLa mémoire à poids de base constitue le facteur limitant
DoRASépare l’amplitude du poids de la direction mises à jour par LoRAUne base de référence mesurée LoRA crée un écart de qualité qui justifie une complexité supplémentaire
fine-tuning completTous les poids du modèlePEFT rate manque sa cible, et l’amélioration de qualité justifie l’entraînement distribué ainsi que l’utilisation d’un checkpoints complet.

Quand choisir l’un ou l’autre

DoRA : LoRA décomposé en poids

DoRA (Adaptation à bas rang décomposée en composantes de poids) permet de séparer l’amplitude de chaque vecteur de poids de sa direction. Elle applique une mise à jour LoRA à la composante directionnelle tout en apprenant séparément l’amplitude correspondante.

DoRA Architecture

Fonctionnement :

Plutôt que de traiter les poids comme une entité unique, DoRA divise les poids pré-entraînés en deux composants :

  1. Magnitude — une valeur entraînable par vecteur de poids.
  2. Direction — un vecteur normalisé mis à jour au moyen de matrices à rang faible.

En notation compacte par colonnes :

[ W’ = m \frac{V + BA}{\lVert V + BA \rVert_c} ]

où :

Ce que vous obtenez avec cette structure supplémentaire :

Adapter l’opération de fusion pour l’apprentissage multi-tâche

Des adaptateurs distincts permettent à une base figée de gérer plusieurs tâches. Il est possible d’orienter les requêtes vers un adaptateur, de faire fonctionner plusieurs adaptateurs depuis un même moteur lorsque c’est pris en charge, ou encore de générer une version fusionnée hors ligne. La fusion peut engendrer des interférences ; il convient donc d’évaluer l’artefact résultant plutôt que de supposer que les adaptateurs sources s’intègrent sans problème.

Méthodes de fusion courantes :

  1. Concaténation — permet de combiner les paramètres des adaptateurs afin d’augmenter le rang effectif. Méthode rapide et simple.
  2. Combinaison linéaire — somme pondérée des adaptateurs. Offre des paramètres de réglage.
  3. SVD — décomposition matricielle utilisée pour la fusion. Plus flexible, mais plus lente.

Exemple : un adaptateur pour la synthèse, un autre pour la traduction, fusionnés en un seul modèle multi-tâches.


Étape 4 : Fine-tuning et alignement des préférences

SFT apprend à partir de démonstrations. L’optimisation par préférences, quant à elle, s’appuie sur des comparaisons du type « la réponse choisie A est meilleure que la réponse rejetée B ». Il convient de l’utiliser uniquement lorsque la représentation par préférences paire correspond bien au type d’erreur en question ; dans les cas où la justesse factuelle ou le respect des politiques exigent une évaluation plus fine, des critères plus robustes que des préférences globales sont généralement nécessaires.

Méthodes d’alignement

PPO basé sur RLHF

La méthode initiale était une procédure en trois étapes pipeline :

  1. SFT — apprendre la tâche.
  2. Modèle de récompense — entraînement sur les préférences humaines (sélectionnées versus rejetées).
  3. PPO (Optimisation de politique proximale) — apprentissage par renforcement utilisé pour optimiser la politique.

Le coût d’exploitation provient des éléments mobiles :

DPO

DPO (Optimisation directe des préférences) élimine le modèle de récompense explicite ainsi que la boucle d’apprentissage par renforcement. Elle continue toutefois d’optimiser l’objectif RLHF (maximisation de la récompense sous contrainte de divergence KL), mais ce faisant en le traitant comme un problème d’apprentissage supervisé reparamétrisé plutôt qu’à l’aide de l’apprentissage par renforcement :

{
    "prompt": "Explain quantum computing",
    "chosen": "Quantum computing uses qubits...",   # Preferred response
    "rejected": "Well, it's complicated..."        # Non-preferred response
}

Quelles sont les modifications opérationnelles :

Il est plus simple de prototyper DPO que de développer un PPO pipeline complet, mais cela ne garantit pas automatiquement une amélioration de la qualité. Les résultats dépendent de la politique de départ, de la qualité des paires, des paramètres de perte, des effets liés à la longueur ainsi que du protocole d’évaluation. Il convient de le comparer à un SFT checkpoint utilisé sur les mêmes ensembles de préférences et de tâches non entraînées.

ORPO

ORPO (Odds-Ratio Preference Optimization) associe la perte de vraisemblance logarithmique négative SFT à une pénalité basée sur le rapport des probabilités appliquée aux réponses rejetées. Ce cadre élimine le besoin d’un modèle de référence distinct et permet d’intégrer à la fois l’apprentissage par tâche et l’optimisation des préférences au cours d’une seule exécution.

Fonctionnement : ORPO utilise une perte combinée qui effectue deux opérations en même temps :

  1. Maximise la probabilité de la réponse choisie (apprentissage de la tâche).
  2. Pénalise la réponse rejetée par un terme de rapport de chances (apprentissage des préférences).

Hyperparamètres à connaître :

from trl import ORPOConfig

config = ORPOConfig(
    learning_rate=8e-6,  # Very low, as recommended by the ORPO paper
    beta=0.1,            # Controls strength of preference penalty
    # ... other params
)

Le compromis :

Sélectionnez parmi les données et le concept de conception d’évaluation :

Aucune valeur n’est définie par défaut pour toutes les tâches. Il convient de conserver une ligne de base exclusive SFT et de rapporter à la fois les métriques relatives aux tâches et celles liées aux préférences.


Fine-tuning frameworks

Frameworks l’overlap et évoluent rapidement. Choisissez en fonction du chemin d’exécution que vous devez prendre en charge, fixez les versions, et assurez que la configuration d’entraînement reste suffisamment portable pour être reproduite en dehors d’un notebook.

Unsloth — efficacité en termes de vitesse et d’utilisation mémoire

Unsloth s’intègre avec Hugging Face trl et transformers et fournit des noyaux optimisés, un mécanisme de sauvegarde des états, ainsi que des chemins fine-tuning quantifiés pour les modèles pris en charge.

[!IMPORTANT] L’ordre des imports est crucial Respectez l’ordre d’importation indiqué dans l’exemple Unsloth pour la version que vous utilisez. Unsloth applique des correctifs au cours de l’import, il convient donc de l’importer en premier trl et transformers Évite les optimisations manquantes ou les erreurs spécifiques à une version.

# ✅ Correct order
from unsloth import FastLanguageModel  # Must be first!
from trl import SFTTrainer
from transformers import TrainingArguments

# Avoid this order with Unsloth's patched path
from trl import SFTTrainer
from unsloth import FastLanguageModel

Idéal pour : l’entraînement unique-GPU, la prototypage, les notebooks Colab, ainsi que pour toute personne soucieuse de réduire sa facture GPU.

Les valeurs indiquées pour la vitesse de traitement et la consommation mémoire varient en fonction du modèle, de la longueur de la séquence, du batch, de la précision ainsi que du matériel utilisé. Benchmark les tokens par seconde ainsi que la mémoire maximale lors de votre propre exécution, plutôt que de considérer un rapport indicatif comme une framework propriété.

Axolotl — entraînement piloté par des configurations

# config.yaml - no code required
base_model: meta-llama/Meta-Llama-3-8B
adapter: qlora
lora_r: 32
lora_alpha: 16
datasets:
    - path: data/my_data.jsonl
      type: alpaca
sample_packing: true

Exécuter avec : accelerate launch -m axolotl.cli.train config.yaml

Idéal pour : des exécutions déclaratives et reproductibles, ainsi que des options de démarrage intégrées pour l’entraînement distribué.

L’avantage majeur réside dans une configuration déclarative qui peut être revue, versionnée et réutilisée tant lors d’exécutions locales que distribuées.

Framework comparaison

OutilUtile lorsqueVérifier avant de commiter
UnslothVous souhaitez un chemin vers un modèle pris en charge optimisé, accompagné d’exemples concis.Le modèle, GPU, la quantification et la matrice de support distribué
AxolotlVous souhaitez des configurations déclaratives ainsi que des recettes distribuées intégrées.Schéma de configuration exact et lanceur correspondant à la version fixée
TRLVous souhaitez un accès direct aux Hugging Face SFT ainsi qu’aux entraîneurs de préférences.format Dataset, modèle de chat, masquage de la perte, et intégration avec PEFT
TorchtuneVous souhaitez des recettes et des composants natifs pour PyTorchCouverture des recettes de modèle et compatibilité d’exportation

Démonstration pratique : fine-tuning avec Unsloth

Voici un exemple complet issu de mon unsloth-finetune-demo répertoire. La démonstration effectue un affinage de Nemotron-Nano pour function calling.

Entraînement Pipeline

Début rapide

# Clone and setup
git clone https://github.com/slavadubrov/unsloth-finetune-demo.git
cd unsloth-finetune-demo

# Install with uv (recommended)
uv sync

# Run fine-tuning (quick test)
uv run finetune --max-samples 1000

Configuration

Les parties intéressantes se trouvent dans config.py:

# Model & Dataset
MODEL_NAME = "nvidia/Llama-3.1-Nemotron-Nano-4B-v1.1"  # 4B params, 128K context
DATASET_NAME = "glaiveai/glaive-function-calling-v2"   # 113K examples

# LoRA Configuration
LORA_R = 16        # Adapter capacity; tune against held-out results
LORA_ALPHA = 32    # Update scaling; alpha/r is the classic LoRA scale
MAX_SEQ_LENGTH = 4096

# Candidate modules for this Llama-family model
LORA_TARGET_MODULES = [
    "q_proj", "k_proj", "v_proj", "o_proj",
    "gate_proj", "up_proj", "down_proj",
]

[!NOTE] Le rapport alpha/rank alpha/r il échelle la mise à jour classique LoRA. alpha = 2r Il s’agit d’une heuristique de départ courante dans certaines documents d’utilisation des outils, mais elle ne constitue pas une garantie de stabilité. Il faut n’ajuster le rang de balayage, la valeur alpha, le taux d’apprentissage ainsi que les modules cibles qu’après avoir fixé les données et la ligne de base.

Code de formation principal

from unsloth import FastLanguageModel
from trl import SFTConfig, SFTTrainer

# Load model with 4-bit quantization
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="nvidia/Llama-3.1-Nemotron-Nano-4B-v1.1",
    max_seq_length=4096,
    load_in_4bit=True,
)

# Add LoRA adapters
model = FastLanguageModel.get_peft_model(
    model,
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
                    "gate_proj", "up_proj", "down_proj"],
    use_gradient_checkpointing="unsloth",  # Lower activation memory; extra compute
)

# The data step creates versioned train_dataset and eval_dataset objects.
# Each row has the chat messages and tool schemas expected by current TRL.

# Train with the current TRL configuration surface.
trainer = SFTTrainer(
    model=model,
    processing_class=tokenizer,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    args=SFTConfig(
        output_dir="outputs/nemotron-function-calling",
        max_length=4096,
        packing=True,
        per_device_train_batch_size=2,
        gradient_accumulation_steps=4,
        learning_rate=2e-4,
        num_train_epochs=3,
        bf16=True,
    ),
)
trainer.train()

Fine-tuning avec Axolotl

[!NOTE] Démonstration en cours de préparation Je travaille actuellement sur une démonstration pratique Axolotl. En attendant, le Guide pour accélérer le parallélisme n-D Le document fourni par Hugging Face constitue une référence utile pour les stratégies d’entraînement multi-GPU.

Pour les configurations en priorité et les architectures distribuées, Axolotl rend le flux de travail reproductible :

# axolotl_config.yaml
base_model: meta-llama/Meta-Llama-3-8B
model_type: LlamaForCausalLM

# QLoRA configuration
load_in_4bit: true
adapter: qlora
lora_r: 32
lora_alpha: 16
lora_dropout: 0.05
lora_target_modules:
    - q_proj
    - k_proj
    - v_proj
    - o_proj
    - gate_proj
    - up_proj
    - down_proj

# Dataset
datasets:
    - path: data/training_data.jsonl
      type: alpaca

# Training settings
sequence_len: 4096
sample_packing: true # Benchmark with your length distribution
micro_batch_size: 2
gradient_accumulation_steps: 4
learning_rate: 0.0002
num_epochs: 3

# Precision and attention path; verify support on the pinned stack
bf16: true
flash_attention: true

Lancer l’entraînement :

axolotl train axolotl_config.yaml

Étape 5 : Évaluation

Gelz le contrat d’évaluation avant la première exécution. Au minimum, comparez la version checkpoint optimisée avec la version de base non optimisée, dans les mêmes conditions de prompt, de paramètres de décodage et d’environnement d’outil. Ne rapportez les indicateurs globaux de qualité qu’après avoir vérifié les segments défaillants que le projet devait améliorer.

Suivez quatre groupes :

  1. Tâche cible : correspondance exacte, succès de l’exécution, évaluation par un humain, ou tout autre résultat lié au cas d’usage.
  2. Régression : capacités générales ainsi que les sous-tâches précédemment prises en charge qui pourraient être endommagées par une adaptation.
  3. Sécurité et politiques : refus de traitement, fuite de données, prompt injection, ou contraintes spécifiques au domaine.
  4. Opérations : latence, débit, mémoire, taille des artefacts, et coûts dans la configuration serving prévue.

Automatisation de benchmarks

Utiliser lm-evaluation-harness pour les tâches normalisées pertinentes, et non comme substitut à l’évaluation du produit :

lm_eval --model hf \
    --model_args pretrained=./outputs/merged-model \
    --tasks hellaswag,arc_easy,mmlu \
    --batch_size 8

LLM en tant que juge

En ce qui concerne la qualité subjective, un modèle plus grand peut aider à évaluer les scores, mais il convient de le calibrer à l’aide d’exemples examinés par des humains et de garder l’identité du candidat anonyme :

judge_prompt = """
Rate this response from 1-5 on:
- Relevance
- Accuracy
- Formatting

Response: {model_output}
Expected: {ground_truth}
"""

Évaluation spécifique au domaine

Évitez les doublons quasi identiques en préservant des exemples réels par source, utilisateur, document ou période, afin d’empêcher toute fuite d’informations entre les deux ensembles de données. Pour function calling, validez l’ensemble du parcours : sélection de l’outil, arguments transmis, résultat de l’exécution, mécanismes de récupération, ainsi que la réponse finale. Lorsque l’échantillon est restreint, indiquez des intervalles de confiance ou des comptes de victoires/défaites correspondants, et analysez attentivement chaque dérive dans une tranche critique.


Étape 6 : Déploiement et formats de sortie

Choisissez l’artefact en fonction du moteur serving et du plan de rollback, et non uniquement de la taille du fichier :

Formats de sortie

1. LoRA adaptateur

uv run finetune  # Saves ~100-500MB adapter

2. Modèle fusionné

uv run finetune --merge  # Creates a standalone full model

3. Format GGUF

uv run finetune --gguf q4_k_m  # Creates ~2-4GB quantized model

Étape 7 : Serving et surveillance

Avec vLLM

# Serve the base and expose a PEFT adapter as a model name.
vllm serve nvidia/Llama-3.1-Nemotron-Nano-4B-v1.1 \
    --enable-lora \
    --lora-modules function-calling=./outputs/adapter \
    --host 0.0.0.0 \
    --port 8000 \
    --max-model-len 4096

Requête via l’interface compatible OpenAI API :

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")
response = client.chat.completions.create(
    model="function-calling",
    messages=[{"role": "user", "content": "Book a flight to Tokyo"}]
)

Avec Ollama (local)

# Create Modelfile
echo 'FROM ./outputs/unsloth-nemotron-function-calling-gguf/model-q4_k_m.gguf' > Modelfile

# Import to Ollama
ollama create my-function-model -f Modelfile

# Run
ollama run my-function-model

Avec llama.cpp (CPU)

./llama-cli -m ./outputs/model-q4_k_m.gguf \
    -p "What's the weather in Tokyo?" \
    --ctx-size 4096

Surveiller le modèle déployé

Le cycle de vie ne s’arrête pas dès que la perte d’entraînement atteint une valeur considérée comme « saine ». Il convient d’enregistrer la version du modèle de base, le tokenizer ainsi que le template de conversation, l’hash de l’adapter, la version de dataset, les paramètres de configuration d’entraînement et le rapport d’évaluation en tant qu’unité de déploiement unique. En environnement de production, il faut surveiller le succès des tâches, les sorties invalides, les échecs de politique, la latence et l’évolution des entrées à l’aide des mêmes échantillons utilisés en mode hors ligne. Il est également essentiel de conserver la capacité de charger les versions antérieures et de définir un seuil de rollback avant de lancer le système.


Principaux enseignements

  1. Ne procédez au fine-tuning qu’après avoir constaté, à partir d’une version de base non ajustée ainsi que d’une taxonomie des échecs, que l’adaptation des poids résout bien le problème.
  2. La récupération gère les éléments de preuve en évolution ; constrained decoding s’occupe de la syntaxe ; aucun de ces mécanismes n’est remplacé par SFT.
  3. LoRA réduit le nombre d’états pouvant être entraînés. QLoRA compresse en outre les poids de base figés. Il ne faut pas attribuer aux performances mémoire de QLoRA les effets de LoRA.
  4. La couverture des données, l’intégrité des splits, l’origine des données et le masquage des pertes sont plus importants que la simple copie d’une configuration d’optimiseur à la mode.
  5. DPO, ORPO ainsi que les RLHF basés sur PPO représentent des architectures expérimentales distinctes, et non une hiérarchie de qualité disposant d’un paramètre par défaut universel.
  6. Évaluez le comportement cible, les régressions, la sécurité ainsi que les opérations en utilisant le même modèle de base.
  7. Avant de commencer l’entraînement, choisissez entre l’adaptateur, la version fusionnée ou la sortie GGUF issue des exigences de serving et de gestion des rollbacks.

Références

Articles et recherches

Outils de traitement des données

Constrained decoding

Entraînement frameworks

Inférence et déploiement

Évaluation

Guides et ressources