☰
模型量化选型指南:QAT与PTQ方案优选与工程实践
2026/10/24 4:37:46 网站建设 项目流程

模型量化这两年越来越像是一个“必选项”而不是“加分项”。不管你是做移动端App里的实时推理,还是做云端推理服务的降本增效,模型体积和推理延迟都是躲不过去的坎。我接手过好几个从训练到部署的项目,最后都压在模型压缩这一环上。而量化这个方向,经常让团队在两条路之间纠结:是花时间做高精度的量化感知训练(QAT),还是先用低成本的后训练量化(PTQ)快速看到效果。这两条路没有绝对的好坏,但选错了,后面返工的成本会翻好几倍。

这篇文章就围绕“高精度量化感知训练(QAT)与低成本后训练量化(PTQ)方案优选”这个题目展开。我会从方案选型的决策依据、量化原理的底层细节、实操步骤以及典型的精度掉点排查思路这几个维度,把我实际踩过的坑和验证过的做法尽量讲清楚。内容会偏底层一些,但也会照顾到刚接触量化的读者,复杂的地方我会用类比拆开讲。

1. 整体设计思路与选型逻辑拆解

很多人在量化选型上有一个误区,觉得QAT是“高级方案”,PTQ是“初级方案”,所以一个项目上来就直接上QAT,觉得这样最保险。但实际情况恰恰相反。QAT训练耗时、调参复杂、对训练pipeline侵入性强,而且一旦模型结构后续还要改,前面的量化训练基本白做。PTQ则轻量得多,通常只需要准备一批校准数据,跑一遍校准流程,就能拿到一个可部署的量化模型。多数场景下,PTQ的精度损失在1%以内,完全够用。

选型的第一步,其实是回答一个问题:你的部署目标对精度和成本分别有多敏感。

1.1 为什么PTQ是大多数场景的第一选择

PTQ全称Post-Training Quantization,意思是在模型训练完成之后,直接对权重和激活做量化。它的核心优势是快,几乎不依赖原始训练数据和训练环境。在实际项目里,我通常在半天内就能完成一个模型的PTQ量化评估。你需要准备的只是:一个训练好的浮点模型、一份有代表性的校准数据集、以及目标推理框架的量化工具链。

PTQ适合的场景非常广。比如内部工具类模型、原型验证、以及精度冗余较大的任务(像部分分类任务或简单检测任务)。在这些场景下,浮点模型本身的精度余量足够,PTQ掉的那零点几个点根本不伤筋骨。我曾经把一个图像分类模型从FP32压到INT8,精度只掉了0.3%,但模型体积变成原来的四分之一,推理延迟在边缘设备上缩短了将近一半。这种性价比,QAT很难追。

但PTQ也有明显的天花板。如果你的模型包含比较敏感的层,比如某些小通道数的高动态范围特征层、或者带有长尾分布的激活值,PTQ的静态校准很容易把这些层的量化误差放大,导致精度崩塌。我遇到过一个语义分割模型,PTQ后mIoU直接掉了7个百分点,后来排查发现就是某个特征层激活值分布极不均匀,MinMax校准出的量化范围被个别离群点带偏了。

1.2 QAT的“高精度”究竟高在哪里

QAT(Quantization-Aware Training)的思路是在训练阶段就模拟量化的误差,让模型权重和激活逐步适应低比特表示的“噪声”。它不是在训练完再做量化,而是把量化当成训练过程中的一个固有环节。训练出来的模型,权重分布被隐式地约束在当前量化粒度能较好表达的范围内,因此部署时真正转成INT8几乎不会再有大的精度损失。

QAT高精度的本质,不是因为它用了什么更神奇的量化算法,而是它让模型在训练阶段就学会了“容忍”量化误差。换个角度理解,PTQ相当于让一个习惯了高清画面的人去看低分辨率视频,肯定会不适应;QAT则是让这个人从出生起就戴着磨砂眼镜看世界,大脑已经自动补齐了模糊的部分。

代价也很直接。QAT需要你有完整的训练数据和训练脚本,需要重新跑一遍完整的训练流程(通常至少是正常训练epoch的10%到25%,但有些任务需要更多),还需要调整学习率策略、初始化方式、以及蒸馏技巧等超参数。训练时间翻倍是常态。另外,QAT对整个训练链路的技术沉淀有要求,如果团队没有系统做过模型训练,直接上QAT大概率会四处碰壁。

1.3 方案优选的核心决策矩阵

