跳到正文

目录

OpenRSI 工程全解:把「AI 改进 AI」变成可执行代码的完整技术栈

2026 年七月底,FrontisAI 把 OpenRSI 推上了 GitHub。仓库定位写在 README 第一行:Making “AI improving AI” executable, measurable, and reproducible——让"AI 改进 AI"变得可执行、可测量、可复现。

三个词里,“可执行"最难。递归自我改进(RSI)作为概念在讨论区存在多年,论文也出了不少,但绝大多数止步于"提出了框架,在小规模任务上验证了可行性”。真正做成能 clone 下来、有完整训练管线、有部署模式选择、有权重和数据分发的工程项目,OpenRSI 是少数几个之一。

本文从工程视角看这套系统:代码怎么组织,训练怎么跑起来,每个架构决策背后是哪一种取舍

为什么把 RSI 工程化很难

AI 改进 AI,落到机器学习工程(MLE)场景,就是给一个模型一个 ML 任务(比如 Kaggle 竞赛),让它自己写代码、跑实验、看结果、改方案、再跑,循环往复直到性能收敛。这个循环听起来像普通 Agent 任务,工程上有四道难关:

第一道:执行接地。 模型生成的不是文本答案,而是要在沙箱里真实运行的代码。一次 rollout 涉及几十上百次代码执行,每次可能跑几十分钟。训练系统必须和一个异步的、长尾延迟的执行环境打交道,这和传统 RLHF 里"调一次 reward model 打分"不是同一个量级。

第二道:奖励异构。 不同任务的评分体系完全不同——AUC 越高越好,RMSE 越低越好,有些还有自定义指标。把几千个任务的原始分数映射成统一的、可用于梯度更新的奖励信号,需要一个专门的归一化层。

第三道:长时程搜索的信用分配。 一次完整的进化搜索可能有几百代,最终的性能提升该归功于哪一步——是第 3 代的 Draft 方案开了好头,还是第 47 代的 Debug 修复了关键 bug?信用分配链条极长。

第四道:规模。 论文报告的训练用了 5,758 个任务环境、26,259 条 SFT 样本、成规模的在线 RL。没有分布式训练框架和异步 rollout 架构,这套系统跑不动。

OpenRSI 对四道难题都给出了工程答案,并把答案开源了。

顶层架构:四个组件各司其职

仓库顶层结构很克制,核心是四个目录:

OpenRSI/
├── OpenMLE-Gym/      # 任务构建与评估
├── OpenMLE-ERL/      # SFT + RL 训练
│   ├── SFT/
│   └── RL/
├── OpenMLE-Evo/      # 长时程进化搜索
├── docs/             # 结果、训练、发布范围文档
├── assets/           # 图与品牌资源
├── LICENSE
└── NOTICE

四个组件对应流水线的四个阶段:

组件角色一句话理解
OpenMLE-Gym任务环境把"一个 ML 任务"打包成可执行、可验证的标准格式
OpenMLE-ERL训练引擎用 SFT + 在线 RL 教会模型四个进化操作符
Frontis-MA1推理产物训练出来的权重,在 HuggingFace 上分发
OpenMLE-Evo搜索引擎把操作符组织成跨任务的长时程进化搜索

这套分层的关键是训练和推理共享同一套动作空间:模型在训练时学的 Draft / Improve / Debug / Crossover 四个操作符,推理时搜索引擎调用的也是这四个操作符。动作空间从训练到部署零漂移,训练阶段收集的每一条经验,都在直接优化推理时真正会用到的那组行为。

模型权重(Frontis-MA1)不在代码仓库里,而是作为 HuggingFace 产物分发。代码仓库只管"怎么训"和"怎么搜",权重是流水线的输出;用同一套代码也可以训出自己的权重。

OpenMLE-Gym:把一切变成可验证任务包

流水线的源头是任务。OpenMLE-Gym 负责构建、描述、执行和质量检查可验证的 MLE 任务包。

任务来源分三档:

来源任务数
精选锚点156
Kaggle Dataset 任务3,362
Kaggle Competition 任务2,240
总计5,758

