trashchenkov commited on
Commit
52a10bb
·
verified ·
1 Parent(s): b758af6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +206 -83
app.py CHANGED
@@ -1,62 +1,111 @@
1
  import gradio as gr
2
  import numpy as np
3
- import random
4
-
5
- # import spaces #[uncomment to use ZeroGPU]
6
- from diffusers import DiffusionPipeline
7
  import torch
 
 
 
8
 
 
9
  device = "cuda" if torch.cuda.is_available() else "cpu"
10
- model_repo_id = "stabilityai/sdxl-turbo" # Replace to the model you would like to use
11
 
12
- if torch.cuda.is_available():
13
- torch_dtype = torch.float16
14
- else:
15
- torch_dtype = torch.float32
16
-
17
- pipe = DiffusionPipeline.from_pretrained(model_repo_id, torch_dtype=torch_dtype)
18
- pipe = pipe.to(device)
19
 
 
20
  MAX_SEED = np.iinfo(np.int32).max
21
  MAX_IMAGE_SIZE = 1024
22
 
 
 
 
 
 
 
 
 
 
 
23
 
24
- # @spaces.GPU #[uncomment to use ZeroGPU]
25
  def infer(
 
26
  prompt,
27
  negative_prompt,
28
  seed,
29
- randomize_seed,
30
  width,
31
  height,
32
  guidance_scale,
33
  num_inference_steps,
 
 
 
 
 
 
 
34
  progress=gr.Progress(track_tqdm=True),
35
  ):
36
- if randomize_seed:
37
- seed = random.randint(0, MAX_SEED)
 
 
 
38
 
39
- generator = torch.Generator().manual_seed(seed)
40
 
41
- image = pipe(
42
- prompt=prompt,
43
- negative_prompt=negative_prompt,
44
- guidance_scale=guidance_scale,
45
- num_inference_steps=num_inference_steps,
46
- width=width,
47
- height=height,
48
- generator=generator,
49
- ).images[0]
50
 
51
- return image, seed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
 
 
 
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  examples = [
55
  "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k",
56
  "An astronaut riding a green horse",
57
  "A delicious ceviche cheesecake slice",
58
  ]
59
 
 
60
  css = """
61
  #col-container {
62
  margin: 0 auto;
@@ -64,91 +113,165 @@ css = """
64
  }
65
  """
66
 
 
67
  with gr.Blocks(css=css) as demo:
68
  with gr.Column(elem_id="col-container"):
69
- gr.Markdown(" # Text-to-Image Gradio Template")
70
-
71
- with gr.Row():
72
- prompt = gr.Text(
73
- label="Prompt",
74
- show_label=False,
75
- max_lines=1,
76
- placeholder="Enter your prompt",
77
- container=False,
78
- )
79
 
80
- run_button = gr.Button("Run", scale=0, variant="primary")
 
 
 
 
 
81
 
82
- result = gr.Image(label="Result", show_label=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- with gr.Accordion("Advanced Settings", open=False):
85
- negative_prompt = gr.Text(
86
- label="Negative prompt",
87
- max_lines=1,
88
- placeholder="Enter a negative prompt",
89
- visible=False,
90
- )
 
91
 
92
- seed = gr.Slider(
93
- label="Seed",
94
- minimum=0,
95
- maximum=MAX_SEED,
96
- step=1,
97
- value=0,
98
- )
 
 
 
 
 
 
 
 
99
 
100
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
 
101
 
 
 
 
 
 
102
  with gr.Row():
103
  width = gr.Slider(
104
  label="Width",
105
  minimum=256,
106
  maximum=MAX_IMAGE_SIZE,
107
  step=32,
108
- value=1024, # Replace with defaults that work for your model
109
  )
110
-
111
  height = gr.Slider(
112
  label="Height",
113
  minimum=256,
114
  maximum=MAX_IMAGE_SIZE,
115
  step=32,
116
- value=1024, # Replace with defaults that work for your model
117
  )
118
 
119
- with gr.Row():
120
- guidance_scale = gr.Slider(
121
- label="Guidance scale",
 
 
122
  minimum=0.0,
123
- maximum=10.0,
124
  step=0.1,
125
- value=0.0, # Replace with defaults that work for your model
 
 
 
 
 
 
 
 
 
 
126
  )
127
 
128
- num_inference_steps = gr.Slider(
129
- label="Number of inference steps",
130
- minimum=1,
131
- maximum=50,
132
- step=1,
133
- value=2, # Replace with defaults that work for your model
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  )
135
 
 
 
 
 
 
 
 
 
 
 
 
136
  gr.Examples(examples=examples, inputs=[prompt])
137
- gr.on(
138
- triggers=[run_button.click, prompt.submit],
139
- fn=infer,
140
- inputs=[
141
- prompt,
142
- negative_prompt,
143
- seed,
144
- randomize_seed,
145
- width,
146
- height,
147
- guidance_scale,
148
- num_inference_steps,
149
- ],
150
- outputs=[result, seed],
151
- )
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  if __name__ == "__main__":
154
  demo.launch()
 
1
  import gradio as gr
2
  import numpy as np
 
 
 
 
3
  import torch
4
+ from diffusers import DiffusionPipeline
5
+ from peft import PeftModel
6
+ import re
7
 
8
+ # Устройство и тип данных
9
  device = "cuda" if torch.cuda.is_available() else "cpu"
10
+ torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
11
 
12
+ # Регулярное выражение для проверки корректности модели
13
+ VALID_REPO_ID_REGEX = re.compile(r"^[a-zA-Z0-9._\-]+/[a-zA-Z0-9._\-]+$")
14
+ def is_valid_repo_id(repo_id):
15
+ return bool(VALID_REPO_ID_REGEX.match(repo_id)) and not repo_id.endswith(('-', '.'))
 
 
 
16
 
17
+ # Базовые константы
18
  MAX_SEED = np.iinfo(np.int32).max
19
  MAX_IMAGE_SIZE = 1024
20
 
21
+ # Изначально загружаем модель по умолчанию
22
+ model_repo_id = "CompVis/stable-diffusion-v1-4"
23
+ pipe = DiffusionPipeline.from_pretrained(model_repo_id, torch_dtype=torch_dtype, safety_checker=None).to(device)
24
+
25
+ # Попробуем подгрузить LoRA-модификации
26
+ try:
27
+ pipe.unet = PeftModel.from_pretrained(pipe.unet, "./unet")
28
+ pipe.text_encoder = PeftModel.from_pretrained(pipe.text_encoder, "./text_encoder")
29
+ except Exception as e:
30
+ print(f"Не удалось подгрузить LoRA по умолчанию: {e}")
31
 
 
32
  def infer(
33
+ model,
34
  prompt,
35
  negative_prompt,
36
  seed,
 
37
  width,
38
  height,
39
  guidance_scale,
40
  num_inference_steps,
41
+ use_controlnet,
42
+ control_strength,
43
+ controlnet_mode,
44
+ controlnet_image,
45
+ use_ip_adapter,
46
+ ip_adapter_scale,
47
+ ip_adapter_image,
48
  progress=gr.Progress(track_tqdm=True),
49
  ):
50
+ """
51
+ Функция генерации изображения.
52
+ Параметры use_controlnet, control_strength, controlnet_mode, controlnet_image,
53
+ use_ip_adapter, ip_adapter_scale, ip_adapter_image — это заглушки для демонстрации UI.
54
+ """
55
 
56
+ global model_repo_id, pipe
57
 
58
+ # Если пользователь ввёл другую модель, пробуем её загрузить с нуля
59
+ if model != model_repo_id:
60
+ if not is_valid_repo_id(model):
61
+ raise gr.Error(f"Некорректный идентификатор модели: '{model}'. Проверьте название.")
 
 
 
 
 
62
 
63
+ try:
64
+ new_pipe = DiffusionPipeline.from_pretrained(model, torch_dtype=torch_dtype).to(device)
65
+ # Повторно подгружаем LoRA
66
+ try:
67
+ new_pipe.unet = PeftModel.from_pretrained(new_pipe.unet, "./unet")
68
+ new_pipe.text_encoder = PeftModel.from_pretrained(new_pipe.text_encoder, "./text_encoder")
69
+ except Exception as e:
70
+ raise gr.Error(f"Не удалось подгрузить LoRA: {e}")
71
+
72
+ # Обновляем глобальные переменные
73
+ pipe = new_pipe
74
+ model_repo_id = model
75
+
76
+ except Exception as e:
77
+ raise gr.Error(f"Не удалось загрузить модель '{model}'.\nОшибка: {e}")
78
+
79
+ # Создаём генератор случайных чисел для детерминированности
80
+ generator = torch.Generator(device=device).manual_seed(seed)
81
 
82
+ # --- Здесь должна быть интеграция ControlNet, IP-adapter и т.д. ---
83
+ # Для демонстрации интерфейса просто вызываем pipe как обычно.
84
+ # ------------------------------------------------------------------
85
 
86
+ try:
87
+ image = pipe(
88
+ prompt=prompt,
89
+ negative_prompt=negative_prompt,
90
+ guidance_scale=guidance_scale,
91
+ num_inference_steps=num_inference_steps,
92
+ width=width,
93
+ height=height,
94
+ generator=generator,
95
+ ).images[0]
96
+ except Exception as e:
97
+ raise gr.Error(f"Ошибка при генерации изображения: {e}")
98
+
99
+ return image, seed
100
+
101
+ # Примеры для удобного тестирования
102
  examples = [
103
  "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k",
104
  "An astronaut riding a green horse",
105
  "A delicious ceviche cheesecake slice",
106
  ]
107
 
108
+ # Дополнительный CSS для оформления
109
  css = """
110
  #col-container {
111
  margin: 0 auto;
 
113
  }
114
  """
115
 
116
+ # Создаём Gradio-приложение
117
  with gr.Blocks(css=css) as demo:
118
  with gr.Column(elem_id="col-container"):
119
+ gr.Markdown("# Text-to-Image App")
 
 
 
 
 
 
 
 
 
120
 
121
+ # Поле для ввода/смены модели
122
+ model = gr.Textbox(
123
+ label="Model",
124
+ value="CompVis/stable-diffusion-v1-4", # Значение по умолчанию
125
+ interactive=True
126
+ )
127
 
128
+ # Основные поля для Prompt и Negative Prompt
129
+ prompt = gr.Text(
130
+ label="Prompt",
131
+ show_label=False,
132
+ max_lines=1,
133
+ placeholder="Enter your prompt",
134
+ container=False,
135
+ )
136
+ negative_prompt = gr.Text(
137
+ label="Negative prompt",
138
+ max_lines=1,
139
+ placeholder="Enter a negative prompt",
140
+ visible=True,
141
+ )
142
 
143
+ # Слайдер для выбора seed
144
+ seed = gr.Slider(
145
+ label="Seed",
146
+ minimum=0,
147
+ maximum=MAX_SEED,
148
+ step=1,
149
+ value=42,
150
+ )
151
 
152
+ # Слайдеры для guidance_scale и num_inference_steps
153
+ guidance_scale = gr.Slider(
154
+ label="Guidance scale",
155
+ minimum=0.0,
156
+ maximum=10.0,
157
+ step=0.1,
158
+ value=7.0,
159
+ )
160
+ num_inference_steps = gr.Slider(
161
+ label="Number of inference steps",
162
+ minimum=1,
163
+ maximum=50,
164
+ step=1,
165
+ value=20,
166
+ )
167
 
168
+ # Кнопка запуска
169
+ run_button = gr.Button("Run", variant="primary")
170
 
171
+ # Поле для отображения результата
172
+ result = gr.Image(label="Result", show_label=False)
173
+
174
+ # Продвинутые настройки (Accordion)
175
+ with gr.Accordion("Advanced Settings", open=False):
176
  with gr.Row():
177
  width = gr.Slider(
178
  label="Width",
179
  minimum=256,
180
  maximum=MAX_IMAGE_SIZE,
181
  step=32,
182
+ value=512,
183
  )
 
184
  height = gr.Slider(
185
  label="Height",
186
  minimum=256,
187
  maximum=MAX_IMAGE_SIZE,
188
  step=32,
189
+ value=512,
190
  )
191
 
192
+ # --- Дополнительные элементы для ControlNet ---
193
+ use_controlnet = gr.Checkbox(label="Use ControlNet", value=False)
194
+ with gr.Group(visible=False) as controlnet_group:
195
+ control_strength = gr.Slider(
196
+ label="ControlNet Strength",
197
  minimum=0.0,
198
+ maximum=2.0,
199
  step=0.1,
200
+ value=1.0,
201
+ )
202
+ controlnet_mode = gr.Dropdown(
203
+ label="ControlNet Mode",
204
+ choices=["edge_detection", "pose_estimation", "depth_estimation"],
205
+ value="edge_detection",
206
+ )
207
+ controlnet_image = gr.Image(
208
+ label="ControlNet Image",
209
+ source="upload",
210
+ type="pil"
211
  )
212
 
213
+ # Функция для управления видимостью группы ControlNet
214
+ def update_controlnet_group(use_controlnet):
215
+ return {"visible": use_controlnet}
216
+
217
+ use_controlnet.change(
218
+ update_controlnet_group,
219
+ inputs=[use_controlnet],
220
+ outputs=[controlnet_group]
221
+ )
222
+
223
+ # --- Дополнительные элементы для IP-adapter ---
224
+ use_ip_adapter = gr.Checkbox(label="Use IP-adapter", value=False)
225
+ with gr.Group(visible=False) as ip_adapter_group:
226
+ ip_adapter_scale = gr.Slider(
227
+ label="IP-adapter Scale",
228
+ minimum=0.0,
229
+ maximum=2.0,
230
+ step=0.1,
231
+ value=1.0,
232
+ )
233
+ ip_adapter_image = gr.Image(
234
+ label="IP-adapter Image",
235
+ source="upload",
236
+ type="pil"
237
  )
238
 
239
+ # Функция для управления видимостью группы IP-adapter
240
+ def update_ip_adapter_group(use_ip_adapter):
241
+ return {"visible": use_ip_adapter}
242
+
243
+ use_ip_adapter.change(
244
+ update_ip_adapter_group,
245
+ inputs=[use_ip_adapter],
246
+ outputs=[ip_adapter_group]
247
+ )
248
+
249
+ # Примеры
250
  gr.Examples(examples=examples, inputs=[prompt])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
+ # Связка кнопки "Run" с функцией "infer"
253
+ run_button.click(
254
+ infer,
255
+ inputs=[
256
+ model,
257
+ prompt,
258
+ negative_prompt,
259
+ seed,
260
+ width,
261
+ height,
262
+ guidance_scale,
263
+ num_inference_steps,
264
+ use_controlnet,
265
+ control_strength,
266
+ controlnet_mode,
267
+ controlnet_image,
268
+ use_ip_adapter,
269
+ ip_adapter_scale,
270
+ ip_adapter_image
271
+ ],
272
+ outputs=[result, seed],
273
+ )
274
+
275
+ # Запуск
276
  if __name__ == "__main__":
277
  demo.launch()