Skip to main content

PTWM: lossless compression for PyTorch model weights.

Project description

PTWM

PyPI Python License: MIT CI

A lossless compression library for PyTorch model weights. PTWM exploits the byte-level structure of IEEE 754 floats and the layout of microscaling formats (MXFP4 / NVFP4) to recover compression that generic codecs leave on the table, with fast parallel encode and decode through a native Rust extension.

The output format, .ptwm, is a multi-tensor container with random-access lookup, hash-verified payloads, and per-tensor codec dispatch.

Benchmarks live under docs/benchmarks/; design docs live under docs/architecture/.

What this library does and does not do

Workload Expected ratio Recommendation
bfloat16 / float16 / float32 weights ≈ 0.55–0.75 Use PTWM. Exponent-plane separation is the right tool.
float8_e4m3fn / float8_e5m2 weights ≈ 0.70–0.85 Use PTWM. Nibble-split + plane-aware Huffman.
MXFP4 weights (FP4 nibbles + E8M0 scales) ≈ 0.86–0.90 The main win is the random-access container, not the raw ratio: the nibble plane is already near the byte-level entropy floor.
NVFP4 weights (FP4 nibbles + FP8-E4M3 scales) ≈ 0.90 Same caveat as MXFP4: the FP4 nibble plane is near-uniform and dominates the size.
Already-compressed data (PNG, ZIP, encrypted) ≈ 1.0 No codec helps.

Microscaling formats already sit near the entropy floor at the byte level, so no general-purpose lossless codec extracts more than a few percent from them. See docs/benchmarks/README.md for the benchmark numbers.

How it works

Neural network weights have a hidden structure: trained exponents cluster around a narrow range while mantissa bits are near-random. PTWM exposes this structure through a typed preprocessing graph (PPG) before entropy coding.

1. Bit reorder. IEEE 754 floats place the sign bit between the exponent and mantissa, straddling a byte boundary. The bit reorder shifts the exponent to the most-significant position with the sign tucked below it.

For float32 and bfloat16 (8-bit exponent), the exponent occupies a full byte after reorder:

IEEE 754 fp32:  [S EEEEEEEE MMMMMMMMMMMMMMMMMMMMMMM]
After reorder:  [EEEEEEEE S MMMMMMMMMMMMMMMMMMMMMMM]

For float8_e4m3fn and float8_e5m2 (4–5 bit exponent), the reorder moves the exponent into the high nibble of each byte:

FP8-E4M3FN:    [S EEEE MMM]
After reorder: [EEEE SMMM ]   ← exponent in high nibble

2. Byte / nibble split. The split deinterleaves the reordered data into separate planes. Each plane is entropy-coded independently, using whichever of Huffman, rANS, or Zstd compresses smaller, except the NVFP4 scale plane, which gets a dedicated arithmetic coder tuned to its scale distribution (see the dtype table below).

  • float32: 4-plane round-robin byte split (plane 3 = exponent)
  • float16 / bfloat16: 2-plane byte split (plane 1 = exponent)
  • float8_e4m3fn / float8_e5m2: 2-plane nibble split (plane 0 = exponent nibbles)
  • float4_e2m1fn_x2 (MXFP4 / NVFP4): nibble-pair split for the weight plane; the paired E8M0 (MXFP4) or FP8-E4M3 (NVFP4) scale tensor is a separate plane

The exponent plane typically holds only ~20 unique values out of 256 (~2.6 bits/byte entropy on real-world trained weights), while mantissa planes look near-random. Nearly all the compression savings on float weights come from the exponent plane. Microscaling formats flip the picture: nibble bytes are near-uniform, and almost all the savings come from the scale plane.

The two-step decomposition is a standard byte-shuffle preprocessing step, plus a bit-reorder step that cleanly separates the exponent from the sign. Without it, the sign contaminates the exponent byte.

Contents

Installation

pip install ptwm

Requires Python ≥ 3.12 and PyTorch ≥ 2.6. If you need a specific PyTorch build (CPU-only, a particular CUDA version), install it from the appropriate PyTorch index before or alongside ptwm.

Quickstart

import torch
from ptwm import Compressor, Decompressor, CompressionConfig, Format

config = CompressionConfig(input_format=Format.TORCH)
compressor = Compressor(config)
decompressor = Decompressor()

# float32 / bfloat16 / float16
tensor = torch.randn(1024, 1024, dtype=torch.bfloat16)
restored = decompressor.decompress(compressor.compress(tensor))
assert torch.equal(tensor, restored)

