someone-in-the-world Claude Sonnet 4.6 commited on
Commit
394c2c0
·
1 Parent(s): 3d34bcc

Fix log upload dropped by moving _spawn_log outside @spaces.GPU scope

Browse files

ZeroGPU runs @spaces.GPU-decorated functions in an isolated subprocess;
when the function returns the subprocess exits, killing the daemon log
thread before the HuggingFace upload could complete. Moving _spawn_log
to infer() (main process) ensures the thread outlives the GPU subprocess.

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

Files changed (1) hide show
  1. app.py +13 -6
app.py CHANGED
@@ -339,7 +339,17 @@ def infer(images_b64_json, prompt, seed, randomize_seed, guidance_scale, steps,
339
  _validate_infer_inputs(pil_images, prompt)
340
  seed = _resolve_seed(seed, randomize_seed)
341
  width, height = update_dimensions_on_upload(pil_images[0], max_dim_for_mode(mode))
342
- return _infer_gpu(pil_images, prompt, seed, guidance_scale, steps, width, height)
 
 
 
 
 
 
 
 
 
 
343
 
344
 
345
  @spaces.GPU(duration=120)
@@ -392,8 +402,7 @@ def _infer_gpu(pil_images, prompt, seed, guidance_scale, steps, width, height):
392
  print(f"[infer] VAE decode + postprocess done — {_gpu_mem_str(_cuda_ok, sync=True)} | t={time.perf_counter()-t0:.1f}s")
393
  timer.print_timings()
394
  duration = timer.elapsed_ms("pipe_start", "pipe_end") / 1000.0
395
- _spawn_log(pil_images, result_image, prompt, seed, steps, guidance_scale, width, height, duration, True)
396
- return result_image, seed
397
  except Exception as e:
398
  print(f"[infer] ERROR: {type(e).__name__}: {e} | t={time.perf_counter()-t0:.1f}s")
399
  print(traceback.format_exc())
@@ -402,9 +411,7 @@ def _infer_gpu(pil_images, prompt, seed, guidance_scale, steps, width, height):
402
  except Exception as cuda_err:
403
  print(f"[infer] CUDA synchronize after error: {cuda_err}")
404
  timer.print_timings()
405
- duration = time.perf_counter() - timer.wall_start("pipe_start")
406
- _spawn_log(pil_images, None, prompt, seed, steps, guidance_scale, width, height, duration, False, str(e))
407
- raise e
408
  finally:
409
  gc.collect()
410
  torch.cuda.empty_cache()
 
339
  _validate_infer_inputs(pil_images, prompt)
340
  seed = _resolve_seed(seed, randomize_seed)
341
  width, height = update_dimensions_on_upload(pil_images[0], max_dim_for_mode(mode))
342
+ t0 = time.perf_counter()
343
+ try:
344
+ result_image, seed, duration = _infer_gpu(pil_images, prompt, seed, guidance_scale, steps, width, height)
345
+ # _spawn_log is called here (main process) so the thread survives after _infer_gpu's
346
+ # @spaces.GPU subprocess exits — previously the daemon thread was killed on subprocess exit.
347
+ _spawn_log(pil_images, result_image, prompt, seed, steps, guidance_scale, width, height, duration, True)
348
+ return result_image, seed
349
+ except Exception as e:
350
+ duration = time.perf_counter() - t0
351
+ _spawn_log(pil_images, None, prompt, seed, steps, guidance_scale, width, height, duration, False, str(e))
352
+ raise
353
 
354
 
355
  @spaces.GPU(duration=120)
 
402
  print(f"[infer] VAE decode + postprocess done — {_gpu_mem_str(_cuda_ok, sync=True)} | t={time.perf_counter()-t0:.1f}s")
403
  timer.print_timings()
404
  duration = timer.elapsed_ms("pipe_start", "pipe_end") / 1000.0
405
+ return result_image, seed, duration
 
406
  except Exception as e:
407
  print(f"[infer] ERROR: {type(e).__name__}: {e} | t={time.perf_counter()-t0:.1f}s")
408
  print(traceback.format_exc())
 
411
  except Exception as cuda_err:
412
  print(f"[infer] CUDA synchronize after error: {cuda_err}")
413
  timer.print_timings()
414
+ raise
 
 
415
  finally:
416
  gc.collect()
417
  torch.cuda.empty_cache()