Skip to main content

Text compression that uses a local GPT-2 model as a probability source.

Project description

nnzip (neural network zip)

install

pip install nnzip
Stage Idea Best result
1 Brute-force hash inversion (Python) works for ≤3-byte files; ~0.6 M hashes/s
2 Same, in C with CommonCrypto + threads ~45 M H/s
3 NEON SHA-256 hardware intrinsics + threads ~380 M H/s
4 Apple Metal GPU compute shader ~1.0 GH/s
5 CPU + GPU concurrent ~1.4 GH/s (~2300× the Python version)
6 "Deterministic index" version of the hash idea proved the pigeonhole wall
7 Local GPT-2 + arithmetic coding English text → 13% of original (vs gzip's ~57%)
8 OpenAI API + self-extracting HTML page same idea, no local model needed

Stages 1-6 is one idea, proving why arbitrary lossless compression below input size is impossible. Stages 7-8 is another idea, that proved to be much better than well known compression algorithms for english text.

What's in here

The brute-force hash side (stages 1-5)

File What it does
compress.py / decompress.py The original idea: store a file as just SHA-256 + length; "decompress" by trying every possible file until the hash matches.
compress_index.py / decompress_index.py The "deterministic generator" refinement — turns out it's just storing the file as a big integer. Shows the size wall.
brute.c C version of decompression, CommonCrypto, pthreads. ~75× Python.
brute_neon.c C with ARMv8 SHA-2 hardware instructions. ~635× Python.
brute_mb.c 4-way multi-buffer SIMD SHA-256 — interesting failure: slower than hardware SHA on M1.
brute_metal.m Metal compute shader, all 4096 ALU lanes of the M1 Max GPU. ~1.7×10³ × Python.
brute_combined.m CPU NEON-HW + GPU in parallel. ~2.3×10³ × Python.

The actual-compression side (stages 6-8)

File What it does
nnzip/ Python package: local GPT-2 + arithmetic coding. Installs as compress, decompress, and nnzip CLI commands.
pyproject.toml Packaging config: declares the CLI entry points and dependencies.
arithmetic_coder.py Portable bit-level arithmetic coder. Identical output in Python and the JS port (see template.html).
api_compress.py OpenAI API compression (no local model, but slow and pay-per-use). Three modes: compress produces a binary .api file, decompress reverses it, compress-html bakes the payload into a portable HTML self-extractor.
template.html The HTML self-extractor template with the JS arithmetic decoder inline. The Python compressor fills in the __PAYLOAD_B64__ etc. placeholders.

Test data

File Use
sample.txt ~860-byte English paragraph for compression demos.

How to use

Build the C/Metal brute forcers (the hardware showcase)

clang -O3 -Wall -Wno-deprecated-declarations -o brute brute.c
clang -O3 -Wall -Wno-deprecated-declarations -o brute_neon brute_neon.c
clang -O3 -march=native -Wno-deprecated-declarations -o brute_mb brute_mb.c
clang -O3 -fobjc-arc -framework Foundation -framework Metal -o brute_metal brute_metal.m
clang -O3 -fobjc-arc -framework Foundation -framework Metal -o brute_combined brute_combined.m

Then:

printf 'word' > test4.txt
python3 compress.py test4.txt test4.compressed
./brute_combined test4.compressed test4.recovered 8   # ~2 seconds on M1 Max

The full 4-byte search space is 4.3 billion candidates. The Python decompressor would take ~38 minutes. The combined CPU+GPU version finds the right one in ~2 seconds.

Local LLM compression — the nnzip CLI (works on Mac and Windows)

Install the package (one-time, downloads PyTorch + transformers ~600 MB):

python3.12 -m venv venv
./venv/bin/pip install -e .

On Windows, use python -m venv venv and venv\Scripts\pip install -e . — same package, same commands afterward.

Then compress and decompress are available as commands:

./venv/bin/compress sample.txt           # produces sample.txt.nnz
./venv/bin/decompress sample.txt.nnz     # restores sample.txt

Or use the namespaced command:

./venv/bin/nnzip compress sample.txt
./venv/bin/nnzip decompress sample.txt.nnz

First run downloads GPT-2 (~500 MB) and caches it in ~/.cache/huggingface. Expect ~13-20% of original size on English text. Non-English / source code / random binary may not compress (or may grow).

To use a larger model with better compression, set the environment variable:

NNZIP_MODEL=gpt2-medium ./venv/bin/compress sample.txt   # ~1.5 GB download, better ratio

The model name is stored in the .nnz file so the decompressor automatically loads the matching one.

OpenAI API compression (small payloads, portable HTML)

Requires an OpenAI API key. Put it in .env:

OPENAI_API_KEY=sk-...

(.env is in .gitignore — never gets committed.)

./venv/bin/pip install openai tiktoken
./venv/bin/python api_compress.py compress sample.txt sample.api
./venv/bin/python api_compress.py decompress sample.api sample.out

# or, produce a self-extracting HTML page:
./venv/bin/python api_compress.py compress-html sample.txt sample.html
# then open sample.html in any browser, paste your own API key, click Decompress

The HTML file is ~10 KB of template + the compressed payload (tens of bytes for small texts, scaling with input). Best on files at least a few KB; the template overhead is paid once.

Known limitations

  • API determinism risk. OpenAI's logprobs jitter at ~4th decimal across identical calls. mitigate by (a) quantizing logprobs to 2 decimals before sorting and (b) using a fixed rank distribution rather than one derived from per-call probabilities. Natural English text works in testing; pathological inputs could still desync.
  • Speed. API-based decompression is ~1 token/sec (one network round-trip per token). A 1 KB file takes ~6 minutes to extract. This is a demo, not a tool.
  • Cost. Each decompression costs the recipient ~$0.002 per token via the OpenAI API. A 1 KB file costs about 50¢ per extraction.
  • Only English text compresses well. Random binary, source code, non-English get poor ratios (sometimes worse than the original) because GPT-3.5's predictions are weak there.
  • The compressed payload is not encrypted. Anyone with the same OpenAI API access can decompress. If you want privacy too, encrypt before compressing.

Influences and prior art

License

MIT.

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

nnzip-0.1.2.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

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

nnzip-0.1.2-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file nnzip-0.1.2.tar.gz.

File metadata

  • Download URL: nnzip-0.1.2.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for nnzip-0.1.2.tar.gz
Algorithm Hash digest
SHA256 bd9a40163c9ad011c127668b713a5b5703b70826f072bdc25e12e65ecad401e2
MD5 1c0aab5a8c4d5f2b6dfab8086cbbaa56
BLAKE2b-256 78801f710a9e9102eb0295bb81191d6ad45539c0fd43dd3a36a34f54b0758101

See more details on using hashes here.

File details

Details for the file nnzip-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: nnzip-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for nnzip-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c6f9d899f40fbca7f01cbf853be412e60a78288dcf846392a226c1df95118d9b
MD5 7ddcc9657603d14270a754d254938200
BLAKE2b-256 46ca1318ee65e84113dc0bab51fe0954368ccf6d96fa1cc7aa05a58b7f55b367

See more details on using hashes here.

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