AReaL × Arena 集成实战:面向 SWE Agent 的单流与多流强化学习训练指南
【免费下载链接】AReaLThe RL Bridge for LLM-based Agent Applications. Made Simple & Flexible.项目地址: https://gitcode.com/GitHub_Trending/are/AReaL
导读
本文讲解 AReaL 如何与外部 Arena 评测/数据平台集成,完成基于 SWE(软件工程)Agent 任务的强化学习训练:Arena 负责供给数据集、运行外部 Harness 评测器并返回终态奖励,AReaL 通过其 rollout proxy 提供策略推理服务并对记录的 token 进行训练。整条链路不依赖 AReaL-SWEAgent、PRM 或 RewardSystem,是纯 Arena 数据源 + AReaL 训练引擎的最小闭环。读完本文,你将掌握 Arena 单流/多流训练的全部配置项、预检流程、奖励路由机制,以及 Flash V3 大规模 Megatron 训练 profile 的部署方法。
Arena 集成架构与角色分工
Arena 集成的基本分工如下(原文定义,见 examples/swe/README_arena.md):
- Arena:供给数据集(dataset rows)、运行外部 Harness(评测 Agent)、返回 terminal reward(终态奖励)。
- AReaL:通过 rollout proxy(
session_gateway等路由模式)对外提供策略服务,Harness 作为 LLM 客户端调用该代理;AReaL 记录生成 token 并用于训练。
从源码结构看,这条链路由 examples/swe/arena_client.py 中的ArenaOpenAPIClient承担 Arena OpenAPI 的流发现(list_streams/resolve_stream)、数据集分页拉取(get_all_dataset_rows)、LLM 代理注册(register_llm_proxy)与单任务启动/轮询(launch_one_task/launch_one_task_result)等操作;examples/swe/arena_config.py 与 examples/swe/arena_types.py 则定义了 Stream 配置的解析与校验逻辑。训练入口为 examples/swe/train_swe_rl.py。
这种集成模式的价值在于:评测逻辑完全外置,AReaL 只关心“策略如何被调用、奖励如何回流”,从而让 RL 训练与任务评测解耦。
单流训练:arena_grpo.yaml冒烟 profile
Profile 资源概况
examples/swe/arena_grpo.yaml 是一个两节点 FSDP/SGLang 冒烟测试配置:
- 8 张训练 GPU(
cluster.n_nodes: 2、n_gpus_per_node: 8); - 8 张推理 GPU(rollout 后端
sglang:d4p1t2); - 每个 prompt 采样 2 条(
gconfig.n_samples: 2); - 只训练 1 步(
total_train_steps: 1); - 请求预算 32767 token,SGLang 上下文 32768 token,正好留出 SGLang 检查 prompt+completion 长度时所需的 1 token 余量(配置中注释明确说明)。
必备环境变量
提交前必须设置以下环境变量,全部指向你的集群实际路径:
export AREAL_DIR=/path/to/AReaL export AREAL_IMAGE=/path/to/compatible-image.sif export AREAL_PYTHON=/path/to/python/in/container export AREAL_FILEROOT=/shared/path/to/experiments export MODEL_PATH=/shared/path/to/Qwen3-4B-Instruct export ARENA_CREDENTIALS_FILE=/shared/private/arena.env凭证文件的安全设计
凭证文件是安全边界,submit_arena.sh 的--run分支会在 controller 容器内source该文件,随后将显式启动变量重新覆盖回去(launch_env机制保证“显式启动值优先于旧凭证文件中的部署设置”),worker 侧则在 arena_grpo.yaml 的additional_bash_cmds中通过source "$ARENA_CREDENTIALS_FILE"再次加载。要求如下:
- 凭证文件中只保留凭证与 Arena API base,必须导出以下四个变量:
export ARENA_OPENAPI_BASE=... export ARENA_OPENAPI_TOKEN=... export ARENA_LLM_API_KEY=... export SWE_RL_ADMIN_API_KEY=...ARENA_LLM_API_KEY是 Arena 模型网关(model gateway)的认证密钥,不是上游模型提供商的 key。如果你的部署对两类 API 使用同一个 Arena bearer token,可在凭证文件中写export ARENA_LLM_API_KEY="$ARENA_OPENAPI_TOKEN"。- 控制面 preflight 通过不代表模型网关认证通过,后者只在任务实际发起时才能验证。
- 凭证绝不会被嵌入 worker 命令或提交到 YAML 中,controller 环境也需加载同一凭证文件。
提交脚本的使用
submit_arena.sh假设你有一个兼容容器(controller 可调用 Slurm)、共享存储、以及 Arena 到 rollout proxy 的网络可达性。设置站点相关的挂载后执行:
# Comma-separated Apptainer binds supplied by your cluster setup. # Workers need the shared checkout, model, credentials and output paths. export AREAL_WORKER_MOUNTS="$SITE_SHARED_MOUNTS" # Controller additionally needs working Slurm commands and authentication. export AREAL_CONTROLLER_MOUNTS="$SITE_SHARED_MOUNTS,$SITE_SLURM_MOUNTS" export AREAL_CONTAINER_BIN=apptainer # or singularity, available on compute nodes export SBATCH_PARTITION="$SITE_PARTITION" export SBATCH_TIMELIMIT=01:00:00 # worker limit export ARENA_CONTROLLER_TIME=01:30:00 export ARENA_STREAM_ID=your-stream bash examples/swe/submit_arena.sh --check-arena bash examples/swe/submit_arena.sh流程要点:
- 脚本提交一个CPU-only controller(4 CPU、16 GB),配置校验与 Arena preflight 在容器内先执行,之后 AReaL 才会提交任何 GPU worker;
--check-arena只跑 preflight 就停止;- 检查
$AREAL_FILEROOT/submissions/$TRIAL_NAME/controller-<job-id>.log与preflight.json; - 显式设置
TRIAL_NAME便于标识运行(同时用作 controller 作业名),否则会生成唯一名,可用squeue查看作业及其名称; CONFIG_PATH默认指向examples/swe/arena_grpo.yaml;- 可选 Slurm 站点设置沿用常规的
SBATCH_ACCOUNT、SBATCH_RESERVATION等环境变量; - 脚本不会复制或快照代码:作业排队或运行期间不要改动 checkout 与配置,每个 revision 使用独立 checkout;所有路径必须保证在容器内同一位置可见。
从脚本源码看,submit_arena.sh 先做参数与路径合法性检查(AREAL_DIR、CONFIG_PATH、AREAL_IMAGE、AREAL_PYTHON、MODEL_PATH、AREAL_FILEROOT、ARENA_CREDENTIALS_FILE、AREAL_CONTROLLER_MOUNTS、AREAL_WORKER_MOUNTS均为必需且需绝对路径),然后经sbatch --parsable提交 controller;controller 内再以apptainer exec --no-eval --pid --writable-tmpfs --bind "$AREAL_CONTROLLER_MOUNTS"进入容器执行--run分支。--run分支内嵌 Python 片段,通过load_expr_config解析与训练完全相同的配置文件(含 Hydra defaults),调用load_arena_stream_configs+validate_streams执行预检并写出preflight.json,非--check-arena模式才os.execv进入python -m examples.swe.train_swe_rl。
多流(Multi-Stream)训练
配置切换与 Stream 列表
多流训练切换配置并填写 Stream 条目:
export CONFIG_PATH=examples/swe/arena_multi_stream.yaml # Fill in the Stream/Harness/reward entries before submitting. bash examples/swe/submit_arena.shexamples/swe/arena_multi_stream.yaml 继承arena_grpo默认配置,核心是econfig.arena_streams列表,每个条目包含:
econfig: stream_id: '' arena_streams: - name: first stream_id: your-first-stream sampling_weight: 1 harness: your-harness@version expected_reward_ref: key: your-reward version: 1.0.0 - name: second stream_id: your-second-stream sampling_weight: 1 harness: your-harness@version expected_reward_ref: key: your-reward version: 1.0.0要点:
- 单流场景只需设置
ARENA_STREAM_ID环境变量; - 多流场景直接编辑
econfig.arena_streams的字面量条目并选择对应配置,必须为每个 Stream 钉住其真实 Harness 与 reward key/version; - 每组
n_samples只使用一个 Stream; - Stream 配置可通过三种互斥方式提供(源码 examples/swe/arena_config.py 中的
load_arena_stream_configs验证了这一点):内联arena_streams列表、base64 编码内联 YAML(arena_streams_yaml_b64)或外部 YAML 文件(arena_streams_file); - 每个 Stream 的
name仅允许字母、数字、.、_、-,sampling_weight必须为正有限数值,name与stream_id各自必须唯一;llm_protocol仅支持anthropic、responses、chat_completions(或留空自动推断); expected_reward_ref的key与version必须同时提供或同时为空。
Stream 混合(mixture)语义
- 默认 epoch 对全部源行做无放回交错,每个源数据恰好出现一次(此时
sampling_weight不改变每源数量,而是后续用于加权选择); - 设置正数
arena_mixture_epoch_size时,按权重选取一个确定性的无放回子集:不得超出源行并集,且必须能被训练 batch size 整除(源码build_weighted_arena_rows严格校验这两点,同时拒绝向 union 填充到 batch 倍数,因为填充会重复行); - 注意:rejection(拒绝采样)可能改变最终进入训练的混合结果。
提交前 Stream 校验(不启动任务)
python -m examples.swe.arena_stream_config_projection \ examples/swe/arena_multi_stream.yaml | base64 --decode > /tmp/arena-streams.yaml python -m examples.swe.arena_preflight \ --streams-file /tmp/arena-streams.yaml --base-url "$ARENA_OPENAPI_BASE"- arena_stream_config_projection.py 从训练配置中投影出规范的顶层
streamsYAML 并 base64 输出,且拒绝包含 Hydra 插值的字段——保证 preflight 与训练看到完全相同的 Stream 配置; - arena_preflight.py 校验:Stream 存在且状态
ACTIVE、reward_ref 无漂移(与expected_reward_ref比对)、Harnesskey@version存在且PUBLISHED、数据集至少有一行、以及近期任务健康度(terminal 数与失败率,默认--recent-tasks 100、--min-terminal-tasks 1、--max-failure-rate 0.8); - 新建 Stream 无历史时可用
--min-terminal-tasks 0,但不会绕过其他检查; - 预检支持
--streams-file或--streams-env-b64 NAME两种输入方式,并带指数退避重试(429/5xx 以及特定 403 可重试,默认 3 次)。
Flash V3 多流数据集示例
examples/swe/dataset_configs/flash-v3-multi-stream.yaml 展示了两个真实 Stream 的钉住写法,每个 Stream 显式声明llm_protocol: anthropic,并分别钉住 Harness 与 reward 版本:
streams: - name: vn_greenfield stream_id: vn-greenfield-fixed sampling_weight: 1 harness: flash-vn-agent@2.0.3 llm_protocol: anthropic expected_reward_ref: key: vn-creation-x2env-greenfield-reward version: 2.0.8 - name: favor_app_online_scratch stream_id: favor-app-online-scratch-fixed sampling_weight: 1 harness: claude-code@1.2.31-native-direct-sfx-260821 llm_protocol: anthropic expected_reward_ref: key: favor-app-online-scratch-reward version: 2.0.2路由模式与奖励语义
路由模式
econfig.arena_llm_route_mode控制 Harness 如何访问 AReaL 策略代理,可选三种(见 examples/swe/arena_grpo.yaml 与文档描述):
session_gateway(默认):为每个 rollout worker 复用一次注册,把每个请求绑定到独立的 proxy session。注册的 key只允许生成(generation),不能结束 session、不能分配奖励、不能导出轨迹;注册在任务活跃期间被探测,worker 销毁时清理;gateway:保留旧的 per-rollout 注册模式;direct:要求 Harness 与 proxy 之间有私有网络直连。
奖励语义
- 只有结果信封顶层的
score被用作奖励;每个 Stream 可配置阈值(reward_threshold)与可选的reward_transform_fn钩子来变换它; - 异构的
raw载荷只保留用于审计,绝不被解析为训练奖励——源码 examples/swe/arena_client.py 的_parse_task_result注释明确说明“不进行递归奖励发现”,防止 grader 自有数据意外成为 RL 奖励;_arena_task_type_from_tags从domain:标签提取任务类型,多 domain 时退化为unknown; - 归因于模型的失败可保留交互但奖励为 0;系统性与模糊失败则被拒绝(
FAILED_TASK_STATUSES涵盖CANCELLED、COLLECT_FAILED、EVAL_FAILED、FAILED、HARNESS_FAILED、NO_OUTPUT、SETUP_FAILED、TIMEOUT); - 配置
arena_result_dump_dir时,结果分片会写入该目录(examples/swe/arena_grpo.yaml 中默认为${cluster.fileroot}/${experiment_name}/${trial_name}/arena_results); - 可复用的奖励变换示例见 examples/swe/reward_transforms.py:
astra_partial_reward将低于阈值的 Astra 分数压到十分之一强度、达标则映射为 1.0。
端口来源与适用范围
本文描述的 Arena 端口选取了swe-dev分支提交da1da65c7、1d0fc7ba0、714f733a0、586d7cc06、84f7bb341、ddb7d7f3c、2b994c10c、9ecbde97c中的选定改动,并保留了 main 分支的 processor cache、sample identity 与取消清理逻辑。本端口不包含:训练引擎 API 的改动、仅均值奖励归一化、内部 Astra 启动脚本、AWEX/Qwen3.8 改动、以及 PRM/RewardSystem。
Flash V3 Megatron profile:128K 上下文大规模训练
配置与提交
examples/swe/arena_flash_v3.yaml 与 submit_arena_flash_v3.sh 将模型、资源与采样设置适配自swe-dev@5478d6384的submit_arena_astra_multi_stream.sh。默认配置为:8 个共享训练/推理节点、128K 上下文、batch 32、每个 prompt 12 个样本、1500 个并发 rollout、500 个训练步;生成同样预留 1 token 上下文余量(MAX_TOKENS = CONTEXT_LENGTH - 1)。
N_NODES选择以下 8-GPU 节点 profile(CPU controller 是额外资源):
| Nodes | Megatron actor | SGLang rollout |
|---|---|---|
| 2 | (attn:d1p2t4c2\|ffn:d1p2e8) | d4t4p1 |
| 4 | (attn:d2p2t4c2\|ffn:d2p2e8) | d8t4p1 |
| 8 | (attn:d2p2t2c8\|ffn:d4p2e8) | d16t4p1 |
| 16 | (attn:d4p2t2c8\|ffn:d8p2e8) | d32t4p1 |
profile 要求使用架构为BailingMoeV3ForCausalLM的 checkpoint,复用现有mbridge桥、支持 CP 的 KDA、Adam(3e-6)、FP32 LM head、AWEX 权重更新;MTP 关闭,virtual pipeline size 为 1。
除上述公共提交环境外,还需设置部署相关路径:
export MODEL_PATH="$FLASH_V3_CHECKPOINT" export ROLLOUT_IMAGE="$FLASH_V3_SGLANG_IMAGE" export AWEX_ROOT="$FLASH_V3_AWEX_SOURCE" export FLASH_LINEAR_ATTENTION_ROOT="$FLASH_V3_FLA_SOURCE" # Optional colon-separated module directories, visible inside worker containers: export ACTOR_RUNTIME_PYTHONPATH="$FLASH_V3_ACTOR_MODULES" export ROLLOUT_RUNTIME_PYTHONPATH="$FLASH_V3_ROLLOUT_MODULES" N_NODES=2 bash examples/swe/submit_arena_flash_v3.sh --print-profile N_NODES=2 bash examples/swe/submit_arena_flash_v3.sh --check-arena N_NODES=2 TRAIN_BATCH_SIZE=4 N_SAMPLES=2 TOTAL_TRAIN_STEPS=1 \ MAX_CONCURRENT_ROLLOUTS=4 bash examples/swe/submit_arena_flash_v3.sh说明:
- 小规模试跑保留 128K 上下文;要改上下文需同时设置
CONTEXT_LENGTH(默认 131072),脚本会连带调整默认生成与 microbatch 预算(MAX_TOKENS/MAX_NEW_TOKENS必须为正且小于CONTEXT_LENGTH),并校验N_NODES只能取 2/4/8/16; --print-profile仅打印节点/actor/rollout/上下文/batch/samples/steps/并发等 profile 摘要,不联系 Arena、不提交作业;- 长任务需调整 worker/controller 时间限制;
- 这是资源 profile,不保证所选 checkpoint 与序列长度一定装得进 GPU 显存;
- 默认数据集文件钉住两个源 Stream、其 Harness 与 reward 版本且采样权重相等(即 flash-v3-multi-stream.yaml),需要时可设置
DATASET_CONFIG指向其他共享 streams YAML。
运行时依赖与兼容性约束
- 运行时必须提供 Ling3 工具/推理 parser 与 Flash V3 推理支持(arena_flash_v3.yaml 中
tool_call_parser: ling3、reasoning_parser: ling3,并挂载FLASH_LINEAR_ATTENTION_ROOT与AWEX_ROOT到 workerPYTHONPATH); - 当前 AWEX 插件仅接受 SGLang
0.5.9或0.5.10.post1,外部 AWEX checkout 必须注册 Flash V3 converter; - FLA 必须支持该 checkpoint KDA 的
safe_gate与lower_bound参数; - 脚本不负责安装依赖;GPU worker 为 AWEX 兼容性显式禁用 expandable-segment 分配(
PYTORCH_CUDA_ALLOC_CONF: ''); - worker 侧额外设置了
CUDA_DEVICE_MAX_CONNECTIONS=1、AWEX_COLOCATE_TIMEOUT_S=7200与AREAL_AWEX_PROCESS_QUEUE_WHEN_IDLE=1。
与 swe-dev 完整配方的差异(训练语义提醒)
本 profile 保持 main 分支的outcome-only GRPO:rollout 组归一化包含标准差,不完整组被丢弃(reward_normalization: true、drop_incomplete_group: true)。它不重现swe-dev的 PRM/RewardSystem 奖励、仅均值组归一化、最少 8 个部分组、以及自适应思考控制;chat 渲染使用 checkpoint 模板默认值加 Harness 请求覆盖。这些差异会影响训练语义——该 profile 的定位是Arena 集成验证,而不是完整配方等价性的声明。
小结
从两节点 FSDP 冒烟测试到 16 节点的 Megatron/SGLang Flash V3 profile,AReaL 的 Arena 集成提供了一条“外部评测 + 内部训练”的完整路径:通过凭证文件与 Slurm 提交脚本实现安全部署,通过 Stream 配置与预检工具保证“钉住即正确”,通过session_gateway路由与顶层score奖励保持训练与评测的清晰边界。无论是单流快速验证还是多流大规模训练,都可以基于 examples/swe/ 下的模板直接落地。
【免费下载链接】AReaLThe RL Bridge for LLM-based Agent Applications. Made Simple & Flexible.项目地址: https://gitcode.com/GitHub_Trending/are/AReaL
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考