prithivMLmods's picture
Update app.py
a189e3c verified
Raw
History Blame
7.73 kB
import os
import gradio as gr
import numpy as np
import spaces
import torch
import random
from PIL import Image
from typing import Iterable
# Pipeline for FLUX.2 Klein
from diffusers import Flux2KleinPipeline
from diffusers.utils import load_image
from huggingface_hub import hf_hub_download
# --- Hardware and Theme Setup ---
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
from gradio.themes import Soft
from gradio.themes.utils import colors, fonts, sizes
colors.orange_red = colors.Color(
name="orange_red", c50="#FFF0E5", c100="#FFE0CC", c200="#FFC299", c300="#FFA366",
c400="#FF8533", c500="#FF4500", c600="#E63E00", c700="#CC3700", c800="#B33000",
c900="#992900", c950="#802200",
)
class OrangeRedTheme(Soft):
def __init__(
self, *, primary_hue: colors.Color | str = colors.gray,
secondary_hue: colors.Color | str = colors.orange_red,
neutral_hue: colors.Color | str = colors.slate, text_size: sizes.Size | str = sizes.text_lg,
font: fonts.Font | str | Iterable[fonts.Font | str] = (
fonts.GoogleFont("Outfit"), "Arial", "sans-serif",
),
font_mono: fonts.Font | str | Iterable[fonts.Font | str] = (
fonts.GoogleFont("IBM Plex Mono"), "ui-monospace", "monospace",
),
):
super().__init__(
primary_hue=primary_hue, secondary_hue=secondary_hue, neutral_hue=neutral_hue,
text_size=text_size, font=font, font_mono=font_mono,
)
super().set(
background_fill_primary="*primary_50",
background_fill_primary_dark="*primary_900",
body_background_fill="linear-gradient(135deg, *primary_200, *primary_100)",
body_background_fill_dark="linear-gradient(135deg, *primary_900, *primary_800)",
button_primary_text_color="white",
button_primary_text_color_hover="white",
button_primary_background_fill="linear-gradient(90deg, *secondary_500, *secondary_600)",
button_primary_background_fill_hover="linear-gradient(90deg, *secondary_600, *secondary_700)",
button_primary_background_fill_dark="linear-gradient(90deg, *secondary_600, *secondary_700)",
button_primary_background_fill_hover_dark="linear-gradient(90deg, *secondary_500, *secondary_600)",
slider_color="*secondary_500",
slider_color_dark="*secondary_600",
block_title_text_weight="600", block_border_width="3px",
block_shadow="*shadow_drop_lg", button_primary_shadow="*shadow_drop_lg",
button_large_padding="11px", color_accent_soft="*primary_100",
block_label_background_fill="*primary_200",
)
orange_red_theme = OrangeRedTheme()
MAX_SEED = np.iinfo(np.int32).max
# --- Model Loading ---
print("Loading FLUX.2 Klein 9B model...")
pipe = Flux2KleinPipeline.from_pretrained(
"black-forest-labs/FLUX.2-klein-9B",
torch_dtype=torch.bfloat16
).to(device)
print("Model loaded successfully.")
# --- LoRA Loading (Updated) ---
print("Loading new LoRA adapters...")
pipe.load_lora_weights(
"markury/flux2k9b-simpletuner-lora-loona",
weight_name="pytorch_lora_weights.safetensors",
adapter_name="simple-tuner"
)
pipe.load_lora_weights(
"linoyts/Flux2-Klein-Delight-LoRA",
weight_name="pytorch_lora_weights_v2.safetensors",
adapter_name="klein-delight"
)
print("All LoRA adapters loaded.")
# Updated map for the new adapters
ADAPTER_MAP = {
"Simple-Tuner": "simple-tuner",
"Klein-Delight-Style": "klein-delight",
}
@spaces.GPU
def infer(input_image, prompt, lora_adapter, seed=42, randomize_seed=True, guidance_scale=4.0, steps=4, progress=gr.Progress(track_tqdm=True)):
# Input image is required for image-to-image tasks
if not input_image:
raise gr.Error("Please upload an image to apply a style to.")
# Dynamically set the adapter based on the dropdown choice
adapter_name = ADAPTER_MAP.get(lora_adapter)
if adapter_name:
print(f"Activating LoRA: {lora_adapter} ({adapter_name})")
pipe.set_adapters([adapter_name], adapter_weights=[1.0])
else:
# If "None" is selected (or an invalid choice), disable LoRAs
print("No LoRA selected. Disabling adapters.")
pipe.disable_lora()
if randomize_seed:
seed = random.randint(0, MAX_SEED)
original_image = input_image.copy().convert("RGB")
image = pipe(
image=original_image,
prompt=prompt,
guidance_scale=guidance_scale,
width=original_image.size[0],
height=original_image.size[1],
num_inference_steps=steps,
generator=torch.Generator(device=device).manual_seed(seed),
).images[0]
return image, seed
@spaces.GPU
def infer_example(input_image, prompt, lora_adapter):
# Use a fixed seed for reproducible examples
image, seed = infer(input_image, prompt, lora_adapter, seed=12345, randomize_seed=False)
return image, seed
# --- UI Layout ---
css="""
#col-container { margin: 0 auto; max-width: 960px; }
#main-title h1 { font-size: 2.2em !important; }
"""
with gr.Blocks() as demo:
with gr.Column(elem_id="col-container"):
gr.Markdown("# **FLUX.2 Klein LoRA Stylizer**", elem_id="main-title")
gr.Markdown(
"Apply creative styles to your images using **FLUX.2-klein-9B** and specialized LoRA adapters. "
"Upload an image, select a style, and write a prompt to guide the transformation."
)
with gr.Row(equal_height=True):
with gr.Column():
input_image = gr.Image(label="Upload Image", type="pil", height=290, sources=["upload", "webcam", "clipboard"])
prompt = gr.Text(label="Guiding Prompt", show_label=True, placeholder="e.g., a man with a red superhero mask")
lora_adapter = gr.Dropdown(
label="Choose a Creative Style",
# Updated choices for the new adapters
choices=["Simple-Tuner", "Klein-Delight-Style"],
value="Klein-Delight-Style"
)
run_button = gr.Button("Apply Style", 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)
# Updated defaults suitable for FLUX.2 Klein
guidance_scale = gr.Slider(label="Guidance Scale", minimum=0.0, maximum=10.0, step=0.1, value=4.0)
steps = gr.Slider(label="Steps", minimum=1, maximum=50, value=4, step=1)
with gr.Column():
output_image = gr.Image(label="Stylized Image", interactive=False, format="png", height=450)
used_seed = gr.Textbox(label="Used Seed", interactive=False)
# Updated examples for the new LoRAs
gr.Examples(
examples=[
["examples/animal.jpg", "a cute red panda, charming and delightful illustration, soft lighting", "Klein-Delight-Style"],
],
inputs=[input_image, prompt, lora_adapter],
outputs=[output_image, used_seed],
fn=infer_example,
cache_examples=False,
)
run_button.click(
fn=infer,
inputs=[input_image, prompt, lora_adapter, seed, randomize_seed, guidance_scale, steps],
outputs=[output_image, used_seed]
)
if __name__ == "__main__":
demo.queue().launch(css=css, theme=orange_red_theme, show_error=True)