6.2.12. 精度debug工具

模型转换工具链会基于您提供的校准样本对模型进行校准量化并保障模型高效的部署在地平线计算平台上。 而在模型转换的过程中,难免会因为浮点到定点的量化过程而引入精度损失,通常情况下造成精度损失的主要原因可能有以下几点:

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

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

针对该情况,地平线提供了精度debug工具用以协助您自主定位模型量化过程中产生的精度问题。 该工具能够协助您对校准模型进行节点粒度的量化误差分析,最终帮助您快速定位出现精度异常的节点。

精度debug工具提供多种分析功能供您使用,例如:

  • 获取节点量化敏感度。

  • 获取模型累积误差曲线。

  • 获取指定节点的数据分布。

  • 获取指定节点输入数据通道间数据分布箱线图等。

6.2.12.1. 快速上手

使用精度debug工具主要有以下几个步骤:

1.在yaml中的 模型参数组(model_parameters) 配置参数 debug_mode: "dump_calibration_data" ,保存校准数据。

2.导入debug模块,加载校准模型和数据。

3.通过精度debug工具提供的API或命令行,对精度损失明显的模型进行分析。

整体流程如下图所示:

../../../../_images/accuracy_debug_process.png

6.2.12.1.1. 校准模型与数据的保存

首先需要在yaml文件中配置 debug_mode: "dump_calibration_data" ,以开启精度debug功能, 并保存校准数据(calibration_data),对应的校准模型(calibrated_model.onnx)为常态化保存。其中:

  • 校准数据(calibration_data):在校准阶段,模型通过对这些数据进行前向推理来获取每个被量化节点的量化参数,包括:缩放因子(scale)和阈值(threshold)。

  • 校准模型(calibrated_model.onnx):将在校准阶段计算得到的每个被量化节点的量化参数保存在校准节点中,从而得到校准模型。

注解

此处保存的校准数据与02_preprocess.sh生成的校准数据的区别?

02_preprocess.sh 得到的校准数据是bgr颜色空间的数据,在工具链内部会将数据从bgr转换到yuv444/gray等模型实际输入的格式。 而此处保存的校准数据则是经过颜色空间转换以及预处理之后保存的.npy格式的数据,该数据可以通过np.load()直接送入模型进行推理。

注解

校准模型(calibrated_model.onnx)解读

校准模型是模型转换工具链将浮点模型经过结构优化后,通过校准数据计算得到的每个节点对应的量化参数并将其保存在校准节点中得到的中间产物。 校准模型的主要特点是模型中包含校准节点,校准节点的节点类型为HzCalibration。 这些校准节点主要分为两类: 激活(activation)校准节点权重(weight)校准节点

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

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

除却上述的校准节点,校准模型中的其他节点,精度debug工具将其称为 普通节点(node)普通节点 的类型包括:Conv、Mul、Add等。

../../../../_images/debug_node.png

calibration_data的文件夹结构如下:

|--calibration_data :校准数据
|----input.1 :文件夹名为模型的输入节点并保存对应的输入数据
|--------0.npy
|--------1.npy
|-------- ...
|----input.2 :对于多输入模型将保存多个文件夹
|--------0.npy
|--------1.npy
|-------- ...

6.2.12.1.2. 精度debug模块导入与使用

接下来需要在代码中导入debug模块,并通过 get_sensitivity_of_nodes 接口获取节点量化敏感度(默认使用模型输出的余弦相似度)。 get_sensitivity_of_nodes 的详细参数说明可见 get_sensitivity_of_nodes 章节。

# 导入debug模块
import horizon_nn.debug as dbg
# 导入log日志模块
import logging

# 若verbose=True时,需要先设置log level为INFO
logging.getLogger().setLevel(logging.INFO)
# 获取节点量化敏感度
node_message = dbg.get_sensitivity_of_nodes(
        model_or_file='./calibrated_model.onnx',
        metrics=['cosine-similarity', 'mse'],
        calibrated_data='./calibration_data/',
        output_node=None,
        node_type='node',
        data_num=None,
        verbose=True,
        interested_nodes=None)

6.2.12.1.3. 分析结果展示

下方为 verbose=True 时的打印结果:

=================node sensitivity=================
node                  cosine-similarity  mse
---------------------------------------------------
Conv_60               0.77795            68.02103
Conv_48               0.78428            64.36318
Conv_82               0.80394            61.09268
Conv_94               0.80499            65.05224
Conv_42               0.83787            49.4949
Conv_88               0.84614            49.81132
Conv_54               0.86602            41.69972
Conv_71               0.87148            39.96296
Conv_65               0.87495            40.45997
Conv_25               0.89214            34.30351
Conv_20               0.89829            32.35053
Conv_77               0.89916            31.9907
Conv_14               0.90058            32.40179
Conv_9                0.90107            34.08191
Conv_37               0.91162            28.21194
Conv_31               0.91637            28.79291

除此之外,该API会以字典(Dict)的形式将节点量化敏感度信息返回给您以供后续使用分析。

