feat: add OpenAI-compatible Chatterbox TTS service
This commit is contained in:
commit
38a2a48f28
9 changed files with 620 additions and 0 deletions
53
docs/superpowers/specs/2026-08-08-chatterbox-tts-design.md
Normal file
53
docs/superpowers/specs/2026-08-08-chatterbox-tts-design.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# Chatterbox TTS service design
|
||||
|
||||
## Goal
|
||||
|
||||
Run ResembleAI Chatterbox as an independent GPU-backed text-to-speech service,
|
||||
available at `https://chatterbox.dimensionlab.net`, while preserving the
|
||||
existing Kokoro service unchanged.
|
||||
|
||||
## Architecture
|
||||
|
||||
`chatterbox-tts` is a small Python FastAPI application in
|
||||
`/home/vince/ai/apps/chatterbox-tts`. A user-level systemd unit runs it on
|
||||
loopback port 8881. Caddy terminates TLS for `chatterbox.dimensionlab.net` and
|
||||
reverse-proxies that hostname to `127.0.0.1:8881`.
|
||||
|
||||
The application loads the English `ResembleAI/chatterbox` model on CUDA lazily.
|
||||
It keeps the model resident while requests are active, then frees its GPU
|
||||
allocation after five minutes without a synthesis request. A single-request GPU
|
||||
lock serializes synthesis and model unload operations. This lets it coexist
|
||||
with the existing Kokoro service and other GPU workloads without competing
|
||||
requests exhausting VRAM.
|
||||
|
||||
## API contract
|
||||
|
||||
The service provides:
|
||||
|
||||
- `POST /v1/audio/speech`, accepting the OpenAI speech request fields
|
||||
`model`, `input`, `voice`, `response_format`, and `speed`.
|
||||
- `GET /v1/models`, returning the available Chatterbox model identifier.
|
||||
- `GET /health`, returning a small health response without forcing model load.
|
||||
|
||||
`POST /v1/audio/speech` returns generated WAV audio. `model` defaults to
|
||||
`chatterbox`; `response_format` accepts `wav`; and `input` is capped at 2,000
|
||||
characters. The request's `voice` field is a path relative to the dedicated
|
||||
`/home/vince/ai/apps/chatterbox-tts/voices` directory. The resolved path must
|
||||
remain within that directory, exist, and be readable by the service user before
|
||||
it is supplied as Chatterbox's reference clip. Invalid, missing, or escaping
|
||||
paths fail with a clear 400 response. No upload endpoint or voice catalogue is
|
||||
part of this first version.
|
||||
|
||||
## Failure handling
|
||||
|
||||
Malformed requests, unsupported formats, invalid paths, model-download/load
|
||||
failures, and synthesis errors produce JSON errors. A process crash is restarted
|
||||
by systemd. Caddy continues to expose only the public hostname; the Python
|
||||
service is not publicly bound.
|
||||
|
||||
## Verification
|
||||
|
||||
Verify the unit reaches active status, loopback port 8881 serves `/health`, and
|
||||
the public hostname reaches it through Caddy. Exercise `/v1/models` and a
|
||||
short `/v1/audio/speech` request using a known local reference WAV, checking
|
||||
that the response is valid WAV audio.
|
||||
Loading…
Add table
Add a link
Reference in a new issue