语音与音频机器学习:MFCC、CTC/RNN-T、Whisper、TTS 与声码器

把声音变成可学习的数据:音频采样与频谱基础、MFCC 与梅尔谱特征提取、ASR 三大架构 CTC/RNN-T/注意力编码解码的对比、Whisper 端到端语音识别实战、TTS 声学模型与声码器(HiFi-GAN)流程、说话人识别的嵌入与验证、音频数据增强手段,以及 WER/MOS 等评测指标与工程落地要点。

引言

语音是最高效的人机交互通道,也是机器学习里最「不像图像也不像文本」的模态——它是一维时序信号,采样率高、冗余大、变长且对齐模糊。把「一段波形」变成「一串文字」或「一个说话人身份」,背后是一整套从信号处理到序列建模的技术栈。

本文从最基础的音频表示讲起:采样率、频谱、梅尔谱、MFCC 这些特征决定了模型能「看到」什么;然后对比 ASR 的三大建模范式 CTC、RNN-T、注意力编码解码,并给出 Whisper 的实战用法;接着讲 TTS 与声码器如何把文字变回声音、说话人识别如何用一个向量表征音色;最后覆盖音频增强、WER/MOS 评测与工程落地。全文代码基于 HuggingFace 与 torchaudio 生态。

前置:序列建模与注意力机制见 https://plumephp.com/ml-deep-learning-advanced/;文本侧的语言模型与分词见 https://plumephp.com/ml-nlp-basics/;预训练与迁移复用见 https://plumephp.com/ml-transfer-learning/;语音服务上线见 https://plumephp.com/ml-model-deployment/。


目录


1. 语音任务全景

1.1 常见任务分类

任务输入输出典型应用
ASR 语音识别波形文本语音转写、字幕
TTS 语音合成文本波形语音助手、有声书
说话人识别波形身份/向量声纹解锁、客服质检
语音增强带噪波形干净波形降噪、助听器
关键词唤醒波形命中/未命中「小爱同学」
情感识别波形情感类别客服情绪分析

1.2 三个技术转折

语音技术的演进有三个关键节点:GMM-HMM(传统,靠特征工程 + 隐马尔可夫)→ DNN-HMM / CTC(深度学习接管声学模型)→ 端到端(Whisper 直接把波形映射成文本)。端到端把复杂的多模块流水线压成一个模型,大幅简化了工程。

1.3 语音数据的特殊性

  • 时序变长:一段话可以是 1 秒也可以是 1 分钟;
  • 对齐模糊:文字和音频的时间边界不明确(一个音素对应多少帧?);
  • 冗余高:16kHz 采样,1 秒就是 16000 个点,但信息量远低于此;
  • 噪声敏感:环境噪声、口音、语速都影响识别。

一句话:语音是「高采样率、变长、对齐模糊」的时序信号,所有语音模型的第一课都是「怎么把冗余的波形压缩成有意义的特征」。


2. 音频特征:从波形到梅尔谱

2.1 采样、分帧与加窗

音频是连续的声压变化,数字化要经过采样(通常 16kHz)、分帧(每帧 25ms、步长 10ms)、加窗(汉明窗减少频谱泄漏)。分帧后每帧做短时傅里叶变换(STFT)得到频谱。

波形 (16000 点/秒)
  → 分帧:25ms 一帧、10ms 一帧移 → 每帧 400 点
  → 加窗:汉明窗
  → STFT:每帧 → 频谱
  → 梅尔滤波 → 梅尔谱(80 或 128 维)

2.2 梅尔谱与 MFCC

人耳对频率的感知是非线性的(低频敏感、高频迟钝),梅尔刻度模拟了这种非线性。梅尔谱就是把频谱过一组梅尔滤波器组,得到 80/128 维的表示,是深度学习 ASR 的标准输入。

MFCC 是在梅尔谱基础上再做 DCT(离散余弦变换)取前 13 维,进一步压缩。MFCC 曾是传统 ASR 的标配,如今深度学习更常用原始梅尔谱(保留更多信息)。

特征维度特点用途
原始波形16000/s信息全、冗余大端到端模型
梅尔谱80-128保留感知相关信息主流 ASR 输入
MFCC13-40高度压缩、去相关传统 ASR、说话人

2.3 用 torchaudio 提取特征

import torch
import torchaudio
import torchaudio.transforms as T

waveform, sr = torchaudio.load("speech.wav")   # (channels, samples)
if sr != 16000:
    waveform = torchaudio.functional.resample(waveform, sr, 16000)

mel_transform = T.MelSpectrogram(
    sample_rate=16000, n_fft=400, hop_length=160, n_mels=80, f_min=0, f_max=8000,
)
mfcc_transform = T.MFCC(
    sample_rate=16000, n_mfcc=13,
    melkwargs={"n_fft": 400, "hop_length": 160, "n_mels": 80},
)

