大模型量化技术是降低AI模型部署硬件门槛的核心手段。通过将FP16权重压缩到INT4或INT8位宽,70亿参数模型的显存占用可从14GB降至4GB以下,在消费级GPU上完成推理。当前主流的量化算法分为训练后量化(PTQ)和量化感知训练(QAT)两类,GPTQ和AWQ均属于训练后量化方案,无需重新训练模型即可完成压缩。
大模型量化的核心原理与位宽选择
量化的本质是将浮点数映射到低位整数空间。INT4量化将每个权重表示为4位整数,取值范围-8到7,配合一个缩放因子(scale)和零点(zero_point)完成反量化。对于大模型,权重张量的分布通常呈现近高斯分布,少数极端值会导致整体量化误差增大。分组量化(per-group)比逐张量量化(per-tensor)的精度损失更小,常见的分组大小为128。
位宽选择直接影响量化精度和压缩比。INT8量化对模型精度的影响通常小于1%,但只能压缩2倍;INT4量化可压缩4倍,但需要更精细的算法来补偿精度损失。GPTQ和AWQ都针对INT4场景做了专门优化。
GPTQ量化算法实现:基于Hessian矩阵的二阶压缩
GPTQ(Generalized Post-Training Quantization)由Frantar等人提出,核心思想是利用Hessian矩阵的逆信息,逐列量化权重并补偿误差。算法流程为:首先用校准数据集计算每层权重的Hessian矩阵,然后按列遍历权重矩阵,将每列量化到目标位宽后,将量化误差通过Hessian逆矩阵分配到剩余未量化的列上。
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
from transformers import AutoTokenizer
model_path = "meta-llama/Llama-2-7b-hf"
quant_path = "./llama-2-7b-gptq-4bit"
quant_config = BaseQuantizeConfig(
bits=4,
group_size=128,
desc_act=False
)
tokenizer = AutoTokenizer.from_pretrained(model_path)
examples = [tokenizer("大模型部署中的量化技术") for _ in range(128)]
model = AutoGPTQForCausalLM.from_pretrained(
model_path,
quantize_config=quant_config
)
model.quantize(examples)
model.save_quantized(quant_path)
GPTQ的量化过程需要一组校准数据,通常使用128-512条通用文本。校准数据的质量直接影响最终精度。quantize_config中的group_size设为128是经验最优值,设为-1则为逐列量化,精度下降明显。desc_act参数控制是否按激活值大小排序列量化顺序,设为True可进一步降低误差但增加时间。
AWQ量化算法实现:激活感知的权重缩放
AWQ(Activation-aware Weight Quantization)由MIT HAN Lab提出,核心发现是:并非所有权重对量化精度的影响相同,与较大激活值对应的权重更为关键。AWQ通过搜索最优的缩放因子,将”重要”权重的量化误差降到最低,而不需要任何反向传播。
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
model_path = "meta-llama/Llama-2-7b-hf"
quant_path = "./llama-2-7b-awq-4bit"
model = AutoAWQForCausalLM.from_pretrained(
model_path, device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_path)
quant_config = {
"zero_point": True,
"q_group_size": 128,
"w_bit": 4,
"version": "GEMM"
}
model.quantize(
tokenizer,
quant_config=quant_config,
calib_data="pile"
)
model.save_quantized(quant_path)
AWQ的quantize过程不需要计算Hessian矩阵,因此速度比GPTQ快2-3倍。calib_data参数指定校准数据集来源,pile是默认选项包含通用英文文本。version参数选择GEMM(矩阵乘法)或GEMV(矩阵向量乘法),GEMM适用于批量推理,GEMV适用于逐token生成。
GPTQ与AWQ量化精度对比测试
以Llama-2-7B在WikiText-2数据集上的困惑度(PPL)为指标,对比GPTQ和AWQ的量化效果:
# 精度对比数据
# 模型 方法 PPL(降低)
# Llama-2-7B FP16(基线) 5.47
# Llama-2-7B GPTQ-INT4 5.63 (+2.9%)
# Llama-2-7B AWQ-INT4 5.58 (+2.0%)
# Llama-2-7B RTN-INT4 6.32 (+15.5%)
import torch
from awq.utils.lm_eval import run_eval
results = run_eval(
model_path="./llama-2-7b-awq-4bit",
tasks=["wikitext"],
batch_size=1
)
print(f"AWQ-INT4 PPL: {results['wikitext']['ppl']:.2f}")
RTN(Round-to-Nearest)是最朴素的量化方法,直接四舍五入,精度损失最大。GPTQ和AWQ都能将INT4量化的精度损失控制在3%以内,AWQ在多数基准测试中略优于GPTQ。随着模型规模增大到13B以上,两者的差距进一步缩小。
量化模型推理部署:vLLM与llama.cpp加载方案
量化后的模型可通过多种推理框架加载部署。vLLM原生支持AWQ量化模型的加载,适合高并发服务场景;llama.cpp支持GGUF格式的量化模型,适合边缘设备和CPU推理。
# vLLM加载AWQ量化模型(GPU推理)
from vllm import LLM, SamplingParams
llm = LLM(
model="./llama-2-7b-awq-4bit",
quantization="awq",
dtype="float16",
gpu_memory_utilization=0.9
)
sampling = SamplingParams(temperature=0.7, max_tokens=512)
outputs = llm.generate(["大模型量化的优势有哪些?"], sampling)
# GGUF格式转换(llama.cpp推理)
# python convert_hf_to_gguf.py ./llama-2-7b \
# --outfile llama-2-7b-q4_k_m.gguf --outtype q4_k_m
实际部署中,AWQ量化模型在vLLM上的推理吞吐量约为FP16模型的1.5-2倍,显存占用减少60%以上。如果目标硬件为CPU或低端GPU,将模型转换为GGUF格式并使用Q4_K_M量化级别,可在保持精度的同时获得更大的性能提升。选择GPTQ还是AWQ,取决于具体场景:追求极致精度选AWQ,已有GPTQ工作流或需要更灵活的量化配置则选GPTQ。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/da-mo-xing-liang-hua-bu-shu-shi-zhan-gptq-yu-awq-suan-fa/