GRPO Plus (v0.50.0)

22 features. Unsloth + axolotl GRPO parity.

7 GRPO variants

yaml
task: grpo
training:
  grpo_variant: gspo   # standard | gspo | dapo | dr_grpo | bnpo | two_sided | rft
  grpo_delta: 0.5      # required for two_sided, optional for gspo (clip radius,
                       # default 0.2). (0, 1]. Rejected on every other variant
  grpo_fp16: true      # explicit FP16 mixed precision

Long-context & vision GRPO

yaml
task: grpo
base: Qwen/Qwen2-VL-7B-Instruct   # vision_grpo needs a base from the VLM allowlist
modality: vision                  # and the vision modality, or it is refused
training:
  long_context_grpo: true   # validation gate only
  vision_grpo: true         # validation gate only
  vllm_sleep_mode: true     # free vLLM memory between rollouts

long_context_grpo and vision_grpo are validation gates, not features: they check the task, the backend and, for vision, a known VLM base, and nothing reads them afterwards. long_context_grpo does not extend rope scaling into rollouts, and no Tiled MLP code stands behind it. vision_grpo does not make GRPO multimodal: the GRPO trainer loads the base with AutoModelForCausalLM and a tokenizer, not a vision processor. vllm_sleep_mode is read by the GRPO trainer.

Async rollout backends

yaml
task: grpo
training:
  rollout_backend: openenv   # art | ruler | nemo_gym | openenv
  rollout_func: soup_cli.envs.calculator:rollout   # required by openenv

openenv is the only backend that runs at v0.75.2. rollout_func is a module:function that receives the dataset prompts as seeds and returns the rows GRPO then trains on, which replace the dataset's prompts. It is not given the model and runs no interactive multi-turn episodes; the bundled soup_cli.envs.calculator:rollout is a single-shot seeder (see PRM-guided GRPO). art (OpenPipe ART), ruler and nemo_gym are accepted names whose adapters are not wired: they raise an ImportError naming the missing package, and a "not yet validated" error when it is installed.

Stability knobs (accepted; mostly record-only)

yaml
task: grpo
training:
  ref_model_ema_alpha: 0.99   # EMA-style ref refresh
  replay_buffer_size: 50000
  tis_threshold: 1.5          # truncated importance sampling
  mask_truncated_completions: true
  defer_rerolling: true
  skip_zero_advantage: true
  off_policy_mask_threshold: 0.7
  async_grpo_prefetch: true

At v0.75.2 these eight keys are accepted for task: grpo and attach a callback that writes counters (replay_size, tis_alerts, ema_alpha) into the training log, and that is nearly all it does. async_grpo_prefetch, mask_truncated_completions, defer_rerolling, skip_zero_advantage and off_policy_mask_threshold do not change what the trainer does: the callback's own notes call them advisory, a hint or record-only. The replay buffer is never fed and the TIS counter is never called. ref_model_ema_alpha can only act if the callback is handed a separate reference model, and the Hugging Face callback handler does not hand it one, so there is nothing for it to update; a LoRA run has no separate reference model anyway (read from the code, not run on a GPU). What does work on this page: the seven grpo_variant objectives, grpo_delta, grpo_fp16, vllm_sleep_mode and the openenv rollout.

New task: prm

task: prm (Process Reward Model) wired through the standard reward-model trainer. Gates: vision + GRPO compat checked.

v0.50.0 shipped the schema. v0.53.3 wired grpo_fp16 routing + the known-VLM-base gate for vision_grpo; v0.53.11 lit up real loss kernels for every non-standard variant (gspo / dapo / dr_grpo / bnpo / two_sided / rft) via make_grpo_trainer_variant, made task: prm live with per-step MSE + reward head, and attached GRPOStabilityCallback, which logs counters for the stability knobs above (most of them are record-only, as that section says). See v0.53.11 — GRPO Plus finish.

Soup is free and Apache-2.0. If it saved you a training run, starring the repo costs nothing and helps most. You can also fund the GPU time behind the work a 4 GB laptop cannot reach.