执行摘要
- 一句话:Daytona 配方改用 --fully-async 以启用参数互斥校验
- 推荐动作:值得快速浏览,特别是对全异步 rollout 参数互斥设计感兴趣的读者,可对照 miles/utils/arguments.py 中 _resolve_rollout_functions 理解校验意图。长期建议为该配方补充一条启动脚本快照测试或文档说明,避免再次出现绕过校验的写法。
功能与动机
PR body 指出:run_glm5_2_744b_a40b_daytona.py 原本通过 --rollout-function-path 指向 FullyAsyncRolloutFn 来选中全异步 rollout,而该参数与 --fully-async 互斥(_resolve_rollout_functions 断言 rollout_function_path is None),导致配方走在跳过校验的路径上。换用 --fully-async 后,colocate、partial-rollout、pause-generation-mode abort、recompute-logprobs-via-prefill、rollout-all-samples-process-path 及 multi-LoRA 等不兼容检查开始对配方生效,配方当前配置均能通过这些检查。
实现拆解
- 变更入口:examples/experimental/openenv/glm52_tbench2/run_glm5_2_744b_a40b_daytona.py 的 _execute_train 函数。
- 具体改动:在 rollout_args 字符串拼接中,将 --rollout-function-path miles.rollout.fully_async_rollout.FullyAsyncRolloutFn 替换为 --fully-async,其余参数(如 --pause-generation-mode in_place、--rollout-submission-granularity sample)保持不变。
- 行为等价性论证:resolve_rollout_function_paths 在两种情况下都解析到 FullyAsyncRolloutFn;--fully-async 只被 _resolve_rollout_functions 和 train.py 驱动守卫两处读取,因此运行时无其他变化。配方已显式设置 --rollout-submission-granularity sample,不依赖 fully-async 默认值。
- 配套改动:无。PR 明确说明没有快照测试覆盖该配方(tests/snapshots/launch_scripts/ 中没有对应 fixture),pre-commit run --all-files 通过,未在硬件上执行验证。
关键文件:
examples/experimental/openenv/glm52_tbench2/run_glm5_2_744b_a40b_daytona.py(模块 示例脚本;类别 source;类型 core-logic;符号 _execute_train): 唯一变更文件,也是本 PR 的核心:rollout_args 的选择方式从 --rollout-function-path 切换为 --fully-async,使配方重新接入参数互斥校验,是整个变更的入口和全部内容。
关键符号:_execute_train
关键源码片段
examples/experimental/openenv/glm52_tbench2/run_glm5_2_744b_a40b_daytona.py
唯一变更文件,也是本 PR 的核心:rollout_args 的选择方式从 --rollout-function-path 切换为 --fully-async,使配方重新接入参数互斥校验,是整个变更的入口和全部内容。
def _execute_train(args: ScriptArgs):
_assert_openenv_deps()
load_save_path = f"{args.output_dir}/{args.run_id}/checkpoints"
hf_name = f"{args.model_name}_fp8" if args.fp8_rollout else args.model_name
ckpt_args = (
f"--hf-checkpoint {args.model_local_dir}/{hf_name} "
f"--ref-load {args.model_local_dir}/{args.model_name}_torch_dist "
f"--load {args.load_from or load_save_path} "
f"--save {load_save_path} "
f"--save-interval {args.save_interval} "
)
rollout_args = (
# 用 --fully-async 代替 --rollout-function-path 选中全异步 rollout:
# 前者会触发 _resolve_rollout_functions 中的互斥校验(覆盖 colocate /
# partial-rollout / pause-generation-mode abort / multi-LoRA 等不兼容项),
# 而直接传函数类路径会绕过这些检查。
"--fully-async "
"--pause-generation-mode in_place "
f"--async-max-concurrent-samples {args.async_max_concurrent_samples} "
# 每个完成的样本释放一个提交槽,而不是等整组完成:
# 长时程 agentic 任务里,等组内最慢的兄弟样本是 rollout 吞吐的主要瓶颈。
"--rollout-submission-granularity sample "
f"--prompt-data {args.prompt_data} "
"--input-key prompt "
"--apply-chat-template "
"--rollout-shuffle "
f"--num-rollout {args.num_rollout} "
f"--rollout-batch-size {args.rollout_batch_size} "
f"--n-samples-per-prompt {args.n_samples_per_prompt} "
f"--rollout-max-response-len {args.rollout_max_response_len} "
"--max-seq-len 131072 "
"--rollout-temperature 0.8 "
f"--global-batch-size {args.global_batch_size} "
"--balance-data "
)
评论区精华
本 PR 没有任何 review 评论,评审人 Zhichenzzz 直接给予 APPROVED。唯一的技术论证来自 PR body:作者逐条说明 resolve_rollout_function_paths 在切换前后解析到同一对 rollout/eval 函数,args.fully_async 只被 _resolve_rollout_functions 和 train.py 驱动守卫两处读取,因此行为等价,且新写法能补上互斥校验。
风险与影响
- 风险:
- 静态验证未覆盖运行时行为:作者声明未在硬件上执行验证;train_async.py 对 --fully-async 的守卫分支与显式 rollout_function_path 路径若有隐藏差异,可能改变运行行为(可能性较低,因为解析逻辑已确认等价)。
- 无测试快照:tests/snapshots/launch_scripts/ 无此 recipe 的 fixture,后续若修改 _resolve_rollout_functions 或 fully-async 语义,该配方的回归不易被 CI 捕获。
- 对未来校验的依赖:现在配方依赖 _resolve_rollout_functions 的互斥断言;若未来 fully-async 分支改变默认行为(如默认提交粒度),该配方可能受影响,但当前已显式设置 --rollout-submission-granularity sample,风险低。
- 影响:影响面极窄:仅修改 1 个示例脚本,库代码零改动。对运行 GLM-5.2 × TB2 Daytona 配方的用户,运行行为不变,但启动时会更早暴露参数不兼容错误,而非静默绕过校验。对团队和系统无迁移成本。总体影响程度低。
- 风险标记:缺少测试覆盖, 未在硬件验证, 参数语义耦合
关联脉络
- PR #2220 Add the GLM-5.2 744B x terminal-bench-2 Daytona example: 本 PR 正是对该新增配方脚本的修正,2220 是 run_glm5_2_744b_a40b_daytona.py 的原始来源。
- PR #2366 docs: rewrite the fully async page around schedule, data path, eval, and metrics: 同属 fully-async 功能线,2366 系统梳理了全异步模式的 schedule、数据路径等语义,可与本 PR 对照理解 --fully-async 的完整参数行为。
参与讨论