Whisper 模型微调实战:3 步用自定义数据训练专用语音识别模型
读完你能独立完成一次 Whisper 模型微调,拿到能过业务验收的专用语音识别模型。适合有 Python 基础、要做 ASR 模型定制(医疗、金融、方言场景)的工程师和数据科学家。
动手前先想清楚三件事:要不要做、选多大、数据够不够
这节解决判断题。三个决策有一个错了,后面全是返工。
微调值不值得做。 说白了就看两点:错误是不是"词汇问题",数据是不是"量级问题"。通用模型在你领域里错的主要是专业术语、同音词、口音,说明微调有空间;如果错误集中在背景噪声、录音质量,先治音频。数据少于 10 小时,先别急,用 prompt 工程和热词注入试一轮,往往零成本拿到八成收益。结论一句话:领域词汇错 + 数十小时起的数据,才轮到 Whisper 模型微调出场。
选哪个规格。 微调比推理吃显存得多,官方表里的显存是推理口径,训练时通常要再乘 3~4 倍。按数据量对号入座:
| 规格 | 参数量 | 推理显存(官方口径) | 适用场景 |
|---|---|---|---|
| base.en | 74 M | ~1 GB | 10 小时内数据,先验证流水线 |
| small | 244 M | ~2 GB | 10~50 小时,小预算首选 |
| medium | 769 M | ~5 GB | 50 小时以上,Whisper 中文微调的主力起点 |
| turbo | 809 M | ~6 GB | 要吞吐量、能接受上限略低 |
large(1550 M)不是不行,是大多数团队显存和预算都不行。除非你有 A100 和数据量都富裕,第一版别碰它。
微调到底改了什么。 音频先被转成梅尔频谱(Mel Spectrogram,80 维、100ms 一帧的语音"指纹"),编码器压成表示,解码器逐 token 生成文本。微调主要是在解码器侧重新分配概率,让它适配你的领域词汇。官方架构图如下,底部标注了"纯文本转写允许数据集专属微调",这就是我们做的事:
数据底线。 达不到就别开工:
- 干净标注音频 ≥ 10 小时,少于此先把模型降档而不是硬撑
- 全部统一 16kHz 采样率、单声道
- 转写文本与音频严格一致——标注质量就是微调的天花板
- ≥ 10 个不同说话人,覆盖真实会遇到的语速、口音、方言
- 留出独立测试集,训练全程不许碰
从 0 到 1 跑通一次 Whisper 模型微调
这节只给"跑得起来"所需的最少信息,三步各一段核心代码,能一句话说清的就不贴代码。
Step 1 备料:最小数据集准备清单(16kHz + 文本规范化)
Whisper 的输入链路是固定的,你的数据只需要对齐它:
清单就两列:音频路径 + 转写文本。CSV 或 JSON 都行,字段名统一即可,JSON 就是 {"audio": "...", "text": "..."} 的列表。训练/验证/测试按 7:1.5:1.5 切。核心清洗逻辑如下:
import pandas as pd, re, librosa, soundfile as sf
# 音频统一到 16kHz;文本小写、去特殊字符、压空格
fix = lambda p: sf.write(p, librosa.load(p, sr=16000)[0], 16000)
norm = lambda t: re.sub(r"\s+", " ", re.sub(r"[^\w\s]", " ", t.lower())).strip()
df = pd.read_csv("raw.csv")
df["audio"] = df["audio"].map(fix) # 音频标准化
df["text"] = df["text"].map(norm) # 文本规范化
df.to_csv("train.csv", index=False) # 输出训练清单
两个容易踩的细节:标点策略训练和推理要一致,否则评测数字没法看;仓库里 notebooks/LibriSpeech.ipynb 有一个现成的"加载数据→推理→算 WER"示例,把它换成你自己的数据集,先跑出微调前的基线——没有基线,后面所有数字都没有参照系。
Step 2 开训:环境安装与关键超参数速调表
环境一次装完:
git clone https://gitcode.com/GitHub_Trending/whisp/whisper
cd whisper && pip install -e .
pip install transformers datasets jiwer accelerate
超参先别逐个纠结,照这张表跑通第一版:
| 参数 | 推荐值 | 为什么 |
|---|---|---|
| 基座模型 | medium(中文用多语言版) | 容量够、显存可控,微调性价比最高 |
| 学习率 | 1e-5 | 微调不需要大步长,大了就震荡 |
| Batch | 8 + 4 步梯度累积 | 小显存模拟大 batch |
| Epochs | 3~10,配合早停 | 数据越少,过拟合来得越早 |
| 精度 | fp16 | 显存减半,精度损失可忽略 |
| 评估频率 | 每个 epoch | 靠 val loss 盯过拟合 |
训练核心循环:
from transformers import WhisperProcessor, WhisperForConditionalGeneration, Trainer, TrainingArguments
processor = WhisperProcessor.from_pretrained("openai/whisper-medium")
model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-medium")
args = TrainingArguments(output_dir="./finetuned", learning_rate=1e-5, fp16=True,
per_device_train_batch_size=8, gradient_accumulation_steps=4,
eval_strategy="epoch", save_strategy="epoch", load_best_model_at_end=True)
# train_ds / val_ds:Step 1 的 CSV 经 processor 处理后的数据集对象
Trainer(model=model, args=args, train_dataset=train_ds,
eval_dataset=val_ds).train()
Step 3 看结果:WER/CER 怎么读、过拟合信号识别
这节解决"跑完之后数字怎么读、什么时候该停"。
- WER 是词粒度错误率,CER 是字符粒度。中文场景优先看 CER:把"识别"听成"认知",WER 记 100%,CER 只记约 33%,后者更贴近中文的真实体感。
- 唯一的硬参照是基线:同一测试集上,微调后错误率比微调前降 20% 以上才算有效,目标是语音识别准确率提升一个可感知的台阶。降不下来,先查数据质量,别急着调参。
- 曲线怎么看:val loss 跟 train loss 一起降,继续训;train loss 还在降、val loss 掉头向上,就是过拟合信号。
- 早停标准:val 连续 2 个 epoch 不改善就停,取 val 最优的那个 checkpoint,别迷信最后一个。
调优工具箱:按需取用的 8 个动作
这节是"效果不够好"时的动作清单。按症状挑,别一次全上。
| 手段 | 什么时候用 |
|---|---|
| 加高斯噪声(σ≈0.005) | 训练数据太"棚内",真实场景有噪声 |
| 时间伸缩(0.8~1.2 倍) | 语速多样性不足 |
| LoRA 低秩微调 | 显存紧张,只训注意力层的旁路参数 |
| warmup + cosine 衰减 | 训练早期损失震荡 |
| fp16 换 bf16 | 部分显卡上 fp16 出现 NaN |
| int8 量化 | 部署端显存、延迟双重压力 |
| 导出 ONNX Runtime | 批量推理要提吞吐 |
| num_beams 从 5 降到 1 | 延迟敏感场景,用精度换速度 |
踩坑速查表:6 个高频问题的最快止损
这节解决"报错了或不对劲时,先查哪"。
| 症状 | 最可能原因 | 一招解决 |
|---|---|---|
| 训练中 CUDA out of memory | batch 太大,或显存不够还硬上 large | batch 减半,梯度累积补回来,降一档到 medium |
| train loss 降、val loss 升 | 过拟合 | 早停,加载 val 最优 checkpoint |
| 中文同音字替换特别多 | 训练/推理的文本规范化不一致 | 两端标点、大小写策略统一 |
| 损失出现 NaN | fp16 溢出 | 切 bf16,或学习率降一半 |
| 输出重复、循环生成 | epoch 过多或解码参数过激 | 减 epoch,beam 解码,限制 max_new_tokens |
| 某一轮 WER 突然变差 | 学习率偏大 | lr 减半,加 warmup 步数 |
下一步:5 个可以直接开干的进阶动作
- 二轮迭代:上一轮错得最狠的样本是最值钱的标注来源,回流重训
- 换 LoRA:冻结编码器只微调解码器,显存和过拟合风险同时下降
- 建回归测试集:100~500 条真实业务音频,每轮用 CER + WER 双指标验收
- 导出 ONNX:在真实硬件上压测延迟,再决定部署形态
- 混语料必验语言识别:用 language ID 确认多语言模型没被单语数据"带偏"
参考资料
- 《Robust Speech Recognition via Large-Scale Weak Supervision》(Radford 等,2022,arXiv:2212.04356),Whisper 原始论文
- OpenAI Whisper 官方仓库 openai/whisper,模型权重与规格表
- Hugging Face Transformers 官方文档,Whisper 微调示例章节
- PyTorch 官方文档
- jiwer,WER/CER 评估库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




