Xenova's picture
Xenova HF Staff
sync 91d990483a17
929af3e verified
|
Raw
History Blame
8.07 kB
metadata
library_name: kernels
license: apache-2.0
tags:
  - kernel
  - webgpu
  - wgsl

com.microsoft.MatMulNBits

com.microsoft · ONNX Runtime contrib operator · contrib since_version 1

Description

Matrix multiplication with B block-quantized along K and dequantized as (code - zero_point) * scale. Each power-of-two block_size group has a scale and optional zero point; optional bias is added afterward. Two-, four-, and eight-bit codes are packed low-first, and A may have rank 2 or 3. This package supports standard unpacked zero points with the same dtype as A. Deprecated g_idx, prepacked weights, and bfloat16 tensors are not implemented.

See the ONNX Runtime MatMulNBits contrib-operator spec for the reference semantics.

Inputs

Name Upstream name Logical dtype Rank Shape Description Presence
aT A T1 Float input matrix, not quantized. Rank 2 has shape (M, K) and rank 3 has shape (batch, sequence, K); only the last axis is the reduction axis and the leading axes fold into the row count, so the ordinary activation needs no surrounding Reshape. required
bT B uint8 3 Bit-packed uint8 weight matrix of shape (N, k_blocks, blob_size), where k_blocks = ceil(K / block_size) and blob_size = block_size * bits / 8. Codes are packed low-first along K. Bound in the packed storage layout: four blob bytes per u32 word, so the kernels stream the blob's own bytes rather than one widened word per byte. required
scalesT scales T1 2 Per-block dequantization scale factors of shape (N, k_blocks), with the same dtype as A. required
zeroPointsT zero_points T3 2 Standard unpacked per-block zero points with shape (N, k_blocks) and the same dtype as A. Omission uses 2^(bits - 1). optional
biasT bias T1 1 Optional bias vector of shape [N] added to the output. optional

Outputs

Name Upstream name Logical dtype Rank Shape Description Presence
yT Y T1 same as aT derived Result of A multiplied by the dequantized weight matrix, with optional bias, same dtype and rank as A: the leading axes of A with a trailing N. required

Attributes

Attributes and default values (overridable per request):

Attribute Default Description
K Input feature dimension of the weight matrix.
N Output feature dimension of the weight matrix.
accuracy_level 0 Minimum internal accuracy level: 0 (unset), 1 (float32), 2 (float16), 3 (bfloat16), or 4 (int8).
bits 4 Bit width used to quantize B; this package supports 2, 4, and 8.
block_size Power-of-two quantization block size along K; it must be at least 16.

Type constraints

Variable Allowed dtypes
T1 float32, float16
T3 float32, float16

Implementation variants

One implementation is selected per call from the device capabilities, the request shapes and the dtypes; these notes say what each one covers.

  • prefill_tiled_reg_vec4_splitk_default_zero — Cuts the K reduction of the four-wide register-blocked prefill tile into power-of-two slices across dispatch.z, retaining at least 512 K values per slice, then sums the f32 partials and adds bias in a second pass.
  • prefill_tiled_reg_vec4_default_zero — The register-blocked prefill tile with four-wide activation loads and a 128-row tile above 256 rows: the activation slice of every K tile is staged with one vector load per lane instead of four scalar loads, and the taller tile halves the dequantization work per multiply-add.
  • prefill_tiled_reg_vec4_splitk_zero_bias — Cuts the K reduction of the four-wide register-blocked prefill tile into power-of-two slices across dispatch.z, retaining at least 512 K values per slice, then sums the f32 partials and adds bias in a second pass.
  • prefill_tiled_reg_vec4_zero_bias — The register-blocked prefill tile with four-wide activation loads and a 128-row tile above 256 rows: the activation slice of every K tile is staged with one vector load per lane instead of four scalar loads, and the taller tile halves the dequantization work per multiply-add.
  • prefill_tiled_reg_vec4_splitk_zero_only — Cuts the K reduction of the four-wide register-blocked prefill tile into power-of-two slices across dispatch.z, retaining at least 512 K values per slice, then sums the f32 partials and adds bias in a second pass.
  • prefill_tiled_reg_vec4_zero_only — The register-blocked prefill tile with four-wide activation loads and a 128-row tile above 256 rows: the activation slice of every K tile is staged with one vector load per lane instead of four scalar loads, and the taller tile halves the dequantization work per multiply-add.
  • prefill_tiled_reg_vec4_splitk_bias_only — Cuts the K reduction of the four-wide register-blocked prefill tile into power-of-two slices across dispatch.z, retaining at least 512 K values per slice, then sums the f32 partials and adds bias in a second pass.
  • prefill_tiled_reg_vec4_bias_only — The register-blocked prefill tile with four-wide activation loads and a 128-row tile above 256 rows: the activation slice of every K tile is staged with one vector load per lane instead of four scalar loads, and the taller tile halves the dequantization work per multiply-add.

Device requirements

Some implementation variants require subgroup-matrix and subgroups. These are route-specific capabilities, not package-wide requirements; availability also depends on the request shape and dtype.

Files

Use with @huggingface/kernels

npm install --save-exact @huggingface/kernels@0.0.1-preview.2

Required output shapes and logical data types are inferred from the supplied inputs and attributes; result tensors are allocated automatically.

The version: 1 option selects the published kernel contract; it is independent of any operator opset, contrib since_version, or model version. It follows the v1 branch as fixes land. To pin exact artifact bytes, pass a 40-character commit revision instead of version.

Replace each *Data placeholder with a typed array containing the corresponding input data.

import { getKernel } from "@huggingface/kernels";

const kernel = await getKernel("webgpu-kernels/com.microsoft.MatMulNBits", { version: 1 });
const { yT } = await kernel({
  aT: { data: aTData, shape: [2, 17] },
  bT: { data: bTData, shape: [2, 2, 8] },
  scalesT: { data: scalesTData, shape: [2, 2] },
}, {
  attrs: { K: 17, N: 2, block_size: 16 },
});