# Tutoriel : entraînez votre propre modèle de raisonnement avec GRPO

DeepSeek a développé [GRPO](https://unsloth.ai/blog/grpo) (Group Relative Policy Optimization) pour entraîner leurs modèles de raisonnement R1.

### Démarrage rapide

Ces instructions sont pour nos [carnets](https://unsloth.ai/docs/fr/commencer/unsloth-notebooks). Si vous installez Unsloth localement, vous pouvez aussi copier nos carnets dans votre éditeur de code préféré. Nous utiliserons l’un de ces carnets :

| [**Qwen3.5 (4B)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_5_\(4B\)_Vision_GRPO.ipynb) **- Vision - nouveau** | [**gpt-oss-20b**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt-oss-\(20B\)-GRPO.ipynb) **-** GSPO       | [Gemma 3 (4B)](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3_\(4B\)-Vision-GRPO.ipynb) - Vision GSPO       |
| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Qwen3 (4B)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_\(4B\)-GRPO.ipynb) - Avancé                          | [Qwen3-VL-8B](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_VL_\(8B\)-Vision-GRPO.ipynb) - Vision GSPO | [Llama 3.2 (3B)](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Advanced_Llama3_2_\(3B\)_GRPO_LoRA.ipynb) - Avancé |

{% stepper %}
{% step %}

#### Installer Unsloth

Si vous utilisez notre carnet Colab, cliquez **Runtime > Run all**. Nous vous recommandons vivement de consulter notre [Guide de fine-tuning](https://unsloth.ai/docs/fr/commencer/fine-tuning-llms-guide) avant de commencer.

Si vous installez localement, assurez-vous d'avoir les [requirements](https://unsloth.ai/docs/fr/commencer/fine-tuning-for-beginners/unsloth-requirements) corrects et utilisez `pip install unsloth` sur Linux ou suivez nos [instructions d'installation Windows ](https://unsloth.ai/docs/fr/commencer/install/windows-installation).

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-313fa39c229225ae9d39b7c7a0d05c9005ddb94c%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### En savoir plus sur GRPO et les fonctions de récompense

Avant de commencer, il est recommandé d'en apprendre davantage sur GRPO, les fonctions de récompense et leur fonctionnement. Lisez-en plus à leur sujet, y compris [astuces & conseils](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/..#basics-tips)[ ici](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/..#basics-tips).

Vous aurez également besoin de suffisamment de VRAM. En général, le nombre de paramètres du modèle = quantité de VRAM dont vous aurez besoin. Dans Colab, nous utilisons leurs GPU gratuits de 16 Go de VRAM qui peuvent entraîner n'importe quel modèle jusqu'à 16B de paramètres.
{% endstep %}

{% step %}

#### Configurer les paramètres souhaités

Nous avons déjà présélectionné des paramètres optimaux pour obtenir les meilleurs résultats et vous pouvez changer le modèle pour celui que vous souhaitez parmi ceux listés dans nos [modèles pris en charge](https://unsloth.ai/docs/fr/commencer/unsloth-model-catalog). Nous ne recommandons pas de modifier les autres paramètres si vous êtes débutant.

{% hint style="success" %}
Pour **GRPO avancé** documentation sur le batching, la génération et les paramètres d'entraînement, [lisez notre guide !](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/advanced-rl-documentation)
{% endhint %}

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-b1e9fac448706ac87dff7e7eff1298655dda456e%2Fimage.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Préparation des données

Nous avons présélectionné le [GSM8K](https://huggingface.co/datasets/openai/gsm8k) d'OpenAI qui contient des problèmes de mathématiques de niveau scolaire, mais vous pouvez le remplacer par le vôtre ou par n'importe quel jeu public sur Hugging Face. Vous pouvez en lire plus sur [les jeux de données ici](https://unsloth.ai/docs/fr/commencer/fine-tuning-llms-guide/datasets-guide).

Votre jeu de données doit toujours comporter au moins 2 colonnes pour les paires question-réponse. Cependant, la réponse ne doit pas révéler le raisonnement expliquant comment elle a été dérivée de la question. Voir ci-dessous pour un exemple :

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

Nous structurerons les données pour inciter le modèle à articuler son raisonnement avant de fournir une réponse. Pour commencer, nous établirons un format clair pour les invites et les réponses.

```
# Définir l'invite système qui indique au modèle d'utiliser un format spécifique
SYSTEM_PROMPT = """
Répondez dans le format suivant :
<reasoning>
...
</reasoning>
<answer>
...
</answer>
"""

XML_COT_FORMAT = """\
<reasoning>
{reasoning}
</reasoning>
<answer>
{answer}
</answer>
"""
```

Maintenant, pour préparer le jeu de données :

```
import re
from datasets import load_dataset, Dataset


# Fonctions utilitaires pour extraire les réponses de différents formats
def extract_xml_answer(text: str) -> str:
    answer = text.split("<answer>")[-1]
    answer = answer.split("</answer>")[0]
    return answer.strip()


def extract_hash_answer(text: str) -> str | None:
    if "####" not in text:
        return None
    return text.split("####")[1].strip()


# Fonction pour préparer le jeu de données GSM8K
def get_gsm8k_questions(split="train") -> Dataset:
    data = load_dataset("openai/gsm8k", "main")[split]
    data = data.map(
        lambda x: {
            "prompt": [
                {"role": "system", "content": SYSTEM_PROMPT},
                {"role": "user", "content": x["question"]},
            ],
            "answer": extract_hash_answer(x["answer"]),
        }
    )
    return data


dataset = get_gsm8k_questions()
```

Le jeu de données est préparé en extrayant les réponses et en les formatant en chaînes structurées.
{% endstep %}

{% step %}

#### Fonctions de récompense / Vérificateur

[Fonctions de récompense / Vérificateurs](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/..#reward-functions-verifier) nous indiquent si le modèle fonctionne bien ou non selon le jeu de données que vous avez fourni. Chaque exécution de génération sera évaluée en fonction de ses performances par rapport à la moyenne des autres générations. Vous pouvez créer vos propres fonctions de récompense mais nous les avons déjà présélectionnées pour vous avec [les fonctions de récompense GSM8K de Will](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/..#gsm8k-reward-functions) . Avec cela, nous avons 5 façons différentes de récompenser chaque génération.

Vous pouvez injecter vos générations dans un LLM comme ChatGPT 4o ou Llama 3.1 (8B) et concevoir une fonction de récompense et un vérificateur pour l'évaluer. Par exemple, alimentez vos générations dans un LLM de votre choix et définissez une règle : "Si la réponse paraît trop robotique, déduisez 3 points." Cela aide à affiner les sorties selon des critères de qualité. **Voir des exemples** de ce à quoi ils peuvent ressembler [ici](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/..#reward-function-examples).

**Exemple de fonction de récompense pour une tâche d'automatisation d'e-mails :**

* **Question :** E-mail entrant
* **Réponse :** E-mail sortant
* **Fonctions de récompense :**
  * Si la réponse contient un mot-clé requis → **+1**
  * Si la réponse correspond exactement à la réponse idéale → **+1**
  * Si la réponse est trop longue → **-1**
  * Si le nom du destinataire est inclus → **+1**
  * Si un bloc de signature (téléphone, e-mail, adresse) est présent → **+1**

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-95cd00b6a52b8161b31a2399e25863ee0349920e%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Entraînez votre modèle

Nous avons présélectionné des hyperparamètres pour les résultats les plus optimaux, toutefois vous pouvez les modifier. Lisez tout sur [les paramètres ici](https://unsloth.ai/docs/fr/commencer/fine-tuning-llms-guide/lora-hyperparameters-guide). Pour **GRPO avancé** documentation sur le batching, la génération et les paramètres d'entraînement, [lisez notre guide !](https://unsloth.ai/docs/fr/commencer/reinforcement-learning-rl-guide/advanced-rl-documentation)

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

Le **GRPOConfig** définit les hyperparamètres clés pour l'entraînement :

* `use_vllm` : Active l'inférence rapide en utilisant vLLM.
* `learning_rate` : Détermine la vitesse d'apprentissage du modèle.
* `num_generations` : Spécifie le nombre de complétions générées par invite.
* `max_steps` : Définit le nombre total d'étapes d'entraînement.

{% hint style="success" %}
**NOUVEAU !** Nous prenons désormais en charge DAPO, Dr. GRPO et la plupart des autres nouvelles techniques GRPO. Vous pouvez jouer avec les arguments suivants dans GRPOConfig pour les activer :

```python
epsilon=0.2,
epsilon_high=0.28, # unilatéral
delta=1.5 # bilatéral

loss_type='bnpo',
# ou :
loss_type='grpo',
# ou :
loss_type='dr_grpo',
# ou :
loss_type='dapo',

mask_truncated_completions=True,
```

{% endhint %}

Vous devriez voir la récompense augmenter avec le temps. Nous vous recommandons d'entraîner pendant au moins 300 étapes ce qui peut prendre 30 minutes ; cependant, pour des résultats optimaux, vous devriez entraîner plus longtemps.

{% hint style="warning" %}
Si vous rencontrez des problèmes avec votre modèle GRPO qui n'apprend pas, nous vous recommandons vivement d'utiliser nos [carnets GRPO avancés](https://unsloth.ai/docs/fr/unsloth-notebooks#grpo-reasoning-notebooks) car ils ont une fonction de récompense bien meilleure et vous devriez voir les résultats beaucoup plus rapidement et fréquemment.
{% endhint %}

Vous verrez également des réponses d'exemple qui vous permettent de voir comment le modèle apprend. Certaines peuvent contenir des étapes, des balises XML, des tentatives, etc., et l'idée est qu'à mesure qu'il s'entraîne, il s'améliorera de plus en plus car il obtiendra des scores de plus en plus élevés jusqu'à ce que nous obtenions les sorties souhaitées avec de longues chaînes de raisonnement.

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-f33d6f494605ab9ca69a0b697ed5865dd3a30b18%2Fimage.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Exécutez et évaluez votre modèle

Exécutez votre modèle en cliquant sur le bouton lecture. Dans le premier exemple, il n'y a généralement pas de raisonnement dans la réponse et afin de voir le raisonnement, nous devons d'abord enregistrer les poids LoRA que nous venons d'entraîner avec GRPO en utilisant :

<pre><code><strong>model.save_lora("grpo_saved_lora")
</strong></code></pre>

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-1ab351622655983aeda4d9d6d217cf354cb280be%2Fimage%20(10)%20(1)%20(1).png?alt=media" alt=""><figcaption><p>Le premier exemple d'inférence n'a pas de raisonnement. Vous devez charger la LoRA et la tester pour révéler le raisonnement.</p></figcaption></figure>

Ensuite, nous chargeons la LoRA et la testons. Notre modèle de raisonnement est bien meilleur - il n'est pas toujours correct, puisque nous ne l'avons entraîné qu'une heure environ - il s'améliorera si nous étendons la longueur de la séquence et entraînons plus longtemps !

Vous pouvez ensuite enregistrer votre modèle au format GGUF, Ollama, etc. en suivant notre [guide ici](https://unsloth.ai/docs/fr/fine-tuning-llms-guide#id-7.-running--saving-the-model).

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

Si vous n'obtenez toujours pas de raisonnement, vous avez peut-être entraîné trop peu d'étapes ou votre fonction de récompense/vérificateur n'était pas optimale.
{% endstep %}

{% step %}

#### Enregistrez votre modèle

Nous avons plusieurs options pour enregistrer votre modèle affiné, mais nous nous concentrerons sur les approches les plus simples et les plus populaires dont vous pouvez lire davantage [ici](https://unsloth.ai/docs/fr/bases/inference-and-deployment)

**Enregistrement en précision 16 bits**

Vous pouvez enregistrer le modèle en précision 16 bits en utilisant la commande suivante :

```python
# Enregistrer en précision 16 bits
model.save_pretrained_merged("model", tokenizer, save_method="merged_16bit")
```

**Pousser vers le Hub Hugging Face**

Pour partager votre modèle, nous le pousserons vers le Hub Hugging Face en utilisant la `méthode push_to_hub_merged` . Cela permet d'enregistrer le modèle dans plusieurs formats de quantification.

```python
# Pousser vers le Hub Hugging Face (nécessite un token)
model.push_to_hub_merged(
    "votre-nom-utilisateur/nom-du-model", tokenizer, save_method="merged_16bit", token="votre-token"
)
```

**Enregistrement au format GGUF pour llama.cpp**

Unsloth prend également en charge l'enregistrement en **format GGUF**, le rendant compatible avec **llama.cpp** et **Ollama**.

```python
model.push_to_hub_gguf(
    "votre-nom-utilisateur/nom-du-model",
    tokenizer,
    quantization_method=["q4_k_m", "q8_0", "q5_k_m"],
    token="votre-token",
)
```

Une fois enregistré au format GGUF, le modèle peut être facilement déployé dans des environnements légers en utilisant **llama.cpp** ou utilisé dans d'autres moteurs d'inférence.
{% endstep %}
{% endstepper %}

## Tutoriels vidéo

Voici quelques tutoriels vidéo créés par des YouTubers formidables que nous trouvons fantastiques !

{% embed url="<https://www.youtube.com/watch?v=9t-BAjzBWj8>" %}

{% columns %}
{% column width="50%" %}
{% embed url="<https://www.youtube.com/watch?t=3289s&v=bbFEYPx9Hpo>" %}
Idéal pour apprendre à préparer votre jeu de données et les explications derrière l'apprentissage par renforcement + les bases de GRPO
{% endembed %}

{% embed url="<https://www.youtube.com/watch?v=oF0_eMhzRaQ>" %}
{% endcolumn %}

{% column width="50%" %}
{% embed url="<https://www.youtube.com/watch?v=juOh1afy-IE>" %}

{% embed url="<https://www.youtube.com/watch?v=SoPE1cUz3Hs>" %}
GRPO local sur votre propre appareil
{% endembed %}
{% endcolumn %}
{% endcolumns %}


---

# 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/fr/commencer/reinforcement-learning-rl-guide/tutorial-train-your-own-reasoning-model-with-grpo.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.
