How to Customize TTS Voice and Speaker Settings in the Hugging Face Speech‑to‑Speech Repository
The huggingface/speech-to-speech repository provides a modular handler pattern where every TTS engine exposes its own argument dataclass for voice, speaker, language, and voice-cloning configuration.
Each TTS backend inherits from the abstract BaseHandler class and declares its customization surface through a dedicated arguments dataclass. This design lets you control voice output via CLI flags when running the full pipeline or programmatically when building custom workflows.
TTS Handler Architecture
The repository isolates voice synthesis behind three core components:
- Argument dataclasses — Define CLI/API options per engine (e.g.,
Qwen3TTSHandlerArguments,PocketTTSHandlerArguments,KokoroTTSHandlerArguments) - Handler implementations — Consume arguments, load models, resolve speakers, and stream audio blocks
- Pipeline orchestration — Parses prefixed arguments with
HfArgumentParserand injects configured objects into handlers
All TTS handlers in src/speech_to_speech/TTS/ inherit from BaseHandler in src/speech_to_speech/baseHandler.py, which enforces a unified setup() / generate() contract.
Customizing Voice and Speaker by Engine
Qwen-3-TTS: Preset Speakers and Voice Cloning
The Qwen3TTSHandler in src/speech_to_speech/TTS/qwen3_tts_handler.py supports two modes: preset speaker selection and zero-shot voice cloning.
CLI: Select a preset speaker
python -m speech_to_speech.s2s_pipeline \
--qwen3_tts_speaker "Jordan" \
--qwen3_tts_language "en" \
--qwen3_tts_ref_audio ""
The qwen3_tts_speaker argument accepts any value from _supported_speakers(). When speaker is None or empty, the handler falls back to the first supported speaker (lines 575–588 in qwen3_tts_handler.py).
CLI: Voice cloning with reference audio
python -m speech_to_speech.s2s_pipeline \
--qwen3_tts_ref_audio /path/to/my_voice.wav \
--qwen3_tts_ref_text "Hello, I am your custom avatar." \
--qwen3_tts_speaker ""
Explicitly emptying --qwen3_tts_speaker triggers cloning mode. The handler extracts speaker characteristics from the reference file and associated transcript (lines 92–118).
Python: Direct handler instantiation with preset speaker
from speech_to_speech.TTS.qwen3_tts_handler import Qwen3TTSHandler
from threading import Event
handler = Qwen3TTSHandler()
handler.setup(
should_listen=Event(),
speaker="Aiden",
language="en",
device="cuda"
)
for chunk in handler.generate("Hello, world!"):
# chunk: NumPy array of audio samples
play(chunk)
Python: Voice cloning with pre-computed embedding
from speech_to_speech.TTS.qwen3_tts_handler import Qwen3TTSHandler
from threading import Event
handler = Qwen3TTSHandler()
handler.setup(
should_listen=Event(),
ref_audio="/data/my_voice.wav",
ref_text="I am a synthetic narrator.",
speaker=None, # triggers cloning path
device="cuda"
)
Pocket-TTS: Lightweight Voice Selection
The PocketTTSHandler in src/speech_to_speech/TTS/pocket_tts_handler.py uses a simpler pocket_tts_voice string argument.
CLI usage:
python -m speech_to_speech.s2s_pipeline \
--pocket_tts_voice "cosette"
Python programmatic configuration:
from speech_to_speech.arguments_classes.pocket_tts_arguments import PocketTTSHandlerArguments
from speech_to_speech.s2s_pipeline import parse_arguments
# Pre-configure before pipeline parsing
pocket_args = PocketTTSHandlerArguments(pocket_tts_voice="cosette")
args = parse_arguments()
args.pocket_tts_handler_kwargs = pocket_args
The argument dataclass is defined in src/speech_to_speech/arguments_classes/pocket_tts_arguments.py.
Kokoro TTS: Voice and Language Code Pairs
The KokoroTTSHandler in src/speech_to_speech/TTS/kokoro_handler.py requires both voice and lang_code parameters (defined in KokoroTTSHandlerArguments).
CLI example:
python -m speech_to_speech.s2s_pipeline \
--kokoro_tts_voice "af_bella" \
--kokoro_tts_lang_code "en-us"
Argument Parsing and Pipeline Wire-Up
The central entry point src/speech_to_speech/s2s_pipeline.py uses HfArgumentParser to collect all TTS-specific arguments. Each engine prefixes its flags to avoid collision:
| Engine | Prefix | Example Flag |
|---|---|---|
| Qwen-3-TTS | --qwen3_tts_* |
--qwen3_tts_speaker |
| Pocket-TTS | --pocket_tts_* |
--pocket_tts_voice |
| Kokoro TTS | --kokoro_tts_* |
--kokoro_tts_voice |
After parsing, the pipeline instantiates handlers and passes the configured argument objects to each setup() method.
Key Files for Voice Customization
| Path | Purpose |
|---|---|
src/speech_to_speech/arguments_classes/qwen3_tts_arguments.py |
Qwen3TTSHandlerArguments dataclass with all Qwen-3-TTS options |
src/speech_to_speech/TTS/qwen3_tts_handler.py |
Speaker resolution, voice cloning, and streaming logic |
src/speech_to_speech/arguments_classes/pocket_tts_arguments.py |
PocketTTSHandlerArguments for Pocket-TTS voice selection |
src/speech_to_speech/TTS/pocket_tts_handler.py |
Lightweight TTS handler implementation |
src/speech_to_speech/TTS/kokoro_handler.py |
Kokoro TTS with voice + lang_code pairing |
src/speech_to_speech/s2s_pipeline.py |
Central parser and handler graph construction |
src/speech_to_speech/baseHandler.py |
Abstract base class enforcing setup/generate contract |
Summary
- TTS voice customization flows through engine-specific argument dataclasses parsed by
HfArgumentParserin the pipeline entry point - Qwen-3-TTS supports preset speakers via
qwen3_tts_speakeror voice cloning viaqwen3_tts_ref_audioandqwen3_tts_ref_text - Pocket-TTS uses a single
pocket_tts_voicestring for speaker selection - Kokoro TTS requires paired
voiceandlang_codearguments - Direct handler instantiation bypasses CLI parsing and enables programmatic control of all speaker/voice parameters
Frequently Asked Questions
How do I list available preset speakers for Qwen-3-TTS?
Call _supported_speakers() on an initialized Qwen3TTSHandler instance. The method queries the backend and returns valid speaker names. If you pass an invalid speaker name to setup(), the handler will raise a validation error before generation begins.
Can I use voice cloning with Pocket-TTS or Kokoro?
No. Voice cloning is only implemented in Qwen3TTSHandler. The cloning pipeline requires reference audio processing and speaker embedding extraction that the other engines do not support. For Pocket-TTS and Kokoro, restrict yourself to the built-in voice presets.
What happens if I omit the speaker argument entirely?
Each handler has a fallback strategy. In Qwen3TTSHandler, None triggers the first supported speaker via _resolve_speakers(). Check the specific handler's setup() implementation in the source file to understand its default behavior.
How do I change voice settings at runtime without restarting the pipeline?
Instantiate handlers directly rather than through the CLI pipeline. Call handler.setup() with new parameters, or maintain multiple handler instances with different configurations. The BaseHandler contract in baseHandler.py ensures consistent re-initialization semantics across all engines.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →