aryadomain commited on
Commit
f338ee9
·
verified ·
1 Parent(s): 9ebbe39

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. evaluation/__pycache__/hpsv2_score.cpython-311.pyc +0 -0
  2. evaluation/__pycache__/imagereward_score.cpython-311.pyc +0 -0
  3. evaluation/__pycache__/pick_score.cpython-311.pyc +0 -0
  4. evaluation/blip/__pycache__/__init__.cpython-311.pyc +0 -0
  5. evaluation/blip/__pycache__/blip.cpython-311.pyc +0 -0
  6. evaluation/blip/__pycache__/blip_pretrain.cpython-311.pyc +0 -0
  7. evaluation/blip/__pycache__/med.cpython-311.pyc +0 -0
  8. evaluation/blip/__pycache__/vit.cpython-311.pyc +0 -0
  9. evaluation/blip/med.py +957 -0
  10. evaluation/blip/vit.py +306 -0
  11. evaluation/hpsv2_score.py +110 -0
  12. evaluation/imagereward_score.py +221 -0
  13. evaluation/open_clip/__init__.py +14 -0
  14. evaluation/open_clip/coca_model.py +458 -0
  15. evaluation/open_clip/constants.py +2 -0
  16. evaluation/open_clip/factory.py +433 -0
  17. evaluation/open_clip/generation_utils.py +0 -0
  18. evaluation/open_clip/hf_configs.py +45 -0
  19. evaluation/open_clip/hf_model.py +176 -0
  20. evaluation/open_clip/loss.py +270 -0
  21. evaluation/open_clip/model.py +461 -0
  22. evaluation/open_clip/model_configs/RN101-quickgelu.json +22 -0
  23. evaluation/open_clip/model_configs/RN101.json +21 -0
  24. evaluation/open_clip/model_configs/RN50-quickgelu.json +22 -0
  25. evaluation/open_clip/model_configs/RN50x16.json +21 -0
  26. evaluation/open_clip/model_configs/RN50x4.json +21 -0
  27. evaluation/open_clip/model_configs/ViT-B-16-plus-240.json +16 -0
  28. evaluation/open_clip/model_configs/ViT-B-16-plus.json +16 -0
  29. evaluation/open_clip/model_configs/ViT-B-16.json +16 -0
  30. evaluation/open_clip/model_configs/ViT-B-32-quickgelu.json +17 -0
  31. evaluation/open_clip/model_configs/ViT-B-32.json +16 -0
  32. evaluation/open_clip/model_configs/ViT-H-14.json +17 -0
  33. evaluation/open_clip/model_configs/ViT-L-14-336.json +16 -0
  34. evaluation/open_clip/model_configs/ViT-L-14.json +16 -0
  35. evaluation/open_clip/model_configs/ViT-L-16.json +16 -0
  36. evaluation/open_clip/model_configs/ViT-M-16-alt.json +17 -0
  37. evaluation/open_clip/model_configs/ViT-M-16.json +16 -0
  38. evaluation/open_clip/model_configs/ViT-M-32-alt.json +16 -0
  39. evaluation/open_clip/model_configs/ViT-M-32.json +16 -0
  40. evaluation/open_clip/model_configs/ViT-S-16-alt.json +16 -0
  41. evaluation/open_clip/model_configs/ViT-S-16.json +16 -0
  42. evaluation/open_clip/model_configs/ViT-S-32-alt.json +16 -0
  43. evaluation/open_clip/model_configs/ViT-bigG-14.json +18 -0
  44. evaluation/open_clip/model_configs/ViT-e-14.json +18 -0
  45. evaluation/open_clip/model_configs/ViT-g-14.json +18 -0
  46. evaluation/open_clip/model_configs/coca_ViT-L-14.json +30 -0
  47. evaluation/open_clip/model_configs/coca_base.json +31 -0
  48. evaluation/open_clip/model_configs/coca_roberta-ViT-B-32.json +24 -0
  49. evaluation/open_clip/model_configs/convnext_base.json +19 -0
  50. evaluation/open_clip/model_configs/convnext_base_w.json +19 -0
evaluation/__pycache__/hpsv2_score.cpython-311.pyc ADDED
Binary file (7.41 kB). View file
 
evaluation/__pycache__/imagereward_score.cpython-311.pyc ADDED
Binary file (13 kB). View file
 
evaluation/__pycache__/pick_score.cpython-311.pyc ADDED
Binary file (9.76 kB). View file
 
evaluation/blip/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (216 Bytes). View file
 
evaluation/blip/__pycache__/blip.cpython-311.pyc ADDED
Binary file (4.02 kB). View file
 
evaluation/blip/__pycache__/blip_pretrain.cpython-311.pyc ADDED
Binary file (2.36 kB). View file
 
evaluation/blip/__pycache__/med.cpython-311.pyc ADDED
Binary file (46.9 kB). View file
 
evaluation/blip/__pycache__/vit.cpython-311.pyc ADDED
Binary file (24.6 kB). View file
 