我倾向用一张决策矩阵来梳理选型逻辑,不是凭感觉拍板,而是把场景特征拆成几个维度打分。

维度偏向PTQ偏向QAT
精度冗余浮点模型本身精度超出目标要求浮点精度逼近目标上限,容错空间小
数据可得性原始训练数据不足或涉密,校准数据有限有完整训练集可用
迭代速度需要快速验证、频繁改模型结构模型结构趋于稳定,进入产品化阶段
部署硬件CPU、移动端、通用NPU等宽松平台特定NPU、低比特推理引擎,约束强烈
任务敏感度分类、检索等容错空间大的任务分割、检测、回归等对细节敏感的任务
团队能力以部署为主,训练链路能力弱具备较强的训练与调参能力

如果六个维度里大多数偏向PTQ,就先不要碰QAT。只有PTQ实验后精度不达标,并且模型结构不再大改时,再投入QAT。这个顺序非常重要。我见过不止一个团队一上来就铺人力做QAT,结果做了两周后发现模型结构要重构,所有量化训练的工作全部作废,而同期做PTQ的同事早就完成了部署上线。

2. 量化核心细节与实操要点

不管是PTQ还是QAT,底层原理都是同一套量化映射逻辑。你不需要成为数学专家,但如果连对称量化、非对称量化、逐通道量化这些基本概念都没搞清,那排查精度问题时就会像无头苍蝇。

2.1 量化映射公式与两种经典模式

量化的本质,是把浮点数映射到离散的整数空间。以最常见的INT8为例,量化公式是:

浮点值 ≈ 缩放因子 × (整数表示值) + 零点偏移

用符号表述就是 r = S × (q - Z)。其中S是缩放因子,决定每个量化单位对应的浮点大小;Z是零点,负责对齐浮点0和整数0。这个映射逻辑不难,但实际工程里S和Z怎么确定,直接关系到精度。

对称量化强制Z等于0,非对称量化则允许Z偏移。对称量化实现简单、硬件执行效率高,但对浮点分布不对称的情况不友好。非对称量化更灵活,能适配如ReLU后激活值全非负的分布。大多数情况下,权重用对称量化就够了,激活则要根据实际分布选择。我习惯先跑一版对称量化看精度趋势,如果掉点明显再考虑把激活改成非对称。

2.2 校准方法的选择:MinMax、Percentile与MSE

PTQ里的“校准”过程,本质就是统计激活值的分布范围,从而确定S和Z。校准方法决定了量化范围选得好不好,直接决定精度表现。我用的最多的三种方法是MinMax、Percentile和MSE。

MinMax最简单,直接取校准集所有激活值的最小值到最大值范围。速度快,但怕离群点。比如某个层的激活偶尔出现一个超大值,MinMax会把整个量化范围拉得很宽,导致大多数正常数值的量化分辨率被压缩,精度自然掉。

Percentile用百分位截断,比如取99.99%的分位点作为范围上限,扔掉尾部极端值。这个方法对离群点鲁性强很多,是我做PTQ的默认选择。但百分位参数需要调,截得太多会把有信息量的长尾截掉,截得太少又挡不住离群点。

MSE方法的核心思想是:找到一组量化范围,让量化前后的激活分布误差平方和最小。这个方法理论最优,但计算量大,工程上通常只在敏感层上做探索。我的做法是,先用Percentile快速校准一遍,记录每层的量化噪声情况,然后只对噪声贡献大的层跑MSE优化,既省时间又有效。

2.3 校准数据集的代表性要求

PTQ校准数据的质量,很多时候比数量更重要。校准集不需要像训练集那么大,常見的推理框架跑几百张到一千张代表性样本就足够了。但“代表性”这三个字是关键。我踩过一个典型的坑:用纯白天的街景图做校准,结果模型一到夜间场景掉点严重。因为校准集的激活分布根本没有覆盖到夜间的动态范围,量化范围自然对夜间不友好。

校准数据的选取原则,可以类比成做问卷调查:样本要覆盖模型上线后可能遇到的各种情况。类别要均衡、光照要多样、目标尺度要丰富。尤其是检测模型,不同尺寸的目标特征差异大,校准集里如果全是小目标样本,量化范围对大目标特征就抓不准。我通常会从不同时间段、不同场景的子集里各抽一批,混合成校准集,体量在500到1000张左右,效果比较稳。

2.4 量化粒度:逐张量与逐通道

