其中:
针对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使用
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使用
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使用
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使用
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 误差原因分析
通过使用精度debug工具中的plot_acc_error分别对量化权重和量化激活的部分量化模型进行累积误差分析可知,权重和激活都会导致模型量化精度下降。
通过对节点量化敏感度分析发现,所有节点的量化敏感度均大于0.99,只有top3节点的量化敏感度小于0.999,因此可以推断模型量化精度下降的原因在于各个节点量化误差的累积。
5.2 提升精度建议
若模型中不包含batchnorm,则添加batchnorm后重新训练。
将对量化敏感的节点run on CPU。






