Add default voice for each language (#180)

Fix https://github.com/kyutai-labs/pocket-tts/issues/166
This commit is contained in:
Gabriel de Marmiesse
2026-05-04 15:35:22 +02:00
committed by GitHub
parent de010ea890
commit 7db278ee57
8 changed files with 94 additions and 53 deletions
+16 -1
View File
@@ -1,4 +1,3 @@
DEFAULT_AUDIO_PROMPT = "alba"
DEFAULT_LANGUAGE = "english"
DEFAULT_TEMPERATURE = 0.7
DEFAULT_LSD_DECODE_STEPS = 1
@@ -41,9 +40,25 @@ DEFAULT_TEXT_FOR_LANGUAGE = {
),
}
DEFAULT_VOICE_FOR_LANGUAGE = {
"italian": "giovanni",
"spanish": "lola",
"german": "juergen",
"portuguese": "rafael",
"french": "estelle",
}
DEFAULT_VOICE_FALLBACK = "alba"
def get_default_text_for_language(language: str | None) -> str:
for key, text in DEFAULT_TEXT_FOR_LANGUAGE.items():
if language is not None and key in language:
return text
return DEFAULT_TEXT_FOR_LANGUAGE[DEFAULT_LANGUAGE]
def get_default_voice_for_language(language: str | None) -> str:
for key, voice in DEFAULT_VOICE_FOR_LANGUAGE.items():
if language is not None and key in language:
return voice
return DEFAULT_VOICE_FALLBACK
+15 -4
View File
@@ -16,7 +16,6 @@ from typing_extensions import Annotated
from pocket_tts.data.audio import stream_audio_chunks
from pocket_tts.default_parameters import (
DEFAULT_AUDIO_PROMPT,
DEFAULT_EOS_THRESHOLD,
DEFAULT_FRAMES_AFTER_EOS,
DEFAULT_LSD_DECODE_STEPS,
@@ -24,6 +23,7 @@ from pocket_tts.default_parameters import (
DEFAULT_TEMPERATURE,
MAX_TOKEN_PER_CHUNK,
get_default_text_for_language,
get_default_voice_for_language,
)
from pocket_tts.models.tts_model import TTSModel, export_model_state
from pocket_tts.utils.logging_utils import enable_logging
@@ -136,7 +136,7 @@ def text_to_speech(
raise HTTPException(status_code=400, detail="Text cannot be empty")
if voice_url is None and voice_wav is None:
voice_url = DEFAULT_AUDIO_PROMPT
voice_url = get_default_voice_for_language(str(tts_model.origin))
if voice_url is not None and voice_wav is not None:
raise HTTPException(status_code=400, detail="Cannot provide both voice_url and voice_wav")
@@ -223,8 +223,17 @@ def serve(
def generate(
text: Annotated[str, typer.Option(help="Text to generate")] = None,
voice: Annotated[
str, typer.Option(help="Path to audio conditioning file (voice to clone)")
] = DEFAULT_AUDIO_PROMPT,
str | None,
typer.Option(
help=(
"Path to audio conditioning file (voice to clone). "
"Defaults to a built-in voice chosen from the language: "
"'giovanni' for italian, 'lola' for spanish, 'juergen' for german, "
"'rafael' for portuguese, 'estelle' for french, 'alba' otherwise."
),
show_default=False,
),
] = None,
quiet: Annotated[bool, typer.Option("-q", "--quiet", help="Disable logging output")] = False,
language: Annotated[
str | None,
@@ -293,6 +302,8 @@ def generate(
)
tts_model.to(device)
if voice is None:
voice = get_default_voice_for_language(language)
model_state_for_voice = tts_model.get_state_for_audio_prompt(voice)
# Stream audio generation directly to file or stdout
audio_chunks = tts_model.generate_audio_stream(
+1 -1
View File
@@ -295,7 +295,7 @@ class TTSModel(nn.Module):
if language is not None:
if language == "french":
raise ValueError(
"The french model is not ready yet, please use 'french_24l' instead."
"For technical reasons, only a larger 24-layer model is available for French. Please use the 'french_24l' language instead."
)
config = CONFIGS_DIR / f"{language}.yaml"
config = Path(config)
+6 -4
View File
@@ -40,13 +40,15 @@
id="voice-url-input"
class="w-full border rounded p-2"
placeholder="hf://kyutai/tts-voices/alba-mackenna/casual.wav"
value="alba"
/>
<p class="text-xs text-gray-500 mt-1">
Supports: http://, https://, or hf:// URLs.<br>
You can also use predefined voices:<br>
"alba", "anna", "azelma", "bill_boerst", "caro_davy", "charles", "eponine", "eve",
"fantine", "george", "jane", "jean", "mary", "michael", "paul", "peter_yearsley", "stuart_bell", "vera".
You can also use predefined voices (language code in parentheses):<br>
"alba" (en), "anna" (en), "azelma" (en), "bill_boerst" (en), "caro_davy" (en),
"charles" (en), "cosette" (en), "eponine" (en), "eve" (en), "fantine" (en),
"george" (en), "jane" (en), "javert" (en), "jean" (en),
"marius" (en), "mary" (en), "michael" (en), "paul" (en),
"peter_yearsley" (en), "stuart_bell" (en), "vera" (en), "giovanni" (it), "lola" (es), "juergen" (de), "rafael" (pt), "estelle" (fr).
<br/>
You can find more voices in our
<a
+6 -1
View File
@@ -34,11 +34,16 @@ _ORIGINS_OF_PREDEFINED_VOICES = {
"peter_yearsley": "hf://kyutai/tts-voices/voice-zero/peter_yearsley.wav",
"stuart_bell": "hf://kyutai/tts-voices/voice-zero/stuart_bell.wav",
"caro_davy": "hf://kyutai/tts-voices/voice-zero/caro_davy.wav",
"giovanni": "hf://kyutai/pocket-tts/common_voice_it_36520747-enhanced-v2.mp3@64ab7d24c479d736a83b8cc666c4a776fca30fda",
"lola": "hf://kyutai/pocket-tts/common_voice_es_19762977-enhanced-v2.mp3@64ab7d24c479d736a83b8cc666c4a776fca30fda",
"juergen": "hf://kyutai/pocket-tts/de-DE-juergen.mp3@64ab7d24c479d736a83b8cc666c4a776fca30fda",
"rafael": "hf://kyutai/pocket-tts/g-Vi8PgmSY0-enhanced-v2.wav@64ab7d24c479d736a83b8cc666c4a776fca30fda",
"estelle": "hf://kyutai/tts-voices/unmute-prod-website/developpeuse-3.wav@1fc7395b7e012e2bbebfca14b942a4ef62ccc899",
}
def get_predefined_voice(language: str, name: str) -> str:
return f"hf://kyutai/pocket-tts-without-voice-cloning/languages/{language}/embeddings/{name}.safetensors@d29db7978e464fb90cb3359ee0c69a273b9142cc"
return f"hf://kyutai/pocket-tts-without-voice-cloning/languages/{language}/embeddings/{name}.safetensors@e041936c75475d350b405bc870bcf7c22da4e9e6"
def make_cache_directory() -> Path: