1. 模型量化入门:从零开始理解量化
大家好,我是老张。做深度学习部署这些年,我踩过最多的坑,就是模型量化。今天咱们聊聊这个绕不开的话题。
先问个问题:你训练好的模型,动辄几百MB,怎么塞进手机里?怎么在嵌入式设备上跑起来?答案就是——量化。
1.1 什么是模型量化?
说白了,量化就是把模型里的高精度数字,换成低精度数字。
举个例子。你训练模型时,权重和激活值都是FP32(32位浮点数)。每个数占4个字节。量化之后,变成INT8(8位整数),每个数只占1个字节。模型体积直接缩小4倍。
我在项目中遇到过最夸张的情况:一个BERT模型从FP32量化到INT8,体积从1.2GB缩到300MB,推理速度提升了3倍,精度只掉了0.3%。客户当场就拍板了。
核心概念:量化是将连续取值(浮点数)映射到离散取值(整数)的过程。本质上是信息压缩。
1.2 为什么需要量化?
你想想看,现在的大模型动不动几十亿参数。如果不做量化,部署成本高得吓人。
我总结了一下,量化有三大好处:
- 模型体积变小:FP32→INT8,体积缩小75%。INT4量化能缩小到原来的1/8。
- 推理速度变快:整数运算比浮点运算快得多。在ARM架构的芯片上,INT8推理速度是FP32的2-4倍。
- 功耗降低:整数运算单元更省电。这对移动设备和IoT设备来说,太重要了。
嗯,这里要注意:量化不是免费的午餐。精度损失是必然的,关键是怎么把损失控制在可接受范围内。
我的经验:对于分类任务,量化后精度损失通常在0.5%以内。但对于检测、分割这类任务,损失可能达到1-2%。建议先做小规模实验验证。
1.3 量化的基本原理
量化分两种:线性量化和非线性量化。咱们一个一个说。
1.3.1 线性量化
线性量化是最常用的方法。它的映射关系是一条直线。
公式很简单:
Q = round((R - zero_point) / scale)
其中:
R:原始浮点值Q:量化后的整数值scale:缩放因子(步长)zero_point:零点偏移
反量化公式:
R = Q * scale + zero_point
举个例子。假设原始数据范围是[-1.0, 1.0],要量化到INT8(范围[-128, 127])。
scale = (1.0 - (-1.0)) / (127 - (-128)) = 2.0 / 255 ≈ 0.00784
zero_point = round(-1.0 / 0.00784) + (-128) ≈ -128 + 128 = 0
所以:R = 0.5 → Q = round(0.5 / 0.00784 + 0) = round(63.78) = 64
我曾经在量化一个语音模型时,因为零点计算错误,导致整个模型输出全是噪声。排查了整整两天才发现问题。从那以后,我每次都会手动验证几个点的量化结果。
避坑指南:线性量化对数据分布敏感。如果数据集中在某个小范围,量化精度会严重下降。我曾经遇到过这种情况:模型权重分布是[-0.1, 0.1],但有个别异常值到了10。结果量化后,大部分权重都被压缩到同一个整数值上,模型直接废了。
1.3.2 非线性量化
非线性量化,说白了就是不用直线映射。它用曲线或者分段函数来映射。
常见的非线性量化方法:
- 对数量化:用对数函数映射。适合数据分布呈指数分布的场景。
- 分段量化:把数据分成几段,每段用不同的scale。适合数据分布不均匀的场景。
- 查找表量化:预先计算好映射表,运行时直接查表。速度快,但需要额外存储空间。
我建议:除非数据分布特别特殊,否则优先用线性量化。非线性量化虽然精度更高,但实现复杂,硬件支持也差。
| 量化类型 | 精度 | 实现难度 | 硬件支持 | 推荐场景 |
|---|---|---|---|---|
| 线性量化 | 中等 | 低 | 好 | 通用场景 |
| 对数量化 | 较高 | 中 | 一般 | 音频、传感器数据 |
| 分段量化 | 高 | 高 | 差 | 特殊分布数据 |
| 查找表量化 | 高 | 中 | 差 | 固定场景、资源充足 |
1.4 量化粒度
量化粒度,就是量化时共享scale和zero_point的范围。
- 逐层量化:整个层用一个scale。最简单,但精度最差。
- 逐通道量化:每个通道用一个scale。精度好,实现也简单。我推荐用这个。
- 逐组量化:每N个元素一组,每组一个scale。精度最好,但计算量大。
- 逐元素量化:每个元素一个scale。精度最高,但几乎没人用。
我个人习惯:卷积层用逐通道量化,全连接层用逐层量化。这样在精度和速度之间取得了不错的平衡。
1.5 量化感知训练 vs 训练后量化
这两个概念,新手容易搞混。
训练后量化(PTQ):模型训练完再做量化。简单快速,但精度损失可能大一些。
量化感知训练(QAT):在训练过程中模拟量化效果。精度更好,但需要重新训练模型。
我建议:先试PTQ。如果精度损失在可接受范围内,就用PTQ。如果不行,再上QAT。别一上来就搞QAT,太费时间了。
总结一下:量化是深度学习部署的必修课。线性量化是基础,非线性量化是进阶。从PTQ开始,逐步深入QAT。记住:没有最好的量化方法,只有最适合你场景的方法。
下一章,咱们聊聊量化误差的来源,以及怎么评估量化后的模型质量。到时候我会分享一个我踩过的坑——量化后模型精度没降,但推理结果全错了。你猜猜是什么原因?