Skip to main content

Dequantize compressed-tensors NVFP4 LLM checkpoints to dense safetensors (streaming, constant memory)

Project description

llm-dequant — stream NVFP4 compressed-tensors checkpoints back to dense safetensors

Turn NVFP4-only model releases back into dense safetensors.

Streaming, constant-memory dequantization of compressed-tensors nvfp4-pack-quantized LLM checkpoints — a 300B-parameter MoE converts on a few hundred MB of RAM.

tests license python


Why this exists

A growing number of community models — abliterations, fine-tunes, supertunes — are published only in NVFP4 compressed-tensors form. That single release format locks out most of the ecosystem:

  • llama.cpp's convert_hf_to_gguf.py can't read compressed-tensors checkpoints → no GGUFs
  • fine-tuning frameworks expect dense weights → no further training
  • weight surgery (MTP grafts, merges, pruning) needs real tensors → no surgery

The reference decompression path in compressed-tensors/transformers materializes the whole model in memory, which is a non-starter at 300B scale.

llm-dequant fixes this with a purpose-built converter:

🌊 Streaming module-by-module; peak RSS = one module + one shard buffer
🎯 Exact output is bit-identical to the reference implementation (CI-checked)
🧾 Standard output sharded safetensors + index, quantization_config stripped, tokenizer files copied — a normal dense HF checkpoint
🪶 Dependency-light torch, safetensors, numpy. No compressed-tensors, no transformers
🔍 Self-verifying verify proves round-trip byte-equality against your actual checkpoint before you commit to a 600GB write
🛡️ Defensive untrusted index.json path names rejected, NaN/Inf scales refuse loudly, unsupported formats never convert silently

Born from converting a 295B MoE released as NVFP4-only into a full GGUF quant sweep (SuperHY3-abliterated-GGUF).

Install

pip install llm-dequant            # from PyPI (published releases)

or straight from GitHub (works on any commit, no release needed):

pip install git+https://github.com/vcruz305/llm-dequant.git

Both pull in torch, safetensors, and numpy automatically. For a CPU-only torch (much smaller download):

pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install llm-dequant

Quickstart

# 1. what is this checkpoint?
llm-dequant inspect /models/SomeModel-NVFP4

# 2. prove the math round-trips on THIS checkpoint (seconds, no writes)
llm-dequant verify /models/SomeModel-NVFP4 --sample 16

# 3. convert (bf16 default; fp16/fp32 available)
llm-dequant convert /models/SomeModel-NVFP4 /models/SomeModel-BF16

Then use the output like any dense checkpoint:

python llama.cpp/convert_hf_to_gguf.py /models/SomeModel-BF16 \
    --outfile SomeModel-BF16.gguf --outtype bf16

Python API

from llm_dequant.model import convert, verify, inspect_checkpoint
from llm_dequant.nvfp4 import dequantize_nvfp4, unpack_fp4, pack_fp4

convert("/models/in-nvfp4", "/models/out-bf16", dtype="bf16")

The NVFP4 format, in one table

nvfp4-pack-quantized (emitted by llm-compressor) stores, per quantized Linear:

tensor dtype shape meaning
weight_packed uint8 [m, n/2] two FP4-E2M1 codes per byte, low nibble first
weight_scale fp8-e4m3 [m, n/16] one scale per group of 16 columns
weight_global_scale fp32 scalar per-module global scale (optional)

An FP4 code is 1 sign bit + 3 bits indexing the E2M1 magnitude table [0, 0.5, 1, 1.5, 2, 3, 4, 6], and

W[i, j] = e2m1(code[i, j]) · scale[i, j//16] / weight_global_scale

Dequantization is exact. Every recovered value sits precisely on the scaled FP4 lattice (computed in fp32, cast once to the output dtype). Nothing the NVFP4 checkpoint encodes is lost. What the original 4-bit quantization already destroyed is of course not recoverable — the output is dense, not restored. If you re-quantize the result (e.g. to GGUF), disclose the FP4 provenance: tiers at or below ~4 bpw lose essentially nothing, higher tiers only improve the never-quantized tensors.

How correctness is established

Two independent layers, both of which you can run yourself:

1. llm-dequant verify <src> — against your checkpoint. Samples random packed modules, dequantizes, renormalizes by the effective scale, re-packs with nearest-E2M1 rounding, and requires byte equality with the original weight_packed. Any error in nibble order, scale layout, group mapping, or global-scale handling breaks byte equality. (This proves self-consistency against the real bytes; spec conformance comes from layer 2.)

2. The test suite — against the reference implementation. Hand-computed vectors, exhaustive FP4 code tables, property-based round-trips, end-to-end synthetic checkpoints (sharded + single-file, with/without global scale), corruption and path-traversal rejection, and a bit-exactness test against upstream compressed-tensors (runs in CI).

pip install -e .[dev] && pytest

Scope

Supported: format: nvfp4-pack-quantized, symmetric, group_size: 16 — the only layout llm-compressor emits for NVFP4 today. Fused-MoE expert tensors ([experts, m, n/2]) work unchanged.

Rejected loudly, never converted silently: other compressed-tensors formats, asymmetric quantization (weight_zero_point), NaN/Inf scales, shard names that escape the checkpoint directory, colliding output tensor names.

Dropped by design: activation-quantization metadata (input_global_scale) — the output is dense; runtime activation quantization no longer applies.

License

Apache-2.0. The FP4/E2M1 constant table follows the format specification established by the vLLM / compressed-tensors projects (Apache-2.0).

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

llm_dequant-0.1.0.tar.gz (23.2 kB view details)

Uploaded Source

Built Distribution

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

llm_dequant-0.1.0-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

Details for the file llm_dequant-0.1.0.tar.gz.

File metadata

  • Download URL: llm_dequant-0.1.0.tar.gz
  • Upload date:
  • Size: 23.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llm_dequant-0.1.0.tar.gz
Algorithm Hash digest
SHA256 64b7164f5d99098db228df6e8dbf0b2d70fe9332b06f4e3823055c54f36ec8e7
MD5 48bf432e5811e25a0e7aabf1779afec2
BLAKE2b-256 0f6917e51f917e10acac404ed1a0f4cd814d014d71236f6b702f115fab89b19a

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_dequant-0.1.0.tar.gz:

Publisher: release.yml on vcruz305/llm-dequant

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

File details

Details for the file llm_dequant-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: llm_dequant-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llm_dequant-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 75f9acf88c00a2e64107c6f4432cbd4b1998812a0376d0fa03410312bfb58474
MD5 3a3d98cfbcdfe16e660f1e708dc5306c
BLAKE2b-256 c24121ac4d7304bf439f2d1e30b7e81fc1e5c66dea06c591269d1771d75f62df

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_dequant-0.1.0-py3-none-any.whl:

Publisher: release.yml on vcruz305/llm-dequant

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