compressr

App New

Model conversion and quantization with no Python: reads SafeTensors, GGUF, TCF and PyTorch state dicts, writes SafeTensors, GGUF and TCF, and quantizes to Q2_K through Q8_0 and IQ4 formats, including Q4_K_M mixes. GPTQ, AWQ, NF4, FP8, EXL2 and ONNX input are not implemented.

Checked · Sources

Downloads
23
Dependents
Not applicable
Stars
0
Forks
0
Contributors
1
Commits
63
Latest release
0.2.1 ·

About

From the project README ·

GGUF quantization and model conversion for LLM checkpoints, in Rust.

Converts SafeTensors, GGUF, TCF, and PyTorch checkpoints to GGUF, TCF, or SafeTensors, and quantizes to GGUF block formats. It reads one tensor at a time.

Status · Options · Example · Contributing

compressr is a Rust CLI and library. It converts LLM checkpoints between formats, casts their element type, and quantizes them into GGUF block formats. It writes the GGUF header that llama.cpp's convert_hf_to_gguf.py writes, for the architectures listed under GGUF headers.

  • Language: the conversion path is Rust. It needs no Python. The optional python feature builds a PyO3 module that exports __version__ only.
  • Hardware: CPU only. There is no GPU path.
  • Built on: boostr holds the kernels and block layouts. compressr handles file I/O, planning, and the command line.
  • Used for: models that blazr serves.
  • Not supported yet: GPTQ, AWQ, EXL2, NF4, FP8, ONNX input, sharded PyTorch input, and PyTorch F16 and BF16 tensors. See Status.

Status

Implemented:

Read the full README
CapabilityDetail
SafeTensors inputSingle file, or sharded via model.safetensors.index.json
GGUF inputRead back for re-conversion
TCF inputRead back, verified and decoded, through boostr's reader. Used for info and for conversion to another format
PyTorch inputOne .pt, .pth, or .bin state dict with F32, F64, I32, or I64 tensors, as a file or as pytorch_model.bin in a directory. Sharded PyTorch and ONNX input are refused
Explicit input formatConversionConfig::input_format skips auto-detection. compressr checks the input's content against it and errors on a mismatch
VoxCPM2 companionA safetensors directory with architecture voxcpm2 folds its audio VAE into the output under vae.. Float tensors are stored as F32
SafeTensors outputSharded at --max-shard-size, with a matching index
GGUF outputGGUF v3, one self-contained file
GGUF header from a HuggingFace checkpointHyperparameters, RoPE keys, and tokenizer metadata under llama.cpp's key names. See GGUF headers
TCF outputTCF v1, one self-contained file. Takes every --quantization method and mix
dtype castF32, F16, BF16, round-to-nearest-even. A block-quantized input tensor is decoded first
GGUF quantizationQ4_0, Q4_1, Q8_0, Q2_K, Q3_K, Q4_K, Q5_K, Q6_K, IQ4_NL, IQ4_XS
GGUF mixed precisionQ4_K_S, Q4_K_M, Q5_K_S, Q5_K_M, using llama.cpp's per-tensor allocation
Measured allocation--sensitivity ranks mix promotions by measured task damage per element
Importance matrix--imatrix weights quantizer choices by calibration activations. Off by default
Lowbit repackpq2_0 from a PTQ1_0 GGUF, ptq1_0 from a PQ2_0 GGUF. Codes and scales move between layouts. No value rounds
GGUF header carryA GGUF input's key-value pairs are written whole into a GGUF output
Sidecar copyingTokenizer and config files follow the weights
Conversion reportThe format of every tensor, and the measured bits per weight

Roadmap. Each capability below has an enum variant. compressr refuses each one before it creates an output file:

CapabilityWhat is missing
GPTQ, AWQCalibration, plus the qweight/scales/qzeros/g_idx tensor layout
NF4, FP8An on-disk home for the side-band scales the packed payload omits
EXL2The whole format driver
ONNX inputThe .onnx reader
Sharded PyTorchA pytorch_model.bin.index.json walk. One .bin per model today
PyTorch F16, BF16boostr's .pt reader decodes F32, F64, I32, and I64 only
Python APIThe PyO3 module exports __version__ only
Triple-buffered I/OA prefetch, compute, and write pipeline. Reads and writes are serial
Parallel shard I/OReads and writes are sequential
Q2_K/Q3_K and IQ mixes, other I-quantsMix rules for Q2_K and Q3_K, and boostr writers for IQ2, IQ3, IQ1 formats. The mixes q2_k_s, q3_k_s, q3_k_m, and q3_k_l are refused by name. Flat q2_k and q3_k are written

