# Visuelles Reinforcement Learning (VLM RL)

Unsloth unterstützt jetzt Vision/Multimodal-RL mit [Qwen3-VL](https://unsloth.ai/docs/de/modelle/tutorials/qwen3-how-to-run-and-fine-tune/qwen3-vl-how-to-run-and-fine-tune), [Gemma 3](https://unsloth.ai/docs/de/modelle/tutorials/gemma-3-how-to-run-and-fine-tune) und mehr. Aufgrund von Unsloths einzigartigem [Gewichtsteilung](https://unsloth.ai/docs/de/los-gehts/reinforcement-learning-rl-guide/..#what-unsloth-offers-for-rl) und benutzerdefinierten Kernen macht Unsloth VLM-RL **1,5–2× schneller,** verwendet **90 % weniger VRAM**und ermöglicht **15× längere Kontext** längen als FA2-Setups, ohne Genauigkeitsverlust. Dieses Update führt außerdem Qwens [GSPO](#gspo-rl) Algorithmus.

Unsloth kann Qwen3-VL-8B mit GSPO/GRPO auf einer kostenlosen Colab T4 GPU trainieren. Andere VLMs funktionieren ebenfalls, benötigen aber möglicherweise größere GPUs. Gemma erfordert neuere GPUs als T4, weil vLLM [auf Bfloat16 beschränkt](https://unsloth.ai/docs/de/modelle/tutorials/gemma-3-how-to-run-and-fine-tune#unsloth-fine-tuning-fixes), daher empfehlen wir NVIDIA L4 auf Colab. Unsere Notebooks lösen numerische Mathematikaufgaben mit Bildern und Diagrammen:

* **Qwen-3 VL-8B** (vLLM-Inferenz)**:** [Colab](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_VL_\(8B\)-Vision-GRPO.ipynb)
* **Qwen-2.5 VL-7B** (vLLM-Inferenz)**:** [Colab](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen2_5_7B_VL_GRPO.ipynb) •[ Kaggle](https://www.kaggle.com/notebooks/welcome?src=https://github.com/unslothai/notebooks/blob/main/nb/Kaggle-Qwen2_5_7B_VL_GRPO.ipynb\&accelerator=nvidiaTeslaT4)
* **Gemma-3-4B** (Unsloth-Inferenz): [Colab](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3_\(4B\)-Vision-GRPO.ipynb)

Wir haben vLLM-VLM-Integration außerdem nativ in Unsloth hinzugefügt, sodass Sie für die Verwendung der vLLM-Inferenz nur das `fast_inference=True` Flag beim Initialisieren des Modells aktivieren müssen. Besonderer Dank an [Sinoué GAD](https://github.com/unslothai/unsloth/pull/2752) für die Bereitstellung des [ersten Notebooks](https://github.com/GAD-cell/vlm-grpo/blob/main/examples/VLM_GRPO_basic_example.ipynb) das die Integration von VLM-RL erleichtert hat!

Diese VLM-Unterstützung integriert auch unser neuestes Update für noch speichereffizienteres und schnelleres RL einschließlich unserer [Standby-Funktion](https://unsloth.ai/docs/de/los-gehts/memory-efficient-rl#unsloth-standby), die im Vergleich zu anderen Implementierungen einzigartig die Geschwindigkeitsverschlechterung begrenzt.

{% hint style="info" %}
Sie können nur `fast_inference` für VLMs verwenden, die von vLLM unterstützt werden. Einige Modelle, wie Llama 3.2 Vision, können daher nur ohne vLLM laufen, funktionieren aber trotzdem in Unsloth.
{% endhint %}

```python
os.environ['UNSLOTH_VLLM_STANDBY'] = '1' # Um speichereffizientes GRPO mit vLLM zu aktivieren
model, tokenizer = FastVisionModel.from_pretrained(
    model_name = "Qwen/Qwen2.5-VL-7B-Instruct",
    max_seq_length = 16384, # Muss so groß sein, um das Bild im Kontext unterzubringen
    load_in_4bit = True, # False für LoRA 16bit
    fast_inference = True, # vLLM Fast-Inferenz aktivieren
    gpu_memory_utilization = 0.8, # Reduzieren, wenn kein Speicher verfügbar ist
)
```

Es ist auch wichtig zu beachten, dass vLLM LoRA für Vision-/Encoder-Schichten nicht unterstützt, setzen Sie daher `finetune_vision_layers = False` beim Laden eines LoRA-Adapters.\
Sie KÖNNEN jedoch die Vision-Schichten ebenfalls trainieren, wenn Sie Inferenz über transformers/Unsloth verwenden.

```python
# Fügen Sie dem Modell einen LoRA-Adapter für parameter-effizientes Fine-Tuning hinzu
model = FastVisionModel.get_peft_model(
    model,

    finetune_vision_layers     = False,# fast_inference unterstützt finetune_vision_layers noch nicht :(
    finetune_language_layers   = True, # False, wenn die Sprachschichten nicht feinabgestimmt werden
    finetune_attention_modules = True, # False, wenn die Attention-Schichten nicht feinabgestimmt werden
    finetune_mlp_modules       = True, # False, wenn die MLP-Schichten nicht feinabgestimmt werden

    r = lora_rank, # Wählen Sie eine beliebige Zahl > 0! Vorgeschlagen 8, 16, 32, 64, 128
    lora_alpha = lora_rank*2, # *2 beschleunigt das Training
    use_gradient_checkpointing = "unsloth", # Reduziert den Speicherverbrauch
    random_state = 3407,
)
```

## :butterfly:Qwen 2.5 VL Vision RL Probleme und Eigenheiten

Während des RL für Qwen 2.5 VL könnten Sie die folgende Inferenz-Ausgabe sehen:

{% code overflow="wrap" %}

```
 addCriterion
 <tool_call>\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n\n addCriterion\n\n 自动生成\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n\n addCriterion\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
```

{% endcode %}

Dies wurde [berichtet](https://github.com/QwenLM/Qwen2.5-VL/issues/759) ebenfalls im Qwen2.5-VL-7B-Instruct-Ausgabe unerwartete Ergebnisse "addCriterion". Tatsächlich sehen wir dies auch! Wir haben sowohl Nicht-Unsloth-, bfloat16- als auch float16-Maschinen und andere Dinge ausprobiert, aber es scheint weiterhin aufzutreten. Zum Beispiel Element 165, d.h. `train_dataset[165]` aus dem [AI4Math/MathVista](https://huggingface.co/datasets/AI4Math/MathVista) Datensatz ist unten:

{% code overflow="wrap" %}

```
Die Abbildung ist eine Draufsicht auf die von einem Rennfahrer zurückgelegte Strecke, als sein Auto mit der Streckenbegrenzung kollidiert. Kurz vor der Kollision bewegt er sich mit der Geschwindigkeit v_i=70 m/s entlang einer Geraden in einem Winkel von 30° zur Wand. Kurz nach der Kollision bewegt er sich mit der Geschwindigkeit v_f=50 m/s entlang einer Geraden in einem Winkel von 10° zur Wand. Seine Masse m beträgt 80 kg. Die Kollision dauert 14 ms. Wie groß ist die Magnitude der durchschnittlichen Kraft auf den Fahrer während der Kollision?
```

{% endcode %}

<figure><img src="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-61a659529171fcc10ed6398a15912b21d6b1a076%2FUntitled.png?alt=media" alt="" width="128"><figcaption></figcaption></figure>

Und dann erhalten wir die oben genannten Wirrwar-Ausgaben. Man könnte eine Belohnungsfunktion hinzufügen, um das Hinzufügen von addCriterion zu bestrafen oder wirre Ausgaben zu bestrafen. Die andere Vorgehensweise ist jedoch, länger zu trainieren. Zum Beispiel sehen wir erst nach ungefähr 60 Schritten, dass das Modell tatsächlich durch RL lernt:

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

{% hint style="success" %}
Erzwingung von `<|assistant|>` während der Generierung wird das Auftreten dieser wirren Ergebnisse wie erwartet reduzieren, da dies ein Instruct-Modell ist; dennoch ist es am besten, eine Belohnungsfunktion hinzuzufügen, um schlechte Generierungen zu bestrafen, wie im nächsten Abschnitt beschrieben.
{% endhint %}

## :medal:Belohnungsfunktionen zur Reduzierung von Wirrwarr

Um `addCriterion` und wirre Ausgaben zu bestrafen, haben wir die Belohnungsfunktion so angepasst, dass zu viel von `addCriterion` und Zeilenumbrüchen bestraft wird.

```python
def formatting_reward_func(completions,**kwargs):
    import re
    thinking_pattern = f'{REASONING_START}(.*?){REASONING_END}'
    answer_pattern = f'{SOLUTION_START}(.*?){SOLUTION_END}'

    scores = []
    for completion in completions:
        score = 0
        thinking_matches = re.findall(thinking_pattern, completion, re.DOTALL)
        answer_matches = re.findall(answer_pattern, completion, re.DOTALL)
        if len(thinking_matches) == 1:
            score += 1.0
        if len(answer_matches) == 1:
            score += 1.0

        # Beheben von addCriterion-Problemen
        # Siehe https://docs.unsloth.ai/new/vision-reinforcement-learning-vlm-rl#qwen-2.5-vl-vision-rl-issues-and-quirks
        # Bestrafe übermäßiges addCriterion und Zeilenumbrüche
        if len(completion) != 0:
            removal = completion.replace("addCriterion", "").replace("\n", "")
            if (len(completion)-len(removal))/len(completion) >= 0.5:
                score -= 2.0

        scores.append(score)
    return scores
```

## :checkered\_flag:GSPO Reinforcement Learning

Dieses Update fügt zusätzlich GSPO ([Group Sequence Policy Optimization](https://arxiv.org/abs/2507.18071)) hinzu, eine Variante von GRPO, entwickelt vom Qwen-Team bei Alibaba. Sie stellten fest, dass GRPO implizit Wichtigkeitsgewichte für jedes Token erzeugt, obwohl die expliziten Vorteile nicht mit jedem Token skalieren oder sich ändern.

Dies führte zur Erstellung von GSPO, das nun die Wichtigkeit auf die Sequenzwahrscheinlichkeit anstatt auf die Einzel-Token-Wahrscheinlichkeiten der Tokens zuweist. Der Unterschied zwischen diesen beiden Algorithmen ist unten zu sehen, sowohl aus dem GSPO-Papier von Qwen und Alibaba:

<figure><img src="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-45d743dd5dcd590626777ce09cfab61808aa8c24%2Fimage.png?alt=media" alt="" width="563"><figcaption><p>GRPO-Algorithmus, Quelle: <a href="https://arxiv.org/abs/2507.18071">Qwen</a></p></figcaption></figure>

<figure><img src="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-ee755850cbe17482ce240dde227d55c62e9a3e64%2Fimage.png?alt=media" alt="" width="563"><figcaption><p>GSPO-Algorithmus, Quelle: <a href="https://arxiv.org/abs/2507.18071">Qwen</a></p></figcaption></figure>

In Gleichung 1 ist zu sehen, dass die Vorteile jede der Zeilen in die Token-Logprobs skalieren, bevor dieser Tensor summiert wird. Im Wesentlichen erhält jedes Token dieselbe Skalierung, obwohl diese Skalierung der gesamten Sequenz und nicht jedem einzelnen Token gegeben wurde. Ein einfaches Diagramm dazu ist unten zu sehen:

<figure><img src="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-b3c944808a15dde0a7ff45782f9f074993304bf1%2FCopy%20of%20GSPO%20diagram%20(1).jpg?alt=media" alt="" width="286"><figcaption><p>GRPO Logprob-Verhältnis zeilenweise mit Vorteilen skaliert</p></figcaption></figure>

Gleichung 2 zeigt, dass die Logprob-Verhältnisse für jede Sequenz summiert und nach der Berechnung der Logprob-Verhältnisse exponiert werden und nur die resultierenden nun Sequenz-Verhältnisse zeilenweise mit den Vorteilen multipliziert werden.

<figure><img src="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-62fc5b50921e79cce155d2794201c9b96faf941e%2FGSPO%20diagram%20(1).jpg?alt=media" alt="" width="313"><figcaption><p>GSPO Sequenz-Verhältnis zeilenweise mit Vorteilen skaliert</p></figcaption></figure>

GSPO zu aktivieren ist einfach, alles, was Sie tun müssen, ist das `importance_sampling_level = "sequence"` Flag in der GRPO-Konfiguration zu setzen.

```python
training_args = GRPOConfig(
    output_dir = "vlm-grpo-unsloth",
    per_device_train_batch_size = 8,
    gradient_accumulation_steps = 4,
    learning_rate = 5e-6,
    adam_beta1 = 0.9,
    adam_beta2 = 0.99,
    weight_decay = 0.1,
    warmup_ratio = 0.1,
    lr_scheduler_type = "cosine",
    optim = "adamw_8bit",
    # beta = 0.00,
    epsilon = 3e-4,
    epsilon_high = 4e-4,
    num_generations = 8,    
    max_prompt_length = 1024,
    max_completion_length = 1024,
    log_completions = False,
    max_grad_norm = 0.1,
    temperature = 0.9,
    # report_to = "none", # Auf "wandb" setzen, wenn Sie zu Weights & Biases protokollieren möchten
    num_train_epochs = 2, # Für einen schnellen Testlauf, für vollständiges Training erhöhen
    report_to = "none"
    
    # GSPO ist unten:
    importance_sampling_level = "sequence",
    
    # Dr GRPO / GAPO etc
    loss_type = "dr_grpo",
)
```

Insgesamt ermöglicht Unsloth jetzt mit VLM vLLM Fast-Inferenz sowohl eine um 90 % reduzierte Speichernutzung als auch eine um 1,5–2× höhere Geschwindigkeit mit GRPO und GSPO!

Wenn Sie mehr über Reinforcement Learning lesen möchten, schauen Sie sich unseren RL-Leitfaden an:

[](https://unsloth.ai/docs/de/los-gehts/reinforcement-learning-rl-guide "mention")

***Autoren:** Ein großer Dank an* [*Keith*](https://www.linkedin.com/in/keith-truongcao-7bb84a23b/) *und* [*Datta*](https://www.linkedin.com/in/datta0/) *für seinen Beitrag zu diesem Artikel!*
