长文本语音合成的四个坑:多音字、停顿、分句与音色一致性
接转写系列之后,这次记录语音反方向的工程实录:把长文本(产品文档、有声书章节、内部通报,万字级)稳定合成为语音。短句合成是玩具级问题,任何 TTS 都能出声;长文本合成是工程问题,坑全在「长」这个字上。按踩坑顺序记四个。
坑一:多音字是长文本的重灾区
短句里多音字可以靠上下文盲对,万字文本里多音字的期望出错数会累积到不可忽视。中文多音字两百多个,但工程上真正的高频肇事者就十来个:「行」(银行/一行)、「还」(还有/还钱)、「长」(长度/成长)、「重」(重复/重量)。
我们的解法是分层处理:第一层用词典加规则覆盖已知专有名词(产品名、人名、地名先标音);第二层对剩余文本跑一遍分词加词性判断,多音字按词选择读音;第三层兜底,对合成结果抽样人耳校验,错误回流词典。三层下来,万字文本的多音字错误从平均二十多处压到两三处。
选 TTS 服务时有一点值得先测:服务本身有没有内置多音字消歧。我们落地的算邻坊语音合成接口在这件事上表现不错,常见语境的多音字它自己能处理,词典只需要管业务专有名词——这一步的工程量差别很大,别默认所有服务都做了。
坑二:停顿不是标点符号的自动映射
直觉上「句号=长停、逗号=短停」,实际合成出来会发现:停顿的位置和时长是另一门学问。列表项之间需要等长停顿,转折词前需要微停,「例如」后面要给听者反应时间——这些标点表达不了。
工程解法是文本预处理时注入合成标记(SSML 或服务方的停顿标记):数字列表统一加停顿、小节标题前后加长停、括号内容整体降速。这一步做完,听感从「能听」到「想听下去」的差距比想象中大。万字文本的标记注入我们做成了自动化规则,人工只审标题层级。
坑三:分句与合成的边界
万字文本不能整段扔给合成接口——超出单次合成的长度限制,且失败重试的粒度太粗。按句切分是自然选择,但按句切会产生新问题:句与句之间的韵律断裂,听感上「一句一句蹦」。
实测的平衡点:按语义段分块(300~500 字一块,段内保持完整句子),块间合成、块内连贯。韵律断裂在段边界处被段落感天然掩盖。这个粒度还有一个好处:失败重试的单位是块,万字任务某块失败只重跑那一块。
坑四:音色一致性是隐性约束
长文本如果分块合成,最隐蔽的坑是音色漂移:不同块的合成参数有微小差异,累积起来听感上「换了个人」。测试方法很土:把首块和末块拼接连播,人耳对比。我们在算邻坊上跑万字任务没遇到这个问题(同一音色参数锁定后各块稳定),但历史上用过的某开源方案在第六块之后音调明显上扬,排查了一整天。
顺带把账算了:合成按字符计费,万字符两块钱,一份万字文档的完整语音化成本就是两块钱。对照人工录音(一分钟有效音频的录制加剪辑按半小时人力算),成本差三个数量级。语音合成的算力账简单透明:按量计费、不用不花钱、余额永不过期,对这种「一次文档、多次复用」的场景特别友好。
总结:长文本合成检查单
- 多音字:词典+分词两层兜底,错误回流
- 停顿:语义段规则注入标记,别指望标点
- 分块:300~500 字语义段,失败按块重试
- 一致性:首末块拼接人耳验收
四个坑过完,长文本合成从「能出声」到「能上线」的工程路径就通了。有声化这个需求在内部工具、无障碍、内容分发三个方向都在涨,值得把管线做扎实。
写文里这些合成场景,来自我日常在用的算邻坊(suanlinfang.cn?from=cnblogs-tts)——把闲置算力池化成按量 API 的平台:语音识别/语音合成/文字识别/智能决策/随心翻译,不用不花钱,余额永不过期,新用户送 ¥10 体验金。
浙公网安备 33010602011771号