voidful commited on
Commit
a8231fb
·
verified ·
1 Parent(s): 355336d

Add adjustable cfg_value / inference_timesteps sliders (shared across tabs, defaults = model-card recommendation)

Browse files
Files changed (2) hide show
  1. README.md +4 -2
  2. app.py +47 -16
README.md CHANGED
@@ -40,9 +40,11 @@ CER=合成語音用 ASR 轉寫回文字後,與原文不一致的字元比例
40
 
41
  ## 參數說明
42
 
 
 
43
  | 參數 | 說明 |
44
  |---|---|
45
- | `cfg_value` | 引導強度,數值越大越貼合條件、但可能較不自然(模型卡建議 2.0) |
46
- | `inference_timesteps` | 取樣步數,越多通常品質越好、速度越慢(模型卡建議 10) |
47
 
48
  > 合成的語音僅供研究與評估展示用途,正式使用前請人工檢視。授權:Apache-2.0。
 
40
 
41
  ## 參數說明
42
 
43
+ 兩個生成參數可在頁面上方的「⚙️ 生成參數」區調整(三個分頁共用),預設為模型卡建議值:
44
+
45
  | 參數 | 說明 |
46
  |---|---|
47
+ | `cfg_value` | 引導強度,數值越大越貼合條件、但可能較不自然(預設 2.0,可調 1.0–4.0) |
48
+ | `inference_timesteps` | 取樣步數,越多通常品質越好、速度越慢(預設 10,可調 4–20) |
49
 
50
  > 合成的語音僅供研究與評估展示用途,正式使用前請人工檢視。授權:Apache-2.0。
app.py CHANGED
@@ -91,6 +91,20 @@ except Exception as e: # 任何讀取/解析問題都退回安全的建議值
91
 
92
  print(f"[BlueMagpie] checkpoint={CHECKPOINT}, generation params: {GEN_KWARGS}")
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  # 語者向量:載入多語者表(優先 speaker_centroids.pt),建成「顯示名稱 -> 向量」。
95
  # 內附的李宏毅向量已取得本人授權;其餘為通用語者向量。
96
  _DISPLAY = {"hung_yi_lee": "李宏毅", "female_voice": "女聲"}
@@ -170,25 +184,27 @@ def _split_sentences(text):
170
  # 推論:三種模式都套用 GEN_KWARGS(官方建議參數)
171
  # --------------------------------------------------------------------------- #
172
  @gpu
173
- def tts_speaker(text, speaker=DEFAULT_SPEAKER):
174
  text = (text or "").strip()
175
  if not text:
176
  raise gr.Error("請先輸入要合成的文字。")
177
  audio = model.generate(
178
  target_text=text,
179
  speaker_centroid=SPEAKERS.get(speaker, SPK_CENTROID),
180
- **GEN_KWARGS,
181
  )
182
  return (SR, _to_numpy(audio))
183
 
184
 
185
  @gpu
186
- def _clone_gpu(text, ref_path):
187
- audio = model.generate(target_text=text, reference_wav_path=ref_path, **GEN_KWARGS)
 
 
188
  return (SR, _to_numpy(audio))
189
 
190
 
191
- def tts_clone(text, recording):
192
  """聲音複製(免逐字稿):把參考音檔直接交給模型(reference_wav_path 路徑,
193
  checkpoint step_0006000 起正式支援)。一段 3 秒以上的乾淨語音即可。"""
194
  text = (text or "").strip()
@@ -199,11 +215,11 @@ def tts_clone(text, recording):
199
  dur = _audio_seconds(recording)
200
  if 0 < dur < 3:
201
  gr.Warning(f"參考音檔只有約 {dur:.0f} 秒,建議 3 秒以上會更穩定。")
202
- return _clone_gpu(text, recording)
203
 
204
 
205
  @gpu
206
- def tts_stream(text, speaker=DEFAULT_SPEAKER):
207
  """長文逐句串流(指定語者向量):把長文切成句子,逐句合成、合成一句就播一句。
208
 
209
  逐句串流直到接近單次 GPU 時間配額(約 100s)為止,盡量把整段長文串完,而非固定
@@ -219,6 +235,7 @@ def tts_stream(text, speaker=DEFAULT_SPEAKER):
219
  centroid = SPEAKERS.get(speaker, SPK_CENTROID)
220
  total = len(sentences)
221
  sentences = sentences[:_MAX_STREAM_SENTENCES]
 
222
  start = time.time()
223
  done = 0
224
  for sent in sentences:
@@ -226,7 +243,7 @@ def tts_stream(text, speaker=DEFAULT_SPEAKER):
226
  if done and time.time() - start > _GPU_BUDGET_S:
227
  break
228
  audio = model.generate(
229
- target_text=sent, speaker_centroid=centroid, **GEN_KWARGS
230
  )
231
  yield (SR, _pcm16(_to_numpy(audio)))
232
  done += 1
@@ -254,10 +271,11 @@ STREAM_EXAMPLES = [
254
  ]
255
 
256
  _PARAMS_NOTE = (
257
- f"模型 checkpoint:`{CHECKPOINT}`,已套用官方建議參數:"
258
- f"`cfg_value={GEN_KWARGS.get('cfg_value')}`、"
259
- f"`inference_timesteps={GEN_KWARGS.get('inference_timesteps')}`、"
260
- f"`retry_badcase={'on' if GEN_KWARGS.get('retry_badcase') else 'off'}`。"
 
261
  )
262
 
263
  HEADER = f"""
