OmniVoice_TTS_API / README.md
aspirant312's picture
Add clone-once voice registry (POST /voices + voice_id reuse)
912d5e5
|
Raw
History Blame Contribute Delete
5.4 kB
metadata
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
}
  • 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)   : <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 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

# 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.