adamelliotfields commited on
Commit
ae18532
1 Parent(s): d63620d
Files changed (18) hide show
  1. .gitignore +2 -0
  2. .vscode/settings.json +26 -0
  3. DOCS.md +37 -0
  4. README.md +13 -6
  5. app.css +134 -0
  6. app.js +21 -0
  7. app.py +344 -0
  8. data/prompts.json +154 -0
  9. data/styles.json +638 -0
  10. lib/__init__.py +6 -0
  11. lib/config.py +55 -0
  12. lib/inference.py +252 -0
  13. lib/loader.py +189 -0
  14. lib/upscaler.py +317 -0
  15. partials/head.html +8 -0
  16. partials/intro.html +24 -0
  17. requirements.txt +17 -0
  18. ruff.toml +9 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ __pycache__/
2
+ .venv/
.vscode/settings.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "editor.rulers": [110],
3
+
4
+ "files.exclude": {
5
+ ".venv/**": true
6
+ },
7
+ "files.watcherExclude": {
8
+ ".venv/**": true
9
+ },
10
+
11
+ "notebook.formatOnSave.enabled": true,
12
+ "notebook.codeActionsOnSave": {
13
+ "notebook.source.fixAll.ruff": "explicit",
14
+ "notebook.source.organizeImports.ruff": "explicit"
15
+ },
16
+
17
+ "[python]": {
18
+ "editor.defaultFormatter": "charliermarsh.ruff",
19
+ "editor.formatOnSave": true,
20
+ "editor.tabSize": 4,
21
+ "editor.codeActionsOnSave": {
22
+ "source.fixAll.ruff": "explicit",
23
+ "source.organizeImports.ruff": "explicit"
24
+ }
25
+ }
26
+ }
DOCS.md ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Diffusion XL
2
+
3
+ TL;DR: Enter a prompt or roll the `🎲` and press `Generate`.
4
+
5
+ ## Prompting
6
+
7
+ Positive and negative prompts are embedded by [Compel](https://github.com/damian0815/compel) for weighting. See [syntax features](https://github.com/damian0815/compel/blob/main/doc/syntax.md) to learn more and read [Civitai](https://civitai.com)'s guide on [prompting](https://education.civitai.com/civitais-prompt-crafting-guide-part-1-basics/) for best practices.
8
+
9
+ ### Arrays
10
+
11
+ Arrays allow you to generate different images from a single prompt. For example, `[[cat,corgi]]` will expand into 2 separate prompts. Make sure `Images` is set accordingly (e.g., 2). Only works for the positive prompt. Inspired by [Fooocus](https://github.com/lllyasviel/Fooocus/pull/1503).
12
+
13
+ ## Styles
14
+
15
+ Styles are prompt templates from twri's [sdxl_prompt_styler](https://github.com/twri/sdxl_prompt_styler) Comfy node. Start with a subject like "cat", pick a style, and iterate from there.
16
+
17
+ ## Scale
18
+
19
+ Rescale up to 4x using [Real-ESRGAN](https://github.com/xinntao/Real-ESRGAN) from [ai-forever](https://huggingface.co/ai-forever/Real-ESRGAN).
20
+
21
+ ## Models
22
+
23
+ TBD
24
+
25
+ ## Advanced
26
+
27
+ ### DeepCache
28
+
29
+ [DeepCache](https://github.com/horseee/DeepCache) caches lower UNet layers and reuses them every `Interval` steps. Trade quality for speed:
30
+ * `1`: no caching (default)
31
+ * `2`: more quality
32
+ * `3`: balanced
33
+ * `4`: more speed
34
+
35
+ ### Refiner
36
+
37
+ TBD
README.md CHANGED
@@ -1,13 +1,20 @@
1
  ---
2
- title: Diffusion Xl
3
- emoji: 🐢
4
- colorFrom: red
5
- colorTo: gray
 
 
6
  sdk: gradio
7
- sdk_version: 4.40.0
 
8
  app_file: app.py
 
9
  pinned: false
 
10
  license: apache-2.0
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
  ---
2
+ # https://huggingface.co/docs/hub/en/spaces-config-reference
3
+ title: Diffusion XL
4
+ short_description: Stable Diffusion XL image generation studio
5
+ emoji: 🦣
6
+ colorFrom: gray
7
+ colorTo: red
8
  sdk: gradio
9
+ sdk_version: 4.41.0
10
+ python_version: 3.11.9
11
  app_file: app.py
12
+ fullWidth: false
13
  pinned: false
14
+ header: mini
15
  license: apache-2.0
16
  ---
17
 
18
+ # diffusion-xl
19
+
20
+ Gradio app for Stable Diffusion XL.
app.css ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .accordion {
2
+ --block-border-width: 0px;
3
+ background-color: transparent;
4
+ padding: 0px;
5
+ }
6
+ .accordion > button {
7
+ margin-bottom: 16px;
8
+ justify-content: flex-start;
9
+ color: var(--body-text-color-subdued);
10
+ }
11
+ .accordion > button:hover {
12
+ color: var(--body-text-color);
13
+ }
14
+ .accordion > button > span:first-child {
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);
24
+ }
25
+ .gallery:is(.dark *) {
26
+ background-color: var(--bg-dark);
27
+ }
28
+ .gallery .grid-wrap {
29
+ overflow-y: auto;
30
+ }
31
+ .gallery, .gallery .grid-wrap {
32
+ height: calc(100vh - 360px);
33
+ max-height: none;
34
+ }
35
+
36
+ .icon-button {
37
+ max-width: 42px;
38
+ }
39
+
40
+ .image-container {
41
+ max-height: calc(100vh - 480px);
42
+ }
43
+
44
+ #intro {
45
+ margin-bottom: 8px !important;
46
+ }
47
+ #intro > div {
48
+ display: flex;
49
+ }
50
+ #intro > div > h1 > span {
51
+ font-style: italic;
52
+ color: #047857 !important;
53
+ }
54
+ #intro > div > h1 > span:is(.dark *) {
55
+ color: #10b981 !important;
56
+ }
57
+ #intro > div > svg {
58
+ width: 1.5rem;
59
+ height: 1.5rem;
60
+ margin-top: 0.25rem;
61
+ margin-left: 0.5rem;
62
+ align-self: center;
63
+ fill: #047857 !important;
64
+ animation: spin 3s linear infinite reverse;
65
+ }
66
+ #intro > div > svg:is(.dark *) {
67
+ fill: #10b981 !important;
68
+ }
69
+ #intro nav {
70
+ display: flex;
71
+ column-gap: 0.5rem;
72
+ }
73
+ #intro nav a, #intro nav span {
74
+ white-space: nowrap;
75
+ font-family: monospace;
76
+ }
77
+ #intro nav span {
78
+ font-weight: 500;
79
+ color: var(--body-text-color);
80
+ }
81
+ #intro nav a {
82
+ color: var(--body-text-color-subdued);
83
+ }
84
+ #intro nav a:hover {
85
+ color: var(--body-text-color);
86
+ }
87
+
88
+ .popover {
89
+ position: relative;
90
+ }
91
+ .popover:hover::after {
92
+ white-space: nowrap;
93
+ position: absolute;
94
+ left: 50%;
95
+ bottom: calc(100% + 8px);
96
+ transform: translateX(-50%);
97
+ padding: 4px 8px;
98
+ border-radius: 4px;
99
+ border-width: 1px;
100
+ border-color: var(--button-secondary-border-color-hover);
101
+ background: var(--button-secondary-background-fill-hover);
102
+ color: var(--button-secondary-text-color-hover);
103
+ font-weight: var(--section-header-text-weight);
104
+ font-size: var(--section-header-text-size);
105
+ }
106
+ .popover#random:hover::after {
107
+ content: 'Random prompt';
108
+ }
109
+ .popover#clear:hover::after {
110
+ content: 'Clear gallery';
111
+ }
112
+ .popover#refresh:hover::after {
113
+ content: var(--seed, "-1");
114
+ }
115
+
116
+ .tabs, .tabitem, .tab-nav, .tab-nav > .selected {
117
+ border-width: 0px;
118
+ }
119
+ .tabitem {
120
+ max-height: calc(100vh - 260px);
121
+ overflow-x: hidden;
122
+ overflow-y: auto;
123
+ padding: 0 0 8px;
124
+ }
125
+ .tab-nav {
126
+ margin-bottom: 16px;
127
+ }
128
+ .tab-nav > button {
129
+ padding-bottom: 8px;
130
+ }
131
+
132
+ @keyframes spin {
133
+ 100% { transform: rotate(360deg); }
134
+ }
app.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ };
10
+
11
+ const observer = new MutationObserver(updateMenu);
12
+ observer.observe(menuButton, { attributes: true, attributeFilter: ["class"] });
13
+ updateMenu();
14
+
15
+ if (window.location.hostname.endsWith(".hf.space")) {
16
+ const hfHeader = document.getElementById("huggingface-space-header");
17
+ if (hfHeader) {
18
+ hfHeader.style.display = "none";
19
+ }
20
+ }
21
+ }
app.py ADDED
@@ -0,0 +1,344 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 = """
11
+ () => {
12
+ const n = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
13
+ const button = document.getElementById("refresh");
14
+ button.style.setProperty("--seed", `"${n}"`);
15
+ return n;
16
+ }
17
+ """
18
+
19
+ seed_js = """
20
+ (seed) => {
21
+ const button = document.getElementById("refresh");
22
+ button.style.setProperty("--seed", `"${seed}"`);
23
+ return seed;
24
+ }
25
+ """
26
+
27
+ aspect_ratio_js = """
28
+ (ar, w, h) => {
29
+ if (!ar) return [w, h];
30
+ const [width, height] = ar.split(",");
31
+ return [parseInt(width), parseInt(height)];
32
+ }
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("ValueError: Invalid prompt")
54
+ try:
55
+ images = await async_call(
56
+ generate,
57
+ *args,
58
+ Info=gr.Info,
59
+ Error=gr.Error,
60
+ progress=gr.Progress(),
61
+ )
62
+ except RuntimeError:
63
+ raise gr.Error("RuntimeError: Please try again later")
64
+ return images
65
+
66
+
67
+ with gr.Blocks(
68
+ head=read_file("./partials/head.html"),
69
+ css="./app.css",
70
+ js="./app.js",
71
+ theme=gr.themes.Default(
72
+ # colors
73
+ neutral_hue=gr.themes.colors.gray,
74
+ primary_hue=gr.themes.colors.orange,
75
+ secondary_hue=gr.themes.colors.blue,
76
+ # sizing
77
+ text_size=gr.themes.sizes.text_md,
78
+ radius_size=gr.themes.sizes.radius_sm,
79
+ spacing_size=gr.themes.sizes.spacing_md,
80
+ # fonts
81
+ font=[gr.themes.GoogleFont("Inter"), *Config.SANS_FONTS],
82
+ font_mono=[gr.themes.GoogleFont("Ubuntu Mono"), *Config.MONO_FONTS],
83
+ ).set(
84
+ layout_gap="8px",
85
+ block_shadow="0 0 #0000",
86
+ block_shadow_dark="0 0 #0000",
87
+ block_background_fill=gr.themes.colors.gray.c50,
88
+ block_background_fill_dark=gr.themes.colors.gray.c900,
89
+ ),
90
+ ) as demo:
91
+ gr.HTML(read_file("./partials/intro.html"))
92
+
93
+ with gr.Accordion(
94
+ elem_classes=["accordion"],
95
+ elem_id="menu",
96
+ label="Menu",
97
+ open=False,
98
+ ):
99
+ with gr.Tabs():
100
+ with gr.TabItem("⚙️ Settings"):
101
+ with gr.Group():
102
+ negative_prompt = gr.Textbox(
103
+ value=None,
104
+ label="Negative Prompt",
105
+ placeholder="ugly, bad",
106
+ lines=2,
107
+ )
108
+
109
+ with gr.Row():
110
+ model = gr.Dropdown(
111
+ choices=Config.MODELS,
112
+ filterable=False,
113
+ value=Config.MODEL,
114
+ label="Model",
115
+ min_width=240,
116
+ )
117
+ scheduler = gr.Dropdown(
118
+ choices=Config.SCHEDULERS.keys(),
119
+ value=Config.SCHEDULER,
120
+ elem_id="scheduler",
121
+ label="Scheduler",
122
+ filterable=False,
123
+ )
124
+
125
+ with gr.Row():
126
+ styles = json.loads(read_file("data/styles.json"))
127
+ style = gr.Dropdown(
128
+ value=Config.STYLE,
129
+ label="Style",
130
+ choices=[("None", None)] + [(s["name"], s["id"]) for s in styles],
131
+ )
132
+ # embeddings = gr.Dropdown(
133
+ # elem_id="embeddings",
134
+ # label="Embeddings",
135
+ # choices=[(f"<{e}>", e) for e in Config.EMBEDDINGS],
136
+ # multiselect=True,
137
+ # value=[Config.EMBEDDING],
138
+ # min_width=240,
139
+ # )
140
+
141
+ with gr.Row():
142
+ guidance_scale = gr.Slider(
143
+ value=Config.GUIDANCE_SCALE,
144
+ label="Guidance Scale",
145
+ minimum=1.0,
146
+ maximum=15.0,
147
+ step=0.1,
148
+ )
149
+ inference_steps = gr.Slider(
150
+ value=Config.INFERENCE_STEPS,
151
+ label="Inference Steps",
152
+ minimum=1,
153
+ maximum=50,
154
+ step=1,
155
+ )
156
+ deepcache_interval = gr.Slider(
157
+ value=Config.DEEPCACHE_INTERVAL,
158
+ label="DeepCache",
159
+ minimum=1,
160
+ maximum=4,
161
+ step=1,
162
+ )
163
+
164
+ with gr.Row():
165
+ width = gr.Slider(
166
+ value=Config.WIDTH,
167
+ label="Width",
168
+ minimum=512,
169
+ maximum=1536,
170
+ step=64,
171
+ )
172
+ height = gr.Slider(
173
+ value=Config.HEIGHT,
174
+ label="Height",
175
+ minimum=512,
176
+ maximum=1536,
177
+ step=64,
178
+ )
179
+ aspect_ratio = gr.Dropdown(
180
+ choices=[
181
+ ("Custom", None),
182
+ ("4:7 (768x1344)", "768,1344"),
183
+ ("7:9 (896x1152)", "896,1152"),
184
+ ("1:1 (1024x1024)", "1024,1024"),
185
+ ("9:7 (1152x896)", "1152,896"),
186
+ ("7:4 (1344x768)", "1344,768"),
187
+ ],
188
+ value="896,1152",
189
+ filterable=False,
190
+ label="Aspect Ratio",
191
+ )
192
+
193
+ with gr.Row():
194
+ file_format = gr.Dropdown(
195
+ choices=["png", "jpeg", "webp"],
196
+ label="File Format",
197
+ filterable=False,
198
+ value="png",
199
+ )
200
+ num_images = gr.Dropdown(
201
+ choices=list(range(1, 5)),
202
+ value=Config.NUM_IMAGES,
203
+ filterable=False,
204
+ label="Images",
205
+ )
206
+ scale = gr.Dropdown(
207
+ choices=[(f"{s}x", s) for s in Config.SCALES],
208
+ filterable=False,
209
+ value=Config.SCALE,
210
+ label="Scale",
211
+ )
212
+ seed = gr.Number(
213
+ value=Config.SEED,
214
+ label="Seed",
215
+ minimum=-1,
216
+ maximum=(2**64) - 1,
217
+ )
218
+
219
+ with gr.Row():
220
+ use_karras = gr.Checkbox(
221
+ elem_classes=["checkbox"],
222
+ label="Karras σ",
223
+ value=True,
224
+ )
225
+ use_refiner = gr.Checkbox(
226
+ elem_classes=["checkbox"],
227
+ label="Refiner",
228
+ value=True,
229
+ )
230
+
231
+ # Main content
232
+ with gr.Column(elem_id="content"):
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
+
281
+ refresh_btn.click(None, inputs=[], outputs=[seed], js=refresh_seed_js)
282
+
283
+ seed.change(None, inputs=[seed], outputs=[], js=seed_js)
284
+
285
+ file_format.change(
286
+ lambda f: (gr.Gallery(format=f), gr.Image(format=f), gr.Image(format=f)),
287
+ inputs=[file_format],
288
+ outputs=[output_images],
289
+ show_api=False,
290
+ )
291
+
292
+ # input events are only user input; change events are both user and programmatic
293
+ aspect_ratio.input(
294
+ None,
295
+ inputs=[aspect_ratio, width, height],
296
+ outputs=[width, height],
297
+ js=aspect_ratio_js,
298
+ )
299
+
300
+ # show "Custom" aspect ratio when manually changing width or height
301
+ gr.on(
302
+ triggers=[width.input, height.input],
303
+ fn=None,
304
+ inputs=[],
305
+ outputs=[aspect_ratio],
306
+ js="() => { return null; }",
307
+ )
308
+
309
+ gr.on(
310
+ triggers=[generate_btn.click, prompt.submit],
311
+ fn=generate_fn,
312
+ api_name="generate",
313
+ concurrency_limit=5,
314
+ outputs=[output_images],
315
+ inputs=[
316
+ prompt,
317
+ negative_prompt,
318
+ style,
319
+ seed,
320
+ model,
321
+ scheduler,
322
+ width,
323
+ height,
324
+ guidance_scale,
325
+ inference_steps,
326
+ deepcache_interval,
327
+ scale,
328
+ num_images,
329
+ use_karras,
330
+ use_refiner,
331
+ ],
332
+ )
333
+
334
+ if __name__ == "__main__":
335
+ parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False)
336
+ parser.add_argument("-s", "--server", type=str, metavar="STR", default="0.0.0.0")
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
+ )
data/prompts.json ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "Stunning sunset over a futuristic city, with towering skyscrapers and flying vehicles, golden hour lighting and dramatic clouds, high detail, moody atmosphere",
3
+ "Mystical forest with glowing mushrooms and a babbling brook, surrounded by towering trees and shrouded in mist, ethereal, dreamlike, stylized",
4
+ "Majestic dragon, perched atop a cliff overlooking a fiery landscape, with smoke and ash rising into the air, intense, detailed, scales, dynamic, epic",
5
+ "Serene beach scene with crystal clear water and white sand, tropical palm trees swaying in the breeze, perfect paradise, seascape",
6
+ "Post-apocalyptic wasteland with rusted and abandoned vehicles, dust storms and towering dust clouds, gritty, dark, dramatic, apocalyptic, stylized",
7
+ "Mystical underwater world with vibrant coral and exotic sea creatures, sun beams shining through the water, mysterious, magical, otherworldly",
8
+ "Snowy winter wonderland with a lone cabin in the distance, surrounded by frosty trees and fresh snowfall, peaceful, serene, detailed, winter landscape",
9
+ "Mysterious and abandoned temple in the jungle, surrounded by lush vegetation and tall trees, atmospheric, ancient, moody",
10
+ "Vibrant and bustling city street with busy traffic, bright lights, and towering skyscrapers, chaotic, fast-paced, cityscape, high detail",
11
+ "Gothic cathedral in a stormy night, with lightning illuminating the sky and rain pouring down, dramatic, atmospheric, high detail, moody",
12
+ "Fantasy castle on a hilltop, surrounded by rolling hills and a beautiful sunset, magical, serene, high detail, romantic, stylized",
13
+ "Vast desert with sand dunes and a lone oasis in the distance, hot sun and clear blue sky, peaceful, serene, desertscape, high resolution",
14
+ "Ethereal aurora borealis over a snowy mountain range, with a full moon shining in the background, mystical, peaceful, serene, winter landscape, high detail",
15
+ "Giant robots fighting in a futuristic city, with buildings falling and explosions all around, intense, fast-paced, dramatic, stylized, futuristic",
16
+ "Medieval market square with vendors selling goods, colorful banners, and bustling crowds, lively, busy, historic, high detail, architectural",
17
+ "Abandoned prison on a cliff, with a stormy sea below, eerie, moody, atmospheric, architectural, stylized",
18
+ "Beautiful waterfall in a lush jungle, with sunlight shining through the trees, serene, peaceful, tropical, jungle landscape, high detail",
19
+ "Surreal carnival scene with bright lights, strange creatures, and a full moon, dreamlike, vibrant, stylized, surreal, high detail",
20
+ "Breathtaking mountain range with a clear river running through it, surrounded by tall trees and misty clouds, serene, peaceful, mountain landscape, high detail",
21
+ "Historic battlefield with armies clashing and smoke rising, intense, fast-paced, dramatic, historic, high detail",
22
+ "Enchanted forest with glowing fireflies and a babbling brook, surrounded by towering trees and shrouded in mist, magical, ethereal, dreamlike, stylized",
23
+ "Sunken ship in a vibrant coral reef, with schools of colorful fish swimming by, mysterious, magical, high detail",
24
+ "Futuristic city with towering skyscrapers and flying vehicles, set against a vibrant sunset, futuristic, serene, high detail",
25
+ "Volcanic island with a boiling crater and ash clouds rising into the air, intense, dramatic, natural disaster, high detail, volcanic landscape",
26
+ "Lonely lighthouse on a rocky coast during a storm, with waves crashing and lightning flashing, moody, atmospheric, seascape, high detail",
27
+ "Ruined castle on a cliff overlooking the sea, with a stormy sky and crashing waves, eerie, moody, atmospheric",
28
+ "Vibrant street fair with colorful stalls and bustling crowds, lively, busy, high detail",
29
+ "Mysterious underground cave with glowing crystals and an underground river, dark, mysterious, underground landscape, high detail",
30
+ "Glorious sunrise over a cityscape, with the city slowly coming to life and the sky turning orange and pink, serene, peaceful, cityscape, high detail",
31
+ "Breathtaking view of a snowy mountain range, with crisp clear air and a brilliant blue sky, serene, peaceful, majestic, high detail, winter landscape",
32
+ "Enchanting waterfall in a lush jungle, surrounded by exotic plants and wildlife, tranquil, serene, high detail, tropical landscape",
33
+ "Glowing aurora borealis over a frozen lake, with towering mountains in the distance, ethereal, magical, winter landscape, high detail",
34
+ "Rushing rapids in a crystal clear river, surrounded by towering trees and lush vegetation, energetic, serene, high detail, river landscape",
35
+ "Vibrant flower field in full bloom, surrounded by rolling hills and a brilliant blue sky, colorful, serene, high detail, spring landscape",
36
+ "Glimpses of a herd of wild elephants crossing a savanna, surrounded by tall grass and a brilliant orange sunset, majestic, peaceful, high detail, safari landscape",
37
+ "Tranquil pond surrounded by tall trees, with a beautiful lily pad garden and calm reflection of the sky, serene, peaceful, high detail, water landscape",
38
+ "Giant redwoods in a misty forest, with towering trees and lush vegetation, peaceful, serene, high detail, forest landscape",
39
+ "Breathtaking view of a desert landscape, with towering sand dunes and a brilliant blue sky, serene, vast, high detail, desert landscape",
40
+ "Stunning sunset over an ocean horizon, with orange and pink hues spreading across the sky, peaceful, serene, high detail, seascape",
41
+ "Massive airship floating above a sprawling metropolis, with towering skyscrapers and busy streets below, futuristic, detailed, high resolution, urban landscape",
42
+ "Steampunk submarine exploring a coral reef, surrounded by exotic sea creatures and vibrant coral, detailed, surreal, steampunk style",
43
+ "Medieval castle on a cliff, surrounded by a moat and rolling green hills, majestic, medieval, high detail",
44
+ "Towering robot statue in a desolate wasteland, with dust storms and abandoned vehicles in the distance, mechanical, dystopian, high detail, post-apocalyptic landscape",
45
+ "Massive statue of a dragon in a lush jungle, surrounded by exotic plants and tall trees, mysterious, ancient, high detail, tropical landscape",
46
+ "Ancient temple in a mountain range, surrounded by misty clouds and tall peaks, mysterious, ancient, high detail",
47
+ "Crashed spaceship in a dense forest, surrounded by tall trees and exotic vegetation, futuristic, detailed, high detail, sci-fi landscape",
48
+ "Lighthouse on a stormy beach, surrounded by crashing waves and dramatic clouds, intense, detailed, high detail, coastal landscape",
49
+ "Steam locomotive in a snowy mountain range, surrounded by tall peaks and crisp clear air, nostalgic, detailed, high detail, winter landscape",
50
+ "Old western town in the desert, surrounded by towering sand dunes and a brilliant blue sky, nostalgic, detailed, high detail, western landscape",
51
+ "Futuristic cyborg, sleek metal enhancements and glowing circuits, standing in high-tech laboratory, intense, detailed, high resolution, sci-fi portrait",
52
+ "Medieval knight, armor and shining sword, standing on battle-scarred battlefield, intense, detailed, high detail, portrait",
53
+ "Powerful sorceress, flowing robes and mystical staff, standing in dark and ominous forest, mysterious, detailed, high detail, fantasy portrait",
54
+ "Rogue adventurer, backpack and rugged appearance, standing in dense jungle, adventurous, detailed, high detail, portrait",
55
+ "Wise wizard, long beard and mysterious tome, standing in dimly lit library, wise, detailed, high detail, portrait",
56
+ "Daring astronaut, space suit and helmet, standing in front of futuristic spaceship, adventurous, detailed, high detail, portrait",
57
+ "Skilled archer, bow and quiver of arrows, standing in forest clearing, intense, detailed, high detail, portrait",
58
+ "Daring treasure hunter, map and compass, standing in desolate desert, adventurous, detailed, high detail, portrait",
59
+ "Cosmic swirl of stars and galaxies, swirling in endless black void, otherworldly, abstract, high detail, space",
60
+ "Psychedelic mandala of patterns and shapes, kaleidoscopic, trippy, detailed, abstract art",
61
+ "Fractal landscape of geometric shapes and patterns, complex, intricate, abstract, digital art",
62
+ "Glowing nebula of vibrant gas and dust, celestial, otherworldly, abstract, space art",
63
+ "Hypnotic vortex of swirling colors, intense, detailed, abstract, digital art",
64
+ "Aurora borealis, vibrant lights dancing in the night sky, ethereal, abstract, high detail, nature art",
65
+ "Phantasmagoric carnival, carnival attractions shifting and changing, dreamlike, abstract, high detail, surreal art",
66
+ "Radiant nebula, star clusters and gas clouds shining brightly, celestial, otherworldly, abstract, space art",
67
+ "Iconic Parisian street with quaint cafes and bistros, charming, romantic, high detail, cityscape",
68
+ "Golden hour New York City skyline, towering skyscrapers and bustling streets, iconic, dramatic",
69
+ "Beautiful Venice canals with gondolas and bridges, charming, romantic, high detail, cityscape",
70
+ "Majestic Machu Picchu, set against a backdrop of towering mountains, breathtaking, high detail, landscape",
71
+ "Breathtaking view of the Grand Canyon, vast and awe-inspiring, high detail, landscape",
72
+ "Charming Santorini island with pristine beaches and iconic white buildings, Mediterranean, high detail, seascape",
73
+ "The iconic Great Wall of China, stretching along the countryside, historical, high detail, landscape",
74
+ "Stunning view of the Sydney Opera House, with the harbor and cityscape in the background, iconic, high detail, cityscape",
75
+ "The stunning Taj Mahal, set against a backdrop of lush greenery, historic, high detail, landmark",
76
+ "Breathtaking view of the Serengeti with roaming wildlife, vast, high detail, nature landscape",
77
+ "Giant rubber duck floating in the ocean with a small island on its back, surrounded by tropical palm trees and crystal clear water, bright and sunny day, calm seas, vivid colors, cinematic lighting, high detail",
78
+ "Giant hamster wheel in the middle of a city, with skyscrapers and busy streets in the background, centralized, low details, stylized graphics, night time, lit up, neon lights, no shadows",
79
+ "Humongous teacup and saucer floating in the sky, surrounded by clouds and rainbows, abstract, surreal, dreamlike, stylized oil painting style, vivid colors, detailed, high resolution, wide angled, otherworldly, fantastic",
80
+ "Giant ice cream cone melting and creating a river through a city, with boats floating down it, dramatic, intense, chaotic, high detail, fast-paced, wide angled, aerial view, colorful, fun, stylized graphics",
81
+ "Giant snail racing a car, high speed, intense, dynamic, detailed, cartoon style, wide angled, overhead view, vibrant colors, whimsical, absurd, surreal, fun",
82
+ "A group of giant robots playing a game of soccer, intense, dynamic, high detail, 3D, stylized, futuristic, metallic, robots, absurd, fantastic, wide angled, overhead view, colorful, fun",
83
+ "A city built entirely out of food, colorful, detailed, stylized, fun, absurd, vivid, delicious, overhead view, centralized, wide angled, vibrant, fantastical",
84
+ "Giant fruit and vegetable parade, with various different fruits and vegetables marching down a city street, colorful, detailed, stylized, absurd, fun, vivid, delicious, overhead view, centralized, wide angled",
85
+ "Giant caterpillar riding a bicycle, surreal, absurd, whimsical, stylized, detailed, vivid, high resolution, centralized, overhead view, colorful, fun",
86
+ "A bustling city made entirely of candy, with gumdrop buildings and sugar-coated streets, bright colors, whimsical, playful, detailed",
87
+ "A floating city in the clouds, with airships docking at sky-high platforms and clouds serving as roads, futuristic, whimsical, high-altitude, detailed",
88
+ "An underground city, filled with steam-powered trains, strange creatures, and intricate tunnels and cave systems, dark, detailed, subterranean, steampunk",
89
+ "A jungle city, with vines and roots serving as roads and buildings made of leaves, colorful, detailed, natural, tropical",
90
+ "A city made of ice, with ice slides, frozen rivers, and snow-covered buildings, winter, magical, detailed, cold",
91
+ "A pirate port, with ships setting sail, blacksmiths crafting weapons, and treasure-filled caves, adventurous, detailed, historic, swashbuckling",
92
+ "A space station, with spaceships coming and going, astronauts on EVA missions, and maintenance robots hard at work, futuristic, high-tech, detailed, intergalactic",
93
+ "A dragon's lair, with dragons hoarding treasure, sleeping on piles of gold, and shooting fire from their nostrils, mythical, detailed, adventurous, fantastical",
94
+ "Bowl of steaming hot ramen with a perfect egg in the center, surrounded by thin slices of meat, green onions, and nori, with a flavorful broth and perfect noodles, high detail, focused on texture and steam",
95
+ "Delectable pizza with melted cheese, juicy tomato sauce, and an array of toppings including pepperoni, mushrooms, and black olives, served hot and fresh, high resolution, stylized, focused on ingredients and melted cheese",
96
+ "Sizzling hot sirloin steak with a perfect crust, seared to perfection and topped with herbs and spices, served with a side of roasted vegetables and mashed potatoes, juicy, delicious, high detail",
97
+ "Assorted fruit platter with ripe, juicy strawberries, sweet grapes, tangy citrus, and juicy watermelon, set on a bed of greens and accented with mint leaves, high resolution, vibrant, natural",
98
+ "Chocolate cake with rich, fudgy frosting and perfectly layered cake, garnished with fresh berries and drizzled with melted chocolate, decadent, sweet, high detail, food photography",
99
+ "Baked salmon fillet with a perfectly crispy skin and tender, flaky flesh, served with a side of steamed vegetables and quinoa, healthy, flavorful, high detail, food photography",
100
+ "Bowl of hearty chili with tender chunks of beef, rich tomato sauce, and a mix of spices, topped with grated cheddar cheese and green onions, high detail, focused on texture and heat, comfort food",
101
+ "Platter of sushi rolls with colorful and flavorful ingredients, including avocado, tuna, salmon, and crab, arranged with precision and beauty, high resolution, Asian-style, focused on texture and color",
102
+ "Stuffed bell peppers filled with tender ground beef, flavorful rice, and melted cheese, baked to perfection, juicy, flavorful, high detail, food photography",
103
+ "Tasty tacos filled with seasoned beef, fresh salsa, melted cheese, and crunchy lettuce, served on a warm corn tortilla, Mexican-style, high resolution, focused on texture and flavor, food photography",
104
+ "Contemporary living room with large windows overlooking a cityscape, neutral color palette, minimalistic design, sleek modern furniture, gallery wall of abstract art, warm lighting, high detail, open floor plan",
105
+ "Rustic kitchen with exposed brick wall, reclaimed wood cabinetry, large farmhouse sink, industrial lighting fixtures, antique baking tools on open shelving, cast iron cookware, vintage accents, warm and inviting, detailed textures",
106
+ "Luxurious bathroom with freestanding bathtub, rain shower, heated flooring, marble tiles, brass fixtures, floating vanity with double sink, elegant chandelier, high contrast lighting, spa-like atmosphere, high resolution",
107
+ "Elegant dining room with crystal chandelier, dark wood table, velvet upholstered chairs, large statement art piece, tall windows with lush garden view, sophisticated color scheme, detailed textures, candlelit ambiance",
108
+ "Industrial-style office with concrete floors, raw steel beams, large wooden desk, leather office chair, wall of bookshelves, minimalist design, warm lighting, high detail, organized and professional",
109
+ "Cozy bedroom with four-poster bed, plush bedding, soft lighting, large windows with natural light, statement wallpaper, decorative throw pillows, high resolution textures, intimate and relaxing",
110
+ "Glamorous dressing room with large mirror, Hollywood lights, plush velvet seating, glass shelves displaying designer shoes, hanging rods for clothes, detailed textures, high contrast lighting, organized and stylish",
111
+ "Modern nursery with minimalistic design, white crib, rocking chair, wall mounted bookshelves, abstract art, neutral color palette, warm lighting, high detail, cozy and inviting",
112
+ "Minimalistic home gym with rubber flooring, wall-mounted TV, weight bench, medicine ball, dumbbells, yoga mats, high-tech equipment, high detail, organized and efficient",
113
+ "Traditional library with floor-to-ceiling bookcases, rolling ladder, large wooden desk, leather armchair, antique rug, warm lighting, high resolution textures, intellectual and inviting atmosphere",
114
+ "Contemporary glass and steel building with sleek lines and an innovative facade, surrounded by an urban landscape, modern, high resolution",
115
+ "Sleek and modern shopping center with an emphasis on natural light, an open-air interior, and eco-friendly features, contemporary, high detail, architectural renderings",
116
+ "High-rise residential building with a unique form and facade, featuring terraces and stunning views, minimalist, high-end, architectural design",
117
+ "Contemporary office building with a focus on sustainability, including green roofs and walls, modern, cutting-edge, architectural illustration",
118
+ "Contemporary cultural center with a distinct form, featuring a vibrant public plaza and innovative exhibition spaces, futuristic, visually stunning, architectural drawings",
119
+ "Stylish and modern apartment building with a clean, minimalist design and a focus on natural light, contemporary, high-end, architectural rendering",
120
+ "Innovative mixed-use development featuring an interplay of form and function, with cutting-edge technology and sustainability features, contemporary, visually striking, architectural illustration",
121
+ "Stylish and contemporary hotel with a unique form and facade, featuring luxury amenities and stunning views, modern, visually stunning",
122
+ "Sleek and modern shopping mall with a focus on sustainable design, featuring natural light and innovative materials, contemporary, cutting-edge, architectural drawings",
123
+ "Innovative and contemporary transportation hub with a unique form, featuring cutting-edge technology and sustainable features, modern, visually stunning, architectural illustration",
124
+ "Race car with sleek design, captured in a high speed motion blur, dramatic lighting and shallow depth of field, motorsports, adrenaline, studio lighting",
125
+ "Vintage hot rod with custom flame paint job, captured in low key lighting with selective focus on the chrome details, classic car, retro, high resolution",
126
+ "Luxury sports car with aerodynamic curves, shot in a high contrast, high key lighting with shallow depth of field, exotic, detailed, sporty, studio lighting",
127
+ "Majestic yacht with sleek lines, captured in a serene sunset light, with a shallow depth of field, boating, lifestyle",
128
+ "Futuristic flying car with smooth lines, shot in a low light high contrast studio setting, science fiction, cutting edge, high detail, moody atmosphere",
129
+ "Sturdy pickup truck, captured in a dramatic golden hour light with deep shadows, off-roading, rugged, dramatic, high resolution",
130
+ "Vintage motorcycle with gleaming chrome and polished leather, captured in soft natural light with selective focus on the engine, classic, retro, detailed",
131
+ "Luxury sports car with aggressive lines, shot in a high contrast, high key lighting with shallow depth of field, detailed, sporty, sleek, studio lighting",
132
+ "Massive semi-truck with chrome details, captured in a high key lighting with shallow depth of field, transportation, commercial, detailed, high resolution",
133
+ "Vintage sports car with classic curves, captured in a moody, low key light with selective focus on the grille, classic, retro, moody, detailed",
134
+ "Oil painting of a bustling harbor town, with fishing boats, seagulls, and a lighthouse in the background, high contrast, dramatic lighting, heavily textured brushstrokes",
135
+ "Watercolor painting of a rolling countryside, with fields of flowers, a red barn, and a white picket fence, soft and delicate brushstrokes, pastel colors",
136
+ "Acrylic painting of a mountain landscape, with a stormy sky and a cabin nestled in the forest, high contrast, bold brushstrokes, high-resolution",
137
+ "Oil painting of a sunset over the ocean, with orange and pink hues, gently rolling waves, and palm trees, heavily textured brushstrokes, dramatic lighting",
138
+ "Pen and ink drawing of a cityscape, with tall skyscrapers and bustling city life, high-contrast, detailed linework, dramatic lighting",
139
+ "Oil painting of a enchanted forest, with glowing mushrooms, fireflies, and a unicorn, soft brushstrokes, pastel colors, dream-like atmosphere",
140
+ "Watercolor painting of a desert landscape, with sand dunes, mountains, and a blazing sun, soft and delicate brushstrokes, warm and vibrant colors",
141
+ "Acrylic painting of a futuristic city, with neon lights, advanced technology, and flying cars, bold brushstrokes, high-contrast, highly stylized",
142
+ "Oil painting of a tranquil lake surrounded by mountains, with a cabin on the shore, boats, and a sunset, heavily textured brushstrokes, warm and vibrant colors",
143
+ "Pen and ink drawing of a mystical underwater world, with schools of fish, coral reefs, and a mermaid, highly detailed linework, high-contrast, stylized",
144
+ "Watercolor painting of a rolling countryside, with fields of wheat, a red barn, and a white picket fence, soft and delicate brushstrokes, warm and vibrant colors",
145
+ "Bronze statue of a powerful warrior, with a sword in hand, chiseled muscles, and a determined expression, highly detailed, dramatic lighting, intense gaze",
146
+ "Marble statue of a serene goddess, with flowing robes, delicate features, and a tranquil expression, highly detailed, soft lighting, grace and beauty",
147
+ "Wooden sculpture of a majestic animal, with intricate carving, textured fur, and piercing eyes, highly detailed, natural lighting, raw and powerful",
148
+ "Stone statue of a mythological creature, with wings, horns, and a fierce expression, highly detailed, dramatic lighting, intense and otherworldly",
149
+ "Bronze statue of a philosopher, with a wise expression, long beard, and a tome, highly detailed, soft lighting, introspective gaze",
150
+ "Marble statue of a dancers, with fluid movements, intricate details, and grace, highly detailed, dramatic lighting, intense expression",
151
+ "Wooden sculpture of a seascape, with waves, boats, and sea creatures, intricate carving, textured surface, high-resolution, natural lighting",
152
+ "Bronze statue of a king, with regal attire, a crown, and a stern expression, highly detailed, dramatic lighting, commanding presence",
153
+ "Wooden sculpture of a tree, with intricate branches, textured bark, and a strong trunk, highly detailed, natural lighting, grounding presence"
154
+ ]
data/styles.json ADDED
@@ -0,0 +1,638 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "id": "twri-ads-automotive",
4
+ "name": "Ads: Automotive",
5
+ "prompt": "automotive advertisement style {prompt} . sleek, dynamic, professional, commercial, vehicle-focused, high-resolution, highly detailed",
6
+ "negative_prompt": "noisy, blurry, unattractive, sloppy, unprofessional"
7
+ },
8
+ {
9
+ "id": "twri-ads-corporate",
10
+ "name": "Ads: Corporate",
11
+ "prompt": "corporate branding style {prompt} . professional, clean, modern, sleek, minimalist, business-oriented, highly detailed",
12
+ "negative_prompt": "noisy, blurry, grungy, sloppy, cluttered, disorganized"
13
+ },
14
+ {
15
+ "id": "twri-ads-fashion-editorial",
16
+ "name": "Ads: Fashion Editorial",
17
+ "prompt": "fashion editorial style {prompt} . high fashion, trendy, stylish, editorial, magazine style, professional, highly detailed",
18
+ "negative_prompt": "outdated, blurry, noisy, unattractive, sloppy"
19
+ },
20
+ {
21
+ "id": "twri-ads-food-photography",
22
+ "name": "Ads: Food Photography",
23
+ "prompt": "food photography style {prompt} . appetizing, professional, culinary, high-resolution, commercial, highly detailed",
24
+ "negative_prompt": "unappetizing, sloppy, unprofessional, noisy, blurry"
25
+ },
26
+ {
27
+ "id": "twri-ads-gourmet-food-photography",
28
+ "name": "Ads: Gourmet Food Photography",
29
+ "prompt": "gourmet food photo of {prompt} . soft natural lighting, macro details, vibrant colors, fresh ingredients, glistening textures, bokeh background, styled plating, wooden tabletop, garnished, tantalizing, editorial quality",
30
+ "negative_prompt": "cartoon, anime, sketch, grayscale, dull, overexposed, cluttered, messy plate, deformed"
31
+ },
32
+ {
33
+ "id": "twri-ads-luxury",
34
+ "name": "Ads: Luxury",
35
+ "prompt": "luxury product style {prompt} . elegant, sophisticated, high-end, luxurious, professional, highly detailed",
36
+ "negative_prompt": "cheap, noisy, blurry, unattractive, amateurish"
37
+ },
38
+ {
39
+ "id": "twri-ads-poster",
40
+ "name": "Ads: Poster",
41
+ "prompt": "advertising poster style {prompt} . Professional, modern, product-focused, commercial, eye-catching, highly detailed",
42
+ "negative_prompt": "noisy, blurry, amateurish, sloppy, unattractive"
43
+ },
44
+ {
45
+ "id": "twri-ads-real-estate",
46
+ "name": "Ads: Real Estate",
47
+ "prompt": "real estate photography style {prompt} . professional, inviting, well-lit, high-resolution, property-focused, commercial, highly detailed",
48
+ "negative_prompt": "dark, blurry, unappealing, noisy, unprofessional"
49
+ },
50
+ {
51
+ "id": "twri-ads-retail",
52
+ "name": "Ads: Retail",
53
+ "prompt": "retail packaging style {prompt} . vibrant, enticing, commercial, product-focused, eye-catching, professional, highly detailed",
54
+ "negative_prompt": "noisy, blurry, amateurish, sloppy, unattractive"
55
+ },
56
+ {
57
+ "id": "twri-art-abstract",
58
+ "name": "Art: Abstract",
59
+ "prompt": "abstract style {prompt} . non-representational, colors and shapes, expression of feelings, imaginative, highly detailed",
60
+ "negative_prompt": "realistic, photographic, figurative, concrete"
61
+ },
62
+ {
63
+ "id": "twri-art-abstract-expressionism",
64
+ "name": "Art: Abstract Expressionism",
65
+ "prompt": "abstract expressionist painting {prompt} . energetic brushwork, bold colors, abstract forms, expressive, emotional",
66
+ "negative_prompt": "realistic, photorealistic, low contrast, plain, simple, monochrome"
67
+ },
68
+ {
69
+ "id": "twri-art-art-deco",
70
+ "name": "Art: Art Deco",
71
+ "prompt": "art deco style {prompt} . geometric shapes, bold colors, luxurious, elegant, decorative, symmetrical, ornate, detailed",
72
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, modernist, minimalist"
73
+ },
74
+ {
75
+ "id": "twri-art-art-nouveau",
76
+ "name": "Art: Art Nouveau",
77
+ "prompt": "art nouveau style {prompt} . elegant, decorative, curvilinear forms, nature-inspired, ornate, detailed",
78
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, modernist, minimalist"
79
+ },
80
+ {
81
+ "id": "twri-art-constructivist",
82
+ "name": "Art: Constructivist",
83
+ "prompt": "constructivist style {prompt} . geometric shapes, bold colors, dynamic composition, propaganda art style",
84
+ "negative_prompt": "realistic, photorealistic, low contrast, plain, simple, abstract expressionism"
85
+ },
86
+ {
87
+ "id": "twri-art-cubist",
88
+ "name": "Art: Cubist",
89
+ "prompt": "cubist artwork {prompt} . geometric shapes, abstract, innovative, revolutionary",
90
+ "negative_prompt": "anime, photorealistic, 35mm film, deformed, glitch, low contrast, noisy"
91
+ },
92
+ {
93
+ "id": "twri-art-expressionist",
94
+ "name": "Art: Expressionist",
95
+ "prompt": "expressionist {prompt} . raw, emotional, dynamic, distortion for emotional effect, vibrant, use of unusual colors, detailed",
96
+ "negative_prompt": "realism, symmetry, quiet, calm, photo"
97
+ },
98
+ {
99
+ "id": "twri-art-graffiti",
100
+ "name": "Art: Graffiti",
101
+ "prompt": "graffiti style {prompt} . street art, vibrant, urban, detailed, tag, mural",
102
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic"
103
+ },
104
+ {
105
+ "id": "twri-art-hyperrealism",
106
+ "name": "Art: Hyperrealism",
107
+ "prompt": "hyperrealistic art {prompt} . extremely high-resolution details, photographic, realism pushed to extreme, fine texture, incredibly lifelike",
108
+ "negative_prompt": "simplified, abstract, unrealistic, impressionistic, low resolution"
109
+ },
110
+ {
111
+ "id": "twri-art-impressionist",
112
+ "name": "Art: Impressionist",
113
+ "prompt": "impressionist painting {prompt} . loose brushwork, vibrant color, light and shadow play, captures feeling over form",
114
+ "negative_prompt": "anime, photorealistic, 35mm film, deformed, glitch, low contrast, noisy"
115
+ },
116
+ {
117
+ "id": "twri-art-pointillism",
118
+ "name": "Art: Pointillism",
119
+ "prompt": "pointillism style {prompt} . composed entirely of small, distinct dots of color, vibrant, highly detailed",
120
+ "negative_prompt": "line drawing, smooth shading, large color fields, simplistic"
121
+ },
122
+ {
123
+ "id": "twri-art-pop-art",
124
+ "name": "Art: Pop Art",
125
+ "prompt": "pop Art style {prompt} . bright colors, bold outlines, popular culture themes, ironic or kitsch",
126
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, minimalist"
127
+ },
128
+ {
129
+ "id": "twri-art-psychedelic",
130
+ "name": "Art: Psychedelic",
131
+ "prompt": "psychedelic style {prompt} . vibrant colors, swirling patterns, abstract forms, surreal, trippy",
132
+ "negative_prompt": "monochrome, black and white, low contrast, realistic, photorealistic, plain, simple"
133
+ },
134
+ {
135
+ "id": "twri-art-renaissance",
136
+ "name": "Art: Renaissance",
137
+ "prompt": "renaissance style {prompt} . realistic, perspective, light and shadow, religious or mythological themes, highly detailed",
138
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, modernist, minimalist, abstract"
139
+ },
140
+ {
141
+ "id": "twri-art-steampunk",
142
+ "name": "Art: Steampunk",
143
+ "prompt": "steampunk style {prompt} . antique, mechanical, brass and copper tones, gears, intricate, detailed",
144
+ "negative_prompt": "deformed, glitch, noisy, low contrast, anime, photorealistic"
145
+ },
146
+ {
147
+ "id": "twri-art-surrealist",
148
+ "name": "Art: Surrealist",
149
+ "prompt": "surrealist art {prompt} . dreamlike, mysterious, provocative, symbolic, intricate, detailed",
150
+ "negative_prompt": "anime, photorealistic, realistic, deformed, glitch, noisy, low contrast"
151
+ },
152
+ {
153
+ "id": "twri-art-typography",
154
+ "name": "Art: Typography",
155
+ "prompt": "typographic art {prompt} . stylized, intricate, detailed, artistic, text-based",
156
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic"
157
+ },
158
+ {
159
+ "id": "twri-art-watercolor",
160
+ "name": "Art: Watercolor",
161
+ "prompt": "watercolor painting {prompt} . vibrant, beautiful, painterly, detailed, textural, artistic",
162
+ "negative_prompt": "anime, photorealistic, 35mm film, deformed, glitch, low contrast, noisy"
163
+ },
164
+ {
165
+ "id": "twri-futuristic-biomechanical",
166
+ "name": "Futuristic: Biomechanical",
167
+ "prompt": "biomechanical style {prompt} . blend of organic and mechanical elements, futuristic, cybernetic, detailed, intricate",
168
+ "negative_prompt": "natural, rustic, primitive, organic, simplistic"
169
+ },
170
+ {
171
+ "id": "twri-futuristic-biomechanical-cyberpunk",
172
+ "name": "Futuristic: Biomechanical Cyberpunk",
173
+ "prompt": "biomechanical cyberpunk {prompt} . cybernetics, human-machine fusion, dystopian, organic meets artificial, dark, intricate, highly detailed",
174
+ "negative_prompt": "natural, colorful, deformed, sketch, low contrast, watercolor"
175
+ },
176
+ {
177
+ "id": "twri-futuristic-cybernetic",
178
+ "name": "Futuristic: Cybernetic",
179
+ "prompt": "cybernetic style {prompt} . futuristic, technological, cybernetic enhancements, robotics, artificial intelligence themes",
180
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, historical, medieval"
181
+ },
182
+ {
183
+ "id": "twri-futuristic-cybernetic-robot",
184
+ "name": "Futuristic: Cybernetic Robot",
185
+ "prompt": "cybernetic robot {prompt} . android, AI, machine, metal, wires, tech, futuristic, highly detailed",
186
+ "negative_prompt": "organic, natural, human, sketch, watercolor, low contrast"
187
+ },
188
+ {
189
+ "id": "twri-futuristic-cyberpunk-cityscape",
190
+ "name": "Futuristic: Cyberpunk Cityscape",
191
+ "prompt": "cyberpunk cityscape {prompt} . neon lights, dark alleys, skyscrapers, futuristic, vibrant colors, high contrast, highly detailed",
192
+ "negative_prompt": "natural, rural, deformed, low contrast, black and white, sketch, watercolor"
193
+ },
194
+ {
195
+ "id": "twri-futuristic-general",
196
+ "name": "Futuristic: General",
197
+ "prompt": "futuristic style {prompt} . sleek, modern, ultramodern, high tech, detailed",
198
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, vintage, antique"
199
+ },
200
+ {
201
+ "id": "twri-futuristic-retro-cyberpunk",
202
+ "name": "Futuristic: Retro Cyberpunk",
203
+ "prompt": "retro cyberpunk {prompt} . 80's inspired, synthwave, neon, vibrant, detailed, retro futurism",
204
+ "negative_prompt": "modern, desaturated, black and white, realism, low contrast"
205
+ },
206
+ {
207
+ "id": "twri-futuristic-retro-futurism",
208
+ "name": "Futuristic: Retro Futurism",
209
+ "prompt": "retro-futuristic {prompt} . vintage sci-fi, 50s and 60s style, atomic age, vibrant, highly detailed",
210
+ "negative_prompt": "contemporary, realistic, rustic, primitive"
211
+ },
212
+ {
213
+ "id": "twri-futuristic-sci-fi",
214
+ "name": "Futuristic: Sci-Fi",
215
+ "prompt": "sci-fi style {prompt} . futuristic, technological, alien worlds, space themes, advanced civilizations",
216
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, historical, medieval"
217
+ },
218
+ {
219
+ "id": "twri-futuristic-vaporwave",
220
+ "name": "Futuristic: Vaporwave",
221
+ "prompt": "vaporwave style {prompt} . retro aesthetic, cyberpunk, vibrant, neon colors, vintage 80s and 90s style, highly detailed",
222
+ "negative_prompt": "monochrome, muted colors, realism, rustic, minimalist, dark"
223
+ },
224
+ {
225
+ "id": "twri-game-bubble-bobble",
226
+ "name": "Game: Bubble Bobble",
227
+ "prompt": "Bubble Bobble style {prompt} . 8-bit, cute, pixelated, fantasy, vibrant, reminiscent of Bubble Bobble game",
228
+ "negative_prompt": "realistic, modern, photorealistic, violent, horror"
229
+ },
230
+ {
231
+ "id": "twri-game-cyberpunk",
232
+ "name": "Game: Cyberpunk",
233
+ "prompt": "cyberpunk game style {prompt} . neon, dystopian, futuristic, digital, vibrant, detailed, high contrast, reminiscent of cyberpunk genre video games",
234
+ "negative_prompt": "historical, natural, rustic, low detailed"
235
+ },
236
+ {
237
+ "id": "twri-game-fighting",
238
+ "name": "Game: Fighting",
239
+ "prompt": "fighting game style {prompt} . dynamic, vibrant, action-packed, detailed character design, reminiscent of fighting video games",
240
+ "negative_prompt": "peaceful, calm, minimalist, photorealistic"
241
+ },
242
+ {
243
+ "id": "twri-game-gta",
244
+ "name": "Game: GTA",
245
+ "prompt": "GTA-style artwork {prompt} . satirical, exaggerated, pop art style, vibrant colors, iconic characters, action-packed",
246
+ "negative_prompt": "realistic, black and white, low contrast, impressionist, cubist, noisy, blurry, deformed"
247
+ },
248
+ {
249
+ "id": "twri-game-mario",
250
+ "name": "Game: Mario",
251
+ "prompt": "Super Mario style {prompt} . vibrant, cute, cartoony, fantasy, playful, reminiscent of Super Mario series",
252
+ "negative_prompt": "realistic, modern, horror, dystopian, violent"
253
+ },
254
+ {
255
+ "id": "twri-game-minecraft",
256
+ "name": "Game: Minecraft",
257
+ "prompt": "Minecraft style {prompt} . blocky, pixelated, vibrant colors, recognizable characters and objects, game assets",
258
+ "negative_prompt": "smooth, realistic, detailed, photorealistic, noise, blurry, deformed"
259
+ },
260
+ {
261
+ "id": "twri-game-pokemon",
262
+ "name": "Game: Pokémon",
263
+ "prompt": "Pokémon style {prompt} . vibrant, cute, anime, fantasy, reminiscent of Pokémon series",
264
+ "negative_prompt": "realistic, modern, horror, dystopian, violent"
265
+ },
266
+ {
267
+ "id": "twri-game-retro",
268
+ "name": "Game: Retro",
269
+ "prompt": "retro game art {prompt} . 16-bit, vibrant colors, pixelated, nostalgic, charming, fun",
270
+ "negative_prompt": "realistic, photorealistic, 35mm film, deformed, glitch, low contrast, noisy"
271
+ },
272
+ {
273
+ "id": "twri-game-retro-arcade",
274
+ "name": "Game: Retro Arcade",
275
+ "prompt": "retro arcade style {prompt} . 8-bit, pixelated, vibrant, classic video game, old school gaming, reminiscent of 80s and 90s arcade games",
276
+ "negative_prompt": "modern, ultra-high resolution, photorealistic, 3D"
277
+ },
278
+ {
279
+ "id": "twri-game-rpg-fantasy",
280
+ "name": "Game: RPG Fantasy",
281
+ "prompt": "role-playing game (RPG) style fantasy {prompt} . detailed, vibrant, immersive, reminiscent of high fantasy RPG games",
282
+ "negative_prompt": "sci-fi, modern, urban, futuristic, low detailed"
283
+ },
284
+ {
285
+ "id": "twri-game-strategy",
286
+ "name": "Game: Strategy",
287
+ "prompt": "strategy game style {prompt} . overhead view, detailed map, units, reminiscent of real-time strategy video games",
288
+ "negative_prompt": "first-person view, modern, photorealistic"
289
+ },
290
+ {
291
+ "id": "twri-game-street-fighter",
292
+ "name": "Game: Street Fighter",
293
+ "prompt": "Street Fighter style {prompt} . vibrant, dynamic, arcade, 2D fighting game, highly detailed, reminiscent of Street Fighter series",
294
+ "negative_prompt": "3D, realistic, modern, photorealistic, turn-based strategy"
295
+ },
296
+ {
297
+ "id": "twri-game-zelda",
298
+ "name": "Game: Zelda",
299
+ "prompt": "Legend of Zelda style {prompt} . vibrant, fantasy, detailed, epic, heroic, reminiscent of The Legend of Zelda series",
300
+ "negative_prompt": "sci-fi, modern, realistic, horror"
301
+ },
302
+ {
303
+ "id": "twri-misc-architectural",
304
+ "name": "Misc: Architectural",
305
+ "prompt": "architectural style {prompt} . clean lines, geometric shapes, minimalist, modern, architectural drawing, highly detailed",
306
+ "negative_prompt": "curved lines, ornate, baroque, abstract, grunge"
307
+ },
308
+ {
309
+ "id": "twri-misc-disco",
310
+ "name": "Misc: Disco",
311
+ "prompt": "disco-themed {prompt} . vibrant, groovy, retro 70s style, shiny disco balls, neon lights, dance floor, highly detailed",
312
+ "negative_prompt": "minimalist, rustic, monochrome, contemporary, simplistic"
313
+ },
314
+ {
315
+ "id": "twri-misc-dreamscape",
316
+ "name": "Misc: Dreamscape",
317
+ "prompt": "dreamscape {prompt} . surreal, ethereal, dreamy, mysterious, fantasy, highly detailed",
318
+ "negative_prompt": "realistic, concrete, ordinary, mundane"
319
+ },
320
+ {
321
+ "id": "twri-misc-dystopian",
322
+ "name": "Misc: Dystopian",
323
+ "prompt": "dystopian style {prompt} . bleak, post-apocalyptic, somber, dramatic, highly detailed",
324
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, cheerful, optimistic, vibrant, colorful"
325
+ },
326
+ {
327
+ "id": "twri-misc-fairy-tale",
328
+ "name": "Misc: Fairy Tale",
329
+ "prompt": "fairy tale {prompt} . magical, fantastical, enchanting, storybook style, highly detailed",
330
+ "negative_prompt": "realistic, modern, ordinary, mundane"
331
+ },
332
+ {
333
+ "id": "twri-misc-gothic",
334
+ "name": "Misc: Gothic",
335
+ "prompt": "gothic style {prompt} . dark, mysterious, haunting, dramatic, ornate, detailed",
336
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, cheerful, optimistic"
337
+ },
338
+ {
339
+ "id": "twri-misc-grunge",
340
+ "name": "Misc: Grunge",
341
+ "prompt": "grunge style {prompt} . textured, distressed, vintage, edgy, punk rock vibe, dirty, noisy",
342
+ "negative_prompt": "smooth, clean, minimalist, sleek, modern, photorealistic"
343
+ },
344
+ {
345
+ "id": "twri-misc-horror",
346
+ "name": "Misc: Horror",
347
+ "prompt": "horror-themed {prompt} . eerie, unsettling, dark, spooky, suspenseful, grim, highly detailed",
348
+ "negative_prompt": "cheerful, bright, vibrant, light-hearted, cute"
349
+ },
350
+ {
351
+ "id": "twri-misc-kawaii",
352
+ "name": "Misc: Kawaii",
353
+ "prompt": "kawaii style {prompt} . cute, adorable, brightly colored, cheerful, anime influence, highly detailed",
354
+ "negative_prompt": "dark, scary, realistic, monochrome, abstract"
355
+ },
356
+ {
357
+ "id": "twri-misc-lovecraftian",
358
+ "name": "Misc: Lovecraftian",
359
+ "prompt": "lovecraftian horror {prompt} . eldritch, cosmic horror, unknown, mysterious, surreal, highly detailed",
360
+ "negative_prompt": "light-hearted, mundane, familiar, simplistic, realistic"
361
+ },
362
+ {
363
+ "id": "twri-misc-macabre",
364
+ "name": "Misc: Macabre",
365
+ "prompt": "macabre style {prompt} . dark, gothic, grim, haunting, highly detailed",
366
+ "negative_prompt": "bright, cheerful, light-hearted, cartoonish, cute"
367
+ },
368
+ {
369
+ "id": "twri-misc-manga",
370
+ "name": "Misc: Manga",
371
+ "prompt": "manga style {prompt} . vibrant, high-energy, detailed, iconic, Japanese comic style",
372
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, Western comic style"
373
+ },
374
+ {
375
+ "id": "twri-misc-metropolis",
376
+ "name": "Misc: Metropolis",
377
+ "prompt": "metropolis-themed {prompt} . urban, cityscape, skyscrapers, modern, futuristic, highly detailed",
378
+ "negative_prompt": "rural, natural, rustic, historical, simple"
379
+ },
380
+ {
381
+ "id": "twri-misc-minimalist",
382
+ "name": "Misc: Minimalist",
383
+ "prompt": "minimalist style {prompt} . simple, clean, uncluttered, modern, elegant",
384
+ "negative_prompt": "ornate, complicated, highly detailed, cluttered, disordered, messy, noisy"
385
+ },
386
+ {
387
+ "id": "twri-misc-monochrome",
388
+ "name": "Misc: Monochrome",
389
+ "prompt": "monochrome {prompt} . black and white, contrast, tone, texture, detailed",
390
+ "negative_prompt": "colorful, vibrant, noisy, blurry, deformed"
391
+ },
392
+ {
393
+ "id": "twri-misc-nautical",
394
+ "name": "Misc: Nautical",
395
+ "prompt": "nautical-themed {prompt} . sea, ocean, ships, maritime, beach, marine life, highly detailed",
396
+ "negative_prompt": "landlocked, desert, mountains, urban, rustic"
397
+ },
398
+ {
399
+ "id": "twri-misc-space",
400
+ "name": "Misc: Space",
401
+ "prompt": "space-themed {prompt} . cosmic, celestial, stars, galaxies, nebulas, planets, science fiction, highly detailed",
402
+ "negative_prompt": "earthly, mundane, ground-based, realism"
403
+ },
404
+ {
405
+ "id": "twri-misc-stained-glass",
406
+ "name": "Misc: Stained Glass",
407
+ "prompt": "stained glass style {prompt} . vibrant, beautiful, translucent, intricate, detailed",
408
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic"
409
+ },
410
+ {
411
+ "id": "twri-misc-techwear-fashion",
412
+ "name": "Misc: Techwear Fashion",
413
+ "prompt": "techwear fashion {prompt} . futuristic, cyberpunk, urban, tactical, sleek, dark, highly detailed",
414
+ "negative_prompt": "vintage, rural, colorful, low contrast, realism, sketch, watercolor"
415
+ },
416
+ {
417
+ "id": "twri-misc-tribal",
418
+ "name": "Misc: Tribal",
419
+ "prompt": "tribal style {prompt} . indigenous, ethnic, traditional patterns, bold, natural colors, highly detailed",
420
+ "negative_prompt": "modern, futuristic, minimalist, pastel"
421
+ },
422
+ {
423
+ "id": "twri-misc-zentangle",
424
+ "name": "Misc: Zentangle",
425
+ "prompt": "zentangle {prompt} . intricate, abstract, monochrome, patterns, meditative, highly detailed",
426
+ "negative_prompt": "colorful, representative, simplistic, large fields of color"
427
+ },
428
+ {
429
+ "id": "twri-papercraft-collage",
430
+ "name": "Papercraft: Collage",
431
+ "prompt": "collage style {prompt} . mixed media, layered, textural, detailed, artistic",
432
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic"
433
+ },
434
+ {
435
+ "id": "twri-papercraft-flat-papercut",
436
+ "name": "Papercraft: Flat Papercut",
437
+ "prompt": "flat papercut style {prompt} . silhouette, clean cuts, paper, sharp edges, minimalist, color block",
438
+ "negative_prompt": "3D, high detail, noise, grainy, blurry, painting, drawing, photo, disfigured"
439
+ },
440
+ {
441
+ "id": "twri-papercraft-kirigami",
442
+ "name": "Papercraft: Kirigami",
443
+ "prompt": "kirigami representation of {prompt} . 3D, paper folding, paper cutting, Japanese, intricate, symmetrical, precision, clean lines",
444
+ "negative_prompt": "painting, drawing, 2D, noisy, blurry, deformed"
445
+ },
446
+ {
447
+ "id": "twri-papercraft-paper-mache",
448
+ "name": "Papercraft: Paper Mache",
449
+ "prompt": "paper mache representation of {prompt} . 3D, sculptural, textured, handmade, vibrant, fun",
450
+ "negative_prompt": "2D, flat, photo, sketch, digital art, deformed, noisy, blurry"
451
+ },
452
+ {
453
+ "id": "twri-papercraft-paper-quilling",
454
+ "name": "Papercraft: Paper Quilling",
455
+ "prompt": "paper quilling art of {prompt} . intricate, delicate, curling, rolling, shaping, coiling, loops, 3D, dimensional, ornamental",
456
+ "negative_prompt": "photo, painting, drawing, 2D, flat, deformed, noisy, blurry"
457
+ },
458
+ {
459
+ "id": "twri-papercraft-papercut-collage",
460
+ "name": "Papercraft: Papercut Collage",
461
+ "prompt": "papercut collage of {prompt} . mixed media, textured paper, overlapping, asymmetrical, abstract, vibrant",
462
+ "negative_prompt": "photo, 3D, realistic, drawing, painting, high detail, disfigured"
463
+ },
464
+ {
465
+ "id": "twri-papercraft-papercut-shadow-box",
466
+ "name": "Papercraft: Papercut Shadow Box",
467
+ "prompt": "3D papercut shadow box of {prompt} . layered, dimensional, depth, silhouette, shadow, papercut, handmade, high contrast",
468
+ "negative_prompt": "painting, drawing, photo, 2D, flat, high detail, blurry, noisy, disfigured"
469
+ },
470
+ {
471
+ "id": "twri-papercraft-stacked-papercut",
472
+ "name": "Papercraft: Stacked Papercut",
473
+ "prompt": "stacked papercut art of {prompt} . 3D, layered, dimensional, depth, precision cut, stacked layers, papercut, high contrast",
474
+ "negative_prompt": "2D, flat, noisy, blurry, painting, drawing, photo, deformed"
475
+ },
476
+ {
477
+ "id": "twri-papercraft-thick-layered-papercut",
478
+ "name": "Papercraft: Thick Layered Papercut",
479
+ "prompt": "thick layered papercut art of {prompt} . deep 3D, volumetric, dimensional, depth, thick paper, high stack, heavy texture, tangible layers",
480
+ "negative_prompt": "2D, flat, thin paper, low stack, smooth texture, painting, drawing, photo, deformed"
481
+ },
482
+ {
483
+ "id": "twri-photo-alien",
484
+ "name": "Photo: Alien",
485
+ "prompt": "alien-themed {prompt} . extraterrestrial, cosmic, otherworldly, mysterious, sci-fi, highly detailed",
486
+ "negative_prompt": "earthly, mundane, common, realistic, simple"
487
+ },
488
+ {
489
+ "id": "twri-photo-film-noir",
490
+ "name": "Photo: Film Noir",
491
+ "prompt": "film noir style {prompt} . monochrome, high contrast, dramatic shadows, 1940s style, mysterious, cinematic",
492
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, vibrant, colorful"
493
+ },
494
+ {
495
+ "id": "twri-photo-glamour",
496
+ "name": "Photo: Glamour",
497
+ "prompt": "glamorous photo {prompt} . high fashion, luxurious, extravagant, stylish, sensual, opulent, elegance, stunning beauty, professional, high contrast, detailed",
498
+ "negative_prompt": "ugly, deformed, noisy, blurry, distorted, grainy, sketch, low contrast, dull, plain, modest"
499
+ },
500
+ {
501
+ "id": "twri-photo-hdr",
502
+ "name": "Photo: HDR",
503
+ "prompt": "HDR photo of {prompt} . High dynamic range, vivid, rich details, clear shadows and highlights, realistic, intense, enhanced contrast, highly detailed",
504
+ "negative_prompt": "flat, low contrast, oversaturated, underexposed, overexposed, blurred, noisy"
505
+ },
506
+ {
507
+ "id": "twri-photo-iphone-photographic",
508
+ "name": "Photo: iPhone Photographic",
509
+ "prompt": "iphone photo {prompt} . large depth of field, deep depth of field, highly detailed",
510
+ "negative_prompt": "drawing, painting, crayon, sketch, graphite, impressionist, noisy, blurry, soft, deformed, ugly, shallow depth of field, bokeh"
511
+ },
512
+ {
513
+ "id": "twri-photo-long-exposure",
514
+ "name": "Photo: Long Exposure",
515
+ "prompt": "long exposure photo of {prompt} . Blurred motion, streaks of light, surreal, dreamy, ghosting effect, highly detailed",
516
+ "negative_prompt": "static, noisy, deformed, shaky, abrupt, flat, low contrast"
517
+ },
518
+ {
519
+ "id": "twri-photo-neon-noir",
520
+ "name": "Photo: Neon Noir",
521
+ "prompt": "neon noir {prompt} . cyberpunk, dark, rainy streets, neon signs, high contrast, low light, vibrant, highly detailed",
522
+ "negative_prompt": "bright, sunny, daytime, low contrast, black and white, sketch, watercolor"
523
+ },
524
+ {
525
+ "id": "twri-photo-silhouette",
526
+ "name": "Photo: Silhouette",
527
+ "prompt": "silhouette style {prompt} . high contrast, minimalistic, black and white, stark, dramatic",
528
+ "negative_prompt": "ugly, deformed, noisy, blurry, low contrast, color, realism, photorealistic"
529
+ },
530
+ {
531
+ "id": "twri-photo-tilt-shift",
532
+ "name": "Photo: Tilt-Shift",
533
+ "prompt": "tilt-shift photo of {prompt} . selective focus, miniature effect, blurred background, highly detailed, vibrant, perspective control",
534
+ "negative_prompt": "blurry, noisy, deformed, flat, low contrast, unrealistic, oversaturated, underexposed"
535
+ },
536
+ {
537
+ "id": "sai-3d-model",
538
+ "name": "SAI: 3D Model",
539
+ "prompt": "professional 3d model {prompt} . octane render, highly detailed, volumetric, dramatic lighting",
540
+ "negative_prompt": "ugly, deformed, noisy, low poly, blurry, painting"
541
+ },
542
+ {
543
+ "id": "sai-analog-film",
544
+ "name": "SAI: Analog Film",
545
+ "prompt": "analog film photo {prompt} . faded film, desaturated, 35mm photo, grainy, vignette, vintage, Kodachrome, Lomography, stained, highly detailed, found footage",
546
+ "negative_prompt": "painting, drawing, illustration, glitch, deformed, mutated, cross-eyed, ugly, disfigured"
547
+ },
548
+ {
549
+ "id": "sai-anime",
550
+ "name": "SAI: Anime",
551
+ "prompt": "anime artwork {prompt} . anime style, key visual, vibrant, studio anime, highly detailed",
552
+ "negative_prompt": "photo, deformed, black and white, realism, disfigured, low contrast"
553
+ },
554
+ {
555
+ "id": "sai-cinematic",
556
+ "name": "SAI: Cinematic",
557
+ "prompt": "cinematic film still {prompt} . shallow depth of field, vignette, highly detailed, high budget, bokeh, cinemascope, moody, epic, gorgeous, film grain, grainy",
558
+ "negative_prompt": "anime, cartoon, graphic, text, painting, crayon, graphite, abstract, glitch, deformed, mutated, ugly, disfigured"
559
+ },
560
+ {
561
+ "id": "sai-comic-book",
562
+ "name": "SAI: Comic Book",
563
+ "prompt": "comic {prompt} . graphic illustration, comic art, graphic novel art, vibrant, highly detailed",
564
+ "negative_prompt": "photograph, deformed, glitch, noisy, realistic, stock photo"
565
+ },
566
+ {
567
+ "id": "sai-craft-clay",
568
+ "name": "SAI: Craft Clay",
569
+ "prompt": "play-doh style {prompt} . sculpture, clay art, centered composition, Claymation",
570
+ "negative_prompt": "sloppy, messy, grainy, highly detailed, ultra textured, photo"
571
+ },
572
+ {
573
+ "id": "sai-digital-art",
574
+ "name": "SAI: Digital Art",
575
+ "prompt": "concept art {prompt} . digital artwork, illustrative, painterly, matte painting, highly detailed",
576
+ "negative_prompt": "photo, photorealistic, realism, ugly"
577
+ },
578
+ {
579
+ "id": "sai-enhance",
580
+ "name": "SAI: Enhance",
581
+ "prompt": "breathtaking {prompt} . award-winning, professional, highly detailed",
582
+ "negative_prompt": "ugly, deformed, noisy, blurry, distorted, grainy"
583
+ },
584
+ {
585
+ "id": "sai-fantasy-art",
586
+ "name": "SAI: Fantasy Art",
587
+ "prompt": "ethereal fantasy concept art of {prompt} . magnificent, celestial, ethereal, painterly, epic, majestic, magical, fantasy art, cover art, dreamy",
588
+ "negative_prompt": "photographic, realistic, realism, 35mm film, dslr, cropped, frame, text, deformed, glitch, noise, noisy, off-center, deformed, cross-eyed, closed eyes, bad anatomy, ugly, disfigured, sloppy, duplicate, mutated, black and white"
589
+ },
590
+ {
591
+ "id": "sai-isometric",
592
+ "name": "SAI: Isometric",
593
+ "prompt": "isometric style {prompt} . vibrant, beautiful, crisp, detailed, ultra detailed, intricate",
594
+ "negative_prompt": "deformed, mutated, ugly, disfigured, blur, blurry, noise, noisy, realistic, photographic"
595
+ },
596
+ {
597
+ "id": "sai-line-art",
598
+ "name": "SAI: Line Art",
599
+ "prompt": "line art drawing {prompt} . professional, sleek, modern, minimalist, graphic, line art, vector graphics",
600
+ "negative_prompt": "anime, photorealistic, 35mm film, deformed, glitch, blurry, noisy, off-center, deformed, cross-eyed, closed eyes, bad anatomy, ugly, disfigured, mutated, realism, realistic, impressionism, expressionism, oil, acrylic"
601
+ },
602
+ {
603
+ "id": "sai-lowpoly",
604
+ "name": "SAI: Lowpoly",
605
+ "prompt": "low-poly style {prompt} . low-poly game art, polygon mesh, jagged, blocky, wireframe edges, centered composition",
606
+ "negative_prompt": "noisy, sloppy, messy, grainy, highly detailed, ultra textured, photo"
607
+ },
608
+ {
609
+ "id": "sai-neonpunk",
610
+ "name": "SAI: Neonpunk",
611
+ "prompt": "neonpunk style {prompt} . cyberpunk, vaporwave, neon, vibes, vibrant, stunningly beautiful, crisp, detailed, sleek, ultramodern, magenta highlights, dark purple shadows, high contrast, cinematic, ultra detailed, intricate, professional",
612
+ "negative_prompt": "painting, drawing, illustration, glitch, deformed, mutated, cross-eyed, ugly, disfigured"
613
+ },
614
+ {
615
+ "id": "sai-origami",
616
+ "name": "SAI: Origami",
617
+ "prompt": "origami style {prompt} . paper art, pleated paper, folded, origami art, pleats, cut and fold, centered composition",
618
+ "negative_prompt": "noisy, sloppy, messy, grainy, highly detailed, ultra textured, photo"
619
+ },
620
+ {
621
+ "id": "sai-photographic",
622
+ "name": "SAI: Photographic",
623
+ "prompt": "cinematic photo {prompt} . 35mm photograph, film, bokeh, professional, 4k, highly detailed",
624
+ "negative_prompt": "drawing, painting, crayon, sketch, graphite, impressionist, noisy, blurry, soft, deformed, ugly"
625
+ },
626
+ {
627
+ "id": "sai-pixel-art",
628
+ "name": "SAI: Pixel Art",
629
+ "prompt": "pixel-art {prompt} . low-res, blocky, pixel art style, 8-bit graphics",
630
+ "negative_prompt": "sloppy, messy, blurry, noisy, highly detailed, ultra textured, photo, realistic"
631
+ },
632
+ {
633
+ "id": "sai-texture",
634
+ "name": "SAI: Texture",
635
+ "prompt": "texture {prompt} top down close-up",
636
+ "negative_prompt": "ugly, deformed, noisy, blurry"
637
+ }
638
+ ]
lib/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from .config import Config
2
+ from .inference import async_call, generate
3
+ from .loader import Loader
4
+ from .upscaler import RealESRGAN
5
+
6
+ __all__ = ["Config", "Loader", "RealESRGAN", "async_call", "generate"]
lib/config.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from types import SimpleNamespace
2
+
3
+ from diffusers import (
4
+ DDIMScheduler,
5
+ DEISMultistepScheduler,
6
+ DPMSolverMultistepScheduler,
7
+ EulerAncestralDiscreteScheduler,
8
+ EulerDiscreteScheduler,
9
+ PNDMScheduler,
10
+ StableDiffusionXLImg2ImgPipeline,
11
+ StableDiffusionXLPipeline,
12
+ )
13
+
14
+ Config = SimpleNamespace(
15
+ MONO_FONTS=["monospace"],
16
+ SANS_FONTS=[
17
+ "sans-serif",
18
+ "Apple Color Emoji",
19
+ "Segoe UI Emoji",
20
+ "Segoe UI Symbol",
21
+ "Noto Color Emoji",
22
+ ],
23
+ PIPELINES={
24
+ "txt2img": StableDiffusionXLPipeline,
25
+ "img2img": StableDiffusionXLImg2ImgPipeline,
26
+ },
27
+ MODEL="fluently/Fluently-XL-Final",
28
+ MODELS=[
29
+ "cagliostrolab/animagine-xl-3.1",
30
+ "fluently/Fluently-XL-Final",
31
+ "RunDiffusion/Juggernaut-XL-v9",
32
+ "stabilityai/stable-diffusion-xl-base-1.0",
33
+ ],
34
+ VAE_MODEL="madebyollin/sdxl-vae-fp16-fix",
35
+ REFINER_MODEL="stabilityai/stable-diffusion-xl-refiner-1.0",
36
+ SCHEDULER="DEIS 2M",
37
+ SCHEDULERS={
38
+ "DDIM": DDIMScheduler,
39
+ "DEIS 2M": DEISMultistepScheduler,
40
+ "DPM++ 2M": DPMSolverMultistepScheduler,
41
+ "Euler": EulerDiscreteScheduler,
42
+ "Euler a": EulerAncestralDiscreteScheduler,
43
+ "PNDM": PNDMScheduler,
44
+ },
45
+ STYLE="sai-enhance",
46
+ WIDTH=896,
47
+ HEIGHT=1152,
48
+ NUM_IMAGES=1,
49
+ SEED=-1,
50
+ GUIDANCE_SCALE=5,
51
+ INFERENCE_STEPS=40,
52
+ DEEPCACHE_INTERVAL=1,
53
+ SCALE=1,
54
+ SCALES=[1, 2, 4],
55
+ )
lib/inference.py ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import functools
2
+ import inspect
3
+ import json
4
+ import re
5
+ import time
6
+ from datetime import datetime
7
+ from itertools import product
8
+ from typing import Callable, TypeVar
9
+
10
+ import anyio
11
+ import spaces
12
+ import torch
13
+ from anyio import Semaphore
14
+ from compel import Compel, ReturnedEmbeddingsType
15
+ from compel.prompt_parser import PromptParser
16
+ from typing_extensions import ParamSpec
17
+
18
+ from .loader import Loader
19
+
20
+ __import__("warnings").filterwarnings("ignore", category=FutureWarning, module="transformers")
21
+ __import__("transformers").logging.set_verbosity_error()
22
+
23
+ T = TypeVar("T")
24
+ P = ParamSpec("P")
25
+
26
+ MAX_CONCURRENT_THREADS = 1
27
+ MAX_THREADS_GUARD = Semaphore(MAX_CONCURRENT_THREADS)
28
+
29
+ with open("./data/styles.json") as f:
30
+ STYLES = json.load(f)
31
+
32
+
33
+ # like the original but supports args and kwargs instead of a dict
34
+ # https://github.com/huggingface/huggingface-inference-toolkit/blob/0.2.0/src/huggingface_inference_toolkit/async_utils.py
35
+ async def async_call(fn: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
36
+ async with MAX_THREADS_GUARD:
37
+ sig = inspect.signature(fn)
38
+ bound_args = sig.bind(*args, **kwargs)
39
+ bound_args.apply_defaults()
40
+ partial_fn = functools.partial(fn, **bound_args.arguments)
41
+ return await anyio.to_thread.run_sync(partial_fn)
42
+
43
+
44
+ # parse prompts with arrays
45
+ def parse_prompt(prompt: str) -> list[str]:
46
+ arrays = re.findall(r"\[\[(.*?)\]\]", prompt)
47
+
48
+ if not arrays:
49
+ return [prompt]
50
+
51
+ tokens = [item.split(",") for item in arrays]
52
+ combinations = list(product(*tokens))
53
+ prompts = []
54
+
55
+ for combo in combinations:
56
+ current_prompt = prompt
57
+ for i, token in enumerate(combo):
58
+ current_prompt = current_prompt.replace(f"[[{arrays[i]}]]", token.strip(), 1)
59
+ prompts.append(current_prompt)
60
+
61
+ return prompts
62
+
63
+
64
+ def apply_style(prompt, style_id, negative=False):
65
+ global STYLES
66
+ if not style_id or style_id == "None":
67
+ return prompt
68
+ for style in STYLES:
69
+ if style["id"] == style_id:
70
+ if negative:
71
+ return prompt + " . " + style["negative_prompt"]
72
+ else:
73
+ return style["prompt"].format(prompt=prompt)
74
+ return prompt
75
+
76
+
77
+ # TODO: fine-tune these
78
+ def gpu_duration(**kwargs):
79
+ duration = 20
80
+ scale = kwargs.get("scale", 1)
81
+ num_images = kwargs.get("num_images", 1)
82
+ if scale == 4:
83
+ duration += 10
84
+ return duration * num_images
85
+
86
+
87
+ @spaces.GPU(duration=gpu_duration)
88
+ def generate(
89
+ positive_prompt,
90
+ negative_prompt="",
91
+ style=None,
92
+ seed=None,
93
+ model="stabilityai/stable-diffusion-xl-base-1.0",
94
+ scheduler="DEIS 2M",
95
+ width=1024,
96
+ height=1024,
97
+ guidance_scale=7.5,
98
+ inference_steps=40,
99
+ deepcache=1,
100
+ scale=1,
101
+ num_images=1,
102
+ use_karras=False,
103
+ use_refiner=True,
104
+ Info: Callable[[str], None] = None,
105
+ Error=Exception,
106
+ progress=None,
107
+ ):
108
+ if not torch.cuda.is_available():
109
+ raise Error("RuntimeError: CUDA not available")
110
+
111
+ # https://pytorch.org/docs/stable/generated/torch.manual_seed.html
112
+ if seed is None or seed < 0:
113
+ seed = int(datetime.now().timestamp() * 1_000_000) % (2**64)
114
+
115
+ EMBEDDINGS_TYPE = ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED
116
+
117
+ KIND = "txt2img"
118
+
119
+ CURRENT_IMAGE = 1
120
+ CURRENT_STEP = 0
121
+
122
+ if progress is not None:
123
+ TQDM = False
124
+ progress((0, inference_steps), desc=f"Generating image {CURRENT_IMAGE}/{num_images}")
125
+ else:
126
+ TQDM = True
127
+
128
+ def callback_on_step_end(pipeline, step, timestep, latents):
129
+ nonlocal CURRENT_IMAGE, CURRENT_STEP
130
+ if progress is None:
131
+ return latents
132
+ strength = 1
133
+ total_steps = min(int(inference_steps * strength), inference_steps)
134
+ CURRENT_STEP += step + 1
135
+ progress(
136
+ (CURRENT_STEP, total_steps),
137
+ desc=f"Generating image {CURRENT_IMAGE}/{num_images}",
138
+ )
139
+ return latents
140
+
141
+ start = time.perf_counter()
142
+ loader = Loader()
143
+ pipe, refiner, upscaler = loader.load(
144
+ KIND,
145
+ model,
146
+ scheduler,
147
+ deepcache,
148
+ scale,
149
+ use_karras,
150
+ use_refiner,
151
+ TQDM,
152
+ )
153
+ # prompt embeds for base and refiner
154
+ compel_1 = Compel(
155
+ text_encoder=[pipe.text_encoder, pipe.text_encoder_2],
156
+ tokenizer=[pipe.tokenizer, pipe.tokenizer_2],
157
+ requires_pooled=[False, True],
158
+ returned_embeddings_type=EMBEDDINGS_TYPE,
159
+ dtype_for_device_getter=lambda _: pipe.dtype,
160
+ device=pipe.device,
161
+ )
162
+ compel_2 = Compel(
163
+ text_encoder=[pipe.text_encoder_2],
164
+ tokenizer=[pipe.tokenizer_2],
165
+ requires_pooled=[True],
166
+ returned_embeddings_type=EMBEDDINGS_TYPE,
167
+ dtype_for_device_getter=lambda _: pipe.dtype,
168
+ device=pipe.device,
169
+ )
170
+
171
+ images = []
172
+ current_seed = seed
173
+
174
+ for i in range(num_images):
175
+ # seeded generator for each iteration
176
+ generator = torch.Generator(device=pipe.device).manual_seed(current_seed)
177
+
178
+ try:
179
+ styled_negative_prompt = apply_style(negative_prompt, style, negative=True)
180
+ all_positive_prompts = parse_prompt(positive_prompt)
181
+ prompt_index = i % len(all_positive_prompts)
182
+ prompt = all_positive_prompts[prompt_index]
183
+ styled_prompt = apply_style(prompt, style)
184
+ conditioning_1, pooled_1 = compel_1([styled_prompt, styled_negative_prompt])
185
+ conditioning_2, pooled_2 = compel_2([styled_prompt, styled_negative_prompt])
186
+ except PromptParser.ParsingException:
187
+ raise Error("ValueError: Invalid prompt")
188
+
189
+ # refiner expects latents; upscaler expects numpy array
190
+ pipe_output_type = "pil"
191
+ refiner_output_type = "pil"
192
+ if refiner:
193
+ pipe_output_type = "latent"
194
+ if scale > 1:
195
+ refiner_output_type = "np"
196
+ else:
197
+ if scale > 1:
198
+ pipe_output_type = "np"
199
+
200
+ pipe_kwargs = {
201
+ "width": width,
202
+ "height": height,
203
+ "denoising_end": 0.8 if refiner else None,
204
+ "generator": generator,
205
+ "output_type": pipe_output_type,
206
+ "guidance_scale": guidance_scale,
207
+ "num_inference_steps": inference_steps,
208
+ "prompt_embeds": conditioning_1[0:1],
209
+ "pooled_prompt_embeds": pooled_1[0:1],
210
+ "negative_prompt_embeds": conditioning_1[1:2],
211
+ "negative_pooled_prompt_embeds": pooled_1[1:2],
212
+ }
213
+
214
+ if progress is not None:
215
+ pipe_kwargs["callback_on_step_end"] = callback_on_step_end
216
+
217
+ try:
218
+ image = pipe(**pipe_kwargs).images[0]
219
+
220
+ refiner_kwargs = {
221
+ "image": image,
222
+ "denoising_start": 0.8,
223
+ "generator": generator,
224
+ "output_type": refiner_output_type,
225
+ "guidance_scale": guidance_scale,
226
+ "num_inference_steps": inference_steps,
227
+ "prompt_embeds": conditioning_2[0:1],
228
+ "pooled_prompt_embeds": pooled_2[0:1],
229
+ "negative_prompt_embeds": conditioning_2[1:2],
230
+ "negative_pooled_prompt_embeds": pooled_2[1:2],
231
+ }
232
+
233
+ if progress is not None:
234
+ refiner_kwargs["callback_on_step_end"] = callback_on_step_end
235
+
236
+ if use_refiner:
237
+ image = refiner(**refiner_kwargs).images[0]
238
+ if scale > 1:
239
+ image = upscaler.predict(image)
240
+ images.append((image, str(current_seed)))
241
+ except Exception as e:
242
+ raise Error(f"RuntimeError: {e}")
243
+ finally:
244
+ # reset step and increment image
245
+ CURRENT_STEP = 0
246
+ CURRENT_IMAGE += 1
247
+ current_seed += 1
248
+
249
+ diff = time.perf_counter() - start
250
+ if Info:
251
+ Info(f"Generated {len(images)} image{'s' if len(images) > 1 else ''} in {diff:.2f}s")
252
+ return images
lib/loader.py ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gc
2
+ from threading import Lock
3
+ from warnings import filterwarnings
4
+
5
+ import torch
6
+ from DeepCache import DeepCacheSDHelper
7
+ from diffusers.models import AutoencoderKL
8
+
9
+ from .config import Config
10
+ from .upscaler import RealESRGAN
11
+
12
+ __import__("diffusers").logging.set_verbosity_error()
13
+ filterwarnings("ignore", category=FutureWarning, module="torch")
14
+ filterwarnings("ignore", category=FutureWarning, module="diffusers")
15
+
16
+
17
+ class Loader:
18
+ _instance = None
19
+ _lock = Lock()
20
+
21
+ def __new__(cls):
22
+ with cls._lock:
23
+ if cls._instance is None:
24
+ cls._instance = super().__new__(cls)
25
+ cls._instance.pipe = None
26
+ cls._instance.model = None
27
+ cls._instance.refiner = None
28
+ cls._instance.upscaler = None
29
+ return cls._instance
30
+
31
+ def _flush(self):
32
+ gc.collect()
33
+ torch.cuda.empty_cache()
34
+ torch.cuda.ipc_collect()
35
+ torch.cuda.reset_max_memory_allocated()
36
+ torch.cuda.reset_peak_memory_stats()
37
+ torch.cuda.synchronize()
38
+
39
+ def _should_unload_pipeline(self, model=""):
40
+ if self.pipe is None:
41
+ return False
42
+ if self.model.lower() != model.lower():
43
+ return True
44
+ return False
45
+
46
+ def _should_unload_refiner(self, refiner):
47
+ if self.refiner is not None and not refiner:
48
+ return True
49
+ return False
50
+
51
+ def _should_unload_upscaler(self, scale=1):
52
+ return self.upscaler is not None and scale == 1
53
+
54
+ def _unload(self, model, refiner, scale):
55
+ to_unload = []
56
+ if self._should_unload_upscaler(scale):
57
+ to_unload.append("upscaler")
58
+ if self._should_unload_refiner(refiner):
59
+ to_unload.append("refiner")
60
+ if self._should_unload_pipeline(model):
61
+ to_unload.append("model")
62
+ to_unload.append("pipe")
63
+ for component in to_unload:
64
+ delattr(self, component)
65
+ self._flush()
66
+ for component in to_unload:
67
+ setattr(self, component, None)
68
+
69
+ def _load_pipeline(self, kind, model, tqdm, **kwargs):
70
+ pipeline = Config.PIPELINES[kind]
71
+ if self.pipe is None:
72
+ try:
73
+ print(f"Loading {model}...")
74
+ self.pipe = pipeline.from_pretrained(model, **kwargs).to("cuda")
75
+ self.model = model
76
+ except Exception as e:
77
+ print(f"Error loading {model}: {e}")
78
+ self.model = None
79
+ self.pipe = None
80
+ return
81
+ if not isinstance(self.pipe, pipeline):
82
+ self.pipe = pipeline.from_pipe(self.pipe).to("cuda")
83
+ if self.pipe is not None:
84
+ self.pipe.set_progress_bar_config(disable=not tqdm)
85
+
86
+ def _load_refiner(self, refiner, tqdm, **kwargs):
87
+ if self.refiner is None and refiner:
88
+ model = Config.REFINER_MODEL
89
+ pipeline = Config.PIPELINES["img2img"]
90
+ try:
91
+ print(f"Loading {model}...")
92
+ self.refiner = pipeline.from_pretrained(model, **kwargs).to("cuda")
93
+ except Exception as e:
94
+ print(f"Error loading {model}: {e}")
95
+ self.refiner = None
96
+ return
97
+ if self.refiner is not None:
98
+ self.refiner.set_progress_bar_config(disable=not tqdm)
99
+
100
+ def _load_upscaler(self, scale=1):
101
+ if scale > 1 and self.upscaler is None:
102
+ print(f"Loading {scale}x upscaler...")
103
+ self.upscaler = RealESRGAN(scale, "cuda")
104
+ self.upscaler.load_weights()
105
+
106
+ def _load_deepcache(self, interval=1):
107
+ has_deepcache = hasattr(self.pipe, "deepcache")
108
+ if has_deepcache and self.pipe.deepcache.params["cache_interval"] == interval:
109
+ return
110
+ if has_deepcache:
111
+ self.pipe.deepcache.disable()
112
+ else:
113
+ self.pipe.deepcache = DeepCacheSDHelper(pipe=self.pipe)
114
+ self.pipe.deepcache.set_params(cache_interval=interval)
115
+ self.pipe.deepcache.enable()
116
+
117
+ def load(self, kind, model, scheduler, deepcache, scale, karras, refiner, tqdm):
118
+ model_lower = model.lower()
119
+
120
+ scheduler_kwargs = {
121
+ "beta_start": 0.00085,
122
+ "beta_end": 0.012,
123
+ "beta_schedule": "scaled_linear",
124
+ "timestep_spacing": "leading",
125
+ "steps_offset": 1,
126
+ }
127
+
128
+ if scheduler not in ["DDIM", "Euler a", "PNDM"]:
129
+ scheduler_kwargs["use_karras_sigmas"] = karras
130
+
131
+ # https://github.com/huggingface/diffusers/blob/8a3f0c1/scripts/convert_original_stable_diffusion_to_diffusers.py#L939
132
+ if scheduler == "DDIM":
133
+ scheduler_kwargs["clip_sample"] = False
134
+ scheduler_kwargs["set_alpha_to_one"] = False
135
+
136
+ # no fp16 variant (already half-precision)
137
+ if model_lower not in ["cagliostrolab/animagine-xl-3.1", "fluently/fluently-xl-final"]:
138
+ variant = "fp16"
139
+ else:
140
+ variant = None
141
+
142
+ dtype = torch.float16
143
+ pipe_kwargs = {
144
+ "variant": variant,
145
+ "torch_dtype": dtype,
146
+ "add_watermarker": False,
147
+ "scheduler": Config.SCHEDULERS[scheduler](**scheduler_kwargs),
148
+ "vae": AutoencoderKL.from_pretrained(Config.VAE_MODEL, torch_dtype=dtype),
149
+ }
150
+
151
+ self._unload(model, refiner, scale)
152
+ self._load_pipeline(kind, model, tqdm, **pipe_kwargs)
153
+
154
+ # error loading model
155
+ if self.pipe is None:
156
+ return None, None, None
157
+
158
+ same_scheduler = isinstance(self.pipe.scheduler, Config.SCHEDULERS[scheduler])
159
+ same_karras = (
160
+ not hasattr(self.pipe.scheduler.config, "use_karras_sigmas")
161
+ or self.pipe.scheduler.config.use_karras_sigmas == karras
162
+ )
163
+
164
+ # same model, different scheduler
165
+ if self.model.lower() == model_lower:
166
+ if not same_scheduler:
167
+ print(f"Switching to {scheduler}...")
168
+ if not same_karras:
169
+ print(f"{'Enabling' if karras else 'Disabling'} Karras sigmas...")
170
+ if not same_scheduler or not same_karras:
171
+ self.pipe.scheduler = Config.SCHEDULERS[scheduler](**scheduler_kwargs)
172
+
173
+ # https://huggingface.co/stabilityai/stable-diffusion-xl-refiner-1.0/blob/main/model_index.json
174
+ refiner_kwargs = {
175
+ "variant": "fp16",
176
+ "torch_dtype": dtype,
177
+ "add_watermarker": False,
178
+ "requires_aesthetics_score": True,
179
+ "force_zeros_for_empty_prompt": False,
180
+ "vae": self.pipe.vae,
181
+ "scheduler": self.pipe.scheduler,
182
+ "tokenizer_2": self.pipe.tokenizer_2,
183
+ "text_encoder_2": self.pipe.text_encoder_2,
184
+ }
185
+
186
+ self._load_refiner(refiner, tqdm, **refiner_kwargs)
187
+ self._load_upscaler(scale)
188
+ self._load_deepcache(deepcache)
189
+ return self.pipe, self.refiner, self.upscaler
lib/upscaler.py ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # BSD 3-Clause License
2
+ #
3
+ # Copyright (c) 2021, Sberbank AI
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # 1. Redistributions of source code must retain the above copyright notice, this
10
+ # list of conditions and the following disclaimer.
11
+ #
12
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ #
16
+ # 3. Neither the name of the copyright holder nor the names of its
17
+ # contributors may be used to endorse or promote products derived from
18
+ # this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ import einops
31
+ import numpy as np
32
+ import torch
33
+ from huggingface_hub import hf_hub_download
34
+ from PIL import Image
35
+ from torch import nn as nn
36
+ from torch.nn import functional as F
37
+ from torch.nn import init as init
38
+ from torch.nn.modules.batchnorm import _BatchNorm
39
+
40
+ # https://huggingface.co/ai-forever/Real-ESRGAN
41
+ HF_MODELS = {
42
+ 2: {
43
+ "repo_id": "ai-forever/Real-ESRGAN",
44
+ "filename": "RealESRGAN_x2.pth",
45
+ },
46
+ 4: {
47
+ "repo_id": "ai-forever/Real-ESRGAN",
48
+ "filename": "RealESRGAN_x4.pth",
49
+ },
50
+ # 8: {
51
+ # "repo_id": "ai-forever/Real-ESRGAN",
52
+ # "filename": "RealESRGAN_x8.pth",
53
+ # },
54
+ }
55
+
56
+
57
+ def pad_reflect(image, pad_size):
58
+ # fmt: off
59
+ image_size = image.shape
60
+ height, width = image_size[:2]
61
+ new_image = np.zeros([height + pad_size * 2, width + pad_size * 2, image_size[2]]).astype(np.uint8)
62
+ new_image[pad_size:-pad_size, pad_size:-pad_size, :] = image
63
+ new_image[0:pad_size, pad_size:-pad_size, :] = np.flip(image[0:pad_size, :, :], axis=0) # top
64
+ new_image[-pad_size:, pad_size:-pad_size, :] = np.flip(image[-pad_size:, :, :], axis=0) # bottom
65
+ new_image[:, 0:pad_size, :] = np.flip(new_image[:, pad_size : pad_size * 2, :], axis=1) # left
66
+ new_image[:, -pad_size:, :] = np.flip(new_image[:, -pad_size * 2 : -pad_size, :], axis=1) # right
67
+ return new_image
68
+ # fmt: on
69
+
70
+
71
+ def unpad_image(image, pad_size):
72
+ return image[pad_size:-pad_size, pad_size:-pad_size, :]
73
+
74
+
75
+ def pad_patch(image_patch, padding_size, channel_last=True):
76
+ if channel_last:
77
+ return np.pad(
78
+ image_patch,
79
+ ((padding_size, padding_size), (padding_size, padding_size), (0, 0)),
80
+ "edge",
81
+ )
82
+ else:
83
+ return np.pad(
84
+ image_patch,
85
+ ((0, 0), (padding_size, padding_size), (padding_size, padding_size)),
86
+ "edge",
87
+ )
88
+
89
+
90
+ def unpad_patches(image_patches, padding_size):
91
+ return image_patches[:, padding_size:-padding_size, padding_size:-padding_size, :]
92
+
93
+
94
+ def split_image_into_overlapping_patches(image_array, patch_size, padding_size=2):
95
+ xmax, ymax, _ = image_array.shape
96
+ x_remainder = xmax % patch_size
97
+ y_remainder = ymax % patch_size
98
+
99
+ # modulo here is to avoid extending of patch_size instead of 0
100
+ x_extend = (patch_size - x_remainder) % patch_size
101
+ y_extend = (patch_size - y_remainder) % patch_size
102
+
103
+ # make sure the image is divisible into regular patches
104
+ extended_image = np.pad(image_array, ((0, x_extend), (0, y_extend), (0, 0)), "edge")
105
+
106
+ # add padding around the image to simplify computations
107
+ padded_image = pad_patch(extended_image, padding_size, channel_last=True)
108
+
109
+ patches = []
110
+ xmax, ymax, _ = padded_image.shape
111
+ x_lefts = range(padding_size, xmax - padding_size, patch_size)
112
+ y_tops = range(padding_size, ymax - padding_size, patch_size)
113
+
114
+ for x in x_lefts:
115
+ for y in y_tops:
116
+ x_left = x - padding_size
117
+ y_top = y - padding_size
118
+ x_right = x + patch_size + padding_size
119
+ y_bottom = y + patch_size + padding_size
120
+ patch = padded_image[x_left:x_right, y_top:y_bottom, :]
121
+ patches.append(patch)
122
+ return np.array(patches), padded_image.shape
123
+
124
+
125
+ def stitch_together(patches, padded_image_shape, target_shape, padding_size=4):
126
+ xmax, ymax, _ = padded_image_shape
127
+ patches = unpad_patches(patches, padding_size)
128
+ patch_size = patches.shape[1]
129
+ n_patches_per_row = ymax // patch_size
130
+ complete_image = np.zeros((xmax, ymax, 3))
131
+
132
+ row = -1
133
+ col = 0
134
+ for i in range(len(patches)):
135
+ if i % n_patches_per_row == 0:
136
+ row += 1
137
+ col = 0
138
+ complete_image[
139
+ row * patch_size : (row + 1) * patch_size, col * patch_size : (col + 1) * patch_size, :
140
+ ] = patches[i]
141
+ col += 1
142
+ return complete_image[0 : target_shape[0], 0 : target_shape[1], :]
143
+
144
+
145
+ @torch.no_grad()
146
+ def default_init_weights(module_list, scale=1, bias_fill=0, **kwargs):
147
+ if not isinstance(module_list, list):
148
+ module_list = [module_list]
149
+ for module in module_list:
150
+ for m in module.modules():
151
+ if isinstance(m, nn.Conv2d):
152
+ init.kaiming_normal_(m.weight, **kwargs)
153
+ m.weight.data *= scale
154
+ if m.bias is not None:
155
+ m.bias.data.fill_(bias_fill)
156
+ elif isinstance(m, nn.Linear):
157
+ init.kaiming_normal_(m.weight, **kwargs)
158
+ m.weight.data *= scale
159
+ if m.bias is not None:
160
+ m.bias.data.fill_(bias_fill)
161
+ elif isinstance(m, _BatchNorm):
162
+ init.constant_(m.weight, 1)
163
+ if m.bias is not None:
164
+ m.bias.data.fill_(bias_fill)
165
+
166
+
167
+ def make_layer(basic_block, num_basic_block, **kwarg):
168
+ layers = []
169
+ for _ in range(num_basic_block):
170
+ layers.append(basic_block(**kwarg))
171
+ return nn.Sequential(*layers)
172
+
173
+
174
+ def pixel_unshuffle(x, scale):
175
+ _, _, h, w = x.shape
176
+ assert h % scale == 0 and w % scale == 0, "Height and width must be divisible by scale"
177
+ return einops.rearrange(
178
+ x,
179
+ "b c (h s1) (w s2) -> b (c s1 s2) h w",
180
+ s1=scale,
181
+ s2=scale,
182
+ )
183
+
184
+
185
+ class ResidualDenseBlock(nn.Module):
186
+ def __init__(self, num_feat=64, num_grow_ch=32):
187
+ super(ResidualDenseBlock, self).__init__()
188
+ self.conv1 = nn.Conv2d(num_feat, num_grow_ch, 3, 1, 1)
189
+ self.conv2 = nn.Conv2d(num_feat + num_grow_ch, num_grow_ch, 3, 1, 1)
190
+ self.conv3 = nn.Conv2d(num_feat + 2 * num_grow_ch, num_grow_ch, 3, 1, 1)
191
+ self.conv4 = nn.Conv2d(num_feat + 3 * num_grow_ch, num_grow_ch, 3, 1, 1)
192
+ self.conv5 = nn.Conv2d(num_feat + 4 * num_grow_ch, num_feat, 3, 1, 1)
193
+ self.lrelu = nn.LeakyReLU(negative_slope=0.2, inplace=True)
194
+ default_init_weights([self.conv1, self.conv2, self.conv3, self.conv4, self.conv5], 0.1)
195
+
196
+ def forward(self, x):
197
+ x1 = self.lrelu(self.conv1(x))
198
+ x2 = self.lrelu(self.conv2(torch.cat((x, x1), 1)))
199
+ x3 = self.lrelu(self.conv3(torch.cat((x, x1, x2), 1)))
200
+ x4 = self.lrelu(self.conv4(torch.cat((x, x1, x2, x3), 1)))
201
+ x5 = self.conv5(torch.cat((x, x1, x2, x3, x4), 1))
202
+ return x5 * 0.2 + x # scale the residual by a factor of 0.2
203
+
204
+
205
+ class RRDB(nn.Module):
206
+ def __init__(self, num_feat, num_grow_ch=32):
207
+ super(RRDB, self).__init__()
208
+ self.rdb1 = ResidualDenseBlock(num_feat, num_grow_ch)
209
+ self.rdb2 = ResidualDenseBlock(num_feat, num_grow_ch)
210
+ self.rdb3 = ResidualDenseBlock(num_feat, num_grow_ch)
211
+
212
+ def forward(self, x):
213
+ out = self.rdb1(x)
214
+ out = self.rdb2(out)
215
+ out = self.rdb3(out)
216
+ return out * 0.2 + x # scale the residual by a factor of 0.2
217
+
218
+
219
+ class RRDBNet(nn.Module):
220
+ def __init__(self, num_in_ch, num_out_ch, scale=4, num_feat=64, num_block=23, num_grow_ch=32):
221
+ super(RRDBNet, self).__init__()
222
+ self.scale = scale
223
+ if scale == 2:
224
+ num_in_ch = num_in_ch * 4
225
+ elif scale == 1:
226
+ num_in_ch = num_in_ch * 16
227
+ self.conv_first = nn.Conv2d(num_in_ch, num_feat, 3, 1, 1)
228
+ self.body = make_layer(RRDB, num_block, num_feat=num_feat, num_grow_ch=num_grow_ch)
229
+ self.conv_body = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
230
+ self.conv_up1 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
231
+ self.conv_up2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
232
+ if scale == 8:
233
+ self.conv_up3 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
234
+ self.conv_hr = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
235
+ self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
236
+ self.lrelu = nn.LeakyReLU(negative_slope=0.2, inplace=True)
237
+
238
+ def forward(self, x):
239
+ if self.scale == 2:
240
+ feat = pixel_unshuffle(x, scale=2)
241
+ elif self.scale == 1:
242
+ feat = pixel_unshuffle(x, scale=4)
243
+ else:
244
+ feat = x
245
+ feat = self.conv_first(feat)
246
+ body_feat = self.conv_body(self.body(feat))
247
+ feat = feat + body_feat
248
+ feat = self.lrelu(self.conv_up1(F.interpolate(feat, scale_factor=2, mode="nearest")))
249
+ feat = self.lrelu(self.conv_up2(F.interpolate(feat, scale_factor=2, mode="nearest")))
250
+ if self.scale == 8:
251
+ feat = self.lrelu(self.conv_up3(F.interpolate(feat, scale_factor=2, mode="nearest")))
252
+ out = self.conv_last(self.lrelu(self.conv_hr(feat)))
253
+ return out
254
+
255
+
256
+ class RealESRGAN:
257
+ def __init__(self, scale=2, device=None):
258
+ self.device = device
259
+ self.scale = scale
260
+ self.model = RRDBNet(
261
+ num_in_ch=3,
262
+ num_out_ch=3,
263
+ num_feat=64,
264
+ num_block=23,
265
+ num_grow_ch=32,
266
+ scale=scale,
267
+ )
268
+
269
+ def load_weights(self):
270
+ assert self.scale in [2, 4], "You can download models only with scales: 2, 4"
271
+ config = HF_MODELS[self.scale]
272
+ cache_path = hf_hub_download(config["repo_id"], filename=config["filename"])
273
+ loadnet = torch.load(cache_path)
274
+ if "params" in loadnet:
275
+ self.model.load_state_dict(loadnet["params"], strict=True)
276
+ elif "params_ema" in loadnet:
277
+ self.model.load_state_dict(loadnet["params_ema"], strict=True)
278
+ else:
279
+ self.model.load_state_dict(loadnet, strict=True)
280
+ self.model.eval().to(device=self.device)
281
+
282
+ @torch.cuda.amp.autocast()
283
+ def predict(self, lr_image, batch_size=4, patches_size=192, padding=24, pad_size=15):
284
+ scale = self.scale
285
+ if not isinstance(lr_image, np.ndarray):
286
+ lr_image = np.array(lr_image)
287
+ if lr_image.min() < 0.0:
288
+ lr_image = (lr_image + 1.0) / 2.0
289
+ if lr_image.max() <= 1.0:
290
+ lr_image = lr_image * 255.0
291
+ lr_image = pad_reflect(lr_image, pad_size)
292
+ patches, p_shape = split_image_into_overlapping_patches(
293
+ lr_image,
294
+ patch_size=patches_size,
295
+ padding_size=padding,
296
+ )
297
+ patches = torch.Tensor(patches / 255.0)
298
+ image = einops.rearrange(patches, "b h w c -> b c h w").to(device=self.device)
299
+
300
+ with torch.inference_mode():
301
+ res = self.model(image[0:batch_size])
302
+ for i in range(batch_size, image.shape[0], batch_size):
303
+ res = torch.cat((res, self.model(image[i : i + batch_size])), 0)
304
+
305
+ sr_image = einops.rearrange(res.clamp(0, 1), "b c h w -> b h w c").cpu().numpy()
306
+ padded_size_scaled = tuple(np.multiply(p_shape[0:2], scale)) + (3,)
307
+ scaled_image_shape = tuple(np.multiply(lr_image.shape[0:2], scale)) + (3,)
308
+ sr_image = stitch_together(
309
+ sr_image,
310
+ padded_image_shape=padded_size_scaled,
311
+ target_shape=scaled_image_shape,
312
+ padding_size=padding * scale,
313
+ )
314
+ sr_image = (sr_image * 255).astype(np.uint8)
315
+ sr_image = unpad_image(sr_image, pad_size * scale)
316
+ sr_image = Image.fromarray(sr_image)
317
+ return sr_image
partials/head.html ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <style>
2
+ /* gradio styles go in head */
3
+ @media (min-width: 1536px) {
4
+ gradio-app > .gradio-container {
5
+ max-width: 1280px !important;
6
+ }
7
+ }
8
+ </style>
partials/intro.html ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id="intro">
2
+ <div>
3
+ <h1>
4
+ Diffusion&nbsp;<span>XL</span>
5
+ </h1>
6
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 15 15">
7
+ <path d="M7.48877 6.75C7.29015 6.75 7.09967 6.82902 6.95923 6.96967C6.81879 7.11032 6.73989 7.30109 6.73989 7.5C6.73989 7.69891 6.81879 7.88968 6.95923 8.03033C7.09967 8.17098 7.29015 8.25 7.48877 8.25C7.68738 8.25 7.87786 8.17098 8.0183 8.03033C8.15874 7.88968 8.23764 7.69891 8.23764 7.5C8.23764 7.30109 8.15874 7.11032 8.0183 6.96967C7.87786 6.82902 7.68738 6.75 7.48877 6.75ZM7.8632 0C11.2331 0 11.3155 2.6775 9.54818 3.5625C8.80679 3.93 8.47728 4.7175 8.335 5.415C8.69446 5.565 9.00899 5.7975 9.24863 6.0975C12.0195 4.5975 15 5.19 15 7.875C15 11.25 12.3265 11.325 11.4428 9.5475C11.0684 8.805 10.2746 8.475 9.57813 8.3325C9.42836 8.6925 9.19621 9 8.89665 9.255C10.3869 12.0225 9.79531 15 7.11433 15C3.74438 15 3.67698 12.315 5.44433 11.43C6.17823 11.0625 6.50774 10.2825 6.65751 9.5925C6.29056 9.4425 5.96855 9.2025 5.72891 8.9025C2.96555 10.3875 0 9.8025 0 7.125C0 3.75 2.666 3.6675 3.54967 5.445C3.92411 6.1875 4.71043 6.51 5.40689 6.6525C5.54918 6.2925 5.78882 5.9775 6.09586 5.7375C4.60559 2.97 5.1972 0 7.8632 0Z"></path>
8
+ </svg>
9
+ </div>
10
+ <div>
11
+ <nav>
12
+ <a href="https://huggingface.co/spaces/adamelliotfields/diffusion" target="_blank" rel="noopener noreferrer">1.5</a>
13
+ <span>XL</span>
14
+ <a href="https://huggingface.co/spaces/adamelliotfields/diffusion-flux" target="_blank" rel="noopener noreferrer">FLUX.1</a>
15
+ <a href="https://huggingface.co/spaces/adamelliotfields/diffusion/blob/main/DOCS.md" target="_blank" rel="noopener noreferrer">Docs</a>
16
+ <a href="https://adamelliotfields-diffusion-xl.hf.space" target="_blank" rel="noopener noreferrer">
17
+ <svg style="display: inline-block" width="14px" height="14px" viewBox="0 0 12 12" fill="currentColor" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet">
18
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 1.75H9.75C9.88807 1.75 10 1.86193 10 2V4.25C10 4.38807 9.88807 4.5 9.75 4.5C9.61193 4.5 9.5 4.38807 9.5 4.25V2.60355L6.42678 5.67678C6.32915 5.77441 6.17085 5.77441 6.07322 5.67678C5.97559 5.57915 5.97559 5.42085 6.07322 5.32322L9.14645 2.25H7.5C7.36193 2.25 7.25 2.13807 7.25 2C7.25 1.86193 7.36193 1.75 7.5 1.75Z" fill="currentColor"></path>
19
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.5C6 2.22386 5.77614 2 5.5 2H2.69388C2.50985 2 2.33336 2.07311 2.20323 2.20323C2.0731 2.33336 2 2.50986 2 2.69389V8.93885C2 9.12288 2.0731 9.29933 2.20323 9.42953C2.33336 9.55963 2.50985 9.63273 2.69388 9.63273H8.93884C9.12287 9.63273 9.29941 9.55963 9.42951 9.42953C9.55961 9.29933 9.63271 9.12288 9.63271 8.93885V6.5C9.63271 6.22386 9.40885 6 9.13271 6C8.85657 6 8.63271 6.22386 8.63271 6.5V8.63273H3V3H5.5C5.77614 3 6 2.77614 6 2.5Z" fill="currentColor" fill-opacity="0.3"></path>
20
+ </svg>
21
+ </a>
22
+ </nav>
23
+ </div>
24
+ </div>
requirements.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ anyio==4.4.0
2
+ accelerate
3
+ einops==0.8.0
4
+ compel==2.0.3
5
+ deepcache==0.1.1
6
+ diffusers==0.30.2
7
+ hf-transfer
8
+ gradio==4.41.0
9
+ numpy==1.26.4
10
+ ruff==0.5.7
11
+ spaces
12
+ torch==2.2.0
13
+ torchvision==0.17.0
14
+ transformers==4.43.4
15
+ # TODO: unpin once fixed upstream
16
+ # https://github.com/gradio-app/gradio/issues/9278
17
+ fastapi==0.112.2
ruff.toml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ extend-include = ["*.ipynb"]
2
+
3
+ line-length = 110
4
+
5
+ [lint]
6
+ ignore = ["F401"]
7
+
8
+ [lint.per-file-ignores]
9
+ "*.ipynb" = ["E402"]