用 ONNX/TFLite 模型实现离线语音控制

2026年10月 · ONNX · TFLite Micro · ESP32-S3 · 唤醒词 + 命令词

一套小体积的固定关键词模型——手机、浏览器、桌面用标准 ONNX,单片机用 INT8 TFLite——监听一个唤醒词和少量语音命令,全程离线。本文先讲清什么时候该用这类模型、同一批模型怎么跑遍各平台,再用一个可复现的 ESP32-S3 demo 走完全流程。

什么时候需要这样的模型?

关键词识别(KWS)模型适合的场景是:词表固定且小——一个唤醒词加上至多几十条命令——而且产品需要全天候监听、音频不出设备。用户什么都能说?那需要完整 ASR;但 ASR 的算力和功耗都要高出一个数量级,ESP32 级别的单片机或电池产品通常根本够不着,拿它做全天候监听更是不现实。

固定关键词 KWS
(ONNX/TFLite)
端侧 ASR云端语音助手
词表固定:1 个唤醒词 + 2–10 条命令开放式开放式
体积约 100 KB 量级数百 MB本地为零,音频出设备
硬件单片机(ESP32-S3)到浏览器都行Linux 级 SBC / 手机有麦克风和网络即可
算力与功耗单片机上毫秒级——低到可以全天候监听,电池产品也扛得住高出一个数量级以上——常驻监听不现实本地占用低,但射频和网络持续耗电
联网不需要不需要必须
响应本地即时较重,看设备往返延迟
持续成本无——模型文件归你算力/功耗按次或订阅
隐私音频不出设备留在本地音频上传

具体来说,团队会在这些场景选固定关键词模型:

这些场景词表都是固定的,也都乐意接受 KWS 的取舍:放弃开放对话,换来 tiny、即时、隐私和零运行成本。需要这样一组固定词的 KWS 模型?可以直接在听词官网训练——中、英、日、法、德都支持,下面的步骤带你走完全流程。

一种模型格式,跑遍所有平台

开源的 查看开源推理引擎和演示模型 → 管线从同一次训练产出两种格式:ONNX 给有 ONNX Runtime 的一切设备,INT8 TFLite 给 ESP32-S3 这类 TFLite Micro 设备。推理管线只有三个文件:

音频 (16 kHz) → melspectrogram.onnx → embedding_model.onnx → your_word.onnx → 概率

同一仓库里的开源运行时加载这些文件:Android(android/)、Web(web/,浏览器内 ONNX 推理)、Windows/Linux/macOS 的 Python(linux/)、ESP32-S3/P4(esp32/,TFLite)。Wyoming 侧车把同一批模型接入 Home Assistant。无 AccessKey、无云端推理、无按设备收运行费——下载的模型文件归你随便嵌。

实例:ESP32-S3 上的唤醒词 + 语音命令

为了把整条链路端到端展示一遍,下面把同一套模型放到平台清单里最小的那端。这个 demo 正好由管线产出的两种模型组成:单关键词唤醒模型负责 „Hallo Lumo“,多关键词模型负责识别后续四条命令。板子是 ESP32-S3 HMI DevKit(双核 240 MHz、8 MB PSRAM、ES7210 麦克风编解码),ESP-IDF 6.0.1。说 „Hallo Lumo“,LED 亮起确认唤醒;6 秒窗口内说 „Licht rot / blau / grün / weiß“,灯光变成对应颜色,然后回到唤醒模式。

demo 实测数据(1.5 秒窗口,INT8 经 ESP-NN 加速):Mel ≈ 47 ms + Invoke() ≈ 76 ms ≈ 每帧 121 ms,低于 160 ms 的帧步长,实时无压力。安静和嘈杂房间累计 20+ 次唤醒、四条命令全部识别、零混淆。唤醒模型经困难负样本挖掘后,误触发从约 319 次/小时降到 2.6 次/小时(24 小时 held-out 音频实测)。推理耗时随模型不同而变化,请用自己的模型实测。

为什么自己训练?Espressif 自带的 MultiNet 命令词只支持中文和英语。这里的两个模型都由自研管线基于梅尔特征训练,同一套流程适用于任何语言——demo 用德语只是演示。

想训练自己的关键词模型——单关键词唤醒词,或多关键词命令集,五种语言都支持——就是听词官网做的事,本文剩下的部分带你走一遍。

工作原理:两个小模型分时运行

一颗芯片上跑两个紧凑的 INT8 TFLite 模型,调度上互不冲突:

  1. 唤醒模型常开。ESP-SR AFE 负责音频前端(AEC、降噪、VAD),唤醒模型消费最新的梅尔窗口。命中后设备切换模式。
  2. 命令模型只在唤醒后开启。接下来 6 秒内,第二个多关键词分类器把语音映射到配置的命令(这里是四种颜色)。窗口结束或命令执行后,设备回到只听唤醒词的状态。

这个门控结构是命令词误触发低的原因:命令模型从不单独监听。误触发的压力全部压在唤醒词上——而这正是管线能优化的部分(见第 4 步)。

