feat: add Verifiers rollout integration - #1739
Conversation
There was a problem hiding this comment.
Code Review
This pull request integrates Verifiers environments into Miles, allowing training on Verifiers tasksets and harnesses. It introduces the VerifiersRolloutFn adapter, a custom MilesSGLangTransport for translating requests, CLI argument parsing and validation for --verifiers-config, and corresponding documentation and tests. The review comments identify two key issues: a potential TypeError in evaluation when computing average rewards on dictionary-structured rewards, and an unbounded memory leak in MilesSGLangTransport due to the _seen_sessions set growing without limit.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
f867c8e to
5941d62
Compare
| @@ -0,0 +1,111 @@ | |||
| --- | |||
| title: Verifiers | |||
There was a problem hiding this comment.
"Verifiers" can mean general verifiers in RL setup. Could you change to Verifiers (Prime Intellect) or Prime Intellect Verifiers to avoid confusion?
| | `--rollout-stop` | str+ | – | Stop strings. | | ||
| | `--rollout-stop-token-ids` | int+ | – | Stop token IDs. | | ||
|
|
||
| ### Rollout: Verifiers |
There was a problem hiding this comment.
Could you change this section to Environment Integrations so that flags for other environment solutions can all go here?
| | [Monitoring & Logging](/user-guide/monitoring) | wandb, structured logs, per-source breakdowns, profiling, router metrics. | | ||
| | [Customization](/user-guide/customization) | The 21 `--*-path` plug-points for custom Python — rollout, reward, filters, loss, hooks. | | ||
| | [Rollout Endpoints](/user-guide/rollout-endpoints) | The `/generate` endpoint and the OpenAI chat endpoint for agentic sessions. | | ||
| | [Verifiers](/user-guide/verifiers) | Train on Verifiers tasksets and harnesses. | |
There was a problem hiding this comment.
I added a docs section for environments so that you can put Verifiers there. Could you rebase to #1833?
| args.eval_datasets = _resolve_eval_datasets(args) | ||
|
|
||
| if args.verifiers_config is not None: | ||
| args.rollout_function_path = VERIFIERS_ROLLOUT_FUNCTION_PATH |
There was a problem hiding this comment.
Raise exception if user already set args.rollout_function_path or args.rollout_global_dataset(e.g. multi-lora)
Apply the review feedback from radixark#1739: retitle the page to 'Verifiers (Prime Intellect)' to disambiguate from RL reward verifiers, relocate it from the core User Guide track into the Environments group (added in radixark#1833) with a connectors-table row, drop the user-guide index row (second-level pages are not listed there), and rename the cli-reference section to 'Environment Integrations' so flags of other environment integrations can share it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…claimed Apply review feedback from radixark#1739: --verifiers-config silently overwrote a user-supplied --rollout-function-path, and multi-LoRA (which forces the global prompt dataset back on and swaps in its own rollout function after this block runs) crashed later in data loading with an unrelated error. Raise a clear ValueError for both combinations, with tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
nblintao
left a comment
There was a problem hiding this comment.
I've fixed my comments above.
5277580 to
d2be6da
Compare
# Conflicts: # miles/utils/arguments.py # setup.py # tests/fast/utils/test_arguments.py
… compatibility - Retitle the docs page to 'Verifiers (Prime Intellect)' and move it into the user guide's Environments section, with a connectors-table row; rename the cli-reference section to 'Environment Integrations'. - Reject --verifiers-config combined with a custom --rollout-function-path or with multi-LoRA instead of silently overriding them, with tests. - Survive a CI image without the optional [verifiers] extra: importorskip guards for the tests that import renderers or verifiers at call time, and read verifiers_config with getattr for the partial-Namespace callers in main's validation tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
a696380 to
5ce462f
Compare
|
|
||
| if args.eval_interval is not None: | ||
| # A custom rollout/eval function supplies its own evaluation work (an environment | ||
| # taskset, a benchmark suite, ...); only the built-in path reads --eval-prompt-data. |
There was a problem hiding this comment.
I am not entirely sure about this change... I think it's debatable and merits a standalone PR. Also the assertion message might need updates.
How about this: for this PR we disable --eval-interval in the Verifiers example, or simply set a dummy eval_datasets in the args, to sidestep this assertion. Then let's open another PR dedicated to this args change.
There was a problem hiding this comment.
Yeah, I think we can use dummy eval_datasets to workaround for now. We can revisit when there is another similar case in the future.
5ce462f to
7633ec5
Compare
84a38a0 to
3cd88f8
Compare
Every other environment integration (Harbor, OpenEnv, NeMo-Gym, Strands,
tau-bench) lives under examples/ and wires itself in through the generic
plug-point flags, leaving no footprint in miles/. This one arrived with a
dedicated --verifiers-config flag, a validation block in
miles_validate_args, and the adapter inside miles/rollout/; move it to the
same shape as the others, so this PR touches no core file at all.
The trace-to-Sample conversion, the SGLang transport, and the batch
orchestration are unchanged. What changes is how the adapter is reached:
- The rollout function is selected with the existing
--rollout-function-path, and the taskset replaces prompt data with the
existing --disable-rollout-global-dataset. run.py sets both, plus the
PYTHONPATH that resolves the bare module inside the rollout actor -- the
same mechanism the other examples use for their agent functions.
- The EnvConfig path arrives in VERIFIERS_CONFIG rather than a Miles flag,
matching NEMO_GYM_URL and the OPENENV_* variables.
- The unsupported-combination checks move from miles_validate_args into
the adapter's constructor, which still runs before any episode does, so
a hand-rolled command fails loudly instead of training on wrong data.
- The optional dependencies move from a setup.py extra to
examples/experimental/verifiers/requirements.txt.
- Evaluation keeps working: Miles asserts that eval datasets are
configured whenever --eval-interval is set, so run.py names the taskset
and points a placeholder --eval-prompt-data at the EnvConfig it is
defined in. The adapter serves eval, so the built-in loader never opens
that path. Scoping the assertion instead is proposed separately.
Unit tests stay under tests/fast/ and import the adapter by package path
so CI keeps running them; tests/ci only discovers tests/{fast,fast-gpu,e2e,ci}.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # docs/user-guide/environments.md
3cd88f8 to
9d0340b
Compare
|
thanks!! |
Summary
Add an opt-in Verifiers V1 rollout adapter selected by one new argument:
The adapter loads a V1
EnvConfig, lets Verifiers own grouped episode execution and reward computation, and returns ordinary MilesSamplegroups. Miles continues to own model selection, sampling settings, concurrency, filtering, reward overrides, advantages, and optimization.flowchart LR C["Miles CLI + EnvConfig"] --> V["Verifiers V1 environment"] V --> R["Renderers TrainClient"] R --> S["Miles SGLang /generate"] S --> T["Verifiers traces + group rewards"] T --> M["Miles Sample groups"] M --> O["Miles advantages + optimizer"]This deliberately follows Miles' existing rollout-function extension point instead of changing shared sample conversion or advantage code.
Configuration and ownership
--verifiers-configreplaces the prompt dataset with the configured V1 taskset.--hf-checkpointand--sglang-tokenizer-pathprovide model and renderer identity; no duplicate Verifiers model option is added.--n-samples-per-promptand--n-samples-per-eval-promptdefine each fixed rollout group.The optional dependency group uses
verifiers>=0.2.0,<0.2.1,renderers>=0.1.8, and the compatibleopenai-agentsrange. The ceiling is intentional: Verifiers 0.2.1 requires OpenAI >=2.9 while the current SGLang 0.5.15 dependency pins OpenAI 2.6.1. Supporting 0.2.1 should follow once that upstream dependency constraint is compatible.Supported scope
The adapter supports text-only V1 environments using the Chat Completions dialect, including grouped rollouts and group-level reward computation in both training and evaluation. It also preserves structured prompts, exact sampled token IDs/logprobs, Miles reward hooks, dynamic oversampling/filtering, LoRA requests, and consistent-hash session routing.
Unsupported combinations fail explicitly rather than retrying indefinitely:
The graph-branch restriction is intentional for this first integration. Miles currently flattens multiple training samples without preserving the enclosing Verifiers trace-group boundary, so accepting these traces would silently compute the wrong group-relative advantages. Single-branch multi-turn and tool traces are supported.
Validation
Automated
433 passed, 29 skippedacrosstests/fast/rollout74 passedin the focused adapter, V1 runtime contract, argument, and sample-conversion suitesReal two-GPU end-to-end run
Qwen3-0.6B completed a full Miles optimizer update on Verifiers'
code-golf-v1environment:0.9167, range[0, 2]fastestgroup-reward sums were exactly0.5W&B run
Learning signal
Qwen3-4B-Instruct completed 50 Miles updates on
reverse-text-v1(3,200 trajectories) with no Verifiers errors, non-finite values, or token-alignment failures:0.28070.58910.01511before training to0.55511after training (+0.5400)[0.49878, 0.57921]W&B run
Documentation
The user guide documents installation through the optional Miles extra, Prime CLI environment installation (
./environments,prime env install ...), the single added configuration option, ownership boundaries, and unsupported cases. The implementation follows the rollout-function integration pattern used by prior merged work such as #1487 and #1633.