平台差异说明

在同样的模型量化与部署流程下,不同 J6 计算平台在量化策略、输出精度、输入输出处理和部署能力上并不完全一致。

这些差异会直接影响您在 ONNX 模型量化、PyTorch 模型量化、模型编译、quantized.bc 验证、hbm 验证以及板端部署中的选择。 如果一开始没有把平台差异纳入方案设计,后续就容易在量化配置、结果验证和部署适配上反复返工。

如果您当前正在选择量化链路或调优起点,建议先读完本节,再继续进入后续的量化或部署章节。

先看自己属于哪一类平台

当前实际使用中,可以先把平台差异按下面两类理解:

  • J6E/M/B:以定点能力为主,量化策略更偏 int8 + int16,部署时更需要关注高精度输出形式、输入输出对齐和定点结果验证。

  • J6H/P:浮点能力更强,支持更多 float16 / float32 相关能力,量化与部署时通常会引入更多 float16 配置,同时还要额外考虑多核、L2M 和绑核调度等问题。

如果您的当前目标只是先验证模型是否可部署,可以先重点看“量化策略差异”和“输入输出处理差异”两节。

如果您已经进入板端部署或性能调优阶段,还需要继续看“部署能力差异”一节。

平台差异会先影响哪些决定

不同平台的差异,通常会最先影响下面几类决定:

关注点J6E/M/B 更常见的选择J6H/P 更常见的选择
ONNX 模型量化起始方式各平台整体流程基本一致,通常先做标准 PTQ / int8 快速验证各平台整体流程基本一致,如需继续看性能或精度边界,再补做 int8 + float16 混合精度等配置验证
PyTorch Calibration 起始配置先看 int8,再逐步增加 int16常从 float16 起步,再为 Conv / Matmul / GEMM 回退 int8 / int16
PyTorch QAT 调优重点通过 int16 提升精度上限,再回退到混合精度float16 降低量化难度,再按敏感度补 int16
高精度输出形式模型尾部 GEMM 类算子高精度输出常表现为 int32,再反量化到 float32模型尾部 GEMM 类算子高精度输出常直接表现为 float32
输入 stride 对齐nv12 常见为 32 对齐nv12 常见为 64 对齐
非图像 tensor 最小内存单元J6E/M 常见为 64 字节,J6B 常见为 128 字节常见为 256 字节
部署调度重点更多关注单核结果正确性和一致性还要额外考虑多核、绑核、L2M 和带宽争抢

因此,平台差异并不只是“硬件指标不同”,而是会直接改变您在量化配置、结果验证和部署代码中的推荐做法。

量化策略差异

ONNX 模型量化先怎么理解平台差异

如果当前走的是 ONNX 模型量化链路,平台差异首先不体现在整体流程是否不同,而更多体现在精度配置、输出精度和部署适配上。

ONNX 模型的调优流程在各平台上是通用的,整体流程是先通过标准 PTQ 流程完成模型结构验证、量化编译和基础精度验证。

平台差异主要会进一步影响两件事:

  1. 后续是否需要继续做更高精度配置验证,例如 int8 + float16、全 int16 或局部浮点配置。

  2. 编译完成后,输出类型、输入输出对齐和板端部署适配是否需要随平台调整。

在 J6E/M/B 上,PyTorch 链路通常从哪里起步

在 J6E/M/B 上,PyTorch 模型在进入 QAT 之前的 Calibration 阶段,量化策略通常以 int8 + int16 混合精度为主。

常见的使用顺序是:

  1. 先完成 PyTorch Calibration 或全 int8 验证,确认模型结构、量化链路和基础性能没有明显问题。

  2. 如果精度不满足需求,再通过全 int16 或更高比例的 int16 配置先看精度上限。

  3. 精度达到目标后,再逐步降低 int16 比例,回到更平衡的 int8 / int16 混合精度配置。

  4. 如果 Calibration 已经比较接近浮点结果,再进入 PyTorch QAT 时可优先尝试固定激活 scale 的训练方式。

这一策略的重点不是一开始就把所有算子都提到高精度,而是先看精度上限,再回退高精度比例,最终仍然回到 quantized.bc / hbm 结果验证。

