Views
No views yet
AutoencoderKlMaisi), 1 input channel, 4 latent channels, spatial dimensions 3. Encoder/decoder use num_channels [64, 128, 256] and L1 reconstruction loss with optional perceptual and adversarial terms.DiffusionModelUNetMaisi) in latent space with 4 input/output channels, num_channels [64, 128, 256, 512], attention at the two deepest levels, ResBlock up/down, and conditioning on spacing. The noise process is Rectified Flow (RFlowScheduler, 1000 steps, continuous time, scale 1.4).diffusion_unet_scratch_best.pt.diffusion_unet_20k_finetune.pt) and 10k-step full resume checkpoint for reproducibility (diffusion_unet_resume_10k.pt).z_norm = (z - mean) / std using per-channel statistics computed over the training set. The same normalization must be applied at inference:latent_stats/latent_mean.npy and latent_stats/latent_std.npy (shape [4] for 4 latent channels).z = ae.encode(...) then z_norm = (z - mean) / std.z = z_norm * std + mean then x = ae.decode(z).latent_stats/latent_stats_report.json documents the dataset split, sample count, and per-channel statistics used.hf_release_oct_latent_diffusion/
├── vae/
│ ├── vae_best.pt # VAE best validation checkpoint (recommended)
│ └── vae_final.pt # VAE final training checkpoint
├── diffusion/
│ ├── diffusion_unet_20k_finetune.pt # UNet weights at 15k finetune steps (recommended for sampling)
│ ├── diffusion_unet_scratch_best.pt # UNet best validation from 50k scratch training
│ └── diffusion_unet_resume_10k.pt # Full resume checkpoint at 10k finetune (optimizer/EMA/step)
├── latent_stats/
│ ├── latent_mean.npy # Per-channel latent mean [4]
│ ├── latent_std.npy # Per-channel latent std [4]
│ └── latent_stats_report.json
├── configs/
│ └── cfg_oct_snapshot.json # Training config snapshot (paths may point to local env)
└── README.mdAutoencoderKlMaisi and DiffusionModelUNetMaisi), plus the Rectified Flow scheduler and your datalist/config paths.1import json
2import numpy as np
3import torch
4from pathlib import Path
5
6# Paths (adjust to your clone or Hugging Face cache)
7REPO = Path("hf_release_oct_latent_diffusion")
8VAE_CKPT = REPO / "vae" / "vae_best.pt"
9UNET_CKPT = REPO / "diffusion" / "diffusion_unet_20k_finetune.pt"
10LATENT_MEAN = np.load(REPO / "latent_stats" / "latent_mean.npy")
11LATENT_STD = np.load(REPO / "latent_stats" / "latent_std.npy")
12
13# Load VAE
14def load_ae_state_dict(ckpt_path):
15 ckpt = torch.load(ckpt_path, map_location="cpu", weights_only=False)
16 for k in ["autoencoder_state_dict", "autoencoder", "state_dict", "model"]:
17 if isinstance(ckpt, dict) and k in ckpt and isinstance(ckpt[k], dict):
18 return ckpt[k]
19 return ckpt
20
21ae = ... # build from config_network_rflow.json autoencoder_def
22ae.load_state_dict(load_ae_state_dict(VAE_CKPT), strict=False)
23ae.eval()
24
25# Load UNet (weights-only checkpoint)
26def load_unet_state_dict(ckpt_path):
27 ckpt = torch.load(ckpt_path, map_location="cpu", weights_only=False)
28 for k in ["unet_state_dict", "unet", "state_dict", "model"]:
29 if isinstance(ckpt, dict) and k in ckpt and isinstance(ckpt[k], dict):
30 return ckpt[k]
31 return ckpt
32
33unet = ... # build from config_network_rflow.json diffusion_unet_def
34unet.load_state_dict(load_unet_state_dict(UNET_CKPT), strict=False)
35unet.eval()
36
37# Sampling: initialize z_T ~ N(0, I) in normalized space, then Rectified Flow
38# steps (e.g. 40), then denormalize: z = z_norm * LATENT_STD + LATENT_MEAN, then ae.decode(z).
39# See training repo for full scheduler and sampling loop.