Skip to content

feat: configurable env vars#2863

Merged
samsja merged 2 commits into
mainfrom
feat/consolidate-env-vars
Jun 28, 2026
Merged

feat: configurable env vars#2863
samsja merged 2 commits into
mainfrom
feat/consolidate-env-vars

Conversation

@mikasenghaas

@mikasenghaas mikasenghaas commented Jun 24, 2026

Copy link
Copy Markdown
Member

Summary

Consolidate environment-variable handling for RL and SFT: env vars are set per component from config, with one precedence model applied uniformly across single-node and multi-node (SLURM) launches.

  • Per-component env_vars: [trainer.env_vars], [orchestrator.env_vars], [inference.env_vars] (RL) and [sft.env_vars] (SFT). Disaggregated inference keeps deployment.{prefill,decode}_env_vars layered on top per role.
  • Single source of truth for launcher defaults in utils/process.py: DEFAULT_COMMON_ENV_VARS (every component), DEFAULT_TRAINER_ENV_VARS, DEFAULT_INFERENCE_ENV_VARS. No static defaults are hardcoded in the sbatch templates anymore.
  • Precedence (low → high): os.environ < launcher defaults < [component.env_vars] < protected (CUDA_VISIBLE_DEVICES, WANDB_SHARED_*). Single-node builds the env inline at each launch site; multi-node templates loop the merged dict; standalone uv run inference applies it in inference_local.
  • Protected vars are enforced, not just documented: setting CUDA_VISIBLE_DEVICES or WANDB_SHARED_* in any env_vars now fails config validation (reject_protected_env_vars / PROTECTED_ENV_VARS).
  • Deep-GEMM (VLLM_USE_DEEP_GEMM/VLLM_MOE_USE_DEEP_GEMM) is driven solely by config.use_deep_gemm via setup_vllm_env — single source (removed the hardcoded template export and a redundant config validator).
  • HF_HUB_OFFLINE and WANDB_SHARED_RUN_ID now read from the environment, falling back to the default if unset.
  • Multi-node uses a single uv sync --all-extras on the batch node; the checkout + venv are expected on a shared filesystem (documented in scaling.md).

Changed defaults

Multi-node values are preserved (just moved into DEFAULT_*). The material changes are single-node parity + two removals:

Path Newly applied / changed
single-node inference now inherits DEFAULT_INFERENCE: PYTORCH_CUDA_ALLOC_CONF=expandable_segments:False, VLLM_WORKER_MULTIPROC_METHOD=spawn, VLLM_ENGINE_READY_TIMEOUT_S=4200 (vLLM 0.23 default is 600), UCX_TLS=all; plus DEFAULT_COMMON (CUDA_DEVICE_ORDER, OMP_NUM_THREADS=1, GIT_LFS_SKIP_SMUDGE). Previously single-node inference set only CUDA_VISIBLE_DEVICES.
single-node RL trainer / orchestrator / SFT now get DEFAULT_COMMON — notably OMP_NUM_THREADS=1 (was unset single-node, i.e. all cores).
all (multi-node) removed TRITON_CACHE_DIR and inference VLLM_CACHE_ROOT.

Breaking

  • Config rename: deployment.prefill_env_overridesdeployment.prefill_env_vars and deployment.decode_env_overridesdeployment.decode_env_vars (no back-compat alias). The one in-repo config using the old names (configs/glm5.2_16node_llmd/inference.toml) is updated; update any external disaggregated configs.
  • Protected keys rejected: a [component.env_vars] (or deployment.{prefill,decode}_env_vars) setting CUDA_VISIBLE_DEVICES or WANDB_SHARED_* now raises at config-parse, instead of being silently ineffective (or, on multi-node, overriding the shared W&B run id). No in-repo config does this.

Docs

  • docs/configuration.md[component.env_vars] model + precedence rules.
  • docs/scaling.md — shared-filesystem venv expectation for SLURM.
  • docs/inference.md — the P/D env-var rename.

Note