@@ -274,6 +292,19 @@ HEADER = f"""
274
  with gr.Blocks(title="BlueMagpie-TTS Demo", theme=gr.themes.Soft()) as demo:
275
  gr.Markdown(HEADER)
276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  with gr.Tab("指定語者"):
278
  gr.Markdown(
279
  "用模型內附的**語者向量**控制音色。**李宏毅**老師的向量已取得本人授權;"
@@ -292,7 +323,7 @@ with gr.Blocks(title="BlueMagpie-TTS Demo", theme=gr.themes.Soft()) as demo:
292
  with gr.Column():
293
  s_out = gr.Audio(label="合成結果", type="numpy")
294
  gr.Examples(EXAMPLE_TEXTS, inputs=s_text, label="範例文字")
295
- s_btn.click(tts_speaker, [s_text, s_spk], s_out)
296
 
297
  with gr.Tab("聲音複製"):
298
  gr.Markdown(
@@ -313,13 +344,13 @@ with gr.Blocks(title="BlueMagpie-TTS Demo", theme=gr.themes.Soft()) as demo:
313
  c_btn = gr.Button("複製音色合成", variant="primary")
314
  with gr.Column():
315
  c_out = gr.Audio(label="合成結果", type="numpy")
316
- c_btn.click(tts_clone, [c_text, c_rec], c_out)
317
 
318
  with gr.Tab("長文逐句串流"):
319
  gr.Markdown(
320
  "**長文逐句串流**:把長文切成句子,合成一句就播一句,做出串流(邊聽邊等)效果。"
321
  "第一句很快就能聽到,後面邊播邊合成。用**所選語者向量**。\n\n"
322
- "> ZeroGPU 約 0.44x 即時,句與句之間可能有短暫間隔;每句都套用建議參數(含自動重試)。"
323
  "單次串流以 ZeroGPU 時間配額為限(約可串數十句),超長會自動截斷並提示分批。"
324
  )
325
  with gr.Row():
@@ -335,7 +366,7 @@ with gr.Blocks(title="BlueMagpie-TTS Demo", theme=gr.themes.Soft()) as demo:
335
  with gr.Column():
336
  t_out = gr.Audio(label="逐句串流播放", streaming=True, autoplay=True)
337
  gr.Examples(STREAM_EXAMPLES, inputs=t_text, label="長文範例")
338
- t_btn.click(tts_stream, [t_text, t_spk], t_out)
339
 
340
  gr.Markdown(
341
  "---\n"
 
91
 
92
  print(f"[BlueMagpie] checkpoint={CHECKPOINT}, generation params: {GEN_KWARGS}")
93
 
94
+ # 介面上可調整的兩個生成參數;預設即官方建議值。
95
+ DEFAULT_CFG = float(GEN_KWARGS.get("cfg_value", 2.0))
96
+ DEFAULT_STEPS = int(GEN_KWARGS.get("inference_timesteps", 10))
97
+
98
+
99
+ def _gen_kwargs(cfg_value=None, inference_timesteps=None):
100
+ """以官方建議參數為底,套用使用者在介面上調整的 cfg / 取樣步數。"""
101
+ kw = dict(GEN_KWARGS)
102
+ if cfg_value is not None:
103
+ kw["cfg_value"] = float(cfg_value)
104
+ if inference_timesteps is not None:
105
+ kw["inference_timesteps"] = int(inference_timesteps)
106
+ return kw
107
+
108
  # 語者向量:載入多語者表(優先 speaker_centroids.pt),建成「顯示名稱 -> 向量」。
109
  # 內附的李宏毅向量已取得本人授權;其餘為通用語者向量。
110
  _DISPLAY = {"hung_yi_lee": "李宏毅", "female_voice": "女聲"}
 
184
  # 推論:三種模式都套用 GEN_KWARGS(官方建議參數)
185
  # --------------------------------------------------------------------------- #
186
  @gpu
187
+ def tts_speaker(text, speaker=DEFAULT_SPEAKER, cfg=DEFAULT_CFG, steps=DEFAULT_STEPS):
188
  text = (text or "").strip()
189
  if not text:
190
  raise gr.Error("請先輸入要合成的文字。")
191
  audio = model.generate(
192
  target_text=text,
193
  speaker_centroid=SPEAKERS.get(speaker, SPK_CENTROID),
194
+ **_gen_kwargs(cfg, steps),
195
  )
196
  return (SR, _to_numpy(audio))
197
 
198
 
199
  @gpu
200
+ def _clone_gpu(text, ref_path, cfg, steps):
201
+ audio = model.generate(
202
+ target_text=text, reference_wav_path=ref_path, **_gen_kwargs(cfg, steps)
203
+ )
204
  return (SR, _to_numpy(audio))
205
 
206
 
207
+ def tts_clone(text, recording, cfg=DEFAULT_CFG, steps=DEFAULT_STEPS):
208
  """聲音複製(免逐字稿):把參考音檔直接交給模型(reference_wav_path 路徑,
209
  checkpoint step_0006000 起正式支援)。一段 3 秒以上的乾淨語音即可。"""
210
  text = (text or "").strip()
 
215
  dur = _audio_seconds(recording)
216
  if 0 < dur < 3:
217
  gr.Warning(f"參考音檔只有約 {dur:.0f} 秒,建議 3 秒以上會更穩定。")
218
+ return _clone_gpu(text, recording, cfg, steps)
219
 
220
 
221
  @gpu
222
+ def tts_stream(text, speaker=DEFAULT_SPEAKER, cfg=DEFAULT_CFG, steps=DEFAULT_STEPS):
223
  """長文逐句串流(指定語者向量):把長文切成句子,逐句合成、合成一句就播一句。
