# Gemma 4 Leitfaden zur Feinabstimmung

Du kannst jetzt Googles [Gemma 4](/docs/de/modelle/qwen3.5.md) E2B, E4B, 26B-A4B und 31B mit [**Unsloth**](https://github.com/unslothai/unsloth). Unsloth unterstützt alle Vision-, Text-, Audio- und RL-Fine-Tuning-Verfahren für Gemma 4.

* Unsloth trainiert Gemma 4 **\~1,5x schneller** mit **\~60 % weniger VRAM** als FA2-Setups (kein Genauigkeitsverlust)
* Wir haben viele universelle [Fehler beim Training von Gemma 4 behoben](#bug-fixes--tips) (nicht von Unsloth abgeleitet).
* Gemma 4 E2B trainiert mit **8 GB VRAM**. E4B benötigt 10 GB VRAM.

<a href="/pages/6b0583a8449166f2d11877ed16e0b6c150d61586#quickstart" class="button primary" data-icon="bolt">Schnellstart</a><a href="/pages/6b0583a8449166f2d11877ed16e0b6c150d61586#bug-fixes--tips" class="button secondary" data-icon="sparkle">Fehlerbehebungen + Tipps</a>

Gemma 4 feinabstimmen über unsere **kostenlosen** **Google Colab-Notebooks**:

| [**E4B + E2B** (Studio)](https://colab.research.google.com/github/unslothai/unsloth/blob/main/studio/Unsloth_Studio_Colab.ipynb) | [**31B** (Kaggle)](https://www.kaggle.com/code/danielhanchen/gemma4-31b-unsloth) | [E4B **(Vision + Text)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Vision.ipynb) | [E4B **(Audio)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Audio.ipynb) | [E2B **(RL GRPO)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)_Reinforcement_Learning_Sudoku_Game.ipynb) |
| -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |

{% columns %}
{% column %}
Du kannst Gemma 4 kostenlos mit einer UI in unserem ausführen und trainieren [Unsloth Studio](/docs/de/neu/studio.md)✨ Notebook:

Du kannst weitere [Notebooks hier ansehen](#unsloth-core-code-based-guide).
{% endcolumn %}

{% column %}
{% embed url="<https://colab.research.google.com/github/unslothai/unsloth/blob/main/studio/Unsloth_Studio_Colab.ipynb>" %}
{% endcolumn %}
{% endcolumns %}

* Du kannst Gemma 4 auch mit [bestärkendem Lernen](#reinforcement-learning-rl) (RL) auf 9 GB VRAM trainieren.
* Gemma 4 E2B LoRA funktioniert mit 8–10 GB VRAM. E4B LoRA benötigt 17 GB VRAM.
* **31B QLoRA funktioniert mit 22 GB** und 26B-A4B LoRA benötigt >40 GB
* **Exportieren**/Speichern von Modellen nach GGUF usw. und die vollständiges Fine-Tuning **(FFT)** funktioniert ebenfalls.

### :bug: Fehlerbehebungen + Tipps

{% hint style="success" %}
Wenn du siehst **dass Gemma-4 E2B und E4B einen Loss von 13–15 haben, ist das völlig normal** - das ist eine häufige Eigenart multimodaler Modelle. Das passierte auch bei Gemma-3N, Llama-Vision, Mistral-Vision-Modellen und mehr.

**Gemma 26B und 31B haben einen niedrigeren Loss von 1–3 oder weniger. Vision ist 2x höher, also 3–5**
{% endhint %}

#### :grapes:Gradient Accumulation kann deine Loss-Werte erhöhen

{% columns %}
{% column %}

<div data-with-frame="true"><figure><img src="/files/26f9d908d783b715a05532fb1e01cfdd4462c096" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}

{% column %}

<div data-with-frame="true"><figure><img src="/files/e4bf22cd4b4121411c7d8ce3bc3c5fa52995ce6b" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}
{% endcolumns %}

Wenn du Loss-Werte höher als 13–15 siehst (wie 100 oder 300), wird Gradient Accumulation höchstwahrscheinlich nicht korrekt berücksichtigt - wir haben **das als Teil von Unsloth und Unsloth Studio behoben.**

Um mehr über Gradient Accumulation zu lesen, siehe unseren Blog zur Behebung des Gradient-Accumulation-Fehlers: <https://unsloth.ai/blog/gradient>

#### :interrobang:IndexError bei der Inferenz von Gemma-4 31B und 26B-A4B

Du könntest diesen Fehler bei der Inferenz mit 31B und 26B sehen:

```python
Datei "/.../cache_utils.py", Zeile 937, in update
    keys, values = self.layers[layer_idx].update(...)
IndexError: list index out of range
```

Der Übeltäter ist unten:

```python
if hasattr(decoder_config, "num_kv_shared_layers"):
    layer_types = layer_types[: -decoder_config.num_kv_shared_layers]
```

Dabei werden Gemma-4 31B und 26B-A4B mit `num_kv_shared_layers = 0`. In Python, `-0 == 0`, also `layer_types[:-0]` vereinfacht sich zu `layer_types[:0] == []`. Der Cache wird mit null Layer-Slots aufgebaut und der allererste Attention-Forward bricht in `Cache.update`.

#### :no\_entry: `use_cache = True` war die Generierung für E2B, E4B Kauderwelsch

[Siehe Issue](https://github.com/huggingface/transformers/issues/45242) "\[Gemma 4] `use_cache=False` verfälscht die Attention-Berechnung und erzeugt Müll-Logits #45242"

Gemma-4 E2B und E4B teilen sich den KV-Zustand über die Layer hinweg (`num_kv_shared_layers = 20` und die `18`). Der Cache ist der einzige Ort, an dem frühe Layer KV für spätere Layer ablegen, damit sie sie wiederverwenden können. Wenn `use_cache=False` (wie es jedes QLoRA-Tutorial festlegt, und wie `gradient_checkpointing=True` erzwingt), `Gemma4TextModel.forward` überspringt den Cache-Aufbau, sodass die KV-geteilten Layer stattdessen K und V lokal aus den aktuellen Hidden States neu berechnen. Die Logits werden Müll und der Training-Loss divergiert.

**Vorher (`unsloth/gemma-4-E2B-it`, Prompt "Was ist 1+1?"ահանգ**

```
use_cache=True  -> '1 + 1 = **2**'
use_cache=False -> 'BROAD\肯. Specificallyboard K supposed\_n통  \'
max_abs_logit_diff: 48.937500
```

**Nach unserem Fix:**

```
use_cache=True  -> '1 + 1 = **2**'
use_cache=False -> '1 + 1 = **2**'
max_abs_logit_diff: 0.000000     (bitgenaue Übereinstimmung, alle 9 Tokens identisch)
```

#### :radio:Audio-Float16-Überlauf

`Gemma4AudioAttention` verwendet `config.attention_invalid_logits_value = -1e9` in einem `masked_fill` Aufruf. Bei fp16 (Tesla T4) überschreitet -1e9 den fp16-Maximalwert von 65504 und verursacht:

```python
RuntimeError: value cannot be converted to type c10::Half without overflow
```

Dies lag an `self.config.attention_invalid_logits_value` :

```python
attn_weights = attn_weights.masked_fill(
    attention_mask.logical_not(), self.config.attention_invalid_logits_value
)
```

#### 💡Tipps für Gemma-4

1. Wenn du **Schlussfolgerungsfähigkeit** bewahren möchtest, kannst du Beispiele im Denkstil mit direkten Antworten mischen (halte mindestens 75 % Schlussfolgerung). Andernfalls kannst du es vollständig ausgeben.\
   \
   Verwende `gemma-4` für die Chat-Vorlage ohne Denken und `gemma-4-thinking` für die Denk-Variante.\
   Verwende die Denk-Variante für die größeren 26B- und 31B-Modelle und die Variante ohne Denken für die kleinen Modelle.<br>

   ```python
   from unsloth.chat_templates import get_chat_template
   tokenizer = get_chat_template(
       tokenizer,
       chat_template = "gemma-4-thinking", # Oder "gemma-4"
   )
   ```
2. Um den Denkmodus zu aktivieren, verwende `enable_thinking = True / False` in `tokenizer.apply_chat_template`<br>

   Denken aktiviert:

   <pre class="language-python" data-overflow="wrap"><code class="lang-python">processor.tokenizer.apply_chat_template([
       {"role" : "user", "content" : "Was ist 2+2?"},
   ], tokenize = False, enable_thinking = True, add_generation_prompt = True)
   </code></pre>

   Wird ausgeben `<bos><|turn>system\n<|think|><turn|>\n<|turn>user\nWas ist 2+2?<turn|>\n<|turn>model\n`<br>

   Denken deaktiviert:

   ```python
   processor.tokenizer.apply_chat_template([
       {"role" : "user", "content" : "Was ist 2+2?"},
   ], tokenize = False, enable_thinking = False, add_generation_prompt = True)
   ```

   Wird ausgeben `<bos><|turn>user\nWas ist 2+2?<turn|>\n<|turn>model\n<|channel>thought\n<channel|>`
3. Gemma 4 ist leistungsstark für mehrsprachiges Fine-Tuning, da es 140 Sprachen unterstützt.
4. Es wird empfohlen, **E4B QLoRA** statt **E2B LoRA** zu trainieren, da E4B größer ist und der Unterschied in der Quantisierungsgenauigkeit minimal ist. Gemma 4 E4B LoRA ist sogar besser.
5. Nach dem Fine-Tuning kannst du nach [GGUF](#saving-export-your-fine-tuned-model) exportieren

### ⚡Schnellstart

#### 🦥 Unsloth Studio-Anleitung

{% columns %}
{% column %}
Gemma 4 kann ausgeführt und feinabgestimmt werden in [Unsloth Studio](/docs/de/neu/studio.md), unserer neuen Open-Source-Web-UI für lokale KI.

Mit Unsloth Studio kannst du Modelle lokal ausführen auf **MacOS, Windows**, Linux und NVIDIA-GPUs trainieren. Unterstützung für Intel-, MLX- und AMD-Training kommt noch diesen Monat.
{% endcolumn %}

{% column %}

<div data-with-frame="true"><figure><img src="/files/71ea705f5a8352a564fa5aee8cc93a59fe40d4d1" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}
{% endcolumns %}

{% stepper %}
{% step %}

#### Unsloth installieren

Führe im Terminal aus:

**MacOS, Linux, WSL:**

```bash
curl -fsSL https://unsloth.ai/install.sh | sh
```

**Windows PowerShell:**

```bash
irm https://unsloth.ai/install.ps1 | iex
```

{% hint style="success" %}
**Die Installation wird schnell gehen und ca. 1–2 Minuten dauern.**
{% endhint %}
{% endstep %}

{% step %}

#### Unsloth starten

**MacOS, Linux, WSL und Windows:**

```bash
unsloth studio -H 0.0.0.0 -p 8888
```

**Dann öffne `http://localhost:8888` in deinem Browser.**
{% endstep %}

{% step %}

#### Gemma 4 trainieren

Beim ersten Start musst du ein Passwort erstellen, um dein Konto zu sichern, und dich später erneut anmelden. Danach siehst du einen kurzen Einrichtungsassistenten, um ein Modell, einen Datensatz und grundlegende Einstellungen auszuwählen. Du kannst ihn jederzeit überspringen.

Suche in der Suchleiste nach Gemma 4 und wähle dein gewünschtes Modell und deinen Datensatz aus. Passe als Nächstes deine Hyperparameter und die Kontextlänge nach Wunsch an.

<div data-with-frame="true"><figure><img src="/files/71ea705f5a8352a564fa5aee8cc93a59fe40d4d1" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### Trainingsfortschritt überwachen

Nachdem du auf Training starten geklickt hast, kannst du den Trainingsfortschritt des Modells überwachen und beobachten. Der Trainingsverlust sollte stetig sinken.\
Sobald fertig, wird das Modell automatisch gespeichert.

<div data-with-frame="true"><figure><img src="/files/541c693a5ea8e874e3ffaac3c79009dea65c4bec" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### Dein feinabgestimmtes Modell exportieren

Sobald fertig, ermöglicht Unsloth Studio den Export des Modells in GGUF-, Safetensor- usw. Formate.

<div data-with-frame="true"><figure><img src="/files/34240fd630200fb7af0fe34b85da8a54713c65e5" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### Feinabgestimmtes Modell mit Originalmodell vergleichen

Klicke auf `Vergleichsmodus` um den LoRA-Adapter und das Originalmodell zu vergleichen.

<div data-with-frame="true"><figure><img src="/files/eaa0a63123410343a3c152dbd0f4f37cd4239bb4" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}
{% endstepper %}

#### 🦥 Unsloth Core (codebasiert) Anleitung

Wir haben kostenlose Notebooks für Gemma 4 erstellt:

| [E4B **(Inferenz + Text)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Text.ipynb) | [E4B **(Vision + Text)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Vision.ipynb) | [E4B **(Audio)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Audio.ipynb) |
| -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| [**31B** (Kaggle)](https://www.kaggle.com/code/danielhanchen/gemma4-31b-unsloth)                                                 | [E2B **(Vision + Text)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)-Vision.ipynb) | [E2B **(Audio)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)-Audio.ipynb) |

Und für bestärkendes Lernen (RL): [E2B **(RL GRPO)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)_Reinforcement_Learning_Sudoku_Game.ipynb)

Wir haben auch Notebooks für die größeren Gemma-4-Modelle erstellt, aber diese benötigen A100:

| [Gemma-4-26B-A4B](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(26B_A4B\)-Vision.ipynb) - A100 GPU | [Gemma-4-31B](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(31B\)-Vision.ipynb) - A100 GPU |
| --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |

{% hint style="info" %}
**Wenn du** [**GRPO**](/docs/de/loslegen/reinforcement-learning-rl-guide.md)**möchtest, funktioniert es in Unsloth, wenn du die schnelle vLLM-Inferenz deaktivierst und stattdessen die Unsloth-Inferenz verwendest. Folge unseren** [**Vision-RL**](/docs/de/loslegen/reinforcement-learning-rl-guide/vision-reinforcement-learning-vlm-rl.md) **Notebook-Beispielen.**
{% endhint %}

Unten ist ein eigenständiges Gemma-4-26B-A4B-it-Text-SFT-Rezept. Dies ist nur Text - siehe auch unseren [Bereich zum Vision-Fine-Tuning](/docs/de/grundlagen/vision-fine-tuning.md) für weitere Details.

{% code expandable="true" %}

````python
from unsloth import FastModel
import torch

model, tokenizer = FastModel.from_pretrained(
    model_name = "unsloth/gemma-4-26B-A4B-it", # Ändere dies zu unsloth/gemma-4-E2B-it usw.
    dtype = None, # None für automatische Erkennung
    max_seq_length = 8192, # Wähle einen beliebigen Wert für langen Kontext!
    load_in_4bit = True,  # 4-Bit-Quantisierung zur Reduzierung des Speicherbedarfs
    full_finetuning = False, # [NEU!] Wir haben jetzt vollständiges Fine-Tuning!
    # token = "YOUR_HF_TOKEN", # HF-Token für geschützte Modelle
)

"""# Gemma 4 kann Text, Vision und Audio verarbeiten!

Lass uns zuerst erleben, wie Gemma 4 multimodale Eingaben verarbeiten kann. Wir verwenden die empfohlenen Einstellungen von Gemma 4: `temperature = 1.0, top_p = 0.95, top_k = 64`
"""

from transformers import TextStreamer
# Hilfsfunktion für die Inferenz
def do_gemma_4_inference(messages, max_new_tokens = 128):
    _ = model.generate(
        **tokenizer.apply_chat_template(
            messages,
            add_generation_prompt = True, # Muss für die Generierung hinzugefügt werden
            tokenize = True,
            return_dict = True,
            return_tensors = "pt",
        ).to("cuda"),
        max_new_tokens = max_new_tokens,
        use_cache=True,
        temperature = 1.0, top_p = 0.95, top_k = 64,
        streamer = TextStreamer(tokenizer, skip_prompt = True),
    )

"""# Gemma 4 kann Bilder sehen!

<img src="https://files.worldwildlife.org/wwfcmsprod/images/Sloth_Sitting_iStock_3_12_2014/story_full_width/8l7pbjmj29_iStock_000011145477Large_mini__1_.jpg" alt="Alt-Text" height="256">
"""

sloth_link = "https://files.worldwildlife.org/wwfcmsprod/images/Sloth_Sitting_iStock_3_12_2014/story_full_width/8l7pbjmj29_iStock_000011145477Large_mini__1_.jpg"

messages = [{
    "role" : "user",
    "content": [
        { "type": "image", "image" : sloth_link },
        { "type": "text",  "text" : "In welchen Filmen ist dieses Tier zu sehen?" }
    ]
}]
# Du musst möglicherweise 1 Minute auf den Auto-Compiler von Unsloth warten
do_gemma_4_inference(messages, max_new_tokens = 256)

"""Lass uns ein Gedicht über Faultiere machen!"""

messages = [{
    "role": "user",
    "content": [{ "type" : "text",
                  "text" : "Schreibe ein Gedicht über Faultiere." }]
}]
do_gemma_4_inference(messages)

"""# Lass uns Gemma 4 feinabstimmen!

Du kannst die Vision- und Textteile vorerst per Auswahl feinabstimmen - der Audio-Teil kann ebenfalls feinabgestimmt werden - wir arbeiten daran, ihn ebenfalls auswählbar zu machen!

Wir fügen jetzt LoRA-Adapter hinzu, damit wir nur eine kleine Anzahl von Parametern aktualisieren müssen!
"""

model = FastModel.get_peft_model(
    model,
    finetune_vision_layers     = False, # Ausschalten, wenn nur Text!
    finetune_language_layers   = True,  # Sollte aktiviert bleiben!
    finetune_attention_modules = True,  # Attention gut für GRPO
    finetune_mlp_modules       = True,  # Sollte immer aktiviert bleiben!

    r = 8,           # Größer = höhere Genauigkeit, kann aber überfitten
    lora_alpha = 8,  # Empfohlenes alpha == mindestens r
    lora_dropout = 0,
    bias = "none",
    random_state = 3407,
)

"""<a name="Data"></a>
### Datenaufbereitung
Wir verwenden jetzt das `Gemma-4`-Format für Konversations-Fine-Tunes. Wir verwenden den Datensatz [FineTome-100k von Maxime Labonne](https://huggingface.co/datasets/mlabonne/FineTome-100k) im ShareGPT-Stil. Gemma-4 stellt mehrteilige Konversationen wie unten dar:

```
<bos><|turn>user
Hallo<turn|>
<|turn>model
Hallo!<turn|>
```
Wir verwenden unsere Funktion `get_chat_template`, um die richtige Chat-Vorlage zu erhalten. Wir unterstützen `zephyr, chatml, mistral, llama, alpaca, vicuna, vicuna_old, phi3, llama3, phi4, qwen2.5, gemma3, gemma-4` und mehr.
"""

from unsloth.chat_templates import get_chat_template
tokenizer = get_chat_template(
    tokenizer,
    chat_template = "gemma-4-thinking",
)

"""Wir nehmen die ersten 3000 Zeilen des Datensatzes"""

from datasets import load_dataset
dataset = load_dataset("mlabonne/FineTome-100k", split = "train[:3000]")

"""Wir verwenden jetzt `standardize_data_formats`, um Datensätze für Fine-Tuning-Zwecke in das richtige Format zu überführen!"""

from unsloth.chat_templates import standardize_data_formats
dataset = standardize_data_formats(dataset)

"""Schauen wir uns an, wie Zeile 100 aussieht!"""

dataset[100]

"""Wir müssen jetzt die Chat-Vorlage für `Gemma-3` auf die Konversationen anwenden und sie in `text` speichern. Wir entfernen das `<bos>`-Token mit removeprefix(`'<bos>'`), da wir ein Fine-Tuning durchführen. Der Processor wird dieses Token vor dem Training hinzufügen und das Modell erwartet nur eines."""

def formatting_prompts_func(examples):
   convos = examples["conversations"]
   texts = [tokenizer.apply_chat_template(convo, tokenize = False, add_generation_prompt = False).removeprefix('<bos>') for convo in convos]
   return { "text" : texts, }

dataset = dataset.map(formatting_prompts_func, batched = True)

"""Schauen wir uns an, wie die Chat-Vorlage funktioniert hat! Beachte, dass kein `<bos>`-Token vorhanden ist, da der Processor-Tokenizer eines hinzufügen wird."""

dataset[100]["text"]

"""<a name="Train"></a>
### Modell trainieren
Jetzt trainieren wir unser Modell. Wir machen 60 Schritte, um die Sache zu beschleunigen, aber du kannst `num_train_epochs=1` für einen vollständigen Durchlauf setzen und `max_steps=None` deaktivieren.
"""

from trl import SFTTrainer, SFTConfig
trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = dataset,
    eval_dataset = None, # Bewertung kann eingerichtet werden!
    args = SFTConfig(
        dataset_text_field = "text",
        per_device_train_batch_size = 1,
        gradient_accumulation_steps = 4, # Verwende GA, um die Batchgröße zu imitieren!
        warmup_steps = 5,
        # num_train_epochs = 1, # Dies für einen vollständigen Trainingslauf setzen.
        max_steps = 60,
        learning_rate = 2e-4, # Für lange Trainingsläufe auf 2e-5 reduzieren
        logging_steps = 1,
        optim = "adamw_8bit",
        weight_decay = 0.001,
        lr_scheduler_type = "linear",
        seed = 3407,
        report_to = "none", # Verwende TrackIO/WandB usw.
    ),
)

"""Wir verwenden auch Unsloths Methode `train_on_completions`, um nur auf den Ausgaben des Assistenten zu trainieren und den Loss auf die Eingaben des Benutzers zu ignorieren. Das hilft, die Genauigkeit von Fine-Tunes zu erhöhen!"""

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

"""Lass uns überprüfen, ob das Maskieren des Instruktionsteils funktioniert! Lassen Sie uns die 100. Zeile erneut ausgeben. Beachte, dass das Beispiel wie erwartet nur ein einziges `<bos>` enthält!"""

tokenizer.decode(trainer.train_dataset[100]["input_ids"])

"""Lass uns jetzt das maskierte Beispiel ausgeben - du solltest sehen, dass nur die Antwort vorhanden ist:"""

tokenizer.decode([tokenizer.pad_token_id if x == -100 else x for x in trainer.train_dataset[100]["labels"]]).replace(tokenizer.pad_token, " ")

"""# Lass uns das Modell trainieren!

Um einen Trainingslauf fortzusetzen, setze `trainer.train(resume_from_checkpoint = True)`
"""

trainer_stats = trainer.train()
````

{% endcode %}

{% hint style="info" %}
Wenn du OOM bekommst:

* Reduziere `per_device_train_batch_size` auf **1** und/oder reduziere `max_seq_length`.&#x20;
* Lasse `use_`[`gradient_checkpointing`](/docs/de/blog/500k-context-length-fine-tuning.md#unsloth-gradient-checkpointing-enhancements)`="unsloth"` aktiv (es ist dafür gedacht, den VRAM-Verbrauch zu senken und die Kontextlänge zu erweitern).
  {% endhint %}

**Ladebeispiel für MoE (bf16 LoRA):**

```python
import os
import torch
from unsloth import FastModel

model, tokenizer = FastModel.from_pretrained(
    model_name = "unsloth/Gemma-4-26B-A4B-it",
    max_seq_length = 2048,
    load_in_4bit = False,     # MoE QLoRA nicht empfohlen, dichte 31B ist in Ordnung
    load_in_16bit = True,     # bf16/16-Bit LoRA
    full_finetuning = False,
)
```

Nach dem Laden fügst du LoRA-Adapter hinzu und trainierst ähnlich wie im obigen SFT-Beispiel.

### Bestärkendes Lernen (RL)

Du kannst Gemma 4 jetzt mit RL, GSPO, GRPO usw. trainieren mit [unserem kostenlosen Notebook](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_5_\(4B\)_Vision_GRPO.ipynb).

{% columns %}
{% column %}
Gemma 4 E2B RL funktioniert mit 9 GB.

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_5_(4B)_Vision_GRPO.ipynb>" %}

Das Ziel des Notebooks ist es, Gemma 4 beizubringen, Sudoku-Rätsel mit [GRPO](/docs/de/loslegen/reinforcement-learning-rl-guide.md#from-rlhf-ppo-to-grpo-and-rlvr).

Das Modell wird eine Strategie entwickeln, um leere Felder zu füllen, und wir belohnen es für korrekte Platzierungen und das Lösen gültiger Rätsel.

Du kannst Gemma 4 RL mit Unsloth ausführen, auch wenn es von vLLM nicht unterstützt wird, indem du beim Laden des Modells `fast_inference=False` setzt:
{% endcolumn %}

{% column %}

<figure><img src="/files/ceebeb761da09115dfa4ed1cc6acc3367619e1a6" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

```python
from unsloth import FastLanguageModel

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="unsloth/gemma-4-E2B-it",
    fast_inference=False,
)
```

### MoE-Fine-Tuning (26B-A4B)

ist die **26B-A4B** Modell ist der Mittelweg zwischen Geschwindigkeit und Qualität in der Gemma-4-Reihe. Da es ein **MoE** Modell mit nur einem Teil der pro Token aktiven Parameter ist, lautet ein konservativer Fine-Tuning-Ansatz:

* verwende **LoRA** statt vollständigem Fine-Tuning
* bevorzuge **16-Bit / bf16 LoRA** wenn der Speicher es zulässt
* beginne zunächst mit kürzeren Kontexten und kleineren Rängen
* skalieren erst hoch, wenn die Pipeline stabil ist

Wenn dein Ziel die höchste Qualität ist und du mehr Speicher hast, verwende stattdessen **31B** .

### Multimodales Fine-Tuning (E2B / E4B)

Da **E2B** und die **E4B** unterstützen **Bild** und die **Audio**, sind sie die wichtigsten Gemma-4-Varianten für multimodales Fine-Tuning.

* lade das multimodale Modell mit `FastVisionModel`
* behalte `finetune_vision_layers = False` zuerst
* feinabstimme nur die Sprach-, Attention- und MLP-Schichten
* aktiviere Vision- oder Audioschichten später, wenn deine Aufgabe es erfordert

#### Gemma 4 Multimodal LoRA-Beispiel:

{% code expandable="true" %}

````python
from unsloth import FastVisionModel # FastLanguageModel für LLMs
import torch

model, processor = FastVisionModel.from_pretrained(
    "unsloth/gemma-4-26B-A4B-it",
    load_in_4bit = True, # Verwende 4 Bit, um den Speicherverbrauch zu reduzieren. False für 16-Bit LoRA.
    use_gradient_checkpointing = "unsloth", # True oder "unsloth" für langen Kontext
)

"""Wir fügen jetzt LoRA-Adapter für parameter-effizientes Fine-Tuning hinzu, sodass wir nur 1 % aller Modellparameter effizient trainieren können.

**[NEU]** Wir unterstützen auch das Fine-Tuning nur der Vision-Komponente, nur der Sprachkomponente oder beider. Außerdem kannst du wählen, ob du die Attention-Module, die MLP-Schichten oder beides feinabstimmen möchtest!
"""

model = FastVisionModel.get_peft_model(
    model,
    finetune_vision_layers     = True, # False, wenn keine Vision-Schichten feinabgestimmt werden
    finetune_language_layers   = True, # False, wenn keine Sprachschichten feinabgestimmt werden
    finetune_attention_modules = True, # False, wenn keine Attention-Schichten feinabgestimmt werden
    finetune_mlp_modules       = True, # False, wenn keine MLP-Schichten feinabgestimmt werden

    r = 32,                           # Je größer, desto höher die Genauigkeit, kann aber überfitten
    lora_alpha = 32,                  # Empfohlenes alpha == mindestens r
    lora_dropout = 0,
    bias = "none",
    random_state = 3407,
    use_rslora = False,               # Wir unterstützen rank-stabilisiertes LoRA
    loftq_config = None,               # Und LoftQ
    target_modules = "all-linear",    # Jetzt optional! Kann bei Bedarf eine Liste angegeben werden
)

"""<a name="Data"></a>
### Datenaufbereitung
Wir verwenden einen Stichprobensatz handgeschriebener Matheformeln. Das Ziel ist es, diese Bilder in ein maschinenlesbares Format umzuwandeln — konkret LaTeX — damit sie gerendert werden können. Das ist besonders nützlich für komplexe Ausdrücke.

Du kannst auf den Datensatz [hier](https://huggingface.co/datasets/unsloth/LaTeX_OCR) zugreifen. Der vollständige Datensatz ist [hier](https://huggingface.co/datasets/linxy/LaTeX_OCR).
"""

from datasets import load_dataset
dataset = load_dataset("unsloth/LaTeX_OCR", split = "train")

"""Lassen wir uns einen Überblick über den Datensatz verschaffen. Wir betrachten das zweite Bild und die zugehörige Bildunterschrift."""

dataset

dataset[2]["image"]

dataset[2]["text"]

"""Wir können LaTeX auch direkt im Browser rendern!"""

from IPython.display import display, Math, Latex

latex = dataset[3]["text"]
display(Math(latex))

"""Um den Datensatz zu formatieren, sollten alle Vision-Fine-Tuning-Aufgaben diesem Format folgen:

```python
[
    {
        "role": "user",
        "content": [
            {"type": "text", "text": instruction},
            {"type": "image", "image": sample["image"]},
        ],
    },
    {
        "role": "user",
        "content": [
            {"type": "text", "text": instruction},
            {"type": "image", "image": sample["image"]},
        ],
    },
]
```
"""

instruction = "Schreibe die LaTeX-Darstellung für dieses Bild."

def convert_to_conversation(sample):
    conversation = [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": instruction},
                {"type": "image", "image": sample["image"]},
            ],
        },
        {"role": "assistant", "content": [{"type": "text", "text": sample["text"]}]},
    ]
    return {"messages": conversation}
pass

"""Lassen wir den Datensatz in das "richtige" Format für das Fine-Tuning umwandeln:"""

converted_dataset = [convert_to_conversation(sample) for sample in dataset]

"""Das erste Beispiel ist nun wie unten strukturiert:"""

converted_dataset[0]

"""Lass uns die Gemma-4-Instruktions-Chat-Vorlage nehmen und sie in unserem Basismodell verwenden"""

from unsloth import get_chat_template

processor = get_chat_template(
    processor,
    "gemma-4-thinking"
)

"""Bevor wir feinabstimmen, lassen Sie uns die Leistung des Basismodells bewerten. Wir erwarten keine starken Ergebnisse, da es diese Chat-Vorlage noch nie zuvor gesehen hat."""

image = dataset[2]["image"]
instruction = "Schreibe die LaTeX-Darstellung für dieses Bild."

messages = [
    {
        "role": "user",
        "content": [{"type": "image"}, {"type": "text", "text": instruction}],
    }
]
input_text = processor.apply_chat_template(messages, add_generation_prompt = True)
inputs = processor(
    image,
    input_text,
    add_special_tokens = False,
    return_tensors = "pt",
).to("cuda")

from transformers import TextStreamer

text_streamer = TextStreamer(processor, skip_prompt = True)
result = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128,
                        use_cache = True, temperature = 1.0, top_p = 0.95, top_k = 64)

"""Man sieht, dass es absolut schrecklich ist! Es befolgt die Anweisungen überhaupt nicht

<a name="Train"></a>
### Modell trainieren
Jetzt trainieren wir unser Modell. Wir machen 60 Schritte, um die Sache zu beschleunigen, aber du kannst `num_train_epochs=1` für einen vollständigen Lauf setzen und `max_steps=None` deaktivieren. Wir unterstützen außerdem `DPOTrainer` und `GRPOTrainer` für Reinforcement Learning!!

Wir verwenden unseren neuen `UnslothVisionDataCollator`, der uns bei unserem Vision-Finetuning-Setup hilft.
"""

from unsloth.trainer import UnslothVisionDataCollator
from trl import SFTTrainer, SFTConfig

trainer = SFTTrainer(
    model = model,
    train_dataset = converted_dataset,
    processing_class = processor.tokenizer,
    data_collator = UnslothVisionDataCollator(model, processor),
    args = SFTConfig(
        per_device_train_batch_size = 1,
        gradient_accumulation_steps = 4,
        max_grad_norm = 0.3,
        warmup_ratio = 0.03,
        max_steps = 60,
        # num_train_epochs = 2, # Setze dies statt max_steps für vollständige Trainingsläufe
        learning_rate = 2e-4,
        logging_steps = 1,
        save_strategy = "steps",
        optim = "adamw_8bit",
        weight_decay = 0.001,
        lr_scheduler_type = "cosine",
        seed = 3407,
        output_dir = "outputs",
        report_to = "none", # Für Weights and Biases oder andere

        # Du MUSST die folgenden Punkte für Vision-Finetuning angeben:
        remove_unused_columns = False,
        dataset_text_field = "",
        dataset_kwargs = {"skip_prepare_dataset": True},
        max_length = 2048,
    )
)

trainer_stats = trainer.train()
````

{% endcode %}

#### Bildbeispielformat

Merke dir: Bei multimodalen Gemma-4-Prompts musst du das Bild **vor** der Textanweisung platzieren.

{% code expandable="true" %}

```json
{
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "image", "image": "/path/to/image OR object"},
        {"type": "text", "text": "Extrahiere den gesamten Text aus diesem Beleg. Gib Positionen, Gesamtbetrag, Händler und Datum als JSON zurück."}
      ]
    },
    {
      "role": "assistant",
      "content": [
        {"type": "text", "text": "{\"merchant\": \"Beispielgeschäft\", \"total\": \"19.99\"}"}
      ]
    }
  ]
}
```

{% endcode %}

#### Audio-Beispielformat

Audio ist für **E2B / E4B** nur. Halte Clips kurz und auf die Aufgabe zugeschnitten.

{% code expandable="true" %}

```json
{
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "audio", "audio": "/path/to/audio OR object"},
        {"type": "text", "text": "Transkribiere den folgenden Sprachabschnitt auf Englisch in englischen Text. Gib nur die Transkription aus."}
      ]
    },
    {
      "role": "assistant",
      "content": [
        {"type": "text", "text": "Hallo zusammen und willkommen zurück."}
      ]
    }
  ]
}
```

{% endcode %}

### Feinabgestimmtes Modell speichern / exportieren

Du kannst unsere spezifischen Anleitungen für Inferenz / Bereitstellung ansehen für [Unsloth Studio](/docs/de/neu/studio/export.md), [llama.cpp](/docs/de/grundlagen/inference-and-deployment/saving-to-gguf.md), [vLLM](/docs/de/grundlagen/inference-and-deployment/vllm-guide.md), [llama-server](/docs/de/grundlagen/inference-and-deployment/llama-server-and-openai-endpoint.md), [Ollama](/docs/de/grundlagen/inference-and-deployment/saving-to-ollama.md) oder [SGLang](/docs/de/grundlagen/inference-and-deployment/sglang-guide.md).

#### Als GGUF speichern

Unsloth unterstützt das direkte Speichern als GGUF:

```python
model.save_pretrained_gguf("directory", tokenizer, quantization_method = "q4_k_m")
model.save_pretrained_gguf("directory", tokenizer, quantization_method = "q8_0")
model.save_pretrained_gguf("directory", tokenizer, quantization_method = "f16")
```

Oder GGUFs zu Hugging Face hochladen:

```python
model.push_to_hub_gguf("hf_username/directory", tokenizer, quantization_method = "q4_k_m")
model.push_to_hub_gguf("hf_username/directory", tokenizer, quantization_method = "q8_0")
```

Wenn sich das exportierte Modell in einer anderen Laufzeitumgebung schlechter verhält, nennt Unsloth die häufigste Ursache: **falsche Chatvorlage / EOS-Token zur Inferenzzeit** (du musst dieselbe Chatvorlage verwenden, mit der du trainiert hast).

Für weitere Details lies unsere Inferenzanleitungen:

{% columns %}
{% column width="50%" %}
{% content-ref url="/pages/03532de69dfe0230fe5114e809721d8b7dd74ca6" %}
[Inferenz & Bereitstellung](/docs/de/grundlagen/inference-and-deployment.md)
{% endcontent-ref %}

{% content-ref url="/pages/9cfeafb2cc359999e3a7f6ba6ffa5468e4752653" %}
[GGUF & llama.cpp](/docs/de/grundlagen/inference-and-deployment/saving-to-gguf.md)
{% endcontent-ref %}
{% endcolumn %}

{% column width="50%" %}
{% content-ref url="/pages/13c9d0063a9732a68734b74792f3e30153873bf4" %}
[Model Export](/docs/de/neu/studio/export.md)
{% endcontent-ref %}

{% content-ref url="/pages/af094159d1c157db0d9afc00bd98b849fcdb8f0c" %}
[vLLM](/docs/de/grundlagen/inference-and-deployment/vllm-guide.md)
{% endcontent-ref %}
{% endcolumn %}
{% endcolumns %}

### Best Practices für Gemma-4-Daten

Gemma 4 hat einige Formatierungsdetails, die du beachten musst.

#### 1. Verwende standardmäßige Chat-Rollen

Gemma 4 verwendet die Standardrollen:

* `system`
* `user`
* `assistant`

Das bedeutet, dass dein SFT-Datensatz im normalen Chat-Format geschrieben sein sollte und nicht in älteren, Gemma-spezifischen Rollenformaten.

#### 2. Denkmodus ist explizit

Wenn du das Verhalten im Denkstil während SFT beibehalten möchtest:

* halte das Format konsistent
* entscheide, ob du trainieren willst auf **sichtbaren Denkblöcken** oder auf **nur den endgültigen Antworten**
* mache **nicht** mische nicht mehrere inkompatible Denkformate im selben Datensatz

Für die meisten produktiven Assistenten ist die einfachste Einrichtung, auf den **nur endgültig sichtbaren Antworttext**.

#### 3. Regel für mehrere Gesprächsrunden

Für mehrstufige Gespräche behalte nur die **endgültig sichtbare Antwort** im Gesprächsverlauf. Füge **nicht** frühere Denkblöcke nicht wieder in spätere Runden ein.


---

# 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/de/modelle/gemma-4/train.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.
