跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

Ubuntu 24.04 下使用 Docker Compose 本地部署 Whisper 语音识别

OpenAI Whisper 自动语音识别系统的技术特点与模型规格,详细演示了如何在 Ubuntu 24.04 环境下通过 Docker Compose 本地部署 Whisper。内容涵盖 FastAPI 和 Gradio 两种服务形式的实现代码、Dockerfile 配置及依赖管理,重点解决了音频预处理、模型加载及服务暴露等关键步骤,适用于会议记录、字幕生成等场景。

指针猎手发布于 2026/4/6更新于 2026/10/24123 浏览
Ubuntu 24.04 下使用 Docker Compose 本地部署 Whisper 语音识别

简介

Whisper 是 OpenAI 于 2022 年 9 月开源的一款自动语音识别系统。它最突出的特点在于其鲁棒性,即使在面对口音、背景噪音或专业术语等复杂场景时,也能保持较高的识别准确性,在英语语音识别上已接近人类水平。

核心技术与工作原理

Whisper 的强大能力源于其独特的技术设计,主要包括以下几点:

  • 端到端的 Transformer 架构:Whisper 采用编码器 - 解码器的 Transformer 模型架构。输入音频被分割成 30 秒的片段并转换为对数梅尔频谱图,然后由编码器提取特征,解码器根据这些特征预测对应的文本。
  • 大规模多任务训练:模型在从互联网收集的、高达68 万小时的多语言(支持近百种语言)和多任务监督数据上进行训练,数据集的巨大规模和多样性是其强大泛化能力的基础。训练时,模型会交替执行多项任务,如多语言语音转录、语音翻译(到英语)、语言识别以及生成带短语级时间戳的文本等。
  • 统一的多任务格式:通过引入特殊的标记,Whisper 使用一个统一的模型来处理所有任务。这些标记指示模型当前需要执行的具体任务,这种设计使得单个模型能够替代传统语音处理流程中的多个阶段。
模型规格与选择

Whisper 提供了多种规模的模型,以适应不同场景下对速度和精度的权衡需求。下面的表格整理了可用的模型及其大致参数,你可以根据实际需求(如对准确率的要求、可用的计算资源)进行选择。

模型名称参数量磁盘空间适用场景
tiny约 39 M~75 MB快速演示,对资源极度敏感
base约 74 M~140 MB平衡速度与基本准确率
small约 244 M~480 MB良好准确率与速度的折中
medium约 769 M~1.5 GB追求较高准确率
large约 1550 M~3 GB最高准确率,支持所有任务
主要应用场景

凭借其高准确率和多语言支持,Whisper 可应用于多种场景:

  • 会议记录与转录:自动生成会议纪要,将音频内容转换为可编辑的文本,提高效率。
  • 视频字幕生成:为视频内容自动生成字幕,提升内容的可访问性和传播效果。
  • 多语言翻译与转录:支持将多种语言的语音直接转录或翻译成英语文本,便于跨语言沟通。
  • 语音助手与智能客服:作为语音接口的核心,提升语音助手对指令理解的准确性。
  • 无障碍技术:通过实时语音转文本服务,为听障人士提供沟通便利。
如何使用 Whisper

Whisper 的使用非常灵活,主要有以下几种方式:

  • 命令行直接使用:安装后,可通过简单的命令处理音频文件,例如 whisper audio.wav --model small --language Chinese。
  • 在 Python 代码中调用:在 Python 项目中集成语音识别功能通常只需几行代码,非常方便。
  • 通过 API 调用:OpenAI 也提供了 Whisper 的 API 接口,适合不希望本地部署的云端应用。
总结与优势

总而言之,Whisper 的核心优势可以概括为三点:

  1. 高鲁棒性:得益于海量多样的训练数据,在嘈杂环境、口音等方面表现出色。
  2. 多功能性:一个模型支持转录、翻译、时间戳等多种任务,覆盖近百种语言。
  3. 开放与便捷:完全开源,支持本地部署以保护数据隐私,并提供从命令行到 API 的多种易用接口。

本地部署

  • 运行效果:使用 small 模型以及使用精确的转录参数;整体识别还可以,但依旧有很多同韵母的字和同音字会识别错误;使用 medium 模型会出现一个奇怪的问题,转录文字为繁体字;large 模型运行时间较长(3060 显卡)

  • 优化:音频预处理、优化转录参数、阶段处理

    • 结果也大差不差,最终生成的文本或多或少都有点问题,还是直接交给大模型根据语义做修正并分析吧
  • 转 FastAPI 服务

    • 增加 fastapi、uvicorn、python-multipart 依赖
    • 修改 Dockerfile 程序挂载
    • 修改 docker-compose.yml 端口映射

