Prhub

#2041 Address engines by base URL when the router is dp-aware

原始 PR 作者 yueming-yuan 合并时间 2026-08-01 08:10 文件变更 5 提交数 1 评论 1 代码增减 +39 / -5

执行摘要

修复 dp-aware 路由下 abort 无法触达引擎

PR body 指出 stage-c-2-gpu-h200test_glm5_744b_a40b_4layer_r3.py 持续失败:引擎健康,但 abort() 无法触达,日志显示 All connection attempts failed 并耗尽 60 次重试。根因是 dp-aware 路由下 GET /workers 返回的 url 形如 http://worker1:8080@0,miles 直接拼接 f'{url}/abort_request' 后,httpx 将 host:port 解析为 userinfo、把 0 解析为主机名,所有连接必然失败。该问题由 #2012 开启 dp-aware 路由后暴露;作者明确表示 dp-aware 路由应该保留,需要更新的是消费方。

值得精读。PR 展示了一个典型的路由身份与可寻址地址混淆的排查过程:从失败日志反推 URL 解析行为,对照 router 内部 base_url() 语义,最后用一个小而精确的工具函数统一修复。关注 router_worker_base_urls 的「仅剥离数字后缀」设计与去重逻辑,可作为后续库内地址归一化基础设施的参考。

讨论亮点

审核人 guapisolo 直接批准(LGTM.),没有进一步讨论。唯一外部评论来自 gemini-code-assist[bot] 的停用提醒,无实质技术内容。本 PR 的技术讨论集中在 PR body 中对根因的详细推导:作者用失败日志、sglang-router 的 url()base_url() 语义对比,以及 httpx 对 http://host:port@rank 的解析行为,完整说明了「路由身份≠地址」这一核心矛盾,并据此决定在消费方统一做 base URL 归一化,而不是关闭 dp-aware 路由。

实现拆解

  1. 定位问题根源:dp-aware 路由下,/workers 返回的 url 字段是如 http://host:port@<rank> 的路由身份标识,并非可寻址的 HTTP base。miles 此前直接把它拼接到 /abort_request,导致 httpx 将 host:port 解析为 userinfo、<rank> 解析为 hostname,所有连接必然失败。
  2. 新增统一工具函数:在 miles/utils/http_utils.py 中新增 router_worker_base_urls(),使用 rpartition('@') 剥离数字后缀(仅当后缀为纯数字时),并按首次出现顺序去重,确保同一引擎的多个 rank 只保留一个 base URL。
  3. 接入三处消费点:miles/rollout/inference_rollout_train.py::get_worker_urlsmiles/rollout/sglang_rollout.py::abortmiles/ray/multi_lora/backend.py::worker_urls 在返回前统一经过 router_worker_base_urls() 处理。其中 get_worker_urls 同时服务 abort()dumper_utils.configure_sglang,后者此前在 dp-attention 运行中会同样失败。
  4. 补充测试:在 tests/fast/backends/sglang_utils/test_router_dp_aware.py 中新增 4 个用例,覆盖 rank 后缀剥离与去重、普通 URL 透传、IPv6 地址、非数字后缀保留。pre-commit run --all-files 通过。
  5. 验证:真实回归依赖 stage-c-2-gpu-h200,该测试使用 --sglang-enable-dp-attention --sglang-dp-size 2,可端到端覆盖 dp-aware 路径。
文件 模块 状态 重要度
miles/utils/http_utils.py 网络工具 modified 6.65
tests/fast/backends/sglang_utils/test_router_dp_aware.py DP 路由 modified 6.17
miles/rollout/inference_rollout/inference_rollout_train.py 生成链路 modified 5.4
miles/rollout/sglang_rollout.py 生成链路 modified 4.76
miles/ray/multi_lora/backend.py 多 LoRA modified 4.59

关键符号

router_worker_base_urls get_worker_urls abort worker_urls abort_adapter_requests

关键源码片段

miles/utils/http_utils.py core-logic

新增核心工具函数 router_worker_base_urls(),剥离 dp-aware 路由附加的 @<rank> 后缀并去重,是本次修复的核心逻辑。

def router_worker_base_urls(urls: list[str]) -> list[str]:
    # 剥离 dp-aware 路由附加的 @<rank> 后缀;同一引擎的各 rank 收敛为同一地址
    bases = []
    for url in urls:
        base, sep, rank = url.rpartition('@')
        # 仅当后缀为纯数字时才认定为 DP rank;否则视为 userinfo,保留原样
        if sep and rank.isdigit():
            url = base
        # 按首次出现顺序去重,避免对同一引擎重复发 abort_all
        if url not in bases:
            bases.append(url)
    return bases
tests/fast/backends/sglang_utils/test_router_dp_aware.py test-coverage

为 router_worker_base_urls 补充 4 个单元测试,覆盖 rank 剥离与去重、普通 URL 透传、IPv6、非数字后缀保留,防止回归。

from miles.utils.http_utils import router_worker_base_urls
​
​
def test_dp_rank_suffix_stripped_and_engines_deduplicated():
    # dp-aware 路由为每个 DP rank 上报一条,但共享同一可寻址服务器
    assert router_worker_base_urls(['http://h:8080@0', 'http://h:8080@1']) == ['http://h:8080']
​
​
def test_plain_worker_urls_pass_through_in_order():
    # 普通 URL 不含 @rank 后缀,应原样透传且保持顺序
    assert router_worker_base_urls(['http://h:8080', 'http://h:8081']) == ['http://h:8080', 'http://h:8081']
​
​
def test_ipv6_dp_rank_suffix_stripped():
    # IPv6 地址带方括号,同样支持剥离 @rank 后缀
    assert router_worker_base_urls(['http://[::1]:8080@0']) == ['http://[::1]:8080']
​
​
def test_non_numeric_suffix_is_not_a_dp_rank():
    # 非数字后缀是 userinfo 而非 rank:剥离会改变实际寻址的主机
    assert router_worker_base_urls(['http://user:pass@h:8080']) == ['http://user:pass@h:8080']

评论区精华

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

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

风险与影响

行为变更影响所有经 router worker 条目发起的引擎级请求(abort_requestdumper/configure、adapter abort),都会去掉 @rank 后缀;若未来需要定向请求某个 DP rank,则需要新机制。剥离逻辑依赖数字后缀约定,若 sglang-router 改变格式(如 @rank-0),isdigit() 检查会使 URL 原样透传,可能再次导致连接失败但不会误伤 userinfo。仅覆盖已知三处消费点,其他将 worker['url'] 直接拼 URL 的代码可能遗漏(但 git log -S router_dp_aware 仅一个 commit,概率低)。单测覆盖工具函数,真实回归依赖 stage-c-2-gpu-h200,缺少独立端到端 CI 用例。

修复 dp-attention + dp-aware 路由下 rollout abort() 与 dumper 配置失败的严重问题,避免整轮训练崩溃。影响范围:使用 --sglang-enable-dp-attention 的推理/训练任务(如 GLM5 744B 等),以及 multi-LoRA 场景下的 adapter abort 路径。对非 dp-aware 路径无影响,普通 URL 原样透传。维护方面,库中新增一个可复用的地址归一化工具,后续同类集成应复用。

路由身份与地址混用 仅覆盖已知消费点 依赖 router 后缀格式

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论