evaluation/blip/med.py ADDED
@@ -0,0 +1,957 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''
2
+ * Adapted from BLIP (https://github.com/salesforce/BLIP)
3
+ * Based on huggingface code base
4
+ * https://github.com/huggingface/transformers/blob/v4.15.0/src/transformers/models/bert
5
+ '''
6
+
7
+ import math
8
+ from typing import Tuple
9
+
10
+ import torch
11
+ from torch import Tensor, device, nn
12
+ import torch.utils.checkpoint
13
+ from torch import nn
14
+ from torch.nn import CrossEntropyLoss
15
+
16
+ from transformers.activations import ACT2FN
17
+ from transformers.file_utils import (
18
+ ModelOutput,
19
+ )
20
+ from transformers.modeling_outputs import (
21
+ BaseModelOutputWithPastAndCrossAttentions,
22
+ BaseModelOutputWithPoolingAndCrossAttentions,
23
+ CausalLMOutputWithCrossAttentions,
24
+ MaskedLMOutput,
25
+ MultipleChoiceModelOutput,
26
+ NextSentencePredictorOutput,
27
+ QuestionAnsweringModelOutput,
28
+ SequenceClassifierOutput,
29
+ TokenClassifierOutput,
30
+ )
31
+ from transformers.modeling_utils import (
32
+ PreTrainedModel,
33
+ )
34
+ try:
35
+ # transformers>=4.57 moved these helpers from modeling_utils to pytorch_utils
36
+ from transformers.pytorch_utils import (
37
+ apply_chunking_to_forward,
38
+ find_pruneable_heads_and_indices,
39
+ prune_linear_layer,
40
+ )
41
+ except ImportError:
42
+ from transformers.modeling_utils import (
43
+ apply_chunking_to_forward,
44
+ find_pruneable_heads_and_indices,
45
+ prune_linear_layer,
46
+ )
47
+ from transformers.utils import logging
48
+ from transformers.models.bert.configuration_bert import BertConfig
49
+
50
+
51
+ logger = logging.get_logger(__name__)
52
+
53
+
54
+ class BertEmbeddings(nn.Module):
55
+ """Construct the embeddings from word and position embeddings."""
56
+
57
+ def __init__(self, config):
58
+ super().__init__()
59
+ self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
60
+ self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)
61
+
62
+ # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load
63
+ # any TensorFlow checkpoint file
64
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
65
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
66
+
67
+ # position_ids (1, len position emb) is contiguous in memory and exported when serialized
68
+ self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)))
69
+ self.position_embedding_type = getattr(config, "position_embedding_type", "absolute")
70
+
71
+ self.config = config
72
+
73
+ def forward(
74
+ self, input_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0
75
+ ):
76
+ if input_ids is not None:
77
+ input_shape = input_ids.size()
78
+ else:
79
+ input_shape = inputs_embeds.size()[:-1]
80
+
81
+ seq_length = input_shape[1]
82
+
83
+ if position_ids is None:
84
+ position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length]
85
+
86
+ if inputs_embeds is None:
87
+ inputs_embeds = self.word_embeddings(input_ids)
88
+
89
+ embeddings = inputs_embeds
90
+
91
+ if self.position_embedding_type == "absolute":
92
+ position_embeddings = self.position_embeddings(position_ids)
93
+ embeddings += position_embeddings
94
+ embeddings = self.LayerNorm(embeddings)
95
+ embeddings = self.dropout(embeddings)
96
+ return embeddings
97
+
98
+
99
+ class BertSelfAttention(nn.Module):
100
+ def __init__(self, config, is_cross_attention):
101
+ super().__init__()
102
+ self.config = config
103
+ if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
104
+ raise ValueError(
105
+ "The hidden size (%d) is not a multiple of the number of attention "
106
+ "heads (%d)" % (config.hidden_size, config.num_attention_heads)
107
+ )
108
+
109
+ self.num_attention_heads = config.num_attention_heads
110
+ self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
111
+ self.all_head_size = self.num_attention_heads * self.attention_head_size
112
+
113
+ self.query = nn.Linear(config.hidden_size, self.all_head_size)
114
+ if is_cross_attention:
115
+ self.key = nn.Linear(config.encoder_width, self.all_head_size)
116
+ self.value = nn.Linear(config.encoder_width, self.all_head_size)
117
+ else:
118
+ self.key = nn.Linear(config.hidden_size, self.all_head_size)
119
+ self.value = nn.Linear(config.hidden_size, self.all_head_size)
120
+
121
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
122
+ self.position_embedding_type = getattr(config, "position_embedding_type", "absolute")
123
+ if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query":
124
+ self.max_position_embeddings = config.max_position_embeddings
125
+ self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size)
126
+ self.save_attention = False
127
+
128
+ def save_attn_gradients(self, attn_gradients):
129
+ self.attn_gradients = attn_gradients
130
+
131
+ def get_attn_gradients(self):
132
+ return self.attn_gradients
133
+
134
+ def save_attention_map(self, attention_map):
135
+ self.attention_map = attention_map
136
+
137
+ def get_attention_map(self):
138
+ return self.attention_map
139
+
140
+ def transpose_for_scores(self, x):
141
+ new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size)
142
+ x = x.view(*new_x_shape)
143
+ return x.permute(0, 2, 1, 3)
144
+
145
+ def forward(
146
+ self,
147
+ hidden_states,
148
+ attention_mask=None,
149
+ head_mask=None,
150
+ encoder_hidden_states=None,
151
+ encoder_attention_mask=None,
152
+ past_key_value=None,
153
+ output_attentions=False,
154
+ ):
155
+ mixed_query_layer = self.query(hidden_states)
156
+
157
+ # If this is instantiated as a cross-attention module, the keys
158
+ # and values come from an encoder; the attention mask needs to be
159
+ # such that the encoder's padding tokens are not attended to.
160
+ is_cross_attention = encoder_hidden_states is not None
161
+
162
+ if is_cross_attention:
163
+ key_layer = self.transpose_for_scores(self.key(encoder_hidden_states))
164
+ value_layer = self.transpose_for_scores(self.value(encoder_hidden_states))
165
+ attention_mask = encoder_attention_mask
166
+ elif past_key_value is not None:
167
+ key_layer = self.transpose_for_scores(self.key(hidden_states))
168
+ value_layer = self.transpose_for_scores(self.value(hidden_states))
169
+ key_layer = torch.cat([past_key_value[0], key_layer], dim=2)
170
+ value_layer = torch.cat([past_key_value[1], value_layer], dim=2)
171
+ else:
172
+ key_layer = self.transpose_for_scores(self.key(hidden_states))
173
+ value_layer = self.transpose_for_scores(self.value(hidden_states))
174
+
175
+ query_layer = self.transpose_for_scores(mixed_query_layer)
176
+
177
+ past_key_value = (key_layer, value_layer)
178
+
179
+ # Take the dot product between "query" and "key" to get the raw attention scores.
180
+ attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))
181
+
182
+ if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query":
183
+ seq_length = hidden_states.size()[1]
184
+ position_ids_l = torch.arange(seq_length, dtype=torch.long, device=hidden_states.device).view(-1, 1)
185
+ position_ids_r = torch.arange(seq_length, dtype=torch.long, device=hidden_states.device).view(1, -1)
186
+ distance = position_ids_l - position_ids_r
187
+ positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1)
188
+ positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility
189
+
190
+ if self.position_embedding_type == "relative_key":
191
+ relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding)
192
+ attention_scores = attention_scores + relative_position_scores
193
+ elif self.position_embedding_type == "relative_key_query":
194
+ relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding)
195
+ relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding)
196
+ attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key
197
+
198
+ attention_scores = attention_scores / math.sqrt(self.attention_head_size)
199
+ if attention_mask is not None:
200
+ # Apply the attention mask is (precomputed for all layers in BertModel forward() function)
201
+ attention_scores = attention_scores + attention_mask
202
+
203
+ # Normalize the attention scores to probabilities.
204
+ attention_probs = nn.Softmax(dim=-1)(attention_scores)
205
+
206
+ if is_cross_attention and self.save_attention:
207
+ self.save_attention_map(attention_probs)
208
+ attention_probs.register_hook(self.save_attn_gradients)
209
+
210
+ # This is actually dropping out entire tokens to attend to, which might
211
+ # seem a bit unusual, but is taken from the original Transformer paper.
212
+ attention_probs_dropped = self.dropout(attention_probs)
213
+
214
+ # Mask heads if we want to
215
+ if head_mask is not None:
216
+ attention_probs_dropped = attention_probs_dropped * head_mask
217
+
218
+ context_layer = torch.matmul(attention_probs_dropped, value_layer)
219
+
220
+ context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
221
+ new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
222
+ context_layer = context_layer.view(*new_context_layer_shape)
223
+
224
+ outputs = (context_layer, attention_probs) if output_attentions else (context_layer,)
225
+
226
+ outputs = outputs + (past_key_value,)
227
+ return outputs
228
+
229
+
230
+ class BertSelfOutput(nn.Module):
231
+ def __init__(self, config):
232
+ super().__init__()
233
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
234
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
235
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
236
+
237
+ def forward(self, hidden_states, input_tensor):
238
+ hidden_states = self.dense(hidden_states)
239
+ hidden_states = self.dropout(hidden_states)
240
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
241
+ return hidden_states
242
+
243
+
244
+ class BertAttention(nn.Module):
245
+ def __init__(self, config, is_cross_attention=False):
246
+ super().__init__()
247
+ self.self = BertSelfAttention(config, is_cross_attention)
248
+ self.output = BertSelfOutput(config)
249
+ self.pruned_heads = set()
250
+
251
+ def prune_heads(self, heads):
252
+ if len(heads) == 0:
253
+ return
254
+ heads, index = find_pruneable_heads_and_indices(
255
+ heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads
256
+ )
257
+
258
+ # Prune linear layers
259
+ self.self.query = prune_linear_layer(self.self.query, index)
260
+ self.self.key = prune_linear_layer(self.self.key, index)
261
+ self.self.value = prune_linear_layer(self.self.value, index)
262
+ self.output.dense = prune_linear_layer(self.output.dense, index, dim=1)
263
+
264
+ # Update hyper params and store pruned heads
265
+ self.self.num_attention_heads = self.self.num_attention_heads - len(heads)
266
+ self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads
267
+ self.pruned_heads = self.pruned_heads.union(heads)
268
+
269
+ def forward(
270
+ self,
271
+ hidden_states,
272
+ attention_mask=None,
273
+ head_mask=None,
274
+ encoder_hidden_states=None,
275
+ encoder_attention_mask=None,
276
+ past_key_value=None,
277
+ output_attentions=False,
278
+ ):
279
+ self_outputs = self.self(
280
+ hidden_states,
281
+ attention_mask,
282
+ head_mask,
283
+ encoder_hidden_states,
284
+ encoder_attention_mask,
285
+ past_key_value,
286
+ output_attentions,
287
+ )
288
+ attention_output = self.output(self_outputs[0], hidden_states)
289
+ outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them
290
+ return outputs
291
+
292
+
293
+ class BertIntermediate(nn.Module):
294
+ def __init__(self, config):
295
+ super().__init__()
296
+ self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
297
+ if isinstance(config.hidden_act, str):
298
+ self.intermediate_act_fn = ACT2FN[config.hidden_act]
299
+ else:
300
+ self.intermediate_act_fn = config.hidden_act
301
+
302
+ def forward(self, hidden_states):
303
+ hidden_states = self.dense(hidden_states)
304
+ hidden_states = self.intermediate_act_fn(hidden_states)
305
+ return hidden_states
306
+
307
+
308
+ class BertOutput(nn.Module):
309
+ def __init__(self, config):
310
+ super().__init__()
311
+ self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
312
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
313
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
314
+
315
+ def forward(self, hidden_states, input_tensor):
316
+ hidden_states = self.dense(hidden_states)
317
+ hidden_states = self.dropout(hidden_states)
318
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
319
+ return hidden_states
320
+
321
+
322
+ class BertLayer(nn.Module):
323
+ def __init__(self, config, layer_num):
324
+ super().__init__()
325
+ self.config = config
326
+ self.chunk_size_feed_forward = config.chunk_size_feed_forward
327
+ self.seq_len_dim = 1
328
+ self.attention = BertAttention(config)
329
+ self.layer_num = layer_num
330
+ if self.config.add_cross_attention:
331
+ self.crossattention = BertAttention(config, is_cross_attention=self.config.add_cross_attention)
332
+ self.intermediate = BertIntermediate(config)
333
+ self.output = BertOutput(config)
334
+
335
+ def forward(
336
+ self,
337
+ hidden_states,
338
+ attention_mask=None,
339
+ head_mask=None,
340
+ encoder_hidden_states=None,
341
+ encoder_attention_mask=None,
342
+ past_key_value=None,
343
+ output_attentions=False,
344
+ mode=None,
345
+ ):
346
+ # decoder uni-directional self-attention cached key/values tuple is at positions 1,2
347
+ self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None
348
+ self_attention_outputs = self.attention(
349
+ hidden_states,
350
+ attention_mask,
351
+ head_mask,
352
+ output_attentions=output_attentions,
353
+ past_key_value=self_attn_past_key_value,
354
+ )
355
+ attention_output = self_attention_outputs[0]
356
+
357
+ outputs = self_attention_outputs[1:-1]
358
+ present_key_value = self_attention_outputs[-1]
359
+
360
+ if mode=='multimodal':
361
+ assert encoder_hidden_states is not None, "encoder_hidden_states must be given for cross-attention layers"
362
+
363
+ cross_attention_outputs = self.crossattention(
364
+ attention_output,
365
+ attention_mask,
366
+ head_mask,
367
+ encoder_hidden_states,
368
+ encoder_attention_mask,
369
+ output_attentions=output_attentions,
370
+ )
371
+ attention_output = cross_attention_outputs[0]
372
+ outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights
373
+ layer_output = apply_chunking_to_forward(
374
+ self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output
375
+ )
376
+ outputs = (layer_output,) + outputs
377
+
378
+ outputs = outputs + (present_key_value,)
379
+
380
+ return outputs
381
+
382
+ def feed_forward_chunk(self, attention_output):
383
+ intermediate_output = self.intermediate(attention_output)
384
+ layer_output = self.output(intermediate_output, attention_output)
385
+ return layer_output
386
+
387
+
388
+ class BertEncoder(nn.Module):
389
+ def __init__(self, config):
390
+ super().__init__()
391
+ self.config = config
392
+ self.layer = nn.ModuleList([BertLayer(config,i) for i in range(config.num_hidden_layers)])
393
+ self.gradient_checkpointing = False
394
+
395
+ def forward(
396
+ self,
397
+ hidden_states,
398
+ attention_mask=None,
399
+ head_mask=None,
400
+ encoder_hidden_states=None,
401
+ encoder_attention_mask=None,
402
+ past_key_values=None,
403
+ use_cache=None,
404
+ output_attentions=False,
405
+ output_hidden_states=False,
406
+ return_dict=True,
407
+ mode='multimodal',
408
+ ):
409
+ all_hidden_states = () if output_hidden_states else None
410
+ all_self_attentions = () if output_attentions else None
411
+ all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None
412
+
413
+ next_decoder_cache = () if use_cache else None
414
+
415
+ for i in range(self.config.num_hidden_layers):
416
+ layer_module = self.layer[i]
417
+ if output_hidden_states:
418
+ all_hidden_states = all_hidden_states + (hidden_states,)
419
+
420
+ layer_head_mask = head_mask[i] if head_mask is not None else None
421
+ past_key_value = past_key_values[i] if past_key_values is not None else None
422
+
423
+ if self.gradient_checkpointing and self.training:
424
+
425
+ if use_cache:
426
+ logger.warn(
427
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
428
+ )
429
+ use_cache = False
430
+
431
+ def create_custom_forward(module):
432
+ def custom_forward(*inputs):
433
+ return module(*inputs, past_key_value, output_attentions)
434
+
435
+ return custom_forward
436
+
437
+ layer_outputs = torch.utils.checkpoint.checkpoint(
438
+ create_custom_forward(layer_module),
439
+ hidden_states,
440
+ attention_mask,
441
+ layer_head_mask,
442
+ encoder_hidden_states,
443
+ encoder_attention_mask,
444
+ mode=mode,
445
+ )
446
+ else:
447
+ layer_outputs = layer_module(
448
+ hidden_states,
449
+ attention_mask,
450
+ layer_head_mask,
451
+ encoder_hidden_states,
452
+ encoder_attention_mask,
453
+ past_key_value,
454
+ output_attentions,
455
+ mode=mode,
456
+ )
457
+
458
+ hidden_states = layer_outputs[0]
459
+ if use_cache:
460
+ next_decoder_cache += (layer_outputs[-1],)
461
+ if output_attentions:
462
+ all_self_attentions = all_self_attentions + (layer_outputs[1],)
463
+
464
+ if output_hidden_states:
465
+ all_hidden_states = all_hidden_states + (hidden_states,)
466
+
467
+ if not return_dict:
468
+ return tuple(
469
+ v
470
+ for v in [
471
+ hidden_states,
472
+ next_decoder_cache,
473
+ all_hidden_states,
474
+ all_self_attentions,
475
+ all_cross_attentions,
476
+ ]
477
+ if v is not None
478
+ )
479
+ return BaseModelOutputWithPastAndCrossAttentions(
480
+ last_hidden_state=hidden_states,
481
+ past_key_values=next_decoder_cache,
482
+ hidden_states=all_hidden_states,
483
+ attentions=all_self_attentions,
484
+ cross_attentions=all_cross_attentions,
485
+ )
486
+
487
+
488
+ class BertPooler(nn.Module):
489
+ def __init__(self, config):
490
+ super().__init__()
491
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
492
+ self.activation = nn.Tanh()
493
+
494
+ def forward(self, hidden_states):
495
+ # We "pool" the model by simply taking the hidden state corresponding
496
+ # to the first token.
497
+ first_token_tensor = hidden_states[:, 0]
498
+ pooled_output = self.dense(first_token_tensor)
499
+ pooled_output = self.activation(pooled_output)
500
+ return pooled_output
501
+
502
+
503
+ class BertPredictionHeadTransform(nn.Module):
504
+ def __init__(self, config):
505
+ super().__init__()
506
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
507
+ if isinstance(config.hidden_act, str):
508
+ self.transform_act_fn = ACT2FN[config.hidden_act]
509
+ else:
510
+ self.transform_act_fn = config.hidden_act
511
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
512
+
513
+ def forward(self, hidden_states):
514
+ hidden_states = self.dense(hidden_states)
515
+ hidden_states = self.transform_act_fn(hidden_states)
516
+ hidden_states = self.LayerNorm(hidden_states)
517
+ return hidden_states
518
+
519
+
520
+ class BertLMPredictionHead(nn.Module):
521
+ def __init__(self, config):
522
+ super().__init__()
523
+ self.transform = BertPredictionHeadTransform(config)
524
+
525
+ # The output weights are the same as the input embeddings, but there is
526
+ # an output-only bias for each token.
527
+ self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
528
+
529
+ self.bias = nn.Parameter(torch.zeros(config.vocab_size))
530
+
531
+ # Need a link between the two variables so that the bias is correctly resized with `resize_token_embeddings`
532
+ self.decoder.bias = self.bias
533
+
534
+ def forward(self, hidden_states):
535
+ hidden_states = self.transform(hidden_states)
536
+ hidden_states = self.decoder(hidden_states)
537
+ return hidden_states
538
+
539
+
540
+ class BertOnlyMLMHead(nn.Module):
541
+ def __init__(self, config):
542
+ super().__init__()
543
+ self.predictions = BertLMPredictionHead(config)
544
+
545
+ def forward(self, sequence_output):
546
+ prediction_scores = self.predictions(sequence_output)
547
+ return prediction_scores
548
+
549
+
550
+ class BertPreTrainedModel(PreTrainedModel):
551
+ """
552
+ An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
553
+ models.
554
+ """
555
+
556
+ config_class = BertConfig
557
+ base_model_prefix = "bert"
558
+ _keys_to_ignore_on_load_missing = [r"position_ids"]
559
+
560
+ def _init_weights(self, module):
561
+ """ Initialize the weights """
562
+ if isinstance(module, (nn.Linear, nn.Embedding)):
563
+ # Slightly different from the TF version which uses truncated_normal for initialization
564
+ # cf https://github.com/pytorch/pytorch/pull/5617
565
+ module.weight.data.normal_(mean=0.0, std=self.config.initializer_range)
566
+ elif isinstance(module, nn.LayerNorm):
567
+ module.bias.data.zero_()
568
+ module.weight.data.fill_(1.0)
569
+ if isinstance(module, nn.Linear) and module.bias is not None:
570
+ module.bias.data.zero_()
571
+
572
+
573
+ class BertModel(BertPreTrainedModel):
574
+ """
575
+ The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of
576
+ cross-attention is added between the self-attention layers, following the architecture described in `Attention is
577
+ all you need <https://arxiv.org/abs/1706.03762>`__ by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit,
578
+ Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin.
579
+ argument and :obj:`add_cross_attention` set to :obj:`True`; an :obj:`encoder_hidden_states` is then expected as an
580
+ input to the forward pass.
581
+ """
582
+
583
+ def __init__(self, config, add_pooling_layer=True):
584
+ super().__init__(config)
585
+ self.config = config
586
+
587
+ self.embeddings = BertEmbeddings(config)
588
+
589
+ self.encoder = BertEncoder(config)
590
+
591
+ self.pooler = BertPooler(config) if add_pooling_layer else None
592
+
593
+ self.init_weights()
594
+
595
+
596
+ def get_input_embeddings(self):
597
+ return self.embeddings.word_embeddings
598
+
599
+ def set_input_embeddings(self, value):
600
+ self.embeddings.word_embeddings = value
601
+
602
+ def _prune_heads(self, heads_to_prune):
603
+ """
604
+ Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base
605
+ class PreTrainedModel
606
+ """
607
+ for layer, heads in heads_to_prune.items():
608
+ self.encoder.layer[layer].attention.prune_heads(heads)
609
+
610
+
611
+ def get_extended_attention_mask(self, attention_mask: Tensor, input_shape: Tuple[int], device: device, is_decoder: bool) -> Tensor:
612
+ """
613
+ Makes broadcastable attention and causal masks so that future and masked tokens are ignored.
614
+
615
+ Arguments:
616
+ attention_mask (:obj:`torch.Tensor`):
617
+ Mask with ones indicating tokens to attend to, zeros for tokens to ignore.
618
+ input_shape (:obj:`Tuple[int]`):
619
+ The shape of the input to the model.
620
+ device: (:obj:`torch.device`):
621
+ The device of the input to the model.
622
+
623
+ Returns:
624
+ :obj:`torch.Tensor` The extended attention mask, with a the same dtype as :obj:`attention_mask.dtype`.
625
+ """
626
+ # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
627
+ # ourselves in which case we just need to make it broadcastable to all heads.
628
+ if attention_mask.dim() == 3:
629
+ extended_attention_mask = attention_mask[:, None, :, :]
630
+ elif attention_mask.dim() == 2:
631
+ # Provided a padding mask of dimensions [batch_size, seq_length]
632
+ # - if the model is a decoder, apply a causal mask in addition to the padding mask
633
+ # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, seq_length, seq_length]
634
+ if is_decoder:
635
+ batch_size, seq_length = input_shape
636
+
637
+ seq_ids = torch.arange(seq_length, device=device)
638
+ causal_mask = seq_ids[None, None, :].repeat(batch_size, seq_length, 1) <= seq_ids[None, :, None]
639
+ # in case past_key_values are used we need to add a prefix ones mask to the causal mask
640
+ # causal and attention masks must have same type with pytorch version < 1.3
641
+ causal_mask = causal_mask.to(attention_mask.dtype)
642
+
643
+ if causal_mask.shape[1] < attention_mask.shape[1]:
644
+ prefix_seq_len = attention_mask.shape[1] - causal_mask.shape[1]
645
+ causal_mask = torch.cat(
646
+ [
647
+ torch.ones((batch_size, seq_length, prefix_seq_len), device=device, dtype=causal_mask.dtype),
648
+ causal_mask,
649
+ ],
650
+ axis=-1,
651
+ )
652
+
653
+ extended_attention_mask = causal_mask[:, None, :, :] * attention_mask[:, None, None, :]
654
+ else:
655
+ extended_attention_mask = attention_mask[:, None, None, :]
656
+ else:
657
+ raise ValueError(
658
+ "Wrong shape for input_ids (shape {}) or attention_mask (shape {})".format(
659
+ input_shape, attention_mask.shape
660
+ )
661
+ )
662
+
663
+ # Since attention_mask is 1.0 for positions we want to attend and 0.0 for
664
+ # masked positions, this operation will create a tensor which is 0.0 for
665
+ # positions we want to attend and -10000.0 for masked positions.
666
+ # Since we are adding it to the raw scores before the softmax, this is
667
+ # effectively the same as removing these entirely.
668
+ extended_attention_mask = extended_attention_mask.to(dtype=self.dtype) # fp16 compatibility
669
+ extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0
670
+ return extended_attention_mask
671
+
672
+ def forward(
673
+ self,
674
+ input_ids=None,
675
+ attention_mask=None,
676
+ position_ids=None,
677
+ head_mask=None,
678
+ inputs_embeds=None,
679
+ encoder_embeds=None,
680
+ encoder_hidden_states=None,
681
+ encoder_attention_mask=None,
682
+ past_key_values=None,
683
+ use_cache=None,
684
+ output_attentions=None,
685
+ output_hidden_states=None,
686
+ return_dict=None,
687
+ is_decoder=False,
688
+ mode='multimodal',
689
+ ):
690
+ r"""
691
+ encoder_hidden_states (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`):
692
+ Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if
693
+ the model is configured as a decoder.
694
+ encoder_attention_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
695
+ Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in
696
+ the cross-attention if the model is configured as a decoder. Mask values selected in ``[0, 1]``:
697
+ - 1 for tokens that are **not masked**,
698
+ - 0 for tokens that are **masked**.
699
+ past_key_values (:obj:`tuple(tuple(torch.FloatTensor))` of length :obj:`config.n_layers` with each tuple having 4 tensors of shape :obj:`(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
700
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
701
+ If :obj:`past_key_values` are used, the user can optionally input only the last :obj:`decoder_input_ids`
702
+ (those that don't have their past key value states given to this model) of shape :obj:`(batch_size, 1)`
703
+ instead of all :obj:`decoder_input_ids` of shape :obj:`(batch_size, sequence_length)`.
704
+ use_cache (:obj:`bool`, `optional`):
705
+ If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
706
+ decoding (see :obj:`past_key_values`).
707
+ """
708
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
709
+ output_hidden_states = (
710
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
711
+ )
712
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
713
+
714
+ if is_decoder:
715
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
716
+ else:
717
+ use_cache = False
718
+
719
+ if input_ids is not None and inputs_embeds is not None:
720
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
721
+ elif input_ids is not None:
722
+ input_shape = input_ids.size()
723
+ batch_size, seq_length = input_shape
724
+ device = input_ids.device
725
+ elif inputs_embeds is not None:
726
+ input_shape = inputs_embeds.size()[:-1]
727
+ batch_size, seq_length = input_shape
728
+ device = inputs_embeds.device
729
+ elif encoder_embeds is not None:
730
+ input_shape = encoder_embeds.size()[:-1]
731
+ batch_size, seq_length = input_shape
732
+ device = encoder_embeds.device
733
+ else:
734
+ raise ValueError("You have to specify either input_ids or inputs_embeds or encoder_embeds")
735
+
736
+ # past_key_values_length
737
+ past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0
738
+
739
+ if attention_mask is None:
740
+ attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device)
741
+
742
+ # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
743
+ # ourselves in which case we just need to make it broadcastable to all heads.
744
+ extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape,
745
+ device, is_decoder)
746
+
747
+ # If a 2D or 3D attention mask is provided for the cross-attention
748
+ # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length]
749
+ if encoder_hidden_states is not None:
750
+ if type(encoder_hidden_states) == list:
751
+ encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states[0].size()
752
+ else:
753
+ encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size()
754
+ encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length)
755
+
756
+ if type(encoder_attention_mask) == list:
757
+ encoder_extended_attention_mask = [self.invert_attention_mask(mask) for mask in encoder_attention_mask]
758
+ elif encoder_attention_mask is None:
759
+ encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device)
760
+ encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask)
761
+ else:
762
+ encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask)
763
+ else:
764
+ encoder_extended_attention_mask = None
765
+
766
+ # Prepare head mask if needed
767
+ # 1.0 in head_mask indicate we keep the head
768
+ # attention_probs has shape bsz x n_heads x N x N
769
+ # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads]
770
+ # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]
771
+ head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers)
772
+
773
+ if encoder_embeds is None:
774
+ embedding_output = self.embeddings(
775
+ input_ids=input_ids,
776
+ position_ids=position_ids,
777
+ inputs_embeds=inputs_embeds,
778
+ past_key_values_length=past_key_values_length,
779
+ )
780
+ else:
781
+ embedding_output = encoder_embeds
782
+
783
+ encoder_outputs = self.encoder(
784
+ embedding_output,
785
+ attention_mask=extended_attention_mask,
786
+ head_mask=head_mask,
787
+ encoder_hidden_states=encoder_hidden_states,
788
+ encoder_attention_mask=encoder_extended_attention_mask,
789
+ past_key_values=past_key_values,
790
+ use_cache=use_cache,
791
+ output_attentions=output_attentions,
792
+ output_hidden_states=output_hidden_states,
793
+ return_dict=return_dict,
794
+ mode=mode,
795
+ )
796
+ sequence_output = encoder_outputs[0]
797
+ pooled_output = self.pooler(sequence_output) if self.pooler is not None else None
798
+
799
+ if not return_dict:
800
+ return (sequence_output, pooled_output) + encoder_outputs[1:]
801
+
802
+ return BaseModelOutputWithPoolingAndCrossAttentions(
803
+ last_hidden_state=sequence_output,
804
+ pooler_output=pooled_output,
805
+ past_key_values=encoder_outputs.past_key_values,
806
+ hidden_states=encoder_outputs.hidden_states,
807
+ attentions=encoder_outputs.attentions,
808
+ cross_attentions=encoder_outputs.cross_attentions,
809
+ )
810
+
811
+
812
+
813
+ class BertLMHeadModel(BertPreTrainedModel):
814
+
815
+ _keys_to_ignore_on_load_unexpected = [r"pooler"]
816
+ _keys_to_ignore_on_load_missing = [r"position_ids", r"predictions.decoder.bias"]
817
+
818
+ def __init__(self, config):
819
+ super().__init__(config)
820
+
821
+ self.bert = BertModel(config, add_pooling_layer=False)
822
+ self.cls = BertOnlyMLMHead(config)
823
+
824
+ self.init_weights()
825
+
826
+ def get_output_embeddings(self):
827
+ return self.cls.predictions.decoder
828
+
829
+ def set_output_embeddings(self, new_embeddings):
830
+ self.cls.predictions.decoder = new_embeddings
831
+
832
+ def forward(
833
+ self,
834
+ input_ids=None,
835
+ attention_mask=None,
836
+ position_ids=None,
837
+ head_mask=None,
838
+ inputs_embeds=None,
839
+ encoder_hidden_states=None,
840
+ encoder_attention_mask=None,
841
+ labels=None,
842
+ past_key_values=None,
843
+ use_cache=None,
844
+ output_attentions=None,
845
+ output_hidden_states=None,
846
+ return_dict=None,
847
+ return_logits=False,
848
+ is_decoder=True,
849
+ reduction='mean',
850
+ mode='multimodal',
851
+ ):
852
+ r"""
853
+ encoder_hidden_states (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`):
854
+ Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if
855
+ the model is configured as a decoder.
856
+ encoder_attention_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
857
+ Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in
858
+ the cross-attention if the model is configured as a decoder. Mask values selected in ``[0, 1]``:
859
+ - 1 for tokens that are **not masked**,
860
+ - 0 for tokens that are **masked**.
861
+ labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
862
+ Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
863
+ ``[-100, 0, ..., config.vocab_size]`` (see ``input_ids`` docstring) Tokens with indices set to ``-100`` are
864
+ ignored (masked), the loss is only computed for the tokens with labels n ``[0, ..., config.vocab_size]``
865
+ past_key_values (:obj:`tuple(tuple(torch.FloatTensor))` of length :obj:`config.n_layers` with each tuple having 4 tensors of shape :obj:`(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
866
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
867
+ If :obj:`past_key_values` are used, the user can optionally input only the last :obj:`decoder_input_ids`
868
+ (those that don't have their past key value states given to this model) of shape :obj:`(batch_size, 1)`
869
+ instead of all :obj:`decoder_input_ids` of shape :obj:`(batch_size, sequence_length)`.
870
+ use_cache (:obj:`bool`, `optional`):
871
+ If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
872
+ decoding (see :obj:`past_key_values`).
873
+ Returns:
874
+ Example::
875
+ >>> from transformers import BertTokenizer, BertLMHeadModel, BertConfig
876
+ >>> import torch
877
+ >>> tokenizer = BertTokenizer.from_pretrained('bert-base-cased')
878
+ >>> config = BertConfig.from_pretrained("bert-base-cased")
879
+ >>> model = BertLMHeadModel.from_pretrained('bert-base-cased', config=config)
880
+ >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
881
+ >>> outputs = model(**inputs)
882
+ >>> prediction_logits = outputs.logits
883
+ """
884
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
885
+ if labels is not None:
886
+ use_cache = False
887
+
888
+ outputs = self.bert(
889
+ input_ids,
890
+ attention_mask=attention_mask,
891
+ position_ids=position_ids,
892
+ head_mask=head_mask,
893
+ inputs_embeds=inputs_embeds,
894
+ encoder_hidden_states=encoder_hidden_states,
895
+ encoder_attention_mask=encoder_attention_mask,
896
+ past_key_values=past_key_values,
897
+ use_cache=use_cache,
898
+ output_attentions=output_attentions,
899
+ output_hidden_states=output_hidden_states,
900
+ return_dict=return_dict,
901
+ is_decoder=is_decoder,
902
+ mode=mode,
903
+ )
904
+
905
+ sequence_output = outputs[0]
906
+ prediction_scores = self.cls(sequence_output)
907
+
908
+ if return_logits:
909
+ return prediction_scores[:, :-1, :].contiguous()
910
+
911
+ lm_loss = None
912
+ if labels is not None:
913
+ # we are doing next-token prediction; shift prediction scores and input ids by one
914
+ shifted_prediction_scores = prediction_scores[:, :-1, :].contiguous()
915
+ labels = labels[:, 1:].contiguous()
916
+ loss_fct = CrossEntropyLoss(reduction=reduction, label_smoothing=0.1)
917
+ lm_loss = loss_fct(shifted_prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
918
+ if reduction=='none':
919
+ lm_loss = lm_loss.view(prediction_scores.size(0),-1).sum(1)
920
+
921
+ if not return_dict:
922
+ output = (prediction_scores,) + outputs[2:]
923
+ return ((lm_loss,) + output) if lm_loss is not None else output
924
+
925
+ return CausalLMOutputWithCrossAttentions(
926
+ loss=lm_loss,
927
+ logits=prediction_scores,
928
+ past_key_values=outputs.past_key_values,
929
+ hidden_states=outputs.hidden_states,
930
+ attentions=outputs.attentions,
931
+ cross_attentions=outputs.cross_attentions,
932
+ )
933
+
934
+ def prepare_inputs_for_generation(self, input_ids, past=None, attention_mask=None, **model_kwargs):
935
+ input_shape = input_ids.shape
936
+ # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
937
+ if attention_mask is None:
938
+ attention_mask = input_ids.new_ones(input_shape)
939
+
940
+ # cut decoder_input_ids if past is used
941
+ if past is not None:
942
+ input_ids = input_ids[:, -1:]
943
+
944
+ return {
945
+ "input_ids": input_ids,
946
+ "attention_mask": attention_mask,
947
+ "past_key_values": past,
948
+ "encoder_hidden_states": model_kwargs.get("encoder_hidden_states", None),
949
+ "encoder_attention_mask": model_kwargs.get("encoder_attention_mask", None),
950
+ "is_decoder": True,
951
+ }
952
+
953
+ def _reorder_cache(self, past, beam_idx):
954
+ reordered_past = ()
955
+ for layer_past in past:
956
+ reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),)
957
+ return reordered_past
evaluation/blip/vit.py ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''
2
+ * Adapted from BLIP (https://github.com/salesforce/BLIP)
3
+ * Based on timm code base
4
+ * https://github.com/rwightman/pytorch-image-models/tree/master/timm
5
+ '''
6
+
7
+ import torch
8
+ import torch.nn as nn
9
+ import torch.nn.functional as F
10
+ from functools import partial
11
+
12
+ from timm.models.vision_transformer import _cfg, PatchEmbed
13
+ from timm.models.registry import register_model
14
+ from timm.models.layers import trunc_normal_, DropPath
15
+ from timm.models.helpers import named_apply, adapt_input_conv
16
+
17
+ try:
18
+ from fairscale.nn.checkpoint.checkpoint_activations import checkpoint_wrapper
19
+ except ImportError:
20
+ # Fallback when fairscale is unavailable: disable activation checkpoint wrapping.
21
+ def checkpoint_wrapper(module):
22
+ return module
23
+
24
+ class Mlp(nn.Module):
25
+ """ MLP as used in Vision Transformer, MLP-Mixer and related networks
26
+ """
27
+ def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):
28
+ super().__init__()
29
+ out_features = out_features or in_features
30
+ hidden_features = hidden_features or in_features
31
+ self.fc1 = nn.Linear(in_features, hidden_features)
32
+ self.act = act_layer()
33
+ self.fc2 = nn.Linear(hidden_features, out_features)
34
+ self.drop = nn.Dropout(drop)
35
+
36
+ def forward(self, x):
37
+ x = self.fc1(x)
38
+ x = self.act(x)
39
+ x = self.drop(x)
40
+ x = self.fc2(x)
41
+ x = self.drop(x)
42
+ return x
43
+
44
+
45
+ class Attention(nn.Module):
46
+ def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):
47
+ super().__init__()
48
+ self.num_heads = num_heads
49
+ head_dim = dim // num_heads
50
+ # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights
51
+ self.scale = qk_scale or head_dim ** -0.5
52
+ self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
53
+ self.attn_drop = nn.Dropout(attn_drop)
54
+ self.proj = nn.Linear(dim, dim)
55
+ self.proj_drop = nn.Dropout(proj_drop)
56
+ self.attn_gradients = None
57
+ self.attention_map = None
58
+
59
+ def save_attn_gradients(self, attn_gradients):
60
+ self.attn_gradients = attn_gradients
61
+
62
+ def get_attn_gradients(self):
63
+ return self.attn_gradients
64
+
65
+ def save_attention_map(self, attention_map):
66
+ self.attention_map = attention_map
67
+
68
+ def get_attention_map(self):
69
+ return self.attention_map
70
+
71
+ def forward(self, x, register_hook=False):
72
+ B, N, C = x.shape
73
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
74
+ q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple)
75
+
76
+ attn = (q @ k.transpose(-2, -1)) * self.scale
77
+ attn = attn.softmax(dim=-1)
78
+ attn = self.attn_drop(attn)
79
+
80
+ if register_hook:
81
+ self.save_attention_map(attn)
82
+ attn.register_hook(self.save_attn_gradients)
83
+
84
+ x = (attn @ v).transpose(1, 2).reshape(B, N, C)
85
+ x = self.proj(x)
86
+ x = self.proj_drop(x)
87
+ return x
88
+
89
+
90
+ class Block(nn.Module):
91
+
92
+ def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,
93
+ drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm, use_grad_checkpointing=False):
94
+ super().__init__()
95
+ self.norm1 = norm_layer(dim)
96
+ self.attn = Attention(
97
+ dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
98
+ # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
99
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
100
+ self.norm2 = norm_layer(dim)
101
+ mlp_hidden_dim = int(dim * mlp_ratio)
102
+ self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
103
+
104
+ if use_grad_checkpointing:
105
+ self.attn = checkpoint_wrapper(self.attn)
106
+ self.mlp = checkpoint_wrapper(self.mlp)
107
+
108
+ def forward(self, x, register_hook=False):
109
+ x = x + self.drop_path(self.attn(self.norm1(x), register_hook=register_hook))
110
+ x = x + self.drop_path(self.mlp(self.norm2(x)))
111
+ return x
112
+
113
+
114
+ class VisionTransformer(nn.Module):
115
+ """ Vision Transformer
116
+ A PyTorch impl of : `An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale` -
117
+ https://arxiv.org/abs/2010.11929
118
+ """
119
+ def __init__(self, img_size=224, patch_size=16, in_chans=3, num_classes=1000, embed_dim=768, depth=12,
120
+ num_heads=12, mlp_ratio=4., qkv_bias=True, qk_scale=None, representation_size=None,
121
+ drop_rate=0., attn_drop_rate=0., drop_path_rate=0., norm_layer=None,
122
+ use_grad_checkpointing=False, ckpt_layer=0):
123
+ """
124
+ Args:
125
+ img_size (int, tuple): input image size
126
+ patch_size (int, tuple): patch size
127
+ in_chans (int): number of input channels
128
+ num_classes (int): number of classes for classification head
129
+ embed_dim (int): embedding dimension
130
+ depth (int): depth of transformer
131
+ num_heads (int): number of attention heads
132
+ mlp_ratio (int): ratio of mlp hidden dim to embedding dim
133
+ qkv_bias (bool): enable bias for qkv if True
134
+ qk_scale (float): override default qk scale of head_dim ** -0.5 if set
135
+ representation_size (Optional[int]): enable and set representation layer (pre-logits) to this value if set
136
+ drop_rate (float): dropout rate
137
+ attn_drop_rate (float): attention dropout rate
138
+ drop_path_rate (float): stochastic depth rate
139
+ norm_layer: (nn.Module): normalization layer
140
+ """
141
+ super().__init__()
142
+ self.num_features = self.embed_dim = embed_dim # num_features for consistency with other models
143
+ norm_layer = norm_layer or partial(nn.LayerNorm, eps=1e-6)
144
+
145
+ self.patch_embed = PatchEmbed(
146
+ img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)
147
+
148
+ num_patches = self.patch_embed.num_patches
149
+
150
+ self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))
151
+ self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))
152
+ self.pos_drop = nn.Dropout(p=drop_rate)
153
+
154
+ dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)] # stochastic depth decay rule
155
+ self.blocks = nn.ModuleList([
156
+ Block(
157
+ dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,
158
+ drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,
159
+ use_grad_checkpointing=(use_grad_checkpointing and i>=depth-ckpt_layer)
160
+ )
161
+ for i in range(depth)])
162
+ self.norm = norm_layer(embed_dim)
163
+
164
+ trunc_normal_(self.pos_embed, std=.02)
165
+ trunc_normal_(self.cls_token, std=.02)
166
+ self.apply(self._init_weights)
167
+
168
+ def _init_weights(self, m):
169
+ if isinstance(m, nn.Linear):
170
+ trunc_normal_(m.weight, std=.02)
171
+ if isinstance(m, nn.Linear) and m.bias is not None:
172
+ nn.init.constant_(m.bias, 0)
173
+ elif isinstance(m, nn.LayerNorm):
174
+ nn.init.constant_(m.bias, 0)
175
+ nn.init.constant_(m.weight, 1.0)
176
+
177
+ @torch.jit.ignore
178
+ def no_weight_decay(self):
179
+ return {'pos_embed', 'cls_token'}
180
+
181
+ def forward(self, x, register_blk=-1):
182
+ B = x.shape[0]
183
+ x = self.patch_embed(x)
184
+
185
+ cls_tokens = self.cls_token.expand(B, -1, -1) # stole cls_tokens impl from Phil Wang, thanks
186
+ x = torch.cat((cls_tokens, x), dim=1)
187
+
188
+ x = x + self.pos_embed[:,:x.size(1),:]
189
+ x = self.pos_drop(x)
190
+
191
+ for i,blk in enumerate(self.blocks):
192
+ x = blk(x, register_blk==i)
193
+ x = self.norm(x)
194
+
195
+ return x
196
+
197
+ @torch.jit.ignore()
198
+ def load_pretrained(self, checkpoint_path, prefix=''):
199
+ _load_weights(self, checkpoint_path, prefix)
200
+
201
+
202
+ @torch.no_grad()
203
+ def _load_weights(model: VisionTransformer, checkpoint_path: str, prefix: str = ''):
204
+ """ Load weights from .npz checkpoints for official Google Brain Flax implementation
205
+ """
206
+ import numpy as np
207
+
208
+ def _n2p(w, t=True):
209
+ if w.ndim == 4 and w.shape[0] == w.shape[1] == w.shape[2] == 1:
210
+ w = w.flatten()
211
+ if t:
212
+ if w.ndim == 4:
213
+ w = w.transpose([3, 2, 0, 1])
214
+ elif w.ndim == 3:
215
+ w = w.transpose([2, 0, 1])
216
+ elif w.ndim == 2:
217
+ w = w.transpose([1, 0])
218
+ return torch.from_numpy(w)
219
+
220
+ w = np.load(checkpoint_path)
221
+ if not prefix and 'opt/target/embedding/kernel' in w:
222
+ prefix = 'opt/target/'
223
+
224
+ if hasattr(model.patch_embed, 'backbone'):
225
+ # hybrid
226
+ backbone = model.patch_embed.backbone
227
+ stem_only = not hasattr(backbone, 'stem')
228
+ stem = backbone if stem_only else backbone.stem
229
+ stem.conv.weight.copy_(adapt_input_conv(stem.conv.weight.shape[1], _n2p(w[f'{prefix}conv_root/kernel'])))
230
+ stem.norm.weight.copy_(_n2p(w[f'{prefix}gn_root/scale']))
231
+ stem.norm.bias.copy_(_n2p(w[f'{prefix}gn_root/bias']))
232
+ if not stem_only:
233
+ for i, stage in enumerate(backbone.stages):
234
+ for j, block in enumerate(stage.blocks):
235
+ bp = f'{prefix}block{i + 1}/unit{j + 1}/'
236
+ for r in range(3):
237
+ getattr(block, f'conv{r + 1}').weight.copy_(_n2p(w[f'{bp}conv{r + 1}/kernel']))
238
+ getattr(block, f'norm{r + 1}').weight.copy_(_n2p(w[f'{bp}gn{r + 1}/scale']))
239
+ getattr(block, f'norm{r + 1}').bias.copy_(_n2p(w[f'{bp}gn{r + 1}/bias']))
240
+ if block.downsample is not None:
241
+ block.downsample.conv.weight.copy_(_n2p(w[f'{bp}conv_proj/kernel']))
242
+ block.downsample.norm.weight.copy_(_n2p(w[f'{bp}gn_proj/scale']))
243
+ block.downsample.norm.bias.copy_(_n2p(w[f'{bp}gn_proj/bias']))
244
+ embed_conv_w = _n2p(w[f'{prefix}embedding/kernel'])
245
+ else:
246
+ embed_conv_w = adapt_input_conv(
247
+ model.patch_embed.proj.weight.shape[1], _n2p(w[f'{prefix}embedding/kernel']))
248
+ model.patch_embed.proj.weight.copy_(embed_conv_w)
249
+ model.patch_embed.proj.bias.copy_(_n2p(w[f'{prefix}embedding/bias']))
250
+ model.cls_token.copy_(_n2p(w[f'{prefix}cls'], t=False))
251
+ pos_embed_w = _n2p(w[f'{prefix}Transformer/posembed_input/pos_embedding'], t=False)
252
+ if pos_embed_w.shape != model.pos_embed.shape:
253
+ pos_embed_w = resize_pos_embed( # resize pos embedding when different size from pretrained weights
254
+ pos_embed_w, model.pos_embed, getattr(model, 'num_tokens', 1), model.patch_embed.grid_size)
255
+ model.pos_embed.copy_(pos_embed_w)
256
+ model.norm.weight.copy_(_n2p(w[f'{prefix}Transformer/encoder_norm/scale']))
257
+ model.norm.bias.copy_(_n2p(w[f'{prefix}Transformer/encoder_norm/bias']))
258
+ # if isinstance(model.head, nn.Linear) and model.head.bias.shape[0] == w[f'{prefix}head/bias'].shape[-1]:
259
+ # model.head.weight.copy_(_n2p(w[f'{prefix}head/kernel']))
260
+ # model.head.bias.copy_(_n2p(w[f'{prefix}head/bias']))
261
+ # if isinstance(getattr(model.pre_logits, 'fc', None), nn.Linear) and f'{prefix}pre_logits/bias' in w:
262
+ # model.pre_logits.fc.weight.copy_(_n2p(w[f'{prefix}pre_logits/kernel']))
263
+ # model.pre_logits.fc.bias.copy_(_n2p(w[f'{prefix}pre_logits/bias']))
264
+ for i, block in enumerate(model.blocks.children()):
265
+ block_prefix = f'{prefix}Transformer/encoderblock_{i}/'
266
+ mha_prefix = block_prefix + 'MultiHeadDotProductAttention_1/'
267
+ block.norm1.weight.copy_(_n2p(w[f'{block_prefix}LayerNorm_0/scale']))
268
+ block.norm1.bias.copy_(_n2p(w[f'{block_prefix}LayerNorm_0/bias']))
269
+ block.attn.qkv.weight.copy_(torch.cat([
270
+ _n2p(w[f'{mha_prefix}{n}/kernel'], t=False).flatten(1).T for n in ('query', 'key', 'value')]))
271
+ block.attn.qkv.bias.copy_(torch.cat([
272
+ _n2p(w[f'{mha_prefix}{n}/bias'], t=False).reshape(-1) for n in ('query', 'key', 'value')]))
273
+ block.attn.proj.weight.copy_(_n2p(w[f'{mha_prefix}out/kernel']).flatten(1))
274
+ block.attn.proj.bias.copy_(_n2p(w[f'{mha_prefix}out/bias']))
275
+ for r in range(2):
276
+ getattr(block.mlp, f'fc{r + 1}').weight.copy_(_n2p(w[f'{block_prefix}MlpBlock_3/Dense_{r}/kernel']))
277
+ getattr(block.mlp, f'fc{r + 1}').bias.copy_(_n2p(w[f'{block_prefix}MlpBlock_3/Dense_{r}/bias']))
278
+ block.norm2.weight.copy_(_n2p(w[f'{block_prefix}LayerNorm_2/scale']))
279
+ block.norm2.bias.copy_(_n2p(w[f'{block_prefix}LayerNorm_2/bias']))
280
+
281
+
282
+ def interpolate_pos_embed(pos_embed_checkpoint, visual_encoder):
283
+ # interpolate position embedding
284
+ embedding_size = pos_embed_checkpoint.shape[-1]
285
+ num_patches = visual_encoder.patch_embed.num_patches
286
+ num_extra_tokens = visual_encoder.pos_embed.shape[-2] - num_patches
287
+ # height (== width) for the checkpoint position embedding
288
+ orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)
289
+ # height (== width) for the new position embedding
290
+ new_size = int(num_patches ** 0.5)
291
+
292
+ if orig_size!=new_size:
293
+ # class_token and dist_token are kept unchanged
294
+ extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]
295
+ # only the position tokens are interpolated
296
+ pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]
297
+ pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)
298
+ pos_tokens = torch.nn.functional.interpolate(
299
+ pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)
300
+ pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)
301
+ new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)
302
+ print('reshape position embedding from %d to %d'%(orig_size ** 2,new_size ** 2))
303
+
304
+ return new_pos_embed
305
+ else:
306
+ return pos_embed_checkpoint
evaluation/hpsv2_score.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Adapted from https://github.com/tgxs002/HPSv2. Originally Apache License, Version 2.0, January 2004.
3
+ """
4
+
5
+ import torch
6
+ from open_clip import create_model_and_transforms, get_tokenizer
7
+ from PIL import Image
8
+
9
+
10
+ class HPSv2Scorer():
11
+ def __init__(self, clip_pretrained_name_or_path, model_pretrained_name_or_path, device='cuda'):
12
+ self.model, _, self.preprocess_val = create_model_and_transforms(
13
+ 'ViT-H-14',
14
+ # 'laion2B-s32B-b79K',
15
+ clip_pretrained_name_or_path,
16
+ precision='amp',
17
+ device=device,
18
+ jit=False,
19
+ force_quick_gelu=False,
20
+ force_custom_text=False,
21
+ force_patch_dropout=False,
22
+ force_image_size=None,
23
+ pretrained_image=False,
24
+ image_mean=None,
25
+ image_std=None,
26
+ light_augmentation=True,
27
+ aug_cfg={},
28
+ output_dict=True,
29
+ with_score_predictor=False,
30
+ with_region_predictor=False
31
+ )
32
+ self.device = device
33
+ checkpoint = torch.load(model_pretrained_name_or_path, map_location=device)
34
+ self.model.load_state_dict(checkpoint['state_dict'])
35
+ self.tokenizer = get_tokenizer('ViT-H-14')
36
+ self.model = self.model.to(device)
37
+
38
+
39
+ def score(self, img_path, prompt):
40
+
41
+ if isinstance(img_path, list):
42
+ result = []
43
+ for one_img_path in img_path:
44
+ # Load your image and prompt
45
+ with torch.no_grad():
46
+ # Process the image
47
+ if isinstance(one_img_path, str):
48
+ image = self.preprocess_val(Image.open(one_img_path)).unsqueeze(0).to(device=self.device, non_blocking=True)
49
+ elif isinstance(one_img_path, Image.Image):
50
+ image = self.preprocess_val(one_img_path).unsqueeze(0).to(device=self.device, non_blocking=True)
51
+ else:
52
+ raise TypeError('The type of parameter img_path is illegal.')
53
+ # Process the prompt
54
+ text = self.tokenizer([prompt]).to(device=self.device, non_blocking=True)
55
+ # Calculate the HPS
56
+ with torch.cuda.amp.autocast():
57
+ outputs = self.model(image, text)
58
+ image_features, text_features = outputs["image_features"], outputs["text_features"]
59
+ logits_per_image = image_features @ text_features.T
60
+
61
+ hps_score = torch.diagonal(logits_per_image).cpu().numpy()
62
+ result.append(hps_score[0])
63
+ return result
64
+ elif isinstance(img_path, str):
65
+ # Load your image and prompt
66
+ with torch.no_grad():
67
+ # Process the image
68
+ image = self.preprocess_val(Image.open(img_path)).unsqueeze(0).to(device=self.device, non_blocking=True)
69
+ # Process the prompt
70
+ text = self.tokenizer([prompt]).to(device=self.device, non_blocking=True)
71
+ # Calculate the HPS
72
+ with torch.cuda.amp.autocast():
73
+ outputs = self.model(image, text)
74
+ image_features, text_features = outputs["image_features"], outputs["text_features"]
75
+ logits_per_image = image_features @ text_features.T
76
+
77
+ hps_score = torch.diagonal(logits_per_image).cpu().numpy()
78
+ return [hps_score[0]]
79
+ elif isinstance(img_path, Image.Image):
80
+ # Load your image and prompt
81
+ with torch.no_grad():
82
+ # Process the image
83
+ image = self.preprocess_val(img_path).unsqueeze(0).to(device=self.device, non_blocking=True)
84
+ # Process the prompt
85
+ text = self.tokenizer([prompt]).to(device=self.device, non_blocking=True)
86
+ # Calculate the HPS
87
+ with torch.cuda.amp.autocast():
88
+ outputs = self.model(image, text)
89
+ image_features, text_features = outputs["image_features"], outputs["text_features"]
90
+ logits_per_image = image_features @ text_features.T
91
+
92
+ hps_score = torch.diagonal(logits_per_image).cpu().numpy()
93
+ return [hps_score[0]]
94
+ else:
95
+ raise TypeError('The type of parameter img_path is illegal.')
96
+
97
+
98
+ if __name__ == "__main__":
99
+ from huggingface_hub import hf_hub_download
100
+
101
+ clip_model_path = hf_hub_download(repo_id="laion/CLIP-ViT-H-14-laion2B-s32B-b79K", filename="open_clip_pytorch_model.bin")
102
+ hps_model_path = hf_hub_download(repo_id="xswu/HPSv2", filename="HPS_v2_compressed.pt")
103
+
104
+ hpsv2_scorer = HPSv2Scorer(clip_pretrained_name_or_path=clip_model_path,
105
+ model_pretrained_name_or_path=hps_model_path)
106
+ score = hpsv2_scorer.score(img_path=['./image0.png', './image1.png'],
107
+ prompt='photorealistic image of a lone painter standing in a gallery, watching an exhibition of paintings made entirely with AI. In the foreground of the image a robot looks proudly at his art')
108
+
109
+ print(score)
110
+
evaluation/imagereward_score.py ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Adapted from https://github.com/THUDM/ImageReward. Originally Apache License, Version 2.0, January 2004.
3
+ """
4
+
5
+ import os
6
+ import torch
7
+ import torch.nn as nn
8
+ from io import BytesIO
9
+ from PIL import Image
10
+ from blip.blip_pretrain import BLIP_Pretrain
11
+ from torchvision.transforms import Compose, Resize, CenterCrop, ToTensor, Normalize
12
+ from typing import Any, Union, List
13
+
14
+ try:
15
+ from torchvision.transforms import InterpolationMode
16
+ BICUBIC = InterpolationMode.BICUBIC
17
+ except ImportError:
18
+ BICUBIC = Image.BICUBIC
19
+
20
+
21
+ def open_image(image):
22
+ if isinstance(image, bytes):
23
+ image = Image.open(BytesIO(image))
24
+ elif isinstance(image, str):
25
+ image = Image.open(image)
26
+ image = image.convert("RGB")
27
+ return image
28
+
29
+
30
+ def _convert_image_to_rgb(image):
31
+ return image.convert("RGB")
32
+
33
+
34
+ def _transform(n_px):
35
+ return Compose([
36
+ Resize(n_px, interpolation=BICUBIC),
37
+ CenterCrop(n_px),
38
+ _convert_image_to_rgb,
39
+ ToTensor(),
40
+ Normalize((0.48145466, 0.4578275, 0.40821073), (0.26862954, 0.26130258, 0.27577711)),
41
+ ])
42
+
43
+
44
+ class MLP(nn.Module):
45
+ def __init__(self, input_size):
46
+ super().__init__()
47
+ self.input_size = input_size
48
+
49
+ self.layers = nn.Sequential(
50
+ nn.Linear(self.input_size, 1024),
51
+ #nn.ReLU(),
52
+ nn.Dropout(0.2),
53
+ nn.Linear(1024, 128),
54
+ #nn.ReLU(),
55
+ nn.Dropout(0.2),
56
+ nn.Linear(128, 64),
57
+ #nn.ReLU(),
58
+ nn.Dropout(0.1),
59
+ nn.Linear(64, 16),
60
+ #nn.ReLU(),
61
+ nn.Linear(16, 1)
62
+ )
63
+
64
+ # initial MLP param
65
+ for name, param in self.layers.named_parameters():
66
+ if 'weight' in name:
67
+ nn.init.normal_(param, mean=0.0, std=1.0/(self.input_size+1))
68
+ if 'bias' in name:
69
+ nn.init.constant_(param, val=0)
70
+
71
+ def forward(self, input):
72
+ return self.layers(input)
73
+
74
+
75
+ class ImageReward(nn.Module):
76
+ def __init__(self, med_config, device='cpu'):
77
+ super().__init__()
78
+ self.device = device
79
+
80
+ self.blip = BLIP_Pretrain(image_size=224, vit='large', med_config=med_config)
81
+ self.preprocess = _transform(224)
82
+ self.mlp = MLP(768)
83
+
84
+ self.mean = 0.16717362830052426
85
+ self.std = 1.0333394966054072
86
+
87
+
88
+ def score_gard(self, prompt_ids, prompt_attention_mask, image):
89
+
90
+ image_embeds = self.blip.visual_encoder(image)
91
+ # text encode cross attention with image
92
+ image_atts = torch.ones(image_embeds.size()[:-1],dtype=torch.long).to(self.device)
93
+ text_output = self.blip.text_encoder(prompt_ids,
94
+ attention_mask = prompt_attention_mask,
95
+ encoder_hidden_states = image_embeds,
96
+ encoder_attention_mask = image_atts,
97
+ return_dict = True,
98
+ )
99
+
100
+ txt_features = text_output.last_hidden_state[:,0,:] # (feature_dim)
101
+ rewards = self.mlp(txt_features)
102
+ rewards = (rewards - self.mean) / self.std
103
+
104
+ return rewards
105
+
106
+
107
+ def score(self, prompt, image):
108
+
109
+ if (type(image).__name__=='list'):
110
+ _, rewards = self.inference_rank(prompt, image)
111
+ return rewards
112
+
113
+ # text encode
114
+ text_input = self.blip.tokenizer(prompt, padding='max_length', truncation=True, max_length=35, return_tensors="pt").to(self.device)
115
+
116
+ # image encode
117
+ if isinstance(image, Image.Image):
118
+ pil_image = image
119
+ elif isinstance(image, str):
120
+ if os.path.isfile(image):
121
+ pil_image = Image.open(image)
122
+ else:
123
+ raise TypeError(r'This image parameter type has not been supportted yet. Please pass PIL.Image or file path str.')
124
+
125
+ image = self.preprocess(pil_image).unsqueeze(0).to(self.device)
126
+ image_embeds = self.blip.visual_encoder(image)
127
+
128
+ # text encode cross attention with image
129
+ image_atts = torch.ones(image_embeds.size()[:-1],dtype=torch.long).to(self.device)
130
+ text_output = self.blip.text_encoder(text_input.input_ids,
131
+ attention_mask = text_input.attention_mask,
132
+ encoder_hidden_states = image_embeds,
133
+ encoder_attention_mask = image_atts,
134
+ return_dict = True,
135
+ )
136
+
137
+ txt_features = text_output.last_hidden_state[:,0,:].float() # (feature_dim)
138
+ rewards = self.mlp(txt_features)
139
+ rewards = (rewards - self.mean) / self.std
140
+
141
+ return rewards.detach().cpu().numpy().item()
142
+
143
+
144
+ def inference_rank(self, prompt, generations_list):
145
+
146
+ text_input = self.blip.tokenizer(prompt, padding='max_length', truncation=True, max_length=35, return_tensors="pt").to(self.device)
147
+
148
+ txt_set = []
149
+ for generation in generations_list:
150
+ # image encode
151
+ if isinstance(generation, Image.Image):
152
+ pil_image = generation
153
+ elif isinstance(generation, str):
154
+ if os.path.isfile(generation):
155
+ pil_image = Image.open(generation)
156
+ else:
157
+ raise TypeError(r'This image parameter type has not been supportted yet. Please pass PIL.Image or file path str.')
158
+ image = self.preprocess(pil_image).unsqueeze(0).to(self.device)
159
+ image_embeds = self.blip.visual_encoder(image)
160
+
161
+ # text encode cross attention with image
162
+ image_atts = torch.ones(image_embeds.size()[:-1],dtype=torch.long).to(self.device)
163
+ text_output = self.blip.text_encoder(text_input.input_ids,
164
+ attention_mask = text_input.attention_mask,
165
+ encoder_hidden_states = image_embeds,
166
+ encoder_attention_mask = image_atts,
167
+ return_dict = True,
168
+ )
169
+ txt_set.append(text_output.last_hidden_state[:,0,:])
170
+
171
+ txt_features = torch.cat(txt_set, 0).float() # [image_num, feature_dim]
172
+ rewards = self.mlp(txt_features) # [image_num, 1]
173
+ rewards = (rewards - self.mean) / self.std
174
+ rewards = torch.squeeze(rewards)
175
+ _, rank = torch.sort(rewards, dim=0, descending=True)
176
+ _, indices = torch.sort(rank, dim=0)
177
+ indices = indices + 1
178
+
179
+ return indices.detach().cpu().numpy().tolist(), rewards.detach().cpu().numpy().tolist()
180
+
181
+
182
+ def load_imagereward(model_path: str, med_config: str = None, device: Union[str, torch.device] = "cuda" if torch.cuda.is_available() else "cpu"):
183
+ """Load a ImageReward model
184
+
185
+ Parameters
186
+ ----------
187
+ name : str
188
+ A model name listed by `ImageReward.available_models()`, or the path to a model checkpoint containing the state_dict
189
+
190
+ device : Union[str, torch.device]
191
+ The device to put the loaded model
192
+
193
+
194
+ Returns
195
+ -------
196
+ model : torch.nn.Module
197
+ The ImageReward model
198
+ """
199
+ print('load checkpoint from %s'%model_path)
200
+ state_dict = torch.load(model_path, map_location='cpu')
201
+
202
+ model = ImageReward(device=device, med_config=med_config).to(device)
203
+ msg = model.load_state_dict(state_dict, strict=False)
204
+ print("checkpoint loaded")
205
+ model.eval()
206
+
207
+ return model
208
+
209
+
210
+ if __name__ == '__main__':
211
+ from huggingface_hub import hf_hub_download
212
+
213
+ model_path = hf_hub_download(repo_id="THUDM/ImageReward", filename="ImageReward.pt")
214
+ config_path = hf_hub_download(repo_id="THUDM/ImageReward", filename="med_config.json")
215
+
216
+ image0 = open_image('./image0.png')
217
+ image1 = open_image('./image1.png')
218
+ prompt = "photorealistic image of a lone painter standing in a gallery, watching an exhibition of paintings made entirely with AI. In the foreground of the image a robot looks proudly at his art"
219
+ model = load_imagereward(model_path=model_path, med_config=config_path, device='cuda')
220
+
221
+ print(model.score(prompt, [image0, image1]))
evaluation/open_clip/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .coca_model import CoCa
2
+ from .constants import OPENAI_DATASET_MEAN, OPENAI_DATASET_STD
3
+ from .factory import create_model, create_model_and_transforms, create_model_from_pretrained, get_tokenizer, create_loss
4
+ from .factory import list_models, add_model_config, get_model_config, load_checkpoint
5
+ from .loss import ClipLoss, DistillClipLoss, CoCaLoss
6
+ from .model import CLIP, CustomTextCLIP, CLIPTextCfg, CLIPVisionCfg, \
7
+ convert_weights_to_lp, convert_weights_to_fp16, trace_model, get_cast_dtype
8
+ from .openai import load_openai_model, list_openai_models
9
+ from .pretrained import list_pretrained, list_pretrained_models_by_tag, list_pretrained_tags_by_model, \
10
+ get_pretrained_url, download_pretrained_from_url, is_pretrained_cfg, get_pretrained_cfg, download_pretrained
11
+ from .push_to_hf_hub import push_pretrained_to_hf_hub, push_to_hf_hub
12
+ from .tokenizer import SimpleTokenizer, tokenize, decode
13
+ from .transform import image_transform, AugmentationCfg
14
+ from .utils import freeze_batch_norm_2d
evaluation/open_clip/coca_model.py ADDED
@@ -0,0 +1,458 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import torch
4
+ from torch import nn
5
+ from torch.nn import functional as F
6
+ import numpy as np
7
+ from dataclasses import dataclass
8
+
9
+ from .transformer import (
10
+ LayerNormFp32,
11
+ LayerNorm,
12
+ QuickGELU,
13
+ MultimodalTransformer,
14
+ )
15
+ from .model import CLIPTextCfg, CLIPVisionCfg, _build_vision_tower, _build_text_tower
16
+
17
+ try:
18
+ from transformers import (
19
+ BeamSearchScorer,
20
+ LogitsProcessorList,
21
+ TopPLogitsWarper,
22
+ TopKLogitsWarper,
23
+ RepetitionPenaltyLogitsProcessor,
24
+ MinLengthLogitsProcessor,
25
+ MaxLengthCriteria,
26
+ StoppingCriteriaList
27
+ )
28
+
29
+ GENERATION_TYPES = {
30
+ "top_k": TopKLogitsWarper,
31
+ "top_p": TopPLogitsWarper,
32
+ "beam_search": "beam_search"
33
+ }
34
+ _has_transformers = True
35
+ except ImportError as e:
36
+ GENERATION_TYPES = {
37
+ "top_k": None,
38
+ "top_p": None,
39
+ "beam_search": "beam_search"
40
+ }
41
+ _has_transformers = False
42
+
43
+
44
+ @dataclass
45
+ class MultimodalCfg(CLIPTextCfg):
46
+ mlp_ratio: int = 4
47
+ dim_head: int = 64
48
+ heads: int = 8
49
+ n_queries: int = 256
50
+ attn_pooler_heads: int = 8
51
+
52
+
53
+ def _build_text_decoder_tower(
54
+ embed_dim,
55
+ multimodal_cfg,
56
+ quick_gelu: bool = False,
57
+ cast_dtype: Optional[torch.dtype] = None,
58
+ ):
59
+ multimodal_cfg = MultimodalCfg(**multimodal_cfg) if isinstance(multimodal_cfg, dict) else multimodal_cfg
60
+ act_layer = QuickGELU if quick_gelu else nn.GELU
61
+ norm_layer = (
62
+ LayerNormFp32 if cast_dtype in (torch.float16, torch.bfloat16) else LayerNorm
63
+ )
64
+
65
+ decoder = MultimodalTransformer(
66
+ context_length=multimodal_cfg.context_length,
67
+ width=multimodal_cfg.width,
68
+ heads=multimodal_cfg.heads,
69
+ layers=multimodal_cfg.layers,
70
+ ls_init_value=multimodal_cfg.ls_init_value,
71
+ output_dim=embed_dim,
72
+ act_layer=act_layer,
73
+ norm_layer=norm_layer,
74
+ )
75
+
76
+ return decoder
77
+
78
+
79
+ class CoCa(nn.Module):
80
+ def __init__(
81
+ self,
82
+ embed_dim,
83
+ multimodal_cfg: MultimodalCfg,
84
+ text_cfg: CLIPTextCfg,
85
+ vision_cfg: CLIPVisionCfg,
86
+ quick_gelu: bool = False,
87
+ cast_dtype: Optional[torch.dtype] = None,
88
+ pad_id: int = 0,
89
+ ):
90
+ super().__init__()
91
+ multimodal_cfg = MultimodalCfg(**multimodal_cfg) if isinstance(multimodal_cfg, dict) else multimodal_cfg
92
+ text_cfg = CLIPTextCfg(**text_cfg) if isinstance(text_cfg, dict) else text_cfg
93
+ vision_cfg = CLIPVisionCfg(**vision_cfg) if isinstance(vision_cfg, dict) else vision_cfg
94
+
95
+ self.text = _build_text_tower(
96
+ embed_dim=embed_dim,
97
+ text_cfg=text_cfg,
98
+ quick_gelu=quick_gelu,
99
+ cast_dtype=cast_dtype,
100
+ )
101
+
102
+ vocab_size = (
103
+ text_cfg.vocab_size # for hf models
104
+ if hasattr(text_cfg, "hf_model_name") and text_cfg.hf_model_name is not None
105
+ else text_cfg.vocab_size
106
+ )
107
+
108
+ self.visual = _build_vision_tower(
109
+ embed_dim=embed_dim,
110
+ vision_cfg=vision_cfg,
111
+ quick_gelu=quick_gelu,
112
+ cast_dtype=cast_dtype,
113
+ )
114
+
115
+ self.text_decoder = _build_text_decoder_tower(
116
+ vocab_size,
117
+ multimodal_cfg=multimodal_cfg,
118
+ quick_gelu=quick_gelu,
119
+ cast_dtype=cast_dtype,
120
+ )
121
+
122
+ self.logit_scale = nn.Parameter(torch.ones([]) * np.log(1 / 0.07))
123
+ self.pad_id = pad_id
124
+
125
+ @torch.jit.ignore
126
+ def set_grad_checkpointing(self, enable=True):
127
+ self.visual.set_grad_checkpointing(enable)
128
+ self.text.set_grad_checkpointing(enable)
129
+ self.text_decoder.set_grad_checkpointing(enable)
130
+
131
+ def _encode_image(self, images, normalize=True):
132
+ image_latent, tokens_embs = self.visual(images)
133
+ image_latent = F.normalize(image_latent, dim=-1) if normalize else image_latent
134
+ return image_latent, tokens_embs
135
+
136
+ def _encode_text(self, text, normalize=True, embed_cls=True):
137
+ text = text[:, :-1] if embed_cls else text # make space for CLS token
138
+ text_latent, token_emb = self.text(text)
139
+ text_latent = F.normalize(text_latent, dim=-1) if normalize else text_latent
140
+ return text_latent, token_emb
141
+
142
+ def encode_image(self, images, normalize=True):
143
+ image_latent, _ = self._encode_image(images, normalize=normalize)
144
+ return image_latent
145
+
146
+ def encode_text(self, text, normalize=True, embed_cls=True):
147
+ text_latent, _ = self._encode_text(text, normalize=normalize, embed_cls=embed_cls)
148
+ return text_latent
149
+
150
+ def forward(self, image, text, embed_cls=True, image_latent=None, image_embs=None):
151
+ text_latent, token_embs = self._encode_text(text, embed_cls=embed_cls)
152
+ if image_latent is None or image_embs is None:
153
+ image_latent, image_embs = self._encode_image(image)
154
+
155
+ # TODO: add assertion to avoid bugs?
156
+ labels = text[:, -token_embs.shape[1]:]
157
+
158
+ logits = self.text_decoder(image_embs, token_embs)
159
+ return {
160
+ "image_features": image_latent,
161
+ "text_features": text_latent,
162
+ "logits": logits,
163
+ "labels": labels,
164
+ "logit_scale": self.logit_scale.exp()
165
+ }
166
+
167
+ def generate(
168
+ self,
169
+ image,
170
+ text=None,
171
+ seq_len=30,
172
+ max_seq_len=77,
173
+ temperature=1.,
174
+ generation_type="beam_search",
175
+ top_p=0.1, # keep tokens in the 1 - top_p quantile
176
+ top_k=1, # keeps the top_k most probable tokens
177
+ pad_token_id=None,
178
+ eos_token_id=None,
179
+ sot_token_id=None,
180
+ num_beams=6,
181
+ num_beam_groups=3,
182
+ min_seq_len=5,
183
+ stopping_criteria=None,
184
+ repetition_penalty=1.0,
185
+ fixed_output_length=False # if True output.shape == (batch_size, seq_len)
186
+ ):
187
+ # taking many ideas and components from HuggingFace GenerationMixin
188
+ # https://huggingface.co/docs/transformers/main/en/main_classes/text_generation
189
+ assert _has_transformers, "Please install transformers for generate functionality. `pip install transformers`."
190
+ assert seq_len > min_seq_len, "seq_len must be larger than min_seq_len"
191
+
192
+ with torch.no_grad():
193
+ sot_token_id = 49406 if sot_token_id is None else sot_token_id
194
+ eos_token_id = 49407 if eos_token_id is None else eos_token_id
195
+ pad_token_id = self.pad_id if pad_token_id is None else pad_token_id
196
+ logit_processor = LogitsProcessorList(
197
+ [
198
+ MinLengthLogitsProcessor(min_seq_len, eos_token_id),
199
+ RepetitionPenaltyLogitsProcessor(repetition_penalty),
200
+ ]
201
+ )
202
+
203
+ if stopping_criteria is None:
204
+ stopping_criteria = [MaxLengthCriteria(max_length=seq_len)]
205
+
206
+ stopping_criteria = StoppingCriteriaList(
207
+ stopping_criteria
208
+ )
209
+
210
+ device = image.device
211
+
212
+ if generation_type == "beam_search":
213
+ output = self._generate_beamsearch(
214
+ image_inputs = image,
215
+ pad_token_id=pad_token_id,
216
+ eos_token_id=eos_token_id,
217
+ sot_token_id=sot_token_id,
218
+ num_beams=num_beams,
219
+ num_beam_groups=num_beam_groups,
220
+ min_seq_len=min_seq_len,
221
+ stopping_criteria=stopping_criteria,
222
+ logit_processor=logit_processor,
223
+ )
224
+ if fixed_output_length and output.shape[1] < seq_len:
225
+ return torch.cat(
226
+ (output, torch.ones(output.shape[0], seq_len-output.shape[1], device=device, dtype=output.dtype) * self.pad_id),
227
+ dim=1
228
+ )
229
+ return output
230
+
231
+ elif generation_type == "top_p":
232
+ logit_warper = GENERATION_TYPES[generation_type](top_p)
233
+ elif generation_type == "top_k":
234
+ logit_warper = GENERATION_TYPES[generation_type](top_k)
235
+ else:
236
+ raise ValueError(
237
+ f"generation_type has to be one of "
238
+ f"{'| ' + ' | '.join(list(GENERATION_TYPES.keys())) + ' |'}."
239
+ )
240
+
241
+ image_latent, image_embs = self._encode_image(image)
242
+
243
+ if text is None:
244
+ text = torch.ones((image.shape[0], 1), device=device, dtype=torch.long) * sot_token_id
245
+
246
+ was_training = self.training
247
+ num_dims = len(text.shape)
248
+
249
+ if num_dims == 1:
250
+ text = text[None, :]
251
+
252
+ cur_len = text.shape[1]
253
+ self.eval()
254
+ out = text
255
+
256
+ while True:
257
+ x = out[:, -max_seq_len:]
258
+ cur_len = x.shape[1]
259
+ logits = self(image, x, image_latent=image_latent, image_embs=image_embs, embed_cls=False)["logits"][:, -1]
260
+ mask = (out[:, -1] == eos_token_id) | (out[:, -1] == pad_token_id)
261
+ sample = torch.ones((out.shape[0], 1), device=device, dtype=torch.long) * pad_token_id
262
+
263
+ if mask.all():
264
+ if not fixed_output_length:
265
+ break
266
+ else:
267
+ logits = logits[~mask, :]
268
+ filtered_logits = logit_processor(x[~mask, :], logits)
269
+ filtered_logits = logit_warper(x[~mask, :], filtered_logits)
270
+ probs = F.softmax(filtered_logits / temperature, dim=-1)
271
+
272
+ if (cur_len + 1 == seq_len):
273
+ sample[~mask, :] = torch.ones((sum(~mask), 1), device=device, dtype=torch.long) * eos_token_id
274
+ else:
275
+ sample[~mask, :] = torch.multinomial(probs, 1)
276
+
277
+ out = torch.cat((out, sample), dim=-1)
278
+
279
+ cur_len += 1
280
+
281
+ if stopping_criteria(out, None):
282
+ break
283
+
284
+ if num_dims == 1:
285
+ out = out.squeeze(0)
286
+
287
+ self.train(was_training)
288
+ return out
289
+
290
+ def _generate_beamsearch(
291
+ self,
292
+ image_inputs,
293
+ pad_token_id=None,
294
+ eos_token_id=None,
295
+ sot_token_id=None,
296
+ num_beams=6,
297
+ num_beam_groups=3,
298
+ min_seq_len=5,
299
+ stopping_criteria=None,
300
+ logit_processor=None,
301
+ logit_warper=None,
302
+ ):
303
+ device = image_inputs.device
304
+ batch_size = image_inputs.shape[0]
305
+ image_inputs = torch.repeat_interleave(image_inputs, num_beams, dim=0)
306
+ image_latent, image_embs = self._encode_image(image_inputs)
307
+
308
+ input_ids = torch.ones((batch_size * num_beams, 1), device=device, dtype=torch.long)
309
+ input_ids = input_ids * sot_token_id
310
+ beam_scorer = BeamSearchScorer(
311
+ batch_size=batch_size,
312
+ num_beams=num_beams,
313
+ device=device,
314
+ num_beam_groups=num_beam_groups,
315
+ )
316
+ # instantiate logits processors
317
+ logits_processor = (
318
+ LogitsProcessorList([MinLengthLogitsProcessor(min_seq_len, eos_token_id=eos_token_id)])
319
+ if logit_processor is None
320
+ else logit_processor
321
+ )
322
+
323
+ batch_size = len(beam_scorer._beam_hyps)
324
+ num_beams = beam_scorer.num_beams
325
+ num_beam_groups = beam_scorer.num_beam_groups
326
+ num_sub_beams = num_beams // num_beam_groups
327
+ batch_beam_size, cur_len = input_ids.shape
328
+ beam_indices = None
329
+
330
+ if num_beams * batch_size != batch_beam_size:
331
+ raise ValueError(
332
+ f"Batch dimension of `input_ids` should be {num_beams * batch_size}, but is {batch_beam_size}."
333
+ )
334
+
335
+ beam_scores = torch.full((batch_size, num_beams), -1e9, dtype=torch.float, device=device)
336
+ # initialise score of first beam of each group with 0 and the rest with 1e-9. This ensures that the beams in
337
+ # the same group don't produce same tokens everytime.
338
+ beam_scores[:, ::num_sub_beams] = 0
339
+ beam_scores = beam_scores.view((batch_size * num_beams,))
340
+
341
+ while True:
342
+
343
+ # predicted tokens in cur_len step
344
+ current_tokens = torch.zeros(batch_size * num_beams, dtype=input_ids.dtype, device=device)
345
+
346
+ # indices which will form the beams in the next time step
347
+ reordering_indices = torch.zeros(batch_size * num_beams, dtype=torch.long, device=device)
348
+
349
+ # do one decoder step on all beams of all sentences in batch
350
+ model_inputs = prepare_inputs_for_generation(input_ids=input_ids, image_inputs=image_inputs)
351
+ outputs = self(
352
+ model_inputs['images'],
353
+ model_inputs['text'],
354
+ embed_cls=False,
355
+ image_latent=image_latent,
356
+ image_embs=image_embs
357
+ )
358
+
359
+ for beam_group_idx in range(num_beam_groups):
360
+ group_start_idx = beam_group_idx * num_sub_beams
361
+ group_end_idx = min(group_start_idx + num_sub_beams, num_beams)
362
+ group_size = group_end_idx - group_start_idx
363
+
364
+ # indices of beams of current group among all sentences in batch
365
+ batch_group_indices = []
366
+
367
+ for batch_idx in range(batch_size):
368
+ batch_group_indices.extend(
369
+ [batch_idx * num_beams + idx for idx in range(group_start_idx, group_end_idx)]
370
+ )
371
+ group_input_ids = input_ids[batch_group_indices]
372
+
373
+ # select outputs of beams of currentg group only
374
+ next_token_logits = outputs['logits'][batch_group_indices, -1, :]
375
+ vocab_size = next_token_logits.shape[-1]
376
+
377
+ next_token_scores_processed = logits_processor(
378
+ group_input_ids, next_token_logits, current_tokens=current_tokens, beam_group_idx=beam_group_idx
379
+ )
380
+ next_token_scores = next_token_scores_processed + beam_scores[batch_group_indices].unsqueeze(-1)
381
+ next_token_scores = next_token_scores.expand_as(next_token_scores_processed)
382
+
383
+ # reshape for beam search
384
+ next_token_scores = next_token_scores.view(batch_size, group_size * vocab_size)
385
+
386
+ next_token_scores, next_tokens = torch.topk(
387
+ next_token_scores, 2 * group_size, dim=1, largest=True, sorted=True
388
+ )
389
+
390
+ next_indices = torch.div(next_tokens, vocab_size, rounding_mode="floor")
391
+ next_tokens = next_tokens % vocab_size
392
+
393
+ # stateless
394
+ process_beam_indices = sum(beam_indices, ()) if beam_indices is not None else None
395
+ beam_outputs = beam_scorer.process(
396
+ group_input_ids,
397
+ next_token_scores,
398
+ next_tokens,
399
+ next_indices,
400
+ pad_token_id=pad_token_id,
401
+ eos_token_id=eos_token_id,
402
+ beam_indices=process_beam_indices,
403
+ )
404
+ beam_scores[batch_group_indices] = beam_outputs["next_beam_scores"]
405
+ beam_next_tokens = beam_outputs["next_beam_tokens"]
406
+ beam_idx = beam_outputs["next_beam_indices"]
407
+
408
+ input_ids[batch_group_indices] = group_input_ids[beam_idx]
409
+ group_input_ids = torch.cat([group_input_ids[beam_idx, :], beam_next_tokens.unsqueeze(-1)], dim=-1)
410
+ current_tokens[batch_group_indices] = group_input_ids[:, -1]
411
+
412
+ # (beam_idx // group_size) -> batch_idx
413
+ # (beam_idx % group_size) -> offset of idx inside the group
414
+ reordering_indices[batch_group_indices] = (
415
+ num_beams * torch.div(beam_idx, group_size, rounding_mode="floor") + group_start_idx + (beam_idx % group_size)
416
+ )
417
+
418
+ input_ids = torch.cat([input_ids, current_tokens.unsqueeze(-1)], dim=-1)
419
+
420
+ # increase cur_len
421
+ cur_len = cur_len + 1
422
+ if beam_scorer.is_done or stopping_criteria(input_ids, None):
423
+ break
424
+
425
+ final_beam_indices = sum(beam_indices, ()) if beam_indices is not None else None
426
+ sequence_outputs = beam_scorer.finalize(
427
+ input_ids,
428
+ beam_scores,
429
+ next_tokens,
430
+ next_indices,
431
+ pad_token_id=pad_token_id,
432
+ eos_token_id=eos_token_id,
433
+ max_length=stopping_criteria.max_length,
434
+ beam_indices=final_beam_indices,
435
+ )
436
+ return sequence_outputs['sequences']
437
+
438
+
439
+ def prepare_inputs_for_generation(input_ids, image_inputs, past=None, **kwargs):
440
+ if past:
441
+ input_ids = input_ids[:, -1].unsqueeze(-1)
442
+
443
+ attention_mask = kwargs.get("attention_mask", None)
444
+ position_ids = kwargs.get("position_ids", None)
445
+
446
+ if attention_mask is not None and position_ids is None:
447
+ # create position_ids on the fly for batch generation
448
+ position_ids = attention_mask.long().cumsum(-1) - 1
449
+ position_ids.masked_fill_(attention_mask == 0, 1)
450
+ else:
451
+ position_ids = None
452
+ return {
453
+ "text": input_ids,
454
+ "images": image_inputs,
455
+ "past_key_values": past,
456
+ "position_ids": position_ids,
457
+ "attention_mask": attention_mask,
458
+ }
evaluation/open_clip/constants.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ OPENAI_DATASET_MEAN = (0.48145466, 0.4578275, 0.40821073)
2
+ OPENAI_DATASET_STD = (0.26862954, 0.26130258, 0.27577711)
evaluation/open_clip/factory.py ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import logging
3
+ import os
4
+ import pathlib
5
+ import re
6
+ from copy import deepcopy
7
+ from pathlib import Path
8
+ # from turtle import forward
9
+ from typing import Any, Dict, Optional, Tuple, Union
10
+
11
+ import torch
12
+
13
+ from .constants import OPENAI_DATASET_MEAN, OPENAI_DATASET_STD
14
+ from .model import CLIP, CustomTextCLIP, convert_weights_to_lp, convert_to_custom_text_state_dict,\
15
+ resize_pos_embed, get_cast_dtype
16
+ from .coca_model import CoCa
17
+ from .loss import ClipLoss, DistillClipLoss, CoCaLoss
18
+ from .openai import load_openai_model
19
+ from .pretrained import is_pretrained_cfg, get_pretrained_cfg, download_pretrained, list_pretrained_tags_by_model, download_pretrained_from_hf
20
+ from .transform import image_transform, AugmentationCfg
21
+ from .tokenizer import HFTokenizer, tokenize
22
+
23
+
24
+ HF_HUB_PREFIX = 'hf-hub:'
25
+ _MODEL_CONFIG_PATHS = [Path(__file__).parent / f"model_configs/"]
26
+ _MODEL_CONFIGS = {} # directory (model_name: config) of model architecture configs
27
+
28
+
29
+ def _natural_key(string_):
30
+ return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string_.lower())]
31
+
32
+
33
+ def _rescan_model_configs():
34
+ global _MODEL_CONFIGS
35
+
36
+ config_ext = ('.json',)
37
+ config_files = []
38
+ for config_path in _MODEL_CONFIG_PATHS:
39
+ if config_path.is_file() and config_path.suffix in config_ext:
40
+ config_files.append(config_path)
41
+ elif config_path.is_dir():
42
+ for ext in config_ext:
43
+ config_files.extend(config_path.glob(f'*{ext}'))
44
+
45
+ for cf in config_files:
46
+ with open(cf, 'r') as f:
47
+ model_cfg = json.load(f)
48
+ if all(a in model_cfg for a in ('embed_dim', 'vision_cfg', 'text_cfg')):
49
+ _MODEL_CONFIGS[cf.stem] = model_cfg
50
+
51
+ _MODEL_CONFIGS = {k: v for k, v in sorted(_MODEL_CONFIGS.items(), key=lambda x: _natural_key(x[0]))}
52
+
53
+
54
+ _rescan_model_configs() # initial populate of model config registry
55
+
56
+
57
+ def list_models():
58
+ """ enumerate available model architectures based on config files """
59
+ return list(_MODEL_CONFIGS.keys())
60
+
61
+
62
+ def add_model_config(path):
63
+ """ add model config path or file and update registry """
64
+ if not isinstance(path, Path):
65
+ path = Path(path)
66
+ _MODEL_CONFIG_PATHS.append(path)
67
+ _rescan_model_configs()
68
+
69
+
70
+ def get_model_config(model_name):
71
+ if model_name in _MODEL_CONFIGS:
72
+ return deepcopy(_MODEL_CONFIGS[model_name])
73
+ else:
74
+ return None
75
+
76
+
77
+ def get_tokenizer(model_name):
78
+ if model_name.startswith(HF_HUB_PREFIX):
79
+ tokenizer = HFTokenizer(model_name[len(HF_HUB_PREFIX):])
80
+ else:
81
+ config = get_model_config(model_name)
82
+ tokenizer = HFTokenizer(
83
+ config['text_cfg']['hf_tokenizer_name']) if 'hf_tokenizer_name' in config['text_cfg'] else tokenize
84
+ return tokenizer
85
+
86
+
87
+ def load_state_dict(checkpoint_path: str, map_location='cpu'):
88
+ checkpoint = torch.load(checkpoint_path, map_location=map_location)
89
+ if isinstance(checkpoint, dict) and 'state_dict' in checkpoint:
90
+ state_dict = checkpoint['state_dict']
91
+ else:
92
+ state_dict = checkpoint
93
+ if next(iter(state_dict.items()))[0].startswith('module'):
94
+ state_dict = {k[7:]: v for k, v in state_dict.items()}
95
+ return state_dict
96
+
97
+
98
+ def load_checkpoint(model, checkpoint_path, strict=True):
99
+ state_dict = load_state_dict(checkpoint_path)
100
+ # detect old format and make compatible with new format
101
+ if 'positional_embedding' in state_dict and not hasattr(model, 'positional_embedding'):
102
+ state_dict = convert_to_custom_text_state_dict(state_dict)
103
+ resize_pos_embed(state_dict, model)
104
+ incompatible_keys = model.load_state_dict(state_dict, strict=strict)
105
+ return incompatible_keys
106
+
107
+
108
+ def create_model(
109
+ model_name: str,
110
+ pretrained: Optional[str] = None,
111
+ precision: str = 'fp32',
112
+ device: Union[str, torch.device] = 'cpu',
113
+ jit: bool = False,
114
+ force_quick_gelu: bool = False,
115
+ force_custom_text: bool = False,
116
+ force_patch_dropout: Optional[float] = None,
117
+ force_image_size: Optional[Union[int, Tuple[int, int]]] = None,
118
+ pretrained_image: bool = False,
119
+ pretrained_hf: bool = True,
120
+ cache_dir: Optional[str] = None,
121
+ output_dict: Optional[bool] = None,
122
+ require_pretrained: bool = False,
123
+ ):
124
+ has_hf_hub_prefix = model_name.startswith(HF_HUB_PREFIX)
125
+ if has_hf_hub_prefix:
126
+ model_id = model_name[len(HF_HUB_PREFIX):]
127
+ checkpoint_path = download_pretrained_from_hf(model_id, cache_dir=cache_dir)
128
+ config_path = download_pretrained_from_hf(model_id, filename='open_clip_config.json', cache_dir=cache_dir)
129
+
130
+ with open(config_path, 'r', encoding='utf-8') as f:
131
+ config = json.load(f)
132
+ pretrained_cfg = config['preprocess_cfg']
133
+ model_cfg = config['model_cfg']
134
+ else:
135
+ model_name = model_name.replace('/', '-') # for callers using old naming with / in ViT names
136
+ checkpoint_path = None
137
+ pretrained_cfg = {}
138
+ model_cfg = None
139
+
140
+ if isinstance(device, str):
141
+ device = torch.device(device)
142
+
143
+ if pretrained and pretrained.lower() == 'openai':
144
+ logging.info(f'Loading pretrained {model_name} from OpenAI.')
145
+ model = load_openai_model(
146
+ model_name,
147
+ precision=precision,
148
+ device=device,
149
+ jit=jit,
150
+ cache_dir=cache_dir,
151
+ )
152
+
153
+ # to always output dict even if it is clip
154
+ if output_dict and hasattr(model, "output_dict"):
155
+ model.output_dict = True
156
+ else:
157
+ model_cfg = model_cfg or get_model_config(model_name)
158
+ if model_cfg is not None:
159
+ logging.info(f'Loaded {model_name} model config.')
160
+ else:
161
+ logging.error(f'Model config for {model_name} not found; available models {list_models()}.')
162
+ raise RuntimeError(f'Model config for {model_name} not found.')
163
+
164
+ if force_quick_gelu:
165
+ # override for use of QuickGELU on non-OpenAI transformer models
166
+ model_cfg["quick_gelu"] = True
167
+
168
+ if force_patch_dropout is not None:
169
+ # override the default patch dropout value
170
+ model_cfg["vision_cfg"]["patch_dropout"] = force_patch_dropout
171
+
172
+ if force_image_size is not None:
173
+ # override model config's image size
174
+ model_cfg["vision_cfg"]["image_size"] = force_image_size
175
+
176
+ if pretrained_image:
177
+ if 'timm_model_name' in model_cfg.get('vision_cfg', {}):
178
+ # pretrained weight loading for timm models set via vision_cfg
179
+ model_cfg['vision_cfg']['timm_model_pretrained'] = True
180
+ else:
181
+ assert False, 'pretrained image towers currently only supported for timm models'
182
+
183
+ cast_dtype = get_cast_dtype(precision)
184
+ is_hf_model = 'hf_model_name' in model_cfg.get('text_cfg', {})
185
+ custom_text = model_cfg.pop('custom_text', False) or force_custom_text or is_hf_model
186
+
187
+ if custom_text:
188
+ if is_hf_model:
189
+ model_cfg['text_cfg']['hf_model_pretrained'] = pretrained_hf
190
+ if "coca" in model_name:
191
+ model = CoCa(**model_cfg, cast_dtype=cast_dtype)
192
+ else:
193
+ model = CustomTextCLIP(**model_cfg, cast_dtype=cast_dtype)
194
+ else:
195
+ model = CLIP(**model_cfg, cast_dtype=cast_dtype)
196
+
197
+ pretrained_loaded = False
198
+ if pretrained:
199
+ checkpoint_path = ''
200
+ pretrained_cfg = get_pretrained_cfg(model_name, pretrained)
201
+ if pretrained_cfg:
202
+ checkpoint_path = download_pretrained(pretrained_cfg, cache_dir=cache_dir)
203
+ elif os.path.exists(pretrained):
204
+ checkpoint_path = pretrained
205
+
206
+ if checkpoint_path:
207
+ logging.info(f'Loading pretrained {model_name} weights ({pretrained}).')
208
+ load_checkpoint(model, checkpoint_path)
209
+ else:
210
+ error_str = (
211
+ f'Pretrained weights ({pretrained}) not found for model {model_name}.'
212
+ f'Available pretrained tags ({list_pretrained_tags_by_model(model_name)}.')
213
+ logging.warning(error_str)
214
+ raise RuntimeError(error_str)
215
+ pretrained_loaded = True
216
+ elif has_hf_hub_prefix:
217
+ logging.info(f'Loading pretrained {model_name} weights ({pretrained}).')
218
+ load_checkpoint(model, checkpoint_path)
219
+ pretrained_loaded = True
220
+
221
+ if require_pretrained and not pretrained_loaded:
222
+ # callers of create_model_from_pretrained always expect pretrained weights
223
+ raise RuntimeError(
224
+ f'Pretrained weights were required for (model: {model_name}, pretrained: {pretrained}) but not loaded.')
225
+
226
+ model.to(device=device)
227
+ if precision in ("fp16", "bf16"):
228
+ convert_weights_to_lp(model, dtype=torch.bfloat16 if precision == 'bf16' else torch.float16)
229
+
230
+ # set image / mean metadata from pretrained_cfg if available, or use default
231
+ model.visual.image_mean = pretrained_cfg.get('mean', None) or OPENAI_DATASET_MEAN
232
+ model.visual.image_std = pretrained_cfg.get('std', None) or OPENAI_DATASET_STD
233
+
234
+ # to always output dict even if it is clip
235
+ if output_dict and hasattr(model, "output_dict"):
236
+ model.output_dict = True
237
+
238
+ if jit:
239
+ model = torch.jit.script(model)
240
+
241
+ return model
242
+
243
+
244
+ def create_loss(args):
245
+ if args.distill:
246
+ return DistillClipLoss(
247
+ local_loss=args.local_loss,
248
+ gather_with_grad=args.gather_with_grad,
249
+ cache_labels=True,
250
+ rank=args.rank,
251
+ world_size=args.world_size,
252
+ use_horovod=args.horovod,
253
+ )
254
+ elif "coca" in args.model.lower():
255
+ return CoCaLoss(
256
+ caption_loss_weight=args.coca_caption_loss_weight,
257
+ clip_loss_weight=args.coca_contrastive_loss_weight,
258
+ local_loss=args.local_loss,
259
+ gather_with_grad=args.gather_with_grad,
260
+ cache_labels=True,
261
+ rank=args.rank,
262
+ world_size=args.world_size,
263
+ use_horovod=args.horovod,
264
+ )
265
+ return ClipLoss(
266
+ local_loss=args.local_loss,
267
+ gather_with_grad=args.gather_with_grad,
268
+ cache_labels=True,
269
+ rank=args.rank,
270
+ world_size=args.world_size,
271
+ use_horovod=args.horovod,
272
+ )
273
+
274
+ class MLP(torch.nn.Module):
275
+ def __init__(self, input_size):
276
+ super().__init__()
277
+ self.input_size = input_size
278
+ self.layers = torch.nn.Sequential(
279
+ torch.nn.Linear(self.input_size, 1024),
280
+ torch.nn.Dropout(0.2),
281
+ torch.nn.Linear(1024, 128),
282
+ torch.nn.Dropout(0.2),
283
+ torch.nn.Linear(128, 64),
284
+ torch.nn.Dropout(0.1),
285
+ torch.nn.Linear(64, 16),
286
+ torch.nn.Linear(16, 1)
287
+ )
288
+
289
+ def forward(self, x):
290
+ return self.layers(x)
291
+
292
+ # class semantic_head(torch.nn.Module):
293
+ # def __init__(self, input_size):
294
+ # super().__init__()
295
+ # self.input_size = input_size # for ViT-L-14 is 1024
296
+ # self.seg_head = torch.nn.Sequential(
297
+ # torch.nn.Linear(input_size, 128),
298
+ # torch.nn.Dropout(0.2),
299
+ # torch.nn.Linear(128, 64),
300
+ # torch.nn.Dropout(0.1),
301
+ # torch.nn.Linear(64, 16),
302
+ # torch.nn.Linear(16, 1),
303
+ # )
304
+ # self.sigmoid = torch.nn.Sigmoid()
305
+
306
+ # def forward(self, x):
307
+ # return self.sigmoid(self.seg_head(x))
308
+
309
+ def create_model_and_transforms(
310
+ model_name: str,
311
+ pretrained: Optional[str] = None,
312
+ precision: str = 'fp32',
313
+ device: Union[str, torch.device] = 'cpu',
314
+ jit: bool = False,
315
+ force_quick_gelu: bool = False,
316
+ force_custom_text: bool = False,
317
+ force_patch_dropout: Optional[float] = None,
318
+ force_image_size: Optional[Union[int, Tuple[int, int]]] = None,
319
+ pretrained_image: bool = False,
320
+ pretrained_hf: bool = True,
321
+ image_mean: Optional[Tuple[float, ...]] = None,
322
+ image_std: Optional[Tuple[float, ...]] = None,
323
+ aug_cfg: Optional[Union[Dict[str, Any], AugmentationCfg]] = None,
324
+ cache_dir: Optional[str] = None,
325
+ light_augmentation = False,
326
+ output_dict: Optional[bool] = None,
327
+ with_score_predictor: bool = False,
328
+ with_region_predictor: bool = False
329
+ ):
330
+ model = create_model(
331
+ model_name,
332
+ pretrained,
333
+ precision=precision,
334
+ device=device,
335
+ jit=jit,
336
+ force_quick_gelu=force_quick_gelu,
337
+ force_custom_text=force_custom_text,
338
+ force_patch_dropout=force_patch_dropout,
339
+ force_image_size=force_image_size,
340
+ pretrained_image=pretrained_image,
341
+ pretrained_hf=pretrained_hf,
342
+ cache_dir=cache_dir,
343
+ output_dict=output_dict,
344
+ )
345
+
346
+ image_mean = image_mean or getattr(model.visual, 'image_mean', None)
347
+ image_std = image_std or getattr(model.visual, 'image_std', None)
348
+
349
+ if with_score_predictor:
350
+ model.score_predictor = MLP(model.visual.proj.size(1)).to(device=device, dtype=model.visual.proj.dtype)
351
+
352
+ if with_region_predictor:
353
+ # model.region_predictor = semantic_head(model.visual.proj.size(1)).to(device=device, dtype=model.visual.proj.dtype)
354
+ model.region_predictor = torch.nn.Linear(model.visual.proj.size(0), 1).to(device=device, dtype=model.visual.proj.dtype)
355
+ # preprocess_train = image_transform_region(
356
+ # model.visual.image_size,
357
+ # is_train=True,
358
+ # mean=image_mean,
359
+ # std=image_std
360
+ # )
361
+ # preprocess_val = image_transform_region(
362
+ # model.visual.image_size,
363
+ # is_train=False,
364
+ # mean=image_mean,
365
+ # std=image_std
366
+ # )
367
+
368
+ if light_augmentation:
369
+ preprocess_val = image_transform(
370
+ model.visual.image_size,
371
+ is_train=False,
372
+ mean=image_mean,
373
+ std=image_std,
374
+ resize_longest_max=True,
375
+ )
376
+ preprocess_train = preprocess_val
377
+ else:
378
+ preprocess_train = image_transform(
379
+ model.visual.image_size,
380
+ is_train=True,
381
+ mean=image_mean,
382
+ std=image_std
383
+ )
384
+ preprocess_val = image_transform(
385
+ model.visual.image_size,
386
+ is_train=False,
387
+ mean=image_mean,
388
+ std=image_std
389
+ )
390
+
391
+ return model, preprocess_train, preprocess_val
392
+
393
+
394
+ def create_model_from_pretrained(
395
+ model_name: str,
396
+ pretrained: Optional[str] = None,
397
+ precision: str = 'fp32',
398
+ device: Union[str, torch.device] = 'cpu',
399
+ jit: bool = False,
400
+ force_quick_gelu: bool = False,
401
+ force_custom_text: bool = False,
402
+ force_image_size: Optional[Union[int, Tuple[int, int]]] = None,
403
+ return_transform: bool = True,
404
+ image_mean: Optional[Tuple[float, ...]] = None,
405
+ image_std: Optional[Tuple[float, ...]] = None,
406
+ cache_dir: Optional[str] = None,
407
+ ):
408
+ model = create_model(
409
+ model_name,
410
+ pretrained,
411
+ precision=precision,
412
+ device=device,
413
+ jit=jit,
414
+ force_quick_gelu=force_quick_gelu,
415
+ force_custom_text=force_custom_text,
416
+ force_image_size=force_image_size,
417
+ cache_dir=cache_dir,
418
+ require_pretrained=True,
419
+ )
420
+
421
+ if not return_transform:
422
+ return model
423
+
424
+ image_mean = image_mean or getattr(model.visual, 'image_mean', None)
425
+ image_std = image_std or getattr(model.visual, 'image_std', None)
426
+ preprocess = image_transform(
427
+ model.visual.image_size,
428
+ is_train=False,
429
+ mean=image_mean,
430
+ std=image_std,
431
+ )
432
+
433
+ return model, preprocess
evaluation/open_clip/generation_utils.py ADDED
File without changes
evaluation/open_clip/hf_configs.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # HF architecture dict:
2
+ arch_dict = {
3
+ # https://huggingface.co/docs/transformers/model_doc/roberta#roberta
4
+ "roberta": {
5
+ "config_names": {
6
+ "context_length": "max_position_embeddings",
7
+ "vocab_size": "vocab_size",
8
+ "width": "hidden_size",
9
+ "heads": "num_attention_heads",
10
+ "layers": "num_hidden_layers",
11
+ "layer_attr": "layer",
12
+ "token_embeddings_attr": "embeddings"
13
+ },
14
+ "pooler": "mean_pooler",
15
+ },
16
+ # https://huggingface.co/docs/transformers/model_doc/xlm-roberta#transformers.XLMRobertaConfig
17
+ "xlm-roberta": {
18
+ "config_names": {
19
+ "context_length": "max_position_embeddings",
20
+ "vocab_size": "vocab_size",
21
+ "width": "hidden_size",
22
+ "heads": "num_attention_heads",
23
+ "layers": "num_hidden_layers",
24
+ "layer_attr": "layer",
25
+ "token_embeddings_attr": "embeddings"
26
+ },
27
+ "pooler": "mean_pooler",
28
+ },
29
+ # https://huggingface.co/docs/transformers/model_doc/mt5#mt5
30
+ "mt5": {
31
+ "config_names": {
32
+ # unlimited seqlen
33
+ # https://github.com/google-research/text-to-text-transfer-transformer/issues/273
34
+ # https://github.com/huggingface/transformers/blob/v4.24.0/src/transformers/models/t5/modeling_t5.py#L374
35
+ "context_length": "",
36
+ "vocab_size": "vocab_size",
37
+ "width": "d_model",
38
+ "heads": "num_heads",
39
+ "layers": "num_layers",
40
+ "layer_attr": "block",
41
+ "token_embeddings_attr": "embed_tokens"
42
+ },
43
+ "pooler": "mean_pooler",
44
+ },
45
+ }
evaluation/open_clip/hf_model.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ huggingface model adapter
2
+
3
+ Wraps HuggingFace transformers (https://github.com/huggingface/transformers) models for use as a text tower in CLIP model.
4
+ """
5
+
6
+ import re
7
+
8
+ import torch
9
+ import torch.nn as nn
10
+ from torch import TensorType
11
+
12
+ try:
13
+ import transformers
14
+ from transformers import AutoModel, AutoTokenizer, AutoConfig, PretrainedConfig
15
+ from transformers.modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, \
16
+ BaseModelOutputWithPoolingAndCrossAttentions
17
+ except ImportError as e:
18
+ transformers = None
19
+
20
+
21
+ class BaseModelOutput:
22
+ pass
23
+
24
+
25
+ class PretrainedConfig:
26
+ pass
27
+
28
+ from .hf_configs import arch_dict
29
+
30
+
31
+ # utils
32
+ def _camel2snake(s):
33
+ return re.sub(r'(?<!^)(?=[A-Z])', '_', s).lower()
34
+
35
+
36
+ # TODO: ?last - for gpt-like models
37
+ _POOLERS = {}
38
+
39
+
40
+ def register_pooler(cls):
41
+ """Decorator registering pooler class"""
42
+ _POOLERS[_camel2snake(cls.__name__)] = cls
43
+ return cls
44
+
45
+
46
+ @register_pooler
47
+ class MeanPooler(nn.Module):
48
+ """Mean pooling"""
49
+
50
+ def forward(self, x: BaseModelOutput, attention_mask: TensorType):
51
+ masked_output = x.last_hidden_state * attention_mask.unsqueeze(-1)
52
+ return masked_output.sum(dim=1) / attention_mask.sum(-1, keepdim=True)
53
+
54
+
55
+ @register_pooler
56
+ class MaxPooler(nn.Module):
57
+ """Max pooling"""
58
+
59
+ def forward(self, x: BaseModelOutput, attention_mask: TensorType):
60
+ masked_output = x.last_hidden_state.masked_fill(attention_mask.unsqueeze(-1), -torch.inf)
61
+ return masked_output.max(1).values
62
+
63
+
64
+ @register_pooler
65
+ class ClsPooler(nn.Module):
66
+ """CLS token pooling"""
67
+
68
+ def __init__(self, use_pooler_output=True):
69
+ super().__init__()
70
+ self.cls_token_position = 0
71
+ self.use_pooler_output = use_pooler_output
72
+
73
+ def forward(self, x: BaseModelOutput, attention_mask: TensorType):
74
+ if (self.use_pooler_output and
75
+ isinstance(x, (BaseModelOutputWithPooling, BaseModelOutputWithPoolingAndCrossAttentions)) and
76
+ (x.pooler_output is not None)
77
+ ):
78
+ return x.pooler_output
79
+
80
+ return x.last_hidden_state[:, self.cls_token_position, :]
81
+
82
+
83
+ class HFTextEncoder(nn.Module):
84
+ """HuggingFace model adapter"""
85
+ output_tokens: torch.jit.Final[bool]
86
+
87
+ def __init__(
88
+ self,
89
+ model_name_or_path: str,
90
+ output_dim: int,
91
+ config: PretrainedConfig = None,
92
+ pooler_type: str = None,
93
+ proj: str = None,
94
+ pretrained: bool = True,
95
+ output_tokens: bool = False,
96
+ ):
97
+ super().__init__()
98
+ self.output_tokens = output_tokens
99
+ self.output_dim = output_dim
100
+
101
+ # TODO: find better way to get this information
102
+ uses_transformer_pooler = (pooler_type == "cls_pooler")
103
+
104
+ if transformers is None:
105
+ raise RuntimeError("Please `pip install transformers` to use pre-trained HuggingFace models")
106
+ if config is None:
107
+ self.config = AutoConfig.from_pretrained(model_name_or_path)
108
+ create_func, model_args = (AutoModel.from_pretrained, model_name_or_path) if pretrained else (
109
+ AutoModel.from_config, self.config)
110
+ # TODO: do all model configs have this attribute? PretrainedConfig does so yes??
111
+ if hasattr(self.config, "is_encoder_decoder") and self.config.is_encoder_decoder:
112
+ self.transformer = create_func(model_args)
113
+ self.transformer = self.transformer.encoder
114
+ else:
115
+ self.transformer = create_func(model_args, add_pooling_layer=uses_transformer_pooler)
116
+ else:
117
+ self.config = config
118
+ self.transformer = AutoModel.from_config(config)
119
+ if pooler_type is None: # get default arch pooler
120
+ pooler_type = (arch_dict[self.config.model_type]["pooler"])
121
+
122
+ self.pooler = _POOLERS[pooler_type]()
123
+
124
+ d_model = getattr(self.config, arch_dict[self.config.model_type]["config_names"]["width"])
125
+ if (d_model == output_dim) and (proj is None): # do we always need a proj?
126
+ self.proj = nn.Identity()
127
+ elif proj == 'linear':
128
+ self.proj = nn.Linear(d_model, output_dim, bias=False)
129
+ elif proj == 'mlp':
130
+ hidden_size = (d_model + output_dim) // 2
131
+ self.proj = nn.Sequential(
132
+ nn.Linear(d_model, hidden_size, bias=False),
133
+ nn.GELU(),
134
+ nn.Linear(hidden_size, output_dim, bias=False),
135
+ )
136
+
137
+ def forward(self, x: TensorType):
138
+ attn_mask = (x != self.config.pad_token_id).long()
139
+ out = self.transformer(input_ids=x, attention_mask=attn_mask)
140
+ pooled_out = self.pooler(out, attn_mask)
141
+ projected = self.proj(pooled_out)
142
+
143
+ seq_len = out.last_hidden_state.shape[1]
144
+ tokens = (
145
+ out.last_hidden_state[:, torch.arange(seq_len) != self.pooler.cls_token_position, :]
146
+ if type(self.pooler) == ClsPooler
147
+ else out.last_hidden_state
148
+ )
149
+
150
+ if self.output_tokens:
151
+ return projected, tokens
152
+ return projected
153
+
154
+ def lock(self, unlocked_layers: int = 0, freeze_layer_norm: bool = True):
155
+ if not unlocked_layers: # full freezing
156
+ for n, p in self.transformer.named_parameters():
157
+ p.requires_grad = (not freeze_layer_norm) if "LayerNorm" in n.split(".") else False
158
+ return
159
+
160
+ encoder = self.transformer.encoder if hasattr(self.transformer, 'encoder') else self.transformer
161
+ layer_list = getattr(encoder, arch_dict[self.config.model_type]["config_names"]["layer_attr"])
162
+ print(f"Unlocking {unlocked_layers}/{len(layer_list) + 1} layers of hf model")
163
+ embeddings = getattr(
164
+ self.transformer, arch_dict[self.config.model_type]["config_names"]["token_embeddings_attr"])
165
+ modules = [embeddings, *layer_list][:-unlocked_layers]
166
+ # freeze layers
167
+ for module in modules:
168
+ for n, p in module.named_parameters():
169
+ p.requires_grad = (not freeze_layer_norm) if "LayerNorm" in n.split(".") else False
170
+
171
+ @torch.jit.ignore
172
+ def set_grad_checkpointing(self, enable=True):
173
+ self.transformer.gradient_checkpointing_enable()
174
+
175
+ def init_parameters(self):
176
+ pass
evaluation/open_clip/loss.py ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ from torch.nn import functional as F
4
+ from torch.nn.utils.rnn import pad_sequence
5
+
6
+ try:
7
+ import torch.distributed.nn
8
+ from torch import distributed as dist
9
+
10
+ has_distributed = True
11
+ except ImportError:
12
+ has_distributed = False
13
+
14
+ try:
15
+ import horovod.torch as hvd
16
+ except ImportError:
17
+ hvd = None
18
+
19
+
20
+ def gather_features(
21
+ image_features,
22
+ text_features,
23
+ local_loss=False,
24
+ gather_with_grad=False,
25
+ rank=0,
26
+ world_size=1,
27
+ use_horovod=False
28
+ ):
29
+ assert has_distributed, 'torch.distributed did not import correctly, please use a PyTorch version with support.'
30
+ if use_horovod:
31
+ assert hvd is not None, 'Please install horovod'
32
+ if gather_with_grad:
33
+ all_image_features = hvd.allgather(image_features)
34
+ all_text_features = hvd.allgather(text_features)
35
+ else:
36
+ with torch.no_grad():
37
+ all_image_features = hvd.allgather(image_features)
38
+ all_text_features = hvd.allgather(text_features)
39
+ if not local_loss:
40
+ # ensure grads for local rank when all_* features don't have a gradient
41
+ gathered_image_features = list(all_image_features.chunk(world_size, dim=0))
42
+ gathered_text_features = list(all_text_features.chunk(world_size, dim=0))
43
+ gathered_image_features[rank] = image_features
44
+ gathered_text_features[rank] = text_features
45
+ all_image_features = torch.cat(gathered_image_features, dim=0)
46
+ all_text_features = torch.cat(gathered_text_features, dim=0)
47
+ else:
48
+ # We gather tensors from all gpus
49
+ if gather_with_grad:
50
+ all_image_features = torch.cat(torch.distributed.nn.all_gather(image_features), dim=0)
51
+ all_text_features = torch.cat(torch.distributed.nn.all_gather(text_features), dim=0)
52
+ else:
53
+ gathered_image_features = [torch.zeros_like(image_features) for _ in range(world_size)]
54
+ gathered_text_features = [torch.zeros_like(text_features) for _ in range(world_size)]
55
+ dist.all_gather(gathered_image_features, image_features)
56
+ dist.all_gather(gathered_text_features, text_features)
57
+ if not local_loss:
58
+ # ensure grads for local rank when all_* features don't have a gradient
59
+ gathered_image_features[rank] = image_features
60
+ gathered_text_features[rank] = text_features
61
+ all_image_features = torch.cat(gathered_image_features, dim=0)
62
+ all_text_features = torch.cat(gathered_text_features, dim=0)
63
+
64
+ return all_image_features, all_text_features
65
+
66
+
67
+ class ClipLoss(nn.Module):
68
+
69
+ def __init__(
70
+ self,
71
+ local_loss=False,
72
+ gather_with_grad=False,
73
+ cache_labels=False,
74
+ rank=0,
75
+ world_size=1,
76
+ use_horovod=False,
77
+ ):
78
+ super().__init__()
79
+ self.local_loss = local_loss
80
+ self.gather_with_grad = gather_with_grad
81
+ self.cache_labels = cache_labels
82
+ self.rank = rank
83
+ self.world_size = world_size
84
+ self.use_horovod = use_horovod
85
+
86
+ # cache state
87
+ self.prev_num_logits = 0
88
+ self.labels = {}
89
+
90
+ def get_ground_truth(self, device, num_logits) -> torch.Tensor:
91
+ # calculated ground-truth and cache if enabled
92
+ if self.prev_num_logits != num_logits or device not in self.labels:
93
+ labels = torch.arange(num_logits, device=device, dtype=torch.long)
94
+ if self.world_size > 1 and self.local_loss:
95
+ labels = labels + num_logits * self.rank
96
+ if self.cache_labels:
97
+ self.labels[device] = labels
98
+ self.prev_num_logits = num_logits
99
+ else:
100
+ labels = self.labels[device]
101
+ return labels
102
+
103
+ def get_logits(self, image_features, text_features, logit_scale):
104
+ if self.world_size > 1:
105
+ all_image_features, all_text_features = gather_features(
106
+ image_features, text_features,
107
+ self.local_loss, self.gather_with_grad, self.rank, self.world_size, self.use_horovod)
108
+
109
+ if self.local_loss:
110
+ logits_per_image = logit_scale * image_features @ all_text_features.T
111
+ logits_per_text = logit_scale * text_features @ all_image_features.T
112
+ else:
113
+ logits_per_image = logit_scale * all_image_features @ all_text_features.T
114
+ logits_per_text = logits_per_image.T
115
+ else:
116
+ logits_per_image = logit_scale * image_features @ text_features.T
117
+ logits_per_text = logit_scale * text_features @ image_features.T
118
+
119
+ return logits_per_image, logits_per_text
120
+
121
+ def forward(self, image_features, text_features, logit_scale, output_dict=False):
122
+ device = image_features.device
123
+ logits_per_image, logits_per_text = self.get_logits(image_features, text_features, logit_scale)
124
+
125
+ labels = self.get_ground_truth(device, logits_per_image.shape[0])
126
+
127
+ total_loss = (
128
+ F.cross_entropy(logits_per_image, labels) +
129
+ F.cross_entropy(logits_per_text, labels)
130
+ ) / 2
131
+ return total_loss
132
+
133
+ class PreferenceLoss(nn.Module):
134
+
135
+ def forward(self, logits_per_image, num_images, labels):
136
+
137
+ paired_logits_list = [logit[:,i] for i, logit in enumerate(logits_per_image.split(num_images.tolist()))]
138
+ paired_logits = pad_sequence(paired_logits_list, batch_first=True, padding_value=-999)
139
+
140
+ ce_loss = F.cross_entropy(paired_logits, labels)
141
+ return ce_loss
142
+
143
+ class HPSLoss(nn.Module):
144
+
145
+ def forward(self, text_logits, labels):
146
+
147
+ device = text_logits.device
148
+ text_0_logits, text_1_logits = text_logits.chunk(2, dim=-1)
149
+ label_0, label_1 = labels.chunk(2, dim=-1)
150
+
151
+ index = torch.arange(text_0_logits.shape[0], device=device, dtype=torch.long)
152
+ text_0_logits = text_0_logits[index, index]
153
+ text_1_logits = text_1_logits[index, index]
154
+ text_logits = torch.stack([text_0_logits, text_1_logits], dim=-1)
155
+ text_0_labels = torch.zeros(text_logits.shape[0], device=device, dtype=torch.long)
156
+ text_1_labels = text_0_labels + 1
157
+
158
+ text_0_loss = torch.nn.functional.cross_entropy(text_logits, text_0_labels, reduction="none")
159
+ text_1_loss = torch.nn.functional.cross_entropy(text_logits, text_1_labels, reduction="none")
160
+
161
+ text_loss = label_0 * text_0_loss + label_1 * text_1_loss
162
+
163
+ # absolute_example_weight = 1 / num_per_prompt
164
+ # denominator = absolute_example_weight.sum()
165
+ # weight_per_example = absolute_example_weight / denominator
166
+ # text_loss *= weight_per_example
167
+
168
+ text_loss = text_loss.sum()
169
+ return text_loss
170
+
171
+ class RankingLoss(nn.Module):
172
+
173
+ def forward(self, logits_per_image, num_images, labels, margin = 1.0):
174
+ paired_logits_list = [logit[:,i] for i, logit in enumerate(logits_per_image.split(num_images.tolist()))]
175
+ label_list = [label for label in labels.split(num_images.tolist())]
176
+ # ranked_logits = [torch.index_select(paired_logits_list[i], 0, rank) for i, rank in enumerate(label_list)]
177
+
178
+ paired_logits = pad_sequence(paired_logits_list, batch_first=True, padding_value=-1)
179
+ padded_labels = pad_sequence(label_list, batch_first=True, padding_value=10)
180
+
181
+ # regulized_logits = torch.log(torch.sigmoid(paired_logits))
182
+
183
+ diff = paired_logits.unsqueeze(1) - paired_logits.unsqueeze(2)
184
+ # diff = paired_logits.unsqueeze(1) - paired_logits.unsqueeze(2)
185
+ # diff_label = torch.clamp(padded_labels.unsqueeze(1) - padded_labels.unsqueeze(2), min=-1, max=1)
186
+ diff_label = - (padded_labels.unsqueeze(1) - padded_labels.unsqueeze(2))
187
+ mask = torch.triu(torch.ones(diff.shape[1], diff.shape[1]), diagonal=1).bool().detach()
188
+
189
+ loss = torch.clamp(margin - torch.mul(diff[:, ~mask],diff_label[:,~mask]), min=0).mean()
190
+ return loss
191
+
192
+ class CoCaLoss(ClipLoss):
193
+ def __init__(
194
+ self,
195
+ caption_loss_weight,
196
+ clip_loss_weight,
197
+ pad_id=0, # pad_token for open_clip custom tokenizer
198
+ local_loss=False,
199
+ gather_with_grad=False,
200
+ cache_labels=False,
201
+ rank=0,
202
+ world_size=1,
203
+ use_horovod=False,
204
+ ):
205
+ super().__init__(
206
+ local_loss=local_loss,
207
+ gather_with_grad=gather_with_grad,
208
+ cache_labels=cache_labels,
209
+ rank=rank,
210
+ world_size=world_size,
211
+ use_horovod=use_horovod
212
+ )
213
+
214
+ self.clip_loss_weight = clip_loss_weight
215
+ self.caption_loss_weight = caption_loss_weight
216
+ self.caption_loss = nn.CrossEntropyLoss(ignore_index=pad_id)
217
+
218
+ def forward(self, image_features, text_features, logits, labels, logit_scale, output_dict=False):
219
+ clip_loss = super().forward(image_features, text_features, logit_scale)
220
+ clip_loss = self.clip_loss_weight * clip_loss
221
+
222
+ caption_loss = self.caption_loss(
223
+ logits.permute(0, 2, 1),
224
+ labels,
225
+ )
226
+ caption_loss = caption_loss * self.caption_loss_weight
227
+
228
+ if output_dict:
229
+ return {"contrastive_loss": clip_loss, "caption_loss": caption_loss}
230
+
231
+ return clip_loss, caption_loss
232
+
233
+
234
+ class DistillClipLoss(ClipLoss):
235
+
236
+ def dist_loss(self, teacher_logits, student_logits):
237
+ return -(teacher_logits.softmax(dim=1) * student_logits.log_softmax(dim=1)).sum(dim=1).mean(dim=0)
238
+
239
+ def forward(
240
+ self,
241
+ image_features,
242
+ text_features,
243
+ logit_scale,
244
+ dist_image_features,
245
+ dist_text_features,
246
+ dist_logit_scale,
247
+ output_dict=False,
248
+ ):
249
+ logits_per_image, logits_per_text = \
250
+ self.get_logits(image_features, text_features, logit_scale)
251
+
252
+ dist_logits_per_image, dist_logits_per_text = \
253
+ self.get_logits(dist_image_features, dist_text_features, dist_logit_scale)
254
+
255
+ labels = self.get_ground_truth(image_features.device, logits_per_image.shape[0])
256
+
257
+ contrastive_loss = (
258
+ F.cross_entropy(logits_per_image, labels) +
259
+ F.cross_entropy(logits_per_text, labels)
260
+ ) / 2
261
+
262
+ distill_loss = (
263
+ self.dist_loss(dist_logits_per_image, logits_per_image) +
264
+ self.dist_loss(dist_logits_per_text, logits_per_text)
265
+ ) / 2
266
+
267
+ if output_dict:
268
+ return {"contrastive_loss": contrastive_loss, "distill_loss": distill_loss}
269
+
270
+ return contrastive_loss, distill_loss
evaluation/open_clip/model.py ADDED
@@ -0,0 +1,461 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ CLIP Model
2
+
3
+ Adapted from https://github.com/openai/CLIP. Originally MIT License, Copyright (c) 2021 OpenAI.
4
+ """
5
+ from dataclasses import dataclass
6
+ import logging
7
+ import math
8
+ from typing import Optional, Tuple, Union
9
+
10
+ import numpy as np
11
+ import torch
12
+ import torch.nn.functional as F
13
+ from torch import nn
14
+ from torch.utils.checkpoint import checkpoint
15
+
16
+ from .hf_model import HFTextEncoder
17
+ from .modified_resnet import ModifiedResNet
18
+ from .timm_model import TimmModel
19
+ from .transformer import LayerNormFp32, LayerNorm, QuickGELU, Attention, VisionTransformer, TextTransformer
20
+ from .utils import to_2tuple
21
+
22
+
23
+ @dataclass
24
+ class CLIPVisionCfg:
25
+ layers: Union[Tuple[int, int, int, int], int] = 12
26
+ width: int = 768
27
+ head_width: int = 64
28
+ mlp_ratio: float = 4.0
29
+ patch_size: int = 16
30
+ image_size: Union[Tuple[int, int], int] = 224
31
+ ls_init_value: Optional[float] = None # layer scale initial value
32
+ patch_dropout: float = 0. # what fraction of patches to dropout during training (0 would mean disabled and no patches dropped) - 0.5 to 0.75 recommended in the paper for optimal results
33
+ input_patchnorm: bool = False # whether to use dual patchnorm - would only apply the input layernorm on each patch, as post-layernorm already exist in original clip vit design
34
+ global_average_pool: bool = False # whether to global average pool the last embedding layer, instead of using CLS token (https://arxiv.org/abs/2205.01580)
35
+ attentional_pool: bool = False # whether to use attentional pooler in the last embedding layer
36
+ n_queries: int = 256 # n_queries for attentional pooler
37
+ attn_pooler_heads: int = 8 # n heads for attentional_pooling
38
+ timm_model_name: str = None # a valid model name overrides layers, width, patch_size
39
+ timm_model_pretrained: bool = False # use (imagenet) pretrained weights for named model
40
+ timm_pool: str = 'avg' # feature pooling for timm model ('abs_attn', 'rot_attn', 'avg', '')
41
+ timm_proj: str = 'linear' # linear projection for timm model output ('linear', 'mlp', '')
42
+ timm_proj_bias: bool = False # enable bias final projection
43
+ timm_drop: float = 0. # head dropout
44
+ timm_drop_path: Optional[float] = None # backbone stochastic depth
45
+ output_tokens: bool = False
46
+
47
+
48
+ @dataclass
49
+ class CLIPTextCfg:
50
+ context_length: int = 77
51
+ vocab_size: int = 49408
52
+ width: int = 512
53
+ heads: int = 8
54
+ layers: int = 12
55
+ ls_init_value: Optional[float] = None # layer scale initial value
56
+ hf_model_name: str = None
57
+ hf_tokenizer_name: str = None
58
+ hf_model_pretrained: bool = True
59
+ proj: str = 'mlp'
60
+ pooler_type: str = 'mean_pooler'
61
+ embed_cls: bool = False
62
+ pad_id: int = 0
63
+ output_tokens: bool = False
64
+
65
+
66
+ def get_cast_dtype(precision: str):
67
+ cast_dtype = None
68
+ if precision == 'bf16':
69
+ cast_dtype = torch.bfloat16
70
+ elif precision == 'fp16':
71
+ cast_dtype = torch.float16
72
+ return cast_dtype
73
+
74
+
75
+ def _build_vision_tower(
76
+ embed_dim: int,
77
+ vision_cfg: CLIPVisionCfg,
78
+ quick_gelu: bool = False,
79
+ cast_dtype: Optional[torch.dtype] = None
80
+ ):
81
+ if isinstance(vision_cfg, dict):
82
+ vision_cfg = CLIPVisionCfg(**vision_cfg)
83
+
84
+ # OpenAI models are pretrained w/ QuickGELU but native nn.GELU is both faster and more
85
+ # memory efficient in recent PyTorch releases (>= 1.10).
86
+ # NOTE: timm models always use native GELU regardless of quick_gelu flag.
87
+ act_layer = QuickGELU if quick_gelu else nn.GELU
88
+
89
+ if vision_cfg.timm_model_name:
90
+ visual = TimmModel(
91
+ vision_cfg.timm_model_name,
92
+ pretrained=vision_cfg.timm_model_pretrained,
93
+ pool=vision_cfg.timm_pool,
94
+ proj=vision_cfg.timm_proj,
95
+ proj_bias=vision_cfg.timm_proj_bias,
96
+ drop=vision_cfg.timm_drop,
97
+ drop_path=vision_cfg.timm_drop_path,
98
+ embed_dim=embed_dim,
99
+ image_size=vision_cfg.image_size,
100
+ )
101
+ act_layer = nn.GELU # so that text transformer doesn't use QuickGELU w/ timm models
102
+ elif isinstance(vision_cfg.layers, (tuple, list)):
103
+ vision_heads = vision_cfg.width * 32 // vision_cfg.head_width
104
+ visual = ModifiedResNet(
105
+ layers=vision_cfg.layers,
106
+ output_dim=embed_dim,
107
+ heads=vision_heads,
108
+ image_size=vision_cfg.image_size,
109
+ width=vision_cfg.width,
110
+ )
111
+ else:
112
+ vision_heads = vision_cfg.width // vision_cfg.head_width
113
+ norm_layer = LayerNormFp32 if cast_dtype in (torch.float16, torch.bfloat16) else LayerNorm
114
+ visual = VisionTransformer(
115
+ image_size=vision_cfg.image_size,
116
+ patch_size=vision_cfg.patch_size,
117
+ width=vision_cfg.width,
118
+ layers=vision_cfg.layers,
119
+ heads=vision_heads,
120
+ mlp_ratio=vision_cfg.mlp_ratio,
121
+ ls_init_value=vision_cfg.ls_init_value,
122
+ patch_dropout=vision_cfg.patch_dropout,
123
+ input_patchnorm=vision_cfg.input_patchnorm,
124
+ global_average_pool=vision_cfg.global_average_pool,
125
+ attentional_pool=vision_cfg.attentional_pool,
126
+ n_queries=vision_cfg.n_queries,
127
+ attn_pooler_heads=vision_cfg.attn_pooler_heads,
128
+ output_tokens=vision_cfg.output_tokens,
129
+ output_dim=embed_dim,
130
+ act_layer=act_layer,
131
+ norm_layer=norm_layer,
132
+ )
133
+
134
+ return visual
135
+
136
+
137
+ def _build_text_tower(
138
+ embed_dim: int,
139
+ text_cfg: CLIPTextCfg,
140
+ quick_gelu: bool = False,
141
+ cast_dtype: Optional[torch.dtype] = None,
142
+ ):
143
+ if isinstance(text_cfg, dict):
144
+ text_cfg = CLIPTextCfg(**text_cfg)
145
+
146
+ if text_cfg.hf_model_name:
147
+ text = HFTextEncoder(
148
+ text_cfg.hf_model_name,
149
+ output_dim=embed_dim,
150
+ proj=text_cfg.proj,
151
+ pooler_type=text_cfg.pooler_type,
152
+ pretrained=text_cfg.hf_model_pretrained,
153
+ output_tokens=text_cfg.output_tokens,
154
+ )
155
+ else:
156
+ act_layer = QuickGELU if quick_gelu else nn.GELU
157
+ norm_layer = LayerNormFp32 if cast_dtype in (torch.float16, torch.bfloat16) else LayerNorm
158
+
159
+ text = TextTransformer(
160
+ context_length=text_cfg.context_length,
161
+ vocab_size=text_cfg.vocab_size,
162
+ width=text_cfg.width,
163
+ heads=text_cfg.heads,
164
+ layers=text_cfg.layers,
165
+ ls_init_value=text_cfg.ls_init_value,
166
+ output_dim=embed_dim,
167
+ embed_cls=text_cfg.embed_cls,
168
+ output_tokens=text_cfg.output_tokens,
169
+ pad_id=text_cfg.pad_id,
170
+ act_layer=act_layer,
171
+ norm_layer=norm_layer,
172
+ )
173
+ return text
174
+
175
+
176
+ class CLIP(nn.Module):
177
+ output_dict: torch.jit.Final[bool]
178
+
179
+ def __init__(
180
+ self,
181
+ embed_dim: int,
182
+ vision_cfg: CLIPVisionCfg,
183
+ text_cfg: CLIPTextCfg,
184
+ quick_gelu: bool = False,
185
+ cast_dtype: Optional[torch.dtype] = None,
186
+ output_dict: bool = False,
187
+ ):
188
+ super().__init__()
189
+ self.output_dict = output_dict
190
+ self.visual = _build_vision_tower(embed_dim, vision_cfg, quick_gelu, cast_dtype)
191
+
192
+ text = _build_text_tower(embed_dim, text_cfg, quick_gelu, cast_dtype)
193
+ self.transformer = text.transformer
194
+ self.vocab_size = text.vocab_size
195
+ self.token_embedding = text.token_embedding
196
+ self.positional_embedding = text.positional_embedding
197
+ self.ln_final = text.ln_final
198
+ self.text_projection = text.text_projection
199
+ self.register_buffer('attn_mask', text.attn_mask, persistent=False)
200
+
201
+ self.logit_scale = nn.Parameter(torch.ones([]) * np.log(1 / 0.07))
202
+
203
+ def lock_image_tower(self, unlocked_groups=0, freeze_bn_stats=False):
204
+ # lock image tower as per LiT - https://arxiv.org/abs/2111.07991
205
+ self.visual.lock(unlocked_groups=unlocked_groups, freeze_bn_stats=freeze_bn_stats)
206
+
207
+ def lock_text_tower(self, unlocked_layers: int = 0, freeze_layer_norm: bool = True):
208
+ locked_layers = []
209
+ locked_layers.append(self.token_embedding)
210
+ self.positional_embedding.requires_grad = False
211
+ if unlocked_layers > 0:
212
+ locked_layers.append(self.transformer.resblocks[:-unlocked_layers])
213
+ else:
214
+ locked_layers.append(self.transformer)
215
+ locked_layers.append(self.ln_final)
216
+ self.text_projection.requires_grad = False
217
+
218
+ # freeze layers
219
+ for module in locked_layers:
220
+ for n, p in module.named_parameters():
221
+ p.requires_grad = (not freeze_layer_norm) if "LayerNorm" in n.split(".") else False
222
+
223
+ @torch.jit.ignore
224
+ def set_grad_checkpointing(self, enable=True):
225
+ self.visual.set_grad_checkpointing(enable)
226
+ self.transformer.grad_checkpointing = enable
227
+
228
+ def encode_image(self, image, normalize: bool = False):
229
+ features = self.visual(image)
230
+ return F.normalize(features, dim=-1) if normalize else features
231
+
232
+ def encode_text(self, text, normalize: bool = False):
233
+ cast_dtype = self.transformer.get_cast_dtype()
234
+
235
+ x = self.token_embedding(text).to(cast_dtype) # [batch_size, n_ctx, d_model]
236
+
237
+ x = x + self.positional_embedding.to(cast_dtype)
238
+ x = x.permute(1, 0, 2) # NLD -> LND
239
+ x = self.transformer(x, attn_mask=self.attn_mask)
240
+ x = x.permute(1, 0, 2) # LND -> NLD
241
+ x = self.ln_final(x) # [batch_size, n_ctx, transformer.width]
242
+ # take features from the eot embedding (eot_token is the highest number in each sequence)
243
+ x = x[torch.arange(x.shape[0]), text.argmax(dim=-1)] @ self.text_projection
244
+ return F.normalize(x, dim=-1) if normalize else x
245
+
246
+ def forward(self, image, text):
247
+ image_features = self.encode_image(image, normalize=True)
248
+ text_features = self.encode_text(text, normalize=True)
249
+ if self.output_dict:
250
+ return {
251
+ "image_features": image_features,
252
+ "text_features": text_features,
253
+ "logit_scale": self.logit_scale.exp()
254
+ }
255
+ return image_features, text_features, self.logit_scale.exp()
256
+
257
+
258
+ class CustomTextCLIP(nn.Module):
259
+ output_dict: torch.jit.Final[bool]
260
+
261
+ def __init__(
262
+ self,
263
+ embed_dim: int,
264
+ vision_cfg: CLIPVisionCfg,
265
+ text_cfg: CLIPTextCfg,
266
+ quick_gelu: bool = False,
267
+ cast_dtype: Optional[torch.dtype] = None,
268
+ output_dict: bool = False,
269
+ ):
270
+ super().__init__()
271
+ self.output_dict = output_dict
272
+ self.visual = _build_vision_tower(embed_dim, vision_cfg, quick_gelu, cast_dtype)
273
+ self.text = _build_text_tower(embed_dim, text_cfg, quick_gelu, cast_dtype)
274
+ self.logit_scale = nn.Parameter(torch.ones([]) * np.log(1 / 0.07))
275
+
276
+ def lock_image_tower(self, unlocked_groups=0, freeze_bn_stats=False):
277
+ # lock image tower as per LiT - https://arxiv.org/abs/2111.07991
278
+ self.visual.lock(unlocked_groups=unlocked_groups, freeze_bn_stats=freeze_bn_stats)
279
+
280
+ def lock_text_tower(self, unlocked_layers: int = 0, freeze_layer_norm: bool = True):
281
+ self.text.lock(unlocked_layers, freeze_layer_norm)
282
+
283
+ @torch.jit.ignore
284
+ def set_grad_checkpointing(self, enable=True):
285
+ self.visual.set_grad_checkpointing(enable)
286
+ self.text.set_grad_checkpointing(enable)
287
+
288
+ def encode_image(self, image, normalize: bool = False):
289
+ features = self.visual(image)
290
+ return F.normalize(features, dim=-1) if normalize else features
291
+
292
+ def encode_text(self, text, normalize: bool = False):
293
+ features = self.text(text)
294
+ return F.normalize(features, dim=-1) if normalize else features
295
+
296
+ def forward(self, image, text):
297
+ image_features = self.encode_image(image, normalize=True)
298
+ text_features = self.encode_text(text, normalize=True)
299
+ if self.output_dict:
300
+ return {
301
+ "image_features": image_features,
302
+ "text_features": text_features,
303
+ "logit_scale": self.logit_scale.exp()
304
+ }
305
+ return image_features, text_features, self.logit_scale.exp()
306
+
307
+
308
+ def convert_weights_to_lp(model: nn.Module, dtype=torch.float16):
309
+ """Convert applicable model parameters to low-precision (bf16 or fp16)"""
310
+
311
+ def _convert_weights(l):
312
+ if isinstance(l, (nn.Conv1d, nn.Conv2d, nn.Linear)):
313
+ l.weight.data = l.weight.data.to(dtype)
314
+ if l.bias is not None:
315
+ l.bias.data = l.bias.data.to(dtype)
316
+
317
+ if isinstance(l, (nn.MultiheadAttention, Attention)):
318
+ for attr in [*[f"{s}_proj_weight" for s in ["in", "q", "k", "v"]], "in_proj_bias", "bias_k", "bias_v"]:
319
+ tensor = getattr(l, attr)
320
+ if tensor is not None:
321
+ tensor.data = tensor.data.to(dtype)
322
+
323
+ for name in ["text_projection", "proj"]:
324
+ if hasattr(l, name):
325
+ attr = getattr(l, name)
326
+ if attr is not None:
327
+ attr.data = attr.data.to(dtype)
328
+
329
+ model.apply(_convert_weights)
330
+
331
+
332
+ convert_weights_to_fp16 = convert_weights_to_lp # backwards compat
333
+
334
+
335
+ # used to maintain checkpoint compatibility
336
+ def convert_to_custom_text_state_dict(state_dict: dict):
337
+ if 'text_projection' in state_dict:
338
+ # old format state_dict, move text tower -> .text
339
+ new_state_dict = {}
340
+ for k, v in state_dict.items():
341
+ if any(k.startswith(p) for p in (
342
+ 'text_projection',
343
+ 'positional_embedding',
344
+ 'token_embedding',
345
+ 'transformer',
346
+ 'ln_final',
347
+ )):
348
+ k = 'text.' + k
349
+ new_state_dict[k] = v
350
+ return new_state_dict
351
+ return state_dict
352
+
353
+
354
+ def build_model_from_openai_state_dict(
355
+ state_dict: dict,
356
+ quick_gelu=True,
357
+ cast_dtype=torch.float16,
358
+ ):
359
+ vit = "visual.proj" in state_dict
360
+
361
+ if vit:
362
+ vision_width = state_dict["visual.conv1.weight"].shape[0]
363
+ vision_layers = len(
364
+ [k for k in state_dict.keys() if k.startswith("visual.") and k.endswith(".attn.in_proj_weight")])
365
+ vision_patch_size = state_dict["visual.conv1.weight"].shape[-1]
366
+ grid_size = round((state_dict["visual.positional_embedding"].shape[0] - 1) ** 0.5)
367
+ image_size = vision_patch_size * grid_size
368
+ else:
369
+ counts: list = [
370
+ len(set(k.split(".")[2] for k in state_dict if k.startswith(f"visual.layer{b}"))) for b in [1, 2, 3, 4]]
371
+ vision_layers = tuple(counts)
372
+ vision_width = state_dict["visual.layer1.0.conv1.weight"].shape[0]
373
+ output_width = round((state_dict["visual.attnpool.positional_embedding"].shape[0] - 1) ** 0.5)
374
+ vision_patch_size = None
375
+ assert output_width ** 2 + 1 == state_dict["visual.attnpool.positional_embedding"].shape[0]
376
+ image_size = output_width * 32
377
+
378
+ embed_dim = state_dict["text_projection"].shape[1]
379
+ context_length = state_dict["positional_embedding"].shape[0]
380
+ vocab_size = state_dict["token_embedding.weight"].shape[0]
381
+ transformer_width = state_dict["ln_final.weight"].shape[0]
382
+ transformer_heads = transformer_width // 64
383
+ transformer_layers = len(set(k.split(".")[2] for k in state_dict if k.startswith(f"transformer.resblocks")))
384
+
385
+ vision_cfg = CLIPVisionCfg(
386
+ layers=vision_layers,
387
+ width=vision_width,
388
+ patch_size=vision_patch_size,
389
+ image_size=image_size,
390
+ )
391
+ text_cfg = CLIPTextCfg(
392
+ context_length=context_length,
393
+ vocab_size=vocab_size,
394
+ width=transformer_width,
395
+ heads=transformer_heads,
396
+ layers=transformer_layers,
397
+ )
398
+ model = CLIP(
399
+ embed_dim,
400
+ vision_cfg=vision_cfg,
401
+ text_cfg=text_cfg,
402
+ quick_gelu=quick_gelu, # OpenAI models were trained with QuickGELU
403
+ cast_dtype=cast_dtype,
404
+ )
405
+
406
+ for key in ["input_resolution", "context_length", "vocab_size"]:
407
+ state_dict.pop(key, None)
408
+
409
+ convert_weights_to_fp16(model) # OpenAI state dicts are partially converted to float16
410
+ model.load_state_dict(state_dict)
411
+ return model.eval()
412
+
413
+
414
+ def trace_model(model, batch_size=256, device=torch.device('cpu')):
415
+ model.eval()
416
+ image_size = model.visual.image_size
417
+ example_images = torch.ones((batch_size, 3, image_size, image_size), device=device)
418
+ example_text = torch.zeros((batch_size, model.context_length), dtype=torch.int, device=device)
419
+ model = torch.jit.trace_module(
420
+ model,
421
+ inputs=dict(
422
+ forward=(example_images, example_text),
423
+ encode_text=(example_text,),
424
+ encode_image=(example_images,)
425
+ ))
426
+ model.visual.image_size = image_size
427
+ return model
428
+
429
+
430
+ def resize_pos_embed(state_dict, model, interpolation: str = 'bicubic', antialias: bool = True):
431
+ # Rescale the grid of position embeddings when loading from state_dict
432
+ old_pos_embed = state_dict.get('visual.positional_embedding', None)
433
+ if old_pos_embed is None or not hasattr(model.visual, 'grid_size'):
434
+ return
435
+ grid_size = to_2tuple(model.visual.grid_size)
436
+ extra_tokens = 1 # FIXME detect different token configs (ie no class token, or more)
437
+ new_seq_len = grid_size[0] * grid_size[1] + extra_tokens
438
+ if new_seq_len == old_pos_embed.shape[0]:
439
+ return
440
+
441
+ if extra_tokens:
442
+ pos_emb_tok, pos_emb_img = old_pos_embed[:extra_tokens], old_pos_embed[extra_tokens:]
443
+ else:
444
+ pos_emb_tok, pos_emb_img = None, old_pos_embed
445
+ old_grid_size = to_2tuple(int(math.sqrt(len(pos_emb_img))))
446
+
447
+ logging.info('Resizing position embedding grid-size from %s to %s', old_grid_size, grid_size)
448
+ pos_emb_img = pos_emb_img.reshape(1, old_grid_size[0], old_grid_size[1], -1).permute(0, 3, 1, 2)
449
+ pos_emb_img = F.interpolate(
450
+ pos_emb_img,
451
+ size=grid_size,
452
+ mode=interpolation,
453
+ antialias=antialias,
454
+ align_corners=False,
455
+ )
456
+ pos_emb_img = pos_emb_img.permute(0, 2, 3, 1).reshape(1, grid_size[0] * grid_size[1], -1)[0]
457
+ if pos_emb_tok is not None:
458
+ new_pos_embed = torch.cat([pos_emb_tok, pos_emb_img], dim=0)
459
+ else:
460
+ new_pos_embed = pos_emb_img
461
+ state_dict['visual.positional_embedding'] = new_pos_embed
evaluation/open_clip/model_configs/RN101-quickgelu.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "quick_gelu": true,
4
+ "vision_cfg": {
5
+ "image_size": 224,
6
+ "layers": [
7
+ 3,
8
+ 4,
9
+ 23,
10
+ 3
11
+ ],
12
+ "width": 64,
13
+ "patch_size": null
14
+ },
15
+ "text_cfg": {
16
+ "context_length": 77,
17
+ "vocab_size": 49408,
18
+ "width": 512,
19
+ "heads": 8,
20
+ "layers": 12
21
+ }
22
+ }
evaluation/open_clip/model_configs/RN101.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": [
6
+ 3,
7
+ 4,
8
+ 23,
9
+ 3
10
+ ],
11
+ "width": 64,
12
+ "patch_size": null
13
+ },
14
+ "text_cfg": {
15
+ "context_length": 77,
16
+ "vocab_size": 49408,
17
+ "width": 512,
18
+ "heads": 8,
19
+ "layers": 12
20
+ }
21
+ }
evaluation/open_clip/model_configs/RN50-quickgelu.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 1024,
3
+ "quick_gelu": true,
4
+ "vision_cfg": {
5
+ "image_size": 224,
6
+ "layers": [
7
+ 3,
8
+ 4,
9
+ 6,
10
+ 3
11
+ ],
12
+ "width": 64,
13
+ "patch_size": null
14
+ },
15
+ "text_cfg": {
16
+ "context_length": 77,
17
+ "vocab_size": 49408,
18
+ "width": 512,
19
+ "heads": 8,
20
+ "layers": 12
21
+ }
22
+ }
evaluation/open_clip/model_configs/RN50x16.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 768,
3
+ "vision_cfg": {
4
+ "image_size": 384,
5
+ "layers": [
6
+ 6,
7
+ 8,
8
+ 18,
9
+ 8
10
+ ],
11
+ "width": 96,
12
+ "patch_size": null
13
+ },
14
+ "text_cfg": {
15
+ "context_length": 77,
16
+ "vocab_size": 49408,
17
+ "width": 768,
18
+ "heads": 12,
19
+ "layers": 12
20
+ }
21
+ }
evaluation/open_clip/model_configs/RN50x4.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 640,
3
+ "vision_cfg": {
4
+ "image_size": 288,
5
+ "layers": [
6
+ 4,
7
+ 6,
8
+ 10,
9
+ 6
10
+ ],
11
+ "width": 80,
12
+ "patch_size": null
13
+ },
14
+ "text_cfg": {
15
+ "context_length": 77,
16
+ "vocab_size": 49408,
17
+ "width": 640,
18
+ "heads": 10,
19
+ "layers": 12
20
+ }
21
+ }
evaluation/open_clip/model_configs/ViT-B-16-plus-240.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 640,
3
+ "vision_cfg": {
4
+ "image_size": 240,
5
+ "layers": 12,
6
+ "width": 896,
7
+ "patch_size": 16
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 640,
13
+ "heads": 10,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-B-16-plus.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 640,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 896,
7
+ "patch_size": 16
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 640,
13
+ "heads": 10,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-B-16.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 768,
7
+ "patch_size": 16
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 512,
13
+ "heads": 8,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-B-32-quickgelu.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "quick_gelu": true,
4
+ "vision_cfg": {
5
+ "image_size": 224,
6
+ "layers": 12,
7
+ "width": 768,
8
+ "patch_size": 32
9
+ },
10
+ "text_cfg": {
11
+ "context_length": 77,
12
+ "vocab_size": 49408,
13
+ "width": 512,
14
+ "heads": 8,
15
+ "layers": 12
16
+ }
17
+ }
evaluation/open_clip/model_configs/ViT-B-32.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 768,
7
+ "patch_size": 32
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 512,
13
+ "heads": 8,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-H-14.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 1024,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 32,
6
+ "width": 1280,
7
+ "head_width": 80,
8
+ "patch_size": 14
9
+ },
10
+ "text_cfg": {
11
+ "context_length": 77,
12
+ "vocab_size": 49408,
13
+ "width": 1024,
14
+ "heads": 16,
15
+ "layers": 24
16
+ }
17
+ }
evaluation/open_clip/model_configs/ViT-L-14-336.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 768,
3
+ "vision_cfg": {
4
+ "image_size": 336,
5
+ "layers": 24,
6
+ "width": 1024,
7
+ "patch_size": 14
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 768,
13
+ "heads": 12,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-L-14.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 768,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 24,
6
+ "width": 1024,
7
+ "patch_size": 14
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 768,
13
+ "heads": 12,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-L-16.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 768,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 24,
6
+ "width": 1024,
7
+ "patch_size": 16
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 768,
13
+ "heads": 12,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-M-16-alt.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 384,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 512,
7
+ "patch_size": 16,
8
+ "ls_init_value": 1e-4
9
+ },
10
+ "text_cfg": {
11
+ "context_length": 77,
12
+ "vocab_size": 49408,
13
+ "width": 384,
14
+ "heads": 6,
15
+ "layers": 12
16
+ }
17
+ }
evaluation/open_clip/model_configs/ViT-M-16.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 512,
7
+ "patch_size": 16
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 512,
13
+ "heads": 8,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-M-32-alt.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 384,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 512,
7
+ "patch_size": 32
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 384,
13
+ "heads": 6,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-M-32.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 512,
7
+ "patch_size": 32
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 512,
13
+ "heads": 8,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-S-16-alt.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 256,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 384,
7
+ "patch_size": 16
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 256,
13
+ "heads": 4,
14
+ "layers": 10
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-S-16.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 384,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 384,
7
+ "patch_size": 16
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 384,
13
+ "heads": 6,
14
+ "layers": 12
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-S-32-alt.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 256,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 384,
7
+ "patch_size": 32
8
+ },
9
+ "text_cfg": {
10
+ "context_length": 77,
11
+ "vocab_size": 49408,
12
+ "width": 256,
13
+ "heads": 4,
14
+ "layers": 10
15
+ }
16
+ }
evaluation/open_clip/model_configs/ViT-bigG-14.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 1280,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 48,
6
+ "width": 1664,
7
+ "head_width": 104,
8
+ "mlp_ratio": 4.9231,
9
+ "patch_size": 14
10
+ },
11
+ "text_cfg": {
12
+ "context_length": 77,
13
+ "vocab_size": 49408,
14
+ "width": 1280,
15
+ "heads": 20,
16
+ "layers": 32
17
+ }
18
+ }
evaluation/open_clip/model_configs/ViT-e-14.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 1280,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 56,
6
+ "width": 1792,
7
+ "head_width": 112,
8
+ "mlp_ratio": 8.5715,
9
+ "patch_size": 14
10
+ },
11
+ "text_cfg": {
12
+ "context_length": 77,
13
+ "vocab_size": 49408,
14
+ "width": 1280,
15
+ "heads": 20,
16
+ "layers": 36
17
+ }
18
+ }
evaluation/open_clip/model_configs/ViT-g-14.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 1024,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 40,
6
+ "width": 1408,
7
+ "head_width": 88,
8
+ "mlp_ratio": 4.3637,
9
+ "patch_size": 14
10
+ },
11
+ "text_cfg": {
12
+ "context_length": 77,
13
+ "vocab_size": 49408,
14
+ "width": 1024,
15
+ "heads": 16,
16
+ "layers": 24
17
+ }
18
+ }
evaluation/open_clip/model_configs/coca_ViT-L-14.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 768,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 24,
6
+ "width": 1024,
7
+ "patch_size": 14,
8
+ "attentional_pool": true,
9
+ "attn_pooler_heads": 8,
10
+ "output_tokens": true
11
+ },
12
+ "text_cfg": {
13
+ "context_length": 76,
14
+ "vocab_size": 49408,
15
+ "width": 768,
16
+ "heads": 12,
17
+ "layers": 12,
18
+ "embed_cls": true,
19
+ "output_tokens": true
20
+ },
21
+ "multimodal_cfg": {
22
+ "context_length": 76,
23
+ "vocab_size": 49408,
24
+ "width": 768,
25
+ "heads": 12,
26
+ "layers": 12,
27
+ "attn_pooler_heads": 12
28
+ },
29
+ "custom_text": true
30
+ }
evaluation/open_clip/model_configs/coca_base.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "multimodal_cfg": {
4
+ "width": 768,
5
+ "context_length": 76,
6
+ "vocab_size": 64000,
7
+ "mlp_ratio": 4,
8
+ "layers": 12,
9
+ "dim_head": 64,
10
+ "heads": 12,
11
+ "n_queries": 256,
12
+ "attn_pooler_heads": 8
13
+ },
14
+ "vision_cfg": {
15
+ "image_size": 288,
16
+ "layers": 12,
17
+ "width": 768,
18
+ "patch_size": 18,
19
+ "output_tokens": true
20
+ },
21
+ "text_cfg": {
22
+ "context_length": 76,
23
+ "vocab_size": 64000,
24
+ "layers": 12,
25
+ "heads": 12,
26
+ "width": 768,
27
+ "embed_cls": true,
28
+ "output_tokens": true
29
+ },
30
+ "custom_text": true
31
+ }
evaluation/open_clip/model_configs/coca_roberta-ViT-B-32.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "vision_cfg": {
4
+ "image_size": 224,
5
+ "layers": 12,
6
+ "width": 768,
7
+ "patch_size": 32,
8
+ "output_tokens": true
9
+ },
10
+ "text_cfg": {
11
+ "hf_model_name": "roberta-base",
12
+ "hf_tokenizer_name": "roberta-base",
13
+ "proj": "linear",
14
+ "width": 768,
15
+ "output_tokens": true
16
+ },
17
+ "multimodal_cfg": {
18
+ "context_length": 76,
19
+ "width": 768,
20
+ "heads": 8,
21
+ "layers": 12
22
+ },
23
+ "custom_text": true
24
+ }
evaluation/open_clip/model_configs/convnext_base.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 512,
3
+ "vision_cfg": {
4
+ "timm_model_name": "convnext_base",
5
+ "timm_model_pretrained": false,
6
+ "timm_pool": "",
7
+ "timm_proj": "linear",
8
+ "timm_drop": 0.0,
9
+ "timm_drop_path": 0.1,
10
+ "image_size": 224
11
+ },
12
+ "text_cfg": {
13
+ "context_length": 77,
14
+ "vocab_size": 49408,
15
+ "width": 512,
16
+ "heads": 8,
17
+ "layers": 12
18
+ }
19
+ }
evaluation/open_clip/model_configs/convnext_base_w.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "embed_dim": 640,
3
+ "vision_cfg": {
4
+ "timm_model_name": "convnext_base",
5
+ "timm_model_pretrained": false,
6
+ "timm_pool": "",
7
+ "timm_proj": "linear",
8
+ "timm_drop": 0.0,
9
+ "timm_drop_path": 0.1,
10
+ "image_size": 256
11
+ },
12
+ "text_cfg": {
13
+ "context_length": 77,
14
+ "vocab_size": 49408,
15
+ "width": 640,
16
+ "heads": 10,
17
+ "layers": 12
18
+ }
19
+ }