Skip to content

AWQ 与 GPTQ 量化方法对比

AWQ 和 GPTQ 是当前最主流的 LLM 训练后量化方法,两者都支持 INT4 量化但在算法原理和性能特征上有显著差异。本文深入对比两种方法的原理、效果和适用场景。

AWQ与GPTQ量化对比

GPTQ 原理

GPTQ 基于 Optimal Brain Surgeon(OBS)框架,逐层量化权重并最小化量化误差:

  1. 按行依次量化每个权重
  2. 利用 Hessian 矩阵计算量化误差
  3. 通过剩余权重的调整来补偿量化误差
python
# GPTQ 量化核心逻辑
def gptq_quantize_layer(weight, hessian, bits=4, group_size=128):
    """GPTQ 逐行量化"""
    quantized = torch.zeros_like(weight)
    errors = torch.zeros_like(weight)

    for i in range(weight.shape[0]):
        # 量化当前行
        w = weight[i]
        q = quantize_to_int(w, bits, group_size)
        quantized[i] = q

        # 计算量化误差
        err = (w - dequantize(q)) / torch.diag(hessian)[i]
        errors[i] = err

        # 补偿到后续权重
        weight[i+1:] -= err.unsqueeze(1) * hessian[i, i+1:].unsqueeze(0)

    return quantized

AWQ 原理

AWQ(Activation-Aware Weight Quantization)的核心观察是:并非所有权重同等重要,与激活值交互大的权重(salient weights)对精度影响更大:

  1. 分析激活值识别 salient 权重
  2. 对 salient 权重应用缩放因子降低量化误差
  3. 搜索最优缩放因子
python
# AWQ 核心逻辑
def awq_quantize(weight, activations, bits=4, group_size=128):
    """AWQ 激活感知量化"""
    # 1. 识别 salient 权重
    importance = activations.abs().max(dim=0).values  # 逐通道重要性
    salient_mask = importance > importance.median()

    # 2. 搜索最优缩放因子
    best_scale = search_optimal_scale(
        weight, activations, salient_mask, bits, group_size
    )

    # 3. 应用缩放后量化
    scaled_weight = weight * best_scale.unsqueeze(0)
    quantized = quantize_to_int(scaled_weight, bits, group_size)

    return quantized, best_scale

关键差异对比

维度GPTQAWQ
核心思想Hessian 补偿激活感知缩放
校准数据需求128+ 样本128+ 样本
量化速度较慢(Hessian 计算)较快(仅前向传播)
推理速度与 AWQ 相当与 GPTQ 相当
精度(INT4)略好
FP16 残差不需要不需要
实现复杂度

选择建议

  • 追求最高精度:AWQ(激活感知通常带来更好的量化质量)
  • 已有 GPTQ 工作流:继续使用 GPTQ
  • 需要快速量化:AWQ 速度更快
  • 多模态模型:AWQ 对视觉编码器更友好

实际性能测试

在 Llama-2-7B 上的 MMLU 评测:

量化方案MMLUHumanEval显存占用
FP1645.312.813.5GB
GPTQ-INT4 (g128)43.811.53.9GB
AWQ-INT4 (g128)44.112.03.9GB
GPTQ-INT4 (g32)44.512.24.2GB
AWQ-INT4 (g32)44.812.54.2GB

注意

具体精度差异取决于模型和校准数据。AWQ 在某些任务上优于 GPTQ,但在其他任务上可能持平。建议针对目标应用做 A/B 测试。

相关资源

最近更新