Skip to content

唤醒检测批量通信 ​

本次优化减少主进程与常驻检测进程之间的通信。模型仍按原始帧顺序运行;不改变模型、阈值、声纹竞争规则、前端采集或 ASR 回放。Python worker 协议版本为 1,与定制 wheel 的版本检查独立,不要求更新 wheel。

调度与归属 ​

参数行为
目标批量640 个 16kHz 采样,即 40ms;不切割原始帧
主动等待最早帧首次入队后最多 30ms,新帧不刷新期限
大帧512 采样及以上直接处理,仍排在已有音频之后
帧数上限每批最多 16 帧
检测期限沿用 detector 的批次预算,当前为 2 秒
容量排队与处理中副本共同计入原有 wake_queue_bytes

唯一的 _wake_task 在锁内领取音频,在锁外等待事件或执行检测。准备期间保存首次入队时间;不同 generation、standby_epoch 或不连续帧不合批。30ms 仅限制主动凑批,不保证包含调度、积压和推理的端到端延迟。

worker 在首次命中时停止,返回 WakeWordBatchResult(consumed_frames, detection)。无命中必须确认完整批次。命中范围不能超过已处理音频,关键词起点允许早于本批。单帧 feed() 包装批量入口,共享单次调用保护。

命中被接受后,未处理检测副本退出,完整原始音频继续走现有回放。命中被拒绝且仍属于同一待机轮次时,尾部优先续接,保留入队年龄及原批次检测期限。通信失败或处理确认非法时不重传。关麦、激活、轮次切换和失败唤醒等待任务;迟到结果不能再次激活。

非法确认和期限耗尽使用原不可用通知并有界关闭 detector。自动关闭与会话取消交错时,嵌套 finally 仍清理在途计数和任务引用。未完成资源关闭留给会话关闭路径处理,不把失败伪装为成功。

启用、回退与诊断 ​

VoiceSessionActivationRuntimeConfig.wake_batching_enabled 默认为 true。对照或回退可在创建新 runtime 时设为 false,恢复单帧通信;这是内部配置,不新增用户设置。运行中不切换策略,协议更新或回退需要新 worker。禁用组批仍使用当前批量协议的单帧包装,不试探旧协议并重发。

NEKO_WAKE_WORD_DIAGNOSTICS=1 输出批次帧数、采样数、flush 原因、排队时间、超过主动等待期限的时间、通信耗时、处理确认及容量。scheduling_overrun_ms 也包含积压等待,不能解释为纯操作系统调度延迟。不新增原始音频、关键词或转写文本日志。

评估入口 ​

新增 scripts/wake_word/evaluate_wake_runtime.py,与原离线模型评估脚本分开。它使用正式 activation runtime、controller 和真实检测子进程,通过本地 sink 接收回放,不连接云端 ASR。示例:

powershell
uv run python scripts/wake_word/evaluate_wake_runtime.py --model-dir <模型目录> --wav <16kHz单声道录音.wav> --source recording --paced --frame-samples 160 --repeats 2 --output <报告.json>

用 --frame-samples 512 测试 32ms;可传多个采样数测试循环不规则分包。合成输入必须标为 --source synthetic。无 --paced 时只评估积压吞吐,不能当作实时响应延迟。

每个模式使用新会话,成对轮换 baseline/batch 顺序。报告分别记录尝试与完成的通信次数、确认处理帧数、主进程与子进程 CPU、采样 RSS、输入迟到、命中与激活时刻、状态及轮次、实际回放范围和摘要。指标采集失败仅标记不可用,不改变检测结果。

为隔离 KWS,脚本使用就绪声纹 stub 并发送 voice_activity=false。激活期间停止 KWS,但长录音会依照真实空闲策略重新待机;报告保留这些轮次,不宣称整段始终处于待机。CPU 不含准备和关闭;RSS 为采样值而非操作系统峰值;没有关键词结束标注时,音频起点到激活的时间不是关键词结束后的响应延迟。

本机定向验证(2026-09-24) ​

213 个相关测试通过,覆盖批量协议、确定性调度、确认与尾部、取消清理、容量和激活生命周期,以及独立 ASR/原生语音共用 Core 入口的完整回放。未跑全量测试。测试用可辨认 PCM 检查实际内容、顺序和一次交付。

真实模型经正式 runtime 的本机测量如下;每行环境声/静音为单组对照,不能视为稳定性能保证:

输入单帧 → 组批通信次数合计 CPU 时间结果
34.03s 真实环境声,10ms 分包3403 → 10742.391s → 1.844s,约降 23%确认处理帧数相同,无命中,均保持待机
20s 合成静音,10ms 分包2000 → 6331.109s → 1.016s,约降 8%确认处理帧数相同,无命中
真实唤醒短录音,10ms,两组每组 159 → 50/51录音过短,不据此推断 CPU 收益均激活一次,模型采样范围一致
真实唤醒加指令,32ms40 → 40不作收益承诺均激活一次,模型采样范围一致
真实短唤醒词,489/490/160 采样循环67 → 67不作收益承诺均激活一次,模型采样范围一致

环境声/静音中 worker 采样 RSS 约 112~113MB,没有证明内存下降。Windows 调度使不少批次不足四帧;模型仍处理全部原始帧。本轮结果不支持把此前原型的 37%~42% 推广为正式实现或整个后端的固定降幅。

网页、Electron、真实麦克风两条路由、游戏高负载及更大录音集的唤醒成功率和 P50/P95 延迟仍待人工验收。自动化路由回放通过不等于这些真实设备效果已验证。音频和原始测量报告保留在仓库外,未提交用户录音。

回归报告 / Regression Report ​

此前待机检测逐帧进行 IPC;现在将可合并帧批量发送,保留逐帧模型处理和原始回放,以降低通信开销。核心改动限于 activation 契约、Sherpa worker 和 activation runtime,未修改 Core 运行代码、声纹/唤醒阈值或端点策略。

Review 重点是命中后未处理尾部的唯一归属、同批次期限不刷新、队列与在途计数、取消期间清理,以及声纹和唤醒异步结果的竞争。新增主动等待可能改变两类检测结果到达顺序;保持既有先结算规则,不承诺竞争结果完全相同。实际 CPU 收益、误唤醒率和延迟仍以扩展实测为准。