whisper 简介

Whisper是一个通用的语音识别模型,它使用了大量的多语言和多任务的监督数据来训练,能够在英语语音识别上达到接近人类水平的鲁棒性和准确性。Whisper还可以进行多语言语音识别、语音翻译和语言识别等任务。

whisper 幻觉

使用whisper在识别中文时会出现识别异常的情况。特别是在嘈杂背景的情况。

经常会出现:

请不吝点赞 订阅 转发 打赏支持明镜与点点栏目

谢谢大家

解决思路

对音频文件进行预处理,减少噪音,只保留语音部分。

实现代码

import io
import torchaudio
import torch
from silero_vad import load_silero_vad, get_speech_timestamps
import logging
import noisereduce as nr

logger = logging.getLogger(__name__)

def remove_silence(input_bytes):
    # 将输入的字节流转换为音频波形
    input_stream = io.BytesIO(input_bytes)
    # 将bytes转换为torch张量
    sample_waveform, sample_rate = torchaudio.load(input_stream)

    # 将音频数据转换为单声道
    sample_waveform = sample_waveform.mean(dim=0, keepdim=True)

    #region 音频预处理

    # 采样率转换为16kHz
    new_rate=16000
    resampler = torchaudio.transforms.Resample(orig_freq=sample_rate, new_freq=new_rate)
    waveform = resampler(sample_waveform)

    # 使用 noisereduce 进行降噪
    reduced_noise_audio  = nr.reduce_noise(waveform.numpy(),new_rate,n_fft=512)
    waveform = torch.tensor(reduced_noise_audio, dtype=torch.float32)

    #endregion

    #region VAD检测

    # 初始化VAD模型
    model = load_silero_vad()
    
    # 检测语音活动
    speech_timestamps = get_speech_timestamps(waveform, model)

    isBlankAudio=0

    if(len(speech_timestamps)==0):
        logger.debug("这是空白音频")
        isBlankAudio=1
        speech_timestamps.append({"start":0,"end":0})
    
    # 将时间戳转换为帧索引
    speech_frames = []
    audio_length = 0
    for item in speech_timestamps:
        start_frame = int(item["start"])
        end_frame = int(item["end"])
        audio_length+= end_frame-start_frame+1
        speech_frames.append((start_frame, end_frame))
    
    # 生成新的音频波形
    new_waveform = torch.zeros((1,audio_length))
    new_audio_index = 0
    for start, end in speech_frames:
        new_waveform[:, new_audio_index:new_audio_index+(end-start)] = waveform[:, start:end]
        new_audio_index += (end-start)+1
    
    # 将新的音频波形转换为字节流
    output_stream = io.BytesIO()
    torchaudio.save(output_stream, new_waveform, new_rate,format='mp3')
    output_bytes = output_stream.getvalue()

    logger.debug("返回删除空白音频后的结果")

    #endregion
    
    return output_bytes,isBlankAudio

#示例用法
input_file = 'input.mp3'

with open(input_file, 'rb') as f:
    input_bytes = f.read()

output_bytes,isBlankAudio = remove_silence(input_bytes)

with open('output.mp3', 'wb') as f:
    f.write(output_bytes)