原文:Speech and Language Processing (3rd ed. draft)
当前译文基于 Draft of August 24, 2025。
译文仅供学习参考,请勿转载或用于商业用途。
原书作者:
- Daniel Jurafsky,哈佛大学
- James H. Martin,科罗拉多大学博尔德分校
原文:Speech and Language Processing (3rd ed. draft)
当前译文基于 Draft of August 24, 2025。
译文仅供学习参考,请勿转载或用于商业用途。
原书作者:
TTS 系统通常通过人工评估进行评测:向听者播放一段合成语音,并请他们给出平均意见得分(Mean Opinion Score,简称 MOS)——即对合成语音质量的评分,通常采用 1 到 5 分的等级制。 随后,我们可以通过比较不同系统在相同句子上的 MOS 得分来评估其性能优劣(例如,使用配对 t 检验来判断差异是否具有统计显著性)。 如果仅需比较两个系统(例如,验证某项修改是否真正提升了系统性能),还可以采用 CMOS(Comparative MOS,比较式 MOS)方法。在此方法中,用户需对两个合成语音片段进行偏好选择,判断哪一个更好。 CMOS 评分范围为 -3 到 +3:-3 表示当前系统明显劣于参考系统,+3 表示明显优于参考系统。 具体操作时,我们会将同一句话分别用两个系统合成,播放给听者,由他们选择更偏好的版本。 通常会对约 50 个句子(以随机顺序呈现)重复此过程,再统计每个系统被偏好的句子数量并进行比较。 尽管语音合成系统最可靠的评估方式是人工听测,但某些自动指标也可提供补充信息。 例如,我们可以将 TTS 输出送入一个自动语音识别(ASR)系统,计算词错误率(WER),以衡量合成语音的可懂度或可靠性。 又如,在评估 TTS 系统生成的语音与注册说话人语音的相似度时,可将该任务视为说话人验证问题:将目标语音和注册语音输入一个说话人验证系统,并利用其输出的相似度得分作为音色匹配程度的量化指标。 16.3 VALL-E:使用两阶段语言模型生成音频 目录 16.5 其他语音任务
正如引言中所述,VALL-E 等 TTS 系统的基本结构是:以待合成的文本和目标说话人的语音样本作为输入,分别对二者进行词元化,文本使用 BPE(字节对编码)词元化,语音则通过音频编解码器转换为离散词元。 随后,系统利用一个语言模型,以这些输入为条件,生成与文本提示相对应、且具有语音样本音色的离散音频词元序列。 图 16.7 VALL-E 的两阶段语言建模方法,展示了自回归 Transformer 的推理阶段,以及后续 7 个非自回归 Transformer 中的前 3 个。 离散音频词元序列的生成分为两个阶段。 首先,自回归语言模型从左到右逐帧生成第一个量化器(即第一层 RVQ)的所有词元; 然后,非自回归模型被调用 7 次,每次基于前一层所有量化器的词元(包括右侧未来的词元)生成下一层的词元。 VALL-E 并未采用单一的自回归语言模型来完成这一条件生成任务,而是将其拆分为两阶段过程,使用两种不同的语言模型。 这一架构设计受到 RVQ 量化器(生成音频词元)层级结构的启发。 RVQ 的第一层量化器输出对最终语音质量影响最大,而后续各层仅提供越来越微弱的残差信息。 因此,语言模型也分两阶段生成声学词元。 首先,一个自回归语言模型(autoregressive LM)根据输入文本和注册语音样本(enrolled audio),从左到右生成整个输出序列中第一层量化器的全部词元; 接着,在已知这些第一层词元的前提下,一个非自回归语言模型(non-autoregressive LM)被连续运行 7 次。每次运行时,它以初始自回归生成的词元和之前所有非自回归层的输出为条件,依次生成剩余 7 个量化器层的词元。 图 16.7 直观地展示了这一推理过程。 下面我们更详细地介绍该架构。 在训练阶段,给定一段音频样本 $\mathbf{y}$ 及其对应的词元化后文本转录 $\mathbf{x} = [x_0, x_1, \dots, x_L]$。我们使用一个预训练好的 ENCODEC 模型将 $\mathbf{y}$ 转换为一个词元矩阵 $\mathbf{C}$。设 ENCODEC 输出的下采样向量数量为 $T$,每个向量对应 8 个 RVQ 词元,则编码器输出可表示为: $$ \mathbf{C}^{T \times 8} = \text{ENCODEC}(\mathbf{y}) \tag{16.5} $$此处,$\mathbf{C}$ 是一个二维声学词元矩阵,共包含 $T \times 8$ 个元素。其中,列表示时间步(共 $T$ 列),行表示不同的量化器层级(共 8 行)。 具体来说,矩阵的第 $t$ 行向量 $c_{t,:}$ 包含第 $t$ 个时间帧对应的 8 个词元;第 $j$ 列向量 $c_{:,j}$包含来自第 $j$ 个向量量化器的完整词元序列,其中 $j \in [1, \dots, 8]$。 ...
现代 TTS 系统的核心在于将语音波形转换为一串离散的音频词元(audio tokens)。 这种操作离散音频词元的思想,也适用于其他语音赋能系统,例如口语语言模型(spoken language models)。这类模型可以接收文本或语音输入,并生成文本或语音输出,用于完成语音到语音翻译、说话人日志(diarization)或口语问答等任务。 使用离散词元意味着我们可以利用语言模型技术——因为语言模型正是为处理离散词元序列而设计的。 因此,音频词元化器已成为现代语音工具箱中的关键组件。 目前学习音频词元的标准方法是使用神经网络实现的音频编解码器(audio codec)。“codec”一词由 coder/decoder(编码器/解码器)合成而来。 历史上,编解码器是一种将模拟信号数字化的硬件设备。 如今,我们更广义地用它指代一种机制:将模拟语音信号编码为一种可高效存储和传输的压缩数字表示。 编解码器仍广泛用于压缩,但在 TTS 和口语语言模型中,我们主要利用它们将语音转换为离散词元。 当然,我们在第 14 章描述的语音数字表示本身已经是离散的。 例如,以 16 kHz 采样率、16 位精度存储的语音,可以看作 $2^{16} = 65,536$ 个符号构成的序列,每秒钟的语音包含 16,000 个这种符号。 然而,若一个系统每秒需生成 16,000 个符号,那么语音信号序列就过长,难以被语言模型有效处理——尤其是基于 Transformer 的模型,其注意力机制具有二次方复杂度,效率较低。 因此,我们希望使用能代表更长时间片段的符号,例如每秒仅几百个词元。 图 16.2 音频词元化器的标准推理架构(图改编自 Mousavi 等,2025)。 输入波形 $\mathbf{x}$ 经编码器(通常由一系列下采样卷积网络组成)转换为嵌入序列 $\mathbf{z}_t$。 每个嵌入随后通过量化器,生成离散词元序列 $q_t$。 为重建语音信号,这些量化后的词元会被重新映射为向量 $z_{qt}$,再经解码器(通常由一系列上采样卷积网络组成)还原为波形。 我们将在第 16.2.4 节讨论该架构的训练方式。 图 16.2(改编自 Mousavi 等,2025)展示了音频词元化器的标准架构。 音频词元化器以语音波形作为输入,通过一个由向量量化生成的离散词元构成的中间表示,训练目标是尽可能重建原始语音波形。 音频词元化器包含三个阶段: 编码器(encoder)将声学波形(即长度为 $T$ 的序列 $x = x_1, x_2, \dots, x_T$)映射为长度为 $\tau$ 的嵌入序列 $z = z_1, z_2, \dots, z_\tau$。其中 $\tau$ 通常比 $T$ 小 100 到 1000 倍。 ...
文本到语音(TTS)的任务是:根据用户指定的特定声音,生成与目标文本相对应的语音波形。 传统上,TTS 的实现方式是在实验室中从单一说话人那里收集数百小时的语音数据,并在此基础上训练一个大型系统来。 由此构建的 TTS 系统只能合成一种声音。如果需要第二种声音,就必须重新收集另一位说话人的语音数据。 现代方法则不同:使用来自数千名说话人的数万小时语音数据,训练一个与说话人无关的合成器。 当需要生成训练过程中从未见过的新声音时,只需提供极少量的目标说话人语音(例如几秒钟),即可引导系统生成该声音。 因此,现代 TTS 系统的输入包括一段文本提示,以及大约 3 秒钟的目标说话人语音样本。 这种 TTS 任务被称为 零样本 TTS(zero-shot TTS),因为目标声音可能在训练阶段从未出现过。 现代 TTS 系统解决这一任务的方式是采用语言建模,特别是条件生成方法。 其基本思路是:首先获取一个庞大的语音数据集;然后利用基于音频编解码器(audio codec)的音频词元化器(audio tokenizer),从语音中提取出离散的音频标记(tokens),用以表示语音内容。 接着,我们训练一个语言模型,其词汇表同时包含语音词元和文本词元。 在训练过程中,该语言模型接收两个序列作为输入:一段文本转录稿,以及一小段目标说话人的语音样本。模型将文本和语音分别转换为离散标记,然后以这些标记为条件,生成与输入文本相对应、且具有目标说话人音色的离散语音标记序列。 在推理阶段,我们将经过分词的文本字符串和目标声音样本(由编解码器转换为离散音频标记)作为提示输入该语言模型。模型据此条件生成所需的音频词元。 随后,这些词元可被还原为语音波形。 图 16.1 VALL-E 架构用于个性化 TTS(引自 Chen 等,2025)。 Chen 等人(2025)提出的图 16.1 展示了一种此类 TTS 系统的基本思路,该系统名为 VALL-E。 VALL-E 在超过 7000 名不同说话人的 6 万小时英语语音数据上进行训练。 像 VALL-E 这样的系统包含两个组成部分: 音频词元化器(audio tokenizer),通常基于音频编解码器(audio codec)——我们将在下一节详细描述该系统。 编解码器包含三个部分:编码器(将语音转换为嵌入向量)、量化器(将嵌入向量转换为离散词元),以及解码器(将离散词元还原为语音)。 两阶段的条件语言模型(conditional language model),能够生成与目标文本对应的音频词元。我们将在第 16.3 节简要介绍该模型。 第16章 文本到语音 目录 16.2 使用编解码器学习离散音频词元
“文字的意义远不止于纸面上所写下的内容。唯有通过人的声音,才能为其注入更深层的意蕴。” ——玛雅·安杰卢,《我知道笼中鸟为何歌唱》 将文本转换为语音的任务,其历史甚至比语音识别还要悠久。 1769年,在维也纳,沃尔夫冈·冯·肯佩伦为玛丽亚·特蕾莎女皇制造了著名的“机械土耳其人”。那是一个下棋的自动装置,由一个装满齿轮的木箱构成,箱后坐着一个机器人偶,能用机械手臂移动棋子下棋。 “机械土耳其人”在欧洲和美洲巡展数十年,曾击败拿破仑·波拿巴,甚至还与查尔斯·巴贝奇对弈过。 若非后来被揭穿——原来箱内藏有一名真人棋手操控——它或许会被视为人工智能早期的一大成功案例。 较少为人所知的是,冯·肯佩伦还是一位极其多产的发明家。他在1769年至1790年间,建造了一台绝非骗局的装置:世界上第一台能合成完整句子的语音合成器(部分结构见右图)。 该装置包含一个风箱,用于模拟肺部;一个橡胶制的口模和鼻孔开口;一片簧片,用来模拟声带;若干哨子,用于生成擦音;还有一个小型辅助风箱,专门提供爆破音所需的气流。 操作者双手操纵杠杆,控制各处开口的开合,并调节柔性皮革制成的“声道”,从而发出不同的辅音和元音。 两个多世纪之后,我们不再用木材和皮革来构建语音合成器,也不再需要人工操作。现代的文本到语音(Text-to-Speech,简称 TTS),也称语音合成,其任务正好与自动语音识别(ASR)相反:它将文本: It's time for lunch! 映射为一段声学波形: TTS 拥有广泛的应用场景。 它被用于与人类交互的口语语言系统,用于朗读文本,用于游戏配音,也用于为神经系统疾病患者生成语音。例如,已故天体物理学家斯蒂芬·霍金因罹患肌萎缩侧索硬化症(ALS)而失去发声能力后,就依靠TTS系统进行交流。 本章将介绍一种TTS算法。与上一章所述的ASR算法类似,这种算法也是在海量语音数据集上训练而成的。 我们还将简要介绍其他一些语音应用。 15.6 ASR 评估:词错误率 目录 16.1 TTS 概述
语音识别系统(ASR)的标准评估指标是词错误率(Word Error Rate, WER)。 WER 衡量的是识别器输出的词序列(称为假设(hypothesized)词串)与人工标注的参考转录(reference transcription)之间的差异程度。 计算词错误率的第一步是计算假设词串与参考词串之间的最小编辑距离(minimum edit distance),即把一个词串转换为另一个所需的最少词替换(substitutions)、词插入(insertions)和词删除(deletions)操作总数。 词错误率(WER)的定义如下(注意:由于公式中包含插入操作,WER 可能超过 100%): $$ \text{Word Error Rate} = 100 \times \frac{\text{Insertions} + \text{Substitutions} + \text{Deletions}}{\text{Total Words in Correct Transcript}} $$以下是一个来自 CallHome 语料库的参考转录与系统假设之间的对齐示例,展示了用于计算错误率的各项计数: REF: i *** ** UM the PHONE IS i LEFT THE portable **** PHONE UPSTAIRS last night HYP: i GOT IT TO the ***** FULLEST i LOVE TO portable FORM OF STORES last night Eval: I I S D S S S I S S 该句子包含 6 次替换、3 次插入 和 1 次删除: ...
在上一节中,我们指出语音识别有两个特别的属性,使其非常适合编码器-解码器架构:编码器生成输入的编码,解码器则通过注意力机制来探索这些编码。 首先,在语音中,我们有一个非常长的声学输入序列 $X$ 映射到一个短得多的字母序列 $Y$;其次,很难确切知道 $X$ 的哪一部分映射到 $Y$ 的哪一部分。 在本节中,我们将简要介绍一种替代编码器-解码器的方法:一种名为CTC(Connectionist Temporal Classification,连接时序分类)的算法和损失函数(Graves 等,2006),它以非常不同的方式处理这些问题。 CTC 的原理是为每个输入帧输出一个字符,使得输出长度与输入相同,然后应用一个折叠函数将连续相同的字母合并,从而得到一个较短的序列。 假设我们要识别某人说出“dinner”这个词,并且我们有一个函数可以为每个输入谱帧表示 $x_i$ 选择最可能的字母。 我们将与每个输入帧对应的字母序列称为对齐(alignment),因为它告诉我们声学信号中的每一部分对应哪个字母。 图 15.12 展示了一个这样的对齐示例,以及如果我们使用一个简单的折叠函数去除连续重复字母会发生什么。 显然,这种方法行不通;我们的简单算法将语音转录成了“diner”,而不是“dinner”! 折叠操作无法处理双写字母。 此外,我们的简单函数还有一个问题:它没有告诉我们如何对输入中的静音部分进行对齐。 我们不希望将静音部分转录成随机的字母! CTC 算法通过在转录字母表中添加一个特殊的符号——空白(blank),解决了这两个问题,我们用 ␣ 表示这个符号。 每当不想转录一个字母时,就可以在对齐中使用空白符号。 空白也可以用于字母之间;由于我们的折叠函数只折叠连续重复的字母,因此不会跨过空白折叠。 更正式地讲,让我们定义一个从对齐 $a$ 到输出 $y$ 的映射 $B: a \rightarrow y$,该映射会折叠所有重复的字母并移除所有空白。 图 15.13 展示了这个折叠函数 $B$。 图 15.13 CTC 折叠函数 $B$,显示了空白字符 ␣;对齐 $A$ 中的重复(连续)字符被移除以形成输出 $Y$。 CTC 折叠函数是多对一的;许多不同的对齐可以映射到同一个输出字符串。 例如,图 15.13 所示的对齐并不是唯一产生字符串“dinner”的对齐方式。 图 15.14 展示了其他一些也会产生相同输出的对齐方式。 图 15.14 其他三种合法的对齐方式,均产生转录结果“dinner”。 思考所有可能产生相同输出 $Y$ 的对齐集合是有用的。 我们将使用 $B$ 函数的逆函数 $B^{-1}$,并用 $B^{-1}(Y)$ 表示该集合。 ...
除了编码器-解码器架构外,另一类重要的方法是自监督语音模型(self-supervised speech models)。 这类模型并不直接学习将声学输入映射为字母或标记序列。 相反,它们首先从声学信号中自举(bootstrap)出一组离散的音素单元,然后学习将原始波形映射到这些自动归纳出的单元上。 这一预训练阶段不需要转录文本,仅需未标注的语音文件即可。 完成预训练后,这些模型可以在较小规模的带标注数据集(即语音与其人工转录文本的配对)上进行微调,以执行 ASR 任务。 这种方法的优势在于:其大部分训练可以利用大量无转录文本的语音数据。 下面我们介绍一种典型的自监督模型——HuBERT(Hsu 等,2021)。 HuBERT 及其类似模型(如 wav2vec 2.0(Baevski 等,2020))借鉴了第10章所介绍的 BERT 等掩码语言模型的核心思想。 对输入的一部分进行掩码,并训练模型预测被掩码的内容。 图 15.8 HuBERT 在训练阶段的推理流程示意图。 一个16 kHz的原始音频文件首先通过一系列卷积层;随后,部分帧被替换为一个 MASK 标记;接着,整个序列送入Transformer堆栈;最后通过一个线性层,将Transformer输出投影为输出嵌入。 该嵌入通过余弦相似度与 100(或 500)个音素类别的嵌入逐一比较,生成对应logits,再经 softmax 得到每个时间帧上各类别的概率分布。 15.4.1 HuBERT 的前向传播 我们首先描述 HuBERT 在训练时使用的前向传播过程,稍后再将其置于完整的训练上下文中(包括反向传播)。 如前所述,HuBERT 前向传播的输入是原始的 16 kHz 音频波形,其输出是在每个 20 毫秒时间帧上对一组归纳出的音素类别$C$ 的概率分布(类别数通常为 100 或 500,取决于训练阶段)。 图 15.8 展示了该流程的主要组件。 原始音频波形依次通过 7 层 512 通道的卷积层。这些层不仅学习提取频谱信息,还将输入序列压缩至每 20 毫秒一帧的速率;随后添加位置编码,并依次应用 GELU 激活函数和层归一化。 接着,部分时间帧被随机替换为一个特殊的 MASK 标记,这是一个可学习的嵌入向量,所有被掩码的帧共享同一个 MASK 嵌入。 整个序列被送入一个 Transformer 堆栈;Transformer 的输出再经过一个线性投影层 $\mathbf{A}$, 得到每个 20 毫秒帧的输出嵌入;该嵌入与 100(或500)个音素类别各自的嵌入向量计算余弦相似度,生成100(或500)个 logits,表示当前音频帧与每个类别的相似程度。 最后,这些 logits 经过 softmax 函数,转化为一个在所有音素类别上的概率分布。 ...
我们将介绍的第一种自动语音识别(ASR)架构是编码器-解码器架构,这与第 12 章中为机器翻译(MT)引入的架构相同。 图 15.5 描绘了这种架构,被称为基于注意力的编码器解码器或简称AED,或者根据首次将其应用于语音的两篇论文中的名称,称为聆听、注意和拼写(LAS)(Chorowski等人,2014;Chan等人,2016)。 该架构的输入是一个包含 $t$ 个声学特征向量的序列 $\mathbf{X} = (\mathbf{x}_1, \mathbf{x}_2, \dots, \mathbf{x}_t)$,其中每个向量对应于一个 10 毫秒的语音帧。 我们通常从上一节描述的对数梅尔频谱特征开始,尽管也可以直接从原始 wav 文件开始处理。 输出序列 $Y$ 可以是字母或标记(BPE或sentencepiece),为了简化解释,这里假设是字母。 因此,输出序列 $Y = (\langle \text{SOS} \rangle, y_1, \dots,y_m, \langle \text{EOS} \rangle)$,其中假设有特殊的序列起始和结束标记 $\langle \text{SOS} \rangle$ 和 $\langle \text{EOS} \rangle$,且每个 $y_i$ 都是一个字符;对于英语,我们可能会选择如下集合: $$ y_i \in {a, b, c, \dots, z, 0, \dots,9, \langle \text{space} \rangle, \langle \text{comma} \rangle, \langle \text{period} \rangle, \langle \text{apostrophe} \rangle, \langle \text{unk} \rangle } $$ ...
卷积神经网络,或 CNN(有时简称为 convnet),是一种特别适用于语音和视觉应用中提取特征的网络架构。 语音中的卷积层将音频输入(可以是原始音频或梅尔频谱)作为输入,并输出一系列输入语音的潜在表示。 在像 Whisper、wav2vec2.0 或 HuBERT 这样的 ASR 系统中,卷积层被堆叠为初始层集,用于生成传递给 transformer 层的语音表示。 标准前馈层是全连接的;每个输入都连接到每个输出。 相比之下,卷积网络利用了“核”这一概念,即我们通过输入传递的一种小型网络。 例如,在图像分类任务中,我们将核水平和垂直地在图像上移动以识别视觉特征,因此将这种视觉网络描述为 2D(二维)卷积网络。 对于语音,我们将沿着时间维度滑动核以提取语音特征,因此语音的 CNN 是 1D 卷积网络。 我们更深入地探讨一下这个原理。 我们将从一个非常简化的卷积层版本开始,它接受单个向量序列 $\mathbf{x}_1 \cdots \mathbf{x}_t$ 作为输入,并产生相同长度 $t$ 的单个向量序列 $\mathbf{z}_1 \cdots \mathbf{z}_t$ 作为输出。 之后我们将看到如何处理更复杂的输入和输出。 CNN 使用一个核,这是一个小的权重向量 $\mathbf{w}_1 \cdots \mathbf{w}_k$,用来提取特征。 它是通过将这个核与输入进行卷积来实现的。 核与信号的卷积包含三个步骤: 将核左右翻转。 在输入上逐帧(按时间顺序)通过核。 在每一帧计算核与局部输入值的点积。 输出是这些点积的结果序列。 我们可以把卷积过程看作是在信号中找到与核相似的区域,因为当两个向量相似时,它们的点积会很高。 卷积操作用 * 符号表示(这是对这个符号的不幸重载,它也指简单的乘法)。 我们看看如何计算 $\mathbf{x} * \mathbf{w}$,即单个向量 $\mathbf{x}$ 与核向量 $\mathbf{w}$ 的卷积。首先考虑宽度为 1 的简单情况。 计算每个输出元素 $\mathbf{z}_j$ 作为核与 $\mathbf{x}_j$ 的乘积: $$ \text{宽度为 1 的卷积}:\mathbf{z}_j = \mathbf{x}_j\mathbf{w}_1, \forall j : 1 \leq j \leq t \tag{15.1} $$图 15.2 展示了这种计算的直观理解。 ...