中文语音识别转文字的王者,阿里达摩院FunAsr足可与Whisper相颉顽

君不言语音识别技术则已,言则必称Whisper,没错,OpenAi开源的Whisper确实是世界主流语音识别技术的魁首,但在中文领域,有一个足以和Whisper相颉顽的项目,那就是阿里达摩院自研的FunAsr。

FunAsr主要依托达摩院发布的Paraformer非自回归端到端语音识别模型,它具有高精度、高效率、便捷部署的优点,支持快速构建语音识别服务,最重要的是,FunASR支持标点符号识别、低语音识别、音频-视觉语音识别等功能,也就是说,它不仅可以实现语音转写,还能在转写后进行标注,一石二鸟。

FunAsr和Whisper对比 Medium vs speech_paraformer

首先配置好Python3.10的开发环境,随后在终端运行命令:

复制代码
pip3 install torch torchaudio  
pip3 intall funasr  
pip3 install modelscope

随后编写测试脚本,这里以Bert-vits2里面的转写环节为例子,我们知道,如果想要克隆一个人的声音,那么必须首先把克隆对象的语音转写为文字,并且标注,标注的意义在于可以增强克隆语音的语气韵律问题。

首先看看whisper是怎么做的:

复制代码
def transcribe_one(audio_path):
    model = whisper.load_model("medium")  
    # load audio and pad/trim it to fit 30 seconds  
    audio = whisper.load_audio(audio_path)  
    audio = whisper.pad_or_trim(audio)  
  
    # make log-Mel spectrogram and move to the same device as the model  
    mel = whisper.log_mel_spectrogram(audio).to(model.device)  
  
    # detect the spoken language  
    _, probs = model.detect_language(mel)  
    print(f"Detected language: {max(probs, key=probs.get)}")  
    lang = max(probs, key=probs.get)  
    # decode the audio  
    options = whisper.DecodingOptions(beam_size=5)  
    result = whisper.decode(model, mel, options)  
  
    # print the recognized text  
    print(result.text)  
    return lang, result.text

这通过Whisper的gpu模式来进行推理,模型选择medium,硬件要求是最低6G显存,更多关于whisper的配置,请移步:闻其声而知雅意,M1 Mac基于PyTorch(mps/cpu/cuda)的人工智能AI本地语音识别库Whisper(Python3.10),这里不再赘述。

Whisper转写后效果:

复制代码
./Data\Keira\wavs\Keira_0.wav|Keira|ZH|光动嘴不如亲自做给你看  
./Data\Keira\wavs\Keira_1.wav|Keira|ZH|等我一下呀迫不及待了嘛  
./Data\Keira\wavs\Keira_10.wav|Keira|ZH|你还会帮我吗真没想到你对葡萄酒也这么内行啊  
./Data\Keira\wavs\Keira_11.wav|Keira|ZH|差不多吧好了 聊了这么久我都饿了  
./Data\Keira\wavs\Keira_12.wav|Keira|ZH|还是赶紧开动吧我自己能应付  
./Data\Keira\wavs\Keira_13.wav|Keira|ZH|这些蛋啊 鸡啊 鹅啊 满地都是  
./Data\Keira\wavs\Keira_14.wav|Keira|ZH|再说我的经济状况很快就要改善了  
./Data\Keira\wavs\Keira_15.wav|Keira|ZH|因为我很清楚他的研究有多重要  
./Data\Keira\wavs\Keira_16.wav|Keira|ZH|万一落入心怀不轨的人手里结果不堪设想  
./Data\Keira\wavs\Keira_17.wav|Keira|ZH|再後悔也晚了  
./Data\Keira\wavs\Keira_18.wav|Keira|ZH|抱歉这话题太丧气了  
./Data\Keira\wavs\Keira_19.wav|Keira|ZH|我不應該提起來煞風景的  
./Data\Keira\wavs\Keira_2.wav|Keira|ZH|現在還不是時候  
./Data\Keira\wavs\Keira_20.wav|Keira|ZH|尤其是在我們的浪漫晚餐上  
./Data\Keira\wavs\Keira_21.wav|Keira|ZH|你知道森瑞卡尼亚人管那个星座叫什么吗  
./Data\Keira\wavs\Keira_22.wav|Keira|ZH|不對哦是個含義完全不一樣的名字  
./Data\Keira\wavs\Keira_23.wav|Keira|ZH|事实上有点下流  
./Data\Keira\wavs\Keira_24.wav|Keira|ZH|靠近一点我悄悄告诉你  
./Data\Keira\wavs\Keira_3.wav|Keira|ZH|好了,趕緊出去  
./Data\Keira\wavs\Keira_4.wav|Keira|ZH|你还挺乖的嘛现在差不多准备好了  
./Data\Keira\wavs\Keira_5.wav|Keira|ZH|我不是說差不多好了嗎  
./Data\Keira\wavs\Keira_6.wav|Keira|ZH|别打岔 看仔细了  
./Data\Keira\wavs\Keira_7.wav|Keira|ZH|那是没错但那样我就不会把你请到这儿来了  
./Data\Keira\wavs\Keira_8.wav|Keira|ZH|现在明白我为什么要那些材料了吧  
./Data\Keira\wavs\Keira_9.wav|Keira|ZH|如果我说 去树林里帮我取些食材 我要做晚餐

