用户一多识别就卡?3步打通FunASR多线程并发,吞吐量拉满
2026/9/7 23:34:53 网站建设 项目流程

用户一多识别就卡?3步打通FunASR多线程并发,吞吐量拉满

【免费下载链接】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 的 WebSocket 服务端(runtime/python/websocket/)内置了一套多线程并发机制,通过"异步事件循环 + 线程池 + 按模块限流"的组合,让单机服务能同时扛住多个用户,而且不用改一行模型代码就能上手。

原理讲明白:一个前台,一排灶台

不贴代码,用开饭店的方式理解这套机制 🍜

  • 前台(asyncio 事件循环):负责接待所有客人(WebSocket 连接),接单、传菜、上菜都是它干。它自己不下厨,所以哪怕同时挂着几百个连接,也不会被某个慢活儿拖住。
  • 灶台(线程池 ThreadPoolExecutor):真正费算力的"炒菜"(VAD 端点检测、ASR 推理)丢给后台一群灶台并行做。开几个灶台由--worker_threads决定,默认取"4 和 CPU 核数"中的较大值,保证事件循环不被阻塞计算卡死。
  • 每道菜的限流口(信号量):灶台再多也不能一锅乱炖。服务端给 VAD、流式 ASR、离线 ASR、标点、说话人识别各设了独立的并发上限(默认分别是 4、4、2、1、1),相当于每个窗口前只排固定长度队,重活儿(离线 ASR)自然被控制住,轻活儿(VAD)先跑起来,谁也不会饿死。
  • 独立餐位(连接级状态字典):每个 WebSocket 连接都有自己独立的缓存和状态,A 用户的音频片段绝不会混进 B 用户的识别结果里,多用户并行天然隔离。

一句话总结:前台管接待、灶台管算力、限流口管公平——这就是 FunASR 并发吞吐量的来源。

三步开启并发识别服务

  1. 拿到代码并装好依赖(若已装过 funasr 可跳过前两步)

    git clone https://gitcode.com/GitHub_Trending/fun/FunASR cd FunASR && pip install -U funasr cd runtime/python/websocket && pip install -r requirements_server.txt
  2. 启动服务端,按需带上并发参数:

    python funasr_wss_server.py --port 10095 --ncpu 4 --worker_threads 8

    关键参数速查:

    • --ncpu:单次推理占用的 CPU 核数,别超过物理核数
    • --worker_threads:线程池大小,决定"灶台数",默认max(4, CPU核数)
    • --concurrent_asr_offline:离线/2pass 识别并发上限(默认 2,GPU 富余可调大)
    • --ngpu/--device:指定计算设备,GPU 推理时把并发压力从 CPU 转移到显卡
  3. 拉起客户端压测,用麦克风试或直接喂 wav.scp 文件:

    python funasr_wss_client.py --host 127.0.0.1 --port 10095 --mode 2pass --audio_in "./data/wav.scp"

    --mode可选online(纯流式)、offline(离线)、2pass(流式先出结果、离线再修正,兼顾延迟和准确率)。

线程数怎么配不踩坑:4个常见问题

问题1:并发一上来,所有用户的结果都变慢原因:推理是阻塞型重计算,如果全挤在事件循环上,一个长音频就能卡住所有连接。 解法:确认服务端用了线程池卸载(run_blocking机制),并把--worker_threads设为与物理核数相当的值,让推理真正并行起来。

问题2:线程加多了,CPU 100% 反而吞吐下降原因:线程过多引发上下文切换和内存争抢,--ncpu过大时每次推理还在互相抢核。 解法:--ncpu控制在物理核数的 1~2 倍以内,用top看稳态 CPU 占用,利用率超过 90% 就停止加线程——此时瓶颈是硬件,不是线程数。

问题3:2pass 模式下离线修正迟迟不回来原因:离线 ASR 模型比流式模型重得多,而默认并发上限只有 2,多人同时说完话就会排队。 解法:GPU 有余量就调大--concurrent_asr_offline;没有余量就上多实例,前面挂一层 Nginx 做负载均衡横向扩容。

问题4:结果整体不慢,唯独带标点的那一步拖后腿原因:标点模型(CT-Transformer)默认并发是 1,属于刻意保守。 解法:确认它确实是链路最慢环节后,适度调大--concurrent_punc,观察延迟变化即可 ⚙️

三句话收尾

  • FunASR 的并发 = 异步事件循环接连接 + 线程池跑推理 + 各模块信号量限流,三者缺一不可
  • 调优顺序:先定--ncpu--worker_threads,再按最慢环节调--concurrent_*,最后才考虑多实例扩容
  • 动手前先看官方示例和服务端源码:runtime/python/websocket/,进阶问题可查 docs/reference/FQA.md

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询