13 KiB
13 KiB
Whisper语音识别
概述
Whisper是OpenAI于2022年发布的开源自动语音识别(ASR)系统,采用了基于Transformer的编解码器架构,能够进行多语言识别并具有较强的泛化能力。Whisper的核心创新在于使用弱监督训练方法,通过大规模互联网音频数据学习语音识别能力。
1. Whisper架构详解
1.1 编解码器架构
Whisper采用标准的Transformer编码器-解码器架构:
class Whisper(nn.Module):
def __init__(self, config):
# 编码器
self.encoder = TransformerEncoder(
num_layers=config.num_layers,
d_model=config.d_model, # 1280
num_heads=config.num_heads, # 16
d_ff=config.d_ff, # 5120
dropout=0.1
)
# 解码器
self.decoder = TransformerDecoder(
num_layers=config.num_layers,
d_model=config.d_model,
num_heads=config.num_heads,
d_ff=config.d_ff,
dropout=0.1,
vocab_size=config.vocab_size # 51865
)
# 音频嵌入层
self.audio_embed = nn.Conv2d(
in_channels=80, # Mel频谱通道数
out_channels=config.d_model,
kernel_size=3,
stride=2
)
# 文本嵌入层
self.text_embed = nn.Embedding(
num_embeddings=config.vocab_size,
embedding_dim=config.d_model
)
1.2 音频特征处理
def process_audio(audio, sample_rate=16000):
"""
音频预处理:转换为Mel频谱
"""
# 1. 重采样到16kHz
audio = resample(audio, target_sr=16000)
# 2. 短时傅里叶变换 (STFT)
stft = librosa.stft(audio, n_fft=400, hop_length=160)
# 3. 计算幅度谱
magnitude = np.abs(stft)
# 4. Mel滤波器组变换
mel_spec = librosa.feature.melspectrogram(
S=magnitude,
n_mels=80,
n_fft=400,
hop_length=160,
fmin=0,
fmax=8000
)
# 5. 对数压缩
log_mel = np.log(mel_spec + 1e-9)
# 6. 归一化
log_mel = (log_mel - log_mel.mean()) / log_mel.std()
return log_mel # [80, T] 其中T=audio_duration/0.01
1.3 编码器结构
class WhisperEncoder(nn.Module):
def __init__(self, d_model=1280, num_layers=32):
# 输入卷积层
self.conv1 = nn.Conv1d(80, d_model, kernel_size=3, padding=1)
self.conv2 = nn.Conv1d(d_model, d_model, kernel_size=3, stride=2, padding=1)
# Transformer块
self.blocks = nn.ModuleList([
ResidualAttentionBlock(d_model, num_heads=16)
for _ in range(num_layers)
])
# 层归一化
self.ln = LayerNorm(d_model)
def forward(self, x):
# x: [B, 80, T]
# 初始卷积下采样
x = self.conv1(x)
x = nn.functional.gelu(x)
x = self.conv2(x)
x = nn.functional.gelu(x)
# Transformer处理
for block in self.blocks:
x = block(x, self_attn_mask=None)
# 最终归一化
x = self.ln(x)
return x # [B, D, T']
1.4 解码器结构
class WhisperDecoder(nn.Module):
def __init__(self, d_model=1280, num_layers=32, vocab_size=51865):
# 文本嵌入
self.token_embedding = nn.Embedding(vocab_size, d_model)
# 位置编码
self.positional_embedding = nn.Embedding(5000, d_model)
# Transformer块
self.blocks = nn.ModuleList([
ResidualAttentionBlock(d_model, num_heads=16, use_cross_attention=True)
for _ in range(num_layers)
])
# 输出层
self.ln = LayerNorm(d_model)
self.proj = nn.Linear(d_model, vocab_size)
def forward(self, x, encoder_output):
# x: [B, seq_len] token IDs
# encoder_output: [B, D, T'] 编码器输出
# 文本嵌入 + 位置编码
x = self.token_embedding(x) + self.positional_embedding(
torch.arange(x.shape[1], device=x.device)
)
# 自注意力掩码(causal)
seq_len = x.shape[1]
mask = torch.triu(
torch.ones(seq_len, seq_len, device=x.device),
diagonal=1
).bool()
# Transformer块
for block in self.blocks:
x = block(x, encoder_output, self_attn_mask=mask)
# 输出投影
x = self.ln(x)
logits = self.proj(x)
return logits # [B, seq_len, vocab_size]
2. 多语言识别能力
2.1 支持的语言
Whisper能够识别99种语言:
LANGUAGES = {
'en': 'english',
'zh': 'chinese',
'es': 'spanish',
'fr': 'french',
'de': 'german',
'ja': 'japanese',
'ko': 'korean',
'ar': 'arabic',
'ru': 'russian',
# ... 共99种语言
}
2.2 语言检测与自动切换
def detect_language_and_transcribe(audio, model):
"""
自动检测语言并转录
"""
# 1. 音频特征提取
mel = process_audio(audio)
# 2. 语言检测(使用一小段音频)
lang_mel = mel[:, :3000] # 前30秒
lang_logits = model.detect_language(lang_mel)
detected_lang = LANGUAGES[lang_logits.argmax().item()]
# 3. 完整转录(指定语言)
if detected_lang != 'english':
# 使用语言特定的解码器
transcription = model.transcribe(
audio,
language=detected_lang,
task='transcribe'
)
else:
transcription = model.transcribe(audio)
return transcription
2.3 多语言训练数据
# Whisper训练数据集分布
dataset_distribution = {
'english': 0.35, # 最大比例
'spanish': 0.10,
'chinese': 0.08,
'french': 0.07,
'german': 0.06,
'russian': 0.05,
'other': 0.29 # 其他语言混合
}
3. 弱监督训练方法
3.1 弱监督定义
弱监督(Weak Supervision): 使用互联网上有噪声但数量庞大的音频-文本配对数据进行训练,相比使用人工标注的高质量数据,规模更大但标注质量较低。
# 传统监督 vs 弱监督
traditional_supervision = {
'data_source': '人工标注',
'quality': '高',
'quantity': '低(数千到数万小时)',
'cost': '昂贵',
'annotation': '精确时间对齐'
}
weak_supervision = {
'data_source': '互联网音频(YouTube等)',
'quality': '中等(有噪声)',
'quantity': '大(数百万小时)',
'cost': '低',
'annotation': '不保证时间对齐'
}
3.2 训练数据收集
def collect_weak_supervision_data():
"""
收集弱监督训练数据
"""
data_sources = [
'YouTube videos',
'Podcasts',
'Audiobooks',
'Public speaking recordings',
'Movie trailers',
'News broadcasts',
'Educational content'
]
collection_pipeline = {
'step1': '从公开源收集音频',
'step2': '原始转录文本获取(CC subtitles, transcripts)',
'step3': '质量过滤(长度、语言、清晰度)',
'step4': '音频-文本配对构建',
'step5': '去重(去除重复内容)'
}
return collected_data # Whisper使用约68万小时
3.3 数据预处理
def preprocess_audio_text_pair(audio_path, text):
"""
预处理音频-文本对
"""
# 1. 音频清理
audio = load_audio(audio_path)
audio = remove_silence(audio)
audio = normalize_volume(audio)
# 2. 文本清理
text = clean_transcript(text)
text = remove_filler_words(text) # 可选
text = standardize_punctuation(text)
# 3. 时长过滤
if len(audio) < 0.5 or len(audio) > 30:
return None
# 4. 语言验证
detected_lang = detect_language(text)
if not is_supported_language(detected_lang):
return None
return {'audio': audio, 'text': text, 'language': detected_lang}
3.4 损失函数与训练
def compute_loss(logits, targets, pad_token_id=50257):
"""
计算交叉熵损失
忽略padding token
"""
# logits: [B, seq_len, vocab_size]
# targets: [B, seq_len]
# 移位:解码器预测下一个token
shift_logits = logits[:, :-1, :].contiguous()
shift_targets = targets[:, 1:].contiguous()
# 计算交叉熵
loss = nn.functional.cross_entropy(
shift_logits.view(-1, shift_logits.size(-1)),
shift_targets.view(-1),
ignore_index=pad_token_id,
reduction='mean'
)
return loss
3.5 多任务训练
Whisper使用多任务学习框架:
class MultiTaskWhisper(nn.Module):
def forward(self, audio, targets=None, task='transcribe', language='en'):
# 编码音频
encoder_output = self.encoder(audio)
# 构建任务提示
if task == 'transcribe':
task_tokens = [TO_TRANSCRIBE, LANG_TOKEN[language]]
elif task == 'translate':
task_tokens = [TO_TRANSLATE, LANG_TOKEN[language]]
elif task == 'detect_language':
task_tokens = [TO_DETECT_LANGUAGE]
# 解码
decoder_input = task_tokens + (targets or [])
decoder_output = self.decoder(decoder_input, encoder_output)
return decoder_output
4. 模型变体
4.1 Whisper模型系列
| 模型 | 参数量 | English WER | 多语言 WER |
|---|---|---|---|
| Tiny | 39M | ~8% | ~15% |
| Base | 74M | ~6% | ~12% |
| Small | 244M | ~4% | ~8% |
| Medium | 769M | ~3% | ~6% |
| Large-v2 | 1550M | ~2.5% | ~5% |
| Large-v3 | 1550M | ~2% | ~4% |
4.2 性能对比
# Whisper vs 其他ASR系统
performance_comparison = {
'Whisper-Large-v3': {'WER': '2-3%', 'languages': 99, 'robustness': 'high'},
'Wav2Vec2': {'WER': '4-5%', 'languages': 50+', 'robustness': 'medium'},
'Google Speech-to-Text': {'WER': '3-4%', 'languages': 125+, 'robustness': 'high'},
'DeepSpeech': {'WER': '8-10%', 'languages': 5', 'robustness': 'low'}
}
5. 使用方法
5.1 基本推理
import whisper
# 加载模型
model = whisper.load_model("base")
# 转录
result = model.transcribe("audio.mp3", language='zh')
# 打印结果
print(result["text"])
print(result["segments"])
5.2 多语言识别
# 加载模型
model = whisper.load_model("medium")
# 方法1:自动检测语言
result = model.transcribe("unknown_language_audio.mp3")
# 方法2:指定语言
result = model.transcribe(
"japanese_audio.mp3",
language="ja",
task="transcribe" # 或 'translate'
)
# 方法3:翻译
result = model.transcribe(
"chinese_audio.mp3",
language="zh",
task="translate" # 翻译为英语
)
5.3 批量处理
def batch_transcribe(audio_files, model, language=None):
"""
批量转录多个音频文件
"""
results = []
for audio_path in audio_files:
print(f"Processing: {audio_path}")
result = model.transcribe(
audio_path,
language=language,
verbose=False
)
results.append({
'file': audio_path,
'text': result['text'],
'language': result['language']
})
return results
6. 核心优势
| 优势 | 说明 |
|---|---|
| 多语言支持 | 99种语言,无需微调 |
| 弱监督训练 | 68万小时,规模大 |
| 鲁棒性 | 抗噪声能力强 |
| 开源 | 可本地部署 |
| 零样本能力 | 未经训练的语言也能识别 |
7. 局限性与改进
7.1 当前局限
| 限制 | 描述 |
|---|---|
| 实时性 | 推理延迟较高 |
| 专有名词 | 人名、地名识别准确率低 |
| 方言口音 | 某些方言识别困难 |
| 标点符号 | 自动标点不够准确 |
7.2 改进方向
# Whisper的潜在改进
improvements = {
'speed': '优化推理速度,支持实时',
'accuracy': '提升专有名词识别',
'punctuation': '改进标点生成',
'dialect': '增加方言支持',
'speaker': '加入说话人分离'
}
8. 总结
Whisper的核心技术贡献:
| 技术 | 贡献 | 影响 |
|---|---|---|
| Transformer编解码器 | 统一的多语言ASR | 简化模型架构 |
| 弱监督训练 | 大规模互联网数据 | 降低数据成本 |
| 多语言泛化 | 99种语言零样本 | 广泛适用性 |
| 开源模型 | 可本地部署 | 推动社区发展 |
Whisper证明了弱监督训练在语音识别领域的有效性,为后续多语言语音模型的发展提供了重要参考。