Qwen3-8B-OpenClaw-RL-iter215

Qwen/Qwen3-8BHansBug/OpenClaw-RL 的训练框架做 GRPO outcome-only RL(dense pass-rate reward,无 PRM、无 process reward)跑出来的中间 checkpoint,对应 wandb run msp60ius 的 iter 215。在 terminal-bench v0.1.x 86 个 terminal-agent 任务上把 base Qwen3-8B 的 pass@1 从近 0 推到 0.056(OOD eval)。

完全 drop-in 兼容:config / generation_config / tokenizer 全部跟上游 Qwen/Qwen3-8B 字节级一致(diff 无差);任何能跑 Qwen3-8B 的工具链(HF transformers、vLLM、sglang、ollama、llama.cpp 转 GGUF 等)一行都不用改


目录

  1. 快速开始
  2. 模型从哪来
  3. 训练设置
  4. 训练曲线
  5. 评测结果
  6. 任务级别的训练表现
  7. 推理时的 on-the-wire 协议
  8. 已知限制
  9. 复现 / 推理工具
  10. 引用 / 致谢

快速开始

用 HF transformers

from transformers import AutoTokenizer, AutoModelForCausalLM

tok = AutoTokenizer.from_pretrained("HansBug/Qwen3-8B-OpenClaw-RL-iter215")
model = AutoModelForCausalLM.from_pretrained(
    "HansBug/Qwen3-8B-OpenClaw-RL-iter215",
    torch_dtype="bfloat16",
    device_map="auto",
)

messages = [
    {"role": "user", "content": "Write a one-line bash command to recursively count *.py files under /usr/lib."}
]
text = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tok(text, return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=256, temperature=0.2)
print(tok.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True))

用 sglang(推荐,配 tool-call 支持)

python -m sglang.launch_server \
    --model-path HansBug/Qwen3-8B-OpenClaw-RL-iter215 \
    --served-model-name qwen3-8b-rl-iter215 \
    --tp 1 --port 30000 \
    --tool-call-parser qwen

跟 base Qwen3-8B 一样的启动参数。--tool-call-parser qwen(或 qwen25)把模型的 <tool_call>{...}</tool_call> 还原成 OpenAI 结构化 tool_calls,这正是训练时 rollouts 用的 parser。

用 vLLM

vllm serve HansBug/Qwen3-8B-OpenClaw-RL-iter215 --enable-auto-tool-choice --tool-call-parser hermes

用 oc-repl 直接交互(端到端 demo)

HansBug/oc-repl 是一个针对这个 ckpt 量身写的 Codex 风格 REPL:

pip install git+https://github.com/HansBug/oc-repl

# 起一个 sandbox 容器(任何 ubuntu/python image 都行;下面用 terminal-bench 现成的)
docker run -d --name oc-sandbox -w /app ubuntu:24.04 sleep infinity

# 启动交互式 REPL
oc-repl --sandbox docker:oc-sandbox \
        --api-base http://127.0.0.1:30000/v1 \
        --model qwen3-8b-rl-iter215

oc-repl 默认 --protocol camel-terminal-toolkit 对齐训练分布,详见仓库 README。


模型从哪来

Qwen3-8B-OpenClaw-RL-iter215 = Qwen3-8B + 215 个 RL iteration 的 GRPO outcome-only 训练,rollout 在 SETA terminal env pool 提供的 1367 个 terminal task 上。每个 task 是一个真实的 Linux shell 任务(修脚本、解 base64、起 server、跑 pytest…),在隔离 docker 容器里跑,agent 通过 camel.toolkits.TerminalToolkit 暴露的 4 个工具操作 shell。

简单地说:用 camel-ai 的 agent harness 在 terminal-bench 风格的任务上把 Qwen3-8B 训成一个能干活的 terminal agent

基座 Qwen/Qwen3-8B(reasoning 模型,原生带 <think> chain-of-thought)
训练框架 HansBug/OpenClaw-RL (Megatron + slime + sglang rollout)
Agent harness camel-ai ChatAgent + TerminalToolkit
数据 seta_env 1367 task pool(含 terminal-bench v0.1.x 86 task 子集)
算法 GRPO outcome-only,dense pass-rate reward (advantage_estimator=grpo)
训练总 step 215 iter(约 3440 rollout × 16 prompt × 8 sample/prompt)
训练硬件 8× NVIDIA H200,actor 4×TP + rollout 4×TP
训练时长 约 5 天
Wandb hansbug/openclaw-terminal-rl/runs/msp60ius

训练设置

完整启动命令见 run_qwen3_8b_experiment.sh。关键超参:

# GRPO 算法
--advantage-estimator grpo
--use-kl-loss --kl-loss-coef 0.01 --kl-loss-type k3
--dynamic_history

