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

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.2
File Size Uploaded
quantize_py-0.3.2.tar.gz 96.6 kB Details

Built distributions (wheels)

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

Total release size: 4.6 MB

Release files / quantize_py-0.3.2.tar.gz

Download URL quantize_py-0.3.2.tar.gz
Size 96.6 kB
Tags Source
SHA-256 checksum
How to use checksums
574842f87cf4fcd81bf8dd08e3237a1b90f9700756a3afc8be931d0a361f3927
BLAKE2b-256 checksum
How to use checksums
ddb682a5e65fd0beaaa3398b51c3b682f40242428abb6b3201a899bfb14c3669
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.2-cp314-cp314t-win_amd64.whl

Download URL quantize_py-0.3.2-cp314-cp314t-win_amd64.whl
Size 338.5 kB
Tags CPython 3.14 CPython 3.14 free-threading Windows x86-64
SHA-256 checksum
How to use checksums
308d4e86b6f12c712fc94c410c7ceed7c4aec86682cf59348853241c0e2d5a9f
BLAKE2b-256 checksum
How to use checksums
47f45ffbc6149ce0f1c3b6cb720d7d3ee52c31bc3aadf8c1bb8a5c4d47b3fa77
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.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL quantize_py-0.3.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 500.8 kB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
f72e3dae33f9db98389391235cedae5cef17082c7bbac645774880f1e368597c
BLAKE2b-256 checksum
How to use checksums
0cf14c21772527a617527689d3ecccdf4c47566df1c430db3dca524c673b9c74
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.2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL quantize_py-0.3.2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 492.1 kB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ ARM64
SHA-256 checksum
How to use checksums
96b0c580aaa0bca9d64132af05e0db7e54aaf454fa23533fd7027db926fa2a24
BLAKE2b-256 checksum
How to use checksums
f255d62d1f44768f801d140f385b00b0be3bbc713b9cdd35d3eaa1af7b287f55
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.2-cp314-cp314t-macosx_11_0_arm64.whl

Download URL quantize_py-0.3.2-cp314-cp314t-macosx_11_0_arm64.whl
Size 440.5 kB
Tags CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c87bd6c80b1ffa258b7e8d4ca5e3c39cc9696a60293993d13aa8c71954e80bb2
BLAKE2b-256 checksum
How to use checksums
b1206e334114bcc51443021198a0e9488fde0b7c32a9c47bb94cc2270d675ce8
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.2-cp314-cp314t-macosx_10_12_x86_64.whl

Download URL quantize_py-0.3.2-cp314-cp314t-macosx_10_12_x86_64.whl
Size 459.0 kB
Tags CPython 3.14 CPython 3.14 free-threading macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
88115f82ed620d19b6cdbd7b24e70001750eac035c3e234e69422df7cb61a0d6
BLAKE2b-256 checksum
How to use checksums
81adaea4421f3f005dbd300a501127c24e264ef6bbdf429b2699781641cf1ab1
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.2-cp312-abi3-win_amd64.whl

Download URL quantize_py-0.3.2-cp312-abi3-win_amd64.whl
Size 352.4 kB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
4af794b17fee5ec3bb2a50741c6fdee4ebaebb2a74353bfd22f0440b9a81a588
BLAKE2b-256 checksum
How to use checksums
9cb71803d1588a2abf5fbd0142feef481b512dd98f8a2a0b6b6207a878c8053e
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.2-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL quantize_py-0.3.2-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 513.4 kB
Tags CPython 3.12 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
8a0a715ea1892a46d426ccd8bff1d90e631590b4f11f87ffd4a58625d848a131
BLAKE2b-256 checksum
How to use checksums
9409123e406a29ec856187c7d4d0283ede8c577a53c4ecdbc1e1f7d4441fb98f
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.2-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL quantize_py-0.3.2-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 503.8 kB
Tags CPython 3.12 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
0ec543cdcd17f43d320b257c2115804542691fa124fdcdb9c8e59905920d6942
BLAKE2b-256 checksum
How to use checksums
2516d6cc1de7194acffee123f02c02a76c86ab64f01844aa4daae30c4580a7d7
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.2-cp312-abi3-macosx_11_0_arm64.whl

Download URL quantize_py-0.3.2-cp312-abi3-macosx_11_0_arm64.whl
Size 453.5 kB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b2e100812e81e1539d0372fd5fe08baa292db281f8be3f2365e31768739436d8
BLAKE2b-256 checksum
How to use checksums
6f6c996acf632772374c35a7f135783e19f2f8236e4d900b3bbd33b6a2f0b497
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.2-cp312-abi3-macosx_10_12_x86_64.whl

Download URL quantize_py-0.3.2-cp312-abi3-macosx_10_12_x86_64.whl
Size 473.2 kB
Tags CPython 3.12 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
43b9bec59a95bcc53bad5e36bc5bac23c162e0d9990877a55986c4433b0adb48
BLAKE2b-256 checksum
How to use checksums
777ec9d99cbdfd7055ef5c3b3a64918557a9fbe4b49cc543049c5342e75beca1
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.2 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