ASR 五代演进(五):Gen 4 · 以 Whisper 为代表的大规模弱监督

Gen 4 是五代里架构最朴素的一代 ------OpenAI 2022 年 9 月开源 Whisper(12 月在 arXiv 挂论文 2212.04356 · "Robust Speech Recognition via Large-Scale Weak Supervision" · https://arxiv.org/abs/2212.04356 · 代码 https://github.com/openai/whisper ),模型骨架就是标准 Transformer encoder-decoder :没有 Conformer 那种 Attention+Conv 融合、没有 SSL 预训练、没有花哨的 loss------就是 T5 那种 encoder-decoder + 交叉熵损失

T5 (Google 2019 · arXiv 1910.10683 · https://arxiv.org/abs/1910.10683 )------把所有 NLP 任务统一成"文本 → 文本",任务类型写在输入前缀里,例:translate English to German: That is good.Das ist gut.。Whisper 沿用了这个思路:只是把输入从文本换成音频、前缀 token 换成 <|transcribe|> <|zh|> 这类。

但 Whisper 上线之后迅速改变了 ASR 领域格局------同一模型覆盖 近百种语言 · 多任务(识别 + 翻译 + 时间戳 + 静音判定)· 明显抗噪 · 抗口音 · 抗远场 · 大量场景零样本可用Gen 3 时代 SSL 预训练 + 每域独立微调走几个月的 pipeline,Whisper 一个模型就打了一大片

Whisper 之所以能单独成一代,范式跃迁不在架构而在数据 : - Gen 3 SSL 时代 :1000-10000 小时精标数据微调(用有限的高质量 数据训得精) - Gen 4 Whisper68 万小时弱监督 数据一次训完(用海量的低质量数据训得广)

68 万小时是什么量级 ------粗略估算需要几百万人工小时才能精标出来。OpenAI 没走精标路线,而是从互联网抓已带字幕的音频、清洗后训 ------即论文标题里的 Large-Scale Weak Supervision(数据不完美但海量)。Gen 4 能干 Gen 3 干不了的事,就是这个组合的直接产物。

Gen 4 不只是 Whisper ------同期还有大规模 Conformer-CTC / RNN-T(流式场景更常见)· Google USM / Chirp · Meta MMS(wav2vec 2.0 + CTC · 覆盖 1100+ 语种)· NVIDIA Canary(FastConformer + Transformer decoder · Whisper-like seq2seq)。本篇挑 Whisper 讲,是因为它最集中地展示了 Gen 4 的范式跃迁:用大规模弱监督音频-文本对,把多语种识别、翻译、时间戳、静音判定统一进一个开源 encoder-decoder。

一、Gen 4 的三段接力

仍按前端 / 声学模型 / 解码器三段来看,Gen 4 的实现是:

Gen 4 实现
① 前端 80 mel(large-v3 为 128 mel)× 30 秒固定 chunk + 2 层 Conv1D(第二层 stride=2) 降采样到 T/2 (3000 → 1500 帧) · decoder 顺带吐 no-speech token 作静音判定(近似 VAD,不是独立前端模块)
② 声学模型 Transformer Encoder(4/6/12/24/32 层)· 编码 mel → hidden states
③ LM + 解码器 Transformer Decoder (对应对称层数)· LM 内嵌 decoder · 自回归生成 · prompt token 控制任务

Gen 4 的核心变化 ------三段全部融进一个 encoder-decoder 网络 (3 段 → 1 段)· 无需外挂 LM (decoder 自带一个大内嵌 LM)· 多任务通过 prompt token 切换(不用改架构)。

二、前端:log-mel + 30 秒固定 chunk

Whisper 没走 Gen 3 wav2vec 2.0 那种 raw waveform 路线,而是回到更传统的 log-mel spectrogram :16 kHz 音频先转成 80 维 mel、hop 10 ms(原始 Whisper / large-v2 口径;large-v3 改成 128 mel)· 30 秒音频对应约 3000 帧。随后经过 2 层 Conv1D、第二层 stride=2,把时间长度从 3000 降到 1500,再加位置编码送 Transformer Encoder:

复制代码
16 kHz audio
  ↓ log-mel · 80 mel(large-v3 为 128)· hop 10 ms
mel: (3000, 80)
  ↓ 2 层 Conv1D · 第二层 stride=2
frames: (1500, d_model)
  ↓ + positional embedding
Transformer Encoder

30 秒固定窗口 是 Whisper 前端最重要的工程约束------短音频 padding、长音频切成多个 30 秒 chunk 顺序处理。这样 encoder 输入长度固定,batch 和显存管理都更简单;代价是长音频的跨段上下文不会进入 encoder

Whisper 处理长音频时没有把 encoder 改成长上下文,而是把前一段转录文本作为下一段 decoder 的 prompt

复制代码
chunk_1 audio → encoder → decoder                → text_1
chunk_2 audio → encoder → decoder(prompt=text_1) → text_2
chunk_3 audio → encoder → decoder(prompt=text_2) → text_3

这个设计让专名、句式和话题更容易连续 ,但也会传播错误 ------前一段识别错了后面可能被 prompt 带偏,严重时会放大幻觉。所以长音频生产系统通常配合 VAD、overlap、重打时间戳、更严格的 no-speech 阈值兜底。

30 秒边界如果切在词中间怎么办 ------openai/whispertranscribe() 不做定长硬切,而用时间戳引导的 seek :decoder 除了吐文本 token 还吐时间戳 token(<|0.00|> <|2.10|> 之类),解码完毕后取最后一个可信 segment 的结束时间 作下一 chunk 起点。理想情况下 尾部半个词会落在最后一个时间戳之前,seek 就把边界拉回到较完整的位置;时间戳不可信时仍会退化 ,需要 no_speech_threshold 判静音、logprob_threshold 触发升温重试等 fallback 兜底,都失败才真硬切。faster-whisper / stable-ts / WhisperX 的 VAD-based 切片是另一路------先用 Silero VAD 找静音间隙,只在静音处切,从根本上避开半词问题。

VAD 不是独立前端 ------decoder 在解码初始阶段会给 <|nospeech|> token 分配一个概率,超阈值就视作当前 chunk 无有效语音。这更像"顺带学出来的静音判定",不是单独的前端 VAD 模块。

三、声学模型 + LM/解码器:Encoder-Decoder 合体

Whisper 的架构极其朴素 ------论文 Fig 1 已经把核心结构画得很清楚:左侧是 4 类训练样本、中间是标准 Transformer encoder-decoder、底部是多任务 token 序列。读这张图抓一条主线就行------log-mel 进 encoder,decoder 在 cross-attention 条件下自回归生成文本、时间戳、语种和 no-speech token。这张图的重点不是某个复杂模块,而是"所有 ASR 子任务都被压成同一种 token 生成问题":转录、翻译、时间戳、语种识别、静音判定,都只是 decoder 要预测的不同 token。

输入输出契约------两个模块各接收啥、输出啥、干啥:

模块 输入 输出 作用
Encoder 30 秒音频提取的 log-mel (80/128, 3000)(原始 Whisper / large-v2 为 80 mel · large-v3 为 128 mel)· 2 层 Conv 后变为约 (1500, d_model) 声学 hidden states (1500, d_model) 把"这 30 秒听到了什么"编码成连续表征
Decoder 任务 prompt tokens + 已生成文本 tokens + encoder hidden states(cross-attn 接入) 下一个 token 的概率分布 自回归产生转录 / 翻译 / 时间戳 / no-speech 判断

注意 decoder 不是纯文本 LM ------它通过 cross-attention 条件化在 encoder 的音频表征上,本质是一个带声学条件的自回归文本/时间戳生成器。工程语境里图省事说"内嵌 LM"是可以的,但严格地说,它比一个只接收文本的 LM 多了一路"看着音频写字"的能力。

一个中文转录任务的 decoder 起始 prompt 长这样:<|startoftranscript|><|zh|><|transcribe|><|notimestamps|>,之后逐 token 吐字。<|transcribe|> 换成 <|translate|> 就变成翻译到英文------模型结构不变,输出从"中文语音 → 中文文本"变成"中文语音 → 英文文本"。

5 个官方发布 size 沿用类似 T5 的命名(tiny / base / small / medium / large)

模型 参数量 层数(Enc+Dec) d_model 显存(FP16 推理)
tiny 39M 4+4 384 ~1 GB
base 74M 6+6 512 ~1 GB
small 244M 12+12 768 ~2 GB
medium 769M 24+24 1024 ~5 GB
large-v1 / v2 / v3 1.55B 32+32 1280 ~10 GB

:OpenAI 在 large-v3 之后又放出 Whisper-Turbolarge-v3-turbo)------decoder 从 32 层砍到 4 层,推理明显更快,多语种转录质量接近 large-v3;不视作原 5 size 家族的第 6 个,属于官方优化 / 剪枝版注意 turbo 未针对翻译任务训练,非英语语音翻译到英语场景仍应回退到 multilingual tiny/base/small/medium/large。

训练目标也很直接 ------给定音频和任务 token,用 teacher forcing 让 decoder 预测目标 token 序列,loss 就是标准 cross-entropy。没有 CTC 辅助目标、没有额外的 SSL 预训练阶段------纯 Transformer + 交叉熵训。

任务表达全靠 prompt tokens------识别、翻译、时间戳、语种指定,全部编码进 decoder 起始的 prompt token 序列。

四、68 万小时数据是怎么弄来的

Whisper 论文里 Section 2 花了整整两页讲数据处理 pipeline ,这在 ASR 论文里非常罕见(大家通常把数据当作理所当然)。OpenAI 显然认为数据构建比架构更重要------事实证明说对了。

4.1 数据来源:互联网 audio-text 对

三类有语音训练数据合计约 68 万小时(另有 no-speech 负例任务作为 VAD 训练信号):

数据类型 时长 (约) 语种覆盖 特点
英文 audio + 英文转录(含时间戳) 438,000 h 只英文 干净标注、覆盖各种场景
多语种 audio + 同语种转录 117,000 h 96 种非英语 每种数百至数千小时不等
X → English audio + 英文转录(语音翻译) 125,000 h 96 种非英语 用于训练语音翻译 (X → English translation)
三类小计 ~680,000 h 英文 + 96 种非英语(近百种语言) 论文 Fig 1 还包含 no-speech 负例任务(无语音音频 + 空转录),不计入音频总时长

具体数据来源 OpenAI 论文只说"互联网上带字幕的音频",没细说是哪家平台。业界普遍猜测 YouTube 机器/人工字幕占大头、可能配合早期 Whisper 自蒸馏(用早期 Whisper 打伪标签)------但这些是外部推断,不是官方披露。

4.2 数据清洗:三道过滤

原始互联网带字幕音频质量极不稳定------机器字幕可能错、人工字幕可能不对齐、说话人可能沉默几秒、字幕文件格式各异。Whisper 用三类过滤组合清洗:

过滤 做法 意图
① 剔除机器 ASR 字幕 启发式规则识别机器生成的转录并剔除 避免"教模型学一个更差 ASR 的错误"累积
② 音频-文本对齐验证 用一个初步 ASR 模型跑一遍音频、跟字幕算差异、超阈值扔掉 保证音频和文本真的对上
③ 语言检测 用语言分类器判语种、跟字幕标注不匹配就扔掉 语种一致性

清洗过后留下 68 万小时 ------说明原始互联网字幕数据噪声很高 ,需要多层过滤才能得到可训数据;原始规模和完整清洗规则 OpenAI 均未公开,这也是复现 Whisper 数据侧最难的部分(模型代码开源了,数据构建流程没有)。

4.3 反直觉观察:数据规模压过精度

Gen 3 SSL 时代大家追的都是"用 量数据获得 效果"------10 分钟标注 4.8% WER 是学术金牌。Whisper 团队反其道而行 ------用海量低质量数据换全面性

Gen 3 Gen 4
数据哲学 质量优于数量 数量优于质量
代表 wav2vec 2.0 10 min 微调 Whisper 68w h 弱监督
LibriSpeech 表现 w2v-BERT 1.4% test-clean(同论文自报,用外部 LM) Whisper-large-v3 约 1.8% test-clean(zero-shot,无外部 LM)
跨域鲁棒性 每域独立微调 一模型覆盖近百语种 + 明显抗噪 + 明显抗口音

上表 LibriSpeech 数字来自各自论文,训练 / 解码设置不同(有无外部 LM · 是否 zero-shot · 是否用到 test-other 数据),只作方向性对比,不宜直接横比。

Gen 3 教会 ASR 领域"预训练管用",Gen 4 Whisper 教会 ASR 领域"数据规模比架构讲究更重要"------这个 lesson 后来延续到 Gen 5 Audio LLM(继续扩大数据规模)。

五、多任务 prompt token:同一个模型怎么切任务

Whisper 没有为"转录 / 翻译 / 时间戳 / 语种识别"分别训练不同模型------它的做法是把任务说明写进 decoder 的起始 token ,像一个"遥控器":<|startoftranscript|><|zh|><|transcribe|><|notimestamps|> 分别对应"开始 · 语种=中文 · 任务=转录 · 不输出时间戳"。

同一段中文音频、同一份权重,只换起始 prompt 里的关键 token,输出就跟着变:

起始 prompt 关键 token 期望输出(示意)
<|zh|><|transcribe|><|notimestamps|> 中文纯文本:"今天我们测试 Whisper。"
<|zh|><|transcribe|> 中文 + 时间戳:"<|0.00|> 今天我们测试 Whisper。<|2.10|>"
<|zh|><|translate|><|notimestamps|> 翻译到英文:"Today we are testing Whisper."
<|startoftranscript|>(不指定语种) 先吐语种 token,再继续:"<|zh|> 今天我们测试 Whisper。"

训练时把所有任务统一成同一种 token 序列 ------[任务 token] + [文本 token / 时间戳 token / no-speech token]。decoder 学到的是:看到 <|transcribe|> 输出同语种文本 · 看到 <|translate|> 输出英文 · 看到 <|notimestamps|> 就不插时间戳。

"翻译"任务只训过 X → English ------弱监督数据里主要能找到"其他语种音频 + 英文字幕",反过来极少。官方翻译任务训练目标就是 X → English translation,不应把 Whisper 当作任意目标语种的语音翻译模型(OpenAI README 也是这么描述 translate 任务的)。

六、Whisper 生态:三种常用调用方式

Whisper 是影响力最大的开源 ASR 项目之一,围绕它长起来的生态大致按四个方向分(跟下图 2×2 象限对应):

  • 推理加速 / 生产faster-whisper(CTranslate2 · int8 量化 · GPU)、Distil-Whisper(保留 encoder 深度、把 decoder 从 32 层砍到 2 层 · 配合 KL 蒸馏 + pseudo-label · arXiv 2311.00430 · https://arxiv.org/abs/2311.00430 )、Whisper-Turbo(官方轻量化 large-v3 · 见上节 caveat)· Distil-Whisper 的经验 是优先保留 encoder、压缩 decoder;在它的评测设置里这是速度/精度折中较好的方向,不宜推广成所有 ASR seq2seq 都成立
  • 端侧 / CPUwhisper.cpp(C++ · int8/4-bit 量化 · 小 size 压到几十到一百多 MB · 手机 / 树莓派 CPU 跑,延迟强依赖机型和量化格式)
  • 时间戳 / 字幕对齐WhisperX(+ wav2vec 2.0 forced alignment · 词级时间戳)· whisper-timestamped · stable-ts(长音频 + VAD + 分段)
  • 微调 / 集成HF transformers(pipeline · 微调 · ONNX 导出)· Belle-whisper(中文微调探索)

下面不是严谨 benchmark ,只是在同一段 demo 上把三种常见调用方式的行为差异 过一遍------环境是 4090 D、单条 9.74 秒中英混合音频(Kokoro TTS 合成 · "Hello World, 欢迎收听 ASR 五代演进 25 年 · WER 从 13% 降到 1.5% · Thanks")、batch=1、模型已下载、language auto-detect、beam=5。加载时间受缓存 / 磁盘 / 框架初始化影响,只作参考 ,核心看接口差异和输出差异。端侧 whisper.cpp 是纯 CPU 场景,跟这里的 4090 GPU 数据不同代,不参与本节对比。

6.1 openai/whisper · 官方基线

复制代码
import whisper
model = whisper.load_model("large-v3", device="cuda")
r = model.transcribe(
    "demo_mixed.wav",
    language=None, beam_size=5, fp16=True,
    condition_on_previous_text=False, no_speech_threshold=0.6,
)
print(r["text"])

实测:加载 8.9 s · 推理 0.76 s · RTF 0.078 · 语种自动检测 = zh

复制代码
Hello World,欢迎收听ASR五代演进25年,WER从13%降到1.5%Thanks

这段样本上中英全对、无幻觉。作为官方参考实现,速度不是最快,行为最接近论文 / 官方默认路径,输出可作为基线。

6.2 faster-whisper · CTranslate2 + int8 量化

复制代码
from faster_whisper import WhisperModel
model = WhisperModel("large-v3", device="cuda", compute_type="int8_float16")
segments, info = model.transcribe(
    "demo_mixed.wav",
    language=None, beam_size=5,
    condition_on_previous_text=False, no_speech_threshold=0.6,
)
print(" ".join(s.text.strip() for s in segments))

实测:加载 35.3 s · 推理 0.37 s · RTF 0.038 · 相对官方约快 2× · 语种概率 0.989

复制代码
Hello World,欢迎收听ASR五代演进 25年,WER从13%降到1.5% Thanks

与官方逐字一致 (仅多两处空格)· int8_float16 在这个 demo 上未影响文本;batch=1 短音频跑不满,公开 benchmark 上 batch 更大或长音频加速比通常会更接近 4×。

6.3 Distil-Whisper · 蒸馏版(这次翻车)

复制代码
from transformers import pipeline
import torch
pipe = pipeline(
    "automatic-speech-recognition",
    model="distil-whisper/distil-large-v3",
    torch_dtype=torch.float16, device="cuda",
)
r = pipe(
    "demo_mixed.wav",
    generate_kwargs={"language": None, "task": "transcribe"},
    chunk_length_s=30, batch_size=1,
)
print(r["text"])

实测:加载 30.6 s · 推理 0.12 s · RTF 0.012 · 相对官方快 6.5×

复制代码
Hello World!

这段样本上中文部分整段丢失 · 只识别到英文开头就停了。可能原因包括 :Distil-Whisper 的训练和蒸馏更偏英文长语音 · HF pipeline 的 chunked long-form 处理与原生 generate 路径不同 · 自动语种/任务提示在中英混合短音频上不够稳。这一个样本不能证明"Distil-Whisper 不能用" ,但说明中文 / 中英混合场景不能盲用蒸馏版,至少要拿自己数据回归

6.4 本机单样本汇总

Backend dtype 推理 (s) RTF 中英识别
openai/whisper large-v3 fp16 0.76 0.078 全对
faster-whisper large-v3 int8_float16 0.37 0.038 全对
distil-large-v3(HF pipeline) fp16 0.12 0.012 只英文,中文丢

这些数字不是跨硬件、跨语料的性能结论------只说明在这条 9.74 秒 demo 上,三种调用方式的速度、输出和风险点不同。

三个观察

  1. faster-whisper 提速约 2×、输出与官方逐字一致 ------这段样本上文本基本无损;生产化还要看语料、batch、量化设置和延迟目标。4090 D 上 batch=1 只到 2×,长音频 / 大 batch 时会更接近 4×。

  2. Distil-Whisper 快归快、但要挑场景------RTF 0.012 领先,但英文以外场景不能默认走。要在中文 / 混合语种上蒸馏,需要用中文数据重训 student。

  3. 相比 Gen 3 单语基线 ------同一段音频交给英文 wav2vec 2.0 baseline 时中文完全识别不出、交给 XLSR-zh 时英文识别不出;Whisper large-v3 一份权重就覆盖两语种。不是精度上打赢,而是范式上跨过了"每语种单独部署一套"的门槛

工程口径 ------生产里用 faster-whisper 时常见配置是 large-v3 / int8_float16 / beam_size=5,长音频再打开 vad_filter=Truecondition_on_previous_text 按任务是否需要跨段上下文调开或关。真正在做取舍的是三件事:速度、幻觉控制、长音频切分------不是 API 有多复杂。

七、Whisper 的短板

幻觉是结构性风险 ------自回归 decoder + 弱监督字幕噪声 + 长音频切段策略共同放大:自回归生成在低置信、静音或字幕噪声场景下仍可能被语言模型先验带着继续生成 (尽管 decoder 可以选择输出 no-speech / EOT,但训练分布里学到的"说话模式"会拉着它继续吐字);训练字幕不总是精确对齐音频,模型学到"某些场景没声音也该输出这些 token"。常见幻觉如 Thanks for watching! · 请订阅点赞 · [Music] · 字幕由 XXX 提供------来自网络字幕/片尾模板类样本的污染缓解不了根本 ,只能用 VAD 预筛 + no_speech_threshold=0.6 + 长音频 chunk 逻辑严格化。

无法流式 ------默认推理按 30 秒窗口做离线 / 分段处理,不是原生低延迟流式架构 。想改流式只能:等 5 秒音频到位再送 encoder(首字延迟 5 秒)· 或社区扩展 streaming Whisper(小 chunk 0.5 秒递进 attention · 牺牲精度换低延迟)。在线低延迟 ASR 场景仍常见 RNN-T(Gen 2)或 Conformer-Transducer(Gen 3) ,Whisper 主要用于离线转录(字幕、会议纪要、播客处理)。

每域精度参差

场景 Whisper 表现
医疗、法律 精度不如领域 fine-tune 版
中文 社区反馈中常见的说法是 large-v3 中文效果不如 large-v2 稳定 · 具体因 corpus 而异
方言 粤语、闽南语等中国方言精度差(训练数据少)
儿童 / 老人 / 病理嗓音 训练数据里少见的说话人类型精度差

Whisper 是"通用 baseline",不是"每场景 SOTA"。工业系统仍要针对特定场景微调,或换 Gen 3 SSL + 微调路线。

八、Gen 4 贡献 + 留给 Gen 5 的坑

Gen 4 三大贡献:数据规模能压过架构讲究(朴素 Transformer + 68 万小时弱监督 · 精度和鲁棒性跟 Conformer + SSL + 微调路线可比)· 一份权重覆盖近百语种(从"每语种独立训练"走向"一模型多语种共享")· 完整开源生态。

留给 Gen 5 的三个坑

  • 只做转录------不理解语义、不识别说话人、不保留情绪、不能跟随指令("只转录女声"、"翻译成英文并归纳三点"这类)。Whisper 是纯转录工具,不是语音理解系统。
  • 幻觉是结构性风险------自回归 decoder + 弱监督字幕噪声 + 长音频切段策略共同放大。缓解需要更强的 grounding、更严格的 no-speech 约束、更好的分段策略,或换成理解式建模------Gen 5 Audio LLM 只是其中一种可能路径。
  • 复杂声学场景弱------多说话人对话、噪声、远场麦克风阵列下能转出部分内容,但说话人区分、重叠语音处理、空间信息利用都不行。

Gen 5 Audio LLM 的核心跃迁 ------把 ASR 从"独立转录任务"抬升到"通用语音理解任务":Seed-ASR · Qwen2-Audio · GPT-4o 语音端------不是转录得更准,而是把转录 + 说话人 + 情绪 + 翻译 + 摘要 + 指令跟随打包进一个通用模型

相关推荐
Generalzy6 天前
Whisper + VAD + TTS:一套完整的 Python 本地语音处理流水线
python·whisper·语音识别
shxjnpl7 天前
Whisper + CAM++ + 本地大模型:一套完全离线的AI会议处理链路
人工智能·机器学习·whisper
shxjnpl7 天前
Whisper large-v3 本地部署实战:从语音转写到AI会议纪要完整链路
人工智能·whisper·语音识别
程序猿编码7 天前
不用PyTorch,不用CUDA,我用C++手写了一个能跑GPT和Whisper的推理库
c++·pytorch·gpt·大模型·whisper
今夕资源网20 天前
今夕语音中枢一键整合包:本地 LuxTTS 发声 + Whisper 听觉 + AIRI一键接入听觉和发声模块
whisper·ai伴侣·airi·ai女友·ai宠物
大鱼>25 天前
Whisper+GPT-SoVITS:语音识别到音色克隆的全链路实战
gpt·whisper·语音识别
维基框架1 个月前
Apple的SpeechAnalyzer API实测:系统级语音识别与Whisper的差距在哪里
人工智能·whisper·语音识别·xcode
向阳是我1 个月前
在 Mac(M2)上用 faster-whisper 实现高精度中文语音转文字
python·macos·ai·whisper·语音识别
localbob2 个月前
日语视频 SRT 字幕生成软件下载:日语视频本地自动翻译SRT字幕生成、日语视频自动翻译 Faster Whisper v1.7 下载与使用教程(含AMD显卡支持)
whisper·音视频·机器翻译·日语字幕翻译·日语视频翻译·本地ai翻译日语视频