出差前收拾行李箱:羽绒服蓬松地摊开,几乎占掉半个箱子;可一旦装进真空压缩袋,立刻变成薄薄一块。衣服还是那件衣服,只是把“空气”(多余的精度)挤掉了,穿起来多了几条褶子而已。手机就是一只迷你登机箱,动辄几百 MB 的大模型是那件羽绒服——不压缩,根本放不进去。 “量化”做的正是这件事:把模型里用 32 位浮点数(FP32)书写的参数和中间结果,改写成 8 位甚至 4 位整数(INT8/INT4)。数值还是那些数值的“近似”,但存储体积、内存带宽、计算能耗统统缩小数倍。于是语音唤醒、人像分割、端侧大模型这些 AI 功能,才能挤进手机、耳机、摄像头这些“小箱子”里。这篇文章,我们跟着一位“出行收纳师”的视角,从压缩袋上的刻度讲到机场安检,把移动端量化的原理、算法和工程坑位一次讲透。

岗位关联

量化是端侧部署的第一张“登机牌”。掌握它,你就能把云端的庞然大物塞进用户口袋,这是 AI 从“能演示”到“能商用”的分水岭。

目录
  1. 可视化演示
  2. 量化基本概念
  3. 硬件算力基础
  4. 核心量化算法
  5. 校准与误差
  6. 量化范式对比
  7. 性能优化策略
  8. 工程实战部署
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示FP32到INT8量化映射原理、PTQ与QAT流程对比及量化后推理加速效果,步进切换查看移动端量化核心机制。

本节配有交互动效(进入视口后自动加载,约 3KB)。

量化映射:FP32到INT8线性变换 scale和zero_point将浮点范围映射到0-255 反量化时q乘scale加zero_point恢复近似值 q = round(x/scale) + zp 对称量化zp=0非对称量化含零点偏移

量化基本概念

收拾行李的第一步,是认清每件物品的“原包装”。模型里的每个参数,默认都穿着 32 位浮点数这件“厚重外套”——它能表达从 1.4e-45 到 3.4e38 的几乎所有数字,细致到小数点后七位,代价是每个数占 4 字节。手机这只小箱子,可没那么多地方。

所谓量化,就是把这些连续的浮点数,映射到一排“预制格子”里。比如 INT8 只有 256 个格子(0~255),INT4 只有 16 个。每个浮点数按“取最近原则”塞进某一格,格的编号就是机器里真正存的数。于是有了两个关键概念:数值精度(FP32/FP16/INT8/INT4 的位宽,决定格子总数)和量化类型(按对象分:只压权重叫权重量化,连中间计算结果一起压叫激活量化;按时机分:训练后量化与量化感知训练,后面细讲)。模型体积与位宽成正比:

把位宽从 32 降到 8,箱子立刻缩到四分之一——羽绒服一压,登机箱就能合上了。当然,衣服版型会变“粗”一点,这就是精度换体积的代价。

模型体积(字节)=参数量×位宽8\displaystyle \text{模型体积(字节)} = \frac{\text{参数量} \times \text{位宽}}{8}
公式解读:一件行李,件数 × 每件的包装厚度 = 总体积。
  1. 参数量模型里待存储的数值个数,相当于行李的总“件数”,包括权重和偏置。
    参数量=∑层(权重数+偏置数)\text{参数量} = \sum_{\text{层}} \left( \text{权重数} + \text{偏置数} \right)
  2. 位宽每个数值用多少比特来表示,相当于每件行李的包装层数。
    位宽∈{32,16,8,4}\text{位宽} \in \{32, 16, 8, 4\}
  3. 除以 8把比特换算成字节,因为 1 字节 = 8 比特。
    1 字节=8 比特1\ \text{字节} = 8\ \text{比特}

硬件算力基础

机场规定登机箱限 20 寸、限重 7 公斤,这就是硬规则。手机的“行李规则”由芯片定:手机里不只有 CPU 一个“搬运工”,GPU 擅长并行图形运算,NPU(神经网络处理单元)则给低比特整数乘法开了“绿色通道”——一次能吞吐海量 INT8 运算,同样的电路跑 FP32 往往只有几分之一。所以在 NPU 上,INT8 不只是省内存,更是“踩中了硬件最擅长的步点”。