# Optimizer (low LR + Adam beta2=0.98)
--optimizer adam --lr 1e-6 --lr-decay-style constant
--weight-decay 0.1 --adam-beta1 0.9 --adam-beta2 0.98

# Rollout
--rollout-batch-size 16
--n-samples-per-prompt 8           # 每 prompt 采 8 个 sample 算 GRPO group std
--num-steps-per-rollout 2
--rollout-temperature 1
--rollout-max-response-len 8192
--rollout-max-context-len 16384

# Megatron
--tensor-model-parallel-size 4
--sequence-parallel
--recompute-granularity full

# Rollout agent + tool-call parser
--custom-config-path configs/rollout_qwen3.yaml   # tool_call_parser: qwen25
                                                  # max_iteration: 10

Reward signal:dense pass-rate, outcome-only —— 每个 rollout 跑完后由任务自带的 run-tests.sh 在 sandbox 里跑 pytest,reward = passed / total_tests ∈ [0, 1],再线性变换到 score = 2·reward − 1 ∈ [-1, +1] 喂给 GRPO;没有 PRM / process reward,整个 episode 共用一个标量。

max_iteration: 10:训练时 agent loop 上限 10 轮。

tool_call_parser: qwen25:sglang 把模型的 <tool_call>{"name":..., "arguments":...}</tool_call> markup 转回 OpenAI tool_calls 喂给 camel ChatAgent。


训练曲线

来自 wandb run msp60ius(rows=1671;以下是用 scan_history API 拉出的实际数据点):

training curves

四个子图说明:

子图 解读
rollout accuracy rollout 阶段 agent 报告的任务通过率。0 → 0.71 顶点,末段 0.576 稳定。整个训练在持续上升。
reward_mean outcome score 的均值(score = 2·pass_rate − 1 ∈ [−1, +1]:−1 = 一个 test 都没过,0 = 平均 pass 一半,+1 = 全过)。从 −0.5 升到 +0.42 顶点,最后稳在 +0.15。穿越 0 是关键信号,表示模型从"过的 test < 一半"转向"过的 test > 一半"。
response_len 每轮 assistant 输出的平均 token 数。一直在涨(150 → 270 → 顶 784),模型在学习更长的多步推理 / 工具调用链。
non_trainable_ratio GRPO group 里 σ=0(同 prompt 8 sample 全成功 / 全失败)的比例。这部分对 GRPO 不贡献梯度。训练始终保持在 < 5%,说明任务 pool 给出了足够的 reward 方差,绝大多数 prompt 都在产生有效梯度。

评测结果

在 terminal-bench v0.1.x(86 task)上的 pass@1

iter215 这个 ckpt 在 OOD eval(agent harness 切到 tb run --agent terminus-2)上的成绩:

模型 pass@1 体量 备注
Qwen3-8B-OpenClaw-RL-iter215 0.056 8 B 本 ckpt(OOD eval)
Qwen3-8B (base) ~0.005 8 B RL 训练起点,几乎全失败
Qwen3-235B-A22B (Terminus 1) 0.066 235 B (active 22 B) TB 官方 leaderboard
DeepSeek-R1 0.057 671 B TB 官方 leaderboard
AfterQuery GPT-OSS-20B SFT+RL 0.170 20 B SFT + RL(更完整的 pipeline)
Qwen3-32B + TerminalAgent 0.155 32 B TB 官方 leaderboard
Claude 4.5 Sonnet 0.645 闭源 frontier
GPT-5 0.525 闭源 frontier

把 base Qwen3-8B 从 ~0 拉到与 Qwen3-235B / DeepSeek-R1 同水位,用 30× 更少的参数

leaderboard chart

在 eval-as-train 设置下的天花板

把 TB v0.1.x 86 个任务直接当训练集跑 84h / 320 rollout 得到上限 pass@1 = 0.092(同样 OOD 评测路径)。意思:模型在 8B 这个尺寸下、消除分布漂移后,自然能力上限大概在 9.2%。剩下要到 17%+(AfterQuery SFT+RL 那个水位)需要 cold-start SFT + 更好的 agent harness + 更对路的数据,详见 OpenClaw-RL issue #10


任务级别的训练表现

把训练 log(37k trial × 85 task)按任务切片,每个任务算 reward (mean, std, strict_n):

per-task scatter

8 个 task 类别:

