(shape, seeds, subseeds=None, subseed_strength=0.0, seed_resize_from_h=0, seed_resize_from_w=0, p=None)
| 218 | |
| 219 | |
| 220 | def create_random_tensors(shape, seeds, subseeds=None, subseed_strength=0.0, seed_resize_from_h=0, seed_resize_from_w=0, p=None): |
| 221 | eta_noise_seed_delta = (getattr(p, 'eta_noise_seed_delta', None) if p is not None else None) |
| 222 | if eta_noise_seed_delta is None: |
| 223 | eta_noise_seed_delta = shared.opts.eta_noise_seed_delta or 0 |
| 224 | enable_batch_seeds = (getattr(p, 'enable_batch_seeds', None) if p is not None else None) |
| 225 | if enable_batch_seeds is None: |
| 226 | enable_batch_seeds = shared.opts.enable_batch_seeds |
| 227 | xs = [] |
| 228 | # if we have multiple seeds, this means we are working with batch size>1; this then |
| 229 | # enables the generation of additional tensors with noise that the sampler will use during its processing. |
| 230 | # Using those pre-generated tensors instead of simple torch.randn allows a batch with seeds [100, 101] to |
| 231 | # produce the same images as with two batches [100], [101]. |
| 232 | if p is not None and p.sampler is not None and ((len(seeds) > 1 and enable_batch_seeds) or (eta_noise_seed_delta > 0)): |
| 233 | sampler_noises = [[] for _ in range(p.sampler.number_of_needed_noises(p))] |
| 234 | else: |
| 235 | sampler_noises = None |
| 236 | for i, seed in enumerate(seeds): |
| 237 | noise_shape = shape if seed_resize_from_h <= 0 or seed_resize_from_w <= 0 else (shape[0], seed_resize_from_h//8, seed_resize_from_w//8) |
| 238 | subnoise = None |
| 239 | if subseeds is not None: |
| 240 | subseed = 0 if i >= len(subseeds) else subseeds[i] |
| 241 | subnoise = devices.randn(subseed, noise_shape) |
| 242 | # randn results depend on device; gpu and cpu get different results for same seed; |
| 243 | # the way I see it, it's better to do this on CPU, so that everyone gets same result; |
| 244 | # but the original script had it like this, so I do not dare change it for now because |
| 245 | # it will break everyone's seeds. |
| 246 | noise = devices.randn(seed, noise_shape) |
| 247 | if subnoise is not None: |
| 248 | noise = slerp(subseed_strength, noise, subnoise) |
| 249 | if noise_shape != shape: |
| 250 | x = devices.randn(seed, shape) |
| 251 | dx = (shape[2] - noise_shape[2]) // 2 |
| 252 | dy = (shape[1] - noise_shape[1]) // 2 |
| 253 | w = noise_shape[2] if dx >= 0 else noise_shape[2] + 2 * dx |
| 254 | h = noise_shape[1] if dy >= 0 else noise_shape[1] + 2 * dy |
| 255 | tx = 0 if dx < 0 else dx |
| 256 | ty = 0 if dy < 0 else dy |
| 257 | dx = max(-dx, 0) |
| 258 | dy = max(-dy, 0) |
| 259 | x[:, ty:ty+h, tx:tx+w] = noise[:, dy:dy+h, dx:dx+w] |
| 260 | noise = x |
| 261 | if sampler_noises is not None: |
| 262 | cnt = p.sampler.number_of_needed_noises(p) |
| 263 | if eta_noise_seed_delta > 0: |
| 264 | torch.manual_seed(seed + eta_noise_seed_delta) |
| 265 | for j in range(cnt): |
| 266 | sampler_noises[j].append(devices.randn_without_seed(tuple(noise_shape))) |
| 267 | xs.append(noise) |
| 268 | if sampler_noises is not None: |
| 269 | p.sampler.sampler_noises = [torch.stack(n).to(shared.device) for n in sampler_noises] |
| 270 | x = torch.stack(xs).to(shared.device) |
| 271 | return x |
| 272 | |
| 273 | |
| 274 | def decode_first_stage(model, x): |
no test coverage detected