OpenAI-compatible text-to-speech API server with zero-shot voice cloning, powered by CosyVoice 3. Works well with Russian and English text, including mixed-language input.
On macOS with Apple Silicon, run locally to take advantage of Metal (MPS) GPU acceleration. Docker cannot pass through the Metal GPU, so local execution is significantly faster.
./run.shOn first run the script will:
- Install uv if missing
- Clone the CosyVoice repository
- Install Python dependencies
- Download the model from HuggingFace (~8 GB)
Server starts on http://localhost:8020
docker build -t cosyvoice-api .
docker run -p 8020:8020 --env-file .env cosyvoice-apiNote: The Docker image is large (~15 GB) because it bundles the model weights. Docker runs on CPU only. For NVIDIA GPU support, use
--gpus allwith an NVIDIA runtime installed.
Drop-in replacement for POST /v1/audio/speech:
curl -s http://localhost:8020/v1/audio/speech \
-H "Content-Type: application/json" \
-d '{"input": "Hello, world!", "voice": "default"}' \
-o speech.wavWorks with the official OpenAI Python client:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8020/v1", api_key="unused")
response = client.audio.speech.create(
model="cosyvoice3-0.5b",
voice="default",
input="Hello, world!",
response_format="wav",
)
response.stream_to_file("speech.wav")Upload a voice sample (WAV, 3-15s) for zero-shot cloning:
curl -s -X POST http://localhost:8020/tts \
-F "text=Hello from a cloned voice!" \
-F "voice=@sample.wav" \
-o cloned.wavcurl -s http://localhost:8020/v1/audio/speech \
-H "Content-Type: application/json" \
-d '{"input": "This is exciting!", "instructions": "Speak with a happy and excited tone"}' \
-o happy.wavAvailable presets via /tts endpoint: happy, sad, angry, whisper, loud, slow, fast, robot.
curl http://localhost:8020/voicesbash record.sh my_voiceRecords using sox (installed via Homebrew if missing) and saves to voices/my_voice.wav. Set VOICE=my_voice in .env to use as default. On Linux, install sox manually via your package manager.
Copy .env.example to .env and adjust as needed:
| Variable | Default | Description |
|---|---|---|
PORT |
8020 | Server port |
USE_RL |
true | Use RL-tuned model variant |
COSYVOICE_DIR |
CosyVoice | Path to CosyVoice repo |
MODEL_DIR |
CosyVoice/pretrained_models/Fun-CosyVoice3-0.5B | Path to model weights |
DEFAULT_VOICE |
CosyVoice/asset/zero_shot_prompt.wav | Default voice sample |
VOICE |
default | Active voice name |
CosyVoice supports inline tags in the text for expressive speech:
[breath], [laughter], [sigh], [cough], [noise], [lipsmack], [mn]
- Languages: Russian + English (cross-lingual)
- Voice cloning: zero-shot from a 3-15s audio sample
- Formats: WAV, MP3
- GPU: Metal (MPS) on Apple Silicon, CUDA on NVIDIA, CPU fallback
- Model: Fun-CosyVoice3-0.5B-RL (~8 GB)
Text-to-speech powered by CosyVoice by FunAudioLLM (Apache-2.0 license).