# PR #29545 完整报告

- 仓库：`sgl-project/sglang`
- 标题：[diffusion] CI: make consistency GT probe robust to transient CDN failures
- 合并时间：2026-06-28 17:13
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/29545

---

# 执行摘要

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

# 功能与动机

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

# 实现拆解

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`（模块 测试工具；类别 test；类型 test-coverage；符号 _remote_file_exists, gt_exists, _gt_exists_remote_cache）: 所有变更均集中在此文件，包括增强 `_remote_file_exists` 的重试逻辑、添加正向缓存、以及调整 `gt_exists` 函数。此文件是 CI 一致性检查的核心工具。

关键符号：_remote_file_exists, gt_exists

## 关键源码片段

### `python/sglang/multimodal_gen/test/test_utils.py`

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

```python
# python/sglang/multimodal_gen/test/test_utils.py

import 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        # 仅有瞬态故障 -> 调用方假定存在

```

# 评论区精华

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

- 暂无高价值评论线程

# 风险与影响

- 风险：
 1. **回归风险**：重试次数从 3 增至 5，退避最长 16s，可能轻微增加单次 GT 探测的最长等待时间（理论最大约 31s）。由于 CI 任务整体超时较长，此影响可忽略。
 2. **逻辑正确性**：`saw_absent` 与 `saw_absent` 的组合逻辑：若所有重试都返回 429 或更高级错误，`saw_absent` 为 `False`，最终返回 `None`，调用方假定存在。若文件确实缺失但 CDN 返回 503，则会被误判为“可能存在”，可能导致后续一致性检查因文件不存在而失败，但错误信息会更清晰。风险较低，因为 503 反映的是服务端问题而非文件缺失。
 3. **缓存一致性**：`_gt_exists_remote_cache` 仅缓存正向结果，且无过期机制。若 GT 文件在运行中途被删除（极不可能），缓存会导致误判。考虑到 CI 的原子性，此风险可接受。
 - 影响：**影响范围**：仅影响 diffusion 测试套件的一致性检查模块，不涉及核心推理逻辑。
**影响程度**：中等。修复了 CI 的假阳性失败，减少人工介入，提高 CI 稳定性。
**用户感知**：无，对最终用户无影响。
**团队影响**：减少 CI 维护负担。

- 风险标记：测试工具变更 , 增加等待时间

# 关联脉络

- PR #28762 ...: PR body 提及 `_find_remote_consistency_gt_files` 的 `bool | None` 契约是 #28762 引入的，本 PR 保持了该契约。
- PR #29514 [diffusion] fix --warmup silently downgrading server-based warmup to request mode: 同一作者 mickqian 的 diffusion 相关修复，属于同一功能领域。
- PR #29434 [diffusion] nightly: track SGLang-Diffusion only: 同一作者 mickqian 的 diffusion CI 相关变更，涉及同一测试工具链。