()
| 272 | return x |
| 273 | |
| 274 | def eval_stable_diffusion(): |
| 275 | import csv, PIL, sys |
| 276 | from tqdm import tqdm |
| 277 | from examples.mlperf.initializers import init_stable_diffusion, gelu_erf |
| 278 | from examples.stable_diffusion import AutoencoderKL |
| 279 | from extra.models.unet import UNetModel |
| 280 | from tinygrad.nn.state import load_state_dict, torch_load |
| 281 | from tinygrad.helpers import BEAM |
| 282 | from extra.models import clip |
| 283 | from extra.models.clip import FrozenOpenClipEmbedder |
| 284 | from extra.models.clip import OpenClipEncoder |
| 285 | from extra.models.inception import FidInceptionV3 |
| 286 | |
| 287 | config = {} |
| 288 | GPUS = config["GPUS"] = [f"{Device.DEFAULT}:{i}" for i in range(getenv("GPUS", 1))] |
| 289 | for x in GPUS: Device[x] |
| 290 | print(f"running eval on {GPUS}") |
| 291 | seed = config["seed"] = getenv("SEED", 12345) |
| 292 | CKPTDIR = config["CKPTDIR"] = Path(getenv("CKPTDIR", "./checkpoints")) |
| 293 | DATADIR = config["DATADIR"] = Path(getenv("DATADIR", "./datasets")) |
| 294 | CONTEXT_BS = config["CONTEXT_BS"] = getenv("CONTEXT_BS", 1 * len(GPUS)) |
| 295 | DENOISE_BS = config["DENOISE_BS"] = getenv("DENOISE_BS", 1 * len(GPUS)) |
| 296 | DECODE_BS = config["DECODE_BS"] = getenv("DECODE_BS", 1 * len(GPUS)) |
| 297 | INCEPTION_BS = config["INCEPTION_BS"] = getenv("INCEPTION_BS", 1 * len(GPUS)) |
| 298 | CLIP_BS = config["CLIP_BS"] = getenv("CLIP_BS", 1 * len(GPUS)) |
| 299 | EVAL_CKPT_DIR = config["EVAL_CKPT_DIR"] = getenv("EVAL_CKPT_DIR", "") |
| 300 | STOP_IF_CONVERGED = config["STOP_IF_CONVERGED"] = getenv("STOP_IF_CONVERGED", 0) |
| 301 | |
| 302 | if (WANDB := getenv("WANDB", "")): |
| 303 | import wandb |
| 304 | wandb.init(config=config, project="MLPerf-Stable-Diffusion") |
| 305 | |
| 306 | assert EVAL_CKPT_DIR != "", "provide a directory with checkpoints to be evaluated" |
| 307 | print(f"running eval on checkpoints in {EVAL_CKPT_DIR}\nSEED={seed}") |
| 308 | eval_queue:list[tuple[int, Path]] = [] |
| 309 | for p in Path(EVAL_CKPT_DIR).iterdir(): |
| 310 | if p.name.endswith(".safetensors"): |
| 311 | ckpt_iteration = p.name.split(".safetensors")[0] |
| 312 | assert ckpt_iteration.isdigit(), f"invalid checkpoint name: {p.name}, expected <digits>.safetensors" |
| 313 | eval_queue.append((int(ckpt_iteration), p)) |
| 314 | assert len(eval_queue), f'no files ending with ".safetensors" were found in {EVAL_CKPT_DIR}' |
| 315 | print(sorted(eval_queue, reverse=True)) |
| 316 | |
| 317 | Tensor.manual_seed(seed) # seed for weight initialization |
| 318 | model, unet, sqrt_alphas_cumprod, sqrt_one_minus_alphas_cumprod = init_stable_diffusion("v2-mlperf-eval", CKPTDIR / "sd" / "512-base-ema.ckpt", GPUS) |
| 319 | |
| 320 | # load prompts for generating images for validation; 2 MB of data total |
| 321 | with open(DATADIR / "coco2014" / "val2014_30k.tsv") as f: |
| 322 | reader = csv.DictReader(f, delimiter="\t") |
| 323 | eval_inputs:list[dict] = [{"image_id": int(row["image_id"]), "id": int(row["id"]), "caption": row["caption"]} for row in reader] |
| 324 | assert len(eval_inputs) == 30_000 |
| 325 | # NOTE: the clip weights are the same between model.cond_stage_model and clip_encoder |
| 326 | eval_timesteps = list(reversed(range(1, 1000, 20))) |
| 327 | |
| 328 | with Context(DEV="CPU"): |
| 329 | # The choice of alphas_prev[0] = alphas_cumprod[0] seems arbitrary, but it's how the mlperf ref does it: |
| 330 | # alphas_prev = np.asarray([alphacums[0]] + alphacums[ddim_timesteps[:-1]].tolist()) |
| 331 | eval_alphas_prev = model.alphas_cumprod[0:1].cat(model.alphas_cumprod[list(range(1, 1000, 20))[:-1]]).to(GPUS).realize() |
searching dependent graphs…