Text-to-Image
Diffusers
Safetensors
recoilme commited on
Commit
33e4060
·
1 Parent(s): 596e9a4
dataset-Copy1.py ADDED
@@ -0,0 +1,412 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # pip install flash-attn --no-build-isolation
2
+ import torch
3
+ import os
4
+ import gc
5
+ import numpy as np
6
+ import random
7
+ import json
8
+ import shutil
9
+ import time
10
+
11
+ from datasets import Dataset, load_from_disk, concatenate_datasets
12
+ from diffusers import AutoencoderKL,AutoencoderKLWan,AsymmetricAutoencoderKL
13
+ from torchvision.transforms import Resize, ToTensor, Normalize, Compose, InterpolationMode, Lambda
14
+ from transformers import AutoModel, AutoImageProcessor, AutoTokenizer, AutoModelForCausalLM
15
+ from typing import Dict, List, Tuple, Optional, Any
16
+ from PIL import Image
17
+ from tqdm import tqdm
18
+ from datetime import timedelta
19
+
20
+ # ---------------- 1️⃣ Настройки ----------------
21
+ dtype = torch.float32
22
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
23
+ batch_size = 5
24
+ min_size = 320 #384 #320 #192 #256 #192
25
+ max_size = 640 #768 #640 #384 #256 #384
26
+ step = 32 #64
27
+ empty_share = 0.0
28
+ limit = 0
29
+ # Основная процедура обработки
30
+ folder_path = "/workspace/dataset" #alchemist"
31
+ save_path = "/workspace/dataset_640" #"alchemist"
32
+ os.makedirs(save_path, exist_ok=True)
33
+
34
+ # Функция для очистки CUDA памяти
35
+ def clear_cuda_memory():
36
+ if torch.cuda.is_available():
37
+ used_gb = torch.cuda.max_memory_allocated() / 1024**3
38
+ print(f"used_gb: {used_gb:.2f} GB")
39
+ torch.cuda.empty_cache()
40
+ gc.collect()
41
+
42
+ # ---------------- 2️⃣ Загрузка моделей ----------------
43
+ def load_models():
44
+ print("Загрузка моделей...")
45
+ vae = AsymmetricAutoencoderKL.from_pretrained("AiArtLab/sdxs-1b",subfolder="vae",torch_dtype=dtype).to(device).eval()
46
+
47
+ #model_name = "Qwen/Qwen3-0.6B"
48
+ #tokenizer = AutoTokenizer.from_pretrained(model_name)
49
+ #model = AutoModelForCausalLM.from_pretrained(
50
+ # model_name,
51
+ # torch_dtype=dtype,
52
+ # device_map=device
53
+ #).eval()
54
+ #tokenizer = AutoTokenizer.from_pretrained('Qwen/Qwen3-Embedding-0.6B', padding_side='left')
55
+ #model = AutoModel.from_pretrained('Qwen/Qwen3-Embedding-0.6B').to("cuda")
56
+ return vae#, model, tokenizer
57
+
58
+ #vae, model, tokenizer = load_models()
59
+ vae = load_models()
60
+
61
+ shift_factor = getattr(vae.config, "shift_factor", 0.0)
62
+ if shift_factor is None:
63
+ shift_factor = 0.0
64
+
65
+ scaling_factor = getattr(vae.config, "scaling_factor", 1.0)
66
+ if scaling_factor is None:
67
+ scaling_factor = 1.0
68
+
69
+ latents_mean = getattr(vae.config, "latents_mean", None)
70
+ latents_std = getattr(vae.config, "latents_std", None)
71
+
72
+ # ---------------- 3️⃣ Трансформации ----------------
73
+ def get_image_transform(min_size=256, max_size=512, step=64):
74
+ def transform(img, dry_run=False):
75
+ # Сохраняем исходные размеры изображения
76
+ original_width, original_height = img.size
77
+
78
+ # 0. Ресайз: масштабируем изображение, чтобы максимальная сторона была равна max_size
79
+ if original_width >= original_height:
80
+ new_width = max_size
81
+ new_height = int(max_size * original_height / original_width)
82
+ else:
83
+ new_height = max_size
84
+ new_width = int(max_size * original_width / original_height)
85
+
86
+ if new_height < min_size or new_width < min_size:
87
+ # 1. Ресайз: масштабируем изображение, чтобы минимальная сторона была равна min_size
88
+ if original_width <= original_height:
89
+ new_width = min_size
90
+ new_height = int(min_size * original_height / original_width)
91
+ else:
92
+ new_height = min_size
93
+ new_width = int(min_size * original_width / original_height)
94
+
95
+ # 2. Проверка: если одна из сторон превышает max_size, готовимся к обрезке
96
+ crop_width = min(max_size, (new_width // step) * step)
97
+ crop_height = min(max_size, (new_height // step) * step)
98
+
99
+ # Убеждаемся, что размеры обрезки не меньше min_size
100
+ crop_width = max(min_size, crop_width)
101
+ crop_height = max(min_size, crop_height)
102
+
103
+ # Если запрошен только предварительный расчёт размеров
104
+ if dry_run:
105
+ return crop_width, crop_height
106
+
107
+ # Конвертация в RGB и ресайз
108
+ img_resized = img.convert("RGB").resize((new_width, new_height), Image.LANCZOS)
109
+
110
+ # Определение координат обрезки (обрезаем с учетом вотермарок - треть сверху)
111
+ top = (new_height - crop_height) // 3
112
+ left = 0
113
+
114
+ # Обрезка изображения
115
+ img_cropped = img_resized.crop((left, top, left + crop_width, top + crop_height))
116
+
117
+ # Сохраняем итоговые размеры после вс��х преобразований
118
+ final_width, final_height = img_cropped.size
119
+
120
+ # тензор
121
+ img_tensor = ToTensor()(img_cropped)
122
+ img_tensor = Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])(img_tensor)
123
+ return img_tensor, img_cropped, final_width, final_height
124
+
125
+ return transform
126
+
127
+ # ---------------- 4️⃣ Функции обработки ----------------
128
+ def last_token_pool(last_hidden_states: torch.Tensor,
129
+ attention_mask: torch.Tensor) -> torch.Tensor:
130
+ # Определяем, есть ли left padding
131
+ left_padding = (attention_mask[:, -1].sum() == attention_mask.shape[0])
132
+ if left_padding:
133
+ return last_hidden_states[:, -1]
134
+ else:
135
+ sequence_lengths = attention_mask.sum(dim=1) - 1
136
+ batch_size = last_hidden_states.shape[0]
137
+ return last_hidden_states[torch.arange(batch_size, device=last_hidden_states.device), sequence_lengths]
138
+
139
+ def encode_texts_batch(texts, tokenizer, model, device="cuda", max_length=150, normalize=False):
140
+ with torch.inference_mode():
141
+ # Токенизация
142
+ batch = tokenizer(
143
+ texts,
144
+ return_tensors="pt",
145
+ padding="max_length",
146
+ truncation=True,
147
+ max_length=max_length
148
+ ).to(device)
149
+
150
+ # Прогон через модель
151
+ #outputs = model(**batch)
152
+
153
+ # Пулинг по last token
154
+ #embeddings = last_token_pool(outputs.last_hidden_state, batch["attention_mask"])
155
+
156
+ # L2-нормализация (опционально, обычно нужна для семантического поиска)
157
+ #if normalize:
158
+ # embeddings = F.normalize(embeddings, p=2, dim=1)
159
+
160
+ # Прогон через базовую модель (внутри CausalLM)
161
+ outputs = model.model(**batch, output_hidden_states=True)
162
+
163
+ # Берем последний слой (эмбеддинги всех токенов)
164
+ hidden_states = outputs.hidden_states[-1] # [B, L, D]
165
+
166
+ # Можно применить нормализацию по каждому токену (как в CLIP)
167
+ if normalize:
168
+ hidden_states = F.normalize(hidden_states, p=2, dim=-1)
169
+
170
+ return hidden_states.cpu().numpy() # embeddings.unsqueeze(1).cpu().numpy()
171
+
172
+ def clean_label(label):
173
+ label = label.replace("Image 1", "").replace("Image 2", "").replace("Image 3", "").replace("Image 4", "").replace("The image depicts ","").replace("The image presents ","").replace("The image features ","").replace("The image portrays ","").replace("The image is ","").strip()
174
+ if label.startswith("."):
175
+ label = label[1:].lstrip()
176
+ return label
177
+
178
+ def process_labels_for_guidance(original_labels, prob_to_make_empty=0.01):
179
+ """
180
+ Обрабатывает список меток для classifier-free guidance.
181
+
182
+ С вероятностью prob_to_make_empty:
183
+ - Метка в первом списке заменяется на пустую строку.
184
+ - К метке во втором списке добавляется префикс "zero:".
185
+
186
+ В противном случае метки в обоих списках остаются оригинальными.
187
+
188
+ """
189
+ labels_for_model = []
190
+ labels_for_logging = []
191
+
192
+ for label in original_labels:
193
+ if random.random() < prob_to_make_empty:
194
+ labels_for_model.append("") # Заменяем на пустую строку для модели
195
+ labels_for_logging.append(f"zero: {label}") # Добавляем префикс для логгирования
196
+ else:
197
+ labels_for_model.append(label) # Оставляем оригинальную метку для модели
198
+ labels_for_logging.append(label) # Оставляем оригинальную метку для логгирования
199
+
200
+ return labels_for_model, labels_for_logging
201
+
202
+ def encode_to_latents(images, texts):
203
+ transform = get_image_transform(min_size, max_size, step)
204
+
205
+ try:
206
+ # Обработка изображений (все одинакового размера)
207
+ transformed_tensors = []
208
+ pil_images = []
209
+ widths, heights = [], []
210
+
211
+ # Применяем трансформацию ко всем изображениям
212
+ for img in images:
213
+ try:
214
+ t_img, pil_img, w, h = transform(img)
215
+ transformed_tensors.append(t_img)
216
+ pil_images.append(pil_img)
217
+ widths.append(w)
218
+ heights.append(h)
219
+ except Exception as e:
220
+ print(f"Ошибка трансформации: {e}")
221
+ continue
222
+
223
+ if not transformed_tensors:
224
+ return None
225
+
226
+ # Создаём батч
227
+ batch_tensor = torch.stack(transformed_tensors).to(device, dtype)
228
+ if batch_tensor.ndim==5:
229
+ batch_tensor = batch_tensor.unsqueeze(2) # [B, C, 1, H, W]
230
+
231
+ # Кодируем батч
232
+ with torch.no_grad():
233
+ posteriors = vae.encode(batch_tensor).latent_dist.mode()
234
+ latents = (posteriors - shift_factor) / scaling_factor
235
+
236
+ latents_np = latents.to(dtype).cpu().numpy()
237
+
238
+ # Обрабатываем тексты
239
+ text_labels = [clean_label(text) for text in texts]
240
+
241
+ model_prompts, text_labels = process_labels_for_guidance(text_labels, empty_share)
242
+ #embeddings = encode_texts_batch(model_prompts, tokenizer, model)
243
+
244
+ return {
245
+ "vae": latents_np,
246
+ #"embeddings": embeddings,
247
+ "text": text_labels,
248
+ "width": widths,
249
+ "height": heights
250
+ }
251
+
252
+ except Exception as e:
253
+ print(f"Критическая ошибка в encode_to_latents: {e}")
254
+ raise
255
+
256
+
257
+ # ---------------- 5️⃣ Обработка папки с изображениями и текстами ----------------
258
+ def process_folder(folder_path, limit=None):
259
+ """
260
+ Рекурсивно обходит указанную директорию и все вложенные директории,
261
+ собирая пути к изображениям и соответствующим текстовым файлам.
262
+ """
263
+ image_paths = []
264
+ text_paths = []
265
+ width = []
266
+ height = []
267
+ transform = get_image_transform(min_size, max_size, step)
268
+
269
+ # Используем os.walk для рекурсивного обхода директорий
270
+ for root, dirs, files in os.walk(folder_path):
271
+ for filename in files:
272
+ # Проверяем, является ли файл изображением
273
+ if filename.lower().endswith((".jpg", ".jpeg", ".png")):
274
+ image_path = os.path.join(root, filename)
275
+ try:
276
+ img = Image.open(image_path)
277
+ except Exception as e:
278
+ print(f"Ошибка при открытии {image_path}: {e}")
279
+ os.remove(image_path)
280
+ text_path = os.path.splitext(image_path)[0] + ".txt"
281
+ if os.path.exists(text_path):
282
+ os.remove(text_path)
283
+ continue
284
+ # Применяем трансформацию только для получения размеров
285
+ w, h = transform(img, dry_run=True)
286
+ # Формируем путь к текстовому файлу
287
+ text_path = os.path.splitext(image_path)[0] + ".txt"
288
+
289
+ # Добавляем пути, если текстовый файл существует
290
+ if os.path.exists(text_path) and min(w, h)>0:
291
+ image_paths.append(image_path)
292
+ text_paths.append(text_path)
293
+ width.append(w) # Добавляем в список
294
+ height.append(h) # Добавляем в список
295
+
296
+ # Проверяем ограничение на количество
297
+ if limit and limit>0 and len(image_paths) >= limit:
298
+ print(f"Достигнут лимит в {limit} изображений")
299
+ return image_paths, text_paths, width, height
300
+
301
+ print(f"Найдено {len(image_paths)} изображений с текстовыми описаниями")
302
+ return image_paths, text_paths, width, height
303
+
304
+ def process_in_chunks(image_paths, text_paths, width, height, chunk_size=10000, batch_size=1):
305
+ total_files = len(image_paths)
306
+ start_time = time.time()
307
+ chunks = range(0, total_files, chunk_size)
308
+
309
+ for chunk_idx, start in enumerate(chunks, 1):
310
+ end = min(start + chunk_size, total_files)
311
+ chunk_image_paths = image_paths[start:end]
312
+ chunk_text_paths = text_paths[start:end]
313
+ chunk_widths = width[start:end] if isinstance(width, list) else [width] * len(chunk_image_paths)
314
+ chunk_heights = height[start:end] if isinstance(height, list) else [height] * len(chunk_image_paths)
315
+
316
+ # Чтение текстов
317
+ chunk_texts = []
318
+ for text_path in chunk_text_paths:
319
+ try:
320
+ with open(text_path, 'r', encoding='utf-8') as f:
321
+ text = f.read().strip()
322
+ chunk_texts.append(text)
323
+ except Exception as e:
324
+ print(f"Ошибка чтения {text_path}: {e}")
325
+ chunk_texts.append("")
326
+
327
+ # Группируем изображения по размерам
328
+ size_groups = {}
329
+ for i in range(len(chunk_image_paths)):
330
+ size_key = (chunk_widths[i], chunk_heights[i])
331
+ if size_key not in size_groups:
332
+ size_groups[size_key] = {"image_paths": [], "texts": []}
333
+ size_groups[size_key]["image_paths"].append(chunk_image_paths[i])
334
+ size_groups[size_key]["texts"].append(chunk_texts[i])
335
+
336
+ # Обрабатываем каждую группу размеров отдельно
337
+ for size_key, group_data in size_groups.items():
338
+ print(f"Обработка группы с размером {size_key[0]}x{size_key[1]} - {len(group_data['image_paths'])} изображений")
339
+
340
+ group_dataset = Dataset.from_dict({
341
+ "image_path": group_data["image_paths"],
342
+ "text": group_data["texts"]
343
+ })
344
+
345
+ # Теперь можно использовать указанный batch_size, т.к. все изображения одного размера
346
+ processed_group = group_dataset.map(
347
+ lambda examples: encode_to_latents(
348
+ [Image.open(path) for path in examples["image_path"]],
349
+ examples["text"]
350
+ ),
351
+ batched=True,
352
+ batch_size=batch_size,
353
+ #remove_columns=["image_path"],
354
+ desc=f"Обработка группы размера {size_key[0]}x{size_key[1]}"
355
+ )
356
+
357
+ # Сохраняем результаты группы
358
+ group_save_path = f"{save_path}_temp/chunk_{chunk_idx}_size_{size_key[0]}x{size_key[1]}"
359
+ processed_group.save_to_disk(group_save_path)
360
+ clear_cuda_memory()
361
+ elapsed = time.time() - start_time
362
+ processed = (chunk_idx - 1) * chunk_size + sum([len(sg["image_paths"]) for sg in list(size_groups.values())[:list(size_groups.values()).index(group_data) + 1]])
363
+ if processed > 0:
364
+ remaining = (elapsed / processed) * (total_files - processed)
365
+ elapsed_str = str(timedelta(seconds=int(elapsed)))
366
+ remaining_str = str(timedelta(seconds=int(remaining)))
367
+ print(f"ETA: Прошло {elapsed_str}, Осталось {remaining_str}, Прогресс {processed}/{total_files} ({processed/total_files:.1%})")
368
+
369
+ # ---------------- 7️⃣ Объединение чанков ----------------
370
+ def combine_chunks(temp_path, final_path):
371
+ """Объединение обработанных чанков в финальный датасет"""
372
+ chunks = sorted([
373
+ os.path.join(temp_path, d)
374
+ for d in os.listdir(temp_path)
375
+ if d.startswith("chunk_")
376
+ ])
377
+
378
+ datasets = [load_from_disk(chunk) for chunk in chunks]
379
+ combined = concatenate_datasets(datasets)
380
+ combined.save_to_disk(final_path)
381
+
382
+ print(f"✅ Датасет успешно сохранен в: {final_path}")
383
+
384
+
385
+
386
+ # Создаем временную папку для чанков
387
+ temp_path = f"{save_path}_temp"
388
+ os.makedirs(temp_path, exist_ok=True)
389
+
390
+ # Получаем список файлов
391
+ image_paths, text_paths, width, height = process_folder(folder_path,limit)
392
+ print(f"Всего найдено {len(image_paths)} изображений")
393
+
394
+ # Обработка с чанкованием
395
+ process_in_chunks(image_paths, text_paths, width, height, chunk_size=20000, batch_size=batch_size)
396
+
397
+ # Удаление папки
398
+ try:
399
+ shutil.rmtree(folder_path)
400
+ print(f"✅ Папка {folder_path} успешно удалена")
401
+ except Exception as e:
402
+ print(f"⚠️ Ошибка при удалении папки: {e}")
403
+
404
+ # Объединение чанков в финальный датасет
405
+ combine_chunks(temp_path, save_path)
406
+
407
+ # Удаление временной папки
408
+ try:
409
+ shutil.rmtree(temp_path)
410
+ print(f"✅ Временная папка {temp_path} успешно удалена")
411
+ except Exception as e:
412
+ print(f"⚠️ Ошибка при удалении временной папки: {e}")
dataset.py CHANGED
@@ -9,7 +9,7 @@ import shutil
9
  import time
10
 
11
  from datasets import Dataset, load_from_disk, concatenate_datasets
12
- from diffusers import AutoencoderKL,AutoencoderKLWan,AsymmetricAutoencoderKL
13
  from torchvision.transforms import Resize, ToTensor, Normalize, Compose, InterpolationMode, Lambda
14
  from transformers import AutoModel, AutoImageProcessor, AutoTokenizer, AutoModelForCausalLM
15
  from typing import Dict, List, Tuple, Optional, Any
@@ -18,17 +18,17 @@ from tqdm import tqdm
18
  from datetime import timedelta
19
 
20
  # ---------------- 1️⃣ Настройки ----------------
21
- dtype = torch.float32
22
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
23
- batch_size = 5
24
  min_size = 320 #384 #320 #192 #256 #192
25
  max_size = 640 #768 #640 #384 #256 #384
26
  step = 32 #64
27
  empty_share = 0.0
28
  limit = 0
29
  # Основная процедура обработки
30
- folder_path = "/workspace/dataset" #alchemist"
31
- save_path = "/workspace/dataset_640" #"alchemist"
32
  os.makedirs(save_path, exist_ok=True)
33
 
34
  # Функция для очистки CUDA памяти
@@ -42,7 +42,8 @@ def clear_cuda_memory():
42
  # ---------------- 2️⃣ Загрузка моделей ----------------
43
  def load_models():
44
  print("Загрузка моделей...")
45
- vae = AsymmetricAutoencoderKL.from_pretrained("AiArtLab/sdxs-1b",subfolder="vae",torch_dtype=dtype).to(device).eval()
 
46
 
47
  #model_name = "Qwen/Qwen3-0.6B"
48
  #tokenizer = AutoTokenizer.from_pretrained(model_name)
@@ -199,6 +200,43 @@ def process_labels_for_guidance(original_labels, prob_to_make_empty=0.01):
199
 
200
  return labels_for_model, labels_for_logging
201
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  def encode_to_latents(images, texts):
203
  transform = get_image_transform(min_size, max_size, step)
204
 
@@ -232,6 +270,7 @@ def encode_to_latents(images, texts):
232
  with torch.no_grad():
233
  posteriors = vae.encode(batch_tensor).latent_dist.mode()
234
  latents = (posteriors - shift_factor) / scaling_factor
 
235
 
236
  latents_np = latents.to(dtype).cpu().numpy()
237
 
 
9
  import time
10
 
11
  from datasets import Dataset, load_from_disk, concatenate_datasets
12
+ from diffusers import AutoencoderKL,AutoencoderKLWan,AsymmetricAutoencoderKL,AutoencoderKLFlux2
13
  from torchvision.transforms import Resize, ToTensor, Normalize, Compose, InterpolationMode, Lambda
14
  from transformers import AutoModel, AutoImageProcessor, AutoTokenizer, AutoModelForCausalLM
15
  from typing import Dict, List, Tuple, Optional, Any
 
18
  from datetime import timedelta
19
 
20
  # ---------------- 1️⃣ Настройки ----------------
21
+ dtype = torch.float16
22
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
23
+ batch_size = 1
24
  min_size = 320 #384 #320 #192 #256 #192
25
  max_size = 640 #768 #640 #384 #256 #384
26
  step = 32 #64
27
  empty_share = 0.0
28
  limit = 0
29
  # Основная процедура обработки
30
+ folder_path = "/home/recoilme/dataset/butterflies/butterfly" #alchemist"
31
+ save_path = "/home/recoilme/sdxs-1b/datasets/butterfly_flux32" #"alchemist"
32
  os.makedirs(save_path, exist_ok=True)
33
 
34
  # Функция для очистки CUDA памяти
 
42
  # ---------------- 2️⃣ Загрузка моделей ----------------
43
  def load_models():
44
  print("Загрузка моделей...")
45
+ #vae = AsymmetricAutoencoderKL.from_pretrained("AiArtLab/sdxs-1b",subfolder="vae",torch_dtype=dtype).to(device).eval()
46
+ vae = AutoencoderKLFlux2.from_pretrained("vae", torch_dtype=dtype).to(device).eval()
47
 
48
  #model_name = "Qwen/Qwen3-0.6B"
49
  #tokenizer = AutoTokenizer.from_pretrained(model_name)
 
200
 
201
  return labels_for_model, labels_for_logging
202
 
203
+ def _patchify_latents(latents):
204
+ batch_size, num_channels_latents, height, width = latents.shape
205
+ latents = latents.view(batch_size, num_channels_latents, height // 2, 2, width // 2, 2)
206
+ latents = latents.permute(0, 1, 3, 5, 2, 4)
207
+ latents = latents.reshape(batch_size, num_channels_latents * 4, height // 2, width // 2)
208
+ return latents
209
+
210
+ @staticmethod
211
+ def _unpatchify_latents(latents):
212
+ batch_size, num_channels_latents, height, width = latents.shape
213
+ latents = latents.reshape(batch_size, num_channels_latents // (2 * 2), 2, 2, height, width)
214
+ latents = latents.permute(0, 1, 4, 2, 5, 3)
215
+ latents = latents.reshape(batch_size, num_channels_latents // (2 * 2), height * 2, width * 2)
216
+ return latents
217
+
218
+ def flux_encode(vae,latents):
219
+ # patch
220
+ image_latents = _patchify_latents(latents)
221
+ # norm
222
+ latents_bn_mean = vae.bn.running_mean.view(1, -1, 1, 1).to(image_latents.device, image_latents.dtype)
223
+ latents_bn_std = torch.sqrt(vae.bn.running_var.view(1, -1, 1, 1) + vae.config.batch_norm_eps)
224
+ latents = (image_latents - latents_bn_mean) / latents_bn_std
225
+ # unpatch
226
+ latents = _unpatchify_latents(latents)
227
+ return latents
228
+
229
+ def flux_decode(vae,latents):
230
+ # patch
231
+ image_latents = _patchify_latents(latents)
232
+ # norm
233
+ latents_bn_mean = vae.bn.running_mean.view(1, -1, 1, 1).to(image_latents.device, image_latents.dtype)
234
+ latents_bn_std = torch.sqrt(vae.bn.running_var.view(1, -1, 1, 1) + vae.config.batch_norm_eps)
235
+ latents = image_latents * latents_bn_std + latents_bn_mean
236
+ # unpatch
237
+ latents = _unpatchify_latents(latents)
238
+ return latents
239
+
240
  def encode_to_latents(images, texts):
241
  transform = get_image_transform(min_size, max_size, step)
242
 
 
270
  with torch.no_grad():
271
  posteriors = vae.encode(batch_tensor).latent_dist.mode()
272
  latents = (posteriors - shift_factor) / scaling_factor
273
+ image_latents = flux_encode(vae, latents)
274
 
275
  latents_np = latents.to(dtype).cpu().numpy()
276
 
girl.jpg CHANGED

Git LFS Details

  • SHA256: 1e3edd66ac80f31c8f91e2d4719220ef3bcd499f619a0c8c3432417b47fe90ad
  • Pointer size: 130 Bytes
  • Size of remote file: 48.5 kB

Git LFS Details

  • SHA256: cc3aa21ed2550d4997bdcfb8b369f38eb6454d6e33a3abc5e701f7cb4fd76320
  • Pointer size: 130 Bytes
  • Size of remote file: 29.9 kB
media/result_grid.jpg CHANGED

Git LFS Details

  • SHA256: 7258028c9041d5853da2dedd8bd7fff472e76dc349c805fc99406937692b1321
  • Pointer size: 132 Bytes
  • Size of remote file: 3.7 MB

Git LFS Details

  • SHA256: 6ed82f42ee98153eaa3b4a209402abb0c84c607913ebd06104346f0e197e0706
  • Pointer size: 132 Bytes
  • Size of remote file: 1.63 MB
samples/unet_320x640_0.jpg → model_index-Copy1.json RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:8f1c5f47692d66d5d06f0324adba126a88fb101ee8bc41400135d52b5afa3645
3
- size 95393
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e7262c65619c10d3d77607525c101c525b6b6a9a3af89f503f35b42e91dd88e2
3
+ size 417
model_index.json CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:e7262c65619c10d3d77607525c101c525b6b6a9a3af89f503f35b42e91dd88e2
3
- size 417
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b6d71e1f562601e1a6bfcd1f0f7f81e021003b5512637d1c14dd77aba88144c8
3
+ size 412
pipeline_sdxs-Copy1.py ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import numpy as np
3
+ from PIL import Image
4
+ from typing import List, Union, Optional, Tuple
5
+ from dataclasses import dataclass
6
+
7
+ from diffusers import DiffusionPipeline
8
+ from diffusers.utils import BaseOutput
9
+ from tqdm import tqdm
10
+
11
+ @dataclass
12
+ class SdxsPipelineOutput(BaseOutput):
13
+ images: Union[List[Image.Image], np.ndarray]
14
+
15
+ class SdxsPipeline(DiffusionPipeline):
16
+ def __init__(self, vae, text_encoder, tokenizer, unet, scheduler):
17
+ super().__init__()
18
+ self.register_modules(
19
+ vae=vae,
20
+ text_encoder=text_encoder,
21
+ tokenizer=tokenizer,
22
+ unet=unet,
23
+ scheduler=scheduler
24
+ )
25
+ self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
26
+
27
+ def preprocess_image(self, image: Image.Image, width: int, height: int):
28
+ """Ресайз и центрированный кроп изображения для асимметричного VAE."""
29
+ # Для энкодера с масштабом 8
30
+ target_height = ((height // self.vae_scale_factor) * self.vae_scale_factor)//2
31
+ target_width = ((width // self.vae_scale_factor) * self.vae_scale_factor)//2
32
+
33
+ w, h = image.size
34
+ aspect_ratio = target_width / target_height
35
+
36
+ if w / h > aspect_ratio:
37
+ new_w = int(h * aspect_ratio)
38
+ left = (w - new_w) // 2
39
+ image = image.crop((left, 0, left + new_w, h))
40
+ else:
41
+ new_h = int(w / aspect_ratio)
42
+ top = (h - new_h) // 2
43
+ image = image.crop((0, top, w, top + new_h))
44
+
45
+ image = image.resize((target_width, target_height), resample=Image.LANCZOS)
46
+ image = np.array(image).astype(np.float32) / 255.0
47
+ image = image[None].transpose(0, 3, 1, 2) # [1, C, H, W]
48
+ image = torch.from_numpy(image)
49
+ return 2.0 * image - 1.0 # [-1, 1]
50
+
51
+ def encode_prompt(self, prompt, negative_prompt, device, dtype):
52
+ def get_single_encode(texts, is_negative=False):
53
+ if texts is None or texts == "":
54
+ hidden_dim = self.text_encoder.config.hidden_size
55
+ shape = (1, self.text_encoder.config.max_position_embeddings, hidden_dim)
56
+ emb = torch.zeros(shape, dtype=dtype, device=device)
57
+ mask = torch.ones((1, self.text_encoder.config.max_position_embeddings), dtype=torch.int64, device=device)
58
+ return emb, mask
59
+
60
+ if isinstance(texts, str):
61
+ texts = [texts]
62
+
63
+ with torch.no_grad():
64
+ toks = self.tokenizer(
65
+ texts,
66
+ padding="max_length",
67
+ max_length=self.text_encoder.config.max_position_embeddings,
68
+ truncation=True,
69
+ return_tensors="pt"
70
+ ).to(device)
71
+
72
+ outputs = self.text_encoder(
73
+ input_ids=toks.input_ids,
74
+ attention_mask=toks.attention_mask,
75
+ output_hidden_states=True
76
+ )
77
+
78
+ layer_index = -2
79
+ prompt_embeds = outputs.hidden_states[layer_index]
80
+ final_layer_norm = self.text_encoder.text_model.final_layer_norm
81
+ prompt_embeds = final_layer_norm(prompt_embeds)
82
+
83
+ return prompt_embeds, toks.attention_mask
84
+
85
+ pos_embeds, pos_mask = get_single_encode(prompt)
86
+ neg_embeds, neg_mask = get_single_encode(negative_prompt, is_negative=True)
87
+
88
+ batch_size = pos_embeds.shape[0]
89
+ if neg_embeds.shape[0] != batch_size:
90
+ neg_embeds = neg_embeds.repeat(batch_size, 1, 1)
91
+ neg_mask = neg_mask.repeat(batch_size, 1)
92
+
93
+ text_embeddings = torch.cat([neg_embeds, pos_embeds], dim=0)
94
+ final_mask = torch.cat([neg_mask, pos_mask], dim=0)
95
+
96
+ return text_embeddings.to(dtype=dtype), final_mask.to(dtype=torch.int64)
97
+
98
+ @torch.no_grad()
99
+ def __call__(
100
+ self,
101
+ prompt: Union[str, List[str]],
102
+ image: Optional[Union[Image.Image, List[Image.Image]]] = None,
103
+ coef: float = 0.97, # ← strength (0.0 = оригинал, 1.0 = полный шум)
104
+ negative_prompt: Optional[Union[str, List[str]]] = None,
105
+ height: int = 1024,
106
+ width: int = 1024,
107
+ num_inference_steps: int = 40,
108
+ guidance_scale: float = 4.0,
109
+ generator: Optional[torch.Generator] = None,
110
+ seed: Optional[int] = None,
111
+ output_type: str = "pil",
112
+ return_dict: bool = True,
113
+ # structure_preservation оставляем для совместимости, но теперь он почти не нужен
114
+ structure_preservation: float = 0.0, # 0.0 = стандартный линейный путь (лучше всего)
115
+ **kwargs,
116
+ ):
117
+ device = self.device
118
+ dtype = self.unet.dtype
119
+
120
+ if generator is None and seed is not None:
121
+ generator = torch.Generator(device=device).manual_seed(seed)
122
+
123
+ # 1. Encode prompt (твой код оставляем без изменений)
124
+ text_embeddings, attention_mask = self.encode_prompt(
125
+ prompt, negative_prompt, device, dtype
126
+ )
127
+ batch_size = 1 if isinstance(prompt, str) else len(prompt)
128
+
129
+ # 2. Scheduler timesteps
130
+ self.scheduler.set_timesteps(num_inference_steps, device=device)
131
+ timesteps = self.scheduler.timesteps
132
+
133
+ # ==================== IMG2IMG БЛОК (НОВАЯ ВЕРСИЯ) ====================
134
+ if image is not None:
135
+ # --- Подготовка изображения ---
136
+ if isinstance(image, Image.Image):
137
+ image_tensor = self.preprocess_image(image, width, height).to(device, self.vae.dtype)
138
+ else:
139
+ image_tensor = self.preprocess_image(image[0], width, height).to(device, self.vae.dtype)
140
+
141
+ # --- Кодируем в latent ---
142
+ latents_clean = self.vae.encode(image_tensor).latent_dist.sample(generator=generator)
143
+ vae_scaling_factor = getattr(self.vae.config, "scaling_factor", 1.0)
144
+ vae_shift_factor = getattr(self.vae.config, "shift_factor", 0.0)
145
+ latents_clean = (latents_clean - vae_shift_factor) / vae_scaling_factor
146
+ latents_clean = latents_clean.to(dtype)
147
+
148
+ # --- Добавляем шум по Rectified Flow формуле ---
149
+ noise = torch.randn_like(latents_clean)
150
+
151
+ # coef = strength (0.0 → оригинал, 1.0 → чистый шум)
152
+ sigma = coef # в Flow Matching sigma = t
153
+ if hasattr(self.scheduler, "sigma_shift"): # если есть shift (Flux-style)
154
+ sigma = self.scheduler.sigma_shift(sigma)
155
+
156
+ latents = (1.0 - sigma) * latents_clean + sigma * noise
157
+
158
+ # Обрезаем timesteps начиная с текущего sigma
159
+ init_timestep = int(num_inference_steps * coef)
160
+ t_start = max(num_inference_steps - init_timestep, 0)
161
+ timesteps = timesteps[t_start:]
162
+
163
+ #print(f"img2img → strength={coef:.2f}, sigma={sigma:.3f}, steps={len(timesteps)}")
164
+
165
+ else:
166
+ # txt2img — оставляем как было
167
+ vae_scaling_factor = getattr(self.vae.config, "scaling_factor", 1.0)
168
+ vae_shift_factor = getattr(self.vae.config, "shift_factor", 0.0)
169
+ latent_h = height // self.vae_scale_factor
170
+ latent_w = width // self.vae_scale_factor
171
+
172
+ latents = torch.randn(
173
+ (batch_size, self.unet.config.in_channels, latent_h, latent_w),
174
+ generator=generator, device=device, dtype=dtype
175
+ )
176
+
177
+ # ==================== DENOISING LOOP (одинаковый для txt2img и img2img) ====================
178
+ for i, t in enumerate(tqdm(timesteps, desc="Sampling")):
179
+ latent_model_input = torch.cat([latents] * 2) if guidance_scale > 1.0 else latents
180
+
181
+ model_out = self.unet(
182
+ latent_model_input,
183
+ t,
184
+ encoder_hidden_states=text_embeddings,
185
+ encoder_attention_mask=attention_mask,
186
+ return_dict=False,
187
+ )[0]
188
+
189
+ if guidance_scale > 1.0:
190
+ flow_uncond, flow_cond = model_out.chunk(2)
191
+ model_out = flow_uncond + guidance_scale * (flow_cond - flow_uncond)
192
+
193
+ # Важно: используем scheduler.step — он сам знает, что делать с velocity
194
+ latents = self.scheduler.step(model_out, t, latents, return_dict=False)[0]
195
+
196
+ # ==================== DECODE ====================
197
+ if output_type == "latent":
198
+ return SdxsPipelineOutput(images=latents)
199
+
200
+ latents = latents * vae_scaling_factor + vae_shift_factor
201
+ image_output = self.vae.decode(latents.to(self.vae.dtype), return_dict=False)[0]
202
+
203
+ image_output = (image_output.clamp(-1, 1) + 1) / 2
204
+ image_np = image_output.cpu().permute(0, 2, 3, 1).float().numpy()
205
+
206
+ if output_type == "pil":
207
+ images = [(Image.fromarray((img * 255).round().astype("uint8"))) for img in image_np]
208
+ else:
209
+ images = image_np
210
+
211
+ if not return_dict:
212
+ return images
213
+ return SdxsPipelineOutput(images=images)
pipeline_sdxs.py CHANGED
@@ -22,7 +22,7 @@ class SdxsPipeline(DiffusionPipeline):
22
  unet=unet,
23
  scheduler=scheduler
24
  )
25
- self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
26
 
27
  def preprocess_image(self, image: Image.Image, width: int, height: int):
28
  """Ресайз и центрированный кроп изображения для асимметричного VAE."""
@@ -48,6 +48,55 @@ class SdxsPipeline(DiffusionPipeline):
48
  image = torch.from_numpy(image)
49
  return 2.0 * image - 1.0 # [-1, 1]
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  def encode_prompt(self, prompt, negative_prompt, device, dtype):
52
  def get_single_encode(texts, is_negative=False):
53
  if texts is None or texts == "":
@@ -198,6 +247,15 @@ class SdxsPipeline(DiffusionPipeline):
198
  return SdxsPipelineOutput(images=latents)
199
 
200
  latents = latents * vae_scaling_factor + vae_shift_factor
 
 
 
 
 
 
 
 
 
201
  image_output = self.vae.decode(latents.to(self.vae.dtype), return_dict=False)[0]
202
 
203
  image_output = (image_output.clamp(-1, 1) + 1) / 2
 
22
  unet=unet,
23
  scheduler=scheduler
24
  )
25
+ self.vae_scale_factor = 16 #2 ** (len(self.vae.config.block_out_channels) - 1)
26
 
27
  def preprocess_image(self, image: Image.Image, width: int, height: int):
28
  """Ресайз и центрированный кроп изображения для асимметричного VAE."""
 
48
  image = torch.from_numpy(image)
49
  return 2.0 * image - 1.0 # [-1, 1]
50
 
51
+ @staticmethod
52
+ def _patchify_latents(latents):
53
+ batch_size, num_channels_latents, height, width = latents.shape
54
+ latents = latents.view(batch_size, num_channels_latents, height // 2, 2, width // 2, 2)
55
+ latents = latents.permute(0, 1, 3, 5, 2, 4)
56
+ latents = latents.reshape(batch_size, num_channels_latents * 4, height // 2, width // 2)
57
+ return latents
58
+
59
+ @staticmethod
60
+ def _unpatchify_latents(latents):
61
+ batch_size, num_channels_latents, height, width = latents.shape
62
+ latents = latents.reshape(batch_size, num_channels_latents // (2 * 2), 2, 2, height, width)
63
+ latents = latents.permute(0, 1, 4, 2, 5, 3)
64
+ latents = latents.reshape(batch_size, num_channels_latents // (2 * 2), height * 2, width * 2)
65
+ return latents
66
+
67
+ def flux_encode(self, latents):
68
+ # 1. Patchify
69
+ image_latents = self._patchify_latents(latents)
70
+
71
+ # 2. Normalization
72
+ # Достаем параметры из self.vae
73
+ bn_mean = self.vae.bn.running_mean.view(1, -1, 1, 1).to(image_latents.device, image_latents.dtype)
74
+ bn_var = self.vae.bn.running_var.view(1, -1, 1, 1).to(image_latents.device, image_latents.dtype)
75
+ eps = getattr(self.vae.config, "batch_norm_eps", 1e-5)
76
+
77
+ latents_bn_std = torch.sqrt(bn_var + eps)
78
+ latents = (image_latents - bn_mean) / latents_bn_std
79
+
80
+ # 3. Unpatchify
81
+ latents = self._unpatchify_latents(latents)
82
+ return latents
83
+
84
+ def flux_decode(self, latents):
85
+ # 1. Patchify
86
+ image_latents = self._patchify_latents(latents)
87
+
88
+ # 2. De-normalization
89
+ bn_mean = self.vae.bn.running_mean.view(1, -1, 1, 1).to(image_latents.device, image_latents.dtype)
90
+ bn_var = self.vae.bn.running_var.view(1, -1, 1, 1).to(image_latents.device, image_latents.dtype)
91
+ eps = getattr(self.vae.config, "batch_norm_eps", 1e-5)
92
+
93
+ latents_bn_std = torch.sqrt(bn_var + eps)
94
+ latents = image_latents * latents_bn_std + bn_mean
95
+
96
+ # 3. Unpatchify
97
+ latents = self._unpatchify_latents(latents)
98
+ return latents
99
+
100
  def encode_prompt(self, prompt, negative_prompt, device, dtype):
101
  def get_single_encode(texts, is_negative=False):
102
  if texts is None or texts == "":
 
247
  return SdxsPipelineOutput(images=latents)
248
 
249
  latents = latents * vae_scaling_factor + vae_shift_factor
250
+ latents = self.flux_decode(latents)
251
+ #latents_bn_mean = self.vae.bn.running_mean.view(1, -1, 1, 1).to(latents.device, latents.dtype)
252
+ #latents_bn_std = torch.sqrt(self.vae.bn.running_var.view(1, -1, 1, 1) + self.vae.config.batch_norm_eps).to(
253
+ # latents.device, latents.dtype
254
+ #)
255
+ #latents = latents * latents_bn_std + latents_bn_mean
256
+ #latents = self._unpatchify_latents(latents)
257
+
258
+ image = self.vae.decode(latents, return_dict=False)[0]
259
  image_output = self.vae.decode(latents.to(self.vae.dtype), return_dict=False)[0]
260
 
261
  image_output = (image_output.clamp(-1, 1) + 1) / 2
samples/unet_352x640_0.jpg DELETED

Git LFS Details

  • SHA256: f2fce8a1180e2cf3697b4f4f8de830a43b905fd7d75585fb618f2e4dfb881761
  • Pointer size: 131 Bytes
  • Size of remote file: 270 kB
samples/unet_384x640_0.jpg DELETED

Git LFS Details

  • SHA256: b070ba2c7b45d2d8da97ebdef34af9558f3e0c1706eeb86a0ff6934069b7e517
  • Pointer size: 130 Bytes
  • Size of remote file: 89.8 kB
samples/unet_416x640_0.jpg DELETED

Git LFS Details

  • SHA256: e9318becc9d3ac641bfd9cf877df87f58b3094cd43ccf4dac1107dbe7783a28d
  • Pointer size: 130 Bytes
  • Size of remote file: 78 kB
samples/unet_448x640_0.jpg DELETED

Git LFS Details

  • SHA256: a5a0453a235dddaaab27695dcb2e584de308107e194aea95ddc9484761f90137
  • Pointer size: 131 Bytes
  • Size of remote file: 116 kB
samples/unet_480x640_0.jpg DELETED

Git LFS Details

  • SHA256: 2f0d2cee3664e5a8897f83f0e135e826a09445c0a11e7766dda70f43cb4612f2
  • Pointer size: 131 Bytes
  • Size of remote file: 481 kB
samples/unet_512x640_0.jpg DELETED

Git LFS Details

  • SHA256: 1c144b213b8db80e6ec6542092ea34a149b2dc88a13abbf4722afd6a53125d04
  • Pointer size: 131 Bytes
  • Size of remote file: 131 kB
samples/unet_544x640_0.jpg DELETED

Git LFS Details

  • SHA256: 7ec37f426b7582f8e3af2ce882943f3cd49bb02a269538b87aa9fb803e4e388e
  • Pointer size: 130 Bytes
  • Size of remote file: 80.4 kB
samples/unet_576x640_0.jpg DELETED

Git LFS Details

  • SHA256: ccf69571878ebb8a35c74f0a0aeaca9e01fd910b520eaf6a92db94f3877ab0ac
  • Pointer size: 130 Bytes
  • Size of remote file: 85.9 kB
samples/unet_608x640_0.jpg DELETED

Git LFS Details

  • SHA256: e1f3cb27c4a0a0d34ecfa0ccdbee791223e1c9ce2a2cdfd12cd04bf14de5a6ca
  • Pointer size: 130 Bytes
  • Size of remote file: 79.5 kB
samples/unet_640x320_0.jpg DELETED

Git LFS Details

  • SHA256: c9e8e1fe93879b189d81b9813af2d01e4771f6eef735cf4cfa982f0aca7ed998
  • Pointer size: 131 Bytes
  • Size of remote file: 108 kB
samples/unet_640x352_0.jpg DELETED

Git LFS Details

  • SHA256: 4cd147003656f04152487f61fe726594cd881972a46e0de1ccd6d6269ff8b755
  • Pointer size: 131 Bytes
  • Size of remote file: 457 kB
samples/unet_640x384_0.jpg DELETED

Git LFS Details

  • SHA256: 14a1c6a56ff09fdcbda7613b30d58485daaa3d71254ef7601e49bfbb7d484a0b
  • Pointer size: 131 Bytes
  • Size of remote file: 125 kB
samples/unet_640x416_0.jpg DELETED

Git LFS Details

  • SHA256: 6f46cd99886fbff1f28f41ec230165a561b3a24f5c1e865baf7b1ea0b1955288
  • Pointer size: 130 Bytes
  • Size of remote file: 36.9 kB
samples/unet_640x448_0.jpg DELETED

Git LFS Details

  • SHA256: ef9795c34c9c6e75ec9a9ed81bcbfd705ebf757a837d98e38e41076dd8ba8872
  • Pointer size: 131 Bytes
  • Size of remote file: 160 kB
samples/unet_640x480_0.jpg DELETED

Git LFS Details

  • SHA256: f0b50bbc66905396a6a64439ec72d1f1113940b153075d428e7b356dcceeb36f
  • Pointer size: 130 Bytes
  • Size of remote file: 84.3 kB
samples/unet_640x512_0.jpg DELETED

Git LFS Details

  • SHA256: 3254444487bc34ec534449f1b7aa00cc6a8d9aa7028e5fbf43fbbf343c8d61d1
  • Pointer size: 131 Bytes
  • Size of remote file: 177 kB
samples/unet_640x544_0.jpg DELETED

Git LFS Details

  • SHA256: adde9c4defb172e5803441cfbdb31602d9dfbf058013802d6cc5c1a34c5e71b7
  • Pointer size: 130 Bytes
  • Size of remote file: 22.5 kB
samples/unet_640x576_0.jpg DELETED

Git LFS Details

  • SHA256: c7f5100905aecc7567941226b89d59b61f4d9e79492e0f8f92985afb65e43344
  • Pointer size: 130 Bytes
  • Size of remote file: 29.7 kB
samples/unet_640x608_0.jpg DELETED

Git LFS Details

  • SHA256: ff8cbc595e3226604f0bd451b6524f776d3c690db6a045e97f5d8f44f8aa3ac8
  • Pointer size: 130 Bytes
  • Size of remote file: 69.6 kB
samples/unet_640x640_0.jpg DELETED

Git LFS Details

  • SHA256: b442d311e6347a1f7d2c228e5213322eaf2de6011593b177f365972a2df377e2
  • Pointer size: 131 Bytes
  • Size of remote file: 157 kB
test.ipynb CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:99418c2b7f273b90540fbefb47fd60793d6973d4d8238c78ceba86716c36a5d6
3
- size 5313615
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0a1db3927bbb12c88ac07d9bf9b8006cc095417b561240413be0c9956618046d
3
+ size 2126983
train_flux.py CHANGED
@@ -33,10 +33,10 @@ from transformers import AutoTokenizer, AutoModel
33
  ds_path = "/workspace/sdxs-1b/datasets/mjnj_640_flux2"
34
  project = "unet"
35
  ## total batch (split // num `GPU)
36
- batch_size = 12
37
  base_learning_rate = 3e-5
38
  min_learning_rate = 1e-5
39
- num_epochs = 1
40
  sample_interval_share = 20
41
  cfg_dropout = 0.10
42
  max_length = 248
@@ -761,4 +761,4 @@ accelerator.free_memory()
761
  if torch.distributed.is_initialized():
762
  torch.distributed.destroy_process_group()
763
 
764
- print("Готово!")
 
33
  ds_path = "/workspace/sdxs-1b/datasets/mjnj_640_flux2"
34
  project = "unet"
35
  ## total batch (split // num `GPU)
36
+ batch_size = 42
37
  base_learning_rate = 3e-5
38
  min_learning_rate = 1e-5
39
+ num_epochs = 8
40
  sample_interval_share = 20
41
  cfg_dropout = 0.10
42
  max_length = 248
 
761
  if torch.distributed.is_initialized():
762
  torch.distributed.destroy_process_group()
763
 
764
+ print("Готово!")
unet/diffusion_pytorch_model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d1a8c9098a3ea786f6c555bfae1d106df7c128e5702314e28c5053938499e724
3
  size 5935560296
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a0bd7c0c156cd06520c8925860a11bf0c7796bc2bf22f5febeb6696dc82896fd
3
  size 5935560296