Skip to content

CLI: --models-dir flag + default to ~/.local/share/Vernacula/models #42

Description

@christopherthompson81

Motivation

Vernacula.CLI currently overloads `--model

` as both the Parakeet
bundle path and the models root for sibling backends. That's a
historical artefact — Granite, Cohere, Qwen3, VibeVoice, and Whisper all
do `Path.Combine(modelDir, Config.SubDir)` and so silently treat
`--model` as the root. But Parakeet (`new ParakeetAsr(modelDir, ...)`)
and `VadSegmenter` load files flat from the directory you pass; they
need a bundle, not a root.

Practical consequence: pointing `--model` at the desktop app's
`~/.local/share/Vernacula/models` works for Granite/Cohere/Qwen3/VibeVoice/Whisper
but breaks Parakeet and VAD because they look for files at the root
instead of in the per-backend subdirs.

The desktop app sidesteps this with `SettingsService.GetModelsDir()`
(root) plus per-backend `GetModelsDir()` (root + canonical subdir).
The CLI should match.

Scope

  1. Add `--models-dir ` as the canonical "where everything lives"
    flag, mirroring the desktop app's models root.
  2. Make `--model` and `--models-dir` both optional. When neither is
    passed, default to `DefaultModelsDir()` — which already exists in
    Program.cs (line 957) and resolves to
    `~/.local/share/Vernacula/models` on Linux. Today the CLI errors with
    "--audio and --model are required"; that becomes "--audio is required"
    and the models root falls back to the desktop app's location.
  3. Add subdir-fallback at flat-load sites. Same pattern Sortformer
    already uses via `Config.GetSortformerModelPath`: when given a root
    that contains a per-backend subdir, prefer the subdir; else fall back
    to root for back-compat with users passing a bundle directly. Sites
    to update:
    • Parakeet construction (Program.cs around line 780):
      `Directory.Exists(Path.Combine(modelDir, Config.ParakeetSubDir)) ? ... : modelDir`
    • VadSegmenter (line 301): same treatment with `Config.VadSubDir`
      ("silero").
    • DiariZen (line 312–313): already does this; verify it covers the
      desktop app's layout.
  4. Update `PrintUsage()` to document the new flag, the default, and
    the convention.

Out of scope

  • Rewriting the per-backend `--cohere-model` / `--qwen3asr-model` /
    `--vibevoice-model` / `--granite-model` overrides. Those stay as
    per-backend escape hatches when someone wants to point at a non-canonical
    bundle location.
  • Changing `Vernacula.Base` constructor signatures (Parakeet, VadSegmenter)
    to do their own subdir resolution. Keep the resolution in CLI; Base stays
    bundle-path-agnostic. Sortformer's `Config.GetSortformerModelPath` is the
    one already-existing exception; leaving it is fine.

Definition of done

  • `dotnet run --project src/Vernacula.CLI -p:EP=Cuda -- --audio foo.wav --asr granite`
    with no `--model` / `--models-dir` succeeds, picks up the desktop app's
    `~/.local/share/Vernacula/models` automatically, and runs Granite.
  • The same invocation with `--asr parakeet` (no `--model`) succeeds and
    resolves Parakeet from `/parakeet/`.
  • `--model ` (the existing pattern) still works
    unchanged for users who have a non-canonical layout.
  • `--help` documents the flag + default.

Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions