RealtimeSTT 唤醒词(Wake Word)完整实战指南:Porcupine 与 OpenWakeWord 双后端配置、调参与源码解析
RealtimeSTT 唤醒词Wake Word完整实战指南Porcupine 与 OpenWakeWord 双后端配置、调参与源码解析【免费下载链接】RealtimeSTTA robust, efficient, low-latency speech-to-text library with advanced voice activity detection, wake word activation and instant transcription.项目地址: https://gitcode.com/GitHub_Trending/re/RealtimeSTTRealtimeSTT 支持在正式录制语音之前先等待一个唤醒词Wake Word只有检测到指定唤醒词后才开始录制并转写后续语音。本文以 docs/wake-words.md 为核心系统讲解其两种后端Porcupine 与 OpenWakeWord的安装、配置、模型文件管理、灵敏度与时机参数、回调函数及排障方法并结合仓库源码RealtimeSTT/core/wakeword.py、RealtimeSTT/core/recording.py、RealtimeSTT/audio_recorder.py深入解析其底层实现原理帮助开发者从能跑通进阶到会调优。唤醒词模式概述与启用方式唤醒词模式是 RealtimeSTT 在 VAD语音活动检测之外提供的一种由关键词触发的录制机制系统持续监听麦克风只有检测到预设的唤醒词后才会进入录制状态并开始转写其后的语音。根据 docs/wake-words.md 的说明RealtimeSTT 支持两种唤醒词后端Porcupine通过可选的pvporcupine包实现由 Picovoice 提供内置多种开箱即用的英文关键词OpenWakeWord通过可选的openwakeword包实现支持加载用户自训练的 ONNX/TFLite 自定义模型。唤醒词模式在以下两种条件下被激活两者满足其一即可设置了wake_words参数此时后端会默认选择 Porcupine以保证向后兼容wakeword_backend显式选择了 OpenWakeWordoww或openwakeword。这一逻辑在源码中有直接体现。RealtimeSTT/core/initialization.py 中的_assign_initial_attributes计算recorder.use_wake_words bool( init_args[wake_words] or normalized_wakeword_backend in OPENWAKEWORD_BACKENDS )而在 RealtimeSTT/core/wakeword.py 中_normalize_wakeword_backend负责后端名称归一化且当wakeword_backend为空但提供了wake_words时会自动回退到 Porcupinedef _normalize_wakeword_backend(wakeword_backend, wake_words): backend (wakeword_backend or ).strip().lower().replace(-, _) if not backend and wake_words: return pvporcupine return backend对应的单元测试位于 tests/unit/test_wakeword.py其中test_bare_wake_words_default_to_porcupine验证了仅设置 wake_words 时默认走 Porcupine的行为test_no_wake_words_keep_backend_empty验证了未设置任何唤醒词参数时后端保持为空。支持的唤醒词后端别名后端别名映射定义在 RealtimeSTT/core/wakeword.py 顶部后端可用别名Porcupinepvp、pvporcupine、porcupineOpenWakeWordoww、openwakeword、openwakewords、open_wakeword、open_wakewords需要注意后端名称中的连字符会被归一化为下划线如open-wakeword等价于open_wakewordtest_openwakeword_backend_normalizes_hyphen测试用例专门验证了这一点。若传入的后端既不属于 Porcupine 集合也不属于 OpenWakeWord 集合setup_wakeword_detection会抛出ValueError提示仅支持pvporcupine与openwakeword。Porcupine 后端安装、使用与内置关键词安装 Porcupine 可选依赖Porcupine 属于可选后端需要先安装对应的 extra 才能使用python -m pip install RealtimeSTT[porcupine]在 setup.py 中可以看到porcupine、pvporcupine、pvp三个 extra 名均映射到同一份porcupine_requirements即pvporcupine包。因此以下三种安装方式等价python -m pip install RealtimeSTT[porcupine] python -m pip install RealtimeSTT[pvporcupine] python -m pip install RealtimeSTT[pvp]如果希望同时安装其他可选依赖可以用逗号分隔多个 extra例如python -m pip install RealtimeSTT[faster-whisper,porcupine]。最小可用示例from RealtimeSTT import AudioToTextRecorder if __name__ __main__: recorder AudioToTextRecorder( wakeword_backendpvporcupine, wake_wordsjarvis, ) print(Say Jarvis and then speak.) print(recorder.text()) recorder.shutdown()运行后程序会持续监听麦克风当检测到用户说出 Jarvis 后才开始录制并转写随后的语音最终把转写文本打印出来。内置关键词列表Porcupine 后端自带一批由 Picovoice 预置的关键词keywordwake_words参数直接传入名称即可使用alexaamericanoblueberrybumblebeecomputergrapefruitsgrasshopperhey googlehey sirijarvisok googlepicovoiceporcupineterminator同时启用多个关键词多个 Porcupine 关键词可以用逗号分隔一次性监听多个唤醒词recorder AudioToTextRecorder(wake_wordsjarvis,computer)在 RealtimeSTT/core/wakeword.py 的setup_wakeword_detection中wake_words字符串会被按逗号拆分、去除空白并转为小写得到wake_words_listrecorder.wake_words_list [ word.strip() for word in wake_words.lower().split(,) if word.strip() ] if wake_words else []随后为每个关键词生成一份灵敏度列表每个关键词可独立使用相同的wake_words_sensitivityrecorder.wake_words_sensitivities [ float(wake_words_sensitivity) for _ in range(len(recorder.wake_words_list)) ]最终通过pvporcupine.create(keywords..., sensitivities...)一次性创建多关键词检测器。需要特别注意的是Porcupine 后端必须有wake_words否则会抛出ValueError源码中明确提示 Porcupine wake word detection requires wake_words。Porcupine 初始化与音频参数的联动从源码可以观察到初始化 Porcupine 后录制器的buffer_size和sample_rate会被 Porcupine 引擎自身的参数覆盖recorder.porcupine pvporcupine.create( keywordsrecorder.wake_words_list, sensitivitiesrecorder.wake_words_sensitivities ) recorder.buffer_size recorder.porcupine.frame_length recorder.sample_rate recorder.porcupine.sample_rate这意味着 Porcupine 对音频帧长和采样率有硬性要求RealtimeSTT 会主动跟随引擎设定确保送入porcupine.process()的每个 PCM 数据块长度与引擎期望的frame_length完全一致。音频处理循环位于 RealtimeSTT/core/recording.py 的_recording_worker中process_wakeword将原始音频按 16-bit 小端有符号整数struct.unpack_from(h * buffer_size, data)解包后交给porcupine.process()返回porcupine_index若返回值 0则判定唤醒词命中。开启debug_modeTrue时每次检测的索引值会输出到日志便于调试。OpenWakeWord 后端安装、自定义模型与推理框架安装 OpenWakeWord 可选依赖python -m pip install RealtimeSTT[openwakeword]在 setup.py 中openwakeword与oww两个 extra 名均映射到openwakeword_requirements即openwakeword包。注意openwakeword包安装时会自动拉取其 ONNX 推理运行时依赖因此无需额外安装onnxruntime。使用示例自定义模型from RealtimeSTT import AudioToTextRecorder if __name__ __main__: recorder AudioToTextRecorder( wakeword_backendoww, openwakeword_model_pathsmodels/hey_assistant.onnx, wake_words_sensitivity0.35, wake_word_buffer_duration1.0, ) print(Say the trained wake word and then speak.) print(recorder.text()) recorder.shutdown()后端选择上wakeword_backendoww与wakeword_backendopenwakeword完全等价。关键特性OpenWakeWord 的唤醒词名称是从模型文件中自动推断的因此使用自定义模型路径时无需再设置wake_words。这在源码中体现为OpenWakeWord 分支不会读取wake_words_list来构造检测器而是直接基于openwakeword_model_paths加载模型。仓库中的 OpenWakeWord 实测示例仓库 tests/openwakeword_test.py 提供了一个可直接运行的 OpenWakeWord 测试脚本展示了唤醒词 回调的完整编排监听唤醒词 samantha模型文件suh_man_tuh.onnx、suh_mahn_thuh.onnx位于 tests 目录检测到唤醒词后录制并转写超时则提示用户重新说出唤醒词def on_wakeword_detected(): global detected detected True def on_wakeword_timeout(): global detected if not detected: print(fTimeout. {say_wakeword_str}) detected False with AudioToTextRecorder( spinnerFalse, modellarge-v2, languageen, wakeword_backendoww, wake_words_sensitivity0.35, openwakeword_model_pathssuh_man_tuh.onnx,suh_mahn_thuh.onnx, on_wakeword_detectedon_wakeword_detected, on_wakeword_timeouton_wakeword_timeout, on_wakeword_detection_starton_wakeword_detection_start, wake_word_buffer_duration1, ) as recorder: while True: recorder.text(text_detected)此外仓库还附带 tests/vad_test.py、tests/openwakeword_test.py 等测试脚本可在本地快速验证唤醒词 VAD 的组合效果。OpenWakeWord 初始化流程源码解读在 RealtimeSTT/core/wakeword.py 的 OpenWakeWord 分支中初始化逻辑如下通过import_module加载openwakeword及其openwakeword.model.Model类若缺少依赖会抛出带有安装提示的ModuleNotFoundError调用openwakeword.utils.download_models()确保 OpenWakeWord 的默认/辅助模型资源可用若提供了openwakeword_model_paths按逗号拆分后传入Model(wakeword_modelsmodel_paths, inference_framework...)否则使用Model(inference_framework...)加载默认模型记录加载的模型数量与每个模型的名称owwModel.models.keys()便于日志排查。在音频处理循环中process_wakeword对 OpenWakeWord 的处理方式与 Porcupine 不同它将原始 PCM 直接转换为 NumPy 数组np.frombuffer(data, dtypenp.int16)调用owwModel.predict(pcm)得到各模型的预测分数然后对prediction_buffer中每个模型的最新分数逐一比较for idx, mdl in enumerate(recorder.owwModel.prediction_buffer.keys()): scores list(recorder.owwModel.prediction_buffer[mdl]) if scores[-1] recorder.wake_words_sensitivity and scores[-1] max_score: max_score scores[-1] max_index idx return max_index # 未命中时返回 -1即任一模型的最近一帧预测分数达到wake_words_sensitivity阈值时即视为命中并返回得分最高的模型索引。模型文件Porcupine 自定义关键词与 OpenWakeWord 模型路径Porcupine 自定义关键词Porcupine 的内置关键词由pvporcupine包直接提供开箱即用。对于自定义关键词官方流程是通过 Picovoice Console 训练生成模型.ppn 文件与关键词定义然后通过 Porcupine 包的keyword_paths等选项加载。RealtimeSTT 当前的唤醒词抽象层尚未直接暴露 Porcupine 的keyword_paths选项因此自定义 Porcupine 关键词需要等待该抽象层扩展后通过 Porcupine 包自身的选项传入——也就是说现阶段使用 Porcupine 时请优先使用上述内置关键词列表。OpenWakeWord 模型路径OpenWakeWord 的openwakeword_model_paths接受逗号分隔的多个模型文件路径openwakeword_model_pathsword1.onnx,word2.onnx每个模型对应一个独立的唤醒词。源码中正是通过openwakeword_model_paths.split(,)得到路径列表后逐个加载。支持的推理框架OpenWakeWord 支持两种推理框架onnxOpen Neural Network Exchange默认tfliteTensorFlow Lite通过openwakeword_inference_framework显式指定openwakeword_inference_frameworkonnx该参数在 RealtimeSTT/audio_recorder.py 中默认值为onnx与openwakeword包的默认行为一致。模型格式转换TFLite 转 ONNX如果手里只有 TensorFlow Lite 模型而希望使用 ONNX 推理可以使用tf2onnx进行转换python -m pip install -U tf2onnx python -m tf2onnx.convert --tflite my_model.tflite --output my_model.onnx训练与转换的一般流程OpenWakeWord 项目本身提供训练 notebook 与格式转换指导。完整工作流为在 RealtimeSTT之外完成数据采集、模型训练与格式转换将最终得到的.onnx或.tflite模型文件放入本地目录通过openwakeword_model_paths将模型路径传给AudioToTextRecorder。灵敏度与时机参数详解以下参数控制唤醒词检测的灵敏度与检测后的时机行为。默认值取自 RealtimeSTT/audio_recorder.py 顶部常量定义INIT_WAKE_WORDS_SENSITIVITY 0.6、INIT_WAKE_WORD_ACTIVATION_DELAY 0.0、INIT_WAKE_WORD_TIMEOUT 5.0、INIT_WAKE_WORD_BUFFER_DURATION 0.1参数默认值含义wake_words_sensitivity0.6检测阈值取值0到1。调低可减少漏检false negatives但可能增加误报false positives。wake_word_activation_delay0.0进入唤醒词激活状态前的延迟秒。若初始未检测到语音系统会在该延迟之后切换到唤醒词监听状态设为0则立即启用唤醒词激活。wake_word_timeout5.0唤醒词命中后等待语音的秒数。若在此窗口内未检测到后续语音系统回到唤醒词模式等待下一次唤醒。wake_word_buffer_duration0.1唤醒词检测前后缓冲/移除的音频时长秒目的是让唤醒词本身尽量不进入最终转写文本。参数在构造函数中的完整定义可参见 RealtimeSTT/audio_recorder.py第 152166 行附近的唤醒词参数段这些参数最终通过 RealtimeSTT/core/recorder_config.py 的build_recorder_init_args统一映射后进入初始化流程。参数背后的源码行为wake_word_activation_delay在 RealtimeSTT/core/recording.py 的录制循环中wake_word_activation_delay_passed表示从开始监听算起已超过该延迟在延迟尚未过去时系统走常规的 VAD 激活逻辑start_recording_on_voice_activity延迟过去后才进入唤醒词检测分支process_wakeword。这提供了一种混合模式先尝试普通语音激活超时后才切换为等待唤醒词。wake_word_timeout唤醒词命中时记录self.wake_word_detect_time time.time()当time.time() - self.wake_word_detect_time self.wake_word_timeout时系统判定超时并调用on_wakeword_timeout回调随后恢复等待下一次唤醒。wake_word_buffer_duration唤醒词命中时系统计算需要从录制缓冲中移除的采样数wakeword_samples_to_remove int(self.sample_rate * self.wake_word_buffer_duration)这部分音频唤醒词本身会从录音缓冲中剔除避免其混入后续语音的转写结果。若发现唤醒词字样仍然出现在最终文本中应调大该参数。OpenWakeWord 的灵敏度起点建议对于 OpenWakeWord 自定义模型官方建议以0.35左右的灵敏度作为首次测试起点再根据真实房间环境下的录音效果逐步调优具体数值与麦克风、环境噪声、说话人距离密切相关。仓库测试脚本 tests/openwakeword_test.py 正是使用了wake_words_sensitivity0.35。回调函数唤醒词生命周期事件RealtimeSTT 为唤醒词的完整生命周期提供了 4 个回调钩子回调触发时机on_wakeword_detection_start系统开始监听唤醒词时on_wakeword_detection_end系统结束监听唤醒词时on_wakeword_detected成功检测到唤醒词时on_wakeword_timeout唤醒词超时检测到唤醒词但后续无语音或进入监听后超时时基本用法def detected(): print(wake word detected) def timeout(): print(wake word timeout) recorder AudioToTextRecorder( wake_wordsjarvis, on_wakeword_detecteddetected, on_wakeword_timeouttimeout, )回调在源码中的触发点on_wakeword_detection_start/on_wakeword_detection_end在 RealtimeSTT/core/state.py 的状态切换逻辑中被调用set_recorder_state在进入/离开唤醒词监听状态时分别触发这两个回调on_wakeword_detected在 RealtimeSTT/core/recording.py 中唤醒词命中分支调用检测到wakeword_index 0后设置wakeword_detected True并执行回调随后系统进入等待 VAD 激活阶段on_wakeword_timeout有两个触发场景一是在激活延迟刚过去wake_word_activation_delay_passed首次变为 True且设置了延迟时触发一次二是在唤醒词已命中但超过wake_word_timeout仍未检测到语音时触发。回调默认在录制线程中同步执行若回调逻辑较重可通过构造参数start_callback_in_new_threadTrue让回调在独立线程中运行避免阻塞音频处理循环。回调的具体分发逻辑由run_callback统一封装。完整实战示例唤醒词 回调 持续对话结合以上内容一个完整的唤醒词驱动对话脚本如下from RealtimeSTT import AudioToTextRecorder def on_wakeword_detected(): print(Wake word detected, start speaking...) def on_wakeword_timeout(): print(No speech after wake word, waiting for wake word again.) def on_recording_start(): print(Recording...) def on_recording_stop(): print(Transcribing...) def text_detected(text): print(f {text}) recorder AudioToTextRecorder( modelsmall, languageen, wakeword_backendpvporcupine, wake_wordsjarvis,computer, wake_words_sensitivity0.5, wake_word_buffer_duration0.3, on_wakeword_detectedon_wakeword_detected, on_wakeword_timeouton_wakeword_timeout, on_recording_starton_recording_start, on_recording_stopon_recording_stop, ) print(Say Jarvis or Computer and then speak.) while True: recorder.text(text_detected)该示例同时演示了多关键词监听、灵敏度与缓冲时长调优、四个唤醒词生命周期回调、以及recorder.text()的持续轮询模式。故障排查Troubleshooting结合 docs/wake-words.md 的官方建议与源码实现常见问题及处理如下1. 唤醒词始终不触发逐项排查以下配置确认wakeword_backend选择了正确的后端pvporcupine/oww且对应的 extra 已安装——未安装时 RealtimeSTT/core/wakeword.py 会抛出带安装提示的ModuleNotFoundError确认麦克风设备input_device_index与采样率配置正确确认模型路径有效Porcupine 需使用内置关键词名OpenWakeWord 需提供真实存在的模型文件。2. OpenWakeWord 模型文件缺失或路径歧义优先使用绝对路径传入openwakeword_model_paths消除相对路径带来的歧义。3. 误报false positive过多调高wake_words_sensitivity阈值越高越难触发降低房间环境噪声或调整麦克风摆放位置若是自定义 OpenWakeWord 模型使用包含更多负样本非唤醒词语音的数据重新训练。4. 唤醒词出现在最终转写文本中调大wake_word_buffer_duration让系统从录制缓冲中移除更多唤醒词音频。默认0.1秒测试中常见取值为1.0秒见 tests/openwakeword_test.py。5. 使用调试日志辅助定位开启debug_modeTrue后每次唤醒词检测的porcupine_index或 OpenWakeWord 的max_index/max_score都会输出到日志可据此确认引擎是否在正常工作、分数是否接近阈值。与录音状态机的协同唤醒词模式并非孤立功能它与 RealtimeSTT 的录音状态机深度集成。在 RealtimeSTT/core/recording.py 中可以看到完整的状态流转未录制时若use_wake_words为真且已过激活延迟状态置为wakeword持续调用process_wakeword监听唤醒词命中后状态切换到等待 VAD检测到语音后开始正式录制进入recording状态wake_word_timeout内无语音则回到wakeword状态重新等待。此外RealtimeSTT/core/lifecycle.py 中的录制停止逻辑也会判断use_wake_words标志确保唤醒词模式下停止录制后正确地回到唤醒词监听状态而非直接进入普通 VAD 监听。这些状态通过 RealtimeSTT/core/state.py 的set_recorder_state统一管理并顺带触发on_wakeword_detection_start/on_wakeword_detection_end回调。需要了解完整状态机的读者可进一步阅读 docs/configuration.md 与 RealtimeSTT/core/state.py。总结RealtimeSTT 的唤醒词功能以wakeword_backendwake_words两个核心参数为入口提供了 Porcupine内置关键词、即插即用与 OpenWakeWord自定义模型、ONNX/TFLite 双框架两种成熟后端。通过wake_words_sensitivity、wake_word_activation_delay、wake_word_timeout、wake_word_buffer_duration四个参数的组合调节开发者可以在漏检与误报之间找到适合自身场景的平衡点而四个生命周期回调则让唤醒词事件可以无缝接入 UI 提示、状态机切换等业务逻辑。本文介绍的安装方式、配置示例、调优思路与排障方法均以仓库源码RealtimeSTT/core/wakeword.py、RealtimeSTT/core/recording.py、RealtimeSTT/audio_recorder.py、setup.py为据读者可在此基础上结合自己的麦克风环境与业务场景进一步迭代调优。【免费下载链接】RealtimeSTTA robust, efficient, low-latency speech-to-text library with advanced voice activity detection, wake word activation and instant transcription.项目地址: https://gitcode.com/GitHub_Trending/re/RealtimeSTT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考