Overview
The Allternit Voice Service (services/voice, crate voice-service) is a Rust HTTP sidecar used by Gizzi Code and Allternit Desktop. Both directions are real and run on sherpa-onnx inside the single binary — no cloud voice APIs, no Python, no whisper.cpp:
- STT: Silero VAD finds speech segments; Moonshine tiny (English, default) or Parakeet TDT 0.6B v3 (accurate) transcribes them. Any sample rate is accepted (resampled to 16 kHz); 8 kHz phone audio including G.711 μ-law WAV works.
- TTS: Kokoro-82M v1.0 (fp32, Apache-2.0), 28 English voices (default
af_heart), 24 kHz, run by the separate programallternit-tts(GPL-3.0-or-later,services/voice-tts), which the service starts as a child process.
/speak) are specified in docs/specs/tts-product.md.
Status: Implementation IMPLEMENTED (STT + TTS) / Exposure INTERNAL.
Models
Model packs download on first use (sha256-verified, resumable) into~/.allternit/models/voice/<pack>/; nothing model-related ships in the
installer. Poll GET /v1/models for state (missing, downloading with
pct, ready, error).
- Packs download from our own mirror,
https://runtime.allternit.com/voice-packs/v1/<file>, and fall back to the upstream URL (GitHub or Hugging Face) if the mirror fails (logged once). The same pinned sha256 is checked either way.ALLTERNIT_VOICE_MODEL_BASEoverrides the base and is then used alone, at<base>/<asset>. See Owned downloads. ALLTERNIT_VOICE_THREADSsets inference threads (default 2), CPU provider — sized for a ~5-year-old 8 GB laptop.ALLTERNIT_VOICE_MODEL_DIRmoves the pack directory.POST /v1/models/<pack>starts a download ahead of first use.
Licences
Parakeet attribution: Speech recognition by Parakeet TDT 0.6B v3 by
NVIDIA, licensed under CC-BY-4.0. Show it wherever the accurate option is
offered. Full list:
services/voice/THIRD_PARTY_NOTICES.md.
Base URL
The service binds to127.0.0.1 on PORT (default 8001).
sherpa-onnx default static feature) on macOS, Windows (static
CRT) and Linux. Desktop ships two files in resources/bin:
allternit-voice-service (STT and the API, no GPL code, checked by
scripts/check-voice-no-gpl.sh) and allternit-tts (Kokoro TTS,
GPL-3.0-or-later, started by the service as a child process that exits with
it). No dylib/DLL accompanies them.
REST endpoints
Health check
Transcribe audio
Send the audio as a multipart form upload (audio field; optional
language, model=moonshine|parakeet). WAV containers of any sample rate
are decoded and resampled to 16 kHz; raw s16le 16 kHz PCM is also accepted.
Speak text
small pack (~39 MB) and the first TTS
request the tts pack (~350 MB, a few minutes on a typical connection,
including unpacking); poll GET /v1/models for progress, or start them
early with POST /v1/models/<pack>. Gizzi Code’s /voice and Desktop dictation wait up to 5 minutes
for that first request.
Performance
Measured withexamples/voice_bench.rs (CPU only, 2 threads, 40
LibriSpeech test-clean utterances; clean 16 kHz, phone line, and raw 8 kHz
μ-law). Per-host results: services/voice/bench/results-<host>.jsonl.
Faster first speech
Kokoro takes a fraction of a second to a couple of seconds to render the first words on a weak CPU. The voice service shortens that wait four ways:- Short first chunk. The first sentence is cut after 2–4 words, so the first audio is a very small render.
- Warm start. On a server that takes phone calls, set
ALLTERNIT_VOICE_WARM=1so the voice service loads its speech models when it starts, not on the first call; the first call after a restart is then as quick as any other. The desktop app leaves it off and loads the models the first time you use voice. - Phrase cache. Common acknowledgements (“Sure.”, “Okay.”, “Got it.”) and the lines a call opens with are rendered once per voice and kept in
phrase-cache/inside the model directory. A cached phrase plays in about a millisecond. The cache is capped byALLTERNIT_VOICE_PHRASE_CACHE_MB(default 64,0turns it off), and only fixed phrases are stored; ordinary replies are never written to disk. - Warm start. The speech engine renders a short sentence at startup, so your first reply isn’t a cold start.
- Fillers. A Voice Session started with
fillers: truesays a short phrase such as “One moment.” if the reply hasn’t started 1.2 seconds after you stop talking, and another every 6 seconds (up to 3) while a slow reply is still pending. Phone calls turn this on; the in-app voice session leaves it off. Seeservices/voice/spec/VOICE_SESSION.mdfor the protocol.