# Guide des hyperparamètres de fine-tuning LoRA

Les hyperparamètres LoRA sont des réglages ajustables qui régissent la façon dont l'Adaptation à Faible Rang [affine](https://unsloth.ai/docs/fr/commencer/fine-tuning-llms-guide) les LLM. Avec de nombreux choix (par ex., taux d'apprentissage et époques) et d'innombrables combinaisons, choisir les bonnes valeurs est essentiel pour la précision, la stabilité, la qualité et la réduction des hallucinations. Bien fait, **LoRA peut égaler les performances d'un fine-tuning complet** tout en utilisant 4× moins de VRAM.

Vous apprendrez les meilleures pratiques pour ces paramètres, basées sur des enseignements tirés de centaines d'articles de recherche et d'expériences, et verrez comment ils impactent le modèle. **Bien que nous recommandions d'utiliser les paramètres par défaut d'Unsloth**, comprendre ces concepts vous donnera un contrôle total.\
\
L'objectif est de modifier les valeurs des hyperparamètres pour augmenter la précision tout en contrebalançant [**le surapprentissage ou le sous-apprentissage**](#overfitting-poor-generalization-too-specialized). Le surapprentissage se produit lorsque le modèle mémorise les données d'entraînement, nuisant à sa capacité à généraliser à de nouvelles entrées non vues. L'objectif est d'obtenir un modèle qui généralise bien, pas un modèle qui se contente de mémoriser.

{% columns %}
{% column %}

#### :question:Mais qu'est-ce que LoRA ?

Dans les LLM, nous avons des poids de modèle. Llama 70B a 70 milliards de nombres. Plutôt que de changer les 70 milliards de nombres, nous ajoutons des matrices minces A et B à chaque poids, et optimisons celles-ci. Cela signifie que nous n'optimisons que 1 % des poids.
{% endcolumn %}

{% column %}

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-715b6260aae497f160d7f9a1019bcfa472675dcf%2Fimage%20(7)%20(1)%20(1).png?alt=media" alt=""><figcaption><p>Au lieu d'optimiser les poids du modèle (en jaune), nous optimisons 2 matrices minces A et B.</p></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

## :1234: Hyperparamètres clés du Fine-tuning

### **Taux d'apprentissage**

Définit dans quelle mesure les poids du modèle sont ajustés à chaque étape d'entraînement.

* **Taux d'apprentissage élevés** : Mènent à une convergence initiale plus rapide mais peuvent rendre l'entraînement instable ou empêcher de trouver un minimum optimal si trop élevés.
* **Taux d'apprentissage faibles** : Donnent un entraînement plus stable et précis mais peuvent nécessiter plus d'époques pour converger, augmentant le temps total d'entraînement. Bien que l'on pense souvent que des taux faibles provoquent du sous-apprentissage, ils peuvent en réalité entraîner **le surapprentissage** ou même empêcher le modèle d'apprendre.
* **Plage typique**: `2e-4` (0.0002) à `5e-6` (0.000005).\
  :green\_square: ***Pour un fine-tuning LoRA/QLoRA normal***, *nous recommandons* **`2e-4`** *comme point de départ.*\
  :blue\_square: ***Pour l'apprentissage par renforcement** (DPO, GRPO etc.), nous recommandons* **`5e-6` .**\
  :white\_large\_square: ***Pour le fine-tuning complet,** des taux d'apprentissage plus faibles sont généralement plus appropriés.*

### **Époques**

Le nombre de fois que le modèle voit l'ensemble complet de données d'entraînement.

* **Plus d'époques :** Peuvent aider le modèle à mieux apprendre, mais un grand nombre peut le faire **mémoriser les données d'entraînement**, nuisant à sa performance sur de nouvelles tâches.
* **Moins d'époques :** Réduisent le temps d'entraînement et peuvent prévenir le surapprentissage, mais peuvent aboutir à un modèle sous-entraîné si le nombre est insuffisant pour que le modèle apprenne les motifs sous-jacents du jeu de données.
* **Recommandé :** 1-3 époques. Pour la plupart des jeux de données basés sur des instructions, s'entraîner plus de 3 époques offre des rendements décroissants et augmente le risque de surapprentissage.

### **LoRA ou QLoRA**

LoRA utilise une précision 16 bits, tandis que QLoRA est une méthode de fine-tuning en 4 bits.

* **LoRA :** Fine-tuning 16 bits. C'est légèrement plus rapide et légèrement plus précis, mais consomme beaucoup plus de VRAM (4× plus que QLoRA). Recommandé pour les environnements 16 bits et les scénarios où la précision maximale est requise.
* **QLoRA :** Fine-tuning 4 bits. Légèrement plus lent et marginalement moins précis, mais utilise beaucoup moins de VRAM (4× moins).\
  :sloth: *LLaMA 70B tient dans <48GB de VRAM avec QLoRA dans Unsloth -* [*plus de détails ici*](https://unsloth.ai/blog/llama3-3)*.*

### Hyperparamètres et recommandations :

<table><thead><tr><th width="154.39678955078125">Hyperparamètre</th><th width="383.6192626953125">Fonction</th><th>Paramètres recommandés</th></tr></thead><tbody><tr><td><strong>Rang LoRA</strong> (<code>r</code>)</td><td>Contrôle le nombre de paramètres entraînables dans les matrices adaptatrices LoRA. Un rang plus élevé augmente la capacité du modèle mais aussi l'utilisation mémoire.</td><td>8, 16, 32, 64, 128<br><br>Choisissez 16 ou 32</td></tr><tr><td><strong>Alpha LoRA</strong> (<code>lora_alpha</code>)</td><td>Ajuste la force des ajustements du fine-tuning par rapport au rang (<code>r</code>).</td><td><code>r</code> (standard) ou <code>r * 2</code> (heuristique courante). <a href="#lora-alpha-and-rank-relationship">Plus de détails ici</a>.</td></tr><tr><td><strong>Dropout LoRA</strong></td><td>Une technique de régularisation qui met aléatoirement une fraction des activations LoRA à zéro pendant l'entraînement pour prévenir le surapprentissage. <strong>Pas très utile</strong>, donc nous le réglons par défaut à 0.</td><td>0 (par défaut) à 0.1</td></tr><tr><td><strong>Décroissance des poids</strong></td><td>Un terme de régularisation qui pénalise les poids importants pour prévenir le surapprentissage et améliorer la généralisation. N'utilisez pas des valeurs trop élevées !</td><td>0.01 (recommandé) - 0.1</td></tr><tr><td><strong>Étapes d'échauffement</strong></td><td>Augmente progressivement le taux d'apprentissage au début de l'entraînement.</td><td>5-10% du nombre total d'étapes</td></tr><tr><td><strong>Type de scheduler</strong></td><td>Ajuste dynamiquement le taux d'apprentissage pendant l'entraînement.</td><td><code>linéaire</code> ou <code>cosine</code></td></tr><tr><td><strong>Graine (<code>random_state</code>)</strong></td><td>Un nombre fixe pour assurer la reproductibilité des résultats.</td><td>N'importe quel entier (par ex., <code>42</code>, <code>3407</code>)</td></tr><tr><td><strong>Modules cibles</strong></td><td><p>Spécifiez quelles parties du modèle vous souhaitez appliquer les adaptateurs LoRA — soit l'attention, le MLP, ou les deux.</p><p><br>Attention : <code>q_proj, k_proj, v_proj, o_proj</code><br><br>MLP : <code>gate_proj, up_proj, down_proj</code></p></td><td>Recommandé de cibler toutes les principales couches linéaires : <code>q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj</code>.</td></tr></tbody></table>

## :deciduous\_tree: Équivalence entre accumulation de gradients et taille de lot

### Taille de lot effective

Configurer correctement votre taille de lot est crucial pour équilibrer la stabilité de l'entraînement avec les limitations de VRAM de votre GPU. Ceci est géré par deux paramètres dont le produit est la **Taille de lot effective**.\
\
**Taille de lot effective** = `batch_size * gradient_accumulation_steps`

* Un **Taille de lot effective plus grande** conduit généralement à un entraînement plus fluide et plus stable.
* Un **Taille de lot effective plus petite** peut introduire davantage de variance.

Bien que chaque tâche soit différente, la configuration suivante offre un excellent point de départ pour obtenir une **Taille de lot effective** de 16, qui fonctionne bien pour la plupart des tâches de fine-tuning sur les GPU modernes.

| Paramètre                                                     | Description                                                                                                                                                                                                                                                                                                                             | Réglage recommandé                                    |
| ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| **Taille de lot** (`batch_size`)                              | <p>Le nombre d'exemples traités dans une seule passe avant/arrière sur un GPU.<br><br><strong>Principal facteur d'utilisation de la VRAM</strong>. Des valeurs plus élevées peuvent améliorer l'utilisation du matériel et accélérer l'entraînement, mais seulement si elles tiennent en mémoire.</p>                                   | 2                                                     |
| **Accumulation de gradients** (`gradient_accumulation_steps`) | <p>Le nombre de micro-lots à traiter avant d'effectuer une seule mise à jour des poids du modèle.<br><br><strong>Principal facteur du temps d'entraînement.</strong> Permet de simuler une plus grande <code>batch\_size</code> pour économiser de la VRAM. Des valeurs plus élevées augmentent le temps d'entraînement par époque.</p> | 8                                                     |
| **Taille de lot effective** (Calculé)                         | La véritable taille de lot utilisée pour chaque mise à jour de gradient. Elle influence directement la stabilité de l'entraînement, la qualité et la performance finale du modèle.                                                                                                                                                      | <p>4 à 16<br>Recommandé : 16 (à partir de 2 \* 8)</p> |

### Le compromis VRAM & performance

Supposez que vous souhaitiez 32 échantillons de données par étape d'entraînement. Vous pouvez alors utiliser l'une des configurations suivantes :

* `batch_size = 32, gradient_accumulation_steps = 1`
* `batch_size = 16, gradient_accumulation_steps = 2`
* `batch_size = 8, gradient_accumulation_steps = 4`
* `batch_size = 4, gradient_accumulation_steps = 8`
* `batch_size = 2, gradient_accumulation_steps = 16`
* `batch_size = 1, gradient_accumulation_steps = 32`

Bien que toutes ces configurations soient équivalentes pour les mises à jour des poids du modèle, elles ont des exigences matérielles très différentes.

La première configuration (`batch_size = 32`) utilise le **plus de VRAM** et échouera probablement sur la plupart des GPU. La dernière configuration (`batch_size = 1`) utilise le **le moins de VRAM,** mais au prix d'un entraînement légèrement plus len&#x74;**.** Pour éviter les erreurs OOM (out of memory), préférez toujours définir un `batch_size` plus petit et augmentez `gradient_accumulation_steps` pour atteindre votre **Taille de lot effective**.

### :sloth: Correction d'accumulation de gradient d'Unsloth

L'accumulation de gradients et les tailles de lot <mark style="color:vert;">**sont désormais entièrement équivalentes dans Unsloth**</mark> grâce à nos corrections de bugs pour l'accumulation de gradients. Nous avons implémenté des corrections spécifiques qui résolvent un problème courant où les deux méthodes ne produisaient pas les mêmes résultats. C'était un défi connu dans la communauté, mais pour les utilisateurs d'Unsloth, les deux méthodes sont désormais interchangeables.

[Lisez notre article de blog](https://unsloth.ai/blog/gradient) pour plus de détails.

Avant nos corrections, des combinaisons de `batch_size` et `gradient_accumulation_steps` qui donnaient le même **Taille de lot effective** (c.-à-d., `batch_size × gradient_accumulation_steps = 16`) n'entraînaient pas un comportement d'entraînement équivalent. Par exemple, des configurations comme `b1/g16`, `b2/g8`, `b4/g4`, `b8/g2`, et `b16/g1` ont toutes un **Taille de lot effective** de 16, mais comme le montre le graphe, les courbes de perte ne s'alignaient pas lors de l'utilisation de l'accumulation de gradient standard :

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-66eb907fd9ce38ab29dacef82794d0525057aeb4%2FBefore_-_Standard_gradient_accumulation_UQOFkUggudXuV9dzrh8MA.svg?alt=media" alt=""><figcaption><p>(Avant - Accumulation de gradient standard)</p></figcaption></figure>

Après l'application de nos corrections, les courbes de perte s'alignent désormais correctement, indépendamment de la façon dont le **Taille de lot effective** de 16 est atteint :

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-61f7c60412a2a39584f75cce5dca41e3e35eb7f2%2FAfter_-_Unsloth_gradient_accumulation_6Y4pJdJF0vruzradUpymY.svg?alt=media" alt=""><figcaption><p>(Après - 🦥 <mark style="color:vert;">Accumulation de gradient Unsloth</mark>)</p></figcaption></figure>

## 🦥 **Hyperparamètres LoRA dans Unsloth**

Ce qui suit démontre une configuration standard. **Bien qu'Unsloth fournisse des valeurs par défaut optimisées**, comprendre ces paramètres est essentiel pour un réglage manuel.

<div data-full-width="false"><figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-9843f8cc26aac6445236250f5c32394186eace59%2Fnotebook_parameter_screenshott.png?alt=media" alt=""><figcaption></figcaption></figure></div>

1. ```python
   r = 16, # Choisissez n'importe quel nombre > 0 ! Suggestion 8, 16, 32, 64, 128
   ```

   Le rang (`r`) du processus de fine-tuning. Un rang plus élevé utilise plus de mémoire et sera plus lent, mais peut augmenter la précision sur des tâches complexes. Nous suggérons des rangs comme 8 ou 16 (pour des fine-tunings rapides) et jusqu'à 128. Utiliser un rang trop grand peut provoquer du surapprentissage et nuire à la qualité de votre modèle.\\
2. ```python
   target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                     "gate_proj", "up_proj", "down_proj",],
   ```

   Pour des performances optimales, <mark style="background-color:blue;">**LoRA devrait être appliqué à toutes les principales couches linéaires**</mark>. [La recherche a montré](#lora-target-modules-and-qlora-vs-lora) que cibler toutes les couches majeures est crucial pour égaler les performances d'un fine-tuning complet. Bien qu'il soit possible de retirer des modules pour réduire l'utilisation mémoire, nous le déconseillons fortement afin de préserver la qualité maximale, car les économies sont minimes.\\
3. ```python
   lora_alpha = 16,
   ```

   Un facteur d'échelle qui contrôle la force des ajustements du fine-tuning. Le régler égal au rang (`r`) est une base fiable. Une heuristique populaire et efficace est de le régler au double du rang (`r * 2`), ce qui pousse le modèle à apprendre de manière plus agressive en donnant plus de poids aux mises à jour LoRA. [Plus de détails ici](#lora-alpha-and-rank-relationship).\\
4. ```python
   lora_dropout = 0, # Accepte n'importe quelle valeur, mais = 0 est optimisé
   ```

   Une technique de régularisation qui aide à [prévenir le surapprentissage](#overfitting-poor-generalization-too-specialized) en mettant aléatoirement une fraction des activations LoRA à zéro à chaque étape d'entraînement. [Des recherches récentes suggèrent](https://arxiv.org/abs/2410.09692) que pour **les courts entraînements** courants dans le fine-tuning, `lora_dropout` peut être un régularisateur peu fiable.\
   🦥 *Le code interne d'Unsloth peut optimiser l'entraînement lorsque* `lora_dropout = 0`*, le rendant légèrement plus rapide, mais nous recommandons une valeur non nulle si vous suspectez du surapprentissage.*\\
5. ```python
   bias = "none",    # Accepte n'importe quelle valeur, mais = "none" est optimisé
   ```

   Laissez ceci sur `"none"` pour un entraînement plus rapide et une utilisation mémoire réduite. Ce réglage évite d'entraîner les termes de biais dans les couches linéaires, ce qui ajoute des paramètres entraînables pour peu ou pas de gain pratique.\\
6. ```python
   use_gradient_checkpointing = "unsloth", # True ou "unsloth" pour un contexte très long
   ```

   Les options sont `True`, `False`, et `"unsloth"`.\
   🦥 *Nous recommandons* `"unsloth"` *car cela réduit l'utilisation mémoire d'environ 30% supplémentaires et prend en charge des fine-tunings avec un contexte extrêmement long. Vous pouvez en lire plus sur* [*notre article de blog sur l'entraînement avec long contexte*](https://unsloth.ai/blog/long-context)*.*\\
7. ```python
   random_state = 3407,
   ```

   La graine pour assurer des exécutions déterministes et reproductibles. L'entraînement implique des nombres aléatoires, donc fixer une graine est essentiel pour des expériences cohérentes.\\
8. ```python
   use_rslora = False,  # Nous supportons le LoRA stabilisé par le rang
   ```

   Une fonctionnalité avancée qui implémente [**Rank-Stabilized LoRA**](https://arxiv.org/abs/2312.03732). Si réglé sur `True`, le facteur d'échelle effectif devient `lora_alpha / sqrt(r)` au lieu du standard `lora_alpha / r`. Cela peut parfois améliorer la stabilité, en particulier pour des rangs élevés. [Plus de détails ici](#lora-alpha-and-rank-relationship).\\
9. ```python
   loftq_config = None, # Et LoftQ
   ```

   Une technique avancée, proposée dans [**LoftQ**](https://arxiv.org/abs/2310.08659), initialise les matrices LoRA avec les 'r' principaux vecteurs singuliers des poids pré-entraînés. Cela peut améliorer la précision mais provoquer un pic significatif de mémoire au démarrage de l'entraînement.

### **Vérification des mises à jour des poids LoRA :**

Lors de la validation que **LoRA** les poids de l'adaptateur ont été mis à jour après le fine-tuning, évitez d'utiliser **np.allclose()** pour la comparaison. Cette méthode peut manquer des changements subtils mais significatifs, en particulier dans **LoRA A**, qui est initialisée avec de petites valeurs gaussiennes. Ces changements peuvent ne pas être considérés comme significatifs sous des tolérances numériques larges. Merci aux [contributeurs](https://github.com/unslothai/unsloth/issues/3035) pour cette section.

Pour confirmer de manière fiable les mises à jour des poids, nous recommandons :

* Utiliser **des comparaisons de sommes de contrôle ou de hachage** (par ex., MD5)
* Calculer la **somme des différences absolues** entre tenseurs
* Inspecter les statistiques de**tenseur** (par ex., moyenne, variance) manuellement
* Ou utiliser **np.array\_equal()** si une égalité exacte est attendue

## :triangular\_ruler:Relation entre Alpha LoRA et Rang

{% hint style="success" %}
Il est préférable de définir `lora_alpha = 2 * lora_rank` ou `lora_alpha = lora_rank`
{% endhint %}

{% columns %}
{% column width="50%" %}
$$
\hat{W} = W + \frac{\alpha}{\text{rank}} \times AB
$$

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-8e4f60c002f22e8ca9c534b48323e9e77e4b5ea6%2Fimage.png?alt=media" alt=""><figcaption><p>rsLoRA autres options d'échelle. sqrt(r) est la meilleure.</p></figcaption></figure>

$$
\hat{W}\_{\text{rslora}} = W + \frac{\alpha}{\sqrt{\text{rank}}} \times AB
$$
{% endcolumn %}

{% column %}
La formule pour LoRA est à gauche. Nous devons mettre à l'échelle les matrices minces A et B par alpha divisé par le rang. <mark style="background-color:blue;">**Cela signifie que nous devons garder alpha/rang au moins = 1**</mark>.

Selon le [article rsLoRA (rank stabilized lora)](https://arxiv.org/abs/2312.03732), nous devrions plutôt mettre à l'échelle alpha par la racine carrée du rang. D'autres options existent, mais théoriquement c'est l'optimum. Le graphique de gauche montre d'autres rangs et leurs perplexités (plus bas est meilleur). Pour activer cela, réglez `use_rslora = True` dans Unsloth.

Notre recommandation est de régler <mark style="background-color:green;">**alpha égal au rang, ou au moins 2 fois le rang.**</mark> Cela signifie alpha/rang = 1 ou 2.
{% endcolumn %}
{% endcolumns %}

## :dart: Modules cibles LoRA et QLoRA vs LoRA

{% hint style="success" %}
Utilisez :\
`target_modules = ["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj",]` pour cibler à la fois **MLP** et **attention** couches pour augmenter la précision.

**QLoRA utilise une précision 4 bits**, réduisant l'utilisation de la VRAM de plus de 75%.

**LoRA (16 bits)** est légèrement plus précis et plus rapide.
{% endhint %}

Selon des expériences empiriques et des articles de recherche comme l'original [article QLoRA](https://arxiv.org/pdf/2305.14314), il est préférable d'appliquer LoRA à la fois aux couches d'attention et MLP.

{% columns %}
{% column %}

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-16bef8165ccace21d0533f1941b8268a165c6a37%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
{% endcolumn %}

{% column %}
Le graphique montre les scores RougeL (plus élevé est mieux) pour différentes configurations de modules cibles, comparant LoRA et QLoRA.

Les 3 premiers points montrent :

1. **QLoRA-All :** LoRA appliqué à toutes les couches FFN/MLP et Attention.\
   :fire: *Celle-ci donne les meilleures performances globales.*
2. **QLoRA-FFN** : LoRA uniquement sur FFN.\
   Équivalent à : `gate_proj`, `up_proj`, `down_proj.`
3. **QLoRA-Attention** : LoRA appliqué uniquement aux couches d'Attention.\
   Équivalent à : `q_proj`, `k_proj`, `v_proj`, `o_proj`.
   {% endcolumn %}
   {% endcolumns %}

## :sunglasses: S'entraîner uniquement sur les complétions, en masquant les entrées

Le [article QLoRA](https://arxiv.org/pdf/2305.14314) montre que masquer les entrées et **s'entraîner seulement sur les complétions** (sorties ou messages de l'assistant) peut encore **augmenter la précision** de quelques points de pourcentage (*1%*). Ci-dessous est démontré comment cela est fait dans Unsloth :

{% columns %}
{% column %}
**PAS** s'entraîner seulement sur les complétions :

**UTILISATEUR :** <mark style="background-color:green;">Bonjour, combien font 2+2 ?</mark>\
**ASSISTANT :** <mark style="background-color:green;">La réponse est 4.</mark>\
**UTILISATEUR :** <mark style="background-color:green;">Bonjour, combien font 3+3 ?</mark>\
**ASSISTANT :** <mark style="background-color:green;">La réponse est 6.</mark>
{% endcolumn %}

{% column %}
**Entraînement** sur les complétions seulement :

**UTILISATEUR :** ~~Bonjour, combien font 2+2 ?~~\
**ASSISTANT :** <mark style="background-color:green;">La réponse est 4.</mark>\
**UTILISATEUR :** ~~Bonjour, combien font 3+3 ?~~\
**ASSISTANT :** <mark style="background-color:green;">La réponse est 6</mark><mark style="background-color:green;">**.**</mark>
{% endcolumn %}
{% endcolumns %}

L'article QLoRA indique que **s'entraîner uniquement sur les complétions** augmente considérablement la précision, surtout pour les fine-tunings conversationnels multi-tours ! Nous faisons cela dans nos [notebooks conversationnels ici](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3.2_\(1B_and_3B\)-Conversational.ipynb).

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-7e73b480d1db1dd3d52dd0d4a7e24caff6a54be0%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

Pour activer **l'entraînement sur les complétions** dans Unsloth, vous devrez définir les parties instruction et assistant. :sloth: *Nous prévoyons d'automatiser cela davantage pour vous à l'avenir !*

Pour Llama 3, 3.1, 3.2, 3.3 et les modèles 4, vous définissez les parties comme suit :

```python
from unsloth.chat_templates import train_on_responses_only
trainer = train_on_responses_only(
    trainer,
    instruction_part = "<|start_header_id|>user<|end_header_id|>\n\n",
    response_part = "<|start_header_id|>assistant<|end_header_id|>\n\n",
)
```

Pour les modèles Gemma 2, 3, 3n, vous définissez les parties comme suit :

```python
from unsloth.chat_templates import train_on_responses_only
trainer = train_on_responses_only(
    trainer,
    instruction_part = "<start_of_turn>user\n",
    response_part = "<start_of_turn>model\n",
)
```

## &#x20;:mag\_right:Entraînement uniquement sur les réponses de l'assistant pour les modèles de vision, VLMs

Pour les modèles de langage, nous pouvons utiliser `from unsloth.chat_templates import train_on_responses_only` comme décrit précédemment. Pour les modèles de vision, utilisez les arguments supplémentaires dans `UnslothVisionDataCollator` comme avant !

{% code overflow="wrap" %}

```python
class UnslothVisionDataCollator :
def __init__(
    self,
    ...
    # from unsloth.chat_templates import train_on_responses_only
    # trainer = train_on_responses_only(
    #     trainer,
    #     instruction_part = "<|start_header_id|>user<|end_header_id|>\n\n",
    #     response_part = "<|start_header_id|>assistant<|end_header_id|>\n\n",
    # )
    train_on_responses_only = False, # ÉQUIVALENT à train_on_responses_only pour les LLM
    instruction_part = None, # ÉQUIVALENT à train_on_responses_only(instruction_part = ...)
    response_part    = None, # ÉQUIVALENT à train_on_responses_only(response_part = ...)
    force_match      = True, # Faire correspondre aussi les retours à la ligne !
)
```

{% endcode %}

Par exemple pour Llama 3.2 Vision :

```python
UnslothVisionDataCollator(
    model, tokenizer,
    ...
    train_on_responses_only = True,
    instruction_part = "<|start_header_id|>user<|end_header_id|>\n\n",
    response_part = "<|start_header_id|>assistant<|end_header_id|>\n\n",
    ...
)
```

## :key: **Éviter le surapprentissage & le sous-apprentissage**

### **Surapprentissage** (Mauvaise généralisation/Trop spécialisé)

Le modèle mémorise les données d'entraînement, y compris le bruit statistique, et par conséquent ne parvient pas à généraliser aux données non vues.

{% hint style="success" %}
Si votre perte d'entraînement descend en dessous de 0.2, votre modèle est probablement **le surapprentissage** — ce qui signifie qu'il peut mal performer sur des tâches non vues.

Une astuce simple est la mise à l'échelle de l'alpha LoRA — multipliez simplement la valeur alpha de chaque matrice LoRA par 0.5. Cela réduit effectivement l'impact du fine-tuning.

**Ceci est étroitement lié à la fusion / moyenne des poids.**\
Vous pouvez prendre le modèle de base original (ou instruct), ajouter les poids LoRA, puis diviser le résultat par 2. Cela vous donne un modèle moyenné — ce qui est fonctionnellement équivalent à réduire `l'alpha` de moitié.
{% endhint %}

**Solution :**

* **Ajustez le taux d'apprentissage :** Un taux d'apprentissage élevé conduit souvent au surapprentissage, surtout lors de courts entraînements. Pour des entraînements plus longs, un taux plus élevé peut mieux fonctionner. Il est préférable d'expérimenter les deux pour voir lequel fonctionne le mieux.
* **Réduire le nombre d'époques d'entraînement**. Arrêtez l'entraînement après 1, 2 ou 3 époques.
* **Augmenter** `weight_decay`. Une valeur de `0.01` ou `0.1` est un bon point de départ.
* **Augmenter** `lora_dropout`. Utilisez une valeur comme `0.1` pour ajouter de la régularisation.
* **Augmenter la taille de lot ou les étapes d'accumulation de gradient**.
* **Expansion du jeu de données**  - augmentez la taille de votre jeu de données en combinant ou en concaténant des jeux de données open source avec votre jeu de données. Choisissez ceux de meilleure qualité.
* **Arrêt précoce basé sur l'évaluation**  - activez l'évaluation et arrêtez lorsque la perte d'évaluation augmente pendant quelques étapes.
* **Mise à l'échelle alpha LoRA**  - réduisez l'alpha après l'entraînement et pendant l'inférence - cela rendra le fine-tuning moins prononcé.
* **Moyennage des poids**  - ajoutez littéralement le modèle instruct original et le fine-tune puis divisez les poids par 2.

### **Sous-apprentissage** (Trop générique)

Le modèle ne parvient pas à capturer les motifs sous-jacents des données d'entraînement, souvent en raison d'une complexité insuffisante ou d'une durée d'entraînement trop courte.

**Solution :**

* **Ajustez le taux d'apprentissage :** Si le taux actuel est trop bas, l'augmenter peut accélérer la convergence, surtout pour les courts entraînements. Pour des runs plus longs, essayez plutôt d'abaisser le taux d'apprentissage. Testez les deux approches pour voir laquelle fonctionne le mieux.
* **Augmenter les époques d'entraînement :** Entraînez plus d'époques, mais surveillez la perte de validation pour éviter le surapprentissage.
* **Augmenter le rang LoRA** (`r`) et l'alpha : le rang doit au moins être égal au nombre alpha, et le rang doit être plus grand pour les modèles plus petits/jeux de données plus complexes ; il se situe généralement entre 4 et 64.
* **Utiliser un jeu de données plus pertinent pour le domaine** : Assurez-vous que les données d'entraînement sont de haute qualité et directement pertinentes pour la tâche cible.
* **Diminuer la taille de lot à 1**. Cela fera que le modèle se mette à jour plus vigoureusement.

{% hint style="success" %}
Le fine-tuning n'a pas d'approche "meilleure" unique, seulement des meilleures pratiques. L'expérimentation est la clé pour trouver ce qui fonctionne pour vos besoins spécifiques. Nos notebooks définissent automatiquement des paramètres optimaux basés sur de nombreuses recherches et nos expériences, vous offrant un excellent point de départ. Bon fine-tuning !
{% endhint %}

***Remerciements :** Un énorme merci à* [*Eyera*](https://huggingface.co/Orenguteng) *pour avoir contribué à ce guide !*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unsloth.ai/docs/fr/commencer/fine-tuning-llms-guide/lora-hyperparameters-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