测试语句:

curl -X POST "http://localhost:7862/transcribe" -F "[email protected]"

更新配置:

# whisper_fastapi.py
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.responses import JSONResponse
import whisper
import tempfile
import os
import numpy as np
from scipy import signal
import librosa
import uvicorn
import soundfile as sf

# 初始化 FastAPI 应用
app = FastAPI(
    title="Whisper 音频转录 API",
    description="基于 OpenAI Whisper 的高级音频转录服务",
    version="1.0.0"
)

# 初始化全局变量
model = None

def load_whisper_model():
    global model
    if model is None:
        model = whisper.load_model("large")
    return model

def preprocess_audio(audio_path):
    """ 音频预处理:重采样、降噪、标准化 """
    try:
        # 加载音频
        y, sr = librosa.load(audio_path, sr=16000)
        # 重采样到 16kHz
        # 应用高通滤波器去除低频噪声
        b, a = signal.butter(4, 100, 'highpass', fs=sr)
        y = signal.filtfilt(b, a, y)
        # 音频标准化
        y = y / np.max(np.abs(y))
        # 保存处理后的临时文件
        temp_path = tempfile.mktemp(suffix='.wav')
        sf.write(temp_path, y, sr)
        return temp_path
    except Exception as e:
        print(f"音频预处理失败:{str(e)}")
        return audio_path  # 如果预处理失败,返回原始文件

@app.on_event("startup")
async def startup_event():
    """应用启动时加载模型"""
    print("正在加载 Whisper 模型...")
    load_whisper_model()
    print("Whisper 模型加载完成!")

@app.post("/transcribe", summary="音频转录", description="上传音频文件并返回转录文本")
async def transcribe_audio(file: UploadFile = File(...)):
    """ 转录音频文件为文本,使用优化参数
    - **file**:音频文件,支持 MP3、WAV、OGG、M4A、FLAC 等格式
    """
    # 更灵活的文件类型检查
    valid_extensions = {'.mp3', '.wav', '.ogg', '.m4a', '.flac', '.aac', '.m4b'}
    file_extension = os.path.splitext(file.filename)[1].lower()
    if file_extension not in valid_extensions:
        raise HTTPException(
            status_code=400,
            detail=f"不支持的文件类型:{file_extension}。请上传音频文件:{valid_extensions}"
        )
    temp_path = None
    processed_audio = None
    try:
        # 保存上传文件到临时位置
        with tempfile.NamedTemporaryFile(delete=False, suffix=file_extension) as temp_file:
            content = await file.read()
            temp_file.write(content)
            temp_path = temp_file.name
        # 音频预处理
        processed_audio = preprocess_audio(temp_path)
        # 加载模型
        model = load_whisper_model()
        # 使用优化的转录参数
        result = model.transcribe(
            processed_audio,
            language="zh",  # 指定中文语言
            task="transcribe",
            beam_size=5,  # 增加束搜索大小以提高准确性
            best_of=5,  # 生成多个候选结果选择最佳
            temperature=0.0,  # 使用确定性输出
            patience=1.0,  # 束搜索耐心参数
            suppress_tokens=[-1]  # 抑制不必要的 token
        )
        # 返回转录结果
        return JSONResponse(content={"status": "success", "text": result["text"], "language": result.get("language", "zh"), "file_name": file.filename})
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"转录过程中出现错误:{str(e)}")
    finally:
        # 清理临时文件
        if temp_path and os.path.exists(temp_path):
            os.unlink(temp_path)
        if processed_audio and processed_audio != temp_path and os.path.exists(processed_audio):
            os.unlink(processed_audio)

@app.get("/health", summary="健康检查", description="检查服务是否正常运行")
async def health_check():
    """健康检查端点"""
    return JSONResponse(content={"status": "healthy", "model_loaded": model is not None})

