常见故障处理

当量化训练、导出或部署验证过程中已经出现明显异常,或者已经直接遇到环境、框架、导出相关报错时,可以从本节开始排查。

如果当前还在判断“这个现象通常意味着什么,应该先看哪里”,建议先看 PyTorch 模型量化常见问题

先确定问题出在哪一段

精度或结果异常通常可以先按下面的顺序缩小范围:

  1. Calibration 后精度是否已经明显下降。

  2. QAT 训练过程中是否出现 loss 异常、NANINF 或长时间不收敛。

  3. QAT 精度是否正常,但 quantized.bc 精度异常。

  4. quantized.bc 精度是否正常,但 hbm 或上板结果掉点。

  5. int16 / fp16 配置是否未按预期生效。

如果遇到的是直接报错,例如 import、deepcopy 或 export 报错,可以直接跳到后半部分的“直接报错排查”。

精度与结果异常排查

Calibration 后精度明显下降

如果掉点在 Calibration 模型阶段就已经出现,排查重点通常不在 export、convert 或 compile,而在校准数据、量化配置和模型结构本身。

先确认:

  • 先比较 float 模型和 Calibration 模型的评测结果,确认问题是否已经在 Calibration 阶段出现。

  • 如果已经做过定点方向验证,再确认后续导出、convert、compile 是否继续放大了误差。

优先看这些产物:

  • Calibration 数据和前处理配置,确认是否足够接近真实推理分布。

  • model_check_result.txt,重点看共享模块、未融合 pattern、各层 qconfig 和高精度输出设置。

  • 如需继续缩小范围,可结合 模型校准精度调优指导 一起看。

下一步怎么处理:

  • 如果问题已经明确出在 Calibration 阶段,优先调整 Calibration 数据、step、batch size 和量化配置。

  • 如果问题只在后续 export、convert 或 compile 之后出现,转到 部署一致性分析说明 继续排查。

QAT 训练过程中 loss 异常

这类问题通常表现为 QAT 初始 loss 很大、训练中出现 NAN / INF,或者 loss 长时间不收敛。排查时建议先确认训练 pipeline 和量化状态是否正确,再决定是否继续调超参数。

先确认:

  • 先检查输入数据是否存在异常值。

  • 再检查浮点模型是否已经收敛。

  • 再检查是否已正确开启 Calibration,并正确加载 Calibration 模型参数。

优先看这些产物:

  • 训练日志,确认异常出现在训练一开始、若干 step 之后,还是某次状态切换之后。

  • model_check_result.txtqconfig_dtypes.pt.py,确认图结构、dtype 和量化配置没有明显异常。

  • 如需排除 pipeline 问题,可继续查看 精度调优指导 中关闭 fake quant、将 lr 设为 0 等方法。

下一步怎么处理:

  • 如果问题集中在训练阶段本身,优先调整学习率、梯度裁剪、BN 策略和 fake quant 状态。

  • 如果 loss 异常只在定点方向放大,再继续转到 部署一致性分析说明 判断问题是否发生在 export 或 convert 之后。

QAT 精度正常,但 quantized.bc 精度异常

这类问题通常说明训练阶段表面上看起来正常,但异常已经出现在 export 或 convert 方向。重点是先找出第一段出现偏差的位置,而不是继续只看 QAT 曲线。

先确认:

  • 先确认 QAT model 精度正常,再继续验证 qat.export.ptqat.bcquantized.bc 的精度表现。

  • 使用 pre_export 判断问题是否已经发生在查表转定点阶段。

优先看这些产物:

  • compare_per_layer_out.txt,用于逐层缩小范围。

  • QuantAnalysis 产出的 bad case、逐层对比结果和一致性敏感度结果。

  • 部署一致性分析说明,用于区分问题发生在 export 还是 convert 阶段。

下一步怎么处理:

  • 如果 qat.ptqat.export.pt 已经不一致,优先按 export 阶段问题处理。

  • 如果 qat.bc 正常而 quantized.bc 异常,优先按 convert 阶段问题处理。

  • 在常规方法无法定位时,可进一步使用 bc_editor 做分段定位。

quantized.bc 精度正常,但 hbm 或上板结果掉点

这类问题更偏向 compile 或部署链路,而不是训练阶段本身。排查时建议按 quantized.bc -> hbm -> 上板 的顺序逐步验证,不要一开始就把问题统称为“QAT 掉点”。

先确认:

  • 先确认 quantized.bc 精度是否正常。

  • 如果 quantized.bc 正常而 hbm 或上板结果掉点,再继续判断问题是在 compile 之后还是在板端输入准备阶段出现。

优先看这些产物:

  • 编译配置、板端输入输出适配和部署日志。

  • 前处理、后处理和输入数据格式配置,确认 RGB、centered YUV444、nv12 等输入域是否与训练阶段一致。

  • 部署一致性分析说明,用于继续判断 compile 和部署链路中的问题位置。

下一步怎么处理:

  • 建议逐段验证每一层产物和输入输出是否一致,再决定下一步是回到训练侧还是继续查部署侧。

  • 如果问题已经明确发生在 compile 或板端适配阶段,就不要继续回到 QAT 参数本身反复试错。

int16 / fp16 配置未按预期生效

这类问题更适合直接看产物,而不是只看配置代码。配置代码是否写了,只能说明您尝试过设置,是否真的生效,需要以调试产物中的最终 dtype 结果为准。

先确认:

  • 先确认问题是“配置没有命中目标模块”,还是“命中了,但最终 dtype 仍与预期不一致”。

  • 再确认问题是单层配置异常,还是整类模板配置都没有生效。

优先看这些产物:

  • model_check_result.txtqconfig_dtypes.pt.pyqconfig_changelogs.txt,用于确认最终算子 dtype 是否符合预期。

  • 配置代码中的 module_name,确认是否使用了正确模块名。该字段只支持 string,不支持按 index 索引进行配置。

  • 如果平台策略和模板配置本身还不明确,可继续参考 构建 QConfig

下一步怎么处理:

  • 建议先确认配置命中的是否为正确模块,再检查模板覆盖顺序和回退日志。

  • 如果配置代码看起来正确,但最终 dtype 仍不符合预期,应以调试产物中的最终结果为准继续排查,而不是仅根据配置代码判断。

直接报错排查

import 出错

Cannot find the extension library(_C.so)

处理建议:

  • 确认 horizon_plugin_pytorch 版本和 CUDA 版本是否对应。

  • 在 python3 中找到 horizon_plugin_pytorch 的执行路径,检查该目录下是否存在 .so 文件。可能同时存在多个 horizon_plugin_pytorch 版本,建议卸载后仅保留需要的版本。

RuntimeError: Cannot load custom ops. Please rebuild the horizon_plugin_pytorch

处理建议:确认本地 CUDA 环境是否正常,例如路径和版本是否正确。

Module 不支持 deepcopy

某些框架,例如 PyTorch Lightning,会对 torch 原生 module 做二次封装,但不支持 deepcopy

处理建议:为模型实现 __deepcopy__ 方法。

class Model(Module):
    ...
    def __deepcopy__(self, memo):
        new_model = Model()
        new_model.xxx = self.xxx
        return new_model

RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment

该报错通常发生在 deepcopy torch.nn.Module 时。常见原因是在 forward 过程中把某些中间结果保存到了模型中,而这些中间结果是 non-leaf tensor,导致 deepcopy 时报错。

class Model(torch.nn.Module):
    ...
    def forward(self, x):
        # x 为某个需要梯度的输入 x.requires_grad = True
        y = x + 1

        # y 为 non-leaf tensor,赋值给模型的某个属性后,deepcopy model 就会报错
        self.yy = y

处理建议:检查模型中,以及 forward 之后,是否存在某些属性是 non-leaf tensor。在保存这些 tensor 之前,确保先进行了 detach

class Model(torch.nn.Module):
    ...
    def forward(self, x):
        # x 为某个需要梯度的输入 x.requires_grad = True
        y = x + 1

        # y 为 non-leaf tensor,保存到模型中时先进行 detach
        self.yy = y.detach()

export 时报错:IndexError: list index out of range

该报错通常是因为模型输出中存在 QTensor

处理建议:检查模型输出,确保所有输出都经过了 dequant