Platform Differences

Under the same model quantization and deployment workflow, the different computing platforms differ in quantization strategy, output accuracy, input/output handling, and deployment capability.

These differences directly affect your choices in ONNX model quantization, PyTorch model quantization, model compilation, quantized.bc verification, hbm verification, and on-board deployment. If platform differences are not considered up front, you can easily end up reworking quantization configuration, result verification, and deployment adaptation.

If you are currently choosing a quantization link or a tuning starting point, we recommend reading this section first before moving on to the following quantization or deployment sections.

In practice, platform differences can first be understood in two categories:

  • J6E/M/B: primarily fixed-point capability. The quantization strategy leans toward int8 + int16, and deployment requires more attention to high-accuracy output form, input/output alignment, and fixed-point result verification.

  • J6H/P/S6P: stronger floating-point capability, supports more float16 / float32 related capabilities. Quantization and deployment typically involve more float16 configurations, and additionally require considering multi-core, L2M, and core-binding scheduling. Among them, S6P matches J6H/P in quantization strategy and input/output handling, with two known differences: first, the maximum available L2 Cache capacity differs, 24MB on J6H/P and 12MB on S6P, second, on the S6P platform UCP supports only the BPU IP, and no other IP is supported.

If your current goal is only to verify whether the model can be deployed, first focus on the Quantization Strategy Differences and Input/Output Handling Differences sections.

If you have entered the on-board deployment or performance tuning stage, also read the Deployment Capability Differences section.

What Decisions Are Affected

Platform differences typically affect the following decisions:

FocusCommon choice on J6E/M/BCommon choice on J6H/P/S6P
ONNX model quantization starting approachThe overall workflow is basically the same across platforms. Start with a standard PTQ / int8 quick verificationThe overall workflow is basically the same across platforms. If you need to explore the performance or accuracy boundary further, add int8 + float16 mixed-accuracy configuration verification
PyTorch Calibration starting configurationStart with int8, then gradually add int16Usually start with float16, then fall back to int8 / int16 for Conv / MatMul / GEMM
PyTorch QAT tuning focusUse int16 to raise the accuracy upper bound, then fall back to mixed accuracyUse float16 to reduce quantization difficulty, then supplement int16 based on sensitivity
High-accuracy output form
  • On J6E/M, the TAE does not support floating-point output. The high-accuracy output of tail GEMM-class operators is usually int32, which is then dequantized to float32
  • On J6B, the TAE supports floating-point output. The high-accuracy output of tail GEMM-class operators is usually directly float32
The high-accuracy output of tail GEMM-class operators is usually directly float32
Input stride alignmentnv12 usually requires 32-byte alignmentnv12 usually requires 64-byte alignment
Minimum memory unit for non-image tensors
  • On J6E/M, usually 64 bytes
  • On J6B, usually 128 bytes
Usually 256 bytes
Deployment scheduling focusMore focus on single-core result correctness and consistencyAdditionally consider multi-core, core binding, L2M, and bandwidth contention
Maximum available L2 Cache capacityNot applicable24MB on J6H/P, and 12MB on S6P

So platform differences are not just "different hardware specs", they directly change the recommended practice in your quantization configuration, result verification, and deployment code.

Quantization Strategy Differences

ONNX Model Quantization Platform Differences

If you are on the ONNX model quantization link, platform differences first show up not in whether the overall workflow differs, but in the accuracy configuration, output accuracy, and deployment adaptation.

The ONNX model tuning workflow is generic across platforms. The overall flow is to first complete model structure validation, quantized compilation, and basic accuracy verification through the standard PTQ workflow.

Platform differences mainly further affect two things:

  1. Whether higher-accuracy configuration verification is needed later, such as int8 + float16, full int16, or local floating-point configuration.

  2. Whether output type, input/output alignment, and on-board deployment adaptation need to be adjusted per platform after compilation.

J6E/M/B Starting Strategy

On J6E/M/B, the default ONNX model quantization strategy is int8 + int16 mixed accuracy, with int8 as the default.