Out:
{'Conv_60': {'cosine-similarity': 0.77795, 'mse': 68.02103},
 'Conv_48': {'cosine-similarity': 0.78428, 'mse': 64.36318},
 'Conv_82': {'cosine-similarity': 0.80394, 'mse': 61.09268},
 'Conv_94': {'cosine-similarity': 0.80499, 'mse': 65.05224},
 'Conv_42': {'cosine-similarity': 0.83787, 'mse': 49.4949},
 'Conv_88': {'cosine-similarity': 0.84614, 'mse': 49.81132},
 'Conv_54': {'cosine-similarity': 0.86602, 'mse': 41.69972},
 'Conv_71': {'cosine-similarity': 0.87148, 'mse': 39.96296},
 'Conv_65': {'cosine-similarity': 0.87495, 'mse': 40.45997},
 'Conv_25': {'cosine-similarity': 0.89214, 'mse': 34.30351},
 'Conv_20': {'cosine-similarity': 0.89829, 'mse': 32.35053},
 'Conv_77': {'cosine-similarity': 0.89916, 'mse': 31.9907},
 'Conv_14': {'cosine-similarity': 0.90058, 'mse': 32.40179},
 'Conv_9': {'cosine-similarity': 0.90107, 'mse': 34.08191},
 'Conv_37': {'cosine-similarity': 0.91162, 'mse': 28.21194},
 'Conv_31': {'cosine-similarity': 0.91637, 'mse': 28.79291}}

更多功能详见 功能说明文档 章节。

为了方便您使用,精度debug工具还支持通过命令行进行使用,可通过 hmct-debugger -h/--help 查看 每个功能对应的子命令。各个子命令的详细参数和用法详见 功能说明文档 章节。

6.2.12.2. 功能说明文档

6.2.12.2.1. get_sensitivity_of_nodes

功能:获取节点量化敏感度。

命令行格式

hmct-debugger get-sensitivity-of-nodes MODEL_OR_FILE CALIBRATION_DATA --other options

可通过 hmct-debugger get-sensitivity-of-nodes -h/--help 查看相关参数。

参数组

编 号

参数名称

命令行参数缩写

参数配置说明

可选/

必选

1

model_or_file

固定参数

参数作用:指定校准模型。

取值范围:无。

默认配置:无。

参数说明:必选,指定需要分析的校准模型。

必选

2

metrics

-m

参数作用:节点量化敏感度的度量方式。

取值范围'cosine-similarity' , 'mse' , 'mre' , 'sqnr' , 'chebyshev'

默认配置'cosine-similarity'

参数说明:指定节点量化敏感度的计算方式,该参数可以为列表(List), 即以多种方式计算量化敏感度, 但是输出结果仅以列表中第一位的计算方式进行排序, 排名越靠前说明量化该节点引入的误差越大。

可选

3

calibrated_data

固定参数

参数作用:指定校准数据。

取值范围:无。

默认配置:无。

参数说明:必选,指定分析所需要的校准数据。

必选

4

output_node

-o

参数作用:指定输出节点。

取值范围:校准模型中的具有对应校准节点的普通节点。

默认配置:None。

参数说明:此参数支持您指定中间节点作为输出并计算节点量化敏感度。 若保持默认参数None,则精度debug工具会获取模型的最终输出 并在此基础上计算节点的量化敏感度。

可选

5

node_type

-n

参数作用:节点类型。

取值范围'node' , 'weight' , 'activation'

默认配置'node'

参数说明:需要计算量化敏感度的节点类型,包括:node(普通节点)、 weight(权重校准节点)、activation(激活校准节点)。

可选

6

data_num

-d

参数作用:计算量化敏感度需要的数据数量。

取值范围:大于0,小于等于calibration_data中数据的总数。

默认配置:1

参数说明:设置计算节点量化敏感度时所需要的数据数量。 默认为None,此时默认使用calibration_data中的所有数据进行计算。 最小设置为1,最大为 calibration_data中的数据数量。

可选

7

verbose

-v

参数作用:选择是否将信息打印在终端上。

取值范围TrueFalse

默认配置False

参数说明:若为True,则将量化敏感度信息打印在终端上。 若metrics包含多种度量方式,则按照第一位进行排序。

可选

8

interested_nodes

-i

参数作用:设置感兴趣节点。

取值范围:校准模型中的所有节点。

默认配置:None。

参数说明:若指定则只获取该节点的量化敏感度,其余节点不获取。 同时,若该参数被指定,将忽视node_type指定的节点类型, 也就是说该参数的优先级要高于node_type。 若保持默认参数None,则计算模型中所有可被量化节点的量化敏感度。

可选

API使用方法:

# 导入debug模块
import horizon_nn.debug as dbg
# 导入log日志模块
import logging

# 若verbose=True时,需要先设置log level为INFO
logging.getLogger().setLevel(logging.INFO)
# 获取节点量化敏感度
node_message = dbg.get_sensitivity_of_nodes(
        model_or_file='./calibrated_model.onnx',
        metrics=['cosine-similarity', 'mse'],
        calibrated_data='./calibration_data/',
        output_node=None,
        node_type='node',
        data_num=None,
        verbose=True,
        interested_nodes=None)

命令行使用方法:

hmct-debugger get-sensitivity-of-nodes calibrated_model.onnx calibration_data -m ['cosine-similarity','mse'] -v True

分析结果展示

描述:首先您通过node_type设置需要计算敏感度的节点类型,然后工具获取校准模型中所有符合node_type的节点,并获取这些节点的量化敏感度。 当verbose设置为True时,工具会将节点量化敏感度进行排序后打印在终端,排序越靠前,说明该节点量化引入的量化误差越大。同时对于不同的node_type,工具会显示不同的节点量化敏感度信息。

verbose=True且node_type=’node’时,打印结果如下:

