multimodalart HF Staff commited on
Commit
0b54347
·
verified ·
1 Parent(s): 53e65a2

Wire example click-to-fill with full generate() defaults; add in-process AoTI compilation of transformer blocks

Browse files
Files changed (1) hide show
  1. app.py +81 -3
app.py CHANGED
@@ -17,6 +17,7 @@ import random # noqa: E402
17
  import gradio as gr # noqa: E402
18
  import torch # noqa: E402
19
  from diffusers import JoyImageEditPlusPipeline # noqa: E402
 
20
 
21
  MODEL_ID = "jdopensource/JoyAI-Image-Edit-Plus-Diffusers"
22
 
@@ -26,6 +27,64 @@ pipe = JoyImageEditPlusPipeline.from_pretrained(
26
  )
27
  pipe.enable_model_cpu_offload()
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  @spaces.GPU(duration=300)
31
  def generate(
@@ -177,11 +236,30 @@ with gr.Blocks() as demo:
177
  )
178
 
179
  gr.Examples(
 
 
 
 
180
  examples=[
181
- [["examples/input_0.png", "examples/input_1.png"],
182
- "The woman is lovingly holding the cute puppy in her arms"],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  ],
184
- inputs=[input_gallery, prompt],
185
  outputs=[output_image, seed],
186
  fn=generate,
187
  cache_examples=True,
 
17
  import gradio as gr # noqa: E402
18
  import torch # noqa: E402
19
  from diffusers import JoyImageEditPlusPipeline # noqa: E402
20
+ from PIL import Image # noqa: E402
21
 
22
  MODEL_ID = "jdopensource/JoyAI-Image-Edit-Plus-Diffusers"
23
 
 
27
  )
28
  pipe.enable_model_cpu_offload()
29
 
30
+ # A minimal, representative call used both to warm the pipeline and to capture
31
+ # example inputs for ahead-of-time (AoTI) compilation of the repeated
32
+ # transformer block. Kept tiny (1 step) so it's cheap during startup.
33
+ _WARMUP_IMAGE = Image.new("RGB", (512, 512), (127, 127, 127))
34
+
35
+
36
+ def _warmup_run():
37
+ """Run a single 1-step pipeline pass (used inside aoti_capture)."""
38
+ pipe(
39
+ images=[_WARMUP_IMAGE],
40
+ prompt="a photo",
41
+ negative_prompt="",
42
+ height=512,
43
+ width=512,
44
+ num_inference_steps=1,
45
+ guidance_scale=1.0,
46
+ generator=torch.Generator(device="cpu").manual_seed(0),
47
+ )
48
+
49
+
50
+ @spaces.GPU(duration=1500)
51
+ def compile_transformer_blocks():
52
+ """Ahead-of-time compile the repeated transformer block and apply it.
53
+
54
+ The transformer is a stack of identical ``JoyImageEditPlusTransformerBlock``
55
+ modules (``pipe.transformer.double_blocks``). We capture one block's real
56
+ inputs from a 1-step run, export + AoTI-compile that single block graph, and
57
+ swap the compiled forward into every block. Weights stay runtime inputs, so
58
+ one compiled graph serves all layers. This removes eager per-step overhead
59
+ and materially speeds up inference. torch.compile (JIT) is unsupported on
60
+ ZeroGPU, so this ahead-of-time path is the supported optimization.
61
+ """
62
+ blocks = pipe.transformer.double_blocks
63
+ block = blocks[0]
64
+
65
+ with spaces.aoti_capture(block) as call:
66
+ _warmup_run()
67
+
68
+ exported = torch.export.export(
69
+ block,
70
+ args=call.args,
71
+ kwargs=call.kwargs,
72
+ strict=False,
73
+ )
74
+ compiled = spaces.aoti_compile(exported)
75
+
76
+ for blk in blocks:
77
+ spaces.aoti_apply(compiled, blk)
78
+
79
+ return len(blocks)
80
+
81
+
82
+ try:
83
+ _n = compile_transformer_blocks()
84
+ print(f"AoTI: compiled and applied to {_n} transformer blocks")
85
+ except Exception as e: # noqa: BLE001 -- keep the Space running if AoTI fails
86
+ print(f"AoTI compile failed ({e!r}); running eager")
87
+
88
 
89
  @spaces.GPU(duration=300)
90
  def generate(
 
236
  )
237
 
238
  gr.Examples(
239
+ # Each row supplies a full set of default values for every generate()
240
+ # input, in the same order as the `inputs` list below, so that clicking
241
+ # an example both populates the controls and calls generate with those
242
+ # defaults.
243
  examples=[
244
+ [
245
+ ["examples/input_0.png", "examples/input_1.png"],
246
+ "The woman is lovingly holding the cute puppy in her arms",
247
+ "low quality, blurry, deformed",
248
+ 30,
249
+ 4.0,
250
+ 42,
251
+ False,
252
+ ],
253
+ ],
254
+ inputs=[
255
+ input_gallery,
256
+ prompt,
257
+ negative_prompt,
258
+ num_inference_steps,
259
+ guidance_scale,
260
+ seed,
261
+ randomize_seed,
262
  ],
 
263
  outputs=[output_image, seed],
264
  fn=generate,
265
  cache_examples=True,