# Erweiterte Dokumentation zu Reinforcement Learning

Detaillierte Anleitungen zum Durchführen von GRPO mit Unsloth für Batch-Verarbeitung, Generierung & Trainingsparameter:

## Trainingsparameter

* **`beta`** *(float, Standard 0.0)*: KL-Koeffizient.
  * `0.0` ⇒ kein Referenzmodell geladen (geringerer Speicherbedarf, schneller).
  * Höher `beta` schränkt die Policy stärker ein, sich näher an der Referenzpolicy zu halten.
* **`num_iterations`** *(int, Standard 1)*: PPO-Epochen pro Batch (μ im Algorithmus).\
  Wiederholt Daten innerhalb jedes Gradient-Accumulation-Schritts; z. B., `2` = zwei Vorwärtsdurchläufe pro Accumulation-Schritt.
* **`epsilon`** *(float, Standard 0.2)*: Clipping-Wert für token‑level Log‑Wahrscheinlichkeitsverhältnisse (typischer Verhältnissbereich ≈ \[-1.2, 1.2] mit Standard-ε).
* **`delta`** *(float, optional)*: Aktiviert **oberes** Clipping-Grenze für **zweiseitiges GRPO** wenn gesetzt. Wenn `None`, wird das standardmäßige GRPO-Clipping verwendet. Empfohlen `> 1 + ε` wenn aktiviert (laut INTELLECT-2 Bericht).
* **`epsilon_high`** *(float, optional)*: Oberer Epsilon-Grenzwert; standardmäßig `epsilon` wenn nicht gesetzt. DAPO empfiehlt **0.28**.
* **`importance_sampling_level`** *(„token“ | „sequence“, Standard "token")*:
  * `"token"`: rohe Token‑weise Verhältnisse (ein Gewicht pro Token).
  * `"sequence"`: mittelt Token‑Verhältnisse zu einem einzelnen sequence‑level Verhältnis.\
    GSPO zeigt, dass sequence‑level Sampling oft stabileres Training für sequence‑level Belohnungen ergibt.
* **`reward_weights`** *(list\[float], optional)*: Ein Gewicht pro Belohnung. Wenn `None`, sind alle Gewichte = 1.0.
* **`scale_rewards`** *(str|bool, Standard "group")*:
  * `True` oder `"group"`: skalieren nach **Std innerhalb jeder Gruppe** (Einheitsvarianz in der Gruppe).
  * `"batch"`: skalieren nach **Std über den gesamten Batch** (laut PPO‑Lite).
  * `False` oder `"none"`: **keine Skalierung**. Dr. GRPO empfiehlt, nicht zu skalieren, um Verzerrungen durch Std‑Skalierung zu vermeiden.
* **`loss_type`** *(str, Standard "dapo")*:
  * `"grpo"`: normalisiert über die Sequenzlänge (Längenbias; nicht empfohlen).
  * `"dr_grpo"`: normalisiert durch eine **globale Konstante** (eingeführt in Dr. GRPO; entfernt Längenbias). Konstante ≈ `max_completion_length`.
  * `"dapo"` **(Standard)**: normalisiert nach **aktiven Tokens im global akkumulierten Batch** (eingeführt in DAPO; entfernt Längenbias).
  * `"bnpo"`: normalisiert nach **aktive Tokens nur im lokalen Batch** (Ergebnisse können mit lokaler Batchgröße variieren; entspricht GRPO, wenn `per_device_train_batch_size == 1`).
