Prhub

#41566 [Quantization] Rework quantization_config to use QuantKey and allow for activation override

原始 PR 作者 mgoin 合并时间 2026-05-14 04:58 文件变更 16 提交数 7 评论 21 代码增减 +626 / -327

执行摘要

重构在线量化配置,引入 QuantSpec 支持按层类型指定量化方案

提供更灵活的配置方式,允许用户对 linear 和 MoE 分别指定 weight 和 activation 的 QuantKey,不再依赖单一的 OnlineQuantScheme 枚举。支持在已有量化检查点上通过 quantization_config 覆盖激活类型(如 MXFP8),移除对 VLLM_USE_FLASHINFER_MOE_MXFP4_MXFP8 等环境变量的依赖,统一配置入口。

该 PR 是 vLLM 量化配置体系的核心架构变更,值得团队成员细致 review,特别是涉及 QuantSpec 设计模式、activate 覆盖与现有量化协议的交互。建议在合并前确保现有集成测试(特别是 Blackwell MoE 和 gpt-oss)通过。

讨论亮点
  • BowenBao 建议 map_mxfp4_backend 返回列表:建议让供应商返回所有激活变体(如 flashinfer_trtllm -> [BF16, MXFP8]),后续由 is_supported_config 筛选。mgoin 采纳并实现。
  • BowenBao 询问激活覆盖冲突处理:当用户覆盖与模型量化配置的 activation_key 冲突时如何处理。mgoin 实现 _resolve_activation_key,用户覆盖优先,冲突则报错。
  • ProExpertProg 建议迁移测试配置:建议将 gpt-oss MXFP8 测试配置从 tests/compile/fusions_e2e/conftest.py 迁移到 models.py,条件化为 is_blackwell。mgoin 完成调整。
  • BowenBao 建议补充文档:建议在 docs/features/quantization/online.md 中详细描述嵌套字典结构和 CLI 参数。mgoin 已更新文档。
  • juhi10071998 询问 NVFP4 激活覆盖:询问是否支持现有 NVFP4 检查点使用 Marlin 后端并覆盖激活。mgoin 建议使用 --moe-backend marlin,并考虑后续支持。