The common order of use is:

  1. First use hb_compile --fast-perf to generate a baseline int8 configuration and quickly obtain a reference to the on-board performance upper bound.

  2. Continue tuning based on the yaml generated by --fast-perf. If accuracy does not meet expectations, use quant_config to promote sensitive operators to int16.

  3. If a hard-to-quantize model still does not meet expectations after switching to int16, consider first running a full int16 calibration to see the accuracy upper bound, then gradually falling back to a balanced mixed-accuracy configuration.

J6H/P/S6P Starting Strategy

On J6H/P/S6P, thanks to stronger floating-point capability, the default ONNX model quantization strategy is also different.

The more common starting strategy is:

  1. Use "global float16 + Conv / GEMM / MatMul / ConvTranspose fallback to int8" as the base configuration.

  2. Resize / GridSample are recommended to be explicitly configured with an int8 fallback in quant_config. int8 performs better on these two operators, so int8 is recommended as the starting point.

  3. If accuracy still does not meet expectations under the base configuration, promote locally sensitive operators to int16 based on sensitivity analysis.

PyTorch Model Quantization Platform Differences

If you are on the PyTorch quantization link, platform differences first show up in the starting quantization strategy of the Calibration and QAT stages, and also in the output type and deployment adaptation.

The overall workflow of the PyTorch link is generic across platforms, all following the main line of "floating-point model reconstruction → Prepare → Calibration → optional QAT → Export / Convert → Compile → on-board verification". Refer to the PyTorch Model Quantization Basic Process section.

Platform differences mainly further affect two things:

  1. The starting quantization strategy of Calibration and QAT (start from int8 + int16, or start from float16).

  2. Whether output type, input/output alignment, and on-board deployment adaptation need to be adjusted per platform after compilation.

J6E/M/B Starting Strategy

On J6E/M/B, in the Calibration stage before entering QAT, the PyTorch quantization strategy is usually int8 + int16 mixed accuracy.

The common order of use is:

  1. First complete PyTorch Calibration or full-int8 verification, and confirm that the model structure, quantization link, and baseline performance have no obvious issues.

  2. If accuracy does not meet expectations, use full int16 or a higher proportion of int16 to first see the accuracy upper bound.

  3. Once accuracy hits the target, gradually reduce the int16 proportion and return to a more balanced int8 / int16 mixed-accuracy configuration.

  4. If Calibration is already close to the floating-point result, when entering PyTorch QAT you can prioritize training with fixed activation scale.

The focus of this strategy is not to raise all operators to high accuracy from the start, but to first see the accuracy upper bound, then reduce the high-accuracy proportion, and eventually still return to quantized.bc / hbm result verification.

J6H/P/S6P Starting Strategy

On J6H/P/S6P, thanks to stronger floating-point capability, the starting points of PyTorch Calibration and the subsequent PyTorch QAT are usually different.

The more common starting strategy is:

  1. First use "global float16 + Conv / Matmul / GEMM using int8" as the base configuration.

  2. If accuracy still does not meet expectations under the base configuration, promote locally sensitive operators to int16 based on sensitivity analysis.

  3. For a large amount of vector-style computation, float16 is usually easier for reducing quantization tuning difficulty than piling up int16.

  4. If some intermediate computations exceed the float16 representation range, then switch back to int16 in a targeted way.

The core reason is that on J6H/P/S6P many vector computations do not show much speed difference between int16 and float16, while float16 is usually more helpful for reducing quantization difficulty and tuning cost.

What These Differences Affect

  • For ONNX model quantization: the overall PTQ workflow is basically generic across platforms. Platform differences mainly show up in the quant_config platform experience template.

  • For PyTorch Calibration: J6E/M/B is more suitable for first using full int8 or full int16 to see the accuracy boundary. J6H/P/S6P is more suitable for including float16 in the base configuration for verification together.

  • For PyTorch QAT: J6E/M/B emphasizes finding the accuracy upper bound with int16 and then falling back. J6H/P/S6P emphasizes using float16 to reduce quantization difficulty and then adding int16 for local operators.

  • For quantization configuration: J6H/P/S6P is more likely to use the global float16 configuration in the new qconfig template, while J6E/M/B usually starts from global int8 and then configures int16 for sensitive operators.

Once you have decided on the platform and the starting strategy, next combine with the Accuracy Tuning Guide and the corresponding link section to refine the configuration.

Output Accuracy Differences

High-Accuracy Output Form Differences