156 个精选锚点是人工把关的高质量任务,保证分布的核心质量;两档 Kaggle 任务提供规模。“少量精 + 大量广"的组合在训练数据构建里常见,但放到"任务环境"粒度,数据配比就从样本级上升到了环境级。

Gym 的核心职责是验证。一个任务包必须能被自动执行、自动评分,才能进入训练管线。它叫 Gym 而不叫数据集,就是因为对标的是强化学习里的环境抽象,而不是一批样本。

OpenMLE-ERL:训练引擎的双层结构

ERL(Evolutionary Reinforcement Learning)目录是仓库的重心,分 SFT 和 RL 两层。这不是简单的"先 SFT 再 RL"两阶段串联,两层各自承担明确的工程职责。

SFT 层:数据选择管线比训练本身更值得看

SFT 的入口在 OpenMLE-ERL/SFT/scripts/sft_data_selection/,四个脚本组成一条四步管线:

exclude_reserved_tasks.py → select_parallel.py → select_evolutionary.py → finalize_messages.py

第一步:排除评测任务。 exclude_reserved_tasks.py 把所有评测基准里出现的任务从训练池里剔除。这是防数据泄漏的硬闸门,放在管线最前面。

第二步:平行路径选 Draft。 select_parallel.py 从平行探索的 rollout 里挑分数过阈值的 Draft 方案。Draft 是冷启动操作符——给一个任务从零写出第一个方案——它的训练数据主要来自"多条独立路径里跑出来的成功尝试”。

第三步:进化路径选改进类步骤。 select_evolutionary.py 从进化链条里挑有用的 Improve、Debug、Crossover 步骤。这三个操作符的输入都依赖上下文——父程序长什么样、上次执行报了什么错、两个父代各有什么优点——所以它们的数据必须来自真实的进化轨迹,而不是独立采样。

第四步:格式化。 finalize_messages.py 统一格式化为训练消息。

第二步和第三步的分野很细腻:冷启动能力和改进能力的数据来源天然不同,混着采样会稀释两者的信号。

最终语料(去重并过滤 32,768-token 全消息后)的构成:

维度类别样本数占比
监督类型完整响应17,24565.7%
监督类型轨迹步骤9,01434.3%
操作符Draft19,43674.0%
操作符Debug4,34016.5%
操作符Improve1,7416.6%
操作符Crossover7422.8%

Draft 占近四分之三,和它在搜索中的角色匹配——大部分计算都花在从零起草上,改进类操作是稀疏但高价值的修正。

Slime:为什么训练后端要自己造

SFT 的训练后端是 OpenMLE-ERL/SFT/slime/,一个基于 SLIME(vendored 的 THUDM 分布式训练框架)改造而来的训练栈。真实结构和通用 SLIME 的布局一致:

slime/
├── slime/                       # SLIME 包本体
│   ├── backends/               # 训练后端
│   │   ├── fsdp_utils/         # FSDP 后端(actor.py 约 41KB)
│   │   ├── megatron_utils/     # Megatron-LM 后端
│   │   └── sglang_utils/       # SGLang 推理后端
│   ├── rollout/                # rollout 组件
│   ├── router/  utils/  ray/
├── slime_plugins/              # 插件
│   ├── models/                 # 模型适配(qwen3_5.py、hf_attention.py)
│   └── megatron_bridge/        # Megatron 与框架的桥接
├── scripts/models/             # 模型配置脚本
├── tools/
└── train.py  train_async.py

两个设计点值得注意:

  1. FSDP 与 Megatron-LM 双后端并存,另有 SGLang 推理后端。30B / 35B 全参数训练走 slime_scripts/ 下的启动器。
  2. Qwen 模型有专门适配slime_plugins/models/qwen3_5.py 是一个独立的模型插件,说明这个栈按多模型可插拔的标准建造,而不是只服务某一张卡。

仓库并不自带训练数据、权重、checkpoint 和凭证,这些都在代码库之外分发。为什么不用现成的通用框架?从 RL 阶段的需求看,训练要和异步沙箱执行深度耦合,通用训练框架的 rollout 接口接不进去这种执行环境;自己掌握训练栈,才能在 SFT 和 RL 之间共享基础设施。

