第①篇《浅析模型量化的数学原理》回答了"量化怎么算":映射、S/Z、误差界、整数 GEMM。这一篇回答一个更本质的问题------量化引入的误差,最后都去哪了?为什么几亿个参数每个都"错一点",模型却几乎不掉精度? 内容框架与 MIT 6.5940 / TinyML(韩松)课程 Quantization 一讲的讨论一致。
本文收录于微信公众号:愤怒的代码 AngryCode
0. TL;DR
量化误差没有消失,它被四道防线层层消化:
- 误差小且互相抵消 :四舍五入最多错半个刻度(int8 的噪声幅度只有满量程的 ~0.4%),而且误差有正有负、平均为零------求和时按 √N 增长,一万个误差叠在一起,典型总误差只有"最坏情况"的 1/170。
- 网络不放大扰动 :常用激活函数都 Lipschitz 连续(ReLU 的 L=1、sigmoid 的 L=0.25),小误差逐层传播不滚雪球。
- 网络有冗余:过参数化 + 平坦极小值,训练本身就把解选在了"不怕扰动"的地方。
- 主动补偿:校准、per-channel、量化感知训练 QAT,工程手段逐一堵住上面的漏洞。
但当位宽降到 2-bit,第一道防线先垮,多米诺式的------这就是低比特掉点的算术根源。
1. 一个值得推敲的经验事实
先看现象(以图像分类为例的典型量级):
| 位宽 | 典型精度损失 |
|---|---|
| FP32 → INT8 | < 1%,常常 0.x% |
| → INT4 | 1% ~ 几个点(需 QAT/per-channel 帮忙) |
| → INT2 | 崩掉,接近瞎猜 |
天真的解释是:"量化误差很小,所以没事。"但这不完整。反过来想:一个网络有 10⁸ ~ 10⁹ 个参数,每个参数都带一点误差,乘法加法层层纠缠------"每个错一点"凭什么不是大错?
直觉上这是"雪崩"该发生的场景。但它没发生,是因为误差的统计结构和网络的数学结构恰好联手设了四道防线。 下面拆解其中的四道防线。
2. 第一道防线:误差的统计结构
2.1 误差本身小:半个刻度
第①篇《浅析模型量化的数学原理》一文中证明过:量化就是四舍五入到最近的刻度,误差被死死限制在步长的一半内:
|ε| ≤ S/2
int8 表示 [−1, 1] 的数据时 S = 1/127:
erlang
最坏误差 = S/2 ≈ 0.39% (满量程的 0.4%)
典型误差 = S/√12 ≈ 0.23%(RMS,见 2.3)
注:满量程 = 数据能取到的最大幅度(此处为 1)。用比例而不用绝对值,是因为这个百分比与数据尺度无关、只由位宽决定------不管数据是 −1,1 还是 −100,100,int8 的最坏误差都是满量程的 ~0.4%。
这是单兵的精度。但关键问题在"集团作战"------几亿个误差加起来会怎样?这取决于两件事:均值 和相关性。
2.2 误差的均值是零:抵消的前提
四舍五入有一个对称性质:一个值落在某个刻度附近时,向上取整错多少、向下取整错多少,机会均等。只要输入数据足够"铺得开",量化误差就在 [−S/2, S/2] 上均匀分布,它的概率密度函数(PDF)是:
scss
⎧ 1/S, ε ∈ [−S/2, S/2]
f(ε) = ⎨
⎩ 0, 其他
PDF 的含义:密度恒为 1/S(= 1 ÷ 区间长度,保证总面积 = 1),误差落在区间内任何等长小段上的概率相等。有了 PDF,两个统计矩就是两个积分:
scss
E[ε] = ∫ ε·f(ε) dε = (1/S)∫_{−S/2}^{S/2} ε dε = 0 (奇函数在对称区间上积分为零)
Var(ε) = ∫ ε²·f(ε) dε = S²/12 (逐步积分见《浅析模型量化的数学原理》)
零均值是整道防线的基石:它意味着误差不是"都往一个方向偏",而是"有的偏大、有的偏小"。这一点看起来平淡,威力在下一步爆发。
反面教材:如果零点 Z 算得不准(比如非对称量化时 Z 四舍五入得太粗糙),整层输出会整体偏移一个常数------这就是系统误差,均值为零的假设被破坏,抵消失效。这也是为什么 Z 必须精确到整数、为什么校准要花功夫。
2.3 抵消的数学:√N 而非 N
N 个独立零均值误差求和,方差相加:
scss
Var(ε₁ + ε₂ + ... + ε_N) = N · S²/12
⟹ std(Σ εᵢ) = √N · S/√12
注意:最坏情况是 N·S/2 ,而典型情况只有 √N·S/√12。最坏情况从哪来?两步推导:
ini
第一步:单个误差有天花板(2.1 节证明过)
|εᵢ| ≤ S/2
第二步:三角不等式------和的绝对值 ≤ 绝对值的和
|ε₁ + ... + ε_N| ≤ |ε₁| + ... + |ε_N| ≤ S/2 + ... + S/2 = N·S/2
它不是新结论,只是把 N 个单兵天花板全部相加。等号成立条件:每一项都取到最大、且全部同号 ------"最倒霉 + 最齐心"。现实中这几乎不靠运气发生:N 个零均值随机误差全部同号的概率是 (1/2)^(N−1) 量级(N=30 时约十亿分之二);真正会触发"全体同号"的不是运气,而是系统性偏置(如 5.2 节的零点 Z 差一个刻度)。
所以两个数分工明确:N·S/2 是保证性上界 (无论误差怎么取都不会超过,防御性编程用它);√N·S/√12 是统计典型值(零均值、近似独立时的实际水平)。两者的差距就是"抵消"的价值。差距有多大?
| N(叠加的误差数) | 最坏情况 | 典型情况(std) | 典型/最坏 |
|---|---|---|---|
| 100 | 50·S | 5.8·S | ~1/8.6 |
| 10 000 | 5 000·S | 28.9·S | ~1/173 |
| 1 000 000 | 500 000·S | 289·S | ~1/1730 |
N 越大,抵消越彻底 ------误差增长是亚线性的(√N),而信号本身随 N 线性增长。这意味着点积越长、卷积核越大,量化误差的相对影响反而越小。
一个类比:一万个人每人随机向左或向右挪一步,人群整体挪多远?不是一万步,是约一百步(√10000)。随机方向互相踩掉,只有"同方向"(系统误差)才可怕。
说明 :√N 假设各误差独立。同一层的误差来自同一把尺子 S,严格说不完全独立;但实践上,只要均值确实为零、没有强相关的系统分量,抵消效应依然显著。真正会毁掉这道防线的是"全体同号"------那是系统误差,见 2.2 的反面教材和第 7 节。
2.4 小结第一道防线
scss
单兵: |ε| ≤ S/2 (小)
集团: E[ε]=0 ⟹ std(Σε) = √N·S/√12 (抵消)
条件: 没有系统误差(Z 要准、S 要贴合分布)
到这一步,我们知道了误差"进"网络时的模样。但它要穿过几十层网络才能到达输出------传播过程中它会不会滚成雪球?
3. 第二道防线:网络不放大扰动(Lipschitz 连续)
3.1 问题的形式
设第 ℓ 层的输出被量化污染了一个小量 Δ。这个 Δ 进入第 ℓ+1 层,经过线性变换 W·x 和激活函数 φ。问:出来的扰动是更大还是更小?
css
干净的链: x → [W₁,φ₁] → [W₂,φ₂] → ... → 输出
被污染的链:x → [W₁,φ₁] → [W₂,φ₂] → ... → 输出
↑每层都多喂进一点量化误差
如果每层都"放大一点",几十层下来就是指数爆炸;如果每层"不放大甚至收缩",误差就传不远。决定这件事的性质叫 Lipschitz 连续。
3.2 Lipschitz 连续:扰动的"放大器上限"
函数 f 是 L-Lipschitz 连续 的,若存在常数 L ≥ 0,对任意 x, y:
scss
|f(x) − f(y)| ≤ L · |x − y|
读法:输入变多少,输出最多变 L 倍,绝不超过 。L 就是这台"放大器"的增益上限。对可导函数,L 就是导数最大绝对值 L = sup|f'(x)|。
sup读"上确界",可粗读为全定义域上的 max------|f'(x)|是每一点的陡度(绝对值:上冲和下坠都放大扰动,方向无关),sup把它们压成全局唯一的天花板:整条曲线上最陡一处的斜率 。用它而不用 max,是因为最大值在无界域上可能取不到,而 sup 总存在(取得到时两者相等;若sup|f'| = ∞则函数不是 Lipschitz 的)。
逐个检查神经网络常用的函数:
| 函数 | 导数范围 | Lipschitz 常数 | 对扰动 |
|---|---|---|---|
ReLU(x) |
0 或 1 | L = 1 | 不放大 |
sigmoid(x) |
(0, 0.25] | L = 0.25 | 最多缩 4 倍 |
tanh(x) |
(−1, 1) | L = 1 | 不放大 |
f(x)=2x |
2 | L = 2 | 放大 2 倍 |
x² |
2x,无界 | ✗ 不 Lipschitz | 离 0 越远越猛 |
ReLU 数值例子(L=1 的含义):
scss
1.0 → 1.1(扰动 0.1):|ReLU(1.1)−ReLU(1.0)| = 0.1 不放大
−1.0 → −0.9(扰动 0.1):|ReLU(−0.9)−ReLU(−1.0)| = 0 缩成零(负半轴抹掉)
关键事实:深度网络最常用的激活函数,Lipschitz 常数全部 ≤ 1------它们天生不放大扰动。 若激活函数像 x² 那样导数无界,量化误差会被逐层疯狂放大,量化根本不可行。深度学习能被量化,一半功劳在激活函数的"性格"。
3.3 误差为什么传不远:逐层的账
完整一层的放大倍数 ≈ ‖W‖ · L_φ(‖W‖ 是权重矩阵的谱范数,即最大奇异值;L_φ 是激活函数的 Lipschitz 常数)。L 层网络的总放大倍数是逐层乘积:
总增益 ≤ ‖W₁‖·L₁ × ‖W₂‖·L₂ × ... × ‖W_L‖·L_L
两个因素在其中角力:
- 激活函数在收缩(L ≤ 1),尤其 sigmoid/tanh 区段收缩得厉害;
- 权重矩阵可能放大(‖W‖ > 1)。
纯 sigmoid 的深链是个极端例子:10 层下来扰动缩到 0.25¹⁰ ≈ 10⁻⁶------百万分之一。真实网络(ReLU 为主)里,权重的放大作用和误差方向的随机性互相制衡,经验上不会指数爆炸,但也不是每层都收缩------个别层会显著放大误差。
这个"个别层敏感"的事实很重要:它解释了为什么均匀给所有层同一精度并不是最优的,也正是后面 HAWQ 混合精度系列要精确度量每层敏感度(Hessian)的动机。
4. 第三道防线:结构冗余------过参数化与平坦极小值
前两道防线是"数学运气",这一道是结构的慷慨。它有两个支柱:训练天然落在平坦极小值(flat minima) ,以及网络参数远超所需(过参数化)------两者共同构成吸收残余扰动的冗余。
4.1 flat minima:训练早就替你选好了位置
先补一块地基:训练到底在做什么?
训练需要一个打分标准:损失函数(loss) ------拿一组参数给网络,喂一批训练数据,用一个数字给"它这次错得有多离谱"打分。损失越低 = 预测越准。于是训练的目标非常明确:调节几百万个参数(想象成几百万个旋钮),让损失尽量小------用地形的话说,就是找到低海拔的位置。
把每个参数组合对应的损失值想象成海拔 ,所有可能的组合就构成一片起伏的地形 。常用算法叫 SGD(随机梯度下降),它的下山方式像蒙着眼下山的人:
每一步:
① 感受脚下的坡度(梯度:哪个方向最陡)
② 朝最陡的反方向迈一小步(海拔下降一点点)
重复几百万步,直到几乎走不动
为什么要走几百万步,又为什么会停下? 两个机制:
- 每步只能走一小段:蒙眼的人只感觉得到脚下的局部坡度,看不见全图;步子迈大会跨过谷底摔上对面坡,所以步长必须小(这个步长叫学习率,训练后期还会主动调小)。几百万个旋钮的迷宫,只能一步一步蹚。
- 谷底会自动"刹车" :越接近谷底,地面越平、坡度越小,每步能下降的高度就越少;坡度趋近零时基本挪不动了------人自然停在某个低谷的谷底。
停在谷底的那组参数,就是训练好的模型。需要注意的细节是:训练保证的是找到一个低谷(局部极小值),并不保证是全图最低点。而停下的这个低谷是尖是平------正是量化命运的开关。
关键来了:低谷有两种形状("挪动"= 改参数,"海拔"= 错误率):
markdown
尖锐低谷(sharp): \/ 谷底很窄:挪半步就撞上陡壁 → 错误率猛涨
平坦低谷(flat): \____/ 谷底宽阔:挪几步海拔几乎不变
现在接回量化:量化正是"把每个权重从训练终点推开一点"------推开最多半个刻度(2.1 节)。于是:
- 终点若在尖锐低谷:推开一点就上陡壁,错误率猛涨 → 量化必掉点;
- 终点若在平坦低谷:推开一点还在谷底平台上,错误率几乎不变 → 量化免疫。
那训练到底落在哪种低谷里?这不是拍脑袋的猜测------学界从 1997 年(Hochreiter 和 Schmidhuber 的《Flat Minima》一文)开始研究这个问题,此后的实验反复确认:SGD 的随机性让训练偏爱平坦低谷。直觉:下山的人一路带着随机晃动(每次只用一小批数据估方向),又窄又尖的缝根本留不住他,只有足够宽敞的盆地才停得住。所以训练收敛到的解,大概率天生就是"抗扰动体质"。
某种意义上,训练过程早就把网络调成了"不怕扰动"的状态,量化只是顺手享受了这个红利------这也是量化与 dropout、混合精度训练等其他"扰动技术"能和平共处的原因:大家都只在宽谷的平底上溜达。
4.2 过参数化:参数比任务需要的多
事实 :现代网络严重过参数化。这不是拍脑袋的断言,而是被剪枝实验反复验证的结论:训练好的网络可以剪掉约 90% 的参数而精度几乎不掉(Han et al. 2015:AlexNet 剪 89%、VGG-16 剪 93%;Frankle & Carbin 2019 的"彩票假说"进一步发现稀疏子网络单独训练也能达到全网水平)。能砍掉九成而不掉点,说明那九成本来就是冗余的"备份"------一个千万参数的分类器,真正承载任务的信息远小于参数量。
一个不严格的类比:合唱团里有一个人唱偏了半度,整个团的音准几乎听不出变化 ------因为每个声部都有十几个人,个体的偏差被集体平均掉了。量化误差就是那个"唱偏半度的人":单看每个权重确实错了,但网络的功能是全体权重共同实现的,个体的偏差被群体的冗余吸收。
信息论视角的另一种说法:网络学到的是数据的统计规律,不是权重的逐个清单。规律的载体可以有很多种(这就是为什么剪枝、蒸馏、低秩分解也都有效)------量化只是把"载体"换成了更粗糙的版本,规律本身还在。
但冗余有边界 :它能吸收随机方向的小扰动 ,吸收不了全体一致的大偏移。这再次呼应 2.2------零均值抵消为什么是生死攸关的前提。
5. 第四道防线:主动补偿
前三道是"天资",这一道是工程上的主动出击。四个手段,每个都精确对应前文指名的一个破绽------本节把机制展开。
5.1 校准:把步长 S 选在总误差最小的位置
堵的漏洞:S 被 outlier 撑大,单兵误差无谓变大(防线一)。
min-max 全覆盖(S = (r_max − r_min)/(q_max − q_min))对 outlier 零容忍:若 99.9% 的值挤在 [0, 0.5]、只有一个 6.0,S 就被撑大 12 倍,所有人的量化误差跟着放大。
更聪明的做法:故意裁掉少量极端值,换取更小的步长 。设对称裁剪阈值 T(S = T/q_max),T 的选取是一个最优化问题,两条准则:
① MSE 准则 :总误差 = 裁剪误差(超出 T 的值被硬夹到端点,误差无界)+ 量化误差(S²/12,T 越小 S 越小、它越小):
r
T* = argmin_T [ 裁剪误差(T) + S(T)²/12 ]
T 太小 → 裁剪误差大;T 太大 → S 大、量化误差大。最优 T 平衡二者------这就是 2.1 节"单兵误差"背后真正的自由度。
② KL 散度准则(TensorRT 的 entropy calibration):
css
KL(P ‖ Q) = Σᵢ P(i)·log( P(i)/Q(i) ) ------ 用 Q 近似 P 时的信息损失
流程分两步。第一步,采集直方图 :激活值依赖输入,不喂真实数据就不知道它们的分布,所以先拿几百~几千张有代表性的真实样本喂进网络,只做前向传播 (输入逐层算到输出,不训练、不反向传播),途中把每层激活值全部记录下来,做成直方图 P(约 2048 个 bin)------这个"带记录的推理"也正是"训练后量化(Post-Training)"名字里"训练后"的含义。第二步,遍历候选阈值 T :饱和合并成参考分布、再合并成 128 个 level、均匀展开回去,算 KL(参考分布 ‖ 展开后),选 KL 最小的 T。KL 准则自动权衡"饱和丢尾巴"与"合并丢分辨率":
- 集中分布 + 细尾巴 → KL 选小 T(尾巴质量占比小,裁掉几乎不丢信息);
- 平缓分布 → KL 选大 T(没有可牺牲的尾巴,保住分辨率)。
数据从哪来:权重的 S 离线一次算完;激活依赖输入,用几百~几千张代表性样本跑前向统计分布------这就是训练后量化(PTQ,Post-Training Quantization)里"校准"的全部含义。
5.2 精确的 Z:堵住系统误差
堵的漏洞:整层输出整体偏移 → 误差均值 ≠ 0 → 第一道防线的抵消失效(零均值假设被破坏)。
激活常非负(如 ReLU 后),需要非对称量化,多一个零点参数:
ini
S = (r_max − r_min) / (q_max − q_min)
Z = round( q_min − r_min/S )
Z 的角色:实数 0 在整数轴上的位置。它必须是整数(与 q 同型),才能用整数减法完成"归零"。
Z 不准的后果是灾难性的:若真实偏移与 Z 差了 1 个刻度,整层输出平移 S------所有误差同号 ,这正是 2.3 节表格里"最坏情况"的形状:误差从 √N·S/√12 恶化到 N·S,√N 抵消完全失效。这就是"精确的 Z"值得单独立一条的原因。
5.3 per-channel:不让 outlier 通道绑架尺子
堵的漏洞:一个 outlier 通道把全张量的 S 撑大(防线一:分而治之)。
先明确"输出通道":卷积权重形状 [C_out, C_in, K_h, K_w],每个滤波器产生一张输出特征图------per-channel 就是每个输出通道(滤波器)一套 S,全连接层即每行一套。
数字例子:权重张量 [64, 3, 3, 3]:
css
通道 3 权重范围 [−0.01, 0.01] ← 都很小
通道 7 权重范围 [−0.5, 0.5] ← outlier 通道
per-tensor:S 必须覆盖 ±0.5 → S ≈ 0.004
通道 3 的 ±0.01 只剩约 ±2.5 个刻度 → 信息几乎丢光
per-channel:通道 3 用 S ≈ 8×10⁻⁵,小值被精细保留
通道 7 用 S ≈ 0.004,照常覆盖
各用各的尺子,谁也不拖累谁。代价是元数据:这一层要存 64 对 S/Z(约 0.17% 开销),几乎免费------这是卷积权重的事实标准。
5.4 量化感知训练(Quantization-Aware Training,QAT):让网络长在量化格点上
堵的漏洞:位宽太低时误差太大,前三道防线压不住------干脆让网络在训练里适应量化。
QAT 用伪量化节点(fake quant)解决"round 不可导"的矛盾------前向装真量化,反向开假梯度:
ini
前向(量化 → 反量化,把值摁到格点上):
q = clamp( round(x/S + Z), q_min, q_max )
x_fake = S·(q − Z) ← 还是 float,但取值只能在格点上
反向(STE:Straight-Through Estimator):
∂x_fake/∂x ≈ 1 ← 假装 round 的导数是 1,梯度照常下传
数值例子:S = 0.1,x = 0.37:t = 3.7 → round = 4 → x_fake = 0.4。前向网络看到的是 0.4(带量化误差),梯度却照着 0.37 往下传------底层真实权重被持续优化,收敛到"即使被摁到格点也照样工作"的状态。
伪量化节点插在权重和激活两处;训练完拆掉节点,部署时做真 int8。训练时"演"量化,部署时"真"量化------4-bit 甚至更低也能保住精度。
训练到什么时候算完? STE 不改变收敛判断------QAT 就是普通 SGD 训练,只是前向带着量化。实践看四个信号:① 训练损失曲线走平;② 验证集精度连续多个 epoch 不再提升;③ fake-quant 精度达标且稳定 (与 FP32 基线的差距收窄到可接受,如 <0.5%)------这是 QAT 特有且最重要的一条:伪量化节点在前向,训练时监控的曲线本来就带量化噪声,收敛它 = 量化后的表现稳定;④ 学习率已衰减到很小且指标仍稳。至于"是否到了严格局部最优"(梯度范数 ≈ 0)------百万维非凸地形里既无法验证,也不必要:我们要的不是谷底那个点,而是 4.1 节说的平坦盆地,而 STE 的梯度噪声反而像下山人的随机晃动,帮着训练停进宽阔的区域。
5.5 小结:各手段与漏洞的对应
| 补偿手段 | 堵住的漏洞 | 对应的防线 |
|---|---|---|
| 校准(MSE / KL 选 T) | S 被 outlier 撑大 → 量化误差无谓放大 | 防线一(误差变小) |
| 非对称量化 / 精确的 Z | 整层输出系统性偏移(均值 ≠ 0) | 防线一(保证抵消前提) |
| per-channel 量化 | outlier 通道影响整把尺子 | 防线一(分而治之) |
| QAT(伪量化 + STE) | 低比特下误差太大,网络需要"学会适应" | 全部(训练期主动免疫) |
一句话:前三个手段保证"误差进入网络时的性质"(小、零均值、无异常值),QAT 则干脆让网络在训练里就长在量化格点上。
6. 算总账:为什么 8-bit 稳、4-bit 悬、2-bit 崩
四道防线不是并联而是串联------总效果是各级抑制的叠加。位宽下降时,看看防线怎么依次失守。
位宽每降 1 bit,步长 S 大约翻倍,SQNR 掉 6.02 dB(见《浅析模型量化的数学原理》§5.3 的推导)。对 [−1,1] 的均匀信号:
| 位宽 | 刻度数 | 最坏误差 |ε|≤S/2 | 典型误差 S/√12 | 体感 |
|---|---|---|---|---|
| int8 | 256 | 0.39% | 0.23% | 噪声不可闻 |
| int4 | 16 | 6.3% | 3.6% | 需要补偿 |
| int2 | 4(±1,0) | 50% | 28.9% | 噪声与信号同量级 |
int8 为什么稳:误差 ~0.4%,四道防线全部满员------抵消把它再压低一个量级,Lipschitz 不放大,冗余吸收残余。四道防线叠下来,精度损失 <1% 完全合理。
int4 为什么悬:误差涨到 6%。抵消、不放大、冗余这些机制还在,但它们能消化的误差有上限,不是无限。此时必须启动第四道防线主动增援------per-channel、分组量化、QAT 上场,把误差重新压回去。这也是 4-bit 量化研究全在做的事。
int2 为什么崩 :最坏误差 50%,典型 29%------噪声和信号一个量级,抵消救不了(√N 抵消的是"求和里的随机分量",但每个乘积项本身的信噪比已经崩了);2-bit 的极端粗糙也常破坏"误差均匀/零均值"假设(数据挤在少数几个刻度上,误差出现相关性)。第一道防线先垮------误差既不再小、也不再零均值,抵消彻底失效,多米诺。
这个视角还给了一个工程判断工具:量化掉点时,先问是哪道防线破了------是 S 选差了(校准问题)、Z 偏了(系统误差)、某几层 outlier(粒度问题),还是单纯位宽太低(需要 QAT/混合精度)。对症下药,而不是笼统地"量化不行"。
7. 边界:量化什么时候真的会掉点
理论讲完,列出四道防线的已知"破绽",也是实践中掉点的四大来源:
- Outlier 激活(LLM 重灾区):个别通道的激活值异常巨大,把全张量的 S 撑大几百倍,其余通道误差被无谓放大------防线一被劫持。解法:per-channel/per-group、outlier 分离处理。
- 系统误差:Z 不准、round 策略偏向一侧、非对称分布硬用对称量化------误差均值 ≠ 0,第一道防线的抵消前提失效。
- 超深网络 / 级联结构:层数极深或误差沿主通路无衰减传播时,逐层乘积仍可能累积------第二道防线不是无限保险,敏感层需要更高精度。
- 分布偏移:校准集和真实输入分布不一致,S 选错区间------防线四的补偿建立在错误的统计上。
每一道防线都对应一类失败模式,也对应一类解法。 这张对照表是本篇最实用的产出。
8. 总结
ini
第一道(统计): |ε| ≤ S/2,E[ε]=0,std(Σε) = √N·S/√12 ------ 误差小且互相抵消
第二道(传播): ReLU L=1,sigmoid L=0.25 ------ 误差逐层不放大
第三道(结构): 过参数化 + flat minima ------ 冗余吸收残余扰动
第四道(补偿): 校准 / per-channel / QAT ------ 主动堵住每个漏洞
量化的精度保全不是单一机制,而是一套纵深防御:误差进来时小、叠加时互相抵消(防线一),传播时不放大(防线二),残余被冗余与平坦极小值吸收(防线三),最后还有工程手段兜底(防线四)。8-bit 时四道全在,4-bit 时靠增援续命,2-bit 时第一道垮、全线崩------整个"量化精度"的故事,就是这四道防线的攻防史。
总结:
量化就是用更粗的刻度尺重新记录数字,四舍五入必然带一点误差。但误差很小、有正有负、平均为零,几千个加在一起时大部分互相抵消;常用激活函数还有个数学性质,输入的小误差传到输出不会被放大------前两条靠数学运气。第三条靠结构的慷慨:网络参数远超所需,训练又天然停在平坦的谷底,个别权重偏一点,整体几乎不受影响。第四条靠人努力:校准会挑误差最小的刻度尺,量化感知训练让网络提前适应粗刻度。四道防线叠下来,误差被压得很低,所以精度几乎不掉。
参考文献
- Hochreiter, S., & Schmidhuber, J. (1997). Flat Minima. Neural Computation, 9(1), 1--42. ------ "平坦低谷更抗扰动"概念的源头文献(见 §4.1)。
- Han, S., Pool, J., Tran, J., & Dally, W. J. (2015). Learning both Weights and Connections for Efficient Neural Networks. NeurIPS 2015. ------ 剪枝实验:AlexNet 可剪 89% 参数几乎不掉点(见 §4)。
- Frankle, J., & Carbin, M. (2019). The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks. ICLR 2019(最佳论文)。 ------ 稀疏子网络可复现全网性能(见 §4)。
- MIT 6.5940 / TinyML and Efficient Deep Learning Computing(EfficientML.ai),韩松(Song Han),MIT:efficientml.ai 。