sheep52031 commited on
Commit
ee1e599
·
verified ·
1 Parent(s): 6edcecd

🔧 修復語音克隆功能 - 使用真正的 BreezyVoice 推論邏輯

Browse files
Files changed (2) hide show
  1. app.py +52 -38
  2. requirements.txt +4 -1
app.py CHANGED
@@ -1,6 +1,7 @@
1
  """
2
  MediaTek BreezyVoice 真實語音克隆 Space
3
  基於成功的本地測試實現真正的語音合成功能
 
4
  """
5
 
6
  import gradio as gr
@@ -14,6 +15,9 @@ import subprocess
14
  import sys
15
  from pathlib import Path
16
 
 
 
 
17
  # 全域變數
18
  cosyvoice = None
19
  bopomofo_converter = None
@@ -46,22 +50,8 @@ def setup_breezyvoice():
46
  # 2. 添加模組路徑
47
  sys.path.insert(0, repo_path)
48
 
49
- # 3. 安裝必要依賴
50
- print("📦 安裝依賴...")
51
- dependencies = [
52
- "g2pw", "WeTextProcessing", "opencc-python-reimplemented",
53
- "hydra-core", "HyperPyYAML", "conformer", "lightning",
54
- "diffusers", "einops"
55
- ]
56
-
57
- for dep in dependencies:
58
- print(f"安裝 {dep}...")
59
- result = subprocess.run(
60
- ["pip", "install", dep, "--no-cache-dir"],
61
- capture_output=True, timeout=120
62
- )
63
- if result.returncode != 0:
64
- print(f"⚠️ {dep} 安裝失敗,繼續...")
65
 
66
  # 4. 導入 BreezyVoice 模組
67
  try:
@@ -116,9 +106,9 @@ def breezy_voice_clone(speaker_audio, content_text, speaker_transcription=None):
116
  sample_rate, audio_data = speaker_audio
117
  torchaudio.save(input_audio_path, torch.tensor(audio_data).unsqueeze(0), sample_rate)
118
 
119
- # 如果沒有提供轉錄,使用預設
120
  if not speaker_transcription or not speaker_transcription.strip():
121
- speaker_transcription = "這是一段參考語音,用於語音克隆分析。"
122
 
123
  print(f"🎤 合成文字: {content_text}")
124
  print(f"📝 參考轉錄: {speaker_transcription}")
@@ -162,6 +152,7 @@ def breezy_voice_clone(speaker_audio, content_text, speaker_transcription=None):
162
 
163
  🎙️ 參考語音: {len(audio_data)/sample_rate:.1f}秒
164
  📝 合成內容: {content_text}
 
165
  ⏱️ 合成時間: {synthesis_time:.1f}秒
166
  🎵 輸出長度: {audio_duration:.1f}秒
167
  📊 RTF: {rtf:.3f} {'(實時)' if rtf < 1.0 else '(非實時)'}
@@ -178,6 +169,10 @@ def breezy_voice_clone(speaker_audio, content_text, speaker_transcription=None):
178
  except Exception as e:
179
  return None, f"❌ 處理錯誤: {str(e)}"
180
 
 
 
 
 
181
  # 創建 Gradio 界面
182
  with gr.Blocks(title="BreezyVoice 語音克隆", theme=gr.themes.Soft()) as demo:
183
  gr.Markdown("# 🎭 MediaTek BreezyVoice 語音克隆")
@@ -196,30 +191,41 @@ with gr.Blocks(title="BreezyVoice 語音克隆", theme=gr.themes.Soft()) as demo
196
  with gr.Row():
197
  with gr.Column(scale=1):
198
  gr.Markdown("### 🎙️ 步驟 1: 上傳參考語音")
199
- gr.Markdown("上傳 5-20 秒清晰的中文語音作為聲音特徵參考")
 
 
 
 
 
 
 
 
 
200
 
201
  speaker_audio = gr.Audio(
202
  sources=["microphone", "upload"],
203
  type="numpy",
204
- label="參考語音 (5-20秒)"
205
  )
206
 
207
- gr.Markdown("### 📝 步驟 2: 輸入文字內容")
208
  content_text = gr.Textbox(
209
  lines=3,
210
  placeholder="請輸入要用克隆聲音說出的內容...",
211
  label="合成文字內容",
212
- value="哈囉!這裡是光鈦廣告的小陳啦,我是林家任創造出來的AI Agent,不是詐騙集團啦。"
213
  )
214
 
