执行摘要
- 一句话:新增 Power VSX 注意力后端并修复 L2 缓存初始化崩溃
- 推荐动作:该 PR 值得关注硬件加速相关的设计模式:如何为不同 ISA 实现微内核并融入统一 dispatch 框架。特别需阅读
cpu_attn_vsx.hpp 中的 BF16 加载技巧和 generate_cpu_attn_dispatch.py 的条件编译方式。建议在合并后补充 VSX 内核的单元测试和基准对比。对于实现的技术细节,可参考最终合并版本是否修正了讨论中的合并方向问题。
功能与动机
来自 PR 描述:目的是为 PowerPC 架构添加原生 VSX 支持,避免回退到标量代码,并解决初始化时 IndexError: unordered_map::at 造成的崩溃。测试用例为 ibm-granite/granite-3.3-8b-instruct 模型,在 ppc64le 上验证。
实现拆解
实现分为四步:
- 新增 VSX 注意力内核文件(
csrc/cpu/cpu_attn_vsx.hpp):实现基于 Power VSX 指令的微内核 gemm_micro_ppc64le_Mx8_Ku4 和 load_row8_B_as_f32 特化,支持 float 和 bfloat16 类型加载,并通过模板类 AttentionImpl 与现有框架对接。
- 扩展 ISA 枚举与分发脚本:在
csrc/cpu/cpu_attn_impl.hpp 的 cpu_attention::ISA 中新增 VSX 枚举值;在 csrc/cpu/generate_cpu_attn_dispatch.py 中注册 VSX 类型并添加到 ISA_FOR_32,生成条件编译宏 #ifdef __powerpc__ 包含新头文件并生成 dispatch case。
- Python 后端架构感知:在
vllm/v1/attention/backends/cpu_attn.py 中的 _CPU_ARCH_PREFER_MIXED_BATCH 元组加入 CpuArchEnum.POWERPC,使 Power 架构优先使用混合批次;在 _get_attn_isa() 函数中检测 arch == CpuArchEnum.POWERPC 返回 "vsx",从而选择 VSX 内核。
- L2 缓存大小修复:在
csrc/cpu/utils.hpp 中,将本用于 __s390x__ 的安全 L2 缓存检测(使用 find 而非 at)扩展到 __powerpc__,避免 unordered_map::at 因键缺失崩溃;同时提供默认回退 256KB。
- 配套调整:修改
csrc/cpu/cpu_attn.cpp 以识别 "vsx" ISA 提示;修改 csrc/cpu/cpu_attn_vec.hpp 添加注释说明 VSX 不支持 FP8 KV cache 并调整 load_b_pair_vec 返回语句;修改 csrc/cpu/cpu_types_vsx.hpp 添加 FP8 标记的 stub 以通过编译。注意:本次未包含直接测试文件变更。
关键文件:
csrc/cpu/cpu_attn_vsx.hpp(模块 VSX内核;类别 source;类型 core-logic;符号 TileGemmPPC64, AttentionImpl, load_row8_B_as_f32, gemm_micro_ppc64le_Mx8_Ku4): 新增文件,实现 Power VSX 注意力微内核,包含 BF16/FP32 加载和 GEMM 微块,是 PR 的核心变更。
csrc/cpu/generate_cpu_attn_dispatch.py(模块 分发生成;类别 source;类型 dependency-wiring;符号 ISA_TYPES, ISA_FOR_32, generate_header_file, _macro_block): 修改分发脚本,注册 VSX ISA 类型、加入 ISA_FOR_32 列表,并生成 powerpc 条件编译分支,将新内核集成到 dispatch 中。
vllm/v1/attention/backends/cpu_attn.py(模块 后端路由;类别 source;类型 core-logic;符号 _CPU_ARCH_PREFER_MIXED_BATCH, _get_attn_isa): 修改 Python 后端,在 _get_attn_isa 中检测 POWERPC 架构并返回 'vsx',同时在 _CPU_ARCH_PREFER_MIXED_BATCH 中加入 POWERPC。
csrc/cpu/cpu_attn_impl.hpp(模块 ISA枚举;类别 source;类型 core-logic;符号 ISA, AttentionMetadata): 在 ISA 枚举中添加 VSX,并在 AttentionMetadata::print() 中加入对应分支字符串。
csrc/cpu/cpu_attn.cpp(模块 调度入口;类别 source;类型 core-logic;符号 get_scheduler_metadata, cpu_attn_reshape_and_cache): 在 isa_hint 解析和 reshape_and_cache 的 ISA 映射中加入 'vsx' 到 ISA::VSX 的转换。
csrc/cpu/cpu_attn_vec.hpp(模块 向量加载;类别 source;类型 core-logic;符号 load_b_pair_vec): 调整 load_b_pair_vec 的返回语句使用 std::make_pair 避免歧义,并添加注释说明 VSX 不支持 FP8 KV cache。
csrc/cpu/cpu_types_vsx.hpp(模块 类型支撑;类别 source;类型 core-logic): 为 VSX 平台提供 FP8 类型标记的空结构体 stub,解决编译错误。
csrc/cpu/utils.hpp(模块 L2检测;类别 source;类型 core-logic;符号 get_available_l2_size): 修复 L2 缓存大小检测崩溃:将 s390x 的安全检测扩展到 powerpc,使用 find 避免 at 抛出异常。
关键符号:load_row8_B_as_f32, gemm_micro_ppc64le_Mx8_Ku4, get_available_l2_size, _get_attn_isa, copy_q_heads_tile
关键源码片段
csrc/cpu/cpu_attn_vsx.hpp
新增文件,实现 Power VSX 注意力微内核,包含 BF16/FP32 加载和 GEMM 微块,是 PR 的核心变更。
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright contributors to the vLLM project
// 以下展示 BFloat16 特化的 load_row8_B_as_f32 函数
// 利用 vec_mergeh/mergel 将 BF16 扩展为 float32,实现内存加载
// 注意:在 ppc64le 小端下,vec_mergeh 取高半部分,vec_mergel 取低半部分
// 若方向错误将导致 GEMM 结果错误(参见 review #1)
template <>
FORCE_INLINE void load_row8_B_as_f32<c10::BFloat16>(const c10::BFloat16* p,
__vector float& b0,
__vector float& b1) {
__vector unsigned short raw = vec_xl(
0, reinterpret_cast<unsigned short*>(const_cast<c10::BFloat16*>(p)));
__vector unsigned short zeros = vec_splat_u16(0);
// LE: zeros 填入低 16 位,raw 填入高 16 位,得到 (bf16_bits << 16) 等价 float32
b0 = (__vector float)vec_mergeh(zeros, raw);
b1 = (__vector float)vec_mergel(zeros, raw);
}
// Note: c10::Half (FP16) is not supported on PowerPC architecture
csrc/cpu/generate_cpu_attn_dispatch.py
修改分发脚本,注册 VSX ISA 类型、加入 ISA_FOR_32 列表,并生成 powerpc 条件编译分支,将新内核集成到 dispatch 中。
# 在 ISA_TYPES 中增加 VSX 类型
ISA_TYPES = {
"AMX": 0,
"VEC": 1,
"VEC16": 2,
"NEON": 3,
"VXE": 4,
"VSX": 5, # 新增 Power VSX
}
# 在 ISA_FOR_32 中加入 VSX,表示 head_dim 可被 32 整除时支持
ISA_FOR_32 = ["AMX", "NEON", "VEC", "VEC16", "VXE", "VSX"]
# 在 generate_header_file 中添加条件包含
#ifdef __powerpc__
#include "cpu_attn_vsx.hpp"
#endif
# 添加 __powerpc__ 宏块,包含 VSX、VEC、VEC16(不带 FP8)
header += _macro_block(
"#elif defined(__powerpc__)",
["VSX", "VEC", "VEC16"],
fp8=False,
)
vllm/v1/attention/backends/cpu_attn.py
修改 Python 后端,在 _get_attn_isa 中检测 POWERPC 架构并返回 'vsx',同时在 _CPU_ARCH_PREFER_MIXED_BATCH 中加入 POWERPC。
def _get_attn_isa(dtype, block_size, head_size=None, kv_cache_dtype=None):
# ... 前面部分 ...
supports_amx = torch.cpu._is_amx_tile_supported()
arch = current_platform.get_cpu_architecture()
supports_arm = arch == CpuArchEnum.ARM
supports_vxe = arch == CpuArchEnum.S390X
supports_vsx = arch == CpuArchEnum.POWERPC # 新增 Power 检测
# ...
if supports_amx and dtype in (torch.bfloat16,) and block_size % 32 == 0:
return "amx"
elif block_size % 32 == 0:
if supports_arm:
return "neon"
elif supports_vxe:
return "vxe"
elif supports_vsx:
return "vsx" # 返回 VSX ISA 名称
else:
return "vec"
else:
return "vec16"
# 同时将 POWERPC 加入混合批次偏好的架构列表
_CPU_ARCH_PREFER_MIXED_BATCH = (
CpuArchEnum.X86, CpuArchEnum.ARM, CpuArchEnum.S390X, CpuArchEnum.POWERPC,
)
评论区精华
Review 中最关键的讨论:
- BFloat16 合并方向错误(gemini-code-assist[bot]):在 ppc64le 小端下,
vec_mergeh/vec_mergel 的选择导致 8 元素行数据高低半部分互换,若未修正将导致 GEMM 结果错误。目前 PR 中代码仍保持此写法,需关注最终合并版本是否已修复。
- Half 类型指针算术错误(gemini-code-assist[bot]):
copy_q_heads_tile 中使用 (float*)curr_src + d 对于 c10::Half 类型地址计算错误。
- FP16 性能瓶颈(gemini-code-assist[bot]):
load_row8_B_as_f32 的 c10::Half 特化使用标量循环,建议使用 xvcvhpsp 向量化。
- L2 缓存修复范围讨论(bigPYJ1151 与 gemini):bigPYJ1151 认为
#if 分支不应移除 x86/ARM,而应为 POWER 单独添加安全分支;gemini 建议全局应用安全模式以提高健壮性。
- FP8 KV cache 编译问题(bigPYJ1151 与 Akashcodes732):bigPYJ1151 建议在
cpu_types_vsx.hpp 中添加空结构体 stub 而非修改 cpu_attn_vec.hpp 的 guard,作者接受并采用。
- BFloat16 合并方向错误 (correctness): 未在 PR 中看到修正,需确认合并状态。
- Half 类型指针错误 (correctness): 建议使用 load_row8_B_as_f32 替代,未确认是否采用。
- FP16 性能瓶颈 (performance): 未在 PR 中改进,可能是后续优化。
- L2 缓存修复范围 (design): 折中处理:仅对 s390x 和 powerpc 使用安全查找,其他架构保持原样。
- FP8 KV cache 编译问题 (testing): 采用 stub 方案,已在 cpu_types_vsx.hpp 中添加。
风险与影响
关联脉络
- PR #37481 [XPU] enable is_act_and_mul for xpu: 类似为不同硬件平台(XPU)启用特定后端,但与本 PR 无直接功能性关联。
- PR #41162 [Model Runner V2] Rebuild attn metadata between draft decode steps: 同样修改 v1 注意力相关代码,但属于 speculative decoding 修复,与本 PR 无关。
参与讨论