ONNX Runtime Compatibility: >= 1.24.1 (compiled with v1.26.0)
QAIRT SDK Compatibility: 2.49.40
pip install onnxruntime==1.26.0
pip install onnxruntime-qnn==2.5.0
Packaging
Platform Support
| Package | Windows ARM64 | Windows ARM64 (ARM64x) | Windows x86_64 | Linux ARM64 | Linux x86_64 | Android ARM64 |
|---|---|---|---|---|---|---|
| Python Wheel | Inference | — | AOT compilation | Inference | AOT compilation | — |
| NuGet | - | Inference | — | — | — | — |
| ZIP | Inference | Inference | AOT compilation | — | AOT compilation | — |
| tgz | — | — | — | Inference | — | — |
| Maven | — | — | — | — | — | Inference |
New Ops and Fusions
- Shape (#510)
- ReduceLogSumExp (#463)
- QLinearMatMul (#467)
- NonMaxSuppression (#559)
- If (#409)
- Reshape-Gemm-Reshape(-Reshape) fusion — Fuses
Reshape(ND→2D) → Gemm → [Reshape(2D→MD) → [Reshape(MD→PD)]]intoQNN_OP_FULLY_CONNECTED(+QNN_OP_RESHAPE), matching the pattern ORT emits for ND matmul+add. (#232) - MatMul → Conv2D (1x1) for LPBQ — Lowers
MatMultoQNN_OP_CONV_2Dwith 1x1 weights when LPBQ encodings are present. (#357)
For the full list of supported operators, see Supported ONNX Operators and for supported fusions, see Supported Operator Fusions.
Improvements
- QNN GPU weight sharing — Extends weight sharing (previously HTP-only) to the QNN GPU backend, reducing per-session memory when multiple sessions share weights. (#67)
- QNN context priority levels — Extended from 4 to 8 levels, adding
NORMAL_LOW,HIGH_PLUS,CRITICAL,CRITICAL_PLUS. (#106, #568) - Framework op tracing — Added profiling↔trace auto-merge (onnx-op column in profiling output at detailed/optrace levels) and AOT Phase 2 sidecar discovery. (#488)
- Framework op tracing — Added
dump_qnn_ep_input_graphsession config, a source-to-optimized ONNX structural matcher, and profiling-CSV enrichment with original ONNX source ops, closing the source→optimized→QNN-op provenance gap. (#491) - QNN API error diagnostics —
graphFinalize,graphExecute,graphCreate, andcontextApplyBinarySectionfailures now include the QNN symbolic error string, not just a bare integer code. (#532) - RMSNorm (HTP) — Removed the dummy all-zeros beta tensor on QAIRT SDK 2.49+, which now accepts beta as a truly optional input. (#581)
- 4-bit block-quantized (BQ) weights on HTP — New
enable_block_quant_weight_optimizationsession option converts int4 BQ weight encodings to LPBQ when supported, falling back to the standard BQ compatibility path otherwise. See Configuration Options for details and trade-offs. (#307) - HTP fp16 overflow clamping — New
fp16_clamp_overflowHTP session option (default OFF, requires QNN API >= 2.38 / QAIRT 2.49) clamps fp16 Conv overflow instead of producing NaN/Inf. Intentionally undocumented as it changes HTP numerical behavior. (#686)
Op Translation Fixes
- Pad — Added float16 support for the
constant_valueattribute on HTP, avoiding CPU fallback. (#546) - ReduceL2 (QDQ) — Registered in the QDQ node-unit selector so quantized
ReduceL2fuses correctly instead of silently decomposing into an unquantized float32 island. (#596) - Clip — Accepts
min/maxfed by aDequantizeLinearover a constant initializer (common AIMET-export pattern), by treating folded-constant DQ outputs the same as initializers. (#586) - Softmax — Fixed HTP misbehaving when AIMET populates a non-natural output encoding (outside
[0, 1]) to satisfy older symmetric-input MatMul requirements; now emits the correct[0, 1]encoding plus aConvertop. Recovers major accuracy loss on YoloV10/V11 detection models. (#558) - SpaceToDepth CRD fusion — Fixed a regression where dynamic batch dimension (
-1) in Reshape shape initializers was rejected, causing 6D-tensor CPU fallback on dynamic-batch models. (#567) - BatchNormalization — Fixed incorrect bias-tensor reuse when two BN nodes share the same ONNX bias initializer but have different mean/variance, silently producing wrong output. Recovers major accuracy loss on Sinet. (#582)
- GroupQueryAttention — Fixed a shape mismatch where QNN's GQA op def requires
total_sequence_lengthas a 0D scalar while ONNX'scom.microsoft.GroupQueryAttentionsupplies it as a 1D[1]tensor, causing op validation failure. (#654)
Bug Fixes
- Utils — Fixed undefined behavior from calling
std::vector::assignwith a reference into the same vector, which crashed MSVC debug builds. (#511) - Android NPU discovery — Standalone QNN EP now detects Qualcomm devices via the
ro.soc.manufacturersystem property instead of scanning/dev/fastrpc-cdsp*, which Android's SELinux policy blocks for untrusted apps. FixesgetEpDevices()returning no NPU device (and QNN EP being unusable) on Android even on supported devices. Linux ARM64 behavior is unchanged. (#683)
Full Changelog: rel-2.4.0...rel-2.5.0
Known Issues
- LLM model load failure (
QNN_MEMORY_ALLOCATION_ERROR, 1002) — Some LLM models fail to load with all EP context binaries. Workaround: enable theenable_vtcm_backup_buffer_sharingQNN EP option. This option is AOT-flow only and may not cover all use cases. Fix targeted for2.6.0.
Contributors
This release includes contributions from:
Ashima Jain, Ashwath Shankarnarayan, Badri Narayanan, Calvin Nguyen, Chun-Chih Teng, Hua-Yu Chou, Kuan-Yu Lin, Kyle Romero, Matthew Sinclair, Mike Hsu, Min Fong Hong, Nageshwar Singh, Nischay Mamidi, Tirupathi Reddy T, Vineeth Jatoth, Yathindra Kota, Yu-Hung Chuang, Yuduo Wu