Skip to content

feat: 新增 tiny_python_expr 最小 RL 示例#60

Open
HansBug wants to merge 2 commits into
opendilab:mainfrom
HansBug:codex/tiny-python-expr-demo
Open

feat: 新增 tiny_python_expr 最小 RL 示例#60
HansBug wants to merge 2 commits into
opendilab:mainfrom
HansBug:codex/tiny-python-expr-demo

Conversation

@HansBug
Copy link
Copy Markdown
Member

@HansBug HansBug commented Apr 20, 2026

改动说明

  • examples/tiny_python_expr 下新增一个最小纯文本 RL example
  • 数据集由 build_dataset.py 现场生成,格式可直接接 LightRFT 训练入口
  • reward 只保留最简单的两部分:format + correctness
  • train_colocate.py 是自包含的最小训练入口,只保留这个例子真正需要的参数
  • run_qwen25_3b.sh 作为本地和集群 worker 共用的最小启动脚本
  • 新增 example 内部 .gitignore,忽略运行时生成的 data/artifacts/__pycache__/
  • 不再保留单独的 run_rlaunch.sh,完整 rlaunch 流程直接写进 README.mdREADME_zh.md
  • 补充了“先单独构建数据集,再复用同一份数据训练”的可复制命令,并增加 SKIP_DATASET_BUILD=1 以避免覆盖已导出的数据

目录结构

  • build_dataset.py:生成 train/test split,并导出 Hugging Face DatasetDict
  • reward_models_utils.py:规则 reward 逻辑
  • train_colocate.py:最小训练入口
  • run_qwen25_3b.sh:最小启动脚本
  • README.md / README_zh.md:中英文使用说明与 rlaunch 流程

验证

  • bash -n examples/tiny_python_expr/run_qwen25_3b.sh
  • python3 -m py_compile examples/tiny_python_expr/build_dataset.py examples/tiny_python_expr/reward_models_utils.py examples/tiny_python_expr/train_colocate.py
  • python3 examples/tiny_python_expr/build_dataset.py --output_dir /tmp/tiny_python_expr_repo_check --train_size 2 --test_size 1 --seed 123
  • python3 examples/tiny_python_expr/build_dataset.py --output_dir /tmp/tiny_python_expr_dataset_doc_check --train_size 4 --test_size 2 --seed 42

说明

  • 这个 PR 当前已经基于最新 upstream/main 重新整理,只包含 examples/tiny_python_expr 相关改动,不再混入 dev/st 的其他内容
  • 默认使用 WANDB_MODE=offline
  • 如果要在线同步 W&B,可额外提供 LIGHTRFT_WANDB_API_KEYWANDB_API_KEY,并设置真实可用的 WANDB_ORG

@HansBug HansBug force-pushed the codex/tiny-python-expr-demo branch from 245344d to ad95a98 Compare April 20, 2026 03:29
@HansBug HansBug changed the title Add tiny Python expression RL example feat: 新增 tiny_python_expr 最小 RL 示例 Apr 20, 2026
@HansBug
Copy link
Copy Markdown
Member Author

HansBug commented Apr 20, 2026

补一份基于当前 tiny_python_expr example 代码路径的真实长运行验证,形式参考此前 dev/st 相关 PR 里的实验汇报 comment。这次使用的是 2026-04-19 在真实 2 GPU rlaunch 环境下完成的一次 20-episode 长运行,而不是只做本地 smoke。

1. 本次实验对应的真实运行

  • W&B run: https://wandb.ai/hansbug/Tiny-Demo-Qwen25-3B/runs/10nhbxla
  • run name: tiny-python-expr-20260419_221302
  • state: finished
  • raw train log: /mnt/shared-storage-user/zhangshaoang/LightRFT/examples/tiny_python_expr/artifacts/rft_logs/tiny-python-expr-20ep-wandb/tiny-python-expr-20ep-wandb_node0_20260419_221302.log
  • host log: /mnt/shared-storage-user/zhangshaoang/LightRFT/examples/tiny_python_expr/artifacts/host_logs/tiny-python-expr-20ep-wandb/tiny-python-expr-20ep-wandb_20260419_221235.log
  • save dir: /mnt/shared-storage-user/zhangshaoang/LightRFT/examples/tiny_python_expr/artifacts/results/tiny-python-expr-20ep-wandb/LightRFT-python-expr-len_128_32-tbs_8-rbs_8-sample_2-ep_20-lr_1e-6-20260419_221302

