enzokro commited on
Commit
9e188c8
1 Parent(s): 5ca3a98

initial app test

Browse files
Files changed (3) hide show
  1. app.ipynb +263 -0
  2. app.py +170 -3
  3. requirements.txt +6 -0
app.ipynb ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "#| default_exp app"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "execution_count": 2,
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "#| export\n",
19
+ "import gradio as gr\n",
20
+ "import cf_guidance\n",
21
+ "import min_diffusion\n",
22
+ "import torch\n",
23
+ "import nbdev"
24
+ ]
25
+ },
26
+ {
27
+ "cell_type": "code",
28
+ "execution_count": 3,
29
+ "metadata": {},
30
+ "outputs": [],
31
+ "source": [
32
+ "#| export\n",
33
+ "\n",
34
+ "## MODEL SETUP\n",
35
+ "######################################\n",
36
+ "######################################\n",
37
+ "model_name = 'stabilityai/stable-diffusion-2'\n",
38
+ "revision = 'fp16'\n",
39
+ "dtype = torch.float16\n",
40
+ "device = ('cpu','cuda')[torch.cuda.is_available()]\n",
41
+ "\n",
42
+ "# model parameters\n",
43
+ "better_vae = ''\n",
44
+ "unet_attn_slice = True\n",
45
+ "sampler_kls = 'dpm_multi'\n",
46
+ "hf_sampler = 'dpm_multi'\n",
47
+ "\n",
48
+ "model_kwargs = {\n",
49
+ " 'better_vae': better_vae,\n",
50
+ " 'unet_attn_slice': unet_attn_slice,\n",
51
+ " 'sampler_kls': hf_sampler,\n",
52
+ "}\n",
53
+ "\n",
54
+ "def load_model():\n",
55
+ " pipeline = min_diffusion.core.MinimalDiffusion(\n",
56
+ " model_name,\n",
57
+ " device,\n",
58
+ " dtype,\n",
59
+ " revision,\n",
60
+ " **model_kwargs,\n",
61
+ " )\n",
62
+ " pipeline.load()\n",
63
+ " return pipeline\n",
64
+ "######################################\n",
65
+ "######################################"
66
+ ]
67
+ },
68
+ {
69
+ "cell_type": "code",
70
+ "execution_count": null,
71
+ "metadata": {},
72
+ "outputs": [],
73
+ "source": [
74
+ "#| export \n",
75
+ "\n",
76
+ "## GENERATION PARAMETERS\n",
77
+ "######################################\n",
78
+ "######################################\n",
79
+ "num_steps = 18\n",
80
+ "height, width = 768, 768\n",
81
+ "k_sampler = 'k_dpmpp_2m' #'k_dpmpp_sde'\n",
82
+ "use_karras_sigmas = True\n",
83
+ "\n",
84
+ "# a good negative prompt\n",
85
+ "NEG_PROMPT = \"ugly, stock photo, tiling, poorly drawn hands, poorly drawn feet, poorly drawn face, out of frame, mutation, mutated, extra limbs, extra legs, extra arms, disfigured, deformed, cross-eye, body out of frame, blurry, bad art, bad anatomy, blurred, text, watermark, grainy\"\n",
86
+ "\n",
87
+ "generation_kwargs = {\n",
88
+ " 'num_steps': num_steps,\n",
89
+ " 'height': height,\n",
90
+ " 'width': width,\n",
91
+ " 'k_sampler': k_sampler,\n",
92
+ " 'negative_prompt': NEG_PROMPT,\n",
93
+ " 'use_karras_sigmas': use_karras_sigmas,\n",
94
+ "}\n",
95
+ "######################################\n",
96
+ "######################################"
97
+ ]
98
+ },
99
+ {
100
+ "cell_type": "code",
101
+ "execution_count": null,
102
+ "metadata": {},
103
+ "outputs": [],
104
+ "source": [
105
+ "#| export \n",
106
+ "\n",
107
+ "## dynamicCFG SETUP\n",
108
+ "######################################\n",
109
+ "######################################\n",
110
+ "\n",
111
+ "# default cosine schedule parameters\n",
112
+ "baseline_g = 9 # default, static guidance value\n",
113
+ "max_val = 9 # the max scheduled guidance scaling value\n",
114
+ "min_val = 6 # the minimum scheduled guidance value\n",
115
+ "num_warmup_steps = 0 # number of warmup steps\n",
116
+ "warmup_init_val = 0 # the intial warmup value\n",
117
+ "num_cycles = 0.5 # number of cosine cycles\n",
118
+ "k_decay = 1 # k-decay for cosine curve scaling \n",
119
+ "\n",
120
+ "# group the default schedule parameters\n",
121
+ "DEFAULT_COS_PARAMS = {\n",
122
+ " 'max_val': max_val,\n",
123
+ " 'num_steps': num_steps,\n",
124
+ " 'min_val': min_val,\n",
125
+ " 'num_cycles': num_cycles,\n",
126
+ " 'k_decay': k_decay,\n",
127
+ " 'num_warmup_steps': num_warmup_steps,\n",
128
+ " 'warmup_init_val': warmup_init_val,\n",
129
+ "}\n",
130
+ "\n",
131
+ "def cos_harness(new_params: dict) -> dict:\n",
132
+ " '''Creates cosine schedules with updated parameters in `new_params`\n",
133
+ " '''\n",
134
+ " # start from the given baseline `default_params`\n",
135
+ " cos_params = dict(DEFAULT_COS_PARAMS)\n",
136
+ " # update the with the new, given parameters\n",
137
+ " cos_params.update(new_params)\n",
138
+ " \n",
139
+ " # return the new cosine schedule\n",
140
+ " sched = cf_guidance.schedules.get_cos_sched(**cos_params)\n",
141
+ " return sched\n",
142
+ "\n",
143
+ "\n",
144
+ "# build the static schedule\n",
145
+ "static_sched = [baseline_g] * num_steps\n",
146
+ "\n",
147
+ "# build the inverted kdecay schedule\n",
148
+ "k_sched = cos_harness({'k_decay': 0.2})\n",
149
+ "inv_k_sched = [max_val - g + min_val for g in k_sched]\n",
150
+ "\n",
151
+ "# group the schedules \n",
152
+ "schedules = {\n",
153
+ " 'cosine': {'g': inv_k_sched},\n",
154
+ " 'static': {'g': static_sched},\n",
155
+ "}\n",
156
+ "######################################\n",
157
+ "######################################"
158
+ ]
159
+ },
160
+ {
161
+ "cell_type": "code",
162
+ "execution_count": null,
163
+ "metadata": {},
164
+ "outputs": [],
165
+ "source": [
166
+ "#| export \n",
167
+ "\n",
168
+ "def compare_dynamic_guidance(prompt):\n",
169
+ " '''\n",
170
+ " Compares the default, static Classifier-free Guidance to a dynamic schedule. \n",
171
+ "\n",
172
+ " Model and sampling paramters:\n",
173
+ " Stable Diffusion 2 v-model\n",
174
+ " Half-precision\n",
175
+ " DPM++ 2M sampler, with Karras sigma schedule\n",
176
+ " 18 sampling steps\n",
177
+ " (768 x 768) image\n",
178
+ " Using a generic negative prompt\n",
179
+ "\n",
180
+ " Schedules:\n",
181
+ " Static guidance with scale of 9\n",
182
+ " Inverse kDecay (cosine variant) scheduled guidance\n",
183
+ " '''\n",
184
+ " # load the model\n",
185
+ " pipeline = load_model()\n",
186
+ "\n",
187
+ " # stores the output images\n",
188
+ " res = []\n",
189
+ "\n",
190
+ " # generate images with static and dynamic schedules\n",
191
+ " for (name,sched) in schedules.items():\n",
192
+ " # make the guidance norm\n",
193
+ " gtfm = cf_guidance.transforms.GuidanceTfm(sched)\n",
194
+ " # generate the image\n",
195
+ " with torch.autocast(device), torch.no_grad():\n",
196
+ " img = pipeline.generate(prompt, gtfm, **generation_kwargs)\n",
197
+ " # add the generated image\n",
198
+ " res.append(name)\n",
199
+ "\n",
200
+ " # return the generated images\n",
201
+ " return {\n",
202
+ " 'values': res,\n",
203
+ " 'label': 'Cosine vs. Static CFG'\n",
204
+ " }"
205
+ ]
206
+ },
207
+ {
208
+ "cell_type": "code",
209
+ "execution_count": 4,
210
+ "metadata": {},
211
+ "outputs": [],
212
+ "source": [
213
+ "\n",
214
+ "#| export\n",
215
+ "\n",
216
+ "iface = gr.Interface(\n",
217
+ " compare_dynamic_guidance,\n",
218
+ " inputs=\"text\",\n",
219
+ " outputs=gr.Gallery(),\n",
220
+ " title=\"Comparison with dynamic Classifier-free Guidance Comparison\",\n",
221
+ ")\n",
222
+ "iface.launch()\n"
223
+ ]
224
+ },
225
+ {
226
+ "cell_type": "code",
227
+ "execution_count": 8,
228
+ "metadata": {},
229
+ "outputs": [],
230
+ "source": [
231
+ "import nbdev\n",
232
+ "nbdev.export.nb_export('app.ipynb', '')"
233
+ ]
234
+ }
235
+ ],
236
+ "metadata": {
237
+ "kernelspec": {
238
+ "display_name": "sdiffkernel",
239
+ "language": "python",
240
+ "name": "sdiffkernel"
241
+ },
242
+ "language_info": {
243
+ "codemirror_mode": {
244
+ "name": "ipython",
245
+ "version": 3
246
+ },
247
+ "file_extension": ".py",
248
+ "mimetype": "text/x-python",
249
+ "name": "python",
250
+ "nbconvert_exporter": "python",
251
+ "pygments_lexer": "ipython3",
252
+ "version": "3.10.8"
253
+ },
254
+ "orig_nbformat": 4,
255
+ "vscode": {
256
+ "interpreter": {
257
+ "hash": "7aa72ffd68a1153f913726b8656445c52d825f656451987cb25ebe84c64ea44d"
258
+ }
259
+ }
260
+ },
261
+ "nbformat": 4,
262
+ "nbformat_minor": 2
263
+ }
app.py CHANGED
@@ -1,7 +1,174 @@
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
- def greet(name):
4
- return "Hello " + name + "!!"
 
 
 
 
 
 
 
 
 
5
 
6
- iface = gr.Interface(fn=greet, inputs="text", outputs="text")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  iface.launch()
 
 
1
+ # AUTOGENERATED! DO NOT EDIT! File to edit: app.ipynb.
2
+
3
+ # %% auto 0
4
+ __all__ = ['model_name', 'revision', 'dtype', 'device', 'better_vae', 'unet_attn_slice', 'sampler_kls', 'hf_sampler',
5
+ 'model_kwargs', 'num_steps', 'height', 'width', 'k_sampler', 'use_karras_sigmas', 'NEG_PROMPT',
6
+ 'generation_kwargs', 'baseline_g', 'max_val', 'min_val', 'num_warmup_steps', 'warmup_init_val', 'num_cycles',
7
+ 'k_decay', 'DEFAULT_COS_PARAMS', 'static_sched', 'k_sched', 'inv_k_sched', 'schedules', 'iface',
8
+ 'load_model', 'cos_harness', 'compare_dynamic_guidance']
9
+
10
+ # %% app.ipynb 1
11
  import gradio as gr
12
+ import cf_guidance
13
+ import min_diffusion
14
+ import torch
15
+ import nbdev
16
+
17
+ # %% app.ipynb 2
18
+ ## MODEL SETUP
19
+ ######################################
20
+ ######################################
21
+ model_name = 'stabilityai/stable-diffusion-2'
22
+ revision = 'fp16'
23
+ dtype = torch.float16
24
+ device = ('cpu','cuda')[torch.cuda.is_available()]
25
+
26
+ # model parameters
27
+ better_vae = ''
28
+ unet_attn_slice = True
29
+ sampler_kls = 'dpm_multi'
30
+ hf_sampler = 'dpm_multi'
31
+
32
+ model_kwargs = {
33
+ 'better_vae': better_vae,
34
+ 'unet_attn_slice': unet_attn_slice,
35
+ 'sampler_kls': hf_sampler,
36
+ }
37
+
38
+ def load_model():
39
+ pipeline = min_diffusion.core.MinimalDiffusion(
40
+ model_name,
41
+ device,
42
+ dtype,
43
+ revision,
44
+ **model_kwargs,
45
+ )
46
+ pipeline.load()
47
+ return pipeline
48
+ ######################################
49
+ ######################################
50
+
51
+ # %% app.ipynb 3
52
+ ## GENERATION PARAMETERS
53
+ ######################################
54
+ ######################################
55
+ num_steps = 18
56
+ height, width = 768, 768
57
+ k_sampler = 'k_dpmpp_2m' #'k_dpmpp_sde'
58
+ use_karras_sigmas = True
59
+
60
+ # a good negative prompt
61
+ NEG_PROMPT = "ugly, stock photo, tiling, poorly drawn hands, poorly drawn feet, poorly drawn face, out of frame, mutation, mutated, extra limbs, extra legs, extra arms, disfigured, deformed, cross-eye, body out of frame, blurry, bad art, bad anatomy, blurred, text, watermark, grainy"
62
+
63
+ generation_kwargs = {
64
+ 'num_steps': num_steps,
65
+ 'height': height,
66
+ 'width': width,
67
+ 'k_sampler': k_sampler,
68
+ 'negative_prompt': NEG_PROMPT,
69
+ 'use_karras_sigmas': use_karras_sigmas,
70
+ }
71
+ ######################################
72
+ ######################################
73
+
74
+ # %% app.ipynb 4
75
+ ## dynamicCFG SETUP
76
+ ######################################
77
+ ######################################
78
+
79
+ # default cosine schedule parameters
80
+ baseline_g = 9 # default, static guidance value
81
+ max_val = 9 # the max scheduled guidance scaling value
82
+ min_val = 6 # the minimum scheduled guidance value
83
+ num_warmup_steps = 0 # number of warmup steps
84
+ warmup_init_val = 0 # the intial warmup value
85
+ num_cycles = 0.5 # number of cosine cycles
86
+ k_decay = 1 # k-decay for cosine curve scaling
87
+
88
+ # group the default schedule parameters
89
+ DEFAULT_COS_PARAMS = {
90
+ 'max_val': max_val,
91
+ 'num_steps': num_steps,
92
+ 'min_val': min_val,
93
+ 'num_cycles': num_cycles,
94
+ 'k_decay': k_decay,
95
+ 'num_warmup_steps': num_warmup_steps,
96
+ 'warmup_init_val': warmup_init_val,
97
+ }
98
 
99
+ def cos_harness(new_params: dict) -> dict:
100
+ '''Creates cosine schedules with updated parameters in `new_params`
101
+ '''
102
+ # start from the given baseline `default_params`
103
+ cos_params = dict(DEFAULT_COS_PARAMS)
104
+ # update the with the new, given parameters
105
+ cos_params.update(new_params)
106
+
107
+ # return the new cosine schedule
108
+ sched = cf_guidance.schedules.get_cos_sched(**cos_params)
109
+ return sched
110
 
111
+
112
+ # build the static schedule
113
+ static_sched = [baseline_g] * num_steps
114
+
115
+ # build the inverted kdecay schedule
116
+ k_sched = cos_harness({'k_decay': 0.2})
117
+ inv_k_sched = [max_val - g + min_val for g in k_sched]
118
+
119
+ # group the schedules
120
+ schedules = {
121
+ 'cosine': {'g': inv_k_sched},
122
+ 'static': {'g': static_sched},
123
+ }
124
+ ######################################
125
+ ######################################
126
+
127
+ # %% app.ipynb 5
128
+ def compare_dynamic_guidance(prompt):
129
+ '''
130
+ Compares the default, static Classifier-free Guidance to a dynamic schedule.
131
+
132
+ Model and sampling paramters:
133
+ Stable Diffusion 2 v-model
134
+ Half-precision
135
+ DPM++ 2M sampler, with Karras sigma schedule
136
+ 18 sampling steps
137
+ (768 x 768) image
138
+ Using a generic negative prompt
139
+
140
+ Schedules:
141
+ Static guidance with scale of 9
142
+ Inverse kDecay (cosine variant) scheduled guidance
143
+ '''
144
+ # load the model
145
+ pipeline = load_model()
146
+
147
+ # stores the output images
148
+ res = []
149
+
150
+ # generate images with static and dynamic schedules
151
+ for (name,sched) in schedules.items():
152
+ # make the guidance norm
153
+ gtfm = cf_guidance.transforms.GuidanceTfm(sched)
154
+ # generate the image
155
+ with torch.autocast(device), torch.no_grad():
156
+ img = pipeline.generate(prompt, gtfm, **generation_kwargs)
157
+ # add the generated image
158
+ res.append(name)
159
+
160
+ # return the generated images
161
+ return {
162
+ 'values': res,
163
+ 'label': 'Cosine vs. Static CFG'
164
+ }
165
+
166
+ # %% app.ipynb 6
167
+ iface = gr.Interface(
168
+ compare_dynamic_guidance,
169
+ inputs="text",
170
+ outputs=gr.Gallery(),
171
+ title="Comparison with dynamic Classifier-free Guidance Comparison",
172
+ )
173
  iface.launch()
174
+
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ min_diffusion
2
+ cf_guidance
3
+ torch
4
+ transformers
5
+ diffusers
6
+ nbdev