Wyoming protocol server for Breeze TTS 2 (Home Assistant voice)
  • Python 79.9%
  • Shell 19.4%
  • Dockerfile 0.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
peter f937ecb87f Add one-shot Strix Halo installer + standalone benchmark client
- scripts/install_strix_halo.sh: preflight (GPU/tools), uv, ROCm torch
  from AMD's multi-arch wheel index (native gfx1151, no HSA_OVERRIDE),
  engine deps, GPU verification, protocol smoke test, checkpoint
  download, server launch, benchmark, ALSA playback sanity, HA hint
- scripts/bench_client.py: standalone Wyoming client printing TTFA/RTF
  and saving a listenable wav (verified live against the silence engine)
- install script flags: --model-dir --port --no-server --skip-model
2026-09-23 23:18:05 -07:00
scripts Add one-shot Strix Halo installer + standalone benchmark client 2026-09-23 23:18:05 -07:00
tests Wyoming protocol server for Breeze TTS 2 2026-09-23 20:46:40 -07:00
voices/sample Wyoming protocol server for Breeze TTS 2 2026-09-23 20:46:40 -07:00
wyoming_breeze Engine adapter against real upstream API + TTFA/RTF logging 2026-09-23 21:21:01 -07:00
.gitignore Wyoming protocol server for Breeze TTS 2 2026-09-23 20:46:40 -07:00
Dockerfile Wyoming protocol server for Breeze TTS 2 2026-09-23 20:46:40 -07:00
pyproject.toml Wyoming protocol server for Breeze TTS 2 2026-09-23 20:46:40 -07:00
README.md Engine adapter against real upstream API + TTFA/RTF logging 2026-09-23 21:21:01 -07:00

wyoming-breeze

Wyoming protocol server for Breeze TTS 2, for use as a text-to-speech provider in Home Assistant Assist.

HA voice assistant ──(Wyoming/TCP)──> wyoming-breeze ──> Breeze TTS 2 engine ──> 24 kHz PCM stream

Breeze TTS 2's native output format — 24 kHz mono signed 16-bit PCM — matches the Wyoming audio transport exactly, so this server is a thin adapter: no resampling, no format conversion.

Status

  • ✅ Wyoming server: Describe/Info, Ping/Pong, Synthesize, bidirectional SynthesizeStart/Chunk/Stop → SynthesizeStopped
  • ✅ Voice discovery from a voices/ folder (voice clone, voice direction, and voice design modes)
  • ✅ End-to-end smoke test against the Wyoming handshake and audio flow (tests/smoke_test.py)
  • ✅ silence engine for validating the HA → audio path before the model runs on your hardware
  • ✅ breeze engine adapter written against the real upstream API (breeze_infer.runtime.load_runtime + models.fast_streaming.FastBreezeStreamingRuntime.iter_audio_chunks), import-checked against a clean checkout of breezeblue-ai/breeze-tts @ main — voice modes verified to select the correct upstream templates (ref_clone_tata / ref_edit_tata / tts_instruction / tts_plain)
  • 🔧 First real-audio synthesis on a CUDA/ROCm host (needs the checkpoint; adapter logic is otherwise API-verified)
  • ⏳ Measured latency on target hardware (see Strix Halo notes); the server logs TTFA and RTF after every synthesis

Quick start (pipe test, no GPU)

uv venv && uv pip install -e .
python -m wyoming_breeze --engine silence --port 10200 --voices-dir voices

In Home Assistant: Settings → Devices & Services → Add Integration → Wyoming Protocol → host:10200. Pick the voice under the TTS tab of your voice assistant. You should hear a short tone followed by near-silence (deliberate — it proves audio really flows rather than failing silently).

Real engine (GPU)

git clone https://github.com/breezeblue-ai/breeze-tts
cd breeze-tts
pip install -r requirements.txt

cd ../wyoming-breeze
uv venv && uv pip install -e .

python -m wyoming_breeze \
    --engine breeze \
    --breeze-repo ../breeze-tts \
    --model-dir /path/to/breeze-tts-2 \
    --voices-dir ./voices \
    --port 10200

--breeze-repo just puts the upstream checkout on sys.path; pip install -e ../breeze-tts works instead. The checkpoint comes from BreezeBlue/Breeze-TTS-2 on Hugging Face.

On ROCm (AMD GPUs) resolve_device() picks the GPU automatically when torch sees it (ROCm presents as cuda), and leave --fast off — the upstream fast paths are CUDA Graphs; with --fast off the runtime runs pure eager, which is the correct mode on gfx1151.

Docker (NVIDIA host):

docker build -t wyoming-breeze .
docker run -d --gpus all -p 10200:10200 \
    -v /path/to/checkpoint:/model:ro \
    -v ./voices:/data/voices \
    wyoming-breeze --model-dir /model --voices-dir /data/voices

Voices

One directory per voice, name = directory name:

voices/
  nat/
    ref.wav            # reference audio (clean speech, mono, any rate)
    ref.txt            # EXACT transcript of ref.wav  (voice clone)
    instruction.txt    # optional style steering      (voice direction)
    meta.json          # optional: name / languages / description
  designer/            # no ref.wav → pure voice design from instruction.txt
  • ref.wav + ref.txt → voice clone (timbre, rhythm, emotion)
  • the above + instruction.txt → voice direction (clone, steered tone/pace)
  • instruction.txt alone → voice design (voice invented from the description)

Breeze's inline vocal events pass through untouched: put (laugh), (sigh), (clears throat) in the text HA speaks, or [笑]/[叹气] for Chinese.

The server refuses half-configured voices at startup rather than failing at synthesis time.

Command line

Flag Default Purpose
--host / --port 0.0.0.0:10200 Wyoming TCP listener (10200 = same port Wyoming Piper uses)
--voices-dir voices Voice folders, see above
--default-voice first found Used when HA doesn't specify one
--engine breeze breeze or silence (pipe test)
--model-dir — Breeze TTS 2 checkpoint
--fast off Upstream CUDA Graph fast paths (NVIDIA only)
--zeroconf off Advertise for HA auto-discovery

Concurrency is deliberately serialized: one synthesis at a time, busy requests get an Error event immediately (keeps VRAM deterministic; home assistants rarely need parallel speech).

AMD Strix Halo notes

Estimated RTF ≈ 0.7–1.5 on gfx1151 (Radeon 8060S, ~240 GB/s measured read vs H100's 3.3 TB/s), with first-audio latency ~0.5–1.5 s — fine for HA announcements and Assist answers, marginal for conversational barge-in. Memory capacity is a non-issue (model ~8 GB eager vs 64–96 GB unified). Bandwidth contention with co-located Ollama models is the tuning problem, not VRAM. AOTriton (flash-attention / torch.compile) on gfx1151 is currently experimental; whether it closes the gap is an open question and the first thing worth benchmarking — tests/rtt_bench.py (planned) measures it against audio wall-clock.

License

Wrapper code: Apache 2.0. Breeze TTS 2 model weights and self-hosted outputs are research / non-commercial only — see upstream license before deploying anywhere that isn't your own home.