Spaces:
Running
on
Zero
Running
on
Zero
Tanut
commited on
Commit
·
91f6a0e
1
Parent(s):
a90b002
Test ZeroGPU
Browse files- app.py +9 -46
- requirements.txt +2 -0
app.py
CHANGED
@@ -1,35 +1,16 @@
|
|
1 |
-
import gc, random
|
2 |
import gradio as gr
|
3 |
import torch, spaces
|
4 |
from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
|
5 |
|
6 |
-
# --- gradio_client bool-schema hotfix (safe no-op if not needed) ---
|
7 |
-
try:
|
8 |
-
import gradio_client.utils as _gcu
|
9 |
-
_orig_get_type = _gcu.get_type
|
10 |
-
def _get_type_safe(schema):
|
11 |
-
# Handle JSON Schema booleans (e.g., additionalProperties: True/False)
|
12 |
-
if isinstance(schema, bool):
|
13 |
-
return "any"
|
14 |
-
return _orig_get_type(schema)
|
15 |
-
_gcu.get_type = _get_type_safe
|
16 |
-
except Exception:
|
17 |
-
pass
|
18 |
-
# -------------------------------------------------------------------
|
19 |
-
|
20 |
-
# sanity: show CPU at startup (no GPU yet)
|
21 |
-
zero = torch.tensor([0.0])
|
22 |
-
print("startup device:", zero.device) # should print: cpu
|
23 |
-
|
24 |
-
# ====== SD 1.5 minimal loader (lazy) ======
|
25 |
MODEL_ID = "runwayml/stable-diffusion-v1-5"
|
26 |
DTYPE = torch.float16
|
27 |
_PIPE = None
|
28 |
|
29 |
def get_pipe():
|
30 |
-
"""Create the pipeline on first use (safe for ZeroGPU)."""
|
31 |
global _PIPE
|
32 |
if _PIPE is None:
|
|
|
33 |
pipe = StableDiffusionPipeline.from_pretrained(
|
34 |
MODEL_ID,
|
35 |
torch_dtype=DTYPE,
|
@@ -37,11 +18,9 @@ def get_pipe():
|
|
37 |
use_safetensors=True,
|
38 |
low_cpu_mem_usage=True,
|
39 |
)
|
40 |
-
# fast/stable scheduler
|
41 |
pipe.scheduler = DPMSolverMultistepScheduler.from_config(
|
42 |
pipe.scheduler.config, use_karras_sigmas=True, algorithm_type="dpmsolver++"
|
43 |
)
|
44 |
-
# memory savers
|
45 |
pipe.enable_attention_slicing()
|
46 |
pipe.enable_vae_slicing()
|
47 |
pipe.enable_model_cpu_offload()
|
@@ -52,20 +31,11 @@ def snap8(x: int) -> int:
|
|
52 |
x = max(256, min(1024, int(x)))
|
53 |
return x - (x % 8)
|
54 |
|
55 |
-
@spaces.GPU # tiny demo proving CUDA is present inside GPU block
|
56 |
-
def greet(n: float):
|
57 |
-
print("inside greet, cuda available:", torch.cuda.is_available())
|
58 |
-
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
59 |
-
t = zero.to(device) + torch.tensor([float(n)], device=device)
|
60 |
-
return f"Hello {t.item():.3f} Tensor (device: {t.device})"
|
61 |
-
|
62 |
-
# SD 1.5 text -> image
|
63 |
@spaces.GPU(duration=120)
|
64 |
def generate(prompt: str, negative: str, steps: int, cfg: float, width: int, height: int, seed: int):
|
65 |
-
pipe = get_pipe()
|
66 |
w, h = snap8(width), snap8(height)
|
67 |
|
68 |
-
# seed
|
69 |
if int(seed) < 0:
|
70 |
seed = random.randint(0, 2**31 - 1)
|
71 |
gen = torch.Generator(device="cuda").manual_seed(int(seed))
|
@@ -85,16 +55,10 @@ def generate(prompt: str, negative: str, steps: int, cfg: float, width: int, hei
|
|
85 |
)
|
86 |
return out.images[0]
|
87 |
|
88 |
-
# ====== UI ======
|
89 |
with gr.Blocks() as demo:
|
90 |
-
gr.Markdown("# ZeroGPU
|
91 |
|
92 |
-
with gr.Tab("
|
93 |
-
n = gr.Number(label="Add to zero", value=1.0)
|
94 |
-
hello = gr.Textbox(label="Result")
|
95 |
-
gr.Button("Greet").click(greet, n, hello)
|
96 |
-
|
97 |
-
with gr.Tab("SD 1.5: Text → Image"):
|
98 |
prompt = gr.Textbox(label="Prompt", value="a cozy reading nook, warm sunlight, cinematic lighting, highly detailed")
|
99 |
negative = gr.Textbox(label="Negative (optional)", value="lowres, blurry, watermark, text")
|
100 |
steps = gr.Slider(8, 40, value=28, step=1, label="Steps")
|
@@ -103,10 +67,9 @@ with gr.Blocks() as demo:
|
|
103 |
height = gr.Slider(256, 1024, value=640, step=16, label="Height")
|
104 |
seed = gr.Number(value=-1, precision=0, label="Seed (-1 random)")
|
105 |
out_img = gr.Image(label="Image", interactive=False)
|
106 |
-
gr.Button("Generate").click(
|
107 |
-
generate, [prompt, negative, steps, cfg, width, height, seed], out_img
|
108 |
-
)
|
109 |
|
110 |
if __name__ == "__main__":
|
111 |
-
# On Spaces
|
112 |
-
|
|
|
|
1 |
+
import gc, random, os
|
2 |
import gradio as gr
|
3 |
import torch, spaces
|
4 |
from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
MODEL_ID = "runwayml/stable-diffusion-v1-5"
|
7 |
DTYPE = torch.float16
|
8 |
_PIPE = None
|
9 |
|
10 |
def get_pipe():
|
|
|
11 |
global _PIPE
|
12 |
if _PIPE is None:
|
13 |
+
# Build on CPU
|
14 |
pipe = StableDiffusionPipeline.from_pretrained(
|
15 |
MODEL_ID,
|
16 |
torch_dtype=DTYPE,
|
|
|
18 |
use_safetensors=True,
|
19 |
low_cpu_mem_usage=True,
|
20 |
)
|
|
|
21 |
pipe.scheduler = DPMSolverMultistepScheduler.from_config(
|
22 |
pipe.scheduler.config, use_karras_sigmas=True, algorithm_type="dpmsolver++"
|
23 |
)
|
|
|
24 |
pipe.enable_attention_slicing()
|
25 |
pipe.enable_vae_slicing()
|
26 |
pipe.enable_model_cpu_offload()
|
|
|
31 |
x = max(256, min(1024, int(x)))
|
32 |
return x - (x % 8)
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
@spaces.GPU(duration=120)
|
35 |
def generate(prompt: str, negative: str, steps: int, cfg: float, width: int, height: int, seed: int):
|
36 |
+
pipe = get_pipe() # stays CPU/offloaded until now
|
37 |
w, h = snap8(width), snap8(height)
|
38 |
|
|
|
39 |
if int(seed) < 0:
|
40 |
seed = random.randint(0, 2**31 - 1)
|
41 |
gen = torch.Generator(device="cuda").manual_seed(int(seed))
|
|
|
55 |
)
|
56 |
return out.images[0]
|
57 |
|
|
|
58 |
with gr.Blocks() as demo:
|
59 |
+
gr.Markdown("# ZeroGPU + SD1.5 (minimal)")
|
60 |
|
61 |
+
with gr.Tab("Text → Image"):
|
|
|
|
|
|
|
|
|
|
|
62 |
prompt = gr.Textbox(label="Prompt", value="a cozy reading nook, warm sunlight, cinematic lighting, highly detailed")
|
63 |
negative = gr.Textbox(label="Negative (optional)", value="lowres, blurry, watermark, text")
|
64 |
steps = gr.Slider(8, 40, value=28, step=1, label="Steps")
|
|
|
67 |
height = gr.Slider(256, 1024, value=640, step=16, label="Height")
|
68 |
seed = gr.Number(value=-1, precision=0, label="Seed (-1 random)")
|
69 |
out_img = gr.Image(label="Image", interactive=False)
|
70 |
+
gr.Button("Generate").click(generate, [prompt, negative, steps, cfg, width, height, seed], out_img)
|
|
|
|
|
71 |
|
72 |
if __name__ == "__main__":
|
73 |
+
# On Spaces: keep it simple; don’t pass odd kwargs.
|
74 |
+
# If you see “localhost is not accessible”, add share=True.
|
75 |
+
demo.queue(max_size=12).launch(share=True)
|
requirements.txt
CHANGED
@@ -6,3 +6,5 @@ safetensors
|
|
6 |
gradio==4.44.1
|
7 |
huggingface-hub
|
8 |
spaces
|
|
|
|
|
|
6 |
gradio==4.44.1
|
7 |
huggingface-hub
|
8 |
spaces
|
9 |
+
qrcode[pil]
|
10 |
+
opencv-python
|