如何构建FunASR的本地语音识别服务
FunASR 简介
FunASR 是阿里巴巴达摩院开源的高性能语音识别工具包,支持离线识别和实时流式识别两种模式。其核心特点包括:
- 支持多种语音任务:ASR(自动语音识别)、VAD(语音活动检测)、标点恢复、关键词检测等。
- 提供预训练模型:覆盖中文、英文等多语言,支持不同场景(通用、会议、直播等)。
- 支持多种部署方式:本地 Python、Docker 容器、ONNX 推理优化等。
- 开源地址:GitHub - FunASR
一、本地 Python 部署
1. 克隆仓库
git clone https://github.com/modelscope/FunASR.gitcd FunASR
2. 创建环境并安装依赖
# 创建 Conda 环境conda create -n funasr python=3.9conda 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 funasrpip 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, HTTPExceptionfrom fastapi.responses import JSONResponseimport uvicornimport waveimport numpy as npfrom funasr import AutoModelapp = 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 requestsurl = \"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}\")
四、性能优化建议
-
模型选择:
- 轻量级模型:
damo/speech_paraformer-tiny_asr_nat-zh-cn-16k-common
(更快) - 通用模型:
damo/speech_paraformer-large_asr_nat-zh-cn-16k-common
(更准)
- 轻量级模型:
-
模型量化:
使用 ONNX 或 TensorRT 对模型进行量化,减少内存占用并提升推理速度。 -
批处理:
对多个音频文件进行批量处理,提高吞吐量。 -
缓存机制:
对相同音频的识别结果进行缓存,避免重复计算。
五、常见问题及解决方案
-
CUDA 兼容性问题:
- 确保 PyTorch 版本与本地 CUDA 驱动匹配。
- CPU 环境使用无 CUDA 的 PyTorch 版本。
-
模型下载失败:
- 手动下载模型并放置到指定路径。
- 配置网络代理或使用国内镜像源。
-
Docker 权限问题:
- 添加
--privileged=true
参数或调整容器权限。
- 添加
通过以上步骤,可以构建一个完整的本地语音识别服务,支持实时语音转文字功能。