LLM量化:在笔记本电脑上运行160GB大模型,损失极小
像Qwen-3-Coder-Next这样拥有800亿参数的模型,内存占用高达159.4GB。通过量化技术,模型体积可缩小至原来的1/4,推理速度提升2倍,仅带来5%–10%的质量下降。这使得在消费级硬件上运行大型语言模型成为可能,且性能几乎不受影响。
参数及其对模型大小的影响
参数——神经网络中的权重——决定了大模型的内存占用。每个参数都以浮点数形式存储。最简单的计算单元:输入乘以权重得到输出。真实模型包含数百层,每层有数千个节点,因此总参数量可达千亿甚至万亿级别。
例如,一个具有2个输入、3层每层4个节点、2个输出的网络,共有64个参数。若扩展到数十万节点规模,权重数量将达万亿级。主流模型的参数分布直方图显示,99%的数值集中在[-0.5, 0.5]区间内,接近零值。
内存中的数值表示
计算机通常使用float32:1位符号位、8位指数位、23位尾数位,数值范围为±3.4×10³⁸,精度约7位有效数字。其分布不均——越靠近零值越密集,极端值区域越稀疏,这恰好契合大模型中权重普遍较小的特点。
float16:1+5+10位,精度3–4位,范围±65,504;bfloat16(1+8+7):范围更广,精度2–3位。Float8/Float4尚处实验阶段,尾数位仅3–4位。
正弦波近似对比:float32平滑连续,而float4呈现阶梯状,误差明显可见。
量化原理
量化是一种有损压缩技术:将浮点数映射到更小的数值集合。简单四舍五入(round-to-nearest)从bfloat16转为float4会导致模型崩溃——权重全变为零,输出也为零。原因在于:float4的取值范围[-3,3]远大于典型权重[-0.89,0.16],导致信息严重失真。
对称量化
将数据缩放到整数范围内。公式如下:
- scale = max_abs / (2^(bits-1) - 1)
- 量化:round(value / scale)
- 反量化:quantized * scale
JavaScript示例代码:
function quantize({ values, bits }) {
const vmax = Math.max(...values.map(Math.abs));
const qmax = 2 ** (bits - 1) - 1;
const scale = vmax / qmax;
return {
values: values.map((v) => Math.round(v / scale)),
scale,
};
}
function dequantize({ values, scale }) {
return values.map((v) => v * scale);
}
以 values = [-0.89, 0.16, 0.08, -0.13, 0.16, -0.54],bits=4为例:
- 量化后:[-7,1,1,-1,1,-4],scale≈0.127
- 反量化后:[-0.89,0.127,0.127,-0.127,0.127,-0.509]
- 平均误差:18%
4比特量化后的模型输出与原始结果偏差达30%,但内存占用仅为原来的1/4。
非对称量化
改进对称量化,分别处理最小值和最大值。将原始范围[ min, max ]映射到[ qmin, qmax ]。公式如下:
- offset = min
- scale = (max - min) / (qmax - qmin)
- quantized = round((value - offset) / scale)
该方法能更高效利用空间:对于负值偏多的数据分布,正向空间不会被浪费。平均误差可降至5%–10%。
应用于张量时,可采用按通道或分组量化(per-group quantization),以最小化激活值误差。
量化后的质量评估
可通过验证集上的困惑度(perplexity)或任务特定指标(如BLEU、ROUGE)进行评估。基准测试结果如下:
- Qwen-3-Coder-Next 4比特版本:相比FP16,困惑度上升7%
- 速度:无张量核心的GPU上提速2倍
| 格式 | 大小(GB) | 困惑度 | 速度(token/秒) |
|--------|-----------|------------|--------------------|
| FP16 | 159.4 | 1.00 | 1.0 |
| INT8 | 39.8 | 1.05 | 1.8 |
| INT4 | 19.9 | 1.09 | 2.1 |
关键要点
- 量化可在不重新训练的前提下,使模型体积缩小4–8倍。
- 对称数据推荐使用对称量化;分布倾斜时选用非对称量化。
- 按组量化(每组128个元素)在精度与速度间取得良好平衡。
- llama.cpp 和 bitsandbytes 原生支持INT4/INT8量化。
- 实际部署前务必在下游任务(如编程、问答)中进行测试。
— Editorial Team
暂无评论。