本地优先 ASR 流水线的设计 — 几条工程原则
这是一组在为桌面构建本地优先 ASR 流水线时写下的工作笔记。不主张是通用法则 — 是六条我们反复回到的原则,常常是违反它们丢了时间之后才回到的。趁还没忘记是哪个错误产生了哪个教训,先记下来。
原则一:热路径要窄、要同步。桌面端的语音转文字是一个交互式系统。用户一边说话一边看屏幕。任何引入等待的东西 — 网络调用、模型加载、序列化 — 都必须放在"每条语音"的循环之外。循环里只做最少的事:采音 → 识别 → 出文。其他一切(词汇学习、评测、遥测)都是侧链。
原则二:单写、验证插入优先。语音输入只有在文字真的落到用户期望的地方时,才会让人觉得可靠。我们把插入当成关键操作 — 写文本到当前焦点字段只走一条路,这条路必须被验证成功,"差不多成功"不算完成态。验证失败就报失败,绝不偷偷用一个略微不同的结果重试。一旦用户不能信任光标,他就不再用这个工具。
Figure 01
本地优先 ASR 流水线 — 六个阶段、一个紧的循环
每条语音的全部步骤都关进热回路里;学习、评测、遥测一律推到旁路。
热路径 · 每条语音
01
采音
AVFoundation · 48 kHz 本地缓冲
02
语音识别
SenseVoice (Sherpa 运行时, int8)
03
修正
预标点 + 词典重写
04
精修
Qwen3-4B (本地 MLX, 约 420 ms)
05
插入
剪贴板传输 + 覆盖粘贴
06
验证
强验证;失败明示报告
旁路 · 异步
Target公开性能目标:写入延迟 0.82 秒 · 强验证识别准确率 97.4%。
原则三:学习行为之前,先把确定性的修正做对。流水线里识别后能改文字的段不止一段 — 标点恢复、用户词典中的词替换、看历史的修正、基于模型的精修。我们吃过亏才学会:确定性的几段必须自己就可靠且可解释,学习层才被允许做任何事。如果用户不信任简单几段,他也不会信任更聪明的那几段。
原则四:精修默认保守。流水线最后一段 — 基于模型的润色 — 是最容易想野心化的地方。忍住。这一层的工作是修明显错误(明显听错、同音字混淆、错的时态标记),不是改写用户意图。我们给它紧的 prompt、低温、和保留否定/术语/专名的明确指令。激进的精修做出来的工具会把用户说过的话"改善"成用户没说过的话。这比完全不精修更糟。
原则五:词典属于用户。系统用着用着,会看到基础模型不知道的用户用语模式 — 行业术语、项目名、常见搭配。这些被用来改善后续识别,但新词通过"待确认"门进 — 系统提议,用户通过。词永远不会偷偷进用户的词典。这部分是正确性问题(模型提议有时是错的),部分是用户和工具关系的问题 — 工具应该始终可被问责。
Figure 02
ORDO 主面板 — 六个一键可达的模块
实装级 v3 布局。状态、当日、词典、历史、流水线详情、快捷设置都在 home 一键之内。
引擎状态
● Ready
Mainline + Enhance + Selection — 全部预热、全部本地。
今日活动
236
246 次发话 · 4 小时免手输入,较 7 日均值 +8.3%。
自适应词典
847
Code / Project / Daily — 从回放自动学习,新词需用户审核。
发话历史
∞
原始识别 · 最终文本 · 各段耗时,每条都保留。
流水线详情
5 → 1
Capture → ASR → Correct → Enhance → Insert。每段可换。
快捷设置
⌥⌘
热键、引擎、精修模型 — 改动即时生效。
布局原则:关键功能不超过一键深度。Home 是状态面板,不是启动器。
原则六:评测用你自己的素材跑。我们维护一个内部夹具,把录制好的音频回放整条流水线,跟踪和真实用户工作相似的素材上的准确率。它不是竞赛 benchmark,是回归网。公开 benchmark 选模型时有用,但生产环境真正重要的问题是"我们最近一次改动让用户体验变差了吗"。这只能用你自己的素材回答。
几点诚实的注脚。这些原则没有一条排除用云模型 — 它们主张的是不管单段在哪运行,面向用户的回路要紧。也没有一条是我们原创的 — 多数都以不同的语汇出现在做得好的信号处理系统和精心打造的编辑器里。把它们写下来,是因为每次设计评审时违反每一条的诱惑都会冒出来,把这张表放到大家都能看到的地方,比把同一个教训学三遍便宜。
只带走一条 — 让用户始终能信任光标。其余都会从这里推出来。