| |
| 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 |
|
|
| |
|
|
| |
| |
| |
| 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; } |
| """ |
|
|
| |
| |
| |
| pipe = Flux2KleinPipeline.from_pretrained( |
| "lea97338/KTXFlux-2.0", |
| token=os.environ["HF_Token"], |
| cache_dir="./model", |
| torch_dtype=torch.float16, |
| ) |
|
|
| |
| pipe.enable_model_cpu_offload() |
| pipe.enable_attention_slicing() |
|
|
| OUTPUT_DIR = "./outputs" |
|
|
| |
| |
| |
| 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]) |
|
|
| |
| |
| |
| 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) |
|
|
| |
| |
| |
| def get_dimensions(res): |
| return { |
| "256x256": (256,256), |
| "512x512": (512,512), |
| "Panorama": (1024,512), |
| }[res] |
|
|
| |
| |
| |
| @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, |
| 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 |
|
|
| |
| |
| |
| 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] |
| ) |
|
|
| |
| |
| |
| if __name__ == "__main__": |
| demo.launch() |