如何用 Vosk 跑通 50MB 离线语音识别:从本地加载到流式转写的完整落地
2026/9/11 16:54:40 网站建设 项目流程

如何用 Vosk 跑通 50MB 离线语音识别:从本地加载到流式转写的完整落地

【免费下载链接】vosk-apiOffline speech recognition API for Android, iOS, Raspberry Pi and servers with Python, Java, C# and Node项目地址: https://gitcode.com/GitHub_Trending/vo/vosk-api

Vosk 是开源的离线语音识别工具箱,把 ASR 模型直接跑在本机:模型 50MB,Python、Java、Node、Go、C 都能调用,支持 20 多种语言,边说话边出字,不依赖网络。以一场 2 小时的评审会为例,人工整理纪要约 1.5 小时(约 75 元),走云端 ASR 则要把录音传给第三方服务器,费用和隐私都卡住。Vosk 的做法是把识别搬到本地,音频不进云端,转写只花处理时间。

为什么离线识别值得单独做一套

云端 ASR 按量计费、数据出本机、网络往返带来延迟;大模型(如本地 Whisper)体积动辄数百 MB 到 GB,树莓派和手机装不下。Vosk 用 Kaldi(开源语音识别工具包)训练的 50MB 小模型换来了三件事:

  • 体积小:小模型约 50MB,能塞进 Android 手机、树莓派这类端侧设备;
  • 流式零延迟:streaming API 边收音频边出字,不用等整段说完;
  • 一套内核多语言绑定:Python、Java、Node、Go、C、C#、Kotlin、Ruby 包的是同一个 C 内核,换语言不用换模型。

整体架构一览

音频按固定大小的块连续喂给识别器,每块都会尝试出结果:话没说完时给中间结果(partial),停顿时才给整句,最后FinalResult收尾。

核心模块拆解

选对模型:语言、名称与本地路径

模型有三种加载方式:lang按语言自动下载,model_name按名称、Model("路径")按本地文件夹加载。小模型体积约 50MB,是端侧首选:

from vosk import Model, SetLogLevel SetLogLevel(-1) # 关闭调试日志,生产环境建议 model = Model(lang="en-us") # 按语言自动下载,约 50MB # model = Model(model_name="vosk-model-en-us-0.21") # 按名称加载 # model = Model("models/en") # 按本地路径加载

产出:一个Model对象,后续所有识别器共享它。输入规格统一为 16kHz 单声道 PCM(原始未压缩采样),音频不符合会识别失败。

流式识别主循环:怎么喂、出什么

参考 python/example/test_simple.py,核心是AcceptWaveform返回值的分叉:返回True表示句末,给整句;否则给当前中间结果。开SetWords后还能拿到每个词的时间戳:

rec = KaldiRecognizer(model, wf.getframerate()) rec.SetWords(True) # 输出词级时间戳 while True: buf = wf.readframes(4000) # 每次读 4000 字节 if not buf: break if rec.AcceptWaveform(buf): # True = 句末,返回整句 print(json.loads(rec.Result())["text"]) else: print(json.loads(rec.PartialResult())["partial"]) # 实时中间结果

配什么:16kHz 单声道wave文件;怎么跑:每轮读 4000 字节喂入;产出:说话中的实时字幕 + 句末整句。

批量转写与字幕导出:整目录一键出 SRT

单文件够用,但会议纪要、访谈录音往往是几十上百个文件。仓库自带转写器 python/vosk/transcriber/cli.py 支持整目录并行转写,直接输出 SRT 字幕、TXT 或 JSON:

# 整目录转写,输出 SRT 字幕,10 个并行任务 python -m vosk.transcriber.cli \ --model models/en \ --input audio_dir/ \ --output srt_out/ \ --output-type srt \ --tasks 10

产出:与输入音频同名的.srt文件,词级时间戳已对齐;--tasks调高可加速批量处理。

底层 C API:所有绑定都包它

上层语言绑定其实都包同一个 C 内核。看 c/test_vosk.c 就明白整个识别流程只有四个函数:建模、喂块、取结果、释放。换语言时不用重新理解模型,只换调用封装:

#include <vosk_api.h> VoskModel *m = vosk_model_new("model"); // 加载模型 VoskRecognizer *r = vosk_recognizer_new(m, 16000.0); // 16kHz 识别器 char buf[3200]; int n; while ((n = fread(buf, 1, sizeof(buf), wavin)) > 0) { if (vosk_recognizer_accept_waveform(r, buf, n)) printf("%s\n", vosk_recognizer_result(r)); } printf("%s\n", vosk_recognizer_final_result(r)); vosk_recognizer_free(r); vosk_model_free(m); // 释放资源

效果验证:训练与转写的实测口径

training/目录提供基于 Kaldi 的自训管线(入口 training/run.sh),其结果文件里的 WER(字错误率,Word Error Rate,越低越好)是衡量模型质量的硬指标:

指标数值说明
模型体积50 MB小模型,端侧可运行
采样率16 kHz 单声道标准输入规格
WER(基线解码)14.10%首次解码结果
WER(语言模型重打分)12.67%重打分后,约每 100 词错 13 个

解读:WER 从 14.10% 降到 12.67% 说明语言模型重打分有效;对会议转写这类场景,这是可接受的起点,可通过扩大词典和语言模型进一步压低。

上生产:打包方式与最小集成

打包:Python 侧pip install vosk,模型解压为文件夹(约 50MB);其他语言用各自包管理器引入,模型是同一份。

最小集成示例(安装后可直接运行,共 13 行):

# pip install vosk 后整段运行 from vosk import Model, KaldiRecognizer, SetLogLevel import wave, json SetLogLevel(-1) model = Model(lang="en-us") # 首次运行自动下载 50MB 模型 wf = wave.open("test.wav", "rb") # 必须 16kHz 单声道 PCM rec = KaldiRecognizer(model, wf.getframerate()) while True: buf = wf.readframes(4000) if not buf: break if rec.AcceptWaveform(buf): print(json.loads(rec.Result())["text"]) print(json.loads(rec.FinalResult())["text"])

关键性能指标

  • 模型体积 50 MB,内存占用与其成正比,建议部署前用tracemalloc或系统工具实测;
  • 输入规格 16 kHz 单声道 PCM,其他采样率需先用 ffmpeg 重采样;
  • 实时率(RTF,Real-Time Factor)要求 < 1,即处理 10 秒音频不到 10 秒,转写器会用xRT打印实测值。

后续方向

Vosk 把 50MB 离线语音识别从云端搬到了本地,流式出字、多语言绑定、端侧可跑都已跑通。后续两个方向比较实际:一是用training/管线针对行业词汇(医学术语、产品名)重训压低 WER;二是把 C 内核封装进树莓派或手机的常驻服务,做离线会议纪要。欢迎在评论区交流你的实测数据和踩坑点。

【免费下载链接】vosk-apiOffline speech recognition API for Android, iOS, Raspberry Pi and servers with Python, Java, C# and Node项目地址: https://gitcode.com/GitHub_Trending/vo/vosk-api

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询