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
ldm/invoke/readline.py ADDED
@@ -0,0 +1,442 @@
1
+ """
2
+ Readline helper functions for invoke.py.
3
+ You may import the global singleton `completer` to get access to the
4
+ completer object itself. This is useful when you want to autocomplete
5
+ seeds:
6
+
7
+ from ldm.invoke.readline import completer
8
+ completer.add_seed(18247566)
9
+ completer.add_seed(9281839)
10
+ """
11
+ import os
12
+ import re
13
+ import atexit
14
+ from ldm.invoke.args import Args
15
+ from ldm.invoke.concepts_lib import Concepts
16
+ from ldm.invoke.globals import Globals
17
+
18
+ # ---------------readline utilities---------------------
19
+ try:
20
+ import readline
21
+ readline_available = True
22
+ except (ImportError,ModuleNotFoundError) as e:
23
+ print(f'** An error occurred when loading the readline module: {str(e)}')
24
+ readline_available = False
25
+
26
+ IMG_EXTENSIONS = ('.png','.jpg','.jpeg','.PNG','.JPG','.JPEG','.gif','.GIF')
27
+ WEIGHT_EXTENSIONS = ('.ckpt','.bae')
28
+ TEXT_EXTENSIONS = ('.txt','.TXT')
29
+ CONFIG_EXTENSIONS = ('.yaml','.yml')
30
+ COMMANDS = (
31
+ '--steps','-s',
32
+ '--seed','-S',
33
+ '--iterations','-n',
34
+ '--width','-W','--height','-H',
35
+ '--cfg_scale','-C',
36
+ '--threshold',
37
+ '--perlin',
38
+ '--grid','-g',
39
+ '--individual','-i',
40
+ '--save_intermediates',
41
+ '--init_img','-I',
42
+ '--init_mask','-M',
43
+ '--init_color',
44
+ '--strength','-f',
45
+ '--variants','-v',
46
+ '--outdir','-o',
47
+ '--sampler','-A','-m',
48
+ '--embedding_path',
49
+ '--device',
50
+ '--grid','-g',
51
+ '--facetool','-ft',
52
+ '--facetool_strength','-G',
53
+ '--codeformer_fidelity','-cf',
54
+ '--upscale','-U',
55
+ '-save_orig','--save_original',
56
+ '--log_tokenization','-t',
57
+ '--hires_fix',
58
+ '--inpaint_replace','-r',
59
+ '--png_compression','-z',
60
+ '--text_mask','-tm',
61
+ '!fix','!fetch','!replay','!history','!search','!clear',
62
+ '!models','!switch','!import_model','!edit_model','!del_model',
63
+ '!mask',
64
+ )
65
+ MODEL_COMMANDS = (
66
+ '!switch',
67
+ '!edit_model',
68
+ '!del_model',
69
+ )
70
+ WEIGHT_COMMANDS = (
71
+ '!import_model',
72
+ )
73
+ IMG_PATH_COMMANDS = (
74
+ '--outdir[=\s]',
75
+ )
76
+ TEXT_PATH_COMMANDS=(
77
+ '!replay',
78
+ )
79
+ IMG_FILE_COMMANDS=(
80
+ '!fix',
81
+ '!fetch',
82
+ '!mask',
83
+ '--init_img[=\s]','-I',
84
+ '--init_mask[=\s]','-M',
85
+ '--init_color[=\s]',
86
+ '--embedding_path[=\s]',
87
+ )
88
+
89
+ path_regexp = '(' + '|'.join(IMG_PATH_COMMANDS+IMG_FILE_COMMANDS) + ')\s*\S*$'
90
+ weight_regexp = '(' + '|'.join(WEIGHT_COMMANDS) + ')\s*\S*$'
91
+ text_regexp = '(' + '|'.join(TEXT_PATH_COMMANDS) + ')\s*\S*$'
92
+
93
+ class Completer(object):
94
+ def __init__(self, options, models=[]):
95
+ self.options = sorted(options)
96
+ self.models = sorted(models)
97
+ self.seeds = set()
98
+ self.matches = list()
99
+ self.default_dir = None
100
+ self.linebuffer = None
101
+ self.auto_history_active = True
102
+ self.extensions = None
103
+ self.concepts = None
104
+ self.embedding_terms = set()
105
+ return
106
+
107
+ def complete(self, text, state):
108
+ '''
109
+ Completes invoke command line.
110
+ BUG: it doesn't correctly complete files that have spaces in the name.
111
+ '''
112
+ buffer = readline.get_line_buffer()
113
+
114
+ if state == 0:
115
+
116
+ # extensions defined, so go directly into path completion mode
117
+ if self.extensions is not None:
118
+ self.matches = self._path_completions(text, state, self.extensions)
119
+
120
+ # looking for an image file
121
+ elif re.search(path_regexp,buffer):
122
+ do_shortcut = re.search('^'+'|'.join(IMG_FILE_COMMANDS),buffer)
123
+ self.matches = self._path_completions(text, state, IMG_EXTENSIONS,shortcut_ok=do_shortcut)
124
+
125
+ # looking for a seed
126
+ elif re.search('(-S\s*|--seed[=\s])\d*$',buffer):
127
+ self.matches= self._seed_completions(text,state)
128
+
129
+ elif re.search('<[\w-]*$',buffer):
130
+ self.matches= self._concept_completions(text,state)
131
+
132
+ # looking for a model
133
+ elif re.match('^'+'|'.join(MODEL_COMMANDS),buffer):
134
+ self.matches= self._model_completions(text, state)
135
+
136
+ elif re.search(weight_regexp,buffer):
137
+ self.matches = self._path_completions(
138
+ text,
139
+ state,
140
+ WEIGHT_EXTENSIONS,
141
+ default_dir=Globals.root,
142
+ )
143
+
144
+ elif re.search(text_regexp,buffer):
145
+ self.matches = self._path_completions(text, state, TEXT_EXTENSIONS)
146
+
147
+ # This is the first time for this text, so build a match list.
148
+ elif text:
149
+ self.matches = [
150
+ s for s in self.options if s and s.startswith(text)
151
+ ]
152
+ else:
153
+ self.matches = self.options[:]
154
+
155
+ # Return the state'th item from the match list,
156
+ # if we have that many.
157
+ try:
158
+ response = self.matches[state]
159
+ except IndexError:
160
+ response = None
161
+ return response
162
+
163
+ def complete_extensions(self, extensions:list):
164
+ '''
165
+ If called with a list of extensions, will force completer
166
+ to do file path completions.
167
+ '''
168
+ self.extensions=extensions
169
+
170
+ def add_history(self,line):
171
+ '''
172
+ Pass thru to readline
173
+ '''
174
+ if not self.auto_history_active:
175
+ readline.add_history(line)
176
+
177
+ def clear_history(self):
178
+ '''
179
+ Pass clear_history() thru to readline
180
+ '''
181
+ readline.clear_history()
182
+
183
+ def search_history(self,match:str):
184
+ '''
185
+ Like show_history() but only shows items that
186
+ contain the match string.
187
+ '''
188
+ self.show_history(match)
189
+
190
+ def remove_history_item(self,pos):
191
+ readline.remove_history_item(pos)
192
+
193
+ def add_seed(self, seed):
194
+ '''
195
+ Add a seed to the autocomplete list for display when -S is autocompleted.
196
+ '''
197
+ if seed is not None:
198
+ self.seeds.add(str(seed))
199
+
200
+ def set_default_dir(self, path):
201
+ self.default_dir=path
202
+
203
+ def set_options(self,options):
204
+ self.options = options
205
+
206
+ def get_line(self,index):
207
+ try:
208
+ line = self.get_history_item(index)
209
+ except IndexError:
210
+ return None
211
+ return line
212
+
213
+ def get_current_history_length(self):
214
+ return readline.get_current_history_length()
215
+
216
+ def get_history_item(self,index):
217
+ return readline.get_history_item(index)
218
+
219
+ def show_history(self,match=None):
220
+ '''
221
+ Print the session history using the pydoc pager
222
+ '''
223
+ import pydoc
224
+ lines = list()
225
+ h_len = self.get_current_history_length()
226
+ if h_len < 1:
227
+ print('<empty history>')
228
+ return
229
+
230
+ for i in range(0,h_len):
231
+ line = self.get_history_item(i+1)
232
+ if match and match not in line:
233
+ continue
234
+ lines.append(f'[{i+1}] {line}')
235
+ pydoc.pager('\n'.join(lines))
236
+
237
+ def set_line(self,line)->None:
238
+ '''
239
+ Set the default string displayed in the next line of input.
240
+ '''
241
+ self.linebuffer = line
242
+ readline.redisplay()
243
+
244
+ def add_model(self,model_name:str)->None:
245
+ '''
246
+ add a model name to the completion list
247
+ '''
248
+ self.models.append(model_name)
249
+
250
+ def del_model(self,model_name:str)->None:
251
+ '''
252
+ removes a model name from the completion list
253
+ '''
254
+ self.models.remove(model_name)
255
+
256
+ def _seed_completions(self, text, state):
257
+ m = re.search('(-S\s?|--seed[=\s]?)(\d*)',text)
258
+ if m:
259
+ switch = m.groups()[0]
260
+ partial = m.groups()[1]
261
+ else:
262
+ switch = ''
263
+ partial = text
264
+
265
+ matches = list()
266
+ for s in self.seeds:
267
+ if s.startswith(partial):
268
+ matches.append(switch+s)
269
+ matches.sort()
270
+ return matches
271
+
272
+ def add_embedding_terms(self, terms:list[str]):
273
+ self.embedding_terms = set(terms)
274
+ if self.concepts:
275
+ self.embedding_terms.update(self.concepts)
276
+
277
+ def _concept_completions(self, text, state):
278
+ if self.concepts is None:
279
+ self.concepts = set(Concepts().list_concepts())
280
+ self.embedding_terms.update(self.concepts)
281
+
282
+ partial = text[1:] # this removes the leading '<'
283
+ if len(partial) == 0:
284
+ return list(self.embedding_terms) # whole dump - think if user wants this!
285
+
286
+ matches = list()
287
+ for concept in self.embedding_terms:
288
+ if concept.startswith(partial):
289
+ matches.append(f'<{concept}>')
290
+ matches.sort()
291
+ return matches
292
+
293
+ def _model_completions(self, text, state):
294
+ m = re.search('(!switch\s+)(\w*)',text)
295
+ if m:
296
+ switch = m.groups()[0]
297
+ partial = m.groups()[1]
298
+ else:
299
+ switch = ''
300
+ partial = text
301
+ matches = list()
302
+ for s in self.models:
303
+ if s.startswith(partial):
304
+ matches.append(switch+s)
305
+ matches.sort()
306
+ return matches
307
+
308
+ def _pre_input_hook(self):
309
+ if self.linebuffer:
310
+ readline.insert_text(self.linebuffer)
311
+ readline.redisplay()
312
+ self.linebuffer = None
313
+
314
+ def _path_completions(self, text, state, extensions, shortcut_ok=True, default_dir:str=''):
315
+ # separate the switch from the partial path
316
+ match = re.search('^(-\w|--\w+=?)(.*)',text)
317
+ if match is None:
318
+ switch = None
319
+ partial_path = text
320
+ else:
321
+ switch,partial_path = match.groups()
322
+
323
+ partial_path = partial_path.lstrip()
324
+
325
+ matches = list()
326
+ path = os.path.expanduser(partial_path)
327
+
328
+ if os.path.isdir(path):
329
+ dir = path
330
+ elif os.path.dirname(path) != '':
331
+ dir = os.path.dirname(path)
332
+ else:
333
+ dir = default_dir if os.path.exists(default_dir) else ''
334
+ path= os.path.join(dir,path)
335
+
336
+ dir_list = os.listdir(dir or '.')
337
+ if shortcut_ok and os.path.exists(self.default_dir) and dir=='':
338
+ dir_list += os.listdir(self.default_dir)
339
+
340
+ for node in dir_list:
341
+ if node.startswith('.') and len(node) > 1:
342
+ continue
343
+ full_path = os.path.join(dir, node)
344
+
345
+ if not (node.endswith(extensions) or os.path.isdir(full_path)):
346
+ continue
347
+
348
+ if path and not full_path.startswith(path):
349
+ continue
350
+
351
+ if switch is None:
352
+ match_path = os.path.join(dir,node)
353
+ matches.append(match_path+'/' if os.path.isdir(full_path) else match_path)
354
+ elif os.path.isdir(full_path):
355
+ matches.append(
356
+ switch+os.path.join(os.path.dirname(full_path), node) + '/'
357
+ )
358
+ elif node.endswith(extensions):
359
+ matches.append(
360
+ switch+os.path.join(os.path.dirname(full_path), node)
361
+ )
362
+
363
+ return matches
364
+
365
+ class DummyCompleter(Completer):
366
+ def __init__(self,options):
367
+ super().__init__(options)
368
+ self.history = list()
369
+
370
+ def add_history(self,line):
371
+ self.history.append(line)
372
+
373
+ def clear_history(self):
374
+ self.history = list()
375
+
376
+ def get_current_history_length(self):
377
+ return len(self.history)
378
+
379
+ def get_history_item(self,index):
380
+ return self.history[index-1]
381
+
382
+ def remove_history_item(self,index):
383
+ return self.history.pop(index-1)
384
+
385
+ def set_line(self,line):
386
+ print(f'# {line}')
387
+
388
+ def generic_completer(commands:list)->Completer:
389
+ if readline_available:
390
+ completer = Completer(commands,[])
391
+ readline.set_completer(completer.complete)
392
+ readline.set_pre_input_hook(completer._pre_input_hook)
393
+ readline.set_completer_delims(' ')
394
+ readline.parse_and_bind('tab: complete')
395
+ readline.parse_and_bind('set print-completions-horizontally off')
396
+ readline.parse_and_bind('set page-completions on')
397
+ readline.parse_and_bind('set skip-completed-text on')
398
+ readline.parse_and_bind('set show-all-if-ambiguous on')
399
+ else:
400
+ completer = DummyCompleter(commands)
401
+ return completer
402
+
403
+ def get_completer(opt:Args, models=[])->Completer:
404
+ if readline_available:
405
+ completer = Completer(COMMANDS,models)
406
+
407
+ readline.set_completer(
408
+ completer.complete
409
+ )
410
+ # pyreadline3 does not have a set_auto_history() method
411
+ try:
412
+ readline.set_auto_history(False)
413
+ completer.auto_history_active = False
414
+ except:
415
+ completer.auto_history_active = True
416
+ readline.set_pre_input_hook(completer._pre_input_hook)
417
+ readline.set_completer_delims(' ')
418
+ readline.parse_and_bind('tab: complete')
419
+ readline.parse_and_bind('set print-completions-horizontally off')
420
+ readline.parse_and_bind('set page-completions on')
421
+ readline.parse_and_bind('set skip-completed-text on')
422
+ readline.parse_and_bind('set show-all-if-ambiguous on')
423
+
424
+ outdir = os.path.expanduser(opt.outdir)
425
+ if os.path.isabs(outdir):
426
+ histfile = os.path.join(outdir,'.invoke_history')
427
+ else:
428
+ histfile = os.path.join(Globals.root, outdir, '.invoke_history')
429
+ try:
430
+ readline.read_history_file(histfile)
431
+ readline.set_history_length(1000)
432
+ except FileNotFoundError:
433
+ pass
434
+ except OSError: # file likely corrupted
435
+ newname = f'{histfile}.old'
436
+ print(f'## Your history file {histfile} couldn\'t be loaded and may be corrupted. Renaming it to {newname}')
437
+ os.replace(histfile,newname)
438
+ atexit.register(readline.write_history_file, histfile)
439
+
440
+ else:
441
+ completer = DummyCompleter(COMMANDS)
442
+ return completer
@@ -0,0 +1,4 @@
1
+ '''
2
+ Initialization file for the ldm.invoke.restoration package
3
+ '''
4
+ from .base import Restoration
@@ -0,0 +1,38 @@
1
+ class Restoration():
2
+ def __init__(self) -> None:
3
+ pass
4
+
5
+ def load_face_restore_models(self, gfpgan_model_path='./models/gfpgan/GFPGANv1.4.pth'):
6
+ # Load GFPGAN
7
+ gfpgan = self.load_gfpgan(gfpgan_model_path)
8
+ if gfpgan.gfpgan_model_exists:
9
+ print('>> GFPGAN Initialized')
10
+ else:
11
+ print('>> GFPGAN Disabled')
12
+ gfpgan = None
13
+
14
+ # Load CodeFormer
15
+ codeformer = self.load_codeformer()
16
+ if codeformer.codeformer_model_exists:
17
+ print('>> CodeFormer Initialized')
18
+ else:
19
+ print('>> CodeFormer Disabled')
20
+ codeformer = None
21
+
22
+ return gfpgan, codeformer
23
+
24
+ # Face Restore Models
25
+ def load_gfpgan(self, gfpgan_model_path):
26
+ from ldm.invoke.restoration.gfpgan import GFPGAN
27
+ return GFPGAN(gfpgan_model_path)
28
+
29
+ def load_codeformer(self):
30
+ from ldm.invoke.restoration.codeformer import CodeFormerRestoration
31
+ return CodeFormerRestoration()
32
+
33
+ # Upscale Models
34
+ def load_esrgan(self, esrgan_bg_tile=400):
35
+ from ldm.invoke.restoration.realesrgan import ESRGAN
36
+ esrgan = ESRGAN(esrgan_bg_tile)
37
+ print('>> ESRGAN Initialized')
38
+ return esrgan;
@@ -0,0 +1,103 @@
1
+ import os
2
+ import torch
3
+ import numpy as np
4
+ import warnings
5
+ import sys
6
+ from ldm.invoke.globals import Globals
7
+
8
+ pretrained_model_url = 'https://github.com/sczhou/CodeFormer/releases/download/v0.1.0/codeformer.pth'
9
+
10
+ class CodeFormerRestoration():
11
+ def __init__(self,
12
+ codeformer_dir='models/codeformer',
13
+ codeformer_model_path='codeformer.pth') -> None:
14
+
15
+ if not os.path.isabs(codeformer_dir):
16
+ codeformer_dir = os.path.join(Globals.root, codeformer_dir)
17
+
18
+ self.model_path = os.path.join(codeformer_dir, codeformer_model_path)
19
+ self.codeformer_model_exists = os.path.isfile(self.model_path)
20
+
21
+ if not self.codeformer_model_exists:
22
+ print('## NOT FOUND: CodeFormer model not found at ' + self.model_path)
23
+ sys.path.append(os.path.abspath(codeformer_dir))
24
+
25
+ def process(self, image, strength, device, seed=None, fidelity=0.75):
26
+ if seed is not None:
27
+ print(f'>> CodeFormer - Restoring Faces for image seed:{seed}')
28
+ with warnings.catch_warnings():
29
+ warnings.filterwarnings('ignore', category=DeprecationWarning)
30
+ warnings.filterwarnings('ignore', category=UserWarning)
31
+
32
+ from basicsr.utils.download_util import load_file_from_url
33
+ from basicsr.utils import img2tensor, tensor2img
34
+ from facexlib.utils.face_restoration_helper import FaceRestoreHelper
35
+ from ldm.invoke.restoration.codeformer_arch import CodeFormer
36
+ from torchvision.transforms.functional import normalize
37
+ from PIL import Image
38
+
39
+ cf_class = CodeFormer
40
+
41
+ cf = cf_class(
42
+ dim_embd=512,
43
+ codebook_size=1024,
44
+ n_head=8,
45
+ n_layers=9,
46
+ connect_list=['32', '64', '128', '256']
47
+ ).to(device)
48
+
49
+ # note that this file should already be downloaded and cached at
50
+ # this point
51
+ checkpoint_path = load_file_from_url(url=pretrained_model_url,
52
+ model_dir=os.path.abspath(os.path.dirname(self.model_path)),
53
+ progress=True
54
+ )
55
+ checkpoint = torch.load(checkpoint_path)['params_ema']
56
+ cf.load_state_dict(checkpoint)
57
+ cf.eval()
58
+
59
+ image = image.convert('RGB')
60
+ # Codeformer expects a BGR np array; make array and flip channels
61
+ bgr_image_array = np.array(image, dtype=np.uint8)[...,::-1]
62
+
63
+ face_helper = FaceRestoreHelper(upscale_factor=1, use_parse=True, device=device)
64
+ face_helper.clean_all()
65
+ face_helper.read_image(bgr_image_array)
66
+ face_helper.get_face_landmarks_5(resize=640, eye_dist_threshold=5)
67
+ face_helper.align_warp_face()
68
+
69
+ for idx, cropped_face in enumerate(face_helper.cropped_faces):
70
+ cropped_face_t = img2tensor(cropped_face / 255., bgr2rgb=True, float32=True)
71
+ normalize(cropped_face_t, (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True)
72
+ cropped_face_t = cropped_face_t.unsqueeze(0).to(device)
73
+
74
+ try:
75
+ with torch.no_grad():
76
+ output = cf(cropped_face_t, w=fidelity, adain=True)[0]
77
+ restored_face = tensor2img(output.squeeze(0), rgb2bgr=True, min_max=(-1, 1))
78
+ del output
79
+ torch.cuda.empty_cache()
80
+ except RuntimeError as error:
81
+ print(f'\tFailed inference for CodeFormer: {error}.')
82
+ restored_face = cropped_face
83
+
84
+ restored_face = restored_face.astype('uint8')
85
+ face_helper.add_restored_face(restored_face)
86
+
87
+
88
+ face_helper.get_inverse_affine(None)
89
+
90
+ restored_img = face_helper.paste_faces_to_input_image()
91
+
92
+ # Flip the channels back to RGB
93
+ res = Image.fromarray(restored_img[...,::-1])
94
+
95
+ if strength < 1.0:
96
+ # Resize the image to the new image if the sizes have changed
97
+ if restored_img.size != image.size:
98
+ image = image.resize(res.size)
99
+ res = Image.blend(image, res, strength)
100
+
101
+ cf = None
102
+
103
+ return res