A self-contained Docker image wrapping VibeVoice-API — a Python/PyTorch implementation of Microsoft's VibeVoice speech synthesis model. Exposes an OpenAI-compatible REST API and a dark HTML WebUI for zero-shot voice cloning TTS. Runs entirely on a single consumer GPU; no multi-GPU setup required.
Docker Hub: k8bit/vibevoice-api-gpu
Upstream: github.com/vibevoice-community/VibeVoice-API
The image bundles:
/v1/audio/speech endpoint. Imports VibeVoiceForConditionalGenerationInference directly via the vibevoice-community/VibeVoice package./, proxies /v1/ to uvicorn, and serves /voices/ for direct audio file access.Model weights are downloaded from HuggingFace at container first start and cached to a mounted volume. Nothing is baked into the image.
| Variant | VIBEVOICE_MODEL_VARIANT | Source | Download | VRAM | Quality |
|---|---|---|---|---|---|
| VibeVoice 1.5B | 1.5b (default) | vibevoice/VibeVoice-1.5B | ~3 GB | ~6–8 GB | Good |
| VibeVoice 7B (4-bit nf4) | 7b-4bit | DevParker/VibeVoice7b-low-vram | ~6.2 GB | ~6.6 GB | Very Good |
Both variants fit comfortably on a single 24 GB GPU (e.g. RTX 3090/4090). The 7B nf4 model offers noticeably better naturalness and prosody at essentially the same VRAM cost as the 1.5B in full precision. The 4-bit quantisation uses bitsandbytes nf4 and is loaded directly from pre-quantised HuggingFace weights — no on-the-fly quantisation.
Unlike most TTS systems, VibeVoice requires no reference transcript for voice cloning. It is a zero-shot cloner: point it at any clean WAV file and it will reproduce the speaker's voice. Just supply the audio.
No CPU-only mode — this image requires a CUDA-capable GPU.
docker run -d \
--name vibevoice-api \
--runtime=nvidia \
--gpus all \
--shm-size=2g \
-p 8889:8889 \
-v /your/models:/models \
-v /your/voices:/voices \
k8bit/vibevoice-api-gpu:latest
On first start the 1.5B model (~3 GB) downloads to /models. Subsequent starts reuse the cache and load in 60–90 seconds while PyTorch initialises. Access the WebUI at http://localhost:8889/.
To use the 7B 4-bit model instead:
docker run -d \
--name vibevoice-api-7b \
--runtime=nvidia \
--gpus all \
--shm-size=2g \
-p 8889:8889 \
-v /your/models:/models \
-v /your/voices:/voices \
-e VIBEVOICE_MODEL_VARIANT=7b-4bit \
k8bit/vibevoice-api-gpu:latest
| Variable | Default | Description |
|---|---|---|
VIBEVOICE_MODEL_VARIANT | 1.5b | Model to run: 1.5b or 7b-4bit |
VIBEVOICE_HF_REPO | (set by variant) | Override the HuggingFace repo. Leave empty unless pointing at a custom fork or fine-tune. |
VIBEVOICE_MODEL | (set by variant) | Override the local model path. Leave empty to use the variant default. |
VIBEVOICE_DEVICE | auto | PyTorch device: auto (CUDA if available), cuda, or cpu |
| Variable | Default | Description |
|---|---|---|
VIBEVOICE_DDPM_STEPS | 10 | Diffusion sampling steps (5–50). Lower = faster; higher = better quality. 10 is a good default for real-time use. |
VIBEVOICE_SEED | 42 | Default RNG seed for the diffusion noise process. Produces consistent output for the same text and voice. Set to 0 for a random seed on every request. |
VIBEVOICE_MAX_CONCURRENCY | 2 | Maximum simultaneous synthesis requests. Each holds the GPU during its diffusion pass. |
VIBEVOICE_SAMPLE_RATE | 24000 | Output sample rate in Hz. |
Every response passes through a two-stage pipeline before being returned:
| Variable | Default | Description |
|---|---|---|
NORM_TARGET_DB | -1.0 | Peak normalisation ceiling in dBFS. -1.0 leaves 1 dB of headroom. Set to 0.0 for full scale, or lower (e.g. -6.0) for more headroom. |
SILENCE_SEC | 0.5 | Seconds of digital silence prepended to every WAV. Useful for playout systems that need a brief buffer before speech begins. Set to 0 to disable. |
| Variable | Default | Description |
|---|---|---|
VIBEVOICE_REQUIRE_API_KEY | 0 | Set to 1 to require a Bearer token on all /v1/ requests. |
VIBEVOICE_ADMIN_TOKEN | (empty) | Admin token for managing API keys via POST /v1/admin/keys. |
| Variable | Default | Description |
|---|---|---|
HF_TOKEN | (empty) | HuggingFace access token. Not required for any default model — both are public. Only needed for private/gated repos. |
HF_HOME | /cache/huggingface | HuggingFace cache directory. Mount a persistent volume here to avoid re-downloading tokeniser and config files. |
| Mount | Purpose |
|---|---|
/models | Persistent model weights. Each variant uses its own subdirectory (vibevoice-1.5B or vibevoice-7b-4bit/4bit), so switching variants does not delete the previous download. |
/voices | Voice reference library. WAV files placed here are automatically registered as voice aliases (filename stem = alias name). Shared across TTS containers. |
/cache/huggingface | HuggingFace metadata cache. Avoids re-downloading tokeniser config on each start. Optional but recommended. |
POST /v1/audio/speech{
"model": "vibevoice-1.5b",
"input": "The quick brown fox.",
"voice": "kate",
"ddpm_steps": 20,
"cfg_scale": 1.5,
"seed": 42
}
Returns audio/wav. Fields:
| Field | Required | Description |
|---|---|---|
input | yes | Text to synthesise |
model | yes | vibevoice-1.5b or vibevoice-7b-4bit (informational; one model is loaded per container) |
voice | no | Voice alias — stem of a WAV file in /voices (e.g. kate for kate.wav) |
voice_path | no | Absolute container path to a WAV reference file (e.g. /voices/kate.wav) |
voice_data | no | Base64 / data-URL encoded reference audio |
speakers | no | Array of voice aliases or paths for multi-speaker dialog |
response_format | no | wav (default), mp3, opus, aac — non-WAV formats require ffmpeg |
speed | no | Speed multiplier, 0.25–4.0 |
cfg_scale | no | Classifier-free guidance scale (default 1.3) |
ddpm_steps | no | Diffusion steps for this request, overrides server default |
seed | no | RNG seed for this request. 0 = random; any other value = reproducible. Overrides VIBEVOICE_SEED env. |
Voice cloning note: VibeVoice is a zero-shot cloner. Unlike ICL-based systems (e.g. Qwen3-TTS), no reference transcript is needed — the model infers speaker characteristics directly from the audio signal. A 5–30 second clean mono recording at 16–48 kHz works well.
GET /health → {"status":"ok","variant":"1.5b","model":"/models/..."}
GET /v1/models → OpenAI-compatible model list
GET /v1/voices/aliases → {"aliases":["kate","james",...],"count":2}
curl http://localhost:8889/v1/audio/speech \
-H 'Content-Type: application/json' \
-d '{"model":"vibevoice-1.5b","input":"Hello from VibeVoice."}' \
-o speech.wav
Place kate.wav in your /voices volume, then:
curl http://localhost:8889/v1/audio/speech \
-H 'Content-Type: application/json' \
-d '{
"model": "vibevoice-1.5b",
"input": "This is a cloned voice.",
"voice": "kate",
"seed": 42
}' -o clone.wav
curl http://localhost:8889/v1/audio/speech \
-H 'Content-Type: application/json' \
-d '{
"model": "vibevoice-1.5b",
"input": "Higher quality with more diffusion steps.",
"voice_path": "/voices/kate.wav",
"ddpm_steps": 30,
"cfg_scale": 1.8
}' -o clone_hq.wav
curl http://localhost:8889/v1/audio/speech \
-H 'Content-Type: application/json' \
-d '{
"model": "vibevoice-1.5b",
"input": "Speaker 1: Good morning.\nSpeaker 2: Morning! How are you?",
"speakers": ["kate", "james"]
}' -o dialog.wav
Pin a seed to get identical output for the same prompt across multiple runs:
for i in 1 2 3; do
curl http://localhost:8889/v1/audio/speech \
-H 'Content-Type: application/json' \
-d '{"model":"vibevoice-1.5b","input":"Take one.","voice":"kate","seed":100}' \
-o "take_${i}.wav"
done
# All three files will be byte-identical.
The WebUI is served at http://<host>:8889/ and requires no login.
/voices volume.The header shows a status indicator (loading / ready) and a chip displaying the active variant (e.g. 7b-4bit) once the model finishes loading.
services:
vibevoice-api:
image: k8bit/vibevoice-api-gpu:latest
runtime: nvidia
environment:
NVIDIA_VISIBLE_DEVICES: all
NVIDIA_DRIVER_CAPABILITIES: compute,utility
VIBEVOICE_MODEL_VARIANT: "1.5b" # or "7b-4bit"
VIBEVOICE_DDPM_STEPS: "10"
VIBEVOICE_SEED: "42"
NORM_TARGET_DB: "-1.0"
SILENCE_SEC: "0.5"
ports:
- "8889:8889"
volumes:
- ./models:/models
- ./voices:/voices
- ./hf-cache:/cache/huggingface
shm_size: "2gb"
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8889/health"]
interval: 30s
timeout: 10s
start_period: 300s
retries: 10
Any WAV file in your /voices mount is automatically registered as a voice alias on container start. The filename stem becomes the alias:
voices/
kate.wav # alias: "kate"
announcer.wav # alias: "announcer"
deep_male.wav # alias: "deep_male"
For best cloning results:
No companion .txt transcript file is needed. VibeVoice infers voice characteristics directly from the audio.
The diffusion decoder runs a fixed number of denoising steps per generation. The default of 10 balances speed and quality well for most use cases. If output sounds slightly rough or unnatural, try increasing steps. Diminishing returns typically set in around 30–40.
| Steps | Relative time | Quality |
|---|---|---|
| 5 | Fastest | Acceptable for low-latency use |
| 10 | 1× (default) | Good — broadcast-ready |
| 20 | ~2× | Better naturalness |
| 30–40 | ~3–4× | Excellent — close to ceiling |
| 50 | ~5× | Marginal gain over 30–40 |
These multipliers are approximate and vary with text length.
flash-attn package is installed. Falls back to SDPA transparently. The image does not pre-install flash-attn due to its long compile time; you can extend the image to add it.VIBEVOICE_MAX_CONCURRENCY=2 allows requests to queue without the server rejecting them. On a single-GPU setup, they execute serially; there is no real parallelism for GPU-bound work.The build script generates a multi-stage-free Dockerfile targeting nvidia/cuda:12.8.0-runtime-ubuntu22.04:
vibevoice (community model code) and vibevoice-api (server package) from their respective GitHub reposbitsandbytes for 4-bit quantised model loadingmain.py), nginx config, entrypoint, and static WebUICUDA architectures compiled into the PyTorch wheel: sm_75, sm_80, sm_86, sm_89 (Turing, Ampere, Ada Lovelace).
bash build_vibevoice_api_gpu.sh
This image packages VibeVoice-API and the vibevoice-community/VibeVoice model code. Refer to the upstream repositories for licence terms. The VibeVoice-1.5B and VibeVoice-7B model weights are subject to their respective HuggingFace repository licences. The 4-bit quantised weights at DevParker/VibeVoice7b-low-vram are released under the MIT licence.
Content type
Image
Digest
sha256:a9785c364…
Size
5.4 GB
Last updated
3 months ago
docker pull k8bit/vibevoice-api-gpu