Flux / app.py
Leteint's picture
Update app.py
2516959 verified
import spaces
import torch
import gradio as gr
from diffusers import FluxPipeline
from huggingface_hub import hf_hub_download, login
import random
import os
# Authentification
hf_token = os.getenv("HF_TOKEN")
print(f"Token trouvé : {bool(hf_token)}")
if hf_token:
login(token=hf_token)
print("✅ Authentifié")
model_id = "black-forest-labs/FLUX.1-schnell"
# Prompt par défaut
DEFAULT_PROMPT = "A stunning portrait of a woman with flowing red hair, piercing green eyes, natural lighting, ultra detailed, 8k quality, professional photography"
# Note: FLUX.1-schnell n'utilise PAS de LoRA par défaut
# Le modèle de base est déjà optimisé pour la génération rapide
# Si vous voulez ajouter des LoRA, utilisez des repositories communautaires comme:
# - XLabs-AI/flux-RealismLora
# - Shakker-Labs/FLUX.1-dev-LoRA-collections
# Abzaloff/Flux_Art_Fusion
# XLabs-AI/flux-RealismLora
# etc.
lora_repo = None
lora_path = None
def load_lora(repo_id, filename):
"""Charge un LoRA depuis un repository HuggingFace"""
global lora_repo, lora_path
if not repo_id or not filename:
return "Abzaloff/Flux_Art_Fusion"
try:
lora_path = hf_hub_download(repo_id=repo_id, filename=filename)
lora_repo = repo_id
return f"✅ LoRA chargé : {repo_id}/{filename}"
except Exception as e:
return f"❌ Erreur : {str(e)}\n\nVérifiez que le repository contient bien ce fichier."
@spaces.GPU(duration=120)
def generate(prompt, negative_prompt="", width=1024, height=1024, steps=4, seed=-1, lora_scale=0.8):
try:
# Initialisation du pipeline
pipe = FluxPipeline.from_pretrained(
model_id,
torch_dtype=torch.bfloat16
)
pipe.to("cuda")
# Chargement du LoRA si disponible
if lora_repo and lora_path:
pipe.load_lora_weights(lora_path)
pipe.fuse_lora(lora_scale=lora_scale)
# Optimisation mémoire
pipe.enable_model_cpu_offload()
# Génération du seed
if seed == -1:
seed = random.randint(0, 2**32 - 1)
generator = torch.Generator("cuda").manual_seed(seed)
# Génération de l'image
image = pipe(
prompt=prompt,
negative_prompt=negative_prompt if negative_prompt else None,
height=height,
width=width,
num_inference_steps=steps,
guidance_scale=0.0,
generator=generator,
max_sequence_length=256
).images[0]
# Nettoyage de la mémoire
del pipe
torch.cuda.empty_cache()
return image
except Exception as e:
print(f"❌ Erreur de génération : {str(e)}")
raise gr.Error(f"Erreur : {str(e)}")
# Interface Gradio
with gr.Blocks(title="Flux Schnell + LoRA") as demo:
gr.Markdown("# 🎨 Générateur Flux Schnell + LoRA")
gr.Markdown(f"**Modèle :** `{model_id}`")
with gr.Row():
with gr.Column():
# LoRA
gr.Markdown("### 🎨 Ajouter un LoRA (optionnel)")
gr.Markdown("""
⚠️ **Important** : Le modèle de base FLUX.1-schnell fonctionne **sans LoRA**.
Si vous voulez ajouter un style avec un LoRA, utilisez des repositories communautaires :
- `XLabs-AI/flux-RealismLora` (fichier: `lora.safetensors`)
- `Shakker-Labs/FLUX.1-dev-LoRA-add-details` (fichier: `FLUX-dev-lora-add_details.safetensors`)
""")
lora_repo_input = gr.Textbox(
label="Repository LoRA",
placeholder="Ex: XLabs-AI/flux-RealismLora",
value="Abzaloff/Flux_Art_Fusion"
)
lora_filename = gr.Textbox(
label="Nom du fichier LoRA",
placeholder="Ex: lora.safetensors",
value="Flux_Art_fusion_v1_fp16_00001_.safetensors"
)
load_btn = gr.Button("Charger LoRA")
lora_status = gr.Textbox(label="Status", interactive=False)
# Paramètres
gr.Markdown("### Paramètres de génération")
prompt = gr.Textbox(
label="Prompt",
placeholder="Décrivez votre image...",
lines=3,
value=DEFAULT_PROMPT
)
negative_prompt = gr.Textbox(
label="Negative Prompt (optionnel)",
placeholder="blurry, low quality, distorted, ugly",
lines=2
)
with gr.Row():
width = gr.Slider(512, 2048, 1024, step=64, label="Largeur")
height = gr.Slider(512, 2048, 1024, step=64, label="Hauteur")
with gr.Row():
steps = gr.Slider(1, 10, 4, step=1, label="Steps")
seed = gr.Number(label="Seed (-1 = aléatoire)", value=-1)
lora_scale = gr.Slider(0, 1, 0.8, step=0.1, label="LoRA Scale")
generate_btn = gr.Button("🚀 Générer", variant="primary")
with gr.Column():
output_image = gr.Image(label="Image générée", type="pil")
gr.Markdown("### 💡 Conseils")
gr.Markdown("""
- **Modèle de base** : FLUX.1-schnell (rapide, sans LoRA nécessaire)
- **Steps recommandés** : 4 pour Schnell
- **Résolution** : 1024x1024 par défaut
- **LoRA Scale** : 0.8 pour un effet équilibré (ajustez entre 0-1)
**Exemples de repositories LoRA compatibles :**
- [XLabs-AI/flux-RealismLora](https://huggingface.co/XLabs-AI/flux-RealismLora)
- [Shakker-Labs collections](https://huggingface.co/Shakker-Labs)
""")
# Actions
load_btn.click(
fn=load_lora,
inputs=[lora_repo_input, lora_filename],
outputs=lora_status
)
generate_btn.click(
fn=generate,
inputs=[prompt, negative_prompt, width, height, steps, seed, lora_scale],
outputs=output_image
)
# Lancement avec gestion propre de l'event loop
if __name__ == "__main__":
demo.queue() # Active la file d'attente
demo.launch(
server_name="0.0.0.0",
server_port=7860,
show_error=True,
quiet=False
)