2. 关键启动配置

这次不是本地单卡试跑,而是实际 2 卡 worker 上完成的完整长运行。核心配置如下:

  • 资源:2 GPU / 40 CPU / 500000 memory
  • GPU: 2 x NVIDIA H200
  • 模型:/mnt/shared-storage-user/puyuan/model/Qwen2.5-3B-Instruct
  • 数据:examples/tiny_python_expr/data/generated
  • rollout engine:sglang
  • num_episodes=20
  • n_samples_per_prompt=2
  • train_batch_size=8
  • rollout_batch_size=8
  • micro_train_batch_size=1
  • micro_rollout_batch_size=1
  • prompt_max_len=128
  • generate_max_len=32
  • actor_learning_rate=1e-6
  • init_kl_coef=0.001
  • reward 组成:0.1 * format + 0.9 * correctness
  • W&B project:Tiny-Demo-Qwen25-3B

3. 核心结果结论

这次 run 是完整跑完的,最终结果如下:

  • 最终 train/global_step = 40
  • 最终 rollout/reward = 1.0
  • 最终 rollout/accuracy_reward = 1.0
  • 最终 rollout/format_reward = 1.0
  • 最终 rollout/response_length = 6.5
  • 最终 train/step_reward_mean = 1.0
  • 最终 train/kl = 4.776e-09
  • 总运行时长约 242s
  • 从日志里的 CUDA memory summary 看,这次运行 CUDA OOMs = 0

如果把整个 20-episode、40 次 rollout update 都看进去,这次 run 的整体统计是:

  • rollout_reward0.7751.0 之间交替
  • rollout_reward 全程均值约 0.8875
  • accuracy_reward 全程均值约 0.875
  • format_reward 全程稳定为 1.0
  • response_length 全程均值约 6.625
  • 40 次 update 里,有 20 次是 reward=0.775,20 次是 reward=1.0

我这里对这次 run 的判断是:

  • 这条 tiny_python_expr 的最小 RL example 在真实 2 GPU rlaunch 环境下已经可以完整跑通,不只是“能启动”。
  • 这个例子的 reward 曲线看起来会颠簸,但从这次长运行看,更像是 小数据集 + 小 batch + prompt group 轮流出现 导致的稳定交替,而不是训练发散。
  • 具体地说,交替出现的两类 batch 分别对应:
    • reward=0.775, accuracy=0.75, format=1.0
    • reward=1.0, accuracy=1.0, format=1.0
  • 因为这个 toy 数据集非常小,而且 rollout 配置也很小,所以曲线不会像大任务那样平滑单调;但这次 run 的最终状态是稳定收敛到满 reward,并且训练结束干净,没有 OOM 或 crash。

4. 图表

Summary Card

Reward Dashboard

Sample Rollout Cases

5. 对这组图怎么解读

  • Summary Card 主要给出这次真实运行的配置、最终指标和我对“为什么曲线会抖”的一句话总结。
  • Reward Dashboard 可以直接看到这次 run 最关键的现象:format_reward 基本恒定为 1.0,波动主要来自 accuracy_reward,进而把 rollout_reward 拉成 0.775 / 1.0 的交替形态。
  • Sample Rollout Cases 里的样例不是手写示意,而是直接从真实训练日志里提取出来的 rollout 输出,目的是证明这条 example 的输出形态确实已经稳定到简短 \boxed{answer} 风格。

如果后续还需要,我可以继续补两类附加材料:

  • 一条更长的 3B run,对比 n_samples_per_prompt=2n_samples_per_prompt=4 的曲线差异
  • 一份 tiny example 的“为什么会出现锯齿曲线”的更系统分析,把数据集规模、batch 组成、reward 离散性三者单独拆开讲

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.

1 participant