grpo-rlvr-training

Par wshobson · agents

Entraînez le raisonnement et les comportements sur des tâches vérifiables avec GRPO et le reinforcement learning from verifiable rewards (RLVR). À utiliser lorsque le succès d'une tâche est vérifiable algorithmiquement (mathématiques, code, tool calls, structured output), lors de la conception de fonctions de récompense GRPO, ou lorsqu'un run GRPO diverge ou présente du reward hacking.

npx skills add https://github.com/wshobson/agents --skill grpo-rlvr-training

Entraînement GRPO & RLVR

Cette compétence suppose que finetuning-method-selection vous a déjà orienté ici parce que le comportement cible possède un signal de succès/échec vérifiable — pas des démonstrations (lora-qlora-recipes) ni des paires de préférence (preference-optimization). Ce qui suit couvre quand l'RL est l'outil approprié, la recette de référence, la porte d'inspection des récompenses obligatoire, et comment choisir une variante GRPO quand la recette de base se comporte mal.

Entrée : une décision de routage (RLVR via GRPO) plus un vérificateur (exécuteur de code, suite de tests, vérificateur de schéma, ou évaluateur) pour la tâche cible. Format de sortie : une configuration GRPO validée — les valeurs kwarg dans references/grpo-memory.md et les fonctions de récompense dans references/reward-functions.md, pas des conseils libres — que llm-finetuning-training-engineer consomme directement.

Quand l'RL s'applique

GRPO+RLVR n'est rentable que quand le succès de la tâche est algorithmiquement vérifiable — un test unitaire passe, un parseur accepte la sortie, un appel d'outil correspond à un schéma attendu, une réponse mathématique correspond à une vérité terrain. Si évaluer la sortie nécessite un jugement humain ou une rubrique subjective, c'est d'abord un problème d'eval-harness et de calibration du juge — voir eval-harness-first — pas une raison de sauter directement à l'RL.

Avant de lancer une exécution GRPO, confirmez que le modèle peut parfois réussir sur la tâche cible déjà. L'RL affine une capacité existante en repondérant vers les échantillons qui fonctionnent déjà ; il n'installe pas une capacité à partir de zéro.

  • Le modèle ne réussit jamais, même à basse température sur de nombreux échantillons : l'écart est lié au format ou à la compréhension de la tâche, pas au raffinement de la politique. Retournez d'abord à l'SFT (lora-qlora-recipes) et ne revenez à cette compétence que quand le taux de succès de base est non nul.
  • Le modèle réussit parfois, de manière inconsistante : c'est le sweet spot de GRPO — procédez à La Recette ci-dessous.

La règle permanente pour tout le plugin : DPO pour le goût, GRPO pour le raisonnement. Si le signal est une préférence entre deux sorties acceptables, c'est preference-optimization, pas cette compétence.

La Recette

La recette de référence est le GRPOTrainer de TRL avec génération backed par vLLM :

from trl import GRPOConfig, GRPOTrainer

grpo_args = GRPOConfig(
    output_dir="./outputs-grpo",
    use_vllm=True,
    vllm_mode="colocate",       # single GPU; "server" pour multi-GPU
    num_generations=8,          # minimum — moins affame le baseline relatif au groupe
    learning_rate=5e-7,         # plage stabilisée pour GRPO
    beta=0.01,                  # coefficient KL vs la politique de référence
    per_device_train_batch_size=8,
    gradient_accumulation_steps=4,
    bf16=True,
    logging_steps=10,
    seed=3407,
)

trainer = GRPOTrainer(
    model=SFT_CHECKPOINT,
    args=grpo_args,
    reward_funcs=[format_reward, correctness_reward],   # references/reward-functions.md
    train_dataset=prompts,       # prompt-only — GRPO génère ses propres complétions
    processing_class=tokenizer,
)

trainer.train()
  • vllm_mode="colocate" exécute la génération et l'entraînement sur le même GPU — la valeur par défaut pour une box single-GPU.
  • vllm_mode="server" pointe vers un processus serveur vLLM séparé et est le chemin multi-GPU — la génération et l'entraînement ne concurrencent pas le même device.
  • num_generations ≥ 8 est un minimum, pas une suggestion : l'estimation d'avantage de GRPO est relative à la moyenne du groupe, et moins de 8 échantillons par prompt produit un baseline bruyant.
  • La récompense est composite — une récompense de format (la sortie a-t-elle parsé / correspond-elle à la structure requise) plus une récompense de correction (la réponse a-t-elle vérifié). Une réponse bien formée mais incorrecte et une malformée ne devraient pas avoir le même score ; la correction seule perd ce signal.
  • learning_rate=5e-7 et beta=0.01 sont le point de départ stabilisé ; ne déviiez que après que la exécution de base soit stable et que la récompense soit inspectée (ci-dessous).

Dimensionnement mémoire pour cette recette par classe de taille cible : references/grpo-memory.md.

La Règle d'inspection

Exécutez la fonction de récompense contre 50–100 sorties échantillonnées et lisez manuellement les résultats avant de démarrer la exécution d'entraînement réelle. C'est une porte, pas un contrôle de santé une seule fois.

Si le jugement de la fonction de récompense ne s'accorde pas avec une lecture humaine de cet échantillon, corrigez d'abord la fonction de récompense. L'entraînement contre une récompense non inspectée, ou l'ajustement des hyperparamètres pour en compenser une qui note silencieusement la mauvaise chose, c'est comment une exécution fait du reward-hacking : le modèle optimise proprement vers la mauvaise cible, et ça ne remonte pas comme un bug de boucle d'entraînement.

Cette inspection est une entrée de porte Phase 1 pour /finetune — la même lecture d'échantillon 50–100 qui détecte une fonction de récompense cassée ici est ce que cette commande vérifie avant de laisser un brief GRPO procéder.

Implémentations complètes de fonction de récompense à inspecter — exact-match, validation de schéma, exécution de test unitaire, un wrapper de pénalité de longueur, et un motif de juge-as-reward basé sur rubrique : references/reward-functions.md.

Sélection de variante

La recette de base ci-dessus est la valeur par défaut. Recourez à une variante seulement quand un mode d'échec spécifique se manifeste, pas préventivement :

Mode d'échec Variante Pourquoi
Effondrement d'entropie / chaîne dégénérée de chain-of-thought DAPO Découple les bornes de clipping et assouplit la pénalité KL qui sur-régularise l'exploration sur les traces de raisonnement long
Tendance de la longueur de récompense ou de sortie à augmenter indépendamment de la qualité Dr.GRPO Supprime le biais de normalisation de longueur de GRPO pour que la récompense suive la correction, pas la longueur de complétion
Entraînement d'un modèle mixture-of-experts GSPO Déplace le ratio d'importance-sampling au niveau de la séquence au lieu de per-token — les ratios per-token sont instables sur le routage MoE, donc GSPO est requis ici, pas optionnel

Commencez avec GRPO simple. Observez le symptôme spécifique — effondrement d'entropie sur long CoT, une corrélation longueur-récompense, ou instabilité MoE — et seulement alors remplacez par la variante correspondante ci-dessus. Ne pré-sélectionnez pas une variante avant que la recette de base n'ait réellement montré le mode d'échec.

VLM RL est Référence uniquement

L'RL vision-language n'est pas exécuté par ce plugin en v1 — c'est documenté ici pour contexte, pas comme un chemin runnable. Les outils sont fragmentés entre ms-swift et des forks dérivés d'EasyR1 sans commande TRL one-line encore, et le GRPO text-only naïf appliqué à un VLM tend à faire du reward-hacking en optimisant la trace de raisonnement textuel tout en ignorant l'image — le modèle apprend à sonner juste sans regarder l'entrée. Une exécution VLM RL est un spike de recherche en dehors de la recette supportée de cette compétence, pas une variante de La Recette ci-dessus.

Références

  • references/reward-functions.md — fonctions de récompense Python complètes (correction exact-match, validation de schéma, exécution de test unitaire, un wrapper de pénalité de longueur, et un motif de juge-as-reward basé sur rubrique) à inspecter sous La Règle d'inspection avant toute exécution d'entraînement.
  • references/grpo-memory.md — dimensionnement mémoire par classe de taille cible, tactiques de sleep-mode vLLM et d'optimizer-state, chunking RL long-context d'Unsloth, et la mise en garde de bande passante DGX Spark pour les rollouts decode-heavy.

Compétences liées : finetuning-method-selection vous oriente ici une fois qu'un signal pass/fail vérifiable existe ; preference-optimization est la compétence sœur pour les paires de préférence plutôt que les récompenses vérifiables ; eval-harness-first couvre la calibration du juge pour toute récompense qui n'est pas purement vérifiable par code. Sur DGX Spark, déférez aux compétences du plugin dgx-spark-ops, quand installé, pour l'échelle de remédiation mémoire/thermale que la table mémoire de cette compétence ne couvre pas.

Skills similaires