Spaces:
Sleeping
title: OmniVoice TTS
emoji: 🎙️
colorFrom: indigo
colorTo: green
sdk: docker
pinned: false
license: apache-2.0
short_description: In-process OmniVoice TTS — Urdu / Punjabi / 600+ languages
suggested_hardware: t4-small
suggested_storage: small
OmniVoice TTS — Self-hosted
Runs k2-fsa/OmniVoice directly on this Space's GPU (T4 / dedicated). No
upstream proxying — the model is loaded in-process at startup.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | / |
Service descriptor (JSON, lists languages / attributes) |
| GET | /health |
Liveness probe |
| POST | /tts |
One-shot WAV (audio/wav, 24 kHz mono int16) |
| POST | /tts/stream |
Chunked WAV (header + raw PCM tail) — same JSON body |
| POST | /tts/clone |
Ad-hoc voice cloning (multipart: text, ref_audio, ref_text?) |
| POST | /voices |
Register a voice once (multipart: name, ref_audio, ref_text?) |
| GET | /voices |
List cached voice ids |
| DELETE | /voices/{name} |
Free a registered voice |
| WS | /ws/tts |
Real-time PCM frames + JSON status messages |
Request body (/tts and /tts/stream)
{
"text": "آپ کا شکریہ",
"language": "Urdu",
"gender": "Female",
"age": "Young Adult",
"pitch": "Moderate",
"style": "Auto",
"accent": "Auto",
"dialect": "Auto",
"speed": 1.0,
"nfe_steps": 32,
"guidance": 2.0,
"denoise": true
}
languageaccepts the English label ("Urdu","Panjabi","Western Panjabi", …) or"Auto".- Voice-design attributes accept friendly aliases (
"female","young","low") or the canonical bilingual labels from the upstream Gradio demo ("Female / 女","Young Adult / 青年"). instruct(string) optionally overrides the auto-built attribute string with a free-form description.
WebSocket protocol (/ws/tts)
client → server (text) : <TTSRequest JSON>
server → client (text) : {"type":"started","sample_rate":24000}
server → client (binary) : raw int16 PCM frames (~0.5 s each)
server → client (text) : {"type":"complete","duration_s":1.23}
On error: {"type":"error","message":"..."} then close.
Voice cloning
Two modes:
Ad-hoc (re-clones every request)
curl -X POST https://<space>.hf.space/tts/clone \
-F text="کلوننگ کا تجربہ" \
-F language=Urdu \
-F ref_audio=@reference.wav \
-F ref_text="ریفرنس آڈیو کا متن" \
--output cloned.wav
Register once, reuse via voice_id (recommended)
Compute the clone prompt a single time, then synthesize unlimited utterances in that voice without re-uploading or re-encoding the reference:
# 1. Register the voice ONCE (name it whatever you like)
curl -X POST https://<space>.hf.space/voices \
-F name=narrator_urdu \
-F ref_audio=@reference.wav \
-F ref_text="ریفرنس آڈیو کا متن"
# → {"voice_id":"narrator_urdu","voices_cached":1,"max_voices":50}
# 2. Reuse it on /tts, /tts/stream, or /ws/tts — just add "voice_id"
curl -X POST https://<space>.hf.space/tts \
-H 'Content-Type: application/json' \
-d '{"text":"آپ کا شکریہ","language":"Urdu","voice_id":"narrator_urdu"}' \
--output out.wav
curl https://<space>.hf.space/voices # list cached voices
curl -X DELETE https://<space>.hf.space/voices/narrator_urdu # free it
Notes:
- Re-registering the same
nameoverwrites it (idempotent). - An unknown
voice_idreturns 404 — register first. - The cache is in-process and in-memory: voices are lost on restart/redeploy, and the least-recently-used voice is evicted once
OMNIVOICE_MAX_VOICES(default 50) is exceeded. - Omitting
ref_textat registration triggers Whisper ASR, so it requiresOMNIVOICE_LOAD_ASR=1.
Configuration
Environment variables (set in the Space settings):
| Variable | Default | Purpose |
|---|---|---|
OMNIVOICE_MODEL |
k2-fsa/OmniVoice |
HF repo id or local path |
OMNIVOICE_DEVICE |
cuda (auto-falls-back CPU) |
torch device for the model |
OMNIVOICE_LOAD_ASR |
1 |
Set 0 to skip whisper download (saves ~1 GB) |
OMNIVOICE_MAX_VOICES |
50 |
Max registered voices kept in memory (LRU-evicted) |
LOG_LEVEL |
INFO |
Python logging level |
PORT |
7860 |
HF Spaces standard port |
Cold start
First request after a cold boot triggers the model download (2 GB to 30 s on T4). Subsequent requests are ~1–3 s/utterance for short Urdu / Punjabi sentences. The voice-agent client already retries 502/503/504 with backoff, so cold starts are absorbed silently./data/.cache/huggingface) and weight load (
Pushing this Space
# From the repo root
huggingface-cli login
git -C deployments/omnivoice_space init
git -C deployments/omnivoice_space remote add origin https://huggingface.co/spaces/ebitlogix/omnivoice-tts
git -C deployments/omnivoice_space add .
git -C deployments/omnivoice_space commit -m "OmniVoice TTS — self-hosted FastAPI"
git -C deployments/omnivoice_space push -u origin main
After push, set hardware to t4-small (or higher) in the Space's "Settings → Hardware" tab.