FunASR语音转文字

之前写过一些语音识别的方案:

  • Whisper,识别速度和识别精度是反比的,如果想要识别速度变快,那就只能使用小的模型,但识别精度就很差了。
  • PaddleSpeech,它推理速度较慢,部署的时候依赖性比较麻烦,而且官方仓库的维护简直就是依托答辩。
  • Windows的语音识别,识别挺快,但是有的时候会出现开机后这项服务无法使用的问题,属于偶发性。

但是阿里新开源的FunASR就比较厉害了,识别速度快,精度高。所以以后我使用的语音转文字识别,都将改为FunASR了。

FunASR的部署可以使用Docker,但我是想让它运行在Windows中,所以使用Python本地部署。

1.下载FunASR仓库

github仓库链接:https://github.com/modelscope/FunASR

直接下载仓库Zip文件。

2.创建虚拟环境

要求:

  • python≥3.8
  • torch≥1.13
  • torchaudio

虚拟环境的创建步骤略过。

3.安装库

分别执行以下命令:

pip install -e ./

pip install modelscope

pip install torch torchaudio   //注意这里的torch是cpu版本,如果要使用GPU版本,请根据cuda版本和python版本进行安装

4.运行示例

运行runtime/python/websocket文件夹下的funasr_wss_server.py文件。

注意:这里运行示例文件是为了下载模型文件,模型文件会被下载到当前电脑用户的.cache/modelscope/hub/iic文件夹中。当然,也可以手动下载模型并放到这个目录下,如果手动下载模型的话,就不需要执行这一步了。

5.测试识别

在仓库根目录下新建一个test.py文件,并输入代码:

from funasr import AutoModel
import datetime

# paraformer-zh is a multi-functional asr model
# use vad, punc, spk or not as you need
model = AutoModel(model="paraformer-zh",  vad_model="fsmn-vad", punc_model="ct-punc")


res = model.generate(input=f"要识别的wav文件路径",
            batch_size_s=300,
            hotword='魔搭')
print(res)

修改代码中的要识别的wav文件路径,然后运行这个test.py,正常的话将看到这样的输出:

我是在PyCharm中运行的,所以红色部分其实是FunASR自带的加载模型、推理模型的输出内容,不影响使用。我们需要的是最后的白色文本,这才是对音频文件的识别结果。

到这里,FunASR就本地部署好了。如果要做成服务端,就用Flask框架写一个接口就好了,这个接口接收上传的音频文件,并调用模型识别,然后返回json结果。其他程序如Unity只需要发送http请求,就能获得识别结果。

经过实测,小段落文本的识别速度几乎都是0秒,相当于秒识别,这个速度很快了。

6.Flask接口(补充)

新建一个mainflask.py文件,并输入代码:

from flask import Flask, request
from werkzeug.utils import secure_filename
import os
from funasr import AutoModel
import datetime
import threading
import time
import json

app = Flask(__name__)


def loadmodel():
    global model, loadedmodel
    loadedmodel = False
    model = AutoModel(model="paraformer-zh", vad_model="fsmn-vad", punc_model="ct-punc")
    loadedmodel = True


@app.route('/upload', methods=['POST'])
def upload_wav():
    # 检查是否有文件在请求中
    if 'file' not in request.files:
        return 'No file part', 400

    time1 = datetime.datetime.now()

    file = request.files['file']
    # 如果用户没有选择文件,浏览器也会提交一个没有文件名的空部分
    if file.filename == '':
        return 'No selected file', 400

    if file:
        filename = secure_filename(file.filename)
        # 确保文件扩展名为wav
        if filename.lower().endswith('.wav'):
            filePath = os.path.join('./upload', filename)
            file.save(filePath)

            res = model.generate(input=filePath,
                                 batch_size_s=300,
                                 hotword='魔搭')
            print((datetime.datetime.now() - time1).seconds)
            print(res)
            return json.dumps(res, ensure_ascii=False), 200
        else:
            return 'Incorrect file type', 400


if __name__ == '__main__':
    thread = threading.Thread(target=loadmodel)
    thread.start()
    global loadedmodel
    while loadedmodel == False:
        time.sleep(1)

    app.run(host="127.0.0.1", port=5000)

然后在仓库的根目录下新建一个upload文件夹,用来保存每次接口上传的音频文件。

然后运行这个mainflask.py文件,就可以访问/upload接口并上传音频文件进行识别了。