Changing pipeline models¶
How to point transcription or diarization at a different model, when that is worth doing, and what you give up by doing it.
Voxint ships with two models chosen and measured for you: whisper large-v2 for transcription and pyannote speaker-diarization-3.1 for speaker separation. They are built into Voxint, run without any internet connection, and are the only two models whose accuracy has actually been tested. For almost everyone, the right choice is to leave them alone.
This guide is for the exception: you have a specific reason to run a different model, you understand it has not been measured, and you want to do it safely. Everything here is optional and advanced. If that is not you, you can close this page.
⚠️ Changing a model is not free. The shipped models are validated, which means Voxint's accuracy numbers were measured against them. Any other model is an unvalidated mechanism: it will run, but no one has checked how good its results are, and some popular alternatives are known to be worse. Whisper v3 and turbo, for example, hallucinate text that was never spoken. Only change a model if you can live with unmeasured results.
Validated versus unvalidated¶
Two words show up throughout Voxint, and they mean something exact here.
- Validated means the shipped default: its accuracy was measured and the results are what Voxint's documentation promises. There are exactly two, one per configurable stage.
- Unvalidated means anything else. It is a supported mechanism, so Voxint will load it and run it, but its accuracy is unknown. You are on your own for judging whether the output is good enough.
The Settings page tells you which one each service is running right now. Open the console, click Settings, and find the Pipeline models panel. Each service shows its model and whether it is the validated default or an unvalidated override. That panel reads the live services every time you load it, so it is the honest place to confirm a change took effect after you restart a service.
The third model, speaker embedding (TitaNet), is fixed. Voxint depends on it for speaker identity, so it is not something you change, and the panel shows it without a warning.
How a change is applied¶
Model choices live in your .env file, the same file the installer wrote. You
edit one or two lines, then restart the single service that changed. Only that
service restarts; the rest of Voxint keeps running.
The restart command uses the same compose files you installed with. If you are not sure which they are, they are listed in the operations guide and in setup for your hardware. For an NVIDIA install, restarting only the transcription service looks like this:
docker compose -f compose.yaml -f compose.gpu.yaml up -d whisper
Compose recreates just the whisper container with the new settings and leaves
everything else running. Swap compose.gpu.yaml for compose.cpu.yaml or
compose.rocm.yaml to match your tier, and swap whisper for pyannote when
you change the diarization model.
After the service comes back up, reload Settings > Pipeline models to confirm it reports the model you expected. A slow first start is normal (see below); if the service reads Unavailable for more than a few minutes, check its logs.
Changing the transcription model (whisper)¶
To use a transcription model other than large-v2, set three keys in .env. All
three are required together, and the whisper service refuses to start (naming
exactly what is missing) if you set the model without the other two:
| Key | What to set it to |
|---|---|
WHISPER_MODEL |
The model you want, for example a Hugging Face repo id. |
WHISPER_ALLOW_DOWNLOAD |
1, to permit the one-time download. |
WHISPER_REVISION |
The model's full 40-character commit hash (lowercase). |
The revision has to be a full commit hash, not a branch name like main and not
a short hash. This is deliberate: it pins the exact weights you downloaded so a
later restart cannot quietly pull a different version.
The first time the service starts with a new model it downloads the weights, which is slow and can be several gigabytes (roughly 3 GB for a large model). The download goes into a separate cache that never overwrites the built-in large-v2, so you can always get back to the validated default by removing these keys and restarting. Later starts reuse the cache and are fast.
A larger transcription model uses more video memory (VRAM), and it replaces the large-v2 model in that GPU slot rather than running alongside it. If a model is too big for your GPU, the service will fail to load it. There is no partial fallback: either it fits and runs, or it does not start.
Changing the diarization model (pyannote)¶
To use a different speaker-diarization pipeline, set these keys:
| Key | What to set it to |
|---|---|
DIARIZER_MODEL_NAME |
The Hugging Face pipeline id to load. |
DIARIZER_REVISION |
Optional. A commit to pin the pipeline to; blank uses the repo's default. |
HF_TOKEN |
Only if the pipeline is gated on Hugging Face and needs an account. |
Pinning DIARIZER_REVISION is worth doing so the model recorded against each run
is reproducible instead of drifting with whatever the repo's default branch
points at today.
One honest caveat about the pin. For the shipped pyannote version (3.1.1), the revision pins the download of the pipeline's configuration file, and Voxint records it as the requested revision, not a guarantee of the exact resolved build. It is a reproducibility aid, not a cryptographic proof. The vendored default does not use this key at all (its configuration is itself the pin), and setting it there is ignored with a warning.
A gated pipeline also needs a Hugging Face account token in HF_TOKEN. Voxint
never displays that token back to you, including in the Settings panel.
Tuning how speakers are separated¶
Beyond which model runs, a few settings control how the diarizer decides where one speaker ends and the next begins. You rarely need to touch them, but they are here if a particular recording clusters poorly, for example everyone collapsed into a single speaker, or one speaker split into several.
| Key | Default | What it does |
|---|---|---|
PYANNOTE_CLUSTERING_THRESHOLD |
0.55 |
How close two voices must sound to be treated as the same person. Lower splits speakers more readily; higher merges them more. |
PYANNOTE_CLUSTERING_MIN_SIZE |
10 |
The smallest group of segments that can become its own speaker. |
PYANNOTE_SEGMENTATION_STEP |
0.5 |
How far the analysis window moves each step. |
PYANNOTE_MIN_DURATION_OFF |
0.6 |
How long a pause must be before it splits one speaker's turn in two. |
These four change the numbers behind speaker separation, so they are part of the diarizer's recorded configuration identity. If you change any of them, the console's Pipeline models panel shows the built-in pipeline as a configuration mismatch until you set them back. That is expected: it is the panel telling you honestly that this deployment no longer matches the validated default. Reset the values to clear it.
⚠️ On the built-in (validated) pipeline these are fail-closed. If you set one to a value the pipeline cannot actually apply, the diarization service refuses to start rather than quietly run a different value while still reporting the validated name. This covers two cases: the pipeline rejecting the value outright, and the subtler one where it accepts the call but silently keeps a frozen default. In both the service stops with a message naming what did not take. An explicitly overridden pipeline (one you pointed at your own
DIARIZER_MODEL_NAME) keeps the older tolerant behavior instead.
Two more keys, PYANNOTE_SEGMENTATION_BATCH_SIZE (default 8) and
PYANNOTE_EMBEDDING_BATCH_SIZE (default 12), only affect speed, not results, so
they are left out of that identity check. Raise them to push the GPU harder, lower
them if you run short of video memory.
When a model is slower¶
A bigger or slower model changes how long a stage takes, and Voxint has time limits that decide when to give up on a stage it believes has hung. If you move to a much slower model on slower hardware, a healthy run can bump into those limits and be treated as dead, then re-run, doubling the work.
If you see that happen, the two budgets to raise are the per-call timeout
(GPU_HTTP_TIMEOUT_SECONDS) and the stage lease that must always be larger than
it. The rules for sizing them so they stay consistent are in
Timeouts, leases, and compute tiers; read that
before changing either, because setting them incorrectly causes exactly the
double-run problem it is meant to prevent.
Transcription on CPU¶
The shipped large-v2 is slow on CPU by design: it is a 1.5B-parameter model. If you need faster transcription on a CPU-only Docker install, medium trades accuracy for speed. Its accuracy has not been measured in Voxint, so you need to judge whether its results are good enough for your recordings.
Set these three keys in your .env file:
WHISPER_MODEL=Systran/faster-whisper-medium
WHISPER_REVISION=08e178d48790749d25932bbc082711ddcfdfbc4f
WHISPER_ALLOW_DOWNLOAD=1
Restart the transcription service to apply the change:
docker compose -f compose.yaml -f compose.cpu.yaml up -d whisper
The download is roughly 1.5 GB, so the first start is slow while it downloads.
To go back to the validated large-v2, remove WHISPER_MODEL,
WHISPER_REVISION, and WHISPER_ALLOW_DOWNLOAD from .env, then run the same
restart command again.
A note for Apple Silicon (Metal) installs¶
The native macOS path runs the model services directly on your Mac rather than in containers, and it pins the shipped validated models on purpose. The alternate-model keys above apply to the Docker installs (CPU, NVIDIA, AMD) only; they are not read on the Metal tier today. If you run the native path and need a different model, you are for now on the validated default. See the native macOS preview for what that path does and does not cover.
For developers¶
Voxint's transcription service can host more than one inference engine behind a
fail-closed registry (the built-in CT2 path, and others added over time). Adding
an engine is a code change in services/whisper/, not an .env setting, and it
carries the same rule as swapping a model: a new engine has to earn a measured
parity verdict before it is validated. The service contracts every model service
must satisfy are documented in GPU service contracts, and
the contribution process is in CONTRIBUTING.md.