IndexTTS 2.5 发音控制 · T8star-Aix
Making IndexTTS 2.5 say 银行 like a human
- 发音标注文本
- 替换/校验报告
Polyphonic Chinese characters are the eternal TTS whack-a-mole. 行 is xíng when you walk and háng when you bank, and a text model guessing wrong mid-narration is exactly the kind of small failure that ruins an otherwise fine generation. This node is the fix: it turns a plain-text dictionary you write once into the official <文字|读音> annotations, so you never have to hand-annotate the same word twice.
How it works
You give it your text, a default language, and a dictionary - one rule per line in 文字|读音|语言 form, where the language column is optional (defaults to the node's language):
银行|YIN2 HANG2|ZH
行长|HANG2 ZHANG3|ZH
Bilibili|B IY1 . L IY1 . B IY1 . L IY1|EN
中文 needs one tone-marked pinyin per character (with spaces between syllables), English uses CMU phonemes, Japanese uses kana. The node rewrites your text into the official annotation format and outputs 发音标注文本, which you connect to Generate's text input. Long words match first, and anything you've already hand-annotated in the source text always wins - the dictionary won't stomp inside an existing <...|...> pair.
The second output, 替换/校验报告, is the part people skip and shouldn't: it lists every replacement made and flags warnings, like a single-character annotation embedded in a longer word (the README calls out official issue #792 - 小明<要|YAO4>求… can get overridden by context, so you must annotate the whole word: 小明<要求|YAO4 QIU2>…).
The strict toggle
Default on, and it's a feature, not a nuisance: invalid pinyin, bad CMU phonemes, broken kana, or a count mismatch between characters and syllables blocks the queue before inference starts. That's exactly when you want the error - queue-time, with a readable message, not mid-generation. Turn strict off and invalid entries pass through with the original text kept and the problem reported instead. The only real footgun is your dictionary entries themselves: one character per pinyin syllable, spaces between syllables, no sloppy shorthand.
Why it beats hand-annotating
The dictionary lives inside the workflow JSON, so it travels with the workflow when you share it - no external file to forget. And because it's rule-based (not a G2P model), there's no model download and it can't silently "improve" a name you deliberately wrote a specific way. For a handful of one-off words, honestly, just type <银行|YIN2 HANG2> in Generate's text field yourself. This node earns its place when you have a recurring cast of names, places, or jargon across many lines - that's when a dictionary you write once beats annotating each line by hand.
Setup
Ships in the pack, no extra dependencies, no model load - it's pure text processing. Install the pack via ComfyUI Manager (IndexTTS 2.5 · T8star-Aix) or clone the repo; nothing else needed. Output wires into Generate's text input in place of your raw text. If you later change your mind about a rule, edit the dictionary and re-run - the report output makes it obvious whether the replacement actually fired.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | 他在银行里工作,行长正在开会。 | — |
| language | COMBO | ZH | 每条词典记录也可在第三列单独指定 ZH、EN 或 JA。 |
| dictionary | STRING | 银行|YIN2 HANG2|ZH 行长|HANG2 ZHANG3|ZH | 按长词优先替换;词典内容保存在工作流中。也支持本项目导出的 YAML/JSON。 |
| strict | BOOLEAN | true | 无效拼音、CMU 音素、日语假名或损坏标注会阻止排队。 |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| 发音标注文本 | STRING | — |
| 替换/校验报告 | STRING | — |