可以看到,medium模型对于中文的泛化效果一般,大多数素材都没有标注,但仅限于Whisper的medium模型。

现在我们来看看阿里的FunAsr:

复制代码
from modelscope.pipelines import pipeline  
from modelscope.utils.constant import Tasks  
  
  
  
from modelscope.hub.snapshot_download import snapshot_download  
  
# 指定本地目录  
local_dir_root = "./models_from_modelscope"  
model_dir = snapshot_download('damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch', cache_dir=local_dir_root)  
  
inference_pipeline = pipeline(  
    task=Tasks.auto_speech_recognition,  
    model=model_dir,  
    vad_model='damo/speech_fsmn_vad_zh-cn-16k-common-pytorch',  
    punc_model='damo/punc_ct-transformer_zh-cn-common-vocab272727-pytorch',  
    #lm_model='damo/speech_transformer_lm_zh-cn-common-vocab8404-pytorch',  
    #lm_weight=0.15,  
    #beam_size=10,  
)  
param_dict = {}  
param_dict['use_timestamp'] = False

这里首先指定模型目录,否则FunAsr会在C盘下载模型。

随后编写转写逻辑:

复制代码
def transcribe_one(audio_path):  
      
    rec_result = inference_pipeline(audio_in=audio_path, param_dict=param_dict)  
  
    print(rec_result["text"])  
  
    return "zh", rec_result["text"]

转写后效果:

复制代码
./Data\Keira\wavs\Keira_0.wav|Keira|ZH|光动嘴不如亲自做给你看。  
./Data\Keira\wavs\Keira_1.wav|Keira|ZH|等我一下呀,迫不及待了吗?  
./Data\Keira\wavs\Keira_10.wav|Keira|ZH|你还会帮我吗?真没想到你对葡萄酒也这么内行啊。  
./Data\Keira\wavs\Keira_11.wav|Keira|ZH|差不多吧。好了,聊了这么久,我都饿了。  
./Data\Keira\wavs\Keira_12.wav|Keira|ZH|还是赶紧开动吧,我自己能应付。  
./Data\Keira\wavs\Keira_13.wav|Keira|ZH|这些蛋啊、鸡啊、鹅啊的满地都是。  
./Data\Keira\wavs\Keira_14.wav|Keira|ZH|再说我的经济状况很快就要改善了。  
./Data\Keira\wavs\Keira_15.wav|Keira|ZH|因为我很清楚他的研究有多重要。  
./Data\Keira\wavs\Keira_16.wav|Keira|ZH|万一落入心怀不轨的人,手里,结果不堪设想。  
./Data\Keira\wavs\Keira_17.wav|Keira|ZH|再后悔也晚了。  
./Data\Keira\wavs\Keira_18.wav|Keira|ZH|哎呀,抱歉,这话题太丧气了。  
./Data\Keira\wavs\Keira_19.wav|Keira|ZH|我不应该提起来煞风景的。  
./Data\Keira\wavs\Keira_2.wav|Keira|ZH|现在还不是时候。  
./Data\Keira\wavs\Keira_20.wav|Keira|ZH|尤其是在我们的浪漫晚餐上。  
./Data\Keira\wavs\Keira_21.wav|Keira|ZH|你知道瑟瑞卡尼亚人管那个星座叫什么吗?  
./Data\Keira\wavs\Keira_22.wav|Keira|ZH|不对哦,是个含义,完全不一样的名字。  
./Data\Keira\wavs\Keira_23.wav|Keira|ZH|事实上有点下流。  
./Data\Keira\wavs\Keira_24.wav|Keira|ZH|靠近一点儿,我悄悄告诉你。  
./Data\Keira\wavs\Keira_3.wav|Keira|ZH|好了,赶紧出去。  
./Data\Keira\wavs\Keira_4.wav|Keira|ZH|你还挺乖的嘛,现在差不多准备好了。  
./Data\Keira\wavs\Keira_5.wav|Keira|ZH|我不是说差不多好了吗?  
./Data\Keira\wavs\Keira_6.wav|Keira|ZH|别打岔看仔细了。  
./Data\Keira\wavs\Keira_7.wav|Keira|ZH|那是没错,但那样我就不会把你请到这儿来了。  
./Data\Keira\wavs\Keira_8.wav|Keira|ZH|现在明白我为什么要那些材料了吧。  
./Data\Keira\wavs\Keira_9.wav|Keira|ZH|如果我说去树林里帮我取些食材,我要做晚餐。

可以看到,几乎不需要修改,而且每一条素材都进行了标注。

对比图如下:

FunAsr和Whisper对比 Large-v2 & Large-v3 vs speech_paraformer

当然,Medium并非whisper的最高水平,现在我们来换成大模型:

复制代码
def transcribe_one(audio_path):  
    model = whisper.load_model("large-v2")  
  
    # load audio and pad/trim it to fit 30 seconds  
    audio = whisper.load_audio(audio_path)  
    audio = whisper.pad_or_trim(audio)  
  
    # make log-Mel spectrogram and move to the same device as the model  
    mel = whisper.log_mel_spectrogram(audio).to(model.device)  
  
    # detect the spoken language  
    _, probs = model.detect_language(mel)  
    print(f"Detected language: {max(probs, key=probs.get)}")  
    lang = max(probs, key=probs.get)  
    # decode the audio  
    options = whisper.DecodingOptions(beam_size=5)  
    result = whisper.decode(model, mel, options)  
  
    # print the recognized text  
    print(result.text)  
    return lang, result.text

返回结果:

复制代码
./Data\Keira\wavs\Keira_0.wav|Keira|ZH|光动嘴不如亲自做给你看  
./Data\Keira\wavs\Keira_1.wav|Keira|ZH|等我一下呀迫不及待了嘛  
./Data\Keira\wavs\Keira_10.wav|Keira|ZH|你还会帮我吗真没想到你对葡萄酒也这么内行啊  
./Data\Keira\wavs\Keira_11.wav|Keira|ZH|差不多吧好了 聊了这么久我都饿了  
./Data\Keira\wavs\Keira_12.wav|Keira|ZH|还是赶紧开动吧我自己能应付  
./Data\Keira\wavs\Keira_13.wav|Keira|ZH|这些蛋啊 鸡啊 鹅啊 满地都是  
./Data\Keira\wavs\Keira_14.wav|Keira|ZH|再说我的经济状况很快就要改善了  
./Data\Keira\wavs\Keira_15.wav|Keira|ZH|因为我很清楚他的研究有多重要  
./Data\Keira\wavs\Keira_16.wav|Keira|ZH|万一落入心怀不轨的人手里结果不堪设想  
./Data\Keira\wavs\Keira_17.wav|Keira|ZH|再後悔也晚了  
./Data\Keira\wavs\Keira_18.wav|Keira|ZH|抱歉这话题太丧气了  
./Data\Keira\wavs\Keira_19.wav|Keira|ZH|我不應該提起來煞風景的  
./Data\Keira\wavs\Keira_2.wav|Keira|ZH|現在還不是時候  
./Data\Keira\wavs\Keira_20.wav|Keira|ZH|尤其是在我們的浪漫晚餐上  
./Data\Keira\wavs\Keira_21.wav|Keira|ZH|你知道森瑞卡尼亚人管那个星座叫什么吗  
./Data\Keira\wavs\Keira_22.wav|Keira|ZH|不對哦是個含義完全不一樣的名字  
./Data\Keira\wavs\Keira_23.wav|Keira|ZH|事实上有点下流  
./Data\Keira\wavs\Keira_24.wav|Keira|ZH|靠近一点我悄悄告诉你  
./Data\Keira\wavs\Keira_3.wav|Keira|ZH|好了,趕緊出去  
./Data\Keira\wavs\Keira_4.wav|Keira|ZH|你还挺乖的嘛现在差不多准备好了  
./Data\Keira\wavs\Keira_5.wav|Keira|ZH|我不是說差不多好了嗎  
./Data\Keira\wavs\Keira_6.wav|Keira|ZH|别打岔 看仔细了  
./Data\Keira\wavs\Keira_7.wav|Keira|ZH|那是没错但那样我就不会把你请到这儿来了  
./Data\Keira\wavs\Keira_8.wav|Keira|ZH|现在明白我为什么要那些材料了吧  
./Data\Keira\wavs\Keira_9.wav|Keira|ZH|如果我说 去树林里帮我取些食材 我要做晚餐

整体上的偏差并不大,但标注上略逊FunAsr一筹。

结语

Funasr的模型paraformer-zh受益于60000小时的纯人工标注的数据来训练,中文参数达到220M个,它的两个模块,一个是基于前馈顺序记忆网络(FSMN-VAD)的语音活动检测模型,另外一个是基于可控时延 Transformer(CT-Transformer),相比 OpenAI 的 Whisper 这两块能力还是比较突出的。

很难想象6w小时的数据还是纯手工标注,毕竟阿里财大气粗。

而Whisper 则用了 68w 小时的数据,从这个层面来看,FunASR 似乎没占便宜。但Whisper 针对的是全球市场,68w小时里面有多少中文素材就很难说了,因此 FunASR 的中文语音转写效果确实比 Whisper 更优秀。

相关推荐
打小就很皮...18 小时前
使用 React 实现语音识别并转换功能
人工智能·语音识别
会游泳的石头1 天前
在Java项目中实现本地语音识别与热点检测,并集成阿里云智能语音服务(优化版)
阿里云·语音识别·xcode
Hello server3 天前
利用 Python pyttsx3实现文字转语音(TTS)
python·学习·语音识别
limingade4 天前
手机打电话时由对方DTMF响应切换多级IVR语音应答(一)
人工智能·语音识别·手机实现来电ivr导航·多级ivr语音导航
create175 天前
使用 AI 如何高效解析视频内容?生成思维导图或分时段概括总结
人工智能·aigc·语音识别·ai写作
limingade6 天前
手机SIM卡打电话时识别对方按下的DTMF按键(二)
智能手机·语音识别·dtmf识别·dtmf解码器·sim卡通话识别dtmf·手机通话识别dtmf·手机通话语音拦截
xu_wenming6 天前
嵌入式MCU语音识别算法及实现方案
单片机·算法·语音识别
waterHBO6 天前
python + whisper 读取蓝牙耳机, 转为文字
python·whisper
瑶光守护者7 天前
【学习笔记】深度学习:典型应用
人工智能·笔记·深度学习·学习·计算机视觉·语音识别
打小就很皮...9 天前
前端 AI 开发实战:基于自定义工具类的大语言模型与语音识别调用指南
人工智能·语言模型·语音识别