MCPcopy
hub / github.com/vladmandic/sdnext / create_random_tensors

Function create_random_tensors

modules/processing_helpers.py:220–271  ·  view source on GitHub ↗
(shape, seeds, subseeds=None, subseed_strength=0.0, seed_resize_from_h=0, seed_resize_from_w=0, p=None)

Source from the content-addressed store, hash-verified

218
219
220def 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
274def decode_first_stage(model, x):

Callers 2

create_latentsFunction · 0.90
process_batchMethod · 0.90

Calls 2

slerpFunction · 0.85
toMethod · 0.45

Tested by

no test coverage detected