Production-ready FastAPI and WebSocket service for VoxCPM2, grown in the open — deploy it anywhere, fork it, improve it:
- REST synthesis via
/v1/speech - streaming synthesis via
/v1/stream - optional transcription via
/v1/transcribe - Linux CUDA auto-selection for
nano-vllm-voxcpm - official
voxcpmbackend support for prompt and reference audio - macOS Apple Silicon compatibility patches for VoxCPM2 CPU inference
- a matching Tauri desktop client released alongside the API
Every tagged release publishes three separate artifact families:
voxcpm2_api-<version>-py3-none-any.whlThe API package with FastAPI, WebSocket endpoints, Docker support, and the built-in compatibility layer.voxcpm2_compat-<version>-py3-none-any.whlThe standalone compatibility wrapper for custom Python integrations that need the macOS and CPU safety patches without the API service.voxcpm2_api_macos-<tag>-<arch>.tar.gzA standalone macOS embedded API bundle for local packaging or custom launchers.VoxCPM2-ui-macos-<tag>-<arch>.zipThe macOS.appbundle for the Tauri desktop client.VoxCPM2-ui-macos-<tag>-<arch>.dmgThe drag-and-drop macOS installer for the desktop client.
pip install "voxcpm2-api[voxcpm]"If you only want the compatibility wrapper for your own VoxCPM2 code:
pip install voxcpm2-compatWheels and sdists are also attached to every GitHub release.
python3 -m venv .venv
. .venv/bin/activate
pip install -e ".[dev,voxcpm]"
cp .env.example .env
voxcpm2-apiThe helper scripts do the same:
./scripts/bootstrap.sh
./scripts/run-dev.shThe default Docker image now installs the official voxcpm backend automatically.
cp .env.example .env
docker compose up --buildThe service keeps one API surface and swaps runtimes underneath it:
- Linux + NVIDIA CUDA: prefers
nano-vllm-voxcpmfor plain text synthesis - macOS, Windows, generic Linux, or conditioned requests: uses the official
voxcpmPython package - prompt or reference audio requests: always route to the official
voxcpmbackend
VoxCPM2 is currently safest on macOS when it runs on CPU:
- MPS is disabled because VoxCPM2 uses
bfloat16and the public runtime is not stable on Apple MPS - the API patches PyTorch
scaled_dot_product_attentionfor the exact CPU decoding path used by VoxCPM2 - OpenMP duplicate-library crashes are suppressed for mixed native dependency stacks
These patches are built into voxcpm2-api and published separately as voxcpm2-compat.
All runtime configuration is environment-driven.
Important variables:
VOXCPM2_MODEL_IDVOXCPM2_MODEL_PATHVOXCPM2_MODEL_CACHE_DIRVOXCPM2_PREFER_BACKENDVOXCPM2_LOAD_DENOISERVOXCPM2_OPTIMIZE_MODELVOXCPM2_LOCAL_FILES_ONLYVOXCPM2_STARTUP_LOAD_MODELVOXCPM2_HF_ENDPOINTVOXCPM2_CORS_ORIGINSVOXCPM2_NANOVLLM_DEVICES
See ./.env.example for the full template.
curl http://localhost:8000/health
curl http://localhost:8000/api/status
curl http://localhost:8000/v1/runtimeWith the server running, open the interactive OpenAPI docs; no model download is needed.
GET /v1/runtime reports selected_backend (chosen for a probe request: voxcpm, nanovllm, or unavailable) and requested_backend (the configured VOXCPM2_PREFER_BACKEND preference).
It also includes the resolved model_source, the hardware probe, and backend_status (a per-backend map of available and reason).
/health and /api/status wrap the same snapshot as {"status": "ok", "runtime": ...}.
Return WAV:
curl -X POST http://localhost:8000/v1/speech \
-H 'Content-Type: application/json' \
-d '{"text":"Hello from VoxCPM2","response_format":"wav"}' \
--output out.wavReturn base64:
curl -X POST http://localhost:8000/v1/speech \
-H 'Content-Type: application/json' \
-d '{"text":"Hello from VoxCPM2","response_format":"base64"}'Prompt continuation:
{
"text": "Continue this in the same voice.",
"prompt_text": "Earlier context",
"prompt_audio_base64": "<wav-as-base64>",
"reference_audio_base64": "<optional-reference-wav>",
"response_format": "base64"
}Connect to /v1/stream, send one JSON request, then read:
session.started- repeated
audio.chunk audio.completed
Example payload:
{
"text": "Stream this sentence.",
"chunk_format": "pcm16"
}curl -X POST http://localhost:8000/v1/transcribe \
-H 'Content-Type: application/json' \
-d '{"audio_base64":"<wav-as-base64>"}'The repository also contains a Tauri desktop app in ./voxcpm2-ui.
On packaged macOS builds:
- the app auto-starts its bundled local API on
http://127.0.0.1:4000 - the top
Connectfield still lets you switch to any other API, for example a manually started development server onhttp://127.0.0.1:8000 - the desktop bundle does not require a preinstalled Python environment
For local packaging or release verification, build the embedded API bundle first:
./scripts/build-macos-embedded-api.shLocal development:
cd voxcpm2-ui/src-tauri
cargo tauri dev. .venv/bin/activate
pytest
ruff check .
./scripts/build-release.shThe default pytest run stays offline: it does not download the VoxCPM2
model and does not require CUDA or a GPU.
tests/test_app.py— uses aFakeRuntime; no model, no networktests/test_audio.py— pure audio helpers; no model, no networktests/test_hardware.py— mocks the hardware probe; no model, no networktests/test_compat.py— needstorchinstalled (pytest.importorskip("torch")) but runs on CPU; it is skipped automatically when torch is absent
Tests that exercise the real voxcpm backend, model download, or CUDA paths are
not part of the default suite. To keep unit tests hermetic, leave these
.env.example values at their defaults (unset or false):
VOXCPM2_STARTUP_LOAD_MODEL=false— do not load the model at startupVOXCPM2_LOCAL_FILES_ONLY=false— allow tests to stay on mocked runtimesVOXCPM2_PREFER_BACKEND=auto— do not force a backend that requires a GPU
CI runs on GitHub Actions for Linux and macOS. Tagged releases automatically publish:
- the API wheel and sdist
- the standalone compatibility wheel and sdist
- the standalone macOS embedded API bundle
- the macOS Tauri desktop
.appZIP - the macOS Tauri desktop
.dmg
This repo is part of the shiftbloom studio garden — an open digital studio in Hamburg building digital public good, commit by commit, in public, with anyone who wants to help. Contributions are welcome; the door is propped open.
- studio — shiftbloom.studio
- open books — opencollective.com/shiftbloom-studio
BLOOM YOUR CODE. BUILD PUBLIC GOOD.
Every commit helps something bloom.
AGPL-3.0-only. See ./LICENSE.