深度学习应用-WeNet语音识别实战01

概括

        本文对WeNet声音识别网络的Python API上介绍的Non-Streaming Usage和 Streaming-Usage分别做了测试,两者本质相同。API对应采样的声音帧率、声道都做了限制。效果还可以,但是部分吐字不清晰、有歧义的地方仍然不能识别清晰。

项目地址:

GitHub - wenet-e2e/wenet: Production First and Production Ready End-to-End Speech Recognition Toolkit

安装:

pip3 install wenetruntime

根据项目要求,python版本必须3.6+,这里为3.8.3, 因此没有问题

应用案例:

官方文档上分为非流式和流式两种,本次先演示非流式应用:

非流式:

第一步:压缩wav文件,根据测试,api使用wave库打开文件。且仅支持单声道、固定帧率。

import wave
with wave.open(wav_file, 'rb') as fin:
    assert fin.getnchannels() == 1
    assert fin.getsampwidth() == 2
    assert fin.getframerate() == 16000

第二步:我准备用来识别的《起风了》wav格式显然不符合要求,使用pydub来压缩帧率、合并为单声道。同时,文件太长也不行。例如全歌一起识别会报错,因此我这里切割,每次取十分之一的歌词内容(约28秒的内容)

# 压缩文件
from pydub import AudioSegment
sound = AudioSegment.from_wav("/root/jupyterprojects/data/起风了.wav")

# 双声道变为单声道
sound = sound.set_channels(1)

# 压缩帧率
sound = sound.set_frame_rate(16000)

# 长度太长了可能会塞爆,每次取十分之一
musicLen = len(sound) 
unitLen = musicLen / 10

for i in range(10):
    _sound = sound[unitLen*i:unitLen*(i+1)]
    _sound.export("/root/jupyterprojects/data/起风了-sub%s.wav" % i, format="wav")

第三步:加载模型、识别。如果不提供model_dir参数,则默认会从github上下载。包比较大,建议提前下载好。

import sys
import torch
import wenetruntime as wenet
# 下载https://github.com/wenet-e2e/wenet/releases/download/v2.0.1/chs.tar.gz
# 并解压缩到/root/.wenet/chs目录下
decoder = wenet.Decoder(model_dir="/root/.wenet/chs/chs/",lang='chs')

第四步:识别。

decoder.decode_wav函数返回一个可以转换为字典的字符串。

import glob
files = glob.glob("/root/jupyterprojects/data/起风了-sub?.wav")
for idx,file in enumerate(files):
    ans=eval(decoder.decode_wav(file))
    print(idx,": ", ans["nbest"][0]["sentence"])

 正确的歌词:

我曾将青春翻涌成她
也曾指尖弹出盛夏
心之所动 且就随缘去吧

这一路上走走停停
顺着少年漂流的痕迹
迈出车站的前一刻
竟有些犹豫
不禁笑这近乡情怯
仍无可避免
而长野的天
依旧那么暖
风吹起了从前
从前初识这世间

万般流连
看着天边似在眼前
也甘愿赴汤蹈火去走它一遍
如今走过这世间
万般流连
翻过岁月不同侧脸
措不及防闯入你的笑颜
我曾难自拔于世界之大
也沉溺于其中梦话
不得真假 不做挣扎 不惧笑话
我曾将青春翻涌成她
也曾指尖弹出盛夏
心之所动 且就随缘去吧
逆着光行走 任风吹雨打
短短的路走走停停
也有了几分的距离
不知抚摸的是故事 还是段心情
也许期待的不过是 与时间为敌
再次看到你
微凉晨光里
笑得很甜蜜
从前初识这世间
万般流连
看着天边似在眼前
也甘愿赴汤蹈火去走它一遍
如今走过这世间
万般流连
翻过岁月不同侧脸
措不及防闯入你的笑颜
我曾难自拔于世界之大
也沉溺于其中梦话
不得真假 不做挣扎 不惧笑话
我曾将青春翻涌成她
也曾指尖弹出盛夏
心之所动 且就随缘去吧
晚风吹起你鬓间的白发
抚平回忆留下的疤
你的眼中 明暗交杂 一笑生花
暮色遮住你蹒跚的步伐
走进床头藏起的画
画中的你 低着头说话
我仍感叹于世界之大
也沉醉于儿时情话
不剩真假 不做挣扎 无谓笑话
我终将青春还给了她
连同指尖弹出的盛夏
心之所动 就随风去了
以爱之名 你还愿意吗

其实还可以,有些歌词吐字本身就不是很清晰。

流式应用(Streaming Usage)

这是官方文档给出的应用案例,看起来我这里的切割歌曲法并没有什么异同,略。

import sys
import torch
import wave
import wenetruntime as wenet

test_wav = sys.argv[1]

with wave.open(test_wav, 'rb') as fin:
    assert fin.getnchannels() == 1
    wav = fin.readframes(fin.getnframes())

decoder = wenet.Decoder(lang='chs')
# We suppose the wav is 16k, 16bits, and decode every 0.5 seconds
interval = int(0.5 * 16000) * 2
for i in range(0, len(wav), interval):
    last = False if i + interval < len(wav) else True
    chunk_wav = wav[i: min(i + interval, len(wav))]
    ans = decoder.decode(chunk_wav, last)
    print(ans)

为了确定两者本质没有区别,这里查看API源代码. 可以看到decode_wav 就是相当于帮你用wave库打开wav文件并传递给decode方法。

 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>