Spaces:
Running
on
Zero
Running
on
Zero
Commit
·
5821d1b
1
Parent(s):
ecf2c6b
Fix lora mem issue with large res
Browse files
app.py
CHANGED
|
@@ -94,6 +94,7 @@ MOD_VALUE = 8
|
|
| 94 |
DEFAULT_H_SLIDER_VALUE = 512
|
| 95 |
DEFAULT_W_SLIDER_VALUE = 768
|
| 96 |
NEW_FORMULA_MAX_AREA = 768.0 * 512.0
|
|
|
|
| 97 |
|
| 98 |
SLIDER_MIN_H, SLIDER_MAX_H = 128, 896
|
| 99 |
SLIDER_MIN_W, SLIDER_MAX_W = 128, 896
|
|
@@ -126,43 +127,56 @@ def parse_lset_prompt(lset_prompt):
|
|
| 126 |
|
| 127 |
return resolved_prompt
|
| 128 |
|
| 129 |
-
def handle_lora_selection_change(preset_name, current_prompt):
|
| 130 |
"""
|
| 131 |
When a preset is selected, this function finds the corresponding .lset file,
|
| 132 |
-
parses it,
|
| 133 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
if not preset_name or preset_name == "None":
|
| 135 |
-
return
|
| 136 |
|
|
|
|
| 137 |
try:
|
| 138 |
-
# The preset_name is the filename without extension
|
| 139 |
lset_filename = f"{preset_name}.lset"
|
| 140 |
-
|
| 141 |
-
# Download the .lset file from the same subfolder as the LoRA
|
| 142 |
lset_path = hf_hub_download(
|
| 143 |
-
repo_id=I2V_LORA_REPO_ID,
|
| 144 |
-
|
| 145 |
-
subfolder=I2V_LORA_SUBFOLDER,
|
| 146 |
-
repo_type='model'
|
| 147 |
)
|
| 148 |
-
|
| 149 |
with open(lset_path, 'r', encoding='utf-8') as f:
|
| 150 |
lset_data = json.load(f)
|
| 151 |
|
| 152 |
-
lset_prompt_raw
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
# Append with newlines for separation. If current prompt is empty, strip() handles it.
|
| 158 |
-
new_prompt = f"{current_prompt}\n\n{resolved_prompt}".strip()
|
| 159 |
-
gr.Info(f"✅ Appended prompt from '{lset_filename}'. Replace highlighted text like __this__.")
|
| 160 |
-
return gr.update(value=new_prompt)
|
| 161 |
except Exception as e:
|
| 162 |
-
# This should be less common now, but good to keep for safety.
|
| 163 |
print(f"Info: Could not process .lset for '{preset_name}'. Reason: {e}")
|
| 164 |
gr.Info(f"ℹ️ Error processing preset '{preset_name}'.")
|
| 165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
|
| 167 |
# --- Helper Functions ---
|
| 168 |
def sanitize_prompt_for_filename(prompt: str, max_len: int = 60) -> str:
|
|
@@ -259,6 +273,21 @@ def generate_i2v_video(input_image, prompt, height, width,
|
|
| 259 |
target_h = max(MOD_VALUE, (int(height) // MOD_VALUE) * MOD_VALUE)
|
| 260 |
target_w = max(MOD_VALUE, (int(width) // MOD_VALUE) * MOD_VALUE)
|
| 261 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
# Calculate and adjust num_frames to be compatible with video codecs
|
| 263 |
target_frames = int(round(duration_seconds * FIXED_FPS))
|
| 264 |
adjusted_frames = 4 * round((target_frames - 1) / 4) + 1
|
|
@@ -393,8 +422,8 @@ with gr.Blocks() as demo:
|
|
| 393 |
# I2V Handlers
|
| 394 |
i2v_preset_name.change(
|
| 395 |
fn=handle_lora_selection_change,
|
| 396 |
-
inputs=[i2v_preset_name, i2v_prompt],
|
| 397 |
-
outputs=[i2v_prompt]
|
| 398 |
)
|
| 399 |
i2v_input_image.upload(
|
| 400 |
fn=handle_image_upload_for_dims_wan,
|
|
|
|
| 94 |
DEFAULT_H_SLIDER_VALUE = 512
|
| 95 |
DEFAULT_W_SLIDER_VALUE = 768
|
| 96 |
NEW_FORMULA_MAX_AREA = 768.0 * 512.0
|
| 97 |
+
LORA_MAX_AREA = 640.0 * 480.0 # Max pixel area when a LoRA is active
|
| 98 |
|
| 99 |
SLIDER_MIN_H, SLIDER_MAX_H = 128, 896
|
| 100 |
SLIDER_MIN_W, SLIDER_MAX_W = 128, 896
|
|
|
|
| 127 |
|
| 128 |
return resolved_prompt
|
| 129 |
|
| 130 |
+
def handle_lora_selection_change(preset_name, current_prompt, current_h, current_w, aspect_ratio):
|
| 131 |
"""
|
| 132 |
When a preset is selected, this function finds the corresponding .lset file,
|
| 133 |
+
parses it, appends the prompt, and resizes dimensions if they are too large.
|
| 134 |
"""
|
| 135 |
+
# Initialize updates to avoid changing UI elements unnecessarily
|
| 136 |
+
prompt_update = gr.update()
|
| 137 |
+
h_update = gr.update()
|
| 138 |
+
w_update = gr.update()
|
| 139 |
+
|
| 140 |
if not preset_name or preset_name == "None":
|
| 141 |
+
return prompt_update, h_update, w_update
|
| 142 |
|
| 143 |
+
# --- Handle Prompt ---
|
| 144 |
try:
|
|
|
|
| 145 |
lset_filename = f"{preset_name}.lset"
|
|
|
|
|
|
|
| 146 |
lset_path = hf_hub_download(
|
| 147 |
+
repo_id=I2V_LORA_REPO_ID, filename=lset_filename,
|
| 148 |
+
subfolder=I2V_LORA_SUBFOLDER, repo_type='model'
|
|
|
|
|
|
|
| 149 |
)
|
|
|
|
| 150 |
with open(lset_path, 'r', encoding='utf-8') as f:
|
| 151 |
lset_data = json.load(f)
|
| 152 |
|
| 153 |
+
if lset_prompt_raw := lset_data.get("prompt"):
|
| 154 |
+
resolved_prompt = parse_lset_prompt(lset_prompt_raw)
|
| 155 |
+
new_prompt = f"{current_prompt}\n\n{resolved_prompt}".strip()
|
| 156 |
+
gr.Info(f"✅ Appended prompt from '{lset_filename}'. Replace highlighted text like __this__.")
|
| 157 |
+
prompt_update = gr.update(value=new_prompt)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
except Exception as e:
|
|
|
|
| 159 |
print(f"Info: Could not process .lset for '{preset_name}'. Reason: {e}")
|
| 160 |
gr.Info(f"ℹ️ Error processing preset '{preset_name}'.")
|
| 161 |
+
|
| 162 |
+
# --- Handle Resolution ---
|
| 163 |
+
if current_h * current_w > LORA_MAX_AREA:
|
| 164 |
+
gr.Info(f"Resolution too high for LoRA. Scaling down to a 640x480 equivalent area.")
|
| 165 |
+
# aspect_ratio is W/H
|
| 166 |
+
if aspect_ratio > 0:
|
| 167 |
+
calc_w = round(np.sqrt(LORA_MAX_AREA * aspect_ratio))
|
| 168 |
+
calc_h = round(np.sqrt(LORA_MAX_AREA / aspect_ratio))
|
| 169 |
+
|
| 170 |
+
new_h = max(MOD_VALUE, (calc_h // MOD_VALUE) * MOD_VALUE)
|
| 171 |
+
new_w = max(MOD_VALUE, (calc_w // MOD_VALUE) * MOD_VALUE)
|
| 172 |
+
|
| 173 |
+
h_update = gr.update(value=new_h)
|
| 174 |
+
w_update = gr.update(value=new_w)
|
| 175 |
+
else: # Fallback if aspect ratio is invalid
|
| 176 |
+
h_update = gr.update(value=480)
|
| 177 |
+
w_update = gr.update(value=640)
|
| 178 |
+
|
| 179 |
+
return prompt_update, h_update, w_update
|
| 180 |
|
| 181 |
# --- Helper Functions ---
|
| 182 |
def sanitize_prompt_for_filename(prompt: str, max_len: int = 60) -> str:
|
|
|
|
| 273 |
target_h = max(MOD_VALUE, (int(height) // MOD_VALUE) * MOD_VALUE)
|
| 274 |
target_w = max(MOD_VALUE, (int(width) // MOD_VALUE) * MOD_VALUE)
|
| 275 |
|
| 276 |
+
# If a LoRA is used, enforce max resolution as a safety net
|
| 277 |
+
if preset_name and preset_name != "None":
|
| 278 |
+
if target_h * target_w > LORA_MAX_AREA:
|
| 279 |
+
print(f"⚠️ Warning: Resolution {target_w}x{target_h} is too high for LoRA. Rescaling to fit max area.")
|
| 280 |
+
aspect_ratio = target_w / target_h if target_h > 0 else 1.0
|
| 281 |
+
|
| 282 |
+
# Re-calculate w and h based on max area
|
| 283 |
+
target_w = round(np.sqrt(LORA_MAX_AREA * aspect_ratio))
|
| 284 |
+
target_h = round(np.sqrt(LORA_MAX_AREA / aspect_ratio))
|
| 285 |
+
|
| 286 |
+
# Snap to MOD_VALUE
|
| 287 |
+
target_h = max(MOD_VALUE, (target_h // MOD_VALUE) * MOD_VALUE)
|
| 288 |
+
target_w = max(MOD_VALUE, (target_w // MOD_VALUE) * MOD_VALUE)
|
| 289 |
+
print(f" - Rescaled to: {target_w}x{target_h}")
|
| 290 |
+
|
| 291 |
# Calculate and adjust num_frames to be compatible with video codecs
|
| 292 |
target_frames = int(round(duration_seconds * FIXED_FPS))
|
| 293 |
adjusted_frames = 4 * round((target_frames - 1) / 4) + 1
|
|
|
|
| 422 |
# I2V Handlers
|
| 423 |
i2v_preset_name.change(
|
| 424 |
fn=handle_lora_selection_change,
|
| 425 |
+
inputs=[i2v_preset_name, i2v_prompt, i2v_height, i2v_width, i2v_aspect_ratio],
|
| 426 |
+
outputs=[i2v_prompt, i2v_height, i2v_width]
|
| 427 |
)
|
| 428 |
i2v_input_image.upload(
|
| 429 |
fn=handle_image_upload_for_dims_wan,
|