Prhub

#2015 scripts, examples: stop forcing the deprecated Miles router in launchers

原始 PR 作者 Shi-Dong 合并时间 2026-08-04 03:57 文件变更 15 提交数 2 评论 1 代码增减 +3 / -15

执行摘要

移除 14 个启动器强制 --use-miles-router,默认走 sgl-router

PR body 明确指出:Miles router 已废弃、sgl-router 为默认,但 14 个 launcher 配方无条件传入 --use-miles-router;该标志声明为 action="store_true" 且没有否定形式,Python launcher 也没有暴露 ScriptArgs 字段,因此调用方除改写脚本外没有任何办法从外部关闭它,等于每次运行都被钉在废弃的文本路由路径上。本 PR 的目的就是摘除这个强制标志,让 router_manager 自然回退到 sgl-router 分支。

值得快速浏览:它是理解 miles 路由演进与“如何用一个最小 diff 改变默认行为”的干净样例。重点可看作者的范围决策——不顺手删参数、不顺手删测试,而是把“移除标志”与“退役参数”两项决策解耦,避免一个看似无害的清理 PR 吞掉大量旧路径覆盖。若想进一步行动,可后续跟进 arguments.py--use-miles-router 的正式退役,以及 3 个 e2e 测试对该标志的依赖清理。

讨论亮点

本 PR 没有实质性的 review 讨论。唯一的审核来自 yueming-yuan,状态为 APPROVED,评论主体为空。值得记录的决策都写在 PR body 里,作者主动划定了三类范围外事项:① 参数本身(arguments.py 与 router 管线)不在本次移除范围,退役标志是独立决策;② 测试刻意保留,以免删除对 Miles router 与 sgl-router 的等价性覆盖;③ 文档页与标志无关。作者还邀请 reviewer 决定是否把 3 个顺带传递该标志的 e2e 测试纳入清理,但最终未纳入。

实现拆解

实现按如下 4 步拆解:

  1. 修改 3 个 Python 启动器的参数拼接:在 scripts/run_glm5_1_744b_a40b_lora.pyscripts/run_glm5_2_744b_a40b_lora.py_train 函数中,从 misc_args 字符串里删除 --use-miles-router;在 examples/multi_lora/run_multi_lora.pytopology_args 中删除同一标志。这些字符串随后被拼进 train_args 并交给 U.execute_train,删除后 router_manager 在启动时不再进入 Miles router 分支,而走默认的 sgl-router 路径。

  2. 清理 12 个 shell 配方examples/lora/ 下的 dev.shrun-kimi-k25-megatron-lora.shrun-qwen2.5-0.5B-megatron-lora.shrun-qwen2.5-3B-megatron-lora-disaggregated.shrun-qwen2.5-3B-megatron-lora-disaggregated-multi-node.shrun-qwen3-4b-megatron-lora-result.shexamples/infra_features/low_precision/ 下的 run-kimi-k2-Thinking-int4.shrun-qwen3-235B-A22B-int4.shrun-qwen3-30b-a3b-fp8-two-nodes.shrun-qwen3-30B-A3B-int4.sh,以及 examples/experimental/reproducibility/run-qwen2.5-0.5B-gsm8k.sh 均删除参数数组或命令行中的 --use-miles-router 一行。examples/infra_features/p2p_weight_transfer/run-glm4.7-flash-2node-profile.sh 删除了一个已注释的死选项,避免该 flags 被误读为值得重新启用的选项。

  3. 明确范围外(不做的事)miles/utils/arguments.py 中的参数定义、router_manager.pysglang_engine.pydashboard/router/ 全部不动;文档页 /advanced/miles-router 也不动,因为其内容是关于 R3 路由回放而非本标志。测试刻意保留:tests/e2e/sglang/test_r3_router_equivalence.py 用于对比 Miles router 与 sgl-router,删除标志会直接删掉覆盖而非现代化覆盖,因此 3 个 e2e 测试(test_lora_qwen2.5_0.5B.pytest_quick_start_glm4_9B.pytest_glm5_2_744b_a40b_5layer_nvfp4.py)仍会顺带传递该标志,作者表示可后续单独清理。

  4. 验证配套:作者用 grep -rn -- "use-miles-router" scripts/ examples/ 确认无残留,bash -n 通过全部 12 个 shell 配方,并对 GLM-5.2 gsm8k 示例在 4x H200 上做了端到端前后对比:删标志后 Megatron 参数 dump 显示 use_miles_router ... Falserouter_manager 日志来自 sgl-router 分支的 Router launched at <host>:<port>,训练/rollout logprob 最大绝对差 2.2e-4(均值 -10.2),与改动前一致。其余 13 个配方是同样的一行删除,未逐一实跑。

文件 模块 状态 重要度
scripts/run_glm5_1_744b_a40b_lora.py 启动脚本 modified 4.89
scripts/run_glm5_2_744b_a40b_lora.py 启动脚本 modified 4.89
examples/multi_lora/run_multi_lora.py 多 LoRA modified 4.32
examples/lora/dev.sh LoRA 配方 modified 2.0
examples/lora/run-kimi-k25-megatron-lora.sh LoRA 配方 modified 2.0
examples/infra_features/low_precision/run-kimi-k2-Thinking-int4.sh 低精度配方 modified 2.0
examples/experimental/reproducibility/run-qwen2.5-0.5B-gsm8k.sh 复现配方 modified 2.0
examples/infra_features/p2p_weight_transfer/run-glm4.7-flash-2node-profile.sh p2p 配置 modified 1.6

关键符号

_train (scripts/run_glm5_1_744b_a40b_lora.py) _train (scripts/run_glm5_2_744b_a40b_lora.py) _train (examples/multi_lora/run_multi_lora.py)

