Skip to content

Commit 735496e

Browse files
authored
Merge pull request 0xShug0#86 from lapy/fix/loader-catalog-sync-orphans
Keep package catalog in sync with registered loaders
2 parents 47a36f3 + 92224dd commit 735496e

10 files changed

Lines changed: 531 additions & 12 deletions

File tree

.github/workflows/linux-build.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ jobs:
3737
- name: Checkout
3838
uses: actions/checkout@v4
3939

40+
- name: Check loader/catalog sync
41+
run: |
42+
python3 tools/check_loader_catalog_sync.py --self-test
43+
python3 tools/check_loader_catalog_sync.py
44+
4045
- name: Install dependencies
4146
run: |
4247
sudo apt-get update

.github/workflows/mac-build.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ jobs:
2626
- name: Checkout
2727
uses: actions/checkout@v4
2828

29+
- name: Check loader/catalog sync
30+
run: |
31+
python3 tools/check_loader_catalog_sync.py --self-test
32+
python3 tools/check_loader_catalog_sync.py
33+
2934
- name: Configure
3035
run: |
3136
cmake -S . -B "$BUILD_DIR" \

.github/workflows/windows-build.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ jobs:
2323
- name: Checkout
2424
uses: actions/checkout@v4
2525

26+
- name: Check loader/catalog sync
27+
shell: pwsh
28+
run: |
29+
python tools/check_loader_catalog_sync.py --self-test
30+
python tools/check_loader_catalog_sync.py
31+
2632
- name: Build audiocpp_cli
2733
shell: pwsh
2834
run: |

CONTRIBUTING.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ Please check the supported model table in [README.md](README.md) before starting
2020

2121
If you want to add support for a model family that is already listed, please focus on improving the existing implementation instead of opening a duplicate port.
2222

23+
When a loader is registered (or parked), keep the **package catalog** in sync. Installable `ModelPackage` entries must not advertise families that `audiocpp_cli --list-loaders` does not expose. Follow the checklist in [docs/maintainers/loader_and_catalog.md](docs/maintainers/loader_and_catalog.md) and run:
24+
25+
```bash
26+
python3 tools/check_loader_catalog_sync.py --self-test
27+
python3 tools/check_loader_catalog_sync.py
28+
```
29+
30+
Do not leave a live Hugging Face `SnapshotSource` for a loader that is commented out of `registry.cpp` — mark it `UnsupportedSource` (or remove it) and update the README package table.
2331
Good follow-up work for existing model families includes:
2432