The optimize subcommand takes --method only. It always errors and writes no file. Every method it names (GPTQ, AWQ, EXL2, NF4, FP8) is on the roadmap. A flat GGUF method passed to it is refused with the convert command that writes it.

SafeTensors output is never quantized. Block quantization writes GGUF, or TCF with --format tcf.

TCF comes from a full-precision checkpoint only. A GGUF or TCF input is refused for TCF output.

Quick Start

compressr needs a Rust toolchain. Cargo.toml takes boostr from crates.io. A checkout beside unreleased sibling crates needs the local build overrides first. The file is gitignored.

cp .cargo/config.toml.example .cargo/config.toml
cargo install --path .

compressr runs every boostr kernel on the CPU. It has no GPU path.

Convert a checkpoint to a quantized GGUF file:

compressr convert ./llama-3-8b --format gguf --quantization q4_k_m

Cast a checkpoint to BF16 SafeTensors:

compressr convert ./llama-3-8b --format safetensors --dtype bf16

Inspect a checkpoint:

compressr info ./llama-3-8b            # format, tensor count, size, metadata
compressr info ./llama-3-8b --verbose  # one line per tensor
compressr info ./llama-3-8b --summary  # tensor count and size only

Usage

Quantization

--quantization takes these flat formats: q4_0, q4_1, q8_0, q2_k, q3_k, q4_k, q5_k, q6_k, iq4_nl, and iq4_xs. It also takes the lowbit repack names pq2_0 and ptq1_0.

A mixed-precision name assigns different GGUF block formats to different tensors. The mix names are q4_k_s, q4_k_m, q5_k_s, and q5_k_m. The mix reproduces llama.cpp's per-tensor allocation by role and layer.

--quantization and --dtype are mutually exclusive. Quantization already fixes the stored representation.

Measured sensitivity and importance matrices

--sensitivity FILE reads measured task deltas as JSON lines. It requires a mixed-precision --quantization and --format gguf or --format tcf. The promotions of the mix are ranked by measured damage per element. They spend the same bytes that llama.cpp's rules spend on the checkpoint. Tensors whose rows are not a whole number of 256-element super-blocks cannot be promoted. compressr counts and reports them.

--imatrix FILE reads an importance matrix from boostr's imatrix example. It weights each quantizer choice by the mean squared activation of each input column. A conversion without the flag writes the same bytes it always wrote. --imatrix works with --format gguf or --format tcf, and with K-quants, iq4_nl, iq4_xs, and K-quant mixes. A tensor the matrix does not measure is quantized without weights.

compressr convert ./llama-3-8b --format tcf --quantization q4_k_m --sensitivity llama.sens.jsonl
compressr convert ./llama-3-8b --format gguf --quantization q4_k_m --imatrix llama.imatrix
Lowbit repack
compressr convert model-PTQ1_0.gguf --format gguf --quantization pq2_0
compressr convert model-PQ2_0.gguf --format gguf --quantization ptq1_0

PTQ1_0 and PQ2_0 store the same ternary codes in two block layouts. A repack moves the codes and scales of each source tensor, and it rounds nothing. Tensors already in the target format, float norms, and other types pass through. A PQ2_0 block that holds code 3 has no trit, so ptq1_0 refuses it. The error names the tensor and block. Neither format is quantized from float weights. A SafeTensors or F16 input is refused.

Output shards
compressr convert ./llama-3-8b --format safetensors --dtype bf16 --max-shard-size 2GB
compressr convert ./llama-3-8b --format safetensors --dtype bf16 --max-shard-size none

SafeTensors output over the limit becomes model-00001-of-000NN.safetensors shards plus model.safetensors.index.json. Output under the limit stays one model.safetensors with no index. A tensor is never split, so a tensor larger than the limit gets a shard of its own. The flag takes a byte count, a decimal suffix (5GB, 500MB), or a binary suffix (1GiB, 512MiB). The default 5GB matches HuggingFace. GGUF ignores the flag.

Input resolution

A directory with a model.safetensors.index.json loads exactly the shards that index names. Other .safetensors files beside them, such as a LoRA adapter or an earlier conversion's output, are ignored.

A directory with shards and no index loads every .safetensors file in name order.

GGUF headers from HuggingFace checkpoints

For a HuggingFace checkpoint, compressr writes the GGUF header that convert_hf_to_gguf.py writes. The architecture comes from model_type in config.json, then architecture, then the first entry of architectures. Pass --arch when the checkpoint names none.

