1. 引言
随着深度学习模型不断发展,网络结构越来越复杂,参数规模和计算量也持续增长。大型神经网络虽然能够带来更强的特征表达能力,但同时也带来了更高的存储需求、更大的计算开销以及更高的部署成本。
在云端服务器环境中,大规模模型通常可以依靠强大的计算资源运行,但对于移动端、嵌入式设备和边缘 AI 芯片而言,计算资源、内存容量以及功耗预算都更加有限。如何让已经训练好的深度学习模型在资源受限设备上高效运行,成为模型部署过程中的关键问题。
围绕模型轻量化,已经出现了多种优化方法。例如:
- 轻量化网络设计:从网络结构层面降低复杂度
- 模型剪枝:删除模型中的冗余参数或结构
- 模型蒸馏:通过知识迁移降低模型规模
除此之外,模型量化也是目前最常用的一类模型压缩技术。
与改变网络结构不同,模型量化主要关注模型内部数据的表示方式。它通过降低模型参数和计算过程中的数值精度,将原本使用高精度浮点数表示的模型转换为低比特整数表示,从而减少模型存储空间,降低计算成本,并提升模型在边缘设备上的推理效率。
例如,一个使用 FP32(32 位浮点数)的模型,在量化后可以转换为 INT8(8 位整数)模型:
- 参数存储空间降低约 75%
- 内存访问压力降低
- 整数计算效率提升
- 更适合 AI 加速硬件部署
因此,模型量化已经成为深度学习模型从训练阶段走向实际部署阶段的重要技术之一。
本文将从模型量化的基本概念出发,介绍为什么需要量化、量化的基本原理,以及 Scale 如何连接浮点模型和整数模型,为后续理解 PTQ(Post Training Quantization)和 QAT(Quantization Aware Training)打下基础。
2. 为什么需要模型量化
2.1 深度学习模型面临的资源压力
现代深度学习模型通常采用浮点数进行训练和推理,其中最常见的是 FP32。
FP32 使用 32 位表示一个数值:
ini
1 个参数 = 32 bit = 4 Byte
对于一个拥有 1 亿参数的模型:
kotlin
模型大小 ≈ 100000000 × 4 Byte
≈ 400 MB
如果模型部署在服务器环境中,这样的规模通常可以接受。
但是在边缘设备中,情况完全不同。
例如:
- MCU 设备可能只有几 MB 存储空间
- 机器人平台需要同时运行多个 AI 模型
- 智能摄像头需要低功耗实时推理
- 自动驾驶芯片需要同时处理多个感知任务
此时,模型存储、计算和功耗都会成为限制因素。
因此,仅依靠提升硬件性能并不能解决所有问题,还需要从模型本身进行优化。
2.2 浮点模型在边缘设备中的挑战
深度学习训练阶段通常采用 FP32 或 FP16,这是因为浮点数具有较大的动态范围,可以更加准确地表示复杂的数据变化。
但是,在推理阶段,模型参数通常已经固定,很多计算并不需要保持训练阶段同样高的数值精度。
例如,一个神经网络权重可能表示为:
0.123456
但在实际推理过程中:
0.123456
0.12345
0.1234
这些细微差异对于最终输出影响可能非常有限。
另一方面,浮点计算对于硬件要求较高:
- 浮点运算单元复杂
- 数据存储空间大
- 内存访问带宽压力高
而很多边缘 AI 芯片针对整数计算进行了专门优化,例如:
- INT8 MAC(乘加)计算单元
- INT8 专用加速模块
- 更高的数据吞吐能力
因此,将模型转换为低精度整数形式,可以更充分利用硬件计算能力。

3. 什么是模型量化
3.1 模型参数的数值表示
神经网络本质上由大量参数组成,包括:
- 权重(Weight)
- 偏置(Bias)
- 激活值(Activation)
这些数据在计算过程中都需要使用某种数值格式表示。
常见的数据格式包括:
| 类型 | 位宽 | 示例 |
|---|---|---|
| FP32 | 32 bit | 1.234567 |
| FP16 | 16 bit | 1.234 |
| INT8 | 8 bit | 123 |
位宽越高,可以表示的数据范围和精度通常越高,但同时需要更多存储空间和计算资源。
模型量化的核心,就是将高精度表示转换为低精度表示。
例如:
diff
FP32:
0.235
-1.762
3.456
↓
INT8:
12
-89
127
转换之后,模型中的参数不再直接保存原始浮点值,而是保存对应的整数表示。
3.2 从 FP32 到 INT8 的转换
模型量化并不是简单地把小数部分删除。
例如:
0.123456
直接变成:
0
这种方式会造成严重信息损失。
实际量化过程需要建立一个浮点空间和整数空间之间的映射关系。
例如:
浮点范围:
css
[-1.0, 1.0]
整数范围:
css
[-128,127]
量化过程需要找到一个比例关系:
浮点值 = 整数值 × Scale
其中:
- 整数值表示量化后的数据
- Scale 表示整数空间和浮点空间之间的比例关系
通过 Scale,可以完成:
浮点 → 整数
以及:
整数 → 浮点
之间的转换。
3.3 量化的基本思想
从数学角度看,量化实际上是一种离散化过程。
原始浮点数据:
erlang
连续空间
0.123456
0.123457
0.123458
...
经过量化后:
erlang
离散空间
12
13
14
...
多个相近的浮点值可能会映射到同一个整数值。
因此,量化本质上是在有限表示范围内,用更少的比特表示原始信息。
它带来的收益包括:
- 存储减少
- 计算加速
- 带宽降低
同时也引入一定的信息损失。
后续文章会进一步分析这种损失产生的原因,以及如何通过 PTQ 和 QAT 方法降低影响。
3.4 量化与模型压缩的关系
模型压缩是一个较大的概念,其中包含多种方法:
模型压缩
├── 网络结构优化
│
├── 剪枝
│
├── 蒸馏
│
└── 量化
模型量化与剪枝不同:
剪枝:
删除参数
量化:
降低参数表示精度
例如:
原始模型:
100M 参数
FP32
量化之后:
100M 参数
INT8
参数数量没有变化,但是每个参数占用空间减少。
因此,量化属于一种"表示方式压缩"。
4. 常见的数据表示格式
4.1 FP32
FP32 是深度学习训练中最常见的数据格式。
特点:
- 使用 32 位表示
- 数值范围大
- 精度高
优点:
- 训练稳定
- 表达能力强
缺点:
- 存储空间大
- 计算成本高
因此,大多数模型训练阶段默认采用 FP32 或 FP16,而部署阶段通常会进一步考虑低精度表示。
4.2 FP16
FP16 使用 16 位表示浮点数。
相比 FP32:
- 存储减少一半
- 计算效率更高
目前很多 GPU 和 AI 芯片都支持 FP16 加速。
FP16 是训练和推理中常见的混合精度方案。
4.3 INT8
INT8 使用 8 位整数表示数据。
范围:
css
[-128,127]
相比 FP32:
存储:
arduino
32 bit → 8 bit
减少 75%
同时:
- 整数计算效率更高
- 更适合 AI 加速器
- 更适合边缘部署
因此 INT8 是目前最常见的部署量化格式。
4.4 不同数据类型对比
| 类型 | 位宽 | 存储大小 | 精度 | 部署特点 |
|---|---|---|---|---|
| FP32 | 32bit | 最大 | 最高 | 常用于训练 |
| FP16 | 16bit | 中等 | 较高 | GPU 推理常见 |
| INT8 | 8bit | 最小 | 有损 | 边缘部署常见 |

5. 模型量化的基本原理
5.1 浮点空间与整数空间
量化的核心,是建立两个数值空间之间的映射:
浮点空间:
diff
Real Value
例如:
-1.0 ~ 1.0
整数空间:
diff
Quantized Value
例如:
-128 ~ 127
模型量化需要找到一个转换比例,使整数能够近似表示浮点数据。
5.2 量化映射关系
最常见的量化关系:
ini
real_value = scale × quantized_value
其中:
real_value
表示原始浮点值。
quantized_value
表示量化后的整数。
scale
表示两个空间之间的比例关系。
例如:
假设:
ini
scale = 0.01
整数:
50
对应:
ini
real_value = 50 × 0.01
= 0.5
因此,Scale 就像一个"刻度尺",负责告诉系统整数值对应多少真实数值。
5.3 Scale 的概念
Scale 是量化过程中最重要的参数之一。
它决定:
一个整数单位,在浮点空间中代表多大的变化。
例如:
Scale 较小:
1 个整数变化
对应较小浮点变化
精度更高
Scale 较大:
1 个整数变化
对应更大浮点变化
精度降低
因此,Scale 的选择直接影响量化效果。
5.4 Zero Point 的概念
除了 Scale,非对称量化中还会引入 Zero Point。
完整关系:
ini
real_value = scale × (quantized_value - zero_point)
Zero Point 用于表示浮点零点在整数空间中的位置。
对于对称量化:
ini
zero_point = 0
对于非对称量化:
zero_point ≠ 0
不同硬件和工具链会根据需求选择不同量化方式。
5.5 反量化过程
模型推理过程中,通常需要将整数结果转换回近似浮点值:
INT8
↓
乘以 Scale
↓
FP32
这个过程称为反量化(Dequantization)。
例如:
ini
INT8:
100
Scale:
0.02
反量化:
100 × 0.02
=2.0

