Tom1986 commited on
Commit
88ea7f6
·
1 Parent(s): 8b86e7b

Add PyAudio alternative installation and improve genie-tts setup process

Browse files
Files changed (1) hide show
  1. installer.py +143 -33
installer.py CHANGED
@@ -10,6 +10,88 @@ import logging
10
  logger = logging.getLogger(__name__)
11
 
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  def install_genie_tts():
14
  """尝试安装genie-tts包,处理Hugging Face Spaces的限制"""
15
  try:
@@ -24,7 +106,10 @@ def install_genie_tts():
24
  "onnxruntime>=1.16.0", # 最关键:没有它TTS完全无法工作
25
  "numpy>=1.21.0", # 基础依赖
26
  "soundfile>=0.12.0", # 音频处理
27
- "huggingface-hub>=0.17.0" # 模型下载
 
 
 
28
  ]
29
 
30
  logger.info("正在安装关键依赖...")
@@ -38,34 +123,41 @@ def install_genie_tts():
38
  logger.error(f"✗ 关键依赖安装失败: {dep} - {e}")
39
  return False, f"关键依赖 {dep} 安装失败: {str(e)}"
40
 
41
- # 尝试安装genie-tts(不包含依赖,避免PyAudio问题)
42
- logger.info("正在安装 genie-tts...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  subprocess.check_call([
44
  sys.executable, "-m", "pip", "install",
45
- "genie-tts", "--no-deps", "--upgrade"
46
  ], timeout=300)
47
 
48
- # 安装其他可选依赖
49
- optional_deps = [
50
- "scipy>=1.9.0",
51
- "rich>=12.0.0",
52
- "pyopenjtalk" # 可能因为C扩展编译失败
53
- ]
54
-
55
- logger.info("正在安装可选依赖...")
56
- for dep in optional_deps:
57
- try:
58
- subprocess.check_call([
59
- sys.executable, "-m", "pip", "install", dep
60
- ], timeout=120)
61
- logger.info(f"✓ 成功安装可选依赖: {dep}")
62
- except Exception as e:
63
- logger.warning(f"⚠ 可选依赖安装失败: {dep} - {e}")
64
-
65
  # 验证安装
66
  import genie_tts
67
  logger.info("✅ genie-tts安装成功")
68
- return True, None
69
 
70
  except subprocess.TimeoutExpired:
71
  error_msg = "安装超时:Hugging Face Spaces 环境可能不支持某些依赖"
@@ -74,14 +166,21 @@ def install_genie_tts():
74
 
75
  except Exception as e:
76
  error_msg = str(e)
77
- if "portaudio" in error_msg.lower():
78
- error_msg = ("PyAudio编译失败:Hugging Face Spaces环境缺少系统级音频依赖。"
79
- "这是已知的限制,请在本地环境运行或使用替代方案。")
80
- elif "onnxruntime" in error_msg.lower():
81
- error_msg = ("ONNX Runtime安装失败:这是Genie TTS的核心依赖,"
82
- "没有它无法运行任何TTS功能。请检查网络连接和环境配置。")
83
- logger.error(f"安装genie-tts失败: {error_msg}")
84
- return False, error_msg
 
 
 
 
 
 
 
85
 
86
 
87
  def setup_genie_import():
@@ -92,9 +191,20 @@ def setup_genie_import():
92
  try:
93
  import genie_tts as genie
94
  logger.info("Genie TTS导入成功")
95
- return genie, None
96
  except ImportError as e:
97
- logger.error(f"导入Genie TTS失败: {e}")
98
- return None, f"导入失败: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
99
  else:
100
  return None, install_error
 
10
  logger = logging.getLogger(__name__)
11
 
12
 
13
+ def install_pyaudio_alternative():
14
+ """尝试安装PyAudio的替代方案或创建mock模块"""
15
+ try:
16
+ # 首先尝试正常安装PyAudio
17
+ subprocess.check_call([
18
+ sys.executable, "-m", "pip", "install", "pyaudio"
19
+ ], timeout=120)
20
+ logger.info("✓ PyAudio 安装成功")
21
+ return True
22
+ except Exception as e:
23
+ logger.warning(f"PyAudio 安装失败: {e}")
24
+
25
+ # 如果PyAudio安装失败,创建一个mock模块
26
+ try:
27
+ import os
28
+ import site
29
+
30
+ # 获取site-packages路径
31
+ site_packages = site.getsitepackages()[0]
32
+ pyaudio_mock_path = os.path.join(site_packages, "pyaudio.py")
33
+
34
+ # 创建mock pyaudio模块
35
+ mock_pyaudio_code = '''"""
36
+ Mock PyAudio module for environments without audio support
37
+ """
38
+
39
+ class PyAudioError(Exception):
40
+ pass
41
+
42
+ class Stream:
43
+ def __init__(self, *args, **kwargs):
44
+ raise PyAudioError("音频流在此环境中不可用")
45
+
46
+ def read(self, *args, **kwargs):
47
+ raise PyAudioError("音频读取在此环境中不可用")
48
+
49
+ def write(self, *args, **kwargs):
50
+ raise PyAudioError("音频写入在此环境中不可用")
51
+
52
+ def start_stream(self):
53
+ pass
54
+
55
+ def stop_stream(self):
56
+ pass
57
+
58
+ def close(self):
59
+ pass
60
+
61
+ class PyAudio:
62
+ paInt16 = 8
63
+ paFloat32 = 1
64
+
65
+ def __init__(self):
66
+ logger.warning("使用Mock PyAudio - 音频功能不可用")
67
+
68
+ def open(self, *args, **kwargs):
69
+ return Stream()
70
+
71
+ def get_device_count(self):
72
+ return 0
73
+
74
+ def get_device_info_by_index(self, index):
75
+ return {"name": "Mock Device", "maxInputChannels": 0, "maxOutputChannels": 0}
76
+
77
+ def terminate(self):
78
+ pass
79
+
80
+ # 导出主要类和常量
81
+ __all__ = ['PyAudio', 'Stream', 'PyAudioError']
82
+ '''
83
+
84
+ with open(pyaudio_mock_path, 'w', encoding='utf-8') as f:
85
+ f.write(mock_pyaudio_code)
86
+
87
+ logger.info("✓ 创建 PyAudio mock 模块成功")
88
+ return True
89
+
90
+ except Exception as mock_error:
91
+ logger.error(f"创建 PyAudio mock 模块失败: {mock_error}")
92
+ return False
93
+
94
+
95
  def install_genie_tts():
