MCPcopy Create free account
hub / github.com/tinygrad/tinygrad / eval_unet

Function eval_unet

examples/mlperf/model_eval.py:362–481  ·  view source on GitHub ↗
(eval_inputs:list[dict], unet:UNetModel, cond_stage:FrozenOpenClipEmbedder, first_stage:AutoencoderKL,
                inception:FidInceptionV3, clip:OpenClipEncoder)

Source from the content-addressed store, hash-verified

360
361 @Tensor.train(mode=False)
362 def eval_unet(eval_inputs:list[dict], unet:UNetModel, cond_stage:FrozenOpenClipEmbedder, first_stage:AutoencoderKL,
363 inception:FidInceptionV3, clip:OpenClipEncoder) -> tuple[float, float]:
364 # Eval is divided into 5 jits, one per model
365 # It doesn't make sense to merge these jits, e.g. unet repeats 50 times in isolation; images fork to separate inception/clip
366 # We're generating and scoring 30,000 images per eval, and all the data can flow through one jit at a time
367 # To maximize throughput for each jit, we have only one model/jit on the GPU at a time, and pool outputs from each jit off-GPU
368 for model in (unet, first_stage, inception, clip):
369 Tensor.realize(*[p.to_("CPU") for p in get_parameters(model)])
370
371 uc_written = False
372 models = (cond_stage, unet, first_stage, inception, clip)
373 jits = (jit_context:=TinyJit(cond_stage.embed_tokens), denoise_step, vae_decode, jit_inception:=TinyJit(inception),
374 jit_clip:=TinyJit(clip.get_clip_score))
375 all_bs = (CONTEXT_BS, DENOISE_BS, DECODE_BS, INCEPTION_BS, CLIP_BS)
376 if (EVAL_SAMPLES:=getenv("EVAL_SAMPLES", 0)) and EVAL_SAMPLES > 0:
377 eval_inputs = eval_inputs[0:EVAL_SAMPLES]
378 output_shapes = [(ns:=len(eval_inputs),77), (ns,77,1024), (ns,4,64,64), (ns,3,512,512), (ns,2048), (ns,)]
379 # Writing progress to disk lets us resume eval if we crash
380 stages = ["tokens", "embeds", "latents", "imgs", "inception", "clip"]
381 disk_tensor_names, disk_tensor_shapes = stages + ["end", "uc"], output_shapes + [(6,), (1,77,1024)]
382 if not all(os.path.exists(f"{EVAL_CKPT_DIR}/{name}.bytes") for name in disk_tensor_names):
383 for name, shape in zip(disk_tensor_names, disk_tensor_shapes):
384 file = Path(f"{EVAL_CKPT_DIR}/{name}.bytes")
385 file.unlink(missing_ok=True)
386 with file.open("wb") as f: f.truncate(prod(shape) * 4)
387 progress = {name: Tensor.empty(*shape, device=f"disk:{EVAL_CKPT_DIR}/{name}.bytes", dtype=dtypes.int if name in {"tokens", "end"} else dtypes.float)
388 for name, shape in zip(disk_tensor_names, disk_tensor_shapes)}
389
390 def embed_tokens(tokens:Tensor) -> Tensor:
391 nonlocal uc_written
392 if not uc_written:
393 with Context(BEAM=0): progress["uc"].assign(cond_stage.embed_tokens(cond_stage.tokenize("").to(GPUS)).to("CPU").realize()).realize()
394 uc_written = True
395 return jit_context(shard_tensor(tokens))
396
397 def generate_latents(embeds:Tensor) -> Tensor:
398 uc_c = Tensor.stack(progress["uc"].to("CPU").expand(bs, 77, 1024), embeds, dim=1).reshape(-1, 77, 1024)
399 uc_c = shard_tensor(uc_c)
400 x = shard_tensor(Tensor.randn(bs,4,64,64))
401 for step_idx, timestep in enumerate(tqdm(eval_timesteps)):
402 reversed_idx = Tensor([50 - step_idx - 1], device=GPUS)
403 alpha_prev = eval_alphas_prev[reversed_idx]
404 ts = Tensor.full(bs, fill_value=timestep, dtype=dtypes.int, device="CPU")
405 ts_ts = shard_tensor(ts.cat(ts))
406 ts = shard_tensor(ts)
407 sqrt_alphas_cumprod_t = sqrt_alphas_cumprod[ts].reshape(bs, 1, 1, 1)
408 sqrt_one_minus_alphas_cumprod_t = sqrt_one_minus_alphas_cumprod[ts].reshape(bs, 1, 1, 1)
409 x_x = shard_tensor(Tensor.stack(x.to("CPU"), x.to("CPU"), dim=1).reshape(-1, 4, 64, 64))
410 x.assign(denoise_step(x, x_x, ts_ts, uc_c, sqrt_alphas_cumprod_t, sqrt_one_minus_alphas_cumprod_t, alpha_prev, unet, GPUS)).realize()
411 return x
412
413 def decode_latents(latents:Tensor) -> Tensor: return vae_decode(shard_tensor(latents), first_stage, disable_beam=True)
414 def generate_inception(imgs:Tensor) -> Tensor: return jit_inception(shard_tensor(imgs))[:,:,0,0]
415
416 def calc_clip_scores(batch:Tensor, batch_tokens:Tensor) -> Tensor:
417 # Tensor.interpolate does not yet support bicubic, so we use PIL
418 batch = (batch.to(GPUS[0]).permute(0,2,3,1) * 255).clip(0, 255).cast(dtypes.uint8).numpy()
419 batch = [np.array(PIL.Image.fromarray(batch[i]).resize((224,224), PIL.Image.BICUBIC)) for i in range(bs)]

Callers 1

eval_stable_diffusionFunction · 0.85

Calls 15

get_parametersFunction · 0.90
TinyJitClass · 0.90
getenvFunction · 0.90
prodFunction · 0.90
TensorClass · 0.90
stage_progressFunction · 0.85
tqdmClass · 0.85
realizeMethod · 0.80
to_Method · 0.80
appendMethod · 0.80
catMethod · 0.80
compute_scoreMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…