Merge pull request #19 from idiap/toml

Move from setup.py to pyproject.toml, simplify requirements
This commit is contained in:
Enno Hermann 2024-05-27 08:59:09 +01:00 committed by GitHub
commit df088e99df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
78 changed files with 445 additions and 374 deletions

1
.github/stale.yml vendored
View File

@ -15,4 +15,3 @@ markComment: >
for your contributions. You might also look our discussion channels. for your contributions. You might also look our discussion channels.
# Comment to post when closing a stale issue. Set to `false` to disable # Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false closeComment: false

View File

@ -42,7 +42,7 @@ jobs:
branch=${github_ref#*refs/heads/} # strip prefix to get branch name branch=${github_ref#*refs/heads/} # strip prefix to get branch name
tags="${base}:${branch},${base}:${{ github.sha }}," tags="${base}:${branch},${base}:${{ github.sha }},"
elif [[ "${{ startsWith(github.ref, 'refs/tags/') }}" = "true" ]]; then elif [[ "${{ startsWith(github.ref, 'refs/tags/') }}" = "true" ]]; then
VERSION="v$(cat TTS/VERSION)" VERSION="v$(grep -m 1 version pyproject.toml | grep -P '\d+\.\d+\.\d+' -o)"
if [[ "${{ github.ref }}" != "refs/tags/${VERSION}" ]]; then if [[ "${{ github.ref }}" != "refs/tags/${VERSION}" ]]; then
echo "Pushed tag does not match VERSION file. Aborting push." echo "Pushed tag does not match VERSION file. Aborting push."
exit 1 exit 1
@ -63,3 +63,58 @@ jobs:
push: ${{ github.event_name == 'push' }} push: ${{ github.event_name == 'push' }}
build-args: "BASE=${{ matrix.base }}" build-args: "BASE=${{ matrix.base }}"
tags: ${{ steps.compute-tag.outputs.tags }} tags: ${{ steps.compute-tag.outputs.tags }}
docker-dev-build:
name: "Build the development Docker image"
runs-on: ubuntu-latest
strategy:
matrix:
arch: ["amd64"]
base:
- "nvidia/cuda:11.8.0-base-ubuntu22.04" # GPU enabled
steps:
- uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Compute Docker tags, check VERSION file matches tag
id: compute-tag
run: |
set -ex
base="ghcr.io/idiap/coqui-tts-dev"
tags="" # PR build
if [[ ${{ matrix.base }} = "python:3.10.8-slim" ]]; then
base="ghcr.io/idiap/coqui-tts-dev-cpu"
fi
if [[ "${{ startsWith(github.ref, 'refs/heads/') }}" = "true" ]]; then
# Push to branch
github_ref="${{ github.ref }}"
branch=${github_ref#*refs/heads/} # strip prefix to get branch name
tags="${base}:${branch},${base}:${{ github.sha }},"
elif [[ "${{ startsWith(github.ref, 'refs/tags/') }}" = "true" ]]; then
VERSION="v$(grep -m 1 version pyproject.toml | grep -P '\d+\.\d+\.\d+' -o)"
if [[ "${{ github.ref }}" != "refs/tags/${VERSION}" ]]; then
echo "Pushed tag does not match VERSION file. Aborting push."
exit 1
fi
tags="${base}:${VERSION},${base}:latest,${base}:${{ github.sha }}"
fi
echo "::set-output name=tags::${tags}"
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: dockerfiles/Dockerfile.dev
platforms: linux/${{ matrix.arch }}
push: false
build-args: "BASE=${{ matrix.base }}"
tags: ${{ steps.compute-tag.outputs.tags }}

View File

@ -14,7 +14,7 @@ jobs:
- name: Verify tag matches version - name: Verify tag matches version
run: | run: |
set -ex set -ex
version=$(cat TTS/VERSION) version=$(grep -m 1 version pyproject.toml | grep -P '\d+\.\d+\.\d+' -o)
tag="${GITHUB_REF/refs\/tags\/}" tag="${GITHUB_REF/refs\/tags\/}"
if [[ "v$version" != "$tag" ]]; then if [[ "v$version" != "$tag" ]]; then
exit 1 exit 1
@ -42,10 +42,9 @@ jobs:
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Install pip requirements - name: Install build requirements
run: | run: |
python -m pip install -U pip setuptools wheel build python -m pip install -U pip setuptools wheel build numpy cython
python -m pip install -r requirements.txt
- name: Setup and install manylinux1_x86_64 wheel - name: Setup and install manylinux1_x86_64 wheel
run: | run: |
python setup.py bdist_wheel --plat-name=manylinux1_x86_64 python setup.py bdist_wheel --plat-name=manylinux1_x86_64

View File

@ -45,7 +45,7 @@ jobs:
sed -i 's/https:\/\/coqui.gateway.scarf.sh\//https:\/\/github.com\/coqui-ai\/TTS\/releases\/download\//g' TTS/.models.json sed -i 's/https:\/\/coqui.gateway.scarf.sh\//https:\/\/github.com\/coqui-ai\/TTS\/releases\/download\//g' TTS/.models.json
- name: Install TTS - name: Install TTS
run: | run: |
python3 -m uv pip install --system "coqui-tts[dev,server,ja] @ ." python3 -m uv pip install --system "coqui-tts[dev,server,languages] @ ."
python3 setup.py egg_info python3 setup.py egg_info
- name: Unit tests - name: Unit tests
run: make ${{ matrix.subset }} run: make ${{ matrix.subset }}

View File

@ -3,10 +3,8 @@ repos:
rev: v4.5.0 rev: v4.5.0
hooks: hooks:
- id: check-yaml - id: check-yaml
# TODO: enable these later; there are plenty of violating - id: end-of-file-fixer
# files that need to be fixed first - id: trailing-whitespace
# - id: end-of-file-fixer
# - id: trailing-whitespace
- repo: "https://github.com/psf/black" - repo: "https://github.com/psf/black"
rev: 24.2.0 rev: 24.2.0
hooks: hooks:
@ -17,3 +15,10 @@ repos:
hooks: hooks:
- id: ruff - id: ruff
args: [--fix, --exit-non-zero-on-fix] args: [--fix, --exit-non-zero-on-fix]
- repo: local
hooks:
- id: generate_requirements.py
name: generate_requirements.py
language: system
entry: python scripts/generate_requirements.py
files: "pyproject.toml|requirements.*\\.txt|tools/generate_requirements.py"

View File

@ -14,8 +14,9 @@ build:
# Optionally set the version of Python and requirements required to build your docs # Optionally set the version of Python and requirements required to build your docs
python: python:
install: install:
- requirements: docs/requirements.txt - path: .
- requirements: requirements.txt extra_requirements:
- docs
# Build documentation in the docs/ directory with Sphinx # Build documentation in the docs/ directory with Sphinx
sphinx: sphinx:

View File

@ -60,7 +60,7 @@ The following steps are tested on an Ubuntu system.
```bash ```bash
$ make system-deps # intended to be used on Ubuntu (Debian). Let us know if you have a different OS. $ make system-deps # intended to be used on Ubuntu (Debian). Let us know if you have a different OS.
$ make install $ make install_dev
``` ```
4. Create a new branch with an informative name for your goal. 4. Create a new branch with an informative name for your goal.

View File

@ -3,6 +3,7 @@ FROM ${BASE}
RUN apt-get update && apt-get upgrade -y RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y --no-install-recommends gcc g++ make python3 python3-dev python3-pip python3-venv python3-wheel espeak-ng libsndfile1-dev && rm -rf /var/lib/apt/lists/* RUN apt-get install -y --no-install-recommends gcc g++ make python3 python3-dev python3-pip python3-venv python3-wheel espeak-ng libsndfile1-dev && rm -rf /var/lib/apt/lists/*
RUN pip3 install -U pip setuptools
RUN pip3 install llvmlite --ignore-installed RUN pip3 install llvmlite --ignore-installed
# Install Dependencies: # Install Dependencies:

View File

@ -1,9 +1,6 @@
include README.md include README.md
include LICENSE.txt include LICENSE.txt
include requirements.*.txt
include *.cff include *.cff
include requirements.txt
include TTS/VERSION
recursive-include TTS *.json recursive-include TTS *.json
recursive-include TTS *.html recursive-include TTS *.html
recursive-include TTS *.png recursive-include TTS *.png
@ -11,5 +8,3 @@ recursive-include TTS *.md
recursive-include TTS *.py recursive-include TTS *.py
recursive-include TTS *.pyx recursive-include TTS *.pyx
recursive-include images *.png recursive-include images *.png
recursive-exclude tests *
prune tests*

View File

@ -1,5 +1,5 @@
.DEFAULT_GOAL := help .DEFAULT_GOAL := help
.PHONY: test system-deps dev-deps deps style lint install help docs .PHONY: test system-deps dev-deps style lint install install_dev help docs
help: help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
@ -62,20 +62,15 @@ system-deps: ## install linux system deps
dev-deps: ## install development deps dev-deps: ## install development deps
pip install -r requirements.dev.txt pip install -r requirements.dev.txt
doc-deps: ## install docs dependencies
pip install -r docs/requirements.txt
build-docs: ## build the docs build-docs: ## build the docs
cd docs && make clean && make build cd docs && make clean && make build
hub-deps: ## install deps for torch hub use install: ## install 🐸 TTS
pip install -r requirements.hub.txt
deps: ## install 🐸 requirements.
pip install -r requirements.txt
install: ## install 🐸 TTS for development.
pip install -e .[all] pip install -e .[all]
install_dev: ## install 🐸 TTS for development.
pip install -e .[all,dev]
pre-commit install
docs: ## build the docs docs: ## build the docs
$(MAKE) -C docs clean && $(MAKE) -C docs html $(MAKE) -C docs clean && $(MAKE) -C docs html

View File

@ -143,9 +143,35 @@ If you plan to code or train models, clone 🐸TTS and install it locally.
```bash ```bash
git clone https://github.com/idiap/coqui-ai-TTS git clone https://github.com/idiap/coqui-ai-TTS
pip install -e .[all,dev,notebooks,server] # Select the relevant extras pip install -e .
``` ```
### Optional dependencies
The following extras allow the installation of optional dependencies:
| Name | Description |
|------|-------------|
| `all` | All optional dependencies, except `dev` and `docs` |
| `dev` | Development dependencies |
| `dev` | Dependencies for building the documentation |
| `notebooks` | Dependencies only used in notebooks |
| `server` | Dependencies to run the TTS server |
| `bn` | Bangla G2P |
| `ja` | Japanese G2P |
| `ko` | Korean G2P |
| `zh` | Chinese G2P |
| `languages` | All language-specific dependencies |
You can install extras with one of the following commands:
```bash
pip install coqui-tts[server,ja]
pip install -e .[server,ja]
```
### Platforms
If you are on Ubuntu (Debian), you can also run following commands for installation. If you are on Ubuntu (Debian), you can also run following commands for installation.
```bash ```bash

View File

@ -1 +0,0 @@
0.23.1

View File

@ -1,6 +0,0 @@
import os
with open(os.path.join(os.path.dirname(__file__), "VERSION"), "r", encoding="utf-8") as f:
version = f.read().strip()
__version__ = version

View File

@ -1,5 +1,4 @@
import torch import torch
from packaging.version import Version
from torch import nn from torch import nn
from torch.nn import functional as F from torch.nn import functional as F
@ -90,9 +89,6 @@ class InvConvNear(nn.Module):
self.no_jacobian = no_jacobian self.no_jacobian = no_jacobian
self.weight_inv = None self.weight_inv = None
if Version(torch.__version__) < Version("1.9"):
w_init = torch.qr(torch.FloatTensor(self.num_splits, self.num_splits).normal_())[0]
else:
w_init = torch.linalg.qr(torch.FloatTensor(self.num_splits, self.num_splits).normal_(), "complete")[0] w_init = torch.linalg.qr(torch.FloatTensor(self.num_splits, self.num_splits).normal_(), "complete")[0]
if torch.det(w_init) < 0: if torch.det(w_init) < 0:

View File

@ -7,7 +7,6 @@ import torch
import torch.nn.functional as F import torch.nn.functional as F
from einops import rearrange, repeat from einops import rearrange, repeat
from einops.layers.torch import Rearrange from einops.layers.torch import Rearrange
from packaging import version
from torch import einsum, nn from torch import einsum, nn
@ -44,9 +43,6 @@ class Attend(nn.Module):
self.register_buffer("mask", None, persistent=False) self.register_buffer("mask", None, persistent=False)
self.use_flash = use_flash self.use_flash = use_flash
assert not (
use_flash and version.parse(torch.__version__) < version.parse("2.0.0")
), "in order to use flash attention, you must be using pytorch 2.0 or above"
# determine efficient attention configs for cuda and cpu # determine efficient attention configs for cuda and cpu
self.config = namedtuple("EfficientAttentionConfig", ["enable_flash", "enable_math", "enable_mem_efficient"]) self.config = namedtuple("EfficientAttentionConfig", ["enable_flash", "enable_math", "enable_mem_efficient"])

View File

@ -4,10 +4,7 @@ import re
import textwrap import textwrap
from functools import cached_property from functools import cached_property
import pypinyin
import torch import torch
from hangul_romanize import Transliter
from hangul_romanize.rule import academic
from num2words import num2words from num2words import num2words
from spacy.lang.ar import Arabic from spacy.lang.ar import Arabic
from spacy.lang.en import English from spacy.lang.en import English
@ -577,6 +574,10 @@ def basic_cleaners(text):
def chinese_transliterate(text): def chinese_transliterate(text):
try:
import pypinyin
except ImportError as e:
raise ImportError("Chinese requires: pypinyin") from e
return "".join( return "".join(
[p[0] for p in pypinyin.pinyin(text, style=pypinyin.Style.TONE3, heteronym=False, neutral_tone_with_five=True)] [p[0] for p in pypinyin.pinyin(text, style=pypinyin.Style.TONE3, heteronym=False, neutral_tone_with_five=True)]
) )
@ -589,6 +590,11 @@ def japanese_cleaners(text, katsu):
def korean_transliterate(text): def korean_transliterate(text):
try:
from hangul_romanize import Transliter
from hangul_romanize.rule import academic
except ImportError as e:
raise ImportError("Korean requires: hangul_romanize") from e
r = Transliter(academic) r = Transliter(academic)
return r.translit(text) return r.translit(text)

View File

@ -1,7 +0,0 @@
# from distutils.core import setup
# from Cython.Build import cythonize
# import numpy
# setup(name='monotonic_align',
# ext_modules=cythonize("core.pyx"),
# include_dirs=[numpy.get_include()])

View File

@ -1,8 +1,11 @@
import re import re
try:
import bangla import bangla
from bnnumerizer import numerize from bnnumerizer import numerize
from bnunicodenormalizer import Normalizer from bnunicodenormalizer import Normalizer
except ImportError as e:
raise ImportError("Bangla requires: bangla, bnnumerizer, bnunicodenormalizer") from e
# initialize # initialize
bnorm = Normalizer() bnorm = Normalizer()

View File

@ -1,7 +1,10 @@
from typing import List from typing import List
try:
import jieba import jieba
import pypinyin import pypinyin
except ImportError as e:
raise ImportError("Chinese requires: jieba, pypinyin") from e
from .pinyinToPhonemes import PINYIN_DICT from .pinyinToPhonemes import PINYIN_DICT

View File

@ -1,4 +1,7 @@
try:
from jamo import hangul_to_jamo from jamo import hangul_to_jamo
except ImportError as e:
raise ImportError("Korean requires: g2pkk, jamo") from e
from TTS.tts.utils.text.korean.korean import normalize from TTS.tts.utils.text.korean.korean import normalize

View File

@ -1,17 +1,29 @@
from TTS.tts.utils.text.phonemizers.bangla_phonemizer import BN_Phonemizer
from TTS.tts.utils.text.phonemizers.base import BasePhonemizer from TTS.tts.utils.text.phonemizers.base import BasePhonemizer
from TTS.tts.utils.text.phonemizers.belarusian_phonemizer import BEL_Phonemizer from TTS.tts.utils.text.phonemizers.belarusian_phonemizer import BEL_Phonemizer
from TTS.tts.utils.text.phonemizers.espeak_wrapper import ESpeak from TTS.tts.utils.text.phonemizers.espeak_wrapper import ESpeak
from TTS.tts.utils.text.phonemizers.gruut_wrapper import Gruut from TTS.tts.utils.text.phonemizers.gruut_wrapper import Gruut
from TTS.tts.utils.text.phonemizers.ko_kr_phonemizer import KO_KR_Phonemizer
from TTS.tts.utils.text.phonemizers.zh_cn_phonemizer import ZH_CN_Phonemizer try:
from TTS.tts.utils.text.phonemizers.bangla_phonemizer import BN_Phonemizer
except ImportError:
BN_Phonemizer = None
try: try:
from TTS.tts.utils.text.phonemizers.ja_jp_phonemizer import JA_JP_Phonemizer from TTS.tts.utils.text.phonemizers.ja_jp_phonemizer import JA_JP_Phonemizer
except ImportError: except ImportError:
JA_JP_Phonemizer = None JA_JP_Phonemizer = None
PHONEMIZERS = {b.name(): b for b in (ESpeak, Gruut, KO_KR_Phonemizer, BN_Phonemizer)} try:
from TTS.tts.utils.text.phonemizers.ko_kr_phonemizer import KO_KR_Phonemizer
except ImportError:
KO_KR_Phonemizer = None
try:
from TTS.tts.utils.text.phonemizers.zh_cn_phonemizer import ZH_CN_Phonemizer
except ImportError:
ZH_CN_Phonemizer = None
PHONEMIZERS = {b.name(): b for b in (ESpeak, Gruut)}
ESPEAK_LANGS = list(ESpeak.supported_languages().keys()) ESPEAK_LANGS = list(ESpeak.supported_languages().keys())
@ -32,17 +44,21 @@ DEF_LANG_TO_PHONEMIZER.update(_new_dict)
# Force default for some languages # Force default for some languages
DEF_LANG_TO_PHONEMIZER["en"] = DEF_LANG_TO_PHONEMIZER["en-us"] DEF_LANG_TO_PHONEMIZER["en"] = DEF_LANG_TO_PHONEMIZER["en-us"]
DEF_LANG_TO_PHONEMIZER["zh-cn"] = ZH_CN_Phonemizer.name()
DEF_LANG_TO_PHONEMIZER["ko-kr"] = KO_KR_Phonemizer.name()
DEF_LANG_TO_PHONEMIZER["bn"] = BN_Phonemizer.name()
DEF_LANG_TO_PHONEMIZER["be"] = BEL_Phonemizer.name() DEF_LANG_TO_PHONEMIZER["be"] = BEL_Phonemizer.name()
# JA phonemizer has deal breaking dependencies like MeCab for some systems. if BN_Phonemizer is not None:
# So we only have it when we have it. PHONEMIZERS[BN_Phonemizer.name()] = BN_Phonemizer
DEF_LANG_TO_PHONEMIZER["bn"] = BN_Phonemizer.name()
if JA_JP_Phonemizer is not None: if JA_JP_Phonemizer is not None:
PHONEMIZERS[JA_JP_Phonemizer.name()] = JA_JP_Phonemizer PHONEMIZERS[JA_JP_Phonemizer.name()] = JA_JP_Phonemizer
DEF_LANG_TO_PHONEMIZER["ja-jp"] = JA_JP_Phonemizer.name() DEF_LANG_TO_PHONEMIZER["ja-jp"] = JA_JP_Phonemizer.name()
if KO_KR_Phonemizer is not None:
PHONEMIZERS[KO_KR_Phonemizer.name()] = KO_KR_Phonemizer
DEF_LANG_TO_PHONEMIZER["ko-kr"] = KO_KR_Phonemizer.name()
if ZH_CN_Phonemizer is not None:
PHONEMIZERS[ZH_CN_Phonemizer.name()] = ZH_CN_Phonemizer
DEF_LANG_TO_PHONEMIZER["zh-cn"] = ZH_CN_Phonemizer.name()
def get_phonemizer_by_name(name: str, **kwargs) -> BasePhonemizer: def get_phonemizer_by_name(name: str, **kwargs) -> BasePhonemizer:
@ -60,14 +76,20 @@ def get_phonemizer_by_name(name: str, **kwargs) -> BasePhonemizer:
if name == "gruut": if name == "gruut":
return Gruut(**kwargs) return Gruut(**kwargs)
if name == "zh_cn_phonemizer": if name == "zh_cn_phonemizer":
if ZH_CN_Phonemizer is None:
raise ValueError("You need to install ZH phonemizer dependencies. Try `pip install coqui-tts[zh]`.")
return ZH_CN_Phonemizer(**kwargs) return ZH_CN_Phonemizer(**kwargs)
if name == "ja_jp_phonemizer": if name == "ja_jp_phonemizer":
if JA_JP_Phonemizer is None: if JA_JP_Phonemizer is None:
raise ValueError("You need to install JA phonemizer dependencies. Try `pip install coqui-tts[ja]`.") raise ValueError("You need to install JA phonemizer dependencies. Try `pip install coqui-tts[ja]`.")
return JA_JP_Phonemizer(**kwargs) return JA_JP_Phonemizer(**kwargs)
if name == "ko_kr_phonemizer": if name == "ko_kr_phonemizer":
if KO_KR_Phonemizer is None:
raise ValueError("You need to install KO phonemizer dependencies. Try `pip install coqui-tts[ko]`.")
return KO_KR_Phonemizer(**kwargs) return KO_KR_Phonemizer(**kwargs)
if name == "bn_phonemizer": if name == "bn_phonemizer":
if BN_Phonemizer is None:
raise ValueError("You need to install BN phonemizer dependencies. Try `pip install coqui-tts[bn]`.")
return BN_Phonemizer(**kwargs) return BN_Phonemizer(**kwargs)
if name == "be_phonemizer": if name == "be_phonemizer":
return BEL_Phonemizer(**kwargs) return BEL_Phonemizer(**kwargs)

View File

@ -11,34 +11,13 @@ RUN apt-get install -y --no-install-recommends \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Install Major Python Dependencies: # Install Major Python Dependencies:
RUN pip3 install -U pip setuptools
RUN pip3 install llvmlite --ignore-installed RUN pip3 install llvmlite --ignore-installed
RUN pip3 install torch torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 RUN pip3 install torch torchaudio --extra-index-url https://download.pytorch.org/whl/cu118
RUN rm -rf /root/.cache/pip RUN rm -rf /root/.cache/pip
WORKDIR /root
# Copy Dependency Lock Files:
COPY \
Makefile \
pyproject.toml \
setup.py \
requirements.dev.txt \
requirements.ja.txt \
requirements.notebooks.txt \
requirements.txt \
/root/
# Install Project Dependencies
# Separate stage to limit re-downloading:
RUN pip install \
-r requirements.txt \
-r requirements.dev.txt \
-r requirements.ja.txt \
-r requirements.notebooks.txt
# Copy TTS repository contents: # Copy TTS repository contents:
WORKDIR /root
COPY . /root COPY . /root
# Installing the TTS package itself:
RUN make install RUN make install

View File

@ -10,26 +10,24 @@
# add these directories to sys.path here. If the directory is relative to the # add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here. # documentation root, use os.path.abspath to make it absolute, like shown here.
# #
import importlib.metadata
import os import os
import sys import sys
sys.path.insert(0, os.path.abspath('../..')) sys.path.insert(0, os.path.abspath("../.."))
# mock deps with system level requirements. # mock deps with system level requirements.
autodoc_mock_imports = ["soundfile"] autodoc_mock_imports = ["soundfile"]
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = 'TTS' project = "TTS"
copyright = "2021 Coqui GmbH, 2020 TTS authors" copyright = "2021 Coqui GmbH, 2020 TTS authors"
author = 'Coqui GmbH' author = "Coqui GmbH"
with open("../../TTS/VERSION", "r") as ver:
version = ver.read().strip()
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
# built documents. # built documents.
release = version release = importlib.metadata.version(project)
# The main toctree document. # The main toctree document.
master_doc = "index" master_doc = "index"
@ -40,32 +38,34 @@ master_doc = "index"
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones. # ones.
extensions = [ extensions = [
'sphinx.ext.autodoc', "sphinx.ext.autodoc",
'sphinx.ext.autosummary', "sphinx.ext.autosummary",
'sphinx.ext.doctest', "sphinx.ext.doctest",
'sphinx.ext.intersphinx', "sphinx.ext.intersphinx",
'sphinx.ext.todo', "sphinx.ext.todo",
'sphinx.ext.coverage', "sphinx.ext.coverage",
'sphinx.ext.napoleon', "sphinx.ext.napoleon",
'sphinx.ext.viewcode', "sphinx.ext.viewcode",
'sphinx.ext.autosectionlabel', "sphinx.ext.autosectionlabel",
'myst_parser', "myst_parser",
"sphinx_copybutton", "sphinx_copybutton",
"sphinx_inline_tabs", "sphinx_inline_tabs",
] ]
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and # List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files. # directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path. # This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'TODO/*'] exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "TODO/*"]
source_suffix = [".rst", ".md"] source_suffix = [".rst", ".md"]
myst_enable_extensions = ['linkify',] myst_enable_extensions = [
"linkify",
]
# 'sphinxcontrib.katex', # 'sphinxcontrib.katex',
# 'sphinx.ext.autosectionlabel', # 'sphinx.ext.autosectionlabel',
@ -76,17 +76,17 @@ myst_enable_extensions = ['linkify',]
# duplicated section names that are in different documents. # duplicated section names that are in different documents.
autosectionlabel_prefix_document = True autosectionlabel_prefix_document = True
language = 'en' language = "en"
autodoc_inherit_docstrings = False autodoc_inherit_docstrings = False
# Disable displaying type annotations, these can be very verbose # Disable displaying type annotations, these can be very verbose
autodoc_typehints = 'none' autodoc_typehints = "none"
# Enable overriding of function signatures in the first line of the docstring. # Enable overriding of function signatures in the first line of the docstring.
autodoc_docstring_signature = True autodoc_docstring_signature = True
napoleon_custom_sections = [('Shapes', 'shape')] napoleon_custom_sections = [("Shapes", "shape")]
# -- Options for HTML output ------------------------------------------------- # -- Options for HTML output -------------------------------------------------
@ -94,7 +94,7 @@ napoleon_custom_sections = [('Shapes', 'shape')]
# The theme to use for HTML and HTML Help pages. See the documentation for # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # a list of builtin themes.
# #
html_theme = 'furo' html_theme = "furo"
html_tite = "TTS" html_tite = "TTS"
html_theme_options = { html_theme_options = {
"light_logo": "logo.png", "light_logo": "logo.png",
@ -103,7 +103,7 @@ html_theme_options = {
} }
html_sidebars = { html_sidebars = {
'**': [ "**": [
"sidebar/scroll-start.html", "sidebar/scroll-start.html",
"sidebar/brand.html", "sidebar/brand.html",
"sidebar/search.html", "sidebar/search.html",
@ -117,4 +117,4 @@ html_sidebars = {
# Add any paths that contain custom static files (such as style sheets) here, # Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files, # relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css". # so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static'] html_static_path = ["_static"]

View File

@ -111,4 +111,3 @@ them and fine-tune it for your own dataset. This will help you in two main ways:
--coqpit.run_name "glow-tts-finetune" \ --coqpit.run_name "glow-tts-finetune" \
--coqpit.lr 0.00001 --coqpit.lr 0.00001
``` ```

View File

@ -26,7 +26,12 @@ This is recommended for development and more control over 🐸TTS.
git clone https://github.com/idiap/coqui-ai-TTS git clone https://github.com/idiap/coqui-ai-TTS
cd coqui-ai-TTS cd coqui-ai-TTS
make system-deps # only on Linux systems. make system-deps # only on Linux systems.
# Install package and optional extras
make install make install
# Same as above + dev dependencies and pre-commit
make install_dev
``` ```
## On Windows ## On Windows

View File

@ -61,5 +61,3 @@ Currently we provide the following pre-configured architectures:
.. autoclass:: TTS.tts.configs.fast_speech_config.FastSpeechConfig .. autoclass:: TTS.tts.configs.fast_speech_config.FastSpeechConfig
:members: :members:
``` ```

View File

@ -59,5 +59,3 @@ If you have a limited VRAM, then you can try using the Guided Attention Loss or
.. autoclass:: TTS.tts.configs.tacotron2_config.Tacotron2Config .. autoclass:: TTS.tts.configs.tacotron2_config.Tacotron2Config
:members: :members:
``` ```

View File

@ -1,15 +1,11 @@
dependencies = [ dependencies = ["torch", "gdown", "pysbd", "gruut", "anyascii", "pypinyin", "coqpit", "mecab-python3", "unidic-lite"]
'torch', 'gdown', 'pysbd', 'gruut', 'anyascii', 'pypinyin', 'coqpit', 'mecab-python3', 'unidic-lite'
]
import torch import torch
from TTS.utils.manage import ModelManager from TTS.utils.manage import ModelManager
from TTS.utils.synthesizer import Synthesizer from TTS.utils.synthesizer import Synthesizer
def tts(model_name='tts_models/en/ljspeech/tacotron2-DCA', def tts(model_name="tts_models/en/ljspeech/tacotron2-DCA", vocoder_name=None, use_cuda=False):
vocoder_name=None,
use_cuda=False):
"""TTS entry point for PyTorch Hub that provides a Synthesizer object to synthesize speech from a give text. """TTS entry point for PyTorch Hub that provides a Synthesizer object to synthesize speech from a give text.
Example: Example:
@ -28,19 +24,20 @@ def tts(model_name='tts_models/en/ljspeech/tacotron2-DCA',
manager = ModelManager() manager = ModelManager()
model_path, config_path, model_item = manager.download_model(model_name) model_path, config_path, model_item = manager.download_model(model_name)
vocoder_name = model_item[ vocoder_name = model_item["default_vocoder"] if vocoder_name is None else vocoder_name
'default_vocoder'] if vocoder_name is None else vocoder_name
vocoder_path, vocoder_config_path, _ = manager.download_model(vocoder_name) vocoder_path, vocoder_config_path, _ = manager.download_model(vocoder_name)
# create synthesizer # create synthesizer
synt = Synthesizer(tts_checkpoint=model_path, synt = Synthesizer(
tts_checkpoint=model_path,
tts_config_path=config_path, tts_config_path=config_path,
vocoder_checkpoint=vocoder_path, vocoder_checkpoint=vocoder_path,
vocoder_config=vocoder_config_path, vocoder_config=vocoder_config_path,
use_cuda=use_cuda) use_cuda=use_cuda,
)
return synt return synt
if __name__ == '__main__': if __name__ == "__main__":
synthesizer = torch.hub.load('coqui-ai/TTS:dev', 'tts', source='github') synthesizer = torch.hub.load("coqui-ai/TTS:dev", "tts", source="github")
synthesizer.tts("This is a test!") synthesizer.tts("This is a test!")

View File

@ -1,11 +1,151 @@
[build-system] [build-system]
requires = [ requires = [
"setuptools", "setuptools",
"wheel",
"cython~=0.29.30", "cython~=0.29.30",
"numpy>=1.22.0", "numpy>=1.24.3",
"packaging",
] ]
build-backend = "setuptools.build_meta"
[tool.setuptools.packages.find]
include = ["TTS*"]
[project]
name = "coqui-tts"
version = "0.24.0"
description = "Deep learning for Text to Speech."
readme = "README.md"
requires-python = ">=3.9, <3.13"
license = {text = "MPL-2.0"}
authors = [
{name = "Eren Gölge", email = "egolge@coqui.ai"}
]
maintainers = [
{name = "Enno Hermann", email = "enno.hermann@gmail.com"}
]
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Development Status :: 3 - Alpha",
"Intended Audience :: Science/Research",
"Intended Audience :: Developers",
"Operating System :: POSIX :: Linux",
"License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
"Topic :: Software Development",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Multimedia :: Sound/Audio :: Speech",
"Topic :: Multimedia :: Sound/Audio",
"Topic :: Multimedia",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
]
dependencies = [
# Core
"numpy>=1.24.3",
"cython>=0.29.30",
"scipy>=1.11.2",
"torch>=2.1",
"torchaudio",
"soundfile>=0.12.0",
"librosa>=0.10.1",
"inflect>=5.6.0",
"tqdm>=4.64.1",
"anyascii>=0.3.0",
"pyyaml>=6.0",
"fsspec[http]>=2023.6.0",
"packaging>=23.1",
# Inference
"pysbd>=0.3.4",
# Notebooks
"umap-learn>=0.5.1",
# Training
"matplotlib>=3.7.0",
# Coqui stack
"coqui-tts-trainer>=0.1",
"coqpit>=0.0.16",
# Gruut + supported languages
"gruut[de,es,fr]==2.2.3",
# Tortoise
"einops>=0.6.0",
"transformers>=4.33.0",
# Bark
"encodec>=0.1.1",
# XTTS
"num2words",
"spacy[ja]>=3"
]
[project.optional-dependencies]
# Development dependencies
dev = [
"black==24.2.0",
"coverage[toml]",
"nose2",
"pre-commit",
"ruff==0.3.0",
"tomli; python_version < '3.11'",
]
# Dependencies for building the documentation
docs = [
"furo",
"myst-parser==2.0.0",
"sphinx==7.2.5",
"sphinx_inline_tabs",
"sphinx_copybutton",
"linkify-it-py",
]
# Only used in notebooks
notebooks = [
"bokeh==1.4.0",
"pandas>=1.4,<2.0",
]
# For running the TTS server
server = ["flask>=2.0.1"]
# Language-specific dependencies, mainly for G2P
# Bangla
bn = [
"bangla",
"bnnumerizer",
"bnunicodenormalizer",
]
# Korean
ko = [
"hangul_romanize",
"jamo",
"g2pkk>=0.1.1",
]
# Japanese
ja = [
"mecab-python3",
"unidic-lite==1.0.8",
"cutlet",
]
# Chinese
zh = [
"jieba",
"pypinyin",
]
# All language-specific dependencies
languages = [
"coqui-tts[bn,ja,ko,zh]",
]
# Installs all extras (except dev and docs)
all = [
"coqui-tts[notebooks,server,bn,ja,ko,zh]",
]
[project.urls]
Homepage = "https://github.com/idiap/coqui-ai-TTS"
Documentation = "https://coqui-tts.readthedocs.io"
Repository = "https://github.com/idiap/coqui-ai-TTS"
Issues = "https://github.com/idiap/coqui-ai-TTS/issues"
Discussions = "https://github.com/idiap/coqui-ai-TTS/discussions"
[project.scripts]
tts = "TTS.bin.synthesize:main"
tts-server = "TTS.server.server:main"
[tool.ruff] [tool.ruff]
target-version = "py39" target-version = "py39"
@ -32,14 +172,9 @@ lint.extend-select = [
] ]
lint.ignore = [ lint.ignore = [
"E501", # line too long
"E722", # bare except (TODO: fix these) "E722", # bare except (TODO: fix these)
"E731", # don't use lambdas "E731", # don't use lambdas
"E741", # ambiguous variable name "E741", # ambiguous variable name
"PLR0912", # too-many-branches
"PLR0913", # too-many-arguments
"PLR0915", # too-many-statements
"UP004", # useless-object-inheritance
"F821", # TODO: enable "F821", # TODO: enable
"F841", # TODO: enable "F841", # TODO: enable
"PLW0602", # TODO: enable "PLW0602", # TODO: enable

View File

@ -1,4 +1,8 @@
# Generated via scripts/generate_requirements.py and pre-commit hook.
# Do not edit this file; modify pyproject.toml instead.
black==24.2.0 black==24.2.0
coverage[toml] coverage[toml]
nose2 nose2
pre-commit
ruff==0.3.0 ruff==0.3.0
tomli; python_version < '3.11'

View File

@ -1,5 +0,0 @@
# These cause some compatibility issues on some systems and are not strictly necessary
# japanese g2p deps
mecab-python3
unidic-lite==1.0.8
cutlet

View File

@ -1,2 +0,0 @@
bokeh==1.4.0
pandas>=1.4,<2.0

View File

@ -1,46 +0,0 @@
# core deps
numpy>=1.24.3
cython>=0.29.30
scipy>=1.11.2
torch>=2.1
torchaudio
soundfile>=0.12.0
librosa>=0.10.1
inflect>=5.6.0
tqdm>=4.64.1
anyascii>=0.3.0
pyyaml>=6.0
fsspec[http]>=2023.6.0 # <= 2023.9.1 makes aux tests fail
packaging>=23.1
# deps for inference
pysbd>=0.3.4
# deps for notebooks
umap-learn>=0.5.1
# deps for training
matplotlib>=3.7.0
# coqui stack
coqui-tts-trainer>=0.1
# config management
coqpit>=0.0.16
# chinese g2p deps
jieba
pypinyin
# korean
hangul_romanize
# gruut+supported langs
gruut[de,es,fr]==2.2.3
# deps for korean
jamo
g2pkk>=0.1.1
# deps for bangla
bangla
bnnumerizer
bnunicodenormalizer
#deps for tortoise
einops>=0.6.0
transformers>=4.33.0
#deps for bark
encodec>=0.1.1
# deps for XTTS
num2words
spacy[ja]>=3

View File

@ -0,0 +1,39 @@
#!/usr/bin/env python
"""Generate requirements/*.txt files from pyproject.toml.
Adapted from:
https://github.com/numpy/numpydoc/blob/e7c6baf00f5f73a4a8f8318d0cb4e04949c9a5d1/tools/generate_requirements.py
"""
import sys
from pathlib import Path
try: # standard module since Python 3.11
import tomllib as toml
except ImportError:
try: # available for older Python via pip
import tomli as toml
except ImportError:
sys.exit("Please install `tomli` first: `pip install tomli`")
script_pth = Path(__file__)
repo_dir = script_pth.parent.parent
script_relpth = script_pth.relative_to(repo_dir)
header = [
f"# Generated via {script_relpth.as_posix()} and pre-commit hook.",
"# Do not edit this file; modify pyproject.toml instead.",
]
def generate_requirement_file(name: str, req_list: list[str]) -> None:
req_fname = repo_dir / f"requirements.{name}.txt"
req_fname.write_text("\n".join(header + req_list) + "\n")
def main() -> None:
pyproject = toml.loads((repo_dir / "pyproject.toml").read_text())
generate_requirement_file("dev", pyproject["project"]["optional-dependencies"]["dev"])
if __name__ == "__main__":
main()

View File

@ -1,8 +0,0 @@
[build_py]
build_lib=temp_build
[bdist_wheel]
bdist_dir=temp_build
[install_lib]
build_dir=temp_build

108
setup.py
View File

@ -20,54 +20,9 @@
# .,*++++::::::++++*,. # .,*++++::::::++++*,.
# `````` # ``````
import os
import subprocess
import sys
import numpy import numpy
import setuptools.command.build_py
import setuptools.command.develop
from Cython.Build import cythonize from Cython.Build import cythonize
from setuptools import Extension, find_packages, setup from setuptools import Extension, setup
if sys.version_info < (3, 9) or sys.version_info >= (3, 13):
raise RuntimeError("Trainer requires python >= 3.6 and <3.13 " "but your Python version is {}".format(sys.version))
cwd = os.path.dirname(os.path.abspath(__file__))
with open(os.path.join(cwd, "TTS", "VERSION")) as fin:
version = fin.read().strip()
class build_py(setuptools.command.build_py.build_py): # pylint: disable=too-many-ancestors
def run(self):
setuptools.command.build_py.build_py.run(self)
class develop(setuptools.command.develop.develop):
def run(self):
setuptools.command.develop.develop.run(self)
# The documentation for this feature is in server/README.md
package_data = ["TTS/server/templates/*"]
def pip_install(package_name):
subprocess.call([sys.executable, "-m", "pip", "install", package_name])
requirements = open(os.path.join(cwd, "requirements.txt"), "r").readlines()
with open(os.path.join(cwd, "requirements.notebooks.txt"), "r") as f:
requirements_notebooks = f.readlines()
with open(os.path.join(cwd, "requirements.dev.txt"), "r") as f:
requirements_dev = f.readlines()
with open(os.path.join(cwd, "requirements.ja.txt"), "r") as f:
requirements_ja = f.readlines()
requirements_server = ["flask>=2.0.1"]
requirements_all = requirements_dev + requirements_notebooks + requirements_ja + requirements_server
with open("README.md", "r", encoding="utf-8") as readme_file:
README = readme_file.read()
exts = [ exts = [
Extension( Extension(
@ -76,68 +31,7 @@ exts = [
) )
] ]
setup( setup(
name="coqui-tts",
version=version,
url="https://github.com/idiap/coqui-ai-TTS",
author="Eren Gölge",
author_email="egolge@coqui.ai",
maintainer="Enno Hermann",
maintainer_email="enno.hermann@gmail.com",
description="Deep learning for Text to Speech.",
long_description=README,
long_description_content_type="text/markdown",
license="MPL-2.0",
# cython
include_dirs=numpy.get_include(), include_dirs=numpy.get_include(),
ext_modules=cythonize(exts, language_level=3), ext_modules=cythonize(exts, language_level=3),
# ext_modules=find_cython_extensions(),
# package
include_package_data=True,
packages=find_packages(include=["TTS"], exclude=["*.tests", "*tests.*", "tests.*", "*tests", "tests"]),
package_data={
"TTS": [
"VERSION",
]
},
project_urls={
"Documentation": "https://coqui-tts.readthedocs.io",
"Tracker": "https://github.com/idiap/coqui-ai-TTS/issues",
"Repository": "https://github.com/idiap/coqui-ai-TTS",
"Discussions": "https://github.com/idiap/coqui-ai-TTS/discussions",
},
cmdclass={
"build_py": build_py,
"develop": develop,
# 'build_ext': build_ext
},
install_requires=requirements,
extras_require={
"all": requirements_all,
"dev": requirements_dev,
"notebooks": requirements_notebooks,
"server": requirements_server,
"ja": requirements_ja,
},
python_requires=">=3.9.0, <3.13",
entry_points={"console_scripts": ["tts=TTS.bin.synthesize:main", "tts-server = TTS.server.server:main"]},
classifiers=[
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Development Status :: 3 - Alpha",
"Intended Audience :: Science/Research",
"Intended Audience :: Developers",
"Operating System :: POSIX :: Linux",
"License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
"Topic :: Software Development",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Multimedia :: Sound/Audio :: Speech",
"Topic :: Multimedia :: Sound/Audio",
"Topic :: Multimedia",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
],
zip_safe=False, zip_safe=False,
) )

View File

@ -4,4 +4,3 @@ BASEDIR=$(dirname "$0")
echo "$BASEDIR" echo "$BASEDIR"
# run training # run training
CUDA_VISIBLE_DEVICES="" python TTS/bin/compute_statistics.py --config_path $BASEDIR/../inputs/test_glow_tts.json --out_path $BASEDIR/../outputs/scale_stats.npy CUDA_VISIBLE_DEVICES="" python TTS/bin/compute_statistics.py --config_path $BASEDIR/../inputs/test_glow_tts.json --out_path $BASEDIR/../outputs/scale_stats.npy

View File

@ -98,5 +98,3 @@
"gst_style_tokens": 10 "gst_style_tokens": 10
} }
} }

View File

@ -21,4 +21,3 @@
"do_trim_silence": false "do_trim_silence": false
} }
} }

View File

@ -163,4 +163,3 @@
// PATHS // PATHS
"output_path": "tests/train_outputs/" "output_path": "tests/train_outputs/"
} }

View File

@ -113,4 +113,3 @@
// PATHS // PATHS
"output_path": "tests/train_outputs/" "output_path": "tests/train_outputs/"
} }

View File

@ -109,4 +109,3 @@
// PATHS // PATHS
"output_path": "tests/train_outputs/" "output_path": "tests/train_outputs/"
} }