Hopefully fix embiggen for CPU users, change embiggen seeding behavior, tweak gradient corner

This commit is contained in:
Travis Palmer 2022-09-13 17:24:04 -04:00
parent bb05a43787
commit 81bb44319a

View File

@ -5,9 +5,10 @@ and generates with ldm.dream.generator.img2img
import torch import torch
import numpy as np import numpy as np
from PIL import Image from tqdm import trange
from PIL import Image
from ldm.dream.devices import choose_autocast_device
from ldm.dream.generator.base import Generator from ldm.dream.generator.base import Generator
from ldm.models.diffusion.ddim import DDIMSampler
from ldm.dream.generator.img2img import Img2Img from ldm.dream.generator.img2img import Img2Img
class Embiggen(Generator): class Embiggen(Generator):
@ -15,6 +16,29 @@ class Embiggen(Generator):
super().__init__(model) super().__init__(model)
self.init_latent = None self.init_latent = None
# Replace generate because Embiggen doesn't need/use most of what it does normallly
def generate(self,prompt,iterations=1,seed=None,
image_callback=None, step_callback=None,
**kwargs):
device_type,scope = choose_autocast_device(self.model.device)
make_image = self.get_make_image(
prompt,
step_callback = step_callback,
**kwargs
)
results = []
seed = seed if seed else self.new_seed()
# Noise will be generated by the Img2Img generator when called
with scope(device_type), self.model.ema_scope():
for n in trange(iterations, desc='Generating'):
# make_image will call Img2Img which will do the equivalent of get_noise itself
image = make_image()
results.append([image, seed])
if image_callback is not None:
image_callback(image, seed)
seed = self.new_seed()
return results
@torch.no_grad() @torch.no_grad()
def get_make_image( def get_make_image(
self, self,
@ -143,7 +167,7 @@ class Embiggen(Generator):
if distanceToLR > 255: if distanceToLR > 255:
distanceToLR = 255 distanceToLR = 255
#Place the pixel as invert of distance #Place the pixel as invert of distance
agradientC.putpixel((x, y), int(255 - distanceToLR)) agradientC.putpixel((x, y), round(255 - distanceToLR))
# Create alpha layers default fully white # Create alpha layers default fully white
alphaLayerL = Image.new("L", (width, height), 255) alphaLayerL = Image.new("L", (width, height), 255)
@ -213,7 +237,7 @@ class Embiggen(Generator):
del agradientT del agradientT
del agradientC del agradientC
def make_image(x_T): def make_image():
# Make main tiles ------------------------------------------------- # Make main tiles -------------------------------------------------
if embiggen_tiles: if embiggen_tiles:
print(f'>> Making {len(embiggen_tiles)} Embiggen tiles...') print(f'>> Making {len(embiggen_tiles)} Embiggen tiles...')
@ -221,7 +245,20 @@ class Embiggen(Generator):
print(f'>> Making {(emb_tiles_x * emb_tiles_y)} Embiggen tiles ({emb_tiles_x}x{emb_tiles_y})...') print(f'>> Making {(emb_tiles_x * emb_tiles_y)} Embiggen tiles ({emb_tiles_x}x{emb_tiles_y})...')
emb_tile_store = [] emb_tile_store = []
# Although we could use the same seed for every tile for determinism, at higher strengths this may
# produce duplicated structures for each tile and make the tiling effect more obvious
# instead track and iterate a local seed we pass to Img2Img
seed = self.seed
seedintlimit = np.iinfo(np.uint32).max - 1 # only retreive this one from numpy
for tile in range(emb_tiles_x * emb_tiles_y): for tile in range(emb_tiles_x * emb_tiles_y):
# Don't iterate on first tile
if tile != 0:
if seed < seedintlimit:
seed += 1
else:
seed = 0
# Determine if this is a re-run and replace # Determine if this is a re-run and replace
if embiggen_tiles and not tile in embiggen_tiles: if embiggen_tiles and not tile in embiggen_tiles:
continue continue
@ -262,7 +299,7 @@ class Embiggen(Generator):
tile_results = gen_img2img.generate( tile_results = gen_img2img.generate(
prompt, prompt,
iterations = 1, iterations = 1,
seed = self.seed, seed = seed,
sampler = sampler, sampler = sampler,
steps = steps, steps = steps,
cfg_scale = cfg_scale, cfg_scale = cfg_scale,
@ -272,7 +309,6 @@ class Embiggen(Generator):
step_callback = step_callback, # called after each intermediate image is generated step_callback = step_callback, # called after each intermediate image is generated
width = width, width = width,
height = height, height = height,
init_img = init_img, # img2img doesn't need this, but it might in the future
init_image = newinitimage, # notice that init_image is different from init_img init_image = newinitimage, # notice that init_image is different from init_img
mask_image = None, mask_image = None,
strength = strength, strength = strength,