224
 
225
  逐句串流直到接近單次 GPU 時間配額(約 100s)為止,盡量把整段長文串完,而非固定
 
235
  centroid = SPEAKERS.get(speaker, SPK_CENTROID)
236
  total = len(sentences)
237
  sentences = sentences[:_MAX_STREAM_SENTENCES]
238
+ gen_kw = _gen_kwargs(cfg, steps)
239
  start = time.time()
240
  done = 0
241
  for sent in sentences:
 
243
  if done and time.time() - start > _GPU_BUDGET_S:
244
  break
245
  audio = model.generate(
246
+ target_text=sent, speaker_centroid=centroid, **gen_kw
247
  )
248
  yield (SR, _pcm16(_to_numpy(audio)))
249
  done += 1
 
271
  ]
272
 
273
  _PARAMS_NOTE = (
274
+ f"模型 checkpoint:`{CHECKPOINT}`,預設套用官方建議參數:"
275
+ f"`cfg_value={DEFAULT_CFG}`、"
276
+ f"`inference_timesteps={DEFAULT_STEPS}`、"
277
+ f"`retry_badcase={'on' if GEN_KWARGS.get('retry_badcase') else 'off'}`;"
278
+ f"可展開下方「⚙️ 生成參數」自行調整。"
279
  )
280
 
281
  HEADER = f"""
 
292
  with gr.Blocks(title="BlueMagpie-TTS Demo", theme=gr.themes.Soft()) as demo:
293
  gr.Markdown(HEADER)
294
 
295
+ with gr.Accordion("⚙️ 生成參數(預設為官方建議值,三個分頁共用)", open=False):
296
+ with gr.Row():
297
+ g_cfg = gr.Slider(
298
+ 1.0, 4.0, value=DEFAULT_CFG, step=0.1,
299
+ label="cfg_value(引導強度)",
300
+ info="越大越貼合語者條件、但可能較不自然(建議 2.0)",
301
+ )
302
+ g_steps = gr.Slider(
303
+ 4, 20, value=DEFAULT_STEPS, step=1,
304
+ label="inference_timesteps(取樣步數)",
305
+ info="���多通常品質越好、速度越慢(建議 10)",
306
+ )
307
+
308
  with gr.Tab("指定語者"):
309
  gr.Markdown(
310
  "用模型內附的**語者向量**控制音色。**李宏毅**老師的向量已取得本人授權;"
 
323
  with gr.Column():
324
  s_out = gr.Audio(label="合成結果", type="numpy")
325
  gr.Examples(EXAMPLE_TEXTS, inputs=s_text, label="範例文字")
326
+ s_btn.click(tts_speaker, [s_text, s_spk, g_cfg, g_steps], s_out)
327
 
328
  with gr.Tab("聲音複製"):
329
  gr.Markdown(
 
344
  c_btn = gr.Button("複製音色合成", variant="primary")
345
  with gr.Column():
346
  c_out = gr.Audio(label="合成結果", type="numpy")
347
+ c_btn.click(tts_clone, [c_text, c_rec, g_cfg, g_steps], c_out)
348
 
349
  with gr.Tab("長文逐句串流"):
350
  gr.Markdown(
351
  "**長文逐句串流**:把長文切成句子,合成一句就播一句,做出串流(邊聽邊等)效果。"
352
  "第一句很快就能聽到,後面邊播邊合成。用**所選語者向量**。\n\n"
353
+ "> ZeroGPU 約 0.44x 即時,句與句之間可能有短暫間隔;每句都套用所選的生成參數(含自動重試)。"
354
  "單次串流以 ZeroGPU 時間配額為限(約可串數十句),超長會自動截斷並提示分批。"
355
  )
356
  with gr.Row():
 
366
  with gr.Column():
367
  t_out = gr.Audio(label="逐句串流播放", streaming=True, autoplay=True)
368
  gr.Examples(STREAM_EXAMPLES, inputs=t_text, label="長文範例")
369
+ t_btn.click(tts_stream, [t_text, t_spk, g_cfg, g_steps], t_out)
370
 
371
  gr.Markdown(
372
  "---\n"