Architecture (model_type)general.architectureTensor names
llama, mistral, mixtralllamallama.cpp's, Q/K rows reordered
qwen2, qwen3as namedllama.cpp's
qwen2_moe, qwen3_moe, gemma, gemma2, gemma3, phi3qwen2moe, qwen3moe, or as namedHuggingFace's
  • Hyperparameters: context length, embedding length, block count, feed-forward length, head counts, and the norm epsilon. It also writes .rope.* keys with scaling, expert counts, and key and value lengths when head_dim is stated. A key whose config.json field is absent is omitted.
  • RoPE tensors: llama3 scaling writes rope_freqs.weight. LongRoPE writes rope_factors_long.weight and rope_factors_short.weight.
  • Tokenizer: tokenizer.model gives tokenizer.ggml.model = "llama". A byte-level BPE tokenizer.json gives "gpt2", with merges and a tokenizer.ggml.pre name from llama.cpp's fingerprint table. An unknown fingerprint omits pre and logs a warning. Special ids, add-token flags, and tokenizer.chat_template follow llama.cpp.
  • Q/K order: llama.cpp's llama architecture rotates adjacent pairs. compressr reorders q_proj and k_proj rows to match. boostr's GGUF loader restores them.
  • HuggingFace names: the architectures in the last row keep HuggingFace tensor names. llama.cpp's converter changes their values: Gemma norms, Phi-3 fused projections, and merged MoE experts. llama.cpp cannot load those files.

Options

compressr convert <INPUT>
FlagDefaultEffect
--formatrequiredgguf, safetensors, or tcf. Other values are roadmap items and fail
-o, --outputderived from inputOutput file, or checkpoint directory. Defaults to <INPUT>.gguf or <INPUT>-<dtype>
--quantizationnoneGGUF block format or mix. Repack name for a lowbit GGUF. Not used with --dtype
--dtypenoneCast target: f32, f16, or bf16
--max-shard-size5GBShard limit for SafeTensors output, or none
--sensitivitynoneMeasured sensitivity JSON lines. Needs a mixed-precision quantization
--imatrixnoneImportance matrix from boostr's imatrix example
--archfrom config.jsonValue written to GGUF general.architecture
-v, --verboseoffLog every tensor as it is processed
compressr info <MODEL>
FlagEffect
-v, --verbosePrint one line per tensor
-s, --summaryPrint tensor count and size only

Memory

Opening a model reads its headers only. Each tensor is then read into an owned buffer, converted, written, and dropped before the next one starts. Peak resident memory is roughly the largest tensor plus its converted copy. It depends on the widest layer, not on the model size.

The loader copies tensor bytes out of the file. It does not memory-map them.

Architecture

compressr is a thin layer over boostr. Every quantization kernel and block layout lives in boostr, behind its Runtime trait.

ModuleResponsibility
src/loader/Format detection, header reading, one-tensor-at-a-time reads
src/policy/Per-tensor plan: quantize, fall back to F32, or pass through
src/quantization/Dispatch into boostr's kernels
src/cast/Element-type conversion with round-to-nearest-even
src/formats/GGUF, SafeTensors, and TCF writers, sharding, sidecar copying
src/importance/Importance matrix input for the quantizer
src/python/PyO3 module (python feature)

A tensor that cannot be block-quantized is stored as F32 instead of failing the run. A rank-1 tensor has no row to pack blocks along. A row length that is not a multiple of the block size cannot be packed. llama.cpp makes the same choice. The conversion report counts both cases.

Contributing

Contributions are welcome. See CONTRIBUTING.md for conventions and checks.

Questions and design discussion happen on Discord.

License

Licensed under Apache-2.0. See LICENSE.

Runs on
GPU support unknown
What shows it
  • no dependency or feature matches a backend row
Native code
None found
  • No native code found
Python bindings
Has Python bindings
  • compressr needs Python only with feature python
License
Apache-2.0

Compare with similar projects

Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days.

compressr beside the projects that share a topic with it
ProjectDownloadsDependentsStarsLatest releaseRuns on (GPU)Native codeLicense
compressr This page App New

Model conversion and quantization with no Python: reads SafeTensors, GGUF, TCF and PyTorch state dicts, writes SafeTensors, GGUF and TCF, and quantizes to Q2_K through Q8_0 and IQ4 formats, including Q4_K_M mixes. GPTQ, AWQ, NF4, FP8, EXL2 and ONNX input are not implemented.

Python bindings

23 downloads over 30 days Not applicable 0 0.2.1 GPU support unknown No native code found Apache-2.0
safetensors Featured

Provides functions to read and write safetensors which aim to be safer than their PyTorch counterpart.

5,486,837 downloads over 30 days 531 3,943 0.8.0 GPU support unknown No native code found Apache-2.0

Minimal ONNX model loader for extracting weights, tensors, operations, and graph structure

