facefusion3 / app.py
ginipick's picture
Update app.py
8c89a89 verified
raw
history blame
9.16 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;
}
"""
# Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
with gr.Blocks(css=custom_css, theme="Yntec/HaleyCH_Theme_Orange") as app:
with gr.Column(elem_classes="container"):
gr.Markdown("# ๐ŸŽญ Fashion Generation Studio", elem_classes="header")
# ๋ชจ๋“œ ์„ ํƒ
with gr.Group(elem_classes="mode-box box-common"):
mode = gr.Radio(
choices=["Generate Model", "Generate Clothes"],
label="Generation Mode",
value="Generate Model"
)
# ์ด๋ฏธ์ง€ ์ถœ๋ ฅ ์˜์—ญ
with gr.Group(elem_classes="result-box box-common"):
gr.Markdown("### ๐Ÿ–ผ๏ธ Generated Fashion")
result = gr.Image(label="Result", elem_classes="image-output")
# ํ”„๋กฌํ”„ํŠธ ์ž…๋ ฅ ์˜์—ญ
with gr.Group(elem_classes="prompt-box box-common"):
prompt = gr.TextArea(
label="โœ๏ธ Fashion Description (ํ•œ๊ธ€ ๋˜๋Š” ์˜์–ด)",
placeholder="ํŒจ์…˜ ๋ชจ๋ธ์ด๋‚˜ ์˜๋ฅ˜๋ฅผ ์„ค๋ช…ํ•˜์„ธ์š”...",
lines=5
)
generate_button = gr.Button(
"๐Ÿš€ Generate Fashion",
elem_classes="generate-btn"
)
# ์˜ˆ์ œ ํƒญ
with gr.Tabs():
with gr.TabItem("Model Examples"):
gr.Examples(
examples=example_model_prompts,
inputs=prompt,
label="Model Prompts"
)
with gr.TabItem("Clothes Examples"):
gr.Examples(
examples=example_clothes_prompts,
inputs=prompt,
label="Clothes Prompts"
)
# ๊ณ ๊ธ‰ ์˜ต์…˜
with gr.Accordion("๐ŸŽจ Advanced Options", open=False, elem_classes="accordion box-common"):
with gr.Group(elem_classes="parameter-box"):
gr.Markdown("### ๐ŸŽ›๏ธ Generation Parameters")
with gr.Row():
with gr.Column():
cfg_scale = gr.Slider(
label="CFG Scale",
minimum=1,
maximum=20,
step=0.5,
value=7.0
)
steps = gr.Slider(
label="Steps",
minimum=1,
maximum=100,
step=1,
value=30
)
lora_scale = gr.Slider(
label="LoRA Scale",
minimum=0,
maximum=1,
step=0.01,
value=0.85
)
with gr.Group(elem_classes="parameter-box"):
gr.Markdown("### ๐Ÿ“ Image Dimensions")
with gr.Row():
width = gr.Slider(
label="Width",
minimum=256,
maximum=1536,
step=64,
value=512
)
height = gr.Slider(
label="Height",
minimum=256,
maximum=1536,
step=64,
value=768
)
with gr.Group(elem_classes="parameter-box"):
gr.Markdown("### ๐ŸŽฒ Seed Settings")
with gr.Row():
randomize_seed = gr.Checkbox(
True,
label="Randomize seed"
)
seed = gr.Slider(
label="Seed",
minimum=0,
maximum=MAX_SEED,
step=1,
value=42
)
# ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
generate_button.click(
generate_fashion,
inputs=[prompt, mode, cfg_scale, steps, randomize_seed, seed, width, height, lora_scale],
outputs=[result, seed]
)
app.queue()
app.launch()