ibcplateformes Claude Opus 4.6 commited on
Commit
8a7554b
·
1 Parent(s): a7c6af3

Add GPU worker debug logging to diagnose ZeroGPU import errors

Browse files

ZeroGPU only forwards exception class names, not messages. This adds:
- Import tests written to debug_gpu.log before conversion attempt
- Full traceback logged on error
- "Debug GPU" tab in UI to read the log file after an error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (2) hide show
  1. app.py +19 -0
  2. pipeline/inference.py +54 -5
app.py CHANGED
@@ -409,6 +409,25 @@ with gr.Blocks(
409
  outputs=[models_delete_status, models_table],
410
  )
411
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
 
413
  if __name__ == "__main__":
414
  app.launch(server_name="0.0.0.0")
 
409
  outputs=[models_delete_status, models_table],
410
  )
411
 
412
+ # Tab 4: Debug (temporary)
413
+ with gr.TabItem("Debug GPU"):
414
+ gr.Markdown("### Logs GPU Worker (pour diagnostic)")
415
+ debug_output = gr.Textbox(
416
+ label="Derniers logs GPU",
417
+ interactive=False,
418
+ lines=20,
419
+ )
420
+ debug_btn = gr.Button("Lire les logs", size="sm")
421
+
422
+ def read_debug_log():
423
+ log_path = "/home/user/app/debug_gpu.log"
424
+ if os.path.exists(log_path):
425
+ with open(log_path, "r") as f:
426
+ return f.read()
427
+ return "Aucun log disponible. Lancez d'abord une conversion."
428
+
429
+ debug_btn.click(fn=read_debug_log, outputs=[debug_output])
430
+
431
 
432
  if __name__ == "__main__":
433
  app.launch(server_name="0.0.0.0")
pipeline/inference.py CHANGED
@@ -169,6 +169,21 @@ def crossfade(chunk1, chunk2, overlap):
169
  return chunk2
170
 
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  @spaces.GPU(duration=120)
173
  def convert_voice(
174
  audio_path,
@@ -190,9 +205,40 @@ def convert_voice(
190
  app_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
191
  if app_dir not in sys.path:
192
  sys.path.insert(0, app_dir)
193
- # Also ensure current working directory is the app directory
194
  os.chdir(app_dir)
195
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  try:
197
  return _convert_voice_impl(
198
  audio_path, reference_path, pitch, index_rate, diffusion_steps
@@ -200,10 +246,13 @@ def convert_voice(
200
  except Exception as e:
201
  import traceback
202
  tb = traceback.format_exc()
203
- # Re-raise as RuntimeError with full details so ZeroGPU forwards the message
204
- raise RuntimeError("Seed-VC error: {}: {}\n{}".format(
205
- type(e).__name__, str(e), tb[-800:]
206
- ))
 
 
 
207
 
208
 
209
  def _convert_voice_impl(audio_path, reference_path, pitch, index_rate, diffusion_steps):
 
169
  return chunk2
170
 
171
 
172
+ DEBUG_LOG = "/home/user/app/debug_gpu.log"
173
+
174
+
175
+ def _test_import(name, module_path, subattr=None):
176
+ """Test a single import and return (ok, error_msg)."""
177
+ try:
178
+ import importlib
179
+ mod = importlib.import_module(module_path)
180
+ if subattr:
181
+ getattr(mod, subattr)
182
+ return True, "OK"
183
+ except Exception as ie:
184
+ return False, "{}: {}".format(type(ie).__name__, ie)
185
+
186
+
187
  @spaces.GPU(duration=120)
188
  def convert_voice(
189
  audio_path,
 
205
  app_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
206
  if app_dir not in sys.path:
207
  sys.path.insert(0, app_dir)
 
208
  os.chdir(app_dir)
209
 
210
+ # Write debug diagnostics BEFORE attempting anything
211
+ try:
212
+ with open(DEBUG_LOG, "w") as f:
213
+ f.write("=== GPU Worker Debug ===\n")
214
+ f.write("app_dir: {}\n".format(app_dir))
215
+ f.write("cwd: {}\n".format(os.getcwd()))
216
+ f.write("sys.path[:5]: {}\n".format(sys.path[:5]))
217
+ f.write("modules/ exists: {}\n".format(os.path.isdir(os.path.join(app_dir, "modules"))))
218
+ f.write("hf_utils.py exists: {}\n".format(os.path.isfile(os.path.join(app_dir, "hf_utils.py"))))
219
+ f.write("cuda available: {}\n".format(torch.cuda.is_available()))
220
+
221
+ # Test each critical import
222
+ tests = [
223
+ ("yaml", "yaml", None),
224
+ ("munch", "munch", "Munch"),
225
+ ("einops", "einops", None),
226
+ ("transformers", "transformers", "WhisperModel"),
227
+ ("modules.commons", "modules.commons", "build_model"),
228
+ ("hf_utils", "hf_utils", "load_custom_model_from_hf"),
229
+ ("modules.campplus.DTDNN", "modules.campplus.DTDNN", "CAMPPlus"),
230
+ ("modules.bigvgan.bigvgan", "modules.bigvgan.bigvgan", "BigVGAN"),
231
+ ("modules.audio", "modules.audio", "mel_spectrogram"),
232
+ ("modules.rmvpe", "modules.rmvpe", "RMVPE"),
233
+ ]
234
+ for label, mod_path, attr in tests:
235
+ ok, msg = _test_import(label, mod_path, attr)
236
+ f.write("IMPORT {}: {} -> {}\n".format("OK" if ok else "FAIL", label, msg))
237
+
238
+ f.write("=== Import tests done ===\n")
239
+ except Exception:
240
+ pass
241
+
242
  try:
243
  return _convert_voice_impl(
244
  audio_path, reference_path, pitch, index_rate, diffusion_steps
 
246
  except Exception as e:
247
  import traceback
248
  tb = traceback.format_exc()
249
+ try:
250
+ with open(DEBUG_LOG, "a") as f:
251
+ f.write("\n=== CONVERSION ERROR ===\n")
252
+ f.write(tb)
253
+ except Exception:
254
+ pass
255
+ raise
256
 
257
 
258
  def _convert_voice_impl(audio_path, reference_path, pitch, index_rate, diffusion_steps):