Prhub

#52064 [CI] Mirror external test assets in vLLM S3

原始 PR 作者 khluu 合并时间 2026-08-13 10:08 文件变更 5 提交数 1 评论 5 代码增减 +30 / -41

执行摘要

将外部测试资源镜像到 vLLM S3,消除 CI 对第三方主机依赖

PR body 明确指出:"Buildkite build 83608 had multiple test failures caused by direct dependencies on third-party hosts, including RemoteDisconnected while fetching OpenCV and Bogotobogo video fixtures"。测试直接依赖第三方站点导致 CI 不稳定,因此将资源镜像到 vLLM 自有 S3 桶,并验证镜像对象与源文件逐字节一致。

值得快速浏览:本 PR 展示了如何系统性消除 CI 对第三方主机的依赖,其中"统一 VLLM_S3_BUCKET_URL 常量 + 动态推导 SSRF 白名单"的做法值得借鉴。若后续出现新的外部资源依赖,可按同样模式迁移。

讨论亮点

该 PR 来自 fork,claude[bot] 提示自动 review 被禁用;维护者 AndreasKaratzas 与 njhill 均直接 approve("LGTM"、"Thanks @khluu !")。PR body 中作者主动说明已检索过相关 PR,确认无重复工作,且 #52043 属于独立的混合依赖构建问题,刻意排除在本 PR 之外。全程无实质技术争议。

实现拆解

  1. 统一资源前缀:在 5 个测试文件中引入 from vllm.assets.base import VLLM_S3_BUCKET_URL,将原本硬编码的第三方 URL / S3 URL 统一改为由该常量拼接,便于后续统一迁移。
  2. 替换 JinaVL 重排序图片(tests/models/multimodal/pooling/test_jinavl_reranker.py):新增 HANDELSBLATT_IMAGE_URLPAPER_IMAGE_URL 常量,替换 TEXT_IMAGE_TEST_DATAIMAGE_TEXT_TEST_DATAIMAGE_IMAGE_TEST_DATATEXT_MIXED_DOCS_TEST_DATA 中 4 处指向 jina-ai GitHub raw 的图片地址,改动量最大(+14/-28)。
  3. 替换视频资源(tests/multimodal/media/test_connector.py、tests/entrypoints/multimodal/openai/chat_completion/test_video.py、tests/entrypoints/pooling/classify/test_online_vision.py):将 Bogotobogo 与 OpenCV GitHub 的视频 URL 改为 {VLLM_S3_BUCKET_URL}/multimodal_asset/ 下的 slow_traffic_small.mp4、vtest.avi、Megamind.avi;同时 test_online_vision.py 中原本硬编码的 S3 图片地址也改为常量拼接。
  4. 调整 SSRF 域白名单(tests/multimodal/media/test_connector.py):由于资源域从 bogotobogo.com / github.com 变为 vllm-public-assets,allowed_media_domains 改为 VLLM_S3_BUCKET_URL.removeprefix("https://") 动态推导,避免白名单与资源地址脱节。
  5. 替换 GSM8K 数据集(tests/evals/gsm8k/gsm8k_eval.py):load_gsm8k_data 中 train/test 的 GitHub raw URL 改为 {VLLM_S3_BUCKET_URL}/ci-datasets/gsm8k/,所有基于该脚本的 eval CI 都会受益。
  6. 验证配套:PR body 说明 7 个镜像资源均从公共 S3 获取并与源 SHA256 校验一致,OpenCV 成功解码全部视频(Megamind.avi 270 帧、slow_traffic_small.mp4 914 帧、vtest.avi 795 帧),GSM8K 数据逐行 JSON 解析通过。
文件 模块 状态 重要度
tests/models/multimodal/pooling/test_jinavl_reranker.py 重排序 modified 5.52
tests/multimodal/media/test_connector.py 媒体连接 modified 4.47
tests/evals/gsm8k/gsm8k_eval.py 评测脚本 modified 3.88
tests/entrypoints/multimodal/openai/chat_completion/test_video.py 视频测试 modified 3.93
tests/entrypoints/pooling/classify/test_online_vision.py 在线视觉 modified 3.63

关键符号

load_gsm8k_data test_allowed_media_domains test_fetch_image_base64

关键源码片段

tests/models/multimodal/pooling/test_jinavl_reranker.py test-coverage

改动量最大的文件,将 jina-ai GitHub raw 的 4 处图片 URL 替换为 S3 镜像并抽取为常量,是本次镜像工作的代表。

