嵌入式AI模型量化五步法:INT8端侧部署与精度平衡 模型在开发机上跑得好好的一烧进板子就卡成幻灯片——做嵌入式 AI 的人多半都撞过这堵墙。权重文件几十兆Flash 装不下单帧推理几百毫秒实时性完全谈不上想换个小模型精度又掉得没法看。嵌入式 AI 模型量化本质上就是在这三件事之间找一个能落地的平衡点把 FP32 的权重和激活压到 INT8 甚至更低让模型体积缩到四分之一让端侧算力跑得动同时把精度损失控制在业务可接受的范围内。这篇内容讲的是一套我自己反复用过的五步流程从一个已经训练收敛的浮点模型开始到最后在目标板子上跑出稳定的延迟和精度数据。它不绑定某个特定框架也不要求你手上有 NPU纯 MCU、带 DSP 扩展的核、轻量级 NPU 都适用。适合两类人看一类是刚把模型训完、准备往端侧搬的算法同学另一类是已经上手部署、但量化后精度或速度总有一头不理想的工程同学。文中涉及的模型和硬件都以虚构的示例代称参数和数字是按常见场景估算的你替换成自己的实测值即可。1. 摸清家底嵌入式量化到底在压什么、速度从哪来动手之前先把原理捋清楚比上来就调工具链参数有用得多。很多人量化失败不是工具不好用而是根本不知道自己压掉的是什么、加速又是从哪个环节省出来的出了问题只能瞎试。1.1 一次 INT8 量化到底发生了什么量化的数学形式很朴素就是给每个张量配一组缩放因子和零点把连续的浮点值映射到有限的整数格点上。对非对称量化映射关系是q clamp(round(x / S) Z, qmin, qmax) x_approx S * (q - Z) S (x_max - x_min) / (q_max - q_min) Z round(q_min - x_min / S)INT8 时qmin-128、qmax127。S 决定了一个整数格代表多大的浮点跨度Z 决定零点的位置。对称量化则强制 Z0只保留 S公式退化成q round(x/S)取值范围通常是 -127 到 127。这里的核心矛盾在于S 一旦定下来整个张量就共用这一把尺子。如果某个张量的激活值分布极不均匀绝大多数值挤在 0 附近只有极少数尖峰跑到很远的地方那么按最大值算出来的 S 会很大0 附近那些值全部被压到相邻的几个整数格上细节信息直接丢了。反过来S 取小了尖峰又被 clamp 削掉。校准算法要解决的就是怎么在这一堆取值里挑一个让信息损失最小的截断阈值。理解这一点你就能明白为什么“量化后精度掉了”几乎总是发生在特定层那些激活分布长尾严重、动态范围跨几个数量级的层才是重灾区。后面讲的敏感度体检就是把这些层找出来。1.2 为什么端侧几乎只认定点FP32 乘加在通用 CPU 上很自然但到了资源受限的嵌入式环境问题就暴露了。一个 FP32 乘加在纯整数流水线的 MCU 上要靠软件模拟浮点运算几十个周期起步而 INT8 乘加可以直接走硬件乘法器一个周期一个。差距不是百分之几十是几十倍。除了算力还有三笔账。第一是存储一个 700 万参数的模型FP32 权重要 28MBINT8 只要 7MB对于只有几百 KB 到几 MB 片上 Flash 的器件这是能不能装下的区别。第二是带宽权重从 Flash 搬到 SRAM 的时间往往比计算本身还长位宽减半搬运量就减半很多模型的瓶颈其实在这里。第三是缓存和 TCM 的占用INT8 激活让同一块 SRAM 能放下更大的张量减少反复换入换出。所以不是大家不想用 FP16而是在多数没有浮点单元的嵌入式核上INT8 是唯一能在算力、存储、功耗三条线上同时交代得过去的方案。带 FPU 的核可以用 FP16 或者 BF16 做些折中但一旦模型规模上去INT8 仍然是主力。1.3 压缩率与精度的三条硬边界做量化之前先认清三条边界能避免很多不切实际的期待。第一条是权重量化几乎无损激活量化才是难点。权重是静态的分布稳定per-channel 量化后 INT8 通常掉点极小激活是动态的随输入变化长尾和离群值都在这边精度损失主要来自激活。第二条是首尾层敏感。第一层卷积直接吃原始输入输入动态范围由传感器决定往往很大最后一层分类头或检测头输出维度小量化误差会被放大。这两处默认保留高精度是性价比最高的操作。第三条是深度可分离卷积和逐元素操作是量化难点。深度卷积每个通道单独做通道间数值范围差异大per-tensor 量化很容易把小通道压死残差相加、逐元素相乘需要两个张量的 S 和 Z 对齐否则要么重新量化引入误差要么多一次搬运。这两类结构在现代轻量骨干里到处都是必须提前规划。2. 五步法整体设计把量化做成可回滚的流水线量化最怕的不是精度掉是掉完之后不知道哪一步掉的、回退回去又不知道改哪个参数。所以流程设计的第一原则是可回滚、可定位、可复现。五步流程就是按这个原则排的。2.1 五步流程与每步的交付物我把整条流水线拆成五步每一步都有明确的输入和产出任何一步出问题都能退回到上一步而不影响全局。步骤主要动作交付物判断通过的标准第一步 模型体检逐层敏感度分析、算子清单核对敏感层名单、不支持算子列表明确哪些层必须保留高精度第二步 图清理BN 折叠、算子融合、布局统一量化友好图图中算子全部在目标后端支持列表内第三步 校准校准集筛选、校准算法选型每张量的 S/Z 参数表校准后逐层余弦相似度达标第四步 量化执行权重量化、激活量化、混合精度回退定点模型文件浮点与定点输出误差在阈值内第五步 端侧实测精度回归、延迟与内存实测部署报告精度损失和延迟均满足业务指标这个表看起来简单实际执行时最容易跳过的是第一步。很多人拿到模型直接丢进量化工具跑完发现掉点再回头一层层试时间全浪费在返工上。先把体检做了后面每一步都是有的放矢。2.2 为什么先做基线而不是先量化基线不只是“量化前跑个精度”这么简单。你需要一份完整的三件套浮点模型在目标数据集上的精度、浮点模型在目标硬件上的延迟和内存占用、以及逐层输出的特征图快照。前两项是后面所有对比的参照物第三项是定位问题的关键。有了逐层特征快照量化后哪一层开始偏离、偏离多少一比对就清楚没有的话你只能看到最终精度掉了两个点然后从第一层开始猜。基线还有个大用处判断这次量化到底值不值得做。如果浮点模型在目标板子上已经是 30ms 一帧业务要求 50ms 以内那你费劲量化可能只省下 5ms收益有限如果浮点是 300ms那就是必须做。先量一遍再决定投入多少精力。做基线时有个细节要注意延迟测量必须在目标硬件、目标主频、目标编译器优化选项下进行开发机上测出来的数字没有参考价值。同一份代码开不开编译优化、数据放不放在 TCM 里延迟能差出两三倍。2.3 方案选型的决策树方案选型不用搞得太复杂按下面的顺序问自己三个问题就够了。第一个问题工具链支持训练后量化PTQ吗校准数据够不够如果模型结构规整、校准集能覆盖真实分布先走 PTQ成本最低一两个小时就能看到结果。第二个问题PTQ 掉点是否在可接受范围内一般分类任务掉 1 个点以内可以接受检测和分割对定位精度敏感阈值要卡得更紧。超了就先试混合精度回退把敏感层保住。第三个问题回退之后还达不到要求吗到这一步再上量化感知训练QAT。QAT 要改训练代码、要重新跑若干 epoch成本高但它能让模型在训练时就适应量化误差通常能比 PTQ 多挽回一半以上的损失。这个顺序不能颠倒。我见过不少团队一上来就上 QAT结果发现 QAT 的训练配置本身就写错了白白烧了几天算力。PTQ 是探路QAT 是兜底混合精度是中间的调节阀。3. 第一步模型体检与量化方案定档这一步的目标很明确在动手量化之前把模型里哪些地方会出问题、出多大问题尽可能地提前暴露出来。3.1 逐层敏感度体检怎么做敏感度体检的常见做法是逐层替换把浮点模型的某一层单独量化成 INT8其余层保持浮点跑一遍验证集看精度掉多少。掉得多的层就是敏感层。这个做法准确但费时间。一个几十层的模型每层跑一遍验证集如果验证集有几千张图在开发机上也要跑上几个小时。实际工程里我用一个更粗但快得多的版本不跑完整验证集只跑几百个样本看输出和浮点输出的余弦相似度或者均方误差。余弦相似度低于 0.99 的层标为可疑再对这些层做精细验证。还有一个更省事的替代方案直接看激活值的统计特性。对每一层统计校准集上激活的最大值、99.9 分位数、均值、标准差算一个“长尾比” 最大值 / 99.9 分位数。这个比值超过 10 的层基本可以判定为量化敏感层因为截断阈值一旦按最大值取大部分有效信息就被压没了。这个方法不需要跑推理验证一次前向统计就够非常适合快速筛查。体检的产出是一张表层名、类型、长尾比、单独量化后的相似度、建议精度。这张表后面会反复用到尤其是做混合精度回退的时候。3.2 PTQ 和 QAT 的取舍两者的差别在误差的来源和补偿方式。PTQ 是事后补救模型已经收敛了量化误差只能靠校准参数去逼近QAT 是事前预防在训练过程中插入伪量化节点让梯度穿过量化操作用直通估计器 STE模型自己学会把权重往量化友好的方向调整。PTQ 的优点是快不用改训练代码不用重新训练缺点是遇到分布复杂的模型精度上限有限。QAT 的优点是精度高通常能接近浮点缺点是要改代码、要调超参、训练不稳定时容易崩。实际选择时看两个指标一是 PTQ 后的精度差距二是业务对精度的容忍度。差距在阈值内就收工别为了多 0.3 个点去折腾 QAT。差距超出阈值先看是不是校准集的问题、是不是某些层的问题把能通过工程手段解决的先解决掉最后再考虑 QAT。QAT 有个容易被忽略的前提伪量化节点插入的位置必须和最终部署时的量化方案一致。训练时按 per-tensor 插的节点部署时用 per-channel两边对不上QAT 白做。所以 QAT 之前必须先把部署端的量化配置定死。3.3 对称、非对称与 per-tensor、per-channel 的组合这四个概念两两组合出四种配置选错了直接影响精度。配置适用对象优点风险对称 per-tensor权重部分后端实现简单零点为 0 便于优化分布偏移时误差大对称 per-channel卷积/全连接权重精度高各通道独立缩放需要后端支持逐通道缩放非对称 per-tensor激活默认选择能表达有偏移的分布需要额外的零点处理非对称 per-channel激活部分后端精度最高计算和存储开销大权重的分布通常围绕 0 对称用对称量化就够配合 per-channel 能几乎无损。激活用非对称因为 ReLU 之后的分布明显偏斜零点不为 0非对称能多挤出一些有效位。这里有个实操判断如果你的目标后端只支持 per-tensor那深度可分离卷积那几层要格外小心必要时把它们单独回退到高精度或者把深度卷积和逐点卷积在图上合并考虑。硬上 per-tensor 量化掉点往往就出在这几层。4. 第二步图清理与算子可量化改造量化工具不是万能的它只能处理它能理解的图结构。很多掉点和部署失败根源在量化之前——图里有奇怪的算子、有可以折叠但没折叠的结构、有布局来回转换的多余节点。4.1 量化友好的图长什么样一个量化友好的图大致满足几个特征算子种类少且都在目标后端支持列表里没有动态 shape 和动态控制流卷积后面紧跟 BN 和激活能被融合成一个算子张量的内存布局从头到尾一致不需要反复 permute没有无意义的 reshape 和 slice 链条。反过来下面这些结构是量化的天敌自定义算子、动态索引、复杂的广播机制、把张量拆成多路再拼回来的分支结构、跨层的注意力计算中出现的 softmax 和 layernorm。不是说这些结构不能量化而是它们要么需要后端专门支持要么会引入额外的量化误差。图清理的产出应该是一份算子清单逐条对照目标后端的支持列表打勾。打不了勾的要么替换成等价的可支持算子要么标记为回退高精度。4.2 BN 折叠与算子融合的收益计算BN 折叠是性价比最高的一步几乎没有精度损失还能直接省掉一次完整的逐通道乘加。原理很简单卷积输出y W*x bBN 做的是z gamma * (y - mean) / sqrt(var eps) beta。把 BN 的参数吸收进卷积得到新的权重和偏置scale gamma / sqrt(var eps) W W * scale b (b - mean) * scale beta折叠之后推理时只需要一次卷积BN 完全不出现。收益可以算一笔账假设某层输出通道 128特征图 56×56BN 本身要做 128×56×56 次乘加约 40 万次运算折叠后归零。整个模型有几十个这样的层累计省下来的运算量相当可观在算力紧张的核上延迟能降 5% 到 15%。除了 BN 折叠还有几个常规融合卷积 激活融合、卷积 加法残差融合、逐点卷积与深度卷积合并调度。融合的价值不只是省计算更重要的是减少中间张量的落内存次数。每多一个中间张量就要多一次写 SRAM 和一次读 SRAM对于带宽受限的嵌入式核这个开销往往比计算本身还大。注意BN 折叠必须在量化之前做而且要用校准集重新统计折叠后的激活分布。折叠改变了数值范围拿折叠前的统计去做校准阈值必然偏。4.3 不支持的算子怎么处理遇到后端不支持的算子有三条路可走按优先级排。第一条是等价替换。比如某些后端不支持带 dilation 的卷积可以用插入零值的方式等效成大核卷积不支持某些激活函数可以用查表或者分段线性的近似实现。替换的前提是数值等价性要在容差内验证过。第二条是算子拆分。把一个大算子拆成几个后端支持的小算子代价是多了中间张量和调度开销。拆分时要算清楚收益拆完之后如果多了三次内存往返省下的那点计算可能还不够填坑。第三条是回退高精度。这个算子保持浮点前后插入量化和反量化节点。代价是这两次转换的开销以及可能打断整个图的定点流水。回退要尽量放在图的边缘或者分支上避免出现在主干路径中间。我个人的经验是回退的算子数量控制在总算子的 5% 以内性能损失基本可接受超过 10%就要重新考虑是不是该换个后端或者换个模型结构了。5. 第三步校准集与校准算法落地校准是 PTQ 的灵魂。同一份模型、同一个工具校准集换一换、算法换一换精度能差出好几个点。这一步值得花时间。5.1 校准集怎么选、选多少校准集的作用是估计每个张量在真实输入下的数值分布所以第一原则是分布要贴近真实场景不是越干净越好也不是越多越好。常见错误是直接拿训练集的一小部分当校准集。训练集经过清洗和筛选分布和线上实际输入有偏差有些场景下这个偏差还很大比如光照变化、噪声水平、目标尺度分布。正确做法是从验证集或者真实采集的数据里抽覆盖各种边界情况最暗的、最亮的、目标最大的、目标最小的、遮挡严重的。数量上100 到 500 个样本通常够用。太少比如 20 个统计不稳定同一份模型跑两次校准结果都不一样太多几千个收益递减校准时间线性增长。我一般取 200 个左右先跑一遍看逐层统计的方差方差大的层再针对性补充样本。还有一个细节校准样本要打乱顺序不要按类别聚在一起。有些工具是按批次统计的滑动平均样本顺序会影响最终结果。5.2 四种校准算法的对比与选择主流校准算法有四种适用场景不同。算法原理优点缺点适用场景MinMax直接取最大最小值实现简单、无截断误差对离群值极敏感分布均匀、无长尾百分位截断取 99.9% 或 99.99% 分位抗离群值百分位需调参通用场景的稳妥选择KL 散度最小化量化前后分布差异自适应强、精度好计算稍慢激活分布复杂的模型MSE 最小化最小化反量化误差平方和对回归类任务友好对分类任务不一定最优检测、回归头默认我推荐 KL 散度它在多数视觉模型上表现稳定。做法是把激活值统计成直方图通常 2048 个 bin然后枚举截断阈值把超过阈值的部分合并到最后一个 bin计算量化前后两个分布的 KL 散度取散度最小的那个阈值作为 S 的依据。百分位截断是更省事的替代效果接近 KL调参更直观。如果你的模型激活里有明显的极端离群值先用百分位截断兜底再考虑 KL。MinMax 只在分布确实均匀的时候用一旦有长尾它会把大量有效值压成同一个整数精度崩得很快。很多“量化后精度暴跌”的案例最后一查就是默认用了 MinMax。5.3 KL 校准的实操细节用伪代码示意一下核心逻辑方便你对照自己工具链里的实现def kl_calibrate(hist, num_bins2048, target_bins128): # hist: 激活值直方图已按最大值归一化 candidates range(target_bins, num_bins) best_threshold, best_kl None, float(inf) for t in candidates: # 把 [0, t] 映射到 target_bins 个量化格 p hist[:t].copy() q quantize_hist(p, target_bins) # 量化后分布 # 把超出 t 的部分并入最后一格 p[-1] hist[t:].sum() kl entropy(p) - entropy_of(q, p) if kl best_kl: best_kl, best_threshold kl, t return best_threshold / num_bins * hist_max几个容易踩的点。第一直方图的 bin 数不要设太小1024 以下会损失分辨率导致阈值估计不准2048 是常见折中。第二KL 校准是逐张量做的不同层的阈值互相独立不要拿全局阈值套所有层。第三校准完之后要把每层的 S 和 Z 存下来部署时直接用不要指望部署端重新算一遍——端侧没有校准数据。还有一点如果你发现某层的校准阈值明显偏离直觉比如把 99% 的值都截掉了先别急着调算法回头看看这一层的输入是不是本身就有问题比如前面某层的输出爆炸了。校准结果异常往往是上游问题的症状。6. 第四步量化执行与混合精度回退到这一步配置都定了开始真正把浮点图转成定点图。这一步的重点不是“跑通”而是“跑对”。6.1 量化配置清单执行前把配置逐项确认一遍能省掉大量返工。下面是我常用的清单。配置项推荐值说明权重量化方案对称 per-channel卷积和全连接层默认开启激活量化方案非对称 per-tensor后端支持时可选 per-channel量化位宽INT8混合精度时个别层用 INT16校准算法KL 散度有离群值时改百分位校准样本数200 左右覆盖各类边界场景首尾层精度保持 FP32 或 INT16输入输出层默认回退BN 折叠开启必须在量化前完成量化粒度对齐与部署端一致QAT 与 PTQ 都要遵守这张表里最容易被忽略的是最后一项。训练侧和部署侧的量化粒度不一致会导致两边算出来的量化参数对不上精度莫名其妙地掉。定配置的时候就把部署端的限制摸清楚别等部署了才发现。6.2 敏感层回退与混合精度混合精度的本质是“花钱买精度”把最敏感的少数层保留高精度用少量的性能和存储代价换回大部分精度。回退策略按优先级排先保首尾层再保体检表里长尾比最高的几层最后保深度可分离卷积层。每次回退一层跑一次验证记录精度和延迟的变化。这里要做的是边际收益分析——回退某一层带来的精度提升除以它带来的延迟增加按这个比值排序从高到低回退直到精度达标就停。回退的代价要提前算清楚。一层 INT8 卷积改成 FP32在某些没有浮点单元的核上延迟可能翻十倍在有 FPU 的核上可能只多 50%。所以回退方案必须结合目标硬件来定不能只看精度。INT16 是中间的折中选项很多后端支持 INT16 累加精度比 INT8 好不少性能损失比 FP32 小得多。6.3 逐层误差定位的方法量化跑完之后如果精度不达标不要急着整体调参先定位误差从哪一层开始放大。具体做法准备一批校准样本同时跑浮点模型和定点模型在每一层输出处取特征图计算两者的余弦相似度和相对误差。正常情况下误差应该逐层缓慢累积如果某一层突然从 0.999 掉到 0.95那一层就是问题源头。定位到问题层之后按这个顺序排查这一层的校准阈值是不是被离群值带偏了这一层的输入是不是本身就有异常值这一层的算子是不是走了不支持的路径被拆分了这一层的 per-tensor 量化是不是把某些通道压死了。四个问题问下来大部分问题都能找到答案。7. 第五步精度回归与端侧实测开发机上跑通不算数端侧的数字才是最终答案。这一步要同时盯精度、延迟、内存三件事。7.1 精度指标体系不能只看 top-1分类任务看 top-1 和 top-5 就够但检测、分割、关键点这类任务光看一个总指标会掩盖局部问题。检测任务要分开看 mAP、小目标 AP、大目标 AP。量化误差往往对小目标更不友好因为小目标的特征响应弱量化噪声的相对影响更大。如果总 mAP 只掉 0.5 但小目标掉了 3 个点这个模型上线后在实际场景里会很难受。分割任务要看 mIoU 和边界区域的精度。量化误差容易在边界处放大整体 mIoU 可能只掉 0.3但边界模糊明显视觉效果差很多。回归类任务建议同时看绝对误差和相对误差的分布不要只看均值。量化误差的分布往往是有偏的均值好看不代表没有长尾。7.2 端侧延迟测量方法延迟测量的坑比精度还多。几个必须遵守的原则第一固定主频和电源模式。动态调频会让测量结果飘忽不定测之前把频率锁死或者至少记录每次测量的频率。第二充分预热。第一次推理包含缓存冷启动、权重从 Flash 搬运等开销不能计入稳态延迟。一般预热 10 到 20 次再开始计时。第三多次测量取中位数。取平均值容易被偶发的长尾干扰中位数更能代表稳态表现。第四区分纯推理时间和端到端时间。纯推理只算模型前向端到端还包括预处理、后处理、数据搬运。业务关心的是端到端但排查性能瓶颈时要看纯推理。第五用硬件周期计数器而不是软件计时。软件计时精度受调度影响周期计数器能精确到单个指令周期定位瓶颈时非常有用。测量结果的呈现建议分三档最小延迟、中位数延迟、95 分位延迟。最小延迟代表理想情况中位数代表典型情况95 分位代表最坏情况。实时系统要看 95 分位不能只看平均值。7.3 内存与功耗实测内存要分三块看权重占用的 Flash、激活和中间张量占用的 SRAM、以及栈和堆的峰值。权重占用相对固定量化后基本就是参数个数乘以位宽除以 8。激活占用是动态的取决于推理时的张量生命周期好的内存规划能让多个张量复用同一块 SRAM。峰值 SRAM 占用要实测不能靠估算因为框架的内部缓冲、算子临时空间都不在纸面计算里。功耗测量需要外部工具但如果手头没有可以用推理时间乘以平均电流粗略估算。量化之后不仅计算量减少权重搬运量也减少功耗下降通常比延迟下降更明显这对电池供电的设备是实打实的收益。8. 常见问题排查速查表下面这些是我在实际项目里反复遇到的症状整理成表出问题时按症状查。8.1 精度塌方的典型症状与对策症状可能原因排查动作对策量化后精度直接归零校准集与真实分布严重不符检查校准样本是否与训练数据同分布重新选校准集某一类目标精度暴跌该类激活分布特殊被截断逐层比对特征图该类相关层回退高精度整体掉 2 到 5 个点用了 MinMax 校准离群值拉偏阈值看各层校准阈值改 KL 或百分位截断输出全是同一个类别最后一层量化溢出或零点错误检查输出层 S/Z输出层回退 FP32检测框位置普遍偏移回归头量化误差对比回归头输出回归头用 INT16 或 FP32深度可分离层掉点明显per-tensor 量化压死小通道逐通道看数值范围改 per-channel 或回退这张表覆盖了大部分常见情况但排查时要有顺序先确认校准集再确认校准算法再看敏感层最后才怀疑工具链本身。工具链出错的概率远低于配置出错。8.2 速度不升反降的原因量化完发现比浮点还慢这事不罕见原因通常在这几个地方。一是量化与反量化节点太多。图被切得七零八落每两个定点算子之间夹一次反量化和量化转换开销把省下的计算全吃掉了。解决办法是尽量减少回退层或者把回退层集中到图的边缘。二是后端没有真正用上定点指令。有些工具链量化后仍然走通用路径没有调用硬件乘加指令位宽减了但指令数没少。这种情况要检查后端配置和算子实现必要的话换后端。三是内存搬运成了新瓶颈。量化减少了计算但如果内存布局不友好、缓存命中率低瓶颈从计算转移到带宽整体时间未必下降。这时候要做的是布局优化和张量复用而不是继续压位宽。四是per-channel 量化引入了额外开销。逐通道缩放需要每个通道单独乘一个系数在通道数多、特征图小的层上这个开销占比不小。如果后端对 per-channel 支持不好某些层退回 per-tensor 反而更快。8.3 一张表总结五步的关键检查点步骤最容易出错的地方一句话检查体检跳过体检直接量化敏感层名单有没有图清理BN 折叠放在量化之后折叠和量化的先后顺序对不对校准校准集不覆盖边界场景最暗最亮最小最大样本在不在里面执行训练侧和部署侧粒度不一致两边的量化配置逐项对齐了吗实测延迟测量没有预热和锁频测量条件写清楚了吗9. 踩过的坑和几句实在话量化这件事工具链能解决的问题其实不到一半剩下的都在流程和细节里。我自己印象最深的一次是一个图像分类的示例模型PTQ 之后精度掉了四个多点怎么调校准算法都没用。折腾了两天才发现校准集是从训练集里直接切的而训练集已经做过归一化和裁剪和板子上实际采集的原始图像差了一截。换成真实采集的数据重新校准精度只掉零点几个点。问题从来不在算法在于我默认了“训练数据就代表真实分布”。还有一个反直觉的体会不是所有层都值得量化。有些模型里某一层的计算量占比很小但量化后对精度影响很大把它保住浮点整体延迟几乎不变精度能回来一大截。做边际收益分析比无脑全量化要划算得多。最后分享一个实用习惯每次量化实验都留一份完整的配置快照包括校准集的文件列表、每层的量化参数、工具链版本、编译选项。量化结果对配置极其敏感没有快照两周后你复现不出同一个结果。这个习惯救过我很多次尤其是在需要向别人解释“为什么这次和上次不一样”的时候。量化没有标准答案只有针对你的模型、你的硬件、你的业务指标调出来的那一组参数。五步流程的价值不在于每一步多高深而在于它把一件混沌的事拆成了可验证的小步骤让你每次只改一个变量每次都知道自己在改什么。