RL 层:核心文件逐个看

OpenMLE-ERL/RL/ 是执行接地强化学习的实现。挑几个最能说明系统设计的文件看:

generate_mle.py(94KB)——Rollout 核心引擎。 全仓库最大的单文件,管理一次 MLE rollout 的完整生命周期:沙箱执行调度、程序数据库交互、操作符调用、经验收集。它本质上是"LLM 策略"和"真实 ML 执行环境"之间的状态机。

program_database.py(62KB)——程序数据库。 进化搜索的核心数据结构。它维护所有候选方案的种群和进化树:父子关系、分数历史、方法族分类。进化算法的"记忆"全在这里——哪些方向试过、效果怎样、哪个族系最有潜力。独立成 62KB 模块而不是散在 rollout 代码里,是因为它的状态管理复杂度足够独立成库,而且 SFT 数据选择阶段也要读它。

reward_func_utils.py(58KB)——奖励归一化。 解决"第二道难关"。几千个异构任务的原始分数(AUC、RMSE、自定义指标)在这里统一映射到 [0,1] 奖励,并实现自适应边界——奖励的上下界随任务历史动态调整,避免不同难度任务的奖励尺度互相碾压。

airaevo_experience.py(25KB)——经验管理。 维护经验卡片和经验板,实现三因子父节点选择。进化搜索里"选谁当父代"直接决定搜索效率,三因子机制让选择不只看分数。

prompt_builder.py(22KB)——操作符 Prompt 构建。 四个操作符各有各的 prompt 模板:Draft 需要任务描述,Improve 需要父程序和执行反馈,Debug 需要错误堆栈,Crossover 需要两个父代。独立成模块,prompt 工程就能和训练逻辑分开迭代。

adaptive_reward_advantage_utils.py——优势计算。 自适应奖励边界 + 熵优势加权的算法实现,和 reward_func_utils.py 配合构成完整的奖励后处理链。

fully_async_rollout.py——异步 rollout 引擎。 传统同步 RL 的节奏是:所有 rollout 跑完 → 更新策略 → 下一轮。MLE 场景里一次代码执行可能要跑几十分钟,同步模式下整个集群都在等最慢的那个沙箱作业。异步 rollout 把策略更新和最慢作业解耦,GPU 利用率不再被长尾延迟绑架。

四种部署模式:从笔记本到集群

RL 层提供了 sync/async × single/multi-node 四种启动模式,每种都有独立的 .env.example 配置模板和 .sh 启动脚本:

configs/
├── sync_single_node.env.example
├── sync_multi_node.env.example
├── async_single_node.env.example
└── async_multi_node.env.example
scripts/
├── run_openmle_rl_sync_single_node.sh
├── run_openmle_rl_sync_multi_node.sh
├── run_openmle_rl_async_single_node.sh
└── run_openmle_rl_async_multi_node.sh

选择指南浓缩成一张表:

模式适用场景取舍
sync_single_node开发调试、单卡/单机验证最直观,吞吐最低
sync_multi_node标准规模训练实现成熟,被长尾沙箱拖累
async_single_node单机榨利用率消除等待,复杂度上升
async_multi_node生产级最大吞吐全量收益,运维成本最高

这个 2×2 矩阵的好处是开发和生产走同一条代码路径,只是配置不同:你在 sync_single_node 上调通的功能,切到 async_multi_node 不需要改代码。异步逻辑的复杂度被收在 fully_async_rollout.py 和配置开关里,不泄漏到算法层。

RL 的关键配置:操作符采样概率 Draft 50% / Improve 17% / Debug 17% / Crossover 16%;每组 rollout 16 prompts × 16 samples;最大响应 24,576 tokens;优化器用 GSPO 加执行接地奖励后处理。注意采样分布和 SFT 语料分布(74/6.6/2.8/16.5)明显不同——RL 阶段刻意压低了 Draft 占比、抬高了三个改进类操作符的占比。SFT 建立基础能力分布,RL 把探索预算往"改进"倾斜,因为改进类操作才是搜索效率的杠杆。

OpenMLE-Evo:搜索引擎的效率账

