音频 Transformer 与 Whisper


文档摘要

音频 Transformer 与 Whisper 本节摘要:音频是一张「频率随时间变化」的图,Whisper 就是一个吃 mel 频谱图、再开口说话的 ViT。在 Whisper(OpenAI,Radford 等 2022)之前,最先进的自动语音识别(ASR)是 wav2vec 2.0 和 HuBERT——自监督特征提取器加微调头,质量高但数据管线昂贵、对领域脆弱,多语种还得按语系各训一个模型。

音频 Transformer 与 Whisper

本节摘要:音频是一张「频率随时间变化」的图,Whisper 就是一个吃 mel 频谱图、再开口说话的 ViT。在 Whisper(OpenAI,Radford 等 2022)之前,最先进的自动语音识别(ASR)是 wav2vec 2.0 和 HuBERT——自监督特征提取器加微调头,质量高但数据管线昂贵、对领域脆弱,多语种还得按语系各训一个模型。Whisper 下了三个赌注:① 用一切数据训练(从互联网抓的 68 万小时弱标注音频,横跨 97 种语言,不要干净的学术语料、不要音素标签);② 多任务单模型(一个解码器联合做转录、翻译、语音活动检测、语言识别、时间戳,靠 task token 切换);③ 标准 encoder-decoder Transformer(编码器吃 log-mel 频谱图,解码器自回归出文本 token,无 vocoder、无 CTC、无 HMM)。结果是:Whisper large-v3 在口音、噪声、零干净标注数据的语言上都鲁棒,是 2026 年每个开源语音助手和大多数商业产品的事实标准语音前端。本节带你搭 log-mel 频谱图管线 + task-token 提示构造器(生产里你真正会碰的那两部分),看清「音频→token」只需频谱图加卷积 stem,以及 large-v3-turbo 怎么把解码器从 32 层砍到 4 层、实现 8 倍加速。

学习目标

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

  1. 说清音频如何被转成「频谱图图像」(log-mel,80 mel 频带 × 约 3000 帧),从而用 ViT 思路处理。
  2. 描述 Whisper 的六步流水线:重采样定窗、Conv1D stem、编码器、解码器、task token、beam search 输出。
  3. 解释 task token 前缀(<|startoftranscript|> <|en|> <|transcribe|>)如何用一个 4 token 前缀控制任务——这是语音版的 instruction tuning。
  4. 区分 Whisper 各尺寸(Tiny~Large-v3)的参数/层数/显存,以及 large-v3-turbo 为何是 2026 年实时语音代理的默认(解码器砍到 4 层,8 倍加速)。
  5. 列出 Whisper 不做的事(说话人分离、原生流式、>30s 长上下文)及其生产对策(pyannote、faster-whisper+VAD、分块)。

一、问题与直觉

Whisper 的核心洞见:音频就是一张频率随时间变化的二维图,所以「图→token」的 ViT 思路完全适用——只不过这里的「图」是 mel 频谱图。

Step 1——重采样 + 定窗

音频 16 kHz,裁剪/填充到 30 秒。算 log-mel 频谱图:80 个 mel 频带,10 ms 步长 → 约 3000 帧 × 80 特征。这就是 Whisper 看到的「输入图像」。

Step 2——卷积 stem

两个 Conv1D(kernel 3、stride 2)把 3000 帧降到 1500。不增加多少参数就 halves 序列长度。

Step 3——编码器

large 是 24 层 Transformer 编码器,处理 1500 个时间步。正弦位置编码、自注意力、GELU FFN,产出 1500 × 1280 隐状态。

Step 4——解码器

24 层 Transformer 解码器,从一个 BPE 词表(GPT-2 词表的超集,加几个音频专用特殊 token)自回归产生 token。

Step 5——task token

解码器提示以控制 token 开头,告诉模型做什么:

<|startoftranscript|> <|en|> <|transcribe|> <|0.00|> # 英文转录 <|startoftranscript|> <|fr|> <|translate|> <|0.00|> # 法语翻译成英文

模型在这个约定上训练,你用前缀控制任务。这是 2026 年 instruction-tuning 的等价物,但用在语音上。

Step 6——输出

beam search(width 5)+ 对数概率阈值。无 <|notimestamps|> token 时,每 0.02 秒预测一个时间戳。

Whisper 尺寸

模型 参数 层数 d_model 头数 显存(fp16)
Tiny 3900 万 4 384 6 约 1 GB
Base 7400 万 6 512 8 约 1 GB
Small 2.44 亿 12 768 12 约 2 GB
Medium 7.69 亿 24 1024 16 约 5 GB
Large 15.5 亿 32 1280 20 约 10 GB
Large-v3 15.5 亿 32 1280 20 约 10 GB
Large-v3-turbo 8.09 亿 32 1280 20 约 6 GB(4 层解码器)

Large-v3-turbo(2024)把解码器从 32 层砍到 4 层,解码快 8 倍、WER 退化不到 1 点。这个解码速度解锁,就是 Whisper-turbo 成为 2026 年实时语音代理默认的原因。

Whisper 不做的事

  • 不做说话人分离(谁在说)——配 pyannote。
  • 原生不支持实时流式——30 秒窗口是固定的。现代包装器(faster-whisperWhisperX)靠 VAD + 重叠块外挂流式。
  • 没有 >30s 的长上下文(不外部分块的话)。实践中够用,因为人类语音转录很少需要长程上下文。

2026 年全景

任务 模型 备注
英文 ASR Whisper-turbo、Moonshine Moonshine 在边缘上快 4 倍
多语种 ASR Whisper-large-v3 97 种语言
流式 ASR faster-whisper + VAD 可达 150 ms 延迟
TTS Piper、XTTS-v2、Kokoro encoder-decoder 模式,但 Whisper 形状
音频 + 语言 AudioLM、SeamlessM4T 文本 token + 音频 token 在一个 Transformer 里

💡 为什么不用 CTC:经典 ASR 用 CTC(Connectionist Temporal Classification)做无对齐训练,需要专门的损失和对齐处理。Whisper 直接用 encoder-decoder + 自回归文本生成,把 ASR 变成「序列到序列翻译」问题——更简单、更强、更通用。

二、从零实现

完整代码见原课程 phases/07-transformers-deep-dive/10-audio-transformers-whisper/code/main.py。我们不训 Whisper——而是搭 log-mel 频谱图管线 + task-token 提示构造器,这是生产里你真正会碰的两部分。

Step 1:合成音频

生成 1 秒、440 Hz、16 kHz 采样的正弦波,16000 个样本。

Step 2:log-mel 频谱图(简化版)

完整 mel 频谱图需要 FFT。我们做一个简化的分帧 + 逐帧能量版本,展示管线而无需 librosa:

def frame_signal(x, frame_size=400, hop=160): frames = [] for start in range(0, len(x) - frame_size + 1, hop): frames.append(x[start:start + frame_size]) return frames

帧 = 25 ms、hop = 10 ms,匹配 Whisper 的窗口化。逐帧能量在教学上代替 mel 频带。

Step 3:填充到 30 秒

Whisper 总是处理 30 秒块。把频谱图填充(或裁剪)到 3000 帧。

Step 4:构造提示 token

def whisper_prompt(lang="en", task="transcribe", timestamps=True): tokens = ["<|startoftranscript|>", f"<|{lang}|>", f"<|{task}|>"] if not timestamps: tokens.append("<|notimestamps|>") return tokens

这就是整个任务控制面——一个 4 token 前缀。

设计要点:Conv1D stem 用 stride 2 把序列减半,是 Whisper 的关键工程决策——它让编码器处理的 token 数从 3000 降到 1500,注意力代价从 3000² 降到 1500²(4 倍),而参数几乎不增。这种「卷积降采样 + Transformer」的混合在音频和视频 Transformer 里很常见。

三、框架对比:OpenAI Whisper 与 faster-whisper

import whisper model = whisper.load_model("large-v3-turbo") result = model.transcribe("meeting.wav", language="en", task="transcribe") print(result["text"]) print(result["segments"][0]["start"], result["segments"][0]["end"])

更快、OpenAI 兼容的版本:

from faster_whisper import WhisperModel model = WhisperModel("large-v3-turbo", compute_type="int8_float16") segments, info = model.transcribe("meeting.wav", vad_filter=True) for s in segments: print(f"{s.start:.2f} - {s.end:.2f}: {s.text}")

2026 年何时选 Whisper:

  • 用一个模型做多语种 ASR。
  • 对噪声大、多样的音频做鲁棒转录。
  • 研究/原型 ASR——最快的起点。

何时选别的:

  • 边缘上超低延迟流式——Moonshine 在等质量下击败 Whisper。
  • 需要 <200 ms 的实时对话 AI——专用流式 ASR。
  • 说话人分离——Whisper 不做,外挂 pyannote。

四、可复用产物

原课程产出 outputs/skill-asr-configurator.md:一个配置器 Skill,为新语音应用选 ASR 模型、解码参数、预处理管线。

五、练习

  1. (Easy)code/main.py,确认 1 秒、16 kHz、10 ms hop 的信号帧数约 100;30 秒约 3000。
  2. (Medium)numpy.fft 搭完整 log-mel 频谱图,验证 80 mel 频带与 librosa.feature.melspectrogram(n_mels=80) 在数值误差内一致。
  3. (Hard) 实现流式推理:把音频切成 10s 窗、2s 重叠,每块跑 Whisper,合并转录。在 5 分钟播客样本上测词错误率,对比单次跑全量。

本节要点回顾

  1. 音频 = 频谱图图像:log-mel(80 频带 × ~3000 帧)让 ViT 思路直接适用,Transformer 不在乎模态。
  2. 六步流水线:重采样定窗 → Conv1D stem(减半)→ 编码器 → 解码器 → task token → beam search 输出。
  3. task token 是 4 token 前缀:<|startoftranscript|> <|语种|> <|任务|> [|notimestamps|] 控制任务——语音版 instruction tuning。
  4. 不用 CTC/HMM/vocoder:encoder-decoder + 自回归文本生成,把 ASR 变成 seq2seq 翻译,更简单更强。
  5. Conv1D stem stride 2 减半:把 3000 帧降到 1500,注意力代价 4 倍下降,参数几乎不增。
  6. large-v3-turbo 砍解码器到 4 层:解码快 8 倍、WER 退化 <1 点,2026 实时语音代理的默认。
  7. 三个不:不做说话人分离(配 pyannote)、不原生流式(faster-whisper+VAD 外挂)、无 >30s 长上下文(分块)。
  8. 2026 全景:多语种用 large-v3,英文/边缘用 Moonshine,流式用 faster-whisper+VAD,音频+语言用 AudioLM/SeamlessM4T。

下一节,我们进入混合专家(MoE)——把 FFN 换成多个「专家」网络,每次只激活少数几个,用稀疏激活换取等质量下更低的推理算力。


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