vLLM 量化实战指南:量化格式全景、硬件兼容矩阵与自定义量化插件扩展机制
本篇指南基于 vLLM 官方量化文档(docs/features/quantization/README.md),系统讲解 vLLM 支持的量化格式清单、各量化实现与 GPU/CPU 硬件平台的兼容性矩阵,以及通过 @register_quantization_config 注册 Out-of-Tree 自定义量化插件的完整机制。读完本文,你将能够:为部署场景选择正确的量化方法名、判断目标硬件是否支持该量化实现、并在不修改 vLLM 代码库的前提下接入自己的量化方案。
量化在 vLLM 中的定位
量化(Quantization)用模型精度的下降换取更小的显存占用,使大模型能够在更广泛的设备上运行。在 vLLM 中,量化能力集中在 vllm/model_executor/layers/quantization 目录下实现,每个量化格式对应一个 QuantizationConfig 子类,引擎启动时根据模型检查点中的量化配置或用户传入的 --quantization 参数选择对应实现。
官方推荐从 LLM Compressor 入手:它是 vLLM 生态中用于“为部署到 vLLM 而优化模型”的量化库,支持 FP8、INT8、INT4 等多种格式,相关文档见 LLM Compressor 入门。
vLLM 支持的量化格式清单
vLLM 当前支持的量化格式(对应各格式的专项文档):
- AutoAWQ
- BitsAndBytes
- GPTQModel
- Intel Neural Compressor
- LLM Compressor
- NVIDIA Model Optimizer
- Online Quantization
- AMD Quark
- Quantized KV Cache
- TorchAO
- FP8 ViT Encoder Attention
硬件平台兼容性矩阵
不同量化实现依赖特定的自定义 CUDA/CPU 内核,因此其与硬件平台存在明确的兼容关系。下表列出各量化实现在不同硬件上的支持情况(“是”表示支持,“否”表示不支持):
| 量化实现 | Volta | Turing | Ampere | Ada | Hopper | AMD GPU | Intel GPU | x86 CPU | Arm CPU |
|---|---|---|---|---|---|---|---|---|---|
| AWQ | 否 | 是 | 是 | 是 | 是 | 否 | 是 | 是 | 否 |
| GPTQ | 是 | 是 | 是 | 是 | 是 | 否 | 是 | 是 | 否 |
| Marlin (GPTQ/AWQ/FP8/FP4) | 否 | 是* | 是 | 是 | 是 | 否 | 否 | 否 | 否 |
| llm-compressor INT8 (W8A8) | 否 | 是 | 是 | 是 | 是 | 否 | 否 | 是 | 是 |
| llm-compressor INT8 (W4A8) | 否 | 否 | 否 | 否 | 否 | 否 | 否 | 否 | 是 |
| llm-compressor FP8 (W8A8) | 否 | 否 | 否 | 是 | 是 | 是 | 否 | 否 | 否 |
| bitsandbytes | 是 | 是 | 是 | 是 | 是 | 否 | 否 | 否 | 否 |
| DeepSpeedFP | 是 | 是 | 是 | 是 | 是 | 否 | 否 | 否 | 否 |
| GGUF | 是 | 是 | 是 | 是 | 是 | 是 | 否 | 否 | 否 |
矩阵中的术语与限制说明:
- 硬件代际对应 CUDA Compute Capability:Volta 为 SM 7.0,Turing 为 SM 7.5,Ampere 为 SM 8.0/8.6,Ada 为 SM 8.9,Hopper 为 SM 9.0。
- Marlin 一行中的星号(*)表示 Turing 不支持 Marlin 的 MXFP4 格式。
- Intel Gaudi 上的全部量化支持已迁移至独立的 vLLM-Gaudi 项目,vLLM 主仓库不再覆盖。
- Google TPU 上的量化支持情况,需查阅 TPU-Inference 官方文档的推荐模型与功能列表。
需要注意:该兼容性表会随 vLLM 持续演进而变化。要获取最新、最权威的硬件支持信息,应直接参考源码目录 vllm/model_executor/layers/quantization,其中的 get_min_capability() 实现即为每个量化方法对 GPU 算力等级的硬性门槛。
Out-of-Tree 量化插件:注册机制解析
vLLM 支持在不修改主代码库的前提下注册自定义(Out-of-Tree)量化方法,入口是 @register_quantization_config 装饰器。从源码看,这一机制的落点在 vllm/model_executor/layers/quantization/init.py:
- 装饰器把自定义配置类写入模块级字典
_CUSTOMIZED_METHOD_TO_QUANT_CONFIG,并将其名称追加到QUANTIZATION_METHODS列表; - 若当前平台维护了
supported_quantization白名单,会同时把新名称加入,使平台校验自动放行; - 引擎侧 get_quantization_config() 在查表时,先用内置的
method_to_config映射解析(覆盖awq、fp8、gptq_marlin、compressed-tensors、modelopt、torchao、quark、online等),随后执行method_to_config.update(_CUSTOMIZED_METHOD_TO_QUANT_CONFIG)合并自定义注册项——因此自定义方法天然被同一条解析路径覆盖。
值得注意的两点实现细节:
- 若注册的名称与内置方法重名,只会输出 debug 日志并直接覆盖,不会报错;
QuantizationMethods是一个Literal类型(init.py 第 15-49 行),其中既包含检查点方法(如fp8、awq_marlin),也包含在线量化的简写名(如fp8_per_tensor、int8_per_channel_weight_only、nvfp4_per_token),二者共用同一个--quantization参数入口。
注册自定义量化方法
注册步骤:创建一个继承自 QuantizationConfig 的类,并用 @register_quantization_config 装饰。get_quant_method 按层类型把调度分发到具体的量化方法。完整示例(继承自官方文档):
import torch
from vllm.model_executor.layers.quantization import (
register_quantization_config,
)
from vllm.model_executor.layers.quantization.base_config import (
QuantizationConfig,
QuantizeMethodBase,
)
from vllm.model_executor.layers.linear import LinearBase
from vllm.model_executor.layers.fused_moe import FusedMoE
@register_quantization_config("my_quant")
class MyQuantConfig(QuantizationConfig):
"""Custom quantization config."""
def get_name(self) -> str:
return "my_quant"
def get_supported_act_dtypes(self) -> list:
return [torch.float16, torch.bfloat16]
@classmethod
def get_min_capability(cls) -> int:
# Minimum GPU compute capability, -1 for no restriction
return -1
@staticmethod
def get_config_filenames() -> list[str]:
# Config files to search for in model directory
return []
@classmethod
def from_config(cls, config: dict) -> "MyQuantConfig":
# Create config from model's quantization config
return cls()
def get_quant_method(
self, layer: torch.nn.Module, prefix: str
) -> QuantizeMethodBase | None:
# Dispatch based on layer type
# NOTE: you only need to implement methods you care about
if isinstance(layer, LinearBase):
return MyQuantLinearMethod()
elif isinstance(layer, FusedMoE):
return MyQuantMoEMethod(layer.moe_config)
return None
必须实现的 QuantizationConfig 抽象方法
QuantizationConfig 基类定义在 vllm/model_executor/layers/quantization/base_config.py,自定义子类必须实现以下抽象方法:
| 方法 | 说明 |
|---|---|
get_name() |
返回量化方法名称 |
get_supported_act_dtypes() |
返回支持的激活 dtype 列表(如 torch.float16) |
get_min_capability() |
返回最低 GPU 算力等级(如 Ampere 为 80,无限制则返回 -1) |
get_config_filenames() |
返回在模型目录中需要搜索的配置文件名列表 |
from_config(config) |
类方法,从模型量化配置字典创建配置对象 |
get_quant_method(layer, prefix) |
给定层返回对应量化方法;返回 None 表示跳过该层 |
其中 get_quant_method(layer, prefix) 的第二个参数 prefix 是该层在 state dict 中的完整名称,可实现按层名前缀做选择性量化(例如只对 mlp 相关前缀启用)。基类还提供了两个便捷工具:get_from_keys / get_from_keys_or,用于从量化配置字典中按候选键名取值,键名缺失时抛错或回退默认值。
实现量化 Linear 方法
对于线性层,get_quant_method 返回 QuantizeMethodBase 的子类。可以以 UnquantizedLinearMethod(linear.py 中定义)为起点继承扩展:
from vllm.model_executor.layers.linear import UnquantizedLinearMethod
class MyQuantLinearMethod(UnquantizedLinearMethod):
"""Custom quantization method for linear layers."""
def create_weights(
self, layer: torch.nn.Module, *weight_args, **extra_weight_attrs
):
# Create quantized weights for the layer
...
def apply(
self,
layer: torch.nn.Module,
x: torch.Tensor,
bias: torch.Tensor | None = None,
) -> torch.Tensor:
# Apply custom quantization logic here
...
从源码结构看,QuantizeMethodBase(base_config.py 第 23-82 行)的完整生命周期接口不止 create_weights 和 apply 两个抽象方法,还包括若干可选钩子:
process_weights_after_loading(layer):权重加载完成后的后处理点,典型用途是转置、重打包权重以匹配内核布局;embedding(layer, *args):仅当子类真正覆写了该函数时(由method_has_implemented_embedding检查是否与基类实现不同)才会被调用,用于量化嵌入查表;tie_weights(layer, embed_tokens):处理词嵌入与 LM Head 的权重共享(tied weights),需要特殊权重布局的量化方法需覆写;- 类属性
uses_meta_device:标记该方法在在线量化时是否在 meta 设备上建权重、逐层量化以降低加载峰值显存; - 类属性
supports_pre_processed_weights:声明process_weights_after_loading是否支持幂等重入。
实现量化 MoE 方法
对于混合专家(MoE)模型,get_quant_method 应返回 FusedMoEMethodBase(fused_moe_method_base.py 第 28 行起)的子类;若不需要量化 MoE,可退回到 UnquantizedFusedMoEMethod(unquantized_fused_moe_method.py 第 45 行):
from vllm.model_executor.layers.fused_moe.layer import UnquantizedFusedMoEMethod
from vllm.model_executor.layers.fused_moe.fused_moe_method_base import (
FusedMoEMethodBase,
)
from vllm.model_executor.layers.fused_moe.config import FusedMoEQuantConfig
class MyQuantMoEMethod(FusedMoEMethodBase):
"""Custom quantization method for MoE layers."""
def create_weights(
self,
layer: torch.nn.Module,
num_experts: int,
hidden_size: int,
intermediate_size_per_partition: int,
params_dtype: torch.dtype,
**extra_weight_attrs,
):
# Create quantized weights for the MoE layer
...
def apply(
self,
layer: torch.nn.Module,
router: "FusedMoERouter",
x: torch.Tensor,
router_logits: torch.Tensor,
) -> torch.Tensor:
# Apply MoE computation with quantized weights
...
def get_fused_moe_quant_config(
self, layer: torch.nn.Module
) -> FusedMoEQuantConfig | None:
# Return the MoE quantization configuration
...
其中 FusedMoEQuantConfig 定义在 fused_moe/config.py 第 214 行。编写参考实现时,官方文档建议直接阅读 Fp8MoEMethod——它位于 vllm/model_executor/layers/quantization/fp8.py 第 481 行,展示了 MoE 层创建量化权重、绑定 MoE 内核配置的标准写法;同文件第 216 行附近可见 Fp8Config.get_quant_method 向 Fp8MoEMethod(self, layer) 的调度方式。
使用插件
注册完成后即可像内置方法一样通过 quantization 参数启用自定义量化:
# Register your quantization method (import the module containing your config)
import my_quant_plugin
from vllm import LLM
# Use the custom quantization method
llm = LLM(model="your-model", quantization="my_quant")
关键点:自定义插件模块必须在构造 LLM 之前被 import,确保装饰器完成注册;插件体系的整体设计(含加载时机与扩展点)可参阅 Plugin System 设计文档。
量化方法的最终解析路径:resolve_quant_method
从源码结构看,模型初始化时每个被量化的层会经由 resolve_quant_method() 得到最终的量化方法。该函数的行为体现了“检查点量化优先、在线量化兜底”的原则:
- 先调用
quant_config.get_quant_method(layer, prefix)取得检查点声明的方法; - 若未配置在线量化(
online_quantization_config is None),直接返回检查点方法; - 在线量化目前仅接管
LinearBase与RoutedExperts两类层,Embedding 与 LM Head 保留检查点方法; - 若层已在检查点中被量化,再请求在线量化会直接抛出
ValueError,防止对已量化权重重复量化。
这条路径解释了为什么自定义插件只需覆写 get_quant_method 的层类型分发:无论是否叠加在线量化,自定义方法都在这一步被统一解析。
小结与延伸阅读
- 选格式:按 支持的量化格式清单 与目标模型的检查点格式匹配(检查点中的
quant_method字段会被对应QuantizationConfig的get_config_filenames/from_config解析); - 查硬件:以本文硬件兼容矩阵初筛,最终以 vllm/model_executor/layers/quantization 中各配置的
get_min_capability与平台白名单为准; - 做扩展:按“注册 Config → 实现 Linear/MoE Method →
LLM(quantization=...)启用”三步接入 Out-of-Tree 插件; - 深入阅读:Plugin System 设计、在线量化、量化 KV Cache 与 LLM Compressor FP8 等专项文档。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0625
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00