语音识别 ASR:CTC、RNN-T 与注意力


文档摘要

语音识别 ASR:CTC、RNN-T 与注意力 本节摘要:语音识别(Speech Recognition, ASR)本质上是「每个时间步做一次音频分类,再用一个懂语言和静音的序列模型把结果粘起来」。CTC、RNN-T 和注意力机制是三种主流做法,选一种并理解为什么。本节的真正难点是结构性的:音频帧与字符并非一一对应——「okay」可能占 200 毫秒也可能占 1200 毫秒,静音穿插其间,音素长短不一,输出 token 数量事先未知。CTC 引入 blank 牌做帧级对齐的非自回归方案;RNN-T 加一个预测器显式建模 token 历史的依赖,天然可流式;注意力编码器-解码器(Whisper、SeamlessM4T)用交叉注意力打破对齐约束,离线质量最高。

语音识别 ASR:CTC、RNN-T 与注意力

本节摘要:语音识别(Speech Recognition, ASR)本质上是「每个时间步做一次音频分类,再用一个懂语言和静音的序列模型把结果粘起来」。CTC、RNN-T 和注意力机制是三种主流做法,选一种并理解为什么。本节的真正难点是结构性的:音频帧与字符并非一一对应——「okay」可能占 200 毫秒也可能占 1200 毫秒,静音穿插其间,音素长短不一,输出 token 数量事先未知。CTC 引入 blank 牌做帧级对齐的非自回归方案;RNN-T 加一个预测器显式建模 token 历史的依赖,天然可流式;注意力编码器-解码器(Whisper、SeamlessM4T)用交叉注意力打破对齐约束,离线质量最高。2026 年 LibriSpeech test-clean 的 SOTA WER 已到 1.4%(Parakeet-TDT-1.1B),数字差异微小,部署差异巨大。读完本节,你能为不同部署目标选对 ASR 范式,手写 CTC 贪心解码与 WER 计算,并避开 VAD 缺失、语种漂移、长音频不切块等生产坑。

学习目标

阅读完本节,你应当能够:

  1. 解释音频帧与输出 token 不对齐这一结构性挑战,说明它为什么要求专门的对齐机制。
  2. 对比 CTC、RNN-T、注意力编码器-解码器 三大范式的直觉、优势、劣势与适用场景。
  3. 手写 CTC 贪心解码(合并连续重复、丢 blank)与 WER 计算(词级编辑距离)。
  4. 理解 CTC 条件独立性假设 的局限,以及外部语言模型融合(beam search + shallow fusion)为何能补救。
  5. 为给定部署目标(离线高精度、流式低延迟、边缘、长音频)选择正确的 2026 年模型与解码策略。

一、问题与直觉

你有一段 10 秒 16 kHz 音频,想要一个字符串:「turn on the kitchen lights」。难点是结构性的:音频帧与字符并不一一对应。「okay」可能占 200 毫秒,也可能占 1200 毫秒;静音把话语切成段;不同音素长度不一;输出 token 数量事先未知。

三种范式解决它:

  1. CTC(连接时序分类):逐帧输出 token 概率(含特殊 blank),解码时合并重复、丢 blank。非自回归、快。wav2vec 2.0、MMS 在用。
  2. RNN-T(循环神经网络转换器):联合网络根据编码器帧和已有 token 预测下一 token。可流式。Google 端上 ASR、NVIDIA Parakeet 在用。
  3. 注意力编码器-解码器:编码器把音频压成隐状态,解码器交叉注意力、自回归生成 token。Whisper、SeamlessM4T 在用。

2026 年 LibriSpeech test-clean 的 SOTA WER 是 1.4%(Parakeet-TDT-1.1B)和 1.58%(Whisper-Large-v3-turbo)。数字差异微小,部署差异巨大。

CTC 直觉:blank 是关键

让编码器对每帧输出 V+1 个 token 上的分布(V 个字符 + blank)。对于长度 U < T 的目标串 y,任何能塌缩成 y 的帧对齐都算数。CTC 损失对所有这样的对齐求和。解码:逐帧 argmax,合并重复,丢 blank。

优势:非自回归、可流式、零前瞻。缺点:条件独立性假设——每帧预测互相独立,没有内部语言模型。补救:用外部 LM 做 beam search 或浅融合。

RNN-T 直觉:显式建模 token 历史

加一个 预测器 网络嵌入 token 历史,加一个 联合器 把预测器状态与编码器帧组合成 V+1 上的联合分布(+1 是 null / 不发射)。显式建模了 CTC 忽略的条件依赖。因为每步只依赖过去的帧与过去的 token,所以可流式。

优势:可流式 + 内置语言模型。缺点:训练更复杂、更吃内存(三维损失格);RNN-T 损失内核本身就是一整个库类别。

注意力编码器-解码器:打破对齐约束

编码器(632 层 Transformer)在对数梅尔帧上跑,解码器(632 层)交叉注意力到编码器输出,自回归生成 token。无对齐约束——注意力可以看音频任何位置。除非限制注意力(2024 年的 chunked Whisper-Streaming),否则不可流式。

优势:离线 ASR 质量最高,标准 seq2seq 工具链易训练。缺点:自回归延迟正比于输出长度;不工程化就无法流式。

💡 三者的本质区别在对齐与依赖:CTC 强对齐、无依赖(条件独立);RNN-T 强对齐、有依赖(可流式);注意力 无对齐、有依赖(全局上下文,但不可流式)。没有银弹,选择取决于「能不能等」与「延迟预算」。

WER:唯一的那个数字

词错率(Word Error Rate) = (S + D + I) / N,其中 S 是替换、D 是删除、I 是插入、N 是参考词数。等价于词级 Levenshtein 编辑距离。越低越好。WER 高于 20% 一般不可用;低于 5% 对朗读语音达到人类水平。2026 年标准基准:

模型 LibriSpeech test-clean LibriSpeech test-other 规模
Parakeet-TDT-1.1B 1.40% 2.78% 1.1B
Whisper-Large-v3-turbo 1.58% 3.03% 809M
Canary-1B Flash 1.48% 2.87% 1B
Seamless M4T v2 1.7% 3.5% 2.3B

这些都是编码器-解码器或 RNN-T。纯 CTC 系统(wav2vec 2.0)在 test-clean 约 1.8~2.1%。

二、从零实现

第 1 步:CTC 贪心解码

def ctc_greedy(frame_logits, blank=0, vocab=None): # frame_logits: 每帧的概率向量列表 preds = [max(range(len(p)), key=lambda i: p[i]) for p in frame_logits] out = [] prev = -1 for p in preds: if p != prev and p != blank: out.append(p) prev = p return "".join(vocab[i] for i in out) if vocab else out

两条规则:合并连续重复、丢 blank。例子:a a _ _ a b b _ ca a b c

设计要点:CTC 解码的两步看似平凡,却暗藏玄机——「合并重复」只在相邻同类时发生,中间若插了 blank,前后两个相同 token 就保留(如 a _ aaa)。这正是 blank 的作用:它允许模型用 blank 把同一个字母的两次连续出现表达成两个独立字母。

def ctc_beam(frame_logits, beam=8, blank=0): import math beams = [([], 0.0)] # (tokens, log_prob) for p in frame_logits: log_p = [math.log(max(pi, 1e-10)) for pi in p] candidates = [] for seq, lp in beams: for t, lpt in enumerate(log_p): new = seq[:] if t == blank else (seq + [t] if not seq or seq[-1] != t else seq) candidates.append((new, lp + lpt)) candidates.sort(key=lambda x: -x[1]) beams = candidates[:beam] return beams[0][0]

生产代码用带 LM 融合的前缀树 beam search;这里只是概念骨架。

第 3 步:WER

def wer(ref, hyp): r, h = ref.split(), hyp.split() dp = [[0] * (len(h) + 1) for _ in range(len(r) + 1)] for i in range(len(r) + 1): dp[i][0] = i for j in range(len(h) + 1): dp[0][j] = j for i in range(1, len(r) + 1): for j in range(1, len(h) + 1): cost = 0 if r[i - 1] == h[j - 1] else 1 dp[i][j] = min( dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost, ) return dp[len(r)][len(h)] / max(1, len(r))

