SpQR: 稀疏量化表示实现大语言模型近无损压缩的深度解析
Dettmers T, Svirschevski R, Egiazarian V, et al. Spqr: A sparse-quantized representation for near-lossless llm weight compression[J]. arXiv preprint arXiv:2306.03078, 2023.
1. 引言与研究背景
大语言模型(LLM)的预训练技术近期取得了显著进展,产生了具有惊人能力的高质量模型。通过量化将这些LLM压缩到每参数3-4比特,它们可以装入内存受限的设备,如笔记本电脑和移动电话,从而实现个性化使用。然而,量化到每参数3-4比特通常会导致中等到较高的准确率损失,特别是对于1-10B参数范围内的较小模型,而这些模型恰好最适合边缘部署。例如,7B参数的LLaMA模型在1T令牌上训练后,其平均性能仅略低于GPT-3,尽管体积小了25倍。当前的LLM压缩技术可以将这些模型进一步缩小约4倍,同时保持其性能。这产生的性能水平可与最大的GPT-3模型相媲美,同时在内存需求方面实现了重大降低。
本研究介绍了稀疏量化表示(Sparse-Quantized Representation, SpQR),这是一种新的压缩格式和量化技术,首次实现了跨模型规模的LLM近无损压缩。SpQR通过识别和隔离导致特别大量化误差的异常权重,将它们以更高精度存储,同时将所有其他权重压缩到3-4比特。
2. 量化敏感性的理论分析
2.1 参数敏感性的数学定义
并非神经网络中的所有参数都同等重要。直观上,如果权重的舍入误差很大(即它不接近量化点),或者它通常乘以的输入很大(放大了小的舍入误差),那么该权重可以被视为对量化敏感。然而,这些简单的敏感性概念忽略了一个事实:LLM在具有显著相关性的非常大的向量上运行。
为了在计算上可行地评估敏感性,我们在每层级别使用小批量校准输入$X$。定义层权重矩阵$W$中某个权重$w{ij}$的敏感性$s{ij}$为:
$$s_{ij} = \min_{W'} \|WX - W'X\|_2^2 \quad \text{s.t.} \quad w'_{ij} = \text{quant}(w_{ij})$$
关键的是,$W'$中除$w'{ij}$外的所有权重可以取任意连续值,以补偿舍入$w{ij}$产生的量化误差,从而捕获了上述讨论的相关性方面。
这个问题有闭式解,可以通过广义最优脑外科(Optimal Brain Surgeon)框架确定:
$$s_{ij} = \frac{(w_{ij} - \text{quant}(w_{ij}))^2}{2[(XX^T)^{-1}]_{jj}}$$
其中$(XX^T)^{-1}$是对应于优化问题的逆Hessian矩阵。
2.2 权重敏感性的结构化模式探索
为了突出量化过程中的这些结构元素,我们计算每个权重的敏感性并将其可视化。作为量化方法,我们使用GPTQ量化到3位,不使用权重分组。我们使用C4作为校准数据集,并在128个长度为2048令牌的序列上估计误差。
图2:LLaMA-65B最后一个注意力层的权重对数敏感性可视化
- 左侧:高级视图,通过最大池化调整到1:32比例
- 中间:从主图放大的两个区域,展示注意力头模式和行异常值模式
- 右侧:取自其他权重矩阵的旋转嵌入模式和列异常值模式
通过敏感性分析,我们观察到权重矩阵中的几种模式:
行异常值:图2底部中心显示为一个输出单元内的高敏感性区域。某些模式跨越整行,而其他模式是部分的。在注意力层中,一些部分行异常值对应于注意力头的某个子集。
列异常值:出现在图2底部右侧,显示在所有行中选择输入维度(列)的高敏感性。后者与Dettmers等人报告的"异常特征"现象相关。
敏感注意力头:图2顶部中心显示宽度为128的规则条纹,突出显示对应于一个注意力头的所有权重。这可能与某些注意力头具有更重要的功能有关。对应的"条纹"在注意力Q和K投影中是水平的,在输出投影中是垂直的,在值投影和任何MLP权重中不存在。
旋转嵌入模式:敏感性的重复垂直模式,周期为64个单位。我们将此归因于旋转嵌入的使用:每个注意力头($\text{dim} = 128$)被分成两半:前64个用余弦"旋转",另外64个使用正弦。正弦和余弦旋转都使用相同的频率集。通常,对应于低频正弦和余弦的权重比其高频对应物更敏感。
非结构化异常值:除了上述模式,每层还有许多不符合任何上述模式的个别敏感性权重。这些非结构化异常值在具有最大输入索引的列(即图像右侧)中更频繁地出现。
3. SpQR方法的详细设计
3.1 核心思想与创新
现有的LLM量化算法平等对待低敏感性和高敏感性权重;然而,我们的分析表明这可能导致次优量化。理想情况下,我们希望表示法为敏感权重分配更多的"大小预算"。然而,这些权重分散在权重矩阵中,作为个别权重或小组。
3.2 双层量化捕获小权重组
在前面的部分中,我们观察到权重在小的连续组中表现相似的几种情况,组之间有突然的变化。当应用标准方法时,会有许多情况下这些权重被分组在一起,共享相同的量化统计信息。
为了减少这种情况的数量,SpQR使用具有极小组的分组量化,通常为$\beta_1 = 8-32$个权重。也就是说,每$\beta_1$个连续权重有一个单独的量化尺度和零点。
为了规避存储量化统计信息的开销问题,我们使用与权重相同的量化算法对分组统计信息本身进行量化——非对称(最小-最大)量化。由于最小-最大量化的工作方式,量化值的范围将适合具有最大(或最小)量化尺度的组,完美地量化它们。
具体来说,我们将来自$\beta_2 = 16$个连续值的分组统计信息分组,并以相同的比特数一起量化它们,使得具有非典型量化参数的组最终使用更多的"量化预算"。
3.3 高敏感性异常值的处理
我们的分析显示存在小百分比的敏感权重以小组(在自注意力中)或个别"异常值"(在MLP中)形式出现的情况。在某些情况下,1%的权重占总量化误差的75%以上。
由于这些权重似乎会导致高且不可约的误差,我们选择以高精度(16位)保留这些异常值。由于这些异常值通常是非结构化的,我们以类似于压缩稀疏行(CSR)表示的逐行排列方式对它们进行单独编码。
3.4 SpQR量化算法详述
算法遵循粗略的两步过程:
- 找到并隔离异常值作为16位权重
- 将非异常值"基础"权重量化为3-4位,并将剩余的量化转移到16位异常值权重中
对于异常值隔离步骤,算法基于方程(2)中的敏感性准则实施过滤技术,用于隔离和分离异常值与基础权重。全局地,对于每个矩阵,算法旨在选择敏感性阈值$\tau$以获得整个模型中所需数量的异常值,通常约为权重的1%。
具体来说,如果将权重保持在16位可以将方程(2)中的误差减少至少$\tau$,则特定权重被视为异常值。
在第一个异常值检测步骤之后,我们量化基础权重,忽略同一量化组中出现的所有异常值。因此,量化统计信息(例如尺度)通过排除异常值来计算。这在误差方面带来了显著改进,因为例如最小-最大尺度将显著减小。
算法1:SpQR量化算法
算法的主要步骤包括:
- 输入:权重矩阵$W \in \mathbb{R}^{m \times n}$,校准数据$X \in \mathbb{R}^{n \times d}$,基础量化比特数$b$,量化组大小$\beta_1, \beta_2$,敏感性异常值阈值$\tau$
- 输出:量化权重$Q$,量化统计信息,稀疏异常值矩阵
核心循环对每个组进行处理:
- 检测异常值:基于敏感性阈值$\tau$识别异常权重
- 拟合统计信息:排除异常值计算量化尺度和零点
- 量化权重:使用双层量化方案
- 误差补偿:使用GPTQ方法调整未量化权重
4. SpQR表示的实现细节
4.1 量化组的存储
图3:单个权重张量的SpQR表示高级概览
图像显示了权重矩阵被分割成$\beta_1 \times \beta_2$块。右侧描述了所有存储的数据类型及其维度,包括3位量化权重、一阶和二阶尺度和零点,以及占总量小于1%的16位异常值。
所有非异常值权重被编码为包含以下内容的结构:
- 一个$b_w$位的个别权重
- 每组大小为$B$的$b_q$位尺度和零点
- 用于量化$B_q$个量化尺度和零点组的16位统计信息
作为一个特定例子,考虑$b_w = b_q = 3$和$B_w = B_q = 16$的SpQR表示。权重矩阵被分割成$B_q \times B_w = 256$个权重的组。一个组包含256个单独的$b_w = 3$位代码。每16个权重使用一个单独的3位尺度和零点。最后,整个组有四个16位标量用于二级量化。
4.2 异常值的存储
我们的异常值是非结构化的;为了存储,我们首先按行排序,然后按列排序,使得同一行中的异常值在内存中是连续的。对于每个异常值,我们存储两个标量:16位权重值和16位列索引。对于每行,我们还存储一个32位数字——直到当前行的行中异常值的总数,用于高效推理。
这导致每个敏感权重的平均存储成本为32.03到32.1位。通过对异常值进行分组,可以显著减少这一成本,我们将其留作未来工作。
4.3 使用SpQR的推理
为了说明我们方法的实用性,我们为SpQR格式设计了一个高效的基于GPU的解码实现,专注于流行的逐令牌LLM生成作为用例。
我们利用GPU上的自回归推理是内存受限的这一事实,因此高压缩率可以在很大程度上隐藏解码开销。在高层次上,我们的算法将组统计信息和量化权重加载到共享内存(SRAM)中,反量化为16位,然后执行16位输入的矩阵乘法。
对于处理异常值,我们设计了一个利用行中出现的异常值的稀疏矩阵算法。粗略地说,算法的工作流程如下:
- 将矩阵划分为大小相等的块
- 每个GPU核心(线程块)将大片异常值加载到共享内存(SRAM)中
- 每个GPU核心确定异常值是否是段的一部分
- 从主内存加载相应的权重
- 执行矩阵乘法
5. 实验验证与结果分析
5.1 近无损压缩性能
图1:LLaMA模型的压缩LLM性能
- 左图:WikiText2上的语言模型损失vs模型大小
- 右图:零样本任务的平均性能vs模型大小
图中显示SpQR(蓝色线)在相似模型大小下显著优于GPTQ(橙色)和RTN(绿色),特别是在较小的模型上。对于所有模型规模,SpQR以4.6到4.71比特每参数接近16位基线,误差在1%以内。
表1:LLaMA模型在三个数据集上的困惑度结果
模型 | 方法 | 平均比特 | WikiText2 | C4 | PTB |
---|---|---|---|---|---|
7B | 16位基线 | 16.00 | 5.68 | 7.08 | 8.80 |
SpQR | 4.63 | 5.73 | 7.13 | 8.88 | |
GPTQ | 4.00 | 6.13 | 7.43 | 9.27 | |
65B | 16位基线 | 16.00 | 3.53 | 5.62 | 6.91 |
SpQR | 4.71 | 3.57 | 5.64 | 6.93 | |
GPTQ | 4.00 | 3.83 | 5.80 | 7.07 |
结果表明,SpQR在所有模型规模上都实现了近无损压缩,相对困惑度增加小于1%。
5.2 推理速度评估
表4:推理速度比较(tokens/s)
实验在A100 GPU上进行,测试了两种设置:
- 从头生成100个令牌
- 在1024令牌前缀后添加100个令牌
模型 | fp16基线 | SpQR (PyTorch) | SpQR (优化) |
---|---|---|---|
LLaMA-7B | 47±2.3 | 30±2.2 | 57±2.4 |
LLaMA-13B | 37±0.8 | 24±1.2 | 44±0.5 |
LLaMA-30B | 19±1.1 | 8.8±0.4 | 22±0.9 |
结果显示,优化的SpQR算法比16位基线快20-30%,同时比标准PyTorch稀疏矩阵乘法快约2倍。
5.3 消融研究
表3:LLaMA-65B模型的消融实验结果
配置 | WikiText2 | C4 | PTB | 平均比特 |
---|---|---|---|---|
未压缩 | 3.53 | 5.62 | 6.91 | 16 |
GPTQ (4位) | 3.83 | 5.80 | 7.07 | 4 |
3位统计 | 3.74 | 5.73 | 7.02 | 3.63 |
16位统计 | 3.84 | 5.83 | 7.12 | 3.67 |
舍入零点 | 3.75 | 5.76 | 7.01 | 3.63 |
无激活顺序 | 3.74 | 5.76 | 7.05 | 3.63 |
实验表明,使用量化统计信息(3位统计)相比保持16位统计信息显著提高了语言建模损失。
5.4 不同异常值类型的比较
图4:不同异常值类型对WikiText2困惑度的影响
图中比较了三种异常值类型:
- 非结构化(SpQR方法)
- 行(MSE)
- Dettmers等人的方法
随着异常值率从0增加到4%,非结构化异常值(蓝线)比其他方法更快地降低困惑度,即使在考虑不同内存占用后也是如此。在1%异常值率时,SpQR达到3.68的困惑度,而行异常值方法为3.72,Dettmers方法为3.70。
5.5 生成质量评估
图9:不同量化LLaMA-65B模型生成的文本示例
对于提示"Every time data scientist Kim ran her new algorithm, it kept outputting the same unexpected result: a recipe for":
- 16位模型:生成了关于冰茶和预测患者再入院可能性的连贯故事
- SpQR:生成了几乎相同的文本,保持了语义一致性
- RTN 4位:产生了不同的续写,语义发生了偏离
这些例子表明SpQR保持了与原始模型更高的语义相似性。
6. 理论分析与数学推导
6.1 敏感性度量的推导
从优化问题开始:
$$\min_{W'} \|WX - W'X\|_2^2 \quad \text{s.t.} \quad w'_{ij} = \text{quant}(w_{ij})$$
展开目标函数:
$$\|WX - W'X\|_2^2 = \text{tr}((W-W')XX^T(W-W')^T)$$
设$E = W - W'$为误差矩阵,其中$e{ij} = w{ij} - w'_{ij}$。
对于固定的$e{ij} = w{ij} - \text{quant}(w_{ij})$,最优化问题变为:
$$\min_{E_{-ij}} \text{tr}(EXX^TE^T)$$
其中$E_{-ij}$表示除$(i,j)$位置外的所有误差项。
通过对$E_{-ij}$求导并设为零,可以得到最优解。最终的敏感性公式为:
$$s_{ij} = \frac{(w_{ij} - \text{quant}(w_{ij}))^2}{2[(XX^T)^{-1}]_{jj}}$$
6.2 双层量化的误差分析
考虑权重$w$,一阶量化尺度$s_1$,二阶量化尺度$s_2$。
总量化误差可以分解为:
$$\epsilon_{total} = \epsilon_{weight} + \epsilon_{scale1} + \epsilon_{scale2}$$
其中:
- $\epsilon_{weight} = w - \text{round}(w/s_1) \cdot s_1$
- $\epsilon_{scale1} = s_1 - \text{round}(s_1/s_2) \cdot s_2$
- $\epsilon_{scale2} = s2 - s{2,quantized}$
通过选择合适的$\beta_1$和$\beta_2$,可以最小化总误差。
6.3 异常值选择的理论依据
定义权重$w_{ij}$的贡献度为其对层输出误差的影响:
$$C_{ij} = \frac{\partial \|f(W) - f(W')\|_2^2}{\partial w'_{ij}}$$
其中$f$表示层的前向传播函数。
异常值选择准则:
$$w_{ij} \in \text{Outliers} \iff C_{ij} > \tau \cdot \text{median}(C)$$
这确保了选择对输出影响最大的权重作为异常值。
7. 附录:额外的技术细节
A. 权重敏感性的额外分析
图5:LLaMA-65B第40层注意力查询投影的权重敏感性
图中显示了两种不同量化方案的比较:
- 上图:每行量化的3位GPTQ
- 下图:块大小为128的3位GPTQ
在底部右侧的放大图中,我们观察到一个权重子集(宽度128)具有显著更高的量化误差。这个特定组包含一个"垂直"异常值,即相应的输入特征相比其他输入维度具有显著更高的方差。
图6:更深层向上投影层的权重对数敏感性
左侧热图表示每个权重的敏感性,右侧直方图捕获前100列和后100列的敏感性(跨输入维度排序)。后者清楚地显示后面的列平均更敏感,这是GPTQ算法从左到右逐列压缩的副作用。
图7:平均量化误差作为层深度函数的变化
图中显示了不同层角色的平均量化误差(垂直轴)与层深度(水平轴)的关系。每个图对应不同的层角色(如self_attn.q、mlp.up等)。观察到LLaMA的前几层通常具有较低的OBC误差(定义为原始和量化层预测之间的L2距离)。
B. 超参数敏感性分析
表5:权重块大小$\beta_1$和统计块大小$\beta_2$在三个数据集上的性能
表格显示了不同$\beta_1$和$\beta_2$组合下的平均比特数和困惑度。结果表明,较小的组大小(如$\beta_1 = 16, \beta_2 = 32$)在保持合理模型大小的同时提供了最佳性能。
对于WikiText2,最佳配置为$\beta_1 = 16, \beta_2 = 32$,达到3.728的困惑度,仅需3.625平均比特。
C. 模型大小的精确估计
对于给定配置,模型大小的详细计算:
考虑量化权重矩阵$\mathbb{R}^{d{out} \times d{in}}$,平均比特数为:
$$\bar{b} \simeq b_w d_{out}d_{in} + (b_s + b_z)\frac{d_{out}d_{in}}{\beta_1} + 2(16 + 16)\frac{d_{out}d_{in}}{\beta_1\beta_2} + 32r_o d_{out}d_{in}$$
简化后:
$$\bar{b} = b_w + \frac{b_s + b_z}{\beta_1} + \frac{64}{\beta_1\beta_2} + 32r_o$$
例如,对于$b_w = 3, b_s = 3, b_z = 3, \beta_1 = 16, \beta_2 = 32$和0.4%的异常值:
$$\bar{b} = 3 + \frac{3 + 3}{16} + \frac{64}{16 \cdot 32} + 0.004 \cdot 32 \simeq 3.63$$
D. 硬件特定的优化配置
表9:给定内存约束下的最佳LLaMA选择
设备 | 内存(GiB) | LLaMA | $\bar{b}$ |
---|---|---|---|
iPhone13 | 4 | 7B | ≤ 3.5 |
iPhone14 | 6 | 7B/13B | ≃ 4.5/≤ 3.5 |
消费级笔记本 | 8 | 13B | ≤ 4 |
RTX4070 | 10-12 | 14B | ≃ 4.5 |
RTX4080 | 16 | 30B | ≤ 4 |
RTX4090 | 24 | 30B | ≃ 4.5 |
V100 | 32 | 65B | ≤ 3.5 |
A6000 | 48 | 65B | ≃ 4.5 |
这些建议考虑了模型参数和激活的内存需求,确保模型可以完全装入设备内存而无需卸载。
E. 策略梯度的详细推导
对于SEENN-II中的策略网络优化,目标函数为:
$$J(\theta) = \mathbb{E}_{z\sim\pi_\theta}[R(z)]$$
梯度计算使用REINFORCE算法:
$$\nabla_\theta J(\theta) = \mathbb{E}_{z\sim\pi_\theta}[R(z)\nabla_\theta\log\pi_\theta(z|x)]$$
由于$\pi\theta(z|x) = \prod{k=1}^n v_k^{z_k}$,我们有:
$$\log\pi_\theta(z|x) = \sum_{k=1}^n z_k\log v_k$$
因此:
$$\nabla_\theta\log\pi_\theta(z|x) = \sum_{k=1}^n z_k\nabla_\theta\log v_k$$
对于分类分布,期望可以精确计算:
$$\nabla_\theta J(\theta) = \sum_{k=1}^n R(z|_{z_k=1})v_k\nabla_\theta\log v_k$$
其中$R(z|_{z_k=1})$是使用$t_k$个时间步时的奖励。
8. 结论
SpQR通过创新的稀疏量化表示实现了大语言模型的近无损压缩。关键贡献包括:
- 系统性的敏感性分析:首次揭示了LLM权重量化误差的结构化模式
- 双层量化方案:通过量化量化统计信息本身实现了极小组大小而不产生过多开销
- 混合稀疏-量化格式:有效结合了密集低位权重和稀疏高精度异常值
- 近无损性能:在3-4位压缩下实现了相对误差小于1%的突破
这项工作使得在消费级硬件上部署高质量LLM成为可能,为LLM的广泛应用开辟了新的可能性。通过使33B参数模型能够在单个24GB GPU上运行而没有性能下降,SpQR代表了模型压缩技术的重要进步。