第 3 章:语音类训练数据集(ASR/说话人/视听语音)

1. 开篇段落

语音(Speech)是音频智能的“Hello World”,也是标准化程度最高、商业落地最成熟的领域。然而,随着 Whisper 等大规模弱监督模型的出现,语音数据的范式正在从“精标小数据”向“海量弱标数据”转移。对于开发者而言,理解语音数据不再仅仅意味着下载一个压缩包,而是需要掌握多语种混合多信道模拟说话人去重以及视听模态对齐的复杂工程。

本章将带你深入语音数据的核心。我们将不仅讨论“用什么数据”,更会剖析“为什么用它”以及“如何处理它”。学习目标包括:

  1. 建立数据分层视角:区分验证型基准(如 AISHELL-1)与生产型语料(如 WenetSpeech、GigaSpeech)。
  2. 掌握核心数据工程:从文本正则化(Text Normalization)到强制对齐(Force Alignment),掌握决定模型上限的数据清洗技术。
  3. 理解跨模态与声纹:从单纯的 ASR 扩展到视听语音(AV-ASR)和说话人识别(SD/SV),理解不同任务对数据维度的不同需求。

2. 文字论述

3.1 中文 ASR:从“玩具”到“工业级”

中文语音识别的数据选型存在明显的“代际差异”。

2.1.1 入门与验证:AISHELL-1

AISHELL-1 是中文 ASR 的 MNIST。它只有 178 小时,但这正是它的价值所在:

  • 用途:当你修改了模型结构(例如从 Conformer 换到 Zipformer),你需要一个能在一张 GPU 上一天内跑完的数据集来验证收敛性。
  • 局限:录音环境过于理想(安静、朗读风格),不可用于生产环境。

2.1.2 进阶与生产:WenetSpeech 与 AISHELL-4

当目标是生产落地时,我们需要应对真实世界的复杂性。

  • WenetSpeech (10000+小时):源自 YouTube 和 Podcast。
  • 强弱标签体系:它并不保证所有文本都是 100% 准确的。它提供了一个 confidence 分数。
  • Rule of Thumb:训练初期使用高置信度数据(Strong Label)预热,中后期混入低置信度数据(Weak Label)以提高鲁棒性。

  • AISHELL-4 (会议场景):专注于远场(Far-field)和重叠语音(Overlapping Speech)

  • 关键特征:包含 8 通道麦克风阵列数据。如果你做智能音箱或会议记录,单通道的 AISHELL-1 毫无意义,必须使用此类多通道数据进行波束成形(Beamforming)后的训练。

3.2 英文与多语种:规模即正义

2.2.1 LibriSpeech:学术界的标尺

尽管由有声读物构成,LibriSpeech 依然是衡量英文 ASR 算法(如 wav2vec 2.0, HuBERT)的标准。

  • 960小时的构成
  • train-clean-100 / train-clean-360:低口音,信噪比高。
  • train-other-500:口音略重,录音质量参差不齐。

  • SOTA 标准:目前 Top-tier 的模型在 test-clean 上的 WER(词错率)通常 < 2%,在 test-other 上 < 4%。如果不分 clean/other 汇报成绩,就是耍流氓。

2.2.2 GigaSpeech 与 Common Voice:野外的声音

  • GigaSpeech (10,000+小时):相比 LibriSpeech,它包含更多样的风格(YouTube、Podcast、有声书)。它按照质量分为 XL, L, M, S, XS 五个子集,方便不同算力用户使用。
  • Common Voice (CV):Mozilla 的全球众包项目。
  • 多语种之王:涵盖 100+ 种语言。
  • 陷阱:由于是网页端录制,包含大量非线性失真(爆音)和编解码伪影(MP3 Artifacts)。在用于训练高保真 TTS 或声码器时需极度小心。

3.3 视听语音(Audio-Visual):看着你的嘴型

视听语音数据集的核心价值在于模态互补。当音频被噪声淹没时,唇形(Visual Stream)能提供关键的音素信息。

2.3.1 AVSpeech vs. LRS 系列

  • AVSpeech:大规模(4700h),弱标注。适合做自监督预训练(Pre-training)。
  • LRS2 (BBC) / LRS3 (TED):较小,但质量极高,句子级对齐。是唇读(Lip Reading)视听语音识别(AV-ASR)的标准测试集。

2.3.2 关键数据结构

处理 AV 数据时,你不再处理单一的 .wav,而是处理“视频帧+音频窗”的切片。

ASCII 图解:视听数据加载器的逻辑

Item: "Speaker_A_Sentence_001"
├── Visual Stream (Video Tensor)
│   └── Shape: [T_v, H, W, C]  (例如: [25帧, 112, 112, 1灰度])
│       (注意:通常需锁定嘴唇区域 ROI,并做灰度化处理以减少计算量)
├── Audio Stream (Audio Tensor)
│   └── Shape: [T_a]           (例如: [16000点]) -> 对应 1秒
└── Synchronization (Sync)
    └── 严格的时间戳对齐:视频第 i 帧 必须对应 音频的时间窗 [t_start, t_end]

3.4 说话人任务:VoxCeleb 与声纹

说话人识别(Speaker Verification/Identification)不关心“说了什么”,只关心“是谁说的”。

  • VoxCeleb 1 & 2
  • 行业惯例:通常使用 VoxCeleb 2 (数据量大,100w+ utterances) 进行训练,使用 VoxCeleb 1 的特定列表(如 Vox1-O, Vox1-E, Vox1-H)进行测试
  • 难点:包含真实的背景音乐、笑声、回声。

  • CN-Celeb:清华发布的中文大规模说话人数据集。

  • 注意:由于中文发音特性和信道差异(微信语音、直播等),在做面向中国用户的声纹系统时,仅用 VoxCeleb 效果会大打折扣,必须引入 CN-Celeb 进行域适应(Domain Adaptation)。

3.5 核心数据工程:Pipeline 决定成败

数据工程不仅仅是清洗,而是特征重构

3.5.1 文本正则化 (Text Normalization)

这是 ASR 数据处理中最容易被忽视的大坑。

  • 问题:音频里读的是 "two thousand and twenty three",但在 Transcript 里写的是 "2023"。如果不处理,模型会学会将音频特征映射到字符 "2" 上,而不是音素序列 "t u ..." 上。
  • 解决:必须使用反文本归一化 (ITN) 库(如 WeTextProcessing),将 "2023" 转写为汉字/单词形式,或者将训练目标统一规范化。

3.5.2 强制对齐 (Forced Alignment)

如果你需要做流式 ASR 或者 TTS,你需要知道每个字确切的开始和结束时间。

  • 工具Montreal Forced Aligner (MFA) 是标准工具。
  • 原理:利用一个预训练好的声学模型(HMM-GMM 或 DNN),将文本音素序列与音频波形进行动态规划对齐。

3.5.3 数据增强配方 (The Augmentation Recipe)

一个标准的抗噪 ASR 训练配方通常包含:

  1. 速度扰动 (Speed Perturbation):0.9x, 1.0x, 1.1x 重采样。这不仅改变时长,也改变基频(Pitch),能有效模拟不同人的语速和音高。
  2. SpecAugment:在梅尔谱(Mel-spectrogram)上随机掩盖(Mask)一段频率或一段时间。这是最强效的正则化手段,防止过拟合。
  3. RIR 混响:使用 OpenSLR 28 等数据集,将纯净语音与房间脉冲响应(RIR)进行卷积,模拟不同房间的回声。

3. 本章小结

  • ASR 阶梯:AISHELL-1 跑通代码 -> WenetSpeech/LibriSpeech 刷 SOTA -> 业务数据微调。
  • 度量标准:中文看 CER (Character Error Rate),英文/拼音文字看 WER (Word Error Rate)。两者不可混淆。
  • 视听关键:AVSpeech 和 LRS3 是核心。视觉模态能显著提升低信噪比(Low SNR)下的识别率。
  • 说话人红线Speaker Leakage 是大忌。训练集和测试集的 Speaker ID 必须严格隔离。
  • 工程核心:文本正则化("123" -> "一百二十三")和 SpecAugment 是提升模型实战能力的各种“魔法”中最有效的两个。

4. 练习题

基础题(巩固概念)

Q1: 词错率 (WER) 与字错率 (CER) 的计算逻辑有何不同?如果在中文 ASR 任务中强行使用 WER 会有什么问题?

点击展开答案

提示:思考中文的分词(Tokenization)不确定性。 答案

  1. 计算逻辑:WER 以空格分隔的“单词”为单位计算 Levenshtein 距离;CER 以“字符”为单位。
  2. 中文的问题:中文没有天然的空格分词。如果使用 WER,必须先进行分词(如使用 Jieba)。由于分词算法本身存在误差(例如“南京市长江大桥”),会导致 ASR 的评估结果混入了分词器的错误,无法客观反映声学模型的性能。因此中文标准是 CER

Q2: 在处理 LibriSpeech 时,为什么 train-clean-100 训练出的模型在 test-other 上表现很差?从数据分布的角度解释。

点击展开答案

提示:域偏移(Domain Shift)。 答案clean 子集主要包含发音清晰、美式口音、无背景噪的录音。other 子集包含非美式口音、背景底噪、麦克风质量差的数据。仅在 clean 上训练的模型,其学到的声学特征分布过于狭窄(Overfitted to clean domain),缺乏对噪声和变异口音的鲁棒性,即发生了域偏移(Domain Shift)

Q3: 什么是 SpecAugment?为什么在频谱图上画“黑条”能提高模型效果?

点击展开答案

提示:模拟丢包和局部特征缺失。 答案

  1. 定义:SpecAugment 是一种数据增强技术,通过在 Mel 频谱图上随机掩盖(Mask)连续的时间步(Time Masking)或频率通道(Frequency Masking)。
  2. 原理:这迫使模型不依赖单一的特征维度(例如某个特定的共振峰频率)来识别语音,而是必须利用上下文信息(Context)和其他频段的冗余信息来推断缺失内容,从而极大提高了模型的鲁棒性。

挑战题(工程实战与深度思考)

Q4: 你正在训练一个端到端的 TTS 模型,使用了网络爬取的 5000 小时数据。训练后发现模型生成的语音经常带有奇怪的“咔哒”声,且高频模糊。这是什么原因?如何清洗数据解决?

点击展开答案

提示:采样率混杂、截断效应、静音段噪点。 答案

  1. 原因分析: * 高频模糊:数据集中可能混入了低采样率(如 16kHz 或 8kHz)后被强行插值到 24kHz/44.1kHz 的音频,导致高频信息缺失。 * 咔哒声:切分音频时未在过零点(Zero-crossing)截断,导致波形突变;或者原始数据首尾包含非静音的噪声突发。

  2. 清洗策略: * 频谱检查:计算所有音频的 STFT,检查 8kHz/16kHz 处是否有明显的能量截断,剔除伪高采样率数据。 * Fade In/Out:对所有训练切片的首尾应用微小的淡入淡出(如 10ms)窗口。

Q5: 在构建视听语音识别(AV-ASR)数据集时,你发现部分视频存在“音画不同步”现象(Lip sync error)。请设计一个自动化的 pipeline 来检测并剔除这些脏数据。

点击展开答案

提示:SyncNet 思想。 答案: 利用预训练的同步检测模型(如 SyncNet):

  1. 特征提取:分别提取视频流的唇部视觉特征和音频流的 MFCC 特征。
  2. 滑动窗口计算:在时间轴上滑动音频窗口,计算其与视觉特征的相关性(Correlation)。
  3. 判定: * 如果最大相关性对应的偏移量(Offset)接近 0,则同步。 * 如果偏移量显著(如 > 200ms),则存在不同步。 * 如果最大相关性极低,说明该片段可能根本没有说话人画面(如画外音),应剔除。

Q6 (开放题): 假设你要发布一个新的中文方言(如粤语、四川话)ASR Benchmark。为了防止“类似于 ImageNet 的过拟合”,你会如何设计 Test Set 的划分策略?

点击展开答案

提示:时间跨度、话题隔离、零样本场景。 答案

  1. 话题隔离(Topic Split):确保 Train 和 Test 覆盖完全不同的话题(例如 Train 是新闻,Test 是生活对话)。这测试模型对语言学结构的泛化,而非对话题词汇的记忆。
  2. 跨时间划分:采集时间应有间隔。例如 Train 是 2023 年的数据,Test 是 2024 年的数据(包含新词、新梗)。
  3. 信道隔离:Train 主要是手机近讲,Test 包含一部分会议室远场或车载噪声环境,设立 Test-Hard 子集。
  4. 说话人隔离:这是基础,Test 必须全是 Unseen Speakers。

Q7 (代码逻辑题): 在使用 PyTorch 的 DataLoader 加载语音数据时,不同长度的音频会被 Padding 到同一长度。为了避免 LSTM/Transformer 处理这些 Padding 部分(无意义的 0),你需要传入什么参数?

点击展开答案

提示:Attention Mask, pad_sequence, pack_padded_sequence. 答案

  1. Length Tensor:Dataloader 除了返回 padded batch,还必须返回一个 real_lengths 向量,记录每条音频的真实长度。
  2. Attention Mask:对于 Transformer,需要构建 key_padding_mask,将 Padding 的位置设为 True(或 -inf),使 Attention 权重为 0。
  3. Pack Padded:对于 LSTM/RNN,使用 torch.nn.utils.rnn.pack_padded_sequence,这不仅忽略 padding,还能优化计算性能。

5. 常见陷阱与错误 (Gotchas)

5.1 采样率的隐形杀手

  • 错误:在训练配置文件中写了 sample_rate: 16000,但数据文件夹里混杂了 44.1kHz 和 48kHz 的文件。
  • 后果:Torchaudio 或 Librosa 读取时如果不强制重采样,会导致音频时长变慢/变快(Pitch Shift),或者输入的 Tensor 长度爆炸。
  • Gotcha:不要相信文件后缀!wav 容器里可能是任何采样率。必须在 Dataloader 的 __getitem__ 里显式调用 Resampler。

5.2 文本正则化的“回马枪”

  • 错误:训练数据里文本是 "Project 101",ASR 输出是 "Project One Oh One"。你计算 WER 时发现错误率极高。
  • 原因:这是评测口径问题,而非模型错误。
  • Gotcha:在计算 WER/CER 之前,必须对 Ground Truth 和 Model Output 应用同一套标准化(Normalization)规则(例如:统一转小写、去除标点、数字转英文单词)。推荐使用 OpenAI Whisper 的 standardize_text 函数作为基准。

5.3 错误的 VAD 截断

  • 错误:VAD 阈值设置过高,导致句子开头的爆破音(如 "P", "B")或句尾的轻音(如 "s", "f")被切掉。
  • 后果:模型学会了“吞音”,或者很难识别句首单词。
  • 调试:VAD 切分时,务必在检测到的语音段前后各加 200ms-300ms 的 Padding(安全余量)

5.4 乱序的数据加载

  • 错误:在训练 RNN/LSTM 等对长度敏感的模型时,直接完全随机 Shuffle 数据。
  • 后果:一个 Batch 里可能同时包含 1秒的短音频和 20秒的长音频。Padding 会填充大量的 0,导致 GPU 显存被无效的 Padding 占满,计算效率极低。
  • 技巧:使用 BucketingSampler (分桶采样)。将长度相近的音频放在一个 Batch 里,可以显著减少 Padding,提升 20%-30% 的训练速度。