# Whisper语音识别 ## 概述 Whisper是OpenAI于2022年发布的开源自动语音识别(ASR)系统,采用了基于Transformer的编解码器架构,能够进行多语言识别并具有较强的泛化能力。Whisper的核心创新在于使用弱监督训练方法,通过大规模互联网音频数据学习语音识别能力。 ## 1. Whisper架构详解 ### 1.1 编解码器架构 Whisper采用标准的Transformer编码器-解码器架构: ```python 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 音频特征处理 ```python 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 编码器结构 ```python 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 解码器结构 ```python 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种语言: ```python LANGUAGES = { 'en': 'english', 'zh': 'chinese', 'es': 'spanish', 'fr': 'french', 'de': 'german', 'ja': 'japanese', 'ko': 'korean', 'ar': 'arabic', 'ru': 'russian', # ... 共99种语言 } ``` ### 2.2 语言检测与自动切换 ```python 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 多语言训练数据 ```python # 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):** 使用互联网上有噪声但数量庞大的音频-文本配对数据进行训练,相比使用人工标注的高质量数据,规模更大但标注质量较低。 ```python # 传统监督 vs 弱监督 traditional_supervision = { 'data_source': '人工标注', 'quality': '高', 'quantity': '低(数千到数万小时)', 'cost': '昂贵', 'annotation': '精确时间对齐' } weak_supervision = { 'data_source': '互联网音频(YouTube等)', 'quality': '中等(有噪声)', 'quantity': '大(数百万小时)', 'cost': '低', 'annotation': '不保证时间对齐' } ``` ### 3.2 训练数据收集 ```python 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 数据预处理 ```python 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 损失函数与训练 ```python 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使用多任务学习框架: ```python 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 性能对比 ```python # 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 基本推理 ```python import whisper # 加载模型 model = whisper.load_model("base") # 转录 result = model.transcribe("audio.mp3", language='zh') # 打印结果 print(result["text"]) print(result["segments"]) ``` ### 5.2 多语言识别 ```python # 加载模型 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 批量处理 ```python 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 改进方向 ```python # Whisper的潜在改进 improvements = { 'speed': '优化推理速度,支持实时', 'accuracy': '提升专有名词识别', 'punctuation': '改进标点生成', 'dialect': '增加方言支持', 'speaker': '加入说话人分离' } ``` ## 8. 总结 Whisper的核心技术贡献: | 技术 | 贡献 | 影响 | |------|------|------| | Transformer编解码器 | 统一的多语言ASR | 简化模型架构 | | 弱监督训练 | 大规模互联网数据 | 降低数据成本 | | 多语言泛化 | 99种语言零样本 | 广泛适用性 | | 开源模型 | 可本地部署 | 推动社区发展 | Whisper证明了弱监督训练在语音识别领域的有效性,为后续多语言语音模型的发展提供了重要参考。