Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -78,8 +78,7 @@ tokenizer = VoiceBpeTokenizer(vocab_file=vocab_file)
|
|
| 78 |
XTTS_MODEL.tokenizer = tokenizer
|
| 79 |
|
| 80 |
# =========================================================
|
| 81 |
-
# 4) Streaming-мі
|
| 82 |
-
# (мінімальная затрымка і «як мага бліжэй да токенаў»)
|
| 83 |
# =========================================================
|
| 84 |
MIN_BUFFER_S = 0.03 # ~30 мс — хутчэйшы старт
|
| 85 |
FADE_S = 0.004 # карацейшы cross-fade
|
|
@@ -159,13 +158,9 @@ def _native_stream(
|
|
| 159 |
speaker_embedding=speaker_embedding,
|
| 160 |
)
|
| 161 |
# перадаём параметры генерацыі, калі яны падтрымліваюцца
|
| 162 |
-
for k in ("temperature", "length_penalty", "repetition_penalty", "top_k", "top_p"):
|
| 163 |
if k in gen_kwargs and k in sig.parameters:
|
| 164 |
call_kwargs[k] = gen_kwargs[k]
|
| 165 |
-
# дробныя кавалкі гуку з боку мадэлі
|
| 166 |
-
if "stream_chunk_size_s" in sig.parameters:
|
| 167 |
-
chunk_s = float(gen_kwargs.get("min_buffer_s", MIN_BUFFER_S))
|
| 168 |
-
call_kwargs["stream_chunk_size_s"] = chunk_s
|
| 169 |
|
| 170 |
generator = model.inference_stream(**call_kwargs)
|
| 171 |
for out in generator:
|
|
@@ -232,8 +227,8 @@ class NewTTSGenerationMixin:
|
|
| 232 |
)
|
| 233 |
return _to_np_audio(out)
|
| 234 |
|
| 235 |
-
#
|
| 236 |
-
|
| 237 |
return self.sample_stream(
|
| 238 |
text=text,
|
| 239 |
language=language,
|
|
@@ -256,6 +251,10 @@ class NewTTSGenerationMixin:
|
|
| 256 |
tokens_per_step: int = TOKENS_PER_STEP,
|
| 257 |
**gen_kwargs,
|
| 258 |
) -> Iterator[np.ndarray]:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
if hasattr(self, "inference_stream"):
|
| 260 |
for chunk in _native_stream(
|
| 261 |
self,
|
|
@@ -263,8 +262,7 @@ class NewTTSGenerationMixin:
|
|
| 263 |
language,
|
| 264 |
gpt_cond_latent,
|
| 265 |
speaker_embedding,
|
| 266 |
-
|
| 267 |
-
**gen_kwargs,
|
| 268 |
):
|
| 269 |
yield chunk
|
| 270 |
return
|
|
@@ -346,7 +344,7 @@ def text_to_speech(belarusian_story, speaker_audio_file=None):
|
|
| 346 |
"""
|
| 347 |
Выхады:
|
| 348 |
1) stream_pipe (hidden Textbox) — base64(PCM float32) па кроках, у фінале "__STOP__" (EOS)
|
| 349 |
-
2) final_file (File)
|
| 350 |
"""
|
| 351 |
if not belarusian_story or str(belarusian_story).strip() == "":
|
| 352 |
raise gr.Error("Увядзі хоць нейкі тэкст 🙂")
|
|
@@ -364,7 +362,7 @@ def text_to_speech(belarusian_story, speaker_audio_file=None):
|
|
| 364 |
except Exception as e:
|
| 365 |
raise gr.Error(f"Памылка пры атрыманні латэнтаў голасу: {e}")
|
| 366 |
|
| 367 |
-
# Генератар гуку
|
| 368 |
gen = XTTS_MODEL.generate(
|
| 369 |
text=str(belarusian_story).strip(),
|
| 370 |
do_stream=True,
|
|
@@ -373,8 +371,6 @@ def text_to_speech(belarusian_story, speaker_audio_file=None):
|
|
| 373 |
speaker_embedding=speaker_embedding,
|
| 374 |
min_buffer_s=MIN_BUFFER_S,
|
| 375 |
tokens_per_step=TOKENS_PER_STEP,
|
| 376 |
-
# Калі форк падтрымлівае — прымусім дробныя кавалкі на баку мадэлі:
|
| 377 |
-
stream_chunk_size_s=MIN_BUFFER_S,
|
| 378 |
temperature=0.1,
|
| 379 |
length_penalty=1.0,
|
| 380 |
repetition_penalty=10.0,
|
|
|
|
| 78 |
XTTS_MODEL.tokenizer = tokenizer
|
| 79 |
|
| 80 |
# =========================================================
|
| 81 |
+
# 4) Streaming-канфіг (мінімальная затрымка)
|
|
|
|
| 82 |
# =========================================================
|
| 83 |
MIN_BUFFER_S = 0.03 # ~30 мс — хутчэйшы старт
|
| 84 |
FADE_S = 0.004 # карацейшы cross-fade
|
|
|
|
| 158 |
speaker_embedding=speaker_embedding,
|
| 159 |
)
|
| 160 |
# перадаём параметры генерацыі, калі яны падтрымліваюцца
|
| 161 |
+
for k in ("temperature", "length_penalty", "repetition_penalty", "top_k", "top_p", "stream_chunk_size_s"):
|
| 162 |
if k in gen_kwargs and k in sig.parameters:
|
| 163 |
call_kwargs[k] = gen_kwargs[k]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
generator = model.inference_stream(**call_kwargs)
|
| 166 |
for out in generator:
|
|
|
|
| 227 |
)
|
| 228 |
return _to_np_audio(out)
|
| 229 |
|
| 230 |
+
# ВАЖНА: НЕ дадаём min_buffer_s у gen_kwargs, каб не было дублікату.
|
| 231 |
+
# stream_chunk_size_s будзе пракінута далей у sample_stream().
|
| 232 |
return self.sample_stream(
|
| 233 |
text=text,
|
| 234 |
language=language,
|
|
|
|
| 251 |
tokens_per_step: int = TOKENS_PER_STEP,
|
| 252 |
**gen_kwargs,
|
| 253 |
) -> Iterator[np.ndarray]:
|
| 254 |
+
# Каб не дубляваць stream_chunk_size_s, ставім яго толькі калі не перададзены звонку
|
| 255 |
+
local_kwargs = dict(gen_kwargs)
|
| 256 |
+
local_kwargs.setdefault("stream_chunk_size_s", float(min_buffer_s))
|
| 257 |
+
|
| 258 |
if hasattr(self, "inference_stream"):
|
| 259 |
for chunk in _native_stream(
|
| 260 |
self,
|
|
|
|
| 262 |
language,
|
| 263 |
gpt_cond_latent,
|
| 264 |
speaker_embedding,
|
| 265 |
+
**local_kwargs,
|
|
|
|
| 266 |
):
|
| 267 |
yield chunk
|
| 268 |
return
|
|
|
|
| 344 |
"""
|
| 345 |
Выхады:
|
| 346 |
1) stream_pipe (hidden Textbox) — base64(PCM float32) па кроках, у фінале "__STOP__" (EOS)
|
| 347 |
+
2) final_file (File) — толькі ў фінале шлях да WAV (не спыняе стрим)
|
| 348 |
"""
|
| 349 |
if not belarusian_story or str(belarusian_story).strip() == "":
|
| 350 |
raise gr.Error("Увядзі хоць нейкі тэкст 🙂")
|
|
|
|
| 362 |
except Exception as e:
|
| 363 |
raise gr.Error(f"Памылка пры атрыманні латэнтаў голасу: {e}")
|
| 364 |
|
| 365 |
+
# Генератар гуку (НЕ перадаём тут stream_chunk_size_s — ён будзе пастаўлены ў sample_stream праз setdefault)
|
| 366 |
gen = XTTS_MODEL.generate(
|
| 367 |
text=str(belarusian_story).strip(),
|
| 368 |
do_stream=True,
|
|
|
|
| 371 |
speaker_embedding=speaker_embedding,
|
| 372 |
min_buffer_s=MIN_BUFFER_S,
|
| 373 |
tokens_per_step=TOKENS_PER_STEP,
|
|
|
|
|
|
|
| 374 |
temperature=0.1,
|
| 375 |
length_penalty=1.0,
|
| 376 |
repetition_penalty=10.0,
|