训练出来的操作符最终由 OpenMLE-Evo 组织成长时程搜索。它支持标准同步和异步多 GPU 两种搜索模式,并提供基准适配器接外部评测(MLE-Bench 和 NatureBench Lite-v2 是并行的两个适配器,共享同一个 AIRA-Evo 运行时)。

和原始 AIRA-Evo 的对比数据(66 个匹配的 task–run,同一 checkpoint、同一 seed、同一 12 小时任务预算):

指标原始 AIRA-EvoOpenMLE-Evo变化
总模型 token129.3M75.3M-41.7%
Prompt token83.5M41.5M-50.3%
评估节点3,4303,004-12.4%
新最佳验证更新229246+7.4%
新最佳/百万 token1.773.27+84.3%
Improve 命中新最佳率4.73%9.36%+4.63pp

先说清楚这张表在测什么:它测的是token 消耗、上下文长度和验证轨迹产出率,不是墙钟速度。两个系统的评估预算和模型输入不同,所以不能从这组数字推出"OpenMLE-Evo 的推理一定更快"。

这组数字里最有信息量的是 3.27 vs 1.77——每百万 token 产出的新最佳方案数提升了 84.3%。token 就是钱和时间,单位 token 的搜索效率接近翻倍,意味着同样的算力预算能搜更深的树。

两个辅助证据支撑这个结论:评估节点数降了 12.4% 但新最佳更新反而多了 7.4%,说明剪枝变准了,砍掉的主要是低价值分支;Improve 命中率从 4.73% 跳到 9.36%,直接验证了 RL 阶段往改进类操作符倾斜探索预算的策略有效。

模型级能力:Frontis-MA1 在 MLE-Bench Lite 上的提升

token 效率回答的是"单位算力搜得更深",但这不等于读者最关心的"模型到底强了多少"。论文对 Frontis-MA1(35B)在 MLE-Bench Lite 上做了一个受控对比:每个任务 12 小时预算、单张 RTX 4090、显存上限 12GB,结果如下:

配置平均奖牌率(Medal Average)
基础模型39.39%
Frontis-MA1(35B)+ OpenMLE-Evo60.61%
Frontis-MA1(35B)+ OpenMLE-Evo-Max71.21%

数字要分开看:从 39.39% 到 60.61% 是"训练带来的提升"——同一个框架,只换模型权重,奖牌率涨了约 21 个百分点;从 60.61% 到 71.21% 是"搜索带来的提升"——模型不变,只把 Evo 换成 Evo-Max(引入 benchmark 无关的经验先验和异步搜索)。论文还给出了对标:60.61% 已超过 GPT-5.5 + Codex,71.21% 逼近 GPT-5.6 Sol 和 2.8T 的 Kimi K3。

另有 NatureBench Lite 上的迁移实验,结论更干净:

  • 框架固定、只换模型:Match-SOTA 从 50% 提到 70%;
  • 模型固定、只换搜索引擎:Match-SOTA 从 20% 提到 50%。

两条结果合起来,正好对应系统里"训练"和"搜索"两个可独立替换的旋钮:调哪一个都能带来可测量的收益,二者叠加才是 71.21% 的完整闭环。

一个任务如何流过系统

拿一个 Kaggle 回归任务(比如房价预测)当例子,看它怎么穿过这套系统:

  1. Gym 打包。 OpenMLE-Gym 把任务整理成可执行、可验证的包:数据、prepare.pymetric.py,以及打分函数。任务是"能跑起来、能评分"的单元,不是静态描述。
  2. SFT 阶段。 模型对这个任务跑出 Draft——从零写一个基线脚本,进沙箱执行,拿到 RMSE。这个 (任务, 响应, 分数) 三元组进入数据选择管线,按操作符和分数决定是否进 SFT 语料。
  3. RL 阶段。 同一个任务被反复启用:Draft 打底 → 沙箱执行 → 分数经 reward_func_utils.py 归一化到 [0,1] → Improve 基于父程序和执行反馈改写 → Debug 修崩溃 → Crossover 把两个高分父代杂交。每一步的产物都写进 program_database.py,形成带父子关系的进化树。
  4. Evo 组织搜索。 进化树在 OpenMLE-Evo 里被组织成长时程搜索,若干代之后出现一个分数最高的方案,提交上去。

