Prhub

#44476 [Bugfix][Compile] Guard per_token_group_fp8_quant lookup on non-CUDA platforms

原始 PR 作者 QiliangCui2023 合并时间 2026-06-04 21:31 文件变更 2 提交数 2 评论 1 代码增减 +7 / -4

执行摘要

修复非 CUDA 平台的 per_token_group_fp8_quant 导入崩溃

修复非 CUDA 平台因 torch.ops._C 缺少 per_token_group_fp8_quant 属性导致的 AttributeError 导入异常。该问题由 PR #42758 引入,其将两个 kv 量化操作条目移出 current_platform.is_cuda() 守卫,导致无条件引用。

值得快速合并的 bugfix。展示了在跨后端环境中正确守卫平台相关操作的最佳实践:使用 hasattr 而非平台枚举来检查操作存在性。

讨论亮点

无实质讨论评论。

实现拆解

  1. matcher_utils.py: 将字典字面量中的 kFp8Dynamic128SymkFp8Dynamic64Sym 条目删除,改为在字典定义后使用 hasattr(torch.ops._C, "per_token_group_fp8_quant") 条件守卫动态添加。
  2. rms_quant_fusion.py: 对同一模式进行相同的结构性调整:移除字面量中的无条件引用,替换为 hasattr 守卫。
  3. 守卫逻辑对齐: 与已有的 scaled_fp4_quant 守卫模式保持一致,但使用更宽松的 hasattr 条件覆盖 ROCm 平台(无需依赖 current_platform.is_cuda())。
文件 模块 状态 重要度
vllm/compilation/passes/fusion/matcher_utils.py 编译优化 modified 5.75
vllm/compilation/passes/fusion/rms_quant_fusion.py 编译优化 modified 5.3

关键源码片段

vllm/compilation/passes/fusion/matcher_utils.py core-logic

核心文件之一:将 per_token_group_fp8_quant 的两个字典条目从无条件字面量移到 hasattr 守卫后。此文件是多个融合 pass 的公共依赖。

# 无条件字典只包含 CUDA/HIP 平台都能保证存在的操作
QUANT_OPS: dict[QuantKey, OpOverload] = {
    kFp8StaticTensorSym: torch.ops._C.static_scaled_fp8_quant.default,
    kFp8DynamicTensorSym: torch.ops._C.dynamic_scaled_fp8_quant.default,
    kFp8DynamicTokenSym: torch.ops._C.dynamic_per_token_scaled_fp8_quant.default,
}# per_token_group_fp8_quant 仅在 GPU 后端存在 (libtorch_stable 扩展 ),
# 用 hasattr 代替平台检查以兼容 ROCm
if hasattr(torch.ops._C, "per_token_group_fp8_quant"):
    QUANT_OPS[kFp8Dynamic128Sym] = torch.ops._C.per_token_group_fp8_quant.default
    QUANT_OPS[kFp8Dynamic64Sym] = torch.ops._C.per_token_group_fp8_quant.default# 保持既有的 fp4 守卫模式不变
if current_platform.is_cuda() and hasattr(torch.ops._C, "scaled_fp4_quant"):
    QUANT_OPS[kNvfp4Dynamic] = torch.ops._C.scaled_fp4_quant.out
vllm/compilation/passes/fusion/rms_quant_fusion.py core-logic

另一个需要修复的文件,与 matcher_utils.py 完全相同的模式修正。该文件专门处理 RMSNorm + 量化融合。

# 同 matcher_utils.py 中的做法,将 GPU 专有的 per_token_group_fp8_quant 操作
# 移到 hasattr 守卫中,避免非 GPU 平台导入崩溃
QUANT_OPS: dict[QuantKey, OpOverload] = {
    kFp8StaticTensorSym: torch.ops._C.static_scaled_fp8_quant.default,
    kFp8DynamicTensorSym: torch.ops._C.dynamic_scaled_fp8_quant.default,
    kFp8DynamicTokenSym: torch.ops._C.dynamic_per_token_scaled_fp8_quant.default,
}
if hasattr(torch.ops._C, "per_token_group_fp8_quant"):
    QUANT_OPS[kFp8Dynamic128Sym] = torch.ops._C.per_token_group_fp8_quant.default
    QUANT_OPS[kFp8Dynamic64Sym] = torch.ops._C.per_token_group_fp8_quant.default
if current_platform.is_cuda() and hasattr(torch.ops._C, "scaled_fp4_quant"):
    QUANT_OPS[kNvfp4Dynamic] = torch.ops._C.scaled_fp4_quant.out

评论区精华

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

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

风险与影响

低风险。CUDA 和 ROCm 平台下 per_token_group_fp8_quant 仍会注册,行为不变;非 GPU 平台只会跳过注册,量化融合不会尝试使用该操作。潜在风险是未来在其他 GPU 后端(如 Intel GPU)上如果注册了同名操作,hasattr 会误判,但当前架构下该操作仅限 CUDA/HIP。

影响范围聚焦于非 CUDA/ROCm 平台(CPU、TPU)。修复了导入崩溃 bug,使序列并行相关的测试可正常运行。CUDA 和 ROCm 平台无任何行为变更。

平台兼容性修复

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论