DotCache-Arena / dotcache /modes /m0_affine.py
DeanoCalver's picture
Initial DotCache Arena Space upload
751ad26 verified
Raw
History Blame Contribute Delete
3 kB
from __future__ import annotations
from math import ceil
import numpy as np
def pad_last_dim(values: np.ndarray, padded_size: int) -> np.ndarray:
pad_width = padded_size - values.shape[-1]
if pad_width <= 0:
return values
return np.pad(values, ((0, 0), (0, pad_width)), mode="constant")
def quantize_tensor(
values: np.ndarray,
*,
group_size: int,
bits: int,
scheme: str = "affine",
eps: float = 1e-8,
) -> tuple[np.ndarray, np.ndarray, np.ndarray | None, int]:
array = np.asarray(values, dtype=np.float32)
if array.ndim != 2:
raise ValueError("values must have shape [token_count, head_dim]")
token_count, head_dim = array.shape
num_groups = ceil(head_dim / group_size)
padded_head_dim = num_groups * group_size
padded = pad_last_dim(array, padded_head_dim)
grouped = padded.reshape(token_count, num_groups, group_size)
if scheme == "affine":
qmin = 0
qmax = (1 << bits) - 1
x_min = grouped.min(axis=-1)
x_max = grouped.max(axis=-1)
scales = np.maximum((x_max - x_min) / max(qmax - qmin, 1), eps)
shifted = (grouped - x_min[..., None]) / scales[..., None]
codes = np.clip(np.round(shifted), qmin, qmax).astype(np.uint8)
bias = x_min.astype(np.float32)
return codes, scales.astype(np.float32), bias, padded_head_dim
if scheme == "symmetric":
qmax = (1 << (bits - 1)) - 1
zero_point = qmax
max_abs = np.max(np.abs(grouped), axis=-1)
scales = np.maximum(max_abs / max(qmax, 1), eps)
signed_codes = np.clip(np.round(grouped / scales[..., None]), -qmax, qmax).astype(np.int32)
codes = np.clip(signed_codes + zero_point, 0, (1 << bits) - 1).astype(np.uint8)
return codes, scales.astype(np.float32), None, padded_head_dim
raise ValueError("scheme must be affine or symmetric")
def dequantize_group(
codes: np.ndarray,
*,
scales: np.ndarray,
bias: np.ndarray | None,
bits: int,
scheme: str,
) -> np.ndarray:
code_array = np.asarray(codes, dtype=np.float32)
scale_array = np.asarray(scales, dtype=np.float32)
if scheme == "affine":
if bias is None:
raise ValueError("affine mode requires bias")
bias_array = np.asarray(bias, dtype=np.float32)
return scale_array * code_array + bias_array
if scheme == "symmetric":
zero_point = (1 << (bits - 1)) - 1
return scale_array * (code_array - zero_point)
raise ValueError("scheme must be affine or symmetric")
def dequantize_groups(
codes: np.ndarray,
*,
scales: np.ndarray,
bias: np.ndarray | None,
bits: int,
scheme: str,
) -> np.ndarray:
expanded_scales = np.asarray(scales, dtype=np.float32)[..., None]
expanded_bias = None if bias is None else np.asarray(bias, dtype=np.float32)[..., None]
return dequantize_group(codes, scales=expanded_scales, bias=expanded_bias, bits=bits, scheme=scheme)