部署一致性分析说明

qat.pt / qat model 到最终部署使用的 hbm,中间还会经过 export、convert、compile 以及部署适配等多个步骤。 如果这些步骤中的某一段引入了额外误差,就可能出现“训练侧结果正常,但部署侧结果不符合预期”的情况。 此章节主要介绍在 QAT 策略上如何避免这类问题,以及发生这类问题时如何定位并解决问题。

注意

训练部署无法做到比特一致,必然存在极少数 case 无法完全对齐, 因此,是否存在一致性问题,应当以数据集上的评测精度、稳定可复现的 badcase,以及多帧可视化结果作为判断依据,而不是只看单帧数值是否完全相同。

训练部署一致性问题分为两类:

  1. 用户侧问题。例如:前后处理不一致,模型版本不一致等。

  2. 工具侧问题。模型在 export / convert / compile 过程中引入了额外误差而产生的不一致。

无论问题最终属于用户侧还是工具侧,我们都建议您结合训练部署一致性分析方法,以及相关排查工具和调试产物完成定位。 对于用户侧问题,通常需要您根据排查结果自行修正。 而在完成明显用户侧问题的初步排除后,通常仍需按 export / convert / compile 阶段继续定位,不同类型问题的排查重点并不完全一样。 如果最终确认为工具侧问题,建议您保留对应阶段的调试产物、badcase 和关键模型产物,并提供给地平线技术支持人员,以便进一步分析并给出解决方案。

在一致性问题的排查过程中,涉及到以下几种模型:

产物类型获取阶段说明获取方法常见用途
qat.pttorch qat 模型Prepare / Calibration / QAT 后torch 侧的伪量化模型对浮点模型使用 prepare 接口作为训练侧精度基线,继续执行 pre_export / export
qat.export.pttorch qat export 模型pre_export仅完成查表转定点的 torch 模型,计算逻辑与 qat.bc 更接近qat.pt 模型使用 pre_export 接口export 阶段一致性分析、查表问题定位
qat.bc导出产生的 HBIR 模型export 后qat.pt 导出的 HBIR 模型qat.pt 模型使用 export 接口export 结果验证、convert 输入
quantized.bc转换生成的 HBIR 模型convert 后qat.bc 定点化得到的模型qat.bc 模型使用 convert 接口compile 前定点精度验证、convert 阶段排查
hbm编译产生的可部署模型compile 后最终部署模型quantized.bc 模型使用 compile 接口最终部署精度验证、compile / 板端问题排查

其中,比较容易混淆的两点如下:

  • qat.export.pt 不是部署主链路中的必选产物,但在 export 阶段排查时非常关键。它主要用于先判断问题是否由查表转定点引入。

  • quantized.bc 是进入 compile 之前最值得优先关注的定点精度基线。如果 quantized.bc 已经异常,就不应直接把问题归因到 compile 或板端部署。

pre_export 接口基本用法如下:

from horizon_plugin_pytorch.quantization.hbdk4 import pre_export
qat_export_pt = pre_export(qat_pt)

一致性问题定位起点

在进入 export / convert / compile 三个阶段的具体排查之前,建议您先完成下面几件事:

  1. 准备一份可稳定复现问题的数据集。通常建议至少包含 1000 帧,并且数据集上的评测结果相对稳定。

  2. 先适配好 bc 模型在 x86 侧的推理流程。

  3. 先排除明显的用户侧问题,再进入按 export / convert / compile 阶段进行的分阶段排查。

原始定位流程如下图所示:

在正式进入一致性排查前,建议您先用小数据集在 CPU 上比较 qat.export.ptqat.bc,先验证 bc 推理流程是否正确。 这一步的目的不是直接定位 export、convert 或 compile 阶段的问题,而是先排除明显的用户侧问题,确认后续用于比较 bc 模型的输入输出处理、推理代码和评测流程本身没有明显错误。

如果两者精度不一致,建议先关闭伪量化,再重新验证 qat.export.ptqat.bc 的结果是否一致:

from horizon_plugin_pytorch.quantization.hbdk4 import export, pre_export
from horizon_plugin_pytorch.quantization import FakeQuantState, set_fake_quantize

qat_pt.eval()
set_fake_quantize(qat_pt, FakeQuantState._FLOAT)
qat_bc = export(qat_pt, example_inputs)
qat_export_pt = pre_export(qat_pt)

关闭伪量化后,常见会出现两种情况:

  1. 如果关闭伪量化后结果一致,通常应优先检查关闭之前模型的 fake quant 和 observer 状态是否处于 validation 状态。
print(qat_pt)
# fake_quant_enabled 应为 True,observer_enabled 应为 False
GraphModuleImpl(
  (quant): QuantStub(
      (activation_post_process): FakeQuantize(
        dtype=qint8, fake_quant_enabled=True, observer_enabled=False,
        qscheme=torch.per_tensor_symmetric, ch_axis=-1,
        scale=tensor([0.1250]), zero_point=tensor([0])
        (activation_post_process): MinMaxObserver(
            min_val=-10.0,
            max_val=9.999998092651367,
            averaging_constant=1,
        )
      )
  )
  ...
)
  1. 如果关闭伪量化后结果仍不一致,建议先对 qat.export.ptqat.bc 分别跑统计量,再做逐层对比。
from horizon_plugin_profiler import QuantAnalysis

qa = QuantAnalysis(qat_export_pt, qat_bc, "export")

# torch 与 bc 可接受同一格式输入时,一起跑统计量
qa.set_bad_case(badcase)
qa.run()

# torch 与 bc 不可接受同一格式输入时,分开跑统计量
# pt_badcase 与 bc_badcase 除格式外内容应保持一致
qa.set_bad_case(pt_badcase)
qa.run(run_baseline_model=True, run_analysis_model=False)
qa.set_bad_case(bc_badcase)
qa.run(run_baseline_model=False, run_analysis_model=True)

qa.compare_per_layer()

如果这一步已经暴露出明显的输入输出处理差异、状态设置问题或 bc 推理流程错误,建议先修正这些用户侧问题,再继续进入下文的分阶段排查。

快速判断问题更可能发生在哪一段

实际排查时,建议您先不要一上来就跑完整套工具,而是先用现象判断问题更可能落在哪一段。

当前现象优先怀疑阶段建议先做什么
qat.pt / qat model 正常,但 qat.bc 异常export 阶段先比较 qat.export.ptqat.pt,再比较 qat.export.ptqat.bc
qat.bc 正常,但 quantized.bc 异常convert 阶段直接比较 qat.bcquantized.bc,做 badcase、逐层对比和敏感度分析
quantized.bc 正常,但 hbm 异常compile / 部署阶段重点检查输入输出处理、插入节点、前后处理适配和板端部署差异

如果还不能快速判断,也建议至少先完成下面两件事:

  1. 确认 plugin / profiler / hbdk 已升级到当前建议版本。

  2. 先验证 quantized.bc 的精度是否满足预期,再决定是否继续往 compile 或板端方向排查。

建议的排查顺序

如果您当前还不确定应该从哪开始,通常建议按下面的顺序处理:

  1. 先确认 qat.ptquantized.bc 哪一个是当前最稳定的精度基线。

  2. 先排除明显的用户侧问题,再用“快速判断”表定位问题更可能发生在哪一段。

  3. 如果是 export 问题,先看 pre_export,再看 qat.export.ptqat.bc

  4. 如果是 convert 问题,先比较 qat.bcquantized.bc,再做敏感度分析。

  5. 如果是 compile / 部署问题,先确认 quantized.bc 正常,再回看输入输出处理和板端部署差异。

  6. 如果常规方法仍无法定位,再使用 bc_editor 继续缩小范围。

如果您在排查过程中还不熟悉 model_check_result.txtfx_graph.txtcompare_per_layer_out.txtoutput_xxx_sensitive_ops.txt 等产物,建议继续阅读 调试产物解读 章节。

Export 一致性

qat.pt 正常,但 qat.bc 不符合预期时,通常应优先怀疑问题发生在 export 阶段。 这类问题最常见的来源包括:查表转定点引入误差、导出图与训练图不一致,以及 export 后某些算子的实现差异。

典型现象

  • qat.pt 的评测精度和多帧可视化正常,但 qat.bc 异常。

  • qat.export.pt 已经异常,说明问题很可能在 pre_export 这一步就开始出现。

  • qat.export.pt 正常,但 qat.bc 异常,说明更可能是 export 图或 HBIR 表达引入的问题。

分析前提

  • qat.pt 必须先 eval,并切换到 FakeQuantState.VALIDATION

  • qat.ptqat.export.ptqat.bc 比较时,应尽量保证输入内容一致。

  • 如果 torch 和 bc 模型无法直接接受同一格式输入,也需要保证两边输入除格式外内容一致。

排查步骤

  1. 先看 qat.export.pt 是否正常。

    也就是说,先不要直接比较 qat.ptqat.bc,而是先用 pre_exportqat.pt 转成 qat.export.pt,判断“查表转定点”这一步是否已经带来明显误差。

    • 如果 qat.export.pt 已经异常,优先判断问题是否由查表转定点引入。

    • 如果 qat.export.pt 正常,但 qat.bc 异常,优先判断问题是否来自 export 图不一致或 HBIR 导出阶段。

  2. 如果 qat.export.pt 已经异常,先定位是不是查表问题。

    此时建议使用 QuantAnalysis(qat_pt, qat_export_pt, "pre_export") 做逐层对比和敏感度分析,优先找出是哪些查表算子带来了明显误差。

from horizon_plugin_profiler import QuantAnalysis
from horizon_plugin_pytorch.quantization.hbdk4 import pre_export

qa = QuantAnalysis(qat_pt, qat_export_pt, "pre_export")
qa.auto_find_bad_case(dataloader)
qa.run()
qa.compare_per_layer()
qa.sensitivity()
  1. 如果常规方法仍然无法缩小范围,可以继续用 pre_export 做分段定位。
from horizon_plugin_pytorch.quantization.hbdk4 import pre_export

qat_pt.module_a = pre_export(qat_pt.module_a)
  1. 如果 qat.export.pt 正常,但 qat.bc 异常,继续比较 qat.export.ptqat.bc

    此时建议使用 QuantAnalysis(qat_export_pt, qat_bc, "export") 做 badcase 定位和逐层对比,确认问题是否来自 export 图、HBIR 表达或个别算子导出实现差异。

from horizon_plugin_profiler import QuantAnalysis

qa = QuantAnalysis(qat_export_pt, qat_bc, "export")

# torch 与 bc 可接受同一格式输入时,一起跑统计量
qa.set_bad_case(badcase)
qa.run()

# torch 与 bc 不可接受同一格式输入时,分开跑统计量
qa.set_bad_case(pt_badcase)
qa.run(run_baseline_model=True, run_analysis_model=False)
qa.set_bad_case(bc_badcase)
qa.run(run_baseline_model=False, run_analysis_model=True)

qa.compare_per_layer()
  1. 如果怀疑导出图本身与训练图不一致,再回看 Prepare 产物。

    尤其是存在 if deploy、动态分支、循环次数变化等情况时,建议结合 fx_graph.txtmodel_check_result.txt 先确认图结构是否与预期一致。

使用工具

  • pre_export

    用于把 export 阶段拆成两段,先判断问题是否已经在查表转定点阶段出现。

  • QuantAnalysis

    用于 badcase 定位、逐层对比和敏感度分析。export 阶段最常见的两种用法是:

    • QuantAnalysis(qat_pt, qat_export_pt, "pre_export")

    • QuantAnalysis(qat_export_pt, qat_bc, "export")

  • fx_graph.txt / model_check_result.txt

    用于辅助判断 export 前后的图结构和 Prepare 结果是否一致。

需要保留的产物

  • qat.export.pt

  • qat.bc

  • compare_per_layer_out.txt

  • output_xxx_sensitive_ops.txt / .pt

  • model_check_result.txt

  • fx_graph.txt

如果仍无法判断问题所在,建议至少保留上述产物,以及对应 badcase,便于继续分析或向技术支持反馈。

Convert 一致性

qat.bc 正常,但 quantized.bc 不符合预期时,通常应优先怀疑问题发生在 convert 阶段。 这类问题的本质,是模型从伪量化表示进入真正定点表示后,某些算子的实现差异被放大了。

对于 J6E/M 平台,如果您主要遇到的是 convert 或部署阶段偏差,也可以结合高一致性 QAT 策略一起考虑。 它虽然需要在 prepare 之前设置,但主要作用仍然是降低 convert / 部署阶段偏差,因此我们放在这一节介绍方便您理解。

高一致性 QAT 策略

如果您当前的问题主要表现为:

  • qat.pt / qat.export.pt / qat.bc 基本正常,但 quantized.bc 开始掉点。

  • 已经基本确认问题不在查表转定点,而更像是 convert 前后的一致性偏差。

  • 当前使用平台为 J6E/M,并且希望优先用更低成本的方式改善 convert 一致性。

那么高一致性策略通常值得您优先评估。

反过来说,如果问题主要发生在 pre_export 或 export 阶段,例如查表转定点本身已经引入明显误差,那么高一致性策略通常不会带来直接帮助,此时仍应优先回到 export 阶段继续分析。

注意
  • 由于 J6E/M 平台浮点算力有限,更容易遇到训练部署一致性问题,为解决此类问题,我们提供了高一致性 QAT 策略,此策略仅对用于 J6E/M 平台生效,其他的平台不推荐您使用。

  • 使用前请确认 hbdk 版本不低于 4.4.2plugin 版本不低于 3.1.2

  • 对于不重训的场景,只有 level 0 有效,level 1 / level 2 需要在设置后重新训练。

  • 高一致性 QAT 策略对查表转定点无影响,主要影响 convert 前后的一致性。

高一致性 QAT 策略封装在 horizon_plugin_pytorch.qat_mode.ConsistencyStrategy 中,用法如下:

from horizon_plugin_pytorch.qat_mode import ConsistencyStrategy

# 必须在 prepare 之前设置一致性策略
ConsistencyStrategy.set_consistency_level(1)
...
qat_pt = prepare(float_model)
...
qat_bc = export(qat_pt, example_inputs)

# 如果设置 ConsistencyStrategy.set_consistency_level(0),可以做如下检查
print(qat_bc._high_precision_qpp)  # 值应为 true
print(qat_bc._fuse_requantize)     # 值应为 False

quantized_bc = convert(qat_bc, march)

当前支持三个等级(0 - 2)的策略。等级越高,一致性越好,但 QAT 精度可能受到轻微影响,因此,我们并不建议一开始就直接使用最高等级。 我们推荐您优先尝试使用 level 1,在大多数情况下对 QAT 精度无影响,且对性能和一致性可以有正向收益。

下表中:

  • POT(Power Of Two)scale,可简单理解为 scale 取值被约束到 2 的幂次形式。

  • A_POT(activation_pot)表示 activation 使用 POT scale,而 weight 仍使用统计型 scale。

结合现有实现,可以先这样理解它们的差异:

level主要特点更适合什么场景
0保持常规统计型 scale 策略,不开启高一致性算子路径,但会开启高精度 qpp,并关闭 requantize fuse。这里的高精度 qpp 可先理解为量化参数传播时尽量保留更高精度的中间结果,以减少参数传递过程中的附加误差。关闭 requantize fuse 则是避免重定点相关逻辑被提前融合进相邻算子,减少 convert 前后因融合方式不同带来的偏差已经完成训练、不希望重训,但希望先尽量改善 convert 一致性的场景
1compute_scale_strategy 切到 A_POT,也就是激活侧使用 POT scale、weight 侧仍保持统计型 scale。同时开启 resize / gridsample / mean / mod_centered 的高一致性路径,并关闭 requantize fuse。核心目的,是先把激活侧 scale 收敛到更接近 convert 行为的形式,减少激活 scale 抖动和边界变化带来的偏差J6E/M 上遇到 convert 一致性问题时,最推荐优先尝试的起点
2compute_scale_strategy 进一步切到 POT,也就是 activation / weight 都使用 POT scale。同时保持 resize / gridsample / mean / mod_centered 的高一致性路径开启,并关闭 requantize fuse。和 level 1 相比,主要多出来的是 weight 侧也切到 POT scale。经验上这通常会进一步压低 Linear / Conv 在 convert 阶段残留的一个 scale 级别误差概率level 1 仍不能满足一致性要求时,继续提高一致性的方案

关于 POT / A_POT,还建议您先这样理解:

  • 它们首先是为了让 scale 形式更接近 convert 侧的实际行为,因此主要作用在训练部署一致性上,而不是直接替代常规精度调优手段。

  • 一致性改善并不等于数据集精度一定同步提升。是否真正带来收益,仍建议回到 quantized.bc / hbm 的评测结果和 badcase 复现情况判断。

  • POT / A_POT 也不应默认理解为性能优化开关。它们更偏向一致性策略,是否带来额外收益或代价,仍需结合实际模型和部署结果确认。

