Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d0af3ab
add initial workflow
MahmoudAshraf97 Jan 1, 2025
eacc567
fix run conditions
MahmoudAshraf97 Jan 1, 2025
657c07a
fix package_dir
MahmoudAshraf97 Jan 1, 2025
8aff498
.
MahmoudAshraf97 Jan 1, 2025
15e55d0
bump python version
MahmoudAshraf97 Jan 1, 2025
5a751b0
add uv action
MahmoudAshraf97 Jan 1, 2025
ed239ff
.
MahmoudAshraf97 Jan 1, 2025
e2255c6
.
MahmoudAshraf97 Jan 1, 2025
7a5c074
.
MahmoudAshraf97 Jan 1, 2025
f4ba425
.
MahmoudAshraf97 Jan 1, 2025
c414e57
.
MahmoudAshraf97 Jan 1, 2025
7734e71
dynamic version
MahmoudAshraf97 Jan 7, 2025
9bf3d33
delete old ci [skip ci]
MahmoudAshraf97 Jan 7, 2025
1b3ba68
add dev dependencies
MahmoudAshraf97 Jan 7, 2025
d4a1810
add tests [skip ci]
MahmoudAshraf97 Jan 7, 2025
7059dbe
update black version [skip ci]
MahmoudAshraf97 Jan 7, 2025
0012b4e
formatting [skip ci]
MahmoudAshraf97 Jan 7, 2025
aa2d0be
new ci
MahmoudAshraf97 Jan 7, 2025
fd043f3
.
MahmoudAshraf97 Jan 7, 2025
9e55b73
.
MahmoudAshraf97 Jan 7, 2025
fd09837
.
MahmoudAshraf97 Jan 7, 2025
b5a31f3
.
MahmoudAshraf97 Jan 7, 2025
3b7c1f1
fix path
MahmoudAshraf97 Jan 7, 2025
a4d588a
fix path
MahmoudAshraf97 Jan 7, 2025
c2c1650
reduce python versions in testing
MahmoudAshraf97 Jan 7, 2025
de7ad06
..
MahmoudAshraf97 Jan 7, 2025
a7967fd
.
MahmoudAshraf97 Jan 7, 2025
a5ad8dd
.
MahmoudAshraf97 Jan 7, 2025
bb8087d
bump macos
MahmoudAshraf97 Jan 7, 2025
0362b03
.
MahmoudAshraf97 Jan 7, 2025
be9a864
.
MahmoudAshraf97 Jan 7, 2025
07d39ee
.
MahmoudAshraf97 Jan 7, 2025
1b25ad0
.
MahmoudAshraf97 Jan 7, 2025
be800cb
.
MahmoudAshraf97 Jan 7, 2025
62954f3
.
MahmoudAshraf97 Jan 7, 2025
e85b875
fix name
MahmoudAshraf97 Jan 7, 2025
96d57d2
remove 3.13 from testing
MahmoudAshraf97 Jan 7, 2025
2a771ac
fix win compile args [skip ci]
MahmoudAshraf97 Jan 7, 2025
7f9729a
multicore testing
MahmoudAshraf97 Jan 7, 2025
4e958fe
.
MahmoudAshraf97 Jan 7, 2025
a1f2ae7
.
MahmoudAshraf97 Jan 8, 2025
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
150 changes: 150 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
name: CI

on:
push:
branches: [ "main" ]
tags:
- v*
pull_request:
branches: [ "main" ]

jobs:
check-python-style:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python 3.9
uses: actions/setup-python@v5
with:
python-version: 3.9

- name: Setup UV
uses: astral-sh/setup-uv@v5
with:
version: "latest"

- name: Install dependencies
run: |
uv pip install --system black==24.* flake8==7.* flake8-pyproject==1.* isort==5.*

