- Python 79.9%
- Shell 19.4%
- Dockerfile 0.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
- 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 |
||
| scripts | ||
| tests | ||
| voices/sample | ||
| wyoming_breeze | ||
| .gitignore | ||
| Dockerfile | ||
| pyproject.toml | ||
| README.md | ||
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, bidirectionalSynthesizeStart/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) - ✅
silenceengine for validating the HA → audio path before the model runs on your hardware - ✅
breezeengine 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 ofbreezeblue-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.txtalone → 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.