2533
- Better CLI or server examples

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ Community model ports live under `community_models` to make the ownership bounda
9090
| **outetts** | TTS, voice cloning | en, ar, zh, nl, fr, de, it, ja, ko, lt, ru, es, pt, be, bn, ka, hu, lv, fa, pl, sw, ta, uk | Mirek [@mirek190](https://github.com/mirek190) | Llama-OuteTTS-1.0-1B TTS and voice cloning support |
9191
| **vietneu_tts** | TTS, voice cloning | vi, en | Phuoc [@phuocnguyen90](https://github.com/phuocnguyen90) | [VieNeu-TTS-v3-Turbo](vietneu_tts.md) TTS and voice cloning support |
9292

93-
WIP: Higgs Audio v3 TTS 4B, Fish Audio S2 Pro.
93+
WIP (loaders not registered in this release tree — catalog entries are `UnsupportedSource`): Kokoro 82M bf16, Higgs Audio v3 TTS 4B, Parakeet TDT 0.6B v3, Fish Audio S2 Pro. See [docs/maintainers/loader_and_catalog.md](docs/maintainers/loader_and_catalog.md).
9494

9595
PocketTTS language selection is a model-load option. When the model path points at the PocketTTS root, the loader uses `english` unless you pass `--load-option language=<name>`. Kyutai's normal non-English PocketTTS releases are smaller distilled language models intended for the fast PocketTTS path. The `_24l` variants are larger 24-layer, undistilled preview models that can sound better but are slower. Kyutai currently publishes French only as `french_24l`, not as a normal distilled `french` language directory, so French is not listed as a normal PocketTTS language here.
9696

@@ -299,7 +299,8 @@ Useful CLI features:
299299
- `--help` with `--task` shows task-oriented help
300300
- `--help` with `--model <path>` and optional `--family <family>` shows model-owned request, session, and load options
301301
- `--inspect` prints discovered configs, weights, and capabilities
302-
- `--list-loaders` prints registered model families
302+
- `--list-loaders` prints registered model families (`--json` for the machine-readable contract)
303+
- `python tools/model_manager.py list --json` prints installable packages; keep it synced with loaders ([docs/maintainers/loader_and_catalog.md](docs/maintainers/loader_and_catalog.md))
303304
- `--batch-text-file <txt>` runs one offline request per non-empty line
304305
- `--batch-text-dir <dir>` runs one offline request per `.txt`, `.md`, or `.json` file, normalizing each file as one paragraph
305306
- `--batch-audio-dir <dir>` runs one offline request per `.wav`
@@ -370,7 +371,7 @@ The CLI also exposes the runtime loader catalog with `audiocpp_cli --list-loader
370371

371372
Recommended top-level install packages:
372373

373-
`Yes` means Hugging Face has a ready-to-use repo that the framework can download as-is. `No` means the tool must assemble, convert, or post-process files before the framework can use them.
374+
`Yes` means Hugging Face has a ready-to-use repo that the framework can download as-is. `No` means the tool must assemble, convert, or post-process files before the framework can use them. Packages whose loaders are not registered in this release tree are listed as **Unavailable** (see [docs/maintainers/loader_and_catalog.md](docs/maintainers/loader_and_catalog.md)).
374375

375376
| Package id | Model | HF ready-to-use repo |
376377
|---|---|---|
@@ -379,12 +380,13 @@ Recommended top-level install packages:
379380
| `citrinet_asr` | Citrinet ASR converted layout | No |
380381
| `heartmula` | HeartMuLa | No |
381382
| `higgs_audio_stt` | Higgs Audio STT | No |
382-
| `higgs_audio_v3_tts_4b` | Higgs Audio v3 TTS 4B | **Yes** |
383+
| `higgs_audio_v3_tts_4b` | Higgs Audio v3 TTS 4B | Unavailable (loader not in this tree) |
383384
| `htdemucs` | HTDemucs | No |
384385
| `hviske_asr` | Hviske ASR | **Yes** |
385386
| `irodori_tts_500m_v3` | Irodori-TTS 500M v3 | No |
386387
| `irodori_tts_600m_v3_voice_design` | Irodori-TTS 600M v3 VoiceDesign | No |
387-
| `kokoro_82m_bf16` | Kokoro 82M bf16 | **Yes** |
388+
| `index_tts2` | IndexTTS-2 | **Yes** |
389+
| `kokoro_82m_bf16` | Kokoro 82M bf16 | Unavailable (loader not in this tree) |
388390
| `marblenet_vad` | MarbleNet VAD converted layout | No |
389391
| `mel_band_roformer` | Mel-Band RoFormer MLX | **Yes** |
390392
| `miocodec_25hz_44k_v2` | MioCodec 25Hz 44.1kHz v2 | No |
@@ -397,7 +399,7 @@ Recommended top-level install packages:
397399
| `nemotron_asr` | Nemotron ASR | **Yes** |
398400
| `omnivoice` | OmniVoice | **Yes** |
399401
| `outetts_1_0_1b` | OuteTTS 1.0 1B with IBM DAC codec and Qwen3-aligned voice cloning | No |
400-
| `parakeet_tdt_0_6b_v3` | Parakeet TDT 0.6B v3 | **Yes** |
402+
| `parakeet_tdt_0_6b_v3` | Parakeet TDT 0.6B v3 | Unavailable (loader not in this tree) |
401403
| `pocket_tts` | PocketTTS | **Yes** |
402404
| `qwen3_asr_0_6b` | Qwen3 ASR 0.6B | **Yes** |
403405
| `qwen3_asr_1_7b_hf` | Qwen3 ASR 1.7B HF | **Yes** |
@@ -413,6 +415,7 @@ Recommended top-level install packages:
413415
| `stable_audio_3_small_sfx` | Stable Audio 3 Small SFX | **Yes** |
414416
| `supertonic_3` | Supertonic 3 | **Yes** |
415417
| `vevo2` | Vevo2 | No |
418+
| `vietneu_tts_v3_turbo` | VieNeu-TTS v3 Turbo | **Yes** |
416419
| `vibevoice_1_5b` | VibeVoice 1.5B | No |
417420
| `vibevoice_7b` | VibeVoice 7B | No |
418421
| `vibevoice_asr` | VibeVoice ASR | No |
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Maintaining Loaders and the Package Catalog
2+
3+
Integrators (CLI users, servers, and UIs such as Studio) treat two exports as
4+
**authoritative**:
5+
6+
1. **Runtime loaders**`audiocpp_cli --list-loaders --json`
7+
2. **Install packages**`python tools/model_manager.py list --json`
8+
9+
Those surfaces must stay in sync. A package that is installable in the catalog
10+
but whose `family` is missing from `--list-loaders` looks available to users and
11+
then fails at runtime or in search/install UIs.
12+
13+
## The rule
14+
15+
For every **installable, standalone** `ModelPackage`:
16+
17+
| Field | Must match |
18+
|---|---|
19+
| `ModelPackage.family` | The loader family string advertised by the C++ loader |
20+
| `model_specs/<family>.json` | Present when the family uses package-spec loading |
21+
| `registry.cpp` entry | Uncommented `make_<family>_loader()` (or the family's actual factory name) |
22+
| README package table | Lists the package; use **Unavailable** when not installable |
23+
24+
Dependency / subcomponent packages (`standalone=False`, with
25+
`parent_package_id`) do **not** need their own loader.
26+
27+
Registered loaders that ship as bundled assets (no downloadable package) are
28+
allowed. List them in `BUNDLED_LOADERS_WITHOUT_PACKAGE` inside
29+
`tools/check_loader_catalog_sync.py`.
30+
31+
If a loader is not ready for this release tree:
32+
33+
1. Keep it **commented out** in `src/framework/runtime/registry.cpp`, and
34+
2. Mark matching catalog packages as `UnsupportedSource(reason=...)`, **or**
35+
remove them from `CATALOG`, and
36+
3. Mark the README package row **Unavailable**.
37+
38+
Do **not** leave a live `SnapshotSource` for a commented-out loader.
39+
40+
Optional catalog↔registry family renames for parked stubs go in
41+
`PARKED_FAMILY_ALIASES` in the sync check (collapse to one id when re-enabling).
42+
43+
## Checklist: adding a model family
44+
45+
1. Implement `include/engine/models/<family>/` (or `community_models/`) with a
46+
loader that overrides `advertised_capabilities()` so tasks/endpoints are
47+
explicit.
48+
2. Register it in `src/framework/runtime/registry.cpp` (include +
49+
`available_loaders` entry). Prefer the factory name
50+
`make_<family>_loader()` so the id matches the advertised family.
51+
3. Add `model_specs/<family>.json` when the family needs package-spec discovery.
52+
4. Add one or more `ModelPackage` entries in `tools/model_manager.py`:
53+
- Set `family="<family>"` explicitly when the package id does not strip cleanly
54+
to the loader id.
55+
- Set `tasks=(...)` when defaults would be ambiguous.
56+
- Use `standalone=False` + `parent_package_id` for tokenizers / subcomponents.
57+
5. Update README supported-model / package tables.
58+
6. Run:
59+
60+
```bash
61+
python3 tools/check_loader_catalog_sync.py --self-test
62+
python3 tools/check_loader_catalog_sync.py
63+
# after building:
64+
build/.../bin/audiocpp_cli --list-loaders --json
65+
python3 tools/model_manager.py list --json
66+
```
67+
68+
Confirm the new family appears in `--list-loaders` and that installable packages
69+
for that family set `"family"` to the same string.
70+
71+
## Checklist: parking or removing a family
72+
73+
1. Comment out the include and `make_*_loader()` entry in `registry.cpp`.
74+
2. Convert related **standalone** packages to `UnsupportedSource` with a reason
75+
that names the missing loader and points at this doc (or delete them).
76+
3. Leave `family=` / `tasks=` on unsupported entries if useful for history.
77+
4. Update README so the package row says **Unavailable**.
78+
5. Run `python3 tools/check_loader_catalog_sync.py`.
79+
80+
## Family id consistency
81+
82+
Pick **one** family string and use it everywhere:
83+
84+
- C++ loader / `advertised_capabilities()`
85+
- `make_<family>_loader()` naming (when practical)
86+
- `model_specs/<family>.json`
87+
- `ModelPackage.family`
88+
- README “Supported Models” family column
89+
90+
Integrators match on the string; aliases are not implied unless listed in
91+
`PARKED_FAMILY_ALIASES` for currently parked stubs.
92+
93+
## CI
94+
95+
`tools/check_loader_catalog_sync.py` runs in GitHub Actions on Linux/macOS/Windows
96+
builds. It:
97+
98+
- Parses active vs commented `make_*_loader()` calls in `registry.cpp`
99+
- Compares them to installable standalone packages from `model_manager.py`
100+
- Cross-checks the README recommended package table
101+
- Does **not** require a compiled binary
102+
103+
```bash
104+
python3 tools/check_loader_catalog_sync.py --self-test
105+
python3 tools/check_loader_catalog_sync.py
106+
```

docs/usage.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ audiocpp_cli --task <task> --family <family> --model <model-dir> --backend <back
1111
| Option | Values | Default | Meaning |
1212
|---|---|---:|---|
1313
| `--task` | `gen`, `tts`, `clon`, `vc`, `svc`, `s2s`, `asr`, `align`, `vad`, `diar`, `sep`, `vdes` | required | User task. |
14-
| `--family` | model family name | required | Selects the model implementation. |
14+
| `--family` | model family name | required | Selects the model implementation. Must match a registered loader (`audiocpp_cli --list-loaders`). |
1515
| `--model` | local model directory | required | Path to local model assets. |
1616
| `--backend` | `cpu`, `cuda`, `vulkan`, `metal`, `best` | `cpu` | Inference backend. |
1717
| `--mode` | `offline`, `streaming` | `offline` | Run mode. Most models are offline. |

src/framework/runtime/registry.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
#include "engine/framework/assets/model_package.h"
55
#include "engine/framework/io/config.h"
66
#include "engine/framework/io/filesystem.h"
7-
// Development registry entries from Share/AudioCPP that are not present in this release tree yet:
7+
// Parked loaders (sources not in this release tree). When commenting these out,
8+
// also mark matching ModelPackage entries UnsupportedSource — see
9+
// docs/maintainers/loader_and_catalog.md and tools/check_loader_catalog_sync.py.
810
// #include "engine/models/higgs_tts/loader.h"
911
// #include "engine/models/kokoro_tts/loader.h"
1012
// #include "engine/models/parakeet_tdt/loader.h"
@@ -242,7 +244,8 @@ ModelRegistry make_registry_from_config(
242244

243245
ModelRegistry make_default_registry(const std::optional<std::filesystem::path> & config_path) {
244246
const std::vector<std::shared_ptr<IVoiceModelLoader>> available_loaders = {
245-
// Development registry entries from Share/AudioCPP that are not present in this release tree yet:
247+
// Parked loaders — keep catalog packages UnsupportedSource while these stay commented.
248+
// See docs/maintainers/loader_and_catalog.md.
246249
// engine::models::kokoro_tts::make_kokoro_tts_loader(),
247250
// engine::models::higgs_tts::make_higgs_tts_loader(),
248251
// engine::models::parakeet_tdt::make_parakeet_tdt_loader(),

0 commit comments

Comments
 (0)