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:
|