调试产物解读

在前文中,我们已经多次提到一些调试产物,例如 model_check_result.txtfx_graph.txtqconfig_dtypes.ptcompare_per_layer_out.txt 等。

这些文件本身并不复杂,真正容易让人卡住的,往往是下面几个问题:

  • 现在这个阶段应该先看哪个文件。

  • 这个文件主要是用来判断什么的。

  • 看到异常之后,下一步应该继续看哪里。

因此,本章把整体链路中最常用的调试产物集中整理在一起,帮助您更快回答下面这些问题:

  • 算子是否融合成功。

  • 是否存在共享模块。

  • dtype 配置是否按预期生效。

  • scale 是否异常。

  • 敏感层怎么判断是哪个。

  • 误差更像截断误差还是舍入误差。

注解

本章更适合作为排查过程中的查阅页使用。 如果您当前还不能判断问题主要发生在哪个阶段,建议优先参考部署一致性分析说明,先判断问题更可能出现在 Prepare、Calibration、QAT、Export、Convert 还是 Compile 阶段,再回到本章查看对应产物。

调试产物总览

从使用时机上看,这些产物大致可以分成两类:

  • Prepare 阶段检查产物:帮助您确认模型结构、图捕获结果和 qconfig 是否基本正常。

  • 误差分析与一致性分析产物:帮助您继续定位误差主要集中在哪些层、哪些算子最敏感。

对应关系如下:

产物生成阶段主要用途典型使用场景
model_check_result.txtPrepare / check_qat_model查看融合结果、共享模块、qconfig 检查结果Prepare 刚完成后做第一次总检查
fx_graph.txtPrepare查看实际捕获到的 FX 图结构怀疑图结构、分支路径或量化节点插入不符合预期
qconfig_dtypes.ptPrepare保存最终算子级 qconfig,供后续复用准备通过 LoadFromFileTemplate 继续复用当前配置
qconfig_dtypes.pt.pyPrepare以可读形式查看最终 dtype 配置人工检查关键模块的 dtype 是否符合预期
qconfig_changelogs.txtPrepare追踪 qconfig 的变化过程判断某个模块为什么最终变成当前 dtype
compare_per_layer_out.txtQuantAnalysis.compare_per_layer()逐层查看统计量、误差指标和 qscale 情况Calibration、QAT 或一致性分析时定位误差起点
output_xxx_sensitive_ops.pt/.txtQuantAnalysis.sensitivity()查看输出相关的敏感算子排序混合精度调优、判断优先提升哪些算子的精度
abnormal_layer_advisor.txtQuantAnalysis.compare_per_layer()快速列出明显异常层先缩小排查范围,再回看逐层对比结果

如果只从排查顺序上理解,一般可以先分成两步:

  1. 先看 Prepare 阶段产物,确认链路有没有搭对。

  2. 再看分析产物,确认误差主要发生在哪、下一步该改哪里。

常见问题与对应产物

如果您当前只想先快速判断“应该优先查看哪个产物”,可以先参考下表:

您现在最想确认什么建议优先看什么必要时再补充看什么
算子是否融合成功model_check_result.txtfx_graph.txt
是否存在共享模块model_check_result.txtfx_graph.txt
dtype 配置是否按预期生效qconfig_dtypes.pt.pymodel_check_result.txtqconfig_changelogs.txt
某个算子为什么变成当前 dtypeqconfig_changelogs.txtqconfig_dtypes.pt.py
scale 是否明显异常compare_per_layer_out.txtmodel_check_result.txtabnormal_layer_advisor.txt
哪些算子最值得优先提升精度output_xxx_sensitive_ops.txtoutput_xxx_sensitive_ops.ptcompare_per_layer_out.txt
误差更像截断还是舍入compare_per_layer_out.txtabnormal_layer_advisor.txt

建议查看顺序

如果您当前还不确定应该怎么使用这些产物,通常可以按下面的顺序来理解:

  1. Prepare 刚完成后,先看 model_check_result.txt,确认模型结构、融合和 qconfig 检查结果是否大体正常。

  2. 如果您怀疑图结构本身就不符合预期,再看 fx_graph.txt,确认实际捕获到的执行路径、模块替换和量化节点插入是否正确。

  3. 如果问题主要集中在 dtype 配置是否生效,再结合 qconfig_dtypes.pt.pyqconfig_changelogs.txt 继续确认最终结果与变化过程。

  4. 如果 Calibration、QAT 或部署侧结果不达标,再开始看 output_xxx_sensitive_ops.txtcompare_per_layer_out.txt,判断哪些输出最敏感、误差从哪一层开始放大。

  5. 最后再用 abnormal_layer_advisor.txt 辅助确认是否存在明显异常层,并决定下一步优先看哪个局部问题。

如果您已经根据这些产物确认问题更可能发生在 Export、Convert 或 Compile 阶段,下一步建议继续阅读部署一致性分析说明,按阶段继续排查。

Prepare 阶段产物

Prepare 阶段产物最适合在链路刚搭好时使用。 如果这一阶段的结构、图和 qconfig 已经存在明显问题,后面的 Calibration、QAT、Export、Convert 和一致性分析结果通常都会受到影响。

model_check_result.txt

model_check_result.txt 会在 Prepare 完成后自动生成,也可以通过 check_qat_model 单独生成。 它会把模型结构检查、算子融合检查、调用次数检查以及 qconfig 检查结果放在一起,是 Prepare 阶段最核心的总览产物。

如果您只想在 Prepare 完成后先做一次总检查,通常建议先看这个文件。

实际使用中,建议重点关注下面几类信息:

  • 是否存在可以 fuse 但没有 fuse 的 pattern。

  • 每个 module 的调用次数是否正常,是否存在共享模块。

  • 各层的 input / weight / output dtype 是否与配置目标大体一致。

  • 是否存在需要额外确认的异常 qconfig 提示,例如 fixed scale、配置冲突或可疑设置。

这个文件最适合回答下面几类问题:

  • 算子是否融合成功。

  • 是否存在共享模块。

  • qconfig 是否明显偏离预期。

如果您在这里已经发现明显异常,通常建议先回看 Prepare 说明构建 QConfig,而不是直接继续做 Calibration 或一致性分析。

注意

当您配置了全局 int8 后,model_check_result.txt 中仍可能看到部分算子以 int16 计算。这不一定就是错误,有些情况是工具为了提升量化精度做的自动处理。 因此看到这类结果时,建议继续结合 qconfig_changelogs.txt 和实际平台策略再判断,不要只凭这一点就认定配置失败。

fx_graph.txt

fx_graph.txt 会在 Prepare 的图模式执行完成后生成,用来保存实际捕获到的 FX 图。 相比 model_check_result.txt,它不直接给出“哪里异常”的结论,但更适合帮助您确认工具最终按什么图在处理模型。

如果您怀疑训练路径和部署路径并不完全一致,或者怀疑某些模块、分支没有真正进入图,通常就应该优先看这个文件。

实际使用中,可重点关注:

  • 模型最终抓到的执行路径是否符合预期。

  • 某些模块、分支或循环是否真的进入了图。

  • 模块替换、算子融合和量化节点插入的位置是否基本合理。

在下面这些场景里,fx_graph.txt 往往尤其值得优先查看:

  • forward 中存在动态分支或 deploy 开关。

  • 某些模块在代码里定义了,但后续结果里看起来没有生效。

  • 您怀疑训练路径和部署路径并不完全一致。

如果 fx_graph.txt 本身就已经和预期结构明显不一致,通常不建议继续往后排查精度问题,而应先回到 Prepare 阶段调整模型写法、example_inputs 或相关配置。

qconfig_dtypes.pt

qconfig_dtypes.pt 会在 Prepare 完成后自动保存,是算子级量化配置的保存文件,主要用于复用已有配置。

如果您后续希望通过 LoadFromFileTemplate 继续使用当前配置,或者希望把这次量化结果保存为后续调优起点,这个文件就会很重要。

不过,如果您当前只是想人工快速检查配置是否符合预期,一般不建议先看这个文件,优先查看 qconfig_dtypes.pt.py 会更直观。

注意

qconfig_dtypes.pt 不保存 fix_scale 信息。 如果原配置中包含 fixed scale,后续加载这份配置时,仍需要手工补配对应的 threshold

qconfig_dtypes.pt.py

qconfig_dtypes.pt.py 同样会在 Prepare 完成后自动保存,它是 qconfig_dtypes.pt 的可读版本,通常最适合人工直接检查。

如果您现在最关心的是“哪些关键模块到底被配成了什么 dtype”,这个文件一般比 .pt 更值得先看。

实际使用中,可重点关注:

  • 关键模块的 input / weight / output dtype。

  • Conv / Linear / Matmul 等关键算子是否真的被配置成了 qint8qint16torch.float16

  • 当前混合精度配置是否大体落在您预期的区域。

这个文件最适合用于下面这些场景:

  • 人工检查 backbone、neck、head 等关键模块的 dtype 是否符合预期。

  • 判断基础混合精度配置是否大体生效。

如果您发现结果和模板直觉不完全一致,不建议直接根据这个文件反推“再手工补几行 dtype 就行”,而应继续结合 qconfig_changelogs.txt 去看是哪个模板、哪条覆盖关系或哪类默认优化改变了结果。

qconfig_changelogs.txt

qconfig_changelogs.txt 会在 Prepare 完成后自动保存,用来记录 qconfig 的变化过程。 如果说 qconfig_dtypes.pt.py 更适合回答“最后是什么结果”,那么 qconfig_changelogs.txt 更适合回答“为什么最后会变成这个结果”。

当您怀疑某个算子的最终 dtype 和模板直觉不一致,或者想进一步确认模板覆盖顺序是否符合预期时,这个文件通常最值得看。

它尤其适合帮助您判断下面几类问题:

  • 某个模块的 qconfig 是被哪个模板改动的。

  • 模板覆盖顺序是否符合预期。

  • 是否出现了您没有预料到的覆盖、回退或简化。

在下面这些场景里,它通常尤其有用:

  • 您明明配置了高精度,但最终没有生效。

  • 全局模板和局部模板叠加后,结果和直觉不一致。

  • 加载 qconfig_dtypes.pt 后继续修改 dtype,结果变得不稳定。

如果您最终确认问题主要来自模板配置关系本身,建议优先回到 构建 QConfig 调整模板,而不是只盯着最终产物临时修结果。

误差分析与一致性分析产物

当 Prepare 阶段已经基本正常,但 Calibration、QAT 或部署侧结果仍然不理想时,接下来更需要关注的通常不是“链路有没有搭对”,而是“误差主要集中在哪、哪些算子最敏感、下一步应该优先调整哪里”。

这时,QuantAnalysis 相关产物会更有帮助。

compare_per_layer_out.txt

compare_per_layer_out.txt 会在执行 QuantAnalysis.compare_per_layer() 后生成,是逐层比较的核心产物。 它会以表格形式给出每层的 shape、量化 dtype、qscale、Cosine、L1、Atol、max_qscale_diff 以及前后统计范围等信息,通常是逐层定位问题时最值得重点看的文件之一。

如果 Calibration 精度不达标、QAT 精度异常,或者 Export / Convert 阶段出现一致性问题,通常都应该回到这个文件来判断误差是从哪一层开始放大的。

实际排查时,可重点看下面几类信息:

  • 从哪一层开始,两个模型的输出指标明显恶化。

  • 异常层的 quant_dtypeqscale 是否合理。

  • base_model_*analy_model_* 的最小值、最大值和均值是否明显偏离。

  • max_qscale_diff 是否异常偏大。

这个文件尤其适合帮助您判断下面几个问题:

  • 问题是从哪一层开始明显放大的。

  • 某一层的 scale 是否可能不合理。

  • 当前误差更像截断误差还是舍入误差。

在判断“更像截断还是舍入”时,可以先按下面的经验观察:

  • 如果待分析模型的数值范围明显被压扁,或者与基准模型相比出现边界收缩、饱和、截平等现象,通常更像是截断误差或 scale 设置不合理。

  • 如果两个模型的整体数值范围接近,但 Atol / L1 持续存在且 Cosine 没有明显崩坏,通常更像是舍入误差、查表近似或实现细节差异。

注意

不要把“指标最差的那一层”直接等同于“根因层”。 误差往往可能是从更早的层传下来的,因此通常需要结合 abnormal_layer_advisor.txt 和敏感度结果一起判断。

output_xxx_sensitive_ops.pt/.txt

这类文件会在执行 QuantAnalysis.sensitivity() 后生成,是混合精度调优和关键层定位时最常用的产物之一。

如果模型存在多个输出,通常会按输出分别生成文件,例如 output_0_ATOL_sensitive_ops.txt。实际使用时,建议您先选对与当前业务指标最相关的那个输出文件,再开始分析。

其中:

  • txt 文件更适合人工阅读。

  • pt 文件更适合脚本加载,或者后续结合模板继续做自动化配置。

这类文件通常最适合下面这些场景:

  • 做混合精度调优时,判断哪些算子最值得优先提升到 qint16torch.float16

  • 模型有多个输出时,判断当前掉点更主要影响哪个输出分支。

实际查看时,可重点关注:

  • 排名前面的高敏感 op 当前使用的量化 dtype。

  • 这些 op 是否仍是 qint8,以及是否值得尝试提升到 qint16torch.float16

  • 这些 op 的计算量占比是否允许您为它们付出更高精度的代价。

  • 敏感的是激活、权重,还是某个输入。

如果某个 op 已经是高精度,但仍然排在前面,往往说明问题不一定只是“精度类型不够”,还需要继续结合 compare_per_layer_out.txt 看它的数值分布和误差是如何产生的。

abnormal_layer_advisor.txt

abnormal_layer_advisor.txt 会在执行 QuantAnalysis.compare_per_layer() 后生成,更像一份异常层提示列表。 它会帮助您快速扫出一些值得优先关注的层,例如数据范围过大、出现 infNaN、输出没有高精度保护等情况。

因此,它更适合作为一个“快速缩小范围”的入口,而不是最终结论。

这个文件最适合下面这些场景:

  • 逐层结果太多,暂时不知道应该先看哪几层。

  • 希望先快速筛出明显异常层,再回到逐层对比结果中进一步核对。

实际使用时,通常可以这样理解它:

  • 如果这里已经明确提示某些层存在明显异常,说明这些层值得优先回到 compare_per_layer_out.txt 中进一步核对。

  • 如果这里没有明显异常,也不代表模型一定没有问题,仍需要结合逐层对比和敏感度结果继续判断。