深夜十一点的电台直播间,主持人阿声接过主编递来的新闻稿,只看了一眼就倒吸一口凉气:“PM2.5浓度达285,GDP增速3.2%(2024年全国数据),今晚3.15特别节目见。”——这要是照着念,“GDP“会被念成”鸡迪屁”,“3.15“会让听众以为他在报小数。好在电台有位从不露面的”备稿编辑“小李,总能在开播前把这些”阅读版“的天书改写成字正腔圆的”朗读版“。小李的岗位,在语音合成(TTS)系统里有一个正式的名字:文本正则化(Text Normalization,TN)。它把数字、日期、缩写、符号这些”非标准词“翻译成人们口语里会说的形式,是 TTS 声学前端中最先发力、也最容易翻车的一环。规则词典负责确定性的”送分题“,序列到序列模型负责泛化的”开放题”,两者按置信度分工协作,再经过可懂度与自然度的层层质检,最终才能让合成的语音像真人主播一样自然流畅。

岗位关联

掌握文本正则化,你就拿到了 TTS 前端的“质量控制钥匙”——无论做语音助手还是有声书,合成语音“读得对不对、像不像人话”,都从这位“备稿编辑”开始。

目录
  1. 可视化演示
  2. 文本正则化概念
  3. 非标准词类型
  4. 规则驱动方法
  5. 序列到序列模型
  6. 混合方案架构
  7. 质量评估方法
  8. 前端完整流程
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示语音合成前端文本正则化流水线,将数字/日期/缩写/符号转为可发音口语形式,对比规则方法与序列模型方案的转换效果。

本节配有交互动效(进入视口后自动加载,约 3KB)。

文本正则化流水线 输入分析:识别数字/日期/缩写/符号等非标准词 规则转换:正则匹配+上下文消歧生成口语形式 Raw Text → Tokenize → Classify → Normalize → Phonetic Output 文本正则化是TTS前端核心步骤,直接影响合成语音的可懂度与自然度

文本正则化概念

深夜十一点,城市电台“悦听FM”的直播间里,主持人阿声接过主编递来的新闻稿,只看了一眼就倒吸一口凉气:稿子上赫然写着“PM2.5浓度达285,GDP增速3.2%,2024年全国数据”。要是照着念,“GDP“会被念成”鸡迪屁”,“3.2%“会变成”三点二百分号“,听众非笑掉大牙不可。好在电台有位从不露面的”备稿编辑“小李,总能在开播前把这些”阅读版“稿子改写成字正腔圆的”朗读版”。在语音合成系统里,这位小李的正式职位就叫文本正则化(Text Normalization,TN)。

文本正则化位于 TTS 声学前端的最前列,负责把原始文本中无法直接按字面发音的内容——专业术语叫非标准词(Non-Standard Word,NSW)——转换成自然的口语表达。所谓“非标准词”,就是“不能按普通发音规则念出来”的词:数字“285“、日期”2024年“、缩写”GDP“、符号”@“,统统归它管。一个完整的文本前端通常由分词、词性标注、文本规整、韵律预测等模块组成,而文本正则化就是其中专门处理非标准词的”翻译枢纽“——上游输入五花八门的原始文本,下游声学模型只认字正腔圆的口语形式。这里一旦出错,合成语音要么”读错“,要么”读死”,轻则拗口,重则让用户理解错误。因此,正则化质量直接影响合成语音的可懂度与自然度。

稿子里到底有多少“暗号”需要翻译?我们可以用一个简单的占比来感受:

小李的工位上贴着一张统计表:一档新闻稿里,非标准词占比能达到一成甚至更高。他常开玩笑说:“稿子里的暗号比主持人的口误还多。”这个占比,就是一个 TTS 系统需要投入多少精力“备稿”的风向标——占比越高,文本正则化模块就越是整个系统的命门。

pNSW=NNSWNtotal\displaystyle p_{\text{NSW}}=\frac{N_{\text{NSW}}}{N_{\text{total}}}
非标准词占比 = 需要翻译的暗号数 ÷ 稿子总词数。新闻、金融类文本里这个比例往往高达 10% 以上,可见备稿任务并不轻松。
  1. 分子 N_NSW稿子中需要改写的非标准词个数,比如"285"、"GDP"各算一个暗号。
    NNSW=数字+缩写+日期+…N_{\text{NSW}}=\text{数字}+\text{缩写}+\text{日期}+\dots
  2. 分母 N_total稿子的总词数,包含普通词和非标准词。
    Ntotal=所有被切分出来的词块数量N_{\text{total}}=\text{所有被切分出来的词块数量}
  3. 占比 p_NSW两者相除,得到“暗号密度”,用来决定需要投入多少备稿资源。
    pNSW=NNSWNtotalp_{\text{NSW}}=\frac{N_{\text{NSW}}}{N_{\text{total}}}

非标准词类型

小李的桌上整整齐齐摆着三大本“暗号手册”,分别记录数字暗号、日期暗号和缩写符号暗号。每次拿到新稿,他先快速扫一遍,拿红笔把所有需要改写的暗号圈出来。圈暗号看似简单,实则暗藏玄机——同一种符号,在不同的句子里可能完全是两种念法。

非标准词大致可以分成几大类。第一类是数字类,这是最常见的暗号:基数词“285“读”二百八十五“;编号类”2857309“读”二八五七三零九“(一位一位念);年份”2024年“按位读”二零二四年“;小数”3.2“读”三点二“。第二类是日期时间:”3.15“若是消费者权益日就念”三一五“,若是距离”3.15米“就念”三点一五米“——同一个符号,语境不同,天壤之别。第三类是缩写符号:”GDP“要念”国内生产总值”,“@“念”艾特“。第四类是特殊格式:网址、邮箱、混合字母数字串,各有各的约定俗成。之所以有这么多讲究,是因为中文口语对”读法”极度敏感:同一串数字,可能是数量、编号、年份、日期、电话,读法完全不同。

一个典型的日期转换可以写成下面的样子:

小李圈暗号时从不靠猜,每种暗号背后都跟着好几种“候选读法”,具体选哪种,要看上下文——这是暗号手册里最厚重的一章,也是最考验“备稿编辑”功力的一环。

"2024年3月15日"⟹"二零二四年三月十五日"\displaystyle \text{"2024年3月15日"} \Longrightarrow \text{"二零二四年三月十五日"}
左是阅读版,右是朗读版:年份按位读,月日用序数读,组装起来就是主持人口中的自然表达。
  1. 年份拆位读把“2024“拆成 2、0、2、4 四个数位,再逐位映射到”零一二三四五六七八九”。
    2024→2,0,2,4→二零二四\text{2024} \rightarrow 2,0,2,4 \rightarrow \text{二零二四}
  2. 月日序数读“3“和”15“不按位数拆,而是当成”第3月、第15日”的序数含义来读。
    3→三,15→十五3 \rightarrow \text{三},\quad 15 \rightarrow \text{十五}
  3. 组装完整串把年份、月份、日期拼接,得到最终朗读稿。
    二零二四+年+三月+十五日=二零二四年三月十五日\text{二零二四} + \text{年} + \text{三月} + \text{十五日} = \text{二零二四年三月十五日}

规则驱动方法

小李刚入行时,师傅递给他一本泛黄的“老编辑字典”,扉页上写着:“凡暗号,必有定法。”字典里的每一条,都是一个确定性的规则:看到四连数字加“年”字,就按位读;看到数字加点数字,就读“几点几”。这套做法,在技术上就叫规则驱动方法。

规则驱动的实现思路很直白:用正则表达式描述暗号的形状(比如 ^\d{4}年$ 匹配“2024年”),用规则表和决策树组织“形状 → 读法”的映射,再配上上下文条件约束(是年份还是数量?是日期还是小数?)。它的优点非常突出:确定性——同样输入永远得到同样输出;可解释——出错了能一步步回溯是哪条规则的责任;零成本——不需要大量训练语料,维护者看得懂、改得动。早期工业级 TTS 系统几乎全靠这套“老编辑字典”撑场面。

但字典再厚,也有漏网之鱼。规则方法的核心短板是覆盖不足:网络新词、"EMO"、"AIGC"这类缩写层出不穷,日期格式千奇百怪,长尾情况永远写不完。我们用一个指标来衡量规则库的完成度:

小李心里清楚,字典再厚,也总有“漏网之鱼”。他每天都能在听众热线里听到新造的缩写和网络新词,靠这本老字典硬撑,迟早要翻车——是时候请一位“新编辑”来帮忙了。

Coverage=NhitNNSW\displaystyle \text{Coverage}=\frac{N_{\text{hit}}}{N_{\text{NSW}}}
覆盖率 = 规则能正确翻译的暗号数 ÷ 暗号总数。覆盖率不到 100%,就意味着总有些稿子会“翻车”。
  1. 分子 N_hit规则库中命中并正确翻译的非标准词数量。
    Nhit=∑规则 r被 r 正确处理的数量N_{\text{hit}}=\sum_{\text{规则 } r} \text{被 } r \text{ 正确处理的数量}
  2. 分母 N_NSW测试稿里全部需要翻译的非标准词总数。
    NNSW=N数字+N日期+N缩写+…N_{\text{NSW}}=N_{\text{数字}}+N_{\text{日期}}+N_{\text{缩写}}+\dots
  3. 覆盖率 Coverage两者相除,值越接近 1,说明字典越接近“全知”。
    Coverage=NhitNNSW\text{Coverage}=\frac{N_{\text{hit}}}{N_{\text{NSW}}}

序列到序列模型

编辑部新来了个年轻编辑小陈。他不翻字典,也不背规则,靠的是“读过的十万篇稿子”练出来的语感:看到上下文,下意识就知道某串暗号该念什么。他的绝活,对应到技术上就是序列到序列(Sequence-to-Sequence,Seq2Seq)模型。

序列到序列模型把文本正则化看成一次“翻译”:输入是原始文本序列,输出是口语形式序列。它用编码器(Encoder)把整句话读进去、编码成语义向量,再用解码器(Decoder)逐词生成口语输出。因为模型见过海量的“原文—口语”对照语料,它天然学会了看上下文——“3.15“后面跟着”消费者权益日“就念”三一五“,后面跟着”米“就念”三点一五“。这种强泛化能力是规则方法不具备的:遇到从未见过的缩写,它能根据语境猜个八九不离十。代价是,训练需要大规模平行语料,也就是”原文 + 对应的标准口语”配对数据,标注成本不菲。

序列到序列模型生成口语词的数学本质,是一个逐步的条件概率计算:

小陈的语感让小李佩服得五体投地,但他也有毛病:太自信。遇到“2024年”这种明明有固定读法的送分题,他偶尔会一本正经地拟出“二千零二十四年”的怪腔调。看来,光有语感还不够——编辑部需要一套能“管住”两个人的规矩。

P(y ∣ x)=∏t=1Tp(yt ∣ y1,y2,…,yt−1,x)\displaystyle P(\mathbf{y}\,|\,\mathbf{x})=\prod_{t=1}^{T} p(y_t\,|\,y_1,y_2,\dots,y_{t-1},\mathbf{x})
整句话念对的概率,等于逐词念对的概率连乘。模型每生成一个口语词,都要参考已经生成的前文和原始句子。
  1. 条件输入 x原始文本序列,也就是“阅读版”的稿子。
    x=(x1,x2,…,xm)\mathbf{x}=(x_1,x_2,\dots,x_m)
  2. 输出词 y_t第 t 步生成的口语词,比如“二百八十五”里的“二百”。
    yt∈{候选口语词}y_t \in \{\text{候选口语词}\}
  3. 条件概率连乘每个词的概率都依赖前文已生成词和原句,全部相乘才是整句的正确概率。
    P(y ∣ x)=∏t=1Tp(yt ∣ y<t,x)P(\mathbf{y}\,|\,\mathbf{x})=\prod_{t=1}^{T} p(y_t\,|\,y_{<t},\mathbf{x})

混合方案架构

编辑部主任最后拍板:小李和小陈搭档干活。规矩很简单——拿到一个暗号,两人各自“阅卷”,报出把握程度;把握高的人说了算,把握低的人别抢话。这套“谁有把握谁上”的办法,在技术上就是混合方案架构。

混合方案的核心思想是“让合适的工具干合适的活”。规则模块负责封闭集:年份、日期、百分比这类确定性强、读法固定的暗号,交给老编辑字典,稳定、可解释、不会抽风;序列到序列模型负责开放集:新词、长尾、上下文相关歧义,交给语感型编辑,靠泛化能力兜住规则覆盖不到的地方。两者之间用一个置信度路由(Confidence Routing)机制衔接:规则给出一个置信度分数,模型也给出一个置信度分数,分数高者获得翻译权。更保险的做法,还会在模型输出后加一道规则校验——模型再怎么天马行空,也翻不出规则库的手掌心。

路由决策可以写成一条简洁的规则:

从此,“2024年”这种送分题归小李,“GDP“这种新词归小陈,连”PM2.5”这种混合体也能被拆开各管一段。两人配合默契,暗号处理得又快又稳——这就是当前工业级 TTS 系统最主流的设计思路。

Route(x)={Rule,crule(x)≥cmodel(x)Seq2Seq,otherwise\displaystyle \text{Route}(x)=\begin{cases}\text{Rule}, & c_{\text{rule}}(x)\ge c_{\text{model}}(x) \\\text{Seq2Seq}, & \text{otherwise}\end{cases}
两者都打分:规则分高走规则,模型分高走模型。等于给字典编辑和语感编辑各配了一把“话语权秤”。
  1. 规则置信度 c_rule规则模块对“我这次翻译对不对”的把握程度,比如年份规则给 0.98。
    crule(x)∈[0,1]c_{\text{rule}}(x)\in[0,1]
  2. 模型置信度 c_model序列到序列模型对输出结果的概率估计,通常取解码概率。
    cmodel(x)=max⁡yP(y ∣ x)c_{\text{model}}(x)=\max_{\mathbf{y}}P(\mathbf{y}\,|\,x)
  3. 比较与路由两者比大小,大者获得处理权,输出最终口语文本。
    Route(x)=max⁡{crule(x), cmodel(x)}\text{Route}(x)=\max\{c_{\text{rule}}(x),\,c_{\text{model}}(x)\}

质量评估方法

节目播出后,听众热线就成了“质检部”。有人打电话说:“阿声今天把'三月十五'念得贼顺!”也有人吐槽:“那个'PM二点五',听得我以为是外语。”小李每天最怕的就是翻热线记录,但正是这些反馈,逼着编辑部把暗号手册越修越准。在 TTS 工程里,这套“热线评价”就是质量评估方法。

文本正则化的质量评估要从两个维度看。第一是可懂度,回答“读得对不对”:规整结果与标准口语是否一致,通常用词错误率(Word Error Rate,WER)或标签准确率来量化。第二是自然度,回答“读得像不像人话”:即使每个词都对,断句、重音、节奏不对,听起来依然别扭,这要靠MOS(平均意见分)这类人工主观评分。工程上还会做错误类型分析:把错误分成“读错(替换)”“漏读(删除)”“多读(插入)”“停顿不当”几类,逐个定位是规则库的锅还是模型的锅。

词错误率的计算公式是:

小李每月最怕“质检复盘会”,但正是一通通热线电话和一条条 WER 数据,让编辑部看清了暗号手册的薄弱章节:哪类暗号总读错、哪个模型在哪个语境不自信,全都一目了然。

WER=S+D+IN\displaystyle \text{WER}=\frac{S+D+I}{N}
分子是三类错误的叠加,分母是参考话术的总词数。WER 越低,说明“读得越对”,可懂度越高。
  1. S 替换数该读“二百八十五”却读成“二百八十六”,就算一次替换错误。
    S=#{被读错的词}S=\#\{\text{被读错的词}\}
  2. D 删除数该读出来的“年”字整段吞掉了,就算一次删除错误。
    D=#{该读而未读的词}D=\#\{\text{该读而未读的词}\}
  3. I 插入数不该读的词凭空多出来,比如多念了一个“零”。
    I=#{多读的词}I=\#\{\text{多读的词}\}
  4. N 参考总词数标准口语稿的总词数,作为归一化的分母。
    WER=S+D+IN\text{WER}=\frac{S+D+I}{N}

前端完整流程

如果把电台开播前的准备比作一条流水线,那么各环节环环相扣:初审编辑负责分词(把稿子切成一块块词),批注员负责词性标注(给每个词贴上“名词”“动词”的标签),紧接着才是小李的备稿(文本规整),再往后是标韵律记号的人(韵律预测),最后稿子才交到阿声手上。任何一个环节掉链子,阿声都得在直播里吃螺丝。

TTS 声学前端的完整链路正是如此:原始文本进入系统后,先经过分词切出词边界,再做词性标注为后续规则提供上下文线索,然后轮到文本规整——也就是本文的主角文本正则化——把非标准词全部译成口语形式,接着是韵律预测标出停顿、重音和语调,最终生成音素序列交给后端声学模型和声码器合成波形。文本规整之所以关键,是因为它处在“承上启下”的枢纽位置:分词的边界影响它能否正确切出暗号,词性标注为它提供读法选择的依据,而它输出的口语文本又直接决定韵律预测有没有“念对的东西”可以标节奏。

整条流水线可以用一个箭头链表示:

小李的工位前传后递,是流水线上最不起眼、却最不能出错的一环。正如他的口头禅:“稿子备不好,阿声开不了嗓。”理解了这条流水线,你就理解了文本正则化在 TTS 系统里沉甸甸的分量。

原始文本→分词词序列→词性标注标注序列→文本规整口语文本→韵律预测韵律标记序列\displaystyle \text{原始文本}\xrightarrow{\text{分词}}\text{词序列}\xrightarrow{\text{词性标注}}\text{标注序列}\xrightarrow{\text{文本规整}}\text{口语文本}\xrightarrow{\text{韵律预测}}\text{韵律标记序列}
每一个箭头都是一道工序,文本规整是其中唯一的“翻译官”:前后环节都在处理形式,只有它在处理含义。
  1. 分词箭头把连续的原始文本切成有意义的词块,暗号才有机会被识别。
    原始文本→切分{w1,w2,…,wk}\text{原始文本}\xrightarrow{\text{切分}}\{w_1,w_2,\dots,w_k\}
  2. 词性标注箭头给每个词块贴上词性标签,为文本规整提供上下文。
    {wi}→标注{(wi,ti)}\{w_i\}\xrightarrow{\text{标注}}\{(w_i,t_i)\}
  3. 文本规整箭头把非标准词替换成口语形式,输出可供朗读的文本。
    标注序列→NSW 翻译口语文本\text{标注序列}\xrightarrow{\text{NSW 翻译}}\text{口语文本}
  4. 韵律预测箭头在口语文本上标注停顿、重音与语调,交给后端合成。
    口语文本→韵律标记可直接开嗓的稿子\text{口语文本}\xrightarrow{\text{韵律标记}}\text{可直接开嗓的稿子}

AI 应用场景

智能语音客服的余额播报

阶段:声学前端文本规整

解决的问题:银行客服要播报“您尾号2857的账户,余额12345.67元,今日消费3.2元”。传统做法用简单数字替换,结果把“2857“读成”二千八百五十七“(正确应为”二八五七“按位读),把”12345.67“读得拖泥带水。AI 文本正则化基于规则+模型混合方案,能识别”尾号“后的编号语境、”余额”后的金额语境,自动选择最自然的读法。

具体案例:某银行智能客服上线混合式文本正则化后,余额播报的 WER 从 8.3% 降到 1.1%,用户“听不清金额”的投诉量下降 72%。数字类暗号的按位读、金额类暗号的“元角分”读法,全部由规则库兜底,模型负责处理“总资产”这类长尾表达。

新闻与有声书的自动备稿

阶段:TTS 前端全流程流水线

解决的问题:新闻稿动辄出现“2024年3月15日”、“GDP达285万亿元”、“增幅3.2%”等密集非标准词,人工预审成本极高。传统正则表达式写不全面的长尾表达经常“裸奔”到合成阶段。混合方案让规则处理确定封闭集、序列到序列模型处理开放集,自动把整篇新闻“备稿”成朗读版。

具体案例:某有声书平台每天处理 2 万篇资讯稿,接入“规则+Seq2Seq+置信度路由”后,前端文本规整的自动化率从 78% 提升到 99.2%,编辑只需抽查置信度偏低的长尾句子。合成新闻的可懂度评分提升了 15%,用户完播率也随之上升。

地图导航的混合读法

阶段:上下文相关的文本正则化

解决的问题:导航播报“前方300米右转,进入G45高速,限速120公里/小时”——“300“是数量,读”三百”;“G45“是道路编号,读”G 四五”;“120“是限速值,读”一百二“。同一个数字,三种语境三种读法。纯规则难以覆盖,纯模型又可能在”2024”年份上翻车。

具体案例:某头部地图 App 在导航语音中启用上下文感知的正则化路由:规则模块给出编号、数量的高置信读法,模型模块负责识别“前方X米”“限速X”等句式。切换后,关键路况数字的播报正确率从 94% 提升到 99.8%,司机因听错距离而走错路的事故类投诉显著下降。

Python 演示

python91 行
# -*- coding: utf-8 -*-"""文本正则化混合方案演示:规则优先 + 置信度路由""" import re DIGITS = "零一二三四五六七八九"UNITS = ["", "十", "百", "千"]ABBR = {"GDP": "国内生产总值", "AI": "人工智能", "TTS": "语音合成"}  def int_to_cn(n: int) -> str:    """把 0-9999 的整数转成中文读法"""    if n == 0:        return "零"    if n < 10:        return DIGITS[n]    if n < 20:        return "十" + (DIGITS[n % 10] if n % 10 else "")    res = ""    zero = False    for i in (3, 2, 1):        d = (n // 10 ** i) % 10        if d:            if zero:                res += "零"                zero = False            res += DIGITS[d] + UNITS[i]        elif res:            zero = True    if n % 10:        if zero or not res:            res += "零"        res += DIGITS[n % 10]    return res  def rule_convert(token: str):    """规则引擎: 命中则返回 (口语形式, 置信度), 否则返回 None"""    if token.isdigit():        return int_to_cn(int(token)), 0.95    m = re.fullmatch(r"(\d{4})年", token)    if m:        return "".join(DIGITS[int(c)] for c in m.group(1)) + "年", 0.98    m = re.fullmatch(r"(\d{1,2})月(\d{1,2})日", token)    if m:        return int_to_cn(int(m.group(1))) + "月" + int_to_cn(int(m.group(2))) + "日", 0.99    m = re.fullmatch(r"(\d+)\.(\d+)", token)    if m:        return int_to_cn(int(m.group(1))) + "点" + "".join(DIGITS[int(c)] for c in m.group(2)), 0.97    return None  def model_guess(token: str):    """模拟序列到序列模型: 词典 + 简单泛化"""    if token in ABBR:        return ABBR[token], 0.80    return token, 0.30  def normalize(sentence: str):    """混合路由: 规则置信度不低于模型时走规则, 否则走模型"""    out_parts = []    detail_lines = []    pattern = r"\d{4}年|\d{1,2}月\d{1,2}日|\d+\.\d+|\d+|\w+"    for token in re.findall(pattern, sentence):        rule_hit = rule_convert(token)        if rule_hit:            spoken, conf_rule = rule_hit            _, conf_model = model_guess(token)            if conf_rule >= conf_model:                out_parts.append(spoken)                detail_lines.append("[规则] " + token + " -> " + spoken)                continue        spoken, conf = model_guess(token)        out_parts.append(spoken)        detail_lines.append("[模型] " + token + " -> " + spoken)    return "".join(out_parts), detail_lines  def main():    sentence = "2024年3月15日GDP达285,创今年新高。"    spoken, details = normalize(sentence)    print("原始文本:", sentence)    print("规整后:", spoken)    print("---- 决策明细 ----")    for line in details:        print(line)  if __name__ == "__main__":    main()
目的:用 60 行代码模拟“规则+模型”混合文本正则化——规则负责年份、日期、小数、整数等确定性暗号,模型兜底处理缩写等开放词,两者按置信度路由,直观展示混合方案的工作过程。
  1. pattern = r"\d{4}年|\d{1,2}月\d{1,2}日|\d+\.\d+|\d+|\w+"正则分词,把稿子切成“暗号块”和普通词块
  2. if token.isdigit(): return int_to_cn(int(token)), 0.95纯数字是送分题,规则直接出手并给出高置信度
  3. return "".join(DIGITS[int(c)] for c in m.group(1)) + "年", 0.98年份“2024年”逐位映射,置信度高达 0.98
  4. if conf_rule >= conf_model:置信度路由,规则把握更大就听规则的
  5. spoken, conf = model_guess(token)规则识别不了时交给“语感型”模型兜底
  6. if __name__ == "__main__": main()可执行入口,直接运行即可看到规整结果和决策明细

常见误区

误区我以为文本正则化就是查表,看到“285“就换成”二百八十五“,看到”2024“就换成”二千零二十四”,别的统统不用管。

正解数字在不同语境下读法差异巨大:“2857309“作为电话号码要按位读”二八五七三零九”,“2024年”作为年份读“二零二四年”,“3.15“作为日期读”三月十五“、作为小数读”三点一五“。此外还有缩写、单位、符号、特殊格式几十类非标准词要处理,远不止”数字变大写”这么简单。

为何常见:因为最直观的例子恰恰是“基数词→中文数字”,初学者容易把局部样例当成全部规则,忽略了语境的威力。

误区我觉得老编辑字典已经覆盖了 90% 的情况,再买点正则表达式补齐长尾就完美了,没必要上序列到序列模型。

正解规则库的覆盖率永远追不上语言演化:新缩写、新格式、新句法层出不穷,纯规则方案会出现“字典没写就翻车”的硬伤;而纯模型又会在“2024年”这类确定性暗号上发挥不稳定。工业界主流是混合方案——规则保确定、模型保泛化、置信度做裁判,两者缺一不可。

为何常见:规则方法可解释、见效快,让人产生“控制感”,容易低估开放集问题的长期维护成本。

误区我以为文本前端最重要的就是分词和韵律,文本规整差不多就行,反正就是改几个数字。

正解文本正则化直接影响合成语音的可懂度与自然度:“PM2.5“读成”PM 二点五“还算可忍,把”GDP“念成”G D P”就很生硬,把日期读错直接闹笑话。它是承接分词、服务韵律的枢纽环节——分词错了它跟着错,它错了韵律预测全白做。

为何常见:文本规整的输出是“文本到文本”,不像语音信号那样直观可见,容易被低估其对最终听感的关键作用。

误区我看到评测报告里 WER 从 5% 降到了 1%,就以为合成语音已经无可挑剔了。

正解WER 衡量的是“读得对不对”(可懂度),只覆盖文本规整的正确性;而“读得好不好听”(自然度)还要看停顿、重音、语调,需要 MOS 这类人工主观评分。一个 WER 为零的系统,依然可能把句子念得毫无感情、断句混乱。

为何常见:WER 是自动化指标,看起来客观又省事,人们容易拿单一数字代替对“可懂度+自然度”双重维度的完整评估。

面试题

Q1. 文本正则化的核心任务是什么?

单选题 · easy

  • A.把非标准词转为口语← 正确答案
  • B.对文本做压缩归档
  • C.对音频信号做去噪
  • D.把语音直接转为文本

答案:A。文本正则化是 TTS 声学前端的第一步,负责把数字、日期、缩写等非标准词(NSW)翻译成可以自然朗读的口语形式。B 是文本压缩、C 是音频降噪、D 是语音识别(ASR),都与“阅读稿→朗读稿”的备稿工作无关。

Q2. 下列哪一项属于典型的非标准词?

单选题 · easy

  • A.你好世界
  • B.三月十五日
  • C.2024年← 正确答案
  • D.语音合成

答案:C。“2024年”不能按字面直接读,必须转换为“二零二四年”,属于最典型的年份类非标准词。“你好世界”“语音合成”是普通词,可直接发音;“三月十五日”本身已经是口语化的朗读稿,是被转换的结果而不是需要转换的暗号。

Q3. 规则驱动方法的主要局限包括哪些?

多选题 · easy

  • A.对新增词汇覆盖不足← 正确答案
  • B.上下文语义理解有限← 正确答案
  • C.运行时完全无需维护
  • D.人工规则维护成本高← 正确答案

答案:ABD。规则方法靠人工写正则和规则表,新缩写、新格式总在涌现,覆盖永远有缺口;它也只能按固定条件匹配,难以理解"3.15"这类依赖语境的歧义;规则库需要持续人工维护,成本很高。C 恰恰说反了——规则库恰恰需要大量维护。

Q4. 序列到序列模型做文本正则化的核心优势是什么?

单选题 · mid

  • A.不需要任何训练语料
  • B.具备更强的上下文泛化能力← 正确答案
  • C.推理过程完全不会出错
  • D.不需要音频前端支持

答案:B。Seq2Seq 模型在海量“原文—口语”平行语料上学习,能利用上下文判断"3.15"是日期还是小数、新缩写大概念什么,这是它优于规则方法的核心能力。但它恰恰需要大量标注数据(A 错),推理也可能出错(C 错),而且它仍是文本前端的一环,谈不上免除前端支持(D 错)。

Q5. 混合方案中“置信度路由”的核心做法是什么?

单选题 · mid

  • A.永远优先执行规则表
  • B.只信任模型的输出
  • C.按置信度高低选择路径← 正确答案
  • D.随机选择处理路径

答案:C。置信度路由让规则模块和模型模块各自打分,谁对当前暗号的把握大,谁就获得处理权——就像电台里小李和小陈“谁有把握谁上”。A、B 是极端化策略,D 是随机碰运气,都不是工业界主流的动态平衡做法。

Q6. 文本正则化质量会直接影响合成语音的哪些指标?

多选题 · mid

  • A.听感可懂程度← 正确答案
  • B.听感自然程度← 正确答案
  • C.音调高低变化
  • D.音频采样率大小

答案:AB。正则化把暗号译错,听众就“听不懂”,这是可懂度受损;译得对但断句重音别扭(比如把“GDP“生硬念成”G D P”),这是自然度受损。音调高低由韵律和声学模型决定,采样率是音频编码参数,都与文本规整没有直接关系。

Q7. “2024年”在中文文本正则化中通常读作什么?

单选题 · hard

  • A.按位读成二零二四年← 正确答案
  • B.按值读成二千零二十四年
  • C.按值读成两千零二十四年
  • D.混合读成二〇二四整年

答案:A。中文年份约定俗成地“逐位读”:2→二、0→零、2→二、4→四,合起来是“二零二四年”。B、C 是把年份当数值整体读,属于典型的口语错误;D 是生造的混合读法。这个细节正是“同一数字在不同语境读法不同”的经典考题。

Q8. 为什么“3.15“与”285”中的数字读法完全不同?

单选题 · mid

  • A.因为数字大小完全不同
  • B.因为文本位置顺序不同
  • C.因为标点符号完全不同
  • D.因为所属语境类型不同← 正确答案

答案:D。“3.15“在”3.15消费者权益日“里是日期代号,读”三一五“;在”3.15米“里是小数,读”三点一五”。“285“作为数量读”二百八十五“,作为编号则按位读”二八五”。决定读法的是语境类型,而不是数字大小、位置或标点本身。

Q9. 下列哪些属于声学前端完整流程的环节?

多选题 · hard

  • A.分词与词性标注← 正确答案
  • B.文本规整处理← 正确答案
  • C.韵律结构预测← 正确答案
  • D.声道参数模拟

答案:ABC。声学前端流水线为“分词→词性标注→文本规整→韵律预测→音素序列”,A、B、C 都是前端环节。D“声道参数模拟”属于后端声学建模/声码器的范畴,模拟发音器官的物理过程,不在文本前端流水线之内。

Q10. 文本正则化评测中,词错误率 WER 公式里的 S 表示什么?

单选题 · extreme

  • A.错误删除的词数
  • B.错误替换的词数← 正确答案
  • C.错误插入的词数
  • D.参考句子总词数

答案:B。WER = (S + D + I) / N 中,S 是替换错误(该读“二百八十五”却读成“二百八十六”),D 是删除错误(漏读“年”字),I 是插入错误(多读“零”),N 是参考总词数。A 是 D、C 是 I、D 是分母 N,三者都不是 S 的定义。