专栏感知【PTQ精度debug示例】mnasnet_1.0_96精度问题分析

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

芯链情报局2023-05-05
145
2
为了帮助用户更加快速地了解精度debug分析的使用方法以及测试流程,我们在此处提供三个测试用例以供用户参考,分别为:MobileVit_s、repvgg_b2_deploy以及mnasnet_1.0_96。
其中:
针对MobileVit_s的分析流程请参考:https://developer.horizon.ai/forumDetail/146176821770229921
针对repvgg_b2_deploy的分析流程请参考:https://developer.horizon.ai/forumDetail/146176821770229922
本文主要使用精度debug工具对mnasnet_1.0_96进行量化精度问题定位。mnasnet_1.0_96模型在 imagenet数据集的50000张图片上进行分类精度测试,在默认情况下,模型精度如下:

模型名称

架构

浮点精度

量化精度

mnasnet_1.0_96

bayes

0.61018

0.59896(98.16%)

量化后定点模型的精度没有达到浮点模型的99%,因此使用精度debug工具对该模型进行精度异常定位。

1. 确认单独量化权重 / 激活 的累积误差分布情况

1.1 API使用

dbg.plot_acc_error(
save_dir='./', # 结果保存路径
calibrated_data='./calibration_data', # 校准数据
model_or_file='./calibrated_model.onnx', # 校准模型
quantize_node=['weight', 'activation'], # 量化节点列表,当设置为['weight','activation']时则分别只量化权重和激活
metric='cosine-similarity', # 计算误差的方式(度量方式)
average_mode=False # 是否采用平均累积误差作为输出

1.2 输出结果


从测试结果来看,单独量化权重校准节点或激活校准节点都会给模型引入量化误差,此时需要对模型中普通节点的敏感度进行分析。

2. 节点敏感度排序

2.1 API使用

node_message = dbg.get_sensitivity_of_nodes(
model_or_file='./calibrated_model.onnx', # 校准模型
metrics='cosine-similarity', # 计算敏感度的方式(度量方式)
calibrated_data='./calibration_data/', # 校准数据
output_node=None, # 选取模型中某个节点的输出用于计算敏感度,默认(None)则采用模型的最终输出
node_type='node', # 节点类型
data_num: int = None,
verbose=True, # 是否在终端显示计算结果。True显示,反之,不显示
interested_nodes=None # 选择某些节点只计算这些节点的敏感度。默认(None)计算模型所有节点
)

2.2 输出结果


模型中每个节点的敏感度均大于0.99,但是相较于其他节点,top3节点的敏感度偏低,小于0.999。

3. 敏感节点输出数据分布情况

3.1 API使用

dbg.plot_distribution(save_dir='./',
model_or_file='./calibrated_model.onnx',
calibrated_data='./calibration_data',
nodes_list=['mnasnet_1/lead_cell_0/op_0/depthwise_0/depthwise',
'mnasnet_1/lead_cell_1/op_0/project_0/Conv2D',
'mnasnet_1/lead_cell_1/op_0/depthwise_0/depthwise',
'mnasnet_1/lead_cell_0/op_0/project_0/Conv2D'])

3.2 输出结果

节点名称

节点输出分布

mnasnet_1/lead_cell_0/op_0/depthwise_0/depthwise

mnasnet_1/lead_cell_1/op_0/project_0/Conv2D

mnasnet_1/lead_cell_1/op_0/depthwise_0/depthwise

mnasnet_1/lead_cell_0/op_0/project_0/Conv2D

节点输出分布的判别标准同样是比较数据分布是否符合对量化友好的正态分布。对于客户模型来说,当节点输出不符合正态分布时,客户可以尝试在模型中增加BatchNorm层并重新训练后,再进行PTQ量化。本例中的mnasnet_1/lead_cell_0/op_0/depthwise_0/depthwise和mnasnet_1/lead_cell_1/op_0/depthwise_0/depthwise节点后均没有BatchNorm层。接下来对模型基于节点量化敏感度进行部分量化精度测试。

4. 部分量化精度测试

4.1 API使用

dbg.plot_acc_error(
save_dir='./', # 结果保存路径
calibrated_data='./calibration_data', # 校准数据
model_or_file='./calibrated_model.onnx', # 校准模型
quantize_node=[['mnasnet_1/lead_cell_0/op_0/depthwise_0/depthwise'],
['mnasnet_1/lead_cell_0/op_0/depthwise_0/depthwise',
'mnasnet_1/lead_cell_1/op_0/project_0/Conv2D'],
['mnasnet_1/lead_cell_0/op_0/depthwise_0/depthwise',
'mnasnet_1/lead_cell_1/op_0/project_0/Conv2D',
'mnasnet_1/lead_cell_1/op_0/depthwise_0/depthwise'],
['mnasnet_1/lead_cell_0/op_0/depthwise_0/depthwise',
'mnasnet_1/lead_cell_1/op_0/project_0/Conv2D',
'mnasnet_1/lead_cell_1/op_0/depthwise_0/depthwise',
'mnasnet_1/lead_cell_0/op_0/project_0/Conv2D']], # 四种部分量化方式对应图中的partial_qmodel_0 ~ partial_qmodel_3
metric='cosine-similarity', # 计算误差的方式(度量方式)
average_mode=False # 是否采用平均累积误差作为输出

4.2 测试结果


经测试发现,解除top3节点的量化对模型精度有较大的提升,继续增加不量化节点对模型的提升效果较小。

model

量化策略

浮点精度

校准方式

calibrated_model

mnasnet_1.0_96

default

0.61018

defualt_kl

0.59896(98.16%)

mnasnet_1.0_96

不量化top1节点

0.61018

defualt_kl

0.60184(98.63%)

mnasnet_1.0_96

不量化top2节点

0.61018

defualt_kl

0.60840(99.71%)

mnasnet_1.0_96

不量化top3节点

0.61018

defualt_kl

0.60912(99.83%)

mnasnet_1.0_96

不量化top4节点

0.61018

defualt_kl

0.61046(100.05%)

5. 总结

5.1 误差原因分析

  1. 通过使用精度debug工具中的plot_acc_error分别对量化权重和量化激活的部分量化模型进行累积误差分析可知,权重和激活都会导致模型量化精度下降。

  2. 通过对节点量化敏感度分析发现,所有节点的量化敏感度均大于0.99,只有top3节点的量化敏感度小于0.999,因此可以推断模型量化精度下降的原因在于各个节点量化误差的累积。

5.2 提升精度建议

  1. 若模型中不包含batchnorm,则添加batchnorm后重新训练。

  2. 将对量化敏感的节点run on CPU。

感知
评论1
0/1000
  • iiiiiiiiiiiiiii
    Lv.1
    您好,请问参数:calibrated_data='./calibration_data', # 校准数据

    对应的“debug校准数据集的生成”有相关文档吗?

    根据手册,查到的方法为:在yaml文件中设置参数:debug_mode: 'dump_calibration_data' 就行。
    但实际上,使用OE1.1.49b,编译模型的时候,显示debug_mode这个关键字error,具体如下:
    2023-05-16
    0
    1
    • 颜值即正义回复iiiiiiiiiiiiiii:
      你好,从报错提示看,应该是debug_mode参数的位置放错了,它应该在模型参数组,你放到编译参数组里去了
      2023-05-16
      0