Skip to main content

Wyoming Piper

Wyoming protocol server for the Piper text to speech system.

Home Assistant Add-on

Show add-on

Source

Local Install

Requires Python 3.10 or later.

Clone the repository and set up Python virtual environment:

git clone https://github.com/OHF-Voice/wyoming-piper.git
cd wyoming-piper
script/setup

Run a Wyoming server that Home Assistant can connect to:

script/run --voice en_US-lessac-medium --uri 'tcp://0.0.0.0:10200' --data-dir /data --download-dir /data 

For a demo web server, make sure to install the http dependencies first:

script/setup --http

Then run in a separate terminal:

script/run_http --uri 'tcp://localhost:10200'

and visit http://localhost:5000 to test.

Optional phonemizers

Most voices are phonemized with espeak-ng, which is built in. Three languages need an extra:

Language Extra Provides
Chinese zh g2pW (pinyin voices only)
Japanese ja OpenJTalk
Thai th TLTK
script/setup --ja --th        # or: pip install '.[ja,th]'

Voices that need a missing extra are not advertised, since a client would otherwise offer them and every request would answer with silence. They reappear once the extra is installed — no restart is needed for the voice list itself, which is rebuilt on each Describe, but the phonemizer has to be importable by the running process. Passing one as --voice is an error at startup.

Chinese is the exception: zh_CN-huayan-medium and zh_CN-huayan-x_low are espeak voices and work without the zh extra, so catalog voices for zh are always advertised. A custom Chinese voice is filtered correctly, because its config records phoneme_type.

OmniVoice backend (experimental)

An alternative OmniVoice backend is available, running a block-wise int4 ONNX export under onnxruntime. Install the extra dependencies and select it with --backend omnivoice:

script/setup --omnivoice
script/run --backend omnivoice \
    --uri 'tcp://0.0.0.0:10200' --data-dir /data --download-dir /data \
    --omnivoice-ref-dir /data/omnivoice_voices --omnivoice-steps 32

Installing with pip takes two steps, because the omnivoice package requires gradio, librosa, webdataset and tensorboardx for its demo and training paths, which this backend never imports. Skipping them drops 42 packages and ~600 MB:

pip install 'wyoming-piper[omnivoice-deps]'
pip install --no-deps omnivoice

The omnivoice extra installs both in one step instead, at that extra ~600 MB.

Voices. Point --omnivoice-ref-dir at a directory of voices organized as <language>/<voice_name>/, for example:

omnivoice_voices/
  en_US/
    lessac/{ref.wav, ref.txt}
    ryan/{ref.wav, ref.txt}
    narrator/{instruct.txt}
  de_DE/
    thorsten/{ref.wav, ref.txt}

Each voice directory is one of two kinds:

  • Cloning — ref.wav + ref.txt (the transcript of the recording); the voice is cloned from the reference audio.
  • Voice design — instruct.txt; its text is a style instruction (e.g. male, deep, slow) describing the voice to generate, with no reference audio. See voice design for valid attributes. Only used when the directory has no ref.wav/ref.txt.

A default voice is also advertised; requesting it (or an empty/unknown voice name) uses OmniVoice's built-in speaker for the requested language.

OmniVoice lists 646 language codes, most of them ISO 639-3 only. Advertising all of them buries the usable ones in Home Assistant's language picker, so default is advertised for the ~128 that have an ISO 639-1 (two-letter) tag, plus Cantonese, Standard Arabic and Odia. This limits only what is advertised — --omnivoice-language and a per-request language still accept any code OmniVoice knows, so the rest stay reachable.

On first use, each reference is encoded and cached next to ref.wav as ref.rvq (regenerated whenever ref.wav is newer), so the reference isn't re-encoded on every request.

The model is a block-wise int4 ONNX graph (see script/quantize_omnivoice.py to reproduce it). If omnivoice.int4.onnx (and its .data) are found in a --data-dir, that copy is used; otherwise it is downloaded into --download-dir (used as the HuggingFace cache) from the repo set by --omnivoice-onnx-repo. Use --local-files-only to run fully offline once the model is cached, and --omnivoice-steps to trade quality for speed — int4 stays clean down to ~10 steps. OmniVoice is compute-heavy and best suited to a desktop/server CPU rather than low-power devices.

Voice management web UI

A small Flask web UI can run alongside the Wyoming server to manage custom voices. It is designed to work as a Home Assistant add-on behind ingress. Install the extra dependency and enable it with --web-server:

script/setup --web
script/run --voice en_US-lessac-medium \
    --uri 'tcp://0.0.0.0:10200' --data-dir /data --download-dir /data \
    --web-server --web-server-port 5000

Then visit http://localhost:5000. The page has two sections:

  • Piper — upload and delete custom voices (a <voice>.onnx model plus its <voice>.onnx.json config) stored in --download-dir. Some metadata (dataset, language, quality, sample rate) is read from each config file.
  • OmniVoice — upload cloned voices (a reference WAV plus its required transcript) into --omnivoice-ref-dir/<language>/<voice_name>/, and delete a cloned voice's whole directory.

Each section shows a warning when its backend is not the one the server was started with (via --backend), but the UI keeps working. The server picks up added and removed voices on its own — no restart — but Home Assistant caches the voice list, so reload the Piper integration for a new voice to appear in it.

--web-server-host / --web-server-port set the bind address (default 127.0.0.1:5000). The UI has no authentication and can upload and delete files under --download-dir / --omnivoice-ref-dir, so only bind it to an address reachable from a network you trust.

When the bind address has to be routable — behind a proxy on another host, as with Home Assistant ingress — --web-server-allow narrows it back down. It takes an IP address or CIDR range, may be repeated, and answers everything else with a 403:

script/run --voice en_US-lessac-medium \
    --uri 'tcp://0.0.0.0:10200' --data-dir /data --download-dir /data \
    --web-server --web-server-host 0.0.0.0 \
    --web-server-allow 172.30.32.2   # the Home Assistant ingress proxy

The check uses the peer address of the connection, never X-Forwarded-For or a similar header, since a client sets those itself. It runs outside every other layer, so a rejected peer never reaches routing or an upload. Without the option, any address that can connect is served, as before.

Docker Image

docker run -it \
    -p 10200:10200 \
    -v /path/to/local/data:/data \
    rhasspy/wyoming-piper \
    --voice en_US-lessac-medium

OmniVoice ships as a separate omnivoice tag, because it pulls in torch and transformers. It is built for linux/amd64 only — OmniVoice needs a desktop/server CPU:

docker run -it \
    -p 10200:10200 \
    -v /path/to/local/data:/data \
    rhasspy/wyoming-piper:omnivoice \
    --backend omnivoice \
    --omnivoice-ref-dir /data/cloned-voices \
    --omnivoice-steps 10  # higher = better quality but slower

The voice management web UI is off by default. It has no authentication, so only enable it on a network you trust, and add --web-server-allow to limit it to the clients that should reach it:

docker run -it \
    -p 10200:10200 -p 5000:5000 \
    -v /path/to/local/data:/data \
    rhasspy/wyoming-piper \
    --voice en_US-lessac-medium \
    --web-server --web-server-host 0.0.0.0

NVIDIA GPU image

Build the local GPU image with:

docker build -f Dockerfile.gpu -t wyoming-piper:gpu .

The image contains CUDA-enabled PyTorch and ONNX Runtime, includes OmniVoice, and enables --use-cuda automatically. Run Piper with the NVIDIA Container Toolkit and a persistent data directory:

docker run --rm -it \
    --gpus all \
    -p 10200:10200 \
    -v /path/to/local/data:/data \
    wyoming-piper:gpu \
    --voice en_US-lessac-medium

Set WYOMING_PIPER_ARGS to a shell-style argument string when Docker Compose environment variables are more convenient than command. For example:

services:
  piper:
    build:
      context: .
      dockerfile: Dockerfile.gpu
    gpus: all
    ports:
      - "10200:10200"
    volumes:
      - ./data:/data
    environment:
      WYOMING_PIPER_ARGS: >-
        --voice en_US-lessac-medium

To run OmniVoice instead, replace the environment value with:

      WYOMING_PIPER_ARGS: >-
        --backend omnivoice
        --omnivoice-ref-dir /data/cloned-voices
        --omnivoice-steps 10

The host must have an NVIDIA driver and the NVIDIA Container Toolkit. The GPU image is currently linux/amd64 only because its PyTorch base image is amd64.

Container health check

The image has a health check that asks the server for its info over the Wyoming protocol, so docker ps reports unhealthy if the server stops answering. It assumes the default tcp://0.0.0.0:10200; if you override --uri, override the check to match:

docker run -it \
    -p 10300:10300 \
    -v /path/to/local/data:/data \
    --health-cmd '/usr/src/.venv/bin/python3 -m wyoming_piper.health_check --uri tcp://127.0.0.1:10300' \
    rhasspy/wyoming-piper \
    --uri tcp://0.0.0.0:10300 \
    --voice en_US-lessac-medium

Loading the backend can take minutes on first run, since the model has to be downloaded before the server starts listening. The check's start period allows for that, so the container reports starting rather than unhealthy until then.

Source

Release files for wyoming-piper 2.5.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wyoming-piper 2.5.2
File Size Uploaded
wyoming_piper-2.5.2.tar.gz 89.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wyoming-piper 2.5.2
File Interpreter ABI Platform
wyoming_piper-2.5.2-py3-none-any.whl Python 3 none any Details

Total release size: 167.3 kB

Release files / wyoming_piper-2.5.2.tar.gz

Download URL wyoming_piper-2.5.2.tar.gz
Size 89.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e0e35349b963ba4d958ef8f7b38f4b3ad633e91a93766b20d137fbf0d2648d81
BLAKE2b-256 checksum
How to use checksums
9da0f7c51a2f84fd853b25a6d7fed62771f350ffa7e869b8a67f00b2f41fc4a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / wyoming_piper-2.5.2-py3-none-any.whl

Download URL wyoming_piper-2.5.2-py3-none-any.whl
Size 78.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ee5aa96cdec6e4695847f261029af7fcb1bf1d777655f958f1c9aa5e5ce847e8
BLAKE2b-256 checksum
How to use checksums
b663187e6f0b3df6fa2eed8a7a55d3652fac25febb90fc901eebf5400c37e833
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.5.2 This release

2 release files

2.5.1

2 release files

2.5.0

2 release files

2.4.3

2 release files

2.4.2

2 release files

2.4.0

2 release files

2.3.1

2 release files

2.2.2

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.2

2 release files

1.6.3

2 release files

1.5.3

2 release files

1.4.0

1 release file

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

1 release file

1.1.0

1 release file

1.0.0

1 release file

0.0.3

1 release file

0.0.2

1 release file

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page