PandaArtStation commited on
Commit
4ebde26
·
verified ·
1 Parent(s): 2072884

Update models.py

Browse files
Files changed (1) hide show
  1. models.py +68 -96
models.py CHANGED
@@ -2,6 +2,8 @@ import torch
2
  from diffusers import (
3
  StableDiffusionXLImg2ImgPipeline,
4
  StableDiffusionInpaintPipeline,
 
 
5
  EulerDiscreteScheduler,
6
  DPMSolverMultistepScheduler
7
  )
@@ -18,7 +20,7 @@ class InteriorDesignerPro:
18
  gpu_name = torch.cuda.get_device_name(0)
19
  self.is_powerful_gpu = any(gpu in gpu_name for gpu in ['A100', 'H100', 'RTX 4090', 'RTX 3090', 'T4'])
20
 
21
- # Основная модель - RealVisXL V4 для фотореалистичных интерьеров
22
  print(f"Loading {self.model_name} on {gpu_name}...")
23
  self.pipe = StableDiffusionXLImg2ImgPipeline.from_pretrained(
24
  "SG161222/RealVisXL_V4.0",
@@ -27,57 +29,53 @@ class InteriorDesignerPro:
27
  variant="fp16"
28
  ).to(self.device)
29
 
30
- # Настройка scheduler для лучшего качества
31
- self.pipe.scheduler = EulerDiscreteScheduler.from_config(self.pipe.scheduler.config)
 
32
 
33
- # Inpainting модель для удаления объектов
34
  try:
35
  self.inpaint_pipe = StableDiffusionInpaintPipeline.from_pretrained(
36
  "stabilityai/stable-diffusion-2-inpainting",
37
  torch_dtype=torch.float16,
38
- safety_checker=None,
39
- requires_safety_checker=False,
40
- local_files_only=False,
41
- resume_download=True
42
  ).to(self.device)
43
- print("Inpainting model loaded successfully")
44
- except Exception as e:
45
- print(f"Warning: Could not load inpainting model: {e}")
46
- print("Using img2img as fallback for object removal")
47
  self.inpaint_pipe = None
48
-
 
49
  def apply_style_pro(self, image, style_name, room_type, strength=0.75, quality="balanced"):
50
- """Применение стиля к изображению с учетом качества"""
51
  from design_styles import DESIGN_STYLES
52
 
53
  style = DESIGN_STYLES.get(style_name, DESIGN_STYLES["Современный минимализм"])
54
 
55
- # Настройки качества
56
  quality_settings = {
57
- "fast": {"steps": 20, "guidance": 7.5},
58
- "balanced": {"steps": 35, "guidance": 8.5},
59
- "ultra": {"steps": 50, "guidance": 10}
60
  }
61
 
62
  settings = quality_settings.get(quality, quality_settings["balanced"])
63
 
64
- # Генерация промпта с учетом комнаты
65
  room_specific = style.get("room_specific", {}).get(room_type, "")
66
  full_prompt = f"{style['prompt']}, {room_specific}, {room_type} interior design, professional photo, high quality, 8k, photorealistic"
67
 
68
- # Генерация с параметрами для SDXL
69
  result = self.pipe(
70
  prompt=full_prompt,
71
- prompt_2=full_prompt, # SDXL требует второй промпт
72
- negative_prompt=style.get("negative", "low quality, blurry, deformed"),
73
- negative_prompt_2=style.get("negative", "low quality, blurry, deformed"),
74
  image=image,
75
  strength=strength,
76
  num_inference_steps=settings["steps"],
77
  guidance_scale=settings["guidance"],
78
- # SDXL специфичные параметры
79
- original_size=(1024, 1024),
80
- target_size=(1024, 1024)
81
  ).images[0]
82
 
83
  return result
@@ -91,14 +89,12 @@ class InteriorDesignerPro:
91
  torch.manual_seed(base_seed + i)
92
 
93
  var = self.pipe(
94
- prompt="interior design variation, same style, different details, photorealistic",
95
- prompt_2="interior design variation, same style, different details, photorealistic",
96
  image=image,
97
  strength=0.4 + (i * 0.05),
98
- num_inference_steps=30,
99
- guidance_scale=7.5,
100
- original_size=(1024, 1024),
101
- target_size=(1024, 1024)
102
  ).images[0]
103
 
104
  variations.append(var)
@@ -144,7 +140,7 @@ class InteriorDesignerPro:
144
  element_info = ROOM_ELEMENTS.get(element, {})
145
  prompt_add = element_info.get("prompt_add", element.lower())
146
 
147
- prompt = f"interior with {value} {prompt_add}, professional photo, photorealistic"
148
  negative = f"old {element}, damaged, ugly"
149
 
150
  result = self.pipe(
@@ -154,10 +150,8 @@ class InteriorDesignerPro:
154
  negative_prompt_2=negative,
155
  image=image,
156
  strength=strength,
157
- num_inference_steps=40,
158
- guidance_scale=8.0,
159
- original_size=(1024, 1024),
160
- target_size=(1024, 1024)
161
  ).images[0]
162
 
163
  return result
@@ -167,13 +161,13 @@ class InteriorDesignerPro:
167
  results = []
168
 
169
  # Настройки для быстрой генерации
170
- steps = 20 if quality == "fast" else 35
171
 
172
  for style in styles:
173
  styled = self.apply_style_pro(
174
  image,
175
  style,
176
- "living room", # default
177
  strength=0.75,
178
  quality=quality
179
  )
@@ -182,6 +176,41 @@ class InteriorDesignerPro:
182
  return results
183
 
184
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  class ObjectRemover:
186
  """Класс для удаления объектов"""
187
 
@@ -221,7 +250,6 @@ class ObjectRemover:
221
  def generate_mask_from_text(self, image, text_description, precision=0.3):
222
  """Генерация маски на основе текстового описания"""
223
  # Простая маска в центре (заглушка)
224
- # В реальности тут должен быть CLIP или SAM
225
  width, height = image.size
226
  mask = Image.new('L', (width, height), 0)
227
 
@@ -236,59 +264,3 @@ class ObjectRemover:
236
  center_x + radius, center_y + radius], fill=255)
237
 
238
  return mask
239
-
240
-
241
- # Добавляем метод _create_comparison_grid к классу при импорте
242
- def _create_comparison_grid(self, images_with_labels):
243
- """Создает сетку из изображений с подписями"""
244
- if not images_with_labels:
245
- return None
246
-
247
- images = [img for _, img in images_with_labels]
248
- labels = [label for label, _ in images_with_labels]
249
-
250
- # Определяем размер сетки
251
- n = len(images)
252
- cols = min(3, n) # Максимум 3 колонки
253
- rows = (n + cols - 1) // cols
254
-
255
- # Размер одного изображения
256
- img_width, img_height = images[0].size
257
- padding = 20
258
- label_height = 40
259
-
260
- # Создаем холст
261
- grid_width = cols * img_width + (cols + 1) * padding
262
- grid_height = rows * (img_height + label_height) + (rows + 1) * padding
263
-
264
- grid = Image.new('RGB', (grid_width, grid_height), 'white')
265
-
266
- # Добавляем изображения
267
- from PIL import ImageDraw, ImageFont
268
- draw = ImageDraw.Draw(grid)
269
-
270
- try:
271
- font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 20)
272
- except:
273
- font = None
274
-
275
- for idx, (img, label) in enumerate(zip(images, labels)):
276
- row = idx // cols
277
- col = idx % cols
278
-
279
- x = col * img_width + (col + 1) * padding
280
- y = row * (img_height + label_height) + (row + 1) * padding
281
-
282
- # Вставляем изображение
283
- grid.paste(img, (x, y))
284
-
285
- # Добавляем подпись
286
- text_x = x + img_width // 2
287
- text_y = y + img_height + 5
288
-
289
- draw.text((text_x, text_y), label, fill='black', font=font, anchor='mt')
290
-
291
- return grid
292
-
293
- # Патчим класс
294
- InteriorDesignerPro._create_comparison_grid = _create_comparison_grid
 
2
  from diffusers import (
3
  StableDiffusionXLImg2ImgPipeline,
4
  StableDiffusionInpaintPipeline,
5
+ DDIMScheduler,
6
+ PNDMScheduler,
7
  EulerDiscreteScheduler,
8
  DPMSolverMultistepScheduler
9
  )
 
20
  gpu_name = torch.cuda.get_device_name(0)
21
  self.is_powerful_gpu = any(gpu in gpu_name for gpu in ['A100', 'H100', 'RTX 4090', 'RTX 3090', 'T4'])
22
 
23
+ # Основная модель - RealVisXL V4
24
  print(f"Loading {self.model_name} on {gpu_name}...")
25
  self.pipe = StableDiffusionXLImg2ImgPipeline.from_pretrained(
26
  "SG161222/RealVisXL_V4.0",
 
29
  variant="fp16"
30
  ).to(self.device)
31
 
32
+ # БЕЗ ЭТИХ СТРОК! Они замедляют H200!
33
+ # self.pipe.enable_model_cpu_offload()
34
+ # self.pipe.enable_vae_slicing()
35
 
36
+ # Inpainting модель
37
  try:
38
  self.inpaint_pipe = StableDiffusionInpaintPipeline.from_pretrained(
39
  "stabilityai/stable-diffusion-2-inpainting",
40
  torch_dtype=torch.float16,
41
+ safety_checker=None
 
 
 
42
  ).to(self.device)
43
+ print("Inpainting model loaded")
44
+ except:
45
+ print("Warning: Using fallback for inpainting")
 
46
  self.inpaint_pipe = None
47
+
48
+ @torch.inference_mode()
49
  def apply_style_pro(self, image, style_name, room_type, strength=0.75, quality="balanced"):
50
+ """Применение стиля к изображению"""
51
  from design_styles import DESIGN_STYLES
52
 
53
  style = DESIGN_STYLES.get(style_name, DESIGN_STYLES["Современный минимализм"])
54
 
 
55
  quality_settings = {
56
+ "fast": {"steps": 15, "guidance": 7.0},
57
+ "balanced": {"steps": 25, "guidance": 8.0},
58
+ "ultra": {"steps": 40, "guidance": 9.0}
59
  }
60
 
61
  settings = quality_settings.get(quality, quality_settings["balanced"])
62
 
63
+ # Промпт для SDXL
64
  room_specific = style.get("room_specific", {}).get(room_type, "")
65
  full_prompt = f"{style['prompt']}, {room_specific}, {room_type} interior design, professional photo, high quality, 8k, photorealistic"
66
 
67
+ # Генерация с SDXL
68
  result = self.pipe(
69
  prompt=full_prompt,
70
+ prompt_2=full_prompt,
71
+ negative_prompt=style.get("negative", "low quality, blurry"),
72
+ negative_prompt_2=style.get("negative", "low quality, blurry"),
73
  image=image,
74
  strength=strength,
75
  num_inference_steps=settings["steps"],
76
  guidance_scale=settings["guidance"],
77
+ original_size=(768, 768),
78
+ target_size=(768, 768)
 
79
  ).images[0]
80
 
81
  return result
 
89
  torch.manual_seed(base_seed + i)
90
 
91
  var = self.pipe(
92
+ prompt="interior design variation, same style, different details",
93
+ prompt_2="interior design variation, same style, different details",
94
  image=image,
95
  strength=0.4 + (i * 0.05),
96
+ num_inference_steps=20,
97
+ guidance_scale=7.5
 
 
98
  ).images[0]
99
 
100
  variations.append(var)
 
140
  element_info = ROOM_ELEMENTS.get(element, {})
141
  prompt_add = element_info.get("prompt_add", element.lower())
142
 
143
+ prompt = f"interior with {value} {prompt_add}, professional photo"
144
  negative = f"old {element}, damaged, ugly"
145
 
146
  result = self.pipe(
 
150
  negative_prompt_2=negative,
151
  image=image,
152
  strength=strength,
153
+ num_inference_steps=30,
154
+ guidance_scale=8.0
 
 
155
  ).images[0]
156
 
157
  return result
 
161
  results = []
162
 
163
  # Настройки для быстрой генерации
164
+ steps = 15 if quality == "fast" else 25
165
 
166
  for style in styles:
167
  styled = self.apply_style_pro(
168
  image,
169
  style,
170
+ "living room",
171
  strength=0.75,
172
  quality=quality
173
  )
 
176
  return results
177
 
178
 
179
+ # Динамическое добавление метода для сетки
180
+ def _create_comparison_grid(self, results):
181
+ """Создание сетки из результатов"""
182
+ if not results:
183
+ return None
184
+
185
+ images = [img for _, img in results]
186
+ titles = [title for title, _ in results]
187
+
188
+ # Определяем размер сетки
189
+ n = len(images)
190
+ cols = min(3, n)
191
+ rows = (n + cols - 1) // cols
192
+
193
+ # Размер одного изображения
194
+ img_width, img_height = images[0].size
195
+ grid_width = img_width * cols
196
+ grid_height = img_height * rows
197
+
198
+ # Создаем сетку
199
+ grid = Image.new('RGB', (grid_width, grid_height), 'white')
200
+
201
+ for idx, (img, title) in enumerate(zip(images, titles)):
202
+ row = idx // cols
203
+ col = idx % cols
204
+ x = col * img_width
205
+ y = row * img_height
206
+ grid.paste(img, (x, y))
207
+
208
+ return grid
209
+
210
+ # Добавляем метод к классу
211
+ InteriorDesignerPro._create_comparison_grid = _create_comparison_grid
212
+
213
+
214
  class ObjectRemover:
215
  """Класс для удаления объектов"""
216
 
 
250
  def generate_mask_from_text(self, image, text_description, precision=0.3):
251
  """Генерация маски на основе текстового описания"""
252
  # Простая маска в центре (заглушка)
 
253
  width, height = image.size
254
  mask = Image.new('L', (width, height), 0)
255
 
 
264
  center_x + radius, center_y + radius], fill=255)
265
 
266
  return mask