from vllm.assets.base import VLLM_S3_BUCKET_URL# 原来直接引用 jina-ai 的 GitHub raw 图片,受第三方主机稳定性影响;
# 镜像后统一走 S3,常量集中管理,测试数据里只引用常量。
HANDELSBLATT_IMAGE_URL = (
    f"{VLLM_S3_BUCKET_URL}/multimodal_asset/jinavl-handelsblatt-preview.png"
)
PAPER_IMAGE_URL = f"{VLLM_S3_BUCKET_URL}/multimodal_asset/jinavl-paper-11.png"IMAGE_IMAGE_TEST_DATA = {
    "query": [{"image": PAPER_IMAGE_URL}],
    "documents": [
        {"image": HANDELSBLATT_IMAGE_URL},
        {"image": PAPER_IMAGE_URL},
    ],
}
tests/multimodal/media/test_connector.py test-coverage

除视频 URL 镜像外,还将 allowed_media_domains 从硬编码外部域改为由 VLLM_S3_BUCKET_URL 动态推导,保证 SSRF 域白名单与资源地址一致。

from vllm.assets.base import VLLM_S3_BUCKET_URL# 视频资源从第三方站点迁移到 vLLM 公共 S3 桶,
# URL 前缀统一由常量推导,避免硬编码第三方域名再次失效。
TEST_VIDEO_URLS = [
    f"{VLLM_S3_BUCKET_URL}/multimodal_asset/slow_traffic_small.mp4",
    f"{VLLM_S3_BUCKET_URL}/multimodal_asset/vtest.avi",
]
​
​
@pytest.mark.asyncio
@pytest.mark.parametrize("video_url", TEST_VIDEO_URLS)
@pytest.mark.parametrize("num_frames", [-1, 32, 1800])
async def test_allowed_media_domains(video_url: str, num_frames: int):
    connector = MediaConnector(
        media_io_kwargs={"video": {"num_frames": num_frames}},
        # 资源迁移到 S3 后,白名单也改为从常量动态推导,
        # 避免域名变更时域白名单与资源地址脱节。
        allowed_media_domains=[VLLM_S3_BUCKET_URL.removeprefix("https://")],
    )
    # 同步与异步取流结果必须一致
    video_sync, metadata_sync = connector.fetch_video(video_url)
    video_async, metadata_async = await connector.fetch_video_async(video_url)
    assert np.array_equal(video_sync, video_async)
    assert metadata_sync == metadata_async
tests/evals/gsm8k/gsm8k_eval.py test-coverage

GSM8K train/test 数据源从 GitHub raw 切到 S3 ci-datasets 目录,影响所有基于该脚本的 eval CI。

def load_gsm8k_data() -> tuple[list[dict], list[dict]]:
    """Load GSM8K train and test data"""
    # GSM8K 数据镜像到公共 S3,避免直接依赖 GitHub raw 的可用性;
    # 前缀从 VLLM_S3_BUCKET_URL 常量推导,便于统一更换存储位置。
    train_url = f"{VLLM_S3_BUCKET_URL}/ci-datasets/gsm8k/train.jsonl"
    test_url = f"{VLLM_S3_BUCKET_URL}/ci-datasets/gsm8k/test.jsonl"
​
    train_file = download_and_cache_file(train_url)
    test_file = download_and_cache_file(test_url)
​
    train_data = list(read_jsonl(train_file))
    test_data = list(read_jsonl(test_file))
​
    return train_data, test_data

评论区精华

Fork 提交的自动 review 限制 other

claude[bot] 提示该 PR 来自 fork,自动 review 被禁用,需要维护者手动触发;随后 AndreasKaratzas 与 njhill 直接 approve。

结论:无技术争议,维护者均认可变更。 · 已解决

风险与影响

  1. 公共 S3 桶可用性依赖:镜像资源位于 vllm-public-assets(us-west-2),若该桶配置、权限或对象内容出现问题,相关测试会失败;缺少对 S3 资源存在性的 CI 预检。
  2. SSRF 域白名单收窄:test_connector.py 的 allowed_media_domains 从两个外部域改为仅允许 S3 域,若未来测试需要引用其他域,需要重新扩展白名单逻辑。
  3. 区域网络延迟:us-west-2 之外运行的 CI 拉取视频可能比原先的 CDN 慢,但通常比第三方主机更稳定;ROCm 测试已保留超时放大设置。
  4. 无生产代码变更:所有改动限于 tests/ 目录,不会引入运行时回归风险。

对用户无影响(纯测试基础设施变更);对 CI 稳定性有明显改善,消除了视频、图片、GSM8K 数据集对第三方主机的网络依赖;对团队而言,后续新增测试资源需要遵循"镜像到 S3 + 使用 VLLM_S3_BUCKET_URL 常量"的约定,并维护镜像与源文件的校验机制。

依赖公共 S3 桶可用性 域白名单收窄 测试基础设施变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论