Add default voice for each language (#180)
Fix https://github.com/kyutai-labs/pocket-tts/issues/166
This commit is contained in:
@@ -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
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user