Prhub

#52050 [Bugfix] Temporarily disable FA4 head-dim 256

原始 PR 作者 taneem-ibrahim 合并时间 2026-08-17 01:13 文件变更 3 提交数 16 评论 34 代码增减 +15 / -14

执行摘要

FA4 head-dim 256 临时回退 FA2,修复 ColPali MRV2 崩溃

PR body 明确指出:PR #42669 在 Blackwell 上启用了 FA4 head-dim 256,但专门的 SM100 2-CTA 内核仍拒绝 seqused_q/seqused_k(vLLM decoder attention 必然提供),ColPali 在 MRV2 下暴露了该失败(关联 Issue #48290)。review 中 yewentao256 建议先查根因,taneem-ibrahim 定位到上游 flash-attention 的 sm100_hd256_2cta_fmha_forward.py 中明确以 TODO 形式断言 mSeqUsedQ/mSeqUsedK 为 None;MatthewBonanni 认为既然该限制排除了所有 decoder 使用场景,应整体禁用 FA4 hdim 256 而不是把支持参数管道化传遍所有路径。

值得精读。改动虽小,但完整展示了「上游内核能力边界 -> 根因定位 -> 临时回退 vs 参数管道化」的工程取舍过程,对注意力后端版本选择逻辑的维护者有直接参考价值。建议关注两点:一是 review 中 MatthewBonanni 对整体禁用的决策理由(避免把支持参数传遍所有路径),二是以 TODO 注释方式记录恢复条件的做法。后续应跟踪 #42669 恢复时机与上游 flash-attention 的 seqused 支持进展。

讨论亮点

核心讨论围绕「根因 vs 回退」与「禁用范围」展开:

  • yewentao256 建议先深挖根因而非简单回退;taneem-ibrahim 给出上游代码证据:assert mSeqUsedQ is None and mSeqUsedK is None,并标注为 TODO(sm100_hd256_2cta_fmha_forward.py 第 186-190 行)。
  • MatthewBonanni 回应「Since this precludes its use for all decoders, I think we should just disable FA4 hdim 256 entirely until we can fix this upstream, rather than piping a new support argument through everything」,确立了整体禁用方案。
  • taneem-ibrahim 确认中心化禁用,并询问是否连 encoder attention 一起禁用;MatthewBonanni 回答「we can effectively revert #42669 temporarily」。
  • MatthewBonanni 提醒删除 requires_local_attention 参数后「we'll need to remember to add this restriction again when we re-enable the kernel」,taneem-ibrahim 随后在代码旁添加 TODO 注释。
  • yewentao256 质疑既然已 revert #42669 就不需要专门单元测试,taneem-ibrahim 按建议删除 test_attention_selector.py 的改动。
  • MatthewBonanni 对 ColPali 测试强制 MRV2 与 FLASH_ATTN 提出两个 nit,taneem-ibrahim 解释多模态 pooling 尚未默认启用 MRV2,不强制则测不到失败路径。

实现拆解

  1. 根因定位与方案决策:在 fa_utils.py 中确认 FA4 head-dim 256 的失败来自上游 flash-attention 内核断言(sm100_hd256_2cta_fmha_forward.py 的 TODO);review 后决定不做参数管道化,而是整体禁用并临时回退 #42669。
  2. 版本选择逻辑改造(vllm/v1/attention/backends/fa_utils.py):get_flash_attn_version 移除 requires_local_attention 参数;head_size == 256 的回退条件从「仅 local attention」改为无条件回退 FA2;TMEM 注释同步更新,明确 256 暂被禁用、192/128 MLA prefill 仍支持;并新增 TODO 注释提醒恢复时需重新加回 requires_local_attention 限制。
  3. 调用方同步(vllm/v1/attention/backends/flash_attn.py):FlashAttentionBackend.init 中移除 requires_local_attention=sliding_window is not None 的参数传递,避免未使用参数残留。
  4. 回归测试(tests/models/multimodal/pooling/test_colpali.py):test_colpali_multimodal_text_query_image_docs 通过 monkeypatch 设置 VLLM_USE_V2_MODEL_RUNNER=1 强制 MRV2,指定 attention_backend="FLASH_ATTN" 与 kernel_config={"enable_flashinfer_autotune": False},并断言 use_v2_model_runner 为真,确保覆盖暴露 bug 的路径。
  5. 测试配套:test_attention_selector.py 的临时改动按 yewentao256 建议删除,与 main 保持一致;PR 验证了 selector 测试(31 passed, 10 skipped)、MLA prefill selector 测试(21 passed)及 B300 真机强制 MRV2 ColPali 测试。
文件 模块 状态 重要度
vllm/v1/attention/backends/fa_utils.py 注意力后端 modified 6.64
vllm/v1/attention/backends/flash_attn.py 注意力后端 modified 4.35
tests/models/multimodal/pooling/test_colpali.py 多模态测试 modified 4.67

关键符号

get_flash_attn_version FlashAttentionBackend.__init__ test_colpali_multimodal_text_query_image_docs

关键源码片段

vllm/v1/attention/backends/fa_utils.py core-logic

核心决策点:get_flash_attn_version 将 head_size == 256 的 FA4 回退条件从 requires_local_attention 扩展为无条件,删除该参数并更新 TMEM 注释与 TODO,是本次修复的主逻辑。

# 以下为 get_flash_attn_version() 中 Blackwell/head_size 相关的核心分支。
# 前面的逻辑已完成 FA2/FA3/FA4 的默认版本选择与环境变量覆盖。# 临时回退:FA4 的 SM100 head_dim=256 专用 2-CTA 内核尚不支持
# seqused_q/seqused_k(上游 flash-attention 的 sm100_hd256_2cta_fmha_forward.py
# 中仍是 TODO 断言),而 vLLM decoder attention 必然传入这两个参数。
# 因此 head_size == 256 时统一降级 FA2;注意这里不再叠加
# requires_local_attention 条件(该参数已删除),意味着 encoder 场景
# 也被一并回退,这是 review 中确认的临时决策。
# TODO: 重新启用 FA4 head-dim 256 时,需恢复 requires_local_attention 限制。
if fa_version == 4 and device_capability.major >= 10 and head_size == 256:
    logger.warning_once(
        "FA4 on Blackwell is temporarily disabled for head_size=256, "
        "defaulting to FA version 2."
    )
    fa_version = 2# FA4 在 SM100 上存在 TMEM 容量限制,head_dim 超过 128 时仅保留
# MLA prefill 的 192/128 组合;原来的 head_size == 256 例外已被上一段
# 回退逻辑吸收,对称 192/384/512 的开发进度见 Dao-AILab/flash-attention#2456。
if (
    fa_version == 4
    and device_capability.major >= 10
    and head_size is not None
    and head_size > 128
    and not (head_size == 192 and head_size_v == 128)
):
    logger.warning_once(
        "FA4 on Blackwell does not support head_size=%d due to TMEM "
        "capacity limits, defaulting to FA version 2.",
        head_size,
    )
    fa_version = 2return fa_version

评论区精华

FA4 head-dim 256 内核不支持 seqused_q/k 的根因 正确性

yewentao256 建议先深挖根因再决定方案;taneem-ibrahim 定位到上游 flash-attention 的 sm100_hd256_2cta_fmha_forward.py 第 186-190 行,该处明确以 assert 拒绝 mSeqUsedQ/mSeqUsedK 并标注为 TODO,而 vLLM decoder attention 必然提供这两个参数。

结论:根因确认在上游内核能力缺失,等待上游支持或临时回退二选一。 · 已解决

整体禁用 FA4 hdim 256 vs 参数管道化传递 设计

MatthewBonanni 认为该限制排除了所有 decoder 使用场景,应整体禁用而不是把新支持参数管道化传遍所有路径;taneem-ibrahim 确认中心化禁用并询问是否连 encoder 一起禁用,MatthewBonanni 答复可视为临时 revert #42669。

结论:采纳整体禁用方案,encoder 场景一并回退。 · 已解决

删除 requires_local_attention 参数后的恢复提醒 设计

MatthewBonanni 提醒删除参数虽合理但重新启用时需恢复该限制;taneem-ibrahim 在回退逻辑旁添加 TODO 注释(ea4f3dc5bd)。

结论:以代码内 TODO 注释形式记录恢复条件。 · 已解决

回退后是否保留 SM100 hd256 单元测试 测试

yewentao256 指出既然整体 revert #42669,就不需要专门单元测试;taneem-ibrahim 删除 test_attention_selector.py 的改动并移除残留 DeviceCapability 导入,使其与 main 一致。

结论:按建议删除 selector 测试改动,回归覆盖由 ColPali 测试承担。 · 已解决

ColPali 测试强制 MRV2 与 FLASH_ATTN 的必要性 测试

MatthewBonanni 对 VLLM_USE_V2_MODEL_RUNNER=1 与 attention_backend="FLASH_ATTN" 提出两个 nit;taneem-ibrahim 解释多模态 pooling 尚未默认启用 MRV2,不强制则测不到暴露 bug 的路径,指定 FLASH_ATTN 可锁定受影响后端。

结论:保留强制配置,作为该回归路径的必要条件。 · 已解决

风险与影响

  1. Blackwell 性能回退:所有 head_size == 256 的注意力在 SM100+ 上从 FA4 降到 FA2,解码吞吐可能下降;这是有意的临时取舍,但 PR 未附性能基准数据。
  2. 禁用范围扩大:原实现仅在 requires_local_attention(sliding_window)场景回退,本 PR 将回退扩展到全部 head_size == 256 场景,包括原本可正常走 FA4 的 encoder 注意力,影响面比 bug 本身更大(review 中已确认接受)。
  3. 上游依赖:恢复 FA4 hdim 256 依赖 Dao-AILab/flash-attention 实现 seqused_q/seqused_k 支持,当前仅有 TODO 注释与 issue 跟踪,存在遗忘风险。
  4. 测试覆盖局限:新增回归测试仅覆盖 ColPali 的文本查图片文档场景,且通过环境变量强制 MRV2;若未来 MRV2 默认启用,该 monkeypatch 会冗余但无害。
  5. 接口签名变更:get_flash_attn_version 删除 requires_local_attention 参数,若其他调用方未同步更新会引发 TypeError;从 patch 看 flash_attn.py 是唯一调用点,风险可控。

用户层面:Blackwell 上 head_size == 256 的模型(含 ColPali 等 pooling 模型)会自动回退 FA2 并打印 warning_once 日志,无需手动配置,但相关场景性能可能回落。系统层面:注意力版本选择逻辑更简洁(少一个参数、256 处理统一),FA4 对 head_dim 128 与 MLA 192/128 保持启用。工程层面:为 #48290 的 MRV2 pooling 默认启用扫清一个崩溃障碍,ColPali 测试成为 MRV2 多模态回归覆盖的一部分;团队需持续跟进上游 flash-attention 进展以恢复 FA4。

核心路径变更 Blackwell 性能回退 上游依赖 临时禁用待恢复

关联 Issue

#48290 [ModelRunner v2] Enable MRV2 for pooling models by default

完整报告

参与讨论