大模型量化部署的核心问题与量化基础
大模型量化部署是将高精度浮点权重压缩到低比特定点数(INT4/INT8)的过程,目标是降低显存占用和推理延迟。量化分为训练后量化(PTQ)和量化感知训练(QAT),工业场景中PTQ因无需训练数据且部署快速而广泛使用。GPTQ和AWQ是当前两种主流的PTQ算法,均支持INT4权重量化,但在计算路径和精度保持策略上存在显著差异。
量化的核心挑战在于:权重从FP16压缩到INT4时,部分敏感权重对模型输出影响极大,直接截断会导致精度骤降。GPTQ通过二阶Hessian信息逐层修正量化误差,AWQ通过激活值感知保护关键权重通道。两者的实现路径不同,适用场景也有区别。
GPTQ算法原理:基于Hessian矩阵的逐层量化误差补偿
GPTQ(Generalized Post-Training Quantization)源自OBQ(Optimal Brain Quantization)方法,核心思路是利用权重矩阵的Hessian逆矩阵来量化每一个权重时补偿前面权重量化引入的误差。具体流程:对每一层权重矩阵W,计算H = X^T * X(X为该层输入),按列逐个量化权重w_i,同时更新剩余权重以补偿量化误差:
import torch
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
# 准备校准数据
calibration_data = load_calibration_dataset(128)
quantize_config = BaseQuantizeConfig(
bits=4, # 量化到4bit
group_size=128, # 分组量化,每组128个权重
desc_act=False # 是否按激活降序排列
)
model = AutoGPTQForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
quantize_config
)
# 执行量化
model.quantize(calibration_data, batch_size=4)
# 保存量化后的模型
model.save_quantized("./llama-7b-gptq-4bit")
GPTQ按列处理权重,量化第i列时,利用Hessian矩阵的逆将量化误差分摊到后续列。group_size参数控制量化粒度,128是常用值,较小组组能提高精度但增加计算量。desc_act=True会按激活值大小降序排列列,让敏感列优先处理,但会增加量化时间。
AWQ算法原理:激活感知权重重要性评估
AWQ(Activation-aware Weight Quantization)的出发点是:并非所有权重同等重要,与大幅激活值相乘的权重对输出影响更大。AWQ不依赖反向传播或Hessian计算,而是通过分析校准数据的激活分布识别重要权重通道,对这些通道使用更精确的量化缩放因子。
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
model_path = "meta-llama/Llama-2-7b-hf"
quant_path = "./llama-7b-awq-4bit"
quant_config = {
"zero_point": True,
"q_group_size": 128,
"w_bit": 4,
"version": "GEMM"
}
model = AutoAWQForCausalLM.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path)
# 使用校准数据搜索最优缩放因子
model.quantize(tokenizer, quant_config=quant_config)
model.save_quantized(quant_path)
AWQ的关键创新是缩放因子搜索:对每个权重通道,引入一个标量s来调整权重量化范围和对应激活值的反缩放。搜索过程在校准数据上最小化量化前后输出的KL散度。AWQ全程保持FP16计算路径,仅对权重存储使用INT4,推理时通过反量化恢复。
GPTQ与AWQ精度与性能对比
两种算法在Llama-2-7B模型上的INT4量化效果对比:
| 指标 | GPTQ-INT4 | AWQ-INT4 | FP16基线 |
|---|---|---|---|
| 显存占用(GB) | 4.1 | 4.0 | 13.5 |
| WikiText2 PPL | 6.09 | 6.06 | 5.92 |
| MMLU(%) | 43.1 | 43.2 | 45.3 |
| 推理速度(tokens/s) | 85 | 92 | 78 |
精度方面,AWQ在PPL和MMLU上略优于GPTQ,差距在0.5%以内。推理速度上,AWQ的GEMM实现经过深度优化(尤其在CUDA核心上),通常比GPTQ快10%-15%。显存占用两者接近,均压缩到FP16的约30%。
部署选型建议与VLLM推理加速
选择GPTQ还是AWQ取决于具体场景:
- 需要最快推理速度的在线服务场景优先选AWQ,其GEMM kernel在CUDA上表现更优
- 需要与ExLlamaV2等推理框架配合时选GPTQ,兼容性更广
- 对精度极度敏感且推理负载不高的场景,两者均可,AWQ略优
使用VLLM加载量化模型进行推理加速:
from vllm import LLM, SamplingParams
# 加载AWQ量化模型
llm = LLM(
model="./llama-7b-awq-4bit",
quantization="awq",
tensor_parallel_size=1,
gpu_memory_utilization=0.85
)
# 加载GPTQ量化模型
# llm = LLM(model="./llama-7b-gptq-4bit", quantization="gptq")
sampling = SamplingParams(temperature=0.7, max_tokens=512)
outputs = llm.generate(["解释量化压缩的原理"], sampling)
print(outputs[0].outputs[0].text)
VLLM的PagedAttention机制与量化权重兼容,配合AWQ模型可实现比原始FP16推理更快的生成速度,同时将显存占用降至1/3以下。在A100 80G GPU上,7B模型的AWQ-INT4推理吞吐量可达FP16的1.8倍。
量化过程中的常见问题排查
精度下降过快时检查校准数据量:GPTQ建议128-512条,AWQ建议128条。校准数据应覆盖目标任务的典型输入分布,文本长度不宜过短。group_size设置过小(如32)会提高精度但增加推理开销,128是平衡点。
量化后推理速度未提升时,确认CUDA kernel正确加载。AWQ需要安装autoawq的CUDA扩展,GPTQ需要auto_gptq的CUDA扩展,两者不支持纯CPU量化推理加速。通过nvidia-smi监控GPU利用率,若低于60%说明kernel未正确加载。
显存仍超限时,尝试将group_size从128调至256或64。配合VLLM的gpu_memory_utilization参数动态调整KV Cache预分配比例。对于13B以上模型,INT4量化搭配张量并行是可行的落地方案。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/da-mo-xing-liang-hua-bu-shu-shi-zhan-gptq-yu-awq-ya-suo/