大模型量化技术GPTQ与AWQ原理对比及GPU部署实践
大模型量化技术已成为降低推理成本、提升GPU部署密度的核心手段。GPTQ和AWQ作为当前主流的两种训练后量化方案,在精度保持、计算速度和显存占用方面各有侧重。本文从算法原理出发,对比两种方案的量化策略差异,并给出在NVIDIA GPU上的实际部署配置与性能数据。
训练后量化PTQ的基本原理与精度损失来源
训练后量化(Post-Training Quantization, PTQ)的核心目标是将模型权重从FP16/BF16转换为INT4或INT8表示,同时最小化推理精度下降。量化误差的主要来源有两类:一是权重舍入导致的逐层误差累积,二是异常值权重(outlier)对整体分布的破坏。
FP16权重矩阵W经量化后的重建误差可表示为:
W_hat = dequant(quant(W, scale, zero_point))
error = ||W - W_hat||_F^2
朴素舍入量化(RTN)直接对每个权重取整,在4bit下精度损失显著,7B模型在WikiText2上的困惑度从5.68暴涨至30+,基本不可用。GPTQ和AWQ分别从不同角度解决这一问题。
GPTQ逐层近似与Hessian矩阵量化补偿
GPTQ源自1990年OBQ(Optimal Brain Quantization)算法的工程化改进。其核心思路是逐行对权重矩阵进行量化,每量化一个权重后,利用Hessian矩阵信息调整同行剩余未量化权重,补偿舍入误差。
具体流程:
import torch
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
model_path = "meta-llama/Llama-3-8B"
quant_config = BaseQuantizeConfig(
bits=4,
group_size=128,
desc_act=True,
damp_percent=0.01
)
model = AutoGPTQForCausalLM.from_pretrained(
model_path,
quantize_config=quant_config,
torch_dtype=torch.float16
)
from datasets import load_dataset
from transformers import AutoTokenizer
calib_data = load_dataset("wikitext", "wikitext-2-raw-v1", split="train[:512]")
tokenizer = AutoTokenizer.from_pretrained(model_path)
calib_samples = [tokenizer(x["text"]) for x in calib_data if x["text"].strip()]
model.quantize(calib_samples)
model.save_quantized("llama3-8b-gptq-4bit")
desc_act参数控制是否按Hessian对角线值排序权重列——开启后精度更好但量化速度显著下降(8B模型从3分钟增至25分钟)。实际部署中,对于代码生成等精度敏感任务建议开启,对话类任务可关闭。
GPTQ的group_size参数将每128个权重共享一组缩放系数,group_size越小精度越高但显存占用略增。128是当前最通用的平衡点。
AWQ激活感知权重缩放与通道重要性保护
AWQ(Activation-Aware Weight Quantization)的观察基础是:并非所有权重通道对精度同等重要。激活值中存在少量显著大于均值的通道(activation outlier),这些通道对应的权重对量化误差极度敏感。
AWQ不做逐权重补偿,而是对每条输入通道学习一个缩放因子s,将敏感通道的权重大幅放大后再量化,量化后还原:
# AWQ核心:per-channel缩放因子搜索
# 对通道j,缩放因子s_j使得量化误差最小
# L = ||Q(W * diag(s)) * diag(1/s) X||_2
缩放因子的搜索空间被简化为[0.5, 1.0]区间的离散网格,通过少量校准数据快速确定。AWQ不需要Hessian计算,量化速度远快于GPTQ。
部署示例:
from awq import AutoAWQForCausalLM
model = AutoAWQForCausalLM.from_pretrained("meta-llama/Llama-3-8B")
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3-8B", trust_remote_code=True)
quant_config = {
"zero_point": True,
"q_group_size": 128,
"w_bit": 4,
"version": "GEMM"
}
model.quantize(tokenizer, quant_config=quant_config)
model.save_quantized("llama3-8b-awq-4bit")
GEMM版本使用INT4矩阵乘法核,GEMV版本适用于单batch推理,速度更快但多batch吞吐不及GEMM。
GPU推理部署性能对比与选择策略
在A100 80GB上部署Llama-3-8B的实测数据:
# vLLM部署GPTQ模型
python -m vllm.entrypoints.openai.api_server \
--model llama3-8b-gptq-4bit \
--quantization gptq \
--dtype float16 \
--max-model-len 4096 \
--gpu-memory-utilization 0.9
# vLLM部署AWQ模型
python -m vllm.entrypoints.openai.api_server \
--model llama3-8b-awq-4bit \
--quantization awq \
--dtype float16 \
--max-model-len 4096 \
--gpu-memory-utilization 0.9
关键指标对比(Llama-3-8B, 4bit, A100, batch=1):
– 困惑度(WikiText2):GPTQ 5.82 / AWQ 5.91 / FP16 5.68
– 显存占用:GPTQ 4.8GB / AWQ 4.8GB / FP16 15.2GB
– 首token延迟:GPTQ 28ms / AWQ 22ms
– 生成吞吐(tokens/s):GPTQ 85 / AWQ 92
– 量化耗时:GPTQ 15min / AWQ 3min
选择建议:追求极致精度选GPTQ+desc_act,追求量化速度和推理吞吐选AWQ。两者在vLLM、TensorRT-LLM等推理框架中均已获得一等支持。
混合精度量化与多GPU部署注意事项
实际生产中,对Attention层使用4bit量化、对Embedding和LM Head保留FP16的混合策略能在精度和显存间取得更优平衡。vLLM通过–enforce-eager参数可避免CUDA Graph与量化kernel的冲突。
多GPU部署时,AWQ模型跨卡通信量与FP16一致,无需额外配置;GPTQ模型在pipeline并行中需确保各卡的group_size对齐,否则会出现反量化shape mismatch报错。
量化模型的KV Cache同样需关注。4bit模型推理时KV Cache仍为FP16,在长上下文场景(128K tokens)下KV Cache可能占用10GB以上显存。开启vLLM的–kv-cache-dtype fp8可额外压缩50%的KV Cache显存,代价是约0.3%的精度损失。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/da-mo-xing-liang-hua-ji-shu-gptq-yu-awq-yuan-li-dui-bi-ji/