TFLM Micro Wake Word 实时唤醒示例 ================================== 功能说明 -------- 本示例在 ``arcs_evb`` 或 ``venusa_rd_evb`` 的 CPU0 上采集 16 kHz 单声道麦克风 PCM,使用 ESPMicroSpeechFeatures 生成 40 维频谱特征,并将连续三帧特征输入 ``XLXL_V4.tflite`` 流式唤醒模型。模型通过 TensorFlow Lite for Microcontrollers 运行,卷积、深度卷积和全连接算子使用 Luna NPU kernel。 音频回调只把 PCM 复制到 PSRAM 环形缓冲区并通知推理任务;音频前处理、TFLM 推理和概率后处理均在独立任务中执行,避免慢速推理阻塞 LISA Audio 分发任务。 录音成功启动后,示例会持续采集和推理,直到开发板复位或断电,不会按固定时长 自动停止。 硬件连接 -------- 示例使用板载 ``audio0`` 录音设备: - 采样率:16 kHz - 通道:左声道 - 位宽:16 bit - 模拟增益:16 dB - 数字增益:8 dB - 输入模式:差分输入,启用高通滤波 使用 ``arcs_evb`` 或 ``venusa_rd_evb`` 的板载麦克风时无需额外连接。若目标硬件 没有板载麦克风,需要按板级原理图将麦克风连接到 ``audio0`` 对应的 ADC 输入。 处理流程 -------- .. code-block:: text audio0 麦克风 PCM -> LISA Audio 回调 -> 128K samples PSRAM 环形缓冲区 -> 独立推理任务 -> ESPMicroSpeechFeatures -> 40 维特征 x 3 帧 -> TFLM + Luna 推理 -> UINT8 输出反量化 -> 5 次推理滑动平均 -> 0.9 触发阈值、74 帧冷却和 0.3 释放阈值 -> 持续输出唤醒日志与运行统计 模型与音频前处理 ---------------- - 模型文件:``models/XLXL_V4.tflite``,大小约 160 KiB。 - 模型输入:``INT8 [1, 3, 40]``,每累计三帧特征执行一次推理。 - 模型输出:单个 ``UINT8`` 唤醒分数,按输出张量量化参数反量化为概率。 - 前端窗口:30 ms,步进 10 ms,40 个 filterbank 通道。 - 频率范围:125 Hz 至 7500 Hz。 - 前端处理:降噪、PCAN 增益控制和对数缩放。 - 后处理:5 次推理概率平均,触发阈值为 ``0.9``;启动后及每次触发后冷却 74 个 特征帧。触发后检测器进入锁定状态,冷却结束且平均概率连续 3 次不高于 ``0.3`` 时才重新允许唤醒,避免同一次语音的持续高分被重复计数。 任务与内存 ---------- - Tensor arena:512 KiB,位于 PSRAM;在 ARCS 上按 512 KiB 对齐并标记为非缓存 区域,保证 CPU 与 Luna NPU 访问同一份张量数据。 - PCM 环形缓冲区:128K 个 ``int16_t`` samples,共 256 KiB,位于 PSRAM。 - PCM 临时缓冲区:1024 个 ``int16_t`` samples,位于 PSRAM。 - Controller 任务栈:1024 个 ``StackType_t``,在当前 RV32 ABI 下为 4 KiB。 - Inference 任务栈:2048 个 ``StackType_t``,在当前 RV32 ABI 下为 8 KiB。 - 两个任务栈均固定在内部 SRAM 的 ``.fast.data`` 段。 - LISA Audio 录音缓冲区:64 个缓冲区,每个 1024 samples。 - ``arcs_evb`` 固件使用 ``-O3`` 构建,确保音频前端与流式推理吞吐不低于 16 kHz 采集速率。 示例步骤 -------- 1. 初始化 Luna、TFLM allocator、资源变量和流式模型。 2. 按 16 kHz 音频参数初始化 ESPMicroSpeechFeatures。 3. 创建使用内部 SRAM 静态栈的独立推理任务。 4. 配置 ``audio0`` 并注册轻量音频回调,将 PCM 写入无锁环形缓冲区。 5. 推理任务消费 PCM,生成特征并执行 TFLM/Luna 推理和概率后处理。 6. 持续采集和推理,并周期输出采集、处理、丢样、积压、推理失败及唤醒次数。 7. 通过复位或断电停止运行;初始化失败时会停止已启动的采集并释放运行时资源。 编译 ---- 模型和音频前端组件已随示例提供,但 TFLM 运行时源码仍来自子模块。首次使用时 初始化子模块: .. code-block:: bash git submodule update --init modules/tflite-micro 构建 ``arcs_evb`` 固件: .. code-block:: bash ./build.sh -C -S labs/tflite_micro/micro_wake_word -DBOARD=arcs_evb 构建 ``venusa_rd_evb`` 固件: .. code-block:: bash ./build.sh -C -S labs/tflite_micro/micro_wake_word -DBOARD=venusa_rd_evb 烧录 ---- 烧录 ARCS CPU0 固件,将 ``<串口设备>`` 替换为实际设备: .. code-block:: bash ./tools/burn/cskburn -C arcs -s <串口设备> -b 3000000 \ --verify-all 0x0 build/tflite_micro_wake_word.bin 烧录 VenusA CPU0 固件: .. code-block:: bash ./tools/burn/cskburn -C venusa -s <串口设备> -b 3000000 \ --verify-all 0x0 build/tflite_micro_wake_word.bin 预期输出 -------- 概率、周期、积压和采样统计会随输入音频及目标平台变化。持续无丢样运行的日志 格式如下,推理序号与采样计数会不断增长: .. code-block:: text I/tflm_micro_wake_word ... asynchronous microphone pipeline started; running continuously I/tflm_micro_wake_word ... inference #20: value=... probability=... average=... invoke=... cycles pending=... captured=... processed=... dropped=0 max_pending=... invoke_failures=0 detections=... I/tflm_micro_wake_word ... inference #400: value=... probability=... average=... invoke=... cycles pending=... captured=... processed=... dropped=0 max_pending=... invoke_failures=0 detections=... 当滑动平均概率超过阈值时,还会输出: .. code-block:: text W/tflm_micro_wake_word ... WAKE WORD DETECTED: probability=... cutoff=0.900 本次语音结束、检测器重新允许唤醒时,会输出: .. code-block:: text I/tflm_micro_wake_word ... wake word detector rearmed: probability=... release=0.300 ``detections=0`` 只表示当前运行期间没有达到唤醒阈值,不代表程序失败。持续模式 不会输出 ``pipeline stopped`` 或最终 ``result=0``;基础成功判据是推理序号持续增长, 且周期日志中的 ``dropped=0``、``invoke_failures=0``。 核心 API -------- .. list-table:: :header-rows: 1 * - API - 说明 * - ``lisa_device_get()`` - 获取 ``audio0`` 录音设备 * - ``lisa_audio_register_callback()`` - 注册 PCM 录音回调 * - ``lisa_audio_record_config()`` - 配置采样率、通道、位宽、增益和输入模式 * - ``lisa_audio_record_start()`` / ``lisa_audio_record_stop()`` - 启动持续麦克风采集;停止接口用于初始化失败时清理 * - ``FrontendPopulateState()`` - 按 16 kHz 参数初始化音频前端 * - ``FrontendProcessSamples()`` - 将连续 PCM 转换为 40 维频谱特征 * - ``tflite::MicroResourceVariables::Create()`` - 为流式模型创建资源变量存储 * - ``tflite::MicroInterpreter::Invoke()`` - 执行一次三帧唤醒模型推理 * - ``xTaskCreateStatic()`` - 使用内部 SRAM 静态栈创建控制与推理任务 核心文件 -------- .. list-table:: :header-rows: 1 * - 文件 - 说明 * - ``models/XLXL_V4.tflite`` - XLXL V4 流式唤醒模型 * - ``src/main.cc`` - 音频环形缓冲区、前处理、推理、后处理和生命周期管理 * - ``src/luna_platform.c`` - Luna 时钟、Cache 和运行时初始化 * - ``components/ESPMicroSpeechFeatures`` - Microfrontend、KissFFT 和频谱特征实现 * - ``prj.conf`` - LISA Audio、PSRAM、静态任务和录音缓冲区配置 * - ``prj_arcs.conf`` / ``prj_venusa.conf`` - ARCS 与 VenusA 的 CPU0 平台配置 注意事项 -------- 1. **真实音频输入**:识别效果取决于麦克风、增益、环境噪声、说话距离和模型 训练数据;需要在目标产品硬件上评估阈值与误报率。 2. **唤醒日志**:未出现 ``WAKE WORD DETECTED`` 不等于运行失败,应检查周期日志中 的 ``dropped``、``invoke_failures``,并确认推理序号持续增长。 3. **实时性**:音频回调不执行前处理或推理。若 ``dropped`` 大于零,说明推理任务 长时间落后于采集速度,应优化模型或增大缓冲能力,不能只忽略统计结果。 4. **持续运行**:录音和推理不会自动结束,需要通过复位或断电停止开发板。 5. **模型兼容性**:通过 ``TFLM_WAKE_MODEL`` 替换模型时,必须保持输入输出类型、 三帧 40 维输入布局和算子集合兼容。 6. **推理任务栈**:Luna 推理任务栈必须位于内部 SRAM,避免命令参数落入 Luna 无法访问的内存。 7. **ARCS Cache**:与 Luna NPU 共享的 tensor arena 使用非缓存 PSRAM;音频前端和 PCM 环形缓冲区仍使用可缓存 PSRAM,避免持续运行时前处理吞吐低于采集速率。