This guide is for the engineers, ops teams, and architects who deploy, operate, extend, or train with Coqui TTS. It covers the system architecture, the model and config systems, deployment topologies, the training pipeline, security posture, and the internals needed to maintain or fork the project. End-user synthesis instructions live in the companion User Guide.
Important
This documentation describes Coqui TTS v0.22.0 at commit
dbf1a08(2024-02-10). The company that built Coqui (Coqui GmbH) has shut down, so this codebase is effectively frozen at this release and is now community-maintained. There will be no upstream patches for new PyTorch/transformersincompatibilities or security findings unless contributed by the community. Treat any deployment as running on unmaintained, archived software and plan dependency pinning and security mitigations accordingly.
1. Executive Summary
Coqui TTS is a PyTorch-based deep-learning toolkit for text-to-speech. It packages:
- A model zoo β ~70 pretrained TTS models, ~17 vocoders, and a voice-conversion model, registered in a single
TTS/.models.jsonmanifest, plus on-demand access to ~1100 Meta MMS/Fairseq voices. - Three runtime surfaces β a
ttsCLI (TTS/bin/synthesize.py), a Python API (TTS/api.py), and a Flask demo server (TTS/server/server.py, console scripttts-server). - A training stack β per-architecture model classes under
TTS/tts,TTS/vocoder,TTS/vc,TTS/encoder, driven by the externaltrainerpackage andcoqpitdataclass configs, with ready-made recipes underrecipes/.
| Attribute | Value |
|---|---|
| Version | 0.22.0 |
| Language | Python (β₯3.9, <3.12) |
| License (code) | MPL-2.0 |
| Core runtime | PyTorch β₯2.1, torchaudio |
| Config system | coqpit dataclasses (per-model config.json) |
| Training engine | external trainer package |
| Web layer | Flask (demo server) |
| Author | Eren GΓΆlge / Coqui |
| Source commit | dbf1a08 |
Note
The code is MPL-2.0, but individual models carry their own licenses spanning Apache-2.0, MPL, MIT, CC-BY-SA, CC-BY-NC-ND, and the bespoke CPML (XTTS β non-commercial). Licensing is per-model, not project-wide. See Β§5.4.
2. Architecture
2.1 High-level component map
βββββββββββββββββββββββββββββββββββββββββββββββ
text βββΆ Entry surface β tts (CLI) tts-server (Flask) TTS.api β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββ
β
βββββββββββΌβββββββββββ
β Synthesizer β TTS/utils/synthesizer.py
β (orchestrator) β
βββββ¬ββββββββ¬ββββββ¬ββββ
ββββββββββββββββββ β βββββββββββββββββ
βββββββββΌβββββββββ ββββββββββΌββββββββ βββββββββββΌβββββββββ
β tts_model β β vocoder model β β speaker encoder β
β TTS/tts/models β β TTS/vocoder β β TTS/encoder β
βββββββββ¬ββββββββββ ββββββββββββββββββ ββββββββββββββββββββ
β
ββββββββββΌββββββββββ βββββββββββββββββββββ
β ModelManager β β load_config β
β TTS/utils/manage β β TTS/config β (coqpit)
β download + cache β βββββββββββββββββββββ
ββββββββββ¬βββββββββββ
βΌ
TTS/.models.json (model registry) βββΆ remote model archives (HF / GitHub releases)
The Synthesizer (TTS/utils/synthesizer.py) is the orchestration hub. It loads a TTS model, an optional vocoder, and an optional speaker encoder, then exposes .tts() and .voice_conversion(). Both the CLI and the server construct a Synthesizer; the TTS.api.TTS class wraps it with a friendlier interface.
2.2 Package layout
| Path | Responsibility |
|---|---|
TTS/api.py |
High-level Python API (TTS class). |
TTS/bin/ |
Executables: synthesize.py (the tts CLI), train_tts.py, train_vocoder.py, train_encoder.py, dataset/compute utilities. |
TTS/tts/ |
Text-to-speech models (models/), neural layers (layers/), configs (configs/), datasets, and text/phoneme utilities (utils/text/). |
TTS/vocoder/ |
Vocoder models (MelGAN, HiFiGAN, WaveGrad, WaveRNN, UnivNet, β¦), layers, datasets. |
TTS/vc/ |
Voice-conversion models (FreeVC). |
TTS/encoder/ |
Speaker/voice encoder models (GE2E, ResNet, angular-loss). |
TTS/utils/ |
ModelManager (manage.py), Synthesizer (synthesizer.py), audio processing (audio/), downloads (download.py), generic utilities. |
TTS/config/ |
load_config() and base config classes (coqpit). |
TTS/server/ |
Flask demo server + HTML templates. |
TTS/model.py |
BaseTrainerModel β the abstract base every model inherits. |
recipes/ |
End-to-end training recipes per dataset (ljspeech, vctk, thorsten_DE, kokoro, β¦). |
notebooks/ |
Jupyter notebooks for dataset analysis and evaluation. |
docs/ |
Sphinx documentation sources. |
tests/ |
Unit, data, inference, and zoo (model-download) tests. |
2.3 The model abstraction
Every model inherits BaseTrainerModel (TTS/model.py), which extends TrainerModel from the external trainer package and requires three methods:
class BaseTrainerModel(TrainerModel):
@staticmethod
@abstractmethod
def init_from_config(config: Coqpit): ... # build the model from its config
@abstractmethod
def inference(self, input, aux_input={}) -> Dict: # returns {"model_outputs": ...}
@abstractmethod
def load_checkpoint(self, config, checkpoint_path, eval=False, strict=True, cache=False): ...
This uniform contract is why one Synthesizer can drive Tacotron2, VITS, XTTS, or a vocoder interchangeably β they all expose init_from_config / inference / load_checkpoint.
2.4 Model families
Coqui implements a broad set of architectures. Knowing which family a model belongs to tells you whether it needs a separate vocoder and what its inference cost looks like.
| Family | Type | Models | Needs vocoder? |
|---|---|---|---|
| Spectrogram (two-stage) | acoustic | Tacotron, Tacotron2, Glow-TTS, Speedy-Speech, Align-TTS, FastPitch, FastSpeech/2, SC-GlowTTS, Capacitron, OverFlow, Neural HMM, Delightful TTS | Yes |
| End-to-end | full | VITS, YourTTS, βTTS (XTTS), Tortoise, Bark | No |
| Vocoders | waveform | MelGAN, Multiband-MelGAN, ParallelWaveGAN, GAN-TTS discriminators, WaveRNN, WaveGrad, HiFiGAN, UnivNet | β |
| Speaker encoders | embedding | GE2E, Angular-loss, ResNet | β |
| Voice conversion | conversion | FreeVC | β |
Note
Two-stage models output a mel-spectrogram and are paired with a vocoder (each model declares a
default_vocoderin.models.json). If no vocoder is supplied, the Synthesizer falls back to Griffin-Lim, which is lower quality. End-to-end models (VITS/XTTS) skip the vocoder entirely.
3. The Model Registry & Manager
3.1 .models.json
TTS/.models.json is the canonical registry. It is a nested tree keyed by model_type β language β dataset β model_name. Each leaf describes one model:
"xtts_v2": {
"description": "XTTS-v2.0.3 by Coqui with 17 languages.",
"hf_url": ["https://.../model.pth", "https://.../config.json", "..."],
"model_hash": "10f92b55c512af7a8d39d650547a15a7",
"default_vocoder": null,
"license": "CPML",
"tos_required": true
}
Key fields:
| Field | Meaning |
|---|---|
hf_url / github_rls_url |
Download source(s). A list means a multi-file model directory. |
model_hash / model_hash |
MD5 checksum verified after download. |
default_vocoder |
Vocoder name to pair with (or null for end-to-end). |
license |
Per-model license string. |
tos_required |
If true, the user must accept terms before download (XTTS). |
commit, author, contact |
Provenance metadata. |
3.2 ModelManager (TTS/utils/manage.py)
ModelManager reads .models.json, resolves a model name to a download, fetches and verifies archives, and caches them. Responsibilities:
list_models()β enumerate the registry (backstts --list_models).download_model(name)β resolve, download, extract, and return local paths.model_info_by_idx/model_info_by_full_nameβ registry lookups.- Terms-of-service gate β raises
Exception: [!] You must agree to the terms of service to use this model.fortos_requiredmodels unlessCOQUI_TOS_AGREED=1. - Hash verification β
TTS/utils/download.pyraisesRuntimeError: The hash of {file} does not match.on a checksum mismatch.
3.3 Cache resolution
The model cache directory is resolved by get_user_data_dir() in TTS/utils/generic_utils.py:
| Priority | Source | Result |
|---|---|---|
| 1 | TTS_HOME env var |
$TTS_HOME/tts/ |
| 2 | XDG_DATA_HOME env var |
$XDG_DATA_HOME/tts/ |
| 3 | default | ~/.local/share/tts/ |
Tip
In containers and CI, set
TTS_HOMEto a mounted volume so model downloads (which can be hundreds of MB to several GB for XTTS/Bark/Tortoise) persist across runs and don't bloat the image layer or re-download on every start.
4. Configuration
Coqui has almost no global configuration β there is no central YAML or .env for the library itself. Behavior is driven two ways:
- Per-model config β each model ships a
config.jsonparsed into acoqpitdataclass viaTTS/config/load_config(). This holds audio settings (sample rate, mel parameters), model hyperparameters, dataset definitions, and inference options. When you run a released model, its config travels with the download; when you run your own, you pass--config_path. - Environment variables β the only three runtime env vars are below.
| Variable | Read in | Purpose |
|---|---|---|
TTS_HOME |
generic_utils.py |
Model cache base directory (priority 1). |
XDG_DATA_HOME |
generic_utils.py |
Model cache base directory (priority 2). |
COQUI_TOS_AGREED |
manage.py |
Set to 1 to pre-accept terms for gated models. |
4.1 Working with a model config
from TTS.config import load_config
config = load_config("path/to/config.json")
print(config.audio.sample_rate)
print(config.model) # architecture name
load_config() raises:
ModuleNotFoundError: [!] Config for {model_name} cannot be found.β unknown model config.TypeError: [!] Unknown config file type {ext}β config file is neither.jsonnor a supported type.
Note
Because config is a
coqpitdataclass, the schema is the Python class (e.g.Tacotron2Config,VitsConfig,XttsConfigunderTTS/tts/configs/), not a documented key list. To see every tunable for a model, read its*Configdataclass. This is the authoritative config reference for training and custom inference.
5. Security
Caution
Coqui TTS has several material security considerations. Because the project is unmaintained, you own these mitigations β there will be no upstream fix. Review this section before any production or multi-user deployment.
5.1 Unsafe model deserialization (pickle)
Model checkpoints are PyTorch .pth files loaded via torch.load() (through load_fsspec), which uses Python's pickle and can execute arbitrary code during deserialization. Combined with on-demand downloads from remote URLs, a tampered checkpoint is a remote-code-execution vector.
- Mitigation: Only load checkpoints from sources you trust. Verify the
.models.jsonchecksums (Coqui does this for registry models). For custom or third-party checkpoints, scan them and load in an isolated environment. Where possible on newer PyTorch, preferweights_only=Trueloading semantics. - Reference: community issue #4409 (Unsafe Deserialization of Model Checkpoints).
5.2 Archive extraction path traversal
Model archives are unpacked with extractall() in TTS/utils/download.py without sanitizing member paths, so a malicious archive could write files outside the cache directory (Zip-Slip).
- Mitigation: Only download models from the official registry/URLs. Run the process as a non-root user with a constrained
TTS_HOMEso any traversal is contained. - Reference: community issue #4409 (Path Traversal in Archive Extraction).
download.pyonly accepts.tar.gz,.tgz, and.zipand raisesNotImplementedErrorfor other formats β but does not guard member paths.
5.3 Demo server exposure
The Flask server (TTS/server/server.py) is for local experimentation:
- It binds to
host="::"(all interfaces) inapp.run(). - It has no authentication, rate limiting, or CSRF protection.
--debug trueenables Flask's debugger (Werkzeug), which must never be exposed publicly./api/ttssynthesizes arbitrary attacker-supplied text; a single globalLockserializes requests, so it is also trivially DoS-able by long inputs.
Warning
Never expose
tts-serverdirectly to untrusted networks. Front it with an authenticated reverse proxy, bind it tolocalhost, disable--debug, and cap request sizes. Treat it as a developer convenience, not a production service.
5.4 Model licensing
Licensing is per-model and some models are non-commercial:
| License | Examples | Commercial use |
|---|---|---|
| Apache-2.0 / MIT / MPL | most Tacotron2, VITS, HiFiGAN voices | Generally yes (verify) |
| CC-BY-SA 4.0 | openbible voices, some community voices | Share-alike conditions |
| CC-BY-NC-ND 4.0 | YourTTS, some VCTK | No (non-commercial) |
| CPML | XTTS v1.1 / v2 | No (non-commercial) |
Important
Always read the
licensefield from.models.json(ortts --model_info_by_name) before shipping a product that uses a Coqui voice. XTTS β the flagship model β is non-commercial CPML and is gated behind a terms-of-service acceptance (tos_required: true).
5.5 Defunct domain
The original coqui.ai domain is no longer controlled by the project after the company's shutdown (community issues #4418, #4392 report it as hijacked). Do not fetch models, configs, or scripts from coqui.ai; rely on the GitHub repository and the registry URLs (which point at coqui.gateway.scarf.sh and Hugging Face mirrors).
6. Deployment
6.1 Topologies
| Topology | How | When |
|---|---|---|
| Library embed | pip install TTS; call TTS.api.TTS in-process |
Batch synthesis, pipelines, apps. |
| CLI / batch | tts ... invoked per job |
Scripted/offline generation. |
| Demo server | tts-server --model_name ... behind a proxy |
Interactive internal tooling. |
| Docker | ghcr.io/coqui-ai/tts-cpu / GPU images |
Reproducible, isolated runs. |
6.2 Docker
docker run --rm -it -p 5002:5002 --entrypoint /bin/bash ghcr.io/coqui-ai/tts-cpu
python3 TTS/server/server.py --model_name tts_models/en/vctk/vits
GPU variants are published alongside the CPU image. Mount a volume at TTS_HOME to persist the model cache.
6.3 Deployment checklist
- [ ] Pin the Python interpreter to 3.9β3.11 (the package refuses 3.12+).
- [ ] Pin
transformersto the 4.x line (5.x breaks XTTS β see Β§8). - [ ] Pin
setuptoolsto a version that still shipspkg_resources. - [ ] Pre-download models into a persistent
TTS_HOMEvolume. - [ ] Set
COQUI_TOS_AGREED=1if (and only if) the model license permits your use. - [ ] Confirm each model's license fits your distribution model.
- [ ] If serving HTTP: bind to localhost, add auth, disable
--debug, cap input length. - [ ] Run as a non-root user with a constrained cache directory.
- [ ] Provision a GPU for XTTS/Bark/Tortoise workloads.
Tip
Capture a known-good environment with
python -m TTS.bin.collect_env_infoand store it next to your deployment manifests. Given the unmaintained dependency surface, an exact, reproducible set of versions is your most important operational artifact.
7. Training & Operations
7.1 Training entry points (TTS/bin/)
| Script | Purpose |
|---|---|
train_tts.py |
Train a TTS (acoustic / end-to-end) model. |
train_vocoder.py |
Train a vocoder. |
train_encoder.py |
Train a speaker encoder. |
tune_wavegrad.py |
Tune WaveGrad noise schedules. |
extract_tts_spectrograms.py |
Pre-extract spectrograms for two-stage training. |
compute_embeddings.py |
Compute speaker d-vector embeddings. |
compute_statistics.py |
Compute dataset audio statistics (normalization). |
compute_attention_masks.py |
Precompute attention masks. |
resample.py |
Resample a dataset to a target sample rate. |
remove_silence_using_vad.py |
Trim leading/trailing silence with VAD. |
find_unique_chars.py / find_unique_phonemes.py |
Build the character/phoneme set for a dataset. |
eval_encoder.py |
Evaluate a trained speaker encoder. |
collect_env_info.py |
Dump environment details for bug reports. |
7.2 Recipes
recipes/<dataset>/<model>/ holds ready-to-run training scripts (e.g. recipes/ljspeech/vits_tts, recipes/vctk/yourtts, recipes/thorsten_DE/...). A recipe wires a dataset config to a model config and calls the trainer. Start from the recipe closest to your data and adjust the config dataclass.
# Example shape of a recipe run
python recipes/ljspeech/vits_tts/train_vits.py
7.3 The training engine
Training is delegated to the external trainer package (trainer>=0.0.36). Models implement the BaseTrainerModel contract; trainer handles the loop, logging (terminal + TensorBoard), checkpointing, and distributed runs. Configs are coqpit dataclasses.
Caution
XTTS cannot be trained through the generic path.
TTS/tts/models/xtts.pyraisesNotImplementedError: XTTS has a dedicated trainer ...from its training hooks. Use the dedicated XTTS fine-tuning recipe/demo (TTS/demos/xtts_ft_demo/) instead. Likewise, Tortoise training is not implemented (NotImplementedError: 'Tortoise Training is not implemented').
7.4 Day-to-day operations
| Task | How |
|---|---|
| Inspect available voices | tts --list_models / --model_info_by_name |
| Clear/refresh a model | delete its folder under $TTS_HOME/tts/ and re-run |
| Monitor a training run | terminal logs + TensorBoard (written by trainer) |
| Serve a voice | tts-server --model_name <name> --port 5002 |
| Capture environment | python -m TTS.bin.collect_env_info |
8. Known Issues & Compatibility
The most common production problems stem from dependency drift, because the codebase is frozen but its dependencies move.
| Symptom | Cause | Fix |
|---|---|---|
ImportError: cannot import name 'isin_mps_friendly' from 'transformers.pytorch_utils' |
transformers too new |
Pin transformers>=4.33,<5 (#4406, #4420). |
AttributeError: 'GenerationConfig' object has no attribute 'do_stream' |
transformers 5.0 breaks XTTS streaming |
Pin transformers<5 (#4394). |
ModuleNotFoundError: No module named 'pkg_resources' |
new setuptools removed pkg_resources |
Install a setuptools that still provides it (#4410). |
| Install fails on Python 3.12+ | hard gate in setup.py |
Use Python 3.9β3.11 (#4416 requests 3.12+ support). |
| XTTS errors inside Docker | environment/transformers mismatch | Use the published image + pinned deps (#4415). |
| First word skipped in output | attention artifact in some models | Add leading punctuation or switch to VITS/XTTS (#4016). |
gpu=True warning |
constructor arg deprecated | Use .to(device) instead. |
Note
Feature requests that remain open against the frozen codebase include FunASR annotation support (#4422) and a standalone compiled binary (#4419). These will not land without community forks.
9. Code Quality & Conventions
- Uniform model contract. Every model implements
init_from_config/inference/load_checkpoint, which is what makes the Synthesizer polymorphic across architectures. - Config-as-dataclass.
coqpitdataclasses give typed, serializable configs; the config is the schema. This keeps training reproducible but means there is no separate documented config reference. - Registry-driven distribution.
.models.json+ModelManagercleanly separate "what models exist" from "how to fetch them," and include checksums and license/ToS metadata. - Late imports for CLI speed.
synthesize.pyimportsTTS.api/Synthesizer/ModelManagerinsidemain()sotts --list_modelsand help screens start fast. - Cython hot path.
TTS/tts/utils/monotonic_align/core.pyxis compiled for alignment performance β note the build dependency (cython) when packaging. - Broad text-frontend support. Per-language G2P/phonemizers (
gruut,jieba/pypinyin,jamo/g2pkk,bangla/bnnumerizer) live underTTS/tts/utils/text/.
Improvement opportunities (for forks)
- Harden checkpoint loading β adopt
weights_only=Trueand reject untrusted pickles (Β§5.1). - Sanitize archive extraction β validate member paths before
extractall()(Β§5.2). - Modernize dependency pins β support
transformers5.x and Python 3.12+ (#4394, #4416). - Secure the server β optional auth, request-size limits, and a
localhostdefault bind (Β§5.3). - Document config dataclasses β auto-generate a config reference from the
*Configclasses.
10. Quick Reference
10.1 Console scripts
| Command | Entry point |
|---|---|
tts |
TTS.bin.synthesize:main |
tts-server |
TTS.server.server:main |
10.2 HTTP API (demo server)
| Method | Path | Purpose |
|---|---|---|
| GET | / |
Web UI |
| GET | /details |
Model details (--show_details) |
| GET/POST | /api/tts |
Synthesize β audio/wav |
| GET | /locales |
MaryTTS locales |
| GET | /voices |
MaryTTS voices |
| GET/POST | /process |
MaryTTS synthesis |
10.3 Environment variables
| Variable | Purpose |
|---|---|
TTS_HOME |
Model cache base (priority 1). |
XDG_DATA_HOME |
Model cache base (priority 2). |
COQUI_TOS_AGREED |
1 to pre-accept gated-model terms. |
10.4 Key dependencies
| Dependency | Role |
|---|---|
torch>=2.1, torchaudio |
Model runtime. |
numpy, scipy, librosa, soundfile |
Audio/DSP. |
transformers>=4.33.0 |
XTTS / Tortoise backbones. |
encodec, einops |
Bark / Tortoise. |
trainer>=0.0.36 |
Training loop. |
coqpit>=0.0.16 |
Config dataclasses. |
gruut[de,es,fr], pysbd, jieba, pypinyin, jamo, g2pkk, bangla |
Text frontends / G2P. |
flask>=2.0.1 |
Demo server. |
cython |
Monotonic-align extension. |
10.5 Critical operational facts
- Python 3.9β3.11 only;
transformers4.x only. - Model cache at
$TTS_HOME/ttsβ$XDG_DATA_HOME/ttsβ~/.local/share/tts. - XTTS is CPML (non-commercial) and gated (
COQUI_TOS_AGREED=1). - Demo server has no auth and binds all interfaces β never expose it directly.
- Checkpoints are pickle; archives are extracted without path guards β load only trusted sources.
- The project is unmaintained β you own all patches and mitigations.