FunASR语音识别(解决-高并发线程问题)

这篇具有很好参考价值的文章主要介绍了FunASR语音识别(解决-高并发线程问题)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、FunASR

在我的另一个博客有介绍FunASR,并且进行了语者分离,不过最近FunASR自带了语者分离,挺好挺好,但是一直看社区就是大家都用python写,会出现线程不安全问题,群里有大佬说使用多台服务器,然后用nginx做代理,这不是妥妥土豪行为吗,感觉很浪费

vad出现的问题
funasr 自动分段,语音识别,人工智能
funasr 自动分段,语音识别,人工智能
funasr 自动分段,语音识别,人工智能

方案解决:
图上部分是大佬给的解决方案
图下部分是我给的解决方案方案

funasr 自动分段,语音识别,人工智能

二、我的方案:上代码(队列解决线程并发问题)

import os

import uuid

import copy

import json

import logging

import queue

import threading



import numpy as np

import torch

from flask import Flask

from flask import request, jsonify

from modelscope.pipelines import pipeline

from modelscope.utils.constant import Tasks



app = Flask(__name__)

# 创建一个队列

pipeline_queue = queue.Queue()

# 实例对象的计数器来存储实例的数量

created_instances = 0

# logging.basicConfig(filename='app.log', level=logging.INFO)

# logger = logging.getLogger('info')

# # 再创建一个handler,用于输出到控制台

# ch = logging.StreamHandler()

# ch.setLevel(logging.INFO)

# # 定义handler的输出格式

# formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# ch.setFormatter(formatter)

# # 给logger添加handler

# logger.addHandler(ch)





def flask_content_type(req) -> dict:

    """根据不同的content_type来解析数据"""

    if req.method == 'POST' or req.method == "PUT":

        if 'application/x-www-form-urlencoded' == req.content_type or 'form-data' in req.content_type:

            data = req.form

        else:  # 无法被解析出来的数据

            if req.data:

                data = json.loads(req.data)

            else:

                raise Exception('无法解析')

    elif req.method == 'GET':

        data = req.args

    else:

        raise Exception('不支持的请求方式')

    return copy.copy(data)





def create_pipelines(num_pipelines):

    """

    @Description:num_pipelines:创建pipeline实例的数量,根据你的显存大小创建,一个实例需要占用2GB

    """

    for _ in range(num_pipelines):

        global created_instances

        inference_pipeline = pipeline(

            task=Tasks.auto_speech_recognition,

            model='/root/autodl-tmp/models_from_modelscope/damo/speech_paraformer-large-vad-punc-spk_asr_nat-zh-cn',

            model_revision='v0.0.2',

            vad_model='/root/autodl-tmp/models_from_modelscope/damo/speech_fsmn_vad_zh-cn-16k-common-pytorch',

            punc_model='/root/autodl-tmp/models_from_modelscope/damo/punc_ct-transformer_cn-en-common-vocab471067-large')

        pipeline_queue.put(inference_pipeline)

        print("=========成功创建实例=========")

        # 更新已创建实例的数量

        created_instances += 1

        print(f"=====队列现有空闲实例数量为{pipeline_queue.qsize()}========")

        print(f"=====实例总数量数量为{created_instances}========")

        print("============================")





def create_pipelines_thread(num_pipelines):

    # 创建线程

    thread = threading.Thread(target=create_pipelines, args=(num_pipelines,))

    # 启动线程

    thread.start()

    return thread





def default_dump(obj):

    """Convert numpy classes to JSON serializable objects."""

    if isinstance(obj, (np.integer, np.floating, np.bool_)):

        return obj.item()

    elif isinstance(obj, np.ndarray):

        return obj.tolist()

    else:

        return obj





@app.route('/queue_size', methods=['GET'])

def get_queue_size():

    # 获取队列数量

    queue_size = pipeline_queue.qsize()



    # 构建响应

    response = {

        'queue_size': queue_size

    }



    # 返回响应

    return jsonify(response), 200





@app.route('/created_instances', methods=['GET'])

def get_created_instances():

    # 获取已创建的实例数量

    response = {

        'created_instances': created_instances

    }

    # 返回响应

    return jsonify(response), 200





@app.route('/add_pipeline/<int:num>', methods=['GET'])

def add_pipeline_queue(num):

    global created_instances

    if (created_instances >= 10):

        return jsonify({'error': f"现有实例数量为{created_instances},无法再添加"})



    print("=========开始创建实例=========")

    print(f"=====队列现有空闲实例数量为{pipeline_queue.qsize()}========")

    thread = create_pipelines_thread(num)

    # 等待线程结束

    thread.join()

    print("=========实例创建结束=========")

    print(pipeline_queue.qsize())



    return jsonify({'success': f"队列现有空闲实例数量为{pipeline_queue.qsize()}!现有实例数量为{created_instances}"})





@app.route('/', methods=['POST'])

def result_test():

    dates = flask_content_type(request).copy()

    print(dates)

    return jsonify({'success': dates})





@app.route('/transcribe', methods=['POST'])

def transcribe():

    print("======队列剩余======")

    print(pipeline_queue.qsize())

    # 第一步,获取请求体



    if 'audio_file' in request.files:

        audio_file = request.files['audio_file']

        file_ext = os.path.splitext(audio_file.filename)[1]

        if file_ext.lower() not in ['.wav', '.mp3']:

            return jsonify({'error': str('Error: Audio file must be either .wav or .mp3')}), 500

        else:

            try:

                # 将音频文件保存到临时文件夹中

                temp_dir_path = 'temp'

                if not os.path.exists(temp_dir_path):

                    os.makedirs(temp_dir_path)

                # 保存上传的临时文件

                file_extension = os.path.splitext(audio_file.filename)[1]

                unique_filename = str(uuid.uuid4()) + file_extension

                temp_file_path = os.path.join(temp_dir_path, unique_filename)

                audio_file.save(temp_file_path)

                return start_asr(temp_file_path)



            except Exception as e:

                return jsonify({'error': str(e)}), 500

            finally:

                # 删除临时文件

                os.remove(temp_file_path)



    else:

        dates = flask_content_type(request).copy()

        return start_asr(dates['file_url'])





def start_asr(temp_file_path):

    import time



    # 记录开始时间

    start_time = time.time()

    inference_pipeline = pipeline_queue.get()

    # 使用 inference pipeline 进行语音转写

    asr_result = inference_pipeline(audio_in=temp_file_path, batch_size_token=5000,

                                    batch_size_token_threshold_s=40,

                                    max_single_segment_time=6000)

    try:

        transform = time.time() - start_time



        asr_result["transform_time"] = transform



        # 将语音识别结果转换为json格式

        result = json.dumps(asr_result, ensure_ascii=False, default=default_dump)

        return result

    except Exception as e:

        print(str(e))

        # 返回错误信息

        return jsonify({'error': str(e)}), 500

    finally:

        pipeline_queue.put(inference_pipeline)





def start_flask_app(port):

    """

    启动 Flask 应用程序并运行在指定端口上

    在调用 Flask 的 app.run 方法后,应用会进入监听状态,等待客户端发起请求。这意味着应用会一直停留在 app.run() 这一行,不会继续执行后续的 Python 代码。

    启动 Flask 应用程序前,使用多线程的方式创建:我这里是32G显存所以默认创建10个实例

    """

    print("============================")

    print("======开始异步创建实例=========")

    print("============================")

    try:

        # 清除显卡

        torch.cuda.empty_cache()



    except Exception as e:

        # 返回错误信息

        print(e)

    create_pipelines_thread(5)

    app.run(port=port)





if __name__ == '__main__':

    start_flask_app(9501)

三、测试

二已经给你完整的示例了,所以我就不测了,我都上生产了,你们自己用postman或者代码试一下把!有问题再联系我18956043585(微信同号)
兄弟们,这是我的解决方案,欢迎交流,如果有帮助,或者有问题,欢迎回来留言,分享一下你的兴奋

funasr 自动分段,语音识别,人工智能
funasr 自动分段,语音识别,人工智能
funasr 自动分段,语音识别,人工智能文章来源地址https://www.toymoban.com/news/detail-794914.html

到了这里,关于FunASR语音识别(解决-高并发线程问题)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于python环境下的语音转文本,whisper或funASR

            因为前阵子,有需求要将语音转为文本再进行下一步操作。感觉这个技术也不算是什么新需求,但是一搜,都是大厂的api,或者是什么什么软件,由于想要免费的,同时也要嵌入在代码中,所以这些都不能用。、         一筹莫展的时候,突然搜到whisper,这是个o

    2024年02月08日
    浏览(46)
  • FunASR服务器安装

    请注意安装环境,根据官网中快速开始不可以使用,需要先安装conda,官方文档: https://alibaba-damo-academy.github.io/FunASR/en/installation/installation_zh.html 执行命令: wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh 继续执行命令: sh Miniconda3-latest-Linux-x86_64.sh 执行此命令后会

    2024年04月28日
    浏览(23)
  • ubuntu使用whisper和funASR-语者分离-二值化

    这个镜像可以 python -m pip install --upgrade pip 我在另一篇博客也写道,互相交流学习 whisper-深入-语者分离 2.1.1安装基础包 2.1.2安装依赖 代码调用 创建key https://huggingface.co/settings/tokens 创建代码 cache_dir:模型啥的下载后存放位置 use_auth_token :创建的key 报错ModuleNotFoundError: No module

    2024年02月05日
    浏览(46)
  • Achronix推出基于FPGA的加速自动语音识别解决方案

    提供超低延迟和 极低 错误率 ( WER )的 实时流式语音 转 文本解决方案,可同时运行超过 1000 个并发语音流 2023 年 11 月 ——高性能FPGA芯片和嵌入式FPGA(eFPGA IP)领域的领先企业Achronix半导体公司日前自豪地宣布:正式推出Achronix与Myrtle.ai合作的最新创新——基于Speedster7t

    2024年01月17日
    浏览(40)
  • 语音识别功能测试:90%问题,可以通过技术解决

    现在市面上的智能电子产品千千万,为了达到人们使用更加方便的目的,很多智能产品都开发了语音识别功能,用来语音唤醒进行交互;另外,各大公司也开发出来了各种智能语音机器人,比如小米公司的“小爱”,百度公司的“小度”,三星公司的“bixby”,苹果的“siri”

    2024年02月03日
    浏览(43)
  • 高并发场景下,6种解决SimpleDateFormat类的线程安全问题方法

    摘要: 解决SimpleDateFormat类在高并发场景下的线程安全问题可以有多种方式,这里,就列举几个常用的方式供参考。 本文分享自华为云社区《【高并发】更正SimpleDateFormat类线程不安全问题分析的错误》,作者: 冰 河 。 解决SimpleDateFormat类在高并发场景下的线程安全问题可以

    2024年02月11日
    浏览(45)
  • 解决在使用 Elasticsearch(ES)多线程批量操作时导致并发一致性的问题!!

    先说一下什么是数据库数据库中 并发一致性 问题! 1、在并发环境下,事务的隔离性很难保证,因此会出现很多并发一致性问题。 数据丢失 T1 和 T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。 读脏数据 T1 修改一个数据,T2 随后读取

    2024年02月04日
    浏览(54)
  • 智能家居(2)---串口通信(语音识别)控制线程封装

    封装语音线程(语音通过串口和主控设备进行交流)实现对智能家居中各种灯光的控制 mainPro.c(主函数) inputCommand.h(控制类) voiceControl.c(语音)

    2024年02月13日
    浏览(45)
  • 【linux 多线程并发】线程退出自动清理函数的使用,释放线程申请的资源,异常退出自动调用

    ​ 专栏内容 : 参天引擎内核架构 本专栏一起来聊聊参天引擎内核架构,以及如何实现多机的数据库节点的多读多写,与传统主备,MPP的区别,技术难点的分析,数据元数据同步,多主节点的情况下对故障容灾的支持。 手写数据库toadb 本专栏主要介绍如何从零开发,开发的

    2024年02月02日
    浏览(47)
  • 什么是自动语音识别?

    在人工智能发展和全球疫情的双重作用下,企业加强了与客户的线上沟通。企业越发依赖于虚拟助手、聊天机器人以及其他的语音技术,以实现与客户的高效互动。这几类人工智能,都是依赖于自动语音识别技术,简称为ASR。ASR涉及到将语音转换为文本,促使计算机理解人类

    2024年02月10日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包