simler commited on
Commit
160abcd
·
verified ·
1 Parent(s): 90a3487

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +94 -102
app.py CHANGED
@@ -1,145 +1,137 @@
1
  import os
2
  import sys
3
- import glob
 
 
 
 
4
 
5
- # --- 1. 强制 CPU 模式 ---
6
- os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
7
  import torch
8
- torch.cuda.is_available = lambda : False
9
- device = "cpu"
10
-
11
- # --- 2. 暴力解决路径问题 ---
12
- # 打印当前目录结构,方便调试
13
- print(f"📂 当前工作目录: {os.getcwd()}")
14
- print(f"📂 根目录文件: {os.listdir('.')}")
15
-
16
- # 把当前目录加入 Python 搜索路径
17
- sys.path.append(os.getcwd())
18
-
19
- # 尝试找到 GPT_SoVITS 文件夹并加入路径
20
- for root, dirs, files in os.walk("."):
21
- if "GPT_SoVITS" in dirs:
22
- gpt_sovits_path = os.path.join(root, "GPT_SoVITS")
23
- sys.path.append(root) # 将父目录加入路径
24
- print(f"✅ 找到核心模块路径: {root}")
25
- break
26
-
27
- # --- 3. 导入核心类 (不依赖 inference_webui) ---
28
  try:
29
- # 直接导入底层推理类,绕过 UI 层的报错
30
- from GPT_SoVITS.TTS_infer_pack.TTS import TTS, TTS_Config
31
- from tools.i18n.i18n import I18nAuto
32
- print("✅ 成功导入核心 TTS 类!")
33
  except ImportError as e:
34
- print(f"❌ 导入失败,尝试备用路径... 错误: {e}")
35
- # 备用方案:如果上面失败,可能是路径层级问题,尝试直接 import
36
- try:
37
- from TTS_infer_pack.TTS import TTS, TTS_Config
38
- print("✅ 备用路径导入成功!")
39
- except Exception as e2:
40
- print(f"❌ 彻底失败,请查看 Files 结构。错误: {e2}")
41
 
42
- # --- 4. 自动寻找模型文件 ---
 
 
 
 
43
  def find_file(pattern, search_path="."):
44
- for root, dirs, files in os.walk(search_path):
45
- for file in files:
46
- if pattern in file:
47
- path = os.path.join(root, file)
48
- print(f"🔍 发现模型: {path}")
49
- return path
 
 
 
 
 
 
 
50
  return None
51
 
 
 
52
  gpt_path = find_file("s1v3.ckpt")
53
- sovits_path = find_file("s2Gv2ProPlus.pth")
54
-
55
- # 如果没找到 V2,找 V1
56
  if not gpt_path: gpt_path = find_file("s1bert")
57
- if not sovits_path: sovits_path = find_file("s2G")
58
 
59
- # --- 5. 初始化 TTS 管道 ---
60
- # 这是最核心的部分,手动启动推理引擎
61
- tts_config = TTS_Config("GPT_SoVITS/configs/tts_infer.yaml")
62
- tts_config.device = "cpu"
63
- tts_config.is_half = False
64
-
65
- if gpt_path and sovits_path:
66
- tts_config.t2s_weights_path = gpt_path
67
- tts_config.vits_weights_path = sovits_path
68
- else:
69
- print("⚠️ 警告:未找到模型文件,后续推理可能会失败!")
70
 
71
- # 实例化管道
72
- tts_pipeline = TTS(tts_config)
73
- print("🚀 TTS 管道初始化完成!")
74
 
75
- # --- 6. 定义推理函数 ---
76
- import soundfile as sf
77
- import numpy as np
78
-
79
- # 这里一定要改!
80
- REF_AUDIO_PATH = "ref.wav" # 请确保你上传了这个文件
81
- REF_TEXT = "你好" # 你的参考音频说了啥
 
 
 
 
 
 
 
 
82
  REF_LANG = "zh"
83
 
84
  def predict_worker(text):
85
  if not os.path.exists(REF_AUDIO_PATH):
86
- return None, "❌ 错误:请先上传 ref.wav!"
87
 
88
- print(f"📥 处理: {text}")
89
 
