快捷方式

量化精度调试

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

  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. 注意:不同后端支持的每种 dtype 和每种算子的内核可用性可能有所不同。

    3. 注意:dtype 转换会增加额外的性能开销。例如,fp32_op -> quant -> int8_op -> dequant -> fp32_op -> quant -> int8_op -> dequant 的性能开销会比 fp32_op -> fp32_op -> quant -> int8_op -> int8_op -> dequant 高,因为需要更多的 dtype 转换次数。

  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 相比有特定的行为。一个例子是在整数 dtype 中进行累积。除非内核保证与参考实现的位级等效性,否则这是正常的。

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

数值调试工具 (原型)

警告

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

文档

查阅 PyTorch 全面的开发者文档

查看文档

教程

获取面向初学者和高级开发者的深度教程

查看教程

资源

查找开发资源并获得问题解答

查看资源