215
- gr.Markdown("### 🔤 步驟 3: 參考語音轉錄 (可選)")
216
  speaker_transcription = gr.Textbox(
217
- lines=2,
218
- placeholder="如果知道參考語音的內容,請輸入轉錄文字以提高品質...",
219
- label="參考語音轉錄 (可選)",
220
- value=""
221
  )
222
 
 
 
 
223
  clone_btn = gr.Button("🎭 開始語音克隆", variant="primary", size="lg")
224
 
225
  with gr.Column(scale=1):
@@ -239,24 +245,27 @@ with gr.Blocks(title="BreezyVoice 語音克隆", theme=gr.themes.Soft()) as demo
239
 
240
  # 使用說明
241
  with gr.Accordion("📖 使用說明", open=False):
242
- gr.Markdown("""
243
- ## 🎯 操作步驟
244
- 1. **初始化**: 點擊「初始化 BreezyVoice」按鈕設置模型
245
- 2. **上傳語音**: 上傳 5-20 秒的清晰中文語音作為參考
246
- 3. **輸入文字**: 輸入要用克隆聲音說出的內容
247
- 4. **開始克隆**: 點擊「開始語音克隆」按鈕
248
 
249
- ## 💡 最佳效果建議
250
- - 🎙️ 參考語音清晰、無雜音
251
- - 📏 長度適中(5-20秒)
252
- - 🗣️ 自然朗讀,發音清楚
253
- - 📝 如果知道參考語音的轉錄內容,填寫可提高品質
254
 
255
  ## ⚡ 技術特色
256
  - 🇹🇼 台灣繁體中文專門優化
257
  - 🎯 零樣本克隆(無需訓練)
258
  - ⚡ ZeroGPU 加速處理
259
  - 🔊 MediaTek 先進語音合成技術
 
 
 
 
 
260
  """)
261
 
262
  # 事件綁定
@@ -265,6 +274,11 @@ with gr.Blocks(title="BreezyVoice 語音克隆", theme=gr.themes.Soft()) as demo
265
  outputs=[setup_status]
266
  )
