Prhub

#43064 [CI] De-flake renderers/test_hf.py::test_resolve_content_format_fallbacks[Qwen/Qwen-VL-string]

原始 PR 作者 haosdent 合并时间 2026-05-22 12:15 文件变更 5 提交数 1 评论 9 代码增减 +62 / -5

执行摘要

预填充 HF 缓存修复 Qwen-VL 测试不稳

Qwen-VL 模型使用的 tokenizer 通过 trust_remote_code 加载时,会执行 tokenization_qwen.py 并从 qianwen-res.oss-cn-beijing.aliyuncs.com 下载 SimSun.ttf 字体。该 CDN 在 AWS us-west-2 CI 中频繁不可达,导致 test_resolve_content_format_fallbacks 测试失败(见 Buildkite #66759)。

该 PR 值得读,因为它展示了一种处理测试中外部依赖的通用模式:通过预填充 local cache 并结合 pytest fixture,以最小侵入性解决 flaky 问题。设计决策(使用 session-scoped fixture、内部 conftest)有参考价值。

讨论亮点

Review 中两个主要讨论点:

  • 使用 session-scoped fixture:DarkLight1337 建议将原始的 pytest_sessionstart hook 改为 session-scoped fixture,作者同意并修改。
  • 移到内部 conftest:DarkLight1337 指出放在顶层 conftest 会影响所有测试,建议移到内部 conftest,作者采纳,并指出将来新增测试需手动添加类似 fixture。

实现拆解

  1. 新增预填充工具函数:在 tests/utils.py 中定义 prewarm_hf_cache(assets: list[tuple[str, str]]) -> None,内部使用 huggingface_hub.hf_hub_download 下载指定文件到本地 HF 缓存。函数支持 HF_HUB_OFFLINE 环境变量,在离线模式跳过下载,失败时记录警告。
  2. 添加 session-scoped autouse fixture:在 tests/renderers/conftest.py、tests/tokenizers_/conftest.py 和 tests/models/multimodal/conftest.py 中分别定义 _prewarm_hf_cache fixture,调用 prewarm_hf_cache 预下载 Qwen/VL-Chat 的 SimSun.ttf。这些 fixture 在所有相关测试执行前自动生效。
  3. 移除旧的跳过逻辑:在 tests/models/multimodal/processing/test_common.py 中删除针对 Qwen/VL 和 Qwen/VL-Chat 的 pytest.skip 条件,因为现在测试已能正常执行。
  4. 配套导入与日志:在 tests/utils.py 中添加 huggingface_hub 导入和 vllm.logger 初始化。
文件 模块 状态 重要度
tests/utils.py 测试工具 modified 5.75
tests/renderers/conftest.py 测试夹具 added 5.41
tests/tokenizers_/conftest.py 测试夹具 added 5.41
tests/models/multimodal/conftest.py 测试夹具 modified 5.28
tests/models/multimodal/processing/test_common.py 处理测试 modified 4.27

关键符号

prewarm_hf_cache _prewarm_hf_cache

关键源码片段

tests/renderers/conftest.py test-coverage

新增 session-scoped fixture 调用 prewarm_hf_cache,消除该目录下测试的 flaky。

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
​
import pytest
​
from tests.utils import prewarm_hf_cache
​
​
@pytest.fixture(scope="session", autouse=True)
def _prewarm_hf_cache():
    # tokenization_qwen.py downloads SimSun.ttf from
    # qianwen-res.oss-cn-beijing.aliyuncs.com ; both Qwen/Qwen-VL and
    # Qwen/Qwen-VL-Chat look it up from the Chat repo.
    prewarm_hf_cache([("Qwen/Qwen-VL-Chat", "SimSun.ttf")])

评论区精华

使用 session-scoped fixture 替代 pytest_sessionstart hook 设计

DarkLight1337 提出初始的 pytest_sessionstart hook 可改为 session-scoped fixture,haosdent 同意并修改。

结论:采用 session-scoped autouse fixture,在 conftest 中实现预填充。 · 已解决

将 fixture 移动到内部 conftest 以减少全局影响 设计

DarkLight1337 指出放在顶层 conftest 会为所有测试命令触发 CDN 请求,建议移到内部 conftest。haosdent 采纳,但指出将来新增测试需手动添加类似 fixture。

结论:fixture 被分散到 tests/renderers/conftest.py, tests/tokenizers_/conftest.py, tests/models/multimodal/conftest.py。 · 已解决

风险与影响

  1. 外部 CDN 依赖仍然存在:预填充仅在缓存失效时下载,若 CDN 持续不可达且 HF 缓存为空,下载尝试将失败,但测试会继续(warning 而非失败)。HF_HUB_OFFLINE 环境变量可完全禁用。
  2. 测试隔离性风险较低:fixture 是 session-scoped 且 autouse,但只预填充字体文件,对非 Qwen 测试无影响。
  3. 维护负担:若有新的测试需类似预填充,开发者需手动添加 conftest 和调用,可能被遗忘。

直接修复 renderers/test_hf.py 中 test_resolve_content_format_fallbacks 测试的不稳定性,使其在 CI 中可靠通过。间接影响同样使用了 Qwen-VL tokenizer 的 tokenizers 测试和多模态处理测试。无用户可见的功能变化。

external_cdn_dependency test_fixture_spread

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论