音频 Transformer 与 Whisper 本节摘要:音频是一张「频率随时间变化」的图,Whisper 就是一个吃 mel 频谱图、再开口说话的 ViT。在 Whisper(OpenAI,Radford 等 2022)之前,最先进的自动语音识别(ASR)是 wav2vec 2.0 和 HuBERT——自监督特征提取器加微调头,质量高但数据管线昂贵、对领域脆弱,多语种还得按语系各训一个模型。
本节摘要:音频是一张「频率随时间变化」的图,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 倍加速。
阅读完本节,你应当能够:
<|startoftranscript|> <|en|> <|transcribe|>)如何用一个 4 token 前缀控制任务——这是语音版的 instruction tuning。Whisper 的核心洞见:音频就是一张频率随时间变化的二维图,所以「图→token」的 ViT 思路完全适用——只不过这里的「图」是 mel 频谱图。
音频 16 kHz,裁剪/填充到 30 秒。算 log-mel 频谱图:80 个 mel 频带,10 ms 步长 → 约 3000 帧 × 80 特征。这就是 Whisper 看到的「输入图像」。
两个 Conv1D(kernel 3、stride 2)把 3000 帧降到 1500。不增加多少参数就 halves 序列长度。
large 是 24 层 Transformer 编码器,处理 1500 个时间步。正弦位置编码、自注意力、GELU FFN,产出 1500 × 1280 隐状态。
24 层 Transformer 解码器,从一个 BPE 词表(GPT-2 词表的超集,加几个音频专用特殊 token)自回归产生 token。
解码器提示以控制 token 开头,告诉模型做什么:
<|startoftranscript|> <|en|> <|transcribe|> <|0.00|> # 英文转录 <|startoftranscript|> <|fr|> <|translate|> <|0.00|> # 法语翻译成英文
模型在这个约定上训练,你用前缀控制任务。这是 2026 年 instruction-tuning 的等价物,但用在语音上。
beam search(width 5)+ 对数概率阈值。无 <|notimestamps|> token 时,每 0.02 秒预测一个时间戳。
| 模型 | 参数 | 层数 | 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 年实时语音代理默认的原因。
faster-whisper、WhisperX)靠 VAD + 重叠块外挂流式。| 任务 | 模型 | 备注 |
|---|---|---|
| 英文 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 提示构造器,这是生产里你真正会碰的两部分。
生成 1 秒、440 Hz、16 kHz 采样的正弦波,16000 个样本。
完整 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 频带。
Whisper 总是处理 30 秒块。把频谱图填充(或裁剪)到 3000 帧。
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 里很常见。
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:
何时选别的:
原课程产出 outputs/skill-asr-configurator.md:一个配置器 Skill,为新语音应用选 ASR 模型、解码参数、预处理管线。
code/main.py,确认 1 秒、16 kHz、10 ms hop 的信号帧数约 100;30 秒约 3000。numpy.fft 搭完整 log-mel 频谱图,验证 80 mel 频带与 librosa.feature.melspectrogram(n_mels=80) 在数值误差内一致。<|startoftranscript|> <|语种|> <|任务|> [|notimestamps|] 控制任务——语音版 instruction tuning。下一节,我们进入混合专家(MoE)——把 FFN 换成多个「专家」网络,每次只激活少数几个,用稀疏激活换取等质量下更低的推理算力。