Parlour

Your own wake word

Train a wake word of your own and drop it in.

The stock words are hey_jarvis, alexa and hey_mycroft. If you would rather Parlour answered to its own name, train one. openWakeWord makes this an hour's work on a free Colab GPU, and Parlour runs any model the notebook produces. The provider in packages/parlour/src/providers/wake/openwakeword.ts uses the same three stage pipeline for every word. A new word is just a new .onnx file and one line of config.

Train it

Open the simple notebook and set the runtime to a GPU (Runtime > Change runtime type > T4):

https://colab.research.google.com/drive/1q1oe2zOyZp7UsB3jJiQ1IFn8z5YfjwEb

Fill in the form cell and run everything.

FieldTryWhy
target_wordhey parlorPiper synthesises the training clips and reads spellings literally. The US spelling comes out right, while "parlour" is sometimes read as "par-loor". The model learns the sound, not the spelling, so spell it however you say it.
number_of_examples2000The default is 1000. More examples cost minutes and noticeably tighten the model.
number_of_training_steps20000The default is 10000.
false_activation_penalty1500Leave it for the first model. Raise it towards 3000 if the result wakes for the television.

The notebook downloads a couple of gigabytes of speech and noise without your word, generates clips with it, trains, and writes my_custom_model/hey_parlor.onnx. Download that file from the file browser on the left of the notebook.

If the first model fires too easily or not at all, try the full notebook. It runs the same process with two extra levers that matter more than any of the numbers above. target_phrase takes a list of spellings (["hey parlour", "hey parlor", "hey par lur"]). custom_negative_phrases takes things that sound like your word but should not fire (["hey harlow", "hey carla", "parlay", "hey pilot"]).

Install it

mv ~/Downloads/hey_parlor.onnx ~/Library/Caches/parlour/models/openwakeword/hey_parlour.onnx

The file name, without the .onnx, is what goes in the config:

{ "wake": { "provider": "openwakeword", "words": ["hey_parlour", "hey_jarvis"], "threshold": 0.5, "refractoryMs": 1500 } }

parlour restart picks it up. parlour doctor confirms it, or names the file it cannot find. Keep hey_jarvis in the list for the first day, as above. It costs a little CPU and gives you a word you know works while you judge the new one.

The provider feeds each word the last 16 speech embeddings. Models the notebooks train for a phrase of a few syllables expect exactly that. If yours stays silent, check its inputs first, from a checkout of this repository:

cd packages/parlour && node -e '
const ort = require("onnxruntime-node");
ort.InferenceSession.create(process.env.HOME + "/Library/Caches/parlour/models/openwakeword/hey_parlour.onnx")
  .then((s) => console.log(s.inputNames, s.outputNames))'

Tune it

Every detection is logged with its score, such as "hey_parlour" fired at 0.83 on local, so leave it running and talk to it. Custom models tend to score a little lower than the stock ones, so you can bring threshold down to 0.4. If it wakes for the room, raise false_activation_penalty and retrain. Pushing the threshold much past 0.7 mostly stops it hearing you too. The other settings are in Tuning.

On this page