Fix Bedtime Voice tab hanging when voice clip submitted
Browse filesThree root causes fixed:
1. Invalid VoxCPM2 kwargs caused silent English TTS crash: normalize=True,
retry_badcase=True, retry_badcase_max_times=3 are not valid params in
voxcpm==2.0.3. Removed all three; kept only reference_wav_path for
voice cloning. Also removed denoise=True (uncertain in 2.0.3).
2. Voice cloning GPU timeout: processing 20+ sentences through VoxCPM2
voice cloning far exceeds the 120s limit. Cap at 10 sentences when
ref_wav is present; increase duration to 180s.
3. Kannada GPU timeout: translating+narrating the full 6-page story
through NLLB-200+IndicF5/MMS-TTS exceeds 120s. Now pass condensed
text (title + first 3 pages) to generate_kannada_gpu and raise
its duration to 240s.
Co-Authored-By: Codex <noreply@codex.ai>
|
@@ -1127,7 +1127,7 @@ def generate_bedtime_story_gpu(hero_name: str, genre: str, mood: str) -> dict:
|
|
| 1127 |
return _normalize_story(_build_bedtime_locally(hero_name, genre))
|
| 1128 |
|
| 1129 |
|
| 1130 |
-
@spaces.GPU(duration=
|
| 1131 |
def generate_tts_cloned_gpu(text: str, ref_wav: str | None, mood: str = "calming") -> str:
|
| 1132 |
"""VoxCPM2 bedtime narration — clones user's voice if ref_wav provided,
|
| 1133 |
otherwise uses Storyteller voice preset. Returns a temp WAV file path."""
|
|
@@ -1150,16 +1150,18 @@ def generate_tts_cloned_gpu(text: str, ref_wav: str | None, mood: str = "calming
|
|
| 1150 |
if not sentences:
|
| 1151 |
sentences = [text.strip() or "Sweet dreams."]
|
| 1152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1153 |
silence = np.zeros(int(0.65 * sr), dtype=np.float32)
|
| 1154 |
pieces = []
|
| 1155 |
|
| 1156 |
for sentence in sentences:
|
| 1157 |
-
kw = dict(text=f"({style}) {sentence}", cfg_value=2.0, inference_timesteps=10
|
| 1158 |
-
if
|
| 1159 |
kw["reference_wav_path"] = ref_wav
|
| 1160 |
-
kw["denoise"] = True
|
| 1161 |
-
kw["retry_badcase"] = True
|
| 1162 |
-
kw["retry_badcase_max_times"] = 3
|
| 1163 |
wav = model.generate(**kw)
|
| 1164 |
wav = np.asarray(wav, dtype=np.float32)
|
| 1165 |
if wav.size:
|
|
@@ -1180,10 +1182,10 @@ def generate_tts_cloned_gpu(text: str, ref_wav: str | None, mood: str = "calming
|
|
| 1180 |
return path
|
| 1181 |
|
| 1182 |
|
| 1183 |
-
@spaces.GPU(duration=
|
| 1184 |
def generate_kannada_gpu(text: str, ref_wav: str, mood: str = "calming") -> str:
|
| 1185 |
-
"""Translate English story to Kannada (NLLB-200) and narrate via MMS-TTS-Kan.
|
| 1186 |
-
ref_wav is accepted for
|
| 1187 |
Returns a WAV file path."""
|
| 1188 |
if not ref_wav or not os.path.exists(str(ref_wav)):
|
| 1189 |
raise ValueError("Voice clip required to enable Kannada narration.")
|
|
@@ -1213,6 +1215,8 @@ def create_bedtime(ref_audio, hero_name, bedtime_genre, bedtime_mood):
|
|
| 1213 |
title = story.get("title", "A Bedtime Story")
|
| 1214 |
page_texts = [p.get("text", "") for p in pages]
|
| 1215 |
full_text = f"{title}. {' '.join(page_texts)}"
|
|
|
|
|
|
|
| 1216 |
story_html = build_bedtime_html(title, pages)
|
| 1217 |
|
| 1218 |
yield (story_html, f"{title} — recording English narration…", None, None)
|
|
@@ -1229,7 +1233,7 @@ def create_bedtime(ref_audio, hero_name, bedtime_genre, bedtime_mood):
|
|
| 1229 |
kn_audio_path = None
|
| 1230 |
if ref_audio:
|
| 1231 |
try:
|
| 1232 |
-
kn_audio_path = generate_kannada_gpu(
|
| 1233 |
except Exception as e:
|
| 1234 |
logger.warning(f"Kannada TTS failed: {e}")
|
| 1235 |
|
|
|
|
| 1127 |
return _normalize_story(_build_bedtime_locally(hero_name, genre))
|
| 1128 |
|
| 1129 |
|
| 1130 |
+
@spaces.GPU(duration=180)
|
| 1131 |
def generate_tts_cloned_gpu(text: str, ref_wav: str | None, mood: str = "calming") -> str:
|
| 1132 |
"""VoxCPM2 bedtime narration — clones user's voice if ref_wav provided,
|
| 1133 |
otherwise uses Storyteller voice preset. Returns a temp WAV file path."""
|
|
|
|
| 1150 |
if not sentences:
|
| 1151 |
sentences = [text.strip() or "Sweet dreams."]
|
| 1152 |
|
| 1153 |
+
has_ref = bool(ref_wav and os.path.exists(str(ref_wav)))
|
| 1154 |
+
# Voice cloning is slower per sentence — cap at 10 to stay within GPU budget
|
| 1155 |
+
if has_ref:
|
| 1156 |
+
sentences = sentences[:10]
|
| 1157 |
+
|
| 1158 |
silence = np.zeros(int(0.65 * sr), dtype=np.float32)
|
| 1159 |
pieces = []
|
| 1160 |
|
| 1161 |
for sentence in sentences:
|
| 1162 |
+
kw = dict(text=f"({style}) {sentence}", cfg_value=2.0, inference_timesteps=10)
|
| 1163 |
+
if has_ref:
|
| 1164 |
kw["reference_wav_path"] = ref_wav
|
|
|
|
|
|
|
|
|
|
| 1165 |
wav = model.generate(**kw)
|
| 1166 |
wav = np.asarray(wav, dtype=np.float32)
|
| 1167 |
if wav.size:
|
|
|
|
| 1182 |
return path
|
| 1183 |
|
| 1184 |
|
| 1185 |
+
@spaces.GPU(duration=240)
|
| 1186 |
def generate_kannada_gpu(text: str, ref_wav: str, mood: str = "calming") -> str:
|
| 1187 |
+
"""Translate English story to Kannada (NLLB-200) and narrate via IndicF5/MMS-TTS-Kan.
|
| 1188 |
+
ref_wav is accepted for voice cloning when IndicF5 is available.
|
| 1189 |
Returns a WAV file path."""
|
| 1190 |
if not ref_wav or not os.path.exists(str(ref_wav)):
|
| 1191 |
raise ValueError("Voice clip required to enable Kannada narration.")
|
|
|
|
| 1215 |
title = story.get("title", "A Bedtime Story")
|
| 1216 |
page_texts = [p.get("text", "") for p in pages]
|
| 1217 |
full_text = f"{title}. {' '.join(page_texts)}"
|
| 1218 |
+
# Condensed text for Kannada: title + first 3 pages keeps translation+TTS within GPU budget
|
| 1219 |
+
kn_source = f"{title}. {' '.join(page_texts[:3])}" if page_texts else full_text
|
| 1220 |
story_html = build_bedtime_html(title, pages)
|
| 1221 |
|
| 1222 |
yield (story_html, f"{title} — recording English narration…", None, None)
|
|
|
|
| 1233 |
kn_audio_path = None
|
| 1234 |
if ref_audio:
|
| 1235 |
try:
|
| 1236 |
+
kn_audio_path = generate_kannada_gpu(kn_source, ref_audio, mood)
|
| 1237 |
except Exception as e:
|
| 1238 |
logger.warning(f"Kannada TTS failed: {e}")
|
| 1239 |
|