专栏算法工具链PTQ精度Debug工具

PTQ精度Debug工具

芯链情报局2023-08-30
486
0

前言

使用PTQ后量化的模型量化方案,可以帮助用户非常简单便捷地完成从浮点模型到地平线混合异构模型的转换,模型转换工具会基于用户提供的校准样本对模型进行校准量化并保障模型高效地部署在地平线计算平台上。但是在模型转换的过程中,不可避免地会因为浮点高精度到定点低精度的量化过程而引入精度损失,因此为了帮助用户准确快速地定位模型精度损失的主要原因,地平线工具链提供了一套PTQ精度Debug工具。本文将基于J5工具链1.1.62版本的OpenExplorer开发包来详细介绍这些工具的使用方法和使用流程,以及对输出结果进行解读,来帮助用户快速上手。J5 OpenExplorer开发包获取路径为地平线征程5 OpenExplorer算法工具链 版本发布

对于XJ3工具链,PTQ精度Debug工具的使用方法一致,但是暂不支持命令行配置和runall功能,详见XJ3算法工具链手册XJ3算法工具链—PTQ Debug工具使用。XJ3 OpenExplorer开发包获取路径为地平线XJ3 OpenExplorer算法工具链 版本发布

在本文开始之前,需要用户参考文章图片校准数据准备问题介绍与处理模型精度验证及调优建议,掌握正确处理校准数据以及评测模型精度的方法,并且排除因输入数据预处理不当和欠佳的推理结果后处理等非模型自身造成的精度问题。

一、基础介绍

在PTQ模型后量化过程中,通常情况下造成精度损失的主要原因可能有以下几点:

  1. 敏感节点量化问题。模型中的一部分节点对量化比较敏感会引入较大误差;

  2. 节点量化误差累积问题。模型中各个节点的量化误差累积导致模型整体出现较大的校准误差,主要包含:权重量化导致的误差累积、激活量化导致的误差累积以及全量量化导致的误差累积。

  • 获取节点量化敏感度;
  • 获取模型累积误差曲线;
  • 获取指定节点的数据分布;
  • 获取指定节点输入数据通道间数据分布箱线图等。

  1. 校准模型和校准数据的准备。校准模型在模型转换过程中为常态化保存,无需用户额外操作,为模型转换的输出目录model_output下的calibrated_model;校准数据的保存需要用户在Yaml文件中的模型参数组中增加如下参数配置(配置后精度Debug功能同时开启,但需要用户重新编译一次模型,编译等级可以配置为O0以减少编译时间):
  1. 通过import horizon_nn.debug as dbg导入Debug模块(使用命令行则无需导入),加载校准模型和校准数据;
  2. 通过精度Debug工具提供的API或者命令行,对精度损失明显的模型进行分析。详细的流程以及分析见后文。

  1. 激活(activation)校准节点。激活校准节点的输入是当前节点的上一个节点的输出,并基于当前激活校准节点中保存的量化参数对输入数据进行量化和反量化后输出;

  2. 权重(weight)校准节点。权重校准节点的输入是模型的原始浮点权重,并基于当前权重校准节点中保存的量化参数对输入的原始浮点权重进行量化和反量化后输出。

  1. 分别获取权重校准节点和激活校准节点的量化敏感度;

  2. 根据step1的结果,分别取权重校准节点的top5和激活校准节点的top5绘制其数据分布;

  3. 针对step2获取的节点,分别绘制其通道间数据分布的箱线图;

  4. 绘制分别只量化权重和只量化激活的累积误差曲线。

  1. 首先根据累积误差曲线判断模型量化掉点是由激活量化导致的还是由权重量化导致的,确定是激活量化问题还是权重量化问题。如果激活和权重的单独量化误差不明显,可以判断是两者共同作用导致的。

  2. 对于激活量化问题,根据激活节点的量化敏感度排序确定敏感节点;对于权重量化问题,根据权重节点的量化敏感度排序确定敏感节点;对于激活和权重量化问题,计算普通节点的量化敏感度并排序,确定敏感节点。

  3. 获取量化敏感节点后,进行部分节点以较高精度量化或部分节点不量化测试。在J5工具链上,可以对敏感节点设置Int16量化,Int16量化调优工具的使用参考社区文章PTQ精度调优手段—设置Int16量化,同时也可以让敏感节点run_on_cpu。XJ3工具链暂不支持用户手动设置节点以Int16精度量化,可以让敏感节点run_on_cpu。
  4. 同时还可以根据敏感节点数据分布直方图以及通道间数据分布的箱线图来明确优化方向,例如激活敏感节点数据分布不均匀则可以通过优化模型结构来改善,权重敏感节点数据分布不均匀则建议使用QAT等。

  • 指定单节点量化/不量化: 如下配置意为分别只量化`Conv_2`和`Conv_90`并保持其他节点不量化,计算累积误差曲线; 或分别解除量化`Conv_2`和`Conv_90`并保持其他节点量化,计算累积误差曲线。 **API配置方式为:**`quantize_node=['Conv_2', 'Conv_90']`/`non_quantize_node=['Conv_2', 'Conv_90']` **命令行配置方式为:**`-q ['Conv_2', 'Conv_90']`/`-nq ['Conv_2', 'Conv_90']`
  • 指定多个节点量化/不量化: 如下配置意为分别只量化`Conv_2`以及只量化`Conv_2`和`Conv_90`并保持其他节点不量化,计算累积误差曲线; 或分别解除量化`Conv_2`以及解除量化`Conv_2`和`Conv_90`并保持其他节点量化,计算累积误差曲线。 **API配置方式为:**`quantize_node=[['Conv_2'], ['Conv_2', 'Conv_90']]`/`non_quantize_node=[['Conv_2'], ['Conv_2', 'Conv_90']]` **命令行配置方式为:**`-q [['Conv_2'], ['Conv_2', 'Conv_90']]`/`-nq [['Conv_2'], ['Conv_2', 'Conv_90']]`
  • 按照量化敏感度排序选择节点量化/不量化:

  1. 【PTQ精度debug示例】mnasnet_1.0_96精度问题分析

  2. 【PTQ精度debug示例】repvgg_b2_deploy精度问题分析

  3. 【PTQ精度debug示例】MobileVit_s精度问题分析

算法工具链
征程3征程5杂谈
评论0
0/1000