Распознавание ключевых слов
Поиск ключевых слов или Keyword spotting (KWS) — это метод распознавания речи, который обнаруживает определенные ключевые слова или триггерные фразы в непрерывном аудиопотоке.
openWakeWord
openWakeWord — это библиотека с открытым исходным кодом для распознавания слов-будильников, которую можно использовать для создания приложений и интерфейсов с голосовым управлением. Она включает в себя предварительно обученные модели для распространённых слов и фраз, которые хорошо работают в реальных условиях.
GitHub,
openWakeWord работает с форматами .onnx и .tflite. Для Windows используется .onnx, а для Linux .tflite.
Инструкция
-
Создать новый проект и установить библиотеки
> pip install openwakeword, sounddevice -
Скачать модель, например hey_jarvis по ссылке https://github.com/dscripka/openWakeWord/releases/tag/v0.5.1 и сохранить в папку проекта
- Запустить код:
import numpy as np
import sounddevice as sd
from openwakeword.model import Model
import time
SAMPLE_RATE = 16000
FRAME_MS = 80
FRAME_SAMPLES = SAMPLE_RATE * FRAME_MS // 1000 # 1280
THRESHOLD = 0.5 # tune for your room
COOLDOWN_SEC = 1.0 # suppress duplicate prints
# load only the “hey jarvis” model; omit arg to load all built-ins
model = Model(wakeword_models=["./hey_jarvis_v0.1.onnx"], vad_threshold=0.0) # set >0 to enable VAD
_last_fired = 0.0
def on_audio(indata, frames, t, status):
global _last_fired
if status:
print(status, flush=True)
audio = indata.reshape(-1).astype(np.int16) # 16-bit PCM
scores = model.predict(audio) # dict: {model_name: score 0..1}
for name, s in scores.items():
if s >= THRESHOLD and (time.time() - _last_fired) >= COOLDOWN_SEC:
print(f"[wake] {name}: {s:.2f}")
_last_fired = time.time()
if __name__ == "__main__":
print("Listening at 16 kHz… Ctrl+C to exit")
with sd.InputStream(
channels=1, samplerate=SAMPLE_RATE, dtype="int16",
blocksize=FRAME_SAMPLES, callback=on_audio
):
while True:
sd.sleep(1000)
Коллекция тренированных слов:
https://github.com/fwartner/home-assistant-wakewords-collection/tree/main/en
Автоматическая тренировка новых слов в Google Colab:
https://colab.research.google.com/drive/1q1oe2zOyZp7UsB3jJiQ1IFn8z5YfjwEb?usp=sharing
Примеры
Скачать файл и загрузить в папку проекта
Jarvis sound
import os
import numpy as np
import sounddevice as sd
from openwakeword.model import Model
import time
import winsound
SAMPLE_RATE = 16000
FRAME_MS = 80
FRAME_SAMPLES = SAMPLE_RATE * FRAME_MS // 1000 # 1280
THRESHOLD = 0.5
COOLDOWN_SEC = 1.0
model = Model(wakeword_models=["./hey_jarvis_v0.1.onnx"], vad_threshold=0.0)
#["./hey_jarvis_v0.1.onnx", "./yo_bitch.onnx"]
_last_fired = 0.0
JARVIS_WAV = os.path.join(os.path.dirname(os.path.abspath(__file__)), "jarvis.wav")
def play_jarvis():
if os.path.isfile(JARVIS_WAV):
winsound.PlaySound(JARVIS_WAV, winsound.SND_FILENAME | winsound.SND_ASYNC)
else:
print(f"[warn] WAV not found: {JARVIS_WAV}")
def on_audio(indata, frames, t, status):
global _last_fired
if status:
print(status, flush=True)
audio = indata.reshape(-1).astype(np.int16)
scores = model.predict(audio)
for name, s in scores.items():
if s >= THRESHOLD and (time.time() - _last_fired) >= COOLDOWN_SEC:
print(f"[wake] {name}: {s:.2f}")
play_jarvis()
_last_fired = time.time()
if __name__ == "__main__":
print("Listening at 16 kHz… Ctrl+C to exit")
with sd.InputStream(
channels=1, samplerate=SAMPLE_RATE, dtype="int16",
blocksize=FRAME_SAMPLES, callback=on_audio
):
while True:
sd.sleep(1000)