[Meetily后端框架] Whisper转录服务器 | 后端服务管理脚本

第七章:Whisper转录服务器

欢迎回来!

到目前为止,我们已经深入探索了"meeting-minutes"项目的"大脑"------Python后端。

我们已经了解了它如何通过后端API网关接收文本转录,使用摘要数据结构(Pydantic模型)理解输出结构,通过巧妙的转录处理逻辑结合AI模型交互(Pydantic-AI代理)处理文本,并利用数据库管理保存所有内容。

但问题是,如果后端处理的是文本,那么最初的文本转录从何而来?特别是当原始输入是会议录音的音频文件时?

这就是Whisper转录服务器的用武之地~


Whisper转录服务器解决什么问题?

假设我们有一个会议的音频录音。在后端进行任何摘要提取或行动项提取之前,我们需要将语音转换为文字------即生成转录文本

这种将音频转换为文本的任务称为**自动语音识别(ASR)**。这是一个需要专用模型的计算密集型过程。

我们的项目需要可靠的ASR执行方式。

虽然有些Python库可以实现此功能,但运行强大的ASR模型通常需要更接近硬件的编程语言(如C++)。Whisper转录服务器正是为此而生。

可以将其想象成一个专用的高效速记员,专门负责监听音频文件(我们的会议录音)并快速提供文字转录。

Whisper转录服务器是什么?

