当前位置: 首页 > article >正文

OpenAI Whisper 语音识别 模型部署及接口封装【干货】

一、安装依赖

pip install -U openai-whisper

二、安装ffmpeg

cd /opt
# 下载 5.1 版本的 ffmpeg
wget http://www.ffmpeg.org/releases/ffmpeg-5.1.tar.gz
# 解压下载的压缩包
tar -zxvf ffmpeg-5.1.tar.gz
# 进入解压后的文件夹
cd ffmpeg-5.1
# 安装ffplay需要的依赖
sudo apt-get install libx11-dev xorg-dev libsdl2-2.0 libsdl2-dev
sudo apt install clang libfdk-aac-dev libspeex-dev libx264-dev libx265-dev libnuma-dev
sudo apt install yasm pkg-config libopencore-amrnb-dev libopencore-amrwb-dev
# 查看帮助文档确定需要安装的相关参数
./configure --help
./configure --enable-gpl --enable-version3 --enable-nonfree --enable-ffplay --enable-ffprobe --enable-libx264 --enable-libx265 --enable-debug
# 编译ffmpeg
make
# 安装编译
sudo make install
# 设置环境变量
# 查看当前路径
pwd
# 将当前路径添加到环境变量当中
export PATH="$PATH:/opt/ffmpeg-5.1/ffmpeg"
# 测试
# 查看ffmpeg的版本
ffmpeg -version
ffplay -version
ffprobe -version

卸载

cd /opt/ffmpeg-5.1
sudo make uninstall

原文链接


三、下载运行模型

# 引用whisper模块
import whisper
# 下载模型到指定路径
# model = whisper.load_model("base", download_root="/opt/Whisper/models") # 基座模型
model = whisper.load_model("large", download_root="/opt/Whisper/models")  # 大模型
# 使用模型
result = model.transcribe("voice.wav")
print(result["text"])

这样模型文件就会被下载到/opt/Whisper/models路径

四、接口封装

# 引用whisper模块
import whisper
from flask import Flask,request
import datetime
import requests
import torch

# 语音识别模型
# model = whisper.load_model("large", download_root="/opt/Whisper/models")    # 同时下载模型
device = torch.device("cpu")                                                  # 使用CPU加载模型
model = whisper.load_model("/opt/Whisper/models/large-v3.pt", device=device)  # 加载模型

# 实例化一个web服务对象
app = Flask(__name__)
# 构造一个接受post请求的响应
@app.route('/',methods=['POST'])
def postRequest():
    data = {}
    data['data'] = {'text':'Not Found!'}
    data['code'] = 404

    # 验证秘钥是否通过
    key = request.form.get('key')
    if key != "OpenAI Whisper":
        data['data'] = {'text':'No permissions!'}
        data['code'] = 400
        return data

    # 判断翻译类型
    lang = 'zh'
    lang_ = request.form.get('lang')
    if lang_ == 'en':
        lang = 'en'

    # 验证是否上传文件,未上传文件使用远程地址或本地地址
    if 'file' not in request.files:

        # 获取路径
        path = request.form.get('path')
        if path.lower().endswith((".wav", ".WAV")) is False:
            data['data'] = {'text':'No wav!'}
            data['code'] = 400
            return data
        typ = request.form.get('typ') # url/path

        # 如果是使用连接,则远程拷贝链接文件到指定地址
        if typ == 'url':
            # 指定地址
            fileName = '/opt/Whisper/voice/' + datetime.datetime.now().strftime('%Y%m%d_%H%M%S') + '.wav'
            downlaod(path, fileName)
            res = toLang(lang, fileName) # model.transcribe(fileName,language='Chinese')
            data['data'] = res
            data['code'] = 200
        # 如果是使用本地文件,则直接读取
        elif typ == 'path':
            res = toLang(lang, path) # model.transcribe(path,language='Chinese')
            data['data'] = res
            data['code'] = 200

    # 如果通过上传文件
    else:
        file = request.files['file']
        if file.filename == '':
            data['data'] = {'text':'No file!'}
            data['code'] = 400
            return data

        # 指定文件保存路径
        file_extension = file.filename.split(".")[-1]

        if file_extension != 'wav' and file_extension!= 'WAV' and file_extension != 'mp3' and file_extension!= 'MP3':
            data['data'] = {'text':'No Voice!'}
            data['code'] = 400
            return data

        # 指定地址
        fileName = '/opt/Whisper/voice/' + datetime.datetime.now().strftime('%Y%m%d_%H%M%S') + '.' + file_extension
        # 保存文件
        file.save(fileName)
        res = toLang(lang, fileName) # model.transcribe(fileName,language='Chinese')
        data['data'] = res
        data['code'] = 200

    return data

