当我们训练一个深度神经网络时,通常使用 32 位浮点数(FP32)来存储权重和激活值。这种精度对于训练过程中的梯度下降是必要的,因为权重需要通过非常小的增量来逐步调整。然而,一旦模型训练完成进入推理阶段,情况就完全不同了 —— 推理需要的计算量与用户数量成正比,而训练的计算量只与研究者数量成正比。正是在这个背景下,量化技术应运而生,成为提升推理效率的核心手段。
量化本质上是一个将高精度浮点数映射到低精度表示的过程。以最常见的 8 位整数量化为例,我们将原本分布在某个范围内的浮点值压缩到 0 到 255 这 256 个离散值中。这个映射过程需要两个关键参数:最小值(min)和最大值(max),它们定义了量化区间的边界。假设某个层的权重分布在 -3.0 到 6.0 之间,那么量化后的值 0 代表 -3.0,255 代表 6.0,而 128 则大约代表 1.5。这种线性映射方式虽然简单,但带来的压缩效果是显著的 —— 模型文件大小可以减少约 75%,从原来的数百 MB 降低到原来的四分之一左右。
为什么神经网络能够容忍如此大的精度损失?这是一个有趣的问题。训练神经网络时,研究者们的首要目标是让模型能够工作,因此精度和速度成为首要考量,浮点运算自然成为默认选择。然而,现代神经网络展现出一种神奇的特性:它们对输入噪声具有很强的鲁棒性。当我们识别照片中的物体时,网络需要忽略 CCD 噪声、光照变化以及各种非本质差异,专注于重要的相似性特征。这种能力意味着低精度计算带来的量化误差被网络当作另一种形式的噪声,而网络仍然能够产生准确的结果。
在工程实践中,量化有两种主要动机。第一种是简单地将模型文件压缩存储 —— 我们只需为每一层保存最小值和最大值,然后将浮点值量化为 8 位整数写入磁盘。这种方式不需要修改任何推理代码,加载模型时再解量化为浮点数即可,现有代码无需任何更改。第二种更激进的方案是直接在 8 位整数上执行完整的推理计算,这需要修改每个计算节点,但带来的收益也更大。8 位数据的读取只需要浮点数 25% 的内存带宽,这意味着缓存利用率大幅提高,RAM 访问不再是瓶颈。同时,现代处理器通常支持 SIMD 指令,可以在单个时钟周期内执行多个整数运算,某些 DSP 芯片还专门针对 8 位运算进行了优化。
确定量化范围是量化过程中的关键步骤。权重参数是常量,在加载时就知道其确切范围,因此可以预先计算量化和解量化参数。许多激活函数的输出范围也是已知的,比如 ReLU 的输出必然非负。然而,对于卷积和矩阵乘法这类运算,其输出范围取决于输入数据,我们需要在推理过程中动态确定。一个重要的工程细节是:8 位乘法产生的 16 位结果在累加时可能需要 20 到 25 位的精度,具体取决于点积的长度。因此,我们需要在计算链中保留足够的中间精度,避免溢出,然后再将最终结果重新量化回 8 位。
对称量化和非对称量化是两种常见的量化方案。对称量化将零点固定在范围的中心,适合数据分布相对均匀的情况;非对称量化则允许零点偏移,能够更好地处理分布不均匀的激活值,但计算复杂度略高。对于大多数 CNN 模型,卷积层权重采用对称量化往往效果不错,而激活值由于 ReLU 等非线性函数的存在,更适合使用非对称量化。
量化误差的主要来源是舍入(rounding)和截断(clipping)。当浮点值落在两个量化整数之间时,必须选择一个作为代表,这种舍入操作在累积计算中可能引入系统性偏差。如果量化范围设置得过宽,有效位宽会被浪费;设置得过窄,又会将重要的大值截断掉。实践中,通常需要使用一组校准数据来统计实际的数据分布,从而确定最优的量化范围。对于大多数模型,使用 1000 到 5000 个代表性样本进行校准就能获得不错的结果。
在部署方面,8 位整数量化在移动设备和嵌入式系统上表现尤为出色。以经典的 AlexNet 为例,原始模型超过 200 MB,量化后可以压缩到约 50 MB,同时推理速度可以提升数倍,功耗显著降低。然而,需要注意的是,并非所有硬件平台都能从量化中获益 —— 某些 GPU 对 8 位运算的支持并不如 CPU 完善,量化后的模型反而可能运行得更慢。因此,在生产环境中部署量化模型之前,务必在目标硬件上进行基准测试。
对于想要深入了解量化技术的工程师,建议从简单的后训练量化(PTQ)开始尝试。主流深度学习框架如 TensorFlow 和 PyTorch 都提供了开箱即用的量化工具,只需几行代码就能将 FP32 模型转换为 INT8 模型。如果量化后精度损失明显,可以考虑量化感知训练(QAT),在训练过程中模拟量化效果,让模型提前适应低精度约束。对于精度要求极高的场景,混合精度量化是更好的选择 —— 对敏感层(如模型的首层和末层)使用较高精度,对中间层使用较低精度,在压缩率和精度之间取得平衡。
资料来源:本文参考了 Pete Warden 在 TensorFlow 官方博客上发表的量化技术详解,该文章详细介绍了 8 位量化的实现细节和工程考量。