目前在 XJ3 浮点转化工具链中,我们为每一个示例模型都提供了一个 yaml 配置文件。有些初次接触的小伙伴可能对于其中某些配置项并没有很好地理解,从而达不到自己预期的性能或精度指标,甚至直接就踩了坑。
下面我将以 efficientnet_lite0 模型为例,分别为大家解读下性能和精度相关的配置参数。
【性能相关】
1) layer_out_dump
该参数服务于 vec_diff 工具(samples/05_miscellaneous/03_vector_diff),打开后会为每一层卷积添加一个输出节点,如下图所示。该功能主要用于逐层比较浮点、量化、混合模型 featuremap 的相似度。
除了调试工作外,正常情况我们应该默认关闭该参数,否则那么多的输出节点肯定会造成很大的性能下降,带宽压力也急剧上升。
2) output_layout
目前默认情况下,我们是不需要手动配置该参数的(配置为 None 即可),工具链内部会自动解析原始浮点模型,保持其原有的 layout 输出。
不过在我们提供的检测模型示例中,大部分都强制配置成了 NHWC,其目的是为了更好地适配我们的后处理逻辑,以达到更好的整体性能。
所以如果基于我们的检测示例 yaml 进行改写的话,需要关注该参数,如果不需要强制转换应该配置为 None,否则可能会引入额外的 transpose(如果模型为多输出,那么性能损失将更大)。
3) compile_mode
该参数用于选择编译器的优化方法,正常情况下我们会以性能优先,即配置为 ‘latency’;
对于比较重型、featuremap 比较大的模型来说,根据实际情况可能需要配置成 ‘bandwidth’,以降低带宽压力,不过相应的性能指标也会有所降低。
4)debug
该参数开启后会得到更加丰富的仿真信息,可以看到在 html 静态性能文件中多出了 layer 级别的仿真信息,如果关闭该参数则没有。
不过开启该参数,也会使得模型本身包含更多的参数信息,对最终的性能就会造成一定的降低。
5)core_num
该参数主要用于配置模型的运行模式。详细说明可参考我们的 FAQ 文档 《FAQ-2-08:单帧单核,单帧双核两种工作模式解析》
6)optimize_level
该参数用于配置编译器的优化等级,O0 到 O3 优化效果逐步提高,但其编译时间也越来越长。
一般我们可能会基于 O0~O2 等级进行模型转换成功率和精度的快速验证,而正式上板测试性能则应该用 O3 来获取最佳指标。
【精度相关】
1)input_type_rt
该参数为模型本身训练时的数据类型,如果误将 rgb/rgbp 配置成 bgr/bgrp 就会造成一定程度的精度损失(一般 5%~10% 左右),而且问题定位还比较难。所以我们应该首先确认该参数配置是否准确。
2)mean_value 和 scale_value
mean_value 和 scale_value 本身并不难配置,主要的踩坑点是可能会和数据预处理存在重复操作的问题。
如果我们在 yaml 中配置了这两项参数,并且通过 norm_type 参数进行了使能,那么我们在模型编译过程中,就会将其作为预处理节点插入到模型前端,以获得更高效的性能。
此时我们在校准数据集或验证/测试集上,就无需再做归一化了。如果进行了重复操作,则其整个数据分布都不正确,精度自然会受到严重影响。
3)cal_data_dir
校准数据集的选择其实对于后量化方法一直有点玄学。不过常规思路还是选择 20~100张左右覆盖典型场景的数据。
数量过多/过少、未覆盖典型场景、包含无效数据(如全黑全白)等可能会造成一定的精度损失。
4)calibration_type
该参数指定模型的校准方法,我们默认提供 max 和 kl 两种,他们在不同类型的模型上表现不一,大家可以自行测试一下。
5)max_percentile
高阶参数 1,非产品化交付功能,主要用于精度调优。
该参数需搭配 max 校准进行使用,是一种以 max 最大值的分位数来选择量化 threshold 的方法。在某些场景的模型上表现比较好。
6)per_channel
高阶参数 2,非产品化交付功能,主要用于精度调优。
该参数可搭配任意一种量化方法进行使用,如 kl、max、max + max_percentile。是一种逐 channel 选择 threshold 的方法,在某些场景的模型上表现比较好。