Skip to content

Commit 1105f25

Browse files
authored
Integrating models with Hugging Face (#957)
* Add dependencies for huggingface_hub * Update alignment analysis calculations * Add command for migrating models to hf format * Bump kalpy versions
1 parent 01b9664 commit 1105f25

101 files changed

Lines changed: 5367 additions & 2074 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,45 @@ Please see the documentation http://montreal-forced-aligner.readthedocs.io for i
1212

1313
If you run into any issues, please check the [mailing list](https://groups.google.com/forum/#!forum/mfa-users) for fixes/workarounds or to post a [new issue](https://github.com/MontrealCorpusTools/Montreal-Forced-Aligner/issues).
1414

15+
## Citation
16+
17+
### MFA 3.0
18+
19+
For citing the latest version of MFA and its pretrained models, please use:
20+
21+
McAuliffe, Michael, Kaylynn Gunter, Michael Wagner, and Morgan Sonderegger (2026).
22+
Montreal Forced Aligner and the state of speech-to-text alignment in 2026. In
23+
*Proceedings of Interspeech 2026*.
24+
25+
26+
```
27+
@inproceedings{mcauliffe26_interspeech,
28+
author={McAuliffe, Michael and Gunter, Kaylynn and Wagner, Michael and Sonderegger, Morgan},
29+
title={{Montreal Forced Aligner and the state of speech-to-text alignment in 2026}},
30+
year=2026,
31+
booktitle={Proc. Interspeech 2026}
32+
}
33+
```
34+
35+
### MFA 1.0
36+
37+
For citing the original software and models (upgrading to the MFA 3.X is recommended!), please use:
38+
39+
McAuliffe, Michael, Michaela Socolof, Sarah Mihuc, Michael Wagner, and Morgan Sonderegger (2017).
40+
Montreal Forced Aligner: trainable text-speech alignment using Kaldi. In
41+
*Proceedings of Interspeech 2017*.
42+
43+
```
44+
@inproceedings{mcauliffe17_interspeech,
45+
author={McAuliffe, Michael and Socolof, Michaela and Mihuc, Sarah and Wagner, Michael and Sonderegger, Morgan},
46+
title={{Montreal Forced Aligner: Trainable Text-Speech Alignment Using Kaldi}},
47+
year=2017,
48+
booktitle={Proc. Interspeech 2017},
49+
pages={498--502},
50+
doi={10.21437/Interspeech.2017-1386}
51+
}
52+
```
53+
1554
## Installation
1655

1756
You can install MFA either entirely through [conda](https://docs.conda.io/en/latest/) or a mix of conda for Kaldi and Pynini dependencies and Python packaging for MFA itself

ci/docker_environment.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,14 @@ dependencies:
3838
- sqlite
3939
- rich
4040
- rich-click
41-
- kalpy>=0.8
41+
- kalpy>=0.10
4242
- spacy
4343
- sudachipy
4444
- sudachidict-core
4545
- spacy-pkuseg
4646
- sentencepiece
47+
- huggingface_hub
48+
- jinja2
4749
- pip
4850
- pip:
4951
- speechbrain==1.0.3
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
.. _changelog_3.4:
3+
4+
*************
5+
3.4 Changelog
6+
*************
7+
8+
3.4.0
9+
-----
10+
11+
- Compatibility with Kalpy 0.9.0
12+
- Introduced new command for :ref:`compare_alignments`
13+
- Introduced new MFA model format for distribution on HuggingFace
14+
- Introduced new commands that use the new MFA model format (i.e. :ref:`pretrained_alignment_hf`) which will replace the default commands (i.e. :ref:`pretrained_alignment`) in MFA 4.0. The default commands will still be available using a legacy command and will be removed in MFA 5.0.
15+
- Deprecated :ref:`train_tokenizer_cli` and :ref:`tokenize_cli` for removal in MFA 4.0
16+
- Added calculation for :ref:`alignment_analysis_intensity_deviation` and :ref:`alignment_analysis_snr` to be included as diagnostic metrics for alignment
17+
- Updated calculation for phone duration deviation to use log-duration to better model the duration distribution
18+
- Added column for :ref:`alignment_max_running_short_intervals` as a measure of alignment quality

docs/source/changelog/index.md

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,52 +7,32 @@
77
Please bear in mind that all plans below are tentative and subject to change.
88
```
99

10-
### Version 3.1
10+
### Version 5.0 (Planned for 2027)
1111

12-
* Persistent server for sending audio/text files to
13-
* May not be necessary/prioritized with {ref}`align_one` command
14-
* Update tokenization to use spacy tokenizers instead of custom specification
15-
* Should be more robust than MFA's custom rules
16-
* Some languages are more finely tokenized than others (i.e., Japanese and Korean tokens are largely morphemes, while the English one doesn't do morpheme analysis), but the ideal would be some morphologically-aware G2P of phonological words
17-
* Add option for training SpeechBrain ASR model on phone strings of MFA models
18-
* Should allow for better single-pass alignment and faster with GPUs
19-
* Release Anchor compatible with the latest versions of MFA
12+
* Removal of legacy alignment commands
13+
* Legacy models can still be used with previous versions of MFA
14+
* Support for neural network acoustic models
2015

21-
### Future
16+
### Version 4.0 (Planned for end of 2026)
17+
18+
* Deprecation of legacy model usage
19+
* Commands for {ref}`align_hf`, {ref}`adapt_hf`, and {ref}`align_one_hf` will be renamed to {ref}`align`, {ref}`adapt`, and {ref}`align_one` and 3.4 {ref}`align`, {ref}`adapt`, and {ref}`align_one` will be renamed {ref}`align_legacy`, {ref}`adapt_legacy`, and {ref}`align_one_legacy`
20+
* Refactor and code clean up
21+
* Broad phone sets with modular implementation of phonological rules
22+
* Richer lexicon support
23+
24+
### Version 3.4 (Released)
25+
26+
* {ref}`changelog_3.4`
2227

23-
* Retrain existing acoustic models with new phone groups and rules features
24-
* Begin work on expanding to new languages
25-
* Japanese (in progress)
26-
* Arabic
27-
* Tamil
28-
* Localize documentation
29-
* I'll initially do a pass at localizing the documentation to Japanese and see if I can crowd source other languages (and fixing my initial Japanese pass)
30-
* Update pitch feature calculation to use speaker-adjusted min and max f0 ranges
3128

32-
* Moving away from Kaldi-based dependencies
33-
* Kaldi is not being actively developed and I don't have much of a desire to depend on it long term
34-
* Most actively developed ASR toolkits and libraries are based around neural networks
35-
* I'm not the biggest fan of using these for alignment, as most of the research is geared towards improving end-to-end signal to orthographic text models that don't have intermediate representations of phones
36-
* That said, if alignment were the task that was being optimized for rather than some "word error rate" style metric, then alignment performance could improve significantly
37-
* One particular direction would be towards sample-based or waveform-based alignment rather than frame-based
38-
* Frame-based methods are time-smeared, so providing an exact time for voicing onset or stop closure is murky
39-
* Phoneticians use spectrograms for gross boundaries, but more accurate manual alignments are determined based on the waveform
40-
* Perhaps combining a model that performs language-independent boundary insertion combined with per-language models to combine resulting segments might perform better ({ipa_inline}`[a]` + {ipa_inline}`[j]` becomes {ipa_inline}`[aj]` in English, but not in other languages like Japanese, Spanish, or Portuguese, etc)
41-
* Additionally, neural networks might allow for better modeling of phone symbols, so embedding {ipa_inline}`[pʲ]` could result in a more compositional "voiceless bilabial stop plus palatalization"
42-
* Other options for toolkits to support MFA are
43-
* [SpeechBrain](https://speechbrain.github.io/)
44-
* Custom PyTorch code
45-
* Custom tensorflow code
46-
* Update dictionary model format to move away from the current plain-text lexicons to a more robust compressed format
47-
* With extra meta data and capabilities in the form of phonological rules and phone groupings, it makes more sense to package those with the lexicon rather than the acoustic model
48-
* Another option would be to package up the lexicon (and maybe G2P models) with the acoustic model into a complete MFA model
49-
* As part of any update, I would expand the {ref}`MFA model CLI <pretrained_models>` with functionality for adding new pronunciations to internal lexicons
50-
* Something like {code}`mfa model update /path/to/g2pped_file.txt`
5129

5230
```{toctree}
5331
:hidden:
5432
:maxdepth: 1
5533
34+
news_3.4.rst
35+
changelog_3.4.rst
5636
changelog_3.3.rst
5737
changelog_3.2.rst
5838
changelog_3.1.rst

docs/source/changelog/news_3.4.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
.. _whats_new_3_4:
3+
4+
What's new in 3.4
5+
=================
6+
7+
Version 3.4 of the Montreal Forced Aligner introduces a new model format to allow for distribution via Hugging Face. See :ref:`mfa_model_versions` for more details on the changes and how to use and distribute these models.
8+
9+
Additionally, MFA-trained tokenizers are being deprecated and will be removed in MFA 4.0, as the language-specific tokenization in training has yielded much better and consistent results (see :ref:`language_tokenization` for more details).
10+
11+
Finally, a new MFA paper reflecting the updates over the past 10 years along with benchmarks with recent and other widely-used aligners across three languages will be presented at Interspeech 2026! See :ref:`citing_mfa` for more details on the updated citation.

docs/source/conf.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
from datetime import date
2323

2424
sys.path.insert(0, os.path.abspath("../../"))
25-
import montreal_forced_aligner # noqa
26-
from montreal_forced_aligner.utils import get_mfa_version # noqa
25+
try:
26+
from montreal_forced_aligner.utils import get_mfa_version # noqa
27+
release = get_mfa_version()
28+
except ImportError:
29+
release = "3.4.0"
2730

2831
# -- General configuration ------------------------------------------------
2932

@@ -76,6 +79,7 @@
7679
}
7780

7881
xref_links = {
82+
"hf": ("Hugging Face", "https://huggingface.co/"),
7983
"mfa_models": ("MFA Models", "https://mfa-models.readthedocs.io/"),
8084
"mfa_models_repo": (
8185
"MFA Models repository",
@@ -229,6 +233,7 @@
229233
"mp.Process": "multiprocessing.Process",
230234
"MetaDict": "dict[str, Any]",
231235
}
236+
autodoc_mock_imports = ['kalpy', 'kalpy.evaluation.naive_boundary_f1']
232237

233238
napoleon_preprocess_types = False
234239
napoleon_attr_annotations = False
@@ -274,9 +279,8 @@
274279
# built documents.
275280
#
276281
# The short X.Y version.
277-
version = ".".join(get_mfa_version().split(".", maxsplit=2)[:2])
282+
version = ".".join(release.split(".", maxsplit=2)[:2])
278283
# The full version, including alpha/beta/rc tags.
279-
release = get_mfa_version()
280284

281285
# The language for content autogenerated by Sphinx. Refer to documentation
282286
# for a list of supported languages.
@@ -397,6 +401,8 @@
397401
# "navigation_depth": 4,
398402
# "show_toc_level": 2,
399403
# "collapse_navigation": True,
404+
"announcement": "Starting with Version 3.4, we are rolling out new model formats that integrate with Hugging Face! "
405+
"See <a href='changelog/news_3.4.html'>here</a> for the latest updates in MFA 3.4.",
400406
}
401407
html_context = {
402408
"github_user": "MontrealCorpusTools",

docs/source/first_steps/index.rst

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,6 @@ There are several broad use cases that you might want to use MFA for. Take a lo
8282
#. Use the trained G2P model in :ref:`first_steps_g2p_pretrained` to generate a pronunciation dictionary
8383
#. Use the generated pronunciation dictionary in :ref:`first_steps_align_train_acoustic_model` to generate aligned TextGrids
8484

85-
#. **Use case 6:** You have a :ref:`speech corpus <corpus_structure>` and the language has a :xref:`pretrained acoustic model <pretrained_acoustic_models>`, but the language does not mark word boundaries in its orthography (and the language has a :xref:`pretrained tokenizer model <pretrained_tokenizer_models>`).
86-
87-
#. Follow :ref:`first_steps_tokenize` to tokenize the corpus
88-
#. Use the tokenized transcripts and follow :ref:`first_steps_align_pretrained`
8985

9086
.. _first_steps_align_pretrained:
9187

@@ -337,36 +333,4 @@ Once the G2P model is trained, you should see the exported archive in the folder
337333
338334
mfa g2p ~/mfa_data/my_new_word_list.txt ~/mfa_data/my_g2p_model.zip ~/mfa_data/my_new_dictionary.txt
339335
340-
Take a look at :ref:`first_steps_g2p_pretrained` with this new model for a more detailed walk-through of generating a dictionary.
341-
.. _first_steps_tokenize:
342-
343-
Tokenize a corpus to add word boundaries
344-
----------------------------------------
345-
346-
For the purposes of this example, we'll also assume that you have done nothing else with MFA other than follow the :ref:`installation` instructions and you have the :code:`mfa` command working. Finally, we'll assume that your corpus is in Japanese and is stored in the folder :code:`~/mfa_data/my_corpus`, so when working with your data, this will be the main thing to update.
347-
348-
To tokenize the Japanese text to add spaces, first download the Japanese tokenizer model via:
349-
350-
351-
.. code-block::
352-
353-
mfa model download tokenizer japanese_mfa
354-
355-
Once you have the model downloaded, you can tokenize your corpus via:
356-
357-
.. code-block::
358-
359-
mfa tokenize ~/mfa_data/my_corpus japanese_mfa ~/mfa_data/tokenized_version
360-
361-
You can check the tokenized text in :code:`~/mfa_data/tokenized_version`, verify that it looks good, and copy the files to replace the untokenized files in :code:`~/mfa_data/my_corpus` for use in alignment.
362-
363-
.. warning::
364-
365-
MFA's tokenizer models are nowhere near state of the art, and I recommend using other tokenizers as they make sense:
366-
367-
* Japanese: `nagisa <https://nagisa.readthedocs.io/en/latest/>`_
368-
* Chinese: `spacy-pkuseg <https://github.com/explosion/spacy-pkuseg/blob/master/readme/readme_english.md>`_
369-
* Thai: `sertiscorp/thai-word-segmentation <https://github.com/sertiscorp/thai-word-segmentation>`_
370-
371-
The above were used in the initial construction of the training corpora for MFA, though the training segmentations for Japanese have begun to diverge from :code:`nagisa`, as they break up phonological words into morphological parses where for the purposes of acoustic model training and alignment it makes more sense to not split (nagisa: :ipa_inline:`使っ て [ts ɨ k a Q t e]` vs mfa: :ipa_inline:`使って [ts ɨ k a tː e]`). The MFA tokenizer models are provided as an easy start up path as the ones listed above may have extra dependencies and platform restrictions.
372-
336+
Take a look at :ref:`first_steps_g2p_oovs` with this new model for a more detailed walk-through of generating a dictionary.

docs/source/user_guide/corpus_creation/tokenize.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
Tokenize utterances ``(mfa tokenize)``
55
=========================================
66

7+
.. deprecated:: 3.4
8+
9+
The functionality for training tokenizers in MFA is deprecated and slated to be removed in MFA 4.0. For better solutions for tokenizing a given language, see :ref:`language_tokenization` for how to use dedicated packages and models for various languages.
10+
711
Use a model trained from :ref:`train_tokenizer_cli` to tokenize a corpus (i.e. insert spaces as word boundaries for orthographic systems that do not require them).
812

913
Command reference

docs/source/user_guide/corpus_creation/train_tokenizer.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
Train a word tokenizer ``(mfa train_tokenizer)``
55
================================================
66

7+
.. deprecated:: 3.4
8+
9+
The functionality for training tokenizers in MFA is deprecated and slated to be removed in MFA 4.0. For better solutions for tokenizing a given language, see :ref:`language_tokenization` for how to use dedicated packages and models for various languages.
10+
711
Training a tokenizer uses a simplified sequence-to-sequence model like G2P, but with the following differences:
812

913
* Both the input and output symbols are graphemes

docs/source/user_guide/implementations/alignment_analysis.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
When exporting textgrids following alignment, an additional file named `alignment_analysis.csv` will be exported. I am still currently working to refine what are the best measures for analyzing alignments as it's not entirely as straightforward as taking the overall alignment log-likelihood.
66

7+
(alignment_analysis_log_likelihood)=
78
## Alignment log-likelihood
89

910
The first measure provided for each utterance is the alignment log-likelihood. This represents overall the objective measure that was optimized for alignment. However, it is extremely important to note that this log-likelihood is a relative measure for the best path of alignment for this particular utterance compared to other possible alignments.
@@ -16,14 +17,35 @@ Additionally, log-likelihood reflects differences in the training data versus al
1617

1718
The overall alignment log-likelihood represents the best path including all sections of silence. In general when we're thinking about how good an alignment is, we don't necessarily care how good of a match the silence intervals in a given utterance are to the trained silence model. So the speech log-likelihood measure takes out all log-likelihoods from silence intervals and is the average of per-phone log-likelihoods in the utterance.
1819

20+
(alignment_analysis_duration_deviation)=
1921
## Phone duration deviation
2022

21-
Stepping back from log-likelihoods generated by the model, we can take a look at statistics of the duration of phones in the aligned corpus. By calculating the mean and standard deviation of durations per phone, we can z-score the individual phone's duration to see how unexpected it is relative to the corpus overall. The phone duration deviation measure is an average of the absolute z-score of each phones duration.
23+
Stepping back from log-likelihoods generated by the model, we can take a look at statistics of the duration of phones in the aligned corpus. By calculating the mean and standard deviation of durations per phone, we can z-score the individual phone's duration to see how unexpected it is relative to the corpus overall. The phone duration deviation measure is the maximum of the absolute z-score of each phone's log-duration.
2224

23-
We use the absolute value of the z-score because often excessive durations due to misalignment will also result in excessively small durations on other phones. The average of raw z-scores in these cases will trend towards zero, when really we want these deviations to aggregate to utterances that clearly had something go wrong.
25+
We use the absolute value of the z-score because often excessive durations due to misalignment will also result in excessively small durations on other phones. The average of raw z-scores in these cases will trend towards zero, when really we want these deviations to aggregate to utterances that clearly had something go wrong. The log-duration is used to better model the distribution of durations, as they are bounded by 0 (i.e., always positive), and skewed heavily towards lower durations with a long tail of longer durations, so a log-normal distribution provides a distribution that matches the assumptions of z-scores.
2426

2527
It is important to note that there stylistic and speaker influences on duration, and statistics are gathered for the whole corpus, not normalized per speaker, so false positives are likely to pop up when sorting by this metric. Normalizing per-speaker, however, might minimize the magnitude of duration deviation if a given speaker's utterances are all poorly aligned. This would increase the likelihood of false negatives, and false positives are more acceptable than false negatives.
2628

29+
(alignment_max_running_short_intervals)=
30+
## Max running short intervals
31+
32+
This measure provides a sense of how many short intervals (10 ms or less) in a row are in the file. For long-running stretches of 10ms intervals in a row, this indicates that significant parts of the transcript were not correctly aligned or shoved together at the beginning/end of the file.
33+
34+
(alignment_analysis_intensity_deviation)=
35+
## Intensity deviation
36+
37+
Similar to {ref}`alignment_analysis_duration_deviation`, intensity deviation first calculates the mean and standard deviation of intensity over phones. The mean and standard deviation are then used to create z-scores of individual interval intensities to allow for querying and search of phones/utterances that unexpectedly high or low intensities for a given interval, which could indicate an issue in alignment, such as if all the speech intervals are aligned to stretches of silence.
38+
39+
However, there can be valid reasons for intensity to deviate related to speech style in particular, either if the speaker is excited or is whispering or is otherwise adopting an affect outside the rest of the speech.
40+
41+
(alignment_analysis_snr)=
42+
## Signal-to-Noise Ratio (SNR)
43+
44+
Signal-to-Noise Ratio (SNR) is calculated as the ratio of the mean intensity of speech phones to the mean intensity of the silence in an utterance. If there is no silence aligned, then the calculation will use the minimum intensity in the utterance, so it may not be entirely accurate.
45+
46+
SNR can be used in certain circumstances to help find alignment or transcript errors, such as when a word is missing from a transcript, and that section of speech is aligned as silence, resulting in a lower than expected SNR.
47+
48+
It is important to note that SNR can vary due to recording conditions and may not be indicative of alignment errors alone. Knowing the source data is particularly important for utilizing this metric to find errors, such as knowing that the data should be generally clean speech in quiet recording conditions vs uncontrolled or variable recording conditions.
2749

2850
## Ideas for the future that need a lot more thinking before I implement them
2951

0 commit comments

Comments
 (0)