类别 数量 占比 含义
truly-cold-flat 25 29% mean = 0、std = 0:320 rollout × 8 sample 从没采到任何 partial reward。GRPO 对这些 task 永远 0 梯度。
truly-cold-noisy 6 7% 接近 0 mean、低 std:偶尔有微小 partial credit 噪声
partial-stuck-flat 9 11% mean ∈ [0.5, 0.9]、std 极低:模型靠 partial credit 拿了 50-90% 分但永远碰不到 strict=1.0 阈值。最高 swe-bench-astropy-2 mean=0.889 strict=0
partial-noisy 22 26% partial credit 区间但 std 较高,可能可以推到 strict
weak-learnable 9 11% low mean、low strict_n:偶有突破但非主流
mid-learnable 5 6% mid mean、中等 strict_n
truly-learnable 4 5% mean > 0.6、strict_n > 100:模型在这 4 个 task 上真实学到东西(hello-world / fix-permissions / fibonacci-server / vim-terminal-task)
strict-flat 1 1% swe-bench-fsspec 异常:100% strict 但 std=0(verifier shortcut)

结论:8B + 86 task pool 的瓶颈不是模型容量,是 task pool 信号分布——36% 真冷 + 38% 差一口气;要进一步提升需要换 dataset(seta_env 1367 task pool 已经在主训练里用了,这是为何 iter215 比 eval-as-train 上限 0.092 还低)。详见 OpenClaw-RL issue #10 长 comment


推理时的 on-the-wire 协议

训练时这个 ckpt 看到的协议是 camel-ai TerminalToolkit 的 4 工具 OpenAI function-calling不是 terminal-bench 的 terminus-2 JSON 协议。证据:

文件 说明
terminal-rl/agent/camel_agent.py rollout agent = camel.agents.ChatAgent 子类
terminal-rl/remote/terminal_env.py:163-185 env 在 reset 时把 camel.toolkits.TerminalToolkit 的 4 个工具(shell_exec / shell_view / shell_write_to_process / shell_write_content_to_file)封装成 OpenAI tool schema 喂给 rollout
terminal-rl/configs/rollout_qwen3.yaml:1 tool_call_parser: qwen25 — sglang 把模型 <tool_call>{...}</tool_call> markup 转回 OpenAI tool_calls
训练 log 实证 <tool_call> 出现 628 次,terminus-2 JSON 的 key "task_complete" 出现 0 次

System prompt 是 terminal-rl/agent/camel_agent.py::get_developer_agent_prompt()system='Linux (in Docker)', machine='x86_64', non_think_mode=True 配置下产出的整段,结尾加 /no_think(关闭 qwen3 的 think trace,让模型直接 emit tool_call)。

如果你想 100% 复刻训练分布在 inference 用这个 ckpt,用 HansBug/oc-repl 的默认 --protocol camel-terminal-toolkit——它把上面这些设置都字节级对齐了。


已知限制

  1. 模型不会主动停止 tool_call。训练时 agent loop 由 max_iteration: 10 硬截断 + outcome reward 兜底,模型没学到"做完后不发 tool_call、写一段总结"这个动作。inference 时如果没有 max-turns 兜底,模型会无限制地重复 verify。Inference 端要自己设上限(oc-repl 默认 12 轮)。

  2. task_complete 自报 ≠ 任务真完成。模型说"完成"不一定真完成,验证要做客观检查(diff、tests、verifier)。oc-repl 提供了 --verify / --verify-file hook 专门处理这件事。

  3. 复杂多步 task adherence 中等。简单任务(chmod、cat、ls)adherence 满分;要写多行 Python 服务器、复杂 awk 这种,模型偶尔会 thinking 太久没产出 tool_call。

  4. terminus-2 / terminus-XML 协议是 OOD。模型没在这些协议上 RL 训练过,能不能跑通靠 qwen3 底座的通用指令跟随能力。要复刻训练分布请用 camel TerminalToolkit 协议。

  5. 不是 frontier 水平。pass@1 0.056 跟 Qwen3-235B 同水位,但跟 Claude 4.5 / GPT-5 还有 10×+ 差距。这个 ckpt 适合做 RL 训练框架的 baseline / case study,不适合直接当 production agent 用。


复现 / 推理工具

仓库 / 工具 用途
HansBug/OpenClaw-RL 完整的训练框架(slime + Megatron + sglang),含 launch script、配置、agent code
HansBug/oc-repl 针对这个 ckpt 的 Codex 风格 REPL,支持 4 种推理协议 (camel-terminal-toolkit 默认 = 训练分布字节级复刻)
HansBug/OpenClaw-RL issue #10 eval-as-train capacity probe 报告 + std analysis + per-task 8 类拆解
HansBug/OpenClaw-RL issue #13 demo 视频(4 个 TB 任务 × 2 个协议 = 8 个 gif/mp4)

引用 / 致谢

License: Apache-2.0(继承自 Qwen3-8B)。

如果你用这个 ckpt 做 paper / blog post,欢迎引用 HansBug/OpenClaw-RL 仓库 + 这个 model card。

Downloads last month
28
Safetensors
Model size
8B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for HansBug/Qwen3-8B-OpenClaw-RL-iter215

Finetuned
Qwen/Qwen3-8B
Finetuned
(1614)
this model