3,975 downloads over 30 days 4 6 0.5.2 GPU support unknown No native code found MIT
gguf Listed

GGUF file parser

2,472 downloads over 30 days 4 25 0.1.8 GPU support unknown No native code found MIT
onnx-rs Listed

Zero-dependency ONNX model parser in Rust

453 downloads over 30 days 5 6 0.1.3 GPU support unknown No native code found MIT
cmf App Listed

One backbone, many specialists. CMF is a self-describing, memory-mappable single-file format and a dependency-free runtime for quantized LLMs — zero-copy execution on CPU or GPU (Vulkan · Metal · DX12) that overlays task-specialized skills onto one shared model, with no per-model duplication.

24 binary downloads per release Not applicable 52 Not measured Not measured Apache-2.0
Why NewIts first release on 1 Nov 2026 is under 180 days old.

The check tests the Featured gates once the first release passes this age limit.

What else the check found

  • The last activity is on 6 Nov 2026, 3 days ago. The rules expect an update within 365 days. Dormancy rule

Check notes

  • the latest release was packaged from a dirty working tree

Exact rules: New. The check on applied thresholds version 9.

Every rule outcome, as the check records it
  • expected-interval: app: E = 365 days
  • dormancy: last activity 2026-11-06, 3 days ago, E = 365: active
  • new: new: first release 2026-11-01 is under 180 days old

Measurements and sources

Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.

Sources6 sources
Adoption0 binary downloads per release4 not measured
Adoption measurements
SignalValueSourceFetchedCounts
Active dependentsNot measuredYes
New dependents (365 days)Not measuredYes
Peak active dependentsNot measuredYes
Active dependents as a share of the peakNot measuredYes
Binary downloads per release0GitHub releasesYes
MaintenanceLatest human commit: 3 days ago4 not measured
Maintenance measurements
SignalValueSourceFetchedCounts
Latest human commit2026-11-06GitHub repositoryYes
Latest release2026-11-06GitHub releasesYes
First release2026-11-01crates.io database dumpYes
Latest version0.2.1crates.io database dumpNo
Days the oldest outside issue waits for a reply0GitHub repositoryYes
Maintainer replies over 365 days0GitHub repositoryYes
Repository archivedfalseGitHub repositoryYes
Repository gonefalseGitHub repositoryYes
Release commit or manifest in the repotruecrates.io packageNo
Published docsNot measuredYes
Latest release fails cargo checkNot measuredYes
Build check dateNot measuredYes
Build check toolchainNot measuredYes
SecurityNot measured
Security measurements
SignalValueSourceFetchedCounts
Unpatched vulnerabilities past the grace windowNot measuredYes
RustSec unmaintained advisoryNot measuredYes
Deprecation noticeNot measuredYes
Deprecated requirementNot measuredYes
Distribution2 releases, 23 downloads over 30 days6 not measured
Distribution measurements
SignalValueSourceFetchedCounts
Releases2crates.io database dumpNo
Downloads over 30 days23crates.io database dumpNo
Binary downloads over the last 3 releases0GitHub releasesYes
Homebrew installs on request over 365 daysNot measuredYes
Repology repository familiesNot measuredYes
Docker pull growth over 90 daysNot measuredYes
Docker pulls at the growth baselineNot measuredYes
Every version a prereleasefalsecrates.io database dumpYes
Every version 0.0.xfalsecrates.io database dumpYes
Every version yankedNot measuredYes
Crate deleted from crates.ioNot measuredYes
Repository0 stars, 0 forks, 1 contributors, 63 commits. Stars alone never qualify a project.
Repository measurements
SignalValueSourceFetchedCounts
GitHub stars0GitHub repositoryYes — one part of the repository route
GitHub forks0GitHub repositoryYes — one part of the repository route
Contributors with a GitHub account1GitHub contributorsYes — one part of the repository route
Commits on the default branch63GitHub repositoryNo
Repository's main crate left out of the entrynonecrates.io database dumpYes
Facts that never count
Facts that never count measurements
SignalValueSourceFetchedCounts
LicenseApache-2.0crates.io database dumpNo
Runs on, from listed crates and their direct dependenciesGPU support unknowncrates.io database dumpNo
What shows each backendno dependency or feature matches a backend rowcrates.io database dumpNo
Native code, from listed crates and their dependenciesNo native code foundcrates.io database dumpNo
Python bindings, from direct dependencies of listed cratesHas Python bindings: compressr needs Python only with feature pythoncrates.io database dumpNo
Crates that depend on a listed crate directlyNot measuredNo

Corrections and review history

Report a correction

No correction applies to this entry.

Judgments

A judgment enters only through an approved issue and a merged pull request.

No judgment applies to this entry.