Repository navigation
feat(training): train a bundle's own agents with AReaL's agent workflows - #438
earakely-scale wants to merge 6 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ches it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aL's proxy does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… bundle without the reward Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
GPU proof setup: one g6.12xlarge (4×L4), AReaL main at d25f292 (SGLang 0.5.10, torch 2.9.1), Qwen3-4B-Instruct-2507 with LoRA, SGLang on one GPU and the FSDP actor on two, the framework at 62d9196. Plumbing: works end to end.
Training: no learning shown in this run. It shows rollouts, rewards, rejections and updates working, not a gain.
What AReaL needed along the way, for the docs:
|
|
Second GPU run, on the setup the TRL harness proof used: Qwen3-4B with thinking off ( What ran:
Before and after, 16 runs a task at AReaL's sampling (temperature 1, completions capped at 2,048 tokens, thinking off), with the merged adapter served by SGLang:
The ranges are 95% Wilson intervals. The change points the right way, mostly on product, the task with the most room. At this size it's within noise (two-proportion z ≈ 0.8), so this run shows AReaL training a bundle's own agent end to end, not a significant gain. The TRL harness run on the same model and tasks went from 0.59 to 0.78 in 12 steps. What it took, in addition to the first run's list:
|
|
Closing without merging. The integration works end to end (rollouts through AReaL's proxy, rewards, per-sample rejection, weight syncs), but the GPU runs didn't show a clear training gain (0.56 to 0.65 after 8 steps, within noise), so AReaL support isn't being added for now. The branch stays for a later look, after AReaL's next release. |
What
agent_env.training.arealtrains a bundle's own agents with AReaL's agent workflows (rollout.agent.mode: inline), the wayagent_env.training.harnessdoes for TRL's harness rollouts.AgentEnvWorkflowis the inline agent AReaL'sOpenAIProxyWorkflowruns for each sample (workflow: agent_env.training.areal.AgentEnvWorkflow, with the bundle and selection asworkflow_kwargs). It plays the row's task asagent-env rundoes, on local Docker. The solver's deploy alone gets AReaL's proxy address and the sample's session key as its model endpoint, so the proxy records the tokens AReaL trains on. The task's other agents and judges keep the configured endpoint.runreturns the task's reward as a float.task_rows(bundle, ...)is the trainer's dataset: a row per trainable task, with its id and first prompt asmessages.should_reject_failed_sampleleaves that one sample out of its group, and the group's other samples still train. The exception is when AReaL itself found the model at fault (context overflow, invalid tool JSON); AReaL keeps those as reward 0.runstops the task and passes the cancel on only once the run is torn down, so no sandbox outlives a cancelled sample.pip install agentenv-framework.Shared with the harness helper
_solver.pyholds what the two helpers share, moved fromharness.pywith no behaviour change: which tasks can train their solver, their preparation for local Docker, and the overrides that point the solver alone at the trainer's endpoint.agent_env.openenv.rewardtoagent_env.training.reward.agent_env.openenv's package init imports the OpenEnv server, so nothing under it imports without theopenenvextra, which this helper doesn't need.build_appimports the rules from the new place. (agent_env.openenv.rewardfirst shipped in 0.9.1408.)_openenv.py, which imports openenv, to_loop.py. The trl, skyrl and harness helpers import it from there.registriesfixture is no longer autouse: the bundle fixture requests it.Tests
tst/unit/training/areal_test.pychecks these behaviours against the harness tests' stand-in steps and model:agent=swaps the solver;tst/areal, run by.github/workflows/areal.ymlon AReaL 2.1.0 and on main with CPU torch over the dev environment. It is not a required check. AReaL's own rollout engine resolves the workflow from its import path into its grouped proxy workflow. Each sample plays under its own session, its reward goes on its last completion, and a failing sample is rejected (alone on main, with its group on 2.1.0).tst/integration/training/areal_test.py: opencode, in local Docker, plays its smoke task against a stand-in model at a proxy-style address without/v1, and the run returns reward 1.0. The stand-in now listens on every interface, as AReaL's proxy does, since a container reaches the host only through the bridge gateway. It no longer needs openenv.make areal-test, and the AGENTS.md rows for the tier, its CI job and the training package.Run on a Linux box:
test_mcp_cli_builder's generated CLIs, which import httpx under the box's systempython3; they are unrelated to this change.tst/unit/trainingagain on the final stand-in: 100 passed.A GPU proof (GRPO through AReaL on a bundle's own opencode agent) follows in a comment.
🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; both previous findings are addressed and no new blocking issues were found.Summary
Adds AReaL training for a bundle’s own agents, with shared task preparation, rewards, and a background event loop.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR A[AReaL sample] --> B[AgentEnvWorkflow] B --> C[Run task on shared loop] C --> D[Solver calls AReaL proxy] D --> C C --> E[Reject unrecovered failures] E --> F[Read scores] F --> G[Tear down run] G --> H[Return reward]Reviews (2) · Last reviewed commit: "fix(training): leave out a run with a st..." · Reviewed by Greptile