RLVR — Reinforcement Learning from Verifiable Rewards

v0.25.0 adds deterministic reward signals for GRPO training on math, code, and JSON-schema tasks. No reward model, no human labels.

Enable it

yaml
base: Qwen/Qwen3-8B
task: grpo

data:
  train: math_problems.jsonl
  format: chatml

training:
  reward_fn: verifiable
  verifiable_domain: math   # math | code | json_schema
  lr: 1e-5
  epochs: 1
  lora: { r: 16, alpha: 32 }

Built-in reward functions

DomainWhat it doesSandbox
mathRegex-extracts the final answer, compares numerically with tolerancepure Python
codeExecutes Python against expected outputsbest-effort sandbox: subprocess, 5 s timeout, 10 KB output cap, 512 MB address-space limit on POSIX. Network isolation is not guaranteed (see Safety)
json_schemaValidates output against a JSON Schema and scores completenesspure Python

All three live in soup_cli/trainer/rewards.py and are routed through the existing GRPO trainer.

Generate training data

bash
soup data generate \
  --prompt "Math word problems, each with a single exact numeric answer" \
  --provider ollama --count 500 --output verifiable.jsonl

--prompt is required, and --template accepts only code, conversation, qa, preference and reasoning; there is no verifiable template and no flag that selects the verifiable helper (--domain exists, but it only picks the domain of the reasoning template). soup_cli/data/templates/verifiable.py builds problems with ground-truth answers you can verify at training time, but it is a library helper with no command-line selector.

Safety

  • code_exec is a best-effort sandbox, not an isolation boundary, and Soup says so in a warning panel the first time it runs. Each completion runs in a short-lived subprocess started with python -I -S, with a 5 s timeout, a 10 KB output cap, a throwaway working directory and a reduced environment. On Linux and macOS it also gets resource limits (512 MB address space, CPU time, file size, open files, processes); on Windows it gets none of those. There is no restricted-builtins mechanism.
  • Network access is not blocked reliably. The guard is a Python-level socket patch, and generated code can bypass it through os.system, subprocess or ctypes. OS-level isolation is added only on Linux with Python 3.12 or newer (the os.unshare call, and only if the kernel allows unprivileged user namespaces; otherwise it falls back silently) and on macOS through sandbox-exec. Do not use verifiable_domain: code on a host that holds secrets or on untrusted data; run training in a container or VM with no network interface. Soup Cans v2 describes the same isolation tiers.
  • math_verify never uses eval() on model output — answers are extracted by regex.
  • verifiable_domain is a Pydantic Literal so arbitrary strings can't reach the dispatcher.

See also

  • Training methods — GRPO
  • Autopilot — --goal reasoning writes task: grpo and leaves reward_fn at its default of accuracy; set reward_fn: verifiable yourself to use RLVR

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.