Piper Text-to-Speech: Fast Local Voices on a Raspberry Pi, Linux, Windows or Mac
Before you start
- 21 min read
Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

What you get in one minute#
Piper is a fast, free text-to-speech engine that turns text into spoken audio on your own computer, with no cloud account, and it is light enough to run on a Raspberry Pi.

Logo: the official Piper project (github.com/OHF-Voice/piper1-gpl)
You give Piper a sentence and a voice file, and it writes a WAV file or streams audio. It speaks about 40 languages, from a command line, a small web server or Home Assistant. People use it for smart-home announcements, screen readers and any project that needs a voice without a cloud service.
The project moved. Read this before you search. Most older tutorials use rhasspy/piper. That repository is now archived and read-only (since October 2025), and its README says "Development has moved" to OHF-Voice/piper1-gpl, run by the Open Home Foundation. The old code was MIT; the new code is GPL-3.0. It is alive (a release in September 2026, commits in November 2026), but its README also asks for new maintainers, and many issues have no reply. We say this plainly so you can decide.
| Current version | piper-tts 1.8.0, released September 2026 (PyPI and GitHub) |
| Time needed | About 20 minutes plus the voice download (our estimate) |
| Size | Install wheel about 34 MB; one medium voice 63 MB; a high voice 114 MB |
| Ports | 5000 for the HTTP server (Piper docs); 10200 for the Home Assistant wrapper |
| Licence | Code: GPL-3.0. Each voice has its own licence, some non-commercial |
| Official docs | github.com/OHF-Voice/piper1-gpl and its docs folder |
At a glance:
- What it is: a Python package,
piper-tts, with a command line, an HTTP server and a Python API. - Where it runs: Linux (x86_64 and 64-bit Arm, so Raspberry Pi 4 and 5 with a 64-bit system), Windows, Mac.
- Voices: two files per voice, a
.onnxmodel and a.onnx.jsonconfig, downloaded once from Hugging Face. - No login: the HTTP server has no password. Keep it on
127.0.0.1or behind a proxy that asks for one. - Not OpenAI-style: the API is Piper's own (
/synthesize). Open WebUI needs an OpenAI-style address; see our Kokoro-FastAPI guide. - Related guides: Home Assistant voice control uses Piper as its voice; Chatterbox clones voices on a stronger computer.
How it fits together#
Text comes in through one of three doors. The engine turns it into phonemes with espeak-ng, then a voice model on your disk turns the phonemes into sound.
Drawn for this guide from the Piper docs (CLI, HTTP API, Voices) and the wyoming-piper README, November 2026. Dashed parts are optional.
Before you start#
| Linux and Raspberry Pi | Windows | Mac | |
|---|---|---|---|
| System | x86_64, or 64-bit Arm (Raspberry Pi OS 64-bit) | Windows, 64-bit Intel or AMD | Intel or Apple Silicon (see the warning in Step 1) |
| Python | 3.9 or newer (PyPI lists 3.9 to 3.13) | same | same |
| RAM | Not documented by Piper | same | same |
| Disk | About 100 MB for the install and one medium voice | same | same |
Check Python, and Docker only if you use Step 5:
python3 --version docker --version docker compose version
python --version docker --version docker compose version
Checklist:
- [ ] Python 3.9 or newer
- [ ] Internet for the install and the one-time voice download
- [ ] Port 5000 free if you run the HTTP server
- [ ] You know what the voice licence allows (see "Voices and licences")
- [ ] For Step 5 only: Docker, and port 10200 free
- [ ] For the HTTPS section only: a DNS name pointing at this machine and ports 80 and 443 free
Tested on November 2026: not run by DIY Lab Hub on Linux, Windows or Mac (a rule for this batch); every command comes from the official docs listed in Sources.
Raspberry Pi: Piper publishes wheels for 64-bit Arm (aarch64) and no 32-bit Arm wheel, so use 64-bit Raspberry Pi OS. Home Assistant's docs say medium voices run at usable speed on a Pi 4, and suggest low or x_low voices if you want more speed.
Step 1: Install Piper in a virtual environment#
Use a virtual environment, not a system-wide install. Recent Debian and Ubuntu systems refuse system-wide pip install with error: externally-managed-environment (issue #318 reports it on Ubuntu 24.04), and a virtual environment is the standard way around that.
Linux#
mkdir -p ~/piper-tts/voices cd ~/piper-tts python3 -m venv .venv source .venv/bin/activate python3 -m pip install --upgrade pip python3 -m pip install "piper-tts[http]==1.8.0"
If python3 -m venv fails, install the venv package for your distribution (the Ubuntu message in issue #318 names python3-full). The [http] part adds Flask for the web server (Piper's HTTP API page). We pin 1.8.0 so a later release cannot change the commands under you.
Windows (PowerShell)#
New-Item -ItemType Directory -Force "$HOME\piper-tts\voices" | Out-Null Set-Location "$HOME\piper-tts" python -m venv .venv .\.venv\Scripts\Activate.ps1 python -m pip install --upgrade pip python -m pip install "piper-tts[http]==1.8.0"
If PowerShell refuses Activate.ps1, the Python docs say to allow scripts for your user once: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser.
Mac (Terminal)#
Same commands as Linux:
mkdir -p ~/piper-tts/voices cd ~/piper-tts python3 -m venv .venv source .venv/bin/activate python3 -m pip install --upgrade pip python3 -m pip install "piper-tts[http]==1.8.0"
The quotes matter on the Mac: zsh, its default shell, reads [http] as a pattern.
Warning, Apple Silicon: issue #272 (open since August 2026) reports that the macOS arm64 wheel of 1.6.1 failed on every sentence with a build-machine path in the error. We did not confirm that for 1.8.0. If you see it, the reporter's workaround was a Linux container; see Troubleshooting.
Check it worked. The package should report version 1.8.0 and the command should print its options:
python3 -m pip show piper-tts python3 -m piper --help
On Windows use python in place of python3.
Step 2: Download a voice#
A voice is two files: en_US-lessac-medium.onnx and en_US-lessac-medium.onnx.json. Names follow <language>_<REGION>-<name>-<quality>. Listen to samples first at rhasspy.github.io/piper-samples, then download. --data-dir is the folder to save to; without it, Piper saves to the current folder.
Linux#
python3 -m piper.download_voices python3 -m piper.download_voices en_US-lessac-medium --data-dir ~/piper-tts/voices
The first command lists all voices. The second downloads one.
Windows (PowerShell)#
python -m piper.download_voices python -m piper.download_voices en_US-lessac-medium --data-dir "$HOME\piper-tts\voices"
Mac (Terminal)#
Same commands as Linux:
python3 -m piper.download_voices python3 -m piper.download_voices en_US-lessac-medium --data-dir ~/piper-tts/voices
Check it worked. The folder has the two files. The .onnx file should be about 63 MB (63,201,294 bytes in the voice list on Hugging Face):
ls -l ~/piper-tts/voices
Get-ChildItem "$HOME\piper-tts\voices"
Tip: Quality levels, from the Home Assistant Piper docs:
x_low(16 kHz, smallest and fastest),low(16 kHz),medium(22.05 kHz, the usual choice),high(22.05 kHz, slowest, best). Start withmedium; go down a level only if your Pi is too slow.
Step 3: Say your first sentence#
Linux#
python3 -m piper -m en_US-lessac-medium --data-dir ~/piper-tts/voices -f test.wav -- 'This is a test.' aplay test.wav
aplay comes with the ALSA tools on most Linux systems; any audio player works.
Windows (PowerShell)#
python -m piper -m en_US-lessac-medium --data-dir "$HOME\piper-tts\voices" -f test.wav -- 'This is a test.' (New-Object System.Media.SoundPlayer "$PWD\test.wav").PlaySync()
Mac (Terminal)#
Same Piper command as Linux, then play it with the built-in afplay:
python3 -m piper -m en_US-lessac-medium --data-dir ~/piper-tts/voices -f test.wav -- 'This is a test.' afplay test.wav
Check it worked. You hear "This is a test." and test.wav exists. The playback commands are standard system tools, not Piper docs. Piper can also read text from a pipe, and from files with --input-file.
If you leave out -f, Piper tries to play through ffplay. Without ffplay it logs Audio playback is not available (ffplay). Writing audio to output.wav. and writes output.wav for you.
Step 4: Run the HTTP server (on this machine only)#
The server loads the voice once, so every request is fast. The Piper docs say the command-line way is slow for repeated use because it reloads the model each time.
The default is wide open. In the 1.8.0 source the --host default is 0.0.0.0 (every network interface), the server has no login, and it runs on Flask's built-in development server. Set --host 127.0.0.1 unless you put a proxy in front (see the HTTPS section).
Linux#
cd ~/piper-tts source .venv/bin/activate export ORT_DISABLE_TELEMETRY=1 python3 -m piper.http_server -m en_US-lessac-medium --host 127.0.0.1 --data-dir ~/piper-tts/voices
In a second terminal:
curl http://127.0.0.1:5000/info
curl -X POST -H 'Content-Type: application/json' -d '{ "text": "This is a test." }' -o test2.wav http://127.0.0.1:5000/synthesize
To keep it running on a Raspberry Pi or server, this is a standard systemd service (not from the Piper docs). Replace <your-user>:
[Unit] Description=Piper HTTP server After=network.target [Service] User=<your-user> WorkingDirectory=/home/<your-user>/piper-tts Environment=ORT_DISABLE_TELEMETRY=1 ExecStart=/home/<your-user>/piper-tts/.venv/bin/python -m piper.http_server -m en_US-lessac-medium --host 127.0.0.1 --data-dir /home/<your-user>/piper-tts/voices Restart=on-failure [Install] WantedBy=multi-user.target
Save it as /etc/systemd/system/piper-http.service, then run sudo systemctl daemon-reload and sudo systemctl enable --now piper-http.
Windows (PowerShell)#
Set-Location "$HOME\piper-tts" .\.venv\Scripts\Activate.ps1 $env:ORT_DISABLE_TELEMETRY = "1" python -m piper.http_server -m en_US-lessac-medium --host 127.0.0.1 --data-dir "$HOME\piper-tts\voices"
In a second PowerShell window (curl in PowerShell is a different command, so use Invoke-RestMethod):
Invoke-RestMethod http://127.0.0.1:5000/info
Invoke-RestMethod -Method Post -Uri http://127.0.0.1:5000/synthesize -ContentType 'application/json' -Body '{"text":"This is a test."}' -OutFile test2.wav
Mac (Terminal)#
Same commands as Linux:
cd ~/piper-tts source .venv/bin/activate export ORT_DISABLE_TELEMETRY=1 python3 -m piper.http_server -m en_US-lessac-medium --host 127.0.0.1 --data-dir ~/piper-tts/voices
Check it worked. /info returns JSON with the voice name, language and number of speakers (Piper docs). test2.wav plays like test.wav. Opening http://127.0.0.1:5000 shows a page where you type text and click Speak. The request fields are text (required), voice, speaker, speaker_id, length_scale (speed), noise_scale and noise_w_scale.
Tip:
ORT_DISABLE_TELEMETRY=1is explained in "Security and testing". Setting it costs nothing, and it is already in the service file above.
Step 5: Use Piper with Home Assistant (optional)#
Home Assistant talks to Piper through the Wyoming protocol, not through the HTTP server above. The maintained wrapper is OHF-Voice/wyoming-piper (version 2.5.2, MIT). If you run Home Assistant OS, you do not need Docker: install the Piper app from Settings > Apps and Home Assistant finds it. Otherwise run the wrapper's image. Our Home Assistant voice guide shows the rest of the chain.
The image is published for amd64 and arm64 only, so a 32-bit Raspberry Pi OS cannot run it. Data goes in ~/docker_volumes/piper.
Linux#
mkdir -p ~/docker_volumes/piper/data ~/docker_volumes/piper/backups
cd ~/docker_volumes/piper
cat > docker-compose.yml << 'EOF'
services:
piper:
image: rhasspy/wyoming-piper:2.5.2
container_name: wyoming-piper
restart: unless-stopped
command: --voice en_US-lessac-medium
ports:
- "10200:10200"
volumes:
- ./data:/data
EOF
docker compose up -d
docker compose ps
docker compose logs --tail=50 piper
Windows (PowerShell)#
Use Docker Desktop. The Compose file is the same as on Linux.
New-Item -ItemType Directory -Force "$HOME\docker_volumes\piper\data", "$HOME\docker_volumes\piper\backups" | Out-Null
Set-Location "$HOME\docker_volumes\piper"
Set-Content -Path docker-compose.yml -Value @'
services:
piper:
image: rhasspy/wyoming-piper:2.5.2
container_name: wyoming-piper
restart: unless-stopped
command: --voice en_US-lessac-medium
ports:
- "10200:10200"
volumes:
- ./data:/data
'@
docker compose up -d
docker compose ps
Mac (Terminal)#
Same commands as Linux, with Docker Desktop.
Check it worked. The container is running. The voice downloads on first start, so the first start takes longer. Then test that the port answers (the Wyoming port speaks TCP, not HTTP):
nc -z 127.0.0.1 10200 && echo "piper port open"
Test-NetConnection 127.0.0.1 -Port 10200
In Home Assistant, go to Settings > Devices & services, add Wyoming Protocol, enter this machine's address and port 10200. Then pick Piper as the text-to-speech engine in Settings > Voice assistants.
Tip: Wyoming has no login either. Publish port 10200 to your home network only, and never to the internet.
Voices and licences#
The Piper docs say: "Piper is intended for personal use and text to speech research only; we do not impose any additional restrictions on voice models. Some voices may have restrictive licenses, however, so please review them carefully!" The MODEL_CARD file next to each voice has the licence of the data it was trained on.
We read the model cards of all 156 voices in the voice list in November 2026: 17 list a non-commercial licence, 9 list none or "Unknown", and 33 more say only "See URL" or similar. A few examples from the cards:
| Voice | Licence on its model card | What it means |
|---|---|---|
en_US-lessac (the default almost everywhere) | The Lessac Blizzard 2013 research licence | That licence excludes commercial use, including developing voice-synthesis products |
en_US-ryan | CC BY-NC-SA 4.0 | Non-commercial, share-alike; fine-tuned from Lessac |
en_US-libritts_r | CC BY 4.0 | Give credit; fine-tuned from Lessac |
en_US-ljspeech | Public domain | The card lists no limit |
en_US-joe | CC0 | The card lists no limit |
For personal and home use this is usually fine. If you sell a product, publish audio or train another model on the output, check the card, and note that three questions about Lessac and the commercial-use position (issues #314, #333 and #340) were open with no maintainer answer when we read them. This is not legal advice. The code licence also matters: Piper itself is GPL-3.0, which brings obligations if you build it into software you distribute.
Put it behind HTTPS (with or without Traefik)#
You only need this if other computers call the HTTP server (Step 4) or you want a browser lock icon. If everything runs on one machine, keep 127.0.0.1 and skip this section. Because the server has no login, put a password at the proxy. This route is for Linux; on Windows and Mac use the Caddy route with Caddy installed natively.
With Traefik#
The HTTP server runs on the host, not in Docker, so use Traefik's file provider rather than labels. Start Piper with --host <piper-host-ip> (not 127.0.0.1, so Traefik can reach it) and block port 5000 for everyone except Traefik with your firewall. On a server with Traefik v3 and an https entrypoint, add piper.yml to the folder set in providers.file.directory. Make the user line with htpasswd -nB <user>:
http:
routers:
piper:
rule: "Host(`tts.<your-domain>`)"
entryPoints:
- https
tls: {}
middlewares:
- piper-auth
service: piper
middlewares:
piper-auth:
basicAuth:
users:
- "<user>:<hash-from-htpasswd>"
services:
piper:
loadBalancer:
servers:
- url: "http://<piper-host-ip>:5000"
Check it worked. curl -I https://tts.<your-domain>/ returns an HTTP status line over HTTPS (401 without the password).
Without Traefik: Caddy#
Caddy gets a Let's Encrypt certificate for a public domain by itself, or makes a local one with tls internal. It can run in Docker with host networking on Linux, so it reaches Piper on 127.0.0.1. We mount the folder conf, not the single Caddyfile (the Caddy Docker docs warn against single-file mounts). Our Caddy guide goes deeper.
mkdir -p ~/docker_volumes/caddy/conf ~/docker_volumes/caddy/data ~/docker_volumes/caddy/config
cd ~/docker_volumes/caddy
cat > docker-compose.yml << 'EOF'
services:
caddy:
image: caddy:2.11.8
container_name: caddy
restart: unless-stopped
network_mode: host
volumes:
- ./conf:/etc/caddy
- ./data:/data
- ./config:/config
EOF
docker run --rm -it caddy:2.11.8 caddy hash-password
The last command asks for a password (it is not echoed) and prints a hash. Paste the hash into conf/Caddyfile. For a public domain:
tts.example.com {
basic_auth {
<user> <paste-the-hash-here>
}
reverse_proxy 127.0.0.1:5000
}
For a name used at home only (tls internal makes Caddy's own local certificate):
tts.home.arpa {
tls internal
basic_auth {
<user> <paste-the-hash-here>
}
reverse_proxy 127.0.0.1:5000
}
Then start it and test:
docker compose up -d curl -I https://tts.example.com/
Windows and Mac: install Caddy natively (Caddy's install page lists Homebrew for Mac with brew install caddy and Chocolatey for Windows with choco install caddy, both community-maintained), save the same Caddyfile, and run caddy run --config Caddyfile. For a local certificate, caddy trust (run as administrator on Windows) installs Caddy's root on that machine. On other devices, copy the root file out of Caddy's data folder and trust it there; Linux Docker users can use docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt ./caddy-root.crt first.
Tip: A certificate error usually means the name in the Caddyfile differs from the DNS record you opened. Let's Encrypt needs ports 80 and 443.
Security and testing#
- No login anywhere. Piper's HTTP server and the Wyoming port have none. Use
--host 127.0.0.1, a firewall, or the proxy above. - The
/downloadendpoint lets any client that can reach the server make it fetch voices onto your disk. Another reason not to expose port 5000. - Development server. Flask's docs say its built-in server is not for production (issue #185 asks for a better one). Behind a proxy on a home network it is acceptable; never put it straight on the internet.
- Telemetry in the engine under Piper. Piper uses ONNX Runtime. The ONNX Runtime privacy page says its official builds on Windows, Linux and macOS have telemetry on by default (added in version 1.29.0), and that setting
ORT_DISABLE_TELEMETRY=1before it starts turns it off. A user of the Wyoming image saw it send traffic, and wyoming-piper 2.5.1 now sets the variable itself. Plainpip installdoes not, so set it. We did not capture any traffic ourselves. - Setting the variable for good. Linux and Mac: add
export ORT_DISABLE_TELEMETRY=1to~/.bashrcor~/.zshrc. Windows:setx ORT_DISABLE_TELEMETRY 1, then open a new window.
Functional test. One command proves the whole chain:
python3 -m piper -m en_US-lessac-medium --data-dir ~/piper-tts/voices -f check.wav -- 'Piper works.'
python -m piper -m en_US-lessac-medium --data-dir "$HOME\piper-tts\voices" -f check.wav -- 'Piper works.'
Check it worked. check.wav plays. For the container: docker compose ps shows running and the log has no error.
Common mistakes#
Each row comes from the Piper docs or source, or a real issue in the Piper tracker (state as read in November 2026). The last row is about AI assistants.
| Mistake | Why it happens | Do this instead |
|---|---|---|
Following a 2023 tutorial and the old rhasspy/piper repo | That repository was archived in October 2025 and says development moved; the current package is GPL-3.0, not MIT | Use OHF-Voice/piper1-gpl and pip install piper-tts as in this guide |
Running pip install piper-tts system-wide | Ubuntu 24.04 answers externally-managed-environment (issue #318) | Use a virtual environment (Step 1) |
| Starting the HTTP server with defaults | The source binds 0.0.0.0, has no login and offers /download | Add --host 127.0.0.1; add a password at a proxy for remote use |
| Starting Piper from the wrong folder | --data-dir defaults to the current folder, so the voice is not found: Unable to find voice | Pass --data-dir with the full path of the voices folder |
| Asking the server for a voice that is not downloaded | It does not fail; it logs "Voice not found ... Using default voice" and speaks with the default one | Download the voice first and check the log |
| Using the default voice in a product | The Lessac voice's licence excludes commercial voice-synthesis use; 17 of 156 voice cards say non-commercial (issues #314, #333, #340 are open questions) | Read each voice's MODEL_CARD before you ship |
| Believing "local" means "no network at all" | ONNX Runtime 1.29 and newer telemetry is on by default in official builds (wyoming-piper issue #64) | Set ORT_DISABLE_TELEMETRY=1 |
| Windows with Smart App Control on | It blocks the unsigned espeakbridge.pyd (issue #323, open since October 2026; the reporter later got audio working) | Check the issue for the current state, or turn the setting off if your policy allows |
An AI assistant gives you OpenAI-style calls, such as /v1/audio/speech with an input field | Piper's routes are /, /info, /voices, /all-voices, /download and /synthesize with a text field. Our assessment from the source, not a test of any assistant | Use the fields in Step 4, or use Kokoro-FastAPI if you need an OpenAI-style address |
Tip: Run
python3 -m piper --helpandpython3 -m piper.http_server --helpbefore you trust any command from a blog or a chatbot. They list every flag of the version you installed.
Tip: Listen to a voice sample before you download it. The samples page plays every voice, and a 114 MB
highvoice is a waste ifmediumsounds the same to you.
Tip: Pin the version (
piper-tts[http]==1.8.0). There were eight releases between January and September 2026, and issue #254 shows one that changed behaviour for the C library.
Troubleshooting#
| Problem | Solution |
|---|---|
error: externally-managed-environment | Make a virtual environment (Step 1) |
Unable to find voice: ... (use piper.download_voices) | Download the voice, and pass --data-dir |
Activate.ps1 is blocked on Windows | Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser (Python docs) |
| Speech is slow on a Pi | Use a low or x_low voice (Home Assistant docs) |
No sound with ffplay and a BrokenPipeError | Write a file with -f and play it with a normal player (issue #149) |
| The new voice is not in Home Assistant | Reload the Wyoming integration for Piper |
[ONNXRuntimeError] : 7 : INVALID_PROTOBUF - Protobuf parsing failed#
Issue #318 (open, October 2026): the voice file was corrupt after piper.download_voices; the reporter got working files by downloading the same voice from the Hugging Face page. Try python3 -m piper.download_voices <voice> --force-redownload, and download the two files by hand if it repeats.
Error processing file '/Users/runner/work/piper1-gpl/...phontab': No such file or directory#
Issue #272 (open, August 2026): on Apple Silicon the wheel looked for its data at the build machine's path (reported on 1.6.1). The reporter ran Piper in a Linux arm64 container (python:3.12-slim, pip install piper-tts flask, then piper.http_server). We did not confirm whether 1.8.0 is affected.
Known bugs (open on November 5, 2026)#
- #323: Windows Smart App Control can block the unsigned
espeakbridge.pyd. - #318: corrupt voice downloads and the externally-managed message.
- #272: macOS arm64 data path (reported on 1.6.1).
- #185: the HTTP server uses the Flask development server.
- #182: the package name
piperclashes with an unrelated tool of the same name if both are installed system-wide. - #116 and #102: GPU use can be slower than CPU, and memory can keep growing on a GPU.
Updates and backups#
Update. Piper has no auto-update. Read the release notes first (they list changes), then change the pinned version:
python3 -m pip install --upgrade "piper-tts[http]==<new-version>"
python -m pip install --upgrade "piper-tts[http]==<new-version>"
For the container, change the tag on the image: line, then docker compose pull && docker compose up -d.
Back up what you cannot download again: voices you trained or got elsewhere, and your Caddyfile. The Hugging Face voices can be downloaded again. On Linux and Mac:
mkdir -p ~/piper-tts/backups tar -czf ~/piper-tts/backups/piper-voices-$(date +%F).tar.gz -C ~/piper-tts voices
New-Item -ItemType Directory -Force "$HOME\piper-tts\backups" | Out-Null Compress-Archive -Path "$HOME\piper-tts\voices" -DestinationPath "$HOME\piper-tts\backups\piper-voices-$(Get-Date -Format yyyy-MM-dd).zip"
Run it at 03:00 with crontab -e on Linux and Mac (0 3 * * * tar -czf ~/piper-tts/backups/piper-voices-$(date +\%F).tar.gz -C ~/piper-tts voices), or with Windows Task Scheduler. For the container, back up ~/docker_volumes/piper/data the same way.
Restore test. Unpack into a new empty folder, never over the live one, and speak with the restored voice:
mkdir -p ~/restore-test && tar -xzf ~/piper-tts/backups/piper-voices-<date>.tar.gz -C ~/restore-test python3 -m piper -m en_US-lessac-medium --data-dir ~/restore-test/voices -f restore.wav -- 'Restore works.'
Performance and resources#
- Speed on a Pi: Home Assistant's docs say a Raspberry Pi with medium voices makes about 1.6 seconds of speech in one second. We took no timings ourselves.
- Quality ladder:
x_lowandloware 16 kHz and faster;mediumandhighare 22.05 kHz. Medium is the usual compromise. - Memory: Piper does not publish a RAM figure. Check it yourself:
docker statsfor the container, or Task Manager, Activity Monitor ortopfor the Python process. - GPU:
--cudaneeds theonnxruntime-gpupackage (CLI docs). Issue #116 reports a GPU run slower than CPU, so measure before you buy hardware for it. - Repeated use: use the HTTP server or the Python API; the command line reloads the model for each call.
- Python API: load the voice once with
PiperVoice.load(...), then callvoice.synthesize_wav(...)as often as you like (API docs).
FAQ#
Is Piper still maintained? Yes, by the Open Home Foundation, but thinly. There were releases through 2026, the newest in September, and commits in November. The README asks for new maintainers, and many issues are unanswered. Pin a version and expect slow fixes.
Why is it GPL now? The new repository is licensed GPL-3.0; the old rhasspy/piper was MIT. The docs give no reason, but the README says Piper embeds espeak-ng. If you only use Piper as a tool, the licence changes little for you. If you build it into software you distribute, read the GPL.
Does it work offline? After the voice download, speaking needs no network. Set ORT_DISABLE_TELEMETRY=1 so the engine underneath does not try to call out, and test on your own network before you rely on it.
Can I use Piper voices commercially? Piper's own docs say it is meant for personal use and research. Each voice has its own licence, and some are non-commercial. See "Voices and licences".
How is Piper different from Kokoro or Chatterbox? Piper is the small, quick one for a Pi: a 63 MB voice, a 34 MB install, no GPU needed. Kokoro-FastAPI is a bigger model behind an OpenAI-style API. Chatterbox can clone a voice but needs a stronger machine.
Sources#
- Piper (OHF-Voice/piper1-gpl) README and release v1.8.0 - read November 2026
- Piper docs: CLI, HTTP API, Python API, Voices, and the source of
http_server.pyand__main__.pyat the same tag - read November 2026 - The archived rhasspy/piper ("Development has moved") - read November 2026
- piper-tts on PyPI (1.8.0, GPL-3.0-or-later) - read November 2026
- Voices on Hugging Face and their model cards, plus the Lessac Blizzard 2013 licence - read November 2026
- wyoming-piper v2.5.2 (README, changelog, Dockerfile,
docker_run.sh), issue #64 and Docker Hub rhasspy/wyoming-piper - read November 2026 - Home Assistant: Piper app docs and local voice assistant - read November 2026
- ONNX Runtime privacy and telemetry and v1.29.0 notes - read November 2026
- Python venv, Externally Managed Environments and Flask: deploying to production - read November 2026
- Caddy: install, command line, basic_auth; Traefik basicAuth - read November 2026
- GitHub issues in OHF-Voice/piper1-gpl: #318, #272, #323, #149, #185, #182, #116, #102, #266, #254, #314, #333, #340 - read November 2026
Checked against the official docs on 2026-11-05.