本项目中的Whisper转录服务器是:

  1. 独立服务:作为独立程序运行,与主Python后端应用分离
  2. 基于whisper.cpp构建 :这是OpenAI流行Whisper ASR模型的C++移植版本。C++常用于需要高性能的任务(如音频处理和直接在计算机硬件CPU/GPU上运行机器学习模型
  3. 专用工具:唯一职责是接收音频并返回文本,不涉及摘要生成、数据库操作或前端API处理
  4. 依赖项:虽然是独立服务,但主Python后端需要依赖此服务器来获取音频文件的转录文本

它会在后台静默运行,监听来自Python后端的请求。

工作原理(概述)

核心交互流程非常简单:

  1. Python后端(或其他客户端应用)持有音频文件
  2. 后端通过本地网络连接将音频文件发送至运行的Whisper转录服务器
  3. Whisper服务器接收音频,加载适当的Whisper模型,通过模型处理音频生成转录文本
  4. Whisper服务器将生成的文本转录返回至后端

这清晰展示了服务器的专注角色:获取音频、使用模型文件、返回文本。

配置Whisper服务器

由于Whisper服务器是独立的C++程序,需要先进行编译构建。项目包含专门用于此的脚本:

  • backend/build_whisper.cmd(适用于Windows)
  • backend/build_whisper.sh(适用于Linux/macOS)

这些脚本会下载必要的whisper.cpp代码(作为git子模块),编译服务器可执行文件,并下载所需的Whisper模型文件。

编译可执行文件

脚本进入whisper.cpp目录,使用cmakemake(常见的C++构建工具)来编译服务器代码:

bash 复制代码
# 摘自build_whisper.sh的简化片段
log_info "进入whisper.cpp目录..."
cd whisper.cpp || handle_error "进入目录失败"

log_info "构建whisper.cpp..."
rm -rf build # 清理旧构建
mkdir build && cd build || handle_error "创建构建目录失败"

log_info "配置CMake..."
cmake -DCMAKE_C_FLAGS="-w" -DCMAKE_CXX_FLAGS="-w" .. || handle_error "CMake配置失败"

make -j4 || handle_error "编译失败" 

cd .. # 返回上级目录
log_success "构建成功完成"

说明:

进入whisper.cpp目录,创建build目录,运行cmake根据CMakeLists.txt文件配置构建过程,然后运行make编译C++源码生成可执行文件(包括whisper-server)。

下载模型

脚本还会下载特定的Whisper模型文件。这些文件包含ASR模型执行转录所需的数据(类似"速记员大脑"的数据)。文件名类似ggml-small.binggml-medium.bin等,模型选择会影响转录速度和准确率。

bash 复制代码
# 摘自build_whisper.sh的简化片段
MODEL_NAME="ggml-$MODEL_SHORT_NAME.bin" # 例如ggml-small.bin

# 检查模型是否存在,不存在则下载
if [ -f "$MODEL_DIR/$MODEL_NAME" ]; then
    log_success "模型文件存在:$MODEL_DIR/$MODEL_NAME"
else
    log_warning "模型文件不存在:$MODEL_DIR/$MODEL_NAME"
    log_info "下载模型中..."
    # 调用专门下载模型的脚本
    ./models/download-ggml-model.sh $MODEL_SHORT_NAME || handle_error "下载失败"
    # 移动下载的模型到正确目录
    mv "./models/$MODEL_NAME" "$MODEL_DIR/" || handle_error "移动模型失败"
fi

说明:

脚本根据用户选择的短名称(如small)确定完整的模型文件名。检查文件是否存在,若不存在则通过download-ggml-model.sh脚本下载,并移动到whisper-server-package内的models目录。

运行这些构建脚本后,将获得whisper-server可执行文件和至少一个ggml-*.bin模型文件。

运行Whisper服务器

与Python后端类似,Whisper服务器需要先运行才能接收请求。主启动脚本(clean_start_backend.shstart_with_output.ps1)确保先启动Whisper服务器再启动Python后端。

脚本使用生成的whisper-server-package目录中的辅助脚本来运行服务器:run-server.shrun-server.cmd

简化版的运行脚本示例:

bash 复制代码
#!/bin/bash

# 默认配置
HOST="127.0.0.1" # 仅监听本地
PORT="8178"      # 监听端口
MODEL="models/ggml-large-v3.bin" # 默认模型路径

# ...(解析命令行参数如--model、--port、--host的逻辑)...

# 运行服务器
./whisper-server \
    --model "$MODEL" \
    --host "$HOST" \
    --port "$PORT" \
    --diarize \
    --print-progress

# 其他选项如--diarize启用说话人区分功能

说明:

此脚本执行编译后的whisper-server程序,传递命令行参数:

  • --model:指定加载的模型文件(.bin)
  • --host--port:设置监听地址和端口(默认127.0.0.1:8178
  • --diarize:启用说话人区分功能,识别音频中的不同说话者

运行主启动脚本(clean_start_backend.sh)时,会执行此run-server.sh脚本(通常在后台)来启动Whisper服务器。

Whisper服务器的API(/inference端点)

whisper.cpp服务器暴露简单的HTTP API。后端主要使用/inference端点来接收音频文件并返回转录文本。

根据whisper.cpp/examples/server/README.md文件,可以使用curl工具与该端点交互:

bash 复制代码
curl 127.0.0.1:8178/inference \
-H "Content-Type: multipart/form-data" \
-F file="@<文件路径>" \
-F response_format="json" \
-F language="en"
# ...其他参数选项...

说明:

  • curl 127.0.0.1:8178/inference:服务器端点地址
  • -H "Content-Type: multipart/form-data":表示发送包含文件的数据
  • -F file="@<文件路径>":发送音频文件内容
  • -F response_format="json":要求返回JSON格式结果
  • -F language="en":提示音频语言

服务器处理音频文件后返回的JSON响应示例:

json 复制代码
{
  "text": "这是测试录音。说话人一陈述内容。说话人二做出回复。"
  // ...可能包含分段、时间戳等信息...
}

其中的text字段包含Python后端所需的关键转录文本。

⭕Whisper服务端(简化版)

查看C++代码(backend/whisper-custom/server/server.cpp)了解/inference端点处理流程:

cpp 复制代码
// 简化版C++代码
int main(int argc, char ** argv) {
    // ...(参数解析和初始化)...

    // 加载Whisper模型
    struct whisper_context * ctx = whisper_init_from_file_with_params(params.model.c_str(), cparams);
    
    Server svr; // 创建HTTP服务器实例

    // 定义/inference端点处理
    svr.Post(sparams.request_path + sparams.inference_path, [&](const Request &req, Response &res){
        std::lock_guard<std::mutex> lock(whisper_mutex); // 线程安全锁
        
        // 1. 检查请求是否包含音频文件
        if (!req.has_file("file")) {
            res.set_content("{\"error\":\"缺少'file'字段\"}", "application/json");
            return;
        }
        auto audio_file = req.get_file_value("file"); // 获取文件内容

        // 2. 获取请求参数
        whisper_params current_params = params; // 使用默认参数
        get_req_parameters(req, current_params);

        // 3. 读取和处理音频数据
        std::vector<float> pcmf32; // 音频数据存储
        if (!::read_wav(audio_file.content, pcmf32, pcmf32s, current_params.diarize)) {
            res.set_content("{\"error\":\"读取WAV文件失败\"}", "application/json");
            return;
        }

        // 4. 运行转录模型
        whisper_full_params wparams = whisper_full_default_params(WHISPER_SAMPLING_GREEDY);
        if (whisper_full_parallel(ctx, wparams, pcmf32.data(), pcmf32.size(), current_params.n_processors) != 0) {
            res.set_content("{\"error\":\"处理音频失败\"}", "application/json");
            return;
        }

        // 5. 格式化输出
        std::string result_content;
        if (current_params.response_format == json_format) {
            json jres = json{ {"text", output_str(ctx, current_params, pcmf32s)} };
            result_content = jres.dump();
            res.set_content(result_content, "application/json");
        } 
        // ...其他格式处理...
    });

    // 启动服务器监听
    svr.bind_to_port(sparams.hostname, sparams.port);
    svr.listen_after_bind();

    // 清理资源
    whisper_free(ctx);
    return 0;
}

使用Whisper语音识别模型构建的HTTP服务端程序,主要功能是接收音频文件返回文字转录结果

核心流程

初始化阶段

  • 加载预训练的Whisper语音识别模型
  • 创建HTTP服务器实例准备接收请求

请求处理阶段

  1. 检查请求合法性:验证是否包含音频文件字段
  2. 参数获取:读取客户端提交的转录参数(如语言、响应格式等)
  3. 音频预处理:将上传的WAV文件解码为模型需要的PCM格式
  4. 语音识别:调用Whisper模型进行并行转录计算
  5. 结果格式化:将识别结果转换为JSON等指定格式返回

终止阶段

  • 释放模型内存
  • 关闭服务器

关键技术点

  • 线程安全机制:通过lock_guard确保多线程安全
  • 错误处理:对每个关键步骤进行错误检测并返回JSON格式错误信息
  • 参数可配置:支持运行时调整转录参数
  • 多格式输出:默认支持JSON响应格式

数据流向

客户端音频文件 → HTTP请求 → WAV解码 → Whisper模型 → 文本结果 → JSON响应 → 客户端

流程复述:

  1. 初始化时加载Whisper模型
  2. 配置HTTP服务器并定义POST请求处理
  3. 检查请求有效性并获取音频文件
  4. 读取音频数据到内存缓冲区
  5. 调用whisper_full_parallel执行语音识别
  6. 根据请求格式生成响应内容
  7. 启动监听循环处理请求
lock_guard的作用

lock_guard是C++中的一种工具,它在构造时自动加锁,析构时自动解锁,确保多线程下某段代码不会被多个线程同时执行。

WAV解码

将WAV音频文件的二进制数据转换成可以播放的声音信号

要点

  • **Whisper转录服务器**是基于C++(whisper.cpp)构建的高性能独立服务,用于音频转文本
  • 是Python后端处理音频输入时的必要依赖
  • 运行时需要加载特定的Whisper模型文件 (.bin)
  • 项目包含构建脚本 编译服务器和下载模型,以及**运行脚本**启动服务
  • 暴露HTTP API (主要使用/inference端点)接收音频并返回转录文本
  • 内部使用whisper.cpp库函数进行模型加载、音频读取、转录执行和输出格式化

理解Whisper转录服务器可以明确音频输入的文本转录来源,完善后端处理流程的数据源头。

下一步

我们已经覆盖了meeting-minutes后端的主要组件及其关键依赖------Whisper转录服务器。

我们已经了解后端如何处理文本,以及音频如何被转换为文本。但这些独立组件(Python后端和Whisper服务器)如何作为整体系统启动和管理?

在最终章,我们将介绍后端服务管理脚本,通过简单命令即可构建、启动和停止所有必要服务。

第八章:后端服务管理脚本


第八章:后端服务管理脚本

欢迎来到meeting-minutes后端教程的最终章!

我们已经涵盖了诸多内容:从前端入口(第一章:后端API网关)及其文档(第二章:API文档),到数据结构(第三章:摘要数据结构(Pydantic模型))、核心处理逻辑(第四章:转录处理逻辑)及其与AI模型的交互(第五章:AI模型交互(Pydantic-AI代理)),再到数据保存(第六章:数据库管理),最后是通过专用章节第七章:Whisper转录服务器实现音频到文本的转换。

我们现在已经了解,后端系统并非单一程序,而是由至少两个需要持续运行的主要部分构成:

  1. Python后端应用 :包含API网关文本处理逻辑数据库管理的主体部分
  2. Whisper转录服务器 :实现音频转文本的独立程序

手动按正确顺序启动这些组件、确保端口监听正确、可能需要清理旧进程等操作,对初学者而言既繁琐又容易出错。

服务管理脚本解决什么问题?

想象我们正在发射火箭(我们的后端系统),需要:

  • 确保所有必要部件已就绪(如Whisper服务器可执行文件)
  • 清理发射场(终止旧服务进程)
  • 启动引擎(Whisper服务器)
  • 激活主火箭系统并确保通信正常(Python后端连接Whisper服务器)

后端服务管理脚本 将此流程自动化。这些简单的命令行文件(Linux/macOS用.sh,Windows用.cmd)将必要步骤封装成单一命令,如同自动化发射序列或后端服务控制面板。

核心管理脚本

backend/目录包含关键脚本:

  • build_whisper.sh/build_whisper.cmd:构建C++版Whisper服务器及下载模型(初始化或更新后使用)
  • clean_start_backend.sh/clean_start_backend.cmd:主启动脚本(终止旧实例并启动Whisper与Python后端)
  • check_status.cmd(Windows专用,Linux/macOS可用pslsof):查看服务运行状态
  • start_with_output.ps1(Windows PowerShell脚本,由start_with_output.cmd调用):调试时在新窗口显示输出

我们重点解析构建与启动相关的核心脚本。

构建Whisper服务器(build_whisper)

第七章所述,该脚本负责编译C++源码。执行backend/build_whisper.sh.cmd时执行以下关键步骤:

  1. 更新Git子模块

    bash 复制代码
    git submodule update --init --recursive
    cmd 复制代码
    :: Windows版
    git submodule update --init --recursive

    说明 :获取whisper.cpp项目代码至backend/whisper.cpp

  2. 部署定制服务文件

    bash 复制代码
    cp -r ../whisper-custom/server/* "examples/server/"
    cmd 复制代码
    xcopy /E /Y /I ..\whisper-custom\server examples\server\

    说明:使用项目定制版服务端代码覆盖默认实现

  3. 执行C++编译

    bash 复制代码
    cd whisper.cpp/build
    cmake ..
    make -j4
    cmd 复制代码
    cd whisper.cpp\build
    cmake .. -DBUILD_SHARED_LIBS=OFF -DWHISPER_BUILD_TESTS=OFF -DWHISPER_BUILD_SERVER=ON
    cmake --build . --config Release

    说明 :生成whisper-server可执行文件

  4. 下载语音模型

    bash 复制代码
    ./models/download-ggml-model.sh $MODEL_SHORT_NAME
    mv "./models/$MODEL_NAME" "$PACKAGE_DIR/models/"
    cmd 复制代码
    call download-ggml-model.cmd %MODEL_SHORT_NAME%
    move "whisper.cpp\models\%MODEL_NAME%" "%PACKAGE_DIR%\models\"

    说明 :获取Whisper服务器所需的.bin模型文件

  5. 文件打包

    bash 复制代码
    mkdir -p "$PACKAGE_DIR/models"
    cp build/bin/whisper-server "$PACKAGE_DIR/"
    cp "$MODEL_DIR/$MODEL_NAME" "$PACKAGE_DIR/models/"
    cmd 复制代码
    mkdir "%PACKAGE_NAME%"
    mkdir "%PACKAGE_NAME%\models"
    copy "whisper.cpp\build\bin\Release\whisper-server.exe" "%PACKAGE_NAME%\"
    copy "whisper.cpp\models\%MODEL_NAME%" "%PACKAGE_NAME%\models\"

    说明 :将运行所需文件集中至whisper-server-package目录

  6. 配置Python环境

    bash 复制代码
    python3 -m venv venv
    source venv/bin/activate
    pip install -r requirements.txt
    cmd 复制代码
    python -m venv venv
    call venv\Scripts\activate.bat
    pip install -r requirements.txt

    说明:创建Python虚拟环境并安装依赖

构建脚本只需执行一次即可完成环境准备。

启动后端(clean_start_backend)

最常用脚本,执行backend/clean_start_backend.sh.cmd时工作流程:

  1. 清理旧进程

    bash 复制代码
    pkill -f "whisper-server" 2>/dev/null
    cmd 复制代码
    taskkill /F /FI "IMAGENAME eq whisper-server.exe" 2>nul

    说明:终止占用端口5167和8178的旧进程

  2. 启动Whisper服务

    bash 复制代码
    cd "$PACKAGE_NAME"
    ./run-server.sh --model "models/$MODEL_NAME" &
    WHISPER_PID=$!
    cd ..
    cmd 复制代码
    cd "%PACKAGE_NAME%"
    start "Whisper Server" cmd /k "whisper-server.exe --model models\%MODEL_NAME% --host 127.0.0.1 --port 8178 --diarize --print-progress"
    cd ..

    说明:后台启动语音识别服务

  3. 服务启动等待

    bash 复制代码
    sleep 2
    cmd 复制代码
    timeout /t 5 >nul

    说明:确保语音服务就绪后再启动后端

  4. 激活Python环境

    bash 复制代码
    source venv/bin/activate
    cmd 复制代码
    call venv\Scripts\activate.bat
  5. 启动Python后端

    bash 复制代码
    python app/main.py &
    PYTHON_PID=$!
    cmd 复制代码
    start "Python Backend" cmd /k "call venv\Scripts\activate.bat && python app\main.py"
  6. 状态验证

    bash 复制代码
    sleep 10
    lsof -i :8178
    lsof -i :5167
    cmd 复制代码
    timeout /t 10 >nul
    netstat -ano | findstr :8178
    netstat -ano | findstr :5167

后端启动流程示意图:

辅助脚本

  • check_status.cmd:Windows环境服务状态检查(进程与端口监听)
  • start_with_output系列:在新窗口启动服务实时显示日志(调试专用)

脚本化管理的优势

优势项 说明
操作简便 单命令启动复杂系统
可靠性增强 确保服务启动顺序正确并清理残留进程
流程自动化 自动处理编译和环境配置等重复性工作
环境一致性 提供跨平台的标准化操作流程
故障排查 状态检查脚本和输出窗口便于问题诊断

总结

本章解析了后端服务管理脚本 的核心价值:通过build_whisper实现环境准备,借助clean_start_backend实现服务启动自动化。

这些脚本作为控制面板,隐藏了多进程管理的复杂性,确保系统可靠启动。

至此我们已完成meeting-minutes后端核心概念的全栈解析,从API入口到AI交互,从数据存储到语音转录,最终通过管理脚本实现系统整合。祝贺完成本教程体系!

相关推荐
卡卡_R-Python2 分钟前
C++编程基础
c++
测试199814 分钟前
软件测试之压力测试总结
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·压力测试
SoFlu软件机器人17 分钟前
Cursor、飞算JavaAI、GitHub Copilot、Gemini CLI 等热门 AI 开发工具合集
人工智能·github·copilot
李昊哲小课42 分钟前
销售数据可视化分析项目
python·信息可视化·数据分析·matplotlib·数据可视化·seaborn
isNotNullX1 小时前
实时数仓和离线数仓还分不清楚?看完就懂了
大数据·数据库·数据仓库·人工智能·数据分析
Azxcc01 小时前
C++迭代器失效
开发语言·c++
烛阴1 小时前
带参数的Python装饰器原来这么简单,5分钟彻底掌握!
前端·python
Liudef061 小时前
大语言模型的极限:知识、推理与创造力的边界探析
人工智能·语言模型·自然语言处理
潮湿的心情1 小时前
亚洲牧原:活跃行业交流,延伸公益版图,市场拓展再结硕果
大数据·人工智能