=================node sensitivity=================
node                  cosine-similarity  mse
---------------------------------------------------
Conv_60               0.77795            68.02103
Conv_48               0.78428            64.36318
Conv_82               0.80394            61.09268
Conv_94               0.80499            65.05224
Conv_42               0.83787            49.4949
Conv_88               0.84614            49.81132
Conv_54               0.86602            41.69972
Conv_71               0.87148            39.96296
Conv_65               0.87495            40.45997
Conv_25               0.89214            34.30351
Conv_20               0.89829            32.35053
Conv_77               0.89916            31.9907
Conv_14               0.90058            32.40179
Conv_9                0.90107            34.08191
Conv_37               0.91162            28.21194
Conv_31               0.91637            28.79291

其中:

  • node:节点名。

  • cosine-similarity、mse:各个节点的量化敏感度数值。

verbose=True且node_type=’weight’时,打印结果如下:

====================================node sensitivity====================================
weight                                              node     cosine-similarity  mse
-----------------------------------------------------------------------------------------
471_HzCalibration                                   Conv_2   0.99978            0.07519
480_HzCalibration                                   Conv_7   0.99986            0.04823
609_HzCalibration                                   Conv_88  0.99997            0.01145
573_HzCalibration                                   Conv_65  0.99997            0.00984
474_HzCalibration                                   Conv_4   0.99997            0.00963
468_HzCalibration                                   Conv_0   0.99997            0.0091
612_HzCalibration                                   Conv_90  0.99997            0.00871
585_HzCalibration                                   Conv_73  0.99997            0.0095
483_HzCalibration                                   Conv_9   0.99998            0.00818
600_HzCalibration                                   Conv_82  0.99998            0.00717
582_HzCalibration                                   Conv_71  0.99998            0.00659
603_HzCalibration                                   Conv_84  0.99998            0.00614
591_HzCalibration                                   Conv_77  0.99998            0.00558
489_HzCalibration                                   Conv_12  0.99998            0.00515
564_HzCalibration                                   Conv_60  0.99999            0.00495
618_HzCalibration                                   Conv_94  0.99999            0.00498
543_HzCalibration                                   Conv_46  0.99999            0.00502
552_HzCalibration                                   Conv_52  0.99999            0.00501
594_HzCalibration                                   Conv_78  0.99999            0.00451
555_HzCalibration                                   Conv_54  0.99999            0.00452
...99classifier.1.weight_conv_weight_HzCalibration  Gemm_99  0.99999            0.00359
558_HzCalibration                                   Conv_56  0.99999            0.00369

其中:

  • weight:权重校准节点名。

  • node:权重校准节点对应的普通节点名,即权重校准节点的输出为其输入。

  • cosine-similarity、mse:各个节点的量化敏感度数值。

verbose=True且node_type=’activation’时,打印结果如下:

===================================node sensitivity===================================
activation          node                  threshold  bit  cosine-similarity  mse
---------------------------------------------------------------------------------------
406_HzCalibration   Conv_60               0.91501    8    0.77851            67.82422
388_HzCalibration   Conv_48               0.55422    8    0.78501            64.16379
440_HzCalibration   Conv_82               2.01577    8    0.8041             61.0322
458_HzCalibration   Conv_94               0.51507    8    0.80466            65.14515
379_HzCalibration   Conv_42               0.53759    8    0.83837            49.35648
449_HzCalibration   Conv_88               2.34071    8    0.84447            50.29965
397_HzCalibration   Conv_54               0.81528    8    0.86499            41.99234
423_HzCalibration   Conv_71               0.84753    8    0.87104            40.09385
414_HzCalibration   Conv_65               0.80155    8    0.87443            40.63319
353_HzCalibration   Conv_25               0.67858    8    0.89199            34.34844
345_HzCalibration   Conv_20               1.06324    8    0.8984             32.31664
432_HzCalibration   Conv_77               2.54515    16   0.89895            32.0417
336_HzCalibration   Conv_14               1.01407    8    0.90091            32.30325
328_HzCalibration   Conv_9                1.61622    8    0.90163            33.78012
371_HzCalibration   Conv_37               0.91038    8    0.91277            27.84864
362_HzCalibration   Conv_31               0.65606    8    0.91683            28.65791
403_HzCalibration   Conv_58               0.95119    8    0.93365            21.32314
391_HzCalibration   Conv_50;Add_55        2.92598    8    0.93984            19.72109
382_HzCalibration   Conv_44;Add_49        2.75416    8    0.95122            17.74137
417_HzCalibration   Conv_67;Add_72        2.85463    8    0.95139            15.81864

其中:

  • activation:激活校准节点名。

  • node:在模型结构中在激活校准节点后的普通节点,即激活校准节点的输出为其输入。

  • threshold:校准阈值,若有多个阈值则取最大值。

  • bit:量化比特。

  • cosine-similarity、mse:各个节点的量化敏感度数值。

API返回值:

API返回值为以字典格式(Key为节点名称,Value为节点的量化敏感度信息)保存的量化敏感度,格式如下:

Out:
{'Conv_60': {'cosine-similarity': 0.77795, 'mse': 68.02103},
 'Conv_48': {'cosine-similarity': 0.78428, 'mse': 64.36318},
 'Conv_82': {'cosine-similarity': 0.80394, 'mse': 61.09268},
 'Conv_94': {'cosine-similarity': 0.80499, 'mse': 65.05224},
 'Conv_42': {'cosine-similarity': 0.83787, 'mse': 49.4949},
 'Conv_88': {'cosine-similarity': 0.84614, 'mse': 49.81132},
 'Conv_54': {'cosine-similarity': 0.86602, 'mse': 41.69972},
 'Conv_71': {'cosine-similarity': 0.87148, 'mse': 39.96296},
 'Conv_65': {'cosine-similarity': 0.87495, 'mse': 40.45997},
 'Conv_25': {'cosine-similarity': 0.89214, 'mse': 34.30351},
 'Conv_20': {'cosine-similarity': 0.89829, 'mse': 32.35053},
 'Conv_77': {'cosine-similarity': 0.89916, 'mse': 31.9907},
 'Conv_14': {'cosine-similarity': 0.90058, 'mse': 32.40179},
 'Conv_9': {'cosine-similarity': 0.90107, 'mse': 34.08191},
 'Conv_37': {'cosine-similarity': 0.91162, 'mse': 28.21194},
 'Conv_31': {'cosine-similarity': 0.91637, 'mse': 28.79291}}

