TTS 前端文本处理:多音字、数字、英文缩写怎么读对

2026-08-24

合成出来的语音听着别扭,第一反应往往是”模型不行”。但相当一部分问题其实出在文本进模型之前的那一步——前端文本处理。

字读错了、数字读法不对、该停的地方没停,这些都不是声学模型或声码器的锅。它们拿到什么标注就发什么音,前端送进去的是错的,后面再好也救不回来。

前端在流水线的哪一段

TTS 通常分成三段:文本 → 前端 → 声学模型 → 声码器 → 波形。整条链路的分工见 TTS 的三段流水线

前端负责的是文本分析:文本规范化、分词、注音(中文这里就是多音字消歧)、韵律预测。它的输出不是音频,而是一串带发音与韵律标注的序列

这一段有个特点:它的错误是确定性的。同一句话送进去,每次都读错同一个字,不会时对时错。这反而是好消息——确定性的错误可以定位、可以修,而且往往一条注音就解决。

TN 与 ITN:一对方向相反的镜像

前端第一步叫 TN(Text Normalization,文本规范化),方向是书面 → 口语

  • 「2025 年」→「二零二五年」
  • 「3.14」→「三点一四」
  • 「30%」→「百分之三十」

语音识别的后处理里有个方向完全相反的兄弟叫 ITN,把「二零二五年」还原成「2025 年」,服务的是要读文字的人。详见 ITN 逆文本规范化

TNITN
用在哪TTS ASR
方向书面 → 口语口语 → 书面
服务谁要发音的声学模型要阅读的人和程序

**记法很简单:机器要念出来,就得先把字变成它会念的样子。**两者共享同一批歧义,只是从两侧各踩一次坑。

数字:同一串字符没有唯一读法

这是前端最典型的难点。同样是 2025

  • 年份读「二零二五」
  • 数量读「两千零二十五」
  • 编号(房间号、末位号)可能逐位读

三种读法都合法,选哪种完全取决于上下文。类似的还有一批:

写法可能读法 A可能读法 B
1-2一到二(区间)一杠二(编号分隔)
3/4四分之三三月四日 / 三比四
2:1二比一两点零一分
007零零七七(去掉前导零)

规则无法脱离上下文——这句话是最需要记住的一句。你可以写一条”四位数字优先按年份读”的规则,它立刻会在价格、编号上出错。前端能做的是覆盖高频模式,剩下的靠人工干预。

多音字:只能靠上下文消歧

中文多音字没有捷径,必须看词、看句:

  • :银行 / 行走
  • :重复 / 重量
  • :了解 / 算了
  • :长度 / 长大
  • :和平 / 和面

工业实现有两条路径:

词典 + 规则。查词表,词表里没有就按规则兜底。优点是可控——某个专名读错了,往词典里加一条就永久修好,不用重训任何东西。缺点是覆盖靠人力堆。

神经网络 G2P(字形到音素)。把注音当成序列标注任务来学,覆盖面广,见过的上下文变体多。代价是会出意外错误:它可能在一个从没出问题的常见词上突然读错,而且不好预判下次在哪犯病。

实际系统常是二者结合:模型兜底覆盖长尾,同时保留一个人工干预入口——词典优先级高于模型,让人能一票否决。这个入口是刚需,不是可选项。人名、地名、品牌名这类专名,是最典型的需要手工加词典的场景。

英文缩写与中英混排

英文缩写在中文里的读法没有通法

  • API 逐字母读(A-P-I)
  • NASA 当一个单词读
  • iOS 有约定俗成的固定读法

同样是三四个大写字母,读法完全不同,靠的只能是词典。没有词典的缩写,系统只能猜,猜错概率不低。

中英混排还有第二层问题:语言切换处的音色与韵律连贯。「用 Python 写个脚本」这句话里,中文和英文如果由不同的发音处理路径生成,切换点可能出现音色跳变、语速突变,听起来像是两个人在接力说话。

韵律:断句错了比读错字更伤

前端还要预测停顿位置、重音、语调。这部分决定的是”听不听得懂”,而不只是”读得对不对”。

经典例子是「下雨天留客天留我不留」。断句方式不同,意思完全相反。合成语音里也一样:每个字都读对了,但停顿位置不对,听者需要在脑子里重新断一遍句才能理解

停顿之外还有重音和语调。全句一个调子、没有重音起伏,就是常说的”机器味”的主要来源之一。这部分展开见 为什么合成音听起来像机器语速与停顿怎么调

排查表:读错了先看哪里

听到一句不对劲的合成音,按下表定位:

读错类型典型表现成因怎么修
多音字「银行」读成「银航」词典没覆盖,或 G2P 判错上下文给出注音标注强制指定读音;专名往词典里加条目
数字读法「2025 年」读成「两千零二十五年」TN 未识别出年份语境把数字直接写成中文(「二零二五年」),绕开 TN
数字边界「1-2 号」读成「一杠二号」连字符语义判错改写成「1 到 2 号」或直接写中文
英文缩写API 被当单词硬拼缩写不在词典里加词典;或在文本里写成「A P I」拉开间隔
专名人名、地名、品牌名读错未登录词,被切词切碎加入词典 + 注音;保持专名不被拆开
断句该停不停、不该停乱停韵律模型判错短语边界插入停顿标记;把长句拆成短句
中英切换切换处音色跳变混排处理不连贯减少混排;把能译的英文译成中文

一条经验:先判断错的是”内容”还是”形式”。字词全对、只有停顿和语调难听,那是韵律;某个字发音就是错的,那是注音。两者的修法完全不同,别混着试。

三个最实用的修法

一、注音标注。给出注音来强制指定读音,是修复读错最直接的手段。它不依赖模型改进,立刻生效,且只影响这一处。

**二、数字直接写成中文。**这是最实用的一招。与其调 TN 规则赌它判对,不如直接在文本里写「二零二五年」。你比系统更清楚这个数字该怎么读——把这个知识直接写进文本,比让系统去猜可靠得多。金额、编号、电话号码同理。

**三、插停顿标记。**很多系统支持 SSML 一类的标记语言来插入停顿、控制语速,但是否支持、支持到什么程度要看你用的具体实现,这个不能想当然,得查所用系统的文档。若不支持标记,退而求其次:把长句在该停的地方切成短句,也能起到类似效果。

这三招的共同点是把不确定性从系统手里拿回到自己手里。前端的很多问题本质是”系统不知道你想要什么”,直接告诉它就行。

常见问题

问:前端是不是可以省掉,让大模型式 TTS 直接吃原始文本?

有些做法确实弱化了显式前端。但只要输入里还有阿拉伯数字和英文缩写,“这串字符怎么读”的歧义就依然存在,只是从显式规则挪进了模型内部。挪进去的代价是不可控——读错了没有一条规则可以改。所以在需要确定性的场景(金额播报、编号确认),显式前端处理仍然有价值。

问:怎么判断问题出在前端还是声学模型?

看错误是否稳定复现。同一句话每次都读错同一个字,基本是前端;音质发闷、有金属味、忽好忽坏,更可能在后两段。另一个办法:把出错的词单独拿出来合成,如果单独合成是对的,那问题多半在分词或上下文判断。

问:多音字词典要维护到多大?

不追求大而全,追求盖住你的业务高频词。做法是收集实际会合成的文本,跑一遍,把读错的挑出来入库。业务文本的词汇分布通常很集中,几百条专名词典能解决绝大部分抱怨。

问:流式合成会不会影响前端的判断?

会。流式场景下前端可能拿不到完整句子就要开始处理,上下文变少,消歧难度上升。这也是首包延迟与质量之间的一处取舍,详见 流式 TTS 与首包延迟

相关阅读


本文讲的是语音合成前端处理的通用原理,不绑定某一个具体实现。 各家系统的文本规范化覆盖范围、注音标注语法、是否支持 SSML 差异很大,请以你所用系统的官方文档为准。 我们没有对文中提到的任何方案做过实测,因此不给准确率、速度一类的数字。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。