量化基础:模型量化原理、定点与浮点表示、对称与非对称量化、量化参数(scale、zero_point)

在进入RKNN量化校准的具体操作之前,必须先建立扎实的量化理论基础。量化本质上是一种信息重编码过程——将神经网络中连续分布的浮点权重和激活值,映射到离散的整数集合上。这一过程直接决定了后续校准数据集的选择策略和精度损失评估方法。理解量化原理,不仅是为了知道“怎么做”,更是为了理解“为什么这样做会损失精度”以及“如何通过参数设计将损失降到最低”。本节将从数值表示、映射方式和核心参数三个维度,系统拆解量化的底层逻辑。

浮点表示 (FP32) 符号位(1) + 指数(8) + 尾数(23) 动态范围: ±3.4×10³⁸ 精度: 约7位有效十进制数字 权重示例: 0.2314567... 激活示例: -1.2345678... 定点表示 (INT8) 符号位(1) + 整数位(7) 动态范围: -128 ~ 127 精度: 固定步长 (scale) 权重示例: 42 (对应浮点值) 激活示例: -57 (对应浮点值) 量化参数 scale (缩放因子) zero_point (零点) 对称: zero_point = 0 非对称: zero_point ≠ 0 映射 控制 核心映射公式 浮点值 = (整数值 - zero_point) × scale 量化过程: 整数值 = round(浮点值 / scale) + zero_point 对称量化 范围: [-max, max] 对称分布 zero_point = 0, 实现简单 非对称量化 范围: [min, max] 任意分布 zero_point ≠ 0, 精度更高

2.1 模型量化原理:从连续域到离散域的映射

神经网络模型在训练阶段通常使用32位浮点数(FP32)存储权重和中间激活值。浮点数的优势在于其巨大的动态范围和相对均匀的精度分布,能够精确表示从极小到极大的数值。然而,在边缘计算场景下,FP32模型存在两个致命问题:一是存储开销大,一个百兆级模型在嵌入式设备上可能占据过多Flash空间;二是计算效率低,通用处理器和NPU对浮点运算的支持远不如整数运算高效。

量化的核心思想是:用有限位宽的整数(如INT8、INT16)来近似表示浮点数值,同时保持神经网络的推理精度在可接受范围内。这一过程可以形式化地描述为:给定一个浮点张量 \( r \),我们希望找到一个映射函数 \( Q(r) \),使得量化后的整数张量 \( q \) 能够以最小的信息损失还原出接近原始值的浮点数。

从信息论角度看,量化是一种有损压缩。其精度损失主要来源于两个环节:舍入误差(rounding error)和截断误差(clipping error)。舍入误差发生在将连续值映射到最近整数点的过程中,而截断误差则源于超出量化范围的值被强制截断到边界值。理解这两种误差的来源,是后续进行精度损失评估的理论基础。

量化误差的数学表达:

设浮点值域为 [r_min, r_max],量化位宽为 n (如 n=8)
量化步长: scale = (r_max - r_min) / (2^n - 1)
量化误差: e = |r - (q - zero_point) × scale|
总误差 = 舍入误差 + 截断误差

2.2 定点与浮点表示:数值系统的本质差异

定点数(Fixed-point)和浮点数(Floating-point)是计算机中两种主要的实数表示方法。浮点数通过科学计数法的方式,将数值拆分为符号位、指数位和尾数位,从而在很宽的范围内保持相对一致的相对精度。而定点数则使用固定的比例因子(即scale)将实数映射到整数域,其精度在数值范围内是均匀的,但动态范围受限。

在神经网络量化中,我们通常将FP32的权重和激活值转换为INT8定点表示。以INT8为例,其取值范围为[-128, 127](有符号)或[0, 255](无符号)。定点表示的关键优势在于:整数运算在硬件上可以实现更高的吞吐量和更低的功耗。例如,RK3588的NPU对INT8运算的峰值算力通常是FP16的2倍以上,是FP32的4倍以上。

特性 FP32 浮点 INT8 定点 INT16 定点
位宽 32 bit 8 bit 16 bit
动态范围 ±3.4×10³⁸ -128 ~ 127 -32768 ~ 32767
相对精度 约10⁻⁷ 约10⁻²(取决于scale) 约10⁻⁴(取决于scale)
存储占用 4 Bytes 1 Byte 2 Bytes
NPU算力(典型) 1x 基准 4x ~ 8x 2x ~ 4x
适用场景 训练、高精度推理 边缘部署、实时推理 精度敏感型边缘推理

在实际的RKNN部署流程中,选择INT8还是INT16取决于任务对精度的敏感程度。例如,图像分类任务通常对INT8量化容忍度较高,而目标检测中的边界框回归分支或关键点检测任务,则可能需要INT16或混合精度方案。

2.3 对称与非对称量化:两种映射策略

对称量化和非对称量化是两种最基础的量化映射策略,它们的区别在于如何处理浮点数据的零点(zero point)与整数零点的对应关系。

