Core API¶
turboquant.core.codebook¶
Lloyd-Max codebook computation for the exact Beta distribution arising from random rotation of unit-norm vectors.
Math background (paper Section 3.1, Lemma 1): After multiplying a unit-norm vector x in S^{d-1} by a Haar-random rotation matrix Pi, each coordinate y_j = (Pi x)_j follows:
f(t) = Gamma(d/2) / (sqrt(pi) * Gamma((d-1)/2))
* (1 - t^2)^((d-3)/2), t in [-1, 1]
which is a scaled-shifted Beta distribution. For large d this converges to N(0, 1/d), but we use the EXACT integral at every d so the codebook is numerically precise for all head dimensions such as 64, 96, 128, 256.
Lloyd-Max algorithm: 1. Initialise 2^bits centroids at quantile midpoints of f. 2. Alternate: a. Boundaries = midpoints between consecutive centroids. b. Centroids = conditional means E[y | boundary[i] < y < boundary[i+1]]. 3. Stop when cost delta < tol.
Caching:
Solved codebooks are stored under
Both the exact Beta and the Gaussian approximation are exposed. Use exact Beta for production; Gaussian is kept as a diagnostic path.
beta_pdf ¶
PDF of a single coordinate of a uniformly random point on S^{d-1}.
f(t) = Gamma(d/2) / (sqrt(pi) * Gamma((d-1)/2))
* (1 - t^2)^((d-3)/2)
Args: t : array of evaluation points in (-1, 1). d : dimension of the embedding space, d >= 3.
Returns: Array of probability density values, same shape as t.
Source code in turboquant/core/codebook.py
gaussian_approx_pdf ¶
Gaussian approximation N(0, 1/d) of the Beta PDF (diagnostic path only). Exact Beta should be preferred for production codebooks.
Source code in turboquant/core/codebook.py
compute_lloyd_max ¶
compute_lloyd_max(d: int, bits: int, *, use_exact: bool = True, max_iter: int = 300, tol: float = 1e-13) -> dict
Solve the 1-D Lloyd-Max problem for the Beta (or Gaussian) distribution.
Args: d : head dimension. bits : bits per coordinate (1-8). use_exact : if True use exact Beta; if False use Gaussian approximation. max_iter : maximum Lloyd-Max iterations. tol : convergence threshold on absolute cost delta.
Returns dict with keys: centroids : list of 2^bits float64 centroids (sorted). boundaries : list of 2^bits + 1 boundaries (includes -1 and +1). mse_per_dim : scalar, MSE per coordinate dimension. d, bits, use_exact.
Source code in turboquant/core/codebook.py
get_codebook ¶
Return a Lloyd-Max codebook, loading from disk or computing on first call.
Args: d : head dimension. bits : bits per coordinate. use_exact : use exact Beta distribution (True) or Gaussian approx (False).
Returns: dict with 'centroids', 'boundaries', 'mse_per_dim', 'd', 'bits'.
Source code in turboquant/core/codebook.py
get_codebook_tensors ¶
get_codebook_tensors(d: int, bits: int, device: device, dtype: dtype = torch.float32, *, use_exact: bool = True) -> Tuple[torch.Tensor, torch.Tensor]
Return (centroids, decision_boundaries) as GPU tensors.
centroids : (2^bits,) centroid values decision_boundaries: (2^bits-1,) interior boundaries for searchsorted
The decision boundaries are the interior ones, i.e., boundaries[1:-1], which is what torch.searchsorted needs to map each coordinate to an index.
Source code in turboquant/core/codebook.py
Rotation helpers for TurboQuant core codecs.
RotationState
dataclass
¶
RotationState(mode: RotationMode, d_orig: int, seed: int, matrix: Optional[Tensor] = None, signs1: Optional[Tensor] = None, signs2: Optional[Tensor] = None, d_pad: int = 0)
Parameters needed to apply and invert a layer rotation.
build_rotation ¶
build_rotation(d: int, mode: RotationMode, device: device, dtype: dtype = torch.float32, seed: int = 42) -> RotationState
Create a rotation state for a layer/head group.
Source code in turboquant/core/rotation.py
derive_transform_seed ¶
Derive a deterministic transform seed for layer/head metadata.
rotation_from_spec ¶
rotation_from_spec(spec: TransformSpec, device: device, dtype: dtype = torch.float32) -> RotationState
Rebuild a rotation state from serialized metadata.
Source code in turboquant/core/rotation.py
rotate_forward ¶
Apply the forward rotation to row-vector inputs.
Source code in turboquant/core/rotation.py
rotate_backward ¶
Apply the inverse rotation to row-vector inputs.
Source code in turboquant/core/rotation.py
build_qjl_matrix ¶
build_qjl_matrix(d: int, device: device, dtype: dtype = torch.float32, seed: int = 12345) -> torch.Tensor
Generate a QJL sketch matrix with i.i.d. standard normal entries.
Source code in turboquant/core/rotation.py
TurboQuant MSE quantizer, Algorithm 1 from the paper.
TorbuquantMSE ¶
TorbuquantMSE(dim: int, bits: int, rotation: RotationState, device: device, *, use_exact: bool = True, norm_correction: bool = False)
Bases: Module
Algorithm 1 TurboQuant quantizer for reconstruction MSE.
Source code in turboquant/core/mse.py
quantize ¶
Quantize a batch of vectors.
Source code in turboquant/core/mse.py
dequantize ¶
Reconstruct vectors from MSEData.
Source code in turboquant/core/mse.py
rotate_query ¶
Apply the quantizer rotation to query vectors.
Source code in turboquant/core/mse.py
score_rotated ¶
Compute inner-product scores from rotated queries and packed indices.
query_rotated may be shaped (..., dim) or (..., query_tokens,
dim). The packed data must be shaped (..., kv_tokens, packed_dim)
with matching leading dimensions. The result has shape
(..., kv_tokens) or (..., query_tokens, kv_tokens).
Source code in turboquant/core/mse.py
score ¶
Compute inner-product scores from unrotated queries and packed indices.
pack_indices ¶
unpack_indices ¶
turboquant.core.qjl¶
Quantized Johnson-Lindenstrauss (QJL) transform, with 1-bit residual correction.
Paper Section 2.2 (Definition 1 / Lemma 2): Given residual r = x - x_mse (x in S^{d-1}, x_mse from Algorithm 1), the QJL quantization is:
z = sign(S * r) in {-1, +1}^d
||r||_2 stored as a scalar
Dequantized QJL contribution: x_qjl = sqrt(pi/2) / d * ||r|| * S^T * z
The combined estimator x_mse + x_qjl is unbiased:
E[
and has inner-product variance bounded by (pi/2) / d * ||y||^2 * D_mse(b-1).
Storage: Signs are packed 8 per byte (1 bit per coordinate) into uint8. One float32 scalar per vector stores ||r||.
Score computation (used during decode attention):
Given pre-sketched query q_sk = q @ S^T:
qjl_score = qjl_scale * ||r|| *
where qjl_scale = sqrt(pi/2) / d.
TorbuquantQJL ¶
Bases: Module
QJL residual quantizer (1 bit per coordinate of the residual).
Args: dim : head dimension d. S : (d, d) float32 Gaussian random matrix generated once per layer by build_qjl_matrix() in rotation.py. device : torch device.
Source code in turboquant/core/qjl.py
quantize ¶
Quantize residual r to 1-bit signs.
Args: residual : (..., d) float, r = x - x_mse.
Returns: signs_packed : (..., ceil(d/8)) uint8. residual_norms : (...,) float32.
Source code in turboquant/core/qjl.py
dequantize ¶
Reconstruct QJL contribution: x_qjl = scale * ||r|| * S^T * z
Returns: x_qjl : (..., d) float32.
Source code in turboquant/core/qjl.py
score ¶
Compute QJL attention score contribution without dequantizing.
Instead of forming x_qjl and then dotting with query, use:
qjl_score[n] = scale * ||r[n]|| *
Args: q_sketched : (BH, d) float32 pre-sketched query q @ S^T. signs_packed : (BH, N, ceil(d/8)) uint8. residual_norms : (BH, N) float32.
Returns: scores : (BH, N) float32.
Source code in turboquant/core/qjl.py
sketch_query ¶
Pre-sketch query: q_sk = q @ S^T.
Args: query : (BH, d) float query vectors.
Returns: q_sketched : (BH, d) float32.
Source code in turboquant/core/qjl.py
pack_signs ¶
Convert real projections to packed sign bits (8 signs per byte).
Args: projected : (..., d) float values from S * r.
Returns: packed : (..., ceil(d/8)) uint8.
Source code in turboquant/core/qjl.py
unpack_signs ¶
Unpack sign bits back to float {-1, +1}.
Args: packed : (..., ceil(d/8)) uint8. d : original number of coordinates.
Returns: signs : (..., d) float32 with values in {-1, +1}.
Source code in turboquant/core/qjl.py
TurboQuant MSE plus QJL residual codec, Algorithm 2 from the paper.
TorbuquantProd ¶
TorbuquantProd(dim: int, bits: int, rotation: RotationState, device: device, *, qjl_seed: int = 12345, use_exact: bool = True, qjl_for_attention: bool = False)
Bases: Module
Algorithm 2: unbiased inner-product TurboQuant quantizer.
Args: dim : head dimension d. bits : total bits per coordinate (must be >= 2). MSE uses (bits-1), QJL uses 1. rotation : RotationState for the MSE stage (shared with layer). device : torch device. qjl_seed : RNG seed for the QJL Gaussian matrix S. use_exact : use exact Beta codebook for MSE stage.
Source code in turboquant/core/polar.py
quantize ¶
Two-stage quantization.
Source code in turboquant/core/polar.py
dequantize ¶
Reconstruct with MSE plus QJL contribution.
Source code in turboquant/core/polar.py
attention_score ¶
Compute raw scores from compressed keys.
Source code in turboquant/core/polar.py
Channel-split TurboQuant codecs for fractional bit targets.
TorbuquantChannelMSE ¶
TorbuquantChannelMSE(*, dim: int, target_bits: float, device: device, seed: int = 42, calibration_scores: Tensor | None = None, rotation_mode: RotationMode = 'rht', use_exact: bool = True, norm_correction: bool = True)
Bases: Module
MSE codec that assigns one extra bit to selected channels.
Source code in turboquant/core/outlier.py
storage_bits_per_vector ¶
Return packed index and norm bits per vector for this codec.
Source code in turboquant/core/outlier.py
split_channel_indices ¶
split_channel_indices(dim: int, target_bits: float, *, calibration_scores: Tensor | None = None, device: device | None = None) -> tuple[torch.Tensor, torch.Tensor, int, int]
Return high-bit and low-bit channel indices for a fractional bit target.
Source code in turboquant/core/outlier.py
channel_energy_scores ¶
Compute mean squared magnitude per channel from calibration tensors.
Source code in turboquant/core/outlier.py
Shared data structures for quantized tensors and codec metadata.
TransformSpec
dataclass
¶
TransformSpec(kind: Literal['qr_rotation', 'rht', 'qjl'], dim: int, seed: int, dtype: str = 'float32', device_type: str = 'cpu', pad_dim: int | None = None)
Serializable rotation or sketch transform metadata.
CodebookSpec
dataclass
¶
CodebookSpec(dim: int, bits: int, distribution: Literal['beta_sphere', 'gaussian_approx'] = 'beta_sphere', cache_key: str | None = None)
Serializable Lloyd-Max codebook metadata.
QuantizedTensor ¶
Bases: NamedTuple
Common tensor payload plus byte-level format metadata.
QuantizedKeys ¶
Bases: NamedTuple
Key payload with transform and codebook specs.
QuantizedValues ¶
Bases: NamedTuple
Value payload with scale/zero metadata.
MSEData ¶
Bases: NamedTuple
Output of TurboQuantMSE.quantize().
indices : (BH, N, Pk) uint8 norms : (BH, N) fp16 bits : int dim : int
ProdData ¶
Bases: NamedTuple
Output of TurboQuantProd.quantize().
mse_indices : (BH, N, Pk) uint8 qjl_signs : (BH, N, Ps) uint8 residual_norms : (BH, N) fp32 norms : (BH, N) fp16 mse_bits : int dim : int
ChannelSplitData ¶
Bases: NamedTuple
Output of channel-split MSE quantization.
high : MSEData for selected high-bit channels, or None low : MSEData for remaining channels, or None high_index : selected high-bit channel indices low_index : remaining channel indices dim : original vector dimension target_bits : average bit target before norm metadata
ValueData ¶
Bases: NamedTuple
Output of quantize_values().
data : (BH, N, Pv) uint8 scales : (BH, N, G) fp16 zeros : (BH, N, G) fp16 bits : int dim : int group_size : int