ComfyUI Extension: ComfyUI-MMS-Aligner

Authored by hnvcam

Created

Updated

0 stars

Run ComfyUI workflows without the setup

No installs, no CUDA version roulette, no GPU sitting idle on your bill. Bring a workflow and run it in the browser.

ComfyUI custom node that force-aligns audio with text into an SRT file using Meta's MMS models.

Looking for a different extension?

Custom Nodes (1)

README

ComfyUI-MMS-Aligner

A ComfyUI custom node that force-aligns an audio clip with its text transcript and writes a timestamped SRT subtitle file.

Uses Meta's facebook/mms-1b-fl102 model (102 languages, FLEURS-trained) via transformers + torchaudio.functional.forced_align. Pure Python — no C++ compilation, no MSVC, no extra build tools.

Why FL102?

facebook/mms-1b-fl102 is the only MMS model used by this node. It covers 102 languages, trained on the cleaner FLEURS dataset, with per-language adapters (each language uses its own native tokenizer — no romanization required for the common cases).

If your language isn't in FL102, this node won't work for you — but for the languages most people actually need (English, Vietnamese, Chinese Mandarin, Spanish, French, German, Japanese, Korean, Arabic, Hindi, Russian, etc.), it does.

Screenshots

MMS Aligner workflow — single-word Vietnamese alignment with Load Audio + Load Text File feeding the aligner, previewed as SRT

Features

  • One node: audio + text in → SRT out (string and/or file).
  • Single model, auto-downloaded to ComfyUI/models/mms/facebook__mms-1b-fl102/ on first use (~3.2 GB).
  • Pure-Python install: no compiler, no headaches on Windows.
  • Language: ~30 common languages in a dropdown, any ISO 639-3 code via custom, or auto-detect from the text.
  • Optional romanize fallback (uroman) for edge cases.
  • Six segmentation modes: single-word (karaoke-style), max chars, punctuation, newlines, or combinations.
  • Optional cue-gap bridging (gap_ms) to eliminate sub-300 ms flicker between consecutive cues.
  • Optional output splitting (split_count, up to 5) to emit name_1.srt, name_2.srt, … for chunked workflows.
  • Tooltips on every input.
  • All processing in-memory — no temp WAV files written.

Installation

Manual

cd ComfyUI/custom_nodes
git clone https://github.com/idealweek/ComfyUI-MMS-Aligner
cd ComfyUI-MMS-Aligner
pip install -r requirements.txt

Restart ComfyUI. The node appears under audio/alignment as "MMS Audio-Text Aligner (SRT)".

Requirements: torch and torchaudio are already provided by ComfyUI. The extras (transformers, huggingface_hub, uroman, lingua-language-detector) are pure Python.

Usage

  1. Add a LoadAudio node and connect its output to the aligner's audio input.
  2. Type or wire the transcript into the text input.
  3. Pick language and segmentation_mode (use single_word for karaoke-style one-word-per-cue output).
  4. Set output_name (no extension — .srt is added automatically). Files are written into ComfyUI's output directory. The srt string output is always populated.
  5. (Optional) raise split_count (max 5) to split the result into output_name_1.srt, output_name_2.srt, …
  6. (Optional) tune gap_ms to bridge tiny silences between consecutive cues — handy for single_word mode to prevent flicker.

Example — Vietnamese

| Input | Value | |---|---| | audio | (from LoadAudio) | | text | Xin chào, đây là một ví dụ.\nMột dòng nữa. | | language | Vietnamese | | romanize | False | | segmentation_mode | max_chars+punctuation+newlines | | max_chars_per_line | 42 | | gap_ms | 300 | | output_name | subs | | split_count | 1 |

Output (srt):

1
00:00:00,120 --> 00:00:02,340
Xin chào, đây là một ví dụ.

2
00:00:02,500 --> 00:00:03,820
Một dòng nữa.

Inputs

| Field | Type | Default | Description | |---|---|---|---| | audio | AUDIO | — | ComfyUI audio. Resampled to 16 kHz mono internally. | | text | STRING (multiline) | "" | Transcript. | | language | enum | auto | auto, ~30 common languages, or custom. | | custom_language_code | STRING | "" | ISO 639-3 (used only when language=custom). | | romanize | BOOL | False | Optional fallback. Usually leave off — the per-language tokenizer handles native scripts. | | segmentation_mode | enum | max_chars+punctuation+newlines | See below. | | max_chars_per_line | INT | 42 | 0 disables the cap. | | remove_punctuation | BOOL | False | Strip .,!?;:"()[]{}—–…«»“”‘’ from SRT lines (keeps apostrophes/hyphens). Doesn't affect segmentation. | | gap_ms | INT | 300 | Bridge consecutive cues whose gap is under this many ms by snapping prev.end to next.start. Real pauses (≥ gap_ms) are preserved. 0 disables. | | output_name | STRING | "subtitles" | Base file name (no extension) written to ComfyUI's output dir. .srt is appended automatically; path separators are stripped. | | split_count | INT | 1 | 1 = single file. 25 splits cues into near-equal chunks named <output_name>_1.srt, <output_name>_2.srt, … |

Segmentation modes

  • single_word — one word per cue (karaoke-style). Pair with gap_ms to avoid flicker.
  • max_chars — pack words greedily up to max_chars_per_line.
  • punctuation — break at . ! ? , ; :.
  • newlines — break wherever the input text has a line break.
  • max_chars+punctuation — both.
  • max_chars+punctuation+newlines — all three.

Outputs

  • srt (STRING) — full SRT content (un-split, even when split_count > 1).
  • output_path (STRING) — newline-separated list of paths written to disk (one entry when split_count=1, N entries otherwise).

How it works

  1. Resample the input audio to 16 kHz mono in memory.
  2. Detect the language from the transcript (lingua) when language=auto.
  3. Download facebook/mms-1b-fl102 to ComfyUI/models/mms/ on first run (cached after).
  4. Load the model with the per-language adapter (model.load_adapter(lang) and processor.tokenizer.set_target_lang(lang)).
  5. Tokenize each transcript word with the language's native tokenizer (optionally romanize first).
  6. Get emissions via a single forward pass; convert to log-probs.
  7. Force-align with torchaudio.functional.forced_align; merge token spans into word boundaries.
  8. Segment word timings into SRT cues per the chosen mode.
  9. Emit the SRT as a string and (optionally) write to disk.

Troubleshooting

  • "Could not auto-detect language" — text too short or mixed; set language explicitly.
  • "Transcript produced no alignable tokens" — text contains characters not in the language's tokenizer vocab. Try romanize=True, or check the language code.
  • Slow first run — model is downloading (~3.2 GB); subsequent runs use the cache.
  • Wrong language adapter — make sure the ISO 639-3 code matches one of the FL102 languages.

License

MIT

Credits

Run ComfyUI workflows without the setup

No installs, no CUDA version roulette, no GPU sitting idle on your bill. Bring a workflow and run it in the browser.

Learn more