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, or 3.14 or newer for free-threaded python. numpy is installed with it. where no wheel fits, like 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. both can write into a float32 numpy array or pytorch tensor you pass, like q.matmul(x, out=y), so a loop can reuse it. 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. it lets other threads run while it works, so threads can refit several layers at once
  • 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 and lets other threads run. 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, and Scheme("symmetric(bits=4)") reads one from text, like a config value, which str(scheme) writes

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.

q.matmul runs on one core, but it lets other threads run while it multiplies, so threads can share out a batch. on an 8-core intel xeon, this multiplies a batch of 512 by a 4-bit 1536 × 576 matrix in 6 ms instead of 33 ms, with the same result, bit for bit:

import os
from concurrent.futures import ThreadPoolExecutor

pool = ThreadPoolExecutor()  # make it once, and reuse it for every layer

def linear(q, x):  # x has shape (batch, columns)
    # a piece per core, or pieces of 64 rows for a big batch, which stay in a core's cache
    pieces = np.array_split(x, max(os.cpu_count(), len(x) // 64))
    return np.concatenate(list(pool.map(q.matmul, pieces)))

out = linear(q, x)

with a gil, while another thread keeps running python, each piece can wait up to sys.getswitchinterval(), 5 ms by default, to get the gil back, so splitting pays off only while your other threads are idle or in native code, or on free-threaded python. dequantize, dot, and matmul on 65,536 values or fewer, like one vector times a 256 × 256 matrix, keep the gil, so they don't wait. quantizing and refitting keep it only up to 4,096 values, so threads can quantize a model's layers in parallel.

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.4.0

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.4.0
File Size Uploaded
quantize_py-0.4.0.tar.gz 104.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for quantize-py 0.4.0
File
quantize_py-0.4.0-cp314-cp314t-win_amd64.whl CPython 3.14 CPython 3.14 free-threading Windows x86-64 Details
quantize_py-0.4.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ x86-64 Details
quantize_py-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ ARM64 Details
quantize_py-0.4.0-cp314-cp314t-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64 Details
quantize_py-0.4.0-cp314-cp314t-macosx_10_12_x86_64.whl CPython 3.14 CPython 3.14 free-threading macOS 10.12+ x86-64 Details
quantize_py-0.4.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
quantize_py-0.4.0-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.4.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.12 abi3 Linux glibc 2.17+ ARM64 Details
quantize_py-0.4.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
quantize_py-0.4.0-cp312-abi3-macosx_10_12_x86_64.whl CPython 3.12 abi3 macOS 10.12+ x86-64 Details

Total release size: 4.7 MB

Release files / quantize_py-0.4.0.tar.gz

Download URL quantize_py-0.4.0.tar.gz
Size 104.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b58656de9f6fc1047d6cc052407427bc13e55051534a4b54b7e3f66e8a471f5c
BLAKE2b-256 checksum
How to use checksums
5fe0ff87f7d583cde5596cec8ea34936ce7cce653ea33e0d215e94311096d0a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp314-cp314t-win_amd64.whl

Download URL quantize_py-0.4.0-cp314-cp314t-win_amd64.whl
Size 341.9 kB
Tags CPython 3.14 CPython 3.14 free-threading Windows x86-64
SHA-256 checksum
How to use checksums
06991fcf3f0c2beb39d292d51835659f986b57ef23df7f82aaa9d851ba94d36c
BLAKE2b-256 checksum
How to use checksums
ab63f0083d0a9da28fd60cec585631f550979202984ef57fc83d322d2701efb8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL quantize_py-0.4.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 504.9 kB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
8ef02f3a245767ad60e623e043816b7678f410d6abf222ff9e16a7dbef9daaba
BLAKE2b-256 checksum
How to use checksums
5c61264bbb490e87d528a293d24ba8dbcb28db3ca211abb73d2139a2e476982a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL quantize_py-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 495.8 kB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ ARM64
SHA-256 checksum
How to use checksums
182230c0c1b16096cfd252522109aa9c685b389b39d8bedca9c77d96f6d1444e
BLAKE2b-256 checksum
How to use checksums
1e30ed876a27819ee368d77ad1cb01dff298c2c2372c3a879903ef917efdb5da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp314-cp314t-macosx_11_0_arm64.whl

Download URL quantize_py-0.4.0-cp314-cp314t-macosx_11_0_arm64.whl
Size 446.5 kB
Tags CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a2b8253a8fb319076656e31cd411440d4150e72875e9da56b3ac6e89714a998c
BLAKE2b-256 checksum
How to use checksums
374df4923beb6b1dffaccc02759b816b9a4a7eb7027597717c0bf7af331f71dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp314-cp314t-macosx_10_12_x86_64.whl

Download URL quantize_py-0.4.0-cp314-cp314t-macosx_10_12_x86_64.whl
Size 465.0 kB
Tags CPython 3.14 CPython 3.14 free-threading macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
887662faec0445ad562924f4de08a36c280880708cd70c0009ee72f2bff3d1b3
BLAKE2b-256 checksum
How to use checksums
39adb05949313b017751d3c993ef10ae75eac7f0cc34ea914c01981aa391b55b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp312-abi3-win_amd64.whl

Download URL quantize_py-0.4.0-cp312-abi3-win_amd64.whl
Size 356.5 kB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
b77ee4266cf683eb412d7bb8faa9683fada964b6e42e88642e9ac5d719abcc92
BLAKE2b-256 checksum
How to use checksums
88f588da8a6304bdee5c237db358339c857734cf723fe6975717bd8c53c83da6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL quantize_py-0.4.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 518.2 kB
Tags CPython 3.12 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
2915c51d9b8b1f706e6eae5f6aece0991ab0d41ec988efb75964c0ee16dd08af
BLAKE2b-256 checksum
How to use checksums
9a1f45a9d3512556030cde15d6777a371f41a7730186fd721bda32243983f0b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL quantize_py-0.4.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 506.2 kB
Tags CPython 3.12 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
ced2917fc2b5a14c47d5400b2e0e4869e71fbad71d92e6b410e4c45f5370df0e
BLAKE2b-256 checksum
How to use checksums
aafde3526dd4b0fc1b21a54aeaf0221af1f03beeaacca5584e1f4a9cbf5d1582
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL quantize_py-0.4.0-cp312-abi3-macosx_11_0_arm64.whl
Size 457.0 kB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
36b4762d0c97f02a4b6dc2e3762e3bf7a9579a3fae9d4ae0979a2dd86f2ffb60
BLAKE2b-256 checksum
How to use checksums
280501163f99307e0e8a3d0748e706a30e1120f4cc13be0c1ba038a2d2264237
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0-cp312-abi3-macosx_10_12_x86_64.whl

Download URL quantize_py-0.4.0-cp312-abi3-macosx_10_12_x86_64.whl
Size 479.3 kB
Tags CPython 3.12 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
bc21fc29bb861ad488edf8cdf796aea681f172996d9e3af8d4cae9565cd9a2e8
BLAKE2b-256 checksum
How to use checksums
1b0978a32e4bda4d6bd5634276c72614f8216f93d3cb2047527148f8d62387da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","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.4.0 This release

11 release files

0.3.1

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