Prhub

#48072 [CI][CPU] Add Qwen2-VL multimodal tests for CPU backend and fix incompatibilities

原始 PR 作者 zhejiangxiaomai 合并时间 2026-07-12 12:30 文件变更 2 提交数 1 评论 21 代码增减 +33 / -7

执行摘要

CPU 后端 Qwen2.5-VL 多模态测试覆盖与 CI 整合

PR body 明确指出需要支持 CPU 后端的多模态嵌入减少。修复两个关键问题:

1) pin_memory 在 CPU 设备上的不兼容;
2) 跨进程 RPC 中本地函数序列化失败。最终目标是使 Qwen2-VL / Qwen2.5-VL 能够在纯 CPU 部署下运行多模态推理。

值得快速阅读,学习如何在多平台项目中利用 current_platform 条件化测试参数,以及如何设计 CI job 隔离以减少测试时间。核心逻辑变更不大,技术决策清晰。

讨论亮点

Review 讨论主要集中在以下方面:

  • 测试参数动态化:reviewer bigPYJ1151 建议使用 current_platform.is_cpu() 来分配不同参数,作者据此修改。
  • CI 分离:reviewer 建议将新启用测试排除在通用 job 之外并独立运行,避免 CI 时间过长;同时建议使用与通用 job 相同的依赖列表,作者均采纳。
  • pin_memory 修复:作者尝试增加 CPU 设备检测禁用 pin_memory,但 reviewer 指出可以更优雅地使用已有 device 变量,最终作者验证测试无需此修改,将其撤回。

实现拆解

实现步骤

  1. 测试文件动态参数化 (tests/models/multimodal/generation/test_qwen2_5_vl.py)
    - 引入 from vllm.platforms import current_platform,在 @pytest.mark.parametrize 装饰器中使用 current_platform.is_cpu() 条件表达式,使 CPU 后端只保留最核心的参数组合(例如 video_pruning_rate 仅保留 [0.0]use_bytecode_hook 仅保留 [True]),避免运行不支持的配置并缩短测试时间。

  2. CI 配置调整 (.buildkite/hardware_tests/cpu.yaml)
    - 在已有的 CPU-Multi-Modal Model Tests job 中,通过 --ignore=tests/models/multimodal/generation/test_qwen2_5_vl.py 将 Qwen2.5-VL 测试排除,避免重复运行。
    - 新增独立的 CPU-Qwen2.5-VL Multimodal Tests job,使用与通用多模态相同的 source_file_dependencies(vllm/model_executor/layers/rotary_embeddingtests/models/multimodal/generation/),通过 VLLM_CI_ENV=0 环境变量并专门运行 test_qwen2_5_vl.py

  3. pin_memory 修复尝试(最终撤回)
    - 在 review 过程中,曾尝试在 vllm/multimodal/inputs.pyreduce_data 函数中增加 CPU 检测逻辑以禁用 pin_memory,但经 reviewer 确认,测试在没有该修改的情况下也能通过,最终该修改被移除。

文件 模块 状态 重要度
tests/models/multimodal/generation/test_qwen2_5_vl.py Qwen2.5-VL modified 5.35
.buildkite/hardware_tests/cpu.yaml CPU CI modified 4.4

关键源码片段

tests/models/multimodal/generation/test_qwen2_5_vl.py test-coverage

测试核心文件,通过条件参数化适配 CPU 后端,避免运行不支持的参数组合。

# SPDX-License-Identifier: Apache-2.0
import pytest
from vllm.platforms import current_platform# 根据当前平台动态裁剪参数组合:
# CPU 后端只运行最核心的配置,跳过 video_pruning_rate=0.75 和 use_bytecode_hook=False 组合,
# 以加速 CI 同时避免潜在的不兼容性。
@pytest.mark.core_model
@pytest.mark.parametrize("model", ["Qwen/Qwen2.5-VL-3B-Instruct"])
@pytest.mark.parametrize(
    "video_pruning_rate",
    [0.0] if current_platform.is_cpu() else [0.0, 0.75]
)
@pytest.mark.parametrize("num_frames", [16])
@pytest.mark.parametrize("dtype", ["bfloat16"])
@pytest.mark.parametrize("max_tokens", [128])
@pytest.mark.parametrize(
    "use_bytecode_hook",
    [True] if current_platform.is_cpu() else [True, False]
)
def test_qwen2_5_vl_evs_functionality(
    vllm_runner, video_assets, model,
    video_pruning_rate: float, num_frames: int,
    dtype: str, max_tokens: int, use_bytecode_hook: bool, monkeypatch
) -> None:
    """Test EVS functionality."""
    monkeypatch.setenv("VLLM_USE_BYTECODE_HOOK",
                       "1" if use_bytecode_hook else "0")
    # 其余主体逻辑保持不变,以聚焦参数化变更

评论区精华

测试参数动态化条件化 测试

Reviewer bigPYJ1151 建议使用 `current_platform.is_cpu()` 来分配不同参数,而不是硬编码缩减参数列表。作者采纳并修改。

结论:采用条件参数化,CPU 上只保留 video_pruning_rate=0.0 和 use_bytecode_hook=True,其他平台保持全组合。 · 已解决

CI job 拆分与依赖配置 infra

Reviewer 指出需要将新启用的测试从通用 job 中排除,并且建议使用相同的依赖列表而非扩大依赖范围。作者按建议修改。

结论:在通用 job 中添加 `--ignore` 排除 Qwen2.5-VL 测试,新增独立 job 并复用相同的 source_file_dependencies。 · 已解决

pin_memory 修复必要性确认 正确性

作者在 vllm/multimodal/inputs.py 中增加了 CPU 检测禁用 pin_memory 的逻辑。Reviewer 提出可以用已有 device 变量更优雅地实现,并最终质疑其必要性。作者验证测试无修复也能通过,决定撤回。

结论:移除 inputs.py 中的 pin_memory 修改,确认 CPU 环境下无需额外修复。 · 已解决

风险与影响

本 PR 仅涉及测试与 CI 配置变更,未改动任何核心运行时逻辑,引入回归风险极低。主要风险包括:

  • 新添加的 CI job 可能因环境(如缺少 CPU 硬件标签或依赖配置错误)而失败,但已使用与现有 job 相同的依赖模式。
  • 测试参数缩减可能导致某些隐藏的 CPU 兼容性问题未被检出;不过保留的组合验证了最核心功能。
  • 用户影响:无直接影响,纯内部 CI 改进。
  • 系统影响:降低 CPU CI 整体耗时(将 Qwen2.5-VL 测试分离后可并行执行)。
  • 团队影响:为 CPU 多模态提供了自动化回归检测,有助于后续 CPU 版本演进。
CI 配置变更 测试覆盖缩减风险

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论