CoolFace
Modelpublic

AfkaraLP/mister-president-wakeword

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes6downloads
Model Card

mister president — Wake Word Model

Custom wake word model for the phrase "mister president", trained with OpenWakeWord and Pocket TTS.

Model Summary

PropertyValue
Wake wordmister president
ArchitectureWakeWordNet
Input16 frames x 96 features (raw audio embeddings)
OutputProbability [0, 1]
Calibrated threshold0.75
Dimensions16 frames x 96 features

Benchmark Results

Evaluated on held-out project data and (where available) OpenWakeWord test data.

MetricValue
Threshold0.75
Recall (val)0.957
FP Rate (val)0.058

Data Sources

  • —Synthetic training data generated via Pocket TTS
  • —Adversarial negative samples (TTS-generated similar phrases)
  • —Noise and silence negative examples

Limitations

  • —Trained on synthetic data from a single speaker pipeline (Pocket TTS).
  • —May have reduced accuracy on speakers with different accents or speech patterns.
  • —False activations can occur with speech that phonetically resembles "mister president".
  • —The model expects raw 16kHz mono audio, not pre-processed features.

Files

  mister_president.onnx
  mister_president.onnx.data
  mister_president_results.json
  mister_president_benchmark.json
  README.md

Install

bash
pip install openwakeword

Usage

Option 1: Streaming (recommended for real-time use)

python
import numpy as np
from huggingface_hub import hf_hub_download
from openwakeword import Model

# Download model from this repo
model_path = hf_hub_download(
    repo_id="<your-username>/mister-president",
    filename="mister_president.onnx",
)

# Load into openwakeword (supports multiple models)
oww = Model(wakeword_model_paths=[model_path])
model_name = list(oww.models.keys())[0]

# Stream audio in 1280-sample (80ms) chunks
sr, audio = scipy.io.wavfile.read("your_audio.wav")
if sr != 16000:
    import scipy.signal
    audio = scipy.signal.resample(
        audio, int(len(audio) * 16000 / sr)
    ).astype(np.int16)
audio = audio.astype(np.int16)

threshold = 0.75
for i in range(0, len(audio), 1280):
    chunk = audio[i : i + 1280]
    if len(chunk) < 1280:
        chunk = np.pad(chunk, (0, 1280 - len(chunk)))
    prediction = oww.predict(chunk)
    score = prediction.get(model_name, 0.0)
    if score >= threshold:
        print(f"Wake word detected! score={score:.3f}")

Option 2: Single clip inference (batch)

python
import numpy as np
import scipy.io.wavfile
import onnxruntime as ort
from huggingface_hub import hf_hub_download
from openwakeword.utils import AudioFeatures

# Download and load the ONNX model
model_path = hf_hub_download(
    repo_id="<your-username>/mister-president",
    filename="mister_president.onnx",
)
sess = ort.InferenceSession(model_path, providers=["CPUExecutionProvider"])

# Load audio (16kHz mono)
sr, audio = scipy.io.wavfile.read("your_audio.wav")
if len(audio.shape) > 1:
    audio = audio[:, 0]
if sr != 16000:
    from scipy.signal import resample
    audio = resample(audio, int(len(audio) * 16000 / sr)).astype(np.int16)
audio = audio[:32000]  # Pad or truncate to 2 seconds

# Compute embeddings and run inference
fe = AudioFeatures()
feats = fe.embed_clips(audio[None, :], batch_size=1).astype(np.float32)
score = sess.run(None, {sess.get_inputs()[0].name: feats})[0][0][0]
print(f'Wake word score: {score:.3f}')
print(f'Detected: {score >= 0.75}')