Skip to main content

quantize-py

python bindings for quantize, a simple, fast quantization library written in rust. quantization stores numbers in fewer bits, trading a little accuracy for a lot less memory.

pip install quantize-py

requires python 3.12 or newer. numpy is installed with it. where no wheel fits, like free-threaded python or alpine linux, pip builds it from source, which needs rust 1.88 or newer.

from quantize import Scale, quantize

weights = [0.42, -0.10, 0.70, -0.50]

q = quantize(weights, bits=8, block=32, scale=Scale.F16)
back = q.dequantize()  # [0.421, -0.098, 0.700, -0.498]
dot = q.dot(weights)  # 0.926

bits is the width of each code, from 2 to 16. block is how many values share one scale, and scale is how that scale is stored: Scale.F32 (the default), Scale.F16, or Scale.BF16. values can be a list, a numpy array, or anything else np.asarray reads, like a pytorch tensor. a 2-d array keeps its shape, so q.dequantize() gives back a matrix and q.matmul(x) computes x @ W.T, like a linear layer. q.shape gives its rows and columns, and len(q) the number of values, as in rust.

the scales count toward the size: 4-bit codes with one f16 scale per 32 values cost 4.5 bits per value, or 5 with the default f32 scale. q.bits_per_element reports it. above about 10 bits, use f32 scales with asymmetric.quantize, since f16 and bf16 zero-points cap its accuracy.

the other schemes return the same Quantized type:

  • asymmetric.quantize(weights, bits=8, block=32) adds a zero-point per block, for values that aren't centered on zero
  • adaptive.quantize(weights, tolerance=0.1 * weights.std()) gives each block the fewest bits, from 2 to 8, that round every weight within tolerance, in the weights' own units. a tenth of their standard deviation gives about 5 bits a block. for a list, use np.std(weights)
  • learned.refine(q, weights) refits each block's scale, and its zero-point if it has one, to lower the mean squared error. it changes q in place, so call q.copy() first to keep the original
  • learned.alternate(q, weights) refits too, then rounds each value to the nearest code on its block's new line, and repeats until no code moves. it also changes q in place. both can raise the worst error past an adaptive tensor's tolerance, and lowering the error of the weights doesn't always lower the error of a model's outputs, so check those too
  • Scheme.Q4_32.quantize(weights) picks a scheme at run time

a block with outliers can need more than 8 bits, which raises ToleranceTooTightError. retrying with its smallest_tolerance works, but loosens every block, not just that one:

import numpy as np
from quantize import ToleranceTooTightError, adaptive

weights = np.array(weights)  # a list has no .std(). skip this line for a pytorch tensor
try:
    q = adaptive.quantize(weights, tolerance=0.1 * weights.std())
except ToleranceTooTightError as error:
    q = adaptive.quantize(weights, tolerance=error.smallest_tolerance)

quantized values can be pickled, and compared with ==. q.to_bytes() saves one as bytes, in the same format as the rust crate, and Quantized.from_bytes(data) loads it back. to keep it in an np.savez or safetensors file, store np.frombuffer(q.to_bytes(), np.uint8).

to save its parts as plain arrays instead, like with np.savez, pass them back by name to Quantized.from_parts. leave out the one that's None: bits for an adaptive tensor, or block_bits for the others:

parts = dict(kind=q.kind, shape=q.shape, block=q.block, bits=q.bits, block_bits=q.block_bits,
             codes=q.codes, scales=q.scales, zero_points=q.zero_points, scale=q.scale.name)
np.savez("layer.npz", **{name: part for name, part in parts.items() if part is not None})
q = Quantized.from_parts(**np.load("layer.npz"))

to keep quantized values in a torch.save checkpoint, store torch.frombuffer(bytearray(q.to_bytes()), dtype=torch.uint8), and load each back with Quantized(t). the checkpoint is then as small as the bytes, and torch.load reads it without add_safe_globals. pickling q itself makes the checkpoint about 1.5 times larger, since torch.save stores bytes as text, and needs torch.serialization.add_safe_globals([Quantized]) before torch.load.

each value decodes as code * scale, or (code - zero_point) * scale with zero-points, using the scale and zero-point of its block. codes are signed and bits wide, and q.codes packs them low bits first. scales can be negative, since a symmetric block puts its value farthest from zero on the most negative code. help(Quantized) has the details.

to build and test from a clone of the repo, with rust 1.88 or newer and just:

just setup
just python

on debian or ubuntu, run sudo apt install python3-venv first.

Metadata

Release files for quantize-py 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for quantize-py 0.3.1
File Size Uploaded
quantize_py-0.3.1.tar.gz 85.2 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for quantize-py 0.3.1
File
quantize_py-0.3.1-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
quantize_py-0.3.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 abi3 Linux glibc 2.17+ x86-64 Details
quantize_py-0.3.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.12 abi3 Linux glibc 2.17+ ARM64 Details
quantize_py-0.3.1-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
quantize_py-0.3.1-cp312-abi3-macosx_10_12_x86_64.whl CPython 3.12 abi3 macOS 10.12+ x86-64 Details

Total release size: 2.3 MB

Release files / quantize_py-0.3.1.tar.gz

Download URL quantize_py-0.3.1.tar.gz
Size 85.2 kB
Tags Source
SHA-256 checksum
How to use checksums
8aab1817b054ad6ea5167a443266b88a638387811a28eed47e72a8e4f3cb66d1
BLAKE2b-256 checksum
How to use checksums
6d3cbeedb797584bfa1f395e26a6804dc1e3718a3ea04fb64abb6df853575772
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / quantize_py-0.3.1-cp312-abi3-win_amd64.whl

Download URL quantize_py-0.3.1-cp312-abi3-win_amd64.whl
Size 336.6 kB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
1143ec0eb84caadb61645f3ef41d987d0163d59b84fd8db5066af8a981e9df7e
BLAKE2b-256 checksum
How to use checksums
bececaf1a0e9047604b63622573c5f15b6e329daad750e091958afc7d8b36aa4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / quantize_py-0.3.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL quantize_py-0.3.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 498.1 kB
Tags CPython 3.12 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
7925350beb217e81632b24d3593709d31d697bca7a19d7428c8963c5e03e40e5
BLAKE2b-256 checksum
How to use checksums
df874fdd2b64856f548f9ccafa906e4922a2436a80932c81bdd5329eb76a9b2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / quantize_py-0.3.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL quantize_py-0.3.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 489.4 kB
Tags CPython 3.12 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
273d117b435aedc4ebc98fe5058d5d6e488f1f5f1e3d771f3719a8cbe1772d36
BLAKE2b-256 checksum
How to use checksums
9338922d477f19bdff218ee7320d08dc8107bdadb2e637aa35a40a73ebbd7914
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / quantize_py-0.3.1-cp312-abi3-macosx_11_0_arm64.whl

Download URL quantize_py-0.3.1-cp312-abi3-macosx_11_0_arm64.whl
Size 440.8 kB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
2947334295a85503bbd4156c747d0ff025e6ea28b4eb8bc15703d2cfe1ff73ec
BLAKE2b-256 checksum
How to use checksums
8397f464835bbe7c15fbf346f51ae9f3f946f75ba62c705aeda72f21d0b9b950
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / quantize_py-0.3.1-cp312-abi3-macosx_10_12_x86_64.whl

Download URL quantize_py-0.3.1-cp312-abi3-macosx_10_12_x86_64.whl
Size 459.4 kB
Tags CPython 3.12 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
39f6a7d4306149d8eec6994c47fdb32be014d003f2b03cbdeb9bb90480eae0c7
BLAKE2b-256 checksum
How to use checksums
b604bbd849e9aae7cd3e921bd34dcde6cfc6df0c47e9b69a5190ea017e1685de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.3.1 This release

6 release files

0.3.0

6 release files

0.2.2

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page