Whisper 语音转文字¶
为什么要学 Whisper¶
OpenAI 的 Whisper 是目前最准确的开源语音识别模型,支持 99 种语言的转录和翻译。它在各种口音、背景噪音和专业术语上的表现远超传统语音识别系统。Whisper 完全可以在本地运行,数据不需要上传到云端。对于会议记录、播客转录、视频字幕、语音笔记等场景,Whisper 是免费且高质量的选择。
核心概念¶
| 概念 | 白话解释 | 用途 |
|---|---|---|
| Transcription | 转录 | 语音转为同语言文字 |
| Translation | 翻译 | 语音转为英文文字 |
| Model Size | 模型大小 | tiny/base/small/medium/large |
| Language Detection | 语言检测 | 自动识别音频语言 |
| Timestamp | 时间戳 | 每段文字对应的音频时间 |
| VAD | 语音活动检测 | 检测音频中有人说话的片段 |
安装配置¶
安装¶
# 官方 Whisper
pip install openai-whisper
# faster-whisper(推荐,速度更快)
pip install faster-whisper
# whisper.cpp Python 绑定
pip install pywhispercpp
系统要求¶
# FFmpeg(音频处理必需)
# Ubuntu
sudo apt install ffmpeg
# macOS
brew install ffmpeg
# Windows
# 从 https://ffmpeg.org/ 下载
模型选择¶
| 模型 | 参数量 | 英文 WER | 显存需求 | 速度 |
|---|---|---|---|---|
| tiny | 39M | ~8% | ~1GB | 最快 |
| base | 74M | ~5.5% | ~1GB | 快 |
| small | 244M | ~3.5% | ~2GB | 中 |
| medium | 769M | ~2.5% | ~5GB | 慢 |
| large-v3 | 1550M | ~1.5% | ~10GB | 最慢 |
| turbo | 809M | ~2% | ~6GB | 较快 |
快速上手¶
命令行使用¶
# 基本转录
whisper audio.mp3
# 指定模型和语言
whisper audio.mp3 --model large-v3 --language Chinese
# 输出 SRT 字幕
whisper audio.mp3 --model medium --output_format srt
# 多种输出格式
whisper audio.mp3 --output_format all # txt, vtt, srt, tsv, json
# 翻译为英文
whisper audio.mp3 --task translate
Python API¶
import whisper
# 加载模型
model = whisper.load_model("medium")
# 转录
result = model.transcribe("audio.mp3")
# 输出文本
print(result["text"])
# 带时间戳的片段
for segment in result["segments"]:
start = segment["start"]
end = segment["end"]
text = segment["text"]
print(f"[{start:.2f} - {end:.2f}] {text}")
# 指定语言
result = model.transcribe("audio.mp3", language="zh")
# 翻译模式
result = model.transcribe("chinese_audio.mp3", task="translate")
faster-whisper(推荐)¶
from faster_whisper import WhisperModel
# 加载模型(CTranslate2 优化,速度快 4 倍)
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
# 转录
segments, info = model.transcribe("audio.mp3", language="zh")
print(f"检测语言: {info.language} (概率: {info.language_probability:.2f})")
for segment in segments:
print(f"[{segment.start:.2f}s -> {segment.end:.2f}s] {segment.text}")
进阶用法¶
带 VAD 的长音频处理¶
from faster_whisper import WhisperModel
model = WhisperModel("large-v3", device="cuda")
# 使用 Silero VAD 过滤静音段
segments, info = model.transcribe(
"long_meeting.mp3",
vad_filter=True,
vad_parameters=dict(
min_silence_duration_ms=500, # 最小静音时长
speech_pad_ms=400, # 语音前后的填充
),
word_timestamps=True, # 逐词时间戳
)
for segment in segments:
print(f"[{segment.start:.2f}s] {segment.text}")
if segment.words:
for word in segment.words:
print(f" {word.word} ({word.start:.2f}-{word.end:.2f})")
生成 SRT 字幕¶
def generate_srt(segments, output_path):
with open(output_path, "w", encoding="utf-8") as f:
for i, segment in enumerate(segments, 1):
start = format_timestamp(segment.start)
end = format_timestamp(segment.end)
f.write(f"{i}\n{start} --> {end}\n{segment.text.strip()}\n\n")
def format_timestamp(seconds):
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = int(seconds % 60)
msecs = int((seconds % 1) * 1000)
return f"{hours:02d}:{minutes:02d}:{secs:02d},{msecs:03d}"
# 使用
segments, _ = model.transcribe("video.mp4")
segments_list = list(segments)
generate_srt(segments_list, "subtitles.srt")
实时转录¶
import pyaudio
import numpy as np
from faster_whisper import WhisperModel
model = WhisperModel("base", device="cpu")
# 音频参数
RATE = 16000
CHUNK = RATE * 5 # 每5秒处理一次
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=RATE, input=True)
print("开始录音... (Ctrl+C 停止)")
try:
while True:
data = stream.read(CHUNK)
audio = np.frombuffer(data, dtype=np.float32)
segments, _ = model.transcribe(audio, language="zh")
for segment in segments:
print(segment.text, end=" ", flush=True)
except KeyboardInterrupt:
print("\n录音停止")
stream.stop_stream()
stream.close()
p.terminate()
批量处理¶
from pathlib import Path
from faster_whisper import WhisperModel
import json
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
audio_dir = Path("./recordings")
output_dir = Path("./transcripts")
output_dir.mkdir(exist_ok=True)
for audio_file in audio_dir.glob("*.mp3"):
print(f"Processing: {audio_file.name}")
segments, info = model.transcribe(str(audio_file), language="zh", vad_filter=True)
segments_list = list(segments)
# 保存纯文本
full_text = " ".join([s.text for s in segments_list])
(output_dir / f"{audio_file.stem}.txt").write_text(full_text, encoding="utf-8")
# 保存带时间戳的 JSON
data = [{
"start": s.start, "end": s.end, "text": s.text
} for s in segments_list]
(output_dir / f"{audio_file.stem}.json").write_text(
json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8"
)
whisper.cpp 极速推理¶
# 编译 whisper.cpp
git clone https://github.com/ggerganov/whisper.cpp.git
cd whisper.cpp
make
# 下载模型
bash models/download-ggml-model.sh large-v3
# 转录
./main -m models/ggml-large-v3.bin -f audio.wav -l zh --output-srt
常见问题¶
Q: 中文转录准确率不高?¶
- 使用
large-v3或turbo模型 - 明确指定
language="zh" - 确保音频采样率为 16kHz
- 使用 VAD 过滤背景噪音
Q: 处理长音频内存不足?¶
- 使用
faster-whisper(内存效率更高) - 启用
compute_type="int8"(量化推理) - 先用 FFmpeg 分段:
Q: 如何区分说话人?¶
Whisper 本身不支持说话人识别。可以配合使用: - pyannote-audio(说话人分离) - whisperX(对齐和分离集成)
Q: GPU 加速选哪个方案?¶
- faster-whisper:CTranslate2 优化,推荐首选
- whisper.cpp:C++ 实现,CPU 最快
- whisper-jax:JAX/TPU 加速
参考资源¶
- GitHub(官方):https://github.com/openai/whisper
- faster-whisper:https://github.com/SYSTRAN/faster-whisper
- whisper.cpp:https://github.com/ggerganov/whisper.cpp
- whisperX:https://github.com/m-bain/whisperX
- 论文:https://arxiv.org/abs/2212.04356