但算得快不快,还取决于另一个瓶颈——内存带宽。模型每算一个数,都要先从内存“搬”到计算单元;手机的内存带宽通常只有几十 GB/s。如果计算速度快于搬运速度,整体就卡在“等数据”上,这叫访存受限。此时压缩体积(量化)的收益最大。算法工程师常用“计算访存比”来判断瓶颈在哪:

手机的算力单位常用 TOPS(每秒万亿次运算),能效比用 TOPS/W 表示。INT8 把访存量降为四分之一,对访存受限的层几乎“搬多快就快多快”。

计算访存比=运算量(FLOPs)访存量(字节)\displaystyle \text{计算访存比} = \frac{\text{运算量(FLOPs)}}{\text{访存量(字节)}}
公式解读:传送带(带宽)太窄时,把每件行李做小,搬运时间立刻缩短。
  1. 运算量(分子)完成一次推理需要的浮点运算次数,比如卷积中乘加次数之和。
    FLOPs≈2×输出元素数×卷积核大小\text{FLOPs} \approx 2 \times \text{输出元素数} \times \text{卷积核大小}
  2. 访存量(分母)推理过程中从内存读取和写回的数据字节数。
    访存量=权重字节+激活字节\text{访存量} = \text{权重字节} + \text{激活字节}
  3. 比值含义若它小于硬件理论计算吞吐与带宽之比,说明算力在等数据,压缩体积收益最大。
    带宽瓶颈  ⟺  FLOPs字节<TOPS带宽\text{带宽瓶颈} \iff \frac{\text{FLOPs}}{\text{字节}} < \frac{\text{TOPS}}{\text{带宽}}

核心量化算法

压缩袋必须印刻度尺,否则看不出“一格”代表多厚。量化也有两个关键参数:缩放因子 s(每格代表多少数值)和零点 z(刻度起点对齐在哪里),它们合起来定义了“一格有多大、从哪开始数”。

对称量化假定数据以 0 为中心对称分布,把 [-rmax, rmax] 映射到 [-127, 127],只需要一个 s;非对称量化允许分布整体偏移,把 [rmin, rmax] 映射到 [0, 255],除了 s 还要一个 z 来对齐最小值。像压缩袋:对称像是“居中折叠”,非对称则是“顺着物品形状错位折叠”,更适合 ReLU 之后全为正数的激活值。完整的非对称量化公式:

拿到编号后,再用 $x \approx s \cdot (x_q - z)$ 还原,就能“穿回”那件压缩过的羽绒服——版型略松紧,但保暖依旧。

