# Apprentissage par renforcement GRPO avec un contexte 7x plus long

Le plus grand défi de l'apprentissage par renforcement (RL) est de prendre en charge de longues traces de raisonnement. Nous présentons de nouveaux algorithmes de mise en lot (batching) pour permettre \~**contexte \~7x plus long** (peut dépasser 12x) Entraînement RL sans dégradation de la précision ou de la vitesse par rapport à d'autres configurations optimisées qui utilisent FA3, des kernels et des pertes en morceaux.

* Unsloth entraîne désormais gpt-oss QLoRA avec **contexte 380K** sur un seul GPU NVIDIA B200 de 192 Go
* [Qwen3](https://unsloth.ai/docs/fr/modeles/tutorials/qwen3-how-to-run-and-fine-tune#fine-tuning-qwen3-with-unsloth)-8B GRPO atteint **contexte 110K** sur un H100 à 80 Go VRAM via [vLLM](#vllm-for-rl) et QLoRA, et **65K** pour [gpt-oss](https://unsloth.ai/docs/fr/modeles/gpt-oss-how-to-run-and-fine-tune/gpt-oss-reinforcement-learning) avec LoRA en BF16.
* Sur 24 Go VRAM, gpt-oss atteint 20K de contexte et 32K pour [Qwen3-VL](https://unsloth.ai/docs/fr/modeles/tutorials/qwen3-how-to-run-and-fine-tune/qwen3-vl-how-to-run-and-fine-tune)-8B QLoRA
* Les exécutions RL Unsloth GRPO fonctionnent avec Llama, Gemma et tous les modèles prennent automatiquement en charge des contextes plus longs

Nos nouveaux kernels et algorithmes de déplacement de données et de mise en lot débloquent plus de contexte en :

* Découpage dynamique [de séquences aplaties en morceaux](#flattened-sequence-length-chunking) pour éviter la matérialisation de tenseurs de logits massifs et
* [Déchargement des activations de log softmax](#offloading-activations-for-log-softmax) ce qui empêche la croissance silencieuse de la mémoire au fil du temps.

{% hint style="info" %}
**Vous pouvez combiner toutes les fonctionnalités d'Unsloth ensemble :**

1. La [partage de poids](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/memory-efficient-rl) d'Unsloth [vLLM](https://github.com/vllm-project/vllm) avec [memory-efficient-rl](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/memory-efficient-rl "mention")
2. La [et notre fonctionnalité Standby dans](https://unsloth.ai/docs/fr/modeles/gpt-oss-how-to-run-and-fine-tune/long-context-gpt-oss-training) Flex Attention [500k-context-length-fine-tuning](https://unsloth.ai/docs/fr/blog/500k-context-length-fine-tuning "mention")
3. pour gpt-oss à long contexte et notre [fp8-reinforcement-learning](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/fp8-reinforcement-learning "mention") entraînement Float8 dans [et le](https://unsloth.ai/blog/long-context) point de contrôle asynchrone des gradients d'Unsloth
   {% endhint %}

### :tada:et bien plus

Premiers pas [Notebooks GRPO](https://unsloth.ai/docs/fr/unsloth-notebooks#grpo-reasoning-rl-notebooks) Pour commencer, vous pouvez utiliser n'importe quel

{% columns %}
{% column width="33.33333333333333%" %}
[**gpt-oss-20b**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt-oss-\(20B\)-GRPO.ipynb) GSPO

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt-oss-(20B)-GRPO.ipynb>" %}
{% endcolumn %}

{% column width="33.33333333333333%" %}
[**(ou mettre à jour Unsloth si local) :**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_VL_\(8B\)-Vision-GRPO.ipynb) Qwen3-VL-8B

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_VL_(8B)-Vision-GRPO.ipynb>" %}
{% endcolumn %}

{% column width="33.33333333333333%" %}
[Qwen3-8B - **FP8**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_8B_FP8_GRPO.ipynb) Vision RL

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_8B_FP8_GRPO.ipynb>" %}
{% endcolumn %}
{% endcolumns %}

GPU L4

* **Adopter Unsloth pour vos tâches RL fournit un cadre robuste pour gérer efficacement des modèles à grande échelle. Pour utiliser efficacement les améliorations d'Unsloth :**&#x52;ecommandations matérielles
* &#x20;**: Utilisation d'un NVIDIA H100 ou équivalent pour une utilisation optimale de la VRAM.**&#x43;onseils de configuration `: Assurez-vous que les paramètres` et `gradient_accumulation_steps` batch\_size

{% hint style="success" %}
sont alignés sur vos ressources informatiques pour de meilleures performances.

```
Mettez Unsloth à jour vers la dernière version sur Pypi pour obtenir les mises à jour les plus récentes :
```

{% endhint %}

pip install --upgrade --no-cache-dir unsloth unsloth\_zoo [Nos benchmarks mettent en évidence les économies de mémoire réalisées par rapport aux versions précédentes pour GPT OSS et Qwen3-8B. Les deux graphiques ci‑dessous (sans](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/memory-efficient-rl)standby `) ont été exécutés avec` et `batch_size = 4` gradient\_accumulation\_steps=2

, puisque standby, par conception, utilise toute la VRAM.

### :1234:Pour nos benchmarks, nous comparons BF16 GRPO à Hugging Face avec toutes les optimisations activées (tous les kernels de la bibliothèque kernels, Flash Attention 3, kernels de perte en morceaux, etc.) :

Découpage de longueur de séquence aplatie

$$
\text{Equation 1: } \text{Logit Memory (GB)} = \frac{\text{batch size} \times\text{context length} \times \text{vocab dim}}{1024^3}
$$

Précédemment, Unsloth réduisait l'utilisation mémoire du RL en évitant la matérialisation complète du tenseur de logits en découpant sur la dimension du batch. Une estimation approximative de la VRAM requise pour matérialiser les logits durant la passe avant est montrée dans l'Équation (1). `) ont été exécutés avec`, `En utilisant cette formulation, une configuration avec`, et `context_length = 8192` vocab\_dim = 128 000 **requiert environ** 3,3 Go de VRAM

pour stocker le tenseur de logits. [long-context-gpt-oss-training](https://unsloth.ai/docs/fr/modeles/gpt-oss-how-to-run-and-fine-tune/long-context-gpt-oss-training "mention") Via **l'année dernière, nous avons ensuite introduit une approche de perte fusionnée pour GRPO. Cette approche garantit qu'un seul échantillon de batch est traité à la fois, réduisant significativement l'utilisation mémoire maximale. Pour la même configuration, l'utilisation de la VRAM tombe à environ**0,83 Go

$$
\text{Equation 2: }\text{Logit Memory (GB)} = \frac{\text{context length} \times \text{vocab dim}}{1024^3}
$$

<div><figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fy1TkzxySrNAeeSWJSVLU%2Funsloth_vs_trl_gpt_oss.png?alt=media&#x26;token=0303423d-1454-4410-8be8-7d6110ac1df0" alt="" width="375"><figcaption><p>, comme reflété dans l'Équation (2).</p></figcaption></figure> <figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FmfKhenN0TGRDlMcuxob6%2Fqwen38b%20long%20context%20grpo.png?alt=media&#x26;token=22883f90-5bf0-4478-91a9-6a191c920f12" alt="" width="375"><figcaption><p>Figure 1 : gpt-oss BF16 GRPO LoRA (Unsloth vs. HF avec toutes les optimisations activées)</p></figcaption></figure></div>

Figure 2 : Qwen3-8B QLoRA GRPO LoRA (Unsloth vs. HF avec toutes les optimisations activées) **Dans cette mise à jour, nous étendons la même idée en introduisant le découpage à travers la** dimension de séquence `également. Au lieu de matérialiser les logits pour l'intégralité de l'espace` (batch\_size × context\_length)

d'un seul coup, nous aplatissons ces dimensions et les traitons en plus petits morceaux en utilisant un multiplicateur configurable. Cela permet à Unsloth de prendre en charge des contextes sensiblement plus longs sans augmenter l'utilisation mémoire maximale. `Dans la Figure 5 ci‑dessous, nous utilisons un multiplicateur de`max(4, context\_length // 4096)`) ont été exécutés avec`, `En utilisant cette formulation, une configuration avec`, `context_length = 8192`, bien que n'importe quel multiplicateur puisse être spécifié selon le compromis mémoire–performance désiré. Avec ce paramètre, la même configuration d'exemple ( **) nécessite désormais seulement** 0,207 Go de VRAM

$$
\text{Equation 3: }\text{Logit Memory (GB)} = \frac{\frac{\text{context length}}{\text{multiplier}} \times \text{vocab dim}}{1024^3}
$$

<div><figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FWFTbejdIn3T6E6yHgF1Z%2FCode_Generated_Image%20(2).png?alt=media&#x26;token=790a1ee4-2814-4b29-afcb-bb9ffd1eb729" alt="" width="375"><figcaption><p>pour la matérialisation des logits.</p></figcaption></figure> <figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fi4QipufoavtPKyeRU0Vv%2FCode_Generated_Image%20(3).png?alt=media&#x26;token=226c5a3c-a0a4-458d-a0df-8c84523b04b5" alt="" width="375"><figcaption><p>Figure 3 : gpt-oss-20b (H100) Unsloth nouveau vs. ancien</p></figcaption></figure> <figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FkSIh5DIWvKGemnNHowPs%2FCode_Generated_Image_4.png?alt=media&#x26;token=0a3dfe85-ae8c-4280-bc0a-6c1f1523c90e" alt="" width="375"><figcaption><p>Figure 4 : Qwen3-8B (H100) Unsloth nouveau vs. ancien</p></figcaption></figure> <figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FRP1RPiOeIYOt82L1Ifkc%2FCode_Generated_Image_5.png?alt=media&#x26;token=4ce06b0f-2464-41fd-8795-e5bf0dbf4327" alt="" width="375"><figcaption><p>Figure 5 : gpt-oss-20b (H100)</p></figcaption></figure></div>

Figure 6 : Qwen3-8B (B200) `Cette mise à jour est reflétée dans le` chunked\_hidden\_states\_selective\_log\_softmax`compilé ci‑dessous, qui prend désormais en charge le découpage à la fois sur les dimensions batch et séquence. Pour préserver le tenseur de logits (`\[batch\_size, context\_length, vocab\_dim] `), il est toujours découpé sur la dimension batch. Le découpage supplémentaire sur la séquence est contrôlé via` unsloth\_logit\_chunk\_multiplier `Dans la Figure 5 ci‑dessous, nous utilisons un multiplicateur de`dans la configuration GRPO ; s'il n'est pas défini, il prend par défaut `. Dans l'exemple ci‑dessous,` input\_ids\_chunk\[0]

```python
correspond à la taille des mini‑lots d'états cachés dans l'optimisation 2.
    logprobs_chunk = chunked_hidden_states_selective_log_softmax( 
    new_hidden_states_chunk, 
    lm_head, 
    completion_ids, 
    chunks=input_ids_chunk.shape[0]*multiplier,
    logit_scale_multiply=logit_scale_multiply,
    logit_scale_divide=logit_scale_divide,
    logit_softcapping=logit_softcapping,                
)
```

1. temperature=temperature,
2. Nous utilisons torch.compile avec des options de compilation personnalisées pour réduire la VRAM et augmenter la vitesse.
3. Tous les logits découpés sont convertis en float32 pour préserver la précision.

### :ghost:Nous prenons en charge le softcapping des logits, le scaling de la température et toutes les autres fonctionnalités.

Découpage des états cachés `Nous avons également observé qu'à des longueurs de contexte plus longues, les états cachés peuvent devenir un contributeur significatif à l'utilisation mémoire. Pour la démonstration, nous supposerons`hidden\_states\_dim=4096&#x20;

$$
\text{Hidden States Memory (GB)} = \frac{\text{batch size} \times\text{context length} \times \text{hidden states dim}}{1024^3}
$$

. L'utilisation mémoire correspondante suit une formulation similaire au cas des logits, montrée ci‑dessous. `Avec un` et `batch_size = 8`context\_length = 64000 **, cela aboutirait à une utilisation de VRAM d'environ**2 Go **. Dans cette version, nous introduisons un découpage optionnel sur la dimension batch pour le tenseur des états cachés lors du calcul des log‑probabilités. Cela ferait que l'utilisation de la VRAM soit divisée par la taille du batch ou, dans ce cas, soit**0,244 Go

$$
\text{Hidden States Memory (GB)} = \frac{\text{context length} \times \text{hidden states dim}}{1024^3}
$$

. Cela réduit la VRAM maximale requise pour matérialiser les états cachés, comme reflété dans l'équation mise à jour ci‑dessous : [500k-context-length-fine-tuning](https://unsloth.ai/docs/fr/blog/500k-context-length-fine-tuning "mention") Similaire à notre perte d'entropie croisée dans notre **publication, la nouvelle implémentation**ajuste automatiquement le lotage des états cachés `. Les utilisateurs peuvent également contrôler ce comportement via`unsloth\_grpo\_mini\_batch `. Les utilisateurs peuvent également contrôler ce comportement via` . Cependant, augmenter

au‑delà de la valeur optimale peut introduire une légère augmentation des performances ou un ralentissement (généralement plus rapide) par rapport à l'ancienne fonction de perte.`Cependant, lors d'une exécution GPT-OSS (`context\_length = 8192, batch\_size = 4, gradient\_accumulation\_steps = 2 `), définir` et `unsloth_grpo_mini_batch = 1` unsloth\_logit\_chunk\_multiplier = 4 **entraîne** peu ou pas de dégradation de la vitesse tout en réduisant l'utilisation de la VRAM d'environ 5 Go

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FYZsgoKpZKyJKrNmbvehR%2FCode_Generated_Image%20(4).png?alt=media&#x26;token=5d3c0605-9ed8-4d4a-a722-a85132510222" alt="" width="375"><figcaption></figcaption></figure>

{% hint style="success" %}
**Remarque :** par rapport aux anciennes versions d'Unsloth. `Dans les Figures 3 et 4, nous utilisons la taille de batch effective maximale, qui est 8 dans cette configuration. La taille de batch effective est calculée comme`batch\_size × gradient\_accumulation\_steps `, donnant`4 × 2 = 8 [. Pour une explication plus approfondie de la façon dont fonctionnent les tailles de batch effectives en RL, voir notre](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/advanced-rl-documentation).&#x20;
{% endhint %}

### :cactus:documentation RL avancée

Déchargement des activations pour le log softmax `Lors du développement de cette version, nous avons découvert que lorsque l'on carrelait (tiling) sur la dimension batch pour les états cachés, les activations n'étaient pas déchargées après le calcul fusionné des logits et des logprobs. Comme les logits sont calculés un batch à la fois en utilisant`hidden\_states\[i] @ lm\_head

, la logique existante de déchargement des activations et de checkpointing des gradients, conçue pour fonctionner dans la passe forward du modèle, ne s'appliquait pas dans ce cas.

```python
Pour y remédier, nous avons ajouté une logique explicite pour décharger ces activations en dehors de la passe forward du modèle, comme montré dans le pseudocode Python ci‑dessous :
    class Unsloth_Offloaded_Log_Softmax(torch.autograd.Function):
        with torch.no_grad():
            def forward(...):
        return output
    output = chunked_hidden_states_selective_log_softmax(hidden_states, lm_head, ...)
        def backward(ctx, grad_output):
        hidden_states.requires_grad_(True)
        with torch.enable_grad():
            def forward(...):
        hidden_states = ctx.saved_hidden_states
        return ...
```

{% hint style="success" %}
**Remarque :** torch.autograd.backward(output, grad\_output) `Cette fonctionnalité n'est efficace que lors du découpage sur la dimension batch ou lorsque`unsloth\_grpo\_mini\_batch > 1 `), définir`. Si tous les états cachés sont matérialisés d'un seul coup pendant la passe forward (c'est‑à‑dire,
{% endhint %}

### :sparkles:), la passe backward nécessite la même quantité de mémoire sur le GPU indépendamment du fait que les activations soient déchargées. Étant donné que le déchargement des activations introduit un léger ralentissement des performances sans réduire l'utilisation mémoire dans ce cas, cela n'apporte aucun bénéfice.

Configuration des paramètres : `. Les utilisateurs peuvent également contrôler ce comportement via` et `), il est toujours découpé sur la dimension batch. Le découpage supplémentaire sur la séquence est contrôlé via`Si vous ne configurez pas **, nous** ajusterons automatiquement ces deux paramètres

```python
training_args = GRPOConfig(
    ...
    pour vous en fonction de votre VRAM disponible et en fonction de la taille de votre longueur de contexte. Ci‑dessous toutefois comment vous pouvez modifier ces variables dans votre exécution GRPO :
    unsloth_grpo_mini_batch = 3
    ...
)
```

unsloth\_logit\_chunk\_multiplier = 2 `. Les utilisateurs peuvent également contrôler ce comportement via` et `), il est toujours découpé sur la dimension batch. Le découpage supplémentaire sur la séquence est contrôlé via` Une visualisation des optimisations et de

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2F2OmZA297HzG3CdRzi3X5%2FLogit%20Chunking%20(1).png?alt=media&#x26;token=b953a62b-fefa-43f2-a9ce-108675b8735f" alt="" width="375"><figcaption></figcaption></figure>

peut être vue dans le schéma ci‑dessous. `. Les utilisateurs peuvent également contrôler ce comportement via` Les 3 matrices représentent le lot global plus large ou `), il est toujours découpé sur la dimension batch. Le découpage supplémentaire sur la séquence est contrôlé via`  (représenté par le nombre de crochets noirs) et les lignes de chacune des matrices représentent la longueur de contexte que le&#x20;

### :vhs:découpe de la longueur de séquence (représenté par le nombre de crochets rouges).

**vLLM pour le RL**Pour les flux de travail RL, la phase d'inférence/génération est le principal goulot d'étranglement [vLLM](https://github.com/vllm-project/vllm). Pour y remédier, nous utilisons

, qui a accéléré la génération jusqu'à 11x par rapport à la génération normale. Depuis que GRPO a été popularisé l'année dernière, vLLM est devenu un composant central de la plupart des frameworks RL, y compris Unsloth. Nous souhaitons exprimer notre gratitude à l'équipe vLLM et à tous ses contributeurs pour leur travail, car ils jouent un rôle essentiel dans l'amélioration du RL d'Unsloth ! [Notebooks GRPO](https://unsloth.ai/docs/fr/unsloth-notebooks#grpo-reasoning-rl-notebooks) Pour commencer, vous pouvez utiliser n'importe quel

{% columns %}
{% column width="33.33333333333333%" %}
[**gpt-oss-20b**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt-oss-\(20B\)-GRPO.ipynb) Pour essayer le RL à plus long contexte, vous pouvez utiliser n'importe quel

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt-oss-(20B)-GRPO.ipynb>" %}
{% endcolumn %}

{% column width="33.33333333333333%" %}
[**(ou mettre à jour Unsloth si local) :**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_VL_\(8B\)-Vision-GRPO.ipynb) Qwen3-VL-8B

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_VL_(8B)-Vision-GRPO.ipynb>" %}
{% endcolumn %}

{% column width="33.33333333333333%" %}
[Qwen3-8B - **FP8**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_8B_FP8_GRPO.ipynb) Vision RL

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_8B_FP8_GRPO.ipynb>" %}
{% endcolumn %}
{% endcolumns %}

\- GSPO