量化粒度决定缩放因子S的使用范围。逐张量量化是整个张量共用一个S,简单但粗糙;逐通道量化是每个通道有自己的S。对于卷积神经网络,权重用逐通道量化几乎是必须的,因为不同通道的权重分布往往差异很大,如果在通道间强行共用一个缩放尺度,小数值通道的精度会被牺牲掉。

激活值一般做逐张量量化,因为硬件上给每个通道单独配缩放因子成本太高。不过有些芯片已经支持激活的逐通道量化,如果你的部署硬件支持,建议开启。我原来在一个分割模型上遇到激活范围过大的问题,就是因为激活只有逐张量量化,某些通道的动态范围太宽,把整体量化分辨率拉低了。后来换了支持逐通道激活量化的推理引擎,精度立刻恢复了一截。

3. PTQ与QAT的实操流程与关键环节实现

我之前带的模拟项目X,是一个在移动端部署的实时图像分割模型,目标是把模型从FP32压到INT8,在保持mIoU不低于浮点版本1.5%以内的前提下,把推理延迟降下来。这个项目的选型过程非常典型,正好可以用来说明PTQ和QAT在实际流程里的衔接方式。

3.1 PTQ快速验证阶段

项目一开始,我建议团队走PTQ路线。因为深度可分离卷积在边缘设备上的浮点推理通用性更好,而且模型原本是部署在服务器端的,现在要迁移到移动端,需要先评估端侧推理框架对各种算子的支持情况。

第一步是准备校准集。我从原始训练数据里按类别均衡采样了600张图,覆盖了不同光照、不同遮挡程度、不同目标密度的样本。校准流程用的是推理引擎自带的PTQ工具,校准方法选择Percentile,百分位参数初步设为99.99%。

第二步是跑量化精度评估。第一次跑完,mIoU从浮点的78.2%掉到74.5%,掉了接近4个点,明显超标。我马上做逐层敏感性分析,发现掉点的核心集中在两个高分辨率的特征融合层上。这两个层的激活值长尾很重,MinMax范围被几颗离群像素带偏了。

第三步是做针对性优化。我做了两件事:一是把这两个层的校准方法改成MSE,让量化范围更贴合真实分布;二是把激活量化改成非对称模式,给ReLU后全非负的激活分布更精细的表示。改完后精度回升到77.4%,距离1.5%的容差线已经很近。我又微调了Percentile的截断参数,把其他层的截断值从99.99%放宽到99.995%,最终mIoU稳定在77.8%,勉强卡在容差线上。

PTQ这一轮下来大概花了两天时间。这个精度虽然达标,但没有任何冗余,后续模型一改或者数据分布稍偏,很容易跌破线。我跟团队说得很清楚:这个结果适合快速验证,不适合直接上生产。

3.2 QAT实施:初始化、训练策略与收敛控制

模型结构确认不再改动后,我们决定上QAT,目标是留出至少2个点的精度余量。

QAT训练的起点不是随机初始化,而是加载PTQ量化后的权重作为初始值。这个做法非常关键。PTQ已经把权重和激活的量化分布摸了一遍,从这些参数出发做QAT,收敛更快,精度也更高。我曾经对比过随机初始化和PTQ权重初始化的差距,后者在相同epoch数下精度平均高出1.2个点。

训练策略上,我们采用了三个关键技巧:

第一个是直通估计器(STE)的使用。QAT里模拟量化操作的导数基本是零,梯度根本无法回传,所以需要STE把梯度近似传导过去。这个操作很简单,就是把量化函数视为恒等函数来计算梯度,但实际效果却是在工程上打通了QAT训练的关键路径。

第二个是学习率策略。QAT通常建议用比原始训练更低的学习率,我用的是余弦退火,从0.0001开始衰减到0.00001。学习率太高会让模型遗忘之前学到的浮点特征,太低则会让量化范围调整不动。

第三个是批量归一化(BN)层的处理。这一步很多人容易忽略。在量化训练中,BN层统计量的更新会和权重量化相互耦合,导致训练不稳定。我习惯的做法是把BN层的统计量固定住,或者直接在量化训练前半段保持权重冻结,只更新BN统计量,等统计量稳定了再放开其他层一起训练。这个细节让我们的训练loss曲线平滑了很多。

训练了大约12个epoch后,量化模型的mIoU恢复到78.6%,超过了浮点基线。再继续训练到20个epoch,精度稳定在78.4%左右,浮点模型本身是78.2%,居然还略微反超了。这种情况在QAT里不算稀罕事,因为量化的正则效果有时候反而让模型泛化得更好。

3.3 从QAT模型到端侧推理引擎的导入

很多团队在QAT训练完成后就觉得万事大吉,实际上最后一步的模型导出与端侧转换同样充满坑。

QAT训练出来的模型,内部包含的是模拟量化的节点,而不是真正的INT8权重。需要先把这些节点剥离,再把权重真正转换为INT8,并生成推理引擎所需的量化参数表。如果做了自定义的量化操作,还要确保目标推理引擎能够识别你的量化语义。

我们在这个环节踩过一次坑:模型里有一个自定义的加权求和算子,在PTQ阶段兼容没问题,但QAT训练后导出的量化节点,目标推理引擎不认,导致模型转换后部分算子退回到FP32执行。结果就是在端侧跑起来,速度只下降了20%,根本没达到预期的4倍加速。最后是重写了一个等价的自定义量化算子注册进推理引擎,才把速度拉回预期。

这个经历提醒我一个非常实际的问题:QAT不是一个人的事,训练团队和推理引擎工具链的团队必须提前对齐算子支持列表。训练侧用了再花哨的量化方案,如果推理引擎不支持,一切都是空谈。

4. 常见问题与排查技巧实录

量化掉点这个问题,几乎每个项目都会遇到。下面这些排查方法和经验,都是我在多次折腾中沉淀下来的,算是比较高频的踩坑点。

4.1 校准集过拟合与分布漂移问题

校准集数量太少或者太偏,会导致量化范围过拟合到校准集的统计特征上,而在真实场景里分布一漂移,精度立刻变差。我遇到过做某跨平台系统的项目,模型在大规模数据集上训练,PTQ校准只用了100张样本,上线后用户上传的真实图片域差异较大,掉点严重。

排查方法分步走。第一步简单验证:在测试集上分开统计不同子集的精度,看是不是集中在某些特定场景掉。第二步检查激活值分布,在校准集和真实数据上分别抽取各层的激活分布直方图做对比,如果两者形态差异明显,基本可以断定是校准集代表性问题。解决方式是扩充校准集覆盖面,或者用在线收集的少量真实数据重新校准。

4.2 敏感层识别与针对性保护

有些层掉一点点范围,整个模型精度就崩,这种层是“敏感层”。敏感层通常有几个特征:激活动态范围大、通道数少、或者和输出端靠得近。识别敏感层,我一般用逐层扰乱法,也就是每次只量化某几层而保持其他层浮点,逐个观察精度变化,把贡献最大的那部分层挑出来。

针对敏感层,可以做的操作有几种:使用更高精度的量化粒度(如逐通道)、用MSE校准、或者干脆让这个层以FP16方式部署。后一种在混合精度推理引擎上特别有效。我们曾在一个检测模型里保留了两个敏感层的FP16计算,精度完全恢复,整体体积和延迟只增加了一点点。

4.3 QAT训练不收敛或精度反降

QAT训练后精度比PTQ还差,这个情况确实出现过。最常见的原因是学习率设置不合理。学习率太高,模型在量化噪声面前震荡得太剧烈,学不到稳定的权重分布;学习率太低,量化范围调整得太慢,训练等于白跑。

另外一个常见原因是初始化策略不对。直接从随机权重初始化做QAT,模型很容易陷入差局部最优,而用PTQ后的权重或浮点预训练权重做初始化,稳定性和精度都会好很多。某些模型结构上,还需要做“感知层麻醉”。简单说,就是在训练初期只在部分层模拟量化,后期再逐渐加入其他层,给模型一个逐步适应量化的过程。这个技巧在Transformer类模型上尤其有效。

4.4 数值溢出与推理结果错误

INT8量化后推理结果偶尔出现极端错误值,这种时候先怀疑数值溢出。比如某个层的中间计算结果超过了INT8能表达的范围,推理引擎又没有饱和处理机制,就会出现异常。

排查手段很简单,在推理引擎里开启调试模式,把每一层的输入输出范围打出来,和量化参数表里的范围做对比。如果发现实际计算值超出了设定的量化范围,就该调大该层的量化范围或者调整分配策略。我们曾经遇到过卷积层输出范围计算错误,导致后续层量化输入全部截断,精度掉成了垃圾值,定位到后只是把该层的RangeEstimation方法改成了MSE,问题就解决了。

4.5 常见问题速查表