# float8: automatic nibble split (exponent / mantissa planes)
fp8 = torch.randn(1024, 1024).to(torch.float8_e4m3fn)
restored_fp8 = decompressor.decompress(compressor.compress(fp8))
assert torch.equal(fp8.view(torch.uint8), restored_fp8.view(torch.uint8))

# float4 (MXFP4 / NVFP4 packed weights, PyTorch ≥ 2.6).
# When paired with their FP8 / E8M0 block scales (via the same model),
# the .ptwm container routes each through the appropriate codec.
if hasattr(torch, "float4_e2m1fn_x2"):
    fp4 = torch.randint(0, 256, (512, 512), dtype=torch.uint8).view(torch.float4_e2m1fn_x2)
    restored_fp4 = decompressor.decompress(compressor.compress(fp4))
    assert torch.equal(fp4.view(torch.uint8), restored_fp4.view(torch.uint8))

For multi-tensor models, use the safetensors integration below; it emits a single .ptwm container with random-access tensor lookup.

CLI

The ptwm command-line tool compresses and decompresses files. Compressed output uses the .ptwm suffix.

Compress a .safetensors model (single multi-tensor .ptwm file):

ptwm compress model.safetensors
# produces model.safetensors.ptwm

Compress any other file:

ptwm compress model.bin
# produces model.bin.ptwm

Compress every .safetensors file in a directory:

ptwm compress /path/to/model/

Decompress:

ptwm decompress model.safetensors.ptwm
# restores model.safetensors

Delta compression (compress relative to a reference file):

ptwm compress model_v2.safetensors --delta model_v1.safetensors

Tune chains for a specific model (extends the production chain set with explorer-discovered candidates; discovered chains are stored inline in the output and decode on any PTWM install):

ptwm compress model.safetensors --explore --out model.ptwm/
ptwm chains cache info        # inspect cached discoveries
ptwm chains export bundle     # share a tuned chain set
ptwm chains import bundle     # adopt a peer's chain set

Run ptwm compress --help or ptwm decompress --help for the full option list.

Python API

from ptwm import (
    Compressor, Decompressor,
    CompressionConfig, DecompressionConfig,
    Method, Format,
)

# Compress raw bytes (dtype hint required for byte-reordering)
config = CompressionConfig(
    method=Method.AUTO,           # AUTO, HUFFMAN, RANS, ZSTD, IDENTITY, or MICROSCALE
    input_format=Format.BYTE,     # BYTE, TORCH, NUMPY, or FILE
    bytearray_dtype="bfloat16",   # dtype hint for byte-reordering (BYTE format only)
    threads=8,                    # parallelism (default: up to 16 cores)
)
compressor = Compressor(config)
compressed: bytes = compressor.compress(data)

# Decompress: the return type (bytes / torch.Tensor / np.ndarray) is
# recovered automatically from metadata embedded at compress time.
decompressor = Decompressor(DecompressionConfig(threads=8))
restored: bytes = decompressor.decompress(compressed)

AUTO (the default) runs the full per-plane trial-encode: every codec candidate for the tensor's dtype and plane roles competes, and the smallest result wins. HUFFMAN, RANS, ZSTD, and IDENTITY force that one codec instead of trial-encoding. MICROSCALE routes MXFP4 / NVFP4 paired tensors through the dedicated scale-plane codec (the weight-nibble plane still trial-encodes).

Random access

from ptwm.random_access import TensorIndex

idx = TensorIndex.open("model.safetensors.ptwm")
weight = idx.get_tensor("layer_5.weight")
for name, tensor in idx.stream_tensors(["embed.weight", "lm_head.weight"]):
    ...

The container's tensor index is small (a manifest of name → offset records), so opening a bundle and fetching one tensor touches only that tensor's bytes.

Integrations

Everything below lives in ptwm.integrations, imported explicitly. Nothing here is re-exported from the top-level ptwm package.

Safetensors

SafeOpen is a drop-in replacement for safetensors.safe_open: same interface (keys(), get_tensor(), context manager), transparently reading .ptwm containers, .safetensors shells wrapping a .ptwm blob, and legacy per-tensor-compressed .safetensors files.

from ptwm.integrations import SafeOpen

with SafeOpen("model.safetensors", framework="pt") as f:
    tensor = f.get_tensor("weight")

HuggingFace Transformers

Decompress a cached snapshot once, then load with plain transformers. No patching is active during the actual model load:

from huggingface_hub import snapshot_download
from ptwm.integrations import materialize_hf_cache

snapshot_dir = snapshot_download("org/model-name")
materialize_hf_cache(snapshot_dir)

from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(snapshot_dir)

