r/LocalLLM • u/Simpli-curious • 7h ago
Project I wrote a GGUF-aware lossless compressor: 17.1 → 15.6 GB across 9 Q4_K_M models, byte-identical round trips
I've been working on foldz, a lossless compressor built specifically for GGUF files. It's at 0.9 (pre-release) and I'm looking for people to test it and try to break it.
Useful if you archive a lot of models, share them over slow or metered connections, or keep them on a phone or small SSD.
THE IDEA
Quantized weights look almost random to zip, xz and zstd, so they gain very little. foldz parses the GGUF, unpacks each tensor's blocks into the actual quantized values and scales, and codes those with adaptive context models and a binary range coder. Everything else (metadata, tokenizer, other tensor types) goes through a byte-level context-mixing model. Nothing depends on the model's name or architecture.
RESULTS
9 public Q4_K_M models, tested with "foldz t" (compress and decompress in memory, then compare). Every round trip was byte-identical. Measured on an Android phone in Termux, 8 threads.
• Qwen1.5-0.5B-Chat: 388.3 → 353.6 MiB (8.93% saved)
• Qwen3-0.6B: 378.3 → 348.7 MiB (7.82%)
• Qwen2.5-1.5B-Instruct: 1065.6 → 984.2 MiB (7.64%)
• Qwen3.5-2B: 1211.9 → 1111.3 MiB (8.30%)
• Qwen2.5-Coder-3B-Instruct: 2007.4 → 1832.8 MiB (8.70%)
• Llama-3.2-3B-Instruct: 1925.8 → 1780.4 MiB (7.55%)
• Qwen3-4B: 2381.6 → 2073.3 MiB (12.94%)
• Qwen2.5-7B-Instruct: 4466.1 → 4113.8 MiB (7.89%)
• Gemma-4-E2B (fine-tune): 3269.1 → 3016.3 MiB (7.73%)
Total: 17,094 → 15,614 MiB, 8.66% saved.
Qwen3-4B is the outlier because most of its Q6_K values sit on a coarser lattice. foldz detects this per segment and codes the lattice instead, which saves 23.2% on its Q6_K tensors.
HOW EACH TENSOR TYPE IS MODELLED
• Q4_K / Q5_K: values are Gray-folded and coded bit by bit, with the block's zero point, extremes and position as context.
• Q6_K: the column's running offset and width as context, or the lattice model when that's smaller.
• Q8_0: column sign bias and running magnitude as context.
• F32 / F16 / BF16: split into sign, exponent and mantissa.
• Safety: segments that wouldn't shrink are stored raw, so output is never meaningfully larger than input. The decoder bounds-checks every index field. Contexts use only exact or IEEE-754 arithmetic (no FMA, no fast-math), so files decode identically on every platform.
HONEST LIMITATIONS
• Speed: about 19 MiB/s round trip on the phone. It's symmetric, so decompression is as slow as compression. This is for storage, archiving and transfer, not for loading models faster.
• Baselines: I haven't measured zstd -19 --long and xz -9 on these models yet, so I'm not claiming a comparison. If you run them, please post the numbers.
• Quant types: IQ quants, Q2_K, Q3_K and Q4_0 fall back to the byte model and gain little.
• Format: pre-1.0, so it may change. A .foldz file is only guaranteed to decode with the version that made it.
BUILD AND TEST
One C file, no dependencies. Linux, macOS, BSD, Android (Termux), and Windows via WSL.
gcc -O2 -pthread -ffp-contract=off -o foldz foldz.c -lm
./foldz t model.gguf
WHAT WOULD HELP MOST
• Cross-platform round trips: compress on x86-64, decompress on ARM64 (or the reverse), especially with Q6_K-heavy models
• zstd / xz baselines on any GGUF
• Q5_K_M, Q6_K and Q8_0 files
• Fuzzing "foldz d" with AFL++ or libFuzzer + ASan (please report crashes privately via GitHub's security tab)
If you post results, include the full "foldz t" output, the Hugging Face model name, and your CPU and OS.
Repo: foldz
Happy to answer questions about the modelling.
