实现更低位深的量化,例如INT4甚至更低,常常会带来一个主要难题:权重和激活中都存在离群值。这些离群值是数值异常大的值,相比张量中的大多数值,它们的幅度异常大。虽然它们可能只占总元素的一小部分,但其不成比例的影响会严重降低量化模型的精度。为什么离群值对量化来说问题如此严重?标准量化方法通常将张量内浮点值的整个范围映射到固定数量的离散整数层级。一个大的离群值可以大幅扩展这个所需的范围。设想一个我们要量化的张量 $X$。一个常用方法是找出最大绝对值 $max(|X|)$,并用它来确定缩放因子。如果 $X$ 包含一个幅度非常大的离群值,那么 $max(|X|)$ 将受此离群值主导。这会使得量化步长 $\Delta$ 变大以覆盖整个范围。$$ \Delta = \frac{2 \cdot max(|X|)}{2^b - 1} $$(针对 $b$ 位对称量化)大的 $\Delta$ 意味着张量中数量更多、数值较小的部分被映射到非常有限的整数层级集合,甚至可能将许多不同的浮点值归并到相同的整数表示。这种对大部分值的精度损失会导致较大的量化误差,进而使得LLM的性能出现明显的精度下降。激活离群值尤为困难,因为它们的值依赖于输入,并在推理过程中显著变化。识别离群值处理离群值的第一步是识别它们。一个常用方法是分析权重张量和有代表性的激活张量(使用校准数据获得)中的数值分布。权重离群值: 它们相对直接识别,因为权重在训练后是静态的。我们可以直接扫描预训练模型的权重张量。直方图或标准差等统计指标可以显现偏离均值的数值。激活离群值: 识别激活离群值需要通过模型传递校准数据并记录中间激活值。由于激活随每个输入变化,我们需要一个有代表性的样本来理解典型的激活分布并识别重复出现的离群模式。可视化常有帮助。设想特定层的权重张量中的数值分布。{"layout": {"title": "显示离群值的权重分布", "xaxis": {"title": "权重值"}, "yaxis": {"title": "频率"}, "bargap": 0.1, "height": 350, "width": 550, "plot_bgcolor": "#e9ecef"}, "data": [{"type": "histogram", "x": [-0.1, -0.05, -0.02, -0.01, 0.0, 0.01, 0.015, 0.02, 0.03, 0.05, 0.1, 0.12, 1.5, -1.2], "marker": {"color": "#1c7ed6"}}]}LLM层中常见的权重分布。大多数值聚集在零附近,但存在少数大数值离群值,大幅扩展了所需的量化范围。缓解办法一旦识别出离群值,可采用多种策略来减轻其负面影响。1. 裁剪最简单的方法是裁剪。在量化之前,超过某个阈值的值被限制在该阈值。工作方式: 定义一个裁剪阈值 $\tau$。任何 $|x| > \tau$ 的值都被设置为 $sign(x) \cdot \tau$。然后对裁剪后的张量进行量化。选择 $\tau$: 这是主要难题。将 $\tau$ 设置得太低会裁剪掉许多有用的值,损害精度。设置得太高则未能减轻离群值的影响。常用策略包括根据百分位数选择阈值(例如,裁剪幅度最大的0.1%)或根据标准差的倍数来选择。需要使用校准数据集进行仔细调整。优点: 易于实现。缺点: 可能丢弃真实离群值中包含的重要信息。寻找最优的 $\tau$ 可能很困难且依赖于数据。2. 每通道或每组量化我们不为整个张量使用单一缩放因子(每张量量化),而是可以为数据的较小部分使用单独的缩放因子。每通道: 对于 Linear 或 Conv2D 等层中的权重张量,我们可以为每个输出通道计算单独的缩放因子。这隔离了单个通道内离群值的影响,使其不影响其他通道的量化。如果一个权重矩阵的形状为 [output_features, input_features],我们将计算 output_features 个不同的缩放因子。每组(细粒度): 我们可以进一步将通道或标记划分为更小的组,并独立量化每个组。例如,沿输入特征维度分组权重(例如,每组64或128个权重)可以进一步隔离离群值。优点: 通过局部化量化范围,大幅减轻了离群值的影响。与每张量量化相比,通常提高精度,尤其是在低位深时。许多硬件后端支持。缺点: 增加元数据开销(需要存储更多缩放因子)。与每张量量化相比,反量化期间可能引入轻微的计算开销。3. 混合精度量化并非模型所有部分都需要量化到相同的位深。我们可以策略性地使用更高精度处理对离群值或量化噪声特别敏感的层或张量。工作方式: 识别受低位量化影响最大的层或张量类型(例如,特定注意力组件、层归一化或存在大量离群值的层)。将这些组件保持更高精度(例如,FP16或INT8),同时对模型主体(例如,大型线性层)进行更激进的量化(例如,INT4)。优点: 提供灵活的方式来平衡性能提升与精度保持。可以专门处理有问题的地方。缺点: 需要仔细分析以识别敏感组件。可能使部署流程复杂化,因为推理引擎需要高效支持混合精度执行。4. 激活感知权重量化 (AWQ)AWQ认识到并非所有权重都同等重要。那些与持续大数值激活输入连接的权重对量化误差更敏感。工作方式: AWQ根据校准数据识别重要权重(那些乘以大激活输入的权重)。然后,它在量化之前对权重进行缩放,以减少这些重要权重的量化误差,通常以牺牲不那么重要的权重为代价。这是通过缩放权重矩阵的整个输出通道,并对后续层的激活(或输入特征)应用逆缩放来实现的,从而保持层输出的数学等效性。选择此缩放因子以最小化权重上的量化误差,有效减轻对应于大激活数值的权重离群值的影响。优点: 专门设计用于处理权重与激活数值之间的关系。通常实现比简单裁剪或每张量量化更好的精度保持,尤其对于权重而言。缺点: 依赖于有代表性的校准数据。引入了对权重的修改,这些修改在推理过程中需要考虑(通常被吸收到层级缩放中)。5. SmoothQuantSmoothQuant应对激活离群值的特有难题,尤其是在相邻权重也有较大变化时。大激活离群值常在多个标记的特定通道中出现。工作方式: SmoothQuant将量化难度从激活(因离群值而难以量化)转移到权重(更易量化)。它通过应用数学等效的缩放变换来做到这一点:它按因子 $s$ 缩小有问题的激活通道,并按相同因子 $s$ 放大相应的权重(沿输入通道维度)。 $$ Y = (X \cdot diag(s)^{-1}) \cdot (diag(s) \cdot W) = XW $$ 此平滑因子 $s$ 按通道选择,以平衡激活和权重的动态范围,使两者都更容易使用每张量量化等标准方法准确量化。优点: 直接处理激活离群值。相对简单的思路,保持数学等效性。可以使每张量量化成为可能,即使它之前对激活失败。缺点: 需要校准数据来确定平滑因子。修改权重,如果处理不当,可能与其他仅权重量化等方法相互作用。增加了缩放操作或在推理过程中需要调整权重/缩放因子。digraph G { rankdir=LR; node [shape=box, style=rounded, fontname="Arial", fontsize=10, margin=0.2]; edge [fontname="Arial", fontsize=9]; subgraph cluster_orig { label = "原始计算"; bgcolor="#e9ecef"; X [label="激活 X\n(大量离群值)", color="#fa5252", style=filled]; W [label="权重 W", color="#4263eb", style=filled]; Y [label="输出 Y"]; X -> Y [label="矩阵乘法"]; W -> Y; } subgraph cluster_smooth { label = "SmoothQuant 变换"; bgcolor="#e9ecef"; X_scaled [label="X' = X * diag(s)^-1\n(已平滑)", color="#74c0fc", style=filled]; W_scaled [label="W' = diag(s) * W\n(吸收缩放)", color="#91a7ff", style=filled]; Y_prime [label="输出 Y'"]; X_scaled -> Y_prime [label="矩阵乘法"]; W_scaled -> Y_prime; } Y -> Y_prime [style=invis]; // 确保 Y 和 Y_prime 大致对齐 note [label="目标: 使 X' 和 W' 更易量化\n结果: Y' = Y", shape=plaintext, fontsize=9]; Y_prime -> note [style=dashed, arrowhead=none]; }SmoothQuant 方法将激活 (X) 和权重 (W) 转换为缩放后的版本 (X' 和 W'),使得最终输出保持不变,但缩放后的张量分布更适合量化。选择恰当策略最佳策略常取决于具体的模型架构、目标位深、硬件限制以及可接受的精度容差。对于适度量化(例如,INT8),每通道权重量化可能足够。对于激进量化(例如,INT4或更低),SmoothQuant(用于激活)和AWQ(用于权重)等方法,可能与每组或每通道量化结合使用,通常是必需的。混合精度为模型高度敏感的部分提供了一种备用方案。裁剪是更简单的起点,但常需要仔细调整,且与更高级的方法相比,可能产生次优结果。处理离群值是激进量化LLM实现良好性能的实际需要。通过理解其影响并应用有针对性的缓解方法,您可以大幅改进部署模型的精度-性能权衡。下一节将说明LLM中量化不同组件(例如注意力机制)相关的具体难题。