Shortcuts

量化精度调试

本文档提供了提高量化精度的高级策略。如果量化模型与原始模型相比存在误差,我们可以将误差分类为:

  1. 数据不敏感错误 - 由内在模型量化误差引起, 大部分输入数据存在较大误差

  2. 数据敏感错误 - 由异常输入数据引起,小部分输入数据存在较大误差

  3. 实现错误 - 量化内核与参考实现不匹配

数据不敏感错误

一般提示

  1. 对于PTQ,请确保您用于校准的数据能够代表您的数据集。例如,对于分类问题,一般的指导原则是每个类别中都有多个样本,并且样本总数应至少为100。除了校准时间外,使用更多数据进行校准不会受到惩罚。

  2. 如果您的模型具有Conv-BN或Linear-BN模式,请考虑将它们融合。 如果您使用的是FX图模式量化,此操作将由工作流自动完成。 如果您使用的是Eager模式量化,您可以使用torch.ao.quantization.fuse_modules API手动完成此操作。

  3. 增加问题操作的dtype的精度。通常,fp32 将具有最高的精度,其次是 fp16,其次是动态量化 int8,最后是静态量化 int8。

    1. 注意:这是在性能和准确性之间进行权衡。

    2. 注意:每个操作的每个数据类型的内核可用性可能因后端而异。

    3. 注意:数据类型转换会增加额外的性能开销。例如, fp32_op -> quant -> int8_op -> dequant -> fp32_op -> quant -> int8_op -> dequant 相比 fp32_op -> fp32_op -> quant -> int8_op -> int8_op -> dequant 会有性能损失,因为需要更多的数据类型转换。

  4. 如果你正在使用PTQ,考虑使用QAT来恢复一些由于量化导致的精度损失。

Int8 量化技巧

  1. 如果你使用的是逐张量权重量化,可以考虑使用逐通道权重量化。

  2. 如果你在使用 fbgemm 进行推理,请确保在 CPU 为 Cooperlake 或更新型号时将 reduce_range 参数设置为 False,否则设置为 True

  3. 审核不同样本之间的输入激活分布变化。如果这种变化较大,该层可能适合动态量化,但不适合静态量化。

数据敏感错误

如果你正在使用静态量化,并且你的输入数据的一小部分导致了高量化误差,你可以尝试:

  1. 调整您的校准数据集,使其更能代表您的推理数据集。

  2. 手动检查(使用 Numeric Suite)哪些层的量化误差较高。对于这些层,考虑将它们保留为浮点数或调整观察者设置以选择更好的 scale 和 zero_point。

实现错误

如果你在使用 PyTorch 量化与自定义后端,你可能会发现操作的参考实现(例如 dequant -> op_fp32 -> quant)与目标硬件上的量化实现(例如 op_int8)之间存在差异。这可能意味着以下两种情况之一:

  1. 由于目标硬件上的目标内核与fp32/cpu相比的特定行为,差异(通常很小)是预期的。一个例子是在整数数据类型中进行累加。除非内核保证与参考实现具有位等效性,否则这是预期的。

  2. 目标硬件上的内核存在精度问题。在这种情况下,请联系内核开发者。

数值调试工具(原型)

警告

数值调试工具是早期原型,可能会发生变化。