Monkey-patching (when you don't control the call site)

If third-party code calls safetensors.torch.safe_open or transformers.modeling_utils.load_state_dict internally, so you can't swap in SafeOpen or run materialize_hf_cache first, both integrations have an opt-in patch that installs transparent .ptwm support into the target library for the lifetime of the process:

from ptwm.integrations import patch_safetensors
patch_safetensors()
from ptwm.integrations import patch_transformers
patch_transformers()

Configuration

A few CompressionConfig options beyond the ones shown above:

Option Default Description
compression_threshold 0.95 Skip compression and store raw bytes if the achieved ratio exceeds this (not worth the container overhead)
codec_menu None (full menu) Restrict per-plane trial-encode to a specific CodecId list, e.g. for ablations
is_streaming / streaming_chunk False / 1048576 (1 MiB) Encode a large tensor as independently-decodable chunks instead of one pass

CompressionConfig also has delta-compression and lossy-compression fields; see its docstring for the full list.

Supported dtypes

PyTorch dtype Strategy Notes
float32 Bit reorder + 4-plane byte split Exponent → plane 3
bfloat16 / float16 Bit reorder + 2-plane byte split Exponent → plane 1
float8_e4m3fn / float8_e5m2 Bit reorder + 2-plane nibble split Exponent → high nibble
float4_e2m1fn_x2 (weight nibbles) Passthrough, per-plane trial-encode PerGroupCodebook competes against Huffman / rANS on the nibble-packed byte stream
MXFP4 scale (uint8, E8M0) Passthrough, per-plane trial-encode Pure 8-bit exponent with no row structure to exploit; compresses to ≈ 0.16 of original via the generic codec menu
NVFP4 scale (FP8-E4M3) Order1ScaleAC (per-row lag-1 arithmetic coding) Mantissa bits give exploitable row autocorrelation that E8M0 lacks
int8, uint8, int16, int32, int64, bool Single stream No byte split or bit reorder yet; whatever wins per-plane trial-encode on the raw bytes

MXFP4 / NVFP4 tensors are compressed as a pair: the packed FP4 weight nibbles (float4_e2m1fn_x2) and their block-scale tensor (E8M0 for MXFP4, FP8-E4M3 for NVFP4) are two separate planes with the codec choices above.

Extensions

PTWM has a native multi-language extension system. New codecs, preprocessing transforms, classifiers, scoring functions, and more can be added as separate signed bundles in WASM, native cdylib, or Python host form, without modifying PTWM core.

Researchers

pip install ptwm[ext-dev]
ptwm ext init my-codec --lang rust --kind plane_codec
cd my-codec
ptwm ext build
ptwm ext sign --key ~/.ptwm/keys/mykey.priv
ptwm ext pack

Operators

ptwm trust add --bundled                   # one-time consent to the bundled keyring
ptwm ext install ./my-codec-0.1.0.tar.zst  # or https://, oci://, git+SHA, or pip name
ptwm ext list                              # confirm

Ablation

ptwm bench compress model.bin \
    --baseline policies/baseline.toml \
    --variant policies/no-huffman.toml \
    --trials 3 --out bench-out/
ptwm bench attribute model.bin --leave-one-out --out attr-out/

Repository layout

  • crates/ptwm-core/: Rust library for the preprocessing graph, entropy coders, and container format.
  • crates/ptwm-py/: PyO3 bindings that build the ptwm._core native extension module.
  • python/ptwm/: the Python package, covering the API, CLI, and integrations (HuggingFace transformers, safetensors).
  • extensions/: reference implementations for the extension system, one per contribution kind.
  • docs/architecture/: design docs covering the wire format, preprocessing graph, codec dispatch, extension system, and trust model.
  • docs/benchmarks/: benchmark results and per-feature CSVs.
  • tests/: the pytest suite.
  • benchmarks/: manual performance and validation harnesses.
  • fuzz/: cargo-fuzz targets for the container format and entropy coders.

Development

The development environment lives in pyproject.toml + uv.lock, driven by uv.

Prerequisites:

  • Python ≥ 3.12 (build supports 3.12 and 3.13)
  • A stable Rust toolchain (rustc, cargo) for building the ptwm._core native extension
  • uv

Install the prerequisites via your system package manager or rustup. uv can provision a matching Python (uv python install 3.13) if your system lacks one. Then:

uv sync --dev
source .venv/bin/activate

Pre-commit hooks. Prek manages the hook set:

uv tool install prek
prek install
prek run --all-files

Benchmarks

docs/benchmarks/README.md summarises the benchmark numbers on representative real-world models, and the same directory holds per-feature CSVs (ablations, plane entropy, codec comparison across the library's own methods, random-access overhead).

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ptwm-1.0.0.tar.gz (473.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ptwm-1.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

ptwm-1.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (10.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

ptwm-1.0.0-cp313-cp313-macosx_11_0_arm64.whl (9.1 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

ptwm-1.0.0-cp313-cp313-macosx_10_12_x86_64.whl (9.0 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

ptwm-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

ptwm-1.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (10.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

ptwm-1.0.0-cp312-cp312-macosx_11_0_arm64.whl (9.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

ptwm-1.0.0-cp312-cp312-macosx_10_12_x86_64.whl (9.0 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

File details

Details for the file ptwm-1.0.0.tar.gz.

File metadata

  • Download URL: ptwm-1.0.0.tar.gz
  • Upload date:
  • Size: 473.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for ptwm-1.0.0.tar.gz
Algorithm Hash digest
SHA256 86cf36935295af8f9aff0d2962e9e7f87f245d194c1af01ad665f722f79eb27b
MD5 319b504bc45471cdfd00e6837b34ec95
BLAKE2b-256 5bd085160895b0ec2c45fd56726d83b508d2dd7edec7d4aaf805be7ed9f8600e

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptwm-1.0.0.tar.gz:

Publisher: release.yml on khwstolle/ptwm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ptwm-1.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ptwm-1.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 027a5acf0102ec984fb170ae67775d06f33b1c7eb1f13015a695466465e6ea11
MD5 e7da32b6ee159b8ef331a29f8ae0bf79
BLAKE2b-256 023068a862f0450d842e3db6b60070115bc0603a41472d75a1cd6eac28ada068

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptwm-1.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on khwstolle/ptwm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ptwm-1.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for ptwm-1.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d3e1419cc6d7002429f84f8548f93ca3643e9720d4e4097bd3a2f55c1a6260ef
MD5 bd440353fd033fe5d59d0c19e7525c1d
BLAKE2b-256 4965eaf679ba08a1615e2806a5f6be2e97f89a4fab375fc71f0229282eaa270a

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptwm-1.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on khwstolle/ptwm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ptwm-1.0.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ptwm-1.0.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a0add124603ab2044d3b7cf90e0471810e11a476893de8521e4945f5b17d0a92
MD5 e5624d795e97c6f10536ddd45ad6cd4e
BLAKE2b-256 c9f244dd91f1cc6329d8651c739d3078fe020cddb694bcf517b5e6215e1a04e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptwm-1.0.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on khwstolle/ptwm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ptwm-1.0.0-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ptwm-1.0.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 fbca71e866bdc69f30b7431384e63b682f5f239c987c38e6c2a72e9b1b8d2738
MD5 26e482b2023a736076f80d329dee699b
BLAKE2b-256 d29cd6d11098e167061609188ddcb2075c0c417c5664e4099ab891c6a054ca03

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptwm-1.0.0-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: release.yml on khwstolle/ptwm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ptwm-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ptwm-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7a5646f71ed862d8be9fc7206ae8813c66fec53f0c8afe02513d35979e5e0562
MD5 17d57dbfb0acb947fa17d5fa042dd1f7
BLAKE2b-256 4297ca46630a10f8b95d69aea762f50a15160129d46a2a16b0d5573b9ac6f74c

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptwm-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on khwstolle/ptwm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ptwm-1.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for ptwm-1.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 baacfe10f054ae1b81a3adabf614203749abb3cc47bc91e7009c3693b00db7be
MD5 ee2ee807fb968e4a96ae93a9583ea41a
BLAKE2b-256 928b900e4f16f3f725dddc49304bcfb8ec06cdf0e987a31d2cf89189ec9147b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptwm-1.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on khwstolle/ptwm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ptwm-1.0.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ptwm-1.0.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ceeaa5e559f17e37d50acf7893298d5daa819c552684720aa8276bcb34aa30aa
MD5 8df4d0ddae882009bc1821c235d04ae1
BLAKE2b-256 a5667c7e6a9f22c8af39887c7300a9883973d4908d5adba935f3815a47083980

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptwm-1.0.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on khwstolle/ptwm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ptwm-1.0.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ptwm-1.0.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 2b5879ee53b074af0f8bc80767643b93426266161229031bea9678cb36cd97d1
MD5 f841a39a452bd1686b56e036430ae2f5
BLAKE2b-256 ffb2cc663a7e3353d85a434216068d7dd4bce3cfccfe6670363808d21a9a3954

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptwm-1.0.0-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on khwstolle/ptwm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page