一个踩坑记录:第一版唤醒模型单次推理约 250 ms,比音频步长还慢,导致语句片段被静默丢掉。解决办法是永远处理最新窗口,并把模型缩到推理耗时小于步长为止。先保证“推理 < 步长”,再谈别的。

第 1 步 · 自己跑通 demo 模型(免费)

两个 demo 模型都在 GitHub 上,无需注册。最快的验证完全不需要硬件——桌面 Python 运行时加载同一批模型文件:

git clone https://github.com/voicute/onnx-wakeword.git
cd onnx-wakeword
pip install onnxruntime numpy sounddevice
python linux/infer.py --model-dir ./models/de/

完整嵌入式路径用已实测的 ESP-IDF 示例:

cd onnx-wakeword/esp32/examples/esp32s3_hmi_devkit
idf.py set-target esp32s3
python patch_led_strip.py
idf.py build
idf.py -p COM6 flash monitor

Web 运行时能在浏览器里跑同一批 demo 模型——碰硬件之前先确认某个词的声音效果很方便。

第 2 步 · 训练你自己的唤醒词(免费)

在听词官网输入你的词、选择语言——中、英、日、法、德都支持。训练产出第一轮模型(R0):桌面/移动/浏览器用标准 ONNX 分类器,ESP32-S3 用配套的 INT8 TFLite。这一步不收费。

第 3 步 · 用真实声音测试(免费)

在控制台用你自己的麦克风、实际使用距离和背景噪声测试 Basic 模型。这一步决定后面所有选择,所以先测再想付费的事:按你平时说话的方式、平时使用的距离去喊。如果召回不理想,补几段这个词的真人录音再重训——录音是可选的训练输入,依然免费。

第 4 步 · 按实测结果对号入座

测完之后,你属于以下四种情况之一:

  1. 有时喊不醒 → 补 5 段真人录音重训(免费)。多数召回问题是覆盖问题,这一步就能解决。
  2. 能唤醒,但电视声、聊天声会误触发 → 做误触发优化(按次收费)——原理见下一节。
  3. 要的是语音控制,不只是唤醒 → 训练一个多关键词模型,2–10 条固定命令装进一个文件;或者干脆不要唤醒词,直接用命令词触发。上面的 demo 就是这套架构。
  4. 效果满意 → 付费下载模型(一次性),部署到上面任意运行时。

误触发控制:R0 与 R1 的区别,以及负样本挖掘

每个模型的起点都是 R0——用准备好的语音数据加一组固定干扰(噪声、混响、音量变化)训练出的第一轮模型。但现实里的干扰多得多:电视、音乐、背景聊天、广告……而且干扰是分词的:同一段广告音频,可能让 „Hallo Lumo“ 的模型误触发,换一个词的模型就完全无感。所以刚训练完的 R0 误触发偏高是所有关键词模型的通病,不是你训练得不好。

R1 就是治它的方案,两步,正好对应控制台的两个按钮:

  1. 负样本扫描。拿你的 R0 去听约 100 小时对应语言的负面音频,把它有反应的片段挑出来——按定义,这些就是这个模型自己的困难负样本(最多保留 10,000 条)。几分钟。
  2. 全量重训。把这些片段作为负样本加进原始训练集,从头完整重训。通常 40–80 分钟。

因为负样本是照着 R0 的真实弱点挑的,一轮就能把误触发从每小时数百次压到个位数(平均约降 95%)——本文 demo 的唤醒词实测 319 次/小时 → 2.6 次/小时(24 小时 held-out 音频)。单关键词和多关键词模型都支持这条流程:demo 里那个四色命令模型同样可以走一遍扫描加重训。R2 管线留给将来出现的全新干扰源,但对绝大多数关键词,一轮 R1 就够日常使用。此优化按次收费,当前价格见官网。

第 5 步 · 实机验证

控制台测试证明模型,实机测试证明产品。上线前三项检查:

常见问题

固定关键词模型什么时候不合适?
词表不固定的时候。听写、随意提问等开放式语音需要完整 ASR——KWS 模型设计上只认训练过的词。
整套方案是完全离线的吗?
是。唤醒词和命令词都在本地运行,无云端推理、无运行时账号密钥。
支持哪些平台和语言?
Android、Web、Python(Windows/Linux/macOS)、ESP32-S3/P4,外加 Wyoming 接入 Home Assistant;已有中、英、日、法、德模型。
哪些免费、哪些收费?
训练和控制台测试免费;下载模型文件和误触发优化收费,当前价格见官网。
无关说话会误触发命令吗?
只在唤醒后 6 秒窗口内可能,唤醒门槛已挡掉大部分;窗口内语音目前仍可能被误分类,管线支持命令词困难负样本挖掘来改善。
说明:本文引用的开源推理运行时与 demo 模型由听词(Voicute)开发,第 2–4 步使用的在线训练平台同为听词产品。
免费训练并测试你自己的唤醒词
查看开源推理引擎和演示模型 →
ONNX / TFLite · Android · ESP32 · Web · Python · Home Assistant