python部署funasr非实时识别服务高并发问题
部署了一个funasr的中文音频非实时识别的服务接口,出现以下几种情况:
- 多次请求时接口未响应
- 音频文件135(1h)时响应很慢
- 用135M的音频文件请求接口,要一分钟后接口才收到请求
测试用例如下:
1. 单例
asr_example(1 min/2M)
山路.mp3(1.34h/135M)
import time
import requests
import socket
import urllib3
def allowed_gai_family():
return socket.AF_INET
# 用于取消ipv6请求
urllib3.util.connection.allowed_gai_family = allowed_gai_family
audio_file=r"D:\pycharm_project\ai-meeting-assistant\example\asr_example.wav"
audio_file=r"D:\pycharm_project\ai-meeting-assistant\example\山路.mp3"
funasr_url="http://xxx:11111/recognition"
with open(audio_file, 'rb') as file:
audio_data = file.read() # 读取整个文件的二进制数据
form_data={
'audio': ('asr_example.wav',audio_data,'audio/wav')
}
start_time=time.time()
response=requests.post(funasr_url,files=form_data)
audio_text=response.json()['text']
end_time=time.time()
print("耗时",end_time-start_time)
audio_text
大文件请求结果
(.venv) (base) PS E:\asr\test> python .\single_test.py
耗时 217.44692373275757
(.venv) (base) PS E:\asr\test> python .\single_test.py
耗时 210.00433087348938
服务构建:
runtime/python/http/server.py
2026.6.15
场景: 会议转录,一般1h+、100MB+的时长,且多家门店同时调用该转录工作流,asr节点超时限制最高600s。
第一版:
runtime/python/http/server.py
使用sdk funasr来加载模型
根据官方说明,使用python构建服务时起三个实例,python + fastapi + ngnix + docker 。当多个超长超大音频等待处理时,就会出现排队的情况,甚至出现超时。

services:
funasr-server1:
image: funasr-server-custom
container_name: funasr-api-1
volumes:
- ./temp_dir:/app/temp_dir
- ./logs/server1:/app/logs
environment:
- TZ=Asia/Shanghai
- KEEP_TEMP_FILES=false
- CUDA_VISIBLE_DEVICES=0
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
restart: unless-stopped
nginx:
image: nginx:latest
container_name: funasr-nginx
ports:
- "10098:10098"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./logs/nginx:/var/log/nginx
- ./nginx/temp:/tmp/nginx # 添加临时目录挂载
depends_on:
- funasr-server1
- funasr-server2
- funasr-server3
restart: unless-stopped
ngnix.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 2048;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/conf.d/*.conf;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
# 优化大文件传输
client_max_body_size 200M;
proxy_connect_timeout 3600s; # 设置与后端建立连接的超时时间为 3600 秒
proxy_send_timeout 3600s; # 设置向后端发送请求的超时时间为 3600 秒
proxy_read_timeout 3600s; # 设置从后端读取响应的超时时间为 3600 秒
send_timeout 3600s; # 设置客户端与 Nginx 之间的超时时间为 3600 秒
upstream funasr_backend {
# 最少连接算法
least_conn;
server funasr-server1:10095;
}
server {
listen 10098;
location / {
proxy_pass http://funasr_backend;
}
}
}
server.py 添加中间件,查看文件上传速度
class UploadProgressMiddleware:
async def __call__(self, request: Request, call_next):
if request.url.path == "/recognition":
content_length = request.headers.get("content-length")
if content_length:
start_time = time.time()
total_size = int(content_length)
logger.info(f"[{time.strftime('%H:%M:%S')}] 开始接收文件上传请求")
logger.info(f"文件大小: {total_size / 1024 / 1024:.2f}MB")
original_receive = request.receive
uploaded_size = 0
last_log_time = time.time() # 添加上次日志时间记录
async def receive_wrapper():
nonlocal uploaded_size, last_log_time
message = await original_receive()
if message["type"] == "http.request":
chunk = message.get("body", b"")
uploaded_size += len(chunk)
current_time = time.time()
elapsed = current_time - start_time
# 每秒最多打印一次日志
if current_time - last_log_time >= 1.0:
speed = uploaded_size / elapsed / 1024 / 1024
progress = uploaded_size / total_size * 100
logger.info(
f"[{time.strftime('%H:%M:%S')}] "
f"上传进度: {progress:.1f}%, "
f"已接收: {uploaded_size / 1024 / 1024:.1f}MB, "
f"速度: {speed:.2f}MB/s"
)
last_log_time = current_time
if message.get("more_body", False) is False:
# 只在最后打印一次完成信息
total_time = time.time() - start_time
logger.info(
f"[{time.strftime('%H:%M:%S')}] "
f"文件接收完成,总耗时: {total_time:.1f}秒, "
f"平均速度: {total_size / total_time / 1024 / 1024:.2f}MB/s"
)
return message
request._receive = receive_wrapper
try:
response = await call_next(request)
return response
except Exception as e:
logger.error(f"请求处理发生错误: {e}")
raise
app.middleware("http")(UploadProgressMiddleware())
当前官方群提供了QA文档,说明主要维护grpc

第二版:
runtime/http
使用源码便衣
第三版:
拉取c++版本离线文件转写服务的镜像
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

简单测试:
python3 python/websocket/funasr_wss_client.py --host "127.0.0.1" --port 10095 --mode offline --audio_in "./funasr_api/asr_example.wav"




浙公网安备 33010602011771号