Skip to content

Repository files navigation

The reason for this repo is pretty straight forward: you're using Atlas Voice or your own custom rolled voice assistant and saying "Hey Jarvis" feels a bit to Hollywood fanboi-ish. This repo will allow you to train whatever word you want to use. It's a Dockerized (and native linux) training pipeline for custom audio trigger models. Compatible with OpenAI Whisper and Faster Whisper and based on the outstanding OpenWakeWord work by David Scripka.

If you want to skip all the formalities of training and use "Hey Atlas" as your trigger word, see "Releases" in the right pane. Both the .onnx and .tflite models can be downloaded.

OpenWakeWord Custom Wake Word Training

The Dependency Problem

Training OpenWakeWord models in 2026 is a dependency nightmare. The training pipeline requires PyTorch 1.13.1, TensorFlow 2.8.1, and dozens of other packages pinned to 2022-era versions that have since aged out of compatibility with modern Python. The train-wakeword.sh script will build a complete dockerized training solution. The train.sh script does the exact same thing, but installs native dependencies with no docker requirement. Both scripts freeze the working environment of openWakeWord to commit 368c037 (main on February 1, 2026).

Objective

To build a Docker container that downloads training data, generates synthetic speech samples, augments them with common noise, trains a neural network, and outputs a model file (~200KB) that can listen for your custom trigger word.

Requirements

  • NVIDIA GPU with CUDA support
  • Docker with nvidia-container-toolkit
  • ~45GB free disk space (20GB training data + container workspace)

All packages and dependencies are handled inside the container.

If you use the bare-metal train.sh path instead, you also need Python 3.10 on the host (python3.10, python3.10-venv, python3.10-dev). PyTorch 1.13.1 and TensorFlow 2.8.1 only ship cp310 wheels - Python 3.11+ will fail at the pip install step. On Ubuntu-based systems the script can install 3.10 from the deadsnakes PPA for you.

Quick Start

git clone https://github.com/briankelley/atlas-voice-training.git
cd atlas-voice-training
./train-wakeword.sh

Launch the main script and it'll walk you through the process:

  1. Builds the Docker image (first run only, cached after that)
  2. Asks if you want to proceed with the ~20GB training data download
  3. Asks for your wake word with advice on what works best
  4. Shows default training settings (configurable)
  5. Launches training inside the container
  6. Models saved to docker-output/

Output

═══════════════════════════════════════════════════════
  Training Complete!
  Wake word: "Hey Atlas"

  Models:
    hey_atlas.onnx    (201K)
    hey_atlas.tflite  (207K)

  Accuracy:  81.07%  (how well it tells your wake word apart from everything else)
  Recall:    62.20%  (how often it catches your wake word; higher = less repeating yourself)
  FP/hr:     1.24    (phantom activations per hour when you're not speaking the wake word)

  Output directory: /output/
═══════════════════════════════════════════════════════

Using the Model

Copy the .tflite file to ~/.local/share/openwakeword/ for use with OpenWakeWord.

The trained model handles wake word detection only. To build a full voice input pipeline, you also need:

Package Purpose
OpenWakeWord Loads the .tflite model and listens for the wake word
faster-whisper Speech-to-text transcription after the wake word triggers
sounddevice Audio capture from your microphone

Wake Word Selection

Use a two-word phrase. This was a big factor in model quality across every configuration I tested. A prefix like "Hey" or "Okay" gives the model a stronger acoustic signature.

Wake Word Accuracy Recall FP/hr Verdict
"Hey Atlas" (50k samples) 81.10% 62.48% 2.12 Best overall
"Globe Master" (50k samples) 81.07% 62.20% 1.24 Two-word phrase, consistent
"Hey Atlas" (100k samples) 77.47% 55.08% 0.62 More conservative, worse recall
"Atlas" (50k, 3 aug rounds) 71.64% 43.54% 2.57 Single word, consistently worse
"Atlas" (50k, 64 neurons) 71.94% 44.04% 2.48 Extra neurons didn't help

No combination of augmentation rounds, sample count, or neuron depth made the model more accurate when the "Hey" prefix was dropped.

Training Settings

The defaults produce the best balance of accuracy and recall based on empirical testing. You can change this before training. Hat tip to @dscripka for great defaults.

Setting Default Purpose Testing Notes
Samples 50,000 Number of synthetic speech clips generated Doubling to 100k didn't improve accuracy or recall
Augmentation rounds 2 Times each clip is re-processed with noise/reverb 3 rounds produced no measurable improvement
Training steps 100,000 Neural network training iterations 150k steps didn't improve results
Layer size 32 Neurons per hidden layer 64 neurons produced identical results to 32

Training Data

Training data is hosted on HuggingFace and downloaded automatically in standalone mode (~20GB as a single tarball).

File Size Purpose
ACAV100M features 17 GB 2,000 hours of pre-computed negative examples
MUSAN music 4.6 GB Background audio for augmentation
MIT Room Impulse Responses 300 MB Room reverb simulation (pre-converted to 16kHz)
Validation features 177 MB False positive testing during training
Piper TTS model 200 MB Synthetic speech generation
Embedding models ~10 MB OpenWakeWord melspectrogram and embedding inference

All training data is bundled in a single ~20GB tarball and downloaded automatically.

How It Works

Training runs in three phases inside the container (start to finish with defaults and broadband is ~1h on a 4090):

  1. Generate clips - Piper TTS creates thousands of synthetic pronunciations of your wake word with varying voices, speeds, and pitch
  2. Augment clips - Each clip is layered with room reverb, background noise, and acoustic conditions (runs on CPU)
  3. Train model - A neural network learns to distinguish your wake word from everything else (runs on GPU)

The output is an ONNX model and a TFLite model, both under 250KB.

Files

File Purpose
train-wakeword.sh What you run - interactive host wrapper (run this on your rig)
train.sh Bare-metal path - installs and runs everything natively without Docker
container-entrypoint.sh Runs inside the Docker container
Dockerfile.training Builds the training environment
validate_model.py Compare model accuracy against test data

Issues encountered and fixed (all from the upstream dependency stack):

  1. torch==1.13.1 - no wheels for Python 3.12+
  2. pyarrow - broke datasets API (pinned <15.0.0)
  3. fsspec - broke datasets glob patterns (pinned <2024.1.0)
  4. webrtcvad - needs C compilation, undocumented dependency on build-essential
  5. python3.10-venv - version-specific package naming
  6. HuggingFace download leaves .cache directories that break training
  7. MIT RIR files nested in 16khz/ subdirectory
  8. MIT RIR files are 32kHz, training expects 16kHz
  9. Docker shared memory - PyTorch DataLoader needs --shm-size=32g
  10. HuggingFace rate limiting from repeated individual file downloads
  11. Training segfaults on cleanup after model is already saved (harmless)
  12. Python output buffering in Docker hides progress (PYTHONUNBUFFERED=1)

License

  • Training scripts and configs: Apache 2.0
  • ACAV100M features: CC-BY-NC-SA-4.0 (non-commercial)
  • MUSAN: CC BY 4.0

Note: The CC-BY-NC-SA-4.0 license on ACAV100M means trained models inherit a non-commercial restriction.

Acknowledgments

About

Customized "wake word" training for David Scripka's "OpenWakeWord"

Resources

Stars

11 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages