NeMo
English
audio
speech
forced-alignment
reference-text-alignment
speech-processing
mfa
whisperx
python
metric:mae
Eval Results (legacy)
Instructions to use vertox-ai/speech-text-data-aligners with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- NeMo
How to use vertox-ai/speech-text-data-aligners with NeMo:
# tag did not correspond to a valid NeMo domain.
- Notebooks
- Google Colab
- Kaggle
Download tests/unit/data/test_metadata.py from vertox-ai/speech-text-data-aligners: direct link, hf CLI and curl.
- Browser
- Download file 4.99 kB
-
https://huggingface.co/vertox-ai/speech-text-data-aligners/resolve/main/tests/unit/data/test_metadata.py
- Command line
-
hf download hf://vertox-ai/speech-text-data-aligners/tests/unit/data/test_metadata.py
-
curl -L -o test_metadata.py https://huggingface.co/vertox-ai/speech-text-data-aligners/resolve/main/tests/unit/data/test_metadata.py
4.99 kB
| # License: Apache-2.0 License | |
| # Created by: Patrick Lumbantobing, VertoX-AI | |
| # Copyright (c) 2026 VertoX-AI. All rights reserved. | |
| # | |
| # This work is licensed under the Apache-2.0 License. | |
| # To view a copy of this license, visit | |
| # https://www.apache.org/licenses/LICENSE-2.0 | |
| from __future__ import annotations | |
| import os | |
| from pathlib import Path | |
| import pytest | |
| from speech_text_data_aligners.core.errors import MetadataError | |
| from speech_text_data_aligners.core.extraction import BOUNDARY_COLUMNS | |
| from speech_text_data_aligners.data.metadata import ( | |
| MetadataTable, | |
| read_metadata, | |
| write_annotated_metadata, | |
| ) | |
| def valid_annotations(count: int) -> tuple[dict[str, str | float | None], ...]: | |
| return tuple( | |
| { | |
| "first_word_text": "Hello", | |
| "first_word_start_s": 0.000001, | |
| "first_word_end_s": 0.5, | |
| "last_word_text": "world", | |
| "last_word_start_s": 1.0, | |
| "last_word_end_s": None, | |
| } | |
| for _ in range(count) | |
| ) | |
| def test_read_and_write_preserve_bom_crlf_quoted_values_and_order( | |
| tmp_path: Path, | |
| ) -> None: | |
| source = tmp_path / "source.csv" | |
| source.write_bytes( | |
| b"\xef\xbb\xbfline_id,audio_id,en_transcript,ru_translation\r\n" | |
| b'L1,a1,"Hello, world",Russian\r\n' | |
| b'L1,a2,"multi\r\nline",Exact\r\n' | |
| ) | |
| table = read_metadata(source) | |
| assert table.csv_format.encoding == "utf-8-sig" | |
| assert table.csv_format.lineterminator == "\r\n" | |
| assert table.row_dict(0)["en_transcript"] == "Hello, world" | |
| assert table.row_dict(1)["en_transcript"] == "multi\r\nline" | |
| output = tmp_path / "output.csv" | |
| write_annotated_metadata(table, output, valid_annotations(2)) | |
| reread = read_metadata(output) | |
| assert reread.fieldnames == (*table.fieldnames, *BOUNDARY_COLUMNS) | |
| assert reread.rows[0][:4] == table.rows[0] | |
| assert reread.row_dict(0)["first_word_start_s"] == "0.000001" | |
| assert reread.row_dict(0)["first_word_end_s"] == "0.5" | |
| assert reread.row_dict(0)["last_word_end_s"] == "" | |
| def test_read_rejects_empty_missing_duplicate_malformed_and_non_utf8( | |
| tmp_path: Path, content: bytes | |
| ) -> None: | |
| path = tmp_path / "bad.csv" | |
| path.write_bytes(content) | |
| with pytest.raises(MetadataError): | |
| read_metadata(path) | |
| def test_read_rejects_missing_path(tmp_path: Path) -> None: | |
| with pytest.raises(MetadataError): | |
| read_metadata(tmp_path / "missing.csv") | |
| def test_write_rejects_unsafe_schema_counts_keys_and_overwrite( | |
| metadata_fixture: tuple[Path, Path], tmp_path: Path | |
| ) -> None: | |
| source, _ = metadata_fixture | |
| table = read_metadata(source) | |
| output = tmp_path / "out.csv" | |
| output.write_text("existing", encoding="utf-8") | |
| with pytest.raises(MetadataError, match="source metadata"): | |
| write_annotated_metadata(table, source, valid_annotations(2)) | |
| with pytest.raises(MetadataError, match="count"): | |
| write_annotated_metadata(table, tmp_path / "other.csv", valid_annotations(1)) | |
| with pytest.raises(MetadataError, match="six"): | |
| write_annotated_metadata(table, tmp_path / "other.csv", ({"bad": "x"},) * 2) | |
| with pytest.raises(MetadataError, match="overwrite"): | |
| write_annotated_metadata(table, output, valid_annotations(2)) | |
| enriched = MetadataTable( | |
| table.source_path, | |
| (*table.fieldnames, BOUNDARY_COLUMNS[0]), | |
| tuple((*row, "") for row in table.rows), | |
| table.csv_format, | |
| ) | |
| with pytest.raises(MetadataError, match="already"): | |
| write_annotated_metadata( | |
| enriched, tmp_path / "enriched.csv", valid_annotations(2) | |
| ) | |
| def test_write_overwrites_when_authorized( | |
| metadata_fixture: tuple[Path, Path], tmp_path: Path | |
| ) -> None: | |
| source, _ = metadata_fixture | |
| table = read_metadata(source) | |
| output = tmp_path / "out.csv" | |
| output.write_text("old", encoding="utf-8") | |
| write_annotated_metadata(table, output, valid_annotations(2), overwrite=True) | |
| assert read_metadata(output).row_dict(0)["first_word_text"] == "Hello" | |
| def test_write_translates_publication_oserror( | |
| metadata_fixture: tuple[Path, Path], tmp_path: Path, monkeypatch: pytest.MonkeyPatch | |
| ) -> None: | |
| source, _ = metadata_fixture | |
| table = read_metadata(source) | |
| def fail_replace(source_path: Path, destination_path: Path) -> None: | |
| raise OSError(source_path, destination_path) | |
| monkeypatch.setattr(os, "replace", fail_replace) | |
| with pytest.raises(MetadataError, match="publish"): | |
| write_annotated_metadata(table, tmp_path / "out.csv", valid_annotations(2)) | |
| assert not list(tmp_path.glob(".out.csv.*.tmp")) | |