4bit 模型量化

模型压到 4bit,
丢掉的到底是什么?

直接丢掉的,是一部分区分权重数值的精细程度。它会不会影响回答,要看这些近似值在具体输入里怎样参与计算。

2.4 ≠ 2.1

原来是两个不同的权重。

2 = 2

若都舍入到整数 2,原来的区别就消失了。

为什么还要这样压缩?

大模型有很多权重。每个权重占的位数少一点,合起来就能省下大量存储和内存传输,让原本装不下的模型更有机会运行起来。

这里讨论的是权重量化:权重的数量通常不变,改的是它们的编码与还原方式。它不等于删掉四分之三的参数,也不能被解释成只剩四分之一的知识。

把 2 写成 2.000000,不会告诉我们它原来是 2.4 还是 2.1。后面用更高精度计算,可以算得更细,却不能凭空找回已经合并的区别。

沿着一条计算链理解

权重数值有限刻度计算偏差候选排序实际任务

你只需要会乘法和加法。我们会沿用视频的四个权重、两组输入,再动手调整刻度和分组,看看哪些变化可以直接计算,哪些必须拿真实模型去测试。

根据过拟合青年的视频整理。片中算例与本页新增实验均为教学演示,不是真实大模型的效果或速度评测。查看来源与补充说明。

4 个比特,只有 16 种编码。

一个比特能记 0 或 1。4 个比特一共有 2 × 2 × 2 × 2 = 16 种组合。编码本身还不是权重数值,还要约定怎样把它还原成一个数。

下面选一种均匀、有符号的 INT4 教学方案:整数代码 q 从 −8 到 7,再乘上间隔 s,还原成近似权重。这个间隔通常叫 scale(缩放因子)。

整数代码 q = 裁剪到 [−8, 7](原权重 w ÷ 间隔 s 的最近整数)

还原权重 ŵ = q × s

把两个数放上同一把尺

初始的 2.4 与 2.1 都落在 2 上。改动原值或间隔,观察它们何时还能区分。

原权重代码 q4 位编码还原权重误差 ŵ − w

间隔更小,范围内的刻度通常更细,但 16 个位置覆盖的范围也会更窄。超出范围时会发生裁剪,数值被限制到端点;这时只谈舍入精度就不够了。

本实验采用对称 INT4,零点为 0;恰好在中间时取最近偶数。4 位编码按二进制补码显示。真实方案也可以使用零点、非均匀映射或 FP4/NF4,4bit 本身不唯一规定这些规则。参见 ONNX 量化定义与 NVIDIA 量化方案。

想一想:某个模型按组使用不同 scale,整个模型只能出现 16 种还原权重吗?

四个权重,算一次选择翻转。

先把复杂模型缩成一个打分器。输入是两个数 x₁、x₂;候选 A 和 B 各有两个权重。分别做两次乘法,再相加,选得分更高的候选。

A 得分 = x₁ × 1.4 + x₂ × 2.4

B 得分 = x₁ × 1.6 + x₂ × 2.1

先用片中的两道题

权重固定。这里改变的是当前输入;模型权重不会因为你切换输入而重新量化。

候选原权重近似权重逐项误差

量化前

量化后

这里观察的是候选排序,不知道哪一个候选才是正确答案。A 变成 B,不自动表示回答变差,也不能从一次翻转推算整个模型的能力损失。

四个权重与两组预设输入来自原视频约 01:54–04:20 的手工算例。滑动输入、调整间隔是本页增加的探索方式。

误差要遇到输入,才会影响这次计算。

第一题中,A 的权重从 [1.4, 2.4] 变成 [1, 2],两个误差都是 −0.4。输入是 [1, 2],所以分数变化不是 −0.8,而是:

A 的分数变化 = 1 × (−0.4) + 2 × (−0.4) = −1.2

B 的权重误差则是 [+0.4, −0.1]。一正一负会抵消一部分:

B 的分数变化 = 1 × (+0.4) + 2 × (−0.1) = +0.2

原来 A 只领先 0.4 分;这次 A 减少 1.2,B 增加 0.2,领先差就从 +0.4 变成 −1,排序因此翻转。

比较两个候选的领先差

此处跟随上一章的输入与刻度。回去滑动输入,再来观察各项误差。

项目第一项贡献第二项贡献合计

为什么第二题不翻转?

把输入换成 [1, 0],第二个权重的影响直接乘上 0。量化前 B 的 1.6 高于 A 的 1.4;量化后 B 的 2 仍高于 A 的 1。权重改了,排名却保持不变。

关键不只有“误差有多大”,还要看输入怎样放大或抵消误差,以及候选原来相差多少。原本非常接近的候选,较小的扰动也可能改变排序。

真实语言模型有很多层,还会连续生成 token。某一步输出不同,后续读到的上下文可能随之改变。这里的固定输入点积只解释局部机制,不能替代整段生成与真实任务测试。

如果量化后从 A 改选 B,能直接断言效果下降吗?

格子有限,就把尺用在合适的地方。

对于 −0.24、0.14、0.31,间隔为 1 的尺会把它们都舍入到 0;间隔换成 0.1,就能分出 −0.2、0.1、0.3。这是视频里安排刻度的例子。

但如果同一组里还有 24,就不能只顾小数。把整把尺拉宽,能装下大数,却可能让许多小权重挤在同一格。一个办法是分组量化:每组单独选 scale。

让一个离群值撑大范围

这是新增的 12 个权重示例。前 8 个较小,后 4 个较大。保持顺序,只改变每组包含多少个权重。

