平台差异说明
在同样的模型量化与部署流程下,不同计算平台在量化策略、输出精度、输入输出处理和部署能力上并不完全一致。
这些差异会直接影响您在 ONNX 模型量化、PyTorch 模型量化、模型编译、quantized.bc 验证、hbm 验证以及板端部署中的选择。
如果一开始没有把平台差异纳入方案设计,后续就容易在量化配置、结果验证和部署适配上反复返工。
如果您当前正在选择量化链路或调优起点,建议先读完本节,再继续进入后续的量化或部署章节。
当前实际使用中,可以先把平台差异按下面两类理解:
-
J6E/M/B:以定点能力为主,量化策略更偏 int8 + int16,部署时更需要关注高精度输出形式、输入输出对齐和定点结果验证。
-
J6H/P/S6P:浮点能力更强,支持更多 float16 / float32 相关能力,量化与部署时通常会引入更多 float16 配置,同时还要额外考虑多核、L2M 和绑核调度等问题。其中 S6P 与 J6H/P 在量化策略和输入输出处理上一致,已知差异有两点:一是 L2 Cache 最大可用容量不同,J6H/P 上为 24MB,S6P 上为 12MB,二是 S6P 平台上 UCP 仅支持 BPU 一个 IP,其他 IP 均不支持。
如果您的当前目标只是先验证模型是否可部署,可以先重点看 量化策略差异 和 输入输出处理差异 两节。
如果您已经进入板端部署或性能调优阶段,还需要继续看 部署能力差异 一节。
平台差异影响哪些决定
不同平台的差异,通常会最先影响下面几类决定:
| 关注点 | J6E/M/B 更常见的选择 | J6H/P/S6P 更常见的选择 |
|---|---|---|
| ONNX 模型量化起始方式 | 各平台整体流程基本一致,通常先做标准 PTQ / int8 快速验证 | 各平台整体流程基本一致,如需继续看性能或精度边界,再补做 int8 + float16 混合精度等配置验证 |
| PyTorch Calibration 起始配置 | 先看 int8,再逐步增加 int16 | 常从 float16 起步,再为 Conv / MatMul / GEMM 回退 int8 / int16 |
| PyTorch QAT 调优重点 | 通过 int16 提升精度上限,再回退到混合精度 | 用 float16 降低量化难度,再按敏感度补 int16 |
| 高精度输出形式 |
| 模型尾部 GEMM 类算子高精度输出常直接表现为 float32 |
| 输入 stride 对齐 | nv12 常见为 32 对齐 | nv12 常见为 64 对齐 |
| 非图像 tensor 最小内存单元 |
| 常见为 256 字节 |
| 部署调度重点 | 更多关注单核结果正确性和一致性 | 还要额外考虑多核、绑核、L2M 和带宽争抢 |
| L2 Cache 最大可用容量 | 不涉及 | J6H/P 上为 24MB,S6P 上为 12MB |
因此,平台差异并不只是“硬件指标不同”,而是会直接改变您在量化配置、结果验证和部署代码中的推荐做法。
量化策略差异
ONNX 模型量化平台差异
如果当前走的是 ONNX 模型量化链路,平台差异首先不体现在整体流程是否不同,而更多体现在精度配置、输出精度和部署适配上。
ONNX 模型的调优流程在各平台上是通用的,整体流程是先通过标准 PTQ 流程完成模型结构验证、量化编译和基础精度验证。
平台差异主要会进一步影响两件事:
-
后续是否需要继续做更高精度配置验证,例如 int8 + float16、全 int16 或局部浮点配置。
-
编译完成后,输出类型、输入输出对齐和板端部署适配是否需要随平台调整。
J6E/M/B 起步策略
在 J6E/M/B 上,ONNX 模型量化的默认策略以 int8 + int16 混合精度为主,int8 作为默认。
常见的使用顺序是:
-
先通过
hb_compile --fast-perf生成基础 int8 配置,快速拿到板端性能上限参考。 -
在
--fast-perf生成的 yaml 基础上继续调优,若精度不满足需求,通过quant_config把敏感算子提升到 int16。 -
若难量化模型直接调 int16 仍不满足需求,可考虑先跑全 int16 校准看精度上限,再逐步回退到平衡的混合精度配置。
J6H/P/S6P 起步策略
在 J6H/P/S6P 上,由于浮点能力增强,ONNX 模型量化的默认策略也随之不同。
更常见的起始策略是:
-
以“全局 float16 + Conv / GEMM / Matmul / ConvTranspose 回退 int8”作为基础配置。
-
Resize / GridSample 建议在
quant_config中显式回退 int8。原因是 int8 在这两个算子上性能更好,起步阶段建议先从 int8 开始尝试。 -
若基础配置下精度仍不满足需求,再依据敏感度结果,把局部敏感算子提高到 int16。
PyTorch 模型量化平台差异
如果当前走的是 PyTorch 量化链路,平台差异首先体现在 Calibration 与 QAT 阶段的量化策略起点上,其次也会体现在输出类型和部署适配上。
PyTorch 链路的整体流程在各平台上是通用的,均遵循"浮点模型改造 → Prepare → Calibration → 可选 QAT → Export / Convert → Compile → 板端验证"这一主线,具体参考 PyTorch 模型量化基本流程说明 章节。
平台差异主要会进一步影响两件事:
-
Calibration 和 QAT 的起始量化策略(是从 int8 + int16 起步,还是从 float16 起步)。
-
编译完成后,输出类型、输入输出对齐和板端部署适配是否需要随平台调整。
J6E/M/B 起步策略
在 J6E/M/B 上,PyTorch 模型在进入 QAT 之前的 Calibration 阶段,量化策略通常以 int8 + int16 混合精度为主。
常见的使用顺序是:
-
先完成 PyTorch Calibration 或全 int8 验证,确认模型结构、量化链路和基础性能没有明显问题。
-
如果精度不满足需求,再通过全 int16 或更高比例的 int16 配置先看精度上限。
-
精度达到目标后,再逐步降低 int16 比例,回到更平衡的 int8 / int16 混合精度配置。
-
如果 Calibration 已经比较接近浮点结果,再进入 PyTorch QAT 时可优先尝试固定激活 scale 的训练方式。
这一策略的重点不是一开始就把所有算子都提到高精度,而是先看精度上限,再回退高精度比例,最终仍然回到 quantized.bc / hbm 结果验证。
J6H/P/S6P 起步策略
在 J6H/P/S6P 上,由于浮点能力增强,PyTorch Calibration 和后续 PyTorch QAT 的起点通常都会不同。
更常见的起始策略是:
-
先以“全局 float16 + Conv / Matmul / GEMM 类算子使用 int8”作为基础配置。
-
如果基础配置下精度仍不满足需求,再依据敏感度结果,把局部敏感算子提高到 int16。
-
对于大量 vector 类计算,float16 往往比直接堆高 int16 更容易降低量化调优难度。
-
若某些中间计算的数值范围超出 float16 表示能力,再有针对性地切回 int16。
这一策略的核心原因是,J6H/P/S6P 上很多 vector 计算中,int16 和 float16 的速度差异并不大,而 float16 通常更有利于降低量化难度和调参成本。
这些差异会直接影响什么
-
对 ONNX 模型量化:整体 PTQ 流程在各平台上基本通用,平台差异主要体现在
quant_config平台经验模板。 -
对 PyTorch Calibration:J6E/M/B 更适合先用全 int8 或全 int16 看精度边界,J6H/P/S6P 更适合把 float16 也纳入基础配置一起验证。
-
对 PyTorch QAT:J6E/M/B 更强调通过 int16 找到精度上限后再回退,J6H/P/S6P 更强调利用 float16 降低量化难度,再对局部算子补 int16。
-
对量化配置:J6H/P/S6P 更容易用到新版 qconfig 模板中的全局 float16 配置,而 J6E/M/B 更多是从全局 int8 出发,再对敏感算子配置 int16。
如果您已经确定平台和起始策略,下一步建议结合 模型精度调优指导 和对应链路章节继续细化配置。
输出精度差异
高精度输出形式差异
不同平台上,模型尾部 GEMM 类算子的高精度输出形式可能不同,这会直接影响后处理代码和结果验证方式。
在 J6E/M 上,由于 TAE 硬件不支持浮点输出,如果模型尾部 Conv / Linear / Matmul 等 GEMM 类算子配置为高精度输出,常见表现形式是:
-
算子本身先输出 int32。
-
再通过反量化节点转成 float32。
在 J6B/H/P/S6P 上,由于 TAE 硬件支持浮点输出,同样的高精度输出更常直接表现为 float32,无需软件侧反量化。
这意味着如果您原先在 J6E/M 上是按“尾部 int32 + 软件侧反量化”的方式处理输出,迁移到 J6B/H/P/S6P 时,软件侧需要重新确认输出类型是否已经变成浮点。
这会影响哪些环节
-
对 ONNX 模型量化:模型尾部 Conv / GEMM 类算子默认走高精度输出,实际输出类型会随平台不同(J6E/M 为 int32,J6B/H/P/S6P 为 float32),一致性对比与板端后处理代码需要按平台适配。
-
对 PyTorch 模型量化:需要确认高精度输出的目标到底是保留 int32 结果,还是直接让模型输出浮点结果。J6B/H/P/S6P 的 TAE 支持 float32 直接输出,J6E/M 则输出 int32 后再软件反量化,两侧路径不同,部署代码需要按平台适配。
-
对
quantized.bc / hbm验证:需要确认比较的对象是否是同一种输出类型,避免把输出类型变化误判为精度异常。 -
对后处理和部署代码:如果代码里假定了固定的 int32 或固定的反量化路径,迁移平台时容易直接出错。
如果您的模型尾部使用了高精度输出:
-
ONNX 模型量化侧,参考 quant_config 说明 章节确认高精度输出配置,参考 ONNX 模型部署一致性分析 章节确认跨平台输出类型对一致性判读的影响。
-
PyTorch 侧,参考 构建 QConfig、精度调优指导 和 部署一致性分析说明 一起确认输出路径。
输入输出处理差异
stride、padding 与 aligned byte size 差异
跨平台迁移时,最常见的问题之一并不是量化本身,而是输入输出 tensor 的内存布局处理不一致。
需要重点关注的差异包括:
-
nv12 输入的 stride 对齐要求不同。
-
非图像 tensor 的最小内存单元不同。
-
模型输入输出 tensor 的
stride和alignedByteSize可能变化。
以常见部署场景为例:
-
J6H/P/S6P 上 nv12 输入常要求 64 对齐。
-
J6E/M/B 上 nv12 输入常要求 32 对齐。
-
非图像 tensor 的最小申请内存单元,J6H/P/S6P 常为 256 字节,J6E/M 常为 64 字节,J6B 常为 128 字节。
这类差异最终都会体现在模型节点属性里的 stride、validShape 和 alignedByteSize 上。
处理建议
建议优先采用下面两种方式,尽量避免写死平台相关处理:
-
编译时统一评估是否开启
input_no_padding=True和output_no_padding=True。 -
部署代码中统一根据
validShape、stride和alignedByteSize准备输入和解析输出,不要依赖 hard code 的固定跨距或固定内存大小。
如果部署代码本身就是按节点属性解析有效数据,那么即使跨平台后 stride 或最小对齐单位变化,通常也不需要再单独改一套逻辑。
这些差异会影响什么
-
对 ONNX 模型量化:yaml 的
compiler_parameters.extra_params是否配置input_no_padding/output_no_padding、nv12 输入的 stride 对齐要求(J6E/M/B 为 32 对齐,J6H/P/S6P 为 64 对齐),会直接影响quantized.bc ↔ hbm一致性对比时的输入准备。若板端输入未按平台对齐,可能表现为hbm输出与quantized.bc不一致。 -
对 PyTorch 模型量化:调用
hbdk4.compiler.compile()时同样需要评估input_no_padding/output_no_padding两个参数。这些开关会直接改变qat.bc / quantized.bc / hbm的输入输出形式,板端输入准备与一致性对比的数据准备都需要与之匹配。 -
对模型编译:是否开启
input_no_padding、output_no_padding,都会影响后续部署时是否还要手动处理 padding。 -
对
quantized.bc / hbm验证:若离线验证和板端输入输出布局不一致,容易把内存布局问题误判成精度问题。 -
对板端部署:如果输入输出仍按旧平台的 stride、padding 或最小内存单元处理,迁移后最容易出现解析错误或结果异常。
如需继续看这部分的具体接口与处理方式,参考 模型推理应用开发指导、动态输入介绍 和 对齐规则 章节。一致性判读方面,ONNX 链路参考 ONNX 模型部署一致性分析 章节,PyTorch 链路参考 部署一致性分析说明 章节。
pyramid / resizer 输入差异
如果模型输入来自 pyramid 或 resizer,平台差异会更早暴露在输入链路里,而不是等到模型本身运行时报错。
需要重点注意的是:
-
pyramid 输入通常是 stride 动态。
-
resizer 输入通常是 shape 和 stride 都动态。
-
不同平台上,图像输入的 stride 对齐要求不同,跨平台迁移时需要同步检查配置文件和输入准备逻辑。
例如在 J6H/P/S6P 上,nv12 输入通常按 64 对齐处理,而在 J6E/M/B 上更常见的是 32 对齐。若原先在 J6E/M/B 上的 pyramid 配置文件就是按 32 对齐写死的,迁移到 J6H/P/S6P 时就需要检查是否满足新的对齐要求。
对这类模型,除了检查输入 stride 外,还应同步确认:
-
训练时输入的数据格式和数值范围。
-
部署时插入的前处理节点和输入类型设置。
-
如果在 PyTorch QAT 中对输入使用了 fixed scale,是否仍与当前平台上的输入来源一致。
这类差异会直接影响 PyTorch Calibration、PyTorch QAT、ONNX 模型量化的输入准备与 quantized.bc / hbm 一致性判读、编译配置和板端验证结果。如果输入链路不一致,即使模型本身量化配置正确,也可能出现精度偏差。
如果您的模型使用 pyramid 或 resizer 输入,建议下一步继续结合 模型推理应用开发指导、动态输入介绍 和量化配置章节一起确认。一致性判读方面,ONNX 链路参考 ONNX 模型部署一致性分析 章节,PyTorch 链路参考 部署一致性分析说明 章节。
部署能力差异
J6H/P/S6P 需要额外关注的能力
相较于 J6E/M/B,J6H/P/S6P 还需要额外关注多核、L2M 和绑核调度等部署能力差异。
这些能力不会直接改变量化公式本身,但会明显影响:
-
模型拆分方式。
-
编译方式。
-
运行时调度方式。
-
板端延时和带宽表现。
多核和绑核
J6H/P/S6P 具备更多 BPU 核心,应用调度空间更大。
在实际使用中,更常见的推荐方式是:
-
优先按功能拆分模型或拆分 pipeline。
-
在静态编排后做绑核运行。
-
尽量减少依赖
HB_UCP_BPU_CORE_ANY这类会引入额外波动的调度方式。
这样做的原因是,模型的性能收益与模型结构耦合较强,且 BPU 是独占式硬件,单次推理占用多个核后,其他任务的调度空间会显著下降。
L2M
J6H/P/S6P 支持 L2M,可用于缓解多核并发场景下的 DDR 带宽争抢问题。
但 L2M 并不是默认自动生效的能力,通常需要同时完成两件事:
-
编译时给模型指定合适的
max_l2m_size。 -
运行时通过环境变量为对应核心分配正确的 L2M 大小。
如果编译时指定了 L2M,运行时却没有分到足够空间,推理可能直接失败,或者没有预期的带宽收益。
需要注意的是,J6H/P 与 S6P 上 L2 Cache 的最大可用容量不同,J6H/P 上为 24MB,S6P 上为 12MB。因此在 S6P 上指定 max_l2m_size 与分配运行时 L2M 时,上限需要按 12MB 而不是 24MB 来评估。若沿用 J6H/P 上的编译与运行时配置直接迁移到 S6P,容易因超出上限而失败或拿不到预期收益。
这些差异会影响什么
-
对模型编译:是否要引入 L2M 会改变编译和部署策略。跨 J6H/P 与 S6P 迁移时,还需要重新评估
max_l2m_size是否仍在目标平台的上限内。 -
对板端部署:是否绑核、是否开启抢占、如何分配 L2M,都会直接影响端到端延时稳定性。
-
对性能评测:J6H/P/S6P 上的评测不再只是单模型 latency,还需要把多核并行、带宽争抢和 pipeline 设计一起纳入考虑。
如果您已经进入部署编排或板端性能优化阶段,建议继续阅读 模型推理应用开发指导 以及对应的性能评测章节。
下一步看哪里
如果您读完本节后,已经明确了自己当前更关心的是哪一类差异,可按下面的方向继续:
-
想继续确认 ONNX 模型量化的通用 PTQ 流程和调优方式:看 ONNX 模型量化原理及流程概述、模型精度调优指导 以及 ONNX 模型量化相关章节。
-
想继续确认 ONNX 模型量化在各平台的
quant_config经验模板:看 quant_config 说明 章节。 -
想排查 ONNX 模型量化的
quantized.bc / hbm一致性:看 ONNX 模型部署一致性分析 章节。 -
想继续确认 PyTorch Calibration 的起始策略:看 模型精度调优指导 和 PyTorch 量化链路相关章节。
-
想继续配置 PyTorch QAT 的精度和输出策略:看 PyTorch 模型量化基本流程说明、构建 QConfig 和 量化感知训练。
-
想排查
quantized.bc / hbm不一致或平台迁移后的结果偏差:看 部署一致性分析说明。 -
想继续处理输入输出、stride、padding、动态 shape 或板端推理代码:看 模型推理应用开发指导、动态输入介绍 和 对齐规则。
