diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml index 822990e967..4122f69f73 100644 --- a/.github/workflows/pypi-release.yml +++ b/.github/workflows/pypi-release.yml @@ -7,8 +7,7 @@ defaults: shell: bash jobs: - build-sdist: - name: Build source distribution + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -20,37 +19,29 @@ jobs: if [[ "v$version" != "$tag" ]]; then exit 1 fi - - uses: actions/setup-python@v5 + - name: Install uv + uses: astral-sh/setup-uv@v3 with: - python-version: 3.9 - - run: | - python -m pip install -U pip setuptools build - - run: | - python -m build - - run: | - pip install dist/*.tar.gz - - uses: actions/upload-artifact@v4 - with: - name: build-sdist - path: dist/*.tar.gz - build-wheels: - name: Build wheels on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - steps: - - uses: actions/checkout@v4 - - name: Build wheels - uses: pypa/cibuildwheel@v2.21.1 + version: "0.4.27" + enable-cache: true + cache-dependency-glob: "**/pyproject.toml" + - name: Set up Python + run: uv python install 3.12 + - name: Build sdist and wheel + run: uv build + - name: Test installation of sdist and wheel + run: | + uv venv --no-project + uv pip install dist/*.tar.gz + uv pip install dist/*.whl - uses: actions/upload-artifact@v4 with: - name: build-wheels-${{ matrix.os }} - path: ./wheelhouse/*.whl + name: build + path: dist/* publish-artifacts: name: Publish to PyPI runs-on: ubuntu-latest - needs: [build-sdist, build-wheels] + needs: [build] environment: name: release url: https://pypi.org/p/coqui-tts @@ -60,8 +51,7 @@ jobs: - uses: actions/download-artifact@v4 with: path: dist - pattern: build-* - merge-multiple: true + pattern: build - run: | ls -lh dist/ - name: Publish package distributions to PyPI diff --git a/CODE_OWNERS.rst b/CODE_OWNERS.rst deleted file mode 100644 index 768b573911..0000000000 --- a/CODE_OWNERS.rst +++ /dev/null @@ -1,75 +0,0 @@ -TTS code owners / governance system -========================================== - -TTS is run under a governance system inspired (and partially copied from) by the `Mozilla module ownership system `_. The project is roughly divided into modules, and each module has its owners, which are responsible for reviewing pull requests and deciding on technical direction for their modules. Module ownership authority is given to people who have worked extensively on areas of the project. - -Module owners also have the authority of naming other module owners or appointing module peers, which are people with authority to review pull requests in that module. They can also sub-divide their module into sub-modules with their owners. - -Module owners are not tyrants. They are chartered to make decisions with input from the community and in the best interest of the community. Module owners are not required to make code changes or additions solely because the community wants them to do so. (Like anyone else, the module owners may write code because they want to, because their employers want them to, because the community wants them to, or for some other reason.) Module owners do need to pay attention to patches submitted to that module. However “pay attention” does not mean agreeing to every patch. Some patches may not make sense for the WebThings project; some may be poorly implemented. Module owners have the authority to decline a patch; this is a necessary part of the role. We ask the module owners to describe in the relevant issue their reasons for wanting changes to a patch, for declining it altogether, or for postponing review for some period. We don’t ask or expect them to rewrite patches to make them acceptable. Similarly, module owners may need to delay review of a promising patch due to an upcoming deadline. For example, a patch may be of interest, but not for the next milestone. In such a case it may make sense for the module owner to postpone review of a patch until after matters needed for a milestone have been finalized. Again, we expect this to be described in the relevant issue. And of course, it shouldn’t go on very often or for very long or escalation and review is likely. - -The work of the various module owners and peers is overseen by the global owners, which are responsible for making final decisions in case there's conflict between owners as well as set the direction for the project as a whole. - -This file describes module owners who are active on the project and which parts of the code they have expertise on (and interest in). If you're making changes to the code and are wondering who's an appropriate person to talk to, this list will tell you who to ping. - -There's overlap in the areas of expertise of each owner, and in particular when looking at which files are covered by each area, there is a lot of overlap. Don't worry about getting it exactly right when requesting review, any code owner will be happy to redirect the request to a more appropriate person. - -Global owners ----------------- - -These are people who have worked on the project extensively and are familiar with all or most parts of it. Their expertise and review guidance is trusted by other code owners to cover their own areas of expertise. In case of conflicting opinions from other owners, global owners will make a final decision. - -- Eren Gölge (@erogol) -- Reuben Morais (@reuben) - -Training, feeding ------------------ - -- Eren Gölge (@erogol) - -Model exporting ---------------- - -- Eren Gölge (@erogol) - -Multi-Speaker TTS ------------------ - -- Eren Gölge (@erogol) -- Edresson Casanova (@edresson) - -TTS ---- - -- Eren Gölge (@erogol) - -Vocoders --------- - -- Eren Gölge (@erogol) - -Speaker Encoder ---------------- - -- Eren Gölge (@erogol) - -Testing & CI ------------- - -- Eren Gölge (@erogol) -- Reuben Morais (@reuben) - -Python bindings ---------------- - -- Eren Gölge (@erogol) -- Reuben Morais (@reuben) - -Documentation -------------- - -- Eren Gölge (@erogol) - -Third party bindings --------------------- - -Owned by the author. diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 8d092ceff2..0000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,10 +0,0 @@ -include README.md -include LICENSE.txt -include *.cff -recursive-include TTS *.json -recursive-include TTS *.html -recursive-include TTS *.png -recursive-include TTS *.md -recursive-include TTS *.py -recursive-include TTS *.pyx -recursive-include images *.png diff --git a/TTS/tts/utils/helpers.py b/TTS/tts/utils/helpers.py index 7429d0fcc8..ab7730ad8e 100644 --- a/TTS/tts/utils/helpers.py +++ b/TTS/tts/utils/helpers.py @@ -1,14 +1,10 @@ import numpy as np import torch +from monotonic_alignment_search import maximum_path as maximum_path_cython from scipy.stats import betabinom from torch.nn import functional as F -try: - from TTS.tts.utils.monotonic_align.core import maximum_path_c - - CYTHON = True -except ModuleNotFoundError: - CYTHON = False +CYTHON = True class StandardScaler: @@ -174,23 +170,23 @@ def maximum_path(value, mask): return maximum_path_numpy(value, mask) -def maximum_path_cython(value, mask): - """Cython optimised version. - Shapes: - - value: :math:`[B, T_en, T_de]` - - mask: :math:`[B, T_en, T_de]` - """ - value = value * mask - device = value.device - dtype = value.dtype - value = value.data.cpu().numpy().astype(np.float32) - path = np.zeros_like(value).astype(np.int32) - mask = mask.data.cpu().numpy() - - t_x_max = mask.sum(1)[:, 0].astype(np.int32) - t_y_max = mask.sum(2)[:, 0].astype(np.int32) - maximum_path_c(path, value, t_x_max, t_y_max) - return torch.from_numpy(path).to(device=device, dtype=dtype) +# def maximum_path_cython(value, mask): +# """Cython optimised version. +# Shapes: +# - value: :math:`[B, T_en, T_de]` +# - mask: :math:`[B, T_en, T_de]` +# """ +# value = value * mask +# device = value.device +# dtype = value.dtype +# value = value.data.cpu().numpy().astype(np.float32) +# path = np.zeros_like(value).astype(np.int32) +# mask = mask.data.cpu().numpy() + +# t_x_max = mask.sum(1)[:, 0].astype(np.int32) +# t_y_max = mask.sum(2)[:, 0].astype(np.int32) +# maximum_path_c(path, value, t_x_max, t_y_max) +# return torch.from_numpy(path).to(device=device, dtype=dtype) def maximum_path_numpy(value, mask, max_neg_val=None): diff --git a/TTS/tts/utils/monotonic_align/__init__.py b/TTS/tts/utils/monotonic_align/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/TTS/tts/utils/monotonic_align/core.pyx b/TTS/tts/utils/monotonic_align/core.pyx deleted file mode 100644 index 091fcc3a50..0000000000 --- a/TTS/tts/utils/monotonic_align/core.pyx +++ /dev/null @@ -1,47 +0,0 @@ -import numpy as np - -cimport cython -cimport numpy as np - -from cython.parallel import prange - - -@cython.boundscheck(False) -@cython.wraparound(False) -cdef void maximum_path_each(int[:,::1] path, float[:,::1] value, int t_x, int t_y, float max_neg_val) nogil: - cdef int x - cdef int y - cdef float v_prev - cdef float v_cur - cdef float tmp - cdef int index = t_x - 1 - - for y in range(t_y): - for x in range(max(0, t_x + y - t_y), min(t_x, y + 1)): - if x == y: - v_cur = max_neg_val - else: - v_cur = value[x, y-1] - if x == 0: - if y == 0: - v_prev = 0. - else: - v_prev = max_neg_val - else: - v_prev = value[x-1, y-1] - value[x, y] = max(v_cur, v_prev) + value[x, y] - - for y in range(t_y - 1, -1, -1): - path[index, y] = 1 - if index != 0 and (index == y or value[index, y-1] < value[index-1, y-1]): - index = index - 1 - - -@cython.boundscheck(False) -@cython.wraparound(False) -cpdef void maximum_path_c(int[:,:,::1] paths, float[:,:,::1] values, int[::1] t_xs, int[::1] t_ys, float max_neg_val=-1e9) nogil: - cdef int b = values.shape[0] - - cdef int i - for i in prange(b, nogil=True): - maximum_path_each(paths[i], values[i], t_xs[i], t_ys[i], max_neg_val) diff --git a/pyproject.toml b/pyproject.toml index 23387fd37d..379187feed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,27 @@ -[build-system] -requires = [ - "setuptools", - "setuptools-scm", - "cython>=3.0.0", - "numpy>=2.0.0", -] -build-backend = "setuptools.build_meta" +# ,*++++++*, ,*++++++*, +# *++. .+++ *++. .++* +# *+* ,++++* *+* *+* ,++++, *+* +# ,+, .++++++++++* ,++,,,,*+, ,++++++++++. *+, +# *+. .++++++++++++..++ *+.,++++++++++++. .+* +# .+* ++++++++++++.*+, .+*.++++++++++++ *+, +# .++ *++++++++* ++, .++.*++++++++* ++, +# ,+++*. . .*++, ,++*. .*+++* +# *+, .,*++**. .**++**. ,+* +# .+* *+, +# *+. Coqui .+* +# *+* +++ TTS +++ *+* +# .+++*. . . *+++. +# ,+* *+++*... ...*+++* *+, +# .++. .""""+++++++****+++++++"""". ++. +# ,++. .++, +# .++* *++. +# *+++, ,+++* +# .,*++++::::::++++*,. +# `````` -[tool.setuptools.packages.find] -include = ["TTS*"] +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" [project] name = "coqui-tts" @@ -64,6 +77,7 @@ dependencies = [ # Coqui stack "coqui-tts-trainer>=0.1.4,<0.2.0", "coqpit>=0.0.16", + "monotonic-alignment-search>=0.1.0", # Gruut + supported languages "gruut[de,es,fr]>=2.4.0", # Tortoise @@ -151,6 +165,22 @@ tts-server = "TTS.server.server:main" [tool.uv] constraint-dependencies = ["numba>0.58.0"] +[tool.hatch.build] +exclude = [ + "/.github", + "/.gitignore", + "/.pre-commit-config.yaml", + "/.readthedocs.yml", + "/Makefile", + "/dockerfiles", + "/run_bash_tests.sh", + "/scripts", + "/tests", +] + +[tool.hatch.build.targets.wheel] +packages = ["TTS"] + [tool.ruff] line-length = 120 extend-exclude = ["*.ipynb"] diff --git a/setup.py b/setup.py deleted file mode 100644 index 1cf2def1d3..0000000000 --- a/setup.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -# ,*++++++*, ,*++++++*, -# *++. .+++ *++. .++* -# *+* ,++++* *+* *+* ,++++, *+* -# ,+, .++++++++++* ,++,,,,*+, ,++++++++++. *+, -# *+. .++++++++++++..++ *+.,++++++++++++. .+* -# .+* ++++++++++++.*+, .+*.++++++++++++ *+, -# .++ *++++++++* ++, .++.*++++++++* ++, -# ,+++*. . .*++, ,++*. .*+++* -# *+, .,*++**. .**++**. ,+* -# .+* *+, -# *+. Coqui .+* -# *+* +++ TTS +++ *+* -# .+++*. . . *+++. -# ,+* *+++*... ...*+++* *+, -# .++. .""""+++++++****+++++++"""". ++. -# ,++. .++, -# .++* *++. -# *+++, ,+++* -# .,*++++::::::++++*,. -# `````` - -import numpy -from Cython.Build import cythonize -from setuptools import Extension, setup - -exts = [ - Extension( - name="TTS.tts.utils.monotonic_align.core", - sources=["TTS/tts/utils/monotonic_align/core.pyx"], - ) -] -setup( - include_dirs=numpy.get_include(), - ext_modules=cythonize(exts, language_level=3), - zip_safe=False, -)