Adding a Codec Family¶
This page is the concrete, operational companion to
Experiment Architecture: it maps the "concept →
helper → feature → golden → release → docs" promotion path onto the actual
files and commands in this repo, and it documents the one place that must stay
in sync whenever a new codec family (today: rvq, spiht, hybrid) is
added.
Two different meanings of "family" — don't conflate them¶
This repo uses "family" for two unrelated concepts. Keep them distinct:
- Codec family (
compressionkit.runtime.base.CodecFamily, values"rvq"/"spiht"/"hybrid") — how a codec is implemented and how its deploy manifest, runtime loader, and HuggingFace bundle are shaped. This is whatCodecFamilySpecbelow is about. - Golden structure (
GoldenExperiment.structure, values"codec"/"two_stage") — whether a golden release is a single artifact or a codec paired with an entropy prior. Unrelated to codec family; atwo_stageentry still has an underlyingmethod(today always"rvq").
Before this rename, both concepts were called family, and that naming
collision was a real source of confusion. If you add a new axis of variation,
give it its own name rather than reusing "family".
The CodecFamilySpec registry¶
Every consumer that needs to know "given family X, which runtime class loads
it / which files are required / which model-card generator applies / what's
the default license" reads that from one place:
compressionkit.export.family_registry.FAMILY_REGISTRY.
Before this registry existed, that same knowledge was re-derived independently
in the runtime loader, the deploy validator, the model-card generator, and the
HuggingFace publisher — each with its own copy of the known-families list.
That duplication is exactly how a real bug shipped: the hybrid lane's
family field went stale in the exporter without the loader, validator, or
publisher ever noticing, because nothing forced them to agree. Adding a family
now means adding one CodecFamilySpec entry, not editing five modules and
hoping none are missed.
Promotion path¶
| Stage | What happens | Where it lives |
|---|---|---|
| Concept | Prototype the idea with no contract yet. | experiments/ (gitignored scratch) or a notebook. |
| Initial helpers | Extract genuinely reusable pieces — a layer, a loss, a DSP transform, a preprocessing block. | compressionkit/{layers,losses,pipeline,dsp}/ |
| Feature iteration | Compare against existing goldens using the same eval harness (scorecard/metrics), not a bespoke one-off script. | experiments/configs/, experiments/scripts/ |
| Hook → golden | Register a stable experiment_id + config/operating point. If it's a genuinely new codec family (not just a new operating point of an existing one), add a CodecFamilySpec entry too. |
compressionkit/experiments/registry.py, compressionkit/export/family_registry.py |
| Produce results | Build the deploy package through the registered entry point, never by hand-assembling manifest JSON. | compressionkit golden run <id> (never invoke a golden script directly if you can help it — see below) |
| Tie into release | Publish via the same family spec so staging/model-card/license logic can't drift from the loader. | compressionkit golden run <id> --publish, scripts/publish_to_huggingface.py |
| Docs | One row in the golden matrix / registry table. | V1 Release Contract, scripts/render_experiment_docs.py output |
Adding a new CodecFamilySpec entry¶
A new family needs, at minimum:
- A runtime class implementing the
Codecprotocol (.compress/.decompress/.name/.modality/.sample_rate/.frame_size/.target_cr) undercompressionkit/runtime/. - An exporter that writes
deploy_manifest.jsonwith the newfamilyvalue, plus whatever artifacts the runtime needs to reload. - A
CodecFamilySpecentry incompressionkit/export/family_registry.pydeclaring: the loader, required/release-extra artifact lists, the HF file-rename map (add one tocompressionkit/export/artifact_contract.pyif the family's files don't already have one), whether it ships ac_sources/C reference, whether it carries trained weights, a model-card generator, and a default license. - A
GoldenMethodentry incompressionkit/experiments/registry.pyif it should appear in the golden matrix, following the existing_ppg_spiht/_ppg_hybrid-style builder functions.
That's it — the runtime loader, deploy validator, and HuggingFace publisher all read the same spec and need no further changes.
Validate before you trust a local build¶
results/ is gitignored, so a local deploy package can silently go stale
relative to the current code (e.g. a manifest-schema change lands but nobody
re-runs the golden that produced an old package). Two guards exist for this:
- Every golden-producing script (
scripts/run_hybrid_golden.py,scripts/run_spiht_golden_{ppg,ecg}.py, and the RVQ training recipe viacompressionkit/recipes/base_rvq.py) self-validates its own output withvalidate_deploy_package(deploy_dir, strict_release=True)as its last step and logs loudly (without aborting a completed training run) if it fails. compressionkit golden validate-all --strict-releasesweeps every registered golden's existing local deploy package in one pass. Run this before cutting a release, or after any change to manifest schema, family semantics, orexport/validate.py's requirements.