Whisper.cpp 离线语音识别实战:不联网,三步跑通本地语音转文字
【免费下载链接】whisper.cppPort of OpenAI's Whisper model in C/C++项目地址: https://gitcode.com/GitHub_Trending/wh/whisper.cpp
你需要把两小时会议录音转成文字,但录音涉及商业机密,上传给云端 API 有隐私风险,而会议室根本没有网络?Whisper.cpp 就是为这类场景准备的:它是 OpenAI Whisper 语音识别模型的 C/C++ 移植,在你自己的电脑或设备上完成离线语音识别,全程不碰网络。这篇文章带你从克隆仓库到输出第一条转写结果,再进阶到批量字幕、麦克风实时转写和程序集成。
📌 项目速览:它是什么、适合谁
| 项目 | 说明 |
|---|---|
| 一句话定位 | OpenAI Whisper 模型的高性能 C/C++ 移植版,纯本地推理 |
| 解决的问题 | 无网络、重隐私环境下的语音转文字,零 API 费用 |
| 适合谁 | 新手:3 条命令出结果;开发者:通过 C API 嵌入自己的应用 |
| 支持平台 | macOS、Linux、Windows、iOS、Android、WebAssembly、树莓派 |
| 模型档位 | 从 tiny(内存约 273 MB)到 large-v3(约 3.9 GB)共 8 档,另有量化版本 |
| 代码构成 | 核心实现集中在 include/whisper.h 和 src/whisper.cpp,底层计算来自自带的 ggml 库 |
🏁 快速上手:三条命令跑通本地语音转文字
先跑通,再谈原理。整个过程只需四步,仓库自带一条 12 秒的示例音频 samples/jfk.wav。
# 1. 克隆仓库 git clone https://gitcode.com/GitHub_Trending/wh/whisper.cpp cd whisper.cpp # 2. 编译(需要 CMake 和 C++ 编译器) cmake -B build cmake --build build --config Release # 3. 下载 base.en 模型(约 142 MB) bash models/download-ggml-model.sh base.en # 4. 转写示例音频 ./build/bin/whisper-cli -f samples/jfk.wav -m models/ggml-base.en.bin你会看到类似这样的输出(时间戳 + 文本):
[00:00:00 --> 00:00:04] And so my fellow Americans... [00:00:04 --> 00:00:12] ask not what your country will do for you...想省步骤的话,直接执行make base.en也可以:它会自动下载模型、编译,并跑完 samples 目录下所有 WAV 文件。
注意:命令行工具目前只接受16-bit WAV格式。手头是 MP3 或 OGG 时,先用 ffmpeg 转一下:
ffmpeg -i input.mp3 -ar 16000 -ac 1 -c:a pcm_s16le input.wav🧩 原理与模型选择:规模、内存、精度怎么权衡
Whisper 的架构是"编码器 + 解码器":编码器把 16 kHz 的音频切成 30 秒的块做特征提取,解码器逐段吐出文本并给出时间戳。Whisper.cpp 做的事情就是把这套模型搬到本地,用 ggml 张量库做推理,并对 CPU 指令集(x86 的 AVX、ARM 的 NEON)和 GPU(Apple Metal、NVIDIA CUDA 等)做了优化。
你唯一要做的选择是模型档位。带.en后缀的是纯英文模型,更小更快;不带后缀的是多语言模型,可识别数十种语言并用--translate翻译成英文。
| 模型 | 磁盘占用 | 内存占用 | 适用判断 |
|---|---|---|---|
| tiny / tiny.en | 75 MiB | ~273 MB | 资源受限设备、实时场景,速度优先 |
| base / base.en | 142 MiB | ~388 MB | 默认推荐,速度与准确率平衡点 |
| small / small.en | 466 MiB | ~852 MB | 需要更高准确率,普通电脑可跑 |
| medium / medium.en | 1.5 GiB | ~2.1 GB | 高精度需求,内存要够 |
| large-v1/v2/v3 | 2.9 GiB | ~3.9 GB | 精度天花板,建议配 GPU 或量化版 |
下载任意档位都用同一个脚本 models/download-ggml-model.sh:
# 不带参数运行可查看当前支持的全部模型 bash models/download-ggml-model.sh small经验法则:先拿base.en(英文)或base(多语言)验证流程,效果不满意再升档,不要一上来就下 3 GB 的 large。
🎬 分场景实战:批量字幕、实时转写与程序集成
场景一:批量转写并导出字幕(会议录音、播客剪辑)
whisper-cli支持一次传入多个文件,并能直接产出 txt / srt / vtt 等格式,不用自己解析:
# 中文录音:指定语言 + 同时导出文本和 SRT 字幕 ./build/bin/whisper-cli -l zh -otxt -osrt -of output/note meeting1.wav meeting2.wav # 不确定语言时,先只检测不转写 ./build/bin/whisper-cli -m models/ggml-small.bin -dl -f podcast.mp3.wav常用参数速记:-l LANG指定语言(auto自动检测)、-tr翻译成英文、-t N线程数、-of输出前缀、--prompt "..."给解码器一段提示词(比如专有名词,可减少同音字错误)。完整列表用./build/bin/whisper-cli -h查看。
如果习惯用脚本处理,examples/python/whisper_processor.py 提供了一个现成的 Python 封装,调用转写并返回文本,适合快速写批处理逻辑。
场景二:麦克风实时转写(语音助手、现场记录)
examples/stream 目录下的whisper-stream工具从麦克风持续采样并滚动转写。它依赖 SDL2 采集音频,需要先安装并重新编译:
# Debian/Ubuntu 或 macOS sudo apt-get install libsdl2-dev # macOS 则用: brew install sdl2 cmake -B build -DWHISPER_SDL2=ON cmake --build build --config Release # 每 500ms 处理最近 5 秒音频 ./build/bin/whisper-stream -m models/ggml-base.en.bin -t 8 --step 500 --length 5000更省资源的用法是滑动窗口模式:--step 0开启 VAD(语音活动检测),只有检测到说话时才转写,适合长时间挂机录音:
./build/bin/whisper-stream -m models/ggml-base.en.bin -t 6 --step 0 --length 30000 -vth 0.6-vth是 VAD 阈值,调高会更容易判定为静音,可按实际环境微调,0.6 是通用起点。
场景三:嵌入你自己的 C++ 程序
核心库的 C 接口非常薄,官方用法示例就写在 include/whisper.h 的头部注释里。最小集成流程如下(pcmf32是你准备好的 16 kHz、单声道、32-bit float 音频数组):
#include "whisper.h" // 1. 加载模型,创建上下文 whisper_context_params cparams = whisper_context_default_params(); struct whisper_context * ctx = whisper_init_from_file_with_params("models/ggml-base.en.bin", cparams); // 2. 配置推理参数并执行转写 struct whisper_full_params params = whisper_full_default_params(WHISPER_SAMPLING_STRATEGY_GREEDY); params.language = "en"; params.n_threads = 4; if (whisper_full(ctx, params, pcmf32.data(), pcmf32.size()) != 0) { fprintf(stderr, "转写失败\n"); return 1; } // 3. 逐段取结果(文本 + 时间戳) for (int i = 0; i < whisper_full_n_segments(ctx); ++i) { printf("[%5d -> %5d] %s", whisper_full_get_segment_t0(ctx, i) / 10, whisper_full_get_segment_t1(ctx, i) / 10, whisper_full_get_segment_text(ctx, i)); } whisper_free(ctx);模型上下文只创建一次,之后可以对任意多段音频复用ctx,这是多线程批量处理的关键。不写 C++ 也没关系,仓库自带 Go 绑定、Java 绑定、Ruby 和 JavaScript 绑定,移动端还有现成的 Android 示例 和 iOS 示例可参考。
⚙️ 进阶调优:量化、线程数与性能测量
量化:把模型权重压成低比特整数,磁盘和内存占用明显下降,推理还可能更快,代价是少量精度损失。用仓库自带的 quantize 工具 生成量化模型:
./build/bin/quantize models/ggml-base.en.bin models/ggml-base.en-q5_0.bin q5_0 ./build/bin/whisper-cli -m models/ggml-base.en-q5_0.bin -f samples/jfk.wav内存紧张时优先上量化版;追求极限精度才用全精度。
线程数:-t N控制计算线程。简单策略:CPU 物理核心数减一。线程不是越多越好,开多了上下文切换反而拖慢长音频。
量化你的硬件:whisper-bench工具用随机音频只跑编码器部分并计时,方便对比不同模型/线程数/GPU 组合的相对速度:
./build/bin/whisper-bench -m models/ggml-small.en.bin -t 4GPU:Apple Silicon 上 Metal 加速是默认行为;NVIDIA 显卡和 Vulkan 通过对应的 CMake 编译选项开启。如果你的机器有合适的 GPU,同档位模型的吞吐通常能上一个台阶。
🩺 排错速查:从现象到解决
| 现象 | 原因 | 解决 |
|---|---|---|
| 报错提示音频格式不支持 | 工具只收 16-bit WAV,你的文件是 MP3/OGG | 用ffmpeg -i in.mp3 -ar 16000 -ac 1 -c:a pcm_s16le out.wav转换 |
| 下载模型失败或中途断掉 | 网络问题 | 重新运行下载脚本即可续传;也可手动下载ggml-<模型名>.bin放进 models/ 目录 |
| 中文音频输出的全是英文 | 用了.en纯英文模型 | 换多语言模型(如bash models/download-ggml-model.sh base)并用-l zh |
| 转写结果夹杂乱码或重复 | 解码器对噪声/长静音过度推测 | 降低-lpt(logprob 阈值)绝对值,或换更大的模型 |
| 速度太慢 | 线程没开满或模型太大 | 加-t参数、换量化版或更小档位;有 GPU 就启用 GPU |
| 内存不足崩溃 | 模型档位超过可用内存 | 看上面的内存占用表降档,或用 q5_0 量化模型 |
找不到whisper-stream | 默认编译未包含 SDL2 工具 | 用cmake -B build -DWHISPER_SDL2=ON重新编译 |
| 时间戳和实际说话位置对不上 | 音频前面有大量静音 | 用-ot N(毫秒偏移)或裁剪音频起点 |
📚 延伸资源与下一步
仓库里值得翻的角落:
- examples/:CLI、实时流、服务器接口、Android/iOS 完整工程等所有示例程序
- bindings/:Go、Java、Ruby、JavaScript 语言绑定
- tests/ 与 tests/run-tests.sh:各模型的标准测试与参考输出
- models/README.md:模型格式与转换脚本说明
- README.md:平台支持、GPU 选项、基准数据的总入口
下一步建议:先编译好仓库、跑通jfk.wav,再拿一段自己领域的真实录音(会议、课程、访谈)测一遍准确率和速度,最后根据场景定下"模型档位 + 线程数"的组合。离线语音识别这条路,你现在已经跑通了前九步。
【免费下载链接】whisper.cppPort of OpenAI's Whisper model in C/C++项目地址: https://gitcode.com/GitHub_Trending/wh/whisper.cpp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考