Spaces:
Running on Zero
Running on Zero
Commit ·
394c2c0
1
Parent(s): 3d34bcc
Fix log upload dropped by moving _spawn_log outside @spaces.GPU scope
Browse filesZeroGPU 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>
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 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 |
-
|
| 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()
|