技术

在 CPU 上运行流式语音转文字:将 NVIDIA Nemotron 集成到桌面应用

OpenWhispr 如何通过本地 WebSocket 上的缓存感知流式模型,在不用 GPU 和云端的情况下边说边显示文字,以及让它可靠运行所需的工程工作。

OpenWhispr

OpenWhispr

工程

2026年7月18日
目录

流式语音转文字不必等待录音结束,而是在你说话时同步转录。从版本1.7.6开始,OpenWhispr完全在设备端完成这项工作:NVIDIA Nemotron 流式模型(600M参数、INT8量化)通过本地sherpa-onnx WebSocket服务器在CPU上运行;部分结果到达时听写预览会实时更新,停止时则立即将流式文字提交为正式转录。 无需 GPU,无需 Python 环境,音频也不会离开设备。

本文记录具体工程实现:旧版实时预览为何迟缓,缓存感知流式处理究竟是什么,整个管线如何装进Electron应用,版本固定错误为何导致全面误解码,以及我们如何从每次重新解码整段录音改为直接提交流。模型之间的比较请参阅 Parakeet vs Whisper vs Nemotron

最后更新于2026年7月18日。实现细节对应 OpenWhispr 1.7.6 发布的流式转录功能;文中内容均可在开源代码库中核查。

事实速查(第一手来源)

问题:在批处理模型上搭建实时预览

OpenWhispr一直有转录预览:听写时用一个小窗口显示模型听到的内容。1.7.6之前,我们采用了让批处理模型看起来实时的唯一办法:缓存约1.5秒麦克风音频,完整转录这个分块,追加文字,然后重复。

这种方式有三个结构性问题。第一是延迟:缓冲区填满前文字无法出现,因此预览总会落后1.5秒加推理时间。第二是边界:跨越两个分块的单词会被切断,而分块独立转录,双方都无法修正。第三是上下文:第五块不知道第四块说了什么,模型每1.5秒都要重新判断同一类歧义。

缩短分块会显得更快,却因上下文减少、边界增多而大幅降低准确率。重叠分块能修复边界,却要重复转录同一音频。真正需要的是为转录音频流而训练的模型,这就是Nemotron。

缓存感知流式处理究竟是什么

缓存感知流式模型会在分块之间保留内部状态。 下一段音频到达时,编码器不会重读此前全部语音,只处理新帧,并查询已计算上下文的缓存。它和让聊天机器人更快的KV缓存原理相同,只是用在语音编码器上。

这种设计带来两个结果。计算量不再随录音长度增长:无论录到10秒还是10分钟,每块成本都一样,因此纯CPU流式处理成为可能。上下文也会延续:模型利用此前全部语音解决歧义,后续音频给出新证据时会修正较早的词。文字在你说完后稍微“稳定”一下,不是故障,而是模型用更充分的依据改正判断。

延迟预算可以调节。Nemotron提供80ms(最快,每步上下文最少)到1.12s(准确率最高,在leaderboard数据集上平均6.93% WER,与最佳批处理模型相差约一个百分点)的分块。训练采用NVIDIA cache-aware FastConformer和transducer解码器;其 工程文章 深入解释了相关原理。

OpenWhispr 内部架构

OpenWhispr 中的实时流式处理路径

Microphone16kHz PCM via AudioWorklet
Local WebSocket127.0.0.1, float32 frames
Nemotron 0.6Bsherpa-onnx, INT8, CPU
Partial resultsJSON per chunk
Live previewText replaced in place
  • One persistent stream for the whole recording — the encoder cache carries context across chunks.
  • Everything is on-device: the WebSocket server is a local sherpa-onnx binary, not a cloud endpoint.
  • A clean flush at stop commits the streamed text as the final transcript; anything less falls back to a full re-decode.

管线刻意保持简单。AudioWorklet以16kHz采集麦克风PCM,将帧转换为float32传输格式,再通过WebSocket推送到sherpa-onnx online服务器。OpenWhispr在本地启动这个原生二进制,并通过127.0.0.1通信,每次录音保持一条长连接。服务器以INT8权重运行Nemotron并返回JSON部分结果;预览窗口会原地替换全文,而不是不断追加。

为何采用独立服务器进程,而不在进程内推理?为了隔离。原生推理运行时可能崩溃;ONNX内核一次错误的内存分配不应拖垮整个桌面应用。辅助进程崩溃只需重连,不会丢失听写。它也让原生代码完全离开Electron主进程:应用负责协议,辅助进程负责计算。

同一模式也用于我们的 本地说话人分离 ——一套sherpa-onnx工具链,多种任务,全都在设备端完成。

实现过程中踩过的坑

运行时版本比预想的更重要。 Nemotron需要sherpa-onnx 1.13.4或更新版本才能准确解码。在为Parakeet打包的旧运行时上,它不会明显报错,而是直接转录错误。修复很普通:升级并重新固定各平台二进制。普遍教训是,对模型运行时而言,“能运行”和“结果正确”是两项测试,只有后者算数。

流会失败,所以旧路径必须保留。 端口可能被占用,模型文件可能缺失,服务器也可能在录音中退出。若长连接无法启动,预览会自动回退到缓冲分块路径——更慢,但不会空白。offline模型(Parakeet、Whisper)本来就保留分块预览;注册表中的每个模型声明运行时为online或offline,应用据此选择。

部分结果需要不同的渲染方式。 分块路径追加文字,流式假设却会自我修正,因此UI在每个部分结果到达时替换整段预览。如果把会变的假设不断追加,就会产生断断续续的重复文字——这是我们很早修复的真实UX问题。

