--- 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`) ```json { "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 } ``` - `language` accepts 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) : 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) ```bash curl -X POST https://.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: ```bash # 1. Register the voice ONCE (name it whatever you like) curl -X POST https://.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://.hf.space/tts \ -H 'Content-Type: application/json' \ -d '{"text":"آپ کا شکریہ","language":"Urdu","voice_id":"narrator_urdu"}' \ --output out.wav curl https://.hf.space/voices # list cached voices curl -X DELETE https://.hf.space/voices/narrator_urdu # free it ``` Notes: - Re-registering the same `name` overwrites it (idempotent). - An unknown `voice_id` returns **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_text` at registration triggers Whisper ASR, so it requires `OMNIVOICE_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 `/data/.cache/huggingface`) and weight load (~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. ## Pushing this Space ```bash # 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.