Skip to main content

Lossless codec for NeuralAmpModeler .nam files — ~5.5x smaller, bit-exact float32, deterministic.

Project description

namz (Python)

Lossless codec for NeuralAmpModeler .nam files.

A .nam is JSON whose bulk is one or more flat "weights" arrays written as ~20-character decimal strings — which the NAM engine loads into float32 anyway. .namz stores each weight as a 4-byte float32 instead: ≈5.5× smaller, bit-exact to what the engine computes, and deterministic (no compression → byte-identical across runs, platforms, and languages). A small readable header exposes tone/gear/device metadata without decoding the weights.

This package is a native Python port of the C++ reference and is byte-for-byte compatible with it and with every other port — it is validated against the shared conformance vectors (the cross-language TCK).

Install

pip install namz

Requires Python ≥ 3.9 and NumPy.

Library

import namz

nam = b'{"architecture":"WaveNet","weights":[0.5,-0.5,0.25]}'

blob = namz.pack(nam)                 # -> .namz bytes
assert namz.is_namz(blob)
assert namz.unpack(blob) == nam       # lossless to float32

# Stamp a readable metadata header (typed: "true"/"false" -> bool, digits -> int, else string):
opts = namz.PackOptions(metadata={"tone_type": "hi-gain", "boost": "true", "device": "tube:1,pnp:1"})
blob = namz.pack(nam, opts)
namz.read_meta(blob)   # {'tone_type': 'hi-gain', 'boost': 'true', 'device': 'tube:1,pnp:1'} — no weight decode

API

function description
pack(nam_json, options=None) -> bytes .nam JSON (str/bytes) → .namz. b"" on invalid JSON.
unpack(data, max_json_bytes=256MiB) -> bytes .namz.nam JSON. b"" on corruption / over-cap. Never raises.
read_meta(data) -> dict[str, str] display header without touching weights. {} for v1 / non-.namz.
is_namz(data) -> bool cheap magic check.
PackOptions(shuffle=True, metadata={}) packing options.

unpack is total: for any input bytes it returns bytes (empty on failure) and never raises.

CLI

namz encode in.nam out.namz [--no-shuffle] [--set key=value ...]
namz decode in.namz out.nam
namz map    in.namz [--json]        # print the metadata header (no weight decode)
namz verify in.nam                  # pack->unpack round-trip check + ratio

(Also available as python -m namz.)

Guarantees

  • Lossless to float32unpack(pack(x)) is bit-exact at any nesting depth, including -0.0, subnormals, and FLT_MAX.
  • Deterministicpack(x) is byte-identical across runs and platforms; the codec is idempotent.
  • Robust — every malformed input (bad magic, unknown version/codec/dtype, truncation, trailing junk, a lying metaLen/numArrays, an over-cap body) is rejected cleanly.

Byte-match note

The skeleton is minified JSON with keys sorted ascending, matching the reference (nlohmann). It is validated byte-for-byte against the reference over the whole NAM domain (a large differential fuzz — config integers, simple decimals, non-ASCII, control chars, nesting). The weight payload itself is always exact float32, never text. Two documented edges, both outside the NAM domain:

  • Non-finite weights (NaN/±Inf) are out of contract and are rejected, exactly as the reference rejects them.
  • An integer literal outside [int64_min, uint64_max] in a non-weight field is coerced to a double, as nlohmann does; this is byte-exact for double-representable magnitudes (e.g. 2**64). For extreme 23+-digit integers nlohmann's own parser rounds imprecisely and may differ by one ULP — such values never occur in NAM config.

Development

pip install -e ".[test]"
pytest                      # runs the shared conformance vectors + property fuzz + adversarial suite

Versioned independently of the C++ reference; tracks wire format version 2.

License

MIT — see LICENSE. © 2026 Oleh Tsymaienko <oleh@darwinscat.com> & Alisa Lafoks <alisa@darwinscat.com> (Darwin's Cat).

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

namz-1.0.0.tar.gz (22.9 kB view details)

Uploaded Source

Built Distribution

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

namz-1.0.0-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file namz-1.0.0.tar.gz.

File metadata

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

File hashes

Hashes for namz-1.0.0.tar.gz
Algorithm Hash digest
SHA256 ac1c9363d23e0404af7d050e5aa7e6bff1420a90cea1e1587b18efcde5c6a9e4
MD5 10d962920dbd298f42c12197a416f5ba
BLAKE2b-256 558a56782b91f0f4869aa113eac0916c60df7d44b220ab2b0f459ae71a840d1b

See more details on using hashes here.

Provenance

The following attestation bundles were made for namz-1.0.0.tar.gz:

Publisher: python.yml on darwinscat/namz

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

File details

Details for the file namz-1.0.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for namz-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c58c4984caa3bb8598cadd930a4122176270d27a92e53ee86fe119cbd9cd3461
MD5 e174f1d752019c3022ea09b8d61e860a
BLAKE2b-256 51e782eadf2d39110ba06348920497e3351f3b597c1d87f042f0802e01cf5355

See more details on using hashes here.

Provenance

The following attestation bundles were made for namz-1.0.0-py3-none-any.whl:

Publisher: python.yml on darwinscat/namz

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