Dequantize compressed-tensors NVFP4 LLM checkpoints to dense safetensors (streaming, constant memory)
Project description
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.
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'sconvert_hf_to_gguf.pycan'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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64b7164f5d99098db228df6e8dbf0b2d70fe9332b06f4e3823055c54f36ec8e7
|
|
| MD5 |
48bf432e5811e25a0e7aabf1779afec2
|
|
| BLAKE2b-256 |
0f6917e51f917e10acac404ed1a0f4cd814d014d71236f6b702f115fab89b19a
|
Provenance
The following attestation bundles were made for llm_dequant-0.1.0.tar.gz:
Publisher:
release.yml on vcruz305/llm-dequant
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
llm_dequant-0.1.0.tar.gz -
Subject digest:
64b7164f5d99098db228df6e8dbf0b2d70fe9332b06f4e3823055c54f36ec8e7 - Sigstore transparency entry: 2165537420
- Sigstore integration time:
-
Permalink:
vcruz305/llm-dequant@b908701f131a9a8e0c14913ae7cd914e9517f9bf -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/vcruz305
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b908701f131a9a8e0c14913ae7cd914e9517f9bf -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75f9acf88c00a2e64107c6f4432cbd4b1998812a0376d0fa03410312bfb58474
|
|
| MD5 |
3a3d98cfbcdfe16e660f1e708dc5306c
|
|
| BLAKE2b-256 |
c24121ac4d7304bf439f2d1e30b7e81fc1e5c66dea06c591269d1771d75f62df
|
Provenance
The following attestation bundles were made for llm_dequant-0.1.0-py3-none-any.whl:
Publisher:
release.yml on vcruz305/llm-dequant
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
llm_dequant-0.1.0-py3-none-any.whl -
Subject digest:
75f9acf88c00a2e64107c6f4432cbd4b1998812a0376d0fa03410312bfb58474 - Sigstore transparency entry: 2165537427
- Sigstore integration time:
-
Permalink:
vcruz305/llm-dequant@b908701f131a9a8e0c14913ae7cd914e9517f9bf -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/vcruz305
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b908701f131a9a8e0c14913ae7cd914e9517f9bf -
Trigger Event:
release
-
Statement type: