Chapter 6: 特征与前端:从 MFCC 到可学习前端,再到 SSL 表征
1. 开篇段落
在构建 ASR 和 Speaker Diarization 系统时,“特征提取”(Feature Extraction)是将原始音频波形(Raw Waveform)转换为机器可理解的二维矩阵(Time × Frequency)的第一步。这一步决定了模型“听”到了什么。如果特征提取丢弃了关键信息(如音素共振峰),模型结构再复杂也无力回天;反之,如果特征保留了过多噪声或信道干扰,模型将难以泛化。
本章将跨越三个技术时代,深入探讨语音特征的演进:
- 信号处理时代:以 MFCC 和 Fbank 为代表,基于人类听觉感知原理(Psychoacoustics)设计的固定变换。这是所有语音工程师的必修课。
- 可学习前端时代:尝试用 Conv1D 和 SincNet 等神经网络结构替代固定的 STFT,让模型从波形直接学习滤波器。
- 自监督学习(SSL)时代:基于 Transformer 的 wav2vec 2.0 / HuBERT / WavLM,它们提取的不再是简单的声学频谱,而是包含上下文和语义的高级表征(Representation)。
最后,我们将重点讨论在 MLLM(多模态大语言模型) 浪潮下,前端如何演变为“音频编码器(Audio Encoder)”与“桥接层(Projector)”,以及如何解决长音频进入 LLM 的时序压缩与模态对齐难题。
6.1 经典声学特征:信号处理的智慧
尽管深度学习模型越来越强,但在许多低资源、低功耗或对延迟极其敏感的场景(如端侧唤醒、实时字幕),基于信号处理的 Fbank 依然是工业界的绝对主力。
6.1.1 核心流程解析
原始音频通常是一维的时域连续信号。为了分析它,我们需要将其转化为频域信号。经典流水线包含以下严格步骤:
[Raw Waveform] (Time Domain)
|
v
1. [Pre-emphasis] (预加重)
| --> y[t] = x[t] - α * x[t-1]
v
2. [Framing] (分帧)
| --> 切分为 25ms 的短片段,重叠 10ms
v
3. [Windowing] (加窗)
| --> 乘以 Hamming/Hanning 窗,减少频谱泄漏
v
4. [FFT] (快速傅里叶变换)
| --> Time Domain -> Frequency Domain (复数)
v
5. [Power Spectrum] (功率谱)
| --> 取模平方 |FFT|^2,丢弃相位信息
v
6. [Mel Filterbanks] (梅尔滤波器组)
| --> 模拟人耳听觉,将线性频率映射到 Mel 刻度
| --> Output: Fbank (Log-Mel) <== 深度学习主流输入
v
7. [Logarithm] (取对数)
| --> 模拟响度感知 (Weber-Fechner Law)
v
8. [DCT] (离散余弦变换)
| --> 去相关性 (Decorrelation)
| --> Output: MFCC <== GMM-HMM 时代主流
6.1.2 关键步骤的技术细节 (Rule of Thumb)
A. 预加重 (Pre-emphasis)
- 物理意义:人类发声时,受唇辐射影响,高频能量随频率增加而衰减(约 -6dB/octave)。如果直接分析,高频共振峰(Formants,对区分辅音至关重要)会被低频能量淹没。
- 公式:y[t] = x[t] - α·x[t-1],通常 α ≈ 0.97。
- 作用:作为高通滤波器,提升高频分量,使频谱变得平坦。
B. 分帧与加窗 (Framing & Windowing)
- 短时平稳假设:语音信号在宏观上是变化的,但在微观(20-30ms)内可视为平稳信号。
- 标准配置:
- Frame Length: 25ms。对于 16kHz 音频,对应 400 个采样点。
-
Frame Shift: 10ms。对应 160 个采样点。即每秒产生 100 帧(100Hz)。
-
为什么要加窗?:直接截断(矩形窗)会导致边界处信号突变,在频域产生严重的频谱泄漏(Spectral Leakage),即不仅主频有能量由于截断效应还会产生大量旁瓣。
- Hamming Window:最常用的窗函数,它将帧两端的信号平滑地压低到接近零,从而抑制旁瓣。
C. Mel 滤波器组 (Mel Filterbanks)
- 人耳的非线性:人耳对低频(如 500Hz vs 600Hz)非常敏感,但对高频(如 10000Hz vs 10100Hz)分辨力很差。
- Mel 刻度公式:mel(f) = 2595 · log10(1 + f/700)。
- 操作:在 FFT 得到的线性频谱上,应用一组三角形滤波器(低频密集、高频稀疏)。通常使用 40 或 80 个滤波器,得到 40/80 维特征。
6.1.3 Fbank vs. MFCC:深度学习选哪个?
- MFCC (Mel-frequency Cepstral Coefficients):在 Log-Mel 之后做离散余弦变换 (DCT)。
- 目的:DCT 可以去除特征维度之间的相关性,生成对角化的协方差矩阵,这是 GMM(高斯混合模型)训练的前提。
-
代价:DCT 是线性变换,且通常只取前 13 维,丢弃了部分非线性信息。
-
Fbank (Log-Mel):不做 DCT,直接保留滤波器组输出。
-
优势:CNN 和 Transformer 擅长处理相关性特征,甚至利用这种频域的局部相关性(如共振峰的结构)。保留更多原始信息通常效果更好。
-
结论:现代 ASR 系统(Conformer, Transducer, MLLM)几乎全部使用 80-dim Fbank。
6.1.4 针对中文/粤语的额外考量:Pitch (F0)
中文和粤语是声调语言(Tonal Language)。虽然 Fbank 包含了部分音高信息,但在某些场景(如情感识别、强噪声下的声调区分)下,显式提取 Pitch (F0) 特征并拼接到 Fbank 中(例如 80维 Fbank + 3维 Pitch = 83维)会有帮助。虽然现代大模型通常能隐式学到,但在小模型上这是提升中文识别率的一个 Trick。
6.2 特征归一化:CMVN 的工程实践
特征的数值范围受录音设备增益、说话人距离等非语义因素影响巨大。归一化是让模型“只关注内容,不关注音量”的关键。
6.2.1 倒谱均值方差归一化 (CMVN)
核心公式: x'{t,f} = (x - μ_f) / σ_f 其中 t 是时间帧,f 是频率通道。
6.2.2 三种归一化策略对比
| 策略 | 描述 | 优点 | 缺点 | 适用场景 |
| 策略 | 描述 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| Global CMVN | 在整个训练集计算固定的均值/方差统计量 | 计算简单,模型输入分布稳定 | 无法消除单条音频特有的信道畸变 | 较少单独使用 |
| Utterance CMVN | 每句话单独计算均值/方差 | 完美消除该句话的信道/响度偏差 | 需要拿到整句音频才能计算 | 离线 ASR 标准方案 |
| Streaming CMVN | 使用滑动窗口或累积统计量估算当前均值/方差 | 低延迟,因果性(Causal) | 早期帧估计不准,实现复杂 | 流式 ASR / 实时会议 |
6.2.3 常见陷阱:Padding 的处理
在 Batch 训练中,短音频会补零(Padding)。
- 错误做法:
mean = input_tensor.mean()。这会将 Padding 的 0 值算入均值,导致特征分布严重左偏。 - 正确做法:必须配合
length_mask,只计算有效帧的统计量。
6.3 SpecAugment:频域与时域的遮挡
SpecAugment 是 ASR 训练中性价比最高的数据增强方法。它不产生新数据,而是通过“破坏”数据来提升鲁棒性。
6.3.1 机制
-
Frequency Masking:随机将频谱图上连续的 F 个频带置为 0(或均值)。 * 目的:模拟频域失真,迫使模型不依赖单一频段(如只看基频),而是利用高频谐波。
-
Time Masking:随机将连续的 T 帧置为 0。 * 目的:模拟短暂的信号丢失或突发噪声,迫使模型根据上下文(Context)推断内容(类似 BERT 的 Mask LM)。
-
Time Warping(可选):在时间轴上做弹性拉伸。由于实现复杂且收益有限,现代框架常省略此步。
6.3.2 经验参数 (Configuration)
对于 LibriSpeech 等标准数据集,常见配置(如 ESPnet/WeNet 默认):
- Freq Masks: 2 个 block,每个最大宽度 30 bins。
- Time Masks: 2 个 block,每个最大宽度 40 frames。
- 自适应策略:Time Mask 的宽度不能超过音频总长的 p(例如 20%),否则短语音可能被完全遮盖导致“空标签”问题。
6.4 可学习前端:从 Conv1D 到 SincNet
这一阶段的研究试图打破 STFT 的物理先验,让神经网络从 Raw Waveform 直接学习。
6.4.1 Conv1D Front-end
用一个步长(Stride)为 160(10ms)、核大小(Kernel Size)为 400(25ms)的 1D 卷积层,去模拟分帧。
- 困境:完全自由学习往往学出一堆杂乱的滤波器,不仅收敛慢,而且不如人工设计的 Mel 滤波器稳定。
6.4.2 SincNet:受约束的卷积 (重点:Diarization)
SincNet 提出了一种折中方案:保留物理约束,学习关键参数。
- 原理:强制卷积核呈现“带通滤波器”(Band-pass filter)的形状。网络不学习卷积核的每一个权重,而是学习滤波器的低频截止频率 f1 和 高频截止频率 f2。卷积核通过 Sinc 函数生成。
- Diarization 价值:在说话人识别(Speaker Verification)任务中,SincNet 往往优于 Fbank。因为 Fbank 的三角滤波抹平了许多高频细节(Pitch 及其谐波的微小抖动),而这些细节正是区分说话人的关键指纹。
6.5 自监督特征(SSL):Wav2vec 2.0, HuBERT, WavLM
这是 ASR 历史上的分水岭。我们不再“提取”特征,而是“预训练”特征。
6.5.1 为什么 SSL 颠覆了 ASR?
传统 Fbank 只是声学信号的压缩,不包含语义。而 SSL 模型(基于 Transformer)在 10万小时(如 LibriLight)的无标注音频上训练,学到了语音的离散结构和长程依赖。 其输出的向量不仅包含声学信息,还隐含了音素甚至词汇级别的聚类属性。
6.5.2 三大里程碑模型对比
| 模型 | 核心机制 | 训练目标 | 优势领域 | Gotcha |
| 模型 | 核心机制 | 训练目标 | 优势领域 | Gotcha |
|---|---|---|---|---|
| wav2vec 2.0 | 对比学习 (Contrastive Learning) | 区分“正确的未来量化向量”与“负样本干扰项” | 通用 ASR | 训练不稳定,对 Batch Size 敏感 |
| HuBERT | 掩码预测 (Masked Prediction) | 类似 BERT,对音频做 K-means 聚类得到伪标签,预测被遮挡帧的 ID | 语义理解,ASR | 训练需多轮迭代(生成伪标签->训练->生成更好伪标签) |
| WavLM | Masked Denoising | 在输入叠加噪声/重叠语音,预测干净语音的伪标签 | ASR + Diarization | 包含了说话人分离能力,SOTA 首选 |
6.5.3 SSL 模型的两种用法
-
Frozen (Upstream):把 SSL 模型看作一个超级特征提取器。输入 Waveform,输出 768/1024 维向量序列,喂给下游的小模型(如 LSTM 或浅层 Transformer)。 * 优点:节省下游训练显存,不用反向传播巨量的 Transformer 参数。
-
Finetune (End-to-End):在 SSL 上加一个 Linear Head,全量微调。 * 优点:WER 效果最好。 * 工程技巧:Layer Freeze。通常在微调初期冻结 SSL 的前几层(CNN 编码层和底层 Transformer),因为底层的声学特征已经学得很好,只需调整高层语义。
6.6 面向 MLLM 的前端演进
当我们将视角转向 GPT-4o、Speech-LLaMA 等多模态大模型时,特征前端面临新的挑战:LLM 无法消化每秒 100 个的音频 Token。
6.6.1 模态对齐 (Alignment)
LLM 的输入是文本 Embedding。音频特征(Continuous)必须映射到文本特征空间(Text Semantic Space)。
- Projector (适配器):通常是一个轻量级的 MLP 或 Multi-head Attention 层,将 SSL 的 1024 维特征投影到 LLM 的 4096 维输入空间。
6.6.2 时序压缩 (Temporal Compression)
10秒音频 = 1000 帧 Fbank。如果直接喂给 LLM,上下文窗口瞬间被占满。必须进行压缩:
- CNN Downsampling:在 Conformer 中,通常包含 2 个 stride=2 的卷积层,将帧率从 10ms 降到 40ms (25Hz)。
- C-Former / Q-Former:使用 Cross-Attention,用固定数量(如 64 个)的 Learnable Queries 去“查询”任意长度的音频特征,提取定长摘要。
- Stacking:简单地将相邻的 4-8 帧拼接成一个大向量。
6.6.3 离散化 Token (Audio Tokenizer)
为了让 LLM像生成文本一样生成音频,或者像理解文本一样理解音频,我们需要将连续音频离散化(Discretization)。
- SoundStream / EnCodec:基于残差矢量量化(RVQ)的神经编解码器。
- SpeechTokenizer:试图解耦“语义 Token”(第一层 RVQ)和“声学细节 Token”(后续 RVQ)。
- 意义:这种“特征”不再是浮点数,而是整数 ID(Codebook Index)。这使得 MLLM 可以直接进行自回归预测。
6.7 本章小结
- 基石:80-dim Fbank + Utterance CMVN + SpecAugment 是目前 ASR 训练的标准“温饱配置”。
- 进阶:对于 Diarization,SincNet 或 WavLM 因保留了更多说话人指纹而优于 Fbank。
- SOTA:SSL (WavLM/HuBERT) 提供了强大的预训练表征,但要注意显存开销和 Layer Freeze 策略。
- 未来:在 MLLM 中,前端不仅是特征提取,更是压缩与离散化的过程,旨在为 LLM 提供高密度的语义 Token。
6.8 练习题
基础题
- Fbank 参数计算:若音频采样率为 16kHz,FFT 点数设置为 512。请问 FFT 输出的频点分辨率是多少 Hz?最高能分析到多少 Hz(奈奎斯特频率)?
- 特征维度:为什么 MFCC 通常取 13 维,而 Fbank 通常取 40/80 维?这反映了 GMM 和 DNN 模型特性的什么差异?
- Padding 陷阱:在 PyTorch 中,如果你对一个 batch
[B, T, D]做mean(dim=1)进行 Global Pooling,而没有使用 mask,由于 padding 的存在,均值会偏大还是偏小?(假设 padding 值为 0,且特征主要为负值,如 Log-Mel)。
挑战题
- SpecAugment 原理:SpecAugment 的 Time Masking 将一段特征置零。这在反向传播时会发什么?它和 Dropout 有何异同?
- 流式 CMVN 设计:设计一个算法,在不允许查看未来帧的情况下,实时计算当前的 Normalized 特征。要求该算法在静音段(长时间低能量)不会导致方差估计发散。(提示:指数移动平均 EMA + 能量阈值门控)。
- MLLM 压缩思考:如果使用 stride=4 的 CNN 进行下采样,对于一个“短促的语气词”(如“啊”,持续 30ms),在特征层面上会发生什么?这会给 MLLM 带来什么困难?
点击查看参考答案与提示
基础题答案:
-
分辨率:。 最高频率: (Nyquist Frequency)。
-
维度差异: * MFCC 取 13 维是因为 DCT 将能量集中在低频倒谱系数,且目的是去相关性以适配 GMM 的对角协方差假设。 * Fbank 取 80 维保留了更多频谱细节。DNN/CNN 擅长处理高维、相关性强的特征,且需要更多原始信息来区分相似音素。
-
Padding 响: Log-Mel 特征通常包含负值(如 -10 到 5 之间)。如果 Padding 为 0,0 比大多数特征值大,因此均值会偏大(偏向 0)。如果特征已经做过 CMVN 均值为 0,则 0 padding 会把方差拉小。
挑战题提示:
- SpecAugment vs Dropout: * 反向传播:Mask 区域梯度为 0,切断了信息流。 * 异同:Dropout 是随机丢弃神经元(特征通道),SpecAugment 是丢弃结构化的时频块(Block)。SpecAugment 强迫模型利用“剩余的上下文”或“剩余的谐波”来重建信息,更像是一种针对时频数据的结构化 Dropout。
- 流式 CMVN: * 使用 EMA:。 * 静音门控:在 VAD 判断为静音(或能量低于阈值)时,停止更新均值 μ 和方差 σ,防止背景噪声主导了统计量,导致后续语音帧归一化后幅值过大(炸音)。
- 短音素消失: * 30ms 的声音只有 3 帧(10ms/帧)。Stride=4 的卷积可能会将其与前后背景音混合,甚至在 MaxPooling 中丢失位置精度。 * 这对 MLLM 的影响是可能产生“吞字”现象,或者时间戳预测不准。解决方案通常是使用重叠切片或更精细的 Tokenizer。
6.9 常见陷阱与错误 (Gotchas)
1. 采样率灾难 (16k vs 44.1k/48k)
- 现象:模型完全听不懂,或者 WER 极高(>80%)。
- 原因:训练数据通常是 16k。如果线上推流送入 48k 音频且未做重采样,STFT 分析的物理频率范围完全改变,共振峰位置整体偏移。
- 调试:在特征提取前,务必打印音频 tensor 的 shape 和 meta info,确保
sr=16000。
2. Dithering (抖动) 的缺失
- 现象:在处理纯数字静音(Digital Silence,全 0 数据)时,训练程序报错
NaN或Inf。 - 原因:。
- 对策:在分帧前,给波形加上极微小的随机高斯噪声(Dither)。这不仅解决了数学错误,还能防止量化噪声带来的伪影。
- Kaldi/ESPnet 认配置:
dither=1.0(对于 16-bit int 音频) 或1e-5(对于 float 音频)。
3. 特征存储格式 (Float16 vs Float32)
- 现象:为了省硬盘,把 dump 下来的 Fbank 存为
float16。训练时 Loss 震荡。 - 原因:Fbank 做完 Log 后范围尚可,但如果在归一化(CMVN)前存为 fp16,由于方差计算涉及平方和,可能会溢出或精度不足。
- 建议:特征预处理阶段尽量保持
float32,进入模型显存后再转mixed precision。
4. 忽略了 DC Offset (直流偏置)
- 现象:低频能量异常高,静音段也不是 0。
- 原因:硬件录音设备的电压零点漂移。
- 对策:在预加重之前,减去整段音频的均值(
waveform = waveform - waveform.mean())。