Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,5 @@ jobs:
# ride along here instead of waiting on a multi-GB backend image build.
- name: run shared python backend helper tests
run: make test-python-helpers
- name: run Chatterbox variant tests
run: make -C backend/python/chatterbox test-unit
6 changes: 5 additions & 1 deletion backend/python/chatterbox/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ test: chatterbox
bash test.sh
@echo "coqui tested."

.PHONY: test-unit
test-unit:
python3 -m unittest discover -s . -p 'test_variants.py' -v

.PHONY: protogen-clean
protogen-clean:
$(RM) backend_pb2_grpc.py backend_pb2.py

.PHONY: clean
clean: protogen-clean
rm -rf venv __pycache__
rm -rf venv __pycache__
47 changes: 32 additions & 15 deletions backend/python/chatterbox/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,18 @@ def is_int(s):
except ValueError:
return False

def coerce_param_value(value):
def coerce_param_value(value, key=None):
"""Coerce a TTSRequest.params value (string on the wire) to the type the
Chatterbox generate() kwargs expect (float/int/bool), matching how static
YAML options are coerced at load time. Non-string values pass through."""
if not isinstance(value, str):
return value
# Transformers requires top_k to be an int, but float controls such as
# temperature must remain floats even when written without a decimal point.
if key == "top_k" and is_int(value):
return int(value)
if is_float(value):
return float(value)
if is_int(value):
return int(value)
if value.lower() in ["true", "false"]:
return value.lower() == "true"
return value
Expand Down Expand Up @@ -157,14 +159,7 @@ def LoadModel(self, request, context):
if ":" not in opt:
continue
key, value = opt.split(":")
# if value is a number, convert it to the appropriate type
if is_float(value):
value = float(value)
elif is_int(value):
value = int(value)
elif value.lower() in ["true", "false"]:
value = value.lower() == "true"
self.options[key] = value
self.options[key] = coerce_param_value(value, key)

self.AudioPath = None

Expand All @@ -177,9 +172,23 @@ def LoadModel(self, request, context):
self.AudioPath = os.path.join(modelFileBase, request.AudioPath)
try:
print("Preparing models, please wait", file=sys.stderr)
if "multilingual" in self.options:
# remove key from options
del self.options["multilingual"]
selectors = {}
for name in ("multilingual", "turbo", "nano"):
value = self.options.pop(name, False)
if not isinstance(value, bool):
raise ValueError(f"{name} must be true or false")
selectors[name] = value
if sum(selectors.values()) > 1:
raise ValueError("Only one of multilingual, turbo, or nano can be true")
self.variant = next((name for name, enabled in selectors.items() if enabled), "original")
if self.variant in ("turbo", "nano"):
# Older installations can still load the original models.
from chatterbox.tts_turbo import ChatterboxTurboTTS
if self.variant == "nano":
self.model = ChatterboxTurboTTS.from_pretrained(device=device, nano=True)
else:
self.model = ChatterboxTurboTTS.from_pretrained(device=device)
elif self.variant == "multilingual":
self.model = ChatterboxMultilingualTTS.from_pretrained(device=device)
else:
self.model = ChatterboxTTS.from_pretrained(device=device)
Expand Down Expand Up @@ -211,7 +220,15 @@ def TTS(self, request, context):
for key, value in request.params.items():
if key == "ref_text":
continue
kwargs[key] = coerce_param_value(value)
kwargs[key] = coerce_param_value(value, key)

# Selectors apply only at load time, including when supplied in params.
for name in ("multilingual", "turbo", "nano"):
kwargs.pop(name, None)
if self.variant in ("turbo", "nano"):
# These controls belong to the original model's sampler.
for name in ("cfg_weight", "exaggeration", "min_p"):
kwargs.pop(name, None)

