FD / app.py
lea97338's picture
Update app.py
ccaae31 verified
Raw
History Blame Contribute Delete
3.78 kB
# ✅ OBLIGATOIRE EN PREMIER
import spaces
import torch
from diffusers import Flux2KleinPipeline
import gradio as gr
import os
from datetime import datetime
from ddgs import DDGS
import requests
from PIL import Image
from io import BytesIO
import re
# ⚠️ pas de empty_cache avant spaces
# =========================
# CSS
# =========================
custom_css = """
* { font-family: Arial, sans-serif !important; }
html, body, .gradio-container { background-color: #0f172a !important; }
h1, h2, h3, label, span, p { color: #22c55e !important; }
input, textarea, select {
background-color: #1f2937 !important;
color: white !important;
border-radius: 8px !important;
border: 1px solid #22c55e !important;
}
button { background: black !important; color: #22c55e !important; }
"""
# =========================
# PIPELINE
# =========================
pipe = Flux2KleinPipeline.from_pretrained(
"lea97338/KTXFlux-2.0",
token=os.environ["HF_Token"], # ✅ en Space, token inutile si public
cache_dir="./model",
torch_dtype=torch.float16,
)
# ✅ meilleur mode pour Spaces
pipe.enable_model_cpu_offload()
pipe.enable_attention_slicing()
OUTPUT_DIR = "./outputs"
# =========================
# CLEAN TEXT
# =========================
def clean_text(text):
text = re.sub(r"#\w+|http\S+|\d+", "", text.lower())
return " ".join([w for w in text.split() if len(w) > 3][:10])
# =========================
# DDGS (light pour Spaces)
# =========================
def ddgs_search(prompt):
texts = []
try:
with DDGS() as ddgs:
for r in ddgs.text(prompt, max_results=2):
t = clean_text(r.get("body", ""))
if t:
texts.append(t)
except:
pass
return " ".join(texts)
# =========================
# RESOLUTION
# =========================
def get_dimensions(res):
return {
"256x256": (256,256),
"512x512": (512,512),
"Panorama": (1024,512),
}[res]
# =========================
# GENERATE
# =========================
@spaces.GPU
def generate_image(prompt, steps, guidance, resolution):
width, height = get_dimensions(resolution)
os.makedirs(OUTPUT_DIR, exist_ok=True)
extra_text = ddgs_search(prompt)
final_prompt = f"{prompt}, {extra_text}"
result = pipe(
prompt=final_prompt,
height=height,
width=width,
num_inference_steps=steps, # ✅ obligatoire pour vitesse
guidance_scale=float(guidance),
)
image = result.images[0]
path = os.path.join(
OUTPUT_DIR,
datetime.now().strftime("img_%Y%m%d_%H%M%S.png")
)
image.save(path)
return image, path
# =========================
# UI
# =========================
with gr.Blocks(css=custom_css) as demo:
gr.Markdown("# ⚡ Flux Generator (HF Spaces optimisé)")
with gr.Row():
with gr.Column():
prompt = gr.Textbox(value="minecraft village", label="Prompt")
steps = gr.Slider(1, 30, 1, step=1, label="Steps")
guidance = gr.Slider(1.0, 5.0, 2.5, step=0.5, label="Guidance")
resolution = gr.Dropdown(
["256x256","512x512","Panorama"],
value="512x512",
label="Résolution"
)
btn = gr.Button("⚡ Générer")
path_out = gr.Textbox(label="Fichier")
with gr.Column():
image_out = gr.Image(label="Résultat")
btn.click(
generate_image,
inputs=[prompt, steps, guidance, resolution],
outputs=[image_out, path_out]
)
# =========================
# RUN (🔥 important)
# =========================
if __name__ == "__main__":
demo.launch() # ❌ PAS de share=True sur Spaces