Skip to content

Commit

Permalink
Merge branch 'prixt-seamless' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
lstein committed Sep 3, 2022
2 parents 1eee811 + 6270e31 commit b90a215
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 4 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ You may also pass a -v<count> option to generate count variants on the original
passing the first generated image back into img2img the requested number of times. It generates interesting
variants.

## Seamless Tiling

The seamless tiling mode causes generated images to seamlessly tile with itself. To use it, add the --seamless option when starting the script which will result in all generated images to tile, or for each dream> prompt as shown here:
```
dream> "pond garden with lotus by claude monet" --seamless -s100 -n4
```

## GFPGAN and Real-ESRGAN Support

The script also provides the ability to do face restoration and
Expand Down Expand Up @@ -400,7 +407,11 @@ repository and associated paper for details and limitations.

# Latest Changes

- v1.13 (3 September 2022)
- v1.14 (In progress)

- Add "seamless mode" for circular tiling of image. Generates beautiful effects. ([prixt](https://github.com/prixt))

- v1.13 (3 September 2022

- Support image variations (see [VARIATIONS](VARIATIONS.md) ([Kevin Gibbons](https://github.com/bakkot) and many contributors and reviewers)
- Supports a Google Colab notebook for a standalone server running on Google hardware [Arturo Mendivil](https://github.com/artmen1516)
Expand Down
2 changes: 2 additions & 0 deletions ldm/dream/pngwriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def normalize_prompt(self):
switches.append(f'-H{opt.height or t2i.height}')
switches.append(f'-C{opt.cfg_scale or t2i.cfg_scale}')
switches.append(f'-A{opt.sampler_name or t2i.sampler_name}')
if opt.seamless or t2i.seamless:
switches.append(f'--seamless')
if opt.init_img:
switches.append(f'-I{opt.init_img}')
if opt.fit:
Expand Down
5 changes: 4 additions & 1 deletion ldm/dream/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ def do_POST(self):
steps = int(post_data['steps'])
width = int(post_data['width'])
height = int(post_data['height'])
fit = 'fit' in post_data
fit = 'fit' in post_data
seamless = 'seamless' in post_data
cfgscale = float(post_data['cfgscale'])
sampler_name = post_data['sampler']
gfpgan_strength = float(post_data['gfpgan_strength']) if gfpgan_model_exists else 0
Expand Down Expand Up @@ -164,6 +165,7 @@ def image_progress(sample, step):
gfpgan_strength = gfpgan_strength,
upscale = upscale,
sampler_name = sampler_name,
seamless = seamless,
step_callback=image_progress,
image_callback=image_done)
else:
Expand All @@ -185,6 +187,7 @@ def image_progress(sample, step):
width = width,
height = height,
fit = fit,
seamless = seamless,
gfpgan_strength=gfpgan_strength,
upscale = upscale,
step_callback=image_progress,
Expand Down
15 changes: 15 additions & 0 deletions ldm/simplet2i.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from tqdm import tqdm, trange
from itertools import islice
from einops import rearrange, repeat
from torch import nn
from torchvision.utils import make_grid
from pytorch_lightning import seed_everything
from torch import autocast
Expand Down Expand Up @@ -109,6 +110,7 @@ class T2I:
downsampling_factor
precision
strength
seamless
embedding_path
The vast majority of these arguments default to reasonable values.
Expand All @@ -132,6 +134,7 @@ def __init__(
precision='autocast',
full_precision=False,
strength=0.75, # default in scripts/img2img.py
seamless=False,
embedding_path=None,
device_type = 'cuda',
# just to keep track of this parameter when regenerating prompt
Expand All @@ -153,6 +156,7 @@ def __init__(
self.precision = precision
self.full_precision = True if choose_torch_device() == 'mps' else full_precision
self.strength = strength
self.seamless = seamless
self.embedding_path = embedding_path
self.device_type = device_type
self.model = None # empty for now
Expand Down Expand Up @@ -217,6 +221,7 @@ def prompt2image(
step_callback = None,
width = None,
height = None,
seamless = False,
# these are specific to img2img
init_img = None,
fit = False,
Expand All @@ -240,6 +245,7 @@ def prompt2image(
width // width of image, in multiples of 64 (512)
height // height of image, in multiples of 64 (512)
cfg_scale // how strongly the prompt influences the image (7.5) (must be >1)
seamless // whether the generated image should tile
init_img // path to an initial image - its dimensions override width and height
strength // strength for noising/unnoising init_img. 0.0 preserves image exactly, 1.0 replaces it completely
gfpgan_strength // strength for GFPGAN. 0.0 preserves image exactly, 1.0 replaces it completely
Expand Down Expand Up @@ -268,6 +274,7 @@ def process_image(image,seed):
steps = steps or self.steps
width = width or self.width
height = height or self.height
seamless = seamless or self.seamless
cfg_scale = cfg_scale or self.cfg_scale
ddim_eta = ddim_eta or self.ddim_eta
iterations = iterations or self.iterations
Expand All @@ -278,6 +285,10 @@ def process_image(image,seed):
model = (
self.load_model()
) # will instantiate the model or return it from cache
for m in model.modules():
if isinstance(m, (nn.Conv2d, nn.ConvTranspose2d)):
m.padding_mode = 'circular' if seamless else m._orig_padding_mode

assert cfg_scale > 1.0, 'CFG_Scale (-C) must be >1.0'
assert (
0.0 <= strength <= 1.0
Expand Down Expand Up @@ -603,6 +614,10 @@ def load_model(self):

self._set_sampler()

for m in self.model.modules():
if isinstance(m, (nn.Conv2d, nn.ConvTranspose2d)):
m._orig_padding_mode = m.padding_mode

return self.model

# returns a tensor filled with random numbers from a normal distribution
Expand Down
14 changes: 14 additions & 0 deletions scripts/dream.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def main():
grid = opt.grid,
# this is solely for recreating the prompt
latent_diffusion_weights=opt.laion400m,
seamless=opt.seamless,
embedding_path=opt.embedding_path,
device_type=opt.device
)
Expand All @@ -87,6 +88,9 @@ def main():
print(f'{e}. Aborting.')
sys.exit(-1)

if opt.seamless:
print(">> changed to seamless tiling mode")

# preload the model
tic = time.time()
t2i.load_model()
Expand Down Expand Up @@ -418,6 +422,11 @@ def create_argv_parser():
default='outputs/img-samples',
help='Directory to save generated images and a log of prompts and seeds. Default: outputs/img-samples',
)
parser.add_argument(
'--seamless',
action='store_true',
help='Change the model to seamless tiling (circular) mode',
)
parser.add_argument(
'--embedding_path',
type=str,
Expand Down Expand Up @@ -540,6 +549,11 @@ def create_cmd_parser():
default=None,
help='Directory to save generated images and a log of prompts and seeds',
)
parser.add_argument(
'--seamless',
action='store_true',
help='Change the model to seamless tiling (circular) mode',
)
parser.add_argument(
'-i',
'--individual',
Expand Down
6 changes: 4 additions & 2 deletions static/dream_web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ <h2 id="header">Stable Diffusion Dream Server</h2>
<option value="k_euler_a">KEULER_A</option>
<option value="k_heun">KHEUN</option>
</select>
<input type="checkbox" name="seamless" id="seamless">
<label for="seamless">Seamless circular tiling</label>
<br>
<label title="Set to multiple of 64" for="width">Width:</label>
<select id="width" name="width" value="512">
Expand Down Expand Up @@ -64,7 +66,7 @@ <h2 id="header">Stable Diffusion Dream Server</h2>
<input value="-1" type="number" id="seed" name="seed">
<button type="button" id="reset-seed">&olarr;</button>
<input type="checkbox" name="progress_images" id="progress_images">
<label for="progress_images">Display in-progress images (slows down generation):</label>
<label for="progress_images">Display in-progress images (slower)</label>
<button type="button" id="reset-all">Reset to Defaults</button>
</div>
<div id="img2img">
Expand All @@ -74,7 +76,7 @@ <h2 id="header">Stable Diffusion Dream Server</h2>
<label for="strength">Img2Img Strength:</label>
<input value="0.75" type="number" id="strength" name="strength" step="0.01" min="0" max="1">
<input type="checkbox" id="fit" name="fit" checked>
<label title="Rescale image to fit within requested width and height" for="fit">Fit to width/height:</label>
<label title="Rescale image to fit within requested width and height" for="fit">Fit to width/height</label>
</div>
<div id="gfpgan">
<label title="Strength of the gfpgan (face fixing) algorithm." for="gfpgan_strength">GPFGAN Strength (0 to disable):</label>
Expand Down

0 comments on commit b90a215

Please sign in to comment.