- name: Check code format with Black
run: |
black --check ctc_forced_aligner/*.py

- name: Check imports order with isort
run: |
isort --check-only ctc_forced_aligner/*.py

- name: Check code style with Flake8
run: |
flake8 ctc_forced_aligner/*.py

build-python-wheels:
needs: [check-python-style]
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macos-14]
arch: [auto64]
include:
- os: ubuntu-20.04
arch: aarch64
- os: windows-2019
arch: ARM64

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: docker/setup-qemu-action@v3
if: ${{ matrix.arch == 'aarch64' }}
name: Set up QEMU

- name: Setup UV
uses: astral-sh/setup-uv@v5
with:
version: "latest"

- name: Build wheels
uses: pypa/[email protected]
with:
output-dir: python/wheelhouse
env:
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux2014
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_SKIP: pp* *-musllinux_*
CIBW_BUILD_FRONTEND: "build[uv]"

- name: Upload Python wheels
uses: actions/upload-artifact@v4
with:
name: python-wheels-${{ runner.os }}-${{ matrix.arch }}
path: python/wheelhouse

test-python-wheels:
# We could test the Python wheels using cibuildwheel but we prefer to run the tests outside
# the build environment to ensure wheels correctly embed all dependencies.
needs: [build-python-wheels]
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
os: [ubuntu-20.04, windows-2019, macos-14]
arch: [auto64]

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Download Python wheels
uses: actions/download-artifact@v4
with:
pattern: python-wheels-${{ runner.os }}-${{ matrix.arch }}
merge-multiple: true
path: wheels

- name: Setup UV
uses: astral-sh/setup-uv@v5
with:
version: "latest"

- name: Install wheel
shell: bash
run: |
wheel_name=$(find wheels -type f -name "*$(echo ${{ matrix.python-version }} | tr -d '.')*")
uv pip install --system "pytest-xdist" "$wheel_name[dev]" --extra-index-url https://download.pytorch.org/whl/cpu

- name: Run tests
shell: bash
run: |
pytest -v -n auto tests/

publish-python-wheels-on-pypi:
needs: [test-python-wheels]
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
runs-on: ubuntu-latest
steps:
- name: Download Python wheels
uses: actions/download-artifact@v4
with:
pattern: python-wheels-*
merge-multiple: true
path: .

- name: Publish Python wheels to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages-dir: .
50 changes: 0 additions & 50 deletions .github/workflows/test_build.yml

This file was deleted.

2 changes: 2 additions & 0 deletions ctc_forced_aligner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
split_text,
text_normalize,
)

__version__ = "0.3.0"
18 changes: 15 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@ build-backend = "setuptools.build_meta"

[project]
name = "ctc-forced-aligner"
version = "0.2"
description = "Text to speech alignment using CTC forced alignment"
license = { text = "CC-BY-NC 4.0" }
authors = [
{name = "Mahmoud Ashraf", email = "[email protected]"},]
dynamic = ["dependencies"]
dynamic = ["version", "dependencies"]
requires-python = ">= 3.9"

[tool.setuptools.dynamic]
version = {attr = "ctc_forced_aligner.__version__"}
dependencies = {file = ["requirements.txt"]}

[project.optional-dependencies]
dev = ["black==23.*", "flake8==7.*", "flake8-pyproject==1.*", "isort==5.*", "pytest==7.*"]

[project.urls]
repository = "https://github.com/MahmoudAshraf97/ctc-forced-aligner"

Expand All @@ -26,4 +30,12 @@ ctc-forced-aligner = "ctc_forced_aligner.align:cli"
"uroman/bin/**/*.*",
"uroman/data/**/*.*",
"uroman/lib/**/*.*",
]
]

[tool.flake8]
max-line-length = 100
ignore = ["E203", "W503"]

[tool.isort]
profile = "black"
lines_between_types = 1
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from pybind11.setup_helpers import Pybind11Extension, build_ext
from setuptools import setup
import sys

ext_modules = [
Pybind11Extension(
"ctc_forced_aligner.ctc_forced_aligner",
["ctc_forced_aligner/forced_align_impl.cpp"],
extra_compile_args=["-O3"],
extra_compile_args=["/O2"] if sys.platform == "win32" else ["-O3"],
)
]

Expand Down
27 changes: 27 additions & 0 deletions tests/test_alignment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import numpy as np
import pytest
import torch
import torchaudio.functional as F

from ctc_forced_aligner.alignment_utils import forced_align


@pytest.mark.parametrize(
"logprobs_size, vocab_size, targets_size",
[
(l, t, int(l * ratio))
for l in range(100, 60101, 20000)
for t in range(30, 41, 10)
for ratio in [0.4, 0.6]
],
)
def test_alignment(logprobs_size, vocab_size, targets_size):
blank = 0
targets = torch.randint(blank + 1, vocab_size, (1, targets_size))
logprobs = torch.randn((1, logprobs_size, vocab_size + 1))
logprobs = 6.5 * logprobs - 13 # same distribution as default model logits

ctc_alignment = forced_align(logprobs.numpy(), targets.numpy())
torch_alignment = F.forced_align(logprobs, targets)

assert np.allclose(ctc_alignment[0], torch_alignment[0].numpy())
Loading