原权重所属组该组间隔还原权重绝对误差
分组数量
平均绝对误差

仅针对这 12 个数。

另外保存的 scale

此例假设每组 1 个 FP16 scale。

本例用“组内最大绝对值 ÷ 7”选择 scale,零值组另作处理。分组不会重排权重;实际格式的分组位置、算法和元数据可以不同。

分组让其他组不必迁就这个离群值,但离群值所在的组仍可能受影响。更小的组也要保存更多 scale,有些方案还保存 zero point(零点),会增加开销。

更灵活的刻度提供了改善近似的空间;不能因此保证每个输入、每项任务都更好。上一章已经看到,参数误差怎样影响输出,还取决于输入与候选得分差。

粒度与缩放开销的取舍参见 NVIDIA 量化工作流。

校准在保留计算结果,不是在找回原小数。

只看权重的舍入距离,还不知道它对输出有多大影响。校准数据提供一些代表性输入,让量化过程观察:哪些近似会让层输出偏得更多。

  1. 先看原来怎么算。

    给一层送入校准样本,记录原权重产生的输出。

  2. 量化一部分,再看偏了多少。

    已经落到格点上的权重会引入输出偏差。

  3. 调整尚未量化的权重。

    尽量减轻偏差,然后继续量化;最终仍须得到受格式约束的权重。

GPTQ 就利用校准输入及相关的二阶信息,近似求解逐层输出重构问题。它优化的是量化层输出与原层输出的差异,不能保证恢复原权重、全局最优或所有任务表现。

依据 GPTQ 原论文第 3 节的目标与第 4 节算法。

只补一条样本,会发生什么?

下面是新增的单样本补偿示意,不是 GPTQ 实现。固定 A 的原权重 [1.4, 2.4],先把第一个权重量化为 1,再允许调整第二个权重,试着补回当前样本的输出。

步骤两个权重校准输入的输出另一个输入 [0, 1]

先把一个浮点权重调到能补偿,不代表量化结束。它还要落到有限刻度上;对一条样本有效,也不保证对其他输入有效。

校准数据应该怎样理解?

校准样本用来帮助估计量化带来的影响,不等于把模型完整训练一次,也不可能覆盖今后的所有问题。量化后的模型是否够用,仍要在自己的任务上单独验证。

文件变小、内存变少、运行变快,要分开看。

同样数量的权重,若代码从每个 16bit 改为 4bit,纯代码存储理论上是原来的四分之一。这还没算 scale、零点、未量化张量和文件结构。

算的是哪一部分空间?

FP16 纯权重

作为 16bit 对照。

4bit 纯代码

只算权重代码。

4bit 代码 + 元数据

GB 按 10⁹ 字节计算。此例假设全部权重均可量化、每组 1 个 16bit scale;不含对齐、文件结构和其他张量。其余运行占用由你假设,两种方案暂设相同,不是设备测量,也不会由参数量自动推算。

查看这次估算的公式

纯代码字节 = 权重数量 × 4 ÷ 8

元数据字节 = 向上取整(权重数量 ÷ 组大小)×(16 + 零点位数)÷ 8

假设运行占用 = 权重与元数据 + 其余运行占用

实际推理还需要激活、中间缓冲、KV cache 等。上下文长度、批量和运行框架都会影响它们,weight-only 量化不会自动把这些部分也改成 4bit。

存成 4bit,不代表每一步都用 4bit 算。

例如 NVIDIA TensorRT 的一种 weight-only 路径,把权重以 INT4 保存;计算时在内核里解量化,输入与点积计算保持较高精度。它减少权重读取量,但不会把原来已经舍入的权重变回原始值。

读入 4bit 代码结合 scale 解量化用近似权重计算

参见 TensorRT 的 weight-only 实现说明与 TensorRT-LLM 内存构成。这是具体实现示例,不是全部 4bit 格式的统一规定。

速度要看完整路径

如果瓶颈主要是权重的内存读取,少读数据可能带来加速;但解量化也有开销,硬件、内核、算子融合、批量和上下文都会影响实际结果。不能把“代码存储减少到四分之一”直接换算成“必然快四倍”。

少存了多少位,不能直接换算成少了多少能力。

量化把许多不同的原值合并到有限格点上。回答效果取决于这些近似怎样改变真实计算与生成过程;空间和速度也各有自己的边界。

权重量化
用较少位数及配套映射,保存权重的近似表示。
scale
把代码还原为数值时用的缩放因子;均匀方案中决定刻度间隔。
分组
让不同组使用自己的刻度,代价是多保存一些元数据。
校准
用有限输入样本观察量化影响,帮助保留层输出。

真要选模型,就用自己的任务比较

  1. 回答效果

    先准备固定问题和判断标准,比较同一个模型的原精度版与量化版。保持提示词和生成设置尽量一致;有采样时,用固定种子或多次运行区分量化影响与随机波动。

  2. 内存占用

    在同一设备、框架、上下文长度和批量下,记录实际峰值占用,不用下载文件大小代替。

  3. 运行速度

    分别测首个 token 等待时间与后续生成吞吐,使用相同负载;确认运行框架对该量化格式有合适的内核。

4bit 文件只有原来的约四分之一大,能推出哪一项?

来源与本页补充

滑动刻度、12 个权重的分组表、单样本补偿表和内存计算器是本页新增的教学演示。它们的数值可以复算,但不能当作真实模型的质量、显存或速度成绩。小测只检查当前问题,不代表已经长期掌握。

想回到关键现象,可以再次切换两组输入: