如何构建FunASR的本地语音识别服务

FunASR 简介

FunASR 是阿里巴巴达摩院开源的高性能语音识别工具包,支持离线识别实时流式识别两种模式。其核心特点包括:

  • 支持多种语音任务:ASR(自动语音识别)、VAD(语音活动检测)、标点恢复、关键词检测等。
  • 提供预训练模型:覆盖中文、英文等多语言,支持不同场景(通用、会议、直播等)。
  • 支持多种部署方式:本地 Python、Docker 容器、ONNX 推理优化等。
  • 开源地址:GitHub - FunASR

一、本地 Python 部署

1. 克隆仓库
git clone https://github.com/modelscope/FunASR.git cd FunASR
2. 创建环境并安装依赖
# 创建 Conda 环境 conda create -n funasr python=3.9 conda activate funasr # 安装 PyTorch(CUDA 11.8 版本,CPU 版本需移除 `-c nvidia`) conda install pytorch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1 pytorch-cuda=11.8 -c pytorch -c nvidia # 安装 FunASR 及相关库 pip install -U funasr pip install -U modelscope huggingface huggingface_hub
3. 模型使用示例
from funasr import AutoModel # 加载 ASR 模型(中文通用) model = AutoModel( model="damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch", model_revision="v2.0.4" ) # 加载标点恢复模型(可选) punc_model = AutoModel( model="damo/punc_ct-transformer_zh-cn-common-vocab272727-pytorch", model_revision="v1.0.4" ) # 语音识别示例(输入为 16kHz 采样率的 WAV 文件) audio_file = "your_audio.wav" result = model(audio_in=audio_file) # 添加标点(可选) if result and punc_model: text = result[0]["text"] result_with_punc = punc_model(text) print("识别结果(带标点):", result_with_punc[0]["text"])

二、Docker 容器部署

1. 拉取 Docker 镜像
# CPU 版本 docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.6 # GPU 版本(需 NVIDIA 驱动和 Docker 支持) docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-gpu-0.4.6
2. 创建模型目录并启动容器
# 创建模型存储目录 mkdir -p ./funasr-runtime-resources/models # 启动 CPU 容器(映射端口 10095) docker run -p 10095:10095 -it --privileged=true \ -v $PWD/funasr-runtime-resources/models:/workspace/models \ registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.6
3. 启动服务(容器内执行)
cd FunASR/runtime # 启动完整服务(包含 VAD、ASR、标点恢复、语言模型等) nohup bash run_server.sh \ --download-model-dir /workspace/models \ --vad-dir damo/speech_fsmn_vad_zh-cn-16k-common-onnx \ --model-dir damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-onnx \ --punc-dir damo/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727-onnx \ --lm-dir damo/speech_ngram_lm_zh-cn-ai-wesp-fst \ --itn-dir thuduj12/fst_itn_zh \ --hotword /workspace/models/hotwords.txt > log.txt 2>&1 & # 关闭 SSL(添加 --certfile 0 参数) nohup bash run_server.sh ... --certfile 0 > log.txt 2>&1 &

三、基于 FastAPI 的 Web 服务实现

1. 服务端代码(asr_service.py
from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import JSONResponse import uvicorn import wave import numpy as np from funasr import AutoModel app = FastAPI(title="FunASR 语音识别服务") # 初始化模型 try: model = AutoModel( model="damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch", model_revision="v2.0.4" ) punc_model = AutoModel( model="damo/punc_ct-transformer_zh-cn-common-vocab272727-pytorch", model_revision="v1.0.4" ) except Exception as e: raise HTTPException(status_code=500, detail=f"模型加载失败: {str(e)}") @app.post("/asr") async def recognize_audio(file: UploadFile = File(...)): try: # 保存临时文件 temp_file = "temp_audio.wav" with open(temp_file, "wb") as f: f.write(await file.read()) # 检查音频格式(需 16kHz 采样率) with wave.open(temp_file, "rb") as wf: sample_rate = wf.getframerate() if sample_rate != 16000: return JSONResponse( content={"error": "请上传 16kHz 采样率的 WAV 文件"}, status_code=400 ) # 执行识别 result = model(audio_in=temp_file) # 添加标点(可选) if result and punc_model: text = result[0]["text"] result_with_punc = punc_model(text) result[0]["text_with_punctuation"] = result_with_punc[0]["text"] return {"result": result} except Exception as e: return JSONResponse(content={"error": str(e)}, status_code=500) finally: # 清理临时文件 import os if os.path.exists(temp_file): os.remove(temp_file) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000)
2. 启动服务
python asr_service.py
3. 客户端调用示例
import requests url = "http://localhost:8000/asr" audio_file = "test.wav" # 16kHz WAV 文件 with open(audio_file, "rb") as f: response = requests.post(url, files={"file": f}) if response.status_code == 200: print("识别结果:", response.json()) else: print(f"错误: {response.status_code}, {response.text}")

四、性能优化建议

  1. 模型选择

    • 轻量级模型:damo/speech_paraformer-tiny_asr_nat-zh-cn-16k-common(更快)
    • 通用模型:damo/speech_paraformer-large_asr_nat-zh-cn-16k-common(更准)
  2. 模型量化
    使用 ONNX 或 TensorRT 对模型进行量化,减少内存占用并提升推理速度。

  3. 批处理
    对多个音频文件进行批量处理,提高吞吐量。

  4. 缓存机制
    对相同音频的识别结果进行缓存,避免重复计算。

五、常见问题及解决方案

  1. CUDA 兼容性问题

    • 确保 PyTorch 版本与本地 CUDA 驱动匹配。
    • CPU 环境使用无 CUDA 的 PyTorch 版本。
  2. 模型下载失败

    • 手动下载模型并放置到指定路径。
    • 配置网络代理或使用国内镜像源。
  3. Docker 权限问题

    • 添加--privileged=true参数或调整容器权限。

通过以上步骤,可以构建一个完整的本地语音识别服务,支持实时语音转文字功能。

启动Fay数字人的语音服务方法如下:

安装启动funasr

1、进入Fay/asr/funasr代码目录

2、安装依赖

在终端或cmd中分别执行以下命令

pip install torch pip install modelscope pip install testresources pip install websockets==10.4 pip install torchaudio pip install FunASR

3、终端或cmd启动funasr服务端(保持启动)

python -u ASR_server.py --host "0.0.0.0" --port 10197 --ngpu 1

说明:--ngpu 0——CPU运行

--ngpu 1——GPU运行

启动后,默认端口为10197,系统配置代码中调用方式为:

local_asr_ip =(本地语音服务的电脑IP) local_asr_port = 10197

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1156118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「测试面试官手记」海投三个月零面试,一招拿到了心仪Offer!

真正的机会,从来不是大海捞针 海投简历,可能是这个时代求职者最大的自我安慰。 作为一名在测试行业摸爬滚打十多年的“老兵”,我见过太多同行陷入同一种困境:每天在招聘平台一键投出几十份简历,结果要么石沉大海&#…

给定一个二叉树,求其最近公共祖先

二叉树最近公共祖先(LCA)问题全解析:从理论到实践的完美指南 关键词 二叉树, 最近公共祖先, LCA算法, 树遍历, 递归, 数据结构, 算法优化 摘要 最近公共祖先(Lowest Common Ancestor, LCA)问题是二叉树操作中的经典问题,在计算机科学领域有着广泛的应用。本文将带领读者深…

Arduino下载安装教程:板卡支持包添加方法

Arduino板卡支持包怎么加?一文搞懂BSP背后的硬核逻辑 你是不是也遇到过这种情况:兴冲冲地下载安装好Arduino IDE,连上开发板,结果一编译就报错“找不到WiFi.h”或者“unknown board”?别急——这根本不是你的代码有问…

图网络的度矩阵D/邻接矩阵A/拉普拉斯矩阵L以及图中的节点如何各自保存更新节点特征

在开始前,我们明确几个概念度矩阵D/邻接矩阵A/拉普拉斯矩阵L分别是做什么的? 度矩阵D:描述一个节点能连接多少其他节点;邻接矩阵A: 描述一个节点具体和其他哪个节点连接;拉普拉斯矩阵L:LD-A描述一个节点的特…

车载电子PCB工艺选型要求:项目应用解析

车载电子PCB工艺选型实战指南:从设计到可靠的工程闭环为什么一块车规级PCB不能“照搬”消费类经验?你有没有遇到过这样的情况:同一块电路板,用在工控设备上稳定运行三年,放到发动机舱里却三个月就出现通信中断&#xf…

自动驾驶场景下的Android HMI开发:资深工程师职位深度解析

上海翰格企业管理咨询有限公司 Android资深开发工程师 职位信息 岗位描述:职位描述 1、基于自动驾驶场景需求,开发Android平台上的HMI应用程序,为用户提供友好直观的交互体验 2、整合地图、导航、传感器等系统模块,确保不同数据流在Android HMI系统中的无缝交互与显示 3、实…

XML处理:提取唯一ID的XSLT优化

在处理XML数据时,如何高效地提取唯一标识符(ID)是一项常见的挑战。今天,我们将探讨如何利用XSLT(Extensible Stylesheet Language Transformations)来实现这一目标。特别是,我们将聚焦于解决一个具体问题:从一个包含多个重复ID的XML文档中提取并统计唯一ID的数量。 问…

揭秘大模型 “胡说八道”:幻觉产生的底层原理与规避逻辑

1. 引言:大模型的“幻觉陷阱”离我们有多近当你向大模型询问“爱因斯坦发明了电灯吗”,它可能一本正经地告诉你“是的,爱因斯坦在1879年发明了电灯,这一发明改变了人类的照明方式”;当你让它撰写一篇关于环境治理的论文…

从文本到图像:多模态大模型跨域理解的核心技术原理

1. 引言:为什么“文本变图像”是AI跨域理解的关键突破在AI发展的早期,大多数模型都只能处理单一类型的信息:有的模型只能“读懂”文字,比如智能客服机器人;有的模型只能“看懂”图像,比如人脸识别系统。这种…

C语言中的逻辑与运算误区

在C语言编程中,逻辑运算符的理解和使用是每个程序员必须掌握的基本技能。然而,在实际编程中,很多初学者(甚至是一些经验丰富的程序员)可能会因为一些细微的误解而陷入困惑。今天,我们通过一个具体的例子来深入探讨C语言中的逻辑与运算(&&)。 问题背景 假设有一…

通过SMBus读取电源状态寄存器:操作指南

如何用SMBus读取电源状态寄存器?一文讲透原理与实战你有没有遇到过这样的问题:系统突然宕机,日志里却找不到原因,最后怀疑是电源异常,但又无法复现?在服务器、工业控制板或高性能嵌入式设备中,这…

GeoPandas绘图技巧:如何优雅地在地图上标注县城信息

引言 在使用GeoPandas进行地理数据可视化时,如何在同一张地图上叠加多个信息层并保持整洁清晰,是许多数据分析师和开发者面临的挑战。本文将结合实际案例,介绍如何利用GeoPandas的高级功能,实现在地图上标注县城的名称和面积信息。 GeoPandas简介 GeoPandas是Python的一…

别让错招毁了团队:入职背景调查,为企业把好人才第一关

“面试时思路清晰、态度积极,入职后却频频出错,连简历上的核心项目经验都是编造的”——这是HR小林最近的烦心事。一场看似成功的招聘,最终却让团队陷入返工内耗,还得重新开启招聘流程。其实,这类招聘“踩雷”的背后&a…

数据分析:自动计算近五个月平均值

在日常的工作中,处理大量的时间序列数据是常有的事,尤其当这些数据涉及到月度平均值的计算时,手动更新公式不仅繁琐,而且容易出错。今天我们要讨论如何使用Google Sheets的公式来自动计算并显示过去五个月的平均值,避免了手动调整VLOOKUP等公式的麻烦。 问题背景 假设我…

核心要点:如何判断是STLink损坏还是配置错误

如何精准判断STLink是真坏了还是配置翻车?从物理连接到固件调试的全链路排障实战 你有没有经历过这样的时刻? 刚坐下准备烧个程序,打开STM32CubeProgrammer,点“Connect”——结果弹出一个冷冰冰的提示: No ST-LINK…

AWS云从业者认证(AWS Certified Cloud Practitioner)

一、认证介绍AWS云从业者认证(AWS Certified Cloud Practitioner)是亚马逊云科技(AWS)推出的一系列认证考试中最基础,最入门的一门。它特别适合对云计算和AWS平台了解不多的"小白"或非IT行业从业者,是进入云计算领域的敲门砖。二、考试内容与目…

深入浅出:Java邮件发送中的换行问题

在Java编程中,发送电子邮件是一个常见的任务。然而,当我们尝试在邮件内容中插入换行时,可能会遇到一些意想不到的问题。今天,我们将详细探讨在Java中如何正确地在邮件内容中使用换行符,并通过一个具体的实例来解释这些问题。 问题背景 在Java中,字符串中的换行符通常用…

Proteus仿真环境下单片机定时器配置实战案例

在Proteus中玩转定时器:从代码配置到仿真验证的完整实战你有没有过这样的经历?写完一段定时器中断代码,烧进单片机却发现LED不闪、频率不对,甚至程序直接跑飞。反复查寄存器、对晶振、看延时计算……调试半天,最后发现…

深入理解XPath文本节点的选取

在Web开发中,XPath是一种强大的工具,用于在HTML或XML文档中定位节点。今天,我们将深入探讨XPath在处理文本节点时的一个常见问题,并通过实际的HTML例子来解释如何正确地使用XPath。 问题描述 假设我们有一个HTML片段如下&#x…

STLink与STM32怎么接线?一文说清基本连接步骤

STLink与STM32怎么接线?一文讲透调试连接的底层逻辑与实战要点在嵌入式开发中,一个看似简单的问题——STLink与STM32怎么接线,却常常让不少工程师卡在项目起步阶段。你有没有遇到过这样的情况:代码写好了,IDE也配置完毕…