关键源码片段

scripts/run_glm5_1_744b_a40b_lora.py core-logic

GLM-5.1 LoRA 启动器:此前在 misc_args 中写死 --use-miles-router,删除后该大规模 LoRA 训练默认走 sgl-router,是本 PR 两个核心启动器之一。

# GLM-5.1 LoRA 启动器的参数组装(变更后)。
# misc_args 是拼接进 train_args 的字符串段;此前这里写死了
# --use-miles-router,把每次运行都钉死在已弃用的文本路由路径上。
# 该标志为 store_true 且无反形式,启动器也没有暴露对应字段,
# 调用方无法从命令行关闭它,只能改脚本本身。
# 删除后 router_manager 会回退到默认的 sgl-router 分支。
misc_args = (
    f"--attention-dropout 0.0 --hidden-dropout 0.0 "
    "--accumulate-allreduce-grads-in-fp32 --attention-softmax-in-fp32 "
    "--attention-backend flash --calculate-per-token-loss "
    f"--actor-num-nodes 1 --actor-num-gpus-per-node {args.num_gpus_per_node} "
    f"--num-gpus-per-node {args.num_gpus_per_node} --colocate "
)
# 顺带保留:--calculate-per-token-loss 与 --colocate 仍由后续
# 逻辑消费,本次变更不触碰这些参数。
train_args = f"{ckpt_args} {lora_args} {rollout_args} {seq_args} {optimizer_args} {grpo_args} {r3_args} {wandb_args} {perf_args} {sglang_args} {save_args} {misc_args} {args.extra_args} "
scripts/run_glm5_2_744b_a40b_lora.py core-logic

GLM-5.2 LoRA 启动器,与 5.1 同为本次端到端验证对象(4x H200 gsm8k);删除后 Megatron 参数 dump 确认 use_miles_router=False。

# GLM-5.2 LoRA 启动器(变更后): fp8 rollout 场景需要额外写一个
# sglang 配置文件,让 update_weights 保持开启以同步每步 LoRA 权重。
if args.fp8_rollout:
    sglang_config_path = f"{load_save_path}/sglang_fp8_rollout.yaml"
    os.makedirs(load_save_path, exist_ok=True)
    with open(sglang_config_path, "w") as f:
        f.write(
            "sglang:\n"
            "  - name: default\n"
            f"    model_path: {args.fp8_rollout_checkpoint}\n"
            "    update_weights: true\n"
            "    server_groups:\n"
            "      - worker_type: regular\n"
            f"        num_gpus: {args.num_gpus_per_node}\n"
        )
    sglang_args += f"--sglang-config {sglang_config_path} "# 变更前 misc_args 里混入了 --use-miles-router,把每次运行钉死在
# 已弃用的文本路由路径上;删除后 router_manager 走 sgl-router 默认。
misc_args = (
    f"--attention-dropout 0.0 --hidden-dropout 0.0 "
    "--accumulate-allreduce-grads-in-fp32 --attention-softmax-in-fp32 "
    "--attention-backend flash --calculate-per-token-loss "
    f"--actor-num-nodes 1 --actor-num-gpus-per-node {args.num_gpus_per_node} "
    f"--num-gpus-per-node {args.num_gpus_per_node} --colocate "
)
examples/multi_lora/run_multi_lora.py core-logic

多 LoRA 训练的驱动启动器:topology_args 中原先强制 --use-miles-router,删除后多 LoRA rollout 统一走 sgl-router 默认路径,与 async 多 LoRA 训练配合。

# 多 LoRA 驱动 : topology_args 此前强制 --use-miles-router,
# 把整套 multi-lora 训练固定到已弃用的文本路由路径。
# 该标志为 store_true 且无 CLI 反形式,配方复制者无法覆盖。
topology_args = (
    f"--actor-num-nodes 1 --actor-num-gpus-per-node {args.actor_num_gpus} "
    f"--rollout-num-gpus {args.rollout_num_gpus} "
)
# 结果 : router_manager 回退到 sgl-router 默认分支,
# rollouts 通过 sgl-router 而非 Miles 文本路由下发。

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

主要风险是默认路由行为的事实切换:改动前所有配方固定走 Miles router(文本路由),改动后统一回退到 sgl-router,两者在 dp-aware 场景下的引擎寻址、错误处理、日志格式和并发语义存在差异。尤其需要关注 dp-attention 下 sgl-router 的 base URL 寻址(PR #2041 刚修复过 abort 无法触达引擎的问题),本次删除使这些配方实际进入该路径。其次,验证只覆盖了 GLM-5.2 gsm8k 一个配方,其余 13 个配方未单独运行,存在未暴露的兼容性回归可能;不过这些配方共用同一条 router_manager 回退逻辑,且均为单行删除,风险等级不高。测试侧并无变更,3 个 e2e 测试仍覆盖旧的 Miles router 路径,反而形成了新默认路径覆盖不足的偏差。

影响范围集中在启动层:使用 scripts/ 中 GLM-5.1/5.2 LoRA 启动器、examples/lora/examples/infra_features/low_precision/examples/multi_lora/ 与 reproducibility 配方的用户,将从已弃用的文本路由自动迁移到 sgl-router,行为上更接近仓库其他脚本的默认路径,也有利于后续统一维护。对核心库无影响,因为 flags 的实际消费逻辑(router_manager 的分支选择)未改动,只是不再有调用方强制走进旧分支。对团队而言,这是一次低成本的默认值对齐,降低了“按示例跑却走上废弃路径”的认知负担。

默认路由行为切换 剩余配方未逐一实测 测试仍覆盖旧路径

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论