第 4 步:用 Whisper 推理

import whisper model = whisper.load_model("large-v3-turbo") result = model.transcribe("clip.wav") print(result["text"])

一行调用即得 2026 年最强通用 ASR,24 GB GPU 上约 20 倍实时。

第 5 步:用 Parakeet 或 wav2vec 2.0 流式

from transformers import pipeline asr = pipeline("automatic-speech-recognition", model="nvidia/parakeet-tdt-1.1b") for chunk in streaming_audio(): print(asr(chunk, return_timestamps=True))

流式 ASR 需要分块编码器注意力和状态延续;用支持它的库(NeMo for Parakeet,带 chunk_length_s 的 transformers pipeline)。

三、框架对比

2026 年工具栈:

场景
英语、离线、最高质量 Whisper-large-v3-turbo
多语种、鲁棒 SeamlessM4T v2
流式、低延迟 Parakeet-TDT-1.1B 或 Riva
边缘、移动、<500 ms 延迟 Whisper-Tiny 量化,或 Moonshine(2024)
长音频 Whisper + 基于 VAD 的切块(WhisperX)
垂直领域(医疗、法律) 微调 wav2vec 2.0 + 领域 LM 融合

⚠️ 四类仍在上线的坑:① 无 VAD——对静音跑 Whisper 会产生幻觉(「Thanks for watching!」),始终用 VAD 把关;② 字符 vs 词 vs 子词 WER——汇报前要先归一化(小写、去标点)再做词级 WER;③ 语种识别漂移——Whisper 自动 LID 会把嘈杂片段误判成日语或威尔士语,确定语种时强制 language="en";④ 长音频不切块——Whisper 窗口是 30 秒,任何更长内容都要 chunk_length_s=30, stride=5

四、可复用产物

本节产出技能文档(原课程 outputs/skill-asr-picker.md),针对给定部署目标选择模型、解码策略、切块方式、LM 融合。决策树:

  • 能离线 + 要质量 → Whisper-large-v3-turbo + VAD 切块。
  • 必须流式 → Parakeet-TDT-1.1B(RNN-T,延迟可控)。
  • 多语种 → SeamlessM4T v2 或 Whisper-large。
  • 边缘 → Whisper-Tiny int8 量化,或 Moonshine。
  • 垂直领域 → wav2vec 2.0 微调 + 领域 n-gram LM 浅融合。

五、练习

  1. 基础:运行 code/main.py。它对一组手工构造的 CTC 输出做贪心解码,并对参考串算 WER。

  2. 进阶:正确实现第 2 步的前缀树 beam search(处理 blank 合并规则),在 10 条合成数据上与贪心解码对比。

  3. 挑战:用 whisper-large-v3-turbo 跑 LibriSpeech test-clean,对前 100 条算 WER,与公开数字对比。强制 language="en" 与自动 LID 对比,看漂移出现在哪里。

本节要点回顾

  1. ASR 的结构性难点:音频帧与字符不对齐,输出长度未知,静音穿插,音素长短不一。
  2. CTC:blank 牌 + 帧级对齐 + 边缘求和,非自回归、快、可流式,但条件独立无内部 LM。
  3. RNN-T:加预测器与联合器,显式建模 token 依赖,可流式 + 内置 LM,但训练复杂、吃内存。
  4. 注意力编码器-解码器:交叉注意力打破对齐约束,离线质量最高,但不可流式。
  5. WER = (S+D+I)/N,词级编辑距离,汇报前必须归一化;>20% 不可用,<5% 接近人类水平。
  6. 2026 SOTA:Parakeet-TDT-1.1B 在 LibriSpeech test-clean 上 WER 1.4%,Whisper-Large-v3-turbo 1.58%。
  7. CTC 解码两规则:合并连续重复、丢 blank;blank 还允许把同一字母的两次连续表达成两个独立字母。
  8. 四类生产坑:无 VAD 致幻觉、未归一化 WER、语种漂移、长音频不切块(Whisper 30 秒窗口)。

下一节,我们深入 2026 年最具统治力的 ASR 模型——Whisper,拆解它的编码器-解码器架构、多任务训练数据,以及如何在你自己的领域上微调。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U