语音识别模型服务器docker部署,封装API接口

模型选择去modelscope下载:Paraformer语音识别-中文-通用-16k-离线-large-长音频版 · 模型库

下载模型就不需要我展示了,各位大佬都会。

api接口应用程序代码app.py:

import os
import tempfile
from flask import Flask, request, jsonify
from funasr import AutoModel
import soundfile as sf

# 初始化Flask应用
app = Flask(__name__)

# 获取模型目录路径 
MODEL_DIR = os.environ.get("MODEL_DIR", os.path.join(os.path.dirname(os.path.abspath(__file__)), "model"))

# 全局模型对象,避免重复加载
model = None

def load_model():
    """加载语音识别模型"""
    global model
    if model is None:
        print(f"正在加载模型: {MODEL_DIR}")
        try:
            model = AutoModel(
                model=MODEL_DIR,
                device="cpu",
                local_files_only=True,
                disable_update=True
            )
            print("模型加载成功")
        except Exception as e:
            print(f"模型加载失败: {str(e)}")
            raise
    return model

@app.route('/health', methods=['GET'])
def health_check():
    """健康检查端点"""
    return jsonify({"status": "healthy", "message": "语音识别API服务运行正常"})

@app.route('/asr', methods=['POST'])
def speech_recognition():
    """语音识别端点,接收音频文件并返回识别结果"""
    # 检查是否有文件上传
    if 'file' not in request.files:
        return jsonify({"error": "没有提供音频文件"}), 400
    
    file = request.files['file']
    
    # 检查文件名是否为空
    if file.filename == '':
        return jsonify({"error": "没有选择文件"}), 400
    
    try:
        # 获取模型
        asr_model = load_model()
        
        # 使用临时文件保存上传的音频
        with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_file:
            temp_file_path = temp_file.name
            file.save(temp_file_path)
        
        try:
            # 读取音频文件
            audio_data, sample_rate = sf.read(temp_file_path)
            print(f"音频文件读取成功: 形状{audio_data.shape}, 采样率{sample_rate}")
            
            # 进行语音识别
            result = asr_model.generate(input=audio_data)
            
            # 解析识别结果
            recognized_text = ""
            if isinstance(result, list):
                for item in result:
                    if isinstance(item, dict):
                        if "text" in item:
                            recognized_text = item["text"]
                        elif "value" in item:
                            recognized_text = item["value"]
                    else:
                        recognized_text = str(item)
            
            return jsonify({
                "success": True,
                "text": recognized_text,
                "message": "语音识别成功"
            })
            
        finally:
            # 清理临时文件
            if os.path.exists(temp_file_path):
                os.remove(temp_file_path)
                
    except Exception as e:
        return jsonify({"error": f"识别过程中出错: {str(e)}"}), 500

if __name__ == '__main__':
    # 启动时加载模型
    load_model()
    # 启动Flask服务
    app.run(host='0.0.0.0', port=8075, debug=False)

语音识别接口的dockerfile代码:

FROM python:3.8-slim-buster

# 设置工作目录
WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc \
    g++ \
    libsndfile1 \
    git \
    && rm -rf /var/lib/apt/lists/*

# 复制依赖文件并安装Python依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用程序代码
COPY . /app/

# 设置环境变量
ENV MODEL_DIR=/app/model
ENV PYTHONUNBUFFERED=1

# 暴露端口
EXPOSE 8075

# 启动命令
CMD ["python", "app.py"]

环境依赖,requirements.txt:

# 基础依赖
numpy==1.22.4
pandas==1.5.3
scipy==1.10.1

# 语音处理
librosa==0.10.0.post2
soundfile==0.12.1

# 深度学习框架
pytorch==1.13.1
torchaudio==0.13.1

# FunASR 相关依赖
modelscope==1.9.5
funasr==0.4.3

# Web API框架
fastapi==0.95.2
uvicorn==0.22.0
python-multipart==0.0.6

# 其他工具
loguru==0.7.0
pyyaml==6.0.1

构建docker镜像命令:docker build -t stt-api .(必须在代码文件目录下使用终端执行)

创建一个docker-compose.yml文件来简化Docker容器的启动:

version: '3'  # Docker Compose 版本,根据实际情况选择

services:
  stt-api:
    image: stt-api
    container_name: stt-api-container
    restart: unless-stopped
    ports:
      - "8075:8075"
    volumes:
      - ./model:/app/model
    environment:
      - MODEL_DIR=/app/model

启动容器:docker-compose up -d

停止容器:docker-compose down

查看日志:docker-compose logs -f

到这里就差不多了,但是其实还可以写一个快速部署启动的脚本文件,只需要将docker容器压缩打包到本地,再写一个脚本就行,这样就方便在别的服务器部署了。

测试代码:

import requests
import os
import json


def recognize_speech(api_url, audio_file_path):
    # 检查文件是否存在
    if not os.path.exists(audio_file_path):
        return {"status": "error", "message": "音频文件不存在"}

    # 上传文件并获取识别结果
    try:
        with open(audio_file_path, 'rb') as audio_file:
            response = requests.post(api_url, files={'file': audio_file}, timeout=300)
            response.raise_for_status()
            return response.json()
    except Exception as e:
        return {"status": "error", "message": str(e)}


# 使用示例
if __name__ == '__main__':
    # 配置参数
    api_url = "http://127.0.0.1:8075/asr"  # 语音识别api地址(根据实际情况修改)
    audio_path = "./output/test_tts.wav"  # 语音文件地址(根据实际情况修改)

    # 调用语音识别并输出结果
    result = recognize_speech(api_url, audio_path)
    print(json.dumps(result, ensure_ascii=False, indent=2))

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值