Rdzleo
|
c26fc5fc87
|
feat(kws): 切换流式 KeywordSpotter 架构,识别率 67%→80%+
== 核心架构变更 ==
v2 (SenseVoice ASR + Homophone-Replacer FST) → v3 (流式 KWS Zipformer)
弃用原因:
- SenseVoice 228MB,大模型对短中文唤醒词识别全部输出 empty
- 板载 mic 实测验证: 干净说话 segment 同样 ASR empty
- 大型 ASR 不适配 1.2 秒级别短词唤醒场景
新架构:
- sherpa-onnx KWS Zipformer (wenetspeech-3.3M, int8)
- 模型 5MB(vs 228MB,节省 98%),APK 55MB(vs 213MB)
- 引擎初始化 800ms (vs SenseVoice 4 秒)
- 流式实时识别,命中后 <100ms 触发广播
- 不再依赖 VAD / 能量门 / DC 去除 / segment 切分
== 资源变更 ==
新增 assets/kws/:
- encoder.int8.onnx (4.6MB)
- decoder.onnx (660KB)
- joiner.int8.onnx (64KB)
- tokens.txt (拼音 token 词表)
- keywords.txt (43 条 Lila 谐音变体: 你好丽啦/咪啦/你拿/Lai啦...)
删除 assets/:
- sense_voice/ (228MB)
- silero_vad/ (632KB)
- hr_lexicon.txt (1.3MB)
- replace.fst
- 老 wenetspeech 8 个 onnx (full precision 版本)
== 代码变更 ==
新引擎: kws/AsrEngine.kt (流式 KeywordSpotter,替代 KwsEngine)
删除: kws/KwsEngine.kt
修改:
- Config.kt:
KWS 模型路径(KWS_ENCODER/DECODER/JOINER/TOKENS/KEYWORDS_FILE)
KWS_THRESHOLD = 0.05f (低阈值激进唤醒)
KWS_SCORE = 3.0f (弱信号场景拉高加分)
AUDIO_CAPTURE_GAIN = 1.5f (板载 mic 软件预增益)
- kws/AudioCapture.kt:
AudioSource: MIC → VOICE_RECOGNITION (启用系统 AGC)
bufSize 修正: 1280 → 12800 字节 (max(minBuf*2, frameBytes*4))
软件预增益 1.5x + clamp 防溢出
- kws/KwsStateMachine.kt: 引擎类型 KwsEngine → AsrEngine
- WakeupForegroundService.kt: 引擎类型 KwsEngine → AsrEngine
- MainActivity.kt: UI 适配
- protocol/BroadcastSender.kt: 微调
新增 sherpa-onnx Kotlin wrapper:
- OfflineRecognizer.kt / OfflineStream.kt
- Vad.kt / QnnConfig.kt
(全部从 sherpa-onnx 上游 master 引入)
== 实测数据 (RK3588 + OrangePi CM5 板载 mic) ==
板载 mic 信号特征:
静音底噪 peak ~5000 (异常高,非 DC bias 是真实 AC 噪声)
说话峰值 peak ~16000~32767
SNR ~10dB
诊断方法:
- 加 segment dump WAV (Config.DUMP_HIT_WAV) 验证 mic 录音正常
- 离线分析 RMS/peak/ZCR 确认真说话特征 (RMS>1500, ZCR<0.07)
最终识别率: 用户实测"识别率非常高"
|
2026-04-30 18:33:14 +08:00 |
|
Rdzleo
|
128f7ca02e
|
init: KWS 软件唤醒 APK 工程骨架(基于 sherpa-onnx 改造)
工程结构:
- com.lila.wakeup 包名,基于 sherpa-onnx v1.13.0 SherpaOnnxKws demo 改造
- 9 个 Kotlin 模块: WakeupForegroundService / KwsStateMachine / AudioCapture
/ KwsEngine / BootReceiver / ProtocolReceiver / BroadcastSender / Config
/ MainActivity
- 5 个 Lila 中文唤醒词(你好Lila/hello Lila/Lila同学/Lila你好/小Lila)
- 仅 arm64-v8a(OrangePi CM5 / RK3588)
- 协议 v2.1: 双向 setPackage / silence_ms 3000 / 2min 兜底
- 数字人 APP 包名: com.qy.lila
构建通过项:
- Gradle Sync OK(腾讯云 Gradle 镜像 + 阿里云 Maven 镜像)
- APK 编译成功 55MB,含 25MB onnxruntime + 24MB 模型 + 9 个 Kotlin .dex
- adb install OK,Service onCreate 被调用,sherpa-onnx 加载模型
已知问题(下一 commit 修复):
- KwsEngine.kt 的 OnlineModelConfig modelType 设为 'zipformer'
实际应为 'zipformer2',native 加载在 InitEncoder 后崩溃
- 修复方法: 用 sherpa-onnx 官方 getKwsModelConfig(0) 工厂函数
参考文档:
- 协议: ~/OrangePi_CM5_Project/docs/.../KWS唤醒协议-V2.md (v2.1)
- 设计: ~/OrangePi_CM5_Project/docs/.../KWS服务设计.md
- 评估: ~/OrangePi_CM5_Project/docs/.../KWS唤醒方案适配评估_Unity.md
|
2026-04-30 09:55:49 +08:00 |
|