# 文件下载
def downlaod(url, file_path):
  headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0"
  }
  r = requests.get(url=url, headers=headers)
  with open(file_path, "wb") as f:
    f.write(r.content)
    f.flush()

# 识别
def toLang(lang, file_path):
    if lang == 'en':
        prompt = 'is English'
        transcription = model.transcribe(file_path, language='en',verbose=True, initial_prompt=prompt)
        print(transcription["text"])
        return transcription
    else:
        prompt = '以下是普通话的句子'
        transcription = model.transcribe(file_path, language='zh',verbose=True, initial_prompt=prompt)
        print(transcription["text"])
        return transcription

if __name__ == '__main__':
    # 运行服务,并确定服务运行的IP和端口
    app.run('0.0.0.0', '8000')

五、后台运行

nohup /root/.virtualenvs/glm/bin/python /opt/Whisper/voice2text.py > /opt/Whisper/voice2text.log 2>&1 &

六、开机自启

vi /etc/rc.local
# 写入
nohup /root/.virtualenvs/glm/bin/python /opt/Whisper/voice2text.py > /opt/Whisper/voice2text.log 2>&1 &
# 给rc.local加上权限【已经配置过的不用重复配置】
sudo chmod +x /etc/rc.local
# 启用服务
sudo systemctl enable rc-local
# 启动服务并检查状态
sudo systemctl start rc-local.service
sudo systemctl status rc-local.service
# 重启测试
reboot

七、使用说明

接口http://127.0.0.1:8000
类型POSTbody 中使用 form-data 上传
keyOpenAI Whisper必填秘钥
langzh en null输出结果语言选择,不传默认输出中文
typurl path null路径类型,远程文件传 url、服务器本地文件传 path
直接上传文件允许不传
path路径地址,远程文件传网址、服务器本地文件传路径
直接上传文件允许不传
file文件,选择文件允许传 wav mp3 否则只允许传 wav

http://www.kler.cn/a/147732.html

相关文章:

  • 制作图片马常用的五种方法总结
  • 《Probing the 3D Awareness of Visual Foundation Models》论文解析——多视图一致性
  • Linux服务器定时执行jar重启命令
  • Redis知识点整理 - 脑图
  • 前端搭建低代码平台,微前端如何选型?
  • ssm114基于SSM框架的网上拍卖系统的设计与实现+vue(论文+源码)_kaic
  • 内网隧道学习
  • 消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!
  • Course1-Week1:机器学习简介
  • QLayout的removeWidget与QButtonGroup的removeButton
  • 接口测试及常用接口测试工具(含文档)
  • 董明珠:创新永远在路上,格力电器坚持自主创新
  • Python基础语法之学习type()函数
  • LVS-DR实验
  • C 语言-循环嵌套-函数
  • 132.四叶玫瑰数-列举、查找、判断等题型【满分解题代码+详细分析】(四叶玫瑰数类型题-C/C++JavaPython实现)
  • 2023-11-26 LeetCode每日一题(统计子串中的唯一字符)
  • Redis缓存设计典型问题
  • oracle rac 19.3安装补丁19.19
  • 显示Excel功能区或工具栏的方法不少,其中快捷方式最快
  • React Hooks函数之useRef
  • docker基础快速入门:基础命令、网络、docker compose工具
  • 井盖倾斜怎么办?智能井盖传感器监测方法
  • 【Linux】驱动程序同步和异步通知方式
  • JavaScript 的初步学习上篇
  • CSS-长度单位篇