Prhub

#1953 refactor(examples): group examples into infra_features/ and experimental/

原始 PR 作者 Shi-Dong 合并时间 2026-07-30 03:10 文件变更 149 提交数 4 评论 1 代码增减 +181 / -1736

执行摘要

重组 examples 目录并清理废弃示例

PR body 明确说明:The top level of examples/ had grown to 24 entries with no signal about which are verified recipes, which are infrastructure plumbing, and which are unverified experiments. This sorts them so the top level mostly holds training recipes people are expected to run. 即顶层目录因缺少分类信号而难以导航,需要按「已验证配方 / 基础设施管道 / 未验证实验」重新分层,同时清理已被替代或废弃的示例。

值得精读,这是大型目录重组的典型案例。重点关注三类引用形式的区分处理、fully_async 与并发 PR 的冲突规避、以及静态审计替代 CI 的验证方法。若不依赖示例目录,可快速浏览执行摘要与风险部分即可。

讨论亮点

该 PR 的 review 评论为空,仅有一条来自合入者 Zhichenzzz 的批准意见:LGTM, and small nits according to the parents path fixed,指向提交 4870aa3 对 12 处向上路径深度的修正。PR body 中另有两处值得关注的决策讨论:

  • fully_async 刻意保留:作者说明有一个进行中的并发 PR 会迁移 examples/fully_async/,因此本 PR 不触碰它,并确保 examples/fully_async/ 与两个 fully-async 文档页相对 main 完全一致、swe-agent 异步启动器保留原 PYTHONPATH 入口,避免与并发迁移冲突。
  • 引用形式的三分类:作者区分了文件系统路径、dotted module 路径与 Mintlify doc route 三种引用,明确定义哪些会随移动失效、哪些不会,并借此解释了为何 docs.json 中的 /examples/search-r1 路由不动而 docs/examples/retool.md 路由必须删除。

实现拆解