267
 
 
 
 
 
 
268
  clone_btn.click(
269
  fn=breezy_voice_clone,
270
  inputs=[speaker_audio, content_text, speaker_transcription],
 
1
  """
2
  MediaTek BreezyVoice 真實語音克隆 Space
3
  基於成功的本地測試實現真正的語音合成功能
4
+ v2.0: 修復依賴問題並添加預設範例
5
  """
6
 
7
  import gradio as gr
 
15
  import sys
16
  from pathlib import Path
17
 
18
+ # 預設參考語音範例 (約20秒朗讀)
19
+ DEFAULT_REFERENCE_TEXT = "台灣是個美麗的島嶼,擁有豐富的自然景觀和多元的文化特色。從北部的陽明山到南部的墾丁,每個地方都有獨特的魅力。四季分明的氣候讓這裡的生活充滿變化,春天櫻花盛開,夏天海灘戲水,秋天楓葉飄香,冬天溫泉暖身。"
20
+
21
  # 全域變數
22
  cosyvoice = None
23
  bopomofo_converter = None
 
50
  # 2. 添加模組路徑
51
  sys.path.insert(0, repo_path)
52
 
53
+ # 3. 安裝必要依賴 (已在 requirements.txt 中)
54
+ print("📦 檢查依賴...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  # 4. 導入 BreezyVoice 模組
57
  try:
 
106
  sample_rate, audio_data = speaker_audio
107
  torchaudio.save(input_audio_path, torch.tensor(audio_data).unsqueeze(0), sample_rate)
108
 
109
+ # 使用參考轉錄或預設值
110
  if not speaker_transcription or not speaker_transcription.strip():
111
+ speaker_transcription = DEFAULT_REFERENCE_TEXT
112
 
113
  print(f"🎤 合成文字: {content_text}")
114
  print(f"📝 參考轉錄: {speaker_transcription}")
 
152
 
153
  🎙️ 參考語音: {len(audio_data)/sample_rate:.1f}秒
154
  📝 合成內容: {content_text}
155
+ 📝 使用轉錄: {speaker_transcription[:30]}...
156
  ⏱️ 合成時間: {synthesis_time:.1f}秒
157
  🎵 輸出長度: {audio_duration:.1f}秒
158
  📊 RTF: {rtf:.3f} {'(實時)' if rtf < 1.0 else '(非實時)'}
 
169
  except Exception as e:
170
  return None, f"❌ 處理錯誤: {str(e)}"
171
 
172
+ def load_example_text():
173
+ """載入預設範例文字"""
174
+ return DEFAULT_REFERENCE_TEXT
175
+
176
  # 創建 Gradio 界面
177
  with gr.Blocks(title="BreezyVoice 語音克隆", theme=gr.themes.Soft()) as demo:
178
  gr.Markdown("# 🎭 MediaTek BreezyVoice 語音克隆")
 
191
  with gr.Row():
192
  with gr.Column(scale=1):
193
  gr.Markdown("### 🎙️ 步驟 1: 上傳參考語音")
194
+ gr.Markdown("請照著下面的範例文字朗讀,上傳 5-20 秒清晰語音")
195
+
196
+ # 顯示範例文字
197
+ gr.Markdown("#### 📖 建議朗讀範例:")
198
+ example_display = gr.Textbox(
199
+ value=DEFAULT_REFERENCE_TEXT,
200
+ label="請照著這段文字朗讀 (約20秒)",
201
+ lines=4,
202
+ interactive=False
203
+ )
204
 
205
  speaker_audio = gr.Audio(
206
  sources=["microphone", "upload"],
207
  type="numpy",
208
+ label="參考語音錄音 (照著上面文字念)"
209
  )
210
 
211
+ gr.Markdown("### 📝 步驟 2: 輸入合成文字")
212
  content_text = gr.Textbox(
213
  lines=3,
214
  placeholder="請輸入要用克隆聲音說出的內容...",
215
  label="合成文字內容",
216
+ value="歡迎來到我們的語音合成系統!這個技術可以模仿任何人的聲音,讓文字轉換成自然流暢的語音。"
217
  )
218
 
219
+ gr.Markdown("### 🔤 步驟 3: 參考語音轉錄")
220
  speaker_transcription = gr.Textbox(
221
+ lines=3,
222
+ label="參考語音轉錄 (預設範例)",
223
+ value=DEFAULT_REFERENCE_TEXT
 
224
  )
225
 
226
+ # 載入範例按鈕
227
+ load_example_btn = gr.Button("📄 載入預設範例", variant="secondary")
228
+
229
  clone_btn = gr.Button("🎭 開始語音克隆", variant="primary", size="lg")
230
 
231
  with gr.Column(scale=1):
 
245
 
246
  # 使用說明
247
  with gr.Accordion("📖 使用說明", open=False):
248
+ gr.Markdown(f"""
249
+ ## 🎯 最佳使用方式
250
+ 1. **📖 朗讀範例**: 請照著範例文字清晰朗讀
251
+ 2. **🎙️ 錄音要求**: 5-20 秒,環境安靜,發音清楚
252
+ 3. **✨ 克隆效果**: 系統會用您的聲音說出任何文字
 
253
 
254
+ ## 📝 範例文字內容
255
+ ```
256
+ {DEFAULT_REFERENCE_TEXT}
257
+ ```
 
258
 
259
  ## ⚡ 技術特色
260
  - 🇹🇼 台灣繁體中文專門優化
261
  - 🎯 零樣本克隆(無需訓練)
262
  - ⚡ ZeroGPU 加速處理
263
  - 🔊 MediaTek 先進語音合成技術
264
+
265
+ ## 💡 使用提示
266
+ - 參考語音與轉錄文字匹配度越高,克隆效果越好
267
+ - 建議使用提供的預設範例文字進行錄音
268
+ - 錄音時保持自然語調,不需刻意
269
  """)
270
 
271
  # 事件綁定
 
274
  outputs=[setup_status]
275
  )
276
 
277
+ load_example_btn.click(
278
+ fn=load_example_text,
279
+ outputs=[speaker_transcription]
280
+ )
281
+
282
  clone_btn.click(
283
  fn=breezy_voice_clone,
284
  inputs=[speaker_audio, content_text, speaker_transcription],
requirements.txt CHANGED
@@ -6,6 +6,7 @@ transformers>=4.40.0
6
  soundfile>=0.12.1
7
  numpy>=1.21.0
8
  librosa>=0.10.0
 
9
  g2pw
10
  WeTextProcessing
11
  opencc-python-reimplemented
@@ -14,4 +15,6 @@ HyperPyYAML>=1.2.0
14
  conformer>=0.3.0
15
  pytorch-lightning
16
  diffusers
17
- einops
 
 
 
6
  soundfile>=0.12.1
7
  numpy>=1.21.0
8
  librosa>=0.10.0
9
+ openai-whisper
10
  g2pw
11
  WeTextProcessing
12
  opencc-python-reimplemented
 
15
  conformer>=0.3.0
16
  pytorch-lightning
17
  diffusers
18
+ einops
19
+ gdown
20
+ wget