关键点在第 2、3、4 步用的是同一套操作符:SFT 按操作符分类、RL 按操作符采样、搜索引擎按操作符调用。系统没有为训练和推理各造一套行为,这也是它能把经验从训练直接复用到搜索的原因。

复现路径与开源边界

从 clone 到跑起来的大致路径:

  1. Clone 仓库,先读 docs/ 下的三份文档——results.md(完整结果表和评估边界)、training.md(训练规模事实)、release.md(发布产物映射)。
  2. 拉取产物:HuggingFace 上有 Frontis-MA1-35B / 30B 的 BF16 和 GGUF 权重、OpenMLE-SFT-Traces 数据集、OpenMLE-Tasks 任务清单。只想做搜索推理的话,权重 + OpenMLE-Evo 就够了。
  3. 重建任务环境:5,758 个环境里完整发布 1,415 个,其余 4,343 个提供重建脚本(源数据许可限制,不能整体打包)。
  4. 训练复现:从 sync_single_node 模式起步,验证管线后再往异步多节点扩。

开源边界同样说得很清楚:

  • ✅ 开放:Gym 工具、SFT/RL 训练代码、搜索/评估实现、模型权重、任务构件、训练轨迹数据
  • ❌ 不开放:外部基准环境、沙箱服务、数据集本体、服务凭证、私有基础设施配置
  • ⚠️ 注意:MLE-Bench / NatureBench 的报告数字依赖外部任务环境和评估资产,不在仓库内

这个边界简单:凡是自己拥有产权的全给了,凡是涉及第三方许可或基础设施依赖的都明确标注。许可证是 CC BY-NC 4.0——研究用途畅通,商用要另外谈。

谁适合用,怎么开始

这套系统是为有算力、做 RSI 或 MLE-Agent 研究的团队准备的,不是拿来跑的轻量 demo。

  • 只想做搜索推理:拉 Frontis-MA1 权重(35B / 30B,BF16 或 GGUF)+ OpenMLE-Evo 就够,不用碰训练代码。这是门槛最低的入口。
  • 想复现训练:从 sync_single_node 起步验证管线,再扩到异步多节点。完整复现需要重建 4,343 个任务环境并提供沙箱服务,单机短时间跑不动。
  • 可以缓一缓的团队:没有自建沙箱/执行环境、只是想在普通任务上用更强的 Agent 的团队,直接用现成权重当推理模型即可,不必自建整套训练栈。

训练侧的验证状态值得留意:仓库标注了单节点异步 profile 已完成端到端验证(checkpoint 恢复、两轮 rollout + 优化、SGLang 权重同步、八卡 H200 上评估),但这不等于论文结果的完整复现——后者还依赖外部环境和评估资产。

设计哲学:三个贯穿始终的决策

通读整个仓库,三个设计决策反复出现:

操作符原子化。 把"改进 AI"这个大动作分解为 Draft / Improve / Debug / Crossover 四个原子操作符,每个有独立的 prompt 模板、独立的数据选择逻辑、独立的采样概率。原子化让信用分配可行——奖励可以打到具体操作符的行为上,而不是模糊的"整个搜索过程"。

训练-推理动作空间统一。 训练学什么,部署用什么。SFT 按操作符分类、RL 按操作符采样、搜索按操作符调用,同一条线贯穿三个环节,这是效率提升的结构性来源之一。

经验驱动搜索。 程序数据库 + 经验卡片 + 三因子父节点选择,构成一套显式的"记忆系统"。搜索不是无状态的随机游走,而是从自己的历史里学习——这可能是 OpenMLE-Evo 相对原始 AIRA-Evo 效率接近翻倍的结构性来源。

结语

OpenRSI 示范了一种把宏大概念工程化的路径:先把"AI 改进 AI"分解为有限个可验证的原子操作,再为每个操作建数据管线、训能力、配奖励,最后用搜索引擎把操作组织回长时程行为。每一步都有对应的代码模块,每个模块都有明确的边界和接口。


项目资源

参与讨论

使用 GitHub 登录。欢迎补充事实、异议与实践。