Spaces:
Running
on
Zero
Running
on
Zero
Layout updates
Browse files
app.css
CHANGED
@@ -15,9 +15,6 @@
|
|
15 |
width: auto;
|
16 |
margin-right: 4px;
|
17 |
}
|
18 |
-
.accordion .tabitem > div {
|
19 |
-
--block-border-width: 1px;
|
20 |
-
}
|
21 |
|
22 |
.gallery {
|
23 |
background-color: var(--bg);
|
@@ -29,7 +26,7 @@
|
|
29 |
overflow-y: auto;
|
30 |
}
|
31 |
.gallery, .gallery .grid-wrap {
|
32 |
-
height: calc(100vh -
|
33 |
max-height: none;
|
34 |
}
|
35 |
|
@@ -120,9 +117,11 @@
|
|
120 |
}
|
121 |
.tab-nav {
|
122 |
margin-bottom: 16px;
|
|
|
123 |
}
|
124 |
.tab-nav > button {
|
125 |
padding-bottom: 8px;
|
|
|
126 |
}
|
127 |
|
128 |
@keyframes spin {
|
|
|
15 |
width: auto;
|
16 |
margin-right: 4px;
|
17 |
}
|
|
|
|
|
|
|
18 |
|
19 |
.gallery {
|
20 |
background-color: var(--bg);
|
|
|
26 |
overflow-y: auto;
|
27 |
}
|
28 |
.gallery, .gallery .grid-wrap {
|
29 |
+
height: calc(100vh - 422px);
|
30 |
max-height: none;
|
31 |
}
|
32 |
|
|
|
117 |
}
|
118 |
.tab-nav {
|
119 |
margin-bottom: 16px;
|
120 |
+
flex-wrap: nowrap;
|
121 |
}
|
122 |
.tab-nav > button {
|
123 |
padding-bottom: 8px;
|
124 |
+
text-wrap: wrap;
|
125 |
}
|
126 |
|
127 |
@keyframes spin {
|
app.js
CHANGED
@@ -1,18 +1,4 @@
|
|
1 |
() =>{
|
2 |
-
const menu = document.querySelector("#menu");
|
3 |
-
const menuButton = menu.querySelector("button");
|
4 |
-
const content = document.querySelector("#content");
|
5 |
-
|
6 |
-
const updateMenu = () => {
|
7 |
-
const isOpen = menuButton.classList.contains("open");
|
8 |
-
content.style.display = isOpen ? "none" : "flex";
|
9 |
-
content.style.marginTop = isOpen ? "0" : "40px";
|
10 |
-
};
|
11 |
-
|
12 |
-
const observer = new MutationObserver(updateMenu);
|
13 |
-
observer.observe(menuButton, { attributes: true, attributeFilter: ["class"] });
|
14 |
-
updateMenu();
|
15 |
-
|
16 |
if (window.location.hostname.endsWith(".hf.space")) {
|
17 |
const hfHeader = document.getElementById("huggingface-space-header");
|
18 |
if (hfHeader) {
|
|
|
1 |
() =>{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
if (window.location.hostname.endsWith(".hf.space")) {
|
3 |
const hfHeader = document.getElementById("huggingface-space-header");
|
4 |
if (hfHeader) {
|
app.py
CHANGED
@@ -1,10 +1,23 @@
|
|
1 |
import argparse
|
2 |
import json
|
|
|
3 |
import random
|
|
|
4 |
|
5 |
import gradio as gr
|
|
|
|
|
6 |
|
7 |
-
from lib import Config, async_call, generate
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
# the CSS `content` attribute expects a string so we need to wrap the number in quotes
|
10 |
refresh_seed_js = """
|
@@ -33,34 +46,34 @@ aspect_ratio_js = """
|
|
33 |
"""
|
34 |
|
35 |
|
36 |
-
def read_file(path: str) -> str:
|
37 |
-
with open(path, "r", encoding="utf-8") as file:
|
38 |
-
return file.read()
|
39 |
-
|
40 |
-
|
41 |
def random_fn():
|
42 |
prompts = read_file("data/prompts.json")
|
43 |
prompts = json.loads(prompts)
|
44 |
return gr.Textbox(value=random.choice(prompts))
|
45 |
|
46 |
|
47 |
-
async def generate_fn(*args):
|
48 |
if len(args) > 0:
|
49 |
prompt = args[0]
|
50 |
else:
|
51 |
prompt = None
|
52 |
if prompt is None or prompt.strip() == "":
|
53 |
-
raise gr.Error("
|
|
|
54 |
try:
|
|
|
|
|
|
|
55 |
images = await async_call(
|
56 |
generate,
|
57 |
*args,
|
58 |
-
Info=gr.Info,
|
59 |
Error=gr.Error,
|
60 |
-
|
|
|
61 |
)
|
62 |
except RuntimeError:
|
63 |
-
raise gr.Error("
|
|
|
64 |
return images
|
65 |
|
66 |
|
@@ -90,191 +103,179 @@ with gr.Blocks(
|
|
90 |
) as demo:
|
91 |
gr.HTML(read_file("./partials/intro.html"))
|
92 |
|
93 |
-
with gr.
|
94 |
-
|
95 |
-
|
96 |
-
label="Menu",
|
97 |
-
open=False,
|
98 |
-
):
|
99 |
-
with gr.Tabs():
|
100 |
-
with gr.TabItem("⚙️ Settings"):
|
101 |
with gr.Group():
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
)
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
with gr.Group():
|
234 |
-
output_images = gr.Gallery(
|
235 |
-
elem_classes=["gallery"],
|
236 |
-
show_share_button=False,
|
237 |
-
object_fit="cover",
|
238 |
-
interactive=False,
|
239 |
-
show_label=False,
|
240 |
-
label="Output",
|
241 |
-
format="png",
|
242 |
-
columns=2,
|
243 |
-
)
|
244 |
-
prompt = gr.Textbox(
|
245 |
-
placeholder="corgi, beach, 8k",
|
246 |
-
autoscroll=False,
|
247 |
-
show_label=False,
|
248 |
-
label="Prompt",
|
249 |
-
max_lines=3,
|
250 |
-
lines=3,
|
251 |
-
)
|
252 |
-
|
253 |
-
# Buttons
|
254 |
-
with gr.Row():
|
255 |
-
generate_btn = gr.Button("Generate", variant="primary")
|
256 |
-
random_btn = gr.Button(
|
257 |
-
elem_classes=["icon-button", "popover"],
|
258 |
-
variant="secondary",
|
259 |
-
elem_id="random",
|
260 |
-
min_width=0,
|
261 |
-
value="🎲",
|
262 |
-
)
|
263 |
-
refresh_btn = gr.Button(
|
264 |
-
elem_classes=["icon-button", "popover"],
|
265 |
-
variant="secondary",
|
266 |
-
elem_id="refresh",
|
267 |
-
min_width=0,
|
268 |
-
value="🔄",
|
269 |
-
)
|
270 |
-
clear_btn = gr.ClearButton(
|
271 |
-
elem_classes=["icon-button", "popover"],
|
272 |
-
components=[output_images],
|
273 |
-
variant="secondary",
|
274 |
-
elem_id="clear",
|
275 |
-
min_width=0,
|
276 |
-
value="🗑️",
|
277 |
-
)
|
278 |
|
279 |
random_btn.click(random_fn, inputs=[], outputs=[prompt], show_api=False)
|
280 |
|
@@ -310,7 +311,6 @@ with gr.Blocks(
|
|
310 |
triggers=[generate_btn.click, prompt.submit],
|
311 |
fn=generate_fn,
|
312 |
api_name="generate",
|
313 |
-
concurrency_limit=2,
|
314 |
outputs=[output_images],
|
315 |
inputs=[
|
316 |
prompt,
|
@@ -337,8 +337,12 @@ if __name__ == "__main__":
|
|
337 |
parser.add_argument("-p", "--port", type=int, metavar="INT", default=7860)
|
338 |
args = parser.parse_args()
|
339 |
|
|
|
|
|
|
|
|
|
340 |
# https://www.gradio.app/docs/gradio/interface#interface-queue
|
341 |
-
demo.queue().launch(
|
342 |
server_name=args.server,
|
343 |
server_port=args.port,
|
344 |
)
|
|
|
1 |
import argparse
|
2 |
import json
|
3 |
+
import os
|
4 |
import random
|
5 |
+
from warnings import filterwarnings
|
6 |
|
7 |
import gradio as gr
|
8 |
+
from diffusers.utils import logging as diffusers_logging
|
9 |
+
from transformers import logging as transformers_logging
|
10 |
|
11 |
+
from lib import Config, async_call, download_repo_files, generate, read_file
|
12 |
+
|
13 |
+
filterwarnings("ignore", category=FutureWarning, module="diffusers")
|
14 |
+
filterwarnings("ignore", category=FutureWarning, module="transformers")
|
15 |
+
|
16 |
+
diffusers_logging.set_verbosity_error()
|
17 |
+
transformers_logging.set_verbosity_error()
|
18 |
+
|
19 |
+
diffusers_logging.disable_progress_bar()
|
20 |
+
transformers_logging.disable_progress_bar()
|
21 |
|
22 |
# the CSS `content` attribute expects a string so we need to wrap the number in quotes
|
23 |
refresh_seed_js = """
|
|
|
46 |
"""
|
47 |
|
48 |
|
|
|
|
|
|
|
|
|
|
|
49 |
def random_fn():
|
50 |
prompts = read_file("data/prompts.json")
|
51 |
prompts = json.loads(prompts)
|
52 |
return gr.Textbox(value=random.choice(prompts))
|
53 |
|
54 |
|
55 |
+
async def generate_fn(*args, progress=gr.Progress(track_tqdm=True)):
|
56 |
if len(args) > 0:
|
57 |
prompt = args[0]
|
58 |
else:
|
59 |
prompt = None
|
60 |
if prompt is None or prompt.strip() == "":
|
61 |
+
raise gr.Error("You must enter a prompt")
|
62 |
+
|
63 |
try:
|
64 |
+
if Config.ZERO_GPU:
|
65 |
+
progress((0, 100), desc="ZeroGPU init")
|
66 |
+
|
67 |
images = await async_call(
|
68 |
generate,
|
69 |
*args,
|
|
|
70 |
Error=gr.Error,
|
71 |
+
Info=gr.Info,
|
72 |
+
progress=progress,
|
73 |
)
|
74 |
except RuntimeError:
|
75 |
+
raise gr.Error("Please try again later")
|
76 |
+
|
77 |
return images
|
78 |
|
79 |
|
|
|
103 |
) as demo:
|
104 |
gr.HTML(read_file("./partials/intro.html"))
|
105 |
|
106 |
+
with gr.Tabs():
|
107 |
+
with gr.TabItem("🏠 Home"):
|
108 |
+
with gr.Column():
|
|
|
|
|
|
|
|
|
|
|
109 |
with gr.Group():
|
110 |
+
output_images = gr.Gallery(
|
111 |
+
elem_classes=["gallery"],
|
112 |
+
show_share_button=False,
|
113 |
+
object_fit="cover",
|
114 |
+
interactive=False,
|
115 |
+
show_label=False,
|
116 |
+
label="Output",
|
117 |
+
format="png",
|
118 |
+
columns=2,
|
119 |
+
)
|
120 |
+
prompt = gr.Textbox(
|
121 |
+
placeholder="What do you want to see?",
|
122 |
+
autoscroll=False,
|
123 |
+
show_label=False,
|
124 |
+
label="Prompt",
|
125 |
+
max_lines=3,
|
126 |
+
lines=3,
|
127 |
+
)
|
128 |
+
|
129 |
+
# Buttons
|
130 |
+
with gr.Row():
|
131 |
+
generate_btn = gr.Button("Generate", variant="primary")
|
132 |
+
random_btn = gr.Button(
|
133 |
+
elem_classes=["icon-button", "popover"],
|
134 |
+
variant="secondary",
|
135 |
+
elem_id="random",
|
136 |
+
min_width=0,
|
137 |
+
value="🎲",
|
138 |
+
)
|
139 |
+
refresh_btn = gr.Button(
|
140 |
+
elem_classes=["icon-button", "popover"],
|
141 |
+
variant="secondary",
|
142 |
+
elem_id="refresh",
|
143 |
+
min_width=0,
|
144 |
+
value="🔄",
|
145 |
+
)
|
146 |
+
clear_btn = gr.ClearButton(
|
147 |
+
elem_classes=["icon-button", "popover"],
|
148 |
+
components=[output_images],
|
149 |
+
variant="secondary",
|
150 |
+
elem_id="clear",
|
151 |
+
min_width=0,
|
152 |
+
value="🗑️",
|
153 |
)
|
154 |
|
155 |
+
with gr.TabItem("⚙️ Menu"):
|
156 |
+
with gr.Group():
|
157 |
+
negative_prompt = gr.Textbox(
|
158 |
+
value="nsfw+",
|
159 |
+
label="Negative Prompt",
|
160 |
+
lines=2,
|
161 |
+
)
|
162 |
+
|
163 |
+
with gr.Row():
|
164 |
+
model = gr.Dropdown(
|
165 |
+
choices=Config.MODELS,
|
166 |
+
filterable=False,
|
167 |
+
value=Config.MODEL,
|
168 |
+
label="Model",
|
169 |
+
min_width=240,
|
170 |
+
)
|
171 |
+
scheduler = gr.Dropdown(
|
172 |
+
choices=Config.SCHEDULERS.keys(),
|
173 |
+
value=Config.SCHEDULER,
|
174 |
+
elem_id="scheduler",
|
175 |
+
label="Scheduler",
|
176 |
+
filterable=False,
|
177 |
+
)
|
178 |
+
|
179 |
+
with gr.Row():
|
180 |
+
styles = json.loads(read_file("data/styles.json"))
|
181 |
+
style_ids = list(styles.keys())
|
182 |
+
style_ids = [sid for sid in style_ids if not sid.startswith("_")]
|
183 |
+
style = gr.Dropdown(
|
184 |
+
value=Config.STYLE,
|
185 |
+
label="Style",
|
186 |
+
min_width=240,
|
187 |
+
choices=[("None", None)] + [(styles[sid]["name"], sid) for sid in style_ids],
|
188 |
+
)
|
189 |
+
|
190 |
+
with gr.Row():
|
191 |
+
guidance_scale = gr.Slider(
|
192 |
+
value=Config.GUIDANCE_SCALE,
|
193 |
+
label="Guidance Scale",
|
194 |
+
minimum=1.0,
|
195 |
+
maximum=15.0,
|
196 |
+
step=0.1,
|
197 |
+
)
|
198 |
+
inference_steps = gr.Slider(
|
199 |
+
value=Config.INFERENCE_STEPS,
|
200 |
+
label="Inference Steps",
|
201 |
+
minimum=1,
|
202 |
+
maximum=50,
|
203 |
+
step=1,
|
204 |
+
)
|
205 |
+
deepcache_interval = gr.Slider(
|
206 |
+
value=Config.DEEPCACHE_INTERVAL,
|
207 |
+
label="DeepCache",
|
208 |
+
minimum=1,
|
209 |
+
maximum=4,
|
210 |
+
step=1,
|
211 |
+
)
|
212 |
+
|
213 |
+
with gr.Row():
|
214 |
+
width = gr.Slider(
|
215 |
+
value=Config.WIDTH,
|
216 |
+
label="Width",
|
217 |
+
minimum=512,
|
218 |
+
maximum=1536,
|
219 |
+
step=64,
|
220 |
+
)
|
221 |
+
height = gr.Slider(
|
222 |
+
value=Config.HEIGHT,
|
223 |
+
label="Height",
|
224 |
+
minimum=512,
|
225 |
+
maximum=1536,
|
226 |
+
step=64,
|
227 |
+
)
|
228 |
+
aspect_ratio = gr.Dropdown(
|
229 |
+
value=f"{Config.WIDTH},{Config.HEIGHT}",
|
230 |
+
label="Aspect Ratio",
|
231 |
+
filterable=False,
|
232 |
+
choices=[
|
233 |
+
("Custom", None),
|
234 |
+
("4:7 (768x1344)", "768,1344"),
|
235 |
+
("7:9 (896x1152)", "896,1152"),
|
236 |
+
("1:1 (1024x1024)", "1024,1024"),
|
237 |
+
("9:7 (1152x896)", "1152,896"),
|
238 |
+
("7:4 (1344x768)", "1344,768"),
|
239 |
+
],
|
240 |
+
)
|
241 |
+
|
242 |
+
with gr.Row():
|
243 |
+
file_format = gr.Dropdown(
|
244 |
+
choices=["png", "jpeg", "webp"],
|
245 |
+
label="File Format",
|
246 |
+
filterable=False,
|
247 |
+
value="png",
|
248 |
+
)
|
249 |
+
num_images = gr.Dropdown(
|
250 |
+
choices=list(range(1, 5)),
|
251 |
+
value=Config.NUM_IMAGES,
|
252 |
+
filterable=False,
|
253 |
+
label="Images",
|
254 |
+
)
|
255 |
+
scale = gr.Dropdown(
|
256 |
+
choices=[(f"{s}x", s) for s in Config.SCALES],
|
257 |
+
filterable=False,
|
258 |
+
value=Config.SCALE,
|
259 |
+
label="Scale",
|
260 |
+
)
|
261 |
+
seed = gr.Number(
|
262 |
+
value=Config.SEED,
|
263 |
+
label="Seed",
|
264 |
+
minimum=-1,
|
265 |
+
maximum=(2**64) - 1,
|
266 |
+
)
|
267 |
+
|
268 |
+
with gr.Row():
|
269 |
+
use_karras = gr.Checkbox(
|
270 |
+
elem_classes=["checkbox"],
|
271 |
+
label="Karras σ",
|
272 |
+
value=True,
|
273 |
+
)
|
274 |
+
use_refiner = gr.Checkbox(
|
275 |
+
elem_classes=["checkbox"],
|
276 |
+
label="Refiner",
|
277 |
+
value=False,
|
278 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
|
280 |
random_btn.click(random_fn, inputs=[], outputs=[prompt], show_api=False)
|
281 |
|
|
|
311 |
triggers=[generate_btn.click, prompt.submit],
|
312 |
fn=generate_fn,
|
313 |
api_name="generate",
|
|
|
314 |
outputs=[output_images],
|
315 |
inputs=[
|
316 |
prompt,
|
|
|
337 |
parser.add_argument("-p", "--port", type=int, metavar="INT", default=7860)
|
338 |
args = parser.parse_args()
|
339 |
|
340 |
+
# download to hub cache
|
341 |
+
for repo_id, allow_patterns in Config.HF_MODELS.items():
|
342 |
+
download_repo_files(repo_id, allow_patterns, token=Config.HF_TOKEN)
|
343 |
+
|
344 |
# https://www.gradio.app/docs/gradio/interface#interface-queue
|
345 |
+
demo.queue(default_concurrency_limit=1).launch(
|
346 |
server_name=args.server,
|
347 |
server_port=args.port,
|
348 |
)
|