Vosk 离线语音指令怎么识别?限定短语并处理未知词

用 Vosk 动态图小模型限定语音短语,读取 16kHz 单声道 WAV,以完整结果进行白名单匹配,并拒绝未知或未匹配文本。

智能体只需要接收“开灯”“关灯”这类少量语音指令时,可以先限定识别短语,再用完整结果匹配动作白名单。Vosk 的运行时词表用于缩小识别范围,未知词和没有精确匹配的结果应进入拒绝分支,而不是猜测后执行动作。

本文示例使用英文小模型、turn on light/turn off light 两条短语。代码在 Windows、Python 3.11.15、vosk 0.3.45 上运行,测试输入包含本机 Microsoft Zira 合成的英文“turn on light”以及项目提供的英文数字录音。合成语音只用于链路验证,没有在真实房间、噪声或中文语音环境测量识别准确率。

Vosk 离线语音指令怎么识别?限定短语并处理未知词

模型必须支持运行时限定词表

官方模型适配说明指出,运行时修改词表需要动态图模型,静态图大模型不支持同样的接口。此处选择 官方模型列表里的 vosk-model-small-en-us-0.15,下载 ZIP 并解压,把完整模型目录交给代码。

英文模型适合本例英文短语;要识别中文,需要相应中文动态图模型及中文短语,并重新验证目标设备、口音和噪声。把英文短语直接替换成中文字符串,并不能改变声学模型的语言能力。

准备真实 16kHz 单声道 PCM 音频

在独立环境安装 vosk==0.3.45。准备 WAV 格式、单声道、16 位 PCM、实际采样率 16000 Hz 的录音。本例会直接拒绝不同格式;修改 WAV 头或只把构造器采样率写成 16000,都不等于对原波形重采样。

例如录制一段清晰的英文 turn on light,保存为 command.wav。把代码保存为 recognize_command.py,运行 python recognize_command.py vosk-model-small-en-us-0.15 command.wav。第一个参数是模型目录,第二个是录音路径。

import json
import sys
import wave
from vosk import KaldiRecognizer, Model, SetLogLevel

SetLogLevel(-1)
model_path = sys.argv[1]
wav_path = sys.argv[2]
phrases = ['turn on light', 'turn off light', '[unk]']
routes = {'turn on light': 'LIGHT_ON', 'turn off light': 'LIGHT_OFF'}

def route(text):
    if '[unk]' in text or text not in routes:
        return 'REJECT'
    return routes[text]

assert route('turn on light') == 'LIGHT_ON'
assert route('[unk]') == 'REJECT'
assert route('turn on light please') == 'REJECT'
with wave.open(wav_path, 'rb') as audio:
    if audio.getnchannels() != 1 or audio.getsampwidth() != 2 or audio.getcomptype() != 'NONE':
        raise ValueError('Expected mono 16-bit PCM WAV')
    if audio.getframerate() != 16000:
        raise ValueError('This example requires an actual 16000 Hz waveform')
    model = Model(model_path)
    recognizer = KaldiRecognizer(model, 16000, json.dumps(phrases))
    print('audio_sample_rate:', audio.getframerate())
    print('grammar:', phrases)
    results=[]
    while True:
        chunk = audio.readframes(4000)
        if not chunk:
            break
        if recognizer.AcceptWaveform(chunk):
            results.append(json.loads(recognizer.Result()))
    results.append(json.loads(recognizer.FinalResult()))
for result in results:
    text=result.get('text', '')
    print('recognized:', text)
    print('route:', route(text))

本地运行输出

light_command.wav
audio_sample_rate: 16000
grammar: ['turn on light', 'turn off light', '[unk]']
recognized: turn on light
route: LIGHT_ON

test.wav
audio_sample_rate: 16000
grammar: ['turn on light', 'turn off light', '[unk]']
recognized: [unk] [unk]
route: REJECT
recognized: [unk]
route: REJECT

完整结果和动作匹配分开处理

官方短语词表示例将 JSON 短语列表传给 KaldiRecognizer,并使用 AcceptWaveform、Result 与 FinalResult 处理分块输入。本例保留 [unk] 作为未知结果通道,只匹配完整最终文本;PartialResult 可能继续变化,不适合直接触发动作。

程序打印 LIGHT_ON/LIGHT_OFF 仅代表演示路由,没有控制真实设备。路由函数对 [unk]、额外词语、空文本和未匹配短语都返回 REJECT;不要用“包含 light”这类宽松判断代替明确指令。

本次合成“turn on light”被识别为 turn on light,路由为 LIGHT_ON;英文数字录音落入未知或不匹配分支,没有触发灯光路由。验收时用两条合法短语、无关语句、静音和噪声分别测试,核对最终文本和动作结果,不只检查程序无异常。

接到真实智能体前还需要什么

  1. 对每种语音输入保留录音、最终文本、路由与人工预期,统计误触发和漏识别。
  2. 设置录音结束或分段规则,避免同一句话在多次结果中重复触发;记录请求编号和动作执行状态。
  3. 动作失败需要单独反馈;识别到短语不代表设备已完成操作。
  4. 账户、支付或不可逆动作应沿用现有权限和确认规则,不能仅靠一次语音转写授权。

限定短语无法保证无关声音总被识别为 unk。仍可能把相近发音误识别成白名单短语,尤其在噪声、回声和不同口音下;本例的拒绝分支能控制文本匹配范围,但不构成语音身份认证。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31867.html

赞 (0)
AI小管家的头像AI小管家
AI 文本怎么训练分词器?用 SentencePiece 生成模型并验证编码解码
上一篇 2小时前
Recraft API 怎么生成矢量图?调用 Vector 模型并核对 SVG 文件
下一篇 2小时前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部