akhaliq HF Staff commited on
Commit
8ad5464
·
verified ·
1 Parent(s): 412af08

Update Gradio app with multiple files

Browse files
Files changed (2) hide show
  1. app.py +54 -68
  2. requirements.txt +20 -7
app.py CHANGED
@@ -17,9 +17,6 @@ from safetensors.torch import load_file
17
 
18
  from PIL import Image
19
  import os
20
- import gradio as gr
21
- from gradio_client import Client, handle_file
22
- import tempfile
23
 
24
 
25
  # --- Model Loading ---
@@ -32,32 +29,20 @@ pipe = QwenImageEditPlusPipeline.from_pretrained("Qwen/Qwen-Image-Edit-2509",
32
  torch_dtype=dtype,
33
  device_map='cuda'),torch_dtype=dtype).to(device)
34
 
35
- pipe.load_lora_weights("autoweeb/Qwen-Image-Edit-2509-Photo-to-Anime", adapter_name="anime")
 
 
36
  pipe.set_adapters(["anime"], adapter_weights=[1.])
37
  pipe.fuse_lora(adapter_names=["anime"], lora_scale=1.0)
38
  pipe.unload_lora_weights()
39
 
40
-
41
-
42
  pipe.transformer.__class__ = QwenImageTransformer2DModel
43
  pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
44
 
45
  optimize_pipeline_(pipe, image=[Image.new("RGB", (1024, 1024)), Image.new("RGB", (1024, 1024))], prompt="prompt")
46
 
47
-
48
  MAX_SEED = np.iinfo(np.int32).max
49
 
50
- def _generate_video_segment(input_image_path: str, output_image_path: str, prompt: str, request: gr.Request) -> str:
51
- """Generates a single video segment using the external service."""
52
- x_ip_token = request.headers['x-ip-token']
53
- video_client = Client("multimodalart/wan-2-2-first-last-frame", headers={"x-ip-token": x_ip_token})
54
- result = video_client.predict(
55
- start_image_pil=handle_file(input_image_path),
56
- end_image_pil=handle_file(output_image_path),
57
- prompt=prompt, api_name="/generate_video",
58
- )
59
- return result[0]["video"]
60
-
61
  @spaces.GPU
62
  def convert_to_anime(
63
  image,
@@ -166,62 +151,63 @@ def update_dimensions_on_upload(image):
166
  return new_width, new_height
167
 
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
- ["tool_of_the_sea.png", 90, 0, 0, False, 0, True, 1.0, 4, 568, 1024],
171
- ["monkey.jpg", -90, 0, 0, False, 0, True, 1.0, 4, 704, 1024],
172
- ["metropolis.jpg", 0, 0, -1, False, 0, True, 1.0, 4, 816, 1024],
173
- ["disaster_girl.jpg", -45, 0, 1, False, 0, True, 1.0, 4, 768, 1024],
174
- ["grumpy.png", 90, 0, 1, False, 0, True, 1.0, 4, 576, 1024]
175
- ],
176
- inputs=[image,rotate_deg, move_forward,
177
- vertical_tilt, wideangle,
178
- seed, randomize_seed, true_guidance_scale, num_inference_steps, height, width],
179
- outputs=outputs,
180
- fn=infer_camera_edit,
181
- cache_examples="lazy",
182
- elem_id="examples"
183
  )
184
-
185
- # Image upload triggers dimension update and control reset
186
  image.upload(
187
  fn=update_dimensions_on_upload,
188
  inputs=[image],
189
  outputs=[width, height]
190
- ).then(
191
- fn=reset_all,
192
- inputs=None,
193
- outputs=[rotate_deg, move_forward, vertical_tilt, wideangle, is_reset],
194
- queue=False
195
- ).then(
196
- fn=end_reset,
197
- inputs=None,
198
- outputs=[is_reset],
199
- queue=False
200
  )
201
 
202
-
203
- # Live updates
204
- def maybe_infer(is_reset, progress=gr.Progress(track_tqdm=True), *args):
205
- if is_reset:
206
- return gr.update(), gr.update(), gr.update(), gr.update()
207
- else:
208
- result_img, result_seed, result_prompt = infer_camera_edit(*args)
209
- # Show video button if we have both input and output
210
- show_button = args[0] is not None and result_img is not None
211
- return result_img, result_seed, result_prompt, gr.update(visible=show_button)
212
-
213
- control_inputs = [
214
- image, rotate_deg, move_forward,
215
- vertical_tilt, wideangle,
216
- seed, randomize_seed, true_guidance_scale, num_inference_steps, height, width, prev_output
217
- ]
218
- control_inputs_with_flag = [is_reset] + control_inputs
219
-
220
- for control in [rotate_deg, move_forward, vertical_tilt]:
221
- control.release(fn=maybe_infer, inputs=control_inputs_with_flag, outputs=outputs + [create_video_button])
222
-
223
- wideangle.input(fn=maybe_infer, inputs=control_inputs_with_flag, outputs=outputs + [create_video_button])
224
-
225
- run_event.then(lambda img, *_: img, inputs=[result], outputs=[prev_output])
226
-
227
  demo.launch()
 
