InvokeAI 2.2.4.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. backend/__init__.py +0 -0
  2. backend/invoke_ai_web_server.py +1724 -0
  3. backend/modules/__init__.py +0 -0
  4. backend/modules/create_cmd_parser.py +55 -0
  5. backend/modules/get_canvas_generation_mode.py +117 -0
  6. backend/modules/parameters.py +71 -0
  7. backend/modules/parse_seed_weights.py +47 -0
  8. configs/INITIAL_MODELS.yaml +80 -0
  9. configs/models.yaml.example +29 -0
  10. configs/sd-concepts.txt +803 -0
  11. configs/stable-diffusion/v1-finetune.yaml +110 -0
  12. configs/stable-diffusion/v1-finetune_style.yaml +103 -0
  13. configs/stable-diffusion/v1-inference.yaml +79 -0
  14. configs/stable-diffusion/v1-inpainting-inference.yaml +79 -0
  15. configs/stable-diffusion/v1-m1-finetune.yaml +110 -0
  16. docs/assets/invoke-web-server-1.png +0 -0
  17. docs/assets/invoke_ai_banner.png +0 -0
  18. invokeai-2.2.4.5.data/data/assets/caution.png +0 -0
  19. invokeai-2.2.4.5.data/data/configs/INITIAL_MODELS.yaml +80 -0
  20. invokeai-2.2.4.5.data/data/configs/models.yaml.example +29 -0
  21. invokeai-2.2.4.5.data/data/configs/sd-concepts.txt +803 -0
  22. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-finetune.yaml +110 -0
  23. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-finetune_style.yaml +103 -0
  24. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-inference.yaml +79 -0
  25. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-inpainting-inference.yaml +79 -0
  26. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-m1-finetune.yaml +110 -0
  27. invokeai-2.2.4.5.data/data/frontend/dist/assets/Inter-Bold.790c108b.ttf +0 -0
  28. invokeai-2.2.4.5.data/data/frontend/dist/assets/Inter.b9a8e5e2.ttf +0 -0
  29. invokeai-2.2.4.5.data/data/frontend/dist/assets/favicon.0d253ced.ico +0 -0
  30. invokeai-2.2.4.5.data/data/frontend/dist/assets/index-legacy-b741077f.js +48 -0
  31. invokeai-2.2.4.5.data/data/frontend/dist/assets/index.0dadf5d0.css +1 -0
  32. invokeai-2.2.4.5.data/data/frontend/dist/assets/index.21ff81eb.js +625 -0
  33. invokeai-2.2.4.5.data/data/frontend/dist/assets/logo.13003d72.png +0 -0
  34. invokeai-2.2.4.5.data/data/frontend/dist/assets/polyfills-legacy-dde3a68a.js +4 -0
  35. invokeai-2.2.4.5.data/data/frontend/dist/assets/polyfills.1ff60148.js +1 -0
  36. invokeai-2.2.4.5.data/data/frontend/dist/index.html +23 -0
  37. invokeai-2.2.4.5.data/data/scripts/configure_invokeai.py +797 -0
  38. invokeai-2.2.4.5.data/data/scripts/create_root.py +43 -0
  39. invokeai-2.2.4.5.data/data/scripts/dream.py +10 -0
  40. invokeai-2.2.4.5.data/data/scripts/images2prompt.py +30 -0
  41. invokeai-2.2.4.5.data/data/scripts/invoke.py +5 -0
  42. invokeai-2.2.4.5.data/data/scripts/legacy_api.py +681 -0
  43. invokeai-2.2.4.5.data/data/scripts/load_models.py +12 -0
  44. invokeai-2.2.4.5.data/data/scripts/merge_embeddings.py +124 -0
  45. invokeai-2.2.4.5.data/data/scripts/preload_models.py +12 -0
  46. invokeai-2.2.4.5.data/data/scripts/sd-metadata.py +22 -0
  47. invokeai-2.2.4.5.dist-info/LICENSE +21 -0
  48. invokeai-2.2.4.5.dist-info/LICENSE-ModelWeights.txt +294 -0
  49. invokeai-2.2.4.5.dist-info/METADATA +288 -0
  50. invokeai-2.2.4.5.dist-info/RECORD +169 -0
  51. invokeai-2.2.4.5.dist-info/WHEEL +5 -0
  52. invokeai-2.2.4.5.dist-info/entry_points.txt +4 -0
  53. invokeai-2.2.4.5.dist-info/top_level.txt +6 -0
  54. invokeai-2.2.4.5.dist-info/zip-safe +1 -0
  55. ldm/__init__.py +0 -0
  56. ldm/data/__init__.py +0 -0
  57. ldm/data/base.py +31 -0
  58. ldm/data/imagenet.py +466 -0
  59. ldm/data/lsun.py +126 -0
  60. ldm/data/personalized.py +202 -0
  61. ldm/data/personalized_style.py +169 -0
  62. ldm/generate.py +1159 -0
  63. ldm/invoke/CLI.py +960 -0
  64. ldm/invoke/__init__.py +3 -0
  65. ldm/invoke/args.py +1257 -0
  66. ldm/invoke/concepts_lib.py +169 -0
  67. ldm/invoke/conditioning.py +289 -0
  68. ldm/invoke/devices.py +27 -0
  69. ldm/invoke/generator/__init__.py +4 -0
  70. ldm/invoke/generator/base.py +335 -0
  71. ldm/invoke/generator/embiggen.py +501 -0
  72. ldm/invoke/generator/img2img.py +97 -0
  73. ldm/invoke/generator/inpaint.py +358 -0
  74. ldm/invoke/generator/omnibus.py +175 -0
  75. ldm/invoke/generator/txt2img.py +88 -0
  76. ldm/invoke/generator/txt2img2img.py +182 -0
  77. ldm/invoke/globals.py +31 -0
  78. ldm/invoke/image_util.py +70 -0
  79. ldm/invoke/log.py +66 -0
  80. ldm/invoke/model_cache.py +449 -0
  81. ldm/invoke/patchmatch.py +44 -0
  82. ldm/invoke/pngwriter.py +113 -0
  83. ldm/invoke/prompt_parser.py +655 -0
  84. ldm/invoke/readline.py +442 -0
  85. ldm/invoke/restoration/__init__.py +4 -0
  86. ldm/invoke/restoration/base.py +38 -0
  87. ldm/invoke/restoration/codeformer.py +103 -0
  88. ldm/invoke/restoration/codeformer_arch.py +276 -0
  89. ldm/invoke/restoration/gfpgan.py +84 -0
  90. ldm/invoke/restoration/outcrop.py +108 -0
  91. ldm/invoke/restoration/outpaint.py +92 -0
  92. ldm/invoke/restoration/realesrgan.py +90 -0
  93. ldm/invoke/restoration/vqgan_arch.py +435 -0
  94. ldm/invoke/seamless.py +30 -0
  95. ldm/invoke/server.py +282 -0
  96. ldm/invoke/server_legacy.py +246 -0
  97. ldm/invoke/txt2mask.py +136 -0
  98. ldm/lr_scheduler.py +143 -0
  99. ldm/models/__init__.py +0 -0
  100. ldm/models/autoencoder.py +596 -0
  101. ldm/models/diffusion/__init__.py +0 -0
  102. ldm/models/diffusion/classifier.py +355 -0
  103. ldm/models/diffusion/cross_attention_control.py +443 -0
  104. ldm/models/diffusion/cross_attention_map_saving.py +95 -0
  105. ldm/models/diffusion/ddim.py +111 -0
  106. ldm/models/diffusion/ddpm.py +2263 -0
  107. ldm/models/diffusion/ksampler.py +312 -0
  108. ldm/models/diffusion/plms.py +146 -0
  109. ldm/models/diffusion/sampler.py +450 -0
  110. ldm/models/diffusion/shared_invokeai_diffusion.py +244 -0
  111. ldm/modules/__init__.py +0 -0
  112. ldm/modules/attention.py +274 -0
  113. ldm/modules/diffusionmodules/__init__.py +0 -0
  114. ldm/modules/diffusionmodules/model.py +894 -0
  115. ldm/modules/diffusionmodules/openaimodel.py +1036 -0
  116. ldm/modules/diffusionmodules/util.py +314 -0
  117. ldm/modules/distributions/__init__.py +0 -0
  118. ldm/modules/distributions/distributions.py +104 -0
  119. ldm/modules/ema.py +88 -0
  120. ldm/modules/embedding_manager.py +413 -0
  121. ldm/modules/encoders/__init__.py +0 -0
  122. ldm/modules/encoders/modules.py +772 -0
  123. ldm/modules/image_degradation/__init__.py +6 -0
  124. ldm/modules/image_degradation/bsrgan.py +846 -0
  125. ldm/modules/image_degradation/bsrgan_light.py +751 -0
  126. ldm/modules/image_degradation/utils_image.py +1024 -0
  127. ldm/modules/losses/__init__.py +1 -0
  128. ldm/modules/losses/contperceptual.py +175 -0
  129. ldm/modules/losses/vqperceptual.py +240 -0
  130. ldm/modules/x_transformer.py +752 -0
  131. ldm/simplet2i.py +13 -0
  132. ldm/util.py +264 -0
  133. scripts/configure_invokeai.py +797 -0
  134. scripts/create_root.py +43 -0
  135. scripts/dream.py +10 -0
  136. scripts/images2prompt.py +30 -0
  137. scripts/invoke.py +5 -0
  138. scripts/legacy_api.py +681 -0
  139. scripts/load_models.py +12 -0
  140. scripts/merge_embeddings.py +124 -0
  141. scripts/orig_scripts/img2img.py +296 -0
  142. scripts/orig_scripts/inpaint.py +98 -0
  143. scripts/orig_scripts/knn2img.py +397 -0
  144. scripts/orig_scripts/sample_diffusion.py +313 -0
  145. scripts/orig_scripts/train_searcher.py +147 -0
  146. scripts/orig_scripts/txt2img.py +324 -0
  147. scripts/preload_models.py +12 -0
  148. scripts/sd-metadata.py +22 -0
  149. vendored/clip/clip/__init__.py +1 -0
  150. vendored/clip/clip/bpe_simple_vocab_16e6.txt.gz +0 -0
  151. vendored/clip/clip/clip.py +237 -0
  152. vendored/clip/clip/model.py +436 -0
  153. vendored/clip/clip/simple_tokenizer.py +132 -0
  154. vendored/clip/hubconf.py +42 -0
  155. vendored/clip/setup.py +21 -0
  156. vendored/clip/tests/test_consistency.py +25 -0
  157. vendored/clipseg/datasets/coco_wrapper.py +99 -0
  158. vendored/clipseg/datasets/pascal_zeroshot.py +60 -0
  159. vendored/clipseg/datasets/pfe_dataset.py +129 -0
  160. vendored/clipseg/datasets/phrasecut.py +380 -0
  161. vendored/clipseg/datasets/utils.py +68 -0
  162. vendored/clipseg/evaluation_utils.py +292 -0
  163. vendored/clipseg/general_utils.py +272 -0
  164. vendored/clipseg/metrics.py +271 -0
  165. vendored/clipseg/models/clipseg.py +538 -0
  166. vendored/clipseg/models/vitseg.py +286 -0
  167. vendored/clipseg/score.py +453 -0
  168. vendored/clipseg/setup.py +30 -0
  169. vendored/clipseg/training.py +266 -0
@@ -0,0 +1,681 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2022 Lincoln D. Stein (https://github.com/lstein)
3
+
4
+ import argparse
5
+ import shlex
6
+ import os
7
+ import re
8
+ import sys
9
+ import copy
10
+ import warnings
11
+ import time
12
+ import ldm.invoke.readline
13
+ from ldm.invoke.pngwriter import PngWriter, PromptFormatter
14
+ from ldm.invoke.server_legacy import DreamServer, ThreadingDreamServer
15
+ from ldm.invoke.image_util import make_grid
16
+ from omegaconf import OmegaConf
17
+
18
+ # Placeholder to be replaced with proper class that tracks the
19
+ # outputs and associates with the prompt that generated them.
20
+ # Just want to get the formatting look right for now.
21
+ output_cntr = 0
22
+
23
+
24
+ def main():
25
+ """Initialize command-line parsers and the diffusion model"""
26
+ arg_parser = create_argv_parser()
27
+ opt = arg_parser.parse_args()
28
+
29
+ if opt.laion400m:
30
+ print('--laion400m flag has been deprecated. Please use --model laion400m instead.')
31
+ sys.exit(-1)
32
+ if opt.weights != 'model':
33
+ print('--weights argument has been deprecated. Please configure ./configs/models.yaml, and call it using --model instead.')
34
+ sys.exit(-1)
35
+
36
+ try:
37
+ models = OmegaConf.load(opt.config)
38
+ width = models[opt.model].width
39
+ height = models[opt.model].height
40
+ config = models[opt.model].config
41
+ weights = models[opt.model].weights
42
+ except (FileNotFoundError, IOError, KeyError) as e:
43
+ print(f'{e}. Aborting.')
44
+ sys.exit(-1)
45
+
46
+ print('* Initializing, be patient...\n')
47
+ sys.path.append('.')
48
+ from pytorch_lightning import logging
49
+ from ldm.generate import Generate
50
+
51
+ # these two lines prevent a horrible warning message from appearing
52
+ # when the frozen CLIP tokenizer is imported
53
+ import transformers
54
+
55
+ transformers.logging.set_verbosity_error()
56
+
57
+ # creating a simple text2image object with a handful of
58
+ # defaults passed on the command line.
59
+ # additional parameters will be added (or overriden) during
60
+ # the user input loop
61
+ t2i = Generate(
62
+ # width=width,
63
+ # height=height,
64
+ sampler_name=opt.sampler_name,
65
+ weights=weights,
66
+ full_precision=opt.full_precision,
67
+ config=config,
68
+ # grid=opt.grid,
69
+ # this is solely for recreating the prompt
70
+ # seamless=opt.seamless,
71
+ embedding_path=opt.embedding_path,
72
+ # device_type=opt.device,
73
+ # ignore_ctrl_c=opt.infile is None,
74
+ )
75
+
76
+ # make sure the output directory exists
77
+ if not os.path.exists(opt.outdir):
78
+ os.makedirs(opt.outdir)
79
+
80
+ # gets rid of annoying messages about random seed
81
+ logging.getLogger('pytorch_lightning').setLevel(logging.ERROR)
82
+
83
+ # load the infile as a list of lines
84
+ infile = None
85
+ if opt.infile:
86
+ try:
87
+ if os.path.isfile(opt.infile):
88
+ infile = open(opt.infile, 'r', encoding='utf-8')
89
+ elif opt.infile == '-': # stdin
90
+ infile = sys.stdin
91
+ else:
92
+ raise FileNotFoundError(f'{opt.infile} not found.')
93
+ except (FileNotFoundError, IOError) as e:
94
+ print(f'{e}. Aborting.')
95
+ sys.exit(-1)
96
+
97
+ if opt.seamless:
98
+ print(">> changed to seamless tiling mode")
99
+
100
+ # preload the model
101
+ t2i.load_model()
102
+
103
+ if not infile:
104
+ print(
105
+ "\n* Initialization done! Awaiting your command (-h for help, 'q' to quit)"
106
+ )
107
+
108
+ cmd_parser = create_cmd_parser()
109
+ if opt.web:
110
+ dream_server_loop(t2i, opt.host, opt.port, opt.outdir)
111
+ else:
112
+ main_loop(t2i, opt.outdir, opt.prompt_as_dir, cmd_parser, infile)
113
+
114
+
115
+ def main_loop(t2i, outdir, prompt_as_dir, parser, infile):
116
+ """prompt/read/execute loop"""
117
+ done = False
118
+ path_filter = re.compile(r'[<>:"/\\|?*]')
119
+ last_results = list()
120
+
121
+ # os.pathconf is not available on Windows
122
+ if hasattr(os, 'pathconf'):
123
+ path_max = os.pathconf(outdir, 'PC_PATH_MAX')
124
+ name_max = os.pathconf(outdir, 'PC_NAME_MAX')
125
+ else:
126
+ path_max = 260
127
+ name_max = 255
128
+
129
+ while not done:
130
+ try:
131
+ command = get_next_command(infile)
132
+ except EOFError:
133
+ done = True
134
+ continue
135
+ except KeyboardInterrupt:
136
+ done = True
137
+ continue
138
+
139
+ # skip empty lines
140
+ if not command.strip():
141
+ continue
142
+
143
+ if command.startswith(('#', '//')):
144
+ continue
145
+
146
+ # before splitting, escape single quotes so as not to mess
147
+ # up the parser
148
+ command = command.replace("'", "\\'")
149
+
150
+ try:
151
+ elements = shlex.split(command)
152
+ except ValueError as e:
153
+ print(str(e))
154
+ continue
155
+
156
+ if elements[0] == 'q':
157
+ done = True
158
+ break
159
+
160
+ if elements[0].startswith(
161
+ '!dream'
162
+ ): # in case a stored prompt still contains the !dream command
163
+ elements.pop(0)
164
+
165
+ # rearrange the arguments to mimic how it works in the Dream bot.
166
+ switches = ['']
167
+ switches_started = False
168
+
169
+ for el in elements:
170
+ if el[0] == '-' and not switches_started:
171
+ switches_started = True
172
+ if switches_started:
173
+ switches.append(el)
174
+ else:
175
+ switches[0] += el
176
+ switches[0] += ' '
177
+ switches[0] = switches[0][: len(switches[0]) - 1]
178
+
179
+ try:
180
+ opt = parser.parse_args(switches)
181
+ except SystemExit:
182
+ parser.print_help()
183
+ continue
184
+ if len(opt.prompt) == 0:
185
+ print('Try again with a prompt!')
186
+ continue
187
+ # retrieve previous value!
188
+ if opt.init_img is not None and re.match('^-\\d+$', opt.init_img):
189
+ try:
190
+ opt.init_img = last_results[int(opt.init_img)][0]
191
+ print(f'>> Reusing previous image {opt.init_img}')
192
+ except IndexError:
193
+ print(
194
+ f'>> No previous initial image at position {opt.init_img} found')
195
+ opt.init_img = None
196
+ continue
197
+
198
+ if opt.seed is not None and opt.seed < 0: # retrieve previous value!
199
+ try:
200
+ opt.seed = last_results[opt.seed][1]
201
+ print(f'>> Reusing previous seed {opt.seed}')
202
+ except IndexError:
203
+ print(f'>> No previous seed at position {opt.seed} found')
204
+ opt.seed = None
205
+ continue
206
+
207
+ do_grid = opt.grid or t2i.grid
208
+
209
+ if opt.with_variations is not None:
210
+ # shotgun parsing, woo
211
+ parts = []
212
+ broken = False # python doesn't have labeled loops...
213
+ for part in opt.with_variations.split(','):
214
+ seed_and_weight = part.split(':')
215
+ if len(seed_and_weight) != 2:
216
+ print(f'could not parse with_variation part "{part}"')
217
+ broken = True
218
+ break
219
+ try:
220
+ seed = int(seed_and_weight[0])
221
+ weight = float(seed_and_weight[1])
222
+ except ValueError:
223
+ print(f'could not parse with_variation part "{part}"')
224
+ broken = True
225
+ break
226
+ parts.append([seed, weight])
227
+ if broken:
228
+ continue
229
+ if len(parts) > 0:
230
+ opt.with_variations = parts
231
+ else:
232
+ opt.with_variations = None
233
+
234
+ if opt.outdir:
235
+ if not os.path.exists(opt.outdir):
236
+ os.makedirs(opt.outdir)
237
+ current_outdir = opt.outdir
238
+ elif prompt_as_dir:
239
+ # sanitize the prompt to a valid folder name
240
+ subdir = path_filter.sub('_', opt.prompt)[:name_max].rstrip(' .')
241
+
242
+ # truncate path to maximum allowed length
243
+ # 27 is the length of '######.##########.##.png', plus two separators and a NUL
244
+ subdir = subdir[:(path_max - 27 - len(os.path.abspath(outdir)))]
245
+ current_outdir = os.path.join(outdir, subdir)
246
+
247
+ print('Writing files to directory: "' + current_outdir + '"')
248
+
249
+ # make sure the output directory exists
250
+ if not os.path.exists(current_outdir):
251
+ os.makedirs(current_outdir)
252
+ else:
253
+ current_outdir = outdir
254
+
255
+ # Here is where the images are actually generated!
256
+ last_results = []
257
+ try:
258
+ file_writer = PngWriter(current_outdir)
259
+ prefix = file_writer.unique_prefix()
260
+ results = [] # list of filename, prompt pairs
261
+ grid_images = dict() # seed -> Image, only used if `do_grid`
262
+
263
+ def image_writer(image, seed, upscaled=False):
264
+ path = None
265
+ if do_grid:
266
+ grid_images[seed] = image
267
+ else:
268
+ if upscaled and opt.save_original:
269
+ filename = f'{prefix}.{seed}.postprocessed.png'
270
+ else:
271
+ filename = f'{prefix}.{seed}.png'
272
+ if opt.variation_amount > 0:
273
+ iter_opt = argparse.Namespace(**vars(opt)) # copy
274
+ this_variation = [[seed, opt.variation_amount]]
275
+ if opt.with_variations is None:
276
+ iter_opt.with_variations = this_variation
277
+ else:
278
+ iter_opt.with_variations = opt.with_variations + this_variation
279
+ iter_opt.variation_amount = 0
280
+ normalized_prompt = PromptFormatter(
281
+ t2i, iter_opt).normalize_prompt()
282
+ metadata_prompt = f'{normalized_prompt} -S{iter_opt.seed}'
283
+ elif opt.with_variations is not None:
284
+ normalized_prompt = PromptFormatter(
285
+ t2i, opt).normalize_prompt()
286
+ # use the original seed - the per-iteration value is the last variation-seed
287
+ metadata_prompt = f'{normalized_prompt} -S{opt.seed}'
288
+ else:
289
+ normalized_prompt = PromptFormatter(
290
+ t2i, opt).normalize_prompt()
291
+ metadata_prompt = f'{normalized_prompt} -S{seed}'
292
+ path = file_writer.save_image_and_prompt_to_png(
293
+ image, metadata_prompt, filename)
294
+ if (not upscaled) or opt.save_original:
295
+ # only append to results if we didn't overwrite an earlier output
296
+ results.append([path, metadata_prompt])
297
+ last_results.append([path, seed])
298
+
299
+ t2i.prompt2image(image_callback=image_writer, **vars(opt))
300
+
301
+ if do_grid and len(grid_images) > 0:
302
+ grid_img = make_grid(list(grid_images.values()))
303
+ grid_seeds = list(grid_images.keys())
304
+ first_seed = last_results[0][1]
305
+ filename = f'{prefix}.{first_seed}.png'
306
+ # TODO better metadata for grid images
307
+ normalized_prompt = PromptFormatter(
308
+ t2i, opt).normalize_prompt()
309
+ metadata_prompt = f'{normalized_prompt} -S{first_seed} --grid -n{len(grid_images)} # {grid_seeds}'
310
+ path = file_writer.save_image_and_prompt_to_png(
311
+ grid_img, metadata_prompt, filename
312
+ )
313
+ results = [[path, metadata_prompt]]
314
+
315
+ except AssertionError as e:
316
+ print(e)
317
+ continue
318
+
319
+ except OSError as e:
320
+ print(e)
321
+ continue
322
+
323
+ print('Outputs:')
324
+ log_path = os.path.join(current_outdir, 'dream_log.txt')
325
+ write_log_message(results, log_path)
326
+ print()
327
+
328
+ print('goodbye!')
329
+
330
+
331
+ def get_next_command(infile=None) -> str: # command string
332
+ if infile is None:
333
+ command = input('dream> ')
334
+ else:
335
+ command = infile.readline()
336
+ if not command:
337
+ raise EOFError
338
+ else:
339
+ command = command.strip()
340
+ print(f'#{command}')
341
+ return command
342
+
343
+
344
+ def dream_server_loop(t2i, host, port, outdir):
345
+ print('\n* --web was specified, starting web server...')
346
+ # Change working directory to the stable-diffusion directory
347
+ os.chdir(
348
+ os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
349
+ )
350
+
351
+ # Start server
352
+ DreamServer.model = t2i
353
+ DreamServer.outdir = outdir
354
+ dream_server = ThreadingDreamServer((host, port))
355
+ print(">> Started Stable Diffusion dream server!")
356
+ if host == '0.0.0.0':
357
+ print(
358
+ f"Point your browser at http://localhost:{port} or use the host's DNS name or IP address.")
359
+ else:
360
+ print(">> Default host address now 127.0.0.1 (localhost). Use --host 0.0.0.0 to bind any address.")
361
+ print(f">> Point your browser at http://{host}:{port}.")
362
+
363
+ try:
364
+ dream_server.serve_forever()
365
+ except KeyboardInterrupt:
366
+ pass
367
+
368
+ dream_server.server_close()
369
+
370
+
371
+ def write_log_message(results, log_path):
372
+ """logs the name of the output image, prompt, and prompt args to the terminal and log file"""
373
+ global output_cntr
374
+ log_lines = [f'{path}: {prompt}\n' for path, prompt in results]
375
+ for l in log_lines:
376
+ output_cntr += 1
377
+ print(f'[{output_cntr}] {l}',end='')
378
+
379
+
380
+ with open(log_path, 'a', encoding='utf-8') as file:
381
+ file.writelines(log_lines)
382
+
383
+
384
+ SAMPLER_CHOICES = [
385
+ 'ddim',
386
+ 'k_dpm_2_a',
387
+ 'k_dpm_2',
388
+ 'k_dpmpp_2_a',
389
+ 'k_dpmpp_2',
390
+ 'k_euler_a',
391
+ 'k_euler',
392
+ 'k_heun',
393
+ 'k_lms',
394
+ 'plms',
395
+ ]
396
+
397
+
398
+ def create_argv_parser():
399
+ parser = argparse.ArgumentParser(
400
+ description="""Generate images using Stable Diffusion.
401
+ Use --web to launch the web interface.
402
+ Use --from_file to load prompts from a file path or standard input ("-").
403
+ Otherwise you will be dropped into an interactive command prompt (type -h for help.)
404
+ Other command-line arguments are defaults that can usually be overridden
405
+ prompt the command prompt.
406
+ """
407
+ )
408
+ parser.add_argument(
409
+ '--laion400m',
410
+ '--latent_diffusion',
411
+ '-l',
412
+ dest='laion400m',
413
+ action='store_true',
414
+ help='Fallback to the latent diffusion (laion400m) weights and config',
415
+ )
416
+ parser.add_argument(
417
+ '--from_file',
418
+ dest='infile',
419
+ type=str,
420
+ help='If specified, load prompts from this file',
421
+ )
422
+ parser.add_argument(
423
+ '-n',
424
+ '--iterations',
425
+ type=int,
426
+ default=1,
427
+ help='Number of images to generate',
428
+ )
429
+ parser.add_argument(
430
+ '-F',
431
+ '--full_precision',
432
+ dest='full_precision',
433
+ action='store_true',
434
+ help='Use more memory-intensive full precision math for calculations',
435
+ )
436
+ parser.add_argument(
437
+ '-g',
438
+ '--grid',
439
+ action='store_true',
440
+ help='Generate a grid instead of individual images',
441
+ )
442
+ parser.add_argument(
443
+ '-A',
444
+ '-m',
445
+ '--sampler',
446
+ dest='sampler_name',
447
+ choices=SAMPLER_CHOICES,
448
+ metavar='SAMPLER_NAME',
449
+ default='k_lms',
450
+ help=f'Set the initial sampler. Default: k_lms. Supported samplers: {", ".join(SAMPLER_CHOICES)}',
451
+ )
452
+ parser.add_argument(
453
+ '--outdir',
454
+ '-o',
455
+ type=str,
456
+ default='outputs/img-samples',
457
+ help='Directory to save generated images and a log of prompts and seeds. Default: outputs/img-samples',
458
+ )
459
+ parser.add_argument(
460
+ '--seamless',
461
+ action='store_true',
462
+ help='Change the model to seamless tiling (circular) mode',
463
+ )
464
+ parser.add_argument(
465
+ '--embedding_path',
466
+ type=str,
467
+ help='Path to a pre-trained embedding manager checkpoint - can only be set on command line',
468
+ )
469
+ parser.add_argument(
470
+ '--prompt_as_dir',
471
+ '-p',
472
+ action='store_true',
473
+ help='Place images in subdirectories named after the prompt.',
474
+ )
475
+ # GFPGAN related args
476
+ parser.add_argument(
477
+ '--gfpgan_bg_upsampler',
478
+ type=str,
479
+ default='realesrgan',
480
+ help='Background upsampler. Default: realesrgan. Options: realesrgan, none.',
481
+
482
+ )
483
+ parser.add_argument(
484
+ '--gfpgan_bg_tile',
485
+ type=int,
486
+ default=400,
487
+ help='Tile size for background sampler, 0 for no tile during testing. Default: 400.',
488
+ )
489
+ parser.add_argument(
490
+ '--gfpgan_model_path',
491
+ type=str,
492
+ default='./models/gfpgan/GFPGANv1.4.pth',
493
+ help='Indicates the path to the GFPGAN model.',
494
+ )
495
+ parser.add_argument(
496
+ '--web',
497
+ dest='web',
498
+ action='store_true',
499
+ help='Start in web server mode.',
500
+ )
501
+ parser.add_argument(
502
+ '--host',
503
+ type=str,
504
+ default='127.0.0.1',
505
+ help='Web server: Host or IP to listen on. Set to 0.0.0.0 to accept traffic from other devices on your network.'
506
+ )
507
+ parser.add_argument(
508
+ '--port',
509
+ type=int,
510
+ default='9090',
511
+ help='Web server: Port to listen on'
512
+ )
513
+ parser.add_argument(
514
+ '--weights',
515
+ default='model',
516
+ help='Indicates the Stable Diffusion model to use.',
517
+ )
518
+ parser.add_argument(
519
+ '--device',
520
+ '-d',
521
+ type=str,
522
+ default='cuda',
523
+ help="device to run stable diffusion on. defaults to cuda `torch.cuda.current_device()` if available"
524
+ )
525
+ parser.add_argument(
526
+ '--model',
527
+ default='stable-diffusion-1.4',
528
+ help='Indicates which diffusion model to load. (currently "stable-diffusion-1.4" (default) or "laion400m")',
529
+ )
530
+ parser.add_argument(
531
+ '--config',
532
+ default='configs/models.yaml',
533
+ help='Path to configuration file for alternate models.',
534
+ )
535
+ return parser
536
+
537
+
538
+ def create_cmd_parser():
539
+ parser = argparse.ArgumentParser(
540
+ description='Example: dream> a fantastic alien landscape -W1024 -H960 -s100 -n12'
541
+ )
542
+ parser.add_argument('prompt')
543
+ parser.add_argument('-s', '--steps', type=int, help='Number of steps')
544
+ parser.add_argument(
545
+ '-S',
546
+ '--seed',
547
+ type=int,
548
+ help='Image seed; a +ve integer, or use -1 for the previous seed, -2 for the one before that, etc',
549
+ )
550
+ parser.add_argument(
551
+ '-n',
552
+ '--iterations',
553
+ type=int,
554
+ default=1,
555
+ help='Number of samplings to perform (slower, but will provide seeds for individual images)',
556
+ )
557
+ parser.add_argument(
558
+ '-W', '--width', type=int, help='Image width, multiple of 64'
559
+ )
560
+ parser.add_argument(
561
+ '-H', '--height', type=int, help='Image height, multiple of 64'
562
+ )
563
+ parser.add_argument(
564
+ '-C',
565
+ '--cfg_scale',
566
+ default=7.5,
567
+ type=float,
568
+ help='Classifier free guidance (CFG) scale - higher numbers cause generator to "try" harder.',
569
+ )
570
+ parser.add_argument(
571
+ '-g', '--grid', action='store_true', help='generate a grid'
572
+ )
573
+ parser.add_argument(
574
+ '--outdir',
575
+ '-o',
576
+ type=str,
577
+ default=None,
578
+ help='Directory to save generated images and a log of prompts and seeds',
579
+ )
580
+ parser.add_argument(
581
+ '--seamless',
582
+ action='store_true',
583
+ help='Change the model to seamless tiling (circular) mode',
584
+ )
585
+ parser.add_argument(
586
+ '-i',
587
+ '--individual',
588
+ action='store_true',
589
+ help='Generate individual files (default)',
590
+ )
591
+ parser.add_argument(
592
+ '-I',
593
+ '--init_img',
594
+ type=str,
595
+ help='Path to input image for img2img mode (supersedes width and height)',
596
+ )
597
+ parser.add_argument(
598
+ '-M',
599
+ '--init_mask',
600
+ type=str,
601
+ help='Path to input mask for inpainting mode (supersedes width and height)',
602
+ )
603
+ parser.add_argument(
604
+ '-T',
605
+ '-fit',
606
+ '--fit',
607
+ action='store_true',
608
+ help='If specified, will resize the input image to fit within the dimensions of width x height (512x512 default)',
609
+ )
610
+ parser.add_argument(
611
+ '-f',
612
+ '--strength',
613
+ default=0.75,
614
+ type=float,
615
+ help='Strength for noising/unnoising. 0.0 preserves image exactly, 1.0 replaces it completely',
616
+ )
617
+ parser.add_argument(
618
+ '-G',
619
+ '--gfpgan_strength',
620
+ default=0,
621
+ type=float,
622
+ help='The strength at which to apply the GFPGAN model to the result, in order to improve faces.',
623
+ )
624
+ parser.add_argument(
625
+ '-U',
626
+ '--upscale',
627
+ nargs='+',
628
+ default=None,
629
+ type=float,
630
+ help='Scale factor (2, 4) for upscaling followed by upscaling strength (0-1.0). If strength not specified, defaults to 0.75'
631
+ )
632
+ parser.add_argument(
633
+ '-save_orig',
634
+ '--save_original',
635
+ action='store_true',
636
+ help='Save original. Use it when upscaling to save both versions.',
637
+ )
638
+ # variants is going to be superseded by a generalized "prompt-morph" function
639
+ # parser.add_argument('-v','--variants',type=int,help="in img2img mode, the first generated image will get passed back to img2img to generate the requested number of variants")
640
+ parser.add_argument(
641
+ '-x',
642
+ '--skip_normalize',
643
+ action='store_true',
644
+ help='Skip subprompt weight normalization',
645
+ )
646
+ parser.add_argument(
647
+ '-A',
648
+ '-m',
649
+ '--sampler',
650
+ dest='sampler_name',
651
+ default=None,
652
+ type=str,
653
+ choices=SAMPLER_CHOICES,
654
+ metavar='SAMPLER_NAME',
655
+ help=f'Switch to a different sampler. Supported samplers: {", ".join(SAMPLER_CHOICES)}',
656
+ )
657
+ parser.add_argument(
658
+ '-t',
659
+ '--log_tokenization',
660
+ action='store_true',
661
+ help='shows how the prompt is split into tokens'
662
+ )
663
+ parser.add_argument(
664
+ '-v',
665
+ '--variation_amount',
666
+ default=0.0,
667
+ type=float,
668
+ help='If > 0, generates variations on the initial seed instead of random seeds per iteration. Must be between 0 and 1. Higher values will be more different.'
669
+ )
670
+ parser.add_argument(
671
+ '-V',
672
+ '--with_variations',
673
+ default=None,
674
+ type=str,
675
+ help='list of variations to apply, in the format `seed:weight,seed:weight,...'
676
+ )
677
+ return parser
678
+
679
+
680
+ if __name__ == '__main__':
681
+ main()
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env python
2
+ # Copyright (c) 2022 Lincoln D. Stein (https://github.com/lstein)
3
+ # Before running stable-diffusion on an internet-isolated machine,
4
+ # run this script from one with internet connectivity. The
5
+ # two machines must share a common .cache directory.
6
+
7
+ import warnings
8
+ import configure_invokeai
9
+
10
+ if __name__ == '__main__':
11
+ configure_invokeai.main()
12
+