如果您只想先抓住这三档策略的核心区别,也可以简单理解为:level 0 主要是在不重训前提下,减少量化参数传播和 requantize 融合带来的额外偏差。level 1 主要是 activation 用 POT scale,weight 仍保持统计型 scale。level 2 则是在 level 1 基础上进一步把 weight 侧也切到 POT scale,并继续压低 Linear / Conv 等关键算子剩余的一致性误差。

如上表所示,实际上:

  • level 0 更像“不重训前提下的补救方案”。

  • level 1 更像“推荐优先尝试的常规方案”。

  • level 2 更像“在 level 1 基础上进一步提高一致性”的加强方案。

使用时还建议您注意下面几点:

  • 如果当前模型原本没有启用高一致性策略,而您又不希望重新训练,那么只能尝试 level 0,在 prepare 模型前设置一致性策略等级为 0。

  • 如果准备正式使用 level 1 / level 2,请在设置策略后重新执行后续训练流程,而不要只在已有 checkpoint 基础上直接套用。

  • 即使启用了高一致性策略,最终仍建议回到 quantized.bc / hbm 的结果做验证,而不是只看训练侧模型是否改善。

使用时,还可以将下面这些现象作为辅助参考:

  • 在 level 1 下,convert 阶段的 Linear / Conv 通常仍可能存在一个 scale 级别的误差,其他算子通常更容易对齐。

  • 在 level 2 下,Linear / Conv 的这类误差概率通常会进一步下降到很低的水平。

  • 对于 Linear / Conv,如果去掉 bias,在 level 2 下 convert 阶段通常更容易做到无误差或近似无误差。

这些现象更适合作为理解策略效果的辅助参考,而不是绝对判断标准。实际项目中,仍建议以数据集评测结果和 badcase 复现情况为准。

如果您希望进一步了解 level 0 / 1 / 2 在实现层面的具体差异,例如各级别分别调整了哪些 scale 策略、哪些高一致性开关以及哪些导出行为,建议结合当前版本源码继续确认。不同版本之间,这部分实现细节可能存在调整。

典型现象

  • qat.bc 的评测精度或可视化结果正常,但 quantized.bc 异常。

  • qat.export.ptqat.pt 没有明显问题,但 quantized.bc 与前两者相比开始掉点。

分析前提

  • qat.bc 本身应已经确认精度正常,否则不要直接进入 convert 排查。

  • 比较 qat.bcquantized.bc 时,必须使用同一套输入和后处理。

  • 建议先在数据集上稳定复现 convert 前后一致性问题,再开始 badcase 和逐层分析。

排查步骤

  1. 先确认 quantized.bc 的异常是稳定可复现的。

    如果 convert 后的精度波动不稳定,或 badcase 不可复现,建议先回到数据集和验证流程,确保比较过程本身可靠。

  2. qat.bcquantized.bc 做 badcase 定位与逐层对比。

    这是 convert 阶段最核心的一步。建议使用 QuantAnalysis(qat_bc, quantized_bc, "convert") 先找 badcase,再看逐层对比结果。

from horizon_plugin_profiler import QuantAnalysis

qa = QuantAnalysis(qat_bc, quantized_bc, "convert")
qa.auto_find_bad_case(dataloader)
qa.run()
qa.compare_per_layer()
  1. 再结合 qat.export.pt 做敏感度分析。

    在 convert 阶段,敏感度分析通常仍然建议基于 torch 侧更易分析的 qat.export.pt 来做,同时复用 qat.bcquantized.bc 对比中找到的 badcase。

from horizon_plugin_profiler import QuantAnalysis

qa = QuantAnalysis(qat_export_pt, quantized_bc, "convert")
qa.load_bad_case()
qa.sensitivity()
  1. 如果已经确认问题主要来自 convert,但常规逐层分析仍然无法缩小范围,再考虑使用更细粒度工具继续分段定位。

使用工具

  • QuantAnalysis

    convert 阶段最常用的用法是:

    • QuantAnalysis(qat_bc, quantized_bc, "convert"):查 badcase、跑逐层对比
    • QuantAnalysis(qat_export_pt, quantized_bc, "convert"):基于同一 badcase 跑敏感度分析
  • 高一致性 QAT 策略

    对 J6E/M 平台,如果您当前主要遇到的是 convert 前后一致性问题,可以优先评估是否需要使用高一致性策略降低 convert 阶段偏差。

  • bc_editor

    当常规分析无法定位问题时,可通过编辑 bc 模型,把部分算子退回 CPU 执行,进一步缩小 convert 问题范围。

需要保留的产物

  • quantized.bc

  • compare_per_layer_out.txt

  • abnormal_layer_advisor.txt

  • output_xxx_sensitive_ops.txt / .pt

  • badcase.txt 或可稳定复现问题的输入样本

如果仍无法判断问题所在,建议至少保留上述产物,以及对应 badcase,便于继续分析或向技术支持反馈。

Compile / 部署一致性

quantized.bc 已经正常,但 hbm 或板端结果不符合预期时,通常应优先怀疑问题发生在 compile 或部署适配阶段。 这一阶段的问题,往往不再只是模型内部数值实现差异,还可能涉及输入输出处理、插入节点、前后处理适配和板端部署方式。

典型现象

  • quantized.bc 精度正常,但 hbm 异常。

  • x86 上的 hbm 结果与板端结果不一致。

  • 插入前处理节点、删除首尾节点或板端接入后结果开始变差。

分析前提

  • 进入 compile / 部署排查前,必须先确认 quantized.bc 自身已经正常。

  • 确保 compile 前后的输入输出定义、layout、前后处理以及 padding / 对齐策略保持一致。

  • 如果板端结果异常,建议先区分是 hbm 仿真就异常,还是仅板端接入异常。

排查步骤

  1. 先确认问题是否真的发生在 compile 之后。

    也就是说,要先明确 quantized.bc 是正常的。如果 quantized.bc 也异常,应回到 convert 阶段继续排查。

  2. 检查输入输出处理是否一致。

    这一阶段最常见的问题,不是算子本身,而是输入输出形式、前后处理、插入节点、删除节点以及部署接口适配不一致。

  3. 如果涉及插入前处理节点、删除首尾节点或其他图修改,建议分别对修改前后结果做比较。

  4. 如果是板端异常但 x86 仿真正常,优先怀疑板端部署接入、数据准备或运行方式差异,而不是直接怀疑模型转换本身。

使用工具

  • hb_verifier 或等效比对方式:用于比较 HBIR 与 HBM、x86 与板端结果之间的一致性。

  • 部署侧日志、输入输出 dump、板端推理脚本:用于确认问题是否来自部署接入而非模型本身。

需要保留的产物

  • quantized.bc

  • hbm

  • compile 配置

  • 板端输入输出样本

  • 对应 badcase 的前后处理输入、输出和日志

如果仍无法判断问题所在,建议至少保留上述产物,以及对应 badcase,便于继续分析或向技术支持反馈。

常规分析仍无法定位时

如果您已经完成 badcase、逐层对比和敏感度分析,仍然无法判断 convert 阶段问题具体落在哪些算子上,可以继续使用 bc_editor 做分段定位。

bc_editor 位于 horizon_plugin_profiler/bc_editor/bc_editor.py,同一目录下通常会提供配置示例。

它的核心思路是:

  1. 先查看 qat.bc 的文本表示,定位可疑算子的 HBIR 编号。

  2. 通过配置文件删除指定范围的 fake quant。

  3. 重新得到修改后的 bc,并再次 convert。

  4. 对比编辑前后的 quantized.bc 表现,判断哪些算子退回 CPU 后能明显改善一致性。

示例如下:

# 查看 qat.bc 模型文本
print(qat_bc.module.get_asm(enable_debug_info=True))

# “%” 后面的数字为 hbir 算子编号
module attributes {hbdk.legacy_round = true} {
  func.func @bev_gkt_mixvargenet_multitask_nuscenes(%arg0: tensor<6x3x512x960...
    %0 = "qnt.const_fake_quant"(%arg0) <{bits = 8 : i64, illegal = true, max...
    %1 = "hbir.constant"() <{values = dense<"0xC27B5D3DFF6DE33C1822093DDA9642...
    %2 = "qnt.const_fake_quant"(%1) <{axis = 0 : i64, bits = 8 : i64, illegal...
......

# config.json
{
    "remove_fake_quant": [[1, 100], 102]  # 删除 hbir 中编号 1~100 和 102 的伪量化
}

# 编辑后得到 qat_modified.bc,再 convert 可以得到部分算子退回 CPU 的 quantized.bc
python3 bc_editor.py --bc_path qat.bc --config_path config.json --new_bc_path qat_modified.bc

对比编辑前后 quantized.bc 的结果,可以进一步看出哪些算子退回 CPU 后能明显提高一致性。