6. Scale 的计算原理
6.1 为什么需要 Scale
由于浮点空间和整数空间的范围不同,需要一个比例关系完成转换。
例如:
浮点:
css
[-2.0,2.0]
INT8:
css
[-128,127]
二者范围不同,因此需要:
ini
Scale = 浮点范围 / 整数范围
6.2 基于最大值的 Scale 计算
一种常见方式是根据数据最大绝对值计算 Scale。
假设:
浮点数据范围:
css
[-a,a]
INT8 范围:
css
[-127,127]
则:
ini
scale = a / 127
例如:
数据最大值:
lua
max(abs(x)) = 2.54
那么:
ini
scale = 2.54 / 127
≈0.02
之后:
整数值 = 浮点值 / scale
6.3 对称量化
对称量化特点:
- 正负范围相同
- zero_point = 0
例如:
ini
FP32:
[-2,2]
INT8:
[-127,127]
优点:
- 计算简单
- 更适合硬件实现
6.4 非对称量化
非对称量化允许数据范围不以 0 为中心。
例如:
ini
FP32:
[-1.2,3.5]
可以映射:
ini
INT8:
[-128,127]
它通过 Zero Point 调整两个空间的位置关系。
优点:
- 对非零中心数据更加灵活
缺点:
- 计算稍复杂
6.5 一个简单量化示例
假设:
浮点范围:
css
[-1,1]
INT8:
css
[-127,127]
计算:
ini
scale = 1 / 127
≈0.00787
浮点:
0.5
量化:
0.5 / 0.00787
≈63
得到:
ini
INT8 = 63
反量化:
63 × 0.00787
≈0.496
可以看到:
量化后的结果接近原始值,但存在一定误差。
这部分误差,就是下一篇文章重点分析的量化损失来源。
7. 模型量化带来的收益
7.1 降低模型存储空间
量化最直接的收益,是减少模型参数占用空间。
例如:
FP32:
kotlin
1 参数 = 4 Byte
INT8:
kotlin
1 参数 = 1 Byte
理论上:
erlang
模型大小降低约 75%
这对于存储空间有限的设备非常重要。
7.2 降低内存访问压力
深度学习推理过程中,大量时间消耗在数据搬运。
更低比特的数据表示意味着:
- 单次传输数据减少
- Cache 利用率提高
- 内存带宽压力降低
因此,量化不仅影响计算,也影响整个推理过程的数据流效率。
7.3 降低计算成本
许多 AI 芯片针对 INT8 进行了专门优化。
相比 FP32:
INT8 计算通常具有:
- 更高吞吐
- 更低功耗
- 更好的硬件利用率
因此,量化模型通常能够获得更好的推理性能。
7.4 提升边缘设备部署能力
对于边缘 AI 应用:
- 智能摄像头
- 工业机器人
- 自动驾驶设备
- 清扫机器人
模型量化能够降低部署门槛,使更多复杂模型可以运行在资源有限的平台上。
8. 模型量化中的关键概念总结
通过本文介绍,可以总结模型量化中的几个核心概念:
| 概念 | 含义 |
|---|---|
| 量化 | 使用低比特数据表示高精度模型 |
| FP32 | 高精度浮点表示 |
| INT8 | 低比特整数表示 |
| Scale | 浮点空间和整数空间之间的比例 |
| Zero Point | 非对称量化中的偏移量 |
| 反量化 | 将整数恢复为近似浮点值 |
模型量化的核心逻辑可以概括为:
高精度浮点模型
↓
建立量化映射关系
↓
低比特整数模型
↓
利用硬件加速推理
9. 总结
模型量化是一种面向模型部署阶段的重要轻量化技术。它通过改变模型参数和计算过程的数据表示方式,将原本使用 FP32 表示的深度学习模型转换为 INT8 等低比特形式,从而降低存储需求、减少计算开销,并提升边缘设备上的推理效率。
量化的核心并不是简单减少数字位数,而是在浮点空间和整数空间之间建立合理映射。Scale 和 Zero Point 正是连接两个空间的重要参数,它们决定了浮点数据如何转换为整数表示,以及整数结果如何恢复为近似浮点值。
从整体来看,模型量化提供了一种在模型性能和部署效率之间进行权衡的方法。它让原本面向服务器环境设计的大规模模型,具备在资源受限设备上运行的可能。