Spaces:
Running
on
Zero
Running
on
Zero
added gpu limit error warning
Browse files
app.py
CHANGED
@@ -66,7 +66,6 @@ async def sentry_call_fn(self, *args, **kwargs):
|
|
66 |
gradio.blocks.Blocks.call_function = sentry_call_fn
|
67 |
|
68 |
|
69 |
-
|
70 |
import gradio as gr
|
71 |
import pandas as pd
|
72 |
import os
|
@@ -91,6 +90,19 @@ DISPLAY_COL_MAP = {
|
|
91 |
}
|
92 |
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
def ensure_required_cols(df, *, in_display_space):
|
95 |
"""
|
96 |
Return a copy of *df* with every required column present.
|
@@ -329,7 +341,8 @@ def run_autoforge_process(cmd, log_path):
|
|
329 |
All stdout/stderr lines are appended (line-buffered) to *log_path*.
|
330 |
Returns the CLI's exit-code.
|
331 |
"""
|
332 |
-
|
|
|
333 |
with open(log_path, "w", buffering=1, encoding="utf-8") as log_f: # line-buffered
|
334 |
proc = subprocess.Popen(
|
335 |
cmd,
|
@@ -840,35 +853,40 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
840 |
# a non-zero code tells the outer loop something went wrong
|
841 |
self.returncode = -1
|
842 |
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
|
|
|
|
|
|
|
|
|
|
872 |
|
873 |
# If the GPU scheduler threw, we already wrote the text into the log.
|
874 |
# Just read the tail once more so it reaches the UI textbox.
|
@@ -876,13 +894,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
876 |
lf.seek(file_pos)
|
877 |
log_output += lf.read()
|
878 |
|
879 |
-
# if worker.exc is not None:
|
880 |
-
# # Do NOT raise – raising would hide the explanation behind Gradio’s generic banner.
|
881 |
-
# return (
|
882 |
-
# "".join(log_output),
|
883 |
-
# None, # no preview
|
884 |
-
# gr.update(visible=False, interactive=False),
|
885 |
-
# )
|
886 |
return_code = worker.returncode
|
887 |
|
888 |
try:
|
|
|
66 |
gradio.blocks.Blocks.call_function = sentry_call_fn
|
67 |
|
68 |
|
|
|
69 |
import gradio as gr
|
70 |
import pandas as pd
|
71 |
import os
|
|
|
90 |
}
|
91 |
|
92 |
|
93 |
+
def _check_quota(required_sec: int):
|
94 |
+
"""
|
95 |
+
Check if the user has enough ZeroGPU quota remaining.
|
96 |
+
Raises RuntimeError if not enough.
|
97 |
+
"""
|
98 |
+
remaining = int(os.getenv("ZEROGPU_REMAINING", "0"))
|
99 |
+
if remaining < required_sec:
|
100 |
+
raise RuntimeError(
|
101 |
+
f"Insufficient ZeroGPU quota: need {required_sec}s but only {remaining}s left.\n"
|
102 |
+
"Please log in to Hugging Face or wait a few minutes for quota to recharge."
|
103 |
+
)
|
104 |
+
|
105 |
+
|
106 |
def ensure_required_cols(df, *, in_display_space):
|
107 |
"""
|
108 |
Return a copy of *df* with every required column present.
|
|
|
341 |
All stdout/stderr lines are appended (line-buffered) to *log_path*.
|
342 |
Returns the CLI's exit-code.
|
343 |
"""
|
344 |
+
_check_quota(90)
|
345 |
+
|
346 |
with open(log_path, "w", buffering=1, encoding="utf-8") as log_f: # line-buffered
|
347 |
proc = subprocess.Popen(
|
348 |
cmd,
|
|
|
853 |
# a non-zero code tells the outer loop something went wrong
|
854 |
self.returncode = -1
|
855 |
|
856 |
+
try:
|
857 |
+
worker = Worker(command, log_file)
|
858 |
+
worker.start()
|
859 |
+
|
860 |
+
preview_mtime = 0
|
861 |
+
last_push = 0
|
862 |
+
file_pos = 0 # how far we've read
|
863 |
+
|
864 |
+
while worker.is_alive() or file_pos < os.path.getsize(log_file):
|
865 |
+
# read any new console text
|
866 |
+
with open(log_file, "r", encoding="utf-8") as lf:
|
867 |
+
lf.seek(file_pos)
|
868 |
+
new_txt = lf.read()
|
869 |
+
file_pos = lf.tell()
|
870 |
+
log_output += new_txt
|
871 |
+
|
872 |
+
now = time.time()
|
873 |
+
if now - last_push >= 1.0: # one-second UI tick
|
874 |
+
current_preview = _maybe_new_preview()
|
875 |
+
yield (
|
876 |
+
"".join(log_output),
|
877 |
+
current_preview,
|
878 |
+
gr.update(), # placeholder for download widget
|
879 |
+
)
|
880 |
+
last_push = now
|
881 |
+
|
882 |
+
time.sleep(0.05)
|
883 |
+
|
884 |
+
worker.join() # make sure it’s done
|
885 |
+
except RuntimeError as e:
|
886 |
+
# Show toast to user
|
887 |
+
gr.Error(str(e)) # <-- this is the toast
|
888 |
+
capture_exception(e)
|
889 |
+
return create_empty_error_outputs(str(e))
|
890 |
|
891 |
# If the GPU scheduler threw, we already wrote the text into the log.
|
892 |
# Just read the tail once more so it reaches the UI textbox.
|
|
|
894 |
lf.seek(file_pos)
|
895 |
log_output += lf.read()
|
896 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
897 |
return_code = worker.returncode
|
898 |
|
899 |
try:
|