ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

深度学习模型压缩与推理加速:量化剪枝蒸馏实战指南

深度学习模型压缩与推理加速:量化剪枝蒸馏实战指南 去年年初我们团队要把一个在 A100 上跑得很顺的目标检测模型搬到客户的工控机上。模型的骨干是 ResNet50 级别加一个检测头训练时 batch 8 在单卡上毫无压力可一放到对方那台 8 核 CPU、16G 内存、没有独显的一体机里就露馅了单帧推理 900 多毫秒内存吃到 2.3GB而客户的验收标准是单帧 50ms 以内、内存 1GB 以内。换硬件不在预算里重新训练一个小模型又意味着重新标注、重新调参剩下唯一可行的路就是把现有模型本身做小做快。这个项目最终沉淀成了一套内部工具我叫它 Model-Optimizer。它不是某个开源库的简单套壳而是一条面向 PyTorch 模型的完整优化流水线输入一个训练好的模型输出一个能直接对接推理引擎的优化后模型中间统一管理量化、剪枝、蒸馏这三条技术路线并自动产出一份精度对比报告。这篇文章不是工具文档式的功能介绍而是把这个项目从设计到落地过程中踩过的坑、验证过的参数、总结出的选型逻辑完整地讲一遍。适合正在做模型压缩、端侧或边缘侧部署、以及被模型能跑但上线不行困扰的工程师参考。1. 模型部署的三堵墙体积、时延与能耗的底层关系1.1 从研究环境到生产环境的水土不服很多团队对模型优化的理解停留在模型太大放不下这一层。但真实部署场景里体积只是最表面的指标。我前后接触过几种典型的部署环境痛点完全不一样云端推理服务在乎的是 P99 时延和单实例吞吐。模型大意味着显存占用高同一张卡上能并发跑的实例数量直接缩水按实例计费的账单会翻着跟头涨。移动端在乎的是包体积和内存峰值。模型是 App 安装包的一部分一个 50MB 的模型能让安装包直接大上两三个档次用户对安装包大小非常敏感渠道方也有硬性限制。边缘一体机在乎的是 CPU 推理时延和散热功耗。很多一体机根本没有独显纯 CPU 推理模型理论算力再强也发挥不出来再加上被动散热持续跑满载时还会降频。同一套模型权重在不同硬件上表现出的瓶颈完全不一样。Model-Optimizer 在设计时我没有一上来就套某个现成方案而是先让每个接入的项目回答三个问题模型现在多大、线上要求多快、功耗和显存预算多少。这三个答案决定了后面选哪条优化路线。1.2 三堵墙其实是同一个预算问题体积、时延、能耗表面上是三个指标本质上是同一个问题你的硬件资源池里存得下多少计算和多少数据搬运。这里有一个经常被忽视的底层事实深度学习推理的瓶颈很多时候不是运算单元而是内存带宽。推理过程就像快递分拣运算单元是那个分拣的小哥内存带宽是传送带。模型参数量翻倍传送带上的包裹数量就要翻倍如果传送带宽度不变小哥再快也白搭。量化为什么能显著加速不只是因为 INT8 计算快更关键的是权重和激活从 FP32 变成 INT8 后数据体积直接砍掉四分之三内存带宽压力大幅下降。我认为做模型优化脑子里要时刻有一张资源预算表目标设备的内存带宽、算力上限、缓存大小、支持的指令集每一项都对应着模型的一个特征。比如在 CPU 上做推理INT8 卷积的加速主要来自 AVX512_VNNI 这类专用指令如果你的目标 CPU 不支持这些指令INT8 的收益要大打折扣。这类信息决定优化方案的可行性必须最先确认。1.3 换硬件不一定划算优化模型才是杠杆我有一个很直接的经验当性能不达标时优先考虑优化模型而不是换硬件。换硬件是加法成本线性往上走模型优化是乘法成本主要集中在研发侧的一次性投入。举个实际数字。客户那台工控机的采购成本大约八千元如果换一台带 GPU 方案的设备单价直接到三万以上还要考虑散热、电源、尺寸变更整体改造成本轻松突破五万。反过来把模型做 4 倍压缩、量化后推理速度提升 3 到 4 倍这些改造全部在现有设备上发生硬件预算一分钱不用动。量化通常是投入产出比最高的一步模型权重从 FP32 压到 INT8理论上体积直接变为四分之一对支持 INT8 加速的推理引擎来说速度能提升 2 到 4 倍。剪枝则是另一条路它主要砍计算冗余速度提升在 1.5 到 2 倍左右。知识蒸馏比较特殊它不直接压缩现有模型而是引导出一个结构更小的新模型。三者的节奏和技术路径完全不同这也就是为什么需要一个统一的流水线来管理而不是每次靠人肉脚本东拼西凑。1.4 Model-Optimizer 的定位把优化从玄学变成工程很多工程师做模型优化靠的是散装经验在 Colab 里试过某个量化库、GitHub 上找到一个剪枝 repo、改过几个蒸馏 loss。能跑通但换一个模型、换一个部署环境一切又要重来。Model-Optimizer 想解决的问题就是把某一次实验成功变成每一次都能复现。所以这个工具在设计上定了三条原则所有优化手段共用一套配置接口所有优化前和优化后的模型统一做精度评估所有中间产物都记录在台账里。说白了就是让优化过程可配置、可对比、可回退。这也是我在前几个项目里被教训出来的如果一次量化实验找不到当时用的校准集和参数出了问题根本没法定位。2. 流水线怎么搭量化、剪枝、蒸馏的串联与并联2.1 三条优化路线在流水线中的分工Model-Optimizer 的核心是一张编排表定义了每条优化路线在流水线中的位置和作用路线做什么主要收益主要成本量化把 FP32 权重和激活压成 INT8/FP16 等低精度体积降 4 倍速度提升 2~4 倍精度可能掉点需要校准集剪枝删除冗余权重或整个通道体积和计算量下降重新训练或微调否则精度崩蒸馏大模型当老师教一个小模型让小模型学到接近大模型的能力需要额外训练流程和算力这三条路线并不互斥。我在流水线里把它们设计成可叠加的模块先跑一轮轻量结构化剪枝去掉冗余通道再对剪枝后的模型做量化校准量化掉点控制在预算内时直接用量化模型导出部署如果掉点超预算则拉起一轮蒸馏或量化感知训练来回血。2.2 校准集准备整个流水线最容易出错的第一步量化里的校准这一步业内叫 calibration目的是统计权重和激活的动态范围算出缩放系数。很多第一次用的人会随手拿训练集抽几百张图丢进去这恰恰是一个大坑。校准集不应该等于训练集。训练集和真实推理场景的数据分布往往不同比如训练集里晴天场景占大多数而实际线上夜间图像很多。用训练集做校准算出来的量化参数会偏向训练分布真实分布下精度就崩了。校准集应该从真实目标场景里采样覆盖亮度变化、目标大小差异、背景复杂度等实际情况。数量上CV 模型一般 200 到 500 张足够多不是好事校准集太大反而会让统计量被稀碎样本稀释而且校准本身也要消耗推理时间。另外非常关键的一点校准集和最终评估用的测试集必须严格分开。如果拿同一批图又做校准又测精度评估结果会虚高上线后就傻眼。我在流水线里强制做了文件隔离校准集目录和测试集目录在配置层面就不允许重叠。2.3 先量化还是先剪枝我的答案是分场景这个问题几乎每个接入的团队都会问。我的默认建议是先做轻量结构化剪枝再做量化。原因是剪枝会改变权重分布经过剪枝后的模型保留通道的权重通常分布更集中量化时数值范围更好处理不容易出现极端离群值。反过来如果先量化再剪枝剪枝操作会重新打乱已经校准好的量化分布量化参数就白算了。但也不是绝对。如果你的剪枝方案是掩码式的即权重矩阵里一部分位置被置零但结构保留这时可以先量化后剪枝因为掩码不影响激活分布的整体统计。但如果走的是通道剪枝、滤波器剪枝这种真正改变张量结构的路线那一定先剪后量化。实际项目里我还遇到一种折中剪枝后精度掉得不多但量化后掉点超过预算这时就要激活蒸馏这一路用一个轻量的蒸馏训练把精度拉回来然后再重新量化。2.4 导出与推理引擎对接优化完的模型最终要落到推理引擎上跑。Model-Optimizer 默认把 PyTorch 模型导出为 ONNX再对接 ONNX Runtime、TensorRT、OpenVINO 或 CoreML。这一步看似简单实则是问题高发区。问题主要集中在算子兼容性上。PyTorch 里一个 fancy 的自定义算子在 ONNX 里可能没有对应实现导出时会 fallback 到拆分成一堆基础算子甚至在推理引擎里根本不支持。我的做法是查算子支持列表永远在写优化代码之前。比如 TensorRT 对某些动态 Shape 操作支持不好OpenVINO 对某些 Transformer 算子的实现效率很低这些问题在优化前就要通过算子兼容性分析脚本排查不要在导出阶段才手忙脚乱。量化导出还有一个关键概念叫 QDQ 节点量化后的模型在 ONNX 结构里会表现为 Quantize 和 Dequantize 成对的节点推理引擎看到 QDQ 结构就知道该层要做 INT8 计算。这个结构是优化后的模型与推理引擎之间最重要的协议。如果 QDQ 插入位置不对比如把 Dequantize 插在了计算密度很高的层前面运行时会产生大量无效数据传输速度反而不升反降。Model-Optimizer 在导出后会做一次结构检查专门统计 QDQ 节点的分布密度避免这个问题。3. 先别急着动手三类优化手段的选型逻辑3.1 三句话讲清量化、剪枝、蒸馏的原理量化好比把一本记录精确到小数点后 32 位的账本改成只记整数。省地方、算得快但小尾数会被抹掉关键是别抹掉那些重要的数。剪枝好比从一箱零件里扔掉根本不会用到的备用件。不乱扔就没事扔错关键零件机器就转不起来了。蒸馏让经验丰富的大师傅带一个学徒学徒不用自己把所有路都走一遍照着师傅的判断方式来学学成后干活效率和师傅接近但身板小得多。3.2 场景与手段的对应关系你的场景首选手段次选手段理由云端 GPU 推理模型大但时延不达标量化INT8/FP16蒸馏换小骨干GPU 算力强量化带来的带宽收益最直接移动端 App包体积和内存敏感剪枝结构化 量化蒸馏先剪结构减体积再量化进一步压缩边缘一体机CPU 推理量化 通道剪枝换轻量骨干CPU 对 INT8 指令敏感剪枝减少计算量Transformer / 大模型量化INT8 权重或更低蒸馏参数量大内存占用是主要瓶颈模型已经在线上跑稳定赚钱不做任何优化只做增量测试优化的真实收益可以被货币化衡量后再做这个表格是我在项目里反复验证过的默认选择但真正接入时还是要用业务指标精度、时延、吞吐做一次小规模 AB 测试再拍板。3.3 组合优化时的精度预算分配叠加使用多种优化手段时最忌讳的是每种方法都试到极限。量化单独用能压到 1 个点掉的精度剪枝单独用能压到 1 个点两个叠加起来往往不是 2 个点而是 4 到 5 个点。原因是两种方法都在挤压模型的表达能力误差会相互放大。我把这个现象叫作精度损失的非线性叠加。所以我在流水线里给用户暴露一个总预算参数比如budget0.02表示整体精度损失不能超过 2 个点。系统会在这个预算内自动分配剪枝只用掉 0.5量化用掉 1.0剩下 0.5 作为安全边际。这样的分配看起来保守但实际落地时非常稳不至于优化完的模型在真实数据上突然崩盘。3.4 什么时候应该选择不优化做这个项目久了我反而越来越强调不优化的价值。如果模型规模不大、目标硬件算力富余、迭代频率又很高优化带来的收益会被每一次新版本发布带来的回归成本抵消。比如一个每周都要更新数据重训的模型每次重训后都要重新校准、重新验证这个持续成本可能比省下来的推理成本还高。另外一个反直觉的场景是如果模型精度本来就在及格线边缘那先别优化先把模型本身调好。优化是在衰减精度换速度精度底子都不够换回来的速度毫无意义。Model-Optimizer 在跑优化前会先做一次精度基线检查基线不达标就直接拒绝执行这个无理取闹的设计后来被好几个团队反馈说真香。4. 实操复现从训练好的模型到可部署的推理文件4.1 环境准备与默认配置下面这段是实际项目中最小可用的流程基于 Model-Optimizer 的思路你完全可以用同类开源工具复现。环境方面我建议 Python 3.10 以上、PyTorch 2.x推理引擎按目标设备选。pip install model-optimizer onnx onnxruntime然后是一个最简调用from model_optimizer import Pipeline pipeline Pipeline( modelmodel, calib_loadercalib_loader, val_loaderval_loader, metric_fnmy_metric, # 自定义精度评估函数 budget0.02, # 允许的精度损失2个百分点 strategy[prune_structured:0.3, ptq:int8], # 先剪30%通道再INT8量化 ) result pipeline.run() result.summary() result.export(deploy_model.onnx)pipe 的核心逻辑并不复杂先计算原始模型在 val_loader 上的精度作为基线按策略顺序执行剪枝和量化每一步后重新评估精度累计损失超过 budget 时停止后续步骤并回退到上一版本。整个流程跑完输出优化后的 ONNX 文件和一份 Markdown 格式的优化报告。4.2 校准集的构建细节校准集我强烈建议单独写一个脚本构建不要和训练数据加载器混在一起。我的做法是从线上日志里捞真实请求的样本按场景分层抽样。比如目标检测模型会覆盖大目标、小目标、遮挡、夜间、模糊等类别每类 50 张左右总共 300 张。这里有一个细节校准样本最好做一次简单的去重否则同源图片太多统计分布会被带偏。校准样本的预处理要和线上推理保持完全一致包括尺寸缩放、归一化参数、颜色通道顺序。我在项目里遇到过一次校准和线上不一致的问题线上用的是 BGR 输入校准脚本里却用成了 RGB最后模型在真机上的首帧检测率直接掉了一截。4.3 配置文件的字段说明与逐项含义流水线的配置我都写在 YAML 里方便每个项目单独管理model: path: ./checkpoints/best.pth input_names: [input] input_size: [1, 3, 640, 640] calibrate: method: percentile # 使用百分位法统计动态范围 percentile: [0.999, 0.001] # 忽略极端离群值防止 scale 被拉爆 calib_size: 300 quantize: bits: 8 per_channel: true # 权重按通道独立量化效果更好 symmetric: false # 激活用非对称量化对 ReLU 友好 prune: method: l1_channel # 按 L1 范数裁剪通道 ratio: 0.3 fine_tune_epochs: 5 export: format: onnx opset: 17 target_engine: onnxruntime这里重点说三个字段。percentile是我反复试出来的关键参数如果按最大值来做动态范围个别极端离群值会把 scale 撑得很大导致正常数值全部被压扁取 99.9% 分位点相当于主动忽略那 0.1% 的极端样本量化精度会明显改善。per_channel对权重量化基本是必开项尤其是卷积层不同通道的权重分布差异很大统一一个 scale 会很吃亏。symmetric对 ReLU 类的激活输出建议用非对称量化因为激活值大多是非负的非对称量化能更好利用表示范围。4.4 敏感度分析与精度回退即使有预算自动分配我还是推荐做一次逐层敏感度分析尤其是对精度要求高的模型。做法是每次只量化某一层其他层保持 FP32看哪一层单独量化后精度掉得最厉害。这就像体检报告告诉你身体哪个部位最脆弱。实际跑出来的结果通常很有规律靠近输入输出端的层往往比较敏感中间主干相对皮实。检测模型里回归头的那几层和最后输出的卷积层通常是最敏感的区域。敏感度分析产出一张表格每一层的精度损失一目了然。基于这个表我会把损失阈值超过 0.5 个百分点的层加入禁量化名单让这些层在导出时保留 FP32其余层走 INT8。这种混合精度的方案通常能在只牺牲 10% 到 20% 压缩收益的情况下挽回大部分精度。4.5 端到端一致性验证优化完的模型不能只在 PyTorch 里验证必须跑到目标推理引擎里验证和训练框架下的一致性。我的验证有三步张量级对比准备一组固定输入分别用 PyTorch 原始模型和优化后模型推理对比每一层输出的余弦相似度低于 0.99 就要定位。指标级对比在完整的验证集上用同一个评估脚本算 mAP、准确率等指标和优化前基线对比。真机抽检把模型放到目标设备上跑一段时间收集线上真实样本比对优化前后的表现。第三步是最容易被忽视但是最关键的。很多模型在离线指标上差别很小一上真实场景就出现系统性偏差基本都出在数据分布差异上。真机抽检能把这些隐藏问题提前暴露。5. 踩坑实录一次量化后精度暴跌的完整排查过程5.1 症状与第一直觉有次接一个客户的目标检测模型PTQ 量化完成后离线验证集上 mAP 从 78.4 直接掉到 66.1整整掉了 12 个点。这个幅度属于明显异常一般的量化掉点应该在 1 到 2 个点。当时团队里第一反应是校准集出了问题因为我反复强调校准集要贴合真实分布大家都往这个方向怀疑。我先换了三个不同的校准集做对比一个用训练集一个用线上采集的真实图一个混合两者。结果 mAP 都在 66 到 67 之间差异很小。这说明校准集不是主要因素。5.2 逐层排查先怀疑校准集再怀疑统计量接下来做动态量化对照实验只量化权重激活保持 FP32。这个实验的结果非常关键——mAP 恢复到 77.9几乎无损。这说明问题出在激活量化而不是权重量化。激活量化需要校准集来统计动态范围既然换了校准集没改善那要么是统计方法有问题要么是某一层的激活分布有特殊形态。我用脚本逐层对比了 FP32 模型和 INT8 模型在相同输入下的激活张量分布重点看量化前后的均值、标准差和最大绝对值。大部分层的差异都很正常唯独第四个尺度输出层的回归分支第一个卷积差异极大FP32 下该层激活值集中在 0.02 到 0.15 这么窄的区间里而量化后这一层的有效数值几乎全被压成了几个离散值看起来就像被碾碎了一样。5.3 根因定位一个算子的数值溢出进一步分析找到两个叠加的根因。第一这一层的激活分布是超窄的高斯分布集中在很小的正数区间。但校准集里有几张极端曝光过度的样本让这一层的最大激活值达到了 4.2是正常值的几十倍。校准统计用的是最大值量化 scale 被这 4.2 拉得很大正常 0.02 到 0.15 的数值在量化后都落到同一个整数档位里等于分辨率归零。第二这一层在导出时被插入了 Dequantize 后接另一个算子的结构推理引擎把上一层输出转回 FP32 再给这一层计算这个中间转换放大了量化误差。两个因素叠加最终造成 mAP 崩盘。这里值得说明的是回归分支输出的是坐标偏移量数值天然很小且集中对量化误差极其敏感。这类层在设计上就应该被排除在 INT8 之外不管它的权重看起来有多正常。5.4 修复方案混合精度护住敏感层定位到根因后修复反而简单。我把这层加进禁量化名单导出时让它保持 FP32同时在校准统计里把百分位法从最大值改成 99.9% 分位点避免极端曝光样本污染 scale。两个改动一起生效后mAP 恢复到 76.8只比基线掉了 1.6 个点完全在预算范围内。我还额外试了一个组合方案保留该层 INT8 量化但单独对它的 scale 做裁剪限制最大值不超过正常分布的 99 分位点。效果也不错掉了 2.1 个点。两种方案都能用但禁量化名单更简单直观而且不需要引入额外的自定义算子我最终选了这个。5.5 这件事留下的方法论这次排查最大的收获是量化不是一个全局开关而是一个逐层决策。全局一把梭的量化方式迟早会在某个特殊层翻车。我在 Model-Optimizer 里加入了一个默认机制自动检测激活值动态范围极窄的层自动建议添加到禁量化名单。这个机制的灵感就是来自这次排查经历。后来我又复盘了一次发现这种激活范围极窄的层在检测、分割模型的回归头里很常见在 Transformer 模型里也有类似情况比如某些 LayerNorm 之后的层。如果你在量化后遇到精度暴跌不要急着怀疑工具先做一次逐层敏感度分析大多数时候元凶就藏在那张表里。6. 部署落地最容易翻车的五个细节6.1 动态 Shape 与固定 Batch 的矛盾很多模型在导出时输入 Shape 写成了[1, 3, 640, 640]跑单张没问题但线上真实推理可能有 batch 请求或者输入尺寸不固定。推理引擎对动态 Shape 的支持差异很大ONNX Runtime 好些TensorRT 就会因为动态 Shape 额外做很多优化上的妥协性能打折。我的建议是如果业务允许尽量固定输入尺寸和 batch用 padding 或外部排队来凑齐。这能让推理引擎做更激进的布局优化实测 TensorRT 下固定 Shape 的 INT8 推理比动态 Shape 快 20% 到 30%。如果必须动态那在导出时就要显式声明 dynamic axes并且不要把一个完全没有动态声明的模型硬塞给推理引擎。6.2 预处理管线不一致RGB、BGR与归一化这是部署阶段最隐蔽的坑。PyTorch 训练时用的是(x/255 - mean)/std的归一化颜色顺序是 RGB而 OpenCV 读出来的图片是 BGR两者不统一时模型输入数值完全不同。FP32 模型对这一点还能靠鲁棒性扛一扛量化模型就真不行了误差会被量化放大。每个做部署的团队都应该有一个预处理一致性检查项列清楚输入尺寸、通道顺序、归一化公式、色域区间然后在集成测试里专门跑一组 RGB/BGR 对照样例。我见过有项目因为这个问题在客户现场排查了一整天最后发现是预处理里一个cv2.cvtColor没调用。6.3 半精度与整型的混合计算INT8 卷积之后通常跟着一个 Dequantize 转回 FP32再接后续的 BN 或激活层。这里如果发生 FP16 和 FP32 混用或者某些层在 INT8 和 FP16 之间反复横跳精度会累积误差而且性能还可能因为频繁格式转换而下降。另一个常见的坑是 BN 层的折叠。量化时BN 层最好先折叠进卷积里否则 BN 的统计量会在 INT8 推理时丢失精度。Model-Optimizer 在导出链路里默认做了 BN 吸收但在你自己手工导出模型时要特别注意如果一个量化模型在推理引擎里结果和 PyTorch 对不上先查 BN 是不是没折叠。6.4 多实例部署下的缓存与线程问题模型优化完之后大家都会想着多开几个实例提升吞吐。但量化模型有些算子会申请大的工作区内存多实例同时启动时内存峰值可能比单实例简单相乘还要高因为每个实例都会为工作区预留额外空间。另外 ONNX Runtime 默认的线程数设置不一定适配你的容器 CPU 配额有时开 8 线程反而比 4 线程慢因为线程频繁切换的开销超过了并行收益。我的建议是在大规模部署前一定要做一次多实例内存压测Threads 数用二分法扫一遍找到最优配置。别想当然地认为线程越多越快量化后的模型瓶颈往往在内存带宽线程加多了反而打架。6.5 最终底线不要为了优化而优化最后一条其实是原则问题。优化有收益但也有成本包括研发时间、回归测试、部署复杂度和后续维护。如果一个模型当前的推理速度已经满足线上需求且未来的迭代不会让模型显著变大那就不要动它。项目里有一类需求我经常劝退客户觉得模型还有优化空间不优化亏了。但如果优化后省下的推理成本抵不上每次模型更新后重新做校准和回归的成本这笔账是亏的。问题典型现象快速排查方法动态 Shape 未声明推理引擎报错或性能低于预期检查导出配置里的 input shape 和 dynamic axes预处理不一致离线指标好真机差对比 RGB/BGR、归一化参数、resize 插值方式BN 未折叠量化后结果与 PyTorch 不一致检查网络结构里是否有独立的 BN 层多实例内存超限部署后 OOM 或被 kill逐实例压测内存峰值量化敏感层未保护精度暴跌跑逐层敏感度分析找出 TOP 敏感层7. 写在最后我在这个项目里养成的三个工程习惯Model-Optimizer 这个项目做下来我自己最大的改变不是会用了更多工具而是养成了三个工程习惯这里分享出来。第一永远保留一份金标本。每次项目接入我都会单独留出一组经过人工复核、覆盖各种边缘场景的样本不参与任何校准和训练只用来做最终的精度验收。这组样本保证了无论优化流程怎么调整最后的评估口径始终一致不会因为换了测试集而出现虚假精度。第二每个优化步骤都记录台账。模型优化是一个多步骤、可回退的过程。我在项目里强制要求每次实验都要记录校准集的来源和数量、量化的具体配置、剪枝比例、蒸馏的 epoch 数、当时的精度值。这个台账在后续几个月后回查问题时价值简直不可估量。第三每次模型更新都要重新跑优化回归。模型迭代了校准集对应的分布变了上一次的最优量化参数不一定还适用。我现在养成的习惯是每次重训后直接把新模型丢进同样的优化流水线跑一遍回归对比优化前后和上一次记录的指标差。虽然多花几小时但能避免模型一更新线上精度悄悄掉这种慢性问题。如果你正准备把一个训练好的模型推向真实设备希望这些从项目里踩出来的经验能帮你少走几趟弯路。优化这条路最怕的不是不会用工具而是不知道工具每一步在做什么、为什么要这么做。把这篇文章里说的原理和排查链路吃透你手里的模型离又快又稳就不远了。
返回列表