Medium Risk
Touches all launch paths (single-node, SLURM, standalone inference) and changes default process environment (e.g. single-node OMP_NUM_THREADS, inference vLLM timeouts), which can affect performance or stability; protected-var validation is a breaking config change for anyone overriding W&B or GPU visibility via TOML.

Overview
Adds configurable env_vars across RL, SFT, and inference, with launcher defaults centralized in utils/process.py (DEFAULT_COMMON_ENV_VARS, DEFAULT_TRAINER_ENV_VARS, DEFAULT_INFERENCE_ENV_VARS) instead of hardcoded exports in sbatch templates.

RL gets top-level [env_vars] plus [trainer.env_vars], [orchestrator.env_vars], and [inference.env_vars]; SFT and inference get their own [env_vars]. Single-node launchers merge defaults → shared → component env at each Popen; SLURM templates loop merged dicts (trainer_env_vars, etc.). Standalone uv run inference applies the same merge in-process before setup_vllm_env.

Disaggregated P/D renames prefill_env_overrides / decode_env_overridesprefill_env_vars / decode_env_vars (breaking, no alias). EnvVars validation rejects CUDA_VISIBLE_DEVICES and WANDB_SHARED_* in user config.

Docs cover precedence and shared-filesystem venv for SLURM. Notable behavior shifts: single-node inference/trainer now inherit the same default env as multi-node; TRITON_CACHE_DIR and VLLM_CACHE_ROOT are removed from templates; WANDB_SHARED_RUN_ID can be preset via the environment.

Reviewed by Cursor Bugbot for commit 676a4fb. Bugbot is set up for automated code reviews on this repo. Configure here.

samsja
samsja previously approved these changes Jun 24, 2026
@samsja samsja force-pushed the feat/consolidate-env-vars branch from 9bcd69a to 566f368 Compare June 26, 2026 01:32
@mikasenghaas mikasenghaas changed the title feat: configurable per-component env vars for RL runs feat: configurable env vars Jun 28, 2026
@mikasenghaas mikasenghaas requested review from S1ro1 and samsja June 28, 2026 18:43
@mikasenghaas mikasenghaas marked this pull request as ready for review June 28, 2026 18:53
@samsja samsja force-pushed the feat/consolidate-env-vars branch 2 times, most recently from 9bf81fb to 285900b Compare June 28, 2026 20:41

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1944a35. Configure here.

Comment thread src/prime_rl/entrypoints/inference.py
Comment thread packages/prime-rl-configs/src/prime_rl/configs/inference.py
@samsja samsja force-pushed the feat/consolidate-env-vars branch from 1944a35 to 7aa4844 Compare June 28, 2026 22:28
samsja and others added 2 commits June 28, 2026 15:30
Add shared env var defaults and per-component env_vars plumbing across RL, SFT, and inference launch paths.

Update launcher filtering, SLURM templates, examples, and docs to match the consolidated env config surface.
@samsja samsja force-pushed the feat/consolidate-env-vars branch from 7aa4844 to 676a4fb Compare June 28, 2026 22:31
@samsja samsja merged commit d700753 into main Jun 28, 2026
17 of 18 checks passed
mikasenghaas added a commit that referenced this pull request Jun 29, 2026
Move the cache-dir env vars out of the SLURM templates and into the config
so the PR only adds the TOML (the merged env-var feature, #2863, makes this
possible):
- [env_vars] TRITON_CACHE_DIR (trainer + inference)
- [inference.env_vars] VLLM_CACHE_ROOT, FLASHINFER_WORKSPACE_BASE

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mikasenghaas added a commit that referenced this pull request Jun 29, 2026
… penalty config (#2905)

* fix(template): orchestrator URLs use canonical model.client path (#2899)

The multinode RL sbatch template launched the orchestrator with
--student.client.{base-url,admin-base-url}, but OrchestratorConfig has no
`student` field — the canonical path is `model.client` (base_url /
admin_base_url on ClientConfig). The orchestrator-config rename left the
template stale, so every multi-node RL launch fails config parsing with
"Unrecognized arguments: <inference URLs>".

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: correct env log glob to logs/envs/<split>/<env>.log (#2898)

* fix: correct env log glob to logs/envs/<split>/<env>.log

Since the nano-as-v1 migration each env writes a single
logs/envs/{train,eval}/<env>.log file (two levels), but the launch
banner still printed three-level globs (logs/envs/*/*/*.log), which
match nothing. Fix the banner generator and the captured example
outputs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs: drop captured launch-banner output from example READMEs

The "Output of the command" blocks duplicated the live launch banner
(now fixed in pathing.py) and drift out of sync. Remove them; the run
command stays.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat: configurable env vars (#2863)

* feat(env): consolidate component env vars

Add shared env var defaults and per-component env_vars plumbing across RL, SFT, and inference launch paths.

Update launcher filtering, SLURM templates, examples, and docs to match the consolidated env config surface.

* feat: add rl-wide env vars (#2897)

---------

Co-authored-by: Sami Jaghouar <sami.jaghouar@hotmail.fr>
Co-authored-by: samsja <55492238+samsja@users.noreply.github.com>

* Update configs for renderer thinking retention (#2900)

* chore: migrate to consolidated Trace/Branch num_ token properties

Bump deps/verifiers to the property consolidation (verifiers #1894) and
rename every prime-rl access of the renamed Trace/Branch properties:

  completion_len / output_len -> num_output_tokens
  prompt_len                  -> num_input_tokens
  rollout total_tokens        -> num_total_tokens

progress.total_tokens, Usage.total_tokens and RunStats.total_tokens are
unrelated and left unchanged; num_turns is unchanged upstream.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: rename length penalty config to num_*_tokens_weight + num_turns_weight

Align the linear length-penalty config (from #2901) with the consolidated
num_-prefixed trace property names:

  [orchestrator.algo.length_pen]  -> [orchestrator.algo.length_penalty]
  completion_pen                  -> num_output_tokens_weight
  input_pen                       -> num_input_tokens_weight
  turns_pen                       -> num_turns_weight

Updates grpo.score_group, the config class, docs, CHANGELOG, and tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: bump verifiers + research-environments to main (#2904)

* chore: bump verifiers + research-environments to main

- verifiers: aa95826d → 97be43bf
- research-environments: 99ebd2e13 → bae0ffe5a
- lock new v1 envs: lean-v1 (6 per-dataset Lean tasksets), prolog-v1
- bump verifiers floor 0.1.15.dev400 → dev404

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: lock remaining research-environments v1 envs

Lock the 21 previously-unlocked RE v1 env packages into the `envs` extra
+ tool.uv.sources, and alphabetize both the `envs` list and the env source
entries.

tau3-bench-v1 is intentionally excluded: it requires tau2 @ git 58e5e1a,
which conflicts with the tau2 @ 337326e pinned by the already-locked
tau2-bench-v1 (uv cannot resolve two URLs for one package).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: drop rlm-swe to remove the verifiers override

rlm-swe pins verifiers>=0.1.15.dev17,<0.1.15.dev156 — a stale upper bound
that conflicts with the editable verifiers submodule (dev404) and with the
other envs / prime-rl-configs. It was the sole reason verifiers needed a
global override-dependencies entry (without it, resolution is unsatisfiable).

Dropping rlm-swe lets us remove that override: verifiers now resolves to the
editable submodule through tool.uv.sources alone. Also prunes rlm-swe's heavy
transitive deps (modal, swebench, swe-rex, pygithub, …) from the lock.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: migrate rlm_swe config dependents to r2e-gym-v1

Dropping the rlm-swe env orphaned its in-repo config dependents:
- examples/glm5_llmd/rl.toml: migrate the v0 `rlm_swe` env block to the v1
  `r2e-gym-v1` taskset on the rlm harness (prime runtime), mirroring
  configs/debug/v1/r2e_gym.toml
- configs/rlm_swe/qwen35_4b.toml: remove (superseded by configs/debug/v1/r2e_gym.toml)
- skills/training/start-run: point the find_spec example at r2e_gym_v1
- configs/debug/v1/r2e_gym.toml: drop the stale reference to the removed v0 config

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: re-pin deps/verifiers to merged verifiers main (#1894)

The Trace/Branch num_ consolidation landed on verifiers main; point the
submodule at the merge commit instead of the temporary cherry-pick pin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: require verifiers >=0.1.15.dev405 (Trace/Branch num_ consolidation)

The submodule is pinned at the consolidation commit (0.1.15.dev405); raise
the floor so the renamed Trace/Branch token properties are guaranteed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: samsja <55492238+samsja@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Sami Jaghouar <sami.jaghouar@hotmail.fr>
Co-authored-by: eligotts <78387377+eligotts@users.noreply.github.com>
mikasenghaas added a commit that referenced this pull request Jun 29, 2026
* feat(v1): GLM-4.5-Air scaleswe SWE ablation config (router replay)

v1 RL config: GLM-4.5-Air (zai-org/GLM-4.5-Air, 100B MoE) on scaleswe-v1 (train)
+ swebench-verified (eval), bash harness on prime sandboxes. Router replay on
(trainer.enable_router_replay + inference.enable_return_routed_experts).

2 train + 2 infer nodes. Trainer: cp=8 ulysses, muon, + GLM-5.1 prod-run memory
improvements (LM-head chunking, AC + activation offload, optimizer CPU offload,
skip-gather/skip-optimizer ckpt). Inference: 2x tp=8 replicas, NO expert
parallelism (inference EP + router-replay capture deadlocked the engine via
cross-node EP all-to-all). Renderer/parsers auto-resolve from the official slug.

Relies on fixes already in main: the glm4_moe routed_experts .contiguous() slice
(torch.compile stride assert) and the verifiers always-install-uv bootstrap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(slurm): VLLM_CACHE_ROOT=/tmp in multi_node_rl template

vLLM's compile cache defaulted to NFS (~/.cache/vllm), which hung inference
startup on slow shared FS. Point it at node-local /tmp (matching inference.sbatch.j2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(swe-abl): online fp8 inference + 384 rollout concurrency for glm45air

Inference runs vLLM online fp8 quant (vllm_extra={quantization="fp8"}) over the
bf16 policy for faster generation; trainer/inference/orchestrator all use the
bf16 zai-org/GLM-4.5-Air. The per-channel GLM-4.5-Air-FP8 checkpoint is
incompatible with prime-rl's block-wise fp8 path (use_deep_gemm /
quantize_in_weight_transfer), so we use online quant instead. max_inflight_rollouts=384.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(swe-abl): glm45air-scaleswe -lp variant (default length penalty)

Sibling of glm45air_scaleswe.toml with orchestrator.advantage.length_penalty
enabled at defaults (coef=0.25, gate_by_correctness=false). Distinct slurm
job_name + sandbox labels (glm45air-swe-lp) so it runs alongside the no-penalty
run without sharing prime sandboxes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(swe-abl): bump weight_broadcast timeout to 3600s for cold NFS loads

Cold-cache nodes read the 206GB bf16 model from NFS at ~50s/shard (~46min
total). The weight-broadcast store rendezvous default (1200s/20min) times out
before inference finishes loading (DistStoreError: 1/17 clients joined), killing
the trainer. 3600s covers the cold-load worst case with margin. Applied to both
the base and -lp ablation configs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): kv-offload + fp8, drop router replay, bash_edit

- Drop router replay (trainer.enable_router_replay + inference.enable_return_routed_experts):
  mutually exclusive with inference.kv_cache_offload (rl.py validator — external KV cache hits
  don't carry routed-expert decisions).
- Enable native KV-cache offloading with a 128GB CPU tier (extends the prefix cache).
- FP8 trainer (DeepGEMM blockwise linear/MoE) — impl=custom is already set.
- Use the bash_edit harness (bash + local edit tool) for train + eval, replacing pure bash.
- Bump max_inflight_rollouts 384 -> 512.
- Keep LM-head token chunking + activation checkpointing explicit at the values that become
  trainer defaults in #2867 (not merged yet, so removing them would disable the features).
- Drop the -lp length-penalty variant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): kv-offload + fp8, drop router replay, bash_edit

- Drop router replay (trainer.enable_router_replay + inference.enable_return_routed_experts):
  mutually exclusive with inference.kv_cache_offload (rl.py validator — external KV cache hits
  don't carry routed-expert decisions).
- Enable native KV-cache offloading with a 128GB CPU tier (extends the prefix cache).
- FP8 trainer (DeepGEMM blockwise linear/MoE) — impl=custom is already set.
- Use the bash_edit harness (bash + local edit tool) for train + eval, replacing pure bash.
- Bump max_inflight_rollouts 384 -> 512.
- Keep LM-head token chunking + activation checkpointing explicit at the values that become
  trainer defaults in #2867 (not merged yet, so removing them would disable the features).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): drop inference fp8 quant to lower mismatch

Run bf16 inference (remove vllm_extra quantization=fp8). fp8 inference added
~10x mismatch KL (~0.002 vs ~0.0002); bf16 inference lowers it. Trainer fp8 +
native KV-cache offload (and the now-disabled router replay) unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): bump context to 131072

seq_len + inference.model.max_model_len 65536 -> 131072.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): revert to 65k ctx, drop kv offload, 384 inflight

- seq_len + inference.model.max_model_len 131072 -> 65536
- Remove inference.kv_cache_offload (native CPU tier)
- max_inflight_rollouts 512 -> 384

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): eval at step 0 (explicit skip_first_step=false)

Make the startup eval explicit so SWE-Bench Verified runs at step 0 before
any train rollouts (already the default; pinned for clarity).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): drop fp8 trainer

Remove trainer.model.fp8 (back to bf16 training).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): bring back router replay

Re-enable trainer.enable_router_replay + inference.enable_return_routed_experts.
Compatible again now that kv-cache offload and fp8 (both mutually exclusive with
router replay) have been dropped; replaying inference's routed-expert decisions in
the trainer cuts the train/inference mismatch by ~an order of magnitude.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): scale inference to 4 nodes / 4 replicas

num_infer_replicas 2 -> 4 (num_infer_nodes is per-replica, so total inference
nodes = num_infer_nodes * num_infer_replicas = 4). Total job = 2 train + 4 infer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): bump max_inflight_rollouts 384 -> 512

Increase orchestrator rollout concurrency to better saturate the 4 inference replicas.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(slurm): node-local FlashInfer JIT cache to avoid weka lock deadlock

FLASHINFER_WORKSPACE_BASE defaulted to $HOME/.cache/flashinfer on shared weka.
With concurrent GLM-4.5-Air/MoE runs every TP worker contends on the same
fused_moe_*.lock there and deadlocks in uninterruptible (D-state) filesystem
I/O during the CUTLASS fused-MoE JIT build, so inference never serves. Pin it
to node-local /tmp like the Triton/vLLM caches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* glm45air-scaleswe: bump max_steps 400 -> 1000

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): set node-local cache dirs via config env_vars

Move the cache-dir env vars out of the SLURM templates and into the config
so the PR only adds the TOML (the merged env-var feature, #2863, makes this
possible):
- [env_vars] TRITON_CACHE_DIR (trainer + inference)
- [inference.env_vars] VLLM_CACHE_ROOT, FLASHINFER_WORKSPACE_BASE

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* exp(glm45air-scaleswe): migrate renderer preserve_all_thinking -> thinking_retention

Main #2900 replaced the renderer `preserve_all_thinking` bool with
`thinking_retention`; the merge left the config on the removed field, so it
failed the config-load unit test ("No config class could be parsed"). Switch
to `thinking_retention = "all"` (the documented equivalent).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Mika Senghaas <mail@mikasenghaas.de>
Co-authored-by: Mika Senghaas <mika@primeintellect.ai>
mikasenghaas added a commit that referenced this pull request Jun 29, 2026
…GRPO (#2901)

* feat(algo): linear length penalty (completion + context + turns) for GRPO

Port the length-penalty-context-turns branch onto current main's algorithm
abstraction as a new `linear` LengthPenaltyConfig variant. It subtracts a single
pass_rate-scaled penalty from each reward before the GRPO baseline: coef *
completion tokens + context_coef * non-completion (context) tokens over the
group's longest sequence, plus turns_coef * turns over the group's most turns —
each normalized by the group's own max, optionally gated to correct rollouts.

context_coef and turns_coef default to 0.1 (completion coef 0.25).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(algo): make linear the only length penalty (remove tokens/turns)

Per review, the linear penalty replaces the existing efficiency-shaping
length penalties rather than coexisting with them:
- Remove TokensLengthPenaltyConfig / TurnsLengthPenaltyConfig; LengthPenaltyConfig
  is now just LinearLengthPenaltyConfig.
- Simplify GRPOAlgorithm.score_group to None vs linear.
- Remove the now-orphaned efficiency_shaping (delete algo/advantage.py) and its
  references in algo/__init__ and docs.
- Rewrite test_advantage.py: drop the efficiency_shaping / tokens / turns cases,
  add linear-penalty tests (completion / context / turns terms, gating, and the
  equal-length reduce-to-plain-GRPO invariant).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(algo): drop gate_by_correctness; compute turns term unconditionally

- Remove the gate_by_correctness option from the linear length penalty.
- Always add the turns term (it contributes 0 when turns_coef=0); drops the
  asymmetric guard so all three terms are handled uniformly.
- Remove the gating unit test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(algo): rename linear length-penalty fields + per-term-max normalization

- Rename GRPOAlgoConfig.length_penalty -> length_pen; lp -> length_pen in grpo.
- Rename coef/context_coef/turns_coef -> completion_pen/input_pen/turns_pen.
- Normalize each term by its own group max: completion / max completion,
  input (= total - completion) / max input, turns / max turns (previously the
  completion and input terms shared the max-total denominator).
- Drop the explanatory comments in score_group; fix stale field/doc text.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(algo): rename input_tokens -> input for naming consistency

Matches the other bare locals (completion, total, turns).

* docs(changelog): note length_pen rename + tokens/turns removal

* chore: adopt consolidated num_ trace token properties + rename length penalty config (#2905)

* fix(template): orchestrator URLs use canonical model.client path (#2899)

The multinode RL sbatch template launched the orchestrator with
--student.client.{base-url,admin-base-url}, but OrchestratorConfig has no
`student` field — the canonical path is `model.client` (base_url /
admin_base_url on ClientConfig). The orchestrator-config rename left the
template stale, so every multi-node RL launch fails config parsing with
"Unrecognized arguments: <inference URLs>".

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: correct env log glob to logs/envs/<split>/<env>.log (#2898)

* fix: correct env log glob to logs/envs/<split>/<env>.log

Since the nano-as-v1 migration each env writes a single
logs/envs/{train,eval}/<env>.log file (two levels), but the launch
banner still printed three-level globs (logs/envs/*/*/*.log), which
match nothing. Fix the banner generator and the captured example
outputs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs: drop captured launch-banner output from example READMEs

The "Output of the command" blocks duplicated the live launch banner
(now fixed in pathing.py) and drift out of sync. Remove them; the run
command stays.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat: configurable env vars (#2863)

* feat(env): consolidate component env vars

Add shared env var defaults and per-component env_vars plumbing across RL, SFT, and inference launch paths.

Update launcher filtering, SLURM templates, examples, and docs to match the consolidated env config surface.

* feat: add rl-wide env vars (#2897)

---------

Co-authored-by: Sami Jaghouar <sami.jaghouar@hotmail.fr>
Co-authored-by: samsja <55492238+samsja@users.noreply.github.com>

* Update configs for renderer thinking retention (#2900)

* chore: migrate to consolidated Trace/Branch num_ token properties

Bump deps/verifiers to the property consolidation (verifiers #1894) and
rename every prime-rl access of the renamed Trace/Branch properties:

  completion_len / output_len -> num_output_tokens
  prompt_len                  -> num_input_tokens
  rollout total_tokens        -> num_total_tokens

progress.total_tokens, Usage.total_tokens and RunStats.total_tokens are
unrelated and left unchanged; num_turns is unchanged upstream.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: rename length penalty config to num_*_tokens_weight + num_turns_weight

Align the linear length-penalty config (from #2901) with the consolidated
num_-prefixed trace property names:

  [orchestrator.algo.length_pen]  -> [orchestrator.algo.length_penalty]
  completion_pen                  -> num_output_tokens_weight
  input_pen                       -> num_input_tokens_weight
  turns_pen                       -> num_turns_weight

Updates grpo.score_group, the config class, docs, CHANGELOG, and tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: bump verifiers + research-environments to main (#2904)

* chore: bump verifiers + research-environments to main

- verifiers: aa95826d → 97be43bf
- research-environments: 99ebd2e13 → bae0ffe5a
- lock new v1 envs: lean-v1 (6 per-dataset Lean tasksets), prolog-v1
- bump verifiers floor 0.1.15.dev400 → dev404

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: lock remaining research-environments v1 envs

Lock the 21 previously-unlocked RE v1 env packages into the `envs` extra
+ tool.uv.sources, and alphabetize both the `envs` list and the env source
entries.

tau3-bench-v1 is intentionally excluded: it requires tau2 @ git 58e5e1a,
which conflicts with the tau2 @ 337326e pinned by the already-locked
tau2-bench-v1 (uv cannot resolve two URLs for one package).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: drop rlm-swe to remove the verifiers override

rlm-swe pins verifiers>=0.1.15.dev17,<0.1.15.dev156 — a stale upper bound
that conflicts with the editable verifiers submodule (dev404) and with the
other envs / prime-rl-configs. It was the sole reason verifiers needed a
global override-dependencies entry (without it, resolution is unsatisfiable).

Dropping rlm-swe lets us remove that override: verifiers now resolves to the
editable submodule through tool.uv.sources alone. Also prunes rlm-swe's heavy
transitive deps (modal, swebench, swe-rex, pygithub, …) from the lock.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: migrate rlm_swe config dependents to r2e-gym-v1

Dropping the rlm-swe env orphaned its in-repo config dependents:
- examples/glm5_llmd/rl.toml: migrate the v0 `rlm_swe` env block to the v1
  `r2e-gym-v1` taskset on the rlm harness (prime runtime), mirroring
  configs/debug/v1/r2e_gym.toml
- configs/rlm_swe/qwen35_4b.toml: remove (superseded by configs/debug/v1/r2e_gym.toml)
- skills/training/start-run: point the find_spec example at r2e_gym_v1
- configs/debug/v1/r2e_gym.toml: drop the stale reference to the removed v0 config

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: re-pin deps/verifiers to merged verifiers main (#1894)

The Trace/Branch num_ consolidation landed on verifiers main; point the
submodule at the merge commit instead of the temporary cherry-pick pin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: require verifiers >=0.1.15.dev405 (Trace/Branch num_ consolidation)

The submodule is pinned at the consolidation commit (0.1.15.dev405); raise
the floor so the renamed Trace/Branch token properties are guaranteed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: samsja <55492238+samsja@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Sami Jaghouar <sami.jaghouar@hotmail.fr>
Co-authored-by: eligotts <78387377+eligotts@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: samsja <55492238+samsja@users.noreply.github.com>
Co-authored-by: Sami Jaghouar <sami.jaghouar@hotmail.fr>
Co-authored-by: eligotts <78387377+eligotts@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants