1. 量化基础:什么是模型量化、为什么需要量化、量化的数学原理

大家好,我是你们这趟量化之旅的向导。今天咱们来聊聊最基础的东西——量化到底是什么。

说实话,我刚开始接触深度学习那会儿,觉得模型量化这事儿挺玄乎的。明明训练好的模型跑得好好的,干嘛非得折腾它?后来在边缘设备上栽了几次跟头,才明白这玩意儿有多重要。

1.1 什么是模型量化?

模型量化,说白了就是给模型“减肥”。

你想想看,我们训练模型时,参数都是32位浮点数(FP32)。这就像用大卡车运货,虽然能装,但油耗也高。量化就是把32位的浮点数,变成8位甚至更低的整数(比如INT8)。

举个例子:

# 原始FP32权重
weight_fp32 = 0.72345678

# 量化后的INT8权重
weight_int8 = 185  # 映射到0-255范围

嗯,这里要注意:量化不是简单的四舍五入。它有一套完整的映射机制。

1.2 为什么需要量化?

我在项目中遇到过这么个事儿:一个视觉检测模型,在服务器上跑得飞快,精度98%。结果部署到树莓派上,直接卡成PPT,帧率不到1。客户当场就急了。

这就是量化的价值所在:

  • 模型变小:FP32转INT8,体积直接缩到1/4。32位变8位,你算算省了多少?
  • 速度变快:整数运算比浮点快得多。尤其在ARM架构的芯片上,差距更明显。
  • 功耗降低:边缘设备电池就那么点,省电就是续命。
  • 内存带宽节省:数据量小了,搬运起来自然快。

核心数据对比

指标 FP32 INT8 提升
模型大小 100MB 25MB 4x
推理速度 30 FPS 120 FPS 4x
内存占用 512MB 128MB 4x

1.3 量化的数学原理

讲原理之前,我先问大家一个问题:怎么把0到100之间的数,映射到0到255之间?

很简单,乘以2.55再取整就行。量化也是这个道理。

1.3.1 对称量化

对称量化,就是正负数对称处理。它的核心公式是:

# 对称量化公式
scale = max(|x_min|, |x_max|) / 127
x_quantized = round(x / scale)

# 反量化
x_dequantized = x_quantized * scale

我习惯用对称量化处理权重。为什么?因为权重分布通常是对称的,正负值差不多。这样量化误差最小。

个人经验:对称量化在卷积层表现特别好。我做过实验,ResNet50用对称量化,精度损失不到0.5%。

1.3.2 非对称量化

非对称量化就灵活多了。它允许零点偏移:

# 非对称量化公式
scale = (x_max - x_min) / 255
zero_point = round(-x_min / scale)
x_quantized = round(x / scale) + zero_point

# 反量化
x_dequantized = (x_quantized - zero_point) * scale

非对称量化适合激活值。为什么?因为ReLU之后全是正数,用对称量化会浪费一半的表示范围。

类型 适用场景 优点 缺点
对称量化 权重 计算简单,硬件友好 分布不对称时精度差
非对称量化 激活值 充分利用量化范围 需要额外存储零点

1.4 量化误差从哪来?

我曾经踩过一个坑:量化后模型直接崩了,输出全是乱码。排查了半天,发现是某个层的激活值范围特别大,量化时把信息都丢了。

量化误差主要有三个来源:

  • 舍入误差:浮点转整数,必然有精度损失。就像3.14159变成3一样。
  • 截断误差:超出量化范围的值被截断。比如最大值127,你非要量化128,那就只能截断。
  • 量化粒度:逐层量化还是逐通道量化?粒度越细,精度越高,但计算量也越大。

避坑指南:我曾经在MobileNet上做量化,发现深度可分离卷积对量化特别敏感。后来改用逐通道量化,才把精度拉回来。所以,不同网络结构要区别对待。

1.5 小结

量化这事儿,说白了就是一场精度和效率的博弈。你牺牲一点精度,换来的是模型体积缩小4倍、速度提升4倍、功耗降低一大截。

我个人觉得,对于边缘部署来说,这个交换太划算了。毕竟在树莓派上跑30FPS的模型,比在服务器上跑100FPS但部署不了,要实用得多。

下一章,咱们聊聊量化感知训练(QAT)的具体实现。到时候我会手把手带大家跑一个完整的量化流程。