feat(cli): config-file-driven rllm train / rllm eval (phases 1–2) - #803
Closed
jeffreysijuntan wants to merge 2 commits into
Closed
feat(cli): config-file-driven rllm train / rllm eval (phases 1–2)#803jeffreysijuntan wants to merge 2 commits into
rllm train / rllm eval (phases 1–2)#803jeffreysijuntan wants to merge 2 commits into
Conversation
Add a self-contained config-file mode to `rllm train`: a single TOML/YAML file specifies the whole run and launches with `rllm train run.toml [key=value ...]`. Foundation for the same on `rllm eval` (next). - rllm/config/run_config.py: parse (.toml/.yaml) -> (DictConfig, RunSpec). Composes the full trainer config for the file's `backend` via Hydra's compose API (handles the @Package _global_ split, ${...} interpolations, and verl's `defaults: /ppo_trainer`), merges the file's config-tree sections, mirrors [data] into [rllm.data], resolves `extends`, and applies Hydra-style dotlist overrides. RunSpec captures the [run] definition ([run.agent]/.dataset/.sandbox/.env) + [eval] block. - rllm/cli/_run_resolve.py: resolve a RunSpec into agent_flow / evaluator / train+val datasets (+ entrypoint escape hatch), reusing load_agent / load_evaluator / DatasetRegistry / BenchmarkLoader. - rllm/cli/train.py: detect a config-file positional -> config-file driver; add `--dry-run` to print the composed config + resolved run without launching. Flag mode unchanged. - rllm/eval/agent_loader.py: `load_agent(name, agent_args=...)` now threads agent_args as constructor kwargs (class) or via configure() (instance), so `[run.agent.args]` (e.g. terminus2 max_turns) applies whether the agent is named or imported. Default None = unchanged behavior. - design/config-file-driven-train-eval.md: design doc. - tests: loader (parse/merge/extends/mirror/overrides), RunSpec, and agent_args threading. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add config-file mode to `rllm eval` (symmetric to `rllm train`): `rllm eval run.toml [key=value ...]` runs the `[run]` definition (agent/evaluator/dataset/ sandbox) plus an optional `[eval]` block (split, concurrency, attempts, max_examples, task_indices, sampling, snapshot, base_url/model, output, ui). Consolidation: - Extract `_resolve_eval_model_source(base_url, model) -> (base_url, model, proxy_manager)` from `eval_cmd`; both flag mode and config mode use it (one model-source/proxy-lifecycle implementation). Flag-path strings unchanged. - `_run_eval` gains `agent_args` (threaded into its load_agent calls); config mode funnels into the *same* `_run_eval` core, so eval resolution stays a single implementation. Flag mode passes None (unchanged). - File detection + `--dry-run` mirror the train command. entrypoint-for-eval is not wired yet (declarative [run.agent]/[run.dataset] only) — fails with a clear message; tracked as a follow-up. Tests: eval config dry-run, missing-dataset error, and _resolve_eval_model_source direct-mode (+ requires-model). Full tests/cli + tests/config + agent_loader green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rllm train run.toml (phase 1)rllm train / rllm eval (phases 1–2)
Contributor
Author
|
Superseded by the terminal-rl-based PR (this branch targeted main; terminal-rl has diverged train.py/eval.py). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds self-contained config-file mode to both
rllm trainandrllm eval: one TOML/YAML file specifies the whole run, launched asrllm train run.toml [key=value ...]/rllm eval run.toml [key=value ...]. Implements phases 1–2 ofdesign/config-file-driven-train-eval.md(included in this PR).A cookbook run — e.g. terminal-rl's
train.py+train_fireworks_a35b.sh(~220 lines) — collapses to one ~40-linerun.toml, and the same file drives eval.Schema
Components
rllm/config/run_config.py— parse.toml/.yaml→(DictConfig, RunSpec). Composes the full trainer config for the file'sbackendvia Hydra'scomposeAPI (handles the@package _global_split,${...}interpolations, verl'sdefaults: /ppo_trainer), merges config-tree sections, mirrors[data]→[rllm.data], resolvesextends, applies dotlist overrides.rllm/cli/_run_resolve.py— resolve aRunSpecintoagent_flow/evaluator/datasets (+entrypointescape hatch for train), reusingload_agent/load_evaluator/DatasetRegistry/BenchmarkLoader.rllm/cli/train.py— config-file positional → config driver;--dry-runprints the composed config + resolved run.rllm/cli/eval.py— config-file positional → config driver reading[run]+[eval];--dry-run.rllm/eval/agent_loader.py—load_agent(name, agent_args=...)threadsagent_argsas constructor kwargs (class) or viaconfigure()(instance).None= unchanged.Consolidation (bundled)
_run_evalcore as flag-eval (no duplicated dataset/agent/evaluator/materialization logic);_run_evalgained anagent_argsparam._resolve_eval_model_sourcefromeval_cmd; flag mode and config mode both use it (one proxy-lifecycle implementation). Flag-path user-facing strings are byte-identical.agent_argshandling centralized inload_agent(used by train, eval, and the resolver).Testing
tests/config/test_run_config.py(17) — parse, backend compose (tinker/fireworks),[data]mirror + precedence,extends, dotlist overrides, RunSpec (nested + scalar shorthands),export_env, errors.tests/eval/test_agent_loader.py(+3) —agent_argsas constructor kwargs (import-path + catalog-name),Noneunchanged.tests/cli/test_eval_command.py(+4) — eval config dry-run, missing-dataset error,_resolve_eval_model_sourcedirect-mode (+ requires-model).tests/cli+tests/config+tests/eval/test_agent_loader.py= 133 passing; ruff clean.--dry-runfor bothtrainandevalon a fireworks config: composes config, resolves terminus2 + datasets, applies dotlist overrides, renders headers.Deliberately deferred (follow-ups)
ppo_trainersearchpath)._run_train→ shared resolver /build_train_config→merge_backend_config— the flag paths still have their own compose/resolution. Left as a separate refactor to avoid regressing the working flag training path in this PR.rllm.*+ extending each_SHARED_KEYSso flippingbackendcarries all common config (design §"Backend selection & cross-backend portability").run.toml) +rllm-docspage.🤖 Generated with Claude Code