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 program allternit-tts (GPL-3.0-or-later, services/voice-tts), which the service starts as a child process.
Voice cloning is not part of this service. The remaining product surfaces (Desktop speak button, voice picker UI, Gizzi /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_BASE overrides the base and is then used alone, at <base>/<asset>. See Owned downloads.
  • ALLTERNIT_VOICE_THREADS sets inference threads (default 2), CPU provider — sized for a ~5-year-old 8 GB laptop.
  • ALLTERNIT_VOICE_MODEL_DIR moves 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 to 127.0.0.1 on PORT (default 8001).
The sherpa-onnx and onnxruntime native libraries link statically (crate 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

The first STT request downloads the 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 with examples/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=1 so 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 by ALLTERNIT_VOICE_PHRASE_CACHE_MB (default 64, 0 turns 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: true says 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. See services/voice/spec/VOICE_SESSION.md for the protocol.