量化精度调试¶
本文档提供提高量化精度的全局策略。如果量化模型与原始模型相比存在误差,我们可以将误差归类为
**数据不敏感误差** - 由模型量化本身的内在误差引起,大部分输入数据存在较大误差
**数据敏感误差** - 由离群输入数据引起,一小部分输入数据存在较大误差
**实现误差** - 量化内核与参考实现不匹配
数据不敏感误差¶
一般提示¶
对于 PTQ,请确保用于校准的数据代表您的数据集。例如,对于分类问题,一般准则是在每个类别中具有多个样本,并且样本总数至少应为 100。除了校准时间外,使用更多数据进行校准不会造成任何损失。
如果您的模型具有 Conv-BN 或 Linear-BN 模式,请考虑将它们融合。如果您使用的是 FX 图模式量化,则工作流程会自动执行此操作。如果您使用的是 Eager 模式量化,您可以使用
torch.ao.quantization.fuse_modules
API 手动执行此操作。提高有问题的运算符的数据类型精度。通常,fp32 的精度最高,其次是 fp16,然后是动态量化的 int8,最后是静态量化的 int8。
注意:这是以牺牲性能为代价来换取精度。
注意:每个运算符每个数据类型内核的可用性可能因后端而异。
注意:数据类型转换会增加额外的性能成本。例如,
fp32_op -> quant -> int8_op -> dequant -> fp32_op -> quant -> int8_op -> dequant
的性能成本将高于fp32_op -> fp32_op -> quant -> int8_op -> int8_op -> dequant
,因为需要进行更多的数据类型转换。
如果您使用的是 PTQ,请考虑使用 QAT 来恢复量化造成的一些精度损失。
Int8 量化提示¶
如果您使用的是每张量权重量化,请考虑使用每通道权重量化。
如果您在 fbgemm 上进行推理,请确保如果您的 CPU 是 Cooperlake 或更新版本,将 reduce_range 参数设置为 False,否则设置为 True。
审核不同样本的输入激活分布变化。如果这种变化很大,那么该层可能适合动态量化,但不适合静态量化。
数据敏感误差¶
如果您使用的是静态量化,并且一小部分输入数据导致高量化误差,您可以尝试
调整校准数据集以使其更能代表您的推理数据集。
手动检查(使用数值套件)哪些层存在高量化误差。对于这些层,请考虑将它们保留在浮点状态或调整观察器设置以选择更好的比例和零点。
实现误差¶
如果您使用的是 PyTorch 量化以及自己的后端,您可能会看到操作的参考实现(例如 dequant -> op_fp32 -> quant
)与目标硬件上操作的量化实现(例如 op_int8)之间存在差异。这可能意味着以下两种情况之一
由于目标硬件上目标内核的特定行为与 fp32/cpu 相比,差异(通常很小)是预期的。一个例子是在整数数据类型中累积。除非内核保证与参考实现的逐位等效性,否则这是预期的。
目标硬件上的内核存在精度问题。在这种情况下,请联系内核开发者。
数值调试工具(原型)¶
警告
数值调试工具处于早期原型阶段,可能会发生变化。
torch.ao.ns._numeric_suite Eager 模式数值套件
torch.ao.ns._numeric_suite_fx FX 数值套件