Elea Zhong
update app
1b9d6c7
import copy
import math
import random
import os
import tempfile
import sys
import numpy as np
import torch
from PIL import Image
import gradio as gr
import spaces
import subprocess
GIT_TOKEN = os.environ.get("GIT_TOKEN")
import subprocess
# cmd = f"pip install git+https://eleazhong:{GIT_TOKEN}@github.com/wand-ai/wand-ml"
# proc = subprocess.Popen(
# cmd,
# stdout=subprocess.PIPE,
# stderr=subprocess.STDOUT,
# text=True, # or encoding="utf-8" on older Python
# bufsize=1,
# )
# for line in proc.stdout:
# print(line, end="") # already has newline
# proc.wait()
# print("Exit code:", proc.returncode)
from qwenimage.debug import ctimed
from qwenimage.models.pipeline_qwenimage_edit_plus import QwenImageEditPlusPipeline
from qwenimage.models.transformer_qwenimage import QwenImageTransformer2DModel
# --- Model Loading ---
# foundation = QwenImageFoundation(QwenConfig(
# vae_image_size=1024 * 1024,
# regression_base_pipe_steps=4,
# ))
# finetuner = QwenLoraFinetuner(foundation, foundation.config)
# finetuner.load("checkpoints/reg-mse-pixel-lpips_005000", lora_rank=32)
dtype = torch.bfloat16
device = "cuda" if torch.cuda.is_available() else "cpu"
pipe = QwenImageEditPlusPipeline.from_pretrained(
"Qwen/Qwen-Image-Edit-2509",
transformer=QwenImageTransformer2DModel.from_pretrained(
"Qwen/Qwen-Image-Edit-2509",
subfolder='transformer',
torch_dtype=dtype,
device_map=device
),
torch_dtype=dtype,
)
pipe = pipe.to(device=device, dtype=dtype)
pipe.load_lora_weights(
"checkpoints/distill_5k_lora.safetensors",
adapter_name="fast_5k",
)
# pipe.unload_lora_weights()
MAX_SEED = np.iinfo(np.int32).max
@spaces.GPU
def run_pipe(
image,
prompt,
seed,
randomize_seed,
num_inference_steps,
shift,
prev_output = None,
progress=gr.Progress(track_tqdm=True)
):
with ctimed("pre pipe"):
if randomize_seed:
seed = random.randint(0, MAX_SEED)
device = "cuda" if torch.cuda.is_available() else "cpu"
generator = torch.Generator(device=device).manual_seed(seed)
# Choose input image (prefer uploaded, else last output)
pil_images = []
if image is not None:
if isinstance(image, Image.Image):
pil_images.append(image.convert("RGB"))
elif hasattr(image, "name"):
pil_images.append(Image.open(image.name).convert("RGB"))
elif prev_output:
pil_images.append(prev_output.convert("RGB"))
if len(pil_images) == 0:
raise gr.Error("Please upload an image first.")
print(f"{len(pil_images)=}")
# finetuner.enable()
pipe.scheduler.config["base_shift"] = shift
pipe.scheduler.config["max_shift"] = shift
result = pipe(
image=pil_images,
prompt=prompt,
num_inference_steps=num_inference_steps,
generator=generator,
).images[0]
return result, seed
# --- UI ---
with gr.Blocks(theme=gr.themes.Citrus()) as demo:
gr.Markdown("Qwen Image Demo")
with gr.Row():
with gr.Column():
image = gr.Image(label="Input Image", type="pil")
prev_output = gr.Image(value=None, visible=False)
is_reset = gr.Checkbox(value=False, visible=False)
prompt = gr.Textbox(label="Prompt", placeholder="Prompt", lines=2)
run_btn = gr.Button("Generate", variant="primary")
with gr.Accordion("Advanced Settings", open=False):
seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0)
randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
num_inference_steps = gr.Slider(label="Inference Steps", minimum=1, maximum=40, step=1, value=2)
shift = gr.Slider(label="Timestep Shift", minimum=0.0, maximum=4.0, step=0.1, value=2.0)
with gr.Column():
result = gr.Image(label="Output Image", interactive=False)
inputs = [
image,
prompt,
seed,
randomize_seed,
num_inference_steps,
shift,
prev_output,
]
outputs = [result, seed]
run_event = run_btn.click(
fn=run_pipe,
inputs=inputs,
outputs=outputs
)
run_event.then(lambda img, *_: img, inputs=[result], outputs=[prev_output])
demo.launch()