* **`mask_truncated_completions`** *(bool, Standard False)*:\
  Wenn `True`, werden abgeschnittene Completionen von der Loss ausgeschlossen (von DAPO für Stabilität empfohlen).\
  **Hinweis**: Es gibt einige KL‑Probleme mit diesem Flag, daher empfehlen wir, es zu deaktivieren.

  ```python
  # Wenn mask_truncated_completions aktiviert ist, abgeschnittene Completionen in completion_mask auf Null setzen
  if self.mask_truncated_completions:
      truncated_completions = ~is_eos.any(dim=1)
      completion_mask = completion_mask * (~truncated_completions).unsqueeze(1).int()
  ```

  Dies kann alle `completion_mask` Einträge nullen, wenn viele Completionen abgeschnitten sind, wodurch `n_mask_per_reward = 0` und KL zu NaN werden kann. [Siehe](https://github.com/unslothai/unsloth-zoo/blob/e705f7cb50aa3470a0b6e36052c61b7486a39133/unsloth_zoo/rl_replacements.py#L184)
* **`vllm_importance_sampling_correction`** *(bool, Standard True)*:\
  Wendet an **Truncated Importance Sampling (TIS)** um Off‑Policy‑Effekte zu korrigieren, wenn die Generierung (z. B. vLLM / fast\_inference) sich vom Trainings‑Backend unterscheidet.\
  In Unsloth ist dies **automatisch auf True gesetzt** wenn Sie vLLM/fast\_inference verwenden; andernfalls **False**.
* **`vllm_importance_sampling_cap`** *(float, Standard 2.0)*:\
  Trunkierungsparameter **C** für TIS; setzt eine obere Schranke für das Importance‑Sampling‑Verhältnis zur Verbesserung der Stabilität.
* **`dtype`** bei der Wahl von float16 oder bfloat16 siehe [fp16-vs-bf16-for-rl](https://unsloth.ai/docs/de/los-gehts/reinforcement-learning-rl-guide/advanced-rl-documentation/fp16-vs-bf16-for-rl "mention")

### RL bei nicht unterstützten Modellen:

Sie können RL mit Unsloth auch auf Modellen ausführen, die von vLLM nicht unterstützt werden, wie z. B. [Qwen3.5](https://unsloth.ai/docs/de/modelle/qwen3.5/fine-tune). Setzen Sie einfach `fast_inference=False` beim Laden des Modells.

```python
from unsloth import FastLanguageModel

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="unsloth/Qwen3.5-4B",
    fast_inference=False,
)
```

## Generierungsparameter

* `temperature (float, Standardwert 1.0):`\
  Temperatur für das Sampling. Je höher die Temperatur, desto zufälliger die Completionen. Stellen Sie sicher, dass Sie eine relativ hohe (1.0) Temperatur verwenden, um Vielfalt in den Generierungen zu haben, was das Lernen unterstützt.
* `top_p (float, optional, Standardwert 1.0):`\
  Float, der die kumulative Wahrscheinlichkeit der obersten Tokens steuert, die berücksichtigt werden. Muss in (0, 1] liegen. Auf 1.0 setzen, um alle Tokens zu berücksichtigen.
* `top_k (int, optional):`\
  Anzahl der Vokabeltokens mit höchster Wahrscheinlichkeit, die für das Top‑k‑Filtering beibehalten werden. Wenn None, ist Top‑k‑Filtering deaktiviert und alle Tokens werden berücksichtigt.
* `min_p (float, optional):`\
  Minimale Token‑Wahrscheinlichkeit, die durch die Wahrscheinlichkeit des wahrscheinlichsten Tokens skaliert wird. Muss einen Wert zwischen 0.0 und 1.0 haben. Typische Werte liegen im Bereich 0.01–0.2.
* `repetition_penalty (float, optional, Standardwert 1.0):`\
  Float, das neue Tokens basierend darauf bestraft, ob sie im Prompt und im bisher generierten Text erscheinen. Werte > 1.0 fördern die Nutzung neuer Tokens, während Werte < 1.0 das Wiederholen von Tokens fördern.
* `steps_per_generation: (int, optional):`\
  Anzahl der Schritte pro Generierung. Wenn None, ist der Standardwert `gradient_accumulation_steps`. Steht in gegenseitigem Ausschluss mit `generation_batch_size`.

{% hint style="info" %}
Es ist etwas verwirrend, mit diesem Parameter zu hantieren; empfohlen wird, `per_device_train_batch_size` und die Gradientenakkumulation für die Batchgrößen zu bearbeiten
{% endhint %}

## Batch‑ & Durchsatzparameter

### Parameter, die Batches steuern

* **`train_batch_size`**: Anzahl der Samples **pro Prozess** pro Schritt.\
  Wenn diese Ganzzahl **kleiner als `num_generations`**, wird sie standardmäßig auf `num_generations`.
* **`steps_per_generation`**: Anzahl der **Microbatches** die zu **der Verlustberechnung einer Generation beitragen (nur Vorwärtsdurchläufe).**\
  **Ein neuer Datensatz wird alle** Schritte generiert; das Timing der Rückpropagation hängt von `steps_per_generation` num\_processes `gradient_accumulation_steps`.
* **`: Anzahl der verteilten Trainingsprozesse (z. B. GPUs / Worker).`**(auch bekannt als
* **`gradient_accumulation_steps`** gradient\_accumulation `): Anzahl der Microbatches, die akkumuliert werden sollen`bevor **Rückpropagation und Optimizer‑Update angewendet werden.** Effektive Batchgröße
* **effective\_batch\_size = steps\_per\_generation \* num\_processes \* train\_batch\_size**:

  ```
  Gesamtsamples, die vor einem Update zu den Gradienten beitragen (über alle Prozesse und Schritte hinweg).
  ```

  Optimizer‑Schritte pro Generation
* **optimizer\_steps\_per\_generation = steps\_per\_generation / gradient\_accumulation\_steps**:

  ```
  Beispiel:
  ```

  : Anzahl der erzeugten Generierungen `4 / 2 = 2`.
* **`num_generations`**&#x70;ro Prompt **(angewendet** nach **Berechnung der** effective\_batch\_size `).`\
  `Die Anzahl der`einzigartigen Prompts **in einem Generierungszyklus ist:** unique\_prompts = effective\_batch\_size / num\_generations

  ```
  Muss > 2 sein
  ```

  **damit GRPO funktioniert.** GRPO Batch‑Beispiele

### Die folgenden Tabellen veranschaulichen, wie Batches durch die Schritte fließen, wann Optimizer‑Updates stattfinden und wie neue Batches generiert werden.

Beispiel 1

#### num\_gpus = 1

```
per_device_train_batch_size = 3
gradient_accumulation_steps = 2
steps_per_generation = 4
effective_batch_size = 4 * 3 * 1 = 12

num_generations = 3
Generierungszyklus A
```

**Schritt**

| Batch | Anmerkungen | → Optimizer‑Update (accum = 2 erreicht) |
| ----: | ----------- | --------------------------------------- |
|     0 | \[0,0,0]    |                                         |
|     1 | \[1,1,1]    | Optimizer‑Update                        |
|     2 | \[2,2,2]    |                                         |
|     3 | \[3,3,3]    | Generierungszyklus B                    |

**Beispiel 2**

| Batch | Anmerkungen | → Optimizer‑Update (accum = 2 erreicht) |
| ----: | ----------- | --------------------------------------- |
|     0 | \[4,4,4]    |                                         |
|     1 | \[5,5,5]    | Optimizer‑Update                        |
|     2 | \[6,6,6]    |                                         |
|     3 | \[7,7,7]    | Generierungszyklus B                    |

#### steps\_per\_generation = gradient\_accumulation\_steps = 4

```
per_device_train_batch_size = 3
gradient_accumulation_steps = 2
Optimizer‑Update (accum = 4 erreicht)

num_generations = 3
Generierungszyklus A
```

**Schritt**

| Batch | Anmerkungen | → Optimizer‑Update (accum = 2 erreicht) |
| ----: | ----------- | --------------------------------------- |
|     0 | \[0,0,0]    |                                         |
|     1 | \[1,1,1]    |                                         |
|     2 | \[2,2,2]    |                                         |
|     3 | \[3,3,3]    | Beispiel 3                              |

**Beispiel 2**

| Batch | Anmerkungen | → Optimizer‑Update (accum = 2 erreicht) |
| ----: | ----------- | --------------------------------------- |
|     0 | \[4,4,4]    |                                         |
|     1 | \[5,5,5]    |                                         |
|     2 | \[6,6,6]    |                                         |
|     3 | \[7,7,7]    | Beispiel 3                              |

#### num\_generations = 4

```
per_device_train_batch_size = 3
gradient_accumulation_steps = 2
Optimizer‑Update (accum = 4 erreicht)

num_generations = 3
unique_prompts = effective_batch_size / num_generations = 3
Beispiel 4
```

**Schritt**

| Batch | Anmerkungen | → Optimizer‑Update (accum = 2 erreicht) |
| ----: | ----------- | --------------------------------------- |
|     0 | \[0,0,0]    |                                         |
|     1 | \[0,1,1]    |                                         |
|     2 | \[1,1,3]    |                                         |
|     3 | \[3,3,3]    | Beispiel 3                              |

**Beispiel 2**

| Batch | Anmerkungen | → Optimizer‑Update (accum = 2 erreicht) |
| ----: | ----------- | --------------------------------------- |
|     0 | \[4,4,4]    |                                         |
|     1 | \[4,5,5]    |                                         |
|     2 | \[5,5,6]    |                                         |
|     3 | \[6,6,6]    | Beispiel 3                              |

#### per\_device\_train\_batch\_size = 6

```
per_device_train_batch_size = 3
steps_per_generation = gradient_accumulation_steps = 2
effective_batch_size = 2 * 6 * 1 = 12

unique_prompts = 4
Generierungszyklus A
Optimizer‑Update (accum = 2 erreicht)
```

**Schritt**

| Batch | Anmerkungen     | → Optimizer‑Update (accum = 2 erreicht) |
| ----: | --------------- | --------------------------------------- |
|     0 | \[0,0,0, 1,1,1] |                                         |
|     1 | \[2,2,2, 3,3,3] | Schnelle Formelreferenz                 |

**Beispiel 2**

| Batch | Anmerkungen     | → Optimizer‑Update (accum = 2 erreicht) |
| ----: | --------------- | --------------------------------------- |
|     0 | \[4,4,4, 5,5,5] |                                         |
|     1 | \[6,6,6, 7,7,7] | Schnelle Formelreferenz                 |

### unique\_prompts = effective\_batch\_size / num\_generations   # muss > 2 sein

```
Gesamtsamples, die vor einem Update zu den Gradienten beitragen (über alle Prozesse und Schritte hinweg).
Beispiel:
unique_prompts = effective_batch_size / num_generations   # muss > 2 sein
```
