Spaces:
Sleeping
Sleeping
File size: 9,094 Bytes
8ce917e 7c7b227 8ce917e 5ef00f9 8ce917e c9cb9a7 5f454af dcaef81 8ce917e 1cb8693 8ce917e 1cb8693 8ce917e 7c466dd a289439 42f684a 7c466dd a289439 42f684a a289439 42f684a 7c466dd 8ce917e 9edfe45 8ce917e 9edfe45 8ce917e a289439 8ce917e 8135193 8ce917e c9cb9a7 dcaef81 c9cb9a7 3590498 8ce917e 86d893d 8ce917e 7c466dd 86d893d 8ce917e 7c466dd 8ce917e 7c466dd 8ce917e 7c466dd 8ce917e 7c466dd c9cb9a7 86d893d c9cb9a7 7c466dd dcaef81 7c466dd dcaef81 7c466dd 8ce917e 7c466dd 8ce917e 7c466dd 8ce917e 7c466dd 8ce917e 7c466dd 8ce917e 7c466dd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
import os
import gradio as gr
import json
import logging
import torch
from PIL import Image
import spaces
from diffusers import DiffusionPipeline, FlowMatchEulerDiscreteScheduler
from huggingface_hub import hf_hub_download, HfFileSystem, ModelCard, snapshot_download
import copy
import random
import time
import re
import math
import numpy as np
import traceback
# Load LoRAs from JSON file
def load_loras_from_file():
"""Load LoRA configurations from external JSON file."""
try:
with open('loras.json', 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print("Warning: loras.json file not found. Using empty list.")
return []
except json.JSONDecodeError as e:
print(f"Error parsing loras.json: {e}")
return []
# Load the LoRAs
loras = load_loras_from_file()
# Initialize the base model
dtype = torch.bfloat16
device = "cuda" if torch.cuda.is_available() else "cpu"
base_model = "Qwen/Qwen-Image"
# Scheduler configuration from the Qwen-Image-Lightning repository
scheduler_config = {
"base_image_seq_len": 256,
"base_shift": math.log(3),
"invert_sigmas": False,
"max_image_seq_len": 8192,
"max_shift": math.log(3),
"num_train_timesteps": 1000,
"shift": 1.0,
"shift_terminal": None,
"stochastic_sampling": False,
"time_shift_type": "exponential",
"use_beta_sigmas": False,
"use_dynamic_shifting": True,
"use_exponential_sigmas": False,
"use_karras_sigmas": False,
}
scheduler = FlowMatchEulerDiscreteScheduler.from_config(scheduler_config)
pipe = DiffusionPipeline.from_pretrained(
base_model, scheduler=scheduler, torch_dtype=dtype
).to(device)
# Lightning LoRA info (no global state)
LIGHTNING_LORA_REPO = "lightx2v/Qwen-Image-Lightning"
LIGHTNING_LORA_WEIGHT = "Qwen-Image-Lightning-4steps-V2.0-bf16.safetensors"
LIGHTNING8_LORA_WEIGHT = "Qwen-Image-Lightning-8steps-V2.0-bf16.safetensors"
MAX_SEED = np.iinfo(np.int32).max
class calculateDuration:
def __init__(self, activity_name=""):
self.activity_name = activity_name
def __enter__(self):
self.start_time = time.time()
return self
def __exit__(self, exc_type, exc_value, traceback):
self.end_time = time.time()
self.elapsed_time = self.end_time - self.start_time
if self.activity_name:
print(f"Elapsed time for {self.activity_name}: {self.elapsed_time:.6f} seconds")
else:
print(f"Elapsed time: {self.elapsed_time:.6f} seconds")
def get_image_size(aspect_ratio):
"""Converts aspect ratio string to width, height tuple."""
if aspect_ratio == "1:1":
return 1024, 1024
elif aspect_ratio == "2:1":
return 1280, 640
elif aspect_ratio == "16:9":
return 1152, 640
elif aspect_ratio == "9:16":
return 640, 1152
elif aspect_ratio == "4:3":
return 1024, 768
elif aspect_ratio == "3:4":
return 768, 1024
elif aspect_ratio == "3:2":
return 1024, 688
elif aspect_ratio == "2:3":
return 688, 1024
elif aspect_ratio == "3:1":
return 1920, 640
elif aspect_ratio == "2:1":
return 1280, 640
else:
return 1024, 1024
def update_selection(evt: gr.SelectData, aspect_ratio):
selected_lora = loras[evt.index]
new_placeholder = f"Type a prompt for {selected_lora['title']}"
lora_repo = selected_lora["repo"]
updated_text = f"### Selected: [{lora_repo}](https://huggingface.co/{lora_repo}) ✨"
# Get model card examples
examples_list = []
try:
model_card = ModelCard.load(lora_repo)
widget_data = model_card.data.get("widget", [])
if widget_data and len(widget_data) > 0:
# Get examples from widget data
for example in widget_data[:4]:
if "output" in example and "url" in example["output"]:
image_url = f"https://huggingface.co/{lora_repo}/resolve/main/{example['output']['url']}"
prompt_text = example.get("text", "")
examples_list.append([prompt_text])
except Exception as e:
print(f"Could not load model card for {lora_repo}: {e}")
# Update aspect ratio if specified in LoRA config
if "aspect" in selected_lora:
if selected_lora["aspect"] == "portrait":
aspect_ratio = "9:16"
elif selected_lora["aspect"] == "landscape":
aspect_ratio = "16:9"
elif selected_lora["aspect"] == "square":
aspect_ratio = "1:1"
else:
aspect_ratio = selected_lora["aspect"]
return (
gr.update(placeholder=new_placeholder),
updated_text,
evt.index,
aspect_ratio
)
def handle_speed_mode(speed_mode):
"""Update UI based on speed/quality toggle."""
if speed_mode == "Speed (4 steps)":
return gr.update(value="Speed mode selected - 4 steps with Lightning LoRA"), 4, 1.0
elif speed_mode == "Speed (8 steps)":
return gr.update(value="Speed mode selected - 8 steps with Lightning LoRA"), 8, 1.0
else:
return gr.update(value="Quality mode selected - 45 steps for best quality"), 45, 3.5
@spaces.GPU(duration=70)
def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, lora_scale, negative_prompt=""):
pipe.to("cuda")
generator = torch.Generator(device="cuda").manual_seed(seed)
with calculateDuration("Generating image"):
# Generate image
image = pipe(
prompt=prompt_mash,
negative_prompt=negative_prompt,
num_inference_steps=steps,
true_cfg_scale=cfg_scale, # Use true_cfg_scale for Qwen-Image
width=width,
height=height,
generator=generator,
).images[0]
return image
@spaces.GPU(duration=70)
def run_lora(prompt, cfg_scale, steps, selected_index, randomize_seed, seed, aspect_ratio, lora_scale, speed_mode, progress=gr.Progress(track_tqdm=True)):
if selected_index is None:
raise gr.Error("You must select a LoRA before proceeding.")
selected_lora = loras[selected_index]
lora_path = selected_lora["repo"]
trigger_word = selected_lora["trigger_word"]
# Prepare prompt with trigger word
if trigger_word:
if "trigger_position" in selected_lora:
if selected_lora["trigger_position"] == "prepend":
prompt_mash = f"{trigger_word} {prompt}"
else:
prompt_mash = f"{prompt} {trigger_word}"
else:
prompt_mash = f"{trigger_word} {prompt}"
else:
prompt_mash = prompt
# Always unload any existing LoRAs first to avoid conflicts
with calculateDuration("Unloading existing LoRAs"):
pipe.unload_lora_weights()
# Load LoRAs based on speed mode
if speed_mode == "Speed (4 steps)":
with calculateDuration("Loading Lightning LoRA and style LoRA"):
pipe.load_lora_weights(
LIGHTNING_LORA_REPO,
weight_name=LIGHTNING_LORA_WEIGHT,
adapter_name="lightning"
)
weight_name = selected_lora.get("weights", None)
pipe.load_lora_weights(
lora_path,
weight_name=weight_name,
low_cpu_mem_usage=True,
adapter_name="style"
)
pipe.set_adapters(["lightning", "style"], adapter_weights=[1.0, lora_scale])
elif speed_mode == "Speed (8 steps)":
with calculateDuration("Loading Lightning LoRA and style LoRA"):
pipe.load_lora_weights(
LIGHTNING_LORA_REPO,
weight_name=LIGHTNING8_LORA_WEIGHT,
adapter_name="lightning"
)
weight_name = selected_lora.get("weights", None)
pipe.load_lora_weights(
lora_path,
weight_name=weight_name,
low_cpu_mem_usage=True,
adapter_name="style"
)
pipe.set_adapters(["lightning", "style"], adapter_weights=[1.0, lora_scale])
else:
with calculateDuration(f"Loading LoRA weights for {selected_lora['title']}"):
weight_name = selected_lora.get("weights", None)
pipe.load_lora_weights(
lora_path,
weight_name=weight_name,
low_cpu_mem_usage=True,
adapter_name="style"
)
pipe.set_adapters(["style"], adapter_weights=[lora_scale])
# Set random seed for reproducibility
with calculateDuration("Randomizing seed"):
if randomize_seed:
seed = random.randint(0, MAX_SEED)
# Get image dimensions from aspect ratio
width, height = get_image_size(aspect_ratio)
# Generate the image
final_image = generate_image(prompt_mash, steps, seed, cfg_scale, width, height, lora_scale)
return final_image, seed
# (resto del código con interfaz Gradio, etc.)
|