现象可能原因处理建议
PTQ掉点集中某个场景校准集场景覆盖不足扩充校准集,增加场景多样性
精度掉点分布于所有场景量化范围选取过窄放宽Percentile截断参数,检查离群值处理
QAT训练loss波动剧烈学习率过大降低学习率,参考PTQ权重初始化
QAT收敛后精度仍不达标敏感层过多或分布特复杂做逐层敏感性分析,考虑混合精度
推理输出部分异常数值溢出检查每层计算范围,调整量化参数
量化后模型体积没变小部分算子回退FP32检查算子兼容性,替换不支持量化的算子

5. 从精度与部署成本角度谈长期维护

项目上线之后,最容易被忽视的是量化方案的长期维护问题。模型在真实场景跑一段时间后,输入数据的分布往往会发生漂移,这时候固定死的量化范围就会慢慢失效。尤其是PTQ的静态量化,几乎无法自动适应数据漂移,所以需要建立周期性的量化效果监测机制。

我的习惯做法是,在服务端搭建一个离线评测通道,定期抽样线上数据,跑一遍量化模型和浮点模型的精度对比,一旦量化掉点超过阈值,就触发重新校准或重训。这个过程听起来复杂,其实就是把校准和评测脚本流程化,配合定时任务自动跑。很多项目上线半年后精度开始下滑,不是模型本身学习能力不行,而是量化范围和线上数据已经“对不上”了。

另外,硬件平台升级也会影响量化方案的选择。有些芯片的新一代架构开始支持更低比特的量化,比如INT4或混合精度。这些能力如果利用起来,吞吐能力又会有显著提升。但是低比特量化对QAT训练的依赖更强,几乎很少见到纯PTQ能在INT4上保持好精度。如果团队后续有往低比特方向走的规划,我建议从现在就逐步在训练流程里引入模拟量化算子,提前积累QAT能力,而不是等到需求出现时再从零开始。

工具链的成熟度也会直接影响维护成本。我所接触过的行业通用推理引擎,普遍对PTQ支持得比较成熟,对QAT的支持则参差不齐。上线之前最好花时间调研目标推理引擎的量化文档,确认它支持哪些量化方案、如何导入量化参数、哪些算子会计入量化范围。这个调研花不了几个小时,但对后续的稳定性帮助非常大。

6. 实操心得与最终建议

如果让我用一句话总结QAT和PTQ的取舍:PTQ是低成本高回报的起点,QAT是追求极致性能的上限。项目一开始永远不要直接梭哈QAT,先用PTQ把精度底数和性能收益跑出来。PTQ都跑不出满意效果时,再考虑上QAT。用PTQ先探底,这个经验帮我在多个项目里省掉了至少两周无用功。

给正在做量化选型的读者几个非常具体的建议:

第一,校准数据永远要比你预想的多准备20%到30%。实际校准效果不只看数量,还要看分布覆盖。做一个简单的分布对齐检查,比盲目堆数据有效得多。

第二,PTQ阶段一定要做逐层敏感性分析。这个分析看似会花半天,实际上它能帮你快速定位是否应该上QAT,以及QAT训练时哪些层需要特殊照顾。用数据说话,比靠感觉判断靠谱得多。

第三,QAT训练过程中保持和浮点训练的对比实验。很多人训练完QAT,直接拿量化模型精度和浮点模型精度比,发现差不多就收工了。我建议把QAT用到的学习率和收敛曲线同浮点训练对齐分析。若QAT模型收敛速度明显快于浮点训练,通常说明量化本身已适应良好;如果曲线震荡厉害,先检查学习率或BN统计量的处理。

第四,不要忽视模型结构差异对量化需求的影响。卷积网络和Transformer架构在量化上的表现差异非常大。Transformer里的Attention层拥有过高的动态范围,做PTQ时最好配合逐层或逐通道的细化校准。我们在这方面试过直接把整个模型的所有层都做MSE校准,结果不仅慢,精度提升也有限,因为敏感层其实就那么几个。

最后分享一个我经常用的技巧:在做PTQ之前,先跑一个“伪量化”实验。也就是不转真正的INT8,只是在浮点模型上模拟量化误差,一边观察精度的变化趋势。这能帮你快速判断这个模型对量化的敏感程度,从而决定该不该投入资源做QAT。很多问题在这个阶段就会暴露出来,比完整量化流程跑完再排查要高效得多。

量化的路,说难不难,但细节确实多。希望这篇基于实际项目经验的内容,能帮你在QAT和PTQ之间做出更合理的判断,少踩几个我们曾经踩过的坑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询