8. 量化技巧

结合1684芯片的特点这里给出了3类优化网络量化效果的技巧:

  • 阈值计算

  • 混合执行

  • 网络图优化

8.1. 阈值计算

8.1.1. 分布统计

calibration_use_pb命令行添加如下参数:

  • -dump_dist: 指向一个输出文件的路径。将网络各层统计的最大值及feature的分布信息保存到文件。

  • -load_dist: 指向一个-dump_dist参数生成的文件的路径。从-dump_dist参数生成的文件 中读取网络各个层的最大值及feature分布信息。

针对有些网络需要量化调优进行多次量化的场景,采用此参数可以只统计一次分布信息并多 次使用。可以大大加快量化调优的速度。

注:选择使用ADMM方法不支持保存和加载feature分布。

8.1.2. 阈值调整

阈值的选取对于网络量化效果有很大的影响,这里给出两种方式来对量化阈值进行调整。

8.1.2.1. 针对所有的层进行调整

calibration_use_pb命令行添加如下参数:

  • -th_method:可选参数,指定计算各个层量化阈值的方法,可选参数:KL,SYMKL,JSD,ADMM,ACIQ以及MAX,默认值为KL。

8.1.2.2. 针对具体的层进行调整

为了更精细地对某个具体层的阈值进行调整,在layer_parameter中增加了部分参数,可以通 过下面方式在prototxt文件中进行使用。

../_images/ch5_001.png

图 8.1 Prototxt文件中设置采用最大值作为阈值

  • th_strategy:设置当前layer的量化阈值计算策略。

    可选参数:USE_DEFAULT,USE_KL,USE_MAX,默认值为USE_DEFAULT。

    USE_DEFAULT:采用calibration-tools量化程序内部定义的规则来计算当前 layer的阈值。

    USE_KL:采用求KL分布的方式来计算当前layer的阈值,这里的KL是相对MAX 而言,具体的阈值计算策略可能是KL,SYMKL或者JSD。

    USE_MAX:采用统计的最大值做为当前layer的最大值。

  • th_scale:在计算得到的阈值上面乘以缩放系数th_scale,默认值为1.0。

  • threshold:设置当前layer的量化阈值,无默认值。

8.2. 混合执行

1684芯片内部集成了浮点计算单元,可以高效地利用浮点进行计算。根据芯片的这个特点, 这里提供了一种混合执行的方式来运行网络,允许部分层用定点进行计算,部分层用浮点进 行计算。通过允许部分层用浮点进行计算,可以有效地提高网络的整体量化精度。

8.2.1. 复杂网络的前处理/ 后处理

Tensorflow及Pytorch等基于python的框架灵活度较大,从这些框架转过来的网络模型中可 能包含前后处理相关的算子。对于这些算子做量化将很大程度上影响网络的量化精度。这里 提供了一种方式在网络中标记出前处理、后处理相关的层,并允许这些层以浮点运行。在calibration_use_pb命令行中使用如下参数:

  • -fpfwd_inputs:用逗号分隔开的网络layer name,在网络中这些layer及它们之前的layer 被标记为网络前处理。网络前处理不算做正式网络的一部分,在calibration过程中不被 量化,在推理过程中保持使用浮点进行计算。

  • -fpfwd_outputs:用逗号分隔开的网络layer name,在网络中这些layer及它们之后的 layer被标记为网络后处理。网络后处理不算做正式网络的一部分,在calibration过程中 不被量化,在推理过程中保持使用浮点进行计算。

8.2.2. 对量化损失敏感的层

8.2.2.1. 通过命令行参数指定

在calibration_use_pb命令行中使用如下参数:

  • -fpfwd_blocks:用逗号分隔开的网络layer name,在网络中每个layer及它们之后直到下一 个进行数据计算的层在calibration过程中都不被量化,在推理过程中保持使用浮点进行计算。

calibration-tools程序会根据指定的layer name自动判断这个layer后面有多少个layer需 要用浮点进行计算,把网络的这个block做为一个整体用浮点进行计算,来达到提高量化精 度的目的。如下图所示在命令行中用-fpfwd_blocks指定Softmax层的layer name, calibration-tools程序会将图中红色框中的layer都标识为用浮点进行计算。 calibration-tools程序会在此block的输入处自动将输入数据转换成浮点格式,在输出位置 转换为int8数据格式。

