一句话定义:LLM.int8() 是一种面向大语言模型的 8 比特量化推理方案——矩阵乘法里数值特别大的"离群"通道用 FP16 算,其余通道用 INT8 算,再把两半结果相加,从而在几乎不损失精度的前提下把推理显存和算力需求降下来。
问题出在哪
把模型从 FP16 压到 INT8,直觉上很简单:找出一组数里的最大值,把整段区间线性映射到 -128~127 这 256 个整数格子里。麻烦在于,大模型内部的激活值(activation)分布并不均匀。少数几个特征维度会冒出"离群值"(outlier),比其它维度大上几十倍。
打个比方:全班考试,大多数人考 50~90 分,偏偏有一位考了 8000 分。如果坐标轴必须覆盖到 8000,那 50 分和 90 分就挤在原点附近,根本分不出来。INT8 只有 256 个格子,被离群值一拉,正常数值的量化精度就崩了。权重矩阵的分布相对温和,问题主要出在激活上。
怎么解决
研究者发现,这些离群值不是随机噪声,而是稳定集中在少数几个特征维度上。既然只有少数维度难搞,那就区别对待。
做矩阵乘法时逐维度扫描激活,把超过阈值的那些列拆出来,这部分用 FP16 计算;剩下的绝大多数维度用 INT8 计算;两部分的乘积最后相加,结果与全精度几乎一致。这个做法叫混合精度分解(mixed-precision decomposition)。
回到考试的例子:不用一根坐标轴管所有人。绝大多数人用普通刻度尺量,那几个"超级分数"单独用一把大尺子量,最后汇总。
和相邻概念的区别
| 方案 | 量化对象 | 对离群值的态度 | 典型取舍 |
|---|---|---|---|
| 普通 INT8 量化 | 权重 + 激活 | 一刀切,被离群值拖累 | 省显存,但精度掉得明显 |
| LLM.int8() | 权重 + 激活 | 离群通道拆出来走 FP16 | 精度基本保住,显存约减半 |
| 权重量化(GPTQ、AWQ 等) | 只量化权重,激活仍用 FP16 | 不处理激活离群值 | 权重压得更狠,矩阵乘仍按 FP16 算 |
关键差别:GPTQ、AWQ 这类方法主要在"存"上做文章,激活仍以 FP16 参与计算;LLM.int8() 是权重和激活都走 8 位,省的是实打实的矩阵乘法开销。
对从业者意味着什么
一是显存门槛下降。FP16 换成 INT8,权重占用的显存大致砍半,原本要两张卡才放得下的模型,可能一张就能跑起来。二是它属于训练后量化(post-training quantization),不用重新训练,拿来即用。它在 bitsandbytes 库中有开源实现,主流推理框架也有对应支持,具体支持范围和参数以官方文档为准。
需要注意两点:它面向推理,训练阶段不适用;离群值现象的强弱因模型、因层而异,实际能省多少、精度掉多少,最好在自己的任务上实测一遍。
