hakakusan commited on
Commit
35d249c
verified
1 Parent(s): f117889

Add guidance schedule controls

Browse files
Files changed (1) hide show
  1. app.py +39 -10
app.py CHANGED
@@ -36,10 +36,12 @@ MAX_SEED = 2**31 - 1
36
  HF_TOKEN = os.environ.get("HF_TOKEN")
37
 
38
  MODES = {
39
- "Turbo 路 12 steps": dict(num_inference_steps=12, guidance_schedule=(7.0,) * 11 + (3.0,) * 1, mu=0.5, std=1.75),
40
- "Default 路 20 steps": dict(num_inference_steps=20, guidance_schedule=(7.0,) * 18 + (3.0,) * 2, mu=0.0, std=1.75),
41
- "Quality 路 48 steps": dict(num_inference_steps=48, guidance_schedule=(7.0,) * 45 + (3.0,) * 3, mu=0.0, std=1.5),
42
  }
 
 
43
 
44
  DEFAULT_CAPTION = {
45
  "high_level_description": "A clean poster announcing a small experimental image generation lab.",
@@ -97,6 +99,16 @@ def normalize_caption(raw_caption):
97
  return json.dumps(caption, ensure_ascii=False, separators=(",", ":")), caption
98
 
99
 
 
 
 
 
 
 
 
 
 
 
100
  t = time.perf_counter()
101
  if TEXT_ENCODER_ID:
102
  text_encoder = AutoModel.from_pretrained(
@@ -161,32 +173,46 @@ def _per_step(width, height):
161
  return max(0.2, _PS_A + _PS_B * ((int(width) // 16) * (int(height) // 16)))
162
 
163
 
164
- def _gpu_duration(caption_text, mode, width, height, seed, progress=None):
165
  steps = MODES.get(mode, MODES["Default 路 20 steps"])["num_inference_steps"]
166
  budget = steps * _per_step(width, height) + DIFFUSION_OVERHEAD_S
167
  return max(60, int(math.ceil(budget * DURATION_MARGIN)))
168
 
169
 
170
  @spaces.GPU(duration=_gpu_duration, size="xlarge")
171
- def _gpu_generate(caption_text, mode, width, height, seed, progress=gr.Progress(track_tqdm=True)):
172
  aoti_thread = Thread(target=_apply_aoti, daemon=True)
173
  aoti_thread.start()
174
  aoti_thread.join()
175
 
176
  progress(0.0, desc="Generating image")
177
  generator = torch.Generator(device="cuda").manual_seed(int(seed))
178
- preset = MODES.get(mode, MODES["Default 路 20 steps"])
179
  t = time.perf_counter()
180
  image = pipe(prompt=caption_text, width=int(width), height=int(height), generator=generator, **preset).images[0]
181
- print(f"[timing] diffusion ({mode}): {time.perf_counter() - t:.2f}s", flush=True)
 
 
 
 
182
  return image
183
 
184
 
185
- def generate(caption_json, mode="Default 路 20 steps", width=1024, height=1024, seed=0, randomize_seed=False, progress=gr.Progress(track_tqdm=True)):
 
 
 
 
 
 
 
 
 
 
186
  caption_text, parsed_caption = normalize_caption(caption_json)
187
  if randomize_seed or seed < 0:
188
  seed = random.randint(0, MAX_SEED)
189
- image = _gpu_generate(caption_text, mode, width, height, seed)
190
  return image, int(seed), parsed_caption, caption_text
191
 
192
 
@@ -209,6 +235,9 @@ with gr.Blocks(theme=gr.themes.Citrus(), title="Ideogram 4 JSON Lab", css=CSS) a
209
  mode = gr.Radio(choices=list(MODES.keys()), value="Default 路 20 steps", label="Mode")
210
  width = gr.Slider(512, 2048, value=1024, step=64, label="Width")
211
  height = gr.Slider(512, 2048, value=1024, step=64, label="Height")
 
 
 
212
  with gr.Row():
213
  seed = gr.Number(label="Seed", value=0, precision=0)
214
  randomize = gr.Checkbox(label="Randomize seed", value=False)
@@ -266,7 +295,7 @@ with gr.Blocks(theme=gr.themes.Citrus(), title="Ideogram 4 JSON Lab", css=CSS) a
266
 
267
  run.click(
268
  generate,
269
- inputs=[caption, mode, width, height, seed, randomize],
270
  outputs=[out_image, seed, out_caption, out_text],
271
  )
272
 
 
36
  HF_TOKEN = os.environ.get("HF_TOKEN")
37
 
38
  MODES = {
39
+ "Turbo 路 12 steps": dict(num_inference_steps=12, final_guidance_steps=1, mu=0.5, std=1.75),
40
+ "Default 路 20 steps": dict(num_inference_steps=20, final_guidance_steps=2, mu=0.0, std=1.75),
41
+ "Quality 路 48 steps": dict(num_inference_steps=48, final_guidance_steps=3, mu=0.0, std=1.5),
42
  }
43
+ DEFAULT_MAIN_GUIDANCE = 7.0
44
+ DEFAULT_FINAL_GUIDANCE = 3.0
45
 
46
  DEFAULT_CAPTION = {
47
  "high_level_description": "A clean poster announcing a small experimental image generation lab.",
 
99
  return json.dumps(caption, ensure_ascii=False, separators=(",", ":")), caption
100
 
101
 
102
+ def build_preset(mode, main_guidance=DEFAULT_MAIN_GUIDANCE, final_guidance=DEFAULT_FINAL_GUIDANCE):
103
+ preset = dict(MODES.get(mode, MODES["Default 路 20 steps"]))
104
+ steps = int(preset.pop("num_inference_steps"))
105
+ final_steps = min(int(preset.pop("final_guidance_steps")), steps)
106
+ main_steps = steps - final_steps
107
+ guidance_schedule = (float(main_guidance),) * main_steps + (float(final_guidance),) * final_steps
108
+ preset.update(num_inference_steps=steps, guidance_schedule=guidance_schedule)
109
+ return preset
110
+
111
+
112
  t = time.perf_counter()
113
  if TEXT_ENCODER_ID:
114
  text_encoder = AutoModel.from_pretrained(
 
173
  return max(0.2, _PS_A + _PS_B * ((int(width) // 16) * (int(height) // 16)))
174
 
175
 
176
+ def _gpu_duration(caption_text, mode, width, height, seed, main_guidance, final_guidance, progress=None):
177
  steps = MODES.get(mode, MODES["Default 路 20 steps"])["num_inference_steps"]
178
  budget = steps * _per_step(width, height) + DIFFUSION_OVERHEAD_S
179
  return max(60, int(math.ceil(budget * DURATION_MARGIN)))
180
 
181
 
182
  @spaces.GPU(duration=_gpu_duration, size="xlarge")
183
+ def _gpu_generate(caption_text, mode, width, height, seed, main_guidance, final_guidance, progress=gr.Progress(track_tqdm=True)):
184
  aoti_thread = Thread(target=_apply_aoti, daemon=True)
185
  aoti_thread.start()
186
  aoti_thread.join()
187
 
188
  progress(0.0, desc="Generating image")
189
  generator = torch.Generator(device="cuda").manual_seed(int(seed))
190
+ preset = build_preset(mode, main_guidance, final_guidance)
191
  t = time.perf_counter()
192
  image = pipe(prompt=caption_text, width=int(width), height=int(height), generator=generator, **preset).images[0]
193
+ print(
194
+ f"[timing] diffusion ({mode}, guidance={float(main_guidance):.2f}->{float(final_guidance):.2f}): "
195
+ f"{time.perf_counter() - t:.2f}s",
196
+ flush=True,
197
+ )
198
  return image
199
 
200
 
201
+ def generate(
202
+ caption_json,
203
+ mode="Default 路 20 steps",
204
+ width=1024,
205
+ height=1024,
206
+ seed=0,
207
+ randomize_seed=False,
208
+ main_guidance=DEFAULT_MAIN_GUIDANCE,
209
+ final_guidance=DEFAULT_FINAL_GUIDANCE,
210
+ progress=gr.Progress(track_tqdm=True),
211
+ ):
212
  caption_text, parsed_caption = normalize_caption(caption_json)
213
  if randomize_seed or seed < 0:
214
  seed = random.randint(0, MAX_SEED)
215
+ image = _gpu_generate(caption_text, mode, width, height, seed, main_guidance, final_guidance)
216
  return image, int(seed), parsed_caption, caption_text
217
 
218
 
 
235
  mode = gr.Radio(choices=list(MODES.keys()), value="Default 路 20 steps", label="Mode")
236
  width = gr.Slider(512, 2048, value=1024, step=64, label="Width")
237
  height = gr.Slider(512, 2048, value=1024, step=64, label="Height")
238
+ with gr.Row():
239
+ main_guidance = gr.Slider(0.0, 9.0, value=DEFAULT_MAIN_GUIDANCE, step=0.25, label="Main guidance")
240
+ final_guidance = gr.Slider(0.0, 9.0, value=DEFAULT_FINAL_GUIDANCE, step=0.25, label="Final guidance")
241
  with gr.Row():
242
  seed = gr.Number(label="Seed", value=0, precision=0)
243
  randomize = gr.Checkbox(label="Randomize seed", value=False)
 
295
 
296
  run.click(
297
  generate,
298
+ inputs=[caption, mode, width, height, seed, randomize, main_guidance, final_guidance],
299
  outputs=[out_image, seed, out_caption, out_text],
300
  )
301