ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

MNN INT8 量化指南:一条命令把模型体积砍掉 75%,精度损失压在 5% 以内

MNN INT8 量化指南:一条命令把模型体积砍掉 75%,精度损失压在 5% 以内 MNN INT8 量化指南一条命令把模型体积砍掉 75%精度损失压在 5% 以内【免费下载链接】MNNMNN: A blazing-fast, lightweight inference engine battle-tested by Alibaba, powering high-performance on-device LLMs and Edge AI.项目地址: https://gitcode.com/GitHub_Trending/mn/MNNMNN 的离线 INT8 量化能把浮点模型压缩约 75%在 ARM 端侧还能换来实测加速校准数据只需几百张图全程不用重训。下面按问题驱动的方式带你走通全流程。什么场景下你会用到 INT8 离线量化模型包体超标是最常见的起因一个 40MB 的视觉模型塞进 App 安装包商店审核和用户下载转化都会被拖累。量化后体积直接缩到四分之一左右。第二个场景是端侧内存吃紧。浮点推理的中间激活占用大输入输出尺寸一放大老机型容易 OOM全 int8 推理能把这部分占用一起降下来。第三个场景是速度。ARMv8 的 int8 指令只有在真正做 int8 运算时才发挥作用离线量化后的模型正好走这条路。只压权值不压特征的话加速是打折扣的。这三件事一起做离线量化就是唯一选择代价是准备一小批校准数据。三步跑通从浮点模型到 int8 模型先编译出量化工具两条命令的事mkdir build cd build cmake .. -DMNN_BUILD_CONVERTERON -DMNN_BUILD_QUANTOOLSON make -j8这会在 build 目录下生成 MNNConvert 和 quantized.out 两个可执行文件。用 Python 的话装官方 pip 包即可mnnquant 是 quantized.out 的封装后续命令都能互换。接着准备校准数据。挑 100~1000 张能代表真实分布的图放进一个目录再写一份 quant.json把预处理信息format、mean、normal、width、height和校准目录path填进去字段含义见下面参数速查。最后执行一条命令./quantized.out model_float.mnn model_quant_int8.mnn quant.json跑完得到 int8 模型。用同一批输入分别推理两个模型对比输出或用 benchmark 工具测吞吐心里就有底了。官方文档离线量化工具说明。参数速查quant.json 核心字段一览字段含义format图片通道格式如 RGB、BGR、GRAYmean / normal预处理参数变换公式 dst (src - mean) * normalwidth / height模型输入宽高path校准图片目录used_image_num使用的校准图片数缺省为目录下全部feature_quantize_method特征量化方法KL、ADMM、EMAweight_quantize_method权值量化方法MAX_ABS、ADMMfeature_clamp_value / weight_clamp_value量化取值范围默认 127batch_sizeEMA 方法的批大小quant_bits量化位宽默认 8skip_quant_op_names跳过量化的算子名列表input_type输入类型默认 image多输入模型改 sequencedebug是否输出各层余弦距离和溢出率两个易错点mean 和 normal 必须和你训练时的预处理完全一致对不上精度会莫名其妙地掉weight_clamp_value 不建议动权值范围改动对精度影响更大。精度掉了、溢出了四个高频问题怎么排查量化后精度下降明显。多半是校准数据不真实图太少或分布和线上场景对不上。先换一批更有代表性的数据把数量控制在 100~1000 张。还降不下来就开 debug 看每层的余弦距离和溢出率定位到具体层后把它加进 skip_quant_op_names或者用仓库里的 tools/converter/tools/auto_quant.py 自动搜索敏感层。校准日志里溢出率很高。说明特征动态范围超出了量化范围被截断成平顶分布。处理办法是把 feature_clamp_value 从 127 适当下调比如 120降太多分辨率会变差需要反复试。多输入模型非图片输入跑不了校准。要把 input_type 改成 sequence按 path 下的子目录组织数据每个输入名一个 txt 文件再配一个 input.json 写清各输入输出的名字和 shape用 GetMNNInfo 工具可以查模型的真实输入输出名。量化了却没提速。确认运行时真的在做 int8 运算权值量化默认是推理时还原成 float 的想加速要么走离线量化要么编译时加 -DMNN_LOW_MEMORYON、推理时把 memory 模式设成 Memory_Low缺一个都不加速。进阶精度与体积的取舍顺序先说清楚不是每一层都值得压。取舍按下面的顺序来每做一步都重新测精度。第一优先跳过敏感层。第一层卷积这类层对精度影响大宁可保留浮点。用 auto_quant.py 配一个最大允许误差率它会替你找出该跳的层。第二优先收紧特征范围。溢出率降不下来的时候把 feature_clamp_value 从 127 往 120 附近调。第三优先换量化方法。特征方法从 KL 换 EMA非对称量化精度经常更好batch_size 设得和训练时接近权值方法从 MAX_ABS 换 ADMM 也能再抠一点精度。最后才考虑压体积。空间实在不够再用 4bit 权值这类手段。顺序别反别一上来就全图低 bit 硬压那是拿精度换体积的下策。收尾量化该做成什么样MNN 的离线 INT8 量化做到位就是体积省 75%、精度损失压在 5% 以内MobileNetV2 从 14M 压到 3.5M华为 P20 Pro 上推理从 62ms 到 42msResNet-18 也有 187ms 到 167ms 的提升。关键就三件事校准数据要真、敏感层要跳、预处理要对齐。更多方案对比和完整字段说明见 模型压缩指南离线量化工具入口在 docs/tools/quant.md源码实现位于 source/backend/cpu/ 目录。【免费下载链接】MNNMNN: A blazing-fast, lightweight inference engine battle-tested by Alibaba, powering high-performance on-device LLMs and Edge AI.项目地址: https://gitcode.com/GitHub_Trending/mn/MNN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进