直接提交流:从两次解码到一次

第一版只把流式结果当作预览:停止听写后,应用会从头重新解码完整录音,并粘贴那份结果。这样很稳妥,因为最终处理能看到完整上下文;但每次听写都付出两次解码的成本,而且你已经看着文字稳定下来,却仍要等待几乎总是相同的第二意见。

于是我们在同一版本中把流设为事实来源。无论预览窗口是否打开,听写都会走长连接;停止时,应用刷新模型尾部,直接提交流式文字,不再进行第二次解码。结束延迟只剩一次尾部刷新,每次听写的CPU开销约减半。

安全网没有消失,而是成为回退机制。停止刷新会感知截断,只要结果仍在到达便延长期限。若连接中断或结果被截断,应用会丢弃流,改用经典的“先录音、后转录”方式处理完整录音。只有既快又正确时才走快速路径。

性能与资源占用

  • 模型: Nemotron Speech Streaming EN 0.6B(632MB)和Nemotron 3.5 ASR Streaming 0.6B(650MB、15种可转录语言、自动检测)——INT8 ONNX,只下载一次并在本地缓存。
  • 运行时: sherpa-onnx 1.13.4,自包含的原生二进制。无需Python、PyTorch或CUDA。
  • 硬件: 现代笔记本CPU可实时处理;Apple Silicon和较新的x86都能轻松跟上说话速度。
  • 体感: 部分文字落后语音远不到1秒;停止时一次尾部刷新即可提交转录,无需再次解码。

这条路径完全不接触互联网。应用通过127.0.0.1与服务器通信(Windows上还用限定范围的防火墙规则阻止网络访问该端口),模型文件位于本地缓存,音频从不离开设备。这与 我们的本地转录体系其余部分采用相同的隐私标准。

坦诚的局限

  • 流式处理以少量准确率换取即时性。 在相同基准上,流式约为~6.9%,NVIDIA最佳英语批处理模型为5.91%。现在正式转录来自流,因此你确实接受了这项取舍。若只在意最终结果,offline Parakeet仍是准确率更高的选择。
  • 语言覆盖范围小于Whisper。 多语言模型有15种可直接转录语言,Whisper则有99种。普通话和泰语流式识别目前尚不可用。
  • 部分文字会变化。 假设会随上下文修正。我们认为看着它逐渐稳定是一项优点;若觉得分心,可关闭预览,听写仍和以前完全一样。
  • 磁盘会再占用650MB 如果已经装有offline模型,这就是为不同任务优化第二套引擎的代价。

在 OpenWhispr 中选择模型

你的需求选择
听写时实时预览英语文字Nemotron Speech Streaming EN 0.6B
实时预览西班牙语、日语、阿拉伯语、印地语等Nemotron 3.5 ASR Streaming 0.6B
英语准确率最高,不需要实时文字Parakeet Unified EN 0.6B
使用NVIDIA范围外的语言Whisper (turbo 或 large)

这些模型都可在“设置”的下拉菜单中选择;完整的容量和取舍信息见 模型页面。OpenWhispr免费、开源,并支持macOS、Windows和Linux。

常见问题

什么是流式语音转文字?

流式(online)语音转文字会在说话尚未结束时处理音频,并在固定延迟范围内输出部分结果,通常为80毫秒到约1秒。Whisper 等批处理(offline)模型则要等录音结束后一次性处理全部内容。实时字幕、语音智能体和边说边显示的听写预览都依赖流式处理。

没有 GPU,能否在本地运行流式语音转文字?

可以。NVIDIA Nemotron 流式模型有600M参数,以约650MB的INT8量化ONNX文件提供,通过无需Python或PyTorch的原生二进制运行时sherpa-onnx,可在现代CPU上实时运行。OpenWhispr为macOS、Windows和Linux提供了这套配置。

什么是缓存感知流式 ASR?

这是 NVIDIA cache-aware FastConformer 架构:模型会在音频分块之间保留编码器内部状态。每个新分块只处理一次,并使用此前语音的缓存上下文,而不是重新编码相互重叠的音频窗口。因此,低延迟流式识别可以轻量到在笔记本CPU上运行。

实时预览文字为何显示后还会变化?

流式模型会随着更多音频到达而修正假设。单词边界或同音词有时只能靠后文确定,因此部分结果会原地替换。这是有意设计。停止听写时,OpenWhispr会刷新模型尾部,并将稳定后的流式文字写入转录;若刷新中断或结果被截断,应用会自动重新解码完整录音,绝不会把不稳定的流式结果粘贴出去。

流式转录是否不如批处理准确?

略低,因为流式模型无法看到未来音频。Nemotron 英语流式模型在 Open ASR Leaderboard 数据集上使用1.12秒分块时,平均词错误率为6.93%。这已非常接近批处理模型,但仍落后于 NVIDIA 最佳英语批处理模型的5.91%。选择流式模型,就是以这点差距换取实时文字和停止即得的转录;若最高准确率更重要,可选择offline Parakeet模型。

OpenWhispr 的流式模式支持哪些语言?

目前有两个 Nemotron 模型:仅英语模型,以及支持自动语言检测的 Nemotron 3.5。后者有15种可直接转录的语言(英语、西班牙语、法语、意大利语、葡萄牙语、荷兰语、德语、土耳其语、俄语、阿拉伯语、印地语、日语、韩语、越南语、乌克兰语)。Parakeet 和 Whisper 等 offline 模型覆盖更多语言,但预览使用缓冲分块而不是实时流。