# Leitfaden zu Hyperparametern für LoRA-Fine-Tuning

LoRA-Hyperparameter sind einstellbare Parameter, die steuern, wie Low-Rank-Adaptation [feinabstimmt](https://unsloth.ai/docs/de/los-gehts/fine-tuning-llms-guide) LLMs. Bei vielen Optionen (z. B. Lernrate und Epochen) und zahllosen Kombinationen ist die Wahl der richtigen Werte entscheidend für Genauigkeit, Stabilität, Qualität und weniger Halluzinationen. Richtig angewendet kann **LoRA die Leistung einer vollständigen Feinabstimmung erreichen** während es 4× weniger VRAM verwendet.

Sie lernen die besten Praktiken für diese Parameter basierend auf Erkenntnissen aus Hunderten von Forschungsarbeiten und Experimenten und sehen, wie sie das Modell beeinflussen. **Während wir empfehlen, Unsloths Standardeinstellungen zu verwenden**, wird Ihnen das Verständnis dieser Konzepte vollständige Kontrolle geben.\
\
Das Ziel ist, Hyperparameterwerte zu ändern, um die Genauigkeit zu erhöhen und gleichzeitig [**Overfitting oder Underfitting**](#overfitting-poor-generalization-too-specialized). Overfitting tritt auf, wenn das Modell die Trainingsdaten auswendig lernt, was seine Fähigkeit beeinträchtigt, auf neue, ungesehene Eingaben zu generalisieren. Das Ziel ist ein Modell, das gut generalisiert, nicht eines, das einfach nur auswendig lernt.

{% columns %}
{% column %}

#### :question:Aber was ist LoRA?

In LLMs haben wir Modellgewichte. Llama 70B hat 70 Milliarden Zahlen. Anstatt alle 70 Mrd. Zahlen zu verändern, fügen wir stattdessen dünne Matrizen A und B zu jedem Gewicht hinzu und optimieren diese. Das bedeutet, dass wir nur 1 % der Gewichte optimieren.
{% endcolumn %}

{% column %}

<figure><img src="https://797013937-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>Anstatt die Modellgewichte (gelb) zu optimieren, optimieren wir 2 dünne Matrizen A und B.</p></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

## :1234: Wichtige Fine-Tuning-Hyperparameter

### **Lernrate**

Definiert, wie stark die Gewichte des Modells bei jedem Trainingsschritt angepasst werden.

* **Höhere Lernraten**: Führen zu schnellerer anfänglicher Konvergenz, können aber das Training instabil machen oder verhindern, dass ein optimales Minimum gefunden wird, wenn sie zu hoch eingestellt sind.
* **Niedrigere Lernraten**: Führen zu stabilerem und präziserem Training, können jedoch mehr Epochen benötigen, um zu konvergieren, was die gesamte Trainingszeit erhöht. Obwohl oft angenommen wird, dass niedrige Lernraten zu Underfitting führen, können sie tatsächlich zu **Overfitting** oder sogar dazu führen, dass das Modell nicht lernt.
* **Typischer Bereich**: `2e-4` (0,0002) bis `5e-6` (0.000005).\
  :green\_square: ***Für normales LoRA/QLoRA-Fine-Tuning***, *empfehlen wir* **`2e-4`** *als Ausgangspunkt.*\
  :blue\_square: ***Für Reinforcement Learning** (DPO, GRPO usw.) empfehlen wir* **`5e-6` .**\
  :white\_large\_square: ***Für vollständiges Fine-Tuning** sind in der Regel niedrigere Lernraten angemessener.*

### **Epochen**

Die Anzahl der Male, die das Modell das gesamte Trainingsdatenset sieht.

* **Mehr Epochen:** können dem Modell helfen, besser zu lernen, aber eine hohe Anzahl kann dazu führen, dass es **die Trainingsdaten auswendig lernt**, was seine Leistung bei neuen Aufgaben beeinträchtigt.
* **Weniger Epochen:** reduzieren die Trainingszeit und können Overfitting verhindern, können jedoch zu einem unzureichend trainierten Modell führen, wenn die Anzahl nicht ausreicht, damit das Modell die zugrundeliegenden Muster des Datensatzes lernt.
* **Empfohlen:** 1–3 Epochen. Für die meisten instruktionalen Datensätze bringt Training für mehr als 3 Epochen abnehmende Erträge und erhöht das Risiko von Overfitting.

### **LoRA oder QLoRA**

LoRA verwendet 16-Bit-Präzision, während QLoRA eine 4-Bit-Fine-Tuning-Methode ist.

* **LoRA:** 16-Bit-Fine-Tuning. Es ist etwas schneller und etwas genauer, verbraucht jedoch deutlich mehr VRAM (4× mehr als QLoRA). Empfohlen für 16-Bit-Umgebungen und Szenarien, in denen maximale Genauigkeit erforderlich ist.
* **QLoRA:** 4-Bit-Fine-Tuning. Etwas langsamer und marginal weniger genau, verwendet aber viel weniger VRAM (4× weniger).\
  :sloth: *70B LLaMA passt mit QLoRA in Unsloth in <48GB VRAM -* [*mehr Details hier*](https://unsloth.ai/blog/llama3-3)*.*

### Hyperparameter & Empfehlungen:

<table><thead><tr><th width="154.39678955078125">Hyperparameter</th><th width="383.6192626953125">Funktion</th><th>Empfohlene Einstellungen</th></tr></thead><tbody><tr><td><strong>LoRA-Rang</strong> (<code>r</code>)</td><td>Steuert die Anzahl der trainierbaren Parameter in den LoRA-Adaptermatrizen. Ein höherer Rang erhöht die Modellkapazität, aber auch den Speicherverbrauch.</td><td>8, 16, 32, 64, 128<br><br>Wählen Sie 16 oder 32</td></tr><tr><td><strong>LoRA Alpha</strong> (<code>lora_alpha</code>)</td><td>Skaliert die Stärke der feinabgestimmten Anpassungen in Bezug auf den Rang (<code>r</code>).</td><td><code>r</code> (Standard) oder <code>r * 2</code> (häufige Heuristik). <a href="#lora-alpha-and-rank-relationship">Mehr Details hier</a>.</td></tr><tr><td><strong>LoRA Dropout</strong></td><td>Eine Regularisierungstechnik, die zufällig einen Bruchteil der LoRA-Aktivierungen während des Trainings auf null setzt, um Overfitting zu verhindern. <strong>Nicht so nützlich</strong>, daher setzen wir den Standardwert auf 0.</td><td>0 (Standard) bis 0,1</td></tr><tr><td><strong>Gewichtszerfall</strong></td><td>Ein Regularisierungsterm, der große Gewichte bestraft, um Overfitting zu verhindern und die Generalisierung zu verbessern. Verwenden Sie keine zu großen Werte!</td><td>0,01 (empfohlen) - 0,1</td></tr><tr><td><strong>Warmup-Schritte</strong></td><td>Erhöht die Lernrate zu Beginn des Trainings schrittweise.</td><td>5–10 % der Gesamtschritte</td></tr><tr><td><strong>Scheduler-Typ</strong></td><td>Passt die Lernrate während des Trainings dynamisch an.</td><td><code>linear</code> oder <code>cosine</code></td></tr><tr><td><strong>Seed (<code>random_state</code>)</strong></td><td>Eine feste Zahl, um die Reproduzierbarkeit der Ergebnisse sicherzustellen.</td><td>Jede ganze Zahl (z. B. <code>42</code>, <code>3407</code>)</td></tr><tr><td><strong>Zielmodule</strong></td><td><p>Geben Sie an, auf welche Teile des Modells Sie LoRA-Adapter anwenden möchten — entweder die Attention, das MLP oder beides.</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>Empfohlen, alle wichtigen linearen Schichten anzusprechen: <code>q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj</code>.</td></tr></tbody></table>

## :deciduous\_tree: Gradientenakkumulation und Äquivalenz der Batch-Größe

### Effektive Batch-Größe

Die korrekte Konfiguration Ihrer Batch-Größe ist entscheidend, um Trainingsstabilität mit den VRAM-Beschränkungen Ihrer GPU in Einklang zu bringen. Dies wird durch zwei Parameter gesteuert, deren Produkt die **Effektive Batch-Größe**.\
\
**Effektive Batch-Größe** = `batch_size * gradient_accumulation_steps`

* Eine **größere effektive Batch-Größe** führt im Allgemeinen zu einem ruhigeren, stabileren Training.
* Eine **kleinere effektive Batch-Größe** kann mehr Varianz einführen.

Während jede Aufgabe anders ist, bietet die folgende Konfiguration einen guten Ausgangspunkt, um eine stabile **Effektive Batch-Größe** von 16, die für die meisten Fine-Tuning-Aufgaben auf modernen GPUs gut funktioniert.

| Parameter                                                  | Beschreibung                                                                                                                                                                                                                                                                                                           | Empfohlene Einstellung                        |
| ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| **Batch-Größe** (`batch_size`)                             | <p>Die Anzahl der Beispiele, die in einem einzigen Vorwärts-/Rückwärtsdurchlauf auf einer GPU verarbeitet werden.<br><br><strong>Haupttreiber des VRAM-Verbrauchs</strong>. Höhere Werte können die Hardware-Auslastung verbessern und das Training beschleunigen, aber nur, wenn sie in den Speicher passen.</p>      | 2                                             |
| **Gradientenakkumulation** (`gradient_accumulation_steps`) | <p>Die Anzahl der Micro-Batches, die verarbeitet werden, bevor ein einzelnes Modellgewichts-Update durchgeführt wird.<br><br><strong>Haupttreiber der Trainingszeit.</strong> Erlaubt die Simulation einer größeren <code>batch\_size</code> um VRAM zu sparen. Höhere Werte erhöhen die Trainingszeit pro Epoche.</p> | 8                                             |
| **Effektive Batch-Größe** (Berechnet)                      | Die tatsächliche Batch-Größe, die für jedes Gradientenupdate verwendet wird. Sie beeinflusst direkt Trainingsstabilität, Qualität und die endgültige Modellleistung.                                                                                                                                                   | <p>4 bis 16<br>Empfohlen: 16 (von 2 \* 8)</p> |

### Der VRAM- & Leistungs-Trade-off

Angenommen, Sie möchten 32 Datenproben pro Trainingsschritt. Dann können Sie eine der folgenden Konfigurationen verwenden:

* `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`

Während all diese für die Gewichtsupdates des Modells äquivalent sind, haben sie sehr unterschiedliche Hardware-Anforderungen.

Die erste Konfiguration (`batch_size = 32`) verwendet den **meisten VRAM** und wird wahrscheinlich auf den meisten GPUs fehlschlagen. Die letzte Konfiguration (`batch_size = 1`) verwendet den **am wenigsten VRAM,** aber auf Kosten eines etwas langsameren Training&#x73;**.** Um OOM-Fehler (Out of Memory) zu vermeiden, bevorzugen Sie immer, eine kleinere `batch_size` einzustellen und `gradient_accumulation_steps` zu erhöhen, um Ihr Ziel **Effektive Batch-Größe**.

### :sloth: Unsloth-Gradientenakkumulations-Fix

Gradientenakkumulation und Batch-Größen <mark style="color:grün;">**sind jetzt in Unsloth vollständig äquivalent**</mark> aufgrund unserer Fehlerbehebungen für die Gradientenakkumulation. Wir haben spezifische Fehlerbehebungen für die Gradientenakkumulation implementiert, die ein häufiges Problem lösen, bei dem die beiden Methoden nicht die gleichen Ergebnisse lieferten. Dies war eine bekannte Herausforderung in der breiteren Community, aber für Unsloth-Nutzer sind die beiden Methoden jetzt austauschbar.

[Lesen Sie unseren Blogbeitrag](https://unsloth.ai/blog/gradient) für weitere Details.

Vor unseren Fixes führten Kombinationen aus `batch_size` und `gradient_accumulation_steps` die dasselbe ergaben **Effektive Batch-Größe** (d. h., `batch_size × gradient_accumulation_steps = 16`) nicht zu äquivalentem Trainingsverhalten. Zum Beispiel führten Konfigurationen wie `b1/g16`, `b2/g8`, `b4/g4`, `b8/g2`, und `b16/g1` haben alle eine **Effektive Batch-Größe** von 16, aber wie im Diagramm gezeigt, stimmten die Verlustkurven bei Verwendung der standardmäßigen Gradientenakkumulation nicht überein:

<figure><img src="https://797013937-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>(Vorher - Standardmäßige Gradientenakkumulation)</p></figcaption></figure>

Nach Anwendung unserer Fixes stimmen die Verlustkurven nun korrekt überein, unabhängig davon, wie die **Effektive Batch-Größe** von 16 erreicht wird:

<figure><img src="https://797013937-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>(Nach - 🦥 <mark style="color:grün;">Unsloth-Gradientenakkumulation</mark>)</p></figcaption></figure>

## 🦥 **LoRA-Hyperparameter in Unsloth**

Das Folgende demonstriert eine Standardkonfiguration. **Während Unsloth optimierte Standardeinstellungen bietet**, ist das Verständnis dieser Parameter der Schlüssel zum manuellen Tuning.

<div data-full-width="false"><figure><img src="https://797013937-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, # Wählen Sie eine beliebige Zahl > 0! Vorgeschlagen: 8, 16, 32, 64, 128
   ```

   Der Rang (`r`) des Fine-Tuning-Prozesses. Ein größerer Rang verbraucht mehr Speicher und ist langsamer, kann aber die Genauigkeit bei komplexen Aufgaben erhöhen. Wir empfehlen Ränge wie 8 oder 16 (für schnelle Feinabstimmungen) und bis zu 128. Die Verwendung eines zu großen Rangs kann Overfitting verursachen und die Qualität Ihres Modells beeinträchtigen.\\
2. ```python
   target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                     "gate_proj", "up_proj", "down_proj",],
   ```

   Für optimale Leistung <mark style="background-color:blue;">**sollte LoRA auf alle wichtigen linearen Schichten angewendet werden**</mark>. [Forschung hat gezeigt](#lora-target-modules-and-qlora-vs-lora) , dass das Ansprechen aller wichtigen Schichten entscheidend ist, um die Leistung einer vollständigen Feinabstimmung zu erreichen. Zwar ist es möglich, Module zu entfernen, um Speicher zu sparen, wir raten jedoch dringend davon ab, um die maximale Qualität zu erhalten, da die Einsparungen minimal sind.\\
3. ```python
   lora_alpha = 16,
   ```

   Ein Skalierungsfaktor, der die Stärke der feinabgestimmten Anpassungen steuert. Ihn gleich dem Rang zu setzen (`r`) ist eine verlässliche Basislinie. Eine populäre und effektive Heuristik ist, ihn auf das Doppelte des Rangs zu setzen (`r * 2`), was das Modell aggressiver lernen lässt, indem den LoRA-Updates mehr Gewicht gegeben wird. [Mehr Details hier](#lora-alpha-and-rank-relationship).\\
4. ```python
   lora_dropout = 0, # Unterstützt beliebige Werte, aber = 0 ist optimiert
   ```

   Eine Regularisierungstechnik, die hilft, [Overfitting zu verhindern](#overfitting-poor-generalization-too-specialized) , indem sie zufällig einen Bruchteil der LoRA-Aktivierungen während jedes Trainingsschritts auf null setzt. [Jüngste Forschung legt nahe](https://arxiv.org/abs/2410.09692) , dass für **die kurzen Trainingsläufe** die beim Fine-Tuning üblich sind, `kann lora_dropout` ein unzuverlässiger Regularisierer sein.\
   🦥 *Unsloths interner Code kann das Training optimieren, wenn* `lora_dropout = 0`*, wodurch es etwas schneller wird, aber wir empfehlen einen von null verschiedenen Wert, wenn Sie Overfitting vermuten.*\\
5. ```python
   bias = "none",    # Unterstützt beliebige Werte, aber = "none" ist optimiert
   ```

   Lassen Sie dies als `"none"` für schnelleres Training und reduzierten Speicherverbrauch. Diese Einstellung vermeidet das Trainieren der Bias-Terme in den linearen Schichten, die trainierbare Parameter hinzufügen, ohne praktisch nennenswerten Gewinn zu bringen.\\
6. ```python
   use_gradient_checkpointing = "unsloth", # True oder "unsloth" für sehr langen Kontext
   ```

   Optionen sind `True`, `False`, und `"unsloth"`.\
   🦥 *Wir empfehlen* `"unsloth"` *da es den Speicherverbrauch um zusätzliche 30% reduziert und extrem lange Kontext-Finetunings unterstützt. Mehr dazu lesen Sie in* [*unserem Blogbeitrag über Training mit langem Kontext*](https://unsloth.ai/blog/long-context)*.*\\
7. ```python
   random_state = 3407,
   ```

   Der Seed, um deterministische, reproduzierbare Durchläufe sicherzustellen. Training beinhaltet Zufallszahlen, daher ist das Setzen eines festen Seeds für konsistente Experimente unerlässlich.\\
8. ```python
   use_rslora = False,  # Wir unterstützen rank-stabilisiertes LoRA
   ```

   Eine fortgeschrittene Funktion, die [**Rank-Stabilized LoRA**](https://arxiv.org/abs/2312.03732). Wenn auf `True`gesetzt, wird die effektive Skalierung `lora_alpha / sqrt(r)` statt der standardmäßigen `lora_alpha / r`. Dies kann die Stabilität verbessern, insbesondere bei höheren Rängen. [Mehr Details hier](#lora-alpha-and-rank-relationship).\\
9. ```python
   loftq_config = None, # Und LoftQ
   ```

   Eine fortgeschrittene Technik, wie in [**LoftQ**](https://arxiv.org/abs/2310.08659)vorgeschlagen, initialisiert LoRA-Matrizen mit den oberen 'r' Singulärvektoren aus den vortrainierten Gewichten. Dies kann die Genauigkeit verbessern, kann aber zu einem signifikanten Speicheranstieg zu Beginn des Trainings führen.

### **Verifizierung von LoRA-Gewichtsaktualisierungen:**

Beim Validieren, dass **LoRA** Adaptergewichte nach dem Fine-Tuning aktualisiert wurden, vermeiden Sie die Verwendung von **np.allclose()** für den Vergleich. Diese Methode kann subtile, aber bedeutende Änderungen übersehen, insbesondere in **LoRA A**, das mit kleinen gaußschen Werten initialisiert wird. Diese Änderungen könnten unter lockeren numerischen Toleranzen nicht als signifikant erkannt werden. Dank an [Mitwirkende](https://github.com/unslothai/unsloth/issues/3035) für diesen Abschnitt.

Um Gewichtsaktualisierungen zuverlässig zu bestätigen, empfehlen wir:

* Die Verwendung von **Prüfsummen- oder Hash-Vergleichen** (z. B. MD5)
* Berechnung der **Summe der absoluten Unterschiede** zwischen Tensoren
* Untersuchung von**Tensorstatistiken** (z. B. Mittelwert, Varianz) manuell
* Oder die Verwendung von **np.array\_equal()** wenn exakte Gleichheit erwartet wird

## :triangular\_ruler:Beziehung zwischen LoRA Alpha und Rang

{% hint style="success" %}
Es ist am besten, `lora_alpha = 2 * lora_rank` oder `lora_alpha = lora_rank`
{% endhint %}

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

<figure><img src="https://797013937-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 andere Skalierungsoptionen. sqrt(r) ist die beste.</p></figcaption></figure>

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

{% column %}
Die Formel für LoRA steht links. Wir müssen die dünnen Matrizen A und B mit alpha geteilt durch den Rang skalieren. <mark style="background-color:blue;">**Das bedeutet, wir sollten alpha/rank mindestens = 1 halten**</mark>.

Laut dem [rsLoRA (rank stabilized lora) Papier](https://arxiv.org/abs/2312.03732)sollten wir stattdessen alpha mit der Quadratwurzel des Rangs skalieren. Es existieren andere Optionen, aber theoretisch ist dies optimal. Die linke Grafik zeigt andere Ränge und deren Perplexitäten (niedriger ist besser). Um dies zu aktivieren, setzen Sie `use_rslora = True` in Unsloth.

Unsere Empfehlung ist, das <mark style="background-color:green;">**Alpha gleich dem Rang zu setzen, oder zumindest 2 mal den Rang.**</mark> Das bedeutet alpha/rank = 1 oder 2.
{% endcolumn %}
{% endcolumns %}

## :dart: LoRA-Zielmodule und QLoRA vs LoRA

{% hint style="success" %}
Verwenden Sie:\
`target_modules = ["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj",]` um sowohl **MLP** und **Aufmerksamkeits-** Schichten zu zielen, um die Genauigkeit zu erhöhen.

**QLoRA verwendet 4-Bit-Präzision**, wodurch der VRAM-Verbrauch um über 75% reduziert wird.

**LoRA (16-Bit)** ist etwas genauer und schneller.
{% endhint %}

Laut empirischen Experimenten und Forschungsarbeiten wie dem ursprünglichen [QLoRA-Papier](https://arxiv.org/pdf/2305.14314)ist es am besten, LoRA sowohl auf Aufmerksamkeits- als auch auf MLP-Schichten anzuwenden.

{% columns %}
{% column %}

<figure><img src="https://797013937-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 %}
Das Diagramm zeigt RougeL-Werte (höher ist besser) für verschiedene Konfigurationen der Zielmodule und vergleicht LoRA vs QLoRA.

Die ersten 3 Punkte zeigen:

1. **QLoRA-All:** LoRA angewendet auf alle FFN/MLP- und Attention-Schichten.\
   :fire: *Dies liefert insgesamt die beste Leistung.*
2. **QLoRA-FFN**: LoRA nur auf FFN.\
   Entspricht: `gate_proj`, `up_proj`, `down_proj.`
3. **QLoRA-Attention**: LoRA nur auf Attention-Schichten angewendet.\
   Entspricht: `q_proj`, `k_proj`, `v_proj`, `o_proj`.
   {% endcolumn %}
   {% endcolumns %}

## :sunglasses: Training nur auf Completion-Antworten, Eingaben maskieren

Das [QLoRA-Papier](https://arxiv.org/pdf/2305.14314) zeigt, dass das Maskieren der Eingaben und **nur auf Completion-Antworten zu trainieren** (Ausgaben oder Assistentenmeldungen) weiter **die Genauigkeit erhöhen kann** um ein paar Prozentpunkte (*1%*). Unten wird demonstriert, wie dies in Unsloth gemacht wird:

{% columns %}
{% column %}
**NICHT** nur auf Completion-Antworten trainieren:

**BENUTZER:** <mark style="background-color:green;">Hallo, was ist 2+2?</mark>\
**ASSISTENT:** <mark style="background-color:green;">Die Antwort ist 4.</mark>\
**BENUTZER:** <mark style="background-color:green;">Hallo, was ist 3+3?</mark>\
**ASSISTENT:** <mark style="background-color:green;">Die Antwort ist 6.</mark>
{% endcolumn %}

{% column %}
**Training** nur auf Completion-Antworten:

**BENUTZER:** ~~Hallo, was ist 2+2?~~\
**ASSISTENT:** <mark style="background-color:green;">Die Antwort ist 4.</mark>\
**BENUTZER:** ~~Hallo, was ist 3+3?~~\
**ASSISTENT:** <mark style="background-color:green;">Die Antwort ist 6</mark><mark style="background-color:green;">**.**</mark>
{% endcolumn %}
{% endcolumns %}

Das QLoRA-Papier besagt, dass **nur auf Completion-Antworten zu trainieren** die Genauigkeit deutlich erhöht, insbesondere bei mehrschrittigen Konversations-Finetunings! Das machen wir in unseren [konversationellen Notebooks hier](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3.2_\(1B_and_3B\)-Conversational.ipynb).

<figure><img src="https://797013937-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>

Um das **Training auf Completion-Antworten** in Unsloth zu aktivieren, müssen Sie die Instruction- und Assistant-Teile definieren. :sloth: *Wir planen, dies in Zukunft weiter für Sie zu automatisieren!*

Für Llama 3, 3.1, 3.2, 3.3 und 4 Modelle definieren Sie die Teile wie folgt:

```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",
)
```

Für Gemma 2, 3, 3n Modelle definieren Sie die Teile wie folgt:

```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:Training nur auf Assistentenantworten für Vision-Modelle, VLMs

Für Sprachmodelle können wir `from unsloth.chat_templates import train_on_responses_only` wie zuvor beschrieben verwenden. Für Vision-Modelle verwenden Sie die zusätzlichen Argumente als Teil von `UnslothVisionDataCollator` genau wie zuvor!

{% 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 zu train_on_responses_only für LLMs
    instruction_part = None, # ÄQUIVALENT zu train_on_responses_only(instruction_part = ...)
    response_part    = None, # ÄQUIVALENT zu train_on_responses_only(response_part = ...)
    force_match      = True, # Übereinstimmung von Newlines ebenfalls!
)
```

{% endcode %}

Zum Beispiel für Llama 3.2 Vision:

```python
UnslothVisionDataCollator(
    Modell, 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: **Vermeidung von Overfitting & Underfitting**

### **Overfitting** (Schlechte Generalisierung/ZU spezialisiert)

Das Modell memoriert die Trainingsdaten, einschließlich ihres statistischen Rauschens, und versagt folglich darin, auf ungesehene Daten zu verallgemeinern.

{% hint style="success" %}
Wenn Ihr Trainingsverlust unter 0,2 fällt, ist Ihr Modell wahrscheinlich **Overfitting** — was bedeutet, dass es bei ungesehenen Aufgaben schlecht abschneiden kann.

Ein einfacher Trick ist das Skalieren von LoRA-Alpha — multiplizieren Sie einfach den Alpha-Wert jeder LoRA-Matrix mit 0,5. Das reduziert effektiv den Einfluss des Finetunings.

**Dies steht in engem Zusammenhang mit dem Mergen / Durchschnittsbilden von Gewichten.**\
Sie können das ursprüngliche Basis- (oder Instruct-) Modell nehmen, die LoRA-Gewichte hinzufügen und das Ergebnis dann durch 2 teilen. Das ergibt ein gemitteltes Modell — was funktional dem Halbieren des `alpha` entspricht.
{% endhint %}

**Lösung:**

* **Passen Sie die Lernrate an:** Eine hohe Lernrate führt oft zu Overfitting, besonders bei kurzen Trainingsläufen. Für längeres Training kann eine höhere Lernrate besser funktionieren. Es ist am besten, mit beiden zu experimentieren, um zu sehen, welche am besten abschneidet.
* **Reduzieren Sie die Anzahl der Trainingsepochen**. Stoppen Sie das Training nach 1, 2 oder 3 Epochen.
* **Erhöhen Sie** `weight_decay`. Ein Wert von `0.01` oder `0.1` ist ein guter Ausgangspunkt.
* **Erhöhen Sie** `kann lora_dropout`. Verwenden Sie einen Wert wie `0.1` um Regularisierung hinzuzufügen.
* **Erhöhen Sie die Batch-Größe oder die Anzahl der Gradient-Accumulation-Schritte**.
* **Datensatz-Erweiterung** - Vergrößern Sie Ihren Datensatz, indem Sie Open-Source-Datensätze mit Ihrem Datensatz kombinieren oder aneinanderreihen. Wählen Sie qualitativ hochwertigere aus.
* **Evaluation Early Stopping** - Aktivieren Sie die Evaluation und stoppen Sie, wenn der Evaluationsverlust für einige Schritte ansteigt.
* **LoRA Alpha Skalierung** - Skalieren Sie das Alpha nach dem Training und während der Inferenz herunter – dadurch wird das Finetune weniger ausgeprägt.
* **Gewichtsdurchschnitt** - Fügen Sie wörtlich das ursprüngliche Instruct-Modell und das Finetune zusammen und teilen Sie die Gewichte durch 2.

### **Underfitting** (Zu generisch)

Das Modell erfasst nicht die zugrunde liegenden Muster in den Trainingsdaten, oft aufgrund unzureichender Komplexität oder Trainingsdauer.

**Lösung:**

* **Passen Sie die Lernrate an:** Wenn die aktuelle Rate zu niedrig ist, kann eine Erhöhung die Konvergenz beschleunigen, insbesondere bei kurzen Trainingsläufen. Für längere Läufe versuchen Sie stattdessen, die Lernrate zu senken. Testen Sie beide Ansätze, um zu sehen, welcher am besten funktioniert.
* **Erhöhen Sie die Trainings-Epochen:** Trainieren Sie für mehr Epochen, überwachen Sie aber den Validierungsverlust, um Overfitting zu vermeiden.
* **Erhöhen Sie den LoRA-Rang** (`r`) und Alpha: Der Rang sollte mindestens gleich der Alpha-Zahl sein, und der Rang sollte für kleinere Modelle/komplexere Datensätze größer sein; normalerweise liegt er zwischen 4 und 64.
* **Verwenden Sie einen domänenrelevanteren Datensatz**: Stellen Sie sicher, dass die Trainingsdaten von hoher Qualität und direkt relevant für die Zielaufgabe sind.
* **Verringern Sie die Batch-Größe auf 1**. Das führt dazu, dass das Modell stärkere Updates durchführt.

{% hint style="success" %}
Finetuning hat keinen einzigen „besten" Ansatz, nur Best Practices. Experimentieren ist der Schlüssel, um zu finden, was für Ihre spezifischen Bedürfnisse funktioniert. Unsere Notebooks setzen automatisch optimale Parameter basierend auf vielen Forschungsarbeiten und unseren Experimenten, was Ihnen einen großartigen Ausgangspunkt bietet. Viel Erfolg beim Finetuning!
{% endhint %}

***Danksagungen:** Ein riesiges Dankeschön an* [*Eyera*](https://huggingface.co/Orenguteng) *für die Mitarbeit an diesem Leitfaden!*
