Data, rewards and evaluation
The structured workflow prepares data in the GPU job where mounts and tokenizer are available. It records preparation under the run root; do not place reference assistant solutions into training prompts. See workflow for paths.
Selecting data
Choose exactly one mode under [data]:
| Mode | Contract |
|---|---|
[[data.tasks]] |
Named tasks with train/eval counts and optional prompt wrapper |
rl_manifest |
Adopt an immutable prepared manifest and supported verifier bindings |
prompt_data |
Prepared JSONL; supply reward_config and optional alternating dataset-name/eval-path entries |
recipe |
Rejected: named recipes are not supported |
Current named tasks are gsm8k, gsm8k-less-noise, gsm8k_original, math, legacy ifeval, and
generated multiplication. Dataset IDs/revisions live in open_instruct/miles/datasets/run_data.py.
gsm8k uses the established ai2-adapt-dev/rlvr_gsm8k_zs train split.
gsm8k_original remains a compatibility alias for the same pinned dataset,
retaining its historical sampling seed convention.
The maintained dev example uses gsm8k-less-noise, which selects
techarb/gsm8k-cleaner, an
informally cleaned variant that has not been rigorously validated. It has 39
corrected targets and omits 93 problems judged ambiguous or unreliable, leaving
7,380 rows. Each prepared row records metadata.original_row, its index in the
original dataset.
For fresh preparations that previously selected the cleaned data as gsm8k, use
task = "gsm8k-less-noise". It retains that variant's sampling seed convention;
task names and prepared sample IDs identify it explicitly. Equal seeds across the
original and cleaned datasets do not select the same problems. Existing prepared runs retain their immutable
data on resume; keep their original configuration rather than renaming the task
inside an existing preparation contract.
Fresh preparations select training rows first, independently of eval_count,
then select held-out rows from the remainder. This can change selections compared
with older preparations that sampled both partitions together. Existing prepared
runs reuse their recorded data unchanged. For named source datasets, the train
component in prepared_sample_id identifies the source split, including when the
row is assigned to this run's held-out partition; it is not a training assignment.
The single-node example takes prepared math, instruction-following and code JSONL with a verifier registry, without judge-dependent tasks; its placeholder paths do not identify the complete published Olmo 3 mixture. Use manifest adoption when starting from dataset manifests. Unsupported task/verifier contracts fail rather than silently substituting a different judge or reward.
The trusted verifier registry names factories and configurations; individual
samples select registered names, targets and weights. Preparation writes the
resolved registry to prepared/data/verifiers.json. Code verification may
need an externally provisioned service. GPU judges have an explicit preparation,
service and rubric contract in managed judges; launch does not
automatically supply every Olmo 3 external service.
prompt_wrapper supports the task-specific contracts in the preparation code.
Review rendered prompts and answer format after changing it. A familiar task
name or equal split count does not prove identical questions or reward semantics.
Three-node training mixture
three-node.toml targets the full train split of
allenai/Dolci-Think-RL-7B,
pinned to revision 0fb6466d31ef3a9dd16985ef635e6429e05a6491.
This is the dataset selected by the checked-in
Olmo 3 7B Think RL recipe.
The dataset card
reports these source-group counts:
| Source group | Rows |
|---|---|
| Math | 30,180 |
| Instruction following | 29,813 |
| Code | 21,385 |
| General | 20,636 |
| Total | 102,014 |
Prepare every source row once, preserving the published proportions, source
identities, verifier names and targets. Do not substitute a balanced four-domain
basket, an RLZero mixture or a smoke-test subset. Render and tokenize prompts with
the selected policy checkpoint; the source's saved token IDs belong to its original
tokenizer. Preserve the full question for judged examples in metadata.judge_query.
The trusted verifier registry must support math, code/code_stdio and instruction
following; general-quality and general-quality_ref use the template's named bindings.
Code verification requires an externally provisioned service.
The dolci-think-rl-7b paths in the template are prepared-artifact placeholders,
not an automatic Hugging Face download or proof of provenance. Before launch,
record the source ID/revision and verify row counts, source-group counts and retained
identities against the pinned source. Record any deliberate exclusions as a changed
mixture; do not silently filter rows to satisfy the policy's prompt-length limit.
Use the existing prepared-JSONL or immutable-manifest input contract. Background
benchmark evaluation is configured separately and does not change this training mix.
Online group filtering
MILES/Core training defaults to online reward-group filtering:
[training]
filter_zero_std_groups = true
The low-level equivalent is core.filter_zero_std_groups. By default the compiler resolves
this to miles.dynamic_sampling_filter_path =
"miles.rollout.filter_hub.dynamic_sampling_filters.check_reward_nonzero_std";
plan records the effective native path. The native filter keeps a complete prompt
group only when the standard deviation of its selected reward scores exceeds
1e-8. All-0, all-1 and other constant-reward groups are discarded before trainer
packing/scoring. Mixed groups retain every response, including zero-reward ones.
This requires more than one training response per prompt. Evaluation is unfiltered
and may still use one response per prompt.
With custom_reward_post_process_path="open_instruct.miles.rewards.truncation.exclude_truncated",
the compiler instead selects the built-in finished-response filter. It ignores
truncated responses when checking reward variation and drops groups with fewer
than two finished responses. A reward earned by unfinished text cannot keep an
otherwise constant-reward group in the training batch.
Generation continues until the configured number of accepted groups fills the
collection; global batch size counts retained responses. This works with barrier,
engine-drain and mixed-policy refresh publication. Async filtering occurs before
completed-buffer admission, after checking group provenance; staleness is still
checked at consumption. Filtered groups are dropped, even when
async_unused_samples_handler="retry", and retired from the checkpoint retry
ledger. Their prompts remain eligible on later dataset passes.
Filtering saves trainer work but still pays generation and verification costs.
A low acceptance rate increases collection time; if every group is rejected,
collection waits for useful data and cannot advance the policy. The tiny dev
mechanics example therefore explicitly sets this switch to false.
Monitor rollout/dynamic_filter/drop_zero_std_0.0,
rollout/dynamic_filter/drop_zero_std_1.0 and the corresponding counters for other
constant rewards, together with trainer wait time and accepted task proportions.
These are per-report drop counts, not accuracy estimates. Use unfiltered held-out
evaluation to assess learning.
Zero group-relative advantage removes the reward-driven policy-gradient signal, but the discarded responses would still affect loss normalization and any enabled KL, entropy or router auxiliary objectives. Treat enabling filtering as a recipe change and compare learning at matched wall time or generated-token budgets. Do not change filtering in-place and call the run a resume.
Offline preprocessing remains compatible and can reduce online rejection rates.
The existing correctness filter
scores saved completions and retains prompts within inclusive average-score bounds.
Its default [0, 1] bounds retain all prompts; use bounds strictly inside that range
to exclude all-wrong/all-correct prompts for binary rewards. This is a snapshot of
an earlier policy, so newly sampled groups can still have constant rewards after
preprocessing. Online filtering continues to check the current groups. For graded
rewards, average-score filtering and zero-variance filtering are different tests.
Advanced custom native filters require core.filter_zero_std_groups=false to
avoid conflicting with the built-in selection. They remain unsupported with
refresh or engine-drain publication; those modes allow only the built-in filter.
Held-out evaluation and comparison
Specify eval_count per task, or explicit held-out files. The structured defaults use greedy evaluation, one response per question, initial evaluation and periodic evaluation every 20 collections when held-out data exists. Examples can override these values; inspect plan. Eval shares rollout engine admission and cache limits.
Retain question IDs, rendered prompt/token IDs, generations, rewards, lengths, cap hits, policy versions and source/config provenance. Compare update zero on the same checkpoint before interpreting learning differences. For matched studies use the same immutable held-out set, template, sampling, response limit and reward implementation. Examine paired answer changes rather than just aggregate scores.
Rollout dumps are trusted tensor artifacts on WEKA; do not load arbitrary external pickle files. The small Beaker reports are an index into the larger retained artifacts, not a replacement for per-sample auditing. See operations.
Reward-service failure policies
MILES inherits the existing Open Instruct GRPO verifiers' default of assigning zero reward when judge or code-service requests fail after retries. This keeps training running through transient failures, but a fallback zero is an ungraded response. In a group with successfully graded responses, it can affect relative advantages as though the response were incorrect. Failures correlated with response content or length can therefore bias learning. Use the strict policies below when failed grading should stop the run.
Service-error and timeout metrics cover the consumed collection, after group filtering. Dropped groups are absent from those fractions, so the metrics can understate failures. With zero-variance filtering enabled, a total outage can prevent a collection from filling and produce no new collection metrics at all. Inspect individual failure warnings as well; a low or missing error fraction does not establish service health.
Code-service failure policy
Code rewards default to Open Instruct's zero-reward continuation behavior. After existing HTTP retries are exhausted, a transport/gateway failure or invalid service reply receives zero reward, logs a warning, and leaves the rollout running. This is a fallback reward, not proof that the generated code failed its tests. Existing HTTP rejection handling is unchanged.
Set OI_MILES_CODE_FAILURE_POLICY = "raise" in [launch.env] for strict
service-failure handling, or set failure_policy to "zero" or "raise" in
the code verifier's trusted JSON config. An explicit verifier setting takes
precedence over the environment. Configuration errors and cancellation still
propagate; known-answer preparation canaries use strict mode.
Per-sample diagnostics distinguish service_error, rejected, and successful
grading. W&B records rollout/code_verifier/service_errors and
rollout/code_verifier/service_error_fraction, with status breakdowns alongside
the existing rejection counters. The fraction covers code verifier calls in
the consumed collection; it is not the fraction of HTTP attempts or all
samples generated. Retain these metrics when comparing learning curves.
General judge failures
Judge transport failures and invalid or incomplete replies default to zero
reward after retries, with a warning and per-sample judge_error diagnostics.
Set OI_MILES_JUDGE_FAILURE_POLICY="raise" in [launch.env] to stop on those
failures. Detected context overflow and configuration errors raise regardless
of that fallback policy. The three-node example explicitly selects "zero" for judge
failures; both node and three-node select it for code-service failures. Change those
settings to opt into strict handling. Managed judge health-check failures separately stop
training; the fallback applies to grading requests.
Symbolic math timeouts
Symbolic math runs in a bounded subprocess pool. An individual request exceeding
45 seconds kills and replaces that worker and defaults to reward zero. The sample
retains verifier_diagnostics with kind=math, status=timeout and elapsed time;
rollout/math_verifier/timeouts and timeout_fraction count these separately from
ordinary incorrect answers. Set OI_MILES_MATH_TIMEOUT_POLICY=raise for strict
handling. Configuration errors, unexpected worker failures and cancellation
still propagate. A timeout-zero is an ungraded sample, not proof of a wrong
mathematical answer; include the timeout rate when interpreting benchmark scores.
Independent background evaluation
For best-effort external olmo-eval jobs and checkpoint-axis W&B curves, see background evaluation. Selecting this mode replaces shared-engine evaluation; failed or skipped jobs leave gaps without blocking training.