Piper TTS
Piper TTS is a fast, local, and neural text-to-speech engine optimized for CPU performance, allowing speech synthesis directly on device. It is currently at version 1.4.2 and receives frequent minor updates with occasional major version changes that introduce new features and API adjustments.
Common errors
-
FileNotFoundError: [Errno 2] No such file or directory: 'path/to/model.onnx'
cause The Piper TTS model (.onnx) or its configuration file (.json) was not found at the specified path. These files are not installed with the pip package.fixDownload the desired model and config files (e.g., from huggingface.co/rhasspy/piper-voices) and ensure the `model_path` and `config_path` arguments to `PiperVoice.load()` are correct. -
AttributeError: 'PiperVoice' object has no attribute 'synthesize_raw'
cause The `synthesize_raw` method was removed in version 1.3.0 as part of an API overhaul.fixMigrate your code to use the `PiperVoice.synthesize()` method. It now takes a `piper.voices.SynthesisConfig` object (e.g., `voice.config.synthesis`) and yields audio bytes directly. -
TypeError: PiperVoice.synthesize() missing 1 required positional argument: 'config'
cause Since Piper TTS v1.3.0, the `synthesize` method requires a `piper.voices.SynthesisConfig` object as its second argument.fixPass a `SynthesisConfig` object, typically obtained from the loaded voice (`voice.config.synthesis`), as the second argument: `voice.synthesize(text, voice.config.synthesis)`.
Warnings
- breaking The Python API for `PiperVoice.synthesize` changed significantly in v1.3.0. It now requires a `SynthesisConfig` object as its second argument and directly yields raw audio bytes, rather than returning a stream or requiring `synthesize_raw`.
- breaking The project license changed from MIT to GPLv3 in v1.3.0. This has implications for how you can use and distribute software built with Piper TTS.
- gotcha Piper TTS model files (`.onnx` for the model and `.json` for its configuration) are NOT included with the pip package. You must download them separately from external sources (e.g., Hugging Face).
- gotcha For phonemization, Piper TTS relies on `espeak-ng`. While the Python package embeds `espeak-ng`'s Python bindings, the underlying `espeak-ng` C library binaries are still a system-level dependency for many phonemization tasks.
Install
-
pip install piper-tts
Imports
- PiperVoice
from piper import PiperVoice
- SynthesisConfig
from piper import SynthesisConfig
from piper.voices import SynthesisConfig
Quickstart
import piper
import os
# NOTE: Model files (.onnx and .json) are NOT included with the pip package.
# You MUST download them separately, e.g., from huggingface.co/rhasspy/piper-voices
# Example: 'en_US-lessac-medium.onnx' and 'en_US-lessac-medium.json'
# Provide paths to your downloaded model files
model_path = os.environ.get('PIPER_MODEL_PATH', 'path/to/your_downloaded_model.onnx')
config_path = os.environ.get('PIPER_CONFIG_PATH', 'path/to/your_downloaded_model.json')
if not os.path.exists(model_path) or not os.path.exists(config_path):
print(f"Error: Model files not found. Please download '.onnx' and '.json' files.")
print(f" Expected model at: {model_path}")
print(f" Expected config at: {config_path}")
print(f" Download example: https://huggingface.co/rhasspy/piper-voices/tree/main")
else:
try:
# Load the voice model
voice = piper.PiperVoice.load(model_path, config_path=config_path)
# Get default synthesis configuration
synthesis_config = voice.config.synthesis
text = "Hello, this is a test from Piper TTS."
print(f"Synthesizing: '{text}'")
audio_chunks_generator = voice.synthesize(text, synthesis_config)
num_chunks = 0
for audio_bytes in audio_chunks_generator:
num_chunks += 1
# In a real application, you would save audio_bytes to a file
# or stream it for real-time playback (e.g., using 'sounddevice').
# Example: print(f"Received chunk of {len(audio_bytes)} bytes.")
pass # Just iterate to demonstrate generation
print(f"Successfully generated {num_chunks} audio chunks.")
print("Audio can be saved to a WAV file using Python's 'wave' module or 'soundfile'.")
except Exception as e:
print(f"An unexpected error occurred: {e}")