@app.get("/", summary="根端点", description="API 基本信息")
async def root():
    """根端点,返回 API 基本信息"""
    return {
        "message": "Whisper 音频转录 API 服务",
        "version": "1.0.0",
        "endpoints": {
            "transcribe": "/transcribe (POST)",
            "health": "/health (GET)",
            "docs": "/docs (GET)",
            "redoc": "/redoc (GET)"
        },
        "model": "large",
        "supported_languages": "近百种语言,支持中文转录"
    }

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=7862)
FROM nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04
# 设置工作目录
WORKDIR /app
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
# 安装系统依赖
RUN apt-get update && apt-get install -y \
    ffmpeg \
    python3 \
    python3-pip \
    python3-venv \
    && rm -rf /var/lib/apt/lists/* \
    && ln -sf /usr/bin/python3 /usr/bin/python
# 复制依赖文件
COPY requirements.txt .
# 安装 Python 依赖
RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
# 复制应用代码(修改为 FastAPI 文件)
COPY whisper_fastapi.py .
# 暴露 FastAPI 端口
EXPOSE 7862
# 设置环境变量:模型缓存路径
ENV WHISPER_MODEL_CACHE=/root/.cache/whisper
# 启动应用(修改为 FastAPI 启动命令)
CMD ["uvicorn", "whisper_fastapi:app", "--host", "0.0.0.0", "--port", "7862"]
# docker-compose.yml
services:
  whisper-api:
    build: .
    container_name: whisper-fastapi
    ports:
      - "7862:7862"
    volumes:
      # 持久化缓存模型
      - ./model_cache:/root/.cache/whisper
      # 可选:挂载音频文件目录
      - ./audio_files:/app/audio_files
    environment:
      - WHISPER_MODEL=medium
    restart: unless-stopped
    # 可选:设置资源限制
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 2
              capabilities: [gpu]

Gradio 服务

# whisper_gradio.py
import gradio as gr
import whisper
import tempfile
import os
import numpy as np
from scipy import signal
import librosa

# 初始化全局变量
model = None

def load_whisper_model():
    global model
    if model is None:
        model = whisper.load_model("medium")
    return model

def preprocess_audio(audio_path):
    """ 音频预处理:重采样、降噪、标准化 """
    try:
        # 加载音频
        y, sr = librosa.load(audio_path, sr=16000)
        # 重采样到 16kHz
        # 应用高通滤波器去除低频噪声
        b, a = signal.butter(4, 100, 'highpass', fs=sr)
        y = signal.filtfilt(b, a, y)
        # 音频标准化
        y = y / np.max(np.abs(y))
        # 保存处理后的临时文件
        temp_path = tempfile.mktemp(suffix='.wav')
        librosa.output.write_wav(temp_path, y, sr)
        return temp_path
    except Exception as e:
        print(f"音频预处理失败:{str(e)}")
        return audio_path  # 如果预处理失败,返回原始文件

def transcribe_audio(audio_file):
    """ 转录音频文件为文本,使用优化参数 """
    # 加载模型
    model = load_whisper_model()
    # 安全检查上传的文件
    if audio_file is None:
        return "错误:请上传一个音频文件。"
    try:
        # 音频预处理
        processed_audio = preprocess_audio(audio_file)
        # 使用优化的转录参数
        result = model.transcribe(
            processed_audio,
            language="zh",  # 指定中文语言
            task="transcribe",
            beam_size=5,  # 增加束搜索大小以提高准确性
            best_of=5,  # 生成多个候选结果选择最佳
            temperature=0.0,  # 使用确定性输出
            patience=1.0,  # 束搜索耐心参数
            suppress_tokens=[-1]  # 抑制不必要的 token
        )
        # 清理临时文件
        if processed_audio != audio_file:
            try:
                os.unlink(processed_audio)
            except:
                pass
        return result["text"]
    except Exception as e:
        return f"转录过程中出现错误:{str(e)}"

# 创建 Gradio 界面
with gr.Blocks(title="Whisper 音频转录") as demo:
    gr.Markdown("# 🎤 Whisper 音频转录")
    gr.Markdown("上传 MP3、WAV、OGG 等音频文件,使用优化的参数将其转换为文本")
    with gr.Row():
        with gr.Column():
            audio_input = gr.Audio(sources=["upload"], type="filepath", label="上传音频文件", interactive=True)
            submit_btn = gr.Button("开始转录", variant="primary")
        with gr.Column():
            text_output = gr.Textbox(label="转录结果", placeholder="转录文本将显示在这里...", lines=10, max_lines=15)
        # 处理提交动作
        submit_btn.click(fn=transcribe_audio, inputs=audio_input, outputs=text_output)
    # 附加说明
    gr.Markdown("""
### 使用说明
1. 点击"上传音频文件"或拖放文件到上传区域
2. 支持格式:MP3, WAV, OGG, M4A, FLAC 等
3. 点击"开始转录"按钮
4. 等待转录结果出现在右侧文本框中
**注意**:首次使用需要下载 Whisper Large 模型,请耐心等待。转录过程可能需要较长时间。
""")

if __name__ == "__main__":
    demo.launch(server_name="0.0.0.0", server_port=7862, share=False)

Docker 配置

FROM nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04
# 设置工作目录
WORKDIR /app
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
# 安装系统依赖
RUN apt-get update && apt-get install -y \
    ffmpeg \
    python3 \
    python3-pip \
    python3-venv \
    && rm -rf /var/lib/apt/lists/* \
    && ln -sf /usr/bin/python3 /usr/bin/python
# 复制依赖文件
COPY requirements.txt .
# 安装 Python 依赖
RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
# 复制应用代码
COPY whisper_gradio.py .
# 暴露 Gradio 默认端口
EXPOSE 7862
# 设置环境变量:禁用 Gradio 分析,缓存模型
ENV GRADIO_ANALYTICS_ENABLED=False
ENV WHISPER_MODEL_CACHE=/root/.cache/whisper
# 启动应用
CMD ["python", "whisper_gradio.py"]
# docker-compose.yml
services:
  whisper-app:
    build: .
    ports:
      - "29999:7862"
    volumes:
      # 可选:持久化缓存模型,避免每次重启下载
      - ./cache:/root/.cache/whisper
    environment:
      - GRADIO_SERVER_NAME=0.0.0.0
      - GRADIO_SERVER_PORT=7862
    restart: unless-stopped
# requirements.txt
torch openai-whisper gradio ffmpeg-python pydub scipy librosa numpy soundfile fastapi uvicorn python-multipart

目录

  1. 简介
  2. 核心技术与工作原理
  3. 模型规格与选择
  4. 主要应用场景
  5. 如何使用 Whisper
  6. 总结与优势
  7. 本地部署
  8. whisper_fastapi.py
  9. 初始化 FastAPI 应用
  10. 初始化全局变量
  11. 设置工作目录
  12. 安装系统依赖
  13. 复制依赖文件
  14. 安装 Python 依赖
  15. 复制应用代码(修改为 FastAPI 文件)
  16. 暴露 FastAPI 端口
  17. 设置环境变量:模型缓存路径
  18. 启动应用(修改为 FastAPI 启动命令)
  19. docker-compose.yml
  20. whisper_gradio.py
  21. 初始化全局变量
  22. 创建 Gradio 界面
  23. 使用说明
  24. 设置工作目录
  25. 安装系统依赖
  26. 复制依赖文件
  27. 安装 Python 依赖
  28. 复制应用代码
  29. 暴露 Gradio 默认端口
  30. 设置环境变量:禁用 Gradio 分析,缓存模型
  31. 启动应用
  32. docker-compose.yml
  33. requirements.txt

更多推荐文章

查看全部
  • 选择排序算法原理与实现
  • 基于Vivado的RISC-V五级流水线CPU FPGA实现详解
  • FireRedASR-AED-L 嘈杂环境中文语音识别效果对比与原理分析
  • AI 并非前端 UI 的终结者,而是效率加速器
  • Python 与 PyCharm 虚拟环境搭建及实战指南
  • Spatial Joy 2025 全球 AR&AI 赛事:开发者资源、玩法及避坑攻略
  • 基于 RetinaFace 和 CurricularFace 的教育考勤自动化方案
  • 模拟算法实战:替换问号、提莫攻击、Z 字形变换等 5 题解析
  • Linux 共享内存实现进程间高效数据传输
  • 金仓数据库 KingbaseES:多模融合架构与全场景替代方案
  • 使用 DeepSeek API 构建贪吃蛇游戏实战
  • Java 类加载机制与双亲委派模型深度解析
  • Python 调用 Windows CMD 命令的多种实现方式
  • C++ STL list 容器底层实现详解
  • TensorFlow 安装教程
  • AI 产品经理学习路线与核心技能指南
  • AIGC 插画生成技术解析与 Python 代码实战
  • GLM-4.7 基于 vLLM Ascend 的 12 项核心性能优化实战
  • RNN 与序列数据处理实战:从原理到 LSTM 文本分类
  • Llama-3.2-3B 本地部署实战:Ollama 与 Open WebUI 集成指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online