Prhub

#54172 [Tests][XPU] Limit Qwen2-VL generation length to avoid flaky numerical divergence

原始 PR 作者 faaany 合并时间 2026-08-31 22:59 文件变更 1 提交数 2 评论 3 代码增减 +16 / -8

执行摘要

XPU 上 Qwen2-VL 测试限长 64,规避 BF16 数值发散 flaky

XPU 上运行 Qwen2-VL 多图测试时,HF 与 vLLM 会先在前缀保持一致,然后在自回归解码后期数值发散,导致 check_logprobs_close 失败。作者在 PR body 中明确论证取舍:该测试的目的是验证 vLLM 相对 Hugging Face 的整体正确性,而非 ViT FlashAttention 在超长自回归生成下的数值稳定性,因此沿用 CPU 上已有的处理方式(参照 pytorch/pytorch#187735)把 XPU 的 max_tokens 限制到 64。

值得快速浏览(约 5 分钟),不建议精读。它展示了“注释文档化 + 平台特判”处理跨后端数值发散的模式,作者在 PR body 中关于“测试目的与数值稳定性取舍”的论证是值得借鉴的表达方式。若后续要根治 ViT FlashAttention 数值问题,PR 注释中的证据链(BF16 + FlashAttention、num_logprobs 无效、FP32/Triton 通过)是可复用的排查起点。

讨论亮点

该 PR 没有实质性的 review 讨论:claude[bot] 因 fork 分支自动 review 被禁用仅给出流程提示,维护者 jikunshang 直接 approve 并触发 CI。值得注意的权衡点——把对比 token 数从 128 减半到 64、牺牲长尾正确性验证——由作者在 PR body 中预先论证(测试目的是整体正确性而非 ViT FlashAttention 数值稳定性),因此未引起质疑。

实现拆解

  1. 问题定位:在 XPU 后端运行 tests/models/multimodal/generation/test_common.py::test_multi_image_models[qwen2_vl-test-case12] 时,BF16 精度配合 ViT FlashAttention 内核会在长自回归后期出现 HF 与 vLLM 的 logprobs 发散。作者本地复现表明:将 num_logprobs 从 10 提高到 20 无法消除发散,而 FP32 或 BF16 + Triton ViT attention 均能通过,说明问题集中在 BF16 + FlashAttention 组合的数值路径上。
  2. 配置修改:在 tests/models/multimodal/generation/test_common.py 的 qwen2_vl VLMTestInfo 条目中,将 max_tokens 的平台条件由 current_platform.is_cpu() 扩展为 current_platform.is_cpu() or current_platform.is_xpu(),使 CPU 与 XPU 均使用 64 而非 128。num_logprobs 的平台差异保持不变(CPU 20、其余 10)。
  3. 注释同步:将原先只针对 CPU 的注释重写为同时记录 CPU(torch 2.13、pytorch/pytorch#187735)与 XPU 的实测证据,包括“提高 num_logprobs 无效”和“FP32/Triton 路径可通过”两个关键排除结论,为后续根因定位保留上下文。
  4. 验证与配套:作者本地运行目标测试通过(约 443 秒),随后触发 Buildkite CI #86364 全量验证;无源码、文档或配置的配套改动。
文件 模块 状态 重要度
tests/models/multimodal/generation/test_common.py 多模态测试 modified 4.84

关键源码片段

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

唯一变更文件。将 Qwen2-VL 多图测试的 max_tokens 在 XPU 上从 128 收窄到 64,与 CPU workaround 对齐,并重写注释记录 BF16 + ViT FlashAttention 的数值发散证据与排除结论。

# qwen2_vl 的 VLMTestInfo 配置(节选):
# 该测试以 HF 为参考对比 vLLM 的 logprobs 输出,目标是验证多模态整体正确性,
# 而非验证 ViT FlashAttention 在超长自回归下的数值稳定性。
"qwen2_vl": VLMTestInfo(
    models=["Qwen/Qwen2-VL-2B-Instruct"],
    test_type=(VLMTestType.IMAGE, VLMTestType.MULTI_IMAGE, VLMTestType.VIDEO),
    # 多图场景下,HF 与 vLLM 会在生成长前缀(约 69 个 token)后于尾部发散。
    # CPU 上的成因是 torch 2.13 累积的数值漂移(见 pytorch/pytorch#187735);
    # XPU 上 BF16 + ViT FlashAttention 表现出同类后期发散,
    # 且提高 num_logprobs(10 -> 20)无法消除,而 FP32 或 BF16 + Triton
    # 注意力路径可以通过本地复现,说明问题与 BF16 + FlashAttention 组合相关。
    # 因此在 CPU 与 XPU 上把 max_tokens 从 128 收窄到 64,
    # 使对比区间落在发散点之前,以较低成本保留多图路径的覆盖。
    max_tokens=64
    if current_platform.is_cpu() or current_platform.is_xpu()
    else 128,
    num_logprobs=20 if current_platform.is_cpu() else 10,
    auto_cls=AutoModelForImageTextToText,
    vllm_output_post_proc=model_utils.qwen2_vllm_to_hf_output,
)

评论区精华

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

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

风险与影响

技术风险:max_tokens 从 128 减到 64 后,测试只比对前半段生成的 logprobs,后半段正确性不再被检验,未来 Qwen2-VL 尾部生成若出现回归可能被此测试漏检。平台特判条件从单分支扩展到双分支,若后续更多平台出现同类问题会继续堆积条件;根治方向应是修复 ViT FlashAttention 的数值稳定性,而非继续叠加平台特判。兼容性:非 CPU/XPU 平台仍为 128,行为无变化。该改动仅影响测试文件,产品代码零风险。

影响范围仅限 XPU CI 上的 Qwen2-VL 多模态正确性测试:测试稳定性提升、减少 rerun 成本;代价是验证区间减半,对该路径长序列正确性的覆盖强度下降。对用户、运行时系统、其他平台无影响,对 Intel GPU 团队 CI 维护有直接收益。

测试覆盖强度下降 平台特判分支累积 数值根因未修复

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论