Windows + AMD 显卡部署 whisper.cpp:中文转写、本地 API 与登录自启动实战 2026-10-11 程序之旅,记录 暂无评论 4 次阅读 # Windows + AMD 显卡部署 whisper.cpp:中文转写、本地 API 与登录自启动实战 > 本文记录一次实际部署:Ryzen 5 3600、约 32GB 内存、Radeon RX 6700 XT,使用 whisper.cpp、Vulkan 和 large-v3-turbo Q8 模型,在 Windows 上搭建本地语音转写服务。部署与测试日期:2026 年 10 月 11 日。 我希望让电脑提供一个随时可用的语音转写接口:音频在本机处理,支持中文,可以通过网页上传,也能让支持自定义转写地址的客户端调用。开机登录后,服务自动在后台运行。 最后采用的方案是:**whisper.cpp 负责识别,Vulkan 使用 AMD 显卡加速,Python 提供 OpenAI 兼容的转写 API,Windows 启动文件夹负责登录自启动。** 下面记录完整流程。文中的命令使用 Windows PowerShell 语法,下载命令明确使用 `curl.exe`,避免 Windows PowerShell 将 `curl` 解释成别名。 ## 一、先看硬件,再选模型 这次部署的电脑配置如下: | 项目 | 实际配置 | |---|---| | CPU | AMD Ryzen 5 3600,6 核 12 线程 | | 内存 | 31.9GB | | GPU | AMD Radeon RX 6700 XT | | 系统 | Windows,x64 | | 后端 | Vulkan | | 计算线程 | 6 | | 模型 | large-v3-turbo Q8,多语言版本 | 可以用 PowerShell 查看基础信息: ```powershell Get-CimInstance Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors Get-CimInstance Win32_ComputerSystem | Select-Object TotalPhysicalMemory Get-CimInstance Win32_VideoController | Select-Object Name, DriverVersion ``` 这里有一个容易误判的地方:`Win32_VideoController.AdapterRAM` 在这台电脑上返回约 4GB,不能据此断言显卡只有 4GB 显存。因此,本文不拿这个值作为选型依据,而是通过后端实际识别和模型加载来确认可用性。 对 AMD 显卡,这次选择 Vulkan,而不是 CUDA。实际运行中,日志明确识别到了 RX 6700 XT,并使用 `Vulkan0` 完成推理。 模型选择 **`ggml-large-v3-turbo-q8_0.bin`**。它是多语言模型,能处理中文;文件大小为 **874,188,075 字节,约 874MB(834MiB)**。Q8 是量化版本,相比未量化权重减少了存储占用。选择它,是为了在下载体积、识别质量和处理速度之间取得合适的平衡;本文没有做多模型准确率评测,不能据此宣称它在所有任务上最优。 另外,模型文件大小不等于实际显存占用。运行时还会分配缓存和计算缓冲区。 ## 二、弄清楚各组件分别做什么 整个处理链路可以理解为: ```text 网页或客户端上传音频 ↓ Python / FastAPI 接收请求 ↓ FFmpeg 转换为 16kHz 单声道 WAV ↓ whisper.cpp CLI 调用 Vulkan 进行识别 ↓ 返回文字、段落时间戳或字幕 ``` 这里需要区分两个概念: - **OpenAI 兼容接口**:让客户端通过 `/v1/audio/transcriptions` 这样的路径提交转写请求。 - **OpenAPI 文档**:描述接口参数与结构的规范文件,本次服务通过 `/openapi.json` 提供,并通过 `/docs` 展示交互式文档。 它们不是同一个东西。这次部署同时实现了两者,但不包含聊天接口,也不是完整复刻 OpenAI 的全部音频 API。 ## 三、准备目录与源码 为了方便复现,下面统一使用: ```text C:\AI\whisper-local ``` 实际部署可以选择其他路径,只需同步调整启动入口中的绝对路径。建议不要放在临时目录。 本文配套文件为 **`whisper-blog-source.zip`**。解压后包含: ```text whisper-local/ ├── api.py # OpenAI 兼容转写接口及上传页面 ├── config.json # 模型、后端、端口等配置 ├── background.py # 后台启动、单实例控制、日志 ├── stop_background.py # 正常停止后台服务 ├── requirements.txt # Python 直接依赖版本 ├── start-api.cmd # 前台启动,便于调试 ├── start-background.cmd # 后台启动 ├── stop-background.cmd # 停止后台服务 └── Whisper Local API.cmd # 放入 Windows 启动文件夹的入口 ``` **源码包不包含 whisper.cpp 二进制和模型,需要按后续步骤下载。** 它也不包含本机日志、运行状态文件或停止控制凭据。博客发布时,建议将这个源码包作为附件一起提供,否则读者无法直接得到文中使用的自定义 API 程序。 解压到 `C:\AI` 后,应能找到 `C:\AI\whisper-local\api.py`。 ## 四、安装或复用 Python,创建独立环境 我的电脑已经有可用的 Python,后来复核的实际版本为 **3.13.14**,所以没有再次安装另一套 Python。 读者如果尚未安装 Python,可以从 [Python 官方 Windows 下载页面](https://www.python.org/downloads/windows/) 安装 x64 版本。本文测试环境为 Python 3.13;安装时可勾选加入 PATH。安装后重新打开 PowerShell,用以下命令确认: ```powershell python --version ``` 若 `python` 未正确解析,应使用实际安装位置的 `python.exe`,不要仅凭命令名称认定环境已可用。 为项目创建虚拟环境: ```powershell $root = 'C:\AI\whisper-local' python -m venv "$root\.venv" & "$root\.venv\Scripts\python.exe" -m pip install -r "$root\requirements.txt" ``` 配套文件记录的直接依赖为: ```text fastapi==0.143.0 uvicorn==0.54.0 python-multipart==0.0.32 imageio-ffmpeg==0.6.0 ``` `python-multipart` 用来接收上传文件,`imageio-ffmpeg` 在本次 Windows 环境提供了可用的 FFmpeg 二进制。模型推理由 whisper.cpp 完成,Python 主要负责服务适配。 安装后可以验证依赖与 FFmpeg 路径: ```powershell & "$root\.venv\Scripts\python.exe" -c "import fastapi, uvicorn, multipart, imageio_ffmpeg; print(imageio_ffmpeg.get_ffmpeg_exe())" ``` ## 五、安装 whisper.cpp:注意官方 CPU 包与 Vulkan 包的区别 本次下载的官方 Windows x64 包来自 **b5454**,是 v1.9.5 发布说明所关联的构建。这个包包含 CPU 后端和 `whisper-server.exe`,但**不包含本次需要的 Vulkan 后端**。 因此最终保留了两套引擎: 1. 官方 CPU 包,用于备用。 2. 社区预编译 Vulkan 包,用于 RX 6700 XT 加速。 ### 1. 下载并校验二进制 ```powershell $root = 'C:\AI\whisper-local' New-Item -ItemType Directory -Force "$root\downloads", "$root\models" | Out-Null curl.exe -fL --retry 2 -o "$root\downloads\whisper-bin-x64.zip" 'https://github.com/ggml-org/whisper.cpp/releases/download/b5454/whisper-bin-x64.zip' curl.exe -fL --retry 2 -o "$root\downloads\whisper-vulkan-win-x64.zip" 'https://github.com/eviscerations/whisper-windows-mcp/releases/download/v1.4.0/whisper-vulkan-win-x64.zip' ``` 本文实际核对的 SHA-256 为: | 文件 | SHA-256 | |---|---| | 官方 CPU 包 | `6ba69e3482d7826214f90a6a9c84ca07782aec1e1d0c6a7c30c994fd5d816ccb` | | 社区 Vulkan 包 | `8913366b0d97764767bacaf73b23e433563ab97dee6ce9550460a54215669ddb` | 可以在解压前自动校验: ```powershell $cpuHash = (Get-FileHash "$root\downloads\whisper-bin-x64.zip" -Algorithm SHA256).Hash $gpuHash = (Get-FileHash "$root\downloads\whisper-vulkan-win-x64.zip" -Algorithm SHA256).Hash if ($cpuHash -ne '6ba69e3482d7826214f90a6a9c84ca07782aec1e1d0c6a7c30c994fd5d816ccb') { throw 'CPU archive checksum mismatch' } if ($gpuHash -ne '8913366b0d97764767bacaf73b23e433563ab97dee6ce9550460a54215669ddb') { throw 'Vulkan archive checksum mismatch' } Expand-Archive "$root\downloads\whisper-bin-x64.zip" -DestinationPath "$root\bin" Expand-Archive "$root\downloads\whisper-vulkan-win-x64.zip" -DestinationPath "$root\vulkan" ``` 解压后的关键文件应包括: ```text bin\Release\whisper-cli.exe vulkan\whisper-cli.exe vulkan\ggml-vulkan.dll vulkan\ggml-cpu.dll vulkan\whisper.dll ``` 不要混用两个目录里的 DLL;可执行文件应和所属版本的动态库保存在一起。 **来源说明:Vulkan 包是社区构建,不是 whisper.cpp 官方 Vulkan 发行包。** 校验哈希用于确认下载内容和指定发行资产一致,不等于对源码、构建过程做了安全审计。这次也没有安装该社区项目的 MCP 服务。 如果希望完全自行构建,可以从官方 whisper.cpp 源码构建,需要 C++ 编译工具、CMake 和匹配源码要求的 Vulkan SDK;核心构建选项为 `-DGGML_VULKAN=ON`。本次使用预编译包,没有实际执行这条源码构建路线。 ### 2. 验证 AMD GPU 是否被识别 ```powershell & "$root\vulkan\whisper-cli.exe" --help ``` 这台电脑输出了: ```text ggml_vulkan: Found 1 Vulkan devices: ggml_vulkan: 0 = AMD Radeon RX 6700 XT ... ``` 这一步只能说明后端能够识别设备,接下来还需要加载模型、完成真实转写。 ## 六、下载模型并核对完整性 模型来自 `ggerganov/whisper.cpp` 模型仓库。原站连接不顺畅,因此本次通过镜像下载: ```powershell curl.exe -fL --retry 2 -o "$root\models\ggml-large-v3-turbo-q8_0.bin" 'https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo-q8_0.bin' $modelHash = (Get-FileHash "$root\models\ggml-large-v3-turbo-q8_0.bin" -Algorithm SHA256).Hash if ($modelHash -ne '317eb69c11673c9de1e1f0d459b253999804ec71ac4c23c17ecf5fbe24e259a1') { throw 'Model checksum mismatch' } ``` 原始模型地址为: ```text https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo-q8_0.bin ``` 文件大小为 **874,188,075 字节**。下载失败时,不要把不完整的文件当作已安装模型;应先检查命令状态、文件大小与 SHA-256。 ## 七、先验证 CLI,再启动 API 用官方仓库提供的 11 秒英文样本验证: ```powershell curl.exe -fL -o "$root\downloads\jfk.wav" 'https://raw.githubusercontent.com/ggml-org/whisper.cpp/v1.9.5/samples/jfk.wav' & "$root\vulkan\whisper-cli.exe" -m "$root\models\ggml-large-v3-turbo-q8_0.bin" -f "$root\downloads\jfk.wav" -l en -t 6 ``` 本次日志确认: ```text use gpu = 1 using Vulkan0 backend ``` 识别结果正确,CLI 日志记录的总时间约 **4.85 秒**,模型加载约 **1.17 秒**。这证明该配置可以工作,但只是短音频样本,不代表长音频、噪声录音和多语言任务都有相同速度。 ## 八、配置 OpenAI 兼容转写 API 官方 `whisper-server` 文档的默认转写路径是 `/inference`。本次为方便客户端接入,使用配套 `api.py` 提供 `/v1/audio/transcriptions`,底层调用 Vulkan 版 CLI。 这意味着:**单独解压 whisper.cpp,不会自动得到本文的 `/v1` 服务。** 必须准备配套 Python 程序,并启动它。 关键配置保存在 `config.json`: ```json { "host": "127.0.0.1", "port": 8178, "backend": "vulkan", "executable": "vulkan/whisper-cli.exe", "cpu_executable": "bin/Release/whisper-cli.exe", "model": "models/ggml-large-v3-turbo-q8_0.bin", "model_id": "large-v3-turbo", "threads": 6, "gpu_device": 0, "default_language": "auto", "max_upload_mb": 256, "timeout_seconds": 1800 } ``` 当前代码的请求语言默认值是 `auto`;想指定中文,应在网页或请求参数中设置 `language=zh`。`default_language` 是配置预留字段,本版接口未用它覆盖请求默认值。 前台启动便于观察日志: ```powershell & "$root\.venv\Scripts\python.exe" "$root\api.py" ``` 看到服务监听 `http://127.0.0.1:8178` 后,即可访问: | 地址 | 用途 | |---|---| | `http://127.0.0.1:8178/` | 上传音频的网页 | | `http://127.0.0.1:8178/health` | 健康检查 | | `http://127.0.0.1:8178/v1/models` | 模型名称列表 | | `http://127.0.0.1:8178/docs` | 交互式接口文档 | | `http://127.0.0.1:8178/openapi.json` | OpenAPI 描述文件 | ### 客户端该怎么填? | 配置项 | 填写内容 | |---|---| | Base URL | `http://127.0.0.1:8178/v1` | | 转写接口 | `http://127.0.0.1:8178/v1/audio/transcriptions` | | 模型 | `whisper-1` 或 `large-v3-turbo` | | 语言 | `zh`,或 `auto` | | API Key | 可留空;强制必填时填 `local-not-required` | **`whisper-1` 和 `large-v3-turbo` 在这套服务里调用的是同一个本地 Q8 模型。** 前者只是兼容别名,并没有调用 OpenAI 云端,也不存在两种名称之间的性能差异。 **`local-not-required` 是占位文本,不是真正的密钥。** 本版转写 API 没有校验 `Authorization` 请求头,其他非空字符串也可以。以后若要开放到其他机器,应另行增加访问控制;当前仅监听本机回环地址。 注意,有些客户端需要填写完整转写 URL,有些使用 Base URL 自动拼接路径,应根据客户端的具体设置选择,避免拼出两个 `/v1`。 ### 测试一次中文转写 将下面的文件路径换成自己的音频: ```powershell curl.exe -fS 'http://127.0.0.1:8178/v1/audio/transcriptions' -F 'file=@C:/path/audio.mp3' -F 'model=whisper-1' -F 'language=zh' -F 'response_format=json' ``` 本次使用公开中文样本,返回: ```json {"text":"欢迎大家来体验达摩院推出的语音识别模型"} ``` 想生成字幕,把 `response_format` 改为 `srt` 或 `vtt`。实际中文 MP3 转 SRT 测试也通过了。 ## 九、配置 Windows 登录后自启动 前台运行时需要保持终端窗口打开。为日常使用,本次增加了 `background.py`,通过 `pythonw.exe` 在后台运行。 后台程序做了几件事: - 使用命名互斥锁避免重复启动。 - 将服务日志写入 `logs\whisper-api.log`,按 5MB 轮转,保留 3 份历史日志。 - 将启动异常和标准输出写入 `logs\background-errors.log`;这个辅助日志不轮转。 - 提供本机控制凭据保护的停止接口,由配套停止脚本调用。 - 转写子进程使用 `CREATE_NO_WINDOW`,避免 FFmpeg 或 CLI 弹出控制台窗口。 ### 1. 先停止前台服务 在运行 `api.py` 的窗口按 **Ctrl+C**。不要让前台和后台服务同时争用 8178 端口。 ### 2. 测试后台启动 双击配套的 `start-background.cmd`,或在 PowerShell 中运行: ```powershell Start-Process -FilePath "$root\.venv\Scripts\pythonw.exe" -ArgumentList ('"' + "$root\background.py" + '"') -WorkingDirectory $root ``` 然后打开健康检查或上传页面,确认服务正常。 ### 3. 将启动入口放入当前用户的启动文件夹 配套 `Whisper Local API.cmd` 默认内容如下: ```bat @echo off start "" "C:\AI\whisper-local\.venv\Scripts\pythonw.exe" "C:\AI\whisper-local\background.py" exit /b ``` 如果选择了其他安装位置,先修改这两个绝对路径。 通过 PowerShell 放入启动文件夹: ```powershell $startup = [Environment]::GetFolderPath('Startup') Copy-Item -LiteralPath "$root\Whisper Local API.cmd" -Destination $startup ``` 也可以按 **Win+R**,输入 `shell:startup`,把文件手动放进去。 此后,当前用户登录 Windows 时会自动运行这个入口。启动窗口可能短暂闪过,随后服务在后台运行,无需打开 WorkBuddy或保持终端窗口。 ### 4. 启动、停止和取消自启动 - **手动后台启动**:双击 `start-background.cmd`。 - **停止后台服务**:双击 `stop-background.cmd`。 - **取消下次登录自启动**:将 `Whisper Local API.cmd` 移出启动文件夹。 停止服务不会取消下次登录自启动;取消自启动也不会自动停止当前运行的实例。 这里配置的是**当前用户登录后启动**,不是登录前运行的 Windows 系统服务,也未设置崩溃后自动拉起。 本次已经实际执行了启动文件夹内入口,验证启动、正常停止和再次启动,但没有重启电脑测试完整登录过程。 ## 十、部署过程中遇到的几个问题 ### 下载或浏览页面失败,不等于项目不可用 本次网页读取及部分下载遇到连接问题,随后通过官方 GitHub API 获取发行资产信息,模型则通过镜像下载并核对哈希。换下载通道后仍要核对来源与文件完整性。 ### 官方包没有 Vulkan,不能拿“下载完成”当作 GPU 部署完成 要确认是否存在 `ggml-vulkan.dll`,再看运行日志是否真的使用 `Vulkan0`。这次通过实际音频转写验证了 GPU 后端。 ### 后台运行时需要主动保存日志 `pythonw.exe` 通常没有控制台标准输出。若不设置日志,启动异常可能只表现为“网页打不开”。因此本次显式配置了日志文件,并为相关库准备了可写的输出流。 ### 快捷方式创建受到环境策略限制 原本计划创建登录启动快捷方式,但部署环境阻止了相关 COM 调用。最终使用启动文件夹里的 `.cmd` 入口完成自启动。这是本次工具环境的限制,并不是所有 Windows 电脑都不能创建快捷方式。 ### 出现端口占用时,先检查已有服务 如果 8178 已占用,先访问 `/health`。服务已经正常运行时,不需要反复启动。若想改端口,应修改 `config.json` 后重启;配套后台程序的互斥锁名称按本次 8178 单实例场景设计,不应直接用于同时运行多个不同端口实例。 ## 十一、实测与功能边界 | 验证项 | 结果 | |---|---| | Vulkan 识别 RX 6700 XT | 通过 | | large-v3-turbo Q8 加载与推理 | 通过 | | 11 秒英文样本 | 正确转写,CLI 总时间约 4.85 秒 | | 中文音频 | 成功返回中文文本 | | 中文 MP3 → SRT | 通过 | | 健康检查、模型列表、OpenAPI 导出 | 通过 | | 空文件请求 | 正确返回 HTTP 400 | | 后台启动、停止、再次启动 | 通过 | | 完整重启后登录验证 | 本次未执行 | 这套方案的边界也需要明确: - 每个请求调用一次 CLI,重新加载模型,没有常驻模型推理服务。 - 一次处理一个请求,忙碌时返回 429;没有完善的任务队列。 - 支持 `json`、`text`、`verbose_json`、`srt`、`vtt`。 - `verbose_json` 提供段落时间戳,不提供词级时间戳。 - 上传文件大小限制为 256MB,转换超时 180 秒,转写超时 1800 秒。 - 不支持流式转写、说话人分离、聊天接口或完整 OpenAI API 功能集。 - 转写请求使用临时目录,处理结束后清理;模型和引擎安装完成后,推理无需云端接口。 - API 的 Swagger 文档默认可能从外部 CDN 加载页面资源;这不等于音频被上传到云端。普通上传页使用本地资源。 如果后续要做高频调用、长录音批处理或多人访问,可以进一步考虑模型常驻、任务队列、鉴权与更完善的运行管理;这些不在本次部署范围内。 ## 参考与配套文件 - whisper.cpp 官方仓库:https://github.com/ggml-org/whisper.cpp - 官方 b5454 发行资产:https://github.com/ggml-org/whisper.cpp/releases/tag/b5454 - 官方服务器文档:https://github.com/ggml-org/whisper.cpp/blob/v1.9.5/examples/server/README.md - 本次使用的社区 Vulkan 包:https://github.com/eviscerations/whisper-windows-mcp/releases/tag/v1.4.0 - 模型仓库:https://huggingface.co/ggerganov/whisper.cpp - 模型下载镜像:https://hf-mirror.com/ggerganov/whisper.cpp - 英文测试样本:https://github.com/ggml-org/whisper.cpp/blob/v1.9.5/samples/jfk.wav - 中文测试样本:https://github.com/modelscope/FunASR/blob/main/runtime/funasr_api/asr_example.wav - Python Windows 下载:https://www.python.org/downloads/windows/ 这次部署的结果,是让现有 Windows 和 AMD 显卡电脑提供了一个可直接调用的本地中文转写接口。实际落地最关键的步骤,是确认 GPU 后端真正参与推理、明确 API 适配层的职责,并把后台启动与日志一起配置好。 打赏: 微信, 支付宝 标签: ai, whisper 本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。