17
 
18
  from PIL import Image
19
  import os
 
 
 
20
 
21
 
22
  # --- Model Loading ---
 
29
  torch_dtype=dtype,
30
  device_map='cuda'),torch_dtype=dtype).to(device)
31
 
32
+ pipe.load_lora_weights("autoweeb/Qwen-Image-Edit-2509-Photo-to-Anime",
33
+ weight_name="Qwen-Image-Edit-2509-Photo-to-Anime_000001000.safetensors",
34
+ adapter_name="anime")
35
  pipe.set_adapters(["anime"], adapter_weights=[1.])
36
  pipe.fuse_lora(adapter_names=["anime"], lora_scale=1.0)
37
  pipe.unload_lora_weights()
38
 
 
 
39
  pipe.transformer.__class__ = QwenImageTransformer2DModel
40
  pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
41
 
42
  optimize_pipeline_(pipe, image=[Image.new("RGB", (1024, 1024)), Image.new("RGB", (1024, 1024))], prompt="prompt")
43
 
 
44
  MAX_SEED = np.iinfo(np.int32).max
45
 
 
 
 
 
 
 
 
 
 
 
 
46
  @spaces.GPU
47
  def convert_to_anime(
48
  image,
 
151
  return new_width, new_height
152
 
153
 
154
+ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
155
+ with gr.Column(elem_id="col-container"):
156
+ gr.Markdown("# 🎨 Photo to Anime", elem_id="title")
157
+ gr.Markdown(
158
+ """
159
+ Transform your photos into beautiful anime-style images ✨
160
+ <br>
161
+ <div style='text-align: center; margin-top: 1rem;'>
162
+ <a href='https://huggingface.co/spaces/akhaliq/anycoder' target='_blank' style='color: #0071e3; text-decoration: none; font-weight: 500;'>Built with anycoder</a>
163
+ </div>
164
+ """,
165
+ elem_id="description"
166
+ )
167
+
168
+ with gr.Row():
169
+ with gr.Column(scale=1):
170
+ image = gr.Image(
171
+ label="Upload Photo",
172
+ type="pil",
173
+ elem_classes="image-container"
174
+ )
175
+
176
+ with gr.Accordion("⚙️ Advanced Settings", open=False):
177
+ seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0)
178
+ randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
179
+ true_guidance_scale = gr.Slider(label="Guidance Scale", minimum=1.0, maximum=10.0, step=0.1, value=1.0)
180
+ num_inference_steps = gr.Slider(label="Inference Steps", minimum=1, maximum=40, step=1, value=4)
181
+ height = gr.Slider(label="Height", minimum=256, maximum=2048, step=8, value=1024, visible=False)
182
+ width = gr.Slider(label="Width", minimum=256, maximum=2048, step=8, value=1024, visible=False)
183
+
184
+ convert_btn = gr.Button("Convert to Anime", variant="primary", elem_id="convert-btn", size="lg")
185
+
186
+ with gr.Column(scale=1):
187
+ result = gr.Image(
188
+ label="Anime Result",
189
+ interactive=False,
190
+ elem_classes="image-container"
191
+ )
192
+
193
+ inputs = [
194
+ image, seed, randomize_seed, true_guidance_scale,
195
+ num_inference_steps, height, width
196
+ ]
197
+ outputs = [result, seed]
198
 
199
+ # Convert button click
200
+ convert_btn.click(
201
+ fn=convert_to_anime,
202
+ inputs=inputs,
203
+ outputs=outputs
 
 
 
 
 
 
 
 
204
  )
205
+
206
+ # Image upload triggers dimension update
207
  image.upload(
208
  fn=update_dimensions_on_upload,
209
  inputs=[image],
210
  outputs=[width, height]
 
 
 
 
 
 
 
 
 
 
211
  )
212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  demo.launch()
requirements.txt CHANGED
@@ -1,10 +1,23 @@
1
- git+https://github.com/huggingface/diffusers.git
2
- transformers
3
- accelerate
4
  safetensors
 
 
 
 
 
5
  sentencepiece
6
- dashscope
7
- kernels
 
 
8
  torchvision
9
- peft
10
- torchao==0.11.0
 
 
 
 
 
 
 
1
+ huggingface_hub
2
+ gradio
3
+ git+https://github.com/huggingface/diffusers
4
  safetensors
5
+ numpy
6
+ torch
7
+ spaces
8
+ Pillow
9
+ git+https://github.com/huggingface/transformers
10
  sentencepiece
11
+ accelerate
12
+ tokenizers
13
+ requests
14
+ tqdm
15
  torchvision
16
+ opencv-python
17
+ scikit-learn
18
+ matplotlib
19
+ xformers
20
+ bitsandbytes
21
+ pillow-heif
22
+ imageio
23
+ timm