Prhub

#42225 [CPU] Fix rotary embedding for CPU without flash-attn ops

原始 PR 作者 jmamou 合并时间 2026-05-12 23:05 文件变更 1 提交数 4 评论 5 代码增减 +2 / -1

执行摘要

修复 CPU 环境下 Rotary Embedding 导入 flash_attn 崩溃

CPU 推理中,当加载使用 RoPE 的现代模型(如 Llama 3.x、Qwen 2.x/3.x)时,代码仅通过 find_spec("flash_attn") 判断包是否存在,但 CPU 环境下包元数据存在而实际 ops 模块缺失,导致 ModuleNotFoundError: No module named 'flash_attn.ops'。该 PR 旨在消除这一运行时错误,使 CPU 推理正常工作。

值得立即合并。改动极小,修复明确,已通过实际模型验证。建议合并后补充 CPU 环境下的 CI 测试,覆盖 RoPE 模型加载场景。

讨论亮点

核心讨论围绕实现方式展开。初审时 reviewer yewentao256 指出不应在 CPU 环境下 silent pass,应直接跳过导入路径。提交者 jmamou 随后将 try-except 方案改为基于 current_platform.is_cpu() 的条件判断。reviewer 还建议移除代码中的注释,因“CPU 不适用 flash_attn”属已知事实。最终 reviewer 批准并指示重试后强制合并。

实现拆解

  1. 导入 current_platform:在文件 vllm/model_executor/layers/rotary_embedding/common.py 顶部增加 from vllm.platforms import current_platform 导入。
  2. 添加平台条件判断:将 __init__ 中原本的 if find_spec("flash_attn") is not None: 改为 if not current_platform.is_cpu() and find_spec("flash_attn") is not None:。该改动确保 CPU 环境下完全跳过 flash_attn 的导入和赋值,避免后续引用 self.apply_rotary_emb_flash_attnNone 时自动回退到原生 PyTorch 实现。
  3. 无测试配套变更:PR 未包含针对性测试,但作者已在 Intel Xeon Platinum 8580 CPU 上对 Qwen2.5-3B-Instruct 和 Llama-3.2-3B-Instruct 进行了端到端验证,模型加载和推理均成功。
文件 模块 状态 重要度
vllm/model_executor/layers/rotary_embedding/common.py 模型执行器 modified 5.77

关键符号

ApplyRotaryEmb.__init__

关键源码片段

vllm/model_executor/layers/rotary_embedding/common.py core-logic

唯一变更文件,包含旋转位置嵌入的核心逻辑。在 `ApplyRotaryEmb.__init__` 中增加平台检查,避免 CPU 环境导入 flash_attn 失败。

# vllm/model_executor/layers/rotary_embedding/common.pyfrom importlib.util import find_spec
import torch
from vllm.platforms import current_platform # 新增:用于识别当前运行平台class ApplyRotaryEmb(CustomOp):
    def __init__(self, enforce_enable: bool = False, is_neox_style: bool = True,
                 enable_fp32_compute: bool = False) -> None:
        super().__init__(enforce_enable=enforce_enable)
        self.is_neox_style = is_neox_style
        self.enable_fp32_compute = enable_fp32_compute
​
        self.apply_rotary_emb_flash_attn = None
        # 核心修复:仅当非 CPU 平台且 flash_attn 包存在时才尝试导入
        if not current_platform.is_cpu() and find_spec("flash_attn") is not None:
            from flash_attn.ops.triton.rotary import apply_rotary
            self.apply_rotary_emb_flash_attn = apply_rotary
        # CPU 环境下跳过导入,后续 forward 会自动回退到原生 PyTorch 实现

评论区精华

实现方式:try-except 与平台检查的选择 设计

reviewer yewentao256 指出使用 try-except 静默跳过 import 不是好做法,建议 CPU 环境直接不执行该导入路径。

结论:提交者将方案改为 `if not current_platform.is_cpu() and find_spec(...)`,去掉 try-except。reviewer 批准。 · 已解决

代码注释必要性 style

reviewer yewentao256 建议移除代码中的注释,认为“CPU 不适用 flash_attn”是广泛已知的事实。

结论:提交者采纳了 reviewer 的建议,移除了相关注释。 · 已解决

风险与影响

风险极低。变更仅增加一处平台检查,不影响 GPU 路径(GPU 下 current_platform.is_cpu() 返回 False,行为不变)。CPU 环境下,若 self.apply_rotary_emb_flash_attnNoneApplyRotaryEmb 类会使用原生 PyTorch 实现,功能完备。需注意本 PR 与 #35301 存在 HEAD SHA 冲突,合并时需处理。

影响范围小但意义明确:修复 CPU 推理中的阻塞性崩溃,使现代模型(Llama 3.x、Qwen 2.x/3.x)可在 CPU 环境下正常使用。对 GPU 用户无任何影响。团队后续需在 CI 中增加 CPU 环境下的模型加载测试,防止此类回归。

与 #35301 冲突

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论