mmacosha commited on
Commit
ac166e5
·
verified ·
1 Parent(s): a634199

Add cifar10_cd_ct_lpips: pkl + cm.py + load.py

Browse files
cifar10_cd_ct_lpips/cifar10_cd_ct_lpips.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:67cc54eecab61615a8f019399e18b3c8b28d04275ed3007969ed8a65caec6858
3
+ size 225605629
cifar10_cd_ct_lpips/cm.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Consistency-Distillation / Consistency-Training generator wrapper for CIFAR10.
2
+
3
+ Wraps OpenAI's CIFAR10 consistency model (`consistency_models_cifar10`, package
4
+ `jcm`) so it can stand in as a generator with a decode-style API: build once,
5
+ then `decode(z)` maps a noise-space input to a 32x32x3 image in [0, 1].
6
+
7
+ Latents are flat vectors of shape `(batch, 3072)` (== 32*32*3), drawn from
8
+ N(0, sigma_max**2 * I) and reshaped internally.
9
+
10
+ Only the generator path is exercised - LPIPS / classifier heads / training-time
11
+ losses are not imported. `distiller_fn` math is inlined (KVE-SDE Karras et al.
12
+ 2022 conditioning) so we don't depend on `jcm.sde_lib`.
13
+ """
14
+
15
+ from pathlib import Path
16
+
17
+ import jax
18
+ import jax.numpy as jnp
19
+ import ml_collections
20
+
21
+ # Registers "ncsnpp" in jcm.models.utils._MODELS via decorator side-effect.
22
+ from jcm.models import ncsnpp # noqa: F401
23
+ from jcm.models import utils as mutils
24
+
25
+ Array = jax.Array
26
+
27
+ IMAGE_SIZE = 32
28
+ NUM_CHANNELS = 3
29
+ NOISE_DIM = IMAGE_SIZE * IMAGE_SIZE * NUM_CHANNELS # 3072
30
+ SIGMA_MAX = 80.0
31
+ SIGMA_MIN = 0.002
32
+ DATA_STD = 0.5
33
+
34
+
35
+ def _default_config() -> ml_collections.ConfigDict:
36
+ """NCSN++ config used by the CT-LPIPS CIFAR10 checkpoint."""
37
+ c = ml_collections.ConfigDict()
38
+ c.data = ml_collections.ConfigDict(
39
+ dict(
40
+ dataset="CIFAR10",
41
+ image_size=IMAGE_SIZE,
42
+ num_channels=NUM_CHANNELS,
43
+ random_flip=False,
44
+ uniform_dequantization=False,
45
+ )
46
+ )
47
+ c.model = ml_collections.ConfigDict(
48
+ dict(
49
+ name="ncsnpp",
50
+ ema_rate=0.9999,
51
+ normalization="GroupNorm",
52
+ nonlinearity="swish",
53
+ nf=128,
54
+ ch_mult=(2, 2, 2),
55
+ num_res_blocks=4,
56
+ attn_resolutions=(16,),
57
+ resamp_with_conv=True,
58
+ conditional=True,
59
+ fir=True,
60
+ fir_kernel=[1, 3, 3, 1],
61
+ skip_rescale=True,
62
+ resblock_type="biggan",
63
+ progressive="none",
64
+ progressive_input="residual",
65
+ progressive_combine="sum",
66
+ attention_type="ddpm",
67
+ embedding_type="fourier",
68
+ init_scale=0.0,
69
+ fourier_scale=16,
70
+ conv_size=3,
71
+ rho=7.0,
72
+ data_std=DATA_STD,
73
+ num_scales=18,
74
+ dropout=0.0,
75
+ sigma_min=0.02,
76
+ sigma_max=100,
77
+ beta_min=0.1,
78
+ beta_max=20.0,
79
+ t_min=SIGMA_MIN,
80
+ t_max=SIGMA_MAX,
81
+ double_heads=False,
82
+ )
83
+ )
84
+ c.training = ml_collections.ConfigDict(dict(sde="kvesde"))
85
+ c.sampling = ml_collections.ConfigDict(dict(method="onestep", std=SIGMA_MAX))
86
+ return c
87
+
88
+
89
+ def _build_model_and_shapes(config: ml_collections.ConfigDict, seed: int):
90
+ import functools
91
+
92
+ model_def = functools.partial(mutils.get_model("ncsnpp"), config=config)
93
+ model = model_def()
94
+ rng = jax.random.PRNGKey(seed)
95
+ p_rng, d_rng = jax.random.split(rng)
96
+ fake_x = jnp.zeros((1, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))
97
+ fake_t = jnp.zeros((1,), dtype=jnp.float32)
98
+ variables = model.init({"params": p_rng, "dropout": d_rng}, fake_x, fake_t)
99
+ return model, variables["params"]
100
+
101
+
102
+ class CD:
103
+ """Consistency-Distillation / Consistency-Training generator.
104
+
105
+ Instantiate with `pretrained` naming a checkpoint kind and an explicit
106
+ `checkpoint_path` pointing at the slim pickle bundle
107
+ (`{"params", "meta"}`). Latents are flat vectors of shape `(batch, 3072)`
108
+ for consistency with the target's expected `n_dim`; the wrapper reshapes
109
+ internally. `decode(z)` returns 32x32x3 images in [0, 1].
110
+ """
111
+
112
+ z_dim: int = NOISE_DIM
113
+ image_size: int = IMAGE_SIZE
114
+ num_channels: int = NUM_CHANNELS
115
+
116
+ def __init__(
117
+ self,
118
+ pretrained: str = "ct-lpips",
119
+ checkpoint_path: str | Path | None = None,
120
+ seed: int = 0,
121
+ ) -> None:
122
+ if pretrained != "ct-lpips":
123
+ raise ValueError(
124
+ f"only 'ct-lpips' is wired up; got {pretrained!r}. "
125
+ "Add another config in `_default_config` to support others."
126
+ )
127
+ if checkpoint_path is None:
128
+ raise ValueError("checkpoint_path is required (path to the slim .pkl bundle)")
129
+
130
+ self.pretrained = pretrained
131
+ self.sigma_max = SIGMA_MAX
132
+ self.sigma_min = SIGMA_MIN
133
+ self.data_std = DATA_STD
134
+
135
+ self.config = _default_config()
136
+ self.model, init_params = _build_model_and_shapes(self.config, seed)
137
+
138
+ import pickle
139
+
140
+ from flax import serialization
141
+
142
+ with open(checkpoint_path, "rb") as f:
143
+ bundle = pickle.load(f)
144
+ self.params = serialization.from_state_dict(init_params, bundle["params"])
145
+
146
+ def _decode(z_flat: Array) -> Array:
147
+ batch = z_flat.shape[0]
148
+ # Reshape flat noise vector to image; scale by sigma_max (prior std).
149
+ x = z_flat.reshape(batch, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS) * SIGMA_MAX
150
+ img = _distill_one_step(self.model, self.params, x, SIGMA_MAX)
151
+ # Consistency models output pixels in ~[-1, 1]; map to [0, 1].
152
+ return jnp.clip((img + 1.0) * 0.5, 0.0, 1.0)
153
+
154
+ self._decode = jax.jit(_decode)
155
+
156
+ def decode(self, z: Array) -> Array:
157
+ return self._decode(z)
158
+
159
+ def sample_prior(self, key: Array, n: int) -> Array:
160
+ z = jax.random.normal(key, (n, self.z_dim))
161
+ return self.decode(z)
162
+
163
+
164
+ def _distill_one_step(model, params, x: Array, sigma: float) -> Array:
165
+ """Inline KVE-SDE consistency-model one-step distillation (Karras et al. 2022).
166
+
167
+ x: (B, H, W, C) noise-scaled inputs (i.e. x ~ N(0, sigma**2 * I) reshaped).
168
+ sigma: scalar noise level (== SIGMA_MAX for one-step from prior).
169
+ """
170
+ t = jnp.asarray(sigma, dtype=x.dtype)
171
+ pred_t = SIGMA_MIN
172
+ d2 = DATA_STD * DATA_STD
173
+ in_scale = 1.0 / jnp.sqrt(t * t + d2)
174
+ cond_t = 0.25 * jnp.log(t)
175
+ cond_batch = jnp.full((x.shape[0],), cond_t, dtype=x.dtype)
176
+ raw = model.apply({"params": params}, x * in_scale, cond_batch, train=False)
177
+ out_scale = (t - pred_t) * DATA_STD / jnp.sqrt(t * t + d2)
178
+ skip_scale = d2 / ((t - pred_t) ** 2 + d2)
179
+ return skip_scale * x + out_scale * raw
cifar10_cd_ct_lpips/load.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from cm import CD
2
+
3
+ model = CD(pretrained="ct-lpips", checkpoint_path="cifar10_cd_ct_lpips.pkl")