96
  """尝试安装genie-tts包,处理Hugging Face Spaces的限制"""
97
  try:
 
106
  "onnxruntime>=1.16.0", # 最关键:没有它TTS完全无法工作
107
  "numpy>=1.21.0", # 基础依赖
108
  "soundfile>=0.12.0", # 音频处理
109
+ "huggingface-hub>=0.17.0", # 模型下载
110
+ "scipy>=1.9.0", # 科学计算
111
+ "pyyaml>=6.0", # 配置文件解析
112
+ "rich>=12.0.0" # 终端输出美化
113
  ]
114
 
115
  logger.info("正在安装关键依赖...")
 
123
  logger.error(f"✗ 关键依赖安装失败: {dep} - {e}")
124
  return False, f"关键依赖 {dep} 安装失败: {str(e)}"
125
 
126
+ # 处理PyAudio依赖
127
+ logger.info("正在处理PyAudio依赖...")
128
+ pyaudio_success = install_pyaudio_alternative()
129
+ if not pyaudio_success:
130
+ logger.warning("PyAudio处理失败,但将继续安装...")
131
+
132
+ # 尝试安装可选的日语处理依赖
133
+ try:
134
+ subprocess.check_call([
135
+ sys.executable, "-m", "pip", "install", "pyopenjtalk"
136
+ ], timeout=120)
137
+ logger.info("✓ 成功安装 pyopenjtalk")
138
+ except Exception as e:
139
+ logger.warning(f"⚠ pyopenjtalk 安装失败: {e}")
140
+
141
+ # 尝试安装可选的音频重采样依赖
142
+ try:
143
+ subprocess.check_call([
144
+ sys.executable, "-m", "pip", "install", "soxr"
145
+ ], timeout=120)
146
+ logger.info("✓ 成功安装 soxr")
147
+ except Exception as e:
148
+ logger.warning(f"⚠ soxr 安装失败: {e}")
149
+
150
+ # 最后安装genie-tts主包
151
+ logger.info("正在安装 genie-tts 主包...")
152
  subprocess.check_call([
153
  sys.executable, "-m", "pip", "install",
154
+ "genie-tts", "--upgrade"
155
  ], timeout=300)
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  # 验证安装
158
  import genie_tts
159
  logger.info("✅ genie-tts安装成功")
160
+ return True, "安装成功,但某些音频功能可能不可用(PyAudio限制)"
161
 
162
  except subprocess.TimeoutExpired:
163
  error_msg = "安装超时:Hugging Face Spaces 环境可能不支持某些依赖"
 
166
 
167
  except Exception as e:
168
  error_msg = str(e)
169
+
170
+ # 如果仍然是PyAudio相关错误,提供更详细的解决建议
171
+ if "pyaudio" in error_msg.lower():
172
+ error_msg = (
173
+ "PyAudio依赖问题:即使创建了mock模块,genie-tts仍无法正常导入。"
174
+ "建议解决方案:\n"
175
+ "1. 在本地环境运行(安装了音频驱动)\n"
176
+ "2. 使用替代的TTS库(如 pyttsx3 或 espeak)\n"
177
+ "3. 联系Hugging Face支持团队关于音频依赖问题"
178
+ )
179
+ logger.error(error_msg)
180
+ return False, error_msg
181
+ else:
182
+ logger.error(f"安装genie-tts失败: {error_msg}")
183
+ return False, error_msg
184
 
185
 
186
  def setup_genie_import():
 
191
  try:
192
  import genie_tts as genie
193
  logger.info("Genie TTS导入成功")
194
+ return genie, install_error # 返回警告信息(如果有)
195
  except ImportError as e:
196
+ error_msg = f"导入失败: {str(e)}"
197
+
198
+ # 如果导入仍然失败,提供备用方案的建议
199
+ if "pyaudio" in error_msg.lower():
200
+ error_msg += (
201
+ "\n\n建议的备用方案:\n"
202
+ "1. 使用在线TTS服务(Google TTS, Azure Speech等)\n"
203
+ "2. 在本地环境部署Genie TTS\n"
204
+ "3. 使用其他兼容Hugging Face Spaces的TTS模型"
205
+ )
206
+
207
+ logger.error(error_msg)
208
+ return None, error_msg
209
  else:
210
  return None, install_error