实现拆解共分 5 步:

  1. 建立分类目录并迁移:新增 examples/infra_features/ 收纳运行时/基础设施类管道,包括 low_precisionp2p_weight_transfertrain_infer_mismatch_helpertrue_on_policyrandom_async;将 DrGRPOevaleval_multi_taskformal_mathmulti_agentreproducibilitysearch-r1strands_sglangtau-bench 迁入已有的 examples/experimental/(与 openenv 并列)。

  2. 合并与删除:将 examples/geo3k_vlm_multi_turn/ 合并为 examples/geo3k_vlm/multi_turn/,使两个 geo3k 配方同处一个目录;删除被 retool_v2 完全取代的 examples/retool/ 和废弃的 examples/true_on_policy_vlm/,并移除孤儿文档页 docs/examples/retool.md,同时删掉 retool_v2/tool_sandbox.py 中指向已不存在来源的 provenance docstring。

  3. 三类引用分别处理:PR body 梳理了三种引用形式——文件系统路径(移动即需改)、dotted module 路径(常藏在 scripts/run_*.py 启动器里,最容易漏)、Mintlify 文档路由(由 docs/examples/*.md 文件名派生,与目录布局无关,因此故意不动)。此项顺带修复了三个本来就失效的 dotted path:examples.Dr.GRPO.custom_reducerexamples.experimental.DrGRPO.custom_reducerexamples.vlm_multi_turn.env_geo3kexamples.geo3k_vlm.multi_turn.env_geo3k(后者是 DEFAULT_ENV_MODULE 运行时默认值)、examples/full_asyncexamples/fully_async(注释中的拼写错误)。

  4. 路径深度修复:最后一个提交 4870aa3 修正搬迁后层级加深导致的 __file__/$SCRIPT_DIR 向上路径失效,共 12 处,例如 skills_server.pyparents[3] 改为 parents[4]p2p_weight_transfer/run.pyparents[2] 改为 parents[3],以及 eval/scripts/run-qwen3-{4B,32B}.sh 等 shell 脚本补一个 ..

  5. 文档与静态验证:重写 examples/README.md,补录此前缺失的 loramulti_lorap2p_weight_transferrandom_asyncretool_v2 条目,并修复失效的 strands-agents 链接;新增 examples/infra_features/README.md 落地页;更新 docs/docs.json 导航。由于 examples/ 在 pytest 的 norecursedirs 中、CI 不 import 示例代码,验证改为静态审计:所有 examples/... 路径 token、所有 dotted examples.* 引用、docs.json 中 76 条页面/组根引用、9 条 from examples.... import ... 均逐一核对可解析。

文件 模块 状态 重要度
examples/README.md 示例索引 modified 7.44
docs/docs.json 文档导航 modified 6.72
examples/experimental/eval/nemo_skills/skills_server.py 评测服务 renamed 6.25
examples/geo3k_vlm/multi_turn/rollout.py 多轮环境 renamed 6.16
miles/utils/arguments.py 参数解析 modified 5.0
examples/retool/generate_with_retool.py 旧版示例 removed 8.22
examples/retool/tool_sandbox.py 旧版示例 removed 8.22
examples/infra_features/README.md 基础设施 added 4.0
examples/true_on_policy_vlm/run_simple.py 示例脚本 removed 7.16
docs/examples/retool.md 文档页面 removed 5.73

关键符号

DEFAULT_ENV_MODULE format_conversation_with_tools postprocess_predictions postprocess_responses execute_predictions PythonSandbox execute_code prepare execute

关键源码片段

examples/experimental/eval/nemo_skills/skills_server.py rename-or-move

典型的重命名加固文件:目录层级加深后 REPO_ROOT 从 parents[3] 改为 parents[4],同包 import 前缀改为 examples.experimental,可看出所有搬迁文件需要同步处理的两种路径写法。

# examples/experimental/eval/nemo_skills/skills_server.py
# 目录层级加深后,需要同步修正两类路径写法,否则脚本无法启动。# 1) REPO_ROOT: 从 examples/eval/nemo_skills/ 向上到仓库根原来是 parents[3];
# 搬进 examples/experimental/eval/nemo_skills/ 后多了一层,必须改成 parents[4],
# 否则 sys.path 会注入到 examples/ 而不是仓库根。
REPO_ROOT = Path(__file__).resolve().parents[4]
if str(REPO_ROOT) not in sys.path:
    sys.path.insert(0, str(REPO_ROOT))# 2) 同包 import 一律改为 examples.experimental 前缀,
# 保持 dotted module path 与磁盘布局一致。
from examples.experimental.eval.nemo_skills.skills_config import SkillsEvalEnvDatasetConfig
examples/geo3k_vlm/multi_turn/rollout.py rename-or-move

目录合并的代表文件,且顺带修复了 DEFAULT_ENV_MODULE 这个运行时默认值——旧值指向从未存在的模块,属于 PR 提到的“本已损坏、顺带修正”的关键例子。

# examples/geo3k_vlm/multi_turn/rollout.py
# 该文件由 examples/geo3k_vlm_multi_turn/rollout.py 合并而来,
# 搬迁后模块路径和运行时默认值需要同步修正,否则按默认参数启动会直接 import 失败。# 1) 模块内跨文件 import 跟随新目录
from examples.geo3k_vlm.multi_turn.base_env import BaseInteractionEnv# 2) DEFAULT_ENV_MODULE 是训练启动时的运行时默认值。
# 旧值 examples.vlm_multi_turn.env_geo3k 是一个从未存在过的模块路径,
# 这次重组把它纠正为合并后的真实模块,避免 --custom-env-module 未指定时崩溃。
DEFAULT_ENV_MODULE = "examples.geo3k_vlm.multi_turn.env_geo3k"

评论区精华

fully_async 是否纳入本次重组 设计

PR body 说明:一个进行中的独立 PR 将迁移 examples/fully_async/,因此本 PR 刻意不触碰它,并保证 examples/fully_async/ 与两个 fully-async 文档页相对 main 逐字节一致,swe-agent 异步启动器保留原 PYTHONPATH 入口,避免冲突。

结论:fully_async 保留在顶层,待并发 PR 再迁移;同时提醒后续迁移需同步更新 swe-agent 脚本与 docs/user-guide/fully-async.md。 · 已解决

parents 路径深度修正 正确性

Zhichenzzz 在批准时指出:LGTM, and small nits according to the parents path fixed。最终提交 4870aa3 将 12 处从 __file__ 或 $SCRIPT_DIR 向上找仓库根的 parents 深度 +1,例如 skills_server.py 从 parents[3] 改为 parents[4]、p2p_weight_transfer/run.py 从 parents[2] 改为 parents[3]。

结论:已修复并合入,无遗留问题。 · 已解决

DEFAULT_ENV_MODULE 运行时默认路径修复 正确性

PR body 指出 examples.vlm_multi_turn.env_geo3k 是运行时默认值,原先就指向不存在的模块;在合并 geo3k_vlm 目录时顺带修正。

结论:改为 examples.geo3k_vlm.multi_turn.env_geo3k 并合入,避免默认参数启动时的 import 崩溃。 · 已解决

静态审计代替 CI 验证 测试

examples/ 位于 pytest 的 norecursedirs,CI 不会 import 示例代码;PR 采用静态审计:所有 examples/... 路径 token、dotted 引用、docs.json 中 76 条路由、9 条 from examples.... import 语句均需可解析。

结论:静态审计通过;但示例级 import 错误仍无自动化防护,风险由人工审计兜底。 · 已解决

风险与影响

主要风险集中在路径引用与验证盲区:

  1. dotted module 路径回归:这类引用大量存在于 scripts/run_*.py 启动器而非示例目录内部,静态审计已覆盖仓库内所有 token,但审计是一次性动作,后续新增引用仍可能踩中旧路径。
  2. 向上路径深度依赖REPO_ROOTparents[n] 计算对目录深度敏感,本次靠提交 4870aa3 修复 12 处,但未来继续向 examples/experimental/ 下层嵌套时仍容易重犯,缺少运行时校验。
  3. CI 覆盖缺失examples/ 在 pytest 的 norecursedirs 中,示例代码的 import 错误不会被 CI 捕获;本次依赖静态审计,后续示例级改动若无对应测试,同样存在回归风险。
  4. retool 删除影响:删除 examples/retool/ 后,任何未纳入审计的外部脚本或文档若仍引用该目录将直接中断;PR 声称仓库内已无残留引用,但对外部使用者有破坏性。
  5. fully_async 并发依赖fully_async_rollout.generate_rollout_fully_asyncexamples/swe-agent/run-glm47-flash-agentic-async.pydocs/user-guide/fully-async.md 依赖,并发 PR 落地时需要同步更新,否则会出现文档与代码脱节。

对用户:所有依赖旧示例路径的 shell 脚本、启动命令和文档链接都需要更新,examples/retoolexamples/true_on_policy_vlm 被直接删除,属于破坏性变更;对系统:核心训练/推理代码无功能改动,但 miles/utils/arguments.py 的 help text 和 examples/geo3k_vlm/multi_turn/rollout.pyDEFAULT_ENV_MODULE 属运行时可见修正;对团队:examples 目录从此有了「顶层为可运行配方、infra_features 为管道、experimental 为未验证研究」的清晰分层,降低导航与甄别成本,也减少了未来新示例乱放的可能。

大型目录重组 引用路径易回归 无自动化测试覆盖 并发 PR 依赖 CI 不校验 examples/import

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论