跳转至

NPU 量化精度调试*

为了减少模型权重的存储大小,使用 NPU 编译器时可配置模型权重使用 int8 量化,NPU 运行时会把 int8 权重数据反量化成 fp16 格式再进行计算。 量化可能会导致模型性能的损失,NPU 编译器提供了一些参数和配置项调试精度问题。

量化相关的参数和配置项*

配置项*

配置项 选项 说明
COMPRESS true / false 是否打开全连接权重压缩
CONV2D_COMPRESS true / false 是否打开卷积权重压缩(默认 false)
FUSE_BN true / false 是否把 BN 参数合并到卷积中(默认 false) (1.5.2rc6以上)
EXCLUDE_COMPRESS_OPS [op_name, ...] 指定不做量化压缩的权重(1.5.6以上)
WEIGHT_MIN_MAX op_name:[min,max] ... 指定权重量化时的最小值和最大值(1.5.7rc0以上)

参数*

参数名 说明
-w / --weight 编译时打印量化压缩的权重名称
-s / --save 权重分布直方图输出到 npu_jpgs 目录中

量化精度调试举例*

场景1*

用户设置配置项 COMPRESSCONV2D_COMPRESStrue,测试模型准确率和 TensorFlow 相比差异较大。

调试步骤:

  1. 将配置项 COMPRESSCONV2D_COMPRESS 都设置为 false,测试模型,测试结果准确率和 TensorFlow 基本一致,认为是量化导致的模型性能问题。
  2. 将配置项 COMPRESS 设置为 trueCONV2D_COMPRESS 设置为 false,测试结果还是和 TensorFlow 基本一致,认为是卷积权重量化引起的问题。
  3. 将配置项 CONV2D_COMPRESS 设置为 trueFUSE_BN 设置为 false,BN 参数不融合到卷积权重中,测试结果差异较大,继续调试卷积权重量化的问题。
  4. 将配置项 CONV2D_COMPRESS 设置为 true,编译时加上参数-w,打印出量化压缩的权重名称。编译时加上参数-s,输出权重分布直方图。
    $ gxnpuc -w config.yaml
    tdnn1.affine/conv1d/ExpandDims_1/_7__cf__7: [1, 3, 40, 208]
    prefinal-l/conv1d/ExpandDims_1/_5__cf__5: [1, 1, 208, 120]
    ...
    
    $ gxnpuc -s config.yaml
    
    查看npu_jpgs目录中的直方图,权重prefinal-l/conv1d/ExpandDims_1/_5__cf__5对应的直方图权重值不是长尾分布(如下所示),认为量化对精度影响有限。 权重tdnn1.affine/conv1d/ExpandDims_1/_7__cf__7对应的直方图权重值长尾分布(如下所示),对量化不友好。尝试对该权重不量化。 增加配置项,
    EXCLUDE_COMPRESS_OPS: [tdnn1.affine/conv1d/ExpandDims_1/_7__cf__7]
    
    重新编译测试,结果和 TensorFlow 基本一致。 再查看权重内存,如果超出预期大小,可以继续调试该层权重的量化范围。
  5. 按照权重直方图,该层权重值主要分布在-0.06-0.06之间,但量化范围是-0.28-0.37,导致中间大量数据量化精度不够。现设置该权重量化最小值最大值分别为-0.06,0.06,范围外的值都做饱和,增加配置项:
    WEIGHT_MIN_MAX:
        tdnn1.affine/conv1d/ExpandDims_1/_7__cf__7: [-0.06, 0.06]
    
    重新编译,此时直方图如下: 重新编译测试模型,结果和 TensorFlow 基本一致,调试结束。