mel = mel_transform(waveform)          # (1, 80, T)
mfcc = mfcc_transform(waveform)        # (1, 13, T)
log_mel = torch.log(mel + 1e-6)        # 取对数,动态范围更友好
print(mel.shape, mfcc.shape)

一句话:梅尔谱模拟人耳的非线性频率感知,是深度学习 ASR 的标准输入;MFCC 是它的压缩版,适合传统模型和说话人任务。


3. ASR 架构:CTC、RNN-T 与注意力

3.1 核心难题:变长对齐

ASR 的根本困难是输入帧数和输出字符数不对齐:1 秒语音有 100 帧梅尔特征,但只对应几个字。三大架构就是三种解决对齐的思路。

3.2 CTC:引入空白符

CTC(Connectionist Temporal Classification)在词表里加一个空白符(blank),允许模型在任意帧输出 blank 或字符,最后合并重复、删掉 blank 得到文本。它假设输出帧之间条件独立,因此训练快、可并行,但无法建模字符间依赖(需外接语言模型)。

帧输出: _ _ h h _ e e _ l l l _ l l _ o o _ _
合并后: h e l l o
import torch
import torch.nn as nn

# CTC 损失:log_probs 形状 (T, N, C),targets 是文本 id
ctc_loss = nn.CTCLoss(blank=0, zero_infinity=True)
log_probs = model(mel)                      # (T, N, C)
loss = ctc_loss(log_probs, targets, input_lengths, target_lengths)

3.3 RNN-T:流式识别的王者

RNN-T(RNN Transducer)把网络拆成三部分:Encoder(处理音频)、Predictor(处理已输出文本)、Joiner(合并两者预测下一个 token)。它不假设独立性,且天然支持流式(来一帧解一帧),是实时字幕、语音输入法的首选。

架构独立性假设流式训练难度代表
CTC有支持低DeepSpeech
RNN-T无原生支持中Google、Conformer
Attention Enc-Dec无需改造高Whisper

3.4 注意力编码解码

Attention Encoder-Decoder 用编码器压缩音频、解码器自回归生成文本,建模能力最强(能利用全部上下文和语言知识),但不天然流式。Whisper、大部分高质量离线 ASR 都用这个范式。

一句话:CTC 用 blank 解决对齐、训练简单但假设独立;RNN-T 用 Joiner 建模依赖、天生流式;注意力编码解码能力最强但需离线——选架构就是选「流式 vs 精度」的权衡。


4. Whisper 与端到端 ASR

4.1 Whisper 的设计

Whisper 是 OpenAI 的大规模弱监督 ASR:用 68 万小时多语言、多任务的网络音频训练,输入是 30 秒的 log-Mel 谱,输出是文本 token 序列(含任务标记如 <|transcribe|>、<|translate|>、语言标记)。它的核心贡献不是架构创新,而是数据规模 + 多任务统一。

音频 → 30s 窗口 → log-Mel (80维) → Encoder(Transformer) → Decoder → 文本 token
Decoder 前缀:[<|startoftranscript|><|zh|><|transcribe|><|notimestamps|>]

4.2 用 transformers 跑 Whisper

import torch
from transformers import WhisperProcessor, WhisperForConditionalGeneration

processor = WhisperProcessor.from_pretrained("openai/whisper-large-v3")
model = WhisperForConditionalGeneration.from_pretrained(
    "openai/whisper-large-v3", torch_dtype=torch.float16
).to("cuda")

import librosa
audio, sr = librosa.load("speech.wav", sr=16000)
inputs = processor(audio, sampling_rate=16000, return_tensors="pt").to("cuda")

forced_ids = processor.get_decoder_prompt_ids(language="zh", task="transcribe")
ids = model.generate(inputs.input_features, forced_decoder_ids=forced_ids, max_new_tokens=256)
print(processor.batch_decode(ids, skip_special_tokens=True)[0])

4.3 长音频与时间戳

Whisper 原生只吃 30 秒,长音频要滑窗切分 + 拼接。生产环境用 whisperx 或 faster-whisper:前者加 VAD 切分和对齐(给词级时间戳),后者用 CTranslate2 推理,速度提升 4 倍、显存减半。

# faster-whisper:CTranslate2 加速 + int8 量化
pip install faster-whisper
from faster_whisper import WhisperModel

model = WhisperModel("large-v3", device="cuda", compute_type="float16")
segments, info = model.transcribe("long_audio.wav", language="zh", vad_filter=True)
for seg in segments:
    print(f"[{seg.start:.2f}-{seg.end:.2f}] {seg.text}")

一句话:Whisper 靠海量弱监督数据 + 多任务统一标记做到了强大的零样本识别;生产落地要配 VAD 切分、faster-whisper 加速和词级对齐。


5. TTS 与声码器

5.1 两阶段:文本 → 声学特征 → 波形

经典 TTS 是两段式:声学模型把文本转成中间声学特征(梅尔谱),**声码器(Vocoder)**再把梅尔谱还原成波形。声码器质量直接决定音质。

文本 "你好" → [文本前端/音素] → [声学模型 Tacotron/FastSpeech] → 梅尔谱
             → [声码器 HiFi-GAN] → 波形

5.2 声码器:从 Griffin-Lim 到 HiFi-GAN

声码器类型音质速度
Griffin-Lim信号处理差(机械音)慢
WaveNet自回归神经极好极慢
WaveGlow流模型好中
HiFi-GANGAN好快(实时)

HiFi-GAN 是当前主流:用生成器把梅尔谱逐层上采样成波形,配合多周期判别器训练,音质接近真人且可实时。

5.3 现代端到端 TTS

VITS、Tortoise、Bark、以及基于 LLM 的 TTS 把两阶段合并,直接从文本生成波形,并支持零样本音色克隆(给几秒参考音频就能模仿音色)。

from TTS.api import TTS   # Coqui TTS

tts = TTS("tts_models/zh-CN/baker/tacotron2-DDC-GST").to("cuda")
tts.tts_to_file(text="你好,欢迎使用语音合成。", file_path="out.wav")

# 零样本音色克隆
tts_clone = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to("cuda")
tts_clone.tts_to_file(
    text="这是用参考音色说的话。",
    speaker_wav="reference.wav",
    language="zh",
    file_path="clone.wav",
)

5.4 TTS 的评测

TTS 没有唯一正确答案,评测靠主观 MOS(人打分)+ 客观指标(MCD 梅尔倒谱失真、PESQ)。MOS 是黄金标准但昂贵,常做小规模人工评估。

一句话:TTS = 声学模型 + 声码器两段式(或端到端),HiFi-GAN 是声码器的性价比之王;评测依赖主观 MOS,工程上还要关注实时率(RTF)。


6. 说话人识别与音频嵌入

6.1 任务定义

说话人识别分两种:验证(Verification)——判断两段语音是不是同一个人;辨认(Identification)——从注册库里找出是谁。核心是把变长语音压成定长说话人嵌入向量(如 192 维),再算余弦相似度。

6.2 经典模型:ECAPA-TDNN 与 x-vector

模型结构特点
i-vectorGMM + 因子分析传统、已过时
x-vectorTDNN + 池化深度学习的里程碑
ECAPA-TDNN多尺度 TDNN + 注意力当前 SOTA 之一
WavLM/ECAPA自监督前端抗噪强

6.3 用 SpeechBrain 提取嵌入

from speechbrain.inference.speaker import EncoderClassifier
import torch
import torchaudio

classifier = EncoderClassifier.from_hparams(
    source="speechbrain/spkrec-ecapa-voxceleb", run_opts={"device": "cuda"}
)

def embed(path):
    signal, sr = torchaudio.load(path)
    if sr != 16000:
        signal = torchaudio.functional.resample(signal, sr, 16000)
    return classifier.encode_batch(signal).squeeze()   # (192,)

e1, e2 = embed("a.wav"), embed("b.wav")
score = torch.nn.functional.cosine_similarity(e1, e2, dim=0)
print(f"相似度: {score:.3f}")   # 阈值通常 0.25-0.35

6.4 关键指标

  • EER(等错误率):误拒率 = 误受率时的错误率,越低越好;
  • minDCF:给定代价下的最小检测代价;
  • 阈值选择:取决于业务——安全场景宁可误拒(阈值高),便捷场景容忍误受。

一句话:说话人识别的本质是「把音色压成一个向量」,ECAPA-TDNN 是当前主力;评测看 EER,落地要按业务风险选阈值。


7. 音频数据增强

7.1 为什么要增强

语音数据标注昂贵、场景多样(安静/嘈杂/远场/电话),增强能显著提升鲁棒性。音频增强分波形级和特征级两类。

增强手段层级模拟场景
加噪(Noise)波形嘈杂环境
变速(Speed)波形语速差异
变调(Pitch)波形音高差异
混响(Reverb)波形房间声学
SpecAugment特征遮挡时频
音量扰动波形远近距离

7.2 SpecAugment:语音里的 Cutout

SpecAugment 直接作用在梅尔谱上:时间掩蔽(遮一段连续帧)+ 频率掩蔽(遮几个梅尔通道)。它简单有效,是 ASR 训练的标配,几乎零成本。

