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.
- backend/__init__.py +0 -0
- backend/invoke_ai_web_server.py +1724 -0
- backend/modules/__init__.py +0 -0
- backend/modules/create_cmd_parser.py +55 -0
- backend/modules/get_canvas_generation_mode.py +117 -0
- backend/modules/parameters.py +71 -0
- backend/modules/parse_seed_weights.py +47 -0
- configs/INITIAL_MODELS.yaml +80 -0
- configs/models.yaml.example +29 -0
- configs/sd-concepts.txt +803 -0
- configs/stable-diffusion/v1-finetune.yaml +110 -0
- configs/stable-diffusion/v1-finetune_style.yaml +103 -0
- configs/stable-diffusion/v1-inference.yaml +79 -0
- configs/stable-diffusion/v1-inpainting-inference.yaml +79 -0
- configs/stable-diffusion/v1-m1-finetune.yaml +110 -0
- docs/assets/invoke-web-server-1.png +0 -0
- docs/assets/invoke_ai_banner.png +0 -0
- invokeai-2.2.4.5.data/data/assets/caution.png +0 -0
- invokeai-2.2.4.5.data/data/configs/INITIAL_MODELS.yaml +80 -0
- invokeai-2.2.4.5.data/data/configs/models.yaml.example +29 -0
- invokeai-2.2.4.5.data/data/configs/sd-concepts.txt +803 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-finetune.yaml +110 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-finetune_style.yaml +103 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-inference.yaml +79 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-inpainting-inference.yaml +79 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-m1-finetune.yaml +110 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/Inter-Bold.790c108b.ttf +0 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/Inter.b9a8e5e2.ttf +0 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/favicon.0d253ced.ico +0 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/index-legacy-b741077f.js +48 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/index.0dadf5d0.css +1 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/index.21ff81eb.js +625 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/logo.13003d72.png +0 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/polyfills-legacy-dde3a68a.js +4 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/polyfills.1ff60148.js +1 -0
- invokeai-2.2.4.5.data/data/frontend/dist/index.html +23 -0
- invokeai-2.2.4.5.data/data/scripts/configure_invokeai.py +797 -0
- invokeai-2.2.4.5.data/data/scripts/create_root.py +43 -0
- invokeai-2.2.4.5.data/data/scripts/dream.py +10 -0
- invokeai-2.2.4.5.data/data/scripts/images2prompt.py +30 -0
- invokeai-2.2.4.5.data/data/scripts/invoke.py +5 -0
- invokeai-2.2.4.5.data/data/scripts/legacy_api.py +681 -0
- invokeai-2.2.4.5.data/data/scripts/load_models.py +12 -0
- invokeai-2.2.4.5.data/data/scripts/merge_embeddings.py +124 -0
- invokeai-2.2.4.5.data/data/scripts/preload_models.py +12 -0
- invokeai-2.2.4.5.data/data/scripts/sd-metadata.py +22 -0
- invokeai-2.2.4.5.dist-info/LICENSE +21 -0
- invokeai-2.2.4.5.dist-info/LICENSE-ModelWeights.txt +294 -0
- invokeai-2.2.4.5.dist-info/METADATA +288 -0
- invokeai-2.2.4.5.dist-info/RECORD +169 -0
- invokeai-2.2.4.5.dist-info/WHEEL +5 -0
- invokeai-2.2.4.5.dist-info/entry_points.txt +4 -0
- invokeai-2.2.4.5.dist-info/top_level.txt +6 -0
- invokeai-2.2.4.5.dist-info/zip-safe +1 -0
- ldm/__init__.py +0 -0
- ldm/data/__init__.py +0 -0
- ldm/data/base.py +31 -0
- ldm/data/imagenet.py +466 -0
- ldm/data/lsun.py +126 -0
- ldm/data/personalized.py +202 -0
- ldm/data/personalized_style.py +169 -0
- ldm/generate.py +1159 -0
- ldm/invoke/CLI.py +960 -0
- ldm/invoke/__init__.py +3 -0
- ldm/invoke/args.py +1257 -0
- ldm/invoke/concepts_lib.py +169 -0
- ldm/invoke/conditioning.py +289 -0
- ldm/invoke/devices.py +27 -0
- ldm/invoke/generator/__init__.py +4 -0
- ldm/invoke/generator/base.py +335 -0
- ldm/invoke/generator/embiggen.py +501 -0
- ldm/invoke/generator/img2img.py +97 -0
- ldm/invoke/generator/inpaint.py +358 -0
- ldm/invoke/generator/omnibus.py +175 -0
- ldm/invoke/generator/txt2img.py +88 -0
- ldm/invoke/generator/txt2img2img.py +182 -0
- ldm/invoke/globals.py +31 -0
- ldm/invoke/image_util.py +70 -0
- ldm/invoke/log.py +66 -0
- ldm/invoke/model_cache.py +449 -0
- ldm/invoke/patchmatch.py +44 -0
- ldm/invoke/pngwriter.py +113 -0
- ldm/invoke/prompt_parser.py +655 -0
- ldm/invoke/readline.py +442 -0
- ldm/invoke/restoration/__init__.py +4 -0
- ldm/invoke/restoration/base.py +38 -0
- ldm/invoke/restoration/codeformer.py +103 -0
- ldm/invoke/restoration/codeformer_arch.py +276 -0
- ldm/invoke/restoration/gfpgan.py +84 -0
- ldm/invoke/restoration/outcrop.py +108 -0
- ldm/invoke/restoration/outpaint.py +92 -0
- ldm/invoke/restoration/realesrgan.py +90 -0
- ldm/invoke/restoration/vqgan_arch.py +435 -0
- ldm/invoke/seamless.py +30 -0
- ldm/invoke/server.py +282 -0
- ldm/invoke/server_legacy.py +246 -0
- ldm/invoke/txt2mask.py +136 -0
- ldm/lr_scheduler.py +143 -0
- ldm/models/__init__.py +0 -0
- ldm/models/autoencoder.py +596 -0
- ldm/models/diffusion/__init__.py +0 -0
- ldm/models/diffusion/classifier.py +355 -0
- ldm/models/diffusion/cross_attention_control.py +443 -0
- ldm/models/diffusion/cross_attention_map_saving.py +95 -0
- ldm/models/diffusion/ddim.py +111 -0
- ldm/models/diffusion/ddpm.py +2263 -0
- ldm/models/diffusion/ksampler.py +312 -0
- ldm/models/diffusion/plms.py +146 -0
- ldm/models/diffusion/sampler.py +450 -0
- ldm/models/diffusion/shared_invokeai_diffusion.py +244 -0
- ldm/modules/__init__.py +0 -0
- ldm/modules/attention.py +274 -0
- ldm/modules/diffusionmodules/__init__.py +0 -0
- ldm/modules/diffusionmodules/model.py +894 -0
- ldm/modules/diffusionmodules/openaimodel.py +1036 -0
- ldm/modules/diffusionmodules/util.py +314 -0
- ldm/modules/distributions/__init__.py +0 -0
- ldm/modules/distributions/distributions.py +104 -0
- ldm/modules/ema.py +88 -0
- ldm/modules/embedding_manager.py +413 -0
- ldm/modules/encoders/__init__.py +0 -0
- ldm/modules/encoders/modules.py +772 -0
- ldm/modules/image_degradation/__init__.py +6 -0
- ldm/modules/image_degradation/bsrgan.py +846 -0
- ldm/modules/image_degradation/bsrgan_light.py +751 -0
- ldm/modules/image_degradation/utils_image.py +1024 -0
- ldm/modules/losses/__init__.py +1 -0
- ldm/modules/losses/contperceptual.py +175 -0
- ldm/modules/losses/vqperceptual.py +240 -0
- ldm/modules/x_transformer.py +752 -0
- ldm/simplet2i.py +13 -0
- ldm/util.py +264 -0
- scripts/configure_invokeai.py +797 -0
- scripts/create_root.py +43 -0
- scripts/dream.py +10 -0
- scripts/images2prompt.py +30 -0
- scripts/invoke.py +5 -0
- scripts/legacy_api.py +681 -0
- scripts/load_models.py +12 -0
- scripts/merge_embeddings.py +124 -0
- scripts/orig_scripts/img2img.py +296 -0
- scripts/orig_scripts/inpaint.py +98 -0
- scripts/orig_scripts/knn2img.py +397 -0
- scripts/orig_scripts/sample_diffusion.py +313 -0
- scripts/orig_scripts/train_searcher.py +147 -0
- scripts/orig_scripts/txt2img.py +324 -0
- scripts/preload_models.py +12 -0
- scripts/sd-metadata.py +22 -0
- vendored/clip/clip/__init__.py +1 -0
- vendored/clip/clip/bpe_simple_vocab_16e6.txt.gz +0 -0
- vendored/clip/clip/clip.py +237 -0
- vendored/clip/clip/model.py +436 -0
- vendored/clip/clip/simple_tokenizer.py +132 -0
- vendored/clip/hubconf.py +42 -0
- vendored/clip/setup.py +21 -0
- vendored/clip/tests/test_consistency.py +25 -0
- vendored/clipseg/datasets/coco_wrapper.py +99 -0
- vendored/clipseg/datasets/pascal_zeroshot.py +60 -0
- vendored/clipseg/datasets/pfe_dataset.py +129 -0
- vendored/clipseg/datasets/phrasecut.py +380 -0
- vendored/clipseg/datasets/utils.py +68 -0
- vendored/clipseg/evaluation_utils.py +292 -0
- vendored/clipseg/general_utils.py +272 -0
- vendored/clipseg/metrics.py +271 -0
- vendored/clipseg/models/clipseg.py +538 -0
- vendored/clipseg/models/vitseg.py +286 -0
- vendored/clipseg/score.py +453 -0
- vendored/clipseg/setup.py +30 -0
- 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,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
|