Across platforms, the high-accuracy output form of tail GEMM-class operators can differ, which directly affects post-processing code and the way you verify results.

On J6E/M, since the TAE hardware does not support floating-point output, if tail Conv / Linear / Matmul and other GEMM-class operators are configured for high-accuracy output, the common form is:

  • The operator itself first outputs int32.

  • Then a dequantization node converts it to float32.

On J6B/H/P/S6P, since the TAE hardware supports floating-point output, the same high-accuracy output is more often directly float32, without software-side dequantization.

This means if you originally handled outputs on J6E/M as "tail int32 + software-side dequantization", when migrating to J6B/H/P/S6P, the software side needs to re-confirm whether the output type has become floating-point.

What This Affects

  • For ONNX model quantization: tail Conv / GEMM-class operators use high-accuracy output by default. The actual output type varies across platforms (int32 on J6E/M, float32 on J6B/H/P/S6P). Consistency comparison and on-board post-processing code must be adapted per platform.

  • For PyTorch model quantization: you need to confirm whether the goal of high-accuracy output is to keep the int32 result, or to directly output floating-point. The TAE on J6B/H/P/S6P supports float32 direct output, while J6E/M outputs int32 and then dequantizes in software. The two paths are different and deployment code needs per-platform adaptation.

  • For quantized.bc / hbm verification: you need to confirm the compared objects are of the same output type, to avoid mistaking an output-type change for an accuracy anomaly.

  • For post-processing and deployment code: if the code assumes a fixed int32 or a fixed dequantization path, it can break directly when migrating platforms.

If your model uses high-accuracy output at the tail:

Input/Output Handling Differences

stride, padding, and aligned byte size Differences

When migrating across platforms, one of the most common issues is not quantization itself, but inconsistent memory layout handling for input/output tensors.

Key differences to watch:

  • The stride alignment requirement of nv12 input differs.

  • The minimum memory unit for non-image tensors differs.

  • The stride and alignedByteSize of model input/output tensors may change.

Typical deployment scenarios:

  • On J6H/P/S6P, nv12 input usually requires 64-byte alignment.

  • On J6E/M/B, nv12 input usually requires 32-byte alignment.

  • For the minimum memory unit for non-image tensors: usually 256 bytes on J6H/P/S6P, 64 bytes on J6E/M, 128 bytes on J6B.

These differences eventually manifest in the stride, validShape, and alignedByteSize attributes of model nodes.

Handling Suggestions

We recommend the following two practices to avoid hard-coding platform-specific handling:

  1. At compile time, uniformly evaluate whether to enable input_no_padding=True and output_no_padding=True.

  2. In deployment code, uniformly prepare inputs and parse outputs based on validShape, stride, and alignedByteSize, without relying on hard-coded fixed strides or fixed memory sizes.

If the deployment code already parses valid data by node attributes, then even if the stride or minimum alignment unit changes across platforms, you usually do not need a separate set of logic.

What These Differences Affect

  • For ONNX model quantization: whether the yaml's compiler_parameters.extra_params configures input_no_padding / output_no_padding, and the nv12 stride alignment requirement (32-byte on J6E/M/B, 64-byte on J6H/P/S6P), directly affect the input preparation for quantized.bc ↔ hbm consistency comparison. If on-board input is not aligned per platform, hbm output may be inconsistent with quantized.bc.

  • For PyTorch model quantization: when calling hbdk4.compiler.compile(), similarly evaluate the two parameters input_no_padding / output_no_padding. These switches directly change the input/output form of qat.bc / quantized.bc / hbm. On-board input preparation and consistency-comparison data preparation must match.

  • For model compilation: whether to enable input_no_padding and output_no_padding affects whether padding must be handled manually during subsequent deployment.

  • For quantized.bc / hbm verification: if the offline verification and on-board input/output layouts are inconsistent, memory-layout issues are easily mistaken for accuracy issues.

  • For on-board deployment: if input/output is still handled with the old platform's stride, padding, or minimum memory unit, parsing errors or abnormal results are the most common outcomes after migration.

For the specific interfaces and handling of this part, refer to the Embedded Application Development, Dynamic Input Introduction, and Alignment Rules sections. For consistency interpretation, ONNX link refers to the ONNX Model Deployment Consistency Analysis section, and PyTorch link refers to the Deployment Consistency Analysis section.

