FunASR 运行时快速上手:Python WebSocket 服务与 Docker 服务化部署实战
【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR
本文基于 FunASR 仓库的 运行时快速入门文档,系统讲解 FunASR 推理服务的两条落地路径:一条是用 Python WebSocket 服务快速搭起支持实时流式、非流式与 2pass 混合识别的 ASR 服务;另一条是用 Docker 部署 C++ 服务化 SDK,实现高并发的文件转写与低延迟实时识别。读完后,你可以独立完成 FunASR 服务的安装、启动、参数配置与客户端联调,并能对照仓库源码理解 2pass 流水线、并发限流与线程模型的底层设计。
一、FunASR 运行时的三种使用方式
FunASR 的运行时(runtime/)围绕三类场景组织:
- Service Deployment SDK(服务部署 SDK):以 WebSocket 协议对外提供识别服务,分为 Python 版(开发验证、中小并发)和 C++ 版(生产环境最大吞吐);
- 工业模型 egs(Industrial model egs):针对工业级预训练模型的推理/微调示例,位于 examples/industrial_data_pretraining/;
- 学术模型 egs(Academic model egs):Aishell、Wenetspeech 等学术数据集上的模型示例,位于 examples/。
本文聚焦第一种方式——服务部署,这也是生产落地最常用的路径。
二、路径一:Python 版 WebSocket 服务
Python 版服务位于 runtime/python/websocket/,支持实时流式语音识别,并使用非流式模型做纠错、输出带标点的文本。服务端现已支持多客户端并发与非阻塞推理(通过--concurrent_vad / --concurrent_asr_online / --concurrent_asr_offline / --concurrent_punc / --concurrent_sv调节各阶段并发度);文档同时指出,若追求最大吞吐,仍建议使用下文介绍的 C++ 版服务部署 SDK。
2.1 环境准备
服务端与客户端依赖在 runtime/python/websocket/README.md 中给出:
pip install -U modelscope funasr git clone https://github.com/modelscope/FunASR.git && cd FunASR # 服务端依赖(核心依赖即 websockets,见 requirements_server.txt) cd runtime/python/websocket pip install -r requirements_server.txt # 客户端依赖 pip install -r requirements_client.txt若要从视频文件识别,客户端机器需安装ffmpeg。客户端从麦克风推流时还需要pyaudio(源码中record_microphone()会显式检查并给出提示)。
2.2 服务端部署
最简启动命令:
cd runtime/python/websocket python funasr_wss_server.py --port 10095服务端的完整参数(结合 funasr_wss_server.py 源码整理):
| 参数 | 默认值 | 说明 |
|---|---|---|
--host | 0.0.0.0 | 监听地址 |
--port | 10095 | WebSocket 服务端口 |
--asr_model | iic/speech_paraformer-large-contextual_asr_nat-zh-cn-16k-common-vocab8404 | 非流式(离线纠错)ASR 模型 |
--asr_model_online | iic/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online | 流式 ASR 模型 |
--vad_model | iic/speech_fsmn_vad_zh-cn-16k-common-pytorch | FSMN-VAD 模型 |
--punc_model | iic/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727 | 标点模型,传空字符串可关闭 |
--ngpu | 1 | 0表示纯 CPU,1表示使用 GPU |
--device | cuda | 推理设备(cuda/cpu) |
--ncpu | 4 | CPU 线程数 |
--certfile/--keyfile | ../../ssl_key/server.crt/server.key | SSL 证书,对应仓库 runtime/ssl_key/,证书为空则走明文 ws |
--worker_threads | max(4, CPU核数) | 线程池大小,将阻塞推理 offload 出事件循环 |
--concurrent_vad | 4 | VADgenerate()最大并发 |
--concurrent_asr_online | 4 | 流式 ASR 最大并发 |
--concurrent_asr_offline | 2 | 离线 ASR 最大并发 |
--concurrent_punc | 1 | 标点模型最大并发 |
--concurrent_sv | 1 | 声纹(SV)最大并发 |
--speaker_db_reload_sec | 5 | speaker_db.json 最长重载间隔(秒),避免频繁磁盘 IO |
--save_offline_segments | 关闭 | 开启后将 2pass 送入离线 ASR 的每段音频存为 wav,用于排查 VAD 切分 |
从源码结构看,服务启动时会通过AutoModel一次性加载五个模型:离线 ASR(paraformer-zh)、流式 ASR、FSMN-VAD、标点 CT-Transformer,以及用于声纹匹配与说话人归属的 cam++ 声纹模型(iic/speech_campplus_sv_zh-cn_16k-common,见 funasr_wss_server.py)。
2.3 2pass 流水线与并发限流的实现原理
服务端的核心处理逻辑集中在ws_serve()协程中(funasr_wss_server.py),2pass 模式的执行脉络为:
- 配置消息先行:客户端可先发送 JSON 文本消息设置
is_speaking、chunk_size、chunk_interval、hotwords、mode、audio_fs等会话参数;音频帧在chunk_size配置完成前会被丢弃并记录错误; - 在线流式识别:每累计
chunk_interval帧(默认 10 帧)就把已累积 PCM 交给流式模型增量识别,产出 partial 文本; - VAD 驱动离线触发:FSMN-VAD 在线输出
speech_start_i / speech_end_i,语音起点触发时回溯补齐起点前的音频,语音终点(或客户端发送is_speaking: false)触发离线阶段; - 离线纠错:把整段语音送入非流式 Paraformer 精识别,再做声纹匹配与标点补全,输出带
spk_name、text、timestamp、punc_array的最终结果; - 结束确认(ack):客户端发送
{"is_speaking": false, "is_end": true}后,服务端先 flush 未完成的在线/离线推理,再回复{"is_end": true, "is_final": true};若推理失败,ack 中携带{"is_end": true, "is_final": false, "error": "..."}。
并发控制采用「线程池 + 信号量」双层设计:run_blocking()把阻塞的model.generate()调用丢进ThreadPoolExecutor,避免卡住 asyncio 事件循环;同时每个阶段配一个asyncio.Semaphore限流(SEM_VAD、SEM_ASR_ONLINE、SEM_ASR_OFFLINE、SEM_PUNC、SEM_SV),防止多客户端同时涌入时把 GPU/模型打爆(见 funasr_wss_server.py)。这也是文档中「非阻塞推理、多客户端并发」说法的直接来源。
2.4 客户端测试
最简 2pass 客户端:
python funasr_wss_client.py --host "127.0.0.1" --port 10095 --mode 2pass --chunk_size "5,10,5"关键参数说明(依据 funasr_wss_client.py 与 runtime/python/websocket/README.md):
| 参数 | 默认值 | 说明 |
|---|---|---|
--mode | 2pass | online(流式)、offline(非流式)、2pass(流式+非流式统一) |
--chunk_size | "5, 10, 5" | 流式模型分块参数;"5,10,5"对应 600ms,"8,8,4"对应 480ms |
--chunk_interval | 10 | 每多少个发送间隔触发一次推理,如"10"=60ms、"5"=120ms、"20"=30ms |
--audio_in | 不填 | 填 wav.scp(Kaldi 风格)则读文件,否则从麦克风录音 |
--output_dir | 不填 | 设置后把识别结果写入该目录 |
--thread_num | 1 | 并发发送线程数 |
--result_timeout | 300.0 | 等待服务端「输入结束确认」的超时秒数 |
--ssl | 1 | 1走 SSL 连接,0明文 |
三种模式的典型调用(麦克风输入):
# 离线:非流式模型逐文件识别 python funasr_wss_client.py --host "0.0.0.0" --port 10095 --mode offline # 流式:低延迟在线识别 python funasr_wss_client.py --host "0.0.0.0" --port 10095 --mode online --chunk_size "5,10,5" # 2pass:在线出 partial,离线出 final python funasr_wss_client.py --host "0.0.0.0" --port 10095 --mode 2pass --chunk_size "8,8,4"批量识别 wav.scp 并落盘:
python funasr_wss_client.py --host "0.0.0.0" --port 10095 --mode 2pass \ --chunk_size "8,8,4" --audio_in "./data/wav.scp" --output_dir "./results"除命令行客户端外,仓库还封装了可直接复用的识别器类(funasr_client_api.py),三步即可完成一次识别:
from funasr_client_api import Funasr_websocket_recognizer # 1. 创建 recognizer rcg = Funasr_websocket_recognizer(host="127.0.0.1", port="30035", is_ssl=True, mode="2pass") # 2. 发送 PCM 数据并获取识别结果 text = rcg.feed_chunk(data) print("text", text) # 3. 关闭并取最终结果 text = rcg.close(timeout=3) print("text", text)仓库中另有更完整的 API 客户端与示例音频:runtime/funasr_api/example.py 与 runtime/funasr_api/asr_example.wav,可作为联调素材。
三、路径二:服务部署软件(C++ SDK + Docker)
C++ 版 SDK 同时支持高精度、高效率、高并发的文件转写与低延迟实时语音识别,原生支持 Docker 部署与多并发请求。镜像内置编译好的funasr-wss-server(离线)与funasr-wss-server-2pass(实时)二进制,模型目录挂载到容器内/workspace/models,宿主机的 runtime/funasr-runtime-resources/models/hotwords.txt 对应容器内/workspace/models/hotwords.txt。
3.1 Docker 安装(可选)
如果已安装 Docker 可跳过。官方安装脚本可参考仓库 runtime/deploy_tools/install_docker.sh,等效于文档给出的:
sudo bash install_docker.sh3.2 实时语音识别服务(2pass,在线镜像)
拉取并启动 Docker 镜像(在线镜像版本funasr-runtime-sdk-online-cpu-0.1.13,宿主机端口 10096 映射到容器 10095):
sudo docker pull \ registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.13 mkdir -p ./funasr-runtime-resources/models sudo docker run -p 10096:10095 -it --privileged=true \ -v $PWD/funasr-runtime-resources/models:/workspace/models \ registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.13启动服务:进入容器后启动funasr-wss-server-2pass:
cd FunASR/runtime nohup bash run_server_2pass.sh \ --download-model-dir /workspace/models \ --vad-dir damo/speech_fsmn_vad_zh-cn-16k-common-onnx \ --model-dir damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-onnx \ --online-model-dir damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online-onnx \ --punc-dir damo/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727-onnx \ --itn-dir thuduj12/fst_itn_zh \ --hotword /workspace/models/hotwords.txt > log.txt 2>&1 &文档中给出了三条重要的部署备注(见 runtime/quick_start.md 与 run_server_2pass.sh):
- 关闭 SSL:追加参数
--certfile 0(脚本检测到空值或0时会清空 cert/key 路径); - 换用时间戳模型:把
--model-dir设为damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-onnx(timestamp); - 换用 nn 热词模型:把
--model-dir设为damo/speech_paraformer-large-contextual_asr_nat-zh-cn-16k-common-vocab8404-onnx(nn hotword); - 服务端热词:在宿主机
./funasr-runtime-resources/models/hotwords.txt中配置,每行一个热词,格式为热词 权重,例如Alibaba 20。
从 run_server_2pass.sh 源码看,脚本在模型参数之外还自动配置了线程模型:decoder_thread_num取自/proc/cpuinfo的核数(失败时回退为 32),io_thread_num按multiple_io=16均摊计算,model_thread_num=1,最终调用/workspace/FunASR/runtime/websocket/build/bin/funasr-wss-server-2pass启动,并默认加载 runtime/ssl_key/server.crt 与 runtime/ssl_key/server.key 启用 SSL。
客户端测试(端口注意是宿主机的 10096):
python3 funasr_wss_client.py --host "127.0.0.1" --port 10096 --mode 2pass3.3 文件转写服务(普通话,CPU 离线镜像)
拉取并启动 Docker 镜像(离线镜像funasr-runtime-sdk-cpu-0.4.7,端口 10095 对 10095):
sudo docker pull \ registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.7 mkdir -p ./funasr-runtime-resources/models sudo 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.7启动服务(启动funasr-wss-server,注意比 2pass 服务多了一个语言模型参数):
cd FunASR/runtime 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_asr_nat-zh-cn-16k-common-vocab8404-onnx \ --punc-dir damo/punc_ct-transformer_cn-en-common-vocab471067-large-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 &run_server.sh 的线程策略与 2pass 版一致(核数探测 +multiple_io=16均摊 IO 线程),区别在于默认模型使用带时间戳/标点的iic/speech_paraformer-large-vad-punc_asr_nat-...-onnx,并额外传入--lm-dir(n-gram 语言模型iic/speech_ngram_lm_zh-cn-ai-wesp-fst)。
客户端测试(文件转写走--mode offline,--audio_in指定音频文件):
python3 funasr_wss_client.py --host "127.0.0.1" --port 10095 --mode offline --audio_in "../audio/asr_example.wav"3.4 两类部署的模型配置对照
| 配置项 | 实时 2pass(在线镜像) | 文件转写(离线 CPU 镜像) |
|---|---|---|
| 服务二进制 | funasr-wss-server-2pass | funasr-wss-server |
主模型--model-dir | damo/speech_paraformer-large_asr_nat-...-onnx(可换 timestamp/nn 热词变体) | 同左(脚本默认iic/speech_paraformer-large-vad-punc_...-onnx) |
在线模型--online-model-dir | damo/speech_paraformer-large_asr_nat-...-online-onnx | 无 |
VAD--vad-dir | damo/speech_fsmn_vad_zh-cn-16k-common-onnx | damo/speech_fsmn_vad_zh-cn-16k-common-onnx |
标点--punc-dir | damo/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727-onnx | damo/punc_ct-transformer_cn-en-common-vocab471067-large-onnx |
语言模型--lm-dir | 无 | damo/speech_ngram_lm_zh-cn-ai-wesp-fst |
ITN--itn-dir | thuduj12/fst_itn_zh | thuduj12/fst_itn_zh |
客户端--mode | 2pass | offline |
| 客户端端口 | 10096(宿主)→10095(容器) | 10095 |
可以推断,2pass 实时链路用「在线模型低延迟出字 + 离线模型高精度纠错」的组合,而离线转写链路则叠加 n-gram 语言模型进一步提升长文本准确率;两条链路共享同一套 WebSocket 协议与热词机制。
四、延伸阅读与协议细节
- WebSocket 协议与消息格式:runtime/docs/websocket_protocol.md 及各语言 SDK 指南 runtime/docs/SDK_tutorial.md;
- 在线/离线服务进阶配置:runtime/docs/SDK_advanced_guide_online.md、runtime/docs/SDK_advanced_guide_offline.md(含 GPU 版本指南);
- Python WebSocket 服务完整示例:runtime/python/websocket/README.md;
- 其他运行时栈:ONNX Runtime(runtime/onnxruntime/)、C# / Java / Go / CSharp 客户端(runtime/csharp/、runtime/java/、runtime/golang/)以及 runtime/triton_gpu/ 等,可按目标平台选型;
- 热词后处理:服务端热词增强逻辑还可参见 funasr/utils/postprocess_hotwords.py 及其测试 tests/test_postprocess_hotwords.py。
五、小结
FunASR 的运行时快速上手可归纳为三条决策线:开发验证选 Python WebSocket 服务(funasr_wss_server.py+funasr_wss_client.py,5 行命令即可跑通 2pass 全链路,且源码层面已具备线程池 + 信号量的多客户端并发能力);生产实时链路选在线 Docker 镜像 +run_server_2pass.sh;批量文件转写选离线 CPU 镜像 +run_server.sh。两类 Docker 部署通过统一的/workspace/models模型目录、hotwords.txt热词格式(热词 权重)与--certfile 0关 SSL 等约定保持一致,客户端只需切换--mode与端口即可完成联调。
【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考