模型量化入门:从浮点模型到低比特表示

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 正是连接两个空间的重要参数,它们决定了浮点数据如何转换为整数表示,以及整数结果如何恢复为近似浮点值。

从整体来看,模型量化提供了一种在模型性能和部署效率之间进行权衡的方法。它让原本面向服务器环境设计的大规模模型,具备在资源受限设备上运行的可能。

相关推荐
枫叶林FYL1 小时前
【群体智能集群控制工程实践】第10章 无人舰队核心功能实现
大数据·人工智能·算法
不会就选b1 小时前
【无标题】
算法
m0_739312872 小时前
【自动驾驶和机器人控制】万向锁(Gimbal Lock)原理详解 + 和欧拉角 / 四元数 / SO(3)对比
算法·机器人·自动驾驶
Felven2 小时前
A. Eating Game
算法
血小板要健康3 小时前
队列 + 宽搜(BFS):二叉树层序遍历 算法总结
java·数据结构·笔记·算法·leetcode·宽度优先
Felven3 小时前
A. Riptide
算法·c 算法
m0_739312873 小时前
四元数、李群SO(3)/李代数so(3)的作用及应用场景
算法·机器人·自动驾驶
artificiali3 小时前
880 第4章多元
人工智能·算法
Felven4 小时前
B. Deja Vu
数据结构·算法