Model Catalog
The model catalog is the single source of truth for every Qwen3-TTS
variant LunaVox ships with. Every other module — the downloader, the
conversion pipeline, the CLI prompts — reads MODELS from this module.
Adding or renaming a model means touching this file and nothing else.
The MODELS registry
from lunavox.model import MODELS, all_models, get_model
# Dict keyed by internal short name
print(list(MODELS.keys()))
# ['base_small', 'custom_small', 'base', 'custom', 'design']
# Ordered list preserving registry order
for spec in all_models():
print(f"{spec.name:15s} {spec.size} mode={spec.mode} repo={spec.repo_id}")
# Direct lookup raises ValueError on unknown
spec = get_model("base_small")
ModelSpec
ModelSpec
dataclass
ModelSpec(name: str, repo: str, display_name: str, size: str, mode: str)
Catalog entry for one published Qwen3-TTS model.
MODELS
module-attribute
MODELS: dict[str, ModelSpec] = {(name): spec for spec in _REGISTRY}
all_models
Iteration order matches _REGISTRY.
Source code in src/lunavox/model/config.py
| def all_models() -> list[ModelSpec]:
"""Iteration order matches ``_REGISTRY``."""
return list(_REGISTRY)
|
model_keys
model_keys() -> list[str]
Source code in src/lunavox/model/config.py
| def model_keys() -> list[str]:
return [spec.name for spec in _REGISTRY]
|
get_model
Source code in src/lunavox/model/config.py
| def get_model(name: str) -> ModelSpec:
try:
return MODELS[name]
except KeyError:
valid = ", ".join(model_keys())
raise ValueError(f"Unknown model '{name}'. Available: {valid}") from None
|
get_snapshot
get_snapshot(spec_or_name: ModelSpec | str) -> Path
Resolve a cached HF snapshot directory for a model.
Previously this returned a ghost path on miss, which masked failures
downstream. It now raises RuntimeError listing every path tried.
Source code in src/lunavox/model/config.py
| def get_snapshot(spec_or_name: ModelSpec | str) -> Path:
"""Resolve a cached HF snapshot directory for a model.
Previously this returned a ghost path on miss, which masked failures
downstream. It now raises ``RuntimeError`` listing every path tried.
"""
spec = spec_or_name if isinstance(spec_or_name, ModelSpec) else get_model(spec_or_name)
tried: list[str] = []
# 1. Preferred: huggingface_hub resolves the canonical snapshot dir.
try:
path = Path(snapshot_download(repo_id=spec.repo_id, local_files_only=True))
log.debug("snapshot_download hit for %s: %s", spec.repo_id, path)
return path
except Exception as err:
tried.append(f"snapshot_download({spec.repo_id}): {err}")
# 2. Fallback: walk the HF cache layout directly. If the most recent
# snapshot subdir exists, use it.
snap_dir = HF_HUB_ROOT / f"models--{HF_ORG}--{spec.repo}" / "snapshots"
tried.append(str(snap_dir))
if snap_dir.exists():
snaps = [s for s in snap_dir.iterdir() if s.is_dir()]
if snaps:
# Newest-first so resuming an interrupted pull picks up the
# latest commit instead of an abandoned partial.
snaps.sort(key=lambda p: p.stat().st_mtime, reverse=True)
log.debug("cache fallback hit for %s: %s", spec.repo_id, snaps[0])
return snaps[0]
raise RuntimeError(
f"Model snapshot for '{spec.name}' ({spec.repo_id}) not found. Tried:\n - "
+ "\n - ".join(tried)
)
|
ModelConfig and project-rooted view
ModelConfig
dataclass
ModelConfig(name: str, spec: ModelSpec, source: Path, dest: Path)
Per-project binding of a ModelSpec to a local destination.
Models
Models(project_root: Path, names: Iterable[str] | None = None)
Project-rooted view of the model catalog.
Source code in src/lunavox/model/config.py
| def __init__(self, project_root: Path, names: Iterable[str] | None = None):
self.project_root = project_root
keys = list(names) if names is not None else model_keys()
self._models = [
ModelConfig(
name=k,
spec=get_model(k),
source=_probe_source(get_model(k)),
dest=project_root / "models" / k,
)
for k in keys
]
|