Fashion-FLUX / app.py
ginipick's picture
Update app.py
4b8e8f5 verified
raw
history blame
9.84 kB
import spaces
import gradio as gr
import torch
from PIL import Image
from diffusers import DiffusionPipeline
import random
from transformers import pipeline
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
torch.backends.cuda.matmul.allow_tf32 = True
# ๋ฒˆ์—ญ ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
translator = pipeline("translation", model="Helsinki-NLP/opus-mt-ko-en")
# ๊ธฐ๋ณธ ๋ชจ๋ธ ๋ฐ LoRA ์„ค์ •
base_model = "black-forest-labs/FLUX.1-dev"
model_lora_repo = "Motas/Flux_Fashion_Photography_Style" # ํŒจ์…˜ ๋ชจ๋ธ LoRA
clothes_lora_repo = "prithivMLmods/Canopus-Clothing-Flux-LoRA" # ์˜๋ฅ˜ LoRA
pipe = DiffusionPipeline.from_pretrained(base_model, torch_dtype=torch.bfloat16)
pipe.to("cuda")
MAX_SEED = 2**32-1
# ์˜ˆ์ œ ์„ค์ •
example_model_prompts = [
"professional fashion model, full body shot, standing pose, natural lighting, studio background, high fashion, elegant pose",
"fashion model portrait, upper body, confident pose, fashion photography, neutral background, professional lighting",
"stylish fashion model, three-quarter view, editorial pose, high-end fashion magazine style, minimal background"
]
example_clothes_prompts = [
"luxury designer sweater, cashmere material, cream color, cable knit pattern, high-end fashion, product photography",
"elegant business blazer, tailored fit, charcoal grey, premium wool fabric, professional wear",
"modern streetwear hoodie, oversized fit, minimalist design, premium cotton, urban style"
]
@spaces.GPU()
def generate_fashion(prompt, mode, cfg_scale, steps, randomize_seed, seed, width, height, lora_scale, progress=gr.Progress(track_tqdm=True)):
# ํ•œ๊ธ€ ๊ฐ์ง€ ๋ฐ ๋ฒˆ์—ญ
def contains_korean(text):
return any(ord('๊ฐ€') <= ord(char) <= ord('ํžฃ') for char in text)
if contains_korean(prompt):
translated = translator(prompt)[0]['translation_text']
actual_prompt = translated
else:
actual_prompt = prompt
# ๋ชจ๋“œ์— ๋”ฐ๋ฅธ LoRA ๋ฐ ํŠธ๋ฆฌ๊ฑฐ์›Œ๋“œ ์„ค์ •
if mode == "Generate Model":
pipe.load_lora_weights(model_lora_repo)
trigger_word = "fashion photography, professional model"
else:
pipe.load_lora_weights(clothes_lora_repo)
trigger_word = "upper clothing, fashion item"
if randomize_seed:
seed = random.randint(0, MAX_SEED)
generator = torch.Generator(device="cuda").manual_seed(seed)
progress(0, "Starting fashion generation...")
for i in range(1, steps + 1):
if i % (steps // 10) == 0:
progress(i / steps * 100, f"Processing step {i} of {steps}...")
image = pipe(
prompt=f"{actual_prompt} {trigger_word}",
num_inference_steps=steps,
guidance_scale=cfg_scale,
width=width,
height=height,
generator=generator,
joint_attention_kwargs={"scale": lora_scale},
).images[0]
progress(100, "Completed!")
return image, seed
# CSS ์ •์˜
custom_css = """
body {
background-color: #f5f5f5;
font-family: 'Arial', sans-serif;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.header {
text-align: center;
color: #333;
margin-bottom: 30px;
font-size: 2.5em;
text-transform: uppercase;
letter-spacing: 2px;
}
.box-common {
background-color: white;
border-radius: 15px;
padding: 25px;
margin: 20px 0;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.mode-box {
background-color: #fff;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
border: 2px solid #eee;
}
.result-box {
width: 90%;
max-width: 1000px;
margin: 20px auto;
}
.image-output {
width: 100%;
max-width: 800px;
margin: 0 auto;
display: block;
}
.prompt-box {
width: 90%;
max-width: 1000px;
margin: 20px auto;
}
.generate-btn {
background: linear-gradient(45deg, #ff6b6b, #ff8e8e) !important;
color: white !important;
padding: 15px 30px !important;
border-radius: 8px !important;
border: none !important;
font-size: 1.1em !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
width: 250px !important;
margin: 20px auto !important;
display: block !important;
text-transform: uppercase !important;
letter-spacing: 1px !important;
}
.generate-btn:hover {
background: linear-gradient(45deg, #ff8e8e, #ff6b6b) !important;
transform: translateY(-2px) !important;
box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4) !important;
}
.accordion {
width: 90%;
max-width: 1000px;
margin: 20px auto;
}
.examples-table {
background-color: rgba(255, 255, 255, 0.95);
border-radius: 8px;
padding: 15px;
margin-top: 20px;
}
.parameter-box {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin: 10px 0;
}
"""
with gr.Blocks(theme="Yntec/HaleyCH_Theme_Orange") as app:
gr.Markdown("# ๐ŸŽญ Fashion AI Studio")
gr.Markdown("Generate fashion images and try on virtual clothing using AI")
with gr.Tabs():
# Virtual Try-On ํƒญ
with gr.TabItem("๐Ÿ‘” Virtual Try-On"):
with gr.Row():
with gr.Column():
prompt_input = gr.Textbox(
label="Style Description",
placeholder="Describe the desired style (e.g., 'person wearing elegant dress')"
)
with gr.Row():
with gr.Group():
structure_image = gr.Image(
label="Your Photo (Full-body)",
type="filepath"
)
gr.Markdown("*Upload a clear, well-lit full-body photo*")
depth_strength = gr.Slider(
minimum=0,
maximum=50,
value=15,
label="Fitting Strength"
)
with gr.Group():
style_image = gr.Image(
label="Clothing Item",
type="filepath"
)
gr.Markdown("*Upload the clothing item you want to try on*")
style_strength = gr.Slider(
minimum=0,
maximum=1,
value=0.5,
label="Style Transfer Strength"
)
tryon_btn = gr.Button("Generate Try-On")
gr.Examples(
examples=examples,
inputs=[prompt_input, structure_image, style_image, depth_strength, style_strength],
outputs=[output_image],
fn=generate_image,
cache_examples=True
)
with gr.Column():
output_image.render()
# Fashion Generation ํƒญ
with gr.TabItem("๐Ÿ‘— Fashion Generation"):
with gr.Column():
# ๋ชจ๋“œ ์„ ํƒ
with gr.Group():
mode = gr.Radio(
choices=["Generate Model", "Generate Clothes"],
label="Generation Mode",
value="Generate Model"
)
# ํ”„๋กฌํ”„ํŠธ ์ž…๋ ฅ
prompt = gr.TextArea(
label="โœ๏ธ Fashion Description (ํ•œ๊ธ€ ๋˜๋Š” ์˜์–ด)",
placeholder="ํŒจ์…˜ ๋ชจ๋ธ์ด๋‚˜ ์˜๋ฅ˜๋ฅผ ์„ค๋ช…ํ•˜์„ธ์š”...",
lines=5
)
# ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€
result = gr.Image(label="Generated Fashion")
generate_button = gr.Button("๐Ÿš€ Generate Fashion")
# ๊ณ ๊ธ‰ ์„ค์ • ์•„์ฝ”๋””์–ธ
with gr.Accordion("๐ŸŽจ Advanced Options", open=False):
with gr.Row():
cfg_scale = gr.Slider(label="CFG Scale", minimum=1, maximum=20, value=7.0)
steps = gr.Slider(label="Steps", minimum=1, maximum=100, value=30)
lora_scale = gr.Slider(label="LoRA Scale", minimum=0, maximum=1, value=0.85)
with gr.Row():
width = gr.Slider(label="Width", minimum=256, maximum=1536, value=512)
height = gr.Slider(label="Height", minimum=256, maximum=1536, value=768)
with gr.Row():
randomize_seed = gr.Checkbox(True, label="Randomize seed")
seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, value=42)
# ์˜ˆ์ œ ํƒญ
with gr.Tabs():
with gr.TabItem("Model Examples"):
gr.Examples(examples=example_model_prompts, inputs=prompt)
with gr.TabItem("Clothes Examples"):
gr.Examples(examples=example_clothes_prompts, inputs=prompt)
# ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
tryon_btn.click(
fn=generate_image,
inputs=[prompt_input, structure_image, style_image, depth_strength, style_strength],
outputs=[output_image]
)
generate_button.click(
generate_fashion,
inputs=[prompt, mode, cfg_scale, steps, randomize_seed, seed, width, height, lora_scale],
outputs=[result, seed]
)
if __name__ == "__main__":
app.launch(share=True)