量化适配指南#

本文档为适配与 ModelSlim 相关的量化算法和模型提供指导。

量化特性介绍#

量化推理流程#

vLLM Ascend 中注册和获取量化方法的当前流程如下:

get_quant_method

vLLM Ascend 注册了自定义的 Ascend 量化方法。通过配置 --quantization ascend 参数(离线模式使用 quantization="ascend")来启用量化特性。在构建 quant_config 时,会初始化已注册的 AscendModelSlimConfig,并调用 get_quant_method 来获取每个权重部分对应的量化方法,存储在 quant_method 属性中。

当前支持的量化方法包括 AscendLinearMethodAscendFusedMoEMethodAscendEmbeddingMethod 及其对应的非量化方法:

quant_methods_overview

vLLM 定义的量化方法基类以及量化方法的整体调用流程如下:

quant_method_call_flow

量化通常不实现 embedding 方法,只关注其他三种方法。

create_weights 方法用于权重初始化;process_weights_after_loading 方法用于权重的后处理,例如转置、格式转换、数据类型转换等;apply 方法用于在前向过程中执行激活量化和量化矩阵乘法计算。

我们需要针对不同的attentionmlpMoE (Mixture of Experts))实现 create_weightsprocess_weights_after_loadingapply 方法。

补充:加载模型时,需要读取量化模型的描述文件 quant_model_description.json。该文件描述了模型权重各部分的量化配置和参数,例如:

{
    "model.layers.0.linear_attn.dt_bias": "FLOAT",
    "model.layers.0.linear_attn.A_log": "FLOAT",
    "model.layers.0.linear_attn.conv1d.weight": "FLOAT",
    "model.layers.0.linear_attn.in_proj_qkvz.weight": "W8A8_DYNAMIC",
    "model.layers.0.linear_attn.in_proj_qkvz.weight_scale": "W8A8_DYNAMIC",
    "model.layers.0.linear_attn.in_proj_qkvz.weight_offset": "W8A8_DYNAMIC",
    "model.layers.0.linear_attn.in_proj_ba.weight": "FLOAT",
    "model.layers.0.linear_attn.norm.weight": "FLOAT",
    "model.layers.0.linear_attn.out_proj.weight": "FLOAT",
    "model.layers.0.mlp.gate.weight": "FLOAT",
    "model.layers.0.mlp.experts.0.gate_proj.weight": "W8A8_DYNAMIC",
    "model.layers.0.mlp.experts.0.gate_proj.weight_scale": "W8A8_DYNAMIC",
    "model.layers.0.mlp.experts.0.gate_proj.weight_offset": "W8A8_DYNAMIC"
}

基于以上内容,我们简要介绍量化算法和量化模型的适配流程。

量化算法适配#

  • 步骤 1:算法设计。定义算法 ID(例如 W4A8_DYNAMIC),确定支持的层(linear、moe、attention),并设计量化方案(静态/动态、per-tensor/per-channel/per-group)。

  • 步骤 2:注册。在 vllm_ascend/quantization/methods/registry.py 中使用 @register_scheme 装饰器注册量化方案类。

from vllm_ascend.quantization.methods import register_scheme, AscendLinearScheme, AscendMoEScheme

@register_scheme("W4A8_DYNAMIC", "linear")
class AscendW4A8DynamicLinearMethod(AscendLinearScheme):
    ...

@register_scheme("W4A8_DYNAMIC", "moe")
class AscendW4A8DynamicFusedMoEMethod(AscendMoEScheme):
    ...
  • 步骤 3:实现。创建算法实现文件,例如 vllm_ascend/quantization/methods/w4a8.py,并实现方法类和逻辑。

  • 步骤 4:测试。使用算法生成量化配置,并在目标模型和硬件上验证正确性和性能。

量化模型适配#

适配新的量化模型需要确保以下三点:

  • 原始模型已在 vLLM Ascend 中成功适配。

  • 融合模块映射:将模型的 model_type 添加到 vllm_ascend/quantization/modelslim_config.py 中的 packed_modules_model_mapping(例如 qkv_projgate_up_projexperts),以确保分片一致性和正确加载。

packed_modules_model_mapping = {
    "qwen3_moe": {
        "qkv_proj": [
            "q_proj",
            "k_proj",
            "v_proj",
        ],
        "gate_up_proj": [
            "gate_proj",
            "up_proj",
        ],
        "experts":
        ["experts.0.gate_proj", "experts.0.up_proj", "experts.0.down_proj"],
    },
}
  • 量化模型使用的所有量化算法都已集成到 quantization 模块中。

当前支持的量化算法#

vLLM Ascend 支持多种量化算法。下表基于 vllm_ascend.quantization 模块中的实现,概述了每种量化算法:

算法

权重

激活值

权重量化粒度

激活值量化粒度

类型

描述

W4A16

INT4

FP16/BF16

Per-Group

Per-Tensor

静态

4-bit 权重量化配合 16-bit 激活值精度,专为 MoE 模型专家层设计,支持 int32 格式的权重打包

W8A16

INT8

FP16/BF16

Per-Channel

Per-Tensor

静态

8-bit 权重量化配合 16-bit 激活值精度,平衡精度和性能,适用于线性层

W8A8

INT8

INT8

Per-Channel

Per-Tensor

静态

静态激活值量化,适用于需要高精度的场景

W8A8_DYNAMIC

INT8

INT8

Per-Channel

Per-Token

动态

动态激活值量化,按 token 计算缩放因子

W4A8_DYNAMIC

INT4

INT8

Per-Group

Per-Token

动态

支持直接 per-channel 量化为 4-bit,也支持两步量化(per-channel 到 8-bit,然后 per-group 到 4-bit)

W4A4_FLATQUANT_DYNAMIC

INT4

INT4

Per-Channel

Per-Token

动态

在 4-bit 动态量化之前使用 FlatQuant 进行激活值分布平滑,并通过额外的矩阵乘法来保持精度

W8A8_MIX

INT8

INT8

Per-Channel

Per-Tensor/Token

混合

我们支持两种部署模式:PD 共置(P 和 D 均使用动态量化)和 PD 分离(P 使用动态量化,D 使用静态量化)

静态 vs 动态: 静态量化使用预计算的缩放因子,性能更好;动态量化为每个 token/激活张量实时计算缩放因子,精度更高。

粒度: 指缩放因子计算的范围(例如 per-tensor、per-channel、per-group)。