pyramid / resizer Input Differences

If the model input comes from pyramid or resizer, platform differences surface earlier in the input pipeline rather than waiting for the model itself to error out.

Key points to note:

  • pyramid input usually has dynamic stride.

  • resizer input usually has dynamic shape and dynamic stride.

  • Across platforms, the stride alignment requirement of image input differs. Cross-platform migration requires synchronously checking the configuration file and input preparation logic.

For example, on J6H/P/S6P nv12 input is usually handled with 64-byte alignment, while on J6E/M/B 32-byte alignment is more common. If a pyramid configuration file on J6E/M/B was hard-coded with 32-byte alignment, when migrating to J6H/P/S6P you need to check whether it meets the new alignment requirement.

For such models, besides checking input stride, also confirm:

  • The input data format and value range during training.

  • The pre-processing nodes inserted at deployment and the input type settings.

  • If fixed scale is used for the input in PyTorch QAT, whether it is still consistent with the current platform's input source.

These differences directly affect PyTorch Calibration, PyTorch QAT, ONNX model quantization's input preparation, quantized.bc / hbm consistency interpretation, compilation configuration, and on-board verification results. If the input pipeline is inconsistent, even if the model quantization configuration is correct, accuracy deviation may occur.

If your model uses pyramid or resizer input, we recommend further confirming things together with the Embedded Application Development, Dynamic Input Introduction, and the quantization configuration section. For consistency interpretation, ONNX link refers to the ONNX Model Deployment Consistency Analysis section, and PyTorch link refers to the Deployment Consistency Analysis section.

Deployment Capability Differences

Capabilities to Additionally Watch on J6H/P/S6P

Compared to J6E/M/B, J6H/P/S6P additionally requires attention to multi-core, L2M, and core-binding scheduling as deployment capability differences.

These capabilities do not directly change the quantization formula itself, but noticeably affect:

  • Model partitioning.

  • Compilation approach.

  • Runtime scheduling.

  • On-board latency and bandwidth performance.

Multi-core and Core Binding

J6H/P/S6P has more BPU cores, allowing more room for application-level scheduling.

In practice, the more common recommended approach is:

  • Prioritize splitting the model or pipeline by function.

  • After static orchestration, run with core binding.

  • Minimize reliance on scheduling methods like HB_UCP_BPU_CORE_ANY that introduce additional variance.

The reason is that model performance gains are strongly coupled with model structure, and the BPU is exclusive hardware. When a single inference occupies multiple cores, the scheduling room for other tasks drops significantly.

L2M

J6H/P/S6P supports L2M, which can be used to alleviate DDR bandwidth contention in multi-core concurrency scenarios.

However, L2M is not a capability that takes effect automatically. It usually requires doing two things together:

  1. At compile time, specify an appropriate max_l2m_size for the model.

  2. At runtime, allocate the correct L2M size to the corresponding core via environment variables.

If L2M is specified at compile time but not allocated enough at runtime, inference may directly fail or fail to gain the expected bandwidth benefit.

Note that the maximum available L2 Cache capacity differs between J6H/P and S6P, 24MB on J6H/P and 12MB on S6P. When setting max_l2m_size or assigning runtime L2M on S6P, the upper bound needs to be evaluated against 12MB rather than 24MB. Migrating the compile-time and runtime configuration from J6H/P directly to S6P without adjustment can exceed the limit and cause failures or fail to deliver the expected benefit.

What These Differences Affect

  • For model compilation: whether to introduce L2M changes the compilation and deployment strategy. When migrating between J6H/P and S6P, also re-evaluate whether max_l2m_size is still within the target platform's upper bound.

  • For on-board deployment: whether to bind cores, whether to enable preemption, and how L2M is allocated all directly affect end-to-end latency stability.

  • For performance evaluation: evaluation on J6H/P/S6P is no longer just single-model latency, but must also incorporate multi-core parallelism, bandwidth contention, and pipeline design.

If you have entered deployment orchestration or on-board performance optimization, refer to the Embedded Application Development section and the corresponding performance evaluation section.

Where to Look Next

If after reading this section you have already identified which type of difference you care about most, you can continue along these directions: