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
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from os.path import basename, dirname, join, isfile
|
|
3
|
+
import torch
|
|
4
|
+
from torch import nn
|
|
5
|
+
from torch.nn import functional as nnf
|
|
6
|
+
from torch.nn.modules.activation import ReLU
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_prompt_list(prompt):
|
|
10
|
+
if prompt == 'plain':
|
|
11
|
+
return ['{}']
|
|
12
|
+
elif prompt == 'fixed':
|
|
13
|
+
return ['a photo of a {}.']
|
|
14
|
+
elif prompt == 'shuffle':
|
|
15
|
+
return ['a photo of a {}.', 'a photograph of a {}.', 'an image of a {}.', '{}.']
|
|
16
|
+
elif prompt == 'shuffle+':
|
|
17
|
+
return ['a photo of a {}.', 'a photograph of a {}.', 'an image of a {}.', '{}.',
|
|
18
|
+
'a cropped photo of a {}.', 'a good photo of a {}.', 'a photo of one {}.',
|
|
19
|
+
'a bad photo of a {}.', 'a photo of the {}.']
|
|
20
|
+
else:
|
|
21
|
+
raise ValueError('Invalid value for prompt')
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def forward_multihead_attention(x, b, with_aff=False, attn_mask=None):
|
|
25
|
+
"""
|
|
26
|
+
Simplified version of multihead attention (taken from torch source code but without tons of if clauses).
|
|
27
|
+
The mlp and layer norm come from CLIP.
|
|
28
|
+
x: input.
|
|
29
|
+
b: multihead attention module.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
x_ = b.ln_1(x)
|
|
33
|
+
q, k, v = nnf.linear(x_, b.attn.in_proj_weight, b.attn.in_proj_bias).chunk(3, dim=-1)
|
|
34
|
+
tgt_len, bsz, embed_dim = q.size()
|
|
35
|
+
|
|
36
|
+
head_dim = embed_dim // b.attn.num_heads
|
|
37
|
+
scaling = float(head_dim) ** -0.5
|
|
38
|
+
|
|
39
|
+
q = q.contiguous().view(tgt_len, bsz * b.attn.num_heads, b.attn.head_dim).transpose(0, 1)
|
|
40
|
+
k = k.contiguous().view(-1, bsz * b.attn.num_heads, b.attn.head_dim).transpose(0, 1)
|
|
41
|
+
v = v.contiguous().view(-1, bsz * b.attn.num_heads, b.attn.head_dim).transpose(0, 1)
|
|
42
|
+
|
|
43
|
+
q = q * scaling
|
|
44
|
+
|
|
45
|
+
attn_output_weights = torch.bmm(q, k.transpose(1, 2)) # n_heads * batch_size, tokens^2, tokens^2
|
|
46
|
+
if attn_mask is not None:
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
attn_mask_type, attn_mask = attn_mask
|
|
50
|
+
n_heads = attn_output_weights.size(0) // attn_mask.size(0)
|
|
51
|
+
attn_mask = attn_mask.repeat(n_heads, 1)
|
|
52
|
+
|
|
53
|
+
if attn_mask_type == 'cls_token':
|
|
54
|
+
# the mask only affects similarities compared to the readout-token.
|
|
55
|
+
attn_output_weights[:, 0, 1:] = attn_output_weights[:, 0, 1:] * attn_mask[None,...]
|
|
56
|
+
# attn_output_weights[:, 0, 0] = 0*attn_output_weights[:, 0, 0]
|
|
57
|
+
|
|
58
|
+
if attn_mask_type == 'all':
|
|
59
|
+
# print(attn_output_weights.shape, attn_mask[:, None].shape)
|
|
60
|
+
attn_output_weights[:, 1:, 1:] = attn_output_weights[:, 1:, 1:] * attn_mask[:, None]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
attn_output_weights = torch.softmax(attn_output_weights, dim=-1)
|
|
64
|
+
|
|
65
|
+
attn_output = torch.bmm(attn_output_weights, v)
|
|
66
|
+
attn_output = attn_output.transpose(0, 1).contiguous().view(tgt_len, bsz, embed_dim)
|
|
67
|
+
attn_output = b.attn.out_proj(attn_output)
|
|
68
|
+
|
|
69
|
+
x = x + attn_output
|
|
70
|
+
x = x + b.mlp(b.ln_2(x))
|
|
71
|
+
|
|
72
|
+
if with_aff:
|
|
73
|
+
return x, attn_output_weights
|
|
74
|
+
else:
|
|
75
|
+
return x
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class CLIPDenseBase(nn.Module):
|
|
79
|
+
|
|
80
|
+
def __init__(self, version, reduce_cond, reduce_dim, prompt, n_tokens):
|
|
81
|
+
super().__init__()
|
|
82
|
+
|
|
83
|
+
import clip
|
|
84
|
+
|
|
85
|
+
# prec = torch.FloatTensor
|
|
86
|
+
self.clip_model, _ = clip.load(version, device='cpu', jit=False)
|
|
87
|
+
self.model = self.clip_model.visual
|
|
88
|
+
|
|
89
|
+
# if not None, scale conv weights such that we obtain n_tokens.
|
|
90
|
+
self.n_tokens = n_tokens
|
|
91
|
+
|
|
92
|
+
for p in self.clip_model.parameters():
|
|
93
|
+
p.requires_grad_(False)
|
|
94
|
+
|
|
95
|
+
# conditional
|
|
96
|
+
if reduce_cond is not None:
|
|
97
|
+
self.reduce_cond = nn.Linear(512, reduce_cond)
|
|
98
|
+
for p in self.reduce_cond.parameters():
|
|
99
|
+
p.requires_grad_(False)
|
|
100
|
+
else:
|
|
101
|
+
self.reduce_cond = None
|
|
102
|
+
|
|
103
|
+
self.film_mul = nn.Linear(512 if reduce_cond is None else reduce_cond, reduce_dim)
|
|
104
|
+
self.film_add = nn.Linear(512 if reduce_cond is None else reduce_cond, reduce_dim)
|
|
105
|
+
|
|
106
|
+
self.reduce = nn.Linear(768, reduce_dim)
|
|
107
|
+
|
|
108
|
+
self.prompt_list = get_prompt_list(prompt)
|
|
109
|
+
|
|
110
|
+
# precomputed prompts
|
|
111
|
+
import pickle
|
|
112
|
+
if isfile('precomputed_prompt_vectors.pickle'):
|
|
113
|
+
precomp = pickle.load(open('precomputed_prompt_vectors.pickle', 'rb'))
|
|
114
|
+
self.precomputed_prompts = {k: torch.from_numpy(v) for k, v in precomp.items()}
|
|
115
|
+
else:
|
|
116
|
+
self.precomputed_prompts = dict()
|
|
117
|
+
|
|
118
|
+
def rescaled_pos_emb(self, new_size):
|
|
119
|
+
assert len(new_size) == 2
|
|
120
|
+
|
|
121
|
+
a = self.model.positional_embedding[1:].T.view(1, 768, *self.token_shape)
|
|
122
|
+
b = nnf.interpolate(a, new_size, mode='bicubic', align_corners=False).squeeze(0).view(768, new_size[0]*new_size[1]).T
|
|
123
|
+
return torch.cat([self.model.positional_embedding[:1], b])
|
|
124
|
+
|
|
125
|
+
def visual_forward(self, x_inp, extract_layers=(), skip=False, mask=None):
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
with torch.no_grad():
|
|
129
|
+
|
|
130
|
+
inp_size = x_inp.shape[2:]
|
|
131
|
+
|
|
132
|
+
if self.n_tokens is not None:
|
|
133
|
+
stride2 = x_inp.shape[2] // self.n_tokens
|
|
134
|
+
conv_weight2 = nnf.interpolate(self.model.conv1.weight, (stride2, stride2), mode='bilinear', align_corners=True)
|
|
135
|
+
x = nnf.conv2d(x_inp, conv_weight2, bias=self.model.conv1.bias, stride=stride2, dilation=self.model.conv1.dilation)
|
|
136
|
+
else:
|
|
137
|
+
x = self.model.conv1(x_inp) # shape = [*, width, grid, grid]
|
|
138
|
+
|
|
139
|
+
x = x.reshape(x.shape[0], x.shape[1], -1) # shape = [*, width, grid ** 2]
|
|
140
|
+
x = x.permute(0, 2, 1) # shape = [*, grid ** 2, width]
|
|
141
|
+
|
|
142
|
+
x = torch.cat([self.model.class_embedding.to(x.dtype) + torch.zeros(x.shape[0], 1, x.shape[-1], dtype=x.dtype, device=x.device), x], dim=1) # shape = [*, grid ** 2 + 1, width]
|
|
143
|
+
|
|
144
|
+
standard_n_tokens = 50 if self.model.conv1.kernel_size[0] == 32 else 197
|
|
145
|
+
|
|
146
|
+
if x.shape[1] != standard_n_tokens:
|
|
147
|
+
new_shape = int(math.sqrt(x.shape[1]-1))
|
|
148
|
+
x = x + self.rescaled_pos_emb((new_shape, new_shape)).to(x.dtype)[None,:,:]
|
|
149
|
+
else:
|
|
150
|
+
x = x + self.model.positional_embedding.to(x.dtype)
|
|
151
|
+
|
|
152
|
+
x = self.model.ln_pre(x)
|
|
153
|
+
|
|
154
|
+
x = x.permute(1, 0, 2) # NLD -> LND
|
|
155
|
+
|
|
156
|
+
activations, affinities = [], []
|
|
157
|
+
for i, res_block in enumerate(self.model.transformer.resblocks):
|
|
158
|
+
|
|
159
|
+
if mask is not None:
|
|
160
|
+
mask_layer, mask_type, mask_tensor = mask
|
|
161
|
+
if mask_layer == i or mask_layer == 'all':
|
|
162
|
+
# import ipdb; ipdb.set_trace()
|
|
163
|
+
size = int(math.sqrt(x.shape[0] - 1))
|
|
164
|
+
|
|
165
|
+
attn_mask = (mask_type, nnf.interpolate(mask_tensor.unsqueeze(1).float(), (size, size)).view(mask_tensor.shape[0], size * size))
|
|
166
|
+
|
|
167
|
+
else:
|
|
168
|
+
attn_mask = None
|
|
169
|
+
else:
|
|
170
|
+
attn_mask = None
|
|
171
|
+
|
|
172
|
+
x, aff_per_head = forward_multihead_attention(x, res_block, with_aff=True, attn_mask=attn_mask)
|
|
173
|
+
|
|
174
|
+
if i in extract_layers:
|
|
175
|
+
affinities += [aff_per_head]
|
|
176
|
+
|
|
177
|
+
#if self.n_tokens is not None:
|
|
178
|
+
# activations += [nnf.interpolate(x, inp_size, mode='bilinear', align_corners=True)]
|
|
179
|
+
#else:
|
|
180
|
+
activations += [x]
|
|
181
|
+
|
|
182
|
+
if len(extract_layers) > 0 and i == max(extract_layers) and skip:
|
|
183
|
+
print('early skip')
|
|
184
|
+
break
|
|
185
|
+
|
|
186
|
+
x = x.permute(1, 0, 2) # LND -> NLD
|
|
187
|
+
x = self.model.ln_post(x[:, 0, :])
|
|
188
|
+
|
|
189
|
+
if self.model.proj is not None:
|
|
190
|
+
x = x @ self.model.proj
|
|
191
|
+
|
|
192
|
+
return x, activations, affinities
|
|
193
|
+
|
|
194
|
+
def sample_prompts(self, words, prompt_list=None):
|
|
195
|
+
|
|
196
|
+
prompt_list = prompt_list if prompt_list is not None else self.prompt_list
|
|
197
|
+
|
|
198
|
+
prompt_indices = torch.multinomial(torch.ones(len(prompt_list)), len(words), replacement=True)
|
|
199
|
+
prompts = [prompt_list[i] for i in prompt_indices]
|
|
200
|
+
return [promt.format(w) for promt, w in zip(prompts, words)]
|
|
201
|
+
|
|
202
|
+
def get_cond_vec(self, conditional, batch_size):
|
|
203
|
+
# compute conditional from a single string
|
|
204
|
+
if conditional is not None and type(conditional) == str:
|
|
205
|
+
cond = self.compute_conditional(conditional)
|
|
206
|
+
cond = cond.repeat(batch_size, 1)
|
|
207
|
+
|
|
208
|
+
# compute conditional from string list/tuple
|
|
209
|
+
elif conditional is not None and type(conditional) in {list, tuple} and type(conditional[0]) == str:
|
|
210
|
+
assert len(conditional) == batch_size
|
|
211
|
+
cond = self.compute_conditional(conditional)
|
|
212
|
+
|
|
213
|
+
# use conditional directly
|
|
214
|
+
elif conditional is not None and type(conditional) == torch.Tensor and conditional.ndim == 2:
|
|
215
|
+
cond = conditional
|
|
216
|
+
|
|
217
|
+
# compute conditional from image
|
|
218
|
+
elif conditional is not None and type(conditional) == torch.Tensor:
|
|
219
|
+
with torch.no_grad():
|
|
220
|
+
cond, _, _ = self.visual_forward(conditional)
|
|
221
|
+
else:
|
|
222
|
+
raise ValueError('invalid conditional')
|
|
223
|
+
return cond
|
|
224
|
+
|
|
225
|
+
def compute_conditional(self, conditional):
|
|
226
|
+
import clip
|
|
227
|
+
|
|
228
|
+
dev = next(self.parameters()).device
|
|
229
|
+
|
|
230
|
+
if type(conditional) in {list, tuple}:
|
|
231
|
+
text_tokens = clip.tokenize(conditional).to(dev)
|
|
232
|
+
cond = self.clip_model.encode_text(text_tokens)
|
|
233
|
+
else:
|
|
234
|
+
if conditional in self.precomputed_prompts:
|
|
235
|
+
cond = self.precomputed_prompts[conditional].float().to(dev)
|
|
236
|
+
else:
|
|
237
|
+
text_tokens = clip.tokenize([conditional]).to(dev)
|
|
238
|
+
cond = self.clip_model.encode_text(text_tokens)[0]
|
|
239
|
+
|
|
240
|
+
if self.shift_vector is not None:
|
|
241
|
+
return cond + self.shift_vector
|
|
242
|
+
else:
|
|
243
|
+
return cond
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def clip_load_untrained(version):
|
|
247
|
+
assert version == 'ViT-B/16'
|
|
248
|
+
from clip.model import CLIP
|
|
249
|
+
from clip.clip import _MODELS, _download
|
|
250
|
+
model = torch.jit.load(_download(_MODELS['ViT-B/16'])).eval()
|
|
251
|
+
state_dict = model.state_dict()
|
|
252
|
+
|
|
253
|
+
vision_width = state_dict["visual.conv1.weight"].shape[0]
|
|
254
|
+
vision_layers = len([k for k in state_dict.keys() if k.startswith("visual.") and k.endswith(".attn.in_proj_weight")])
|
|
255
|
+
vision_patch_size = state_dict["visual.conv1.weight"].shape[-1]
|
|
256
|
+
grid_size = round((state_dict["visual.positional_embedding"].shape[0] - 1) ** 0.5)
|
|
257
|
+
image_resolution = vision_patch_size * grid_size
|
|
258
|
+
embed_dim = state_dict["text_projection"].shape[1]
|
|
259
|
+
context_length = state_dict["positional_embedding"].shape[0]
|
|
260
|
+
vocab_size = state_dict["token_embedding.weight"].shape[0]
|
|
261
|
+
transformer_width = state_dict["ln_final.weight"].shape[0]
|
|
262
|
+
transformer_heads = transformer_width // 64
|
|
263
|
+
transformer_layers = len(set(k.split(".")[2] for k in state_dict if k.startswith(f"transformer.resblocks")))
|
|
264
|
+
|
|
265
|
+
return CLIP(embed_dim, image_resolution, vision_layers, vision_width, vision_patch_size,
|
|
266
|
+
context_length, vocab_size, transformer_width, transformer_heads, transformer_layers)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class CLIPDensePredT(CLIPDenseBase):
|
|
270
|
+
|
|
271
|
+
def __init__(self, version='ViT-B/32', extract_layers=(3, 6, 9), cond_layer=0, reduce_dim=128, n_heads=4, prompt='fixed',
|
|
272
|
+
extra_blocks=0, reduce_cond=None, fix_shift=False,
|
|
273
|
+
learn_trans_conv_only=False, limit_to_clip_only=False, upsample=False,
|
|
274
|
+
add_calibration=False, rev_activations=False, trans_conv=None, n_tokens=None, complex_trans_conv=False):
|
|
275
|
+
|
|
276
|
+
super().__init__(version, reduce_cond, reduce_dim, prompt, n_tokens)
|
|
277
|
+
# device = 'cpu'
|
|
278
|
+
|
|
279
|
+
self.extract_layers = extract_layers
|
|
280
|
+
self.cond_layer = cond_layer
|
|
281
|
+
self.limit_to_clip_only = limit_to_clip_only
|
|
282
|
+
self.process_cond = None
|
|
283
|
+
self.rev_activations = rev_activations
|
|
284
|
+
|
|
285
|
+
depth = len(extract_layers)
|
|
286
|
+
|
|
287
|
+
if add_calibration:
|
|
288
|
+
self.calibration_conds = 1
|
|
289
|
+
|
|
290
|
+
self.upsample_proj = nn.Conv2d(reduce_dim, 1, kernel_size=1) if upsample else None
|
|
291
|
+
|
|
292
|
+
self.add_activation1 = True
|
|
293
|
+
|
|
294
|
+
self.version = version
|
|
295
|
+
|
|
296
|
+
self.token_shape = {'ViT-B/32': (7, 7), 'ViT-B/16': (14, 14)}[version]
|
|
297
|
+
|
|
298
|
+
if fix_shift:
|
|
299
|
+
# self.shift_vector = nn.Parameter(torch.load(join(dirname(basename(__file__)), 'clip_text_shift_vector.pth')), requires_grad=False)
|
|
300
|
+
self.shift_vector = nn.Parameter(torch.load(join(dirname(basename(__file__)), 'shift_text_to_vis.pth')), requires_grad=False)
|
|
301
|
+
# self.shift_vector = nn.Parameter(-1*torch.load(join(dirname(basename(__file__)), 'shift2.pth')), requires_grad=False)
|
|
302
|
+
else:
|
|
303
|
+
self.shift_vector = None
|
|
304
|
+
|
|
305
|
+
if trans_conv is None:
|
|
306
|
+
trans_conv_ks = {'ViT-B/32': (32, 32), 'ViT-B/16': (16, 16)}[version]
|
|
307
|
+
else:
|
|
308
|
+
# explicitly define transposed conv kernel size
|
|
309
|
+
trans_conv_ks = (trans_conv, trans_conv)
|
|
310
|
+
|
|
311
|
+
if not complex_trans_conv:
|
|
312
|
+
self.trans_conv = nn.ConvTranspose2d(reduce_dim, 1, trans_conv_ks, stride=trans_conv_ks)
|
|
313
|
+
else:
|
|
314
|
+
assert trans_conv_ks[0] == trans_conv_ks[1]
|
|
315
|
+
|
|
316
|
+
tp_kernels = (trans_conv_ks[0] // 4, trans_conv_ks[0] // 4)
|
|
317
|
+
|
|
318
|
+
self.trans_conv = nn.Sequential(
|
|
319
|
+
nn.Conv2d(reduce_dim, reduce_dim, kernel_size=3, padding=1),
|
|
320
|
+
nn.ReLU(),
|
|
321
|
+
nn.ConvTranspose2d(reduce_dim, reduce_dim // 2, kernel_size=tp_kernels[0], stride=tp_kernels[0]),
|
|
322
|
+
nn.ReLU(),
|
|
323
|
+
nn.ConvTranspose2d(reduce_dim // 2, 1, kernel_size=tp_kernels[1], stride=tp_kernels[1]),
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
# self.trans_conv = nn.ConvTranspose2d(reduce_dim, 1, trans_conv_ks, stride=trans_conv_ks)
|
|
327
|
+
|
|
328
|
+
assert len(self.extract_layers) == depth
|
|
329
|
+
|
|
330
|
+
self.reduces = nn.ModuleList([nn.Linear(768, reduce_dim) for _ in range(depth)])
|
|
331
|
+
self.blocks = nn.ModuleList([nn.TransformerEncoderLayer(d_model=reduce_dim, nhead=n_heads) for _ in range(len(self.extract_layers))])
|
|
332
|
+
self.extra_blocks = nn.ModuleList([nn.TransformerEncoderLayer(d_model=reduce_dim, nhead=n_heads) for _ in range(extra_blocks)])
|
|
333
|
+
|
|
334
|
+
# refinement and trans conv
|
|
335
|
+
|
|
336
|
+
if learn_trans_conv_only:
|
|
337
|
+
for p in self.parameters():
|
|
338
|
+
p.requires_grad_(False)
|
|
339
|
+
|
|
340
|
+
for p in self.trans_conv.parameters():
|
|
341
|
+
p.requires_grad_(True)
|
|
342
|
+
|
|
343
|
+
self.prompt_list = get_prompt_list(prompt)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def forward(self, inp_image, conditional=None, return_features=False, mask=None):
|
|
347
|
+
|
|
348
|
+
assert type(return_features) == bool
|
|
349
|
+
|
|
350
|
+
inp_image = inp_image.to(self.model.positional_embedding.device)
|
|
351
|
+
|
|
352
|
+
if mask is not None:
|
|
353
|
+
raise ValueError('mask not supported')
|
|
354
|
+
|
|
355
|
+
# x_inp = normalize(inp_image)
|
|
356
|
+
x_inp = inp_image
|
|
357
|
+
|
|
358
|
+
bs, dev = inp_image.shape[0], x_inp.device
|
|
359
|
+
|
|
360
|
+
cond = self.get_cond_vec(conditional, bs)
|
|
361
|
+
|
|
362
|
+
visual_q, activations, _ = self.visual_forward(x_inp, extract_layers=[0] + list(self.extract_layers))
|
|
363
|
+
|
|
364
|
+
activation1 = activations[0]
|
|
365
|
+
activations = activations[1:]
|
|
366
|
+
|
|
367
|
+
_activations = activations[::-1] if not self.rev_activations else activations
|
|
368
|
+
|
|
369
|
+
a = None
|
|
370
|
+
for i, (activation, block, reduce) in enumerate(zip(_activations, self.blocks, self.reduces)):
|
|
371
|
+
|
|
372
|
+
if a is not None:
|
|
373
|
+
a = reduce(activation) + a
|
|
374
|
+
else:
|
|
375
|
+
a = reduce(activation)
|
|
376
|
+
|
|
377
|
+
if i == self.cond_layer:
|
|
378
|
+
if self.reduce_cond is not None:
|
|
379
|
+
cond = self.reduce_cond(cond)
|
|
380
|
+
|
|
381
|
+
a = self.film_mul(cond) * a + self.film_add(cond)
|
|
382
|
+
|
|
383
|
+
a = block(a)
|
|
384
|
+
|
|
385
|
+
for block in self.extra_blocks:
|
|
386
|
+
a = a + block(a)
|
|
387
|
+
|
|
388
|
+
a = a[1:].permute(1, 2, 0) # rm cls token and -> BS, Feats, Tokens
|
|
389
|
+
|
|
390
|
+
size = int(math.sqrt(a.shape[2]))
|
|
391
|
+
|
|
392
|
+
a = a.view(bs, a.shape[1], size, size)
|
|
393
|
+
|
|
394
|
+
a = self.trans_conv(a)
|
|
395
|
+
|
|
396
|
+
if self.n_tokens is not None:
|
|
397
|
+
a = nnf.interpolate(a, x_inp.shape[2:], mode='bilinear', align_corners=True)
|
|
398
|
+
|
|
399
|
+
if self.upsample_proj is not None:
|
|
400
|
+
a = self.upsample_proj(a)
|
|
401
|
+
a = nnf.interpolate(a, x_inp.shape[2:], mode='bilinear')
|
|
402
|
+
|
|
403
|
+
if return_features:
|
|
404
|
+
return a, visual_q, cond, [activation1] + activations
|
|
405
|
+
else:
|
|
406
|
+
return a,
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
class CLIPDensePredTMasked(CLIPDensePredT):
|
|
411
|
+
|
|
412
|
+
def __init__(self, version='ViT-B/32', extract_layers=(3, 6, 9), cond_layer=0, reduce_dim=128, n_heads=4,
|
|
413
|
+
prompt='fixed', extra_blocks=0, reduce_cond=None, fix_shift=False, learn_trans_conv_only=False,
|
|
414
|
+
refine=None, limit_to_clip_only=False, upsample=False, add_calibration=False, n_tokens=None):
|
|
415
|
+
|
|
416
|
+
super().__init__(version=version, extract_layers=extract_layers, cond_layer=cond_layer, reduce_dim=reduce_dim,
|
|
417
|
+
n_heads=n_heads, prompt=prompt, extra_blocks=extra_blocks, reduce_cond=reduce_cond,
|
|
418
|
+
fix_shift=fix_shift, learn_trans_conv_only=learn_trans_conv_only,
|
|
419
|
+
limit_to_clip_only=limit_to_clip_only, upsample=upsample, add_calibration=add_calibration,
|
|
420
|
+
n_tokens=n_tokens)
|
|
421
|
+
|
|
422
|
+
def visual_forward_masked(self, img_s, seg_s):
|
|
423
|
+
return super().visual_forward(img_s, mask=('all', 'cls_token', seg_s))
|
|
424
|
+
|
|
425
|
+
def forward(self, img_q, cond_or_img_s, seg_s=None, return_features=False):
|
|
426
|
+
|
|
427
|
+
if seg_s is None:
|
|
428
|
+
cond = cond_or_img_s
|
|
429
|
+
else:
|
|
430
|
+
img_s = cond_or_img_s
|
|
431
|
+
|
|
432
|
+
with torch.no_grad():
|
|
433
|
+
cond, _, _ = self.visual_forward_masked(img_s, seg_s)
|
|
434
|
+
|
|
435
|
+
return super().forward(img_q, cond, return_features=return_features)
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
class CLIPDenseBaseline(CLIPDenseBase):
|
|
440
|
+
|
|
441
|
+
def __init__(self, version='ViT-B/32', cond_layer=0,
|
|
442
|
+
extract_layer=9, reduce_dim=128, reduce2_dim=None, prompt='fixed',
|
|
443
|
+
reduce_cond=None, limit_to_clip_only=False, n_tokens=None):
|
|
444
|
+
|
|
445
|
+
super().__init__(version, reduce_cond, reduce_dim, prompt, n_tokens)
|
|
446
|
+
device = 'cpu'
|
|
447
|
+
|
|
448
|
+
# self.cond_layer = cond_layer
|
|
449
|
+
self.extract_layer = extract_layer
|
|
450
|
+
self.limit_to_clip_only = limit_to_clip_only
|
|
451
|
+
self.shift_vector = None
|
|
452
|
+
|
|
453
|
+
self.token_shape = {'ViT-B/32': (7, 7), 'ViT-B/16': (14, 14)}[version]
|
|
454
|
+
|
|
455
|
+
assert reduce2_dim is not None
|
|
456
|
+
|
|
457
|
+
self.reduce2 = nn.Sequential(
|
|
458
|
+
nn.Linear(reduce_dim, reduce2_dim),
|
|
459
|
+
nn.ReLU(),
|
|
460
|
+
nn.Linear(reduce2_dim, reduce_dim)
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
trans_conv_ks = {'ViT-B/32': (32, 32), 'ViT-B/16': (16, 16)}[version]
|
|
464
|
+
self.trans_conv = nn.ConvTranspose2d(reduce_dim, 1, trans_conv_ks, stride=trans_conv_ks)
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
def forward(self, inp_image, conditional=None, return_features=False):
|
|
468
|
+
|
|
469
|
+
inp_image = inp_image.to(self.model.positional_embedding.device)
|
|
470
|
+
|
|
471
|
+
# x_inp = normalize(inp_image)
|
|
472
|
+
x_inp = inp_image
|
|
473
|
+
|
|
474
|
+
bs, dev = inp_image.shape[0], x_inp.device
|
|
475
|
+
|
|
476
|
+
cond = self.get_cond_vec(conditional, bs)
|
|
477
|
+
|
|
478
|
+
visual_q, activations, affinities = self.visual_forward(x_inp, extract_layers=[self.extract_layer])
|
|
479
|
+
|
|
480
|
+
a = activations[0]
|
|
481
|
+
a = self.reduce(a)
|
|
482
|
+
a = self.film_mul(cond) * a + self.film_add(cond)
|
|
483
|
+
|
|
484
|
+
if self.reduce2 is not None:
|
|
485
|
+
a = self.reduce2(a)
|
|
486
|
+
|
|
487
|
+
# the original model would execute a transformer block here
|
|
488
|
+
|
|
489
|
+
a = a[1:].permute(1, 2, 0) # rm cls token and -> BS, Feats, Tokens
|
|
490
|
+
|
|
491
|
+
size = int(math.sqrt(a.shape[2]))
|
|
492
|
+
|
|
493
|
+
a = a.view(bs, a.shape[1], size, size)
|
|
494
|
+
a = self.trans_conv(a)
|
|
495
|
+
|
|
496
|
+
if return_features:
|
|
497
|
+
return a, visual_q, cond, activations
|
|
498
|
+
else:
|
|
499
|
+
return a,
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
class CLIPSegMultiLabel(nn.Module):
|
|
503
|
+
|
|
504
|
+
def __init__(self, model) -> None:
|
|
505
|
+
super().__init__()
|
|
506
|
+
|
|
507
|
+
from third_party.JoEm.data_loader import get_seen_idx, get_unseen_idx, VOC
|
|
508
|
+
|
|
509
|
+
self.pascal_classes = VOC
|
|
510
|
+
|
|
511
|
+
from models.clipseg import CLIPDensePredT
|
|
512
|
+
from general_utils import load_model
|
|
513
|
+
# self.clipseg = load_model('rd64-vit16-neg0.2-phrasecut', strict=False)
|
|
514
|
+
self.clipseg = load_model(model, strict=False)
|
|
515
|
+
|
|
516
|
+
self.clipseg.eval()
|
|
517
|
+
|
|
518
|
+
def forward(self, x):
|
|
519
|
+
|
|
520
|
+
bs = x.shape[0]
|
|
521
|
+
out = torch.ones(21, bs, 352, 352).to(x.device) * -10
|
|
522
|
+
|
|
523
|
+
for class_id, class_name in enumerate(self.pascal_classes):
|
|
524
|
+
|
|
525
|
+
fac = 3 if class_name == 'background' else 1
|
|
526
|
+
|
|
527
|
+
with torch.no_grad():
|
|
528
|
+
pred = torch.sigmoid(self.clipseg(x, class_name)[0][:,0]) * fac
|
|
529
|
+
|
|
530
|
+
out[class_id] += pred
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
out = out.permute(1, 0, 2, 3)
|
|
534
|
+
|
|
535
|
+
return out
|
|
536
|
+
|
|
537
|
+
# construct output tensor
|
|
538
|
+
|