salomonsky commited on
Commit
644a3af
1 Parent(s): 599e239

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +191 -66
app.py CHANGED
@@ -1,77 +1,202 @@
1
- import streamlit as st
2
- import torch
3
  from PIL import Image
 
 
 
 
4
  import random
5
- from diffusers import StableDiffusionInstructPix2PixPipeline, DiffusionPipeline, FluxPipeline
6
-
7
- device = "cuda" if torch.cuda.is_available() else "cpu"
8
-
9
- model_options = {
10
- "Instruct Pix2Pix": "timbrooks/instruct-pix2pix",
11
- "SDXL Turbo": "stabilityai/sdxl-turbo",
12
- "FLUX": "alimama-creative/FLUX.1-Turbo-Alpha"
13
- }
14
-
15
- selected_model = st.sidebar.selectbox("Selecciona el modelo", list(model_options.keys()))
16
- model_id = model_options[selected_model]
17
-
18
- @st.cache_resource
19
- def load_model():
20
- if selected_model == "Instruct Pix2Pix":
21
- return StableDiffusionInstructPix2PixPipeline.from_pretrained(model_id, safety_checker=None).to(device)
22
- elif selected_model == "SDXL Turbo":
23
- return DiffusionPipeline.from_pretrained(model_id, safety_checker=None).to(device)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  else:
25
- return FluxPipeline.from_pretrained(model_id, safety_checker=None).to(device)
26
-
27
- pipe = load_model()
28
 
29
- def resize(img, max_size=512):
30
- ratio = min(max_size / img.width, max_size / img.height)
31
- new_size = (int(img.width * ratio), int(img.height * ratio))
32
- return img.resize(new_size, Image.LANCZOS)
33
 
34
- def infer(source_img, prompt, steps, seed, guidance_scale):
35
- torch.manual_seed(seed)
36
- source_image = resize(source_img)
37
- progress_bar = st.progress(0)
38
- st.text("Generando imagen...")
39
 
 
40
  try:
41
- for i in range(steps):
42
- output = pipe(
43
- prompt,
44
- image=source_image,
45
- guidance_scale=guidance_scale / 10,
46
- num_inference_steps=steps
47
- )
48
-
49
- result = output.images[0] if output.images else None
50
-
51
- if result is None:
52
- raise ValueError("No se generaron imágenes.")
53
-
54
- progress_bar.progress((i + 1) / steps)
55
-
56
- progress_bar.progress(1.0)
57
  except Exception as e:
58
- st.error(f"Error durante la inferencia: {str(e)}")
59
- return None
60
 
61
- return result
62
-
63
- st.title("Flux Image to Image")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
- with st.sidebar:
66
- uploaded_image = st.file_uploader("Sube una imagen", type=["png", "jpg", "jpeg"], key="unique_file_uploader")
67
- prompt = st.text_input("Texto del prompt (máx. 77 tokens)")
68
- steps = st.slider("Número de Iteraciones", min_value=1, max_value=50, value=2, step=1)
69
- randomize_seed = st.radio("Randomize Seed", ["Randomize Seed", "Fix Seed"])
70
- seed = st.slider("Seed", min_value=0, max_value=9999, step=1, value=random.randint(0, 9999) if randomize_seed == "Randomize Seed" else 1)
71
- guidance_scale = st.slider("Guidance Scale", min_value=0.0, max_value=10.0, step=0.01, value=9.0)
72
 
73
- if uploaded_image is not None and st.button("Generar imagen"):
74
- image = Image.open(uploaded_image).convert("RGB")
75
- result_image = infer(image, prompt, steps, seed, guidance_scale)
76
- if result_image is not None:
77
- st.image(result_image, caption="Imagen generada", use_column_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
 
2
  from PIL import Image
3
+ import streamlit as st
4
+ from huggingface_hub import InferenceClient, AsyncInferenceClient
5
+ import asyncio
6
+ import os
7
  import random
8
+ import numpy as np
9
+ import yaml
10
+ import requests
11
+
12
+ HUGGINGFACE_API = os.environ.get("HF_TOKEN")
13
+
14
+ try:
15
+ with open("config.yaml", "r") as file:
16
+ credentials = yaml.safe_load(file)
17
+ except Exception as e:
18
+ st.error(f"Error al cargar el archivo de configuración: {e}")
19
+ credentials = {"username": "", "password": ""}
20
+
21
+ MAX_SEED = np.iinfo(np.int32).max
22
+ client = AsyncInferenceClient()
23
+ llm_client = InferenceClient("mistralai/Mixtral-8x7B-Instruct-v0.1")
24
+ DATA_PATH = Path("./data")
25
+ DATA_PATH.mkdir(exist_ok=True)
26
+
27
+ def authenticate_user(username, password):
28
+ return username == credentials["username"] and password == credentials["password"]
29
+
30
+ async def gen(prompts, width, height, model_name, num_variants, prompt_checkbox, lora=None):
31
+ headers = {"Authorization": f"Bearer {HUGGINGFACE_API}"}
32
+ payload = {
33
+ "inputs": prompts,
34
+ "parameters": {
35
+ "width": width,
36
+ "height": height,
37
+ "num_inference_steps": 50,
38
+ "guidance_scale": 7.5
39
+ }
40
+ }
41
+ if lora:
42
+ payload["parameters"]["lora"] = lora
43
+ url = f"https://api-inference.huggingface.co/models/{model_name}"
44
+
45
+ response = requests.post(url, headers=headers, json=payload)
46
+ if response.status_code != 200:
47
+ raise Exception(f"Error: {response.status_code}, {response.text}")
48
+
49
+ return response.json()
50
+
51
+ def list_saved_images():
52
+ return sorted(DATA_PATH.glob("*.jpg"), key=os.path.getmtime, reverse=True)
53
+
54
+ def display_gallery():
55
+ st.header("Galería de Imágenes Guardadas")
56
+ images = list_saved_images()
57
+ if images:
58
+ cols = st.columns(8)
59
+ for i, image_file in enumerate(images):
60
+ with cols[i % 8]:
61
+ st.image(str(image_file), caption=image_file.name, use_column_width=True)
62
+ prompt = get_prompt_for_image(image_file.name)
63
+ st.write(prompt[:300])
64
+
65
+ if st.button(f"Borrar", key=f"delete_{i}_{image_file.name}"):
66
+ os.remove(image_file)
67
+ st.success("Imagen borrada")
68
+ display_gallery()
69
  else:
70
+ st.info("No hay imágenes guardadas.")
 
 
71
 
72
+ def save_prompt(prompt):
73
+ with open(DATA_PATH / "prompts.txt", "a") as f:
74
+ f.write(prompt + "\n")
 
75
 
76
+ def run_async(func, *args):
77
+ return asyncio.run(func(*args))
 
 
 
78
 
79
+ async def improve_prompt(prompt):
80
  try:
81
+ instructions = [
82
+ "With my idea create a vibrant description for a detailed txt2img prompt, 300 characters max.",
83
+ "With my idea write a creative and detailed text-to-image prompt in English, 300 characters max.",
84
+ "With my idea generate a descriptive and visual txt2img prompt in English, 300 characters max.",
85
+ "With my idea describe a photorealistic with illumination txt2img prompt in English, 300 characters max.",
86
+ "With my idea give a realistic and elegant txt2img prompt in English, 300 characters max.",
87
+ "With my idea conform a visually dynamic and surreal txt2img prompt in English, 300 characters max.",
88
+ "With my idea realize an artistic and cinematic txt2img prompt in English, 300 characters max.",
89
+ "With my idea make a narrative and immersive txt2img prompt in English, 300 characters max."
90
+ ]
91
+ instruction = random.choice(instructions)
92
+ formatted_prompt = f"{prompt}: {instruction}"
93
+ response = llm_client.text_generation(formatted_prompt, max_new_tokens=100)
94
+ return response['generated_text'][:100] if 'generated_text' in response else response.strip()
 
 
95
  except Exception as e:
96
+ return f"Error mejorando el prompt: {e}"
 
97
 
98
+ def save_image(image, file_name, prompt=None):
99
+ image_path = DATA_PATH / file_name
100
+ if image_path.exists():
101
+ st.warning(f"La imagen '{file_name}' ya existe en la galería. No se guardó.")
102
+ return None
103
+ else:
104
+ image.save(image_path, format="JPEG")
105
+ if prompt:
106
+ save_prompt(f"{file_name}: {prompt}")
107
+ return image_path
108
+
109
+ async def generate_image(prompt, width, height, seed, model_name):
110
+ if seed == -1:
111
+ seed = random.randint(0, MAX_SEED)
112
+ image = await client.text_to_image(prompt=prompt, height=height, width=width, model=model_name)
113
+ return image, seed
114
+
115
+ def get_prompt_for_image(image_name):
116
+ prompts = {}
117
+ try:
118
+ with open(DATA_PATH / "prompts.txt", "r") as f:
119
+ for line in f:
120
+ if line.startswith(image_name):
121
+ prompts[image_name] = line.split(": ", 1)[1].strip()
122
+ except FileNotFoundError:
123
+ return "No hay prompt asociado."
124
+ return prompts.get(image_name, "No hay prompt asociado.")
125
+
126
+ def login_form():
127
+ st.title("Iniciar Sesión")
128
+ username = st.text_input("Usuario", value="admin")
129
+ password = st.text_input("Contraseña", value="flux3x", type="password")
130
+ if st.button("Iniciar Sesión"):
131
+ if authenticate_user(username, password):
132
+ st.success("Autenticación exitosa.")
133
+ st.session_state['authenticated'] = True
134
+ else:
135
+ st.error("Credenciales incorrectas. Intenta de nuevo.")
136
+
137
+ async def generate_variations(prompt, num_variants, use_enhanced):
138
+ prompts = set()
139
+ while len(prompts) < num_variants:
140
+ if use_enhanced:
141
+ enhanced_prompt = await improve_prompt(prompt)
142
+ prompts.add(enhanced_prompt)
143
+ else:
144
+ prompts.add(prompt)
145
+ return list(prompts)
146
+
147
+ async def main():
148
+ st.set_page_config(layout="wide")
149
+
150
+ if 'authenticated' not in st.session_state or not st.session_state['authenticated']:
151
+ login_form()
152
+ return
153
+
154
+ st.title("Flux + Multiple Images")
155
+ prompt = st.sidebar.text_area("Descripción de la imagen", height=150, max_chars=500)
156
+
157
+ style_option = st.sidebar.selectbox("Selecciona un estilo",
158
+ ["realistic", "photorealistic", "illustration",
159
+ "cartoon", "comic", "imaginative", "abstract"])
160
+
161
+ prompt_with_style = f"{prompt}, {style_option} style"
162
+
163
+ lora_option = st.sidebar.selectbox("Selecciona un LoRA",
164
+ ["XLabs-AI/flux-RealismLora", "XLabs-AI/flux-RealismLora"])
165
+
166
+ format_option = st.sidebar.selectbox("Formato", ["9:16", "16:9", "1:1"])
167
+ prompt_checkbox = st.sidebar.checkbox("Prompt Enhancer")
168
+ model_option = st.sidebar.selectbox("Modelo",
169
+ ["black-forest-labs/FLUX.1-schnell",
170
+ "black-forest-labs/FLUX.1-dev",
171
+ "enhanceaiteam/Flux-Uncensored-V2",
172
+ "enhanceaiteam/Flux-Uncensored"])
173
+
174
+ width, height = (360, 640) if format_option == "9:16" else (640, 360) if format_option == "16:9" else (640, 640)
175
+
176
+ if prompt_checkbox:
177
+ num_variants = st.sidebar.slider("Número de imágenes a generar", 1, 8, 1)
178
+ else:
179
+ num_variants = 1
180
 
181
+ model_name = model_option
 
 
 
 
 
 
182
 
183
+ if prompt_checkbox:
184
+ with st.spinner("Generando prompts mejorados..."):
185
+ prompts = await generate_variations(prompt_with_style, num_variants, True)
186
+ else:
187
+ prompts = [prompt_with_style]
188
+
189
+ if st.sidebar.button("Generar Imágenes"):
190
+ with st.spinner("Generando imágenes..."):
191
+ try:
192
+ results = await gen(prompts, width, height, model_name, num_variants, prompt_checkbox, lora_option)
193
+ st.session_state['generated_image_paths'] = results
194
+ for result in results:
195
+ st.image(result, caption="Imagen Generada")
196
+ except Exception as e:
197
+ st.error(f"Error al generar las imágenes: {str(e)}")
198
+
199
+ display_gallery()
200
+
201
+ if __name__ == "__main__":
202
+ asyncio.run(main())