执行摘要
- 一句话:移除未使用的 cutlass MXFP8 代码及测试
- 推荐动作:该 PR 是标准的死代码清理,变更清晰、审核充分,建议快速合入。对于其他死代码,可参考此 PR 的模式:提供关联 PR 证据 + 逐一清理所有引用(绑定/注册/实现/构建/测试)。
功能与动机
这些 MXFP8 相关的算子和测试代码在 #34448 之后已不再被生产代码使用。移除它们可以清理仓库,减少维护成本和编译时间。
实现拆解
变更分为几个步骤:
- 移除 Python 绑定:在
vllm/_custom_ops.py 中删除 mxfp8_experts_quant、cutlass_mxfp8_grouped_mm 两个函数定义及其对应的 register_fake 装饰器,消除 Python 层的入口。
- 移除 C++ OP 注册:在
csrc/libtorch_stable/torch_bindings.cpp 中删除 mxfp8_experts_quant 和 cutlass_mxfp8_grouped_mm 的 ops.def 声明,切断 torch 绑定的注册。
- 删除 C++ 内核实现:移除
csrc/libtorch_stable/moe/mxfp8_moe/ 目录下的所有 .cu/.cuh 文件(约 6 个文件),包括量化、GEMM 启动器、functor、traits 等完整实现。
- 更新 CMake 构建:在
CMakeLists.txt 中移除与这些源文件相关的编译目标。
- 删除测试文件:完全删除
tests/kernels/moe/test_cutlass_mxfp8_grouped_mm.py,该文件专门测试这些内核。
所有删除均不可逆,但因为代码已不被任何生产路径引用,风险较低。
关键文件:
vllm/_custom_ops.py(模块 算子绑定;类别 source;类型 core-logic;符号 mxfp8_experts_quant, cutlass_mxfp8_grouped_mm, _mxfp8_experts_quant_fake, _cutlass_mxfp8_grouped_mm_fake): Python 入口点,移除了 MXFP8 相关函数和 fake 注册,是删除的关键桥梁。
tests/kernels/moe/test_cutlass_mxfp8_grouped_mm.py(模块 内核测试;类别 test;类型 deletion;符号 align, calc_diff, is_sm100_supported, compute_ref_output): 整个测试文件被删除,覆盖了 MXFP8 内核的正确性测试。
csrc/libtorch_stable/torch_bindings.cpp(模块 C++ 注册;类别 source;类型 core-logic;符号 mxfp8_experts_quant, cutlass_mxfp8_grouped_mm): 删除了 MXFP8 算子的 C++ op 注册,是 C++ 绑定的关键入口。
csrc/libtorch_stable/moe/mxfp8_moe/mxfp8_experts_quant.cuh(模块 CUDA 内核;类别 other;类型 deletion): MXFP8 量化内核的 C++ CUDA 头文件实现,被完全删除。
csrc/libtorch_stable/moe/mxfp8_moe/cutlass_mxfp8_grouped_mm_launcher.cuh(模块 CUDA 内核;类别 other;类型 deletion): MXFP8 grouped GEMM 启动器的 CUDA 头文件,被完全删除。
关键符号:mxfp8_experts_quant, cutlass_mxfp8_grouped_mm, _mxfp8_experts_quant_fake, _cutlass_mxfp8_grouped_mm_fake, test_cutlass_mxfp8_grouped_mm
关键源码片段
tests/kernels/moe/test_cutlass_mxfp8_grouped_mm.py
整个测试文件被删除,覆盖了 MXFP8 内核的正确性测试。
# 整个文件 tests/kernels/moe/test_cutlass_mxfp8_grouped_mm.py 已删除
# 以下是主要测试函数(已移除)
def is_sm100_supported() -> bool:
return current_platform.is_cuda() and current_platform.is_device_capability_family(100)
def compute_ref_output(input_tensor, weight_list, expert_offsets, expert_offset, num_experts):
# 构建 top-1 路由得分,计算参考输出
score = torch.full((expert_offset, num_experts), -1e9, device=input_tensor.device, dtype=torch.float32)
for g in range(num_experts):
start = expert_offsets[g]
end = expert_offsets[g + 1] if g + 1 < num_experts else expert_offset
score[start:end, g] = 0.0
return torch_moe_single(input_tensor, torch.stack(weight_list, dim=0), score, topk=1)
@pytest.mark.skipif(not is_sm100_supported(), reason="仅支持 SM100")
@pytest.mark.parametrize("num_experts", [8, 16, 32, 64])
@pytest.mark.parametrize("out_dtype", [torch.half, torch.bfloat16])
def test_cutlass_mxfp8_grouped_mm(num_experts, out_dtype):
# 调用 ops.mxfp8_experts_quant 和 ops.cutlass_mxfp8_grouped_mm
# 与参考输出对比,验证正确性
...
csrc/libtorch_stable/torch_bindings.cpp
删除了 MXFP8 算子的 C++ op 注册,是 C++ 绑定的关键入口。
// 以下 C++ OP 注册已在 PR #44681 中删除
// Expert-specialization mxfp8 blockscaled grouped quantization (SM100+).
ops.def(
"mxfp8_experts_quant("
" Tensor input, Tensor problem_sizes, Tensor expert_offsets,"
" Tensor blockscale_offsets, Tensor! quant_output, Tensor! scale_factor)"
" -> ()");
// Expert-specialization mxfp8 blockscaled grouped GEMM (SM100+).
ops.def(
"cutlass_mxfp8_grouped_mm("
" Tensor a, Tensor b, Tensor sfa, Tensor sfb, Tensor! out,"
" Tensor problem_sizes, Tensor expert_offsets, Tensor blockscale_offsets)"
" -> ()");
评论区精华
审核者 Harry-Chen 在首次提交后指出初始 diff 未包含 CMakeLists.txt 和 torch_bindings.cpp 的更改(评论:"the current diff does not include CMakeLists.txt and torch_bindings.cpp?")。PR 作者随后补充了这些文件的修改并回复 "Thanks! Now added",最终审核通过。
- Missing CMakeLists.txt and torch_bindings.cpp in initial diff (question): 作者随后补充了这些文件的修改,Harry-Chen 批准
风险与影响
关联脉络
- PR #34448 原 PR 导致此代码停用: PR body 指出此代码自 #34448 起未使用
参与讨论