Forced alignment with MFA: dictionary preparation, OOV words, and acceptance checks

Montreal Forced Aligner is only as good as the lexicon you feed it. How to prepare the dictionary, resolve out-of-vocabulary words, and check what came back.

Forced alignment maps a transcript onto audio at the word and phoneme level. Montreal Forced Aligner (MFA) does it with a pronunciation dictionary and an acoustic model, and the dictionary is the part you control. When an alignment comes back wrong, the cause is almost always a mismatch between your transcript and the lexicon, not a failure of the aligner.

It is also the part you can inspect before spending compute: coverage can be counted, gaps listed, and entries fixed.

Get the corpus layout right first

MFA expects one folder per speaker, with audio and transcript files sharing a stem and the text in a .lab file. The folder name becomes the speaker label, which the speaker-adapted acoustic models use, so a corpus that drops every file into one folder throws that information away.

Run mfa validate corpus/ dict.dict english_us_arpa before aligning. It reports malformed files, missing pairs, and the out-of-vocabulary rate without doing alignment work. The run itself is mfa align corpus/ dict.dict english_us_arpa out/ --output_format ctm --beam 100 --retry_beam 400. The two beam values are search widths, and raising retry_beam is the standard fix when a few files refuse to align while the rest are fine.

Out-of-vocabulary words, and why numbers cause most of them

MFA 2.x writes every word missing from the dictionary to oovs_found.txt in the output directory, with a per-speaker breakdown beside it. Read that file before you read the alignment.

In transcripts taken from real speech, most OOVs are numbers, abbreviations, and proper nouns. Numbers are the largest group and the cheapest to fix: expanding 23 to twenty three removes the OOV and makes the transcript match what was said, which matters later when the same text is used to score a recognizer.

For names, write the pronunciation by hand while the list is short. A dozen entries takes minutes and beats anything generated. For long lists, mfa g2p corpus/ dict.dict extended.dict produces pronunciations from a grapheme-to-phoneme model for you to merge and re-validate. Expand the transcript first: running G2P before that step generates entries for tokens that should not be in the transcript at all.

Two lexicon details that change the output

Matching is literal, so Hello against a lowercase dictionary is an OOV. Normalise case on both sides at once rather than patching OOVs one at a time.

Pronunciation variants help in moderation. Listing both pronunciations of either lets the aligner pick the path that fits the audio, which improves boundary placement. A wrong variant is worse than no variant, because the aligner will use it when it fits acoustically, and you get a boundary that is confidently misplaced.

Acceptance checks after the run

The output is a TextGrid per file with word and phone tiers. Three numbers decide whether to keep it: the share of words under 30 ms, the longest gap between consecutive words, and the median word duration. For English conversational speech the median usually lands between 200 and 400 ms. A median near 60 ms means the aligner squeezed the whole file.

With praatio those take a few lines: tg = textgrid.openTextgrid(path, includeBlankSpaces=True), then words = tg.tierDict["words"].entryList, and each entry carries start, end, and label. Compute the durations, take statistics.median, and count entries under 0.03 seconds.

The longest gap is the more serious signal. Twenty seconds between consecutive words in a file where nobody paused that long means a stretch of the transcript was never aligned, usually because it was dropped as OOV or because the audio and the text diverge there.

Where these checks stop working

They catch structural failures. They do not catch a uniformly shifted boundary set, which passes every check and is still wrong by 60 ms throughout. For that you need hand marks: twenty utterances with word onsets marked in a waveform editor, compared against the aligned onsets.

Under about 20 ms means the acoustic model matches your recording conditions. Between 40 and 80 ms usually means it does not, and the fix is a model trained on similar audio rather than more tuning. Beyond that, check the transcript before blaming the aligner.

Do not compare MFA boundaries against a neural aligner and treat the disagreement as error. Both are estimates, and on spontaneous speech the gap between two aligners is usually larger than either one's error against hand-marked boundaries.

More insights

Submit a sourcing request

Tell us the language, the hours, and what the data needs to look like. You will get a real number and a real timeline — not a range. If we cannot source it well, we will tell you that instead.

  • Pilot batch before the full run, so problems surface early.
  • Consent documentation delivered with the data.
  • No medical or clinical data. No recorded telephone calls.

We reply within two business days. Your details are used only to answer this request. See our privacy policy.

Contact

Talk to a human

Send a specification and we will come back with a real number and timeline.

Submit a sourcing request

Or email hello@linguacorpus.com