90
  try:
91
- # 手动调用推理管道
92
- # 参数含义: ref_audio, ref_text, ref_lang, target_text, target_lang, ...
93
- # 注意:run 方法返回的是一个 generator
94
- req = {
95
- "text": text,
96
- "text_lang": "zh",
97
- "ref_audio_path": REF_AUDIO_PATH,
98
- "prompt_text": REF_TEXT,
99
- "prompt_lang": REF_LANG,
100
- "top_k": 5,
101
- "top_p": 1,
102
- "temperature": 1,
103
- "text_split_method": "cut4", # 凑四句一切
104
- "batch_size": 1,
105
- "speed_factor": 1.0,
106
- "fragment_interval": 0.3,
107
- "seed": -1,
108
- "return_fragment": False,
109
- "parallel_infer": True,
110
- "repetition_penalty": 1.35
111
- }
112
-
113
- # 调用核心 run 函数
114
- generator = tts_pipeline.run(req)
115
 
116
- # 获取结果
117
  result_list = list(generator)
118
  if result_list:
119
  sampling_rate, audio_data = result_list[0]
120
  output_path = f"out_{os.urandom(4).hex()}.wav"
121
  sf.write(output_path, audio_data, sampling_rate)
122
- return output_path, "✅ 成功"
 
 
123
 
124
  except Exception as e:
125
  import traceback
126
  traceback.print_exc()
127
  return None, f"💥 报错: {e}"
128
 
129
- # --- 7. 界面 ---
130
- import gradio as gr
131
- with gr.Blocks() as app:
132
- gr.Markdown("# ⚡ GPT-SoVITS 纯净核心版")
133
- gr.Markdown(f"模型: `{gpt_path}` | `{sovits_path}`")
134
 
135
  with gr.Row():
136
- inp = gr.Textbox(label="文本", value="测试一下语音合成效果。")
137
- btn = gr.Button("生成")
138
 
139
  with gr.Row():
140
  out = gr.Audio(label="音频")
141
  log = gr.Textbox(label="日志")
142
-
143
  btn.click(predict_worker, [inp], [out, log], api_name="predict")
144
 
145
  if __name__ == "__main__":
 
1
  import os
2
  import sys
3
+ import logging
4
+
5
+ # --- 1. 核弹级补丁:强行阉割 CUDA (防报错核心) ---
6
+ # 这一步必须最先执行!在导入 torch 之前!
7
+ os.environ["CUDA_VISIBLE_DEVICES"] = ""
8
 
 
 
9
  import torch
10
+
11
+ # 欺骗 torch,告诉它没有显卡
12
+ torch.cuda.is_available = lambda: False
13
+ torch.cuda.device_count = lambda: 0
14
+
15
+ # 欺骗 tensor,如果代码调用了 .cuda(),我们把它变成“原地不动”
16
+ # 这样原来的代码写了 x.cuda() 也不会炸,而是继续在 CPU 上跑
17
+ def no_op(self, *args, **kwargs):
18
+ return self
19
+ torch.Tensor.cuda = no_op
20
+ torch.nn.Module.cuda = no_op
21
+
22
+ print("💉 CUDA 阉割补丁已注入,所有 GPU 操作已被重定向至 CPU。")
23
+
24
+ # --- 2. 导入原版逻辑 ---
25
+ now_dir = os.getcwd()
26
+ sys.path.append(now_dir)
27
+
 
 
28
  try:
29
+ # 直接从根目录inference_webui.py 导入函数
30
+ # 这样就能复用它原本的所有逻辑,不用我们自己写路径了
31
+ from inference_webui import change_gpt_weights, change_sovits_weights, get_tts_model
32
+ print("✅ 成功导入原版推理函数!")
33
  except ImportError as e:
34
+ print(f"❌ 导入失败: {e}")
35
+ print("请检查 Files 列表里有没有 inference_webui.py")
 
 
 
 
 
36
 
37
+ import gradio as gr
38
+ import soundfile as sf
39
+ import numpy as np
40
+
41
+ # --- 3. 自动寻找模型文件 ---
42
  def find_file(pattern, search_path="."):
43
+ # 优先找 pretrained_models 文件夹
44
+ potential_paths = [
45
+ os.path.join(search_path, "pretrained_models"),
46
+ os.path.join(search_path, "GPT_SoVITS/pretrained_models"),
47
+ search_path
48
+ ]
49
+
50
+ for path in potential_paths:
51
+ if os.path.exists(path):
52
+ for root, dirs, files in os.walk(path):
53
+ for file in files:
54
+ if pattern in file:
55
+ return os.path.join(root, file)
56
  return None
57
 
58
+ print("🔍 正在寻找模型...")
59
+ # 寻找 GPT 模型
60
  gpt_path = find_file("s1v3.ckpt")
 
 
 
61
  if not gpt_path: gpt_path = find_file("s1bert")
 
62
 
63
+ # 寻找 SoVITS 模型
64
+ sovits_path = find_file("s2Gv2ProPlus.pth")
65
+ if not sovits_path: sovits_path = find_file("s2G")
 
 
 
 
 
 
 
 
66
 
67
+ print(f"👉 GPT模型: {gpt_path}")
68
+ print(f"👉 SoVITS模型: {sovits_path}")
 
69
 
70
+ # --- 4. 加载模型 ---
71
+ try:
72
+ if gpt_path and sovits_path:
73
+ change_gpt_weights(gpt_path=gpt_path)
74
+ change_sovits_weights(sovits_path=sovits_path)
75
+ print(" 模型加载完成!")
76
+ else:
77
+ print("❌ 没找到模型文件,请检查 Logs 里的下载记录。")
78
+ except Exception as e:
79
+ print(f"⚠️ 模型加载警告 (可能是内存不够): {e}")
80
+
81
+ # --- 5. 推理函数 ---
82
+ # 你的参考音频配置
83
+ REF_AUDIO_PATH = "ref.wav"
84
+ REF_TEXT = "你好" # 建议修改为 ref.wav 实际说的话,不改也行,GPT-SoVITS 容错高
85
  REF_LANG = "zh"
86
 
87
  def predict_worker(text):
88
  if not os.path.exists(REF_AUDIO_PATH):
89
+ return None, "❌ 错误:根目录下没找到 ref.wav,请上传!"
90
 
91
+ print(f"📥 收到任务: {text[:15]}...")
92
 
93
  try:
94
+ # 调用原版的 get_tts_model
95
+ # 这里的参数完全照搬 inference_webui.py 里的定义
96
+ generator = get_tts_model(
97
+ ref_wav_path=REF_AUDIO_PATH,
98
+ prompt_text=REF_TEXT,
99
+ prompt_language=REF_LANG,
100
+ text=text,
101
+ text_language="zh",
102
+ how_to_cut="凑四句一切",
103
+ top_k=5,
104
+ top_p=1.0,
105
+ temperature=1.0,
106
+ ref_free=False
107
+ )
 
 
 
 
 
 
 
 
 
 
108
 
 
109
  result_list = list(generator)
110
  if result_list:
111
  sampling_rate, audio_data = result_list[0]
112
  output_path = f"out_{os.urandom(4).hex()}.wav"
113
  sf.write(output_path, audio_data, sampling_rate)
114
+ return output_path, "✅ 功"
115
+ else:
116
+ return None, "❌ 生成结果为空"
117
 
118
  except Exception as e:
119
  import traceback
120
  traceback.print_exc()
121
  return None, f"💥 报错: {e}"
122
 
123
+ # --- 6. 界面 ---
124
+ with gr.Blocks(title="GPT-SoVITS CPU Worker") as app:
125
+ gr.Markdown(f"### 运行模型: `{os.path.basename(gpt_path) if gpt_path else '未找到'}`")
 
 
126
 
127
  with gr.Row():
128
+ inp = gr.Textbox(label="输入文本", value="测试一下,今天天气真不错。")
129
+ btn = gr.Button("生成 (CPU渲染较慢,请耐心)")
130
 
131
  with gr.Row():
132
  out = gr.Audio(label="音频")
133
  log = gr.Textbox(label="日志")
134
+
135
  btn.click(predict_worker, [inp], [out, log], api_name="predict")
136
 
137
  if __name__ == "__main__":