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

Guide du débutant pour transformer un modèle comme Llama 3.1 (8B) en modèle de raisonnement en utilisant Unsloth et GRPO.

DeepSeek a développé GRPOarrow-up-right (Group Relative Policy Optimization) pour entraîner leurs modèles de raisonnement R1.

Démarrage rapide

Ces instructions sont pour notre Google Colab préconfiguré notebooks. Si vous installez Unsloth localement, vous pouvez aussi copier nos notebooks dans votre éditeur de code préféré. Nous utiliserons l’un de ces notebooks :

1

Installer Unsloth

Si vous utilisez notre notebook Colab, cliquez Runtime > Run all. Nous vous recommandons vivement de consulter notre Guide de fine-tuning avant de commencer.

Si vous installez localement, assurez-vous d'avoir les prérequis et utilisez pip install unsloth sur Linux ou suivez nos instructions d'installation pour Windows .

2

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

Avant de commencer, il est recommandé d'en apprendre davantage sur le GRPO, les fonctions de récompense et leur fonctionnement. Lisez-en plus, y compris astuces & conseils ici.

Vous aurez également besoin de suffisamment de VRAM. En général, les 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 tout modèle jusqu'à 16B de paramètres.

3

Configurer les paramètres souhaités

Nous avons déjà présélectionné des paramètres optimaux pour vous et vous pouvez changer le modèle pour celui que vous souhaitez parmi notre modèles pris en charge. Nous ne recommandons pas de modifier les autres paramètres si vous êtes débutant.

circle-check
4

Préparation des données

Nous avons présélectionné le GSM8Karrow-up-right d'OpenAI qui contient des problèmes de mathématiques de niveau scolaire, mais vous pouvez le remplacer par le vôtre ou tout jeu de données public sur Hugging Face. Vous pouvez en savoir plus sur les jeux de données ici.

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

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 comme des chaînes structurées.

5

Fonctions de récompense / Vérificateur

Fonctions de récompense / Vérificateurs 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 au score moyen 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 . Avec cela, nous avons 5 façons différentes de récompenser chaque génération.

Vous pouvez soumettre vos générations à 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, fournissez vos générations à un LLM de votre choix et définissez une règle : "Si la réponse semble trop robotique, déduire 3 points." Cela aide à affiner les sorties en fonction de critères de qualité. Voir des exemples de ce à quoi ils peuvent ressembler ici.

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

6

Entraînez votre modèle

Nous avons présélectionné des hyperparamètres pour des résultats optimaux mais vous pouvez les modifier. Lisez tout sur les paramètres ici. Pour GRPO avancé documentation sur le batching, la génération et les paramètres d'entraînement, lisez notre guide !

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.

circle-check

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

circle-exclamation

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'à obtenir les sorties souhaitées avec de longues chaînes de raisonnement.

7

Exécuter et évaluer votre modèle

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

model.save_lora("grpo_saved_lora")
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.

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'environ une heure - il s'améliorera si nous augmentons la longueur de la séquence et nous entraînons plus longtemps !

Vous pouvez ensuite enregistrer votre modèle au format GGUF, Ollama, etc. en suivant notre guide ici.

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.

8

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

Enregistrement en précision 16 bits

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

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

Publier sur Hugging Face Hub

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

# Pousser vers Hugging Face Hub (nécessite un token)
model.push_to_hub_merged(
    "votre-username/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.

model.push_to_hub_gguf(
    "votre-username/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.

Tutoriels vidéo

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

Idéal pour apprendre à préparer votre jeu de données et les explications sur l'apprentissage par renforcement + les bases du GRPO
GRPO local sur votre propre appareil

Mis à jour

Ce contenu vous a-t-il été utile ?