mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Hopefully fix embiggen for CPU users, change embiggen seeding behavior, tweak gradient corner
This commit is contained in:
parent
bb05a43787
commit
81bb44319a
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user