量化是当前部署大模型最常用的压缩手段之一。相比FP16,INT8量化理论上可以将显存占用减半,INT4更是能压缩到原来的四分之一,这对在消费级显卡甚至边缘设备上跑大模型来说几乎是必需的。但代价也很明显:模型权重从16位浮点被压到4位整数,信息损失不可避免。对于普通对话任务,这种损失可能 barely 可感知;可对于需要多步逻辑链条的推理任务(数学解题、代码生成、复杂指令跟随),哪怕一步出错,整条推理链就断了。本文将系统评估INT8和INT4量化对推理能力的影响,并给出一套可复现的评估方法。

一、量化为什么会损失精度:从舍入误差说起
量化的本质是用更少的比特表示原来的浮点数。以线性量化为例,权重w会被映射为整数q:q = round(w / scale) + zero_point。反量化时再用 q * scale - zero_point 近似还原原值。这个round操作就是一切误差的来源——每一个权重都会产生最多半个量化步长的偏差。
听起来单点误差很小,但问题在于误差会累积。一个7B模型有70亿个权重,一次前向传播中矩阵乘法的输入是成千上万个权重的加权和。如果每个权重平均偏离0.5%的相对幅度,经过多层传播后,激活值的分布可能整体偏移。对于生成式任务,这种偏移表现为 logits 排序的细微变化,最终可能让模型在第k个推理步骤选择了一个概率略低但逻辑错误的路径。
量化还分对称和非对称两种模式。对称量化假设权重分布以0为中心,只保留一个scale参数;非对称量化额外引入zero_point,能更好地拟合偏态分布。对于LLM中常见的离群值问题(部分通道的激活值远大于其他通道),简单的逐层量化往往表现很差,这也是为什么后来的方法引入了逐通道量化、平滑变换等技巧。
二、主流量化方法对推理能力的差异化影响
不是所有量化方法造成的损失都一样。朴素RTN(Round-To-Nearest)量化在INT8下通常还可以接受,但直接降到INT4时,模型能力往往断崖式下跌,尤其是数学和代码类任务。原因是RTN对所有权重一视同仁,而推理能力高度依赖少数关键权重通道。
GPTQ通过逐层最小化重建误差来调整量化后的权重,它把量化问题转化为一个求解过程,利用海森矩阵信息补偿舍入误差,使得INT4下的整体困惑度损失大幅降低。AWQ则走了另一条路:它观察到约1%的显著权重通道对精度影响巨大,通过激活分布感知的缩放保护这些通道,无需重新训练。以下是使用AWQ进行INT4量化的典型代码:
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
model_path = "Qwen/Qwen2.5-7B-Instruct"
output_path = "./qwen2.5-7b-awq-int4"
# 加载模型和分词器
model = AutoAWQForCausalLM.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path)
# 量化配置:逐组量化,group_size越小精度越高但权重体积略增
quant_config = {
"zero_point": True,
"q_group_size": 128,
"w_bit": 4,
"version": "GEMM"
}
model.quantize(tokenizer, quant_config=quant_config)
model.save_quantized(output_path)
tokenizer.save_pretrained(output_path)从实践反馈看,GPTQ和AWQ在INT4下都能将MMLU这类知识型基准的损失控制在1到2个百分点以内,但在需要长链推理的GSM8K、MATH上,损失通常会放大到3到8个百分点,且随着题目难度上升,差距进一步拉大。这说明了量化对推理能力的伤害是非线性的:知识记忆相对鲁棒,多步推理对噪声敏感得多。
三、如何科学评估量化前后的推理能力损失
很多团队量化后只跑几个demo看输出像不像,这是远远不够的。规范的评估应至少覆盖三类基准:数学推理(GSM8K、MATH)、代码生成(HumanEval、MBPP)、通用指令与常识(MMLU、BBH)。每类基准在量化前后的FP16基线上各跑一遍,记录准确率差值。
评估时要注意采样参数的影响。temperature设为0(贪心解码)可以减少随机性干扰,但如果模型量化后logits分布变平,贪心解码会放大差异,因此建议同时报告贪心和固定随机种子的采样结果。此外,评估样本量要足够,GSM8K完整测试集有1319题,只跑100题的置信区间太宽,很容易把噪声当成损失。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
def eval_gsm8k(model_path, n_samples=1319):
model = AutoModelForCausalLM.from_pretrained(
model_path, torch_dtype=torch.float16, device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_path)
correct = 0
for i, sample in enumerate(load_gsm8k_samples(n_samples)):
prompt = build_math_prompt(sample["question"])
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
# 贪心解码,保证量化前后对比的可比性
output = model.generate(**inputs, max_new_tokens=512,
do_sample=False, temperature=1.0)
answer = extract_answer(tokenizer.decode(output[0]))
correct += (answer == sample["answer"])
return correct / n_samples
fp16_acc = eval_gsm8k("./models/qwen2.5-7b-fp16")
int4_acc = eval_gsm8k("./models/qwen2.5-7b-awq-int4")
print(f"FP16: {fp16_acc:.4f}, INT4: {int4_acc:.4f}, "
f"损失: {(fp16_acc - int4_acc) * 100:.2f}%")除了准确率,还建议做误差分析:把量化后做错的题目按错误类型分类——是计算错误、逻辑跳步还是格式错误。经验上,INT4量化模型最常见的失败模式是中间步骤的算术错误和过早给出结论,这类分析能直接指导后续选择缓解策略。
四、典型的量化损失数据与缓解方案
综合公开的评测报告,可以给出一组大致的参考区间。INT8量化(无论是RTN还是LLM.int8风格的混合精度)在绝大多数基准上的损失在1个百分点以内,基本可以视为无损。INT4配合GPTQ或AWQ,知识型任务损失约1到2个百分点,数学推理损失约3到8个百分点,代码生成损失约2到5个百分点。而无校准的朴素INT4在某些模型上可能导致推理能力崩溃,完全不可用。
如果INT4的损失超出承受范围,有几个实用的缓解手段。第一是降低q_group_size,比如从128降到64甚至32,用额外的存储换精度,通常能挽回1到2个百分点。第二是混合精度:对首尾几层和注意力输出层保留更高精度,只对其余层做INT4,因为不同层对量化的敏感度差异很大。第三是量化感知训练(QAT),在少量数据上微调让模型适应低精度表示,效果最好但成本也最高。
还有一个容易被忽视的因素是量化校准数据的选择。默认的校准集偏通用语料,如果你部署的模型专门做数学推理,用数学语料做校准往往能显著降低目标任务上的损失。此外,推理框架本身也有影响,某些内核对INT4的反量化实现存在数值差异,同一份量化权重在不同框架上跑分可能相差1个百分点左右,评估时务必固定运行环境。
总结来说,INT8量化对推理能力的影响通常可以忽略,可以放心用于生产;INT4量化在配GPTQ或AWQ的前提下,对大多数任务损失可控,但在高难度数学和长链推理场景需要认真评估。建议的决策路径是:先量化到INT8验证部署收益,如果显存仍不满足再尝试INT4,并用完整基准测试确认损失在业务可接受范围内,必要时通过分组细化、混合精度和校准数据定制来弥补精度。