在 J6H/P 上,PyTorch 链路通常从哪里起步

在 J6H/P 上,由于浮点能力增强,PyTorch Calibration 和后续 PyTorch QAT 的起点通常都会不同。

更常见的起始策略是:

  1. 先以“全局 float16 + Conv / Matmul / GEMM 类算子使用 int8”作为基础配置。

  2. 如果基础配置下精度仍不满足需求,再依据敏感度结果,把局部敏感算子提高到 int16

  3. 对于大量 vector 类计算,float16 往往比直接堆高 int16 更容易降低量化调优难度。

  4. 若某些中间计算的数值范围超出 float16 表示能力,再有针对性地切回 int16

这一策略的核心原因是,J6H/P 上很多 vector 计算中,int16float16 的速度差异并不大,而 float16 通常更有利于降低量化难度和调参成本。

这些差异会直接影响什么

  • ONNX 模型量化:整体 PTQ 流程在各平台上基本通用,平台差异更多体现在后续精度配置验证、输出形式和部署适配上。

  • PyTorch CalibrationJ6E/M/B 更适合先用全 int8 或全 int16 看精度边界,J6H/P 更适合把 float16 也纳入基础配置一起验证。

  • PyTorch QATJ6E/M/B 更强调通过 int16 找到精度上限后再回退,J6H/P 更强调利用 float16 降低量化难度,再对局部算子补 int16

  • 对量化配置:J6H/P 更容易用到新版 qconfig 模板中的全局 float16 配置,而 J6E/M/B 更多是从全局 int8 出发,再对敏感算子配置 int16

如果您已经确定平台和起始策略,下一步建议结合 模型精度调优指导 和对应链路章节继续细化配置。

输出精度差异

为什么同样是高精度输出,不同平台的结果形式会不同

不同平台上,模型尾部 GEMM 类算子的高精度输出形式可能不同,这会直接影响后处理代码和结果验证方式。

J6E/M 上,如果模型尾部 Conv / Linear / MatmulGEMM 类算子配置为高精度输出,常见表现形式是:

  • 算子本身先输出 int32

  • 再通过反量化节点转成 float32

J6H/P 上,由于硬件支持浮点输出,同样的高精度输出更常直接表现为 float32

这意味着如果您原先在 J6E/M 上是按“尾部 int32 + 软件侧反量化”的方式处理输出,迁移到 J6H/P 时,软件侧需要重新确认输出类型是否已经变成浮点。

这会影响哪些环节

  • PyTorch QAT 配置:需要确认高精度输出的目标到底是保留 int32 结果,还是直接让模型输出浮点结果。

  • quantized.bc / hbm 验证:需要确认比较的对象是否还是同一种输出类型,避免把输出类型变化误判为精度异常。

  • 对后处理和部署代码:如果代码里假定了固定的 int32 或固定的反量化路径,迁移平台时容易直接出错。

如果您的模型尾部使用了高精度输出,建议继续结合 构建 QConfig精度调优指导部署一致性分析说明 一起确认输出路径。

输入输出处理差异

stride、padding 和 aligned byte size 为什么在跨平台时最容易出问题

跨平台迁移时,最常见的问题之一并不是量化本身,而是输入输出 tensor 的内存布局处理不一致。

需要重点关注的差异包括:

  • nv12 输入的 stride 对齐要求不同。

  • 非图像 tensor 的最小内存单元不同。

  • 模型输入输出 tensor 的 stridealignedByteSize 可能变化。

以常见部署场景为例:

  • J6H/Pnv12 输入常要求 64 对齐。

  • J6E/M/Bnv12 输入常要求 32 对齐。

  • 非图像 tensor 的最小申请内存单元,J6H/P 常为 256 字节,J6E/M 常为 64 字节,J6B 常为 128 字节。

这类差异最终都会体现在模型节点属性里的 stridevalidShapealignedByteSize 上。

实际使用时,建议怎么处理

建议优先采用下面两种方式,尽量避免写死平台相关处理:

  1. 编译时统一评估是否开启 input_no_padding=Trueoutput_no_padding=True

  2. 部署代码中统一根据 validShapestridealignedByteSize 准备输入和解析输出,不要依赖 hard code 的固定跨距或固定内存大小。

如果部署代码本身就是按节点属性解析有效数据,那么即使跨平台后 stride 或最小对齐单位变化,通常也不需要再单独改一套逻辑。

这些差异会影响什么

  • 对模型编译:是否开启 input_no_paddingoutput_no_padding,会影响后续部署时是否还要手动处理 padding。

  • quantized.bc / hbm 验证:如果离线验证和板端输入输出布局不一致,容易把内存布局问题误判成精度问题。

  • 对板端部署:如果输入输出仍按旧平台的 stride、padding 或最小内存单元处理,迁移后最容易出现解析错误或结果异常。

如需继续看这部分的具体接口与处理方式,建议继续阅读 模型推理应用开发指导动态输入介绍对齐规则

pyramid / resizer 输入差异

如果模型输入来自 pyramidresizer,平台差异会更早暴露在输入链路里,而不是等到模型本身运行时报错。

需要重点注意的是:

  • pyramid 输入通常是 stride 动态。

  • resizer 输入通常是 shape 和 stride 都动态。

  • 不同平台上,图像输入的 stride 对齐要求不同,跨平台迁移时需要同步检查配置文件和输入准备逻辑。

例如在 J6H/P 上,nv12 输入通常按 64 对齐处理,而在 J6E/M/B 上更常见的是 32 对齐。若原先在 J6E/M/B 上的 pyramid 配置文件就是按 32 对齐写死的,迁移到 J6H/P 时就需要检查是否满足新的对齐要求。

对这类模型,除了检查输入 stride 外,还应同步确认:

  • 训练时输入的数据格式和数值范围。

  • 部署时插入的前处理节点和输入类型设置。

  • 如果在 PyTorch QAT 中对输入使用了 fixed scale,是否仍与当前平台上的输入来源一致。

这类差异会直接影响 PyTorch CalibrationPyTorch QAT、编译配置和板端验证结果。如果输入链路不一致,即使模型本身量化配置正确,也可能出现精度偏差。

如果您的模型使用 pyramidresizer 输入,建议下一步继续结合 模型推理应用开发指导动态输入介绍 和量化配置章节一起确认。

部署能力差异

J6H/P 额外需要关注什么

相较于 J6E/M/BJ6H/P 还需要额外关注多核、L2M 和绑核调度等部署能力差异。

这些能力不会直接改变量化公式本身,但会明显影响:

  • 模型拆分方式。

  • 编译方式。

  • 运行时调度方式。

  • 板端延时和带宽表现。

多核和绑核

J6H/P 具备更多 BPU 核心,应用调度空间更大。

在实际使用中,更常见的推荐方式是:

  • 优先按功能拆分模型或拆分 pipeline。

  • 在静态编排后做绑核运行。

  • 尽量减少依赖 HB_UCP_BPU_CORE_ANY 这类会引入额外波动的调度方式。

这样做的原因是,模型的性能收益与模型结构耦合较强,且 BPU 是独占式硬件,单次推理占用多个核后,其他任务的调度空间会显著下降。

L2M

J6H/P 支持 L2M,可用于缓解多核并发场景下的 DDR 带宽争抢问题。

L2M 并不是默认自动生效的能力,通常需要同时完成两件事:

  1. 编译时给模型指定合适的 max_l2m_size

  2. 运行时通过环境变量为对应核心分配正确的 L2M 大小

如果编译时指定了 L2M,运行时却没有分到足够空间,推理可能直接失败,或者没有预期的带宽收益。

这些差异会影响什么

  • 对模型编译:是否要引入 L2M 会改变编译和部署策略。

  • 对板端部署:是否绑核、是否开启抢占、如何分配 L2M,都会直接影响端到端延时稳定性。

  • 对性能评测:J6H/P 上的评测不再只是单模型 latency,还需要把多核并行、带宽争抢和 pipeline 设计一起纳入考虑。

如果您已经进入部署编排或板端性能优化阶段,建议继续阅读 模型推理应用开发指导 以及对应的性能评测章节。

下一步看哪里

如果您读完本节后,已经明确了自己当前更关心的是哪一类差异,可按下面的方向继续: