Prhub

#29545 [diffusion] CI: make consistency GT probe robust to transient CDN failures

原始 PR 作者 mickqian 合并时间 2026-06-28 17:13 文件变更 1 提交数 3 评论 2 代码增减 +35 / -7

执行摘要

增强远程 GT 文件探测的鲁棒性

PR body 指出 diffusion 一致性检查的 _remote_file_exists 会因 raw.githubusercontent.com 短暂故障而将实际存在的 GT 文件报告为缺失,导致 CI 错误失败且不可重试,需要人工重新运行工作流。具体案例包括 mova_360p_ring1_uly2cosmos3_nano_t2iwan2_2_t2v_a14b_lora_2gpu,其中 wan2_2_t2v_a14b_lora_2gpu 在同一 job 中先通过后失败,证明是探测逻辑的问题而非文件缺失。

该 PR 值得精读,尤其是 _remote_file_exists 的重试逻辑和缓存设计。它展示了一个典型的“探测函数对瞬态故障不鲁棒”问题的处理模式,包括有限重试、指数退避、状态跟踪和正向缓存。代码改动量小但设计周到,适合作为测试工具健壮性改进的参考。

讨论亮点

PR 无 review 评论,讨论仅限于作者在 PR body 中的问题描述、根因分析和修复方案。CI 的 extra test 失败但未关联具体讨论。

实现拆解

  1. 增强 _remote_file_exists 重试策略(multimodal_gen/test/test_utils.py
    - 将重试次数从 3 次增加到 5 次。
    - 引入指数退避机制,初始 1s,每次翻倍,最大 16s,以缓解 429 限流和 CDN 预热窗口。
    - 引入 saw_absent 标记:仅当所有重试均未返回 200/206 且至少观察到一次干净的 4xx(非 403/405/429)时,才返回 False;若仅遇到瞬态错误(429/5xx/网络异常),则返回 None(调用方会假定文件存在)。

  2. 添加正向缓存(_gt_exists_remote_cache
    - 在模块级新增 _gt_exists_remote_cache: set[str],缓存已确认存在的 GT 文件 key。
    - 在 gt_exists 函数中,通过新增的 _get_consistency_gt_cache_key 生成缓存 key,若命中缓存直接返回 True,避免重复探测。
    - 仅缓存确认存在的结果,不缓存缺失结果,确保真正缺失的文件仍能被报告。

  3. 补充单元测试覆盖
    - 在 PR body 中列出了测试计划,覆盖各种输入场景:200、HEAD 405+GET 206、持续 404、伪 404 后 200、持续 429、429 突刺后 200、持续超时、持续 503 等,确保新逻辑正确。

文件 模块 状态 重要度
python/sglang/multimodal_gen/test/test_utils.py 测试工具 modified 5.31

关键符号

_remote_file_exists gt_exists

关键源码片段

python/sglang/multimodal_gen/test/test_utils.py test-coverage

所有变更均集中在此文件,包括增强 `_remote_file_exists` 的重试逻辑、添加正向缓存、以及调整 `gt_exists` 函数。此文件是 CI 一致性检查的核心工具。

# python/sglang/multimodal_gen/test/test_utils.pyimport time# 缓存已确认存在的 GT 文件 key(仅正向结果,不缓存缺失)
_gt_exists_remote_cache: set[str] = set()def _remote_file_exists(url: str) -> bool | None:
    """Probe whether a remote GT file exists, robust to transient failures."""
    attempts = 5
    backoff = 1.0
    saw_absent = False # 记录是否观察到干净的非限流 4xx 状态码
    for attempt in range(attempts):
        for method in ("head", "get"):
            try:
                if method == "head":
                    resp = requests.head(url, timeout=30, allow_redirects=True)
                else:
                    resp = requests.get(
                        url,
                        timeout=30,
                        allow_redirects=True,
                        headers={"Range": "bytes=0-0"},
                        stream=True,
                    )
                try:
                    if resp.status_code in (200, 206):
                        return True
                    if resp.status_code == 404 or (
                        resp.status_code not in (403, 405, 429)
                        and resp.status_code < 500
                    ):
                        # 干净 4xx -> 表面缺失,但不要立即信任:
                        # 刚提交的 commit 可能在 CDN 上短暂 404
                        saw_absent = True
                finally:
                    resp.close()
            except requests.RequestException:
                pass
        if attempt < attempts - 1:
            time.sleep(backoff)
            backoff = min(backoff * 2, 16.0)
​
    # 所有重试均未看到 200/206
    if saw_absent:
        return False # 持续缺失 -> 真正缺失
    return None # 仅有瞬态故障 -> 调用方假定存在

评论区精华

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

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

风险与影响

  1. 回归风险:重试次数从 3 增至 5,退避最长 16s,可能轻微增加单次 GT 探测的最长等待时间(理论最大约 31s)。由于 CI 任务整体超时较长,此影响可忽略。
  2. 逻辑正确性saw_absentsaw_absent 的组合逻辑:若所有重试都返回 429 或更高级错误,saw_absentFalse,最终返回 None,调用方假定存在。若文件确实缺失但 CDN 返回 503,则会被误判为“可能存在”,可能导致后续一致性检查因文件不存在而失败,但错误信息会更清晰。风险较低,因为 503 反映的是服务端问题而非文件缺失。
  3. 缓存一致性_gt_exists_remote_cache 仅缓存正向结果,且无过期机制。若 GT 文件在运行中途被删除(极不可能),缓存会导致误判。考虑到 CI 的原子性,此风险可接受。

影响范围:仅影响 diffusion 测试套件的一致性检查模块,不涉及核心推理逻辑。
影响程度:中等。修复了 CI 的假阳性失败,减少人工介入,提高 CI 稳定性。
用户感知:无,对最终用户无影响。
团队影响:减少 CI 维护负担。

测试工具变更 增加等待时间

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论