实现拆解

  1. 定义 QuantSpec 和 QuantizationConfigArgs:在 vllm/config/quantization.py 中新建 QuantSpec 类,包含 weightactivation 字段,使用 QuantKeyField 类型(通过 pydantic 自定义验证器 _coerce_quant_key 将字符串映射到 QUANT_KEY_NAMES 表中。QuantizationConfigArgs 取代旧的 OnlineQuantizationConfigArgs,其 linearmoe 字段为 QuantSpec,并通过 _coerce_spec 验证器支持字符串简写(如 "fp8_per_block")解析为对应的 QuantSpec

  2. 重构在线量化配置类:在 vllm/model_executor/layers/quantization/online/base.py 中,OnlineQuantizationConfig 的构造函数接受 QuantizationConfigArgs,通过 _dispatch 方法根据 QuantSpec.weight_ONLINE_LINEAR_METHODS_ONLINE_MOE_METHODS 分发表中选取对应方法类。当 spec.activation 非 None 时暂时报错(预留未来支持)。

  3. 修改 MXFP4 MoE 后端选择逻辑:在 vllm/model_executor/layers/fused_moe/oracle/mxfp4.py 中,map_mxfp4_backend 返回值改为 list[Mxfp4MoeBackend],供应商类返回所有变体(如 flashinfer_trtllm -> [BF16, MXFP8])。新增 _user_moe_activation_overrideQuantizationConfigArgs 读取用户覆盖,_filter_by_activationQuantKey 过滤候选列表。当用户指定 --quantization-config.moe.activation mxfp8 时,自动匹配 MXFP8 变体。

  4. 更新引擎参数和测试:在 vllm/engine/arg_utils.py 中注册 --quantization-config CLI 参数并替换 resolve_online_quant_configresolve_quantization_config。新增 tests/quantization/test_quantization_config_args.py 覆盖 QuantSpec 解析、简写解构、合并逻辑。更新 tests/quantization/test_blackwell_moe.py 和编译测试配置,将环境变量迁移为 quantization_config 参数。

文件 模块 状态 重要度
vllm/model_executor/layers/fused_moe/oracle/mxfp4.py MXFP4 路由 modified 9.81
vllm/config/quantization.py 量化配置 modified 9.43
vllm/model_executor/layers/quantization/online/base.py 在线量化 modified 8.16
tests/quantization/test_quantization_config_args.py 测试 added 8.11
vllm/engine/arg_utils.py 引擎参数 modified 6.45

关键符号

map_mxfp4_backend _user_moe_activation_override _resolve_activation_key _filter_by_activation _coerce_quant_key _coerce_spec QuantSpec QuantizationConfigArgs resolve_quantization_config _dispatch

关键源码片段

vllm/model_executor/layers/quantization/online/base.py data-contract

调整 OnlineQuantizationConfig 以使用新的 QuantizationConfigArgs,引入 _dispatch 方法进行方法分派。

# 在线量化方法分发表,键为 QuantSpec.weight 的 QuantKey。
# 对应方法类通过其 supported_activation_quant 集合处理激活选择。
_ONLINE_LINEAR_METHODS: dict[QuantKey, type] = {
    kFp8StaticTensorSym: Fp8PerTensorOnlineLinearMethod,
    kFp8Static128BlockSym: Fp8PerBlockOnlineLinearMethod,
    kMxfp8Dynamic: Mxfp8OnlineLinearMethod,
}_ONLINE_MOE_METHODS: dict[QuantKey, type] = {
    kFp8StaticTensorSym: Fp8PerTensorOnlineMoEMethod,
    kFp8Static128BlockSym: Fp8PerBlockOnlineMoEMethod,
    kMxfp8Dynamic: Mxfp8OnlineMoEMethod,
    kInt8StaticChannelSym: Int8OnlineMoEMethod,
}def _dispatch(
    self,
    spec: QuantSpec | None,
    table: dict[QuantKey, type],
    layer: torch.nn.Module,
) -> "QuantizeMethodBase | None":
    if spec is None or spec.weight is None:
        return None
    cls = table.get(spec.weight)
    if cls is None:
        raise ValueError(
            f"online quantization for {type(layer).__name__} with "
            f"weight={spec.weight} is not supported; supported weight "
            f"keys: {sorted(str(k) for k in table)}"
        )
    # 当前方法类内部选择激活格式,显式激活覆盖暂不支持
    if spec.activation is not None:
        raise ValueError(
            f"activation override (activation={spec.activation}) is not "
            f"yet supported for online {cls.__name__}"
        )
    if isinstance(layer, RoutedExperts):
        return cls(layer=layer)
    return cls()

评论区精华

map_mxfp4_backend 返回列表 vs 单个值 设计

BowenBao 建议 map_mxfp4_backend 返回 list[Mxfp4MoeBackend] 以支持同一供应商的多个激活变体,后续由 is_supported_config 筛选。

结论:mgoin 采纳该建议,修改 map_mxfp4_backend 返回列表,flashinfer_trtllm 等映射包含 BF16 和 MXFP8 变体。 · 已解决

用户激活覆盖与模型 activation_key 冲突处理 正确性

BowenBao 询问当用户通过 quantization_config 设置 activation 覆盖时,如何处理与模型量化配置中 activation_key(如 compressed-tensors W4A8)的冲突。

结论:mgoin 实现 _resolve_activation_key:用户覆盖优先,若两者均非 None 且不一致则报错,否则取非 None 值。 · 已解决

将 gpt-oss MXFP8 测试配置从 conftest 迁移到 models.py refactor

ProExpertProg 建议将 fusions_e2e 测试中 gpt-oss 的 MXFP8 环境变量设置迁移到 models.py 中,条件化为 is_blackwell,避免在 conftest 中保留特殊逻辑。

结论:mgoin 同意并完成迁移,在 models.py 中根据 is_blackwell 在 model_kwargs 中设置 quantization_config。 · 已解决

风险与影响

1) 配置向后兼容性:旧的 OnlineQuantizationConfigArgs 字段(global_scheme 等)不再支持,用户需迁移到新格式。
2) 环境变量移除:依赖 VLLM_USE_FLASHINFER_MOE_MXFP4_MXFP8 等 env 的部署脚本会失效。
3) 测试覆盖:新的解析路径可能未覆盖所有边界情况,如 QuantSpecweightactivation 均为 None 时的行为。
4) 跨后端一致性:_dispatch 目前拒绝 activation 显式设置,但后端方法类内部可能已有隐式激活假设,需要逐类验证。

用户层面:所有使用在线量化的用户需要调整 quantization_config 配置,但 CLI 的 --quantization 简写(如 fp8_per_tensor)保持兼容,可平滑过渡。系统层面:新架构为未来添加每层量化策略和激活感知量化奠定了基础。团队层面:重构集中了配置入口,降低添加新量化方案的门槛。

配置格式变更 环境变量移除 向后兼容性 测试覆盖不足

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论