资讯动态

vllm-ascend 的 GroupedMatmulSwigluQuant 融合算子:分组 Matmul + SwiGLU + 量化全流程原理与调用指南

发布时间:2026/10/4 13:20:09 来源:尧图企业网站定制
人工智能大模型模型推理服务AscendCANN【免费下载链接】vllm-ascendCommunity maintained hardware plugin for vLLM on Huawei Ascend项目地址https://gitcode.com/gh_mirrors/vl/vllm-ascend点击查看免费下载导读GroupedMatmulSwigluQuant 是 vllm-ascend华为昇腾硬件上的 vLLM 社区维护插件在csrc/gmm/grouped_matmul_swiglu_quant目录下实现的一颗融合算子它将分组矩阵乘GroupedMatmul→ 动态反量化dquant→ SwiGLU 激活 → 逐 token 量化quant四个步骤合并为一次硬件执行专为 MoEMixture of Experts架构中「每层多个专家、每个专家分到不同数量 token」的离散分布场景设计是昇腾 NPU 上稀疏激活sparse activation推理的关键性能路径之一。阅读本文后你将完整掌握该算子的数学语义分组机制与量化公式、全部输入输出参数的数据类型与格式约束、产品适配范围与硬件限制以及从 CANN 层aclnn接口到 vllm-ascend 封装调用链的实战用法。一、功能说明一次执行完成四步融合该算子以「接口级融合」的方式将传统上需要多个独立算子串行完成的计算链收敛到单次 NPU 执行中阶段传统拆分融合后分组矩阵乘按groupList拆分 token逐专家执行 GEMM一次内核按分组索引批量执行动态反量化逐 token/逐通道 scale 反量化融合进矩阵乘后的逐元素阶段SwiGLU 激活独立激活算子融合进同一内核动态量化输出再走一次量化算子内核末尾直接产出 INT8 结果与量化因子从源码结构看csrc/gmm/grouped_matmul_swiglu_quant/op_kernel/下的grouped_matmul_swiglu_quant.cpp与grouped_matmul_swiglu_pipeline.h分别承载内核入口与流水线编排而grouped_matmul_swiglu_quant_a8w4_msd_pre/mid/post.h则对应 A8W4 量化路径下前处理、中间计算与后处理的阶段性 Kernel 拆分印证了该算子「一次融合、多阶段流水」的实现方式。在 vllm-ascend 中该算子的典型应用场景是带量化W8A8 / A8W4的 MoE 专家前馈网络FFNgate 门控矩阵先做 Top-K 选择随后每个专家按groupList前缀和切分得到自己的 token 子集最后通过本算子一次完成「分专家 GEMM 反量化 SwiGLU 量化」产出可直接供下一层继续以 INT8 计算的输出。二、产品支持情况当前仓库中该算子声明的适配产品如下产品是否支持Atlas A3 系列产品√Atlas A2 系列产品√Kirin X90 处理器系列产品√Kirin 9030 处理器系列产品√需要注意的硬件差异Kirin X90 / Kirin 9030 处理器系列产品不支持 BFLOAT16详见文档「参数说明」末行因此在 Kirin 平台上使用该算子时weightScale只能选择 FLOAT 或 FLOAT16不可使用 BFLOAT16。三、计算原理分组机制与量化公式3.1 数学符号定义符号含义⋅矩阵乘法⊙逐元素Hadamard乘法$\lfloor x \rceil$将 x 四舍五入到最近的整数$\mathbb{Z_8} {x \in \mathbb{Z} \mid -128 \le x \le 127}$INT8 数值域$\mathbb{Z_{32}} {x \in \mathbb{Z} \mid -2147483648 \le x \le 2147483647}$INT32 数值域3.2 输入定义$X \in \mathbb{Z_8}^{M \times K}$输入矩阵左矩阵M 是总 token 数K 是特征维度$W \in \mathbb{Z_8}^{E \times K \times N}$分组权重矩阵右矩阵E 是专家个数K 是特征维度N 是输出维度$bias \in \mathbb{Z_{32}}^{E \times N}$矩阵乘计算的偏移值当前版本暂未启用$offset \in \mathbb{R}^{E \times N}$per-channel 非对称反量化的偏移当前版本暂未启用$w_scale \in \mathbb{R}^{E \times N}$右矩阵的逐通道per-channel缩放因子$x_scale \in \mathbb{R}^{M}$左矩阵的逐 tokenper-token缩放因子$groupList \in \mathbb{N}^{E}$前缀和形式的分组索引列表。3.3 输出定义$Q \in \mathbb{Z_8}^{M \times N / 2}$量化后的输出矩阵$Q_scale \in \mathbb{R}^{M}$量化缩放因子$Q_offset \in \mathbb{R}^{M}$量化偏移因子对称量化下当前不产出有效值。3.4 分组机制groupList 前缀和语义这是理解本算子最关键的语义。groupList是一个前缀和列表groupList[i]表示前 i 个分组累计消费的 token 数第 i 个右矩阵W[i]只作用于索引区间[groupList[i-1], groupList[i])的 token。文档给出了groupList[3,4,4,6]从 0 开始计数的完整例子分组右矩阵token 区间token 数关联的切片0W[0,:,:]x[0:3]3-03x_scale[0:3]、w_scale[0]、bias[0]、offset[0]、Q[0:3]、Q_scale[0:3]、Q_offset[0:3]1W[1,:,:]x[3:4]4-31索引 3 对应的各切片2W[2,:,:]x[4:4]4-40空分组无 token 参与3W[3,:,:]x[4:6]6-42索引 4、5 对应的各切片两个需要特别留意的行为允许空分组如示例中分组 2 区间长度为 0表示该专家本轮没有分到 token算子会跳过它不会产生计算尾部不更新groupList未覆盖到的 token索引 $\ge groupList[-1]$不参与计算。例如groupList[12,14,18]而X的 shape 为[30, :]时输出Q的 shape 为[30, :]但Q[18:, :]部分不会被更新或初始化保留的是显存申请时的原始数据Q_scale[18:]同理。即Q[:groupList[-1],:]与Q_scale[:groupList[-1]]才是有效数据部分调用方在读取输出时必须依据这一规则裁剪。3.5 核心计算链反量化 GEMM SwiGLU 对称量化按分组确定入参后每个分组 i 依次执行带反量化的矩阵乘当前版本公式 $C_{i} (X_{i}\cdot W_{i}) \odot x_scale_{i_{BroadCast}} \odot w_scale_{i_{BroadCast}}$ 注文档标注当前版本暂不支持bias与offset未来版本将支持 $C_{i} (X_{i}\cdot W_{i} bias_{i_{BroadCast}}) \odot x_scale_{i_{BroadCast}} \odot w_scale_{i_{BroadCast}} offset_{i_{BroadCast}}$。切分 SwiGLU将 C 沿输出维度对半切开 $C_{i,act},\ gate_{i} split(C_{i})$ $S_{i} Swish(C_{i,act}) \odot gate_{i}$其中 $Swish(x) \frac{x}{1e^{-x}}$这正是 SwiGLU 门控线性单元的标准形式一半通道经 SiLUSwish激活后与另一半通道逐元素相乘N 维度因此对半输出输出矩阵列为 $N/2$。动态量化对 S 做逐 token 量化。当前支持对称量化 $Q_scale_{i} \frac{max(|S_{i}|)}{127}$$Q_{i} \lfloor \frac{S_{i}}{Q_scale_{i}} \rceil$非对称量化当前版本暂不支持其未来公式为 $Q_scale_{i} \frac{max(S_{i}) - min(S_{i})}{255}$$Q_offset_{i} -128 - \lfloor \frac{min(S_{i})}{Q_scale_{i}} \rceil$$Q_{i} \lfloor \frac{S_{i}}{Q_scale_{i}} Q_offset_{i} \rceil$。四、参数说明参数名输入/输出/属性描述数据类型数据格式x输入左矩阵公式中的 XINT8NDweight输入权重矩阵公式中的 WINT8ND / NZbias输入矩阵乘计算的偏移值公式中的 biasINT32NDoffset输入per-channel 非对称反量化的偏移公式中的 offsetFLOAT32NDweightScale输入右矩阵的量化因子公式中的 w_scaleFLOAT、FLOAT16、BFLOAT16NDxScale输入左矩阵的量化因子公式中的 x_scaleFLOAT32NDgroupList输入指示每个分组参与计算的 Token 个数公式中的 groupListINT64NDoutput输出输出的量化结果公式中的 QFLOATNDoutputScale输出输出的量化因子公式中的 Q_scaleFLOATNDoutputOffset输出输出的非对称量化的偏移公式中的 Q_offsetFLOATND参数速记要点输入x/weight均为 INT8 定点真正的浮点精度由两个 scale 承载xScaleper-tokenFLOAT32与weightScaleper-channel支持 FLOAT/FLOAT16/BFLOAT16Kirin X90/Kirin 9030 不支持 BFLOAT16weight支持 ND 与 NZ 两种格式其中 NZN 维-Z 维重排是昇腾 Cube 单元偏好的分形格式便于矩阵乘取数输出output表项数据类型标注为 FLOAT但依据算子实际实现见下节源码佐证output实质为 INT8 量化结果、outputScale为 FLOAT 缩放因子outputOffset为非对称量化保留位请以实际接口行为为准。五、约束说明N 轴长度不能超过 10240即单个专家的输出通道数上限K 轴长度不能超过 65536即特征维度上限。超过上述上限时算子无法正确执行MoE 模型的层配置如 FFN 中间维度、专家输出维度需要满足该约束。从算子 tiling分块调度实现看op_host/grouped_matmul_swiglu_quant_tiling.cpp正是依据 M / K / N 与groupList在 Host 侧完成分块规划后下发给 NPU 内核因此 N、K 上限实际由硬件 Cube 单元的可寻址与分块能力决定。六、调用说明从 CANN 接口到 vllm-ascend 封装6.1 aclnn 接口调用README 声明了标准的 aclnn 调用方式通过aclnnGroupedMatmulSwigluQuant接口调用本算子对应调用样例test_aclnn_grouped_matmul_swiglu_quant.cpp与算子文档aclnnGroupedMatmulSwigluQuant.md两文件在 vllm-ascend 仓库的 gmm 目录下未随源码分发实际以 CANN 算子包为准。该接口属于 L0 层l0opAPI其核心签名定义于 grouped_matmul_swiglu_quant.hconst std::tupleaclTensor *, aclTensor * GroupedMatmulSwigluQuant(const aclTensor *x, const aclTensor *weight, const aclTensor *perChannelScale, const aclTensor *perTokenScale, const aclTensor *groupList, float limited, const aclTensor *weightAssistanceMatrix, bool isEnableWeightAssistanceMatrix, int dequantMode, aclOpExecutor *executor);注意 L0 接口相比公式描述多了三个扩展属性limitedFLOATSwiGLU 输出的裁剪阈值即 vllm-ascend 封装中的swiglu_limit用于限制激活值范围weightAssistanceMatrix/isEnableWeightAssistanceMatrix辅助权重矩阵及其开关用于特殊的权重补偿场景dequantModeINT反量化模式选择配合 A8W4 等不同量化位宽路径。6.2 输出 shape 的自动推导从 grouped_matmul_swiglu_quant.cpp 的实现可以确认算子对输出形状的约定int64_t m perTokenScale-GetViewShape().GetDim(0); // M 取自 xScale 第一维 int64_t n perChannelScale-GetViewShape().GetDim(1); // N 取自 weightScale 第二维 int64_t nAfterHalve static_castint64_t(n / 2); // SwiGLU 对半切分 gert::Shape outShape({m, nAfterHalve}); // 输出 Q: [M, N/2] gert::Shape scaleOutShape({m}); // 输出 Q_scale: [M]也就是说接口在执行阶段会自动分配[M, N/2]的 INT8 输出张量与[M]的 FLOAT 缩放张量并返回调用方无需预先构造输出但需要预知「N 被 SwiGLU 对半」这一 shape 规则。6.3 vllm-ascend 中的封装使用在 vllm-ascend 推理框架侧该算子通过自定义算子绑定暴露为torch.ops._C_ascend.grouped_matmul_swiglu_quant_weight_nz(...)并在 device_op.py 中封装为npu_grouped_matmul_swiglu_quant签名如下use_mxfp_quantTrue的 MXFP 路径仅支持 Ascend A5此处会直接抛错def npu_grouped_matmul_swiglu_quant( *, x, weight, group_list, weight_scale, x_scale, biasNone, use_mxfp_quantFalse, act_quant_typetorch.float8_e4m3fn, weight_quant_typetorch.float8_e4m3fn, swiglu_limit0.0, mxfp_quant_dtypeNone, ): ... return torch.ops._C_ascend.grouped_matmul_swiglu_quant_weight_nz( xx, weightweight, weight_scaleweight_scale, x_scalex_scale, group_listgroup_list, biasbias, swiglu_limitswiglu_limit, )可以看到vllm-ascend 的封装把groupList直接透传给底层内核并把swiglu_limit对应 L0 接口的limited传入以控制激活裁剪而 MoE 场景下每轮前向各专家的 token 分布是动态变化的因此group_list必须在每次调用时由调度器根据 Top-K 路由结果重新生成前缀和——这与 vllm-ascend 的 MoE token 分发逻辑见 token_dispatcher.py其中标注了 v2 接口按 per-expert 计数消费相衔接。此外该算子在 W4A8 量化路径w4a8.py与 W8A8 动态量化路径w8a8_dynamic.py中均作为专家 GEMM 的执行后端被调用。6.4 同族算子变体csrc/gmm/目录下还存在两个功能进阶的同族算子可作为选型参考grouped_matmul_swiglu_quant_v2v2 版本op_kernel 中按arch35等架构拆分了 MXFP 量化与 per-token 量化实现接口新增bias支持适配 A4W4 / A8W4 多种量化模式grouped_matmul_swiglu_quant_weight_nz_tensor_list将weight从单一张量改为 tensor list每个专家独立权重张量便于 NZ 格式权重按专家零拷贝装载。七、使用建议与注意事项总结读取输出务必按 groupList 裁剪Q与Q_scale只有[:groupList[-1]]前缀是有效数据尾部保留申请时旧值直接使用会造成脏数据污染后续计算区分空分组groupList允许相邻值相等空分组Kernel 会跳过但调用方生成groupList时仍需保持前缀和形式非严格递增也可以量化模式当前仅对称量化生效非对称量化所需的offset/outputOffset输入输出已预留但未启用bias亦暂未参与计算量化误差与数值行为需按对称量化预估平台差异Kirin X90 / Kirin 9030 上weightScale不可用 BFLOAT16N ≤ 10240、K ≤ 65536 的硬性约束需要在模型层配置前校验性能收益通过单内核融合省去多次中间张量落盘与 Kernel 启动开销量化后的 INT8 GEMM 也能直接利用昇腾 Cube 的 INT8 算力这正是该算子在 vllm-ascend 量化 MoE 推理路径中被选为默认专家计算后端的原因。如需深入内核实现细节可继续阅读 op_kernel 目录 下的grouped_matmul_swiglu_quant_a8w4_msd_pre/mid/post.hA8W4 量化前中后三段 Kernel与grouped_matmul_swiglu_quant_split_ws.h按 WS 切分以及 Host 侧 tiling 实现 的分块策略。赞分享人工智能大模型模型推理服务AscendCANN【免费下载链接】vllm-ascendCommunity maintained hardware plugin for vLLM on Huawei Ascend项目地址https://gitcode.com/gh_mirrors/vl/vllm-ascend点击查看免费下载相关推荐Minecraft区块管理终极指南使用MCA Selector轻松清理和优化世界存档Minecraft区块管理终极指南使用MCA Selector轻松清理和优化世界存档 你是否曾经因为Minecraft世界存档过大而烦恼或者想要删除某些不需人工智能算子库大模型深度学习CANNAscendCANN ops-transformer 算子解析aclnnGroupedMatmulSwigluQuant 分组量化 SwiGLU 融合算子实战指南CANN ops transformer 算子解析aclnnGroupedMatmulSwigluQuant 分组量化 SwiGLU 融合算子实战指南 导读算子库人工智能大模型深度学习CANNAscendCANN ops-transformer 通算融合算子 aclnnAlltoAllQuantMatmulAlltoAll 通信与量化 Matmul 融合原理与实战指南CANN ops transformer 通算融合算子 aclnnAlltoAllQuantMatmulAlltoAll 通信与量化 Matmul 融合原理与算子库人工智能大模型深度学习CANNAscend上一篇Steam成就管理神器终极指南与完整教程下一篇手机号逆向查询QQ号5分钟快速上手完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