端侧 AI · 15 天工程路线
目录首页 English
DAY 03

模型量化

用更少的 bit 换取更低的存储与带宽

建议阅读:约 19 分钟

学习目标

掌握对称/非对称量化、scale/zero-point,并能判断误差来源。

本章关键词

关键词解释ESP32 工程类比
Scale整数码与真实数值之间的比例系数。像 ADC 的量程和每个码的物理含义。
Zero-point映射中代表真实零值的整数偏移。像传感器零偏校正后的基准码。
校准集用于估计激活范围的代表性输入样本。像用真实工况标定 ADC,而非只输入中间值。
Per-channel为不同权重通道分别使用量化参数。像为不同传感器通道分别做增益标定。

承上:回顾与定位

上一章建立了从训练状态到模型包的交付契约;本章开始改变数值表示,用可测误差换取存储、带宽和 kernel 机会。

从源头看今天

历史发展脉络

神经网络量化并非简单追随移动芯片而出现。早期数字与模拟神经硬件就必须面对有限字长;深度学习扩大模型后,研究从“有限精度能否工作”转向压缩、低比特训练与整数算子协同设计。今天的 PTQ、QAT、per-channel 和代表性校准,是数十年精度—存储—硬件权衡的工程化结果。

1990

有限字长被作为神经计算的系统设计问题

Neural Network Number Systems 比较了数字神经网络中的定点、浮点和指数数值表示。早期工作已经意识到,位宽选择同时影响电路成本、动态范围和计算误差,而不是单纯更换文件 dtype。

Neural Network Number Systems 原始论文记录 ↗
2015

Deep Compression 把量化放进完整模型压缩流水线

Deep Compression 将剪枝、训练后权值共享式量化和 Huffman 编码组合,展示模型存储与内存访问可大幅削减。它强化了一个工程事实:压缩方案必须连同编码开销、解码路径和目标硬件一起评估。

Deep Compression 原始论文 ↗
2016–2017

低比特权重与激活进入训练过程

Quantized Neural Networks 在前向和反向计算中引入低精度权重与激活,并研究极低 bit 表示。量化不再只是模型训练完成后的包装,而可以在训练时显式暴露误差,让参数适应离散码本。

Quantized Neural Networks 原始论文 ↗
2018

整数算术从输入贯穿到输出

Jacob 等人给出面向整数算术推理的量化方案与训练流程,同时量化权重和激活,并处理比例因子、zero-point 与累加。算法设计开始明确对接 ARM CPU 和整数加速器,而非只报告文件缩小。

CVPR 整数推理原始论文 ↗
2020s

PTQ 校准成为端侧工具链的标准阶段

LiteRT 的全整数量化流程使用代表性数据估计输入与中间激活范围,并允许把模型 I/O 也设为整数。当前实践因而强调校准数据、算子覆盖和目标硬件实测,而不把 int8 标签当作性能保证。

LiteRT 全整数量化官方教程 ↗
今天为什么仍然重要: 发展脉络从“有限精度是否可用”走到“训练、格式、kernel 与芯片共同设计”。在 ESP32 一类平台上,正确问题不是浮点能压成几 bit,而是目标 ISA 支持什么量化轴、累加位宽与算子组合,以及校准样本是否覆盖真实传感器的长尾范围。
借熟悉的系统建立直觉

类比图解

把连续山景印成一张只有有限色阶的版画

摄影师拥有层次丰富的原片,但印刷机每种颜色只有有限档位。制版师先观察整组照片的最暗与最亮区域,再决定每一格色阶覆盖多大范围;落在两格之间的颜色要舍入,超出纸张量程的高光和阴影只能压成同一个极值。分色制版则像为每个通道单独选量程。

原始山景 连续或高精度的 float 权重与激活
有限调色板 整数码本及由 scale 决定的格距
分色版 per-channel 为不同输出通道选择量化参数
高光溢出 超出校准范围的数值被 clip 后不可恢复

类比的边界: 图像色阶主要诉诸视觉感受,模型误差却会在多层算子中累积,并以任务指标而非“看起来相似”衡量。真实整数 kernel 还涉及偏置尺度、int32 累加、requantize 和硬件指令,版画类比无法说明这些算术约束。

本章讲解

先从可逆近似公式看清三个误差入口

仿射量化用 q=round(x/scale)+zero_point,再把 q 限制到整数范围;反量化只得到格点上的近似值。误差分别来自格距造成的舍入、范围不足造成的饱和,以及统计范围被异常值拉宽后的分辨率浪费。实现时应分别统计量化 MSE、上下界命中率与零点映射,三者混成一个准确率数字很难定位。

对称、非对称与 per-channel 是后端契约选择

对称量化通常令 zero-point 为零,乘法路径更简单;非对称量化能更充分利用偏斜分布的整数范围。per-channel 可为每个输出通道设置 scale,常能缓解权重通道间幅度差异,却要求 kernel 知道量化轴并加载多组参数。选择前应查询目标 runtime 的 dtype、轴和算子限制,不能只凭 PC 精度。

校准不是抽几张“典型图”,而是覆盖激活状态空间

权重范围可以直接扫描,中间激活却由输入和前置层共同决定。代表性数据应覆盖光照、静默、饱和传感器、类别边界和设备噪声,并沿真实前处理进入模型。可按层查看直方图与裁剪比例,发现少量离群值是否支配 scale;若生产分布改变,原校准表也应视为需要重新验证的版本化资产。

整数卷积仍需要高位累加与正确的尺度接力

int8 输入与 int8 权重的乘积通常进入更宽的累加器,偏置尺度应与输入 scale×权重 scale 对齐,输出再经 multiplier、shift 或等价操作 requantize。任何一处零点补偿、舍入规则或饱和次序不同,都可能造成系统偏差。用极小矩阵手算累加与边界值,是验证自定义 kernel 最有效的单元测试之一。

把精度回归与性能验收放在同一张层级报告里

先比较 float 与量化模型的最终任务指标,再对输出漂移最大的样本逐层定位 SQNR、余弦相似度或最大绝对误差;同时从 profile 检查是否出现 Quantize/Dequantize 岛和 float fallback。若文件缩小却执行更慢,问题可能是缺少整数 kernel、布局转换或频繁重标度,而不是量化算法本身失败。

让数据真正跑起来

动态过程演示

浮点波形如何落入 256 个整数格

动画先伸缩一把覆盖实测数据的标尺,再让每个浮点点吸附到最近格位;超界点会撞上红色挡板,随后整数流进入累加器。

步骤 1 / 6

扫描分布 · activation samples → min/max/histogram

样本点铺开成直方图,长尾以另一颜色标出

观察点

激活范围必须由代表性真实输入估计

循环 / 返回条件: 若误差或饱和超限,播放器回到分布扫描,可切换校准样本、量化轴或范围策略;若性能不达标,则回到整数 kernel 检查 fallback 与转换边界。

查看静态全景图
float x ──(x/scale)+zp──► int8 q ──runtime kernel──► int8/float output

代码或命令示例

q = round(x / scale + zero_point)
q = clip(q, -128, 127)
x_hat = (q - zero_point) * scale

动手实验

写一个 numpy/Python 量化器,比较 per-tensor 与 per-channel 的 MSE,并找出饱和比例。
实验记录与导出

工程陷阱

避免误判: 量化为 int8 不保证更快:若目标后端没有 int8 kernel,或频繁插入 dequantize/quantize,转换开销可能抵消收益。

核心测试

完成 3 道单选题后提交;提交前不会显示答案。

1. 全整数量化为何需要 representative dataset?
2. 量化饱和最接近 ADC 的哪种问题?
3. ESP-DL 文档中 ESP32 与 ESP32-S3 常使用的策略是?

一起把本章讲清楚

在 GitHub 上讨论本章

登录 GitHub 后提问、补充实测或分享你的实现;评论会保存在本课程的 GitHub Discussions 中。

评论区需要 JavaScript;也可以直接打开 GitHub 讨论区: 打开 GitHub 讨论区 ↗

延伸阅读

启下:下一章如何使用本章能力

下一章沿算子契约进入 layout、tiling、fusion 与硬件 kernel。

下一天: Day 4 · 算子与 Kernel