6.2.12.2.2. plot_acc_error

功能:只量化浮点模型中的某一个节点,并依次计算该模型与浮点模型中节点输出的误差,获得累积误差曲线。

命令行格式:

hmct-debugger plot-acc-error MODEL_OR_FILE CALIBRATION_DATA --other options

可通过 hmct-debugger plot-acc-error -h/--help 查看相关参数。

参数组

编 号

参数名称

命令行参数缩写

参数配置说明

可选/

必选

1

save_dir

-s

参数作用:保存路径。

取值范围:无。

默认配置:无。

参数说明:可选,指定分析结果的保存路径。

可选

2

calibrated_data

固定参数

参数作用:指定校准数据。

取值范围:无。

默认配置:无。

参数说明:必选,指定需要分析的校准数据。

必选

3

model_or_file

固定参数

参数作用:指定校准模型。

取值范围:无。

默认配置:无。

参数说明:必选,指定需要分析的校准模型。

必选

4

quantize_node

-q

参数作用:只量化模型中指定的节点,查看误差累积曲线。

取值范围:校准模型中的所有节点。

默认配置:None。

参数说明:可选参数。指定模型中需要量化的节点,同时保证其余节点均不量化。 通过判断该参数是否为嵌套列表进而决定是单节点量化还是部分量化。

例如:

  • quantize_node=[‘Conv_2’,’Conv_9’]:分别只量化Conv_2和Conv_9,同时保证其余节点不量化。

  • quantize_node=[[‘Conv_2’],[‘Conv_9’,’Conv_2’]]:只量化Conv_2以及同时量化Conv_2和Conv_9,分别测试模型累积误差。

  • quantize_node 包含两个特殊参数:’weight’ 和 ‘activation’。当:

    • quantize_node = [‘weight’]:只量化权重,不量化激活。

    • quantize_node = [‘activation’]:只量化激活,不量化权重。

    • quantize_node = [‘weight’,’activation’]:权重和激活分别量化。

注:quantize_node和non_quantize_node不可同时为None,必须指定其一。

可选

5

non_quantize_node

-nq

参数作用:指定累积误差的类型。

取值范围:校准模型中的所有节点。

默认配置:None。

参数说明:可选参数。指定模型中不量化的节点,同时保证其余节点全都量化。 通过判断该参数是否为嵌套列表进而决定是单节点不量化还是部分量化。

例如:

  • non_quantize_node=[‘Conv_2’,’Conv_9’]:分别解除Conv_2和Conv_9节点的量化,同时保证其余节点全部量化。

  • non_quantize_node=[[‘Conv_2’],[‘Conv_9’,’Conv_2’]]:只解除Conv_2量化以及同时解除Conv_2和Conv_9量化,分别测试模型累积误差。

注:quantize_node和non_quantize_node不可同时为None,必须指定其一。

可选

6

metric

-m

参数作用:误差度量方式。

取值范围'cosine-similarity' , 'mse' , 'mre' , 'sqnr' , 'chebyshev'

默认配置'cosine-similarity'

参数说明:设置计算模型误差的计算方式。

可选

7

average_mode

-a

参数作用:指定累积误差曲线的输出模式。

取值范围TrueFalse

默认配置False

参数说明:默认为False。若为True,那么获取累积误差的平均值作为结果。

可选

# 导入debug模块
import horizon_nn.debug as dbg

dbg.plot_acc_error(
        save_dir: str,
        calibrated_data: str or CalibrationDataSet,
        model_or_file: ModelProto or str,
        quantize_node: List or str,
        non_quantize_node: List or str,
        metric: str = 'cosine-similarity',
        average_mode: bool = False)

分析结果展示

1.指定节点量化累积误差测试

  • 指定单节点量化

配置方式:quantize_node=[‘Conv_2’, ‘Conv_90’],quantize_node为单列表。

API使用方法:

# 导入debug模块
import horizon_nn.debug as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        quantize_node=['Conv_2', 'Conv_90'],
        metric='cosine-similarity',
        average_mode=False)

命令行使用方法:

hmct-debugger plot-acc-error calibrated_model.onnx calibrated_data -q ['Conv_2','Conv_90']

描述:当quantize_node为单列表时,针对您设置的quantize_node, 分别单独量化quantize_node中的节点并保持模型中其他节点不量化,得到对应的模型后, 对该模型中每个节点的输出计算其与浮点模型中对应节点输出的之间的误差,并得到对应的累积误差曲线。

average_mode = False时:

../../../../_images/average_mode_false_1.png

average_mode = True时:

../../../../_images/average_mode_true_1.png

注解

average_mode

average_mode默认为False。对于一些模型,此时无法通过累积误差曲线判断哪种量化策略更加有效, 因此需要将average_mode设置为True,此时会对前n个节点的累积误差求均值作为第n个节点的累积误差。

具体计算方式如下,例如:

average_mode=False时,accumulate_error=[1.0, 0.9, 0.9, 0.8]。

而将average_mode=True后,accumulate_error=[1.0, 0.95, 0.933, 0.9]。

  • 指定多个节点量化

配置方式:quantize_node=[[‘Conv_2’], [‘Conv_2’, ‘Conv_90’]],quantize_node为嵌套列表

API使用方法:

# 导入debug模块
import horizon_nn.debug as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        quantize_node=[['Conv_2'], ['Conv_2', 'Conv_90']],
        metric='cosine-similarity',
        average_mode=False)

命令行使用方法:

hmct-debugger plot-acc-error calibrated_model.onnx calibration_data -q [['Conv_2'],['Conv_2','Conv_90']]

描述:当quantize_node为嵌套列表时,针对您设置的quantize_node,分别量化quantize_node中的 每个单列表指定的节点并保持模型中其他节点不量化,得到对应的模型后,对该模型中每个节点的输出计算 其与浮点模型中对应节点输出的之间的误差,并得到对应的累积误差曲线。

  • partial_qmodel_0:只量化Conv_2节点,其余节点不量化;

  • partial_qmodel_1:只量化Conv_2和Conv_90节点,其余节点不量化。

average_mode=False时:

../../../../_images/new_average_mode_false_1.png

average_mode=True时:

../../../../_images/new_average_mode_true_1.png

2.解除模型部分节点量化后累积误差测试

  • 指定单节点不量化

配置方式:non_quantize_node=[‘Conv_2’, ‘Conv_90’],non_quantize_node为单列表。

API使用方法:

# 导入debug模块
import horizon_nn.debug as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        non_quantize_node=['Conv_2', 'Conv_90'],
        metric='cosine-similarity',
        average_mode=True)

命令行使用方法:

hmct-debugger plot-acc-error calibrated_model.onnx calibration_data -nq ['Conv_2','Conv_90'] -a True

描述:当non_quantize_node为单列表时,针对您设置的non_quantize_node, 分别解除non_quantize_node中各个节点的量化同时保持其他节点全部量化,得到对应的模型后, 对该模型中每个节点的输出计算其与浮点模型中对应节点输出的之间的误差,并得到对应的累积误差曲线。

average_mode = False时:

../../../../_images/average_mode_false_2.png

average_mode = True时:

../../../../_images/average_mode_true_2.png
  • 指定多个节点不量化

配置方式:non_quantize_node=[[‘Conv_2’], [‘Conv_2’, ‘Conv_90’]],non_quantize_node为嵌套列表。

API使用方法:

# 导入debug模块
import horizon_nn.debug as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        non_quantize_node=[['Conv_2'], ['Conv_2', 'Conv_90']],
        metric='cosine-similarity',
        average_mode=False)

命令行使用方法:

hmct-debugger plot-acc-error calibrated_model.onnx calibration_data -nq [['Conv_2'],['Conv_2','Conv_90']]

描述:当non_quantize_node为嵌套列表时,针对您设置的non_quantize_node, 分别不量化non_quantize_node中的每个单列表指定的节点并保持模型中其他节点均量化, 得到对应的模型后,对该模型中每个节点的输出计算其与浮点模型中对应节点输出的之间的误差, 并得到对应的累积误差曲线。

  • partial_qmodel_0:不量化Conv_2节点,其余节点量化;

  • partial_qmodel_1:不量化Conv_2和Conv_90节点,其余节点量化。

average_mode = False时:

../../../../_images/new_average_mode_false_2.png

average_mode = True时:

../../../../_images/new_average_mode_true_2.png

测试技巧

测试部分量化精度时,您可能会按照量化敏感度排序进行多组量化策略的精度对比,此时可以参考以下用法:

# 导入debug模块
import horizon_nn.debug as dbg

# 首先使用量化敏感度排序函数获取模型中节点的量化敏感度排序
node_message = dbg.get_sensitivity_of_nodes(
        model_or_file='./calibrated_model.onnx',
        metrics='cosine-similarity',
        calibrated_data='./calibration_data/',
        output_node=None,
        node_type='node',
        verbose=False,
        interested_nodes=None)

# node_message为字典类型,其key值为节点名称
nodes = list(node_message.keys())

# 通过nodes来指定不量化节点,可以方便使用
dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        non_quantize_node=[nodes[:1],nodes[:2]],
        metric='cosine-similarity',
        average_mode=True)

3.激活权重分别量化

配置方式:quantize_node=[‘weight’,’activation’]。

API使用方法:

import horizon_nn.debug as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        quantize_node=['weight','activation'],
        metric='cosine-similarity',
        average_mode=False)

命令行使用方法:

hmct-debugger plot-acc-error calibrated_model.onnx calibration_data -q ['weight','activation']

描述:quantize_node也可直接指定’weight’或者’activation’。当:

  • quantize_node = [‘weight’]:只量化权重,不量化激活。

  • quantize_node = [‘activation’]:只量化激活,不量化权重。

  • quantize_node = [‘weight’, ‘activation’]:权重和激活分别量化。

../../../../_images/weight_activation_quantized.png

注解

通常情况下,建议您对累积误差曲线图中靠近模型输出位置的曲线部分多加关注。 当采用某种量化方法后测试得到的累计误差曲线靠近模型输出位置的累积误差较小,即相似度较高时,我们建议您优先测试此种量化方法。

6.2.12.2.3. plot_distribution

功能:选取节点,分别获取该节点在浮点模型和校准模型中的输出,得到输出数据分布。另外,将两个输出结果做差,获取两个输出之间的误差分布。

命令行格式

hmct-debugger plot-distribution MODEL_OR_FILE CALIBRATION_DATA --other options

可通过 hmct-debugger plot-distribution -h/--help 查看相关参数。

参数组

编 号

参数名称

命令行参数缩写

参数配置说明

可选/

必选

1

save_dir

-s

参数作用:保存路径。

取值范围:无。

默认配置:无。

参数说明:可选,指定分析结果的保存路径。

可选

2

model_or_file

固定参数

参数作用:指定校准模型。

取值范围:无。

默认配置:无。

参数说明:必选,指定需要分析的校准模型。

必选

3

calibrated_data

固定参数

参数作用:指定校准数据。

取值范围:无。

默认配置:无。

参数说明:必选,指定分析所需要的校准数据。

必选

4

nodes_list

-n

参数作用:指定需要分析的节点。

取值范围:校准模型中的所有节点。

默认配置:无。

参数说明:必选,指定需要分析的节点。若nodes_list中的节点类型为:

  • 权重校准节点:绘制原始权重和经过校准之后的权重的数据分布。

  • 激活校准节点:绘制激活校准节点的输入数据分布。

  • 普通节点:绘制该节点在量化前后的输出数据分布,同时绘制二者之间的误差分布。

注:nodes_list为 list 类型,可指定一系列节点,并且上述三种类型节点 可同时指定。

必选

# 导入debug模块
import horizon_nn.debug as dbg

dbg.plot_distribution(
        save_dir: str,
        model_or_file: ModelProto or str,
        calibrated_data: str or CalibrationDataSet,
        nodes_list: List[str] or str)

分析结果展示

API使用方法:

# 导入debug模块
import horizon_nn.debug as dbg

dbg.plot_distribution(
        save_dir='./',
        model_or_file='./calibrated_model.onnx',
        calibrated_data='./calibration_data',
        nodes_list=['317_HzCalibration', # 激活节点
                    '471_HzCalibration', # 权重节点
                    'Conv_2']) # 普通节点

命令行使用方法:

hmct-debugger plot-distribution calibrated_model.onnx calibration_data -n ['317_HzCalibration','471_HzCalibration','Conv_2']

node_output:

../../../../_images/node_output.png

weight:

../../../../_images/weight.png

activation:

../../../../_images/activation.png

注解

上方三幅图中,蓝色三角表示:数据绝对值的最大值。红色虚线表示:最大的校准阈值。

6.2.12.2.4. get_channelwise_data_distribution

功能:绘制指定校准节点输入数据通道间数据分布的箱线图。

命令行格式

hmct-debugger get-channelwise-data-distribution MODEL_OR_FILE CALIBRATION_DATA --other options

可通过 hmct-debugger get-channelwise-data-distribution -h/--help 查看相关参数。

参数组

编 号

参数名称

命令行参数缩写

参数配置说明

可选/

必选

1

save_dir

-s

参数作用:保存路径。

取值范围:无。

默认配置:无。

参数说明:可选,指定分析结果的保存路径。

可选

2

model_or_file

固定参数

参数作用:指定校准模型。

取值范围:无。

默认配置:无。

参数说明:必选,指定需要分析的校准模型。

必选

3

calibrated_data

固定参数

参数作用:指定校准数据。

取值范围:无。

默认配置:无。

参数说明:必选,指定分析所需要的校准数据。

必选

4

nodes_list

-n

参数作用:指定校准节点。

取值范围:校准模型中的所有权重校准节点和激活校准节点。

默认配置:无。

参数说明:必选,指定校准节点。

必选

5

axis

-a

参数作用:指定channel所在的维度。

取值范围:小于节点输入数据的维度。

默认配置:None。

参数说明:channel信息所在shape中的位置。 参数默认为None,此时对于激活校准节点, 默认认为节点输入数据的第二个维度表示channel信息,即axis=1; 对于权重校准节点,会读取该节点属性中的axis参数作为channel信息。

可选

# 导入debug模块
import horizon_nn.debug as dbg

dbg.get_channelwise_data_distribution(
        save_dir: str,
        model_or_file: ModelProto or str,
        calibrated_data: str or CalibrationDataSet,
        nodes_list: List[str],
        axis: int = None)

分析结果展示

描述:针对您设置的校准节点列表node_list,从参数axis中获取channel所在的维度,获取节点输入数据通道间的数据分布。 其中axis默认为None,此时若节点为权重校准节点,则channel所在的维度默认为0;若节点为激活校准节点,则channel所在的维度默认为1。

权重校准节点:

../../../../_images/weight_calibration_node.png

激活校准节点:

../../../../_images/activate_calibration_node.png

输出结果如下图所示:

../../../../_images/box_plot.png

图中:

  • 横坐标表示节点输入数据的通道数,图例中输入数据有96个通道。

  • 纵坐标表示每个channel的数据分布范围,其中红色实线表示该channel数据的中位数,蓝色虚线表示均值。每个箱子的上下限分别表示上四分位数和下四分位数,上下限之外的离散点表示异常值,通过观察这些异常值绝对值的最大值来判断当前节点输入数据是否出现较大波动的情况。

关于如何通过观察箱线图判断节点是否存在量化风险,请参考PTQ精度debug示例: MobileVit_s精度问题分析

6.2.12.2.5. sensitivity_analysis

功能:针对量化敏感节点,分别分析测试单独量化以及部分量化这些节点后的模型精度。

命令行格式

hmct-debugger sensitivity-analysis MODEL_OR_FILE CALIBRATION_DATA --other options

可通过 hmct-debugger sensitivity-analysis -h/--help 查看相关参数。

参数组

编 号

参数名称

命令行参数缩写

参数配置说明

可选/

必选

1

model_or_file

固定参数

参数作用:指定校准模型。

取值范围:无。

默认配置:无。

参数说明:必选,指定需要分析的校准模型。

必选

2

calibrated_data

固定参数

参数作用:指定校准数据。

取值范围:无。

默认配置:无。

参数说明:必选,指定分析所需要的校准数据。

必选

3

pick_threshold

-p

参数作用:设置选取节点的敏感度阈值。

取值范围:无。

默认配置:0.999。

参数说明:可选,此功能计算普通节点的量化敏感度,选择敏感度小于 pick_threshold的节点作为敏感节点进行分析测试。

注:当设置sensitive_nodes时,则直接对sensitive_nodes进行测试,不再 另行计算节点敏感度并根据pick_threshold选择敏感节点。

可选

4

data_num

-d

参数作用:计算量化敏感度需要的数据数量。

取值范围:大于0,小于等于calibration_data中数据的总数。

默认配置:1。

参数说明:设置计算节点量化敏感度时所需要的数据数量。

可选

5

sensitive_nodes

-sn

参数作用:指定需要分析的敏感节点。

取值范围:校准模型中的所有节点。

默认配置:无。

参数说明:可选,指定需要分析的敏感节点。

注:当设置此参数时,则直接对此参数中的节点进行测试,不再另行计算 节点敏感度并根据pick_threshold选择敏感节点。

可选

6

save_dir

-sd

参数作用:保存路径。

取值范围:无。

默认配置:无。

参数说明:可选,指定分析结果的保存路径。

可选

API使用方法:

# 导入debug模块
import horizon_nn.debug as dbg

dbg.sensitivity_analysis(model_or_file='calibrated_model.onnx',
                         calibrated_data='calibration_data',
                         pick_threshold=0.9999,
                         data_num=1,
                         sensitive_nodes=[])

命令行使用方法:

hmct-debugger sensitivity-analysis calibrated_model.onnx calibration_data

分析结果展示

../../../../_images/partial_quantization.png

图中:

  • 蓝色虚线:baseline,即浮点模型输出与自身的余弦相似度,为1。

  • 绿色x :只量化当前节点得到部分量化模型,计算部分量化模型与浮点模型最终输出的相似度。

  • 红色实线:不量化当前节点以及当前节点前的所有节点,计算部分量化模型与浮点模型最终输出的相似度。例如:上图中 Conv_92对应的相似度数值大概在0.995左右,表明解除Conv_2、Conv_7和Conv_92节点的量化并保持其余所有节点量化得到部分量化模型,该部分量化模型的最终输出与浮点模型的最终输出之间的余弦相似度为0.995左右。 横坐标第一个none,在红色实线中的含义为calibrated_model。

6.2.12.2.6. runall

功能:一键运行原本debug工具中的所有功能。

命令行格式

hmct-debugger runall MODEL_OR_FILE CALIBRATION_DATA --other options

可通过 hmct-debugger runall -h/--help 查看相关参数。

参数组

编 号

参数名称

命令行参数缩写

参数配置说明

可选/

必选

1

model_or_file

固定参数

参数作用:指定校准模型。

取值范围:无。

默认配置:无。

参数说明:必选,指定需要分析的校准模型。

必选

2

calibrated_data

固定参数

参数作用:指定校准数据。

取值范围:无。

默认配置:无。

参数说明:必选,指定分析所需要的校准数据。

必选

3

save_dir

-s

参数作用:保存路径。

取值范围:无。

默认配置:无。

参数说明:指定分析结果的保存路径。

可选

4

ns_metrics

-nm

参数作用:节点量化敏感度的度量方式。

取值范围'cosine-similarity' , 'mse' , 'mre' , 'sqnr' , 'chebyshev'

默认配置'cosine-similarity'

参数说明:指定节点量化敏感度的计算方式,该参数可以为列表(List), 即以多种方式计算量化敏感度, 但是输出结果仅以列表中第一位的计算方式进行排序, 排名越靠前说明量化该节点引入的误差越大。

可选

5

output_node

-o

参数作用:指定输出节点。

取值范围:校准模型中的具有对应校准节点的普通节点。

默认配置:None。

参数说明:此参数支持您指定中间节点作为输出并计算节点量化敏感度。 若保持默认参数None,则精度debug工具会获取模型的最终输出 并在此基础上计算节点的量化敏感度。

可选

6

node_type

-nt

参数作用:节点类型。

取值范围'node' , 'weight' , 'activation'

默认配置'node'

参数说明:需要计算量化敏感度的节点类型,包括:node(普通节点)、 weight(权重校准节点)、activation(激活校准节点)。

可选

7

data_num

-dn

参数作用:计算量化敏感度需要的数据数量。

取值范围:大于0,小于等于calibration_data中数据的总数。

默认配置:None

参数说明:设置计算节点量化敏感度时所需要的数据数量。 默认为None,此时默认使用calibration_data中的所有数据进行计算。 最小设置为1,最大为 calibration_data中的数据数量。

可选

8

verbose

-v

参数作用:选择是否将信息打印在终端上。

取值范围TrueFalse

默认配置False

参数说明:若为True,则将量化敏感度信息打印在终端上。 若metrics包含多种度量方式,则按照第一位进行排序。

可选

9

interested_nodes

-i

参数作用:设置感兴趣节点。

取值范围:校准模型中的所有节点。

默认配置:None。

参数说明:若指定则只获取该节点的量化敏感度,其余节点不获取。 同时,若该参数被指定,将忽视node_type指定的节点类型, 也就是说该参数的优先级要高于node_type。 若保持默认参数None,则计算模型中所有可被量化节点的量化敏感度。

可选

10

dis_nodes_list

-dnl

参数作用:指定需要分析的节点。

取值范围:校准模型中的所有节点。

默认配置:无。

参数说明:指定需要分析的节点。若nodes_list中的节点类型为:

  • 权重校准节点:绘制原始权重和经过校准之后的权重的数据分布。

  • 激活校准节点:绘制激活校准节点的输入数据分布。

  • 普通节点:绘制该节点在量化前后的输出数据分布,同时绘制二者之间的误差分布。

注:nodes_list为 list 类型,可指定一系列节点,并且上述三种类型节点 可同时指定。

可选

11

cw_nodes_list

-cn

参数作用:指定校准节点。

取值范围:校准模型中的所有权重校准节点和激活校准节点。

默认配置:无。

参数说明:指定校准节点。

可选

12

axis

-a

参数作用:指定channel所在的维度。

取值范围:小于节点输入数据的维度。

默认配置:None。

参数说明:channel信息所在shape中的位置。 参数默认为None,此时对于激活校准节点, 默认认为节点输入数据的第二个维度表示channel信息,即axis=1; 对于权重校准节点,会读取该节点属性中的axis参数作为channel信息。

可选

13

quantize_node

-qn

参数作用:只量化模型中指定的节点,查看误差累积曲线。

取值范围:校准模型中的所有节点。

默认配置:None。

参数说明:可选参数。指定模型中需要量化的节点,同时保证其余节点均不量化。 通过判断该参数是否为嵌套列表进而决定是单节点量化还是部分量化。

例如:

  • quantize_node=[‘Conv_2’,’Conv_9’]:分别只量化Conv_2和Conv_9, 同时保证其余节点不量化。

  • quantize_node=[[‘Conv_2’],[‘Conv_9’,’Conv_2’]]:只量化Conv_2以及 同时量化Conv_2和Conv_9,分别测试模型累积误差。

  • quantize_node 包含两个特殊参数:’weight’ 和 ‘activation’。当:

    • quantize_node = [‘weight’]:只量化权重,不量化激活。

    • quantize_node = [‘activation’]:只量化激活,不量化权重。

    • quantize_node = [‘weight’,’activation’]:权重和激活分别量化。

注:quantize_node和non_quantize_node不可同时为None,必须指定其一。

可选

14

non_quantize_node

-nqn

参数作用:指定累积误差的类型。

取值范围:校准模型中的所有节点。

默认配置:None。

参数说明:可选参数。指定模型中不量化的节点,同时保证其余节点全都量化。 通过判断该参数是否为嵌套列表进而决定是单节点不量化还是部分量化。

例如:

  • non_quantize_node=[‘Conv_2’,’Conv_9’]:分别解除Conv_2和Conv_9节点的量化, 同时保证其余节点全部量化。

  • non_quantize_node=[[‘Conv_2’],[‘Conv_9’,’Conv_2’]]:只解除Conv_2量化 以及同时解除Conv_2和Conv_9量化,分别测试模型累积误差。

注:quantize_node和non_quantize_node不可同时为None,必须指定其一。

可选

15

ae_metric

-am

参数作用:累积误差度量方式。

取值范围'cosine-similarity' , 'mse' , 'mre' , 'sqnr' , 'chebyshev'

默认配置'cosine-similarity'

参数说明:设置计算模型误差的计算方式。

可选

16

average_mode

-avm

参数作用:指定累积误差曲线的输出模式。

取值范围TrueFalse

默认配置False

参数说明:默认为False。若为True,那么获取累积误差的平均值作为结果。

可选

17

pick_threshold

-pt

参数作用:设置选取节点的敏感度阈值。

取值范围:无。

默认配置:0.999。

参数说明:可选,此功能计算普通节点的量化敏感度,选择敏感度小于 pick_threshold的节点作为敏感节点进行分析测试。

注:当设置sensitive_nodes时,则直接对sensitive_nodes进行测试,不再 另行计算节点敏感度并根据pick_threshold选择敏感节点。

可选

18

sensitive_nodes

-sn

参数作用:指定需要分析的敏感节点。

取值范围:校准模型中的所有节点。

默认配置:无。

参数说明:可选,指定需要分析的敏感节点。

注:当设置此参数时,则直接对此参数中的节点进行测试,不再另行计算 节点敏感度并根据pick_threshold选择敏感节点。

可选

API使用方法:

# 导入debug模块
import horizon_nn.debug as dbg

dbg.runall(model_or_file='calibrated_model.onnx',
           calibrated_data='calibration_data')

命令行使用方法:

hmct-debugger runall calibrated_model.onnx calibration_data

runall流程:

../../../../_images/runall.png

当所有参数保持默认时,工具会依次执行以下功能:

  • step1和step2:分别获取权重校准节点和激活校准节点的量化敏感度。

  • step3:根据step1和step2的结果,分别取权重校准节点的top5和激活校准节点的top5绘制其数据分布。

  • step4:针对step3获取的节点,分别绘制其通道间数据分布的箱线图。

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

  • step6:针对敏感节点进行部分量化以及单节点量化精度分析,由于图中示例并没有指定sensitive_nodes,因此需要debug工具自行计算普通节点的量化敏感度并选取敏感度小于指定pick_threshold的节点进行测试分析。

当指定 node_type='node' 时,工具会获取top5节点,并分别找到每个节点对应的校准节点,并获取校准节点的数据分布和箱线图。