xq=clip⁡(round⁡(xs)+z,  0,  2b−1)\displaystyle x_q = \operatorname{clip}\left( \operatorname{round}\left( \frac{x}{s} \right) + z, \; 0, \; 2^{b} - 1 \right)
公式解读:量出物品有几格 → 取整压平 → 对准起点 → 超出箱体就裁掉。
  1. 缩放因子 s一格刻度代表多少数值,s 越小量化越精细。
    s=xmax⁡−xmin⁡2b−1s = \frac{x_{\max} - x_{\min}}{2^{b} - 1}
  2. 除法 x/s把浮点数换算成“它占几格”。
    xs=物品长度÷每格长度\frac{x}{s} = \text{物品长度} \div \text{每格长度}
  3. 取整 round压入最近一格,这一步产生取整误差。
    round⁡(2.3)=2\operatorname{round}(2.3) = 2
  4. 平移 +z把格数换算成 0~255 的编号,z 就是刻度的起点偏移。
    xq=round⁡(xs)+zx_q = \operatorname{round}\left( \frac{x}{s} \right) + z
  5. 截断 clip超出 [0, 2^b-1] 的值一律砍到边界,产生截断误差。
    clip⁡(x, 0, 255)={0x<0x0≤x≤255255x>255\operatorname{clip}(x,\,0,\,255) = \begin{cases} 0 & x < 0 \\ x & 0 \le x \le 255 \\ 255 & x > 255 \end{cases}

校准与误差

压缩袋买多大,得先看一眼要装什么。量化前同样要先“清点行李”:跑一批有代表性的真实输入,统计每层激活的数值分布,这叫校准(Calibration),那批输入叫校准数据集。

最朴素的是 MinMax 法:直接取最小值、最大值当边界。但真实分布常有“长尾”——个别异常值会把范围撑得很大,格子却浪费在无人区。于是有了百分位法和基于 KL 散度的熵校准:宁可牺牲最边缘的几个点,也要保证中间主体部分分得足够细。KL 散度衡量两个分布之间的“信息差距”:

清点得准,压缩袋的刻度才不会浪费:既不会因尺子太大丢了细节,也不会因尺子太小把东西硬塞爆。

DKL(P∥Q)=∑iP(i)ln⁡P(i)Q(i)\displaystyle D_{KL}(P \parallel Q) = \sum_{i} P(i) \ln \frac{P(i)}{Q(i)}
公式解读:把“原行李清单”和“压缩后清单”逐格对比差距,差距最小的方案胜出。
  1. P(i)原始 FP32 分布的直方图概率,即校准集清点出的“原行李清单”。
    P(i)=第 i 个区间的样本数总样本数P(i) = \frac{\text{第 } i \text{ 个区间的样本数}}{\text{总样本数}}
  2. Q(i)量化后重建分布的直方图概率,即“压缩后的小行李箱清单”。
    Q(i)=反量化落在第 i 区间的样本数总样本数Q(i) = \frac{\text{反量化落在第 } i \text{ 区间的样本数}}{\text{总样本数}}
  3. ln(P/Q)两个清单在每一格的差距,差距越大信息丢失越多。
    ln⁡P(i)Q(i)=ln⁡P(i)−ln⁡Q(i)\ln \frac{P(i)}{Q(i)} = \ln P(i) - \ln Q(i)
  4. 求和把所有格的差距按 P 加权相加,得到总失真;逐候选阈值试算,取 KL 最小的那个。
    T∗=arg⁡min⁡TDKL(P∥QT)T^{*} = \arg\min_{T} D_{KL}(P \parallel Q_T)

量化范式对比

打包有两种时机。一种是把行李全装好,到机场再临时塞压缩袋——省事,但容易出褶子;另一种是收拾时就想着“待会儿要压缩”,一边叠一边压——麻烦一点,但衣服板正。

前者对应训练后量化(PTQ):模型已经训练完,直接转换。它又分两种:动态量化(推理时临时统计激活范围,无需数据)和静态量化(用校准集预先定好每层的 s/z,推理零开销,最常用)。后者对应量化感知训练(QAT):在训练图里插入“伪量化节点”,让模型在训练阶段就习惯“被压扁”的感觉。

伪量化节点前向把 x 压成格子再还原(模拟误差),反向则用直通估计(STE)把阶梯函数的梯度“假装成”一条直线传回去,让权重朝着“压扁后依然好用”的方向更新:

QAT 是“带着压缩袋意识叠衣服”,精度要求高的任务里它往往比 PTQ 更稳,代价是训练成本更高。再往上还有混合精度:敏感层保留 FP16/FP32,皮实的层用 INT8/INT4——贵重的西装单独挂,普通 T 恤随便压。

x~=s⋅clip⁡(round⁡(xs),qmin⁡,qmax⁡),∂L∂x≈∂L∂x~\displaystyle \tilde{x} = s \cdot \operatorname{clip}\left( \operatorname{round}\left( \frac{x}{s} \right), q_{\min}, q_{\max} \right), \qquad \frac{\partial L}{\partial x} \approx \frac{\partial L}{\partial \tilde{x}}
公式解读:前向“先压再还原”制造误差,反向“假装可导”把梯度传回去。
  1. 前向伪量化x 先压成格子编号,再乘 s 还原成浮点,模拟真机推理时的形状。
    x~=s⋅xq\tilde{x} = s \cdot x_q
  2. clip 截断防止中间值超出量化范围,超出部分按边界处理。
    xq∈[qmin⁡, qmax⁡]x_q \in [q_{\min},\, q_{\max}]
  3. STE 近似梯度round 不可导,直接把上游梯度当作 x 的梯度传回——把楼梯“看成”斜坡。
    ∂L∂x≈∂L∂x~\frac{\partial L}{\partial x} \approx \frac{\partial L}{\partial \tilde{x}}

性能优化策略

行李整理不只是“压”,还有“合并”与“叠放”。把洗发水和沐浴露倒进同一个分装瓶,叫算子融合;把袜子卷起来塞进鞋里,叫内存布局优化。

以最经典的 Conv+BN+ReLU 融合为例:三个算子原本各自读写一遍中间张量(多次内存往返),融合成一个算子后,卷积算完立刻过 BN 和 ReLU,中间数据只留在寄存器里,既省访存又省内核启动。收益可用加速比衡量:

内存布局上,NHWC 与 NCHW 的选择、按 16 字节对齐,都影响缓存命中率;SIMD 宽度决定了 INT8 一次能并行处理 16 个值,把通道数补到 16 的倍数能避免“空跑”。端侧调优还有绑核、线程数、动态降频策略等——每一条都像行李的叠放顺序:不改变物品数量,却决定能不能塞进去。

加速比=∑i=1ntitfuse\displaystyle \text{加速比} = \frac{\sum_{i=1}^{n} t_i}{t_{\text{fuse}}}
公式解读:分开做 n 件事的总耗时,除以合并成一件事的耗时。
  1. 分子n 个分离算子各自耗时之和,每个算子的耗时 = 计算时间 + 访存时间。
    ∑i=1nti=∑i=1n(ti计算+ti访存)\sum_{i=1}^{n} t_i = \sum_{i=1}^{n} \left( t_i^{\text{计算}} + t_i^{\text{访存}} \right)
  2. 分母融合后单个算子的总耗时,访存次数从 n 次压成 1 次。
    tfuse≈t计算+t一次访存t_{\text{fuse}} \approx t^{\text{计算}} + t^{\text{一次访存}}
  3. 比值大于 1 说明融合有效,值越大收益越明显。
    节省时间=∑i=1nti−tfuse\text{节省时间} = \sum_{i=1}^{n} t_i - t_{\text{fuse}}

工程实战部署

行李打包完,还要过安检、上飞机,落地后在传送带上取回。部署就是把量化模型送上真机的全过程。

工具链上,TFLite、ONNX Runtime、MNN、NCNN、CoreML 都支持一键 PTQ 或导入 QAT 模型,选型要看目标芯片和算子覆盖度。上线前必须做质量评估:精度变化、首帧/平均延迟、内存峰值、功耗和模型体积,其中精度是首要验收线:

排查套路也很固定:先看校准集分布是否贴近真实;再逐层对比中间输出,定位“矫情”层单独回退 FP16;最后检查是否踩中编译器“不支持算子”导致意外回退。只有多机型真机实测、用真实输入分布验过延迟和内存,这箱“量化行李”才算真正交到旅客手上。

Δacc=AccFP32−AccINT8\displaystyle \Delta_{\text{acc}} = \text{Acc}_{\text{FP32}} - \text{Acc}_{\text{INT8}}
公式解读:原样行李和压缩行李各过一次“称重”,差值就是压缩的代价。
  1. FP32 基准原模型在验证集上的准确率。
    AccFP32=预测正确数总样本数\text{Acc}_{\text{FP32}} = \frac{\text{预测正确数}}{\text{总样本数}}
  2. INT8 结果量化后模型在同样数据上的准确率。
    AccINT8=预测正确数总样本数\text{Acc}_{\text{INT8}} = \frac{\text{预测正确数}}{\text{总样本数}}
  3. 差值通常希望 ≤ 1%~2%;若骤降,说明校准或某些层有问题。
    Δacc≤1%∼2%视为合格\Delta_{\text{acc}} \le 1\% \sim 2\% \quad \text{视为合格}

AI 应用场景

手机语音助手的端侧唤醒

阶段:模型压缩与低功耗推理

解决的问题:唤醒词识别需要 7×24 小时常驻运行,FP32 模型功耗高、占用内存大,无法做到“随叫随到”。量化到 INT8 后,模型体积缩小 4 倍,放到低功耗 DSP/NPU 上,待机功耗降到原来的几十分之一,用户喊“你好”的瞬间就能响应。

具体案例:某手机语音助手把 12MB 的唤醒词模型量化至 INT8(3MB),常驻内存减半,唤醒延迟从 250ms 降到 90ms,且断网可用。

实时人像分割与背景虚化

阶段:推理性能优化

解决的问题:拍照预览要求每帧延迟低于 50ms,FP32 模型在手机 NPU 上访存压力大、帧率抖动明显。通过 INT8 静态量化配合 Conv+BN+ReLU 算子融合,延迟从 120ms 降到 30ms,发热也明显缓解。

具体案例:某手机相机 App 的“人像模式”实时分割人像,量化后内存峰值从 800MB 降到 220MB,中低端机型也能流畅预览虚化效果。

端侧大语言模型的本地推理

阶段:模型压缩与内存映射优化

解决的问题:7B 参数的 LLM 用 FP16 存储约需 14GB,手机根本装不下。用 4-bit/8-bit 权重量化把体积压到 4GB 以内,配合内存分页和 KV 缓存量化,用户才能在飞行模式下离线对话。

具体案例:手机厂商在旗舰芯片上本地跑起 7B 级对话模型,首 token 延迟控制在秒级,聊天记录不出设备,隐私性大幅提升。

Python 演示

python47 行
# -*- coding: utf-8 -*-"""移动端量化核心算法演示:对称/非对称量化与误差分析"""import numpy as np def symmetric_quantize(x, bits=8):    qmax = 2 ** (bits - 1) - 1    scale = np.max(np.abs(x)) / qmax    xq = np.clip(np.round(x / scale), -qmax, qmax).astype(np.int8)    return xq, scale def asymmetric_quantize(x, bits=8):    qmin, qmax = 0, 2 ** bits - 1    scale = (np.max(x) - np.min(x)) / qmax    zero_point = qmin - round(np.min(x) / scale)    xq = np.clip(np.round(x / scale) + zero_point, qmin, qmax).astype(np.uint8)    return xq, scale, zero_point def per_channel_quantize(x, bits=8):    qmax = 2 ** (bits - 1) - 1    flat = x.reshape(x.shape[0], -1)    scales = np.max(np.abs(flat), axis=1) / qmax    qflat = np.clip(np.round(flat / scales[:, None]), -qmax, qmax)    return qflat.reshape(x.shape).astype(np.int8), scales def dequantize(xq, scale, zero_point=0):    return scale * (xq.astype(np.float32) - zero_point) def per_channel_dequant(xq, scales):    return xq.astype(np.float32) * scales.reshape(-1, 1, 1, 1) def mse(a, b):    return float(np.mean((a - b) ** 2)) np.random.seed(42)weight = np.random.randn(64, 3, 3, 3) * 0.3   # 模拟 64 个输出通道的卷积权重act = np.abs(np.random.randn(5000)) * 2.0     # 模拟 ReLU 后全为正的激活 wq, ws = symmetric_quantize(weight)wp, wscales = per_channel_quantize(weight)print("per-tensor  MSE: %.6f" % mse(weight, dequantize(wq, ws)))print("per-channel MSE: %.6f" % mse(weight, per_channel_dequant(wp, wscales))) aq, ascale, azero = asymmetric_quantize(act)print("asym activ  MSE: %.6f" % mse(act, dequantize(aq, ascale, azero))) print("FP32 体积: %d B -> INT8 体积: %d B, 压缩 %.2fx"      % (weight.nbytes, wq.nbytes, weight.nbytes / wq.nbytes))
目的:用 NumPy 实现对称/非对称量化和 per-channel 量化,直观对比量化误差与压缩比。
  1. scale = np.max(np.abs(x)) / qmax求出压缩袋的“刻度”:把最大绝对值铺满量化范围。
  2. np.clip(np.round(x / scale), -qmax, qmax)取整压格 + 截断裁边,模拟真机上的 INT8 行为。
  3. zero_point = qmin - round(np.min(x) / scale)计算零点 z,让最小值恰好映射到 0。
  4. return scale * (xq.astype(np.float32) - zero_point)反量化:读回刻度,还原近似浮点值。
  5. flat = x.reshape(x.shape[0], -1)按输出通道展平,为每个通道单独打包。
  6. per_channel_dequant(wp, wscales)每通道刻度分别还原,通常比 per-tensor 误差更小。

常见误区

误区我试过把模型转成 INT8,准确率掉了 5%,说明量化必然损伤精度,生产环境根本不敢用。

正解掉 5% 通常不是“量化”本身的错,而是“没校准就硬压”。只要用贴近真实场景的校准集先统计分布,必要时换 QAT 或混合精度,INT8 的精度损失往往能控制在 1% 以内——就像压缩袋用好了,衣服只多几条褶子,不影响穿。

为何常见:很多人第一次是“零校准一键转换”失败的,于是把个例当成了普遍规律。

误区既然量化能省空间,那就越低越好,直接上 4 位甚至 2 位,反正目标就是更小更快。

正解位宽降到 4 位以下,量化级数只有 16 个,权重和激活的动态范围很难表达,精度往往断崖式下跌。业界做法是混合精度:先逐层测敏感度,“娇气”的层留 FP16,“皮实”的层才压到 INT8/INT4。

为何常见:看到厂商宣传“4-bit 大模型”就觉得越低越好,忽略了背后逐层敏感度分析和混合精度的复杂工程。

误区剪枝、蒸馏、量化都是压缩模型,原理差不多,会一个就会另外两个。

正解三者手术方式完全不同:剪枝删连接(改结构)、蒸馏换小模型(重新学习)、量化只改数值刻度(结构不变)。目标都是“让行李更小”,但一个是扔东西,一个是换小包,一个是真空压缩。

为何常见:模型压缩的几个概念常被放在一起讲,初学者容易混为一谈。

误区在服务器上用相同算子库测了延迟,达到 30ms,直接上架肯定没问题。

正解服务器和手机是两个世界:CPU 降频、NPU 驱动版本、内存带宽、缓存大小都不同,量化算子在不同设备上可能走不同实现。必须多机型真机验收,用真实输入分布测 P99 延迟和内存峰值——行李在家量完,还要到机场实测。

为何常见:桌面端工具链太成熟,让人误以为移动端也“应有尽有”。

误区校准数据越多越准,我从训练集抽一万张喂进去准没错。

正解校准的关键是分布贴近真实场景,而不是数量多。如果只喂白天的照片,模型上线遇到夜景就会把范围估歪。几百张覆盖各场景的代表样本,往往远胜几万张单一分布的偏科样本。

为何常见:“数据越多越好”的直觉太强,忽略了校准统计的是范围与分布形状,而不是在学知识。

面试题

Q1. 移动端部署中,最常见的权重量化目标精度是哪种?

单选题 · easy

  • A.FP16 半精度浮点
  • B.INT8 八位整数← 正确答案
  • C.INT64 大整数类型
  • D.FP64 双精度浮点

答案:B。INT8 用 256 个格子表达数值,体积是 FP32 的四分之一,并且在手机 NPU 上有原生高效算子,是端侧量化的“默认档位”。FP16 只省一半且硬件支持参差;INT64/FP64 反而更大。

Q2. 量化公式 xq=round(x/s)+z 中,z 的作用是什么?

单选题 · easy

  • A.在取整前先做缩放
  • B.对齐刻度的零点← 正确答案
  • C.拉大量化的步长
  • D.消除数值的溢出

答案:B。s 是缩放因子,决定一格多大;round 负责取整;z(零点)把格数平移对齐到 0~255 的编号。好比压缩袋刻度的起点:没有 z,偏置分布的数据就读错数。

Q3. 对称量化与非对称量化最本质的区别是什么?

单选题 · easy

  • A.是否引入零点偏移← 正确答案
  • B.是否扩大表示范围
  • C.是否需要校准数据
  • D.是否改变网络结构

答案:A。对称量化假设数据关于 0 对称分布,只用缩放因子 s;非对称量化多一个零点 z 来适配整体偏移的数据,如 ReLU 后的正激活。B/C/D 都不是两者的本质差异。

Q4. 训练后量化与量化感知训练最主要的区别是什么?

单选题 · mid

  • A.是否在训练中模拟量化误差← 正确答案
  • B.是否使用更大的训练数据集
  • C.是否改变模型的激活函数
  • D.是否增加模型的参数量

答案:A。PTQ 在训练完成后直接转换,快但误差不可控;QAT 在训练时就插入伪量化节点,让模型适应“被压扁”后的表达。核心区别在“是否在训练中模拟误差”,与数据集、激活函数、参数量无关。

Q5. 静态量化前的校准阶段,通常需要做哪些事情?

多选题 · mid

  • A.统计激活值的动态范围← 正确答案
  • B.统计权重的数值分布← 正确答案
  • C.更换全新的训练数据集
  • D.确定缩放因子和零点← 正确答案

答案:ABD。校准要跑一遍真实输入,统计各层激活范围与权重分布,最终确定每层的 s 与 z。更换训练集与校准无关,校准关心的是“分布形状”,不是“学更多知识”。

Q6. KL 散度校准方法最常用于解决什么问题?

单选题 · mid

  • A.为分布选择最优截断阈值← 正确答案
  • B.为网络寻找最佳学习率
  • C.为数据集生成更多样本
  • D.为损失函数调整权重

答案:A。KL 散度衡量原分布与量化后分布的信息差距,逐个候选阈值试算、取 KL 最小的那个,从而解决“异常值撑爆范围、格子浪费在长尾”的问题。

Q7. 为什么 INT8 量化能让许多端侧模型明显提速?

单选题 · mid

  • A.访存量降低为原来的四分之一← 正确答案
  • B.模型参数数量直接减少一半
  • C.网络结构变得更浅更简单
  • D.模型完全不再需要进行推理

答案:A。INT8 比 FP32 小四倍,权重和中间张量的访存都降到四分之一;对访存受限的算子,耗时几乎同步缩四倍,还能踩中 NPU 的低比特计算通道。参数数量、结构、推理本身都不变。

Q8. 量化感知训练中,伪量化节点的作用包括哪些?

多选题 · hard

  • A.前向模拟量化引入的误差← 正确答案
  • B.反向用直通估计传递梯度← 正确答案
  • C.直接把所有权重变成布尔值
  • D.更新统计缩放因子和零点← 正确答案

答案:ABD。伪量化前向把 x 压成格子再还原,制造与真机一致的误差;反向用 STE 把阶梯函数“看成”斜坡传梯度;同时 s 与 z 也随训练更新。它不做二值化,也没有消除计算开销。

Q9. 量化后模型在真机上精度骤降,最优先排查什么?

单选题 · mid

  • A.校准数据是否贴近真实分布← 正确答案
  • B.是否更换最新的旗舰手机
  • C.是否增大推理批处理大小
  • D.是否重新安装手机操作系统

答案:A。精度骤降的头号嫌疑是校准集不贴近真实分布,导致每层的量化范围估歪、截断过多。旗舰机、batch 大小、系统重装与量化误差没有直接关系。

Q10. Conv+BN+ReLU 融合成一个算子的好处包括哪些?

多选题 · hard

  • A.减少中间张量在内存中的读写← 正确答案
  • B.减少内核启动和同步的开销← 正确答案
  • C.让模型体积自动地缩小一半
  • D.避免所有数值溢出和舍入误差

答案:AB。融合把多次内存往返合并成一次,减少中间张量访存和内核启动/同步开销,是性能优化而非压缩手段。模型体积缩小来自量化本身;数值误差也无法靠融合消除。