File size: 1,776 Bytes
1c35eef | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | """Bit-exact GGML numerical primitives.
The C engine relies on two non-obvious primitives:
* ``gguf_nearest_int`` implements round-to-nearest-even with the classic
``float + 1.5*2**23`` mantissa trick rather than ``rint``. The trick is
reproduced here so that every quantized code is bit-identical to the
reference implementation.
* ``gguf_fp32_to_fp16`` / ``gguf_fp16_to_fp32`` are the emitted parameter
domain. Every solver in V2 may optimise in float32, but it reports and
stores only fp16-rounded values.
"""
from __future__ import annotations
import numpy as np
_MAGIC = np.float32(12582912.0)
_F16_MAX_BITS = 0x7BFF
def nearest_int(value) -> np.ndarray:
"""GGML-compatible nearest-integer rounding (ties to even)."""
arr = np.asarray(value, dtype=np.float32)
shifted = arr + _MAGIC
bits = shifted.view(np.int32)
return ((bits & 0x007FFFFF) - 0x00400000).astype(np.int64)
def to_fp16_bits(value) -> np.ndarray:
arr = np.asarray(value, dtype=np.float32)
return arr.astype(np.float16).view(np.uint16).astype(np.uint16)
def from_fp16_bits(bits) -> np.ndarray:
arr = np.asarray(bits, dtype=np.uint16)
return arr.view(np.float16).astype(np.float32)
def round_fp16(value) -> np.ndarray:
return from_fp16_bits(to_fp16_bits(value))
def fp16_ulp_neighbors(bits, radius: int) -> np.ndarray:
"""All non-negative finite fp16 bit patterns within ``radius`` ULPs."""
if radius < 0:
raise ValueError("radius must be non-negative")
b = int(bits)
lo = max(0, b - radius)
hi = min(_F16_MAX_BITS, b + radius)
return np.arange(lo, hi + 1, dtype=np.uint16)
def epsilon_for(scale: np.ndarray, relative: float = 1.0e-7) -> np.ndarray:
return relative * np.abs(scale) + np.float32(1.0e-30)
|