Whisper 架构与微调 本节摘要:Whisper 是 OpenAI 2022 年 9 月发布的 30 秒窗口 Transformer 编码器-解码器,在 68 万小时多语种弱监督「音频-文本」对上训练。一套架构,多种任务,覆盖 99 种语言,对噪声鲁棒——它是首个被当作「商品」使用的 ASR 模型:贴进音频就出文字,笔记本就能跑。到 2026 年,Whisper 已是播客转写、语音助手、YouTube 字幕的事实基线。但它不是一个能永远当黑盒用的流水线:域漂移会击垮它——技术黑话、口音、专有名词、短片段、静音都会让它出错。
本节摘要:Whisper 是 OpenAI 2022 年 9 月发布的 30 秒窗口 Transformer 编码器-解码器,在 68 万小时多语种弱监督「音频-文本」对上训练。一套架构,多种任务,覆盖 99 种语言,对噪声鲁棒——它是首个被当作「商品」使用的 ASR 模型:贴进音频就出文字,笔记本就能跑。到 2026 年,Whisper 已是播客转写、语音助手、YouTube 字幕的事实基线。但它不是一个能永远当黑盒用的流水线:域漂移会击垮它——技术黑话、口音、专有名词、短片段、静音都会让它出错。本节将拆开它的内部结构(编码器卷积下采样 + Transformer、解码器因果自注意力 + 交叉注意力、51865 词表的 BPE、靠特殊 token 操控的多任务提示格式),讲透 30 秒窗口与对数梅尔归一化的硬约束,以及 LoRA 微调的规范流程。读完本节,你能为任意领域正确设计 Whisper 的推理与微调流水线,并避开静音幻觉、上下文级联、错误梅尔统计等坑。
阅读完本节,你应当能够:
language/transcribe/translate/notimestamps),并能通过改提示切换任务与语种。Whisper 是首个被当作「商品」使用的 ASR 模型:贴进音频就出文字,99 种语言,对噪声鲁棒,笔记本就能跑。2024 年 OpenAI 发布 Large-v3 与 Turbo 变体;到 2026 年,Whisper 已是播客转写、语音助手、YouTube 字幕的默认基线。
但 Whisper 不是一个能永远当黑盒用的流水线。域漂移会击垮它——技术黑话、说话人口音、专有名词、短片段、静音。你需要知道三件事:
N 个 Transformer 块。Large-v3 是 32 层、1280 维、20 头。N 个 Transformer 块,因果自注意力 + 对编码器输出的交叉注意力。规模与编码器相同。Large-v3 有 15.5 亿参数。Turbo 把解码器从 32 层砍到 4 层,延迟降到 1/8,WER 损失不到 1%。
Whisper 是靠解码器提示里的特殊 token 操控的多任务模型:
<|startoftranscript|><|en|><|transcribe|><|notimestamps|> Hello world.<|endoftext|>
<|en|>:语种标签,决定转录还是翻译行为。<|transcribe|> 或 <|translate|>:把任意语种输入翻译成英语输出,还是逐字转录。<|notimestamps|>:跳过词级时间戳(更快)。这套提示让一个模型干多种活。把 <|en|> 改成 <|fr|>,它就转录法语。
所有处理都钉在 30 秒上。更长的片段需要切块;更短的片段需要补零。窗口本身不原生支持流式——这就是 WhisperX、Whisper-Streaming、faster-whisper 存在的原因。
(log_mel - mean) / std,其中 mean/std 来自 Whisper 自己的训练语料。必须用 Whisper 的预处理(whisper.audio.log_mel_spectrogram),不能用 librosa.feature.melspectrogram。
| 变体 | 参数 | 延迟(A100) | WER(LibriSpeech-clean) |
|---|---|---|---|
| Tiny | 39M | 1× 实时 | 5.4% |
| Base | 74M | 1× | 4.1% |
| Small | 244M | 1× | 3.0% |
| Medium | 769M | 1× | 2.7% |
| Large-v3 | 1.55B | 2× | 1.8% |
| Large-v3-turbo | 809M | 8× | 1.58% |
| Whisper-Streaming(2024) | 1.55B | 流式 | 2.0% |
2026 年的规范流程:
transformers.Seq2SeqTrainer + generate_with_loss 回调。q_proj、k_proj、v_proj 上加 LoRA,GPU 显存降到 1/4,WER 损失不到 0.3。社区结果:在 20 小时医疗口述上微调 Medium,医疗词表 WER 从 12% 降到 4.5%;在 4 小时冰岛语上微调 Turbo,WER 从 18% 降到 6%。
💡 Whisper 的多任务能力全靠提示 token,这意味着你不需要为「翻译」和「转录」维护两套模型权重——同一套参数,换 token 即换任务。这种设计哲学后来被 SeamlessM4T、Moshi 等模型继承。
import whisper model = whisper.load_model("large-v3-turbo") result = model.transcribe( "clip.wav", language="en", task="transcribe", temperature=0.0, condition_on_previous_text=False, # 防止失控重复 ) print(result["text"]) for seg in result["segments"]: print(f"[{seg['start']:.2f}–{seg['end']:.2f}] {seg['text']}")
应始终覆盖的默认值:temperature=0.0(采样默认走 0.0→0.2→0.4 的回退链)、condition_on_previous_text=False(防止级联幻觉)、no_speech_threshold=0.6(静音检测)。
设计要点:
condition_on_previous_text=True是 OpenAI 的默认值,目的是让跨块输出更流畅,但一旦某块产生幻觉,后续块会被它「污染」级联放大。生产环境几乎总是设False,宁可牺牲一点跨块流畅度,也要阻断幻觉级联。
# whisperx 是 2026 年带词级时间戳长音频的参考实现 import whisperx model = whisperx.load_model("large-v3-turbo", device="cuda", compute_type="float16") segments = model.transcribe("1hour.mp3", batch_size=16, chunk_size=30)
WhisperX 额外提供:(1) Silero VAD 把关;(2) 通过 wav2vec 2.0 做词级对齐;(3) 通过 pyannote.audio 做说话人分离。这是 2026 年生产转写的主力。
from transformers import WhisperForConditionalGeneration, WhisperProcessor from peft import LoraConfig, get_peft_model model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-large-v3-turbo") lora = LoraConfig( r=16, lora_alpha=32, target_modules=["q_proj", "v_proj"], lora_dropout=0.1, bias="none", task_type="SEQ_2_SEQ_LM", ) model = get_peft_model(model, lora) # model.print_trainable_parameters() -> 约 3M 可训练 / 809M 总参
之后是标准 Trainer 循环,每 1000 步存检查点,用留出集算 WER 评估。
# 解码时抓交叉注意力权重,看解码器在看编码器的什么 with torch.inference_mode(): out = model.generate( input_features=features, return_dict_in_generate=True, output_attentions=True, ) # out.cross_attentions: 层 × 头 × 步 × src_len
用热力图可视化——你会看到随解码步进扫过编码器帧的对角线对齐。那条对角线就是 Whisper 的「词时间戳」概念。
2026 年工具栈:
| 场景 | 选 |
|---|---|
| 通用英语、离线 | Large-v3-turbo via whisperx |
| 移动 / 边缘 | Whisper-Tiny 量化(int8),或 Moonshine |
| 多语种长音频 | Large-v3 via whisperx + 说话人分离 |
| 低资源语种 | 用 LoRA 微调 Medium 或 Turbo |
| 流式(2 秒延迟) | Whisper-Streaming 或 Parakeet-TDT |
| 词级时间戳 | WhisperX(经 wav2vec 2.0 强制对齐) |
faster-whisper(CTranslate2 后端)是 2026 年最快的 CPU+GPU 推理运行时——比原版快 4 倍,输出完全一致。
⚠️ 四类仍在上线的坑:① 静音上的幻觉——Whisper 在字幕上训练,会输出「Thanks for watching!」「Subscribe!」、歌词,调用前一定要 VAD 把关;② 上下文级联——一次幻觉污染后续窗口,除非需要跨块流畅度,否则设
False;③ 短片段补零——2 秒片段补到 30 秒会在尾随静音里幻觉,用pad=False或 VAD 把关;④ 错误的梅尔统计——用 librosa 的梅尔而非 Whisper 的会得到近乎随机的输出,务必用whisper.audio.log_mel_spectrogram。
本节产出技能文档(原课程 outputs/skill-whisper-tuner.md),为给定领域设计 Whisper 微调或推理流水线。核心检查清单:
log_mel_spectrogram?temperature=0、condition_on_previous_text=False、no_speech_threshold=0.6?基础:运行 code/main.py。它对一段 Whisper 风格提示做 token 化,算解码形状预算,并打印 10 分钟片段的切块计划。
进阶:装 faster-whisper,转写一段 10 分钟播客,与人工转写对比 WER。试 language="auto" 与强制 language="en",看自动 LID 在哪里漂移。
挑战:用 HF datasets,挑一个 Whisper 表现差的语种(如乌尔都语),用 LoRA 在 2 小时数据上微调 Medium 两个 epoch,报告 WER 变化。
<|en|> 切语种,<|transcribe|>/<|translate|> 切任务,一套参数干多种活。q_proj/k_proj/v_proj 上加低秩适配器,显存降到 1/4;数据 <10 小时则冻结编码器只调解码器。下一节,我们转向「这段声音是谁说的」——说话人识别与验证,从 i-vector 讲到 ECAPA-TDNN 与 WavLM,理解嵌入空间的余弦相似度如何区分说话人。