# Check if text exceeds 250 characters
# (chatterbox does not support long text)
Expand Down
6 changes: 4 additions & 2 deletions backend/python/chatterbox/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ installRequirements
# pip to backtrack through Jinja2/MarkupSafe/omegaconf/ruamel.yaml into Python-2-era
# sdists that no longer build. We install chatterbox-tts itself with --no-deps and
# list its real runtime deps in requirements-*.txt instead.
# Pin the fork so every backend build includes the same Turbo/Nano implementation.
CHATTERBOX_REV=b38c317b03834ef35828ae96c72ac8929b002a05
echo "Installing chatterbox-tts with --no-deps"
if [ "x${USE_PIP}" == "xtrue" ]; then
pip install ${EXTRA_PIP_INSTALL_FLAGS:-} --no-deps "chatterbox-tts@git+https://git@github.com/mudler/chatterbox.git@faster"
pip install ${EXTRA_PIP_INSTALL_FLAGS:-} --no-deps "chatterbox-tts@git+https://git@github.com/mudler/chatterbox.git@${CHATTERBOX_REV}"
else
uv pip install ${EXTRA_PIP_INSTALL_FLAGS:-} --no-deps "chatterbox-tts@git+https://git@github.com/mudler/chatterbox.git@faster"
uv pip install ${EXTRA_PIP_INSTALL_FLAGS:-} --no-deps "chatterbox-tts@git+https://git@github.com/mudler/chatterbox.git@${CHATTERBOX_REV}"
fi
4 changes: 2 additions & 2 deletions backend/python/chatterbox/requirements-cpu.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ accelerate
torch
torchaudio
numpy>=1.24.0,<1.26.0
transformers
transformers==4.46.3
# chatterbox-tts itself is installed with --no-deps in install.sh.
# These are its real runtime deps, mirroring upstream's pyproject.toml
# minus russian-text-stresser (whose ancient pins break the resolver).
Expand All @@ -16,4 +16,4 @@ resemble-perth==1.0.1
conformer
safetensors
spacy-pkuseg
pykakasi==2.3.0
pykakasi==2.3.0
4 changes: 2 additions & 2 deletions backend/python/chatterbox/requirements-cublas12.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
--extra-index-url https://download.pytorch.org/whl/cu124
torch==2.6.0+cu124
torchaudio==2.6.0+cu124
transformers<5
transformers==4.46.3
numpy>=1.24.0,<1.26.0
# chatterbox-tts itself is installed with --no-deps in install.sh.
# These are its real runtime deps, mirroring upstream's pyproject.toml
Expand All @@ -16,4 +16,4 @@ conformer
safetensors
spacy-pkuseg
pykakasi==2.3.0
accelerate
accelerate
2 changes: 1 addition & 1 deletion backend/python/chatterbox/requirements-cublas13.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
--extra-index-url https://download.pytorch.org/whl/cu130
torch
torchaudio
transformers
transformers==4.46.3
numpy>=1.24.0,<1.26.0
# chatterbox-tts itself is installed with --no-deps in install.sh.
# These are its real runtime deps, mirroring upstream's pyproject.toml
Expand Down
2 changes: 1 addition & 1 deletion backend/python/chatterbox/requirements-hipblas.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
--extra-index-url https://download.pytorch.org/whl/rocm7.0
torch==2.10.0+rocm7.0
torchaudio==2.10.0+rocm7.0
transformers
transformers==4.46.3
numpy>=1.24.0,<1.26.0
# chatterbox-tts itself is installed with --no-deps in install.sh.
# These are its real runtime deps, mirroring upstream's pyproject.toml
Expand Down
4 changes: 2 additions & 2 deletions backend/python/chatterbox/requirements-intel.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
--extra-index-url https://download.pytorch.org/whl/xpu
torch
torchaudio
transformers
transformers==4.46.3
numpy>=1.24.0,<1.26.0
# chatterbox-tts itself is installed with --no-deps in install.sh.
# These are its real runtime deps, mirroring upstream's pyproject.toml
Expand All @@ -19,4 +19,4 @@ pykakasi==2.3.0
accelerate
oneccl_bind_pt==2.3.100+xpu
optimum[openvino]
setuptools
setuptools
2 changes: 1 addition & 1 deletion backend/python/chatterbox/requirements-l4t12.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
--extra-index-url https://pypi.jetson-ai-lab.io/jp6/cu126/
torch
torchaudio
transformers
transformers==4.46.3
numpy>=1.24.0,<1.26.0
# chatterbox-tts itself is installed with --no-deps in install.sh.
# These are its real runtime deps, mirroring upstream's pyproject.toml
Expand Down
2 changes: 1 addition & 1 deletion backend/python/chatterbox/requirements-l4t13.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
--extra-index-url https://download.pytorch.org/whl/cu130
torch
torchaudio
transformers
transformers==4.46.3
numpy>=1.24.0,<1.26.0
# chatterbox-tts itself is installed with --no-deps in install.sh.
# These are its real runtime deps, mirroring upstream's pyproject.toml
Expand Down
4 changes: 2 additions & 2 deletions backend/python/chatterbox/requirements-mps.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ torch
torchaudio
accelerate
numpy>=1.24.0,<1.26.0
transformers
transformers==4.46.3
# chatterbox-tts itself is installed with --no-deps in install.sh.
# These are its real runtime deps, mirroring upstream's pyproject.toml
# minus russian-text-stresser (whose ancient pins break the resolver).
Expand All @@ -15,4 +15,4 @@ resemble-perth==1.0.1
conformer
safetensors
spacy-pkuseg
pykakasi==2.3.0
pykakasi==2.3.0
4 changes: 3 additions & 1 deletion backend/python/chatterbox/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ protobuf
certifi
packaging
setuptools<81
poetry
poetry
# Turbo and Nano normalize reference audio before cloning.
pyloudnorm
Loading
Loading