import torch
import torchaudio.transforms as T

spec_aug = T.FrequencyMasking(freq_mask_param=27)
time_aug = T.TimeMasking(time_mask_param=100)

def augment(mel):
    # mel: (C, n_mels, T)
    for _ in range(2):
        mel = spec_aug(mel)   # 频率掩蔽
        mel = time_aug(mel)   # 时间掩蔽
    return mel

7.3 加噪与混响实现

import torch
import torchaudio

def add_noise(waveform, noise, snr_db=10):
    """按指定信噪比混合噪声"""
    signal_power = waveform.norm(p=2) ** 2
    noise_power = noise.norm(p=2) ** 2
    snr = 10 ** (snr_db / 10)
    scale = (signal_power / (snr * noise_power + 1e-8)).sqrt()
    return waveform + scale * noise[:, :waveform.size(-1)]

一句话:SpecAugment 是语音训练的「免费午餐」,直接遮挡时频块;波形级的加噪、变速、混响则模拟真实场景,是鲁棒性的关键。


8. 评测指标与工程落地

8.1 ASR 指标:WER 与 CER

WER(词错误率) = (替换 + 删除 + 插入) / 总词数。中文按字算则用 CER(字错误率)。

import jiwer

reference = "今天天气很好"
hypothesis = "今天天气好"
print("CER:", jiwer.cer(reference, hypothesis))   # 0.2
指标计算单位适用
WER词英文等分词语言
CER字中文、日文
RTF处理时长/音频时长速度(<1 为实时)
MOS人工打分 1-5TTS 音质

8.2 影响 WER 的因素

因素影响缓解
噪声WER 大幅上升增强训练、降噪前端
口音领域偏移口音数据微调
专业术语未登录词热词/上下文偏置
长音频累积错误VAD 切分、分段解码
数字/实体格式不一致文本归一化

8.3 工程落地要点

1. 前端:VAD 切分 + 降噪 + 重采样统一到 16kHz
2. 模型:faster-whisper / onnx 导出 + int8 量化
3. 后处理:标点恢复 + 数字归一化 + 热词替换
4. 部署:流式用 RNN-T/流式 Whisper,离线用大模型
5. 监控:记录 WER 抽样、RTF、失败率

热词偏置是中文 ASR 的刚需——人名、品牌名、专业术语模型常识别错,用 initial_prompt 或专门的热词机制注入:

# Whisper 用 initial_prompt 做热词偏置
ids = model.generate(
    inputs.input_features,
    initial_prompt="以下是关于 Plumephp 框架和 Kubernetes 的技术讨论。",
    language="zh",
)

一句话:ASR 评测看 WER/CER、TTS 看 MOS;工程落地一半的功夫在前后处理(VAD、标点、热词),模型只占另一半。


9. 总结

9.1 技术栈全景

特征层:波形 → 分帧 → 梅尔谱(MFCC)
识别层:CTC / RNN-T(流式)/ 注意力编码解码(精度)
合成层:声学模型 + 声码器(HiFi-GAN)/ 端到端 TTS
表征层:说话人嵌入(ECAPA-TDNN)+ 余弦相似度
工程层:VAD + 增强(SpecAugment)+ 后处理 + 量化

9.2 关键决策点

问题选择
实时字幕/语音输入RNN-T 或流式 Whisper
离线高精度转写Whisper large-v3
快速落地faster-whisper + VAD
定制音色 TTSXTTS / VITS 零样本克隆
声纹验证ECAPA-TDNN + EER 调阈值
噪声环境SpecAugment + 加噪增强 + 降噪前端

9.3 一句话心法

语音建模的核心是「对齐」与「表征」——ASR 解决音频帧与文本的变长对齐,说话人识别解决音色的定长表征,TTS 解决文本到声学的映射;三者共享同一套梅尔谱特征与序列建模工具。


延伸阅读

  • https://plumephp.com/ml-deep-learning-advanced/ — 序列建模、注意力与 Transformer
  • https://plumephp.com/ml-nlp-basics/ — 分词、语言模型与文本处理
  • https://plumephp.com/ml-transfer-learning/ — 预训练模型复用与领域微调
  • https://plumephp.com/ml-model-deployment/ — 模型量化、导出与服务化
  • AI/ML 专题 — 语音与序列建模深度文章
  • Whisper 官方仓库

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「ml」更多文章

  1. 联邦学习与隐私保护机器学习:FedAvg、非 IID、DP-SGD 与安全聚合
  2. 扩散模型与生成式建模:DDPM、U-Net、潜在扩散与 LoRA 微调实战
  3. 多模态视觉语言模型:CLIP、ViT 与 LLaVA 类 VLM 架构全解析