对称量化假设浮点数据的分布关于原点对称,即 \( r_{min} = -r_{max} \)。在这种情况下,量化映射可以简化为 \( q = round(r / scale) \),其中 \( scale = r_{max} / 127 \)(对于INT8有符号)。对称量化的最大优势是实现简单、计算开销小,因为不需要额外处理zero_point的偏移。然而,当浮点数据分布明显偏向某一侧时(例如ReLU激活函数的输出恒为非负),对称量化会浪费一半的量化范围,导致精度下降。

非对称量化则允许浮点数据的最小值和最大值独立确定,即 \( r_{min} \) 和 \( r_{max} \) 可以不对称。此时需要引入zero_point参数来对齐浮点零点与整数零点:\( q = round(r / scale) + zero\_point \),其中 \( scale = (r_{max} - r_{min}) / 255 \),\( zero\_point = round(-r_{min} / scale) \)。非对称量化能够更充分地利用量化范围,尤其适合分布偏斜的激活值,但代价是计算复杂度略高。

经验法则:在RKNN量化中,权重通常使用对称量化(因为权重分布近似对称),而激活值推荐使用非对称量化(因为ReLU等激活函数导致分布偏斜)。RKNN Toolkit在默认配置下会自动为不同层选择合适的量化策略,但高级用户可以通过配置文件手动干预。

2.4 量化参数:scale与zero_point的确定方法

scale(缩放因子)和zero_point(零点)是量化过程中最核心的两个参数。它们共同定义了浮点域到整数域的仿射变换关系。正确确定这两个参数,是保证量化精度的关键。

scale的确定取决于浮点数据的动态范围。最常用的方法是MinMax校准:在推理过程中收集每一层激活值的统计信息(最小值、最大值),然后计算scale。然而,MinMax方法对异常值(outlier)非常敏感——如果数据中存在极端值,会导致scale过大,从而降低整体量化精度。因此,实际工程中更推荐使用百分位法(如99.99%分位)或KL散度校准(Entropy Calibration),后者通过最小化量化前后信息分布的KL散度来寻找最优的截断阈值。

zero_point的确定相对简单:在非对称量化中,它确保浮点零值能够被精确表示。这一点对于神经网络至关重要,因为零值在padding、ReLU激活和BatchNorm操作中频繁出现。如果zero_point计算不准确,会导致零值被映射为非零整数,引入系统性偏差。

# 伪代码:MinMax量化参数计算
def compute_quant_params(tensor, bits=8, symmetric=False):
    r_min = tensor.min()
    r_max = tensor.max()
    
    if symmetric:
        abs_max = max(abs(r_min), abs(r_max))
        scale = abs_max / (2**(bits-1) - 1)
        zero_point = 0
    else:
        scale = (r_max - r_min) / (2**bits - 1)
        zero_point = round(-r_min / scale)
    
    return scale, zero_point

2.5 案例拆解:一个卷积层的量化全过程

为了更直观地理解上述概念,我们以一个实际卷积层的量化过程为例进行拆解。假设某卷积层的权重张量分布范围为[-0.5, 0.5],激活值(经ReLU后)分布范围为[0.0, 6.0]。

步骤 权重(对称量化) 激活(非对称量化)
原始范围 [-0.5, 0.5] [0.0, 6.0]
scale计算 0.5 / 127 ≈ 0.00394 (6.0 - 0.0) / 255 ≈ 0.02353
zero_point 0 round(-0.0 / 0.02353) = 0
浮点值示例 0.23 → round(0.23/0.00394) = 58 3.5 → round(3.5/0.02353) + 0 = 149
反量化误差 |0.23 - 58×0.00394| = 0.0015 |3.5 - 149×0.02353| = 0.0005

从上述案例可以看出,当数据分布范围较窄时,量化步长较小,精度损失也较小。这也解释了为什么校准数据集的选择如此重要——如果校准数据无法覆盖推理时可能出现的数值范围,就会导致scale估计不准,进而放大量化误差。

常见误区警示:

  • 误区一:认为量化就是简单的“除以最大值再乘以127”。实际上,对于非对称分布的数据,这种做法会浪费大量量化区间。
  • 误区二:忽略zero_point的作用。在BatchNorm融合后的层中,zero_point的微小偏差可能被逐层放大。
  • 误区三:对所有层使用相同的量化策略。不同层的数据分布差异巨大,应分别校准。
  • 误区四:混淆“量化精度”与“模型精度”。量化后的模型精度下降可能来自量化误差,也可能来自校准数据代表性不足。

2.6 总结与复盘

本节系统梳理了模型量化的核心理论基础。从浮点到定点的表示转换,到对称与非对称两种映射策略的对比,再到scale和zero_point两个关键参数的确定方法,这些概念构成了后续理解RKNN量化校准流程的基石。在实际工程中,量化参数的选择并非一成不变,而是需要根据具体模型结构、数据分布特征和硬件特性进行动态调整。