onnxruntime
5f4538ac - [MLAS] Add ARM64 2-bit weight CPU kernels (#29466)

Commit
8 days ago
[MLAS] Add ARM64 2-bit weight CPU kernels (#29466) ## Summary Adds a new ARM64 NEON implementation of the 2-bit `MatMulNBits` (`SQNBIT_CompInt8`, `BlkBitWidth=2`) path built on `SDOT` + in-kernel 2-bit unpack. Replaces the previous ARM64 W2 fallback, which dequantized the 2-bit weights to fp32 and dispatched them through the standard fp32 GEMM — correct but far below the achievable throughput for a native int8-dot kernel. Also fixes a correctness bug in `MatMulNBits` that mis-handled the MLFloat16 A-input variant on the `accuracy_level=4` (CompInt8) code path on ARM64. This is the ARM64 equivalent of the PR https://github.com/microsoft/onnxruntime/pull/29064 ## What's in the PR ### New ARM64 W2 DotProd kernel family `onnxruntime/core/mlas/lib/sqnbitgemm_kernel_neon_int8_2bit.cpp` (new TU) - Native `SDOT`-based kernels for `BlkLen ∈ {32, 64, 128}`. - Templated `R{1,2} × C{1,4,8}` DotProd tile grid — one implementation covers the full `M × N` register-tile matrix instead of six copy-pasted variants. - In-kernel 2-bit → int8 unpack via `vsubq_s8(B, 2)`; B zero-point folded into the unpack so no post-kernel `BlkSum` SGEMM is needed. Same shape as the ARM64 W4 DotProd path. - Dispatch plumbing in `qnbitgemm.{cpp,h}` and `qnbitgemm_kernel_neon.{cpp,h}` routes `BlkBitWidth==2` through the new TU on ARM64 hosts with DotProd (Neoverse, Cortex-A76+, Snapdragon X, Apple M-series). ### `MatMulNBits` fp16 A-input CompInt8 fix `onnxruntime/contrib_ops/cpu/quantization/matmul_nbits.cc` - The MLFloat16 specialization of `PrePack` did not follow the same eager-fold path as the fp32 specialization, so the ARM64 CompInt8 W2 dispatch could mis-select a kernel or use un-recomputed `QuantBBlkSum` values when the A-input is fp16 and `accuracy_level=4`. - Fixed by routing the MLFloat16 `PrePack` through a mirror of the fp32 CompInt8 pipeline, and by having the W2 zero-points callback recompute `QuantBBlkSum = -scale × zp` from `scales_fp32_` consistently for both element types. - A `packed_b_finalized_` flag now guards the single-shot CompInt8 packing so a re-entrant `PrePack` cannot double-pack. ### Docs - `docs/Arm64_w2_kernel_future_enhancements.md` — forward-looking notes on the two follow-ups (SMMLA-based I8MM TU; lane-indexed SDOT for the C8 tile). Not required for this PR to land; captures the design context so the next contributor doesn't re-derive it. ## Performance **Throughput comparison (tok/s):** | seq_len | W4 (1.27 release) | W2 (1.27 release, DeQuant + fp32 GEMM) | **W2 (PR)** | W2 PR vs W2 1.27 | W2 PR vs W4 1.27 | |---|---|---|---|---|---| | 32 | 878.3 | 130.7 | 757.2 | 5.8× | 0.86× | | 64 | 904.4 | 220.3 | 953.4 | 4.3× | 1.05× | | 128 | 797.7 | 318.2 | 1032.0 | 3.2× | 1.29× | ## Notes / follow-ups (not in this PR) - SMMLA-based W2 I8MM TU for `FEAT_I8MM` hosts (R2+ tiles, ~2× dot throughput). - Lane-indexed SDOT for the C8 tile (A-load reduction). - Both are described in `docs/Arm64_w2_kernel_future_enhancements.md` §1 and §2.
Author
Parents
Loading