../_images/ch5_002.jpg

图 8.2 通过命令行设置将对精度敏感的layer block用浮点执行

8.2.2.2. 通过配置prototxt指定

  • forward_with_float:将当前layer用浮点进行计算,可选参数为true,false,默认值为false。

具体使用方法参考如下面图 prototxt文件中设置forward_with_float 所示,这里的*_test_fp32.prototxt文件是指 calibration_use_pb命令的输入prototxt文件,见 :ref: grenerate_fp32umodel

../_images/ch5_003.jpg

图 8.3 prototxt文件中设置forward_with_float

8.3. 精度优化参数

在calibration_use_pb命令行中可以尝试使用如下参数提高精度,其效果根据网络特点不同可能不同,以实测为准:

  • -accuracy_opt:将网络中depthwise卷积采用浮点推理以提高精度,默认为false,关闭。

  • -conv_group:将conv的输出channel按照输出幅值进行分组并拆分成不同的组分别进行量化,默认为false,关闭。

  • -per_channel:开启convolution计算的per_channel功能,默认为false,关闭。

为了提高精度和速度,量化过程中会进行简单的网络优化。 使用Parse-tools转换前端网络为fp32U-model的过程中会自动将batchnorm和bias转换为scale层,并且如果有相邻的scale层会合并为一个。 量化命令调用时不提前使用graph-transform参数进行网络优化直接进行量化的时候也会进行网络优化,比如打开accuracy_opt参数会触发网络优化,一些网络优化参数进行的操作如下图所示:

../_images/ch5_004.jpg

图 8.4 是否进行网络优化

进行网络优化的具体操作如下图所示:

../_images/ch5_005.jpg

图 8.5 网络优化操作

8.4. auto_cali量化优化策略

auto_cali可以自动尝试一些量化优化策略,提升网络量化效果,以下是自动搜索量化的例子:

  • pytorch框架下的yolov5s自动搜索量化策略

  • pytorch框架下的yolov5s手工配置量化策略

8.4.1. pytorch框架下的yolov5s自动搜索量化策略

如果在 auto-cali量化 使用中出现量化效果不满足要求的情况,可配置参数postprocess_and_calc_score_class打开精度测试功能 并在阈值计算,混合执行,网络图优化等方法中搜索出最优的量化策略

$ cd /workspace/examples/calibration/yolov5s_demo/auto_cali_demo
$ python3 -m ufw.cali.cali_model \
       --net_name 'yolov5s' \
       --model ./yolov5s_jit.pt \
       --cali_image_path ../../create_lmdb_demo/coco128/images/train2017/ \
       --cali_image_preprocess 'resize_h=640,resize_w=640;scale=0.003921569,bgr2rgb=True' \
       --input_shapes '[1,3,640,640]' \
       --postprocess_and_calc_score_class=feature_similarity \  #该参数支持4类可选项[detect_accuracy、topx_accuracy_for_classify、feature_similarity、None]

8.4.2. Caffe框架下的MobileNet SSD手工配置量化策略

由于自动搜索量化策略较为耗时,可根据后续章节的内容,通过配置参数try_cali_accuracy_opt,在auto_cali中手工调用相应的量化优化策略, 可选量化策略均来自下文calibration_use_pb模块

$ python3 -m ufw.cali.cali_model \
       --net_name 'yolov5s' \
       --model ./yolov5s_jit.pt \
       --cali_image_path ../../create_lmdb_demo/coco128/images/train2017/ \
       --cali_image_preprocess 'resize_h=640,resize_w=640;scale=0.003921569,bgr2rgb=True' \
       --input_shapes '[1,3,640,640]' \
       --postprocess_and_calc_score_class=feature_similarity \
       --try_cali_accuracy_opt='-fpfwd_outputs=< 24 >14,< 24 >51,< 24 >82' #直接指定使用fpfwd_outputs量化参数进行量化,更多策略可参考下文calibration_use_pb模块