Instructions to use AiArtLab/sdxs-1b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use AiArtLab/sdxs-1b with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("AiArtLab/sdxs-1b", dtype=torch.bfloat16, device_map="cuda") prompt = "sdxs-1b" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- Draw Things
- DiffusionBee
recoilme commited on
Commit ·
2582c0d
1
Parent(s): 21db84d
vae8x16x32ch
Browse files- dataset.py +108 -19
- media/result_grid.jpg +2 -2
- model_index.json +2 -2
- girl.jpg → src/girl.jpg +2 -2
- src/test.ipynb +2 -2
- test.ipynb +3 -0
- train.py +6 -12
- vae/config.json +2 -2
- vae/diffusion_pytorch_model.safetensors +2 -2
dataset.py
CHANGED
|
@@ -9,34 +9,32 @@ import shutil
|
|
| 9 |
import time
|
| 10 |
|
| 11 |
from datasets import Dataset, load_from_disk, concatenate_datasets
|
| 12 |
-
from diffusers import
|
| 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 |
-
# --- NEW: accelerate ---
|
| 21 |
from accelerate import Accelerator
|
|
|
|
| 22 |
accelerator = Accelerator()
|
| 23 |
device = accelerator.device
|
| 24 |
is_main_process = accelerator.is_main_process
|
| 25 |
process_index = accelerator.process_index
|
| 26 |
num_processes = accelerator.num_processes
|
| 27 |
-
# --- END NEW ---
|
| 28 |
|
| 29 |
# ---------------- 1️⃣ Настройки ----------------
|
| 30 |
dtype = torch.float16
|
| 31 |
-
batch_size =
|
| 32 |
-
min_size =
|
| 33 |
-
max_size =
|
| 34 |
-
step =
|
| 35 |
empty_share = 0.0
|
| 36 |
limit = 0
|
| 37 |
|
| 38 |
-
folder_path = "/workspace/
|
| 39 |
-
save_path = "/workspace/
|
| 40 |
os.makedirs(save_path, exist_ok=True)
|
| 41 |
|
| 42 |
def clear_cuda_memory():
|
|
@@ -49,7 +47,7 @@ def clear_cuda_memory():
|
|
| 49 |
# ---------------- 2️⃣ Загрузка моделей ----------------
|
| 50 |
def load_models():
|
| 51 |
print(f"[GPU {process_index}] Загрузка моделей...")
|
| 52 |
-
vae =
|
| 53 |
return vae
|
| 54 |
|
| 55 |
vae = load_models()
|
|
@@ -197,7 +195,102 @@ def process_folder(folder_path, limit=None):
|
|
| 197 |
print(f"Найдено {len(image_paths)} изображений")
|
| 198 |
return image_paths, text_paths, width, height
|
| 199 |
|
| 200 |
-
def process_in_chunks(image_paths, text_paths, width, height, chunk_size=10000, batch_size=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
total_files = len(image_paths)
|
| 202 |
start_time = time.time()
|
| 203 |
|
|
@@ -237,7 +330,7 @@ def process_in_chunks(image_paths, text_paths, width, height, chunk_size=10000,
|
|
| 237 |
)
|
| 238 |
|
| 239 |
# --- NEW: уникальный путь ---
|
| 240 |
-
group_save_path = f"{save_path}_temp/
|
| 241 |
# --- END NEW ---
|
| 242 |
|
| 243 |
processed_group.save_to_disk(group_save_path)
|
|
@@ -270,7 +363,7 @@ text_paths = [text_paths[i] for i in sorted_indices]
|
|
| 270 |
width = [width[i] for i in sorted_indices]
|
| 271 |
height = [height[i] for i in sorted_indices]
|
| 272 |
|
| 273 |
-
# ---
|
| 274 |
indices = list(range(len(image_paths)))
|
| 275 |
indices = indices[process_index::num_processes]
|
| 276 |
|
|
@@ -280,13 +373,10 @@ width = [width[i] for i in indices]
|
|
| 280 |
height = [height[i] for i in indices]
|
| 281 |
|
| 282 |
print(f"[GPU {process_index}] обрабатывает {len(image_paths)} файлов")
|
| 283 |
-
# --- END NEW ---
|
| 284 |
|
| 285 |
process_in_chunks(image_paths, text_paths, width, height, chunk_size=20000, batch_size=batch_size)
|
| 286 |
|
| 287 |
-
# --- NEW: sync ---
|
| 288 |
accelerator.wait_for_everyone()
|
| 289 |
-
# --- END NEW ---
|
| 290 |
|
| 291 |
# --- NEW: только главный процесс ---
|
| 292 |
if is_main_process:
|
|
@@ -300,5 +390,4 @@ if is_main_process:
|
|
| 300 |
try:
|
| 301 |
shutil.rmtree(temp_path)
|
| 302 |
except:
|
| 303 |
-
pass
|
| 304 |
-
# --- END NEW ---
|
|
|
|
| 9 |
import time
|
| 10 |
|
| 11 |
from datasets import Dataset, load_from_disk, concatenate_datasets
|
| 12 |
+
from diffusers import 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 |
from accelerate import Accelerator
|
| 20 |
+
|
| 21 |
accelerator = Accelerator()
|
| 22 |
device = accelerator.device
|
| 23 |
is_main_process = accelerator.is_main_process
|
| 24 |
process_index = accelerator.process_index
|
| 25 |
num_processes = accelerator.num_processes
|
|
|
|
| 26 |
|
| 27 |
# ---------------- 1️⃣ Настройки ----------------
|
| 28 |
dtype = torch.float16
|
| 29 |
+
batch_size = 4
|
| 30 |
+
min_size = 384
|
| 31 |
+
max_size = 704
|
| 32 |
+
step = 32
|
| 33 |
empty_share = 0.0
|
| 34 |
limit = 0
|
| 35 |
|
| 36 |
+
folder_path = "/workspace/sdxs-1b/datasets/ds1234_noanime_1280"
|
| 37 |
+
save_path = "/workspace/sdxs-1b/datasets/ds1234_noanime_704_vae8x16x"
|
| 38 |
os.makedirs(save_path, exist_ok=True)
|
| 39 |
|
| 40 |
def clear_cuda_memory():
|
|
|
|
| 47 |
# ---------------- 2️⃣ Загрузка моделей ----------------
|
| 48 |
def load_models():
|
| 49 |
print(f"[GPU {process_index}] Загрузка моделей...")
|
| 50 |
+
vae = AsymmetricAutoencoderKL.from_pretrained("vae", torch_dtype=dtype).to(device).eval()
|
| 51 |
return vae
|
| 52 |
|
| 53 |
vae = load_models()
|
|
|
|
| 195 |
print(f"Найдено {len(image_paths)} изображений")
|
| 196 |
return image_paths, text_paths, width, height
|
| 197 |
|
| 198 |
+
def process_in_chunks(image_paths, text_paths, width, height, chunk_size=10000, batch_size=4):
|
| 199 |
+
total_files = len(image_paths)
|
| 200 |
+
|
| 201 |
+
for chunk_idx, start in enumerate(range(0, total_files, chunk_size), 1):
|
| 202 |
+
end = min(start + chunk_size, total_files)
|
| 203 |
+
|
| 204 |
+
chunk_image_paths = image_paths[start:end]
|
| 205 |
+
chunk_text_paths = text_paths[start:end]
|
| 206 |
+
chunk_widths = width[start:end]
|
| 207 |
+
chunk_heights = height[start:end]
|
| 208 |
+
|
| 209 |
+
# --- читаем тексты ---
|
| 210 |
+
chunk_texts = []
|
| 211 |
+
for text_path in chunk_text_paths:
|
| 212 |
+
try:
|
| 213 |
+
with open(text_path, "r", encoding="utf-8") as f:
|
| 214 |
+
chunk_texts.append(f.read().strip())
|
| 215 |
+
except:
|
| 216 |
+
chunk_texts.append("")
|
| 217 |
+
|
| 218 |
+
# --- группировка по размеру ---
|
| 219 |
+
size_groups = {}
|
| 220 |
+
for i in range(len(chunk_image_paths)):
|
| 221 |
+
key = (chunk_widths[i], chunk_heights[i])
|
| 222 |
+
if key not in size_groups:
|
| 223 |
+
size_groups[key] = {"image_paths": [], "texts": []}
|
| 224 |
+
size_groups[key]["image_paths"].append(chunk_image_paths[i])
|
| 225 |
+
size_groups[key]["texts"].append(chunk_texts[i])
|
| 226 |
+
|
| 227 |
+
# --- обработка групп ---
|
| 228 |
+
for size_key, group_data in size_groups.items():
|
| 229 |
+
image_list = group_data["image_paths"]
|
| 230 |
+
text_list = group_data["texts"]
|
| 231 |
+
|
| 232 |
+
latents_all = []
|
| 233 |
+
texts_all = []
|
| 234 |
+
widths_all = []
|
| 235 |
+
heights_all = []
|
| 236 |
+
|
| 237 |
+
for i in range(0, len(image_list), batch_size):
|
| 238 |
+
batch_paths = image_list[i:i + batch_size]
|
| 239 |
+
batch_texts = text_list[i:i + batch_size]
|
| 240 |
+
|
| 241 |
+
batch_imgs = []
|
| 242 |
+
|
| 243 |
+
for p in batch_paths:
|
| 244 |
+
try:
|
| 245 |
+
with Image.open(p) as img:
|
| 246 |
+
img = img.convert("RGB")
|
| 247 |
+
batch_imgs.append(img.copy())
|
| 248 |
+
except Exception as e:
|
| 249 |
+
print(f"[GPU {process_index}] Ошибка загрузки: {p} | {e}")
|
| 250 |
+
|
| 251 |
+
if len(batch_imgs) == 0:
|
| 252 |
+
continue
|
| 253 |
+
|
| 254 |
+
try:
|
| 255 |
+
out = encode_to_latents(batch_imgs, batch_texts)
|
| 256 |
+
except Exception as e:
|
| 257 |
+
print(f"[GPU {process_index}] Ошибка encode: {e}")
|
| 258 |
+
continue
|
| 259 |
+
|
| 260 |
+
if out is None:
|
| 261 |
+
continue
|
| 262 |
+
|
| 263 |
+
latents_all.extend(out["vae"])
|
| 264 |
+
texts_all.extend(out["text"])
|
| 265 |
+
widths_all.extend(out["width"])
|
| 266 |
+
heights_all.extend(out["height"])
|
| 267 |
+
|
| 268 |
+
# чуть чистим память
|
| 269 |
+
del batch_imgs, out
|
| 270 |
+
if torch.cuda.is_available():
|
| 271 |
+
torch.cuda.empty_cache()
|
| 272 |
+
|
| 273 |
+
if len(latents_all) == 0:
|
| 274 |
+
continue
|
| 275 |
+
|
| 276 |
+
# --- сохраняем ---
|
| 277 |
+
group_save_path = f"{save_path}_temp/chunk_{chunk_idx}_{size_key[0]}x{size_key[1]}_proc_{process_index}"
|
| 278 |
+
|
| 279 |
+
dataset_dict = {
|
| 280 |
+
"vae": latents_all,
|
| 281 |
+
"text": texts_all,
|
| 282 |
+
"width": widths_all,
|
| 283 |
+
"height": heights_all,
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
ds = Dataset.from_dict(dataset_dict)
|
| 287 |
+
ds.save_to_disk(group_save_path)
|
| 288 |
+
|
| 289 |
+
print(f"[GPU {process_index}] Saved: {group_save_path}")
|
| 290 |
+
|
| 291 |
+
clear_cuda_memory()
|
| 292 |
+
|
| 293 |
+
def process_in_chunks2(image_paths, text_paths, width, height, chunk_size=10000, batch_size=1):
|
| 294 |
total_files = len(image_paths)
|
| 295 |
start_time = time.time()
|
| 296 |
|
|
|
|
| 330 |
)
|
| 331 |
|
| 332 |
# --- NEW: уникальный путь ---
|
| 333 |
+
group_save_path = f"{save_path}_temp/chunk_{chunk_idx}_{size_key[0]}x{size_key[1]}_proc_{process_index}_"
|
| 334 |
# --- END NEW ---
|
| 335 |
|
| 336 |
processed_group.save_to_disk(group_save_path)
|
|
|
|
| 363 |
width = [width[i] for i in sorted_indices]
|
| 364 |
height = [height[i] for i in sorted_indices]
|
| 365 |
|
| 366 |
+
# --- shard по GPU ---
|
| 367 |
indices = list(range(len(image_paths)))
|
| 368 |
indices = indices[process_index::num_processes]
|
| 369 |
|
|
|
|
| 373 |
height = [height[i] for i in indices]
|
| 374 |
|
| 375 |
print(f"[GPU {process_index}] обрабатывает {len(image_paths)} файлов")
|
|
|
|
| 376 |
|
| 377 |
process_in_chunks(image_paths, text_paths, width, height, chunk_size=20000, batch_size=batch_size)
|
| 378 |
|
|
|
|
| 379 |
accelerator.wait_for_everyone()
|
|
|
|
| 380 |
|
| 381 |
# --- NEW: только главный процесс ---
|
| 382 |
if is_main_process:
|
|
|
|
| 390 |
try:
|
| 391 |
shutil.rmtree(temp_path)
|
| 392 |
except:
|
| 393 |
+
pass
|
|
|
media/result_grid.jpg
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
model_index.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b9fe0891c1d3f4f0b2a8cbca077be3533f28306768c3ea8d5256924fc677a4b1
|
| 3 |
+
size 438
|
girl.jpg → src/girl.jpg
RENAMED
|
File without changes
|
src/test.ipynb
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:dba3b9d70d28c3827ea6f79c9f70740f79ae7eec0f37291467c4e1a9d708f310
|
| 3 |
+
size 6906512
|
test.ipynb
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f663bb1711eeec7532342a1c4598c317b2eff12bb642855f971448c57cfd3964
|
| 3 |
+
size 6986500
|
train.py
CHANGED
|
@@ -11,7 +11,7 @@ from torch.utils.data import DataLoader, Sampler
|
|
| 11 |
from torch.utils.data.distributed import DistributedSampler
|
| 12 |
from torch.optim.lr_scheduler import LambdaLR
|
| 13 |
from collections import defaultdict
|
| 14 |
-
from diffusers import UNet2DConditionModel,
|
| 15 |
from accelerate import Accelerator, DeepSpeedPlugin
|
| 16 |
from datasets import load_from_disk
|
| 17 |
from tqdm import tqdm
|
|
@@ -31,7 +31,7 @@ from transformers import Qwen3_5Tokenizer, Qwen3_5ForConditionalGeneration
|
|
| 31 |
import argparse
|
| 32 |
|
| 33 |
# --------------------------- Параметры ---------------------------
|
| 34 |
-
ds_path = "datasets/
|
| 35 |
project = "unet"
|
| 36 |
# 1. Считаем локальный батч для ОДНОЙ карты (3 на каждые 32 Гб)
|
| 37 |
gpu_mem_gb = torch.cuda.get_device_properties(0).total_memory / 1e9
|
|
@@ -48,8 +48,8 @@ sample_interval_share = 20
|
|
| 48 |
cfg_dropout = 0.10
|
| 49 |
max_length = 248
|
| 50 |
use_wandb = False
|
| 51 |
-
use_comet_ml =
|
| 52 |
-
save_model =
|
| 53 |
use_decay = True
|
| 54 |
fbp = False
|
| 55 |
optimizer_type = "adam8bit"
|
|
@@ -148,7 +148,7 @@ if accelerator.is_main_process:
|
|
| 148 |
comet_experiment.log_parameters(hyper_params)
|
| 149 |
|
| 150 |
# --------------------------- Загрузка моделей ---------------------------
|
| 151 |
-
vae =
|
| 152 |
tokenizer = Qwen3_5Tokenizer.from_pretrained("tokenizer")
|
| 153 |
text_encoder = Qwen3_5ForConditionalGeneration.from_pretrained("text_encoder", torch_dtype=torch.float16).to(device).eval()
|
| 154 |
scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained("scheduler")
|
|
@@ -432,14 +432,8 @@ if limit > 0:
|
|
| 432 |
else:
|
| 433 |
dataset = load_from_disk(ds_path)
|
| 434 |
|
| 435 |
-
dataset = dataset.filter(
|
| 436 |
-
lambda x: [not (path.startswith("//workspace/ds/animesfw") or path.startswith("//workspace/animesfw") or path.startswith("//workspace/ds/d4/animesfw")) for path in x["image_path"]],
|
| 437 |
|
| 438 |
-
|
| 439 |
-
batch_size=10000, # обрабатываем по 10к строк за раз
|
| 440 |
-
num_proc=8
|
| 441 |
-
)
|
| 442 |
-
print(f"Осталось примеров после фильтрации: {len(dataset)}")
|
| 443 |
|
| 444 |
# --- Collate Function ---
|
| 445 |
def collate_fn_simple(batch):
|
|
|
|
| 11 |
from torch.utils.data.distributed import DistributedSampler
|
| 12 |
from torch.optim.lr_scheduler import LambdaLR
|
| 13 |
from collections import defaultdict
|
| 14 |
+
from diffusers import UNet2DConditionModel,AsymmetricAutoencoderKL,FlowMatchEulerDiscreteScheduler
|
| 15 |
from accelerate import Accelerator, DeepSpeedPlugin
|
| 16 |
from datasets import load_from_disk
|
| 17 |
from tqdm import tqdm
|
|
|
|
| 31 |
import argparse
|
| 32 |
|
| 33 |
# --------------------------- Параметры ---------------------------
|
| 34 |
+
ds_path = "datasets/ds1234_noanime_704_vae8x16x"
|
| 35 |
project = "unet"
|
| 36 |
# 1. Считаем локальный батч для ОДНОЙ карты (3 на каждые 32 Гб)
|
| 37 |
gpu_mem_gb = torch.cuda.get_device_properties(0).total_memory / 1e9
|
|
|
|
| 48 |
cfg_dropout = 0.10
|
| 49 |
max_length = 248
|
| 50 |
use_wandb = False
|
| 51 |
+
use_comet_ml = False
|
| 52 |
+
save_model = False
|
| 53 |
use_decay = True
|
| 54 |
fbp = False
|
| 55 |
optimizer_type = "adam8bit"
|
|
|
|
| 148 |
comet_experiment.log_parameters(hyper_params)
|
| 149 |
|
| 150 |
# --------------------------- Загрузка моделей ---------------------------
|
| 151 |
+
vae = AsymmetricAutoencoderKL.from_pretrained("vae", torch_dtype=dtype).to(device).eval()
|
| 152 |
tokenizer = Qwen3_5Tokenizer.from_pretrained("tokenizer")
|
| 153 |
text_encoder = Qwen3_5ForConditionalGeneration.from_pretrained("text_encoder", torch_dtype=torch.float16).to(device).eval()
|
| 154 |
scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained("scheduler")
|
|
|
|
| 432 |
else:
|
| 433 |
dataset = load_from_disk(ds_path)
|
| 434 |
|
|
|
|
|
|
|
| 435 |
|
| 436 |
+
print(f"images: {len(dataset)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 437 |
|
| 438 |
# --- Collate Function ---
|
| 439 |
def collate_fn_simple(batch):
|
vae/config.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:26f99e8253949bc6a406c5f7c7f1358c76d20eb3564e579378c21e0596c466cf
|
| 3 |
+
size 2379
|
vae/diffusion_pytorch_model.safetensors
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:780993a422cf0d783088c5116063ab6e3b1453a5256f205b78b1c67617f17b33
|
| 3 |
+
size 383499124
|