执行摘要
- 一句话:为Ascend NPU Qwen3 Dense模型添加W8A8 MXFP8量化支持
- 推荐动作:值得精读,尤其
process_weights_after_loading中对.contiguous()的差异化处理是NPU量化的关键设计决策,显示了平台硬件特性对软件实现的约束。
功能与动机
参考PR body:"closes part of the NPU quantization gap tracked in issue #21584"。目标是支持Ascend NPU A5系列硬件的MXFP8量化,以降低内存带宽和计算开销,同时保持接近无损精度。
实现拆解
- NPU旁路与分发:在
fp8.py的Fp8Config.get_min_capability()中增加NPU返回0的旁路,避免CUDA capability检查;在get_quant_method()中增加NPU+use_mxfp8分支,分发到NPUMXFP8LinearMethod。
- 在线量化线性方法:在
linear_method_npu.py新增NPUMXFP8LinearMethod类。create_weights以原始FP16/BF16 dtype预留权重;process_weights_after_loading通过npu_dynamic_mx_quant在线量化为MXFP8并预转置为[in, out]布局(不调用.contiguous()以保留分析视图);apply对激活逐token量化后调用npu_quant_matmul(group_sizes=[1,1,32])。
- 离线量化方案:在
modelslim_mxfp8.py新增ModelSlimMXFP8Scheme类,处理msmodelslim预量化权重(float8_e4m3fn + uint8 scale)。create_weights创建对应dtype的参数;process_weights_after_loading转置但不调用.contiguous()以保持block-scale映射;apply_weights类似在线路径进行激活量化和矩阵乘法。
- 注册与导入调整:在
modelslim/modelslim.py的get_linear_scheme表中注册("W8A8_MXFP8", ModelSlimMXFP8Scheme);在schemes/__init__.py中先导入基类再导入新scheme以避免循环依赖。
- 导入修复:在
rotary_embedding/base.py中将fused_rope_qk_mqa导入包裹在try/except ImportError中,并将符号置为None,避免缺失kernel导致整个模块导入失败进而使模型静默回退。
- 文档:更新
quantization.mdx添加mxfp8行;更新ascend_npu_quantization.mdx补充LLM dense使用示例。
关键文件:
python/sglang/srt/layers/quantization/modelslim/schemes/modelslim_mxfp8.py(模块 量化方案;类别 source;类型 data-contract;符号 ModelSlimMXFP8Scheme, init, create_weights, process_weights_after_loading): 新增离线量化方案,实现预量化权重的加载、转置和MXFP8推理,是离线路径的核心。
python/sglang/srt/hardware_backend/npu/quantization/linear_method_npu.py(模块 量化实现;类别 source;类型 core-logic;符号 NPUMXFP8LinearMethod, create_weights, process_weights_after_loading, apply): 新增NPUMXFP8LinearMethod在线量化类,实现FP16/BF16在线量化为MXFP8并执行量化矩阵乘法,是量化推理的关键执行路径。
python/sglang/srt/layers/rotary_embedding/base.py(模块 位置编码;类别 source;类型 dependency-wiring): 修复缺失fused_rope_qk_mqa kernel时模块导入失败的问题,通过try/except容忍缺失,并在forward_npu中检查None后回退。
python/sglang/srt/layers/quantization/fp8.py(模块 量化框架;类别 source;类型 dependency-wiring): 添加NPU旁路(get_min_capability返回0)和分发逻辑(get_quant_method返回NPUMXFP8LinearMethod),使--quantization mxfp8能在NPU上触发正确路径。
python/sglang/srt/layers/quantization/modelslim/schemes/__init__.py(模块 量化方案;类别 source;类型 data-contract): 导出ModelSlimMXFP8Scheme并调整导入顺序避免循环依赖,是离线量化方案的注册入口。
python/sglang/srt/layers/quantization/modelslim/modelslim.py(模块 量化注册;类别 source;类型 data-contract): 注册("W8A8_MXFP8", ModelSlimMXFP8Scheme)到get_linear_scheme表,使离线量化方案可在配置中通过名称查找。
docs_new/docs/hardware-platforms/ascend-npus/ascend_npu_quantization.mdx(模块 文档;类别 other;类型 core-logic): 更新Ascend NPU量化文档,添加LLM dense MXFP8在线/离线使用示例。
docs_new/docs/advanced_features/quantization.mdx(模块 文档;类别 other;类型 core-logic): 在跨平台量化支持表中增加mxfp8行,标注Ascend A5支持。
关键符号:NPUMXFP8LinearMethod.create_weights, NPUMXFP8LinearMethod.process_weights_after_loading, NPUMXFP8LinearMethod.apply, ModelSlimMXFP8Scheme.create_weights, ModelSlimMXFP8Scheme.process_weights_after_loading, ModelSlimMXFP8Scheme.apply_weights, Fp8Config.get_min_capability, Fp8Config.get_quant_method, ModelSlimConfig.get_linear_scheme
关键源码片段
python/sglang/srt/layers/rotary_embedding/base.py
修复缺失fused_rope_qk_mqa kernel时模块导入失败的问题,通过try/except容忍缺失,并在forward_npu中检查None后回退。
if _is_npu:
import torch_npu
# `fused_rope_qk_mqa` is an optional fast-path kernel shipped with
# `sgl_kernel_npu`. Older NPU CANN / sgl_kernel_npu builds may not
# include it. If we let the ImportError propagate, importing this
# module fails, which in turn causes `ModelRegistry` to silently skip
# every model that depends on it (and fall back to HF Transformers
# without quantisation awareness — see PR #22352). We tolerate the
# missing kernel so model loading still works; call sites must check
# for `None` and use the generic rope path. A warning is emitted so
# the missing kernel is visible in logs instead of being silently
# swallowed.
try:
from sgl_kernel_npu.norm.fused_rope_qk_mqa import fused_rope_qk_mqa
except ImportError:
fused_rope_qk_mqa = None
logger.warning(
"sgl_kernel_npu.norm.fused_rope_qk_mqa is unavailable; "
"falling back to the generic rope implementation. Upgrade "
"sgl_kernel_npu to enable the fused kernel."
)
# ... inside forward_npu:
if (
fused_rope_qk_mqa is not None
and query.shape[0] * query.shape[1] < 65535
):
return fused_rope_qk_mqa(
query,
key,
cos_sin,
self.rotary_dim,
self.is_neox_style,
)
else:
return self.forward_native(positions, query, key, offsets)
评论区精华
风险与影响
关联脉络
- PR #20922 [Diffusion] MXFP8 Quantization Support on Ascend NPU: 前提PR,提供了NPU量化基础设施(MXFP8Config、NPUMXFP8DiffusionLinearMethod),本PR在其基础上构建LLM支持。
- PR #22338 [Diffusion] MXFP4 Quantization Support on Ascend NPU: 前提PR,扩展量化框架支持Diffusion MXFP4,本PR与之共享NPU量化工具函数。
参与讨论