Orangerl commited on
Commit
ce813aa
·
verified ·
1 Parent(s): 81d4e14

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. third_party/transformers/src/transformers/models/cohere2/modeling_cohere2.py +509 -0
  2. third_party/transformers/src/transformers/models/cohere2/modular_cohere2.py +325 -0
  3. third_party/transformers/src/transformers/models/conditional_detr/__init__.py +29 -0
  4. third_party/transformers/src/transformers/models/conditional_detr/configuration_conditional_detr.py +119 -0
  5. third_party/transformers/src/transformers/models/conditional_detr/convert_conditional_detr_original_pytorch_checkpoint_to_pytorch.py +363 -0
  6. third_party/transformers/src/transformers/models/conditional_detr/image_processing_conditional_detr.py +1083 -0
  7. third_party/transformers/src/transformers/models/conditional_detr/image_processing_pil_conditional_detr.py +1136 -0
  8. third_party/transformers/src/transformers/models/conditional_detr/modeling_conditional_detr.py +1827 -0
  9. third_party/transformers/src/transformers/models/conditional_detr/modular_conditional_detr.py +1109 -0
  10. third_party/transformers/src/transformers/models/donut/__init__.py +30 -0
  11. third_party/transformers/src/transformers/models/donut/configuration_donut_swin.py +76 -0
  12. third_party/transformers/src/transformers/models/donut/convert_donut_to_pytorch.py +233 -0
  13. third_party/transformers/src/transformers/models/donut/image_processing_donut.py +206 -0
  14. third_party/transformers/src/transformers/models/donut/image_processing_pil_donut.py +212 -0
  15. third_party/transformers/src/transformers/models/donut/modeling_donut_swin.py +967 -0
  16. third_party/transformers/src/transformers/models/donut/processing_donut.py +135 -0
  17. third_party/transformers/src/transformers/models/ibert/__init__.py +27 -0
  18. third_party/transformers/src/transformers/models/ibert/configuration_ibert.py +61 -0
  19. third_party/transformers/src/transformers/models/ibert/modeling_ibert.py +1201 -0
  20. third_party/transformers/src/transformers/models/ibert/quant_modules.py +819 -0
  21. third_party/transformers/src/transformers/models/layoutlm/__init__.py +29 -0
  22. third_party/transformers/src/transformers/models/layoutlm/configuration_layoutlm.py +67 -0
  23. third_party/transformers/src/transformers/models/layoutlm/modeling_layoutlm.py +1012 -0
  24. third_party/transformers/src/transformers/models/led/__init__.py +28 -0
  25. third_party/transformers/src/transformers/models/led/configuration_led.py +86 -0
  26. third_party/transformers/src/transformers/models/led/modeling_led.py +0 -0
  27. third_party/transformers/src/transformers/models/lfm2_moe/__init__.py +28 -0
  28. third_party/transformers/src/transformers/models/lfm2_moe/configuration_lfm2_moe.py +84 -0
  29. third_party/transformers/src/transformers/models/lfm2_moe/modeling_lfm2_moe.py +704 -0
  30. third_party/transformers/src/transformers/models/lfm2_moe/modular_lfm2_moe.py +214 -0
  31. third_party/transformers/src/transformers/models/lfm2_vl/__init__.py +29 -0
  32. third_party/transformers/src/transformers/models/lfm2_vl/configuration_lfm2_vl.py +63 -0
  33. third_party/transformers/src/transformers/models/lfm2_vl/image_processing_lfm2_vl.py +561 -0
  34. third_party/transformers/src/transformers/models/lfm2_vl/modeling_lfm2_vl.py +482 -0
  35. third_party/transformers/src/transformers/models/lfm2_vl/modular_lfm2_vl.py +359 -0
  36. third_party/transformers/src/transformers/models/lfm2_vl/processing_lfm2_vl.py +272 -0
  37. third_party/transformers/src/transformers/models/minimax_m2/__init__.py +28 -0
  38. third_party/transformers/src/transformers/models/minimax_m2/configuration_minimax_m2.py +94 -0
  39. third_party/transformers/src/transformers/models/minimax_m2/modeling_minimax_m2.py +691 -0
  40. third_party/transformers/src/transformers/models/minimax_m2/modular_minimax_m2.py +246 -0
  41. third_party/transformers/src/transformers/models/mixtral/__init__.py +27 -0
  42. third_party/transformers/src/transformers/models/mixtral/configuration_mixtral.py +93 -0
  43. third_party/transformers/src/transformers/models/mixtral/convert_mixtral_weights_to_hf.py +243 -0
  44. third_party/transformers/src/transformers/models/mixtral/modeling_mixtral.py +702 -0
  45. third_party/transformers/src/transformers/models/mixtral/modular_mixtral.py +448 -0
  46. third_party/transformers/src/transformers/models/mra/__init__.py +27 -0
  47. third_party/transformers/src/transformers/models/mra/configuration_mra.py +76 -0
  48. third_party/transformers/src/transformers/models/mra/convert_mra_pytorch_to_pytorch.py +109 -0
  49. third_party/transformers/src/transformers/models/mra/modeling_mra.py +1332 -0
  50. third_party/transformers/src/transformers/models/nemotron_h/__init__.py +27 -0
third_party/transformers/src/transformers/models/cohere2/modeling_cohere2.py ADDED
@@ -0,0 +1,509 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/cohere2/modular_cohere2.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_cohere2.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2024 Cohere Inc. HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ #
10
+ # Licensed under the Apache License, Version 2.0 (the "License");
11
+ # you may not use this file except in compliance with the License.
12
+ # You may obtain a copy of the License at
13
+ #
14
+ # http://www.apache.org/licenses/LICENSE-2.0
15
+ #
16
+ # Unless required by applicable law or agreed to in writing, software
17
+ # distributed under the License is distributed on an "AS IS" BASIS,
18
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ # See the License for the specific language governing permissions and
20
+ # limitations under the License.
21
+ from collections.abc import Callable
22
+ from typing import Optional
23
+
24
+ import torch
25
+ import torch.nn as nn
26
+
27
+ from ...activations import ACT2FN
28
+ from ...cache_utils import Cache, DynamicCache
29
+ from ...generation import GenerationMixin
30
+ from ...integrations import use_kernelized_func
31
+ from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask
32
+ from ...modeling_layers import GradientCheckpointingLayer
33
+ from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
34
+ from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
35
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
36
+ from ...processing_utils import Unpack
37
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple
38
+ from ...utils.generic import maybe_autocast, merge_with_config_defaults
39
+ from ...utils.output_capturing import capture_outputs
40
+ from .configuration_cohere2 import Cohere2Config
41
+
42
+
43
+ class Cohere2RotaryEmbedding(nn.Module):
44
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
45
+
46
+ def __init__(self, config: Cohere2Config, device=None):
47
+ super().__init__()
48
+ self.max_seq_len_cached = config.max_position_embeddings
49
+ self.original_max_seq_len = config.max_position_embeddings
50
+
51
+ self.config = config
52
+
53
+ self.rope_type = self.config.rope_parameters["rope_type"]
54
+ rope_init_fn: Callable = self.compute_default_rope_parameters
55
+ if self.rope_type != "default":
56
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
57
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
58
+
59
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
60
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
61
+
62
+ @staticmethod
63
+ def compute_default_rope_parameters(
64
+ config: Cohere2Config | None = None,
65
+ device: Optional["torch.device"] = None,
66
+ seq_len: int | None = None,
67
+ ) -> tuple["torch.Tensor", float]:
68
+ """
69
+ Computes the inverse frequencies according to the original RoPE implementation
70
+ Args:
71
+ config ([`~transformers.PreTrainedConfig`]):
72
+ The model configuration.
73
+ device (`torch.device`):
74
+ The device to use for initialization of the inverse frequencies.
75
+ seq_len (`int`, *optional*):
76
+ The current sequence length. Unused for this type of RoPE.
77
+ Returns:
78
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
79
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
80
+ """
81
+ base = config.rope_parameters["rope_theta"]
82
+ dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
83
+
84
+ attention_factor = 1.0 # Unused in this type of RoPE
85
+
86
+ # Compute the inverse frequencies
87
+ inv_freq = 1.0 / (
88
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
89
+ )
90
+ return inv_freq, attention_factor
91
+
92
+ @torch.no_grad()
93
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
94
+ def forward(self, x, position_ids):
95
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1)
96
+ position_ids_expanded = position_ids[:, None, :].float()
97
+
98
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
99
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
100
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
101
+ emb = torch.repeat_interleave(freqs, 2, dim=-1) # diff from Llama: we interleave() instead of cat()
102
+ cos = emb.cos() * self.attention_scaling
103
+ sin = emb.sin() * self.attention_scaling
104
+
105
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
106
+
107
+
108
+ class Cohere2LayerNorm(nn.Module):
109
+ def __init__(self, hidden_size=None, eps=1e-5, bias=False):
110
+ """The hidden size can be a tuple or an int. The tuple is used for QKNorm to normalize across head_dim"""
111
+ super().__init__()
112
+ self.weight = nn.Parameter(torch.ones(hidden_size))
113
+ self.variance_epsilon = eps
114
+
115
+ def forward(self, hidden_states):
116
+ input_dtype = hidden_states.dtype
117
+ hidden_states = hidden_states.to(torch.float32)
118
+ mean = hidden_states.mean(-1, keepdim=True)
119
+ variance = (hidden_states - mean).pow(2).mean(-1, keepdim=True)
120
+ hidden_states = (hidden_states - mean) * torch.rsqrt(variance + self.variance_epsilon)
121
+ hidden_states = self.weight.to(torch.float32) * hidden_states
122
+ return hidden_states.to(input_dtype)
123
+
124
+
125
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
126
+ """
127
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
128
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
129
+ """
130
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
131
+ if n_rep == 1:
132
+ return hidden_states
133
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
134
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
135
+
136
+
137
+ def eager_attention_forward(
138
+ module: nn.Module,
139
+ query: torch.Tensor,
140
+ key: torch.Tensor,
141
+ value: torch.Tensor,
142
+ attention_mask: torch.Tensor | None,
143
+ scaling: float,
144
+ dropout: float = 0.0,
145
+ **kwargs: Unpack[TransformersKwargs],
146
+ ):
147
+ key_states = repeat_kv(key, module.num_key_value_groups)
148
+ value_states = repeat_kv(value, module.num_key_value_groups)
149
+
150
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
151
+ if attention_mask is not None:
152
+ attn_weights = attn_weights + attention_mask
153
+
154
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
155
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
156
+ attn_output = torch.matmul(attn_weights, value_states)
157
+ attn_output = attn_output.transpose(1, 2).contiguous()
158
+
159
+ return attn_output, attn_weights
160
+
161
+
162
+ def rotate_half(x):
163
+ # Split and rotate. Note that this function is different from e.g. Llama.
164
+ x1 = x[..., ::2]
165
+ x2 = x[..., 1::2]
166
+ rot_x = torch.stack([-x2, x1], dim=-1).flatten(-2)
167
+ return rot_x
168
+
169
+
170
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
171
+ """Applies Rotary Position Embedding to the query and key tensors.
172
+
173
+ Args:
174
+ q (`torch.Tensor`): The query tensor.
175
+ k (`torch.Tensor`): The key tensor.
176
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
177
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
178
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
179
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
180
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
181
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
182
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
183
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
184
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
185
+ Returns:
186
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
187
+ """
188
+ dtype = q.dtype
189
+ q = q.float()
190
+ k = k.float()
191
+ cos = cos.unsqueeze(unsqueeze_dim)
192
+ sin = sin.unsqueeze(unsqueeze_dim)
193
+ q_embed = (q * cos) + (rotate_half(q) * sin)
194
+ k_embed = (k * cos) + (rotate_half(k) * sin)
195
+ return q_embed.to(dtype=dtype), k_embed.to(dtype=dtype)
196
+
197
+
198
+ @use_kernelized_func(apply_rotary_pos_emb)
199
+ class Cohere2Attention(nn.Module):
200
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
201
+
202
+ def __init__(self, config: Cohere2Config, layer_idx: int | None = None):
203
+ super().__init__()
204
+ self.config = config
205
+ self.layer_idx = layer_idx
206
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
207
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
208
+ self.scaling = self.head_dim**-0.5
209
+ self.attention_dropout = config.attention_dropout
210
+ self.is_causal = True
211
+ layer_type = config.layer_types[layer_idx] if hasattr(config, "layer_types") else None
212
+ self.sliding_window = config.sliding_window if layer_type == "sliding_attention" else None
213
+
214
+ self.q_proj = nn.Linear(
215
+ config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
216
+ )
217
+ self.k_proj = nn.Linear(
218
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
219
+ )
220
+ self.v_proj = nn.Linear(
221
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
222
+ )
223
+ self.o_proj = nn.Linear(
224
+ config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
225
+ )
226
+
227
+ def forward(
228
+ self,
229
+ hidden_states: torch.Tensor,
230
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
231
+ attention_mask: torch.Tensor | None,
232
+ past_key_values: Cache | None = None,
233
+ **kwargs: Unpack[TransformersKwargs],
234
+ ) -> tuple[torch.Tensor, torch.Tensor | None, tuple[torch.Tensor] | None]:
235
+ input_shape = hidden_states.shape[:-1]
236
+ hidden_shape = (*input_shape, -1, self.head_dim)
237
+
238
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
239
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
240
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
241
+
242
+ cos, sin = position_embeddings
243
+ if self.sliding_window is not None:
244
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
245
+
246
+ if past_key_values is not None:
247
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
248
+
249
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
250
+ self.config._attn_implementation, eager_attention_forward
251
+ )
252
+
253
+ attn_output, attn_weights = attention_interface(
254
+ self,
255
+ query_states,
256
+ key_states,
257
+ value_states,
258
+ attention_mask,
259
+ dropout=0.0 if not self.training else self.attention_dropout,
260
+ scaling=self.scaling,
261
+ sliding_window=self.sliding_window,
262
+ **kwargs,
263
+ )
264
+
265
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
266
+ attn_output = self.o_proj(attn_output)
267
+ return attn_output, attn_weights
268
+
269
+
270
+ class Cohere2MLP(nn.Module):
271
+ def __init__(self, config):
272
+ super().__init__()
273
+ self.config = config
274
+ self.hidden_size = config.hidden_size
275
+ self.intermediate_size = config.intermediate_size
276
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
277
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
278
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
279
+ self.act_fn = ACT2FN[config.hidden_act]
280
+
281
+ def forward(self, x):
282
+ down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
283
+ return down_proj
284
+
285
+
286
+ class Cohere2DecoderLayer(GradientCheckpointingLayer):
287
+ def __init__(self, config: Cohere2Config, layer_idx: int):
288
+ super().__init__()
289
+ self.hidden_size = config.hidden_size
290
+ self.self_attn = Cohere2Attention(config=config, layer_idx=layer_idx)
291
+ self.mlp = Cohere2MLP(config)
292
+ self.input_layernorm = Cohere2LayerNorm(hidden_size=(config.hidden_size), eps=config.layer_norm_eps)
293
+
294
+ def forward(
295
+ self,
296
+ hidden_states: torch.Tensor,
297
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
298
+ attention_mask: torch.Tensor | None = None,
299
+ past_key_values: Cache | None = None,
300
+ use_cache: bool | None = False,
301
+ **kwargs: Unpack[TransformersKwargs],
302
+ ) -> tuple[torch.FloatTensor, tuple[torch.FloatTensor, torch.FloatTensor] | None]:
303
+ """
304
+ Args:
305
+ hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
306
+ attention_mask (`torch.FloatTensor`, *optional*):
307
+ attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1,
308
+ query_sequence_length, key_sequence_length)` if default attention is used.
309
+ past_key_values (`Cache`, *optional*): cached past key and value projection states
310
+ output_attentions (`bool`, *optional*):
311
+ Whether or not to return the attentions tensors of all attention layers. See `attentions` under
312
+ returned tensors for more detail.
313
+ use_cache (`bool`, *optional*):
314
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
315
+ (see `past_key_values`).
316
+ position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*):
317
+ Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`,
318
+ with `head_dim` being the embedding dimension of each attention head.
319
+ """
320
+ residual = hidden_states
321
+ hidden_states = self.input_layernorm(hidden_states)
322
+ hidden_states_attention, _ = self.self_attn(
323
+ hidden_states=hidden_states,
324
+ position_embeddings=position_embeddings,
325
+ attention_mask=attention_mask,
326
+ past_key_values=past_key_values,
327
+ use_cache=use_cache,
328
+ **kwargs,
329
+ )
330
+
331
+ hidden_states_mlp = self.mlp(hidden_states)
332
+ hidden_states = residual + hidden_states_attention + hidden_states_mlp
333
+ return hidden_states
334
+
335
+
336
+ @auto_docstring
337
+ class Cohere2PreTrainedModel(PreTrainedModel):
338
+ config: Cohere2Config
339
+ base_model_prefix = "model"
340
+ supports_gradient_checkpointing = True
341
+ _no_split_modules = ["Cohere2DecoderLayer"]
342
+ _skip_keys_device_placement = ["past_key_values"]
343
+ _supports_flash_attn = True
344
+ _supports_sdpa = True
345
+ _supports_flex_attn = True
346
+
347
+ _can_compile_fullgraph = True
348
+ _supports_attention_backend = True
349
+ _can_record_outputs = {
350
+ "hidden_states": Cohere2DecoderLayer,
351
+ "attentions": Cohere2Attention,
352
+ }
353
+
354
+
355
+ @auto_docstring
356
+ class Cohere2Model(Cohere2PreTrainedModel):
357
+ def __init__(self, config: Cohere2Config):
358
+ super().__init__(config)
359
+ self.padding_idx = config.pad_token_id
360
+ self.vocab_size = config.vocab_size
361
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
362
+ self.layers = nn.ModuleList(
363
+ [Cohere2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
364
+ )
365
+ self.norm = Cohere2LayerNorm(hidden_size=(config.hidden_size), eps=config.layer_norm_eps)
366
+ self.rotary_emb = Cohere2RotaryEmbedding(config)
367
+ self.gradient_checkpointing = False
368
+
369
+ # Initialize weights and apply final processing
370
+ self.post_init()
371
+
372
+ @merge_with_config_defaults
373
+ @capture_outputs
374
+ @auto_docstring
375
+ def forward(
376
+ self,
377
+ input_ids: torch.LongTensor | None = None,
378
+ attention_mask: torch.Tensor | None = None,
379
+ position_ids: torch.LongTensor | None = None,
380
+ past_key_values: Cache | None = None,
381
+ inputs_embeds: torch.FloatTensor | None = None,
382
+ use_cache: bool | None = None,
383
+ **kwargs: Unpack[TransformersKwargs],
384
+ ) -> BaseModelOutputWithPast:
385
+ if (input_ids is None) ^ (inputs_embeds is not None):
386
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
387
+
388
+ if inputs_embeds is None:
389
+ inputs_embeds = self.embed_tokens(input_ids)
390
+
391
+ if use_cache and past_key_values is None:
392
+ past_key_values = DynamicCache(config=self.config)
393
+
394
+ if position_ids is None:
395
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
396
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
397
+ position_ids = position_ids.unsqueeze(0)
398
+
399
+ if not isinstance(causal_mask_mapping := attention_mask, dict):
400
+ mask_kwargs = {
401
+ "config": self.config,
402
+ "inputs_embeds": inputs_embeds,
403
+ "attention_mask": attention_mask,
404
+ "past_key_values": past_key_values,
405
+ "position_ids": position_ids,
406
+ }
407
+ causal_mask_mapping = {
408
+ "full_attention": create_causal_mask(**mask_kwargs),
409
+ "sliding_attention": create_sliding_window_causal_mask(**mask_kwargs),
410
+ }
411
+
412
+ hidden_states = inputs_embeds
413
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
414
+
415
+ for i, decoder_layer in enumerate(self.layers):
416
+ hidden_states = decoder_layer(
417
+ hidden_states,
418
+ attention_mask=causal_mask_mapping[self.config.layer_types[i]],
419
+ position_embeddings=position_embeddings,
420
+ past_key_values=past_key_values,
421
+ use_cache=use_cache,
422
+ position_ids=position_ids,
423
+ **kwargs,
424
+ )
425
+
426
+ hidden_states = self.norm(hidden_states)
427
+ return BaseModelOutputWithPast(
428
+ last_hidden_state=hidden_states,
429
+ past_key_values=past_key_values,
430
+ )
431
+
432
+
433
+ @auto_docstring
434
+ class Cohere2ForCausalLM(Cohere2PreTrainedModel, GenerationMixin):
435
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
436
+ _tp_plan = {"lm_head": "colwise_gather_output"}
437
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
438
+
439
+ def __init__(self, config):
440
+ super().__init__(config)
441
+ self.model = Cohere2Model(config)
442
+ self.vocab_size = config.vocab_size
443
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
444
+ self.logit_scale = config.logit_scale
445
+ self.tie_word_embeddings = config.tie_word_embeddings
446
+
447
+ # Initialize weights and apply final processing
448
+ self.post_init()
449
+
450
+ @can_return_tuple
451
+ @auto_docstring
452
+ def forward(
453
+ self,
454
+ input_ids: torch.LongTensor | None = None,
455
+ attention_mask: torch.Tensor | None = None,
456
+ position_ids: torch.LongTensor | None = None,
457
+ past_key_values: Cache | None = None,
458
+ inputs_embeds: torch.FloatTensor | None = None,
459
+ labels: torch.LongTensor | None = None,
460
+ use_cache: bool | None = None,
461
+ logits_to_keep: int | torch.Tensor = 0,
462
+ **kwargs: Unpack[TransformersKwargs],
463
+ ) -> CausalLMOutputWithPast:
464
+ r"""
465
+ Example:
466
+
467
+ ```python
468
+ >> from transformers import AutoTokenizer, Cohere2ForCausalLM
469
+
470
+ >> model = Cohere2ForCausalLM.from_pretrained("Cohere2ForAI/c4ai-command-r-v01")
471
+ >> tokenizer = AutoTokenizer.from_pretrained("Cohere2ForAI/c4ai-command-r-v01")
472
+
473
+ >> prompt = "Hey, are you conscious? Can you talk to me?"
474
+ >> inputs = tokenizer(prompt, return_tensors="pt")
475
+
476
+ >> # Generate
477
+ >> generate_ids = model.generate(inputs.input_ids, max_length=30)
478
+ >> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
479
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
480
+ ```"""
481
+ outputs: BaseModelOutputWithPast = self.model(
482
+ input_ids=input_ids,
483
+ attention_mask=attention_mask,
484
+ position_ids=position_ids,
485
+ past_key_values=past_key_values,
486
+ inputs_embeds=inputs_embeds,
487
+ use_cache=use_cache,
488
+ **kwargs,
489
+ )
490
+
491
+ hidden_states = outputs.last_hidden_state
492
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
493
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
494
+ logits = logits * self.logit_scale # main diff from Llama
495
+
496
+ loss = None
497
+ if labels is not None:
498
+ loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
499
+
500
+ return CausalLMOutputWithPast(
501
+ loss=loss,
502
+ logits=logits,
503
+ past_key_values=outputs.past_key_values,
504
+ hidden_states=outputs.hidden_states,
505
+ attentions=outputs.attentions,
506
+ )
507
+
508
+
509
+ __all__ = ["Cohere2ForCausalLM", "Cohere2Model", "Cohere2PreTrainedModel"]
third_party/transformers/src/transformers/models/cohere2/modular_cohere2.py ADDED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 Cohere Inc. HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ from collections.abc import Callable
16
+
17
+ import torch
18
+ import torch.nn as nn
19
+ from huggingface_hub.dataclasses import strict
20
+
21
+ from ...cache_utils import Cache, DynamicCache
22
+ from ...configuration_utils import PreTrainedConfig
23
+ from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask
24
+ from ...modeling_outputs import BaseModelOutputWithPast
25
+ from ...modeling_rope_utils import (
26
+ RopeParameters,
27
+ dynamic_rope_update,
28
+ )
29
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS
30
+ from ...processing_utils import Unpack
31
+ from ...utils import TransformersKwargs, auto_docstring, logging
32
+ from ...utils.generic import maybe_autocast
33
+ from ..cohere.modeling_cohere import (
34
+ CohereAttention,
35
+ CohereDecoderLayer,
36
+ CohereForCausalLM,
37
+ CohereLayerNorm,
38
+ CoherePreTrainedModel,
39
+ CohereRotaryEmbedding,
40
+ apply_rotary_pos_emb,
41
+ eager_attention_forward,
42
+ )
43
+ from ..gemma2.modeling_gemma2 import Gemma2Model
44
+
45
+
46
+ logger = logging.get_logger(__name__)
47
+
48
+
49
+ @auto_docstring(checkpoint="CohereForAI/c4ai-command-r-v01")
50
+ @strict
51
+ class Cohere2Config(PreTrainedConfig):
52
+ r"""
53
+ logit_scale (`float`, *optional*, defaults to 0.0625):
54
+ The scaling factor for the output logits.
55
+
56
+ ```python
57
+ >>> from transformers import Cohere2Model, Cohere2Config
58
+
59
+ >>> # Initializing a Cohere Nextmodel configuration
60
+ >>> configuration = Cohere2Config()
61
+
62
+ >>> # Initializing a model from the Cohere2 configuration
63
+ >>> model = Cohere2Model(configuration) # doctest: +SKIP
64
+
65
+ >>> # Accessing the model configuration
66
+ >>> configuration = model.config # doctest: +SKIP
67
+ ```
68
+ """
69
+
70
+ model_type = "cohere2"
71
+ keys_to_ignore_at_inference = ["past_key_values"]
72
+ base_model_tp_plan = {
73
+ "layers.*.self_attn.q_proj": "colwise",
74
+ "layers.*.self_attn.k_proj": "colwise",
75
+ "layers.*.self_attn.v_proj": "colwise",
76
+ "layers.*.self_attn.o_proj": "rowwise",
77
+ "layers.*.mlp.gate_proj": "colwise",
78
+ "layers.*.mlp.up_proj": "colwise",
79
+ "layers.*.mlp.down_proj": "rowwise",
80
+ }
81
+ base_model_pp_plan = {
82
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
83
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
84
+ "norm": (["hidden_states"], ["hidden_states"]),
85
+ }
86
+
87
+ vocab_size: int = 256000
88
+ hidden_size: int = 8192
89
+ intermediate_size: int = 22528
90
+ logit_scale: float = 0.0625
91
+ num_hidden_layers: int = 40
92
+ num_attention_heads: int = 64
93
+ num_key_value_heads: int | None = None
94
+ hidden_act: str = "silu"
95
+ max_position_embeddings: int = 8192
96
+ initializer_range: float = 0.02
97
+ layer_norm_eps: float = 1e-5
98
+ use_cache: bool = True
99
+ pad_token_id: int | None = 0
100
+ bos_token_id: int | None = 5
101
+ eos_token_id: int | list[int] | None = 255001
102
+ tie_word_embeddings: bool = True
103
+ rope_parameters: RopeParameters | dict | None = None
104
+ attention_bias: bool = False
105
+ attention_dropout: float | int = 0.0
106
+ sliding_window: int | None = 4096
107
+ layer_types: list[str] | None = None
108
+
109
+ def __post_init__(self, **kwargs):
110
+ if self.num_key_value_heads is None:
111
+ self.num_key_value_heads = self.num_attention_heads
112
+
113
+ # Need to specify head_dim in the config so it can be used in the attention forward functions
114
+ self.head_dim = self.hidden_size // self.num_attention_heads
115
+
116
+ # BC -> the pattern used to be a simple int, and it's still present in configs on the Hub
117
+ if self.layer_types is None:
118
+ # BC -> the pattern used to be a simple int, and it's still present in configs on the Hub
119
+ _sliding_window_pattern = kwargs.pop("sliding_window_pattern", 4)
120
+ self.layer_types = [
121
+ "sliding_attention" if bool((i + 1) % _sliding_window_pattern) else "full_attention"
122
+ for i in range(self.num_hidden_layers)
123
+ ]
124
+
125
+ super().__post_init__(**kwargs)
126
+
127
+
128
+ class Cohere2RotaryEmbedding(CohereRotaryEmbedding):
129
+ @torch.no_grad()
130
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
131
+ def forward(self, x, position_ids):
132
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1)
133
+ position_ids_expanded = position_ids[:, None, :].float()
134
+
135
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
136
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
137
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
138
+ emb = torch.repeat_interleave(freqs, 2, dim=-1) # diff from Llama: we interleave() instead of cat()
139
+ cos = emb.cos() * self.attention_scaling
140
+ sin = emb.sin() * self.attention_scaling
141
+
142
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
143
+
144
+
145
+ class Cohere2LayerNorm(CohereLayerNorm):
146
+ pass
147
+
148
+
149
+ class Cohere2Attention(CohereAttention):
150
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
151
+
152
+ def __init__(self, config: Cohere2Config, layer_idx: int | None = None):
153
+ nn.Module.__init__(self)
154
+ self.config = config
155
+ self.layer_idx = layer_idx
156
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
157
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
158
+ self.scaling = self.head_dim**-0.5
159
+ self.attention_dropout = config.attention_dropout
160
+ self.is_causal = True
161
+ layer_type = config.layer_types[layer_idx] if hasattr(config, "layer_types") else None
162
+ self.sliding_window = config.sliding_window if layer_type == "sliding_attention" else None
163
+
164
+ self.q_proj = nn.Linear(
165
+ config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
166
+ )
167
+ self.k_proj = nn.Linear(
168
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
169
+ )
170
+ self.v_proj = nn.Linear(
171
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
172
+ )
173
+ self.o_proj = nn.Linear(
174
+ config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
175
+ )
176
+
177
+ def forward(
178
+ self,
179
+ hidden_states: torch.Tensor,
180
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
181
+ attention_mask: torch.Tensor | None,
182
+ past_key_values: Cache | None = None,
183
+ **kwargs: Unpack[TransformersKwargs],
184
+ ) -> tuple[torch.Tensor, torch.Tensor | None, tuple[torch.Tensor] | None]:
185
+ input_shape = hidden_states.shape[:-1]
186
+ hidden_shape = (*input_shape, -1, self.head_dim)
187
+
188
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
189
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
190
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
191
+
192
+ cos, sin = position_embeddings
193
+ if self.sliding_window is not None:
194
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
195
+
196
+ if past_key_values is not None:
197
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
198
+
199
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
200
+ self.config._attn_implementation, eager_attention_forward
201
+ )
202
+
203
+ attn_output, attn_weights = attention_interface(
204
+ self,
205
+ query_states,
206
+ key_states,
207
+ value_states,
208
+ attention_mask,
209
+ dropout=0.0 if not self.training else self.attention_dropout,
210
+ scaling=self.scaling,
211
+ sliding_window=self.sliding_window,
212
+ **kwargs,
213
+ )
214
+
215
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
216
+ attn_output = self.o_proj(attn_output)
217
+ return attn_output, attn_weights
218
+
219
+
220
+ class Cohere2DecoderLayer(CohereDecoderLayer):
221
+ def __init__(self, config: Cohere2Config, layer_idx: int):
222
+ super().__init__(config, layer_idx)
223
+
224
+ def forward(
225
+ self,
226
+ hidden_states: torch.Tensor,
227
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
228
+ attention_mask: torch.Tensor | None = None,
229
+ past_key_values: Cache | None = None,
230
+ use_cache: bool | None = False,
231
+ **kwargs: Unpack[TransformersKwargs],
232
+ ) -> tuple[torch.FloatTensor, tuple[torch.FloatTensor, torch.FloatTensor] | None]:
233
+ residual = hidden_states
234
+ hidden_states = self.input_layernorm(hidden_states)
235
+ hidden_states_attention, _ = self.self_attn(
236
+ hidden_states=hidden_states,
237
+ position_embeddings=position_embeddings,
238
+ attention_mask=attention_mask,
239
+ past_key_values=past_key_values,
240
+ use_cache=use_cache,
241
+ **kwargs,
242
+ )
243
+
244
+ hidden_states_mlp = self.mlp(hidden_states)
245
+ hidden_states = residual + hidden_states_attention + hidden_states_mlp
246
+ return hidden_states
247
+
248
+
249
+ class Cohere2PreTrainedModel(CoherePreTrainedModel):
250
+ config: Cohere2Config
251
+ _can_record_outputs = {
252
+ "hidden_states": Cohere2DecoderLayer,
253
+ "attentions": Cohere2Attention,
254
+ }
255
+
256
+
257
+ class Cohere2Model(Gemma2Model):
258
+ def __init__(self, config: Cohere2Config):
259
+ super().__init__(config)
260
+ self.norm = Cohere2LayerNorm(hidden_size=(config.hidden_size), eps=config.layer_norm_eps)
261
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
262
+
263
+ def forward(
264
+ self,
265
+ input_ids: torch.LongTensor | None = None,
266
+ attention_mask: torch.Tensor | None = None,
267
+ position_ids: torch.LongTensor | None = None,
268
+ past_key_values: Cache | None = None,
269
+ inputs_embeds: torch.FloatTensor | None = None,
270
+ use_cache: bool | None = None,
271
+ **kwargs: Unpack[TransformersKwargs],
272
+ ) -> BaseModelOutputWithPast:
273
+ if (input_ids is None) ^ (inputs_embeds is not None):
274
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
275
+
276
+ if inputs_embeds is None:
277
+ inputs_embeds = self.embed_tokens(input_ids)
278
+
279
+ if use_cache and past_key_values is None:
280
+ past_key_values = DynamicCache(config=self.config)
281
+
282
+ if position_ids is None:
283
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
284
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
285
+ position_ids = position_ids.unsqueeze(0)
286
+
287
+ if not isinstance(causal_mask_mapping := attention_mask, dict):
288
+ mask_kwargs = {
289
+ "config": self.config,
290
+ "inputs_embeds": inputs_embeds,
291
+ "attention_mask": attention_mask,
292
+ "past_key_values": past_key_values,
293
+ "position_ids": position_ids,
294
+ }
295
+ causal_mask_mapping = {
296
+ "full_attention": create_causal_mask(**mask_kwargs),
297
+ "sliding_attention": create_sliding_window_causal_mask(**mask_kwargs),
298
+ }
299
+
300
+ hidden_states = inputs_embeds
301
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
302
+
303
+ for i, decoder_layer in enumerate(self.layers):
304
+ hidden_states = decoder_layer(
305
+ hidden_states,
306
+ attention_mask=causal_mask_mapping[self.config.layer_types[i]],
307
+ position_embeddings=position_embeddings,
308
+ past_key_values=past_key_values,
309
+ use_cache=use_cache,
310
+ position_ids=position_ids,
311
+ **kwargs,
312
+ )
313
+
314
+ hidden_states = self.norm(hidden_states)
315
+ return BaseModelOutputWithPast(
316
+ last_hidden_state=hidden_states,
317
+ past_key_values=past_key_values,
318
+ )
319
+
320
+
321
+ class Cohere2ForCausalLM(CohereForCausalLM):
322
+ pass
323
+
324
+
325
+ __all__ = ["Cohere2Config", "Cohere2ForCausalLM", "Cohere2Model", "Cohere2PreTrainedModel"]
third_party/transformers/src/transformers/models/conditional_detr/__init__.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from .configuration_conditional_detr import *
22
+ from .image_processing_conditional_detr import *
23
+ from .image_processing_pil_conditional_detr import *
24
+ from .modeling_conditional_detr import *
25
+ else:
26
+ import sys
27
+
28
+ _file = globals()["__file__"]
29
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/conditional_detr/configuration_conditional_detr.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Conditional DETR model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...backbone_utils import consolidate_backbone_kwargs_to_config
19
+ from ...configuration_utils import PreTrainedConfig
20
+ from ...utils import auto_docstring
21
+ from ..auto import AutoConfig
22
+
23
+
24
+ @auto_docstring(checkpoint="microsoft/conditional-detr-resnet-50")
25
+ @strict
26
+ class ConditionalDetrConfig(PreTrainedConfig):
27
+ r"""
28
+ num_queries (`int`, *optional*, defaults to 100):
29
+ Number of object queries, i.e. detection slots. This is the maximal number of objects
30
+ [`ConditionalDetrModel`] can detect in a single image. For COCO, we recommend 100 queries.
31
+ auxiliary_loss (`bool`, *optional*, defaults to `False`):
32
+ Whether auxiliary decoding losses (loss at each decoder layer) are to be used.
33
+ position_embedding_type (`str`, *optional*, defaults to `"sine"`):
34
+ Type of position embeddings to be used on top of the image features. One of `"sine"` or `"learned"`.
35
+ dilation (`bool`, *optional*, defaults to `False`):
36
+ Whether to replace stride with dilation in the last convolutional block (DC5). Only supported when
37
+ `use_timm_backbone` = `True`.
38
+
39
+ Examples:
40
+
41
+ ```python
42
+ >>> from transformers import ConditionalDetrConfig, ConditionalDetrModel
43
+
44
+ >>> # Initializing a Conditional DETR microsoft/conditional-detr-resnet-50 style configuration
45
+ >>> configuration = ConditionalDetrConfig()
46
+
47
+ >>> # Initializing a model (with random weights) from the microsoft/conditional-detr-resnet-50 style configuration
48
+ >>> model = ConditionalDetrModel(configuration)
49
+
50
+ >>> # Accessing the model configuration
51
+ >>> configuration = model.config
52
+ ```"""
53
+
54
+ model_type = "conditional_detr"
55
+ sub_configs = {"backbone_config": AutoConfig}
56
+ keys_to_ignore_at_inference = ["past_key_values"]
57
+ attribute_map = {
58
+ "hidden_size": "d_model",
59
+ "num_attention_heads": "encoder_attention_heads",
60
+ "num_hidden_layers": "encoder_layers",
61
+ }
62
+
63
+ backbone_config: dict | PreTrainedConfig | None = None
64
+ num_channels: int = 3
65
+ num_queries: int = 300
66
+ encoder_layers: int = 6
67
+ encoder_ffn_dim: int = 2048
68
+ encoder_attention_heads: int = 8
69
+ decoder_layers: int = 6
70
+ decoder_ffn_dim: int = 2048
71
+ decoder_attention_heads: int = 8
72
+ encoder_layerdrop: float | int = 0.0
73
+ decoder_layerdrop: float | int = 0.0
74
+ is_encoder_decoder: bool = True
75
+ activation_function: str = "relu"
76
+ d_model: int = 256
77
+ dropout: float | int = 0.1
78
+ attention_dropout: float | int = 0.0
79
+ activation_dropout: float | int = 0.0
80
+ init_std: float = 0.02
81
+ init_xavier_std: float = 1.0
82
+ auxiliary_loss: bool = False
83
+ position_embedding_type: str = "sine"
84
+ dilation: bool = False
85
+ class_cost: int = 2
86
+ bbox_cost: int = 5
87
+ giou_cost: int = 2
88
+ mask_loss_coefficient: int = 1
89
+ dice_loss_coefficient: int = 1
90
+ cls_loss_coefficient: int = 2
91
+ bbox_loss_coefficient: int = 5
92
+ giou_loss_coefficient: int = 2
93
+ focal_alpha: float = 0.25
94
+
95
+ def __post_init__(self, **kwargs):
96
+ # Init timm backbone with hardcoded values for BC
97
+ backbone_kwargs = kwargs.get("backbone_kwargs", {})
98
+ timm_default_kwargs = {
99
+ "num_channels": backbone_kwargs.get("num_channels", self.num_channels),
100
+ "features_only": True,
101
+ "use_pretrained_backbone": False,
102
+ "out_indices": backbone_kwargs.get("out_indices", [1, 2, 3, 4]),
103
+ }
104
+ if self.dilation:
105
+ timm_default_kwargs["output_stride"] = backbone_kwargs.get("output_stride", 16)
106
+
107
+ self.backbone_config, kwargs = consolidate_backbone_kwargs_to_config(
108
+ backbone_config=self.backbone_config,
109
+ default_backbone="resnet50",
110
+ default_config_type="resnet",
111
+ default_config_kwargs={"out_features": ["stage4"]},
112
+ timm_default_kwargs=timm_default_kwargs,
113
+ **kwargs,
114
+ )
115
+
116
+ super().__post_init__(**kwargs)
117
+
118
+
119
+ __all__ = ["ConditionalDetrConfig"]
third_party/transformers/src/transformers/models/conditional_detr/convert_conditional_detr_original_pytorch_checkpoint_to_pytorch.py ADDED
@@ -0,0 +1,363 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Inc. team.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Convert Conditional DETR checkpoints."""
15
+
16
+ import argparse
17
+ import json
18
+ from collections import OrderedDict
19
+ from io import BytesIO
20
+ from pathlib import Path
21
+
22
+ import httpx
23
+ import torch
24
+ from huggingface_hub import hf_hub_download
25
+ from PIL import Image
26
+
27
+ from transformers import (
28
+ ConditionalDetrConfig,
29
+ ConditionalDetrForObjectDetection,
30
+ ConditionalDetrForSegmentation,
31
+ ConditionalDetrImageProcessor,
32
+ )
33
+ from transformers.utils import logging
34
+
35
+
36
+ logging.set_verbosity_info()
37
+ logger = logging.get_logger(__name__)
38
+
39
+ # here we list all keys to be renamed (original name on the left, our name on the right)
40
+ rename_keys = []
41
+ for i in range(6):
42
+ # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
43
+ rename_keys.append(
44
+ (f"transformer.encoder.layers.{i}.self_attn.out_proj.weight", f"encoder.layers.{i}.self_attn.out_proj.weight")
45
+ )
46
+ rename_keys.append(
47
+ (f"transformer.encoder.layers.{i}.self_attn.out_proj.bias", f"encoder.layers.{i}.self_attn.out_proj.bias")
48
+ )
49
+ rename_keys.append((f"transformer.encoder.layers.{i}.linear1.weight", f"encoder.layers.{i}.fc1.weight"))
50
+ rename_keys.append((f"transformer.encoder.layers.{i}.linear1.bias", f"encoder.layers.{i}.fc1.bias"))
51
+ rename_keys.append((f"transformer.encoder.layers.{i}.linear2.weight", f"encoder.layers.{i}.fc2.weight"))
52
+ rename_keys.append((f"transformer.encoder.layers.{i}.linear2.bias", f"encoder.layers.{i}.fc2.bias"))
53
+ rename_keys.append(
54
+ (f"transformer.encoder.layers.{i}.norm1.weight", f"encoder.layers.{i}.self_attn_layer_norm.weight")
55
+ )
56
+ rename_keys.append((f"transformer.encoder.layers.{i}.norm1.bias", f"encoder.layers.{i}.self_attn_layer_norm.bias"))
57
+ rename_keys.append((f"transformer.encoder.layers.{i}.norm2.weight", f"encoder.layers.{i}.final_layer_norm.weight"))
58
+ rename_keys.append((f"transformer.encoder.layers.{i}.norm2.bias", f"encoder.layers.{i}.final_layer_norm.bias"))
59
+ # decoder layers: 2 times output projection, 2 feedforward neural networks and 3 layernorms
60
+ rename_keys.append(
61
+ (f"transformer.decoder.layers.{i}.self_attn.out_proj.weight", f"decoder.layers.{i}.self_attn.out_proj.weight")
62
+ )
63
+ rename_keys.append(
64
+ (f"transformer.decoder.layers.{i}.self_attn.out_proj.bias", f"decoder.layers.{i}.self_attn.out_proj.bias")
65
+ )
66
+ rename_keys.append(
67
+ (
68
+ f"transformer.decoder.layers.{i}.cross_attn.out_proj.weight",
69
+ f"decoder.layers.{i}.encoder_attn.out_proj.weight",
70
+ )
71
+ )
72
+ rename_keys.append(
73
+ (
74
+ f"transformer.decoder.layers.{i}.cross_attn.out_proj.bias",
75
+ f"decoder.layers.{i}.encoder_attn.out_proj.bias",
76
+ )
77
+ )
78
+ rename_keys.append((f"transformer.decoder.layers.{i}.linear1.weight", f"decoder.layers.{i}.fc1.weight"))
79
+ rename_keys.append((f"transformer.decoder.layers.{i}.linear1.bias", f"decoder.layers.{i}.fc1.bias"))
80
+ rename_keys.append((f"transformer.decoder.layers.{i}.linear2.weight", f"decoder.layers.{i}.fc2.weight"))
81
+ rename_keys.append((f"transformer.decoder.layers.{i}.linear2.bias", f"decoder.layers.{i}.fc2.bias"))
82
+ rename_keys.append(
83
+ (f"transformer.decoder.layers.{i}.norm1.weight", f"decoder.layers.{i}.self_attn_layer_norm.weight")
84
+ )
85
+ rename_keys.append((f"transformer.decoder.layers.{i}.norm1.bias", f"decoder.layers.{i}.self_attn_layer_norm.bias"))
86
+ rename_keys.append(
87
+ (f"transformer.decoder.layers.{i}.norm2.weight", f"decoder.layers.{i}.encoder_attn_layer_norm.weight")
88
+ )
89
+ rename_keys.append(
90
+ (f"transformer.decoder.layers.{i}.norm2.bias", f"decoder.layers.{i}.encoder_attn_layer_norm.bias")
91
+ )
92
+ rename_keys.append((f"transformer.decoder.layers.{i}.norm3.weight", f"decoder.layers.{i}.final_layer_norm.weight"))
93
+ rename_keys.append((f"transformer.decoder.layers.{i}.norm3.bias", f"decoder.layers.{i}.final_layer_norm.bias"))
94
+
95
+ # q, k, v projections in self/cross-attention in decoder for conditional DETR
96
+ # Self-attention projections moved into self_attn module
97
+ rename_keys.append(
98
+ (
99
+ f"transformer.decoder.layers.{i}.sa_qcontent_proj.weight",
100
+ f"decoder.layers.{i}.self_attn.q_content_proj.weight",
101
+ )
102
+ )
103
+ rename_keys.append(
104
+ (
105
+ f"transformer.decoder.layers.{i}.sa_kcontent_proj.weight",
106
+ f"decoder.layers.{i}.self_attn.k_content_proj.weight",
107
+ )
108
+ )
109
+ rename_keys.append(
110
+ (f"transformer.decoder.layers.{i}.sa_qpos_proj.weight", f"decoder.layers.{i}.self_attn.q_pos_proj.weight")
111
+ )
112
+ rename_keys.append(
113
+ (f"transformer.decoder.layers.{i}.sa_kpos_proj.weight", f"decoder.layers.{i}.self_attn.k_pos_proj.weight")
114
+ )
115
+ rename_keys.append(
116
+ (f"transformer.decoder.layers.{i}.sa_v_proj.weight", f"decoder.layers.{i}.self_attn.v_proj.weight")
117
+ )
118
+ # Cross-attention projections moved into encoder_attn module
119
+ rename_keys.append(
120
+ (
121
+ f"transformer.decoder.layers.{i}.ca_qcontent_proj.weight",
122
+ f"decoder.layers.{i}.encoder_attn.q_content_proj.weight",
123
+ )
124
+ )
125
+ # rename_keys.append((f"transformer.decoder.layers.{i}.ca_qpos_proj.weight", f"decoder.layers.{i}.encoder_attn.q_pos_proj.weight"))
126
+ rename_keys.append(
127
+ (
128
+ f"transformer.decoder.layers.{i}.ca_kcontent_proj.weight",
129
+ f"decoder.layers.{i}.encoder_attn.k_content_proj.weight",
130
+ )
131
+ )
132
+ rename_keys.append(
133
+ (f"transformer.decoder.layers.{i}.ca_kpos_proj.weight", f"decoder.layers.{i}.encoder_attn.k_pos_proj.weight")
134
+ )
135
+ rename_keys.append(
136
+ (f"transformer.decoder.layers.{i}.ca_v_proj.weight", f"decoder.layers.{i}.encoder_attn.v_proj.weight")
137
+ )
138
+ rename_keys.append(
139
+ (
140
+ f"transformer.decoder.layers.{i}.ca_qpos_sine_proj.weight",
141
+ f"decoder.layers.{i}.encoder_attn.q_pos_sine_proj.weight",
142
+ )
143
+ )
144
+
145
+ rename_keys.append(
146
+ (f"transformer.decoder.layers.{i}.sa_qcontent_proj.bias", f"decoder.layers.{i}.self_attn.q_content_proj.bias")
147
+ )
148
+ rename_keys.append(
149
+ (f"transformer.decoder.layers.{i}.sa_kcontent_proj.bias", f"decoder.layers.{i}.self_attn.k_content_proj.bias")
150
+ )
151
+ rename_keys.append(
152
+ (f"transformer.decoder.layers.{i}.sa_qpos_proj.bias", f"decoder.layers.{i}.self_attn.q_pos_proj.bias")
153
+ )
154
+ rename_keys.append(
155
+ (f"transformer.decoder.layers.{i}.sa_kpos_proj.bias", f"decoder.layers.{i}.self_attn.k_pos_proj.bias")
156
+ )
157
+ rename_keys.append((f"transformer.decoder.layers.{i}.sa_v_proj.bias", f"decoder.layers.{i}.self_attn.v_proj.bias"))
158
+ rename_keys.append(
159
+ (
160
+ f"transformer.decoder.layers.{i}.ca_qcontent_proj.bias",
161
+ f"decoder.layers.{i}.encoder_attn.q_content_proj.bias",
162
+ )
163
+ )
164
+ # rename_keys.append((f"transformer.decoder.layers.{i}.ca_qpos_proj.bias", f"decoder.layers.{i}.encoder_attn.q_pos_proj.bias"))
165
+ rename_keys.append(
166
+ (
167
+ f"transformer.decoder.layers.{i}.ca_kcontent_proj.bias",
168
+ f"decoder.layers.{i}.encoder_attn.k_content_proj.bias",
169
+ )
170
+ )
171
+ rename_keys.append(
172
+ (f"transformer.decoder.layers.{i}.ca_kpos_proj.bias", f"decoder.layers.{i}.encoder_attn.k_pos_proj.bias")
173
+ )
174
+ rename_keys.append(
175
+ (f"transformer.decoder.layers.{i}.ca_v_proj.bias", f"decoder.layers.{i}.encoder_attn.v_proj.bias")
176
+ )
177
+ rename_keys.append(
178
+ (
179
+ f"transformer.decoder.layers.{i}.ca_qpos_sine_proj.bias",
180
+ f"decoder.layers.{i}.encoder_attn.q_pos_sine_proj.bias",
181
+ )
182
+ )
183
+
184
+ # convolutional projection + query embeddings + layernorm of decoder + class and bounding box heads
185
+ # for conditional DETR, also convert reference point head and query scale MLP
186
+ rename_keys.extend(
187
+ [
188
+ ("input_proj.weight", "input_projection.weight"),
189
+ ("input_proj.bias", "input_projection.bias"),
190
+ ("query_embed.weight", "query_position_embeddings.weight"),
191
+ ("transformer.decoder.norm.weight", "decoder.layernorm.weight"),
192
+ ("transformer.decoder.norm.bias", "decoder.layernorm.bias"),
193
+ ("class_embed.weight", "class_labels_classifier.weight"),
194
+ ("class_embed.bias", "class_labels_classifier.bias"),
195
+ ("bbox_embed.layers.0.weight", "bbox_predictor.layers.0.weight"),
196
+ ("bbox_embed.layers.0.bias", "bbox_predictor.layers.0.bias"),
197
+ ("bbox_embed.layers.1.weight", "bbox_predictor.layers.1.weight"),
198
+ ("bbox_embed.layers.1.bias", "bbox_predictor.layers.1.bias"),
199
+ ("bbox_embed.layers.2.weight", "bbox_predictor.layers.2.weight"),
200
+ ("bbox_embed.layers.2.bias", "bbox_predictor.layers.2.bias"),
201
+ ("transformer.decoder.ref_point_head.layers.0.weight", "decoder.ref_point_head.layers.0.weight"),
202
+ ("transformer.decoder.ref_point_head.layers.0.bias", "decoder.ref_point_head.layers.0.bias"),
203
+ ("transformer.decoder.ref_point_head.layers.1.weight", "decoder.ref_point_head.layers.1.weight"),
204
+ ("transformer.decoder.ref_point_head.layers.1.bias", "decoder.ref_point_head.layers.1.bias"),
205
+ ("transformer.decoder.query_scale.layers.0.weight", "decoder.query_scale.layers.0.weight"),
206
+ ("transformer.decoder.query_scale.layers.0.bias", "decoder.query_scale.layers.0.bias"),
207
+ ("transformer.decoder.query_scale.layers.1.weight", "decoder.query_scale.layers.1.weight"),
208
+ ("transformer.decoder.query_scale.layers.1.bias", "decoder.query_scale.layers.1.bias"),
209
+ ("transformer.decoder.layers.0.ca_qpos_proj.weight", "decoder.layers.0.encoder_attn.q_pos_proj.weight"),
210
+ ("transformer.decoder.layers.0.ca_qpos_proj.bias", "decoder.layers.0.encoder_attn.q_pos_proj.bias"),
211
+ ]
212
+ )
213
+
214
+
215
+ def rename_key(state_dict, old, new):
216
+ val = state_dict.pop(old)
217
+ state_dict[new] = val
218
+
219
+
220
+ def rename_backbone_keys(state_dict):
221
+ new_state_dict = OrderedDict()
222
+ for key, value in state_dict.items():
223
+ if "backbone.0.body" in key:
224
+ new_key = key.replace("backbone.0.body", "backbone.conv_encoder.model")
225
+ new_state_dict[new_key] = value
226
+ else:
227
+ new_state_dict[key] = value
228
+
229
+ return new_state_dict
230
+
231
+
232
+ def read_in_q_k_v(state_dict, is_panoptic=False):
233
+ prefix = ""
234
+ if is_panoptic:
235
+ prefix = "conditional_detr."
236
+
237
+ # first: transformer encoder
238
+ for i in range(6):
239
+ # read in weights + bias of input projection layer (in PyTorch's MultiHeadAttention, this is a single matrix + bias)
240
+ in_proj_weight = state_dict.pop(f"{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_weight")
241
+ in_proj_bias = state_dict.pop(f"{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_bias")
242
+ # next, add query, keys and values (in that order) to the state dict
243
+ state_dict[f"encoder.layers.{i}.self_attn.q_proj.weight"] = in_proj_weight[:256, :]
244
+ state_dict[f"encoder.layers.{i}.self_attn.q_proj.bias"] = in_proj_bias[:256]
245
+ state_dict[f"encoder.layers.{i}.self_attn.k_proj.weight"] = in_proj_weight[256:512, :]
246
+ state_dict[f"encoder.layers.{i}.self_attn.k_proj.bias"] = in_proj_bias[256:512]
247
+ state_dict[f"encoder.layers.{i}.self_attn.v_proj.weight"] = in_proj_weight[-256:, :]
248
+ state_dict[f"encoder.layers.{i}.self_attn.v_proj.bias"] = in_proj_bias[-256:]
249
+
250
+
251
+ # We will verify our results on an image of cute cats
252
+ def prepare_img():
253
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
254
+ with httpx.stream("GET", url) as response:
255
+ image = Image.open(BytesIO(response.read()))
256
+
257
+ return image
258
+
259
+
260
+ @torch.no_grad()
261
+ def convert_conditional_detr_checkpoint(model_name, pytorch_dump_folder_path):
262
+ """
263
+ Copy/paste/tweak model's weights to our CONDITIONAL_DETR structure.
264
+ """
265
+
266
+ # load default config
267
+ config = ConditionalDetrConfig()
268
+ # set backbone and dilation attributes
269
+ if "resnet101" in model_name:
270
+ config.backbone = "resnet101"
271
+ if "dc5" in model_name:
272
+ config.dilation = True
273
+ is_panoptic = "panoptic" in model_name
274
+ if is_panoptic:
275
+ config.num_labels = 250
276
+ else:
277
+ config.num_labels = 91
278
+ repo_id = "huggingface/label-files"
279
+ filename = "coco-detection-id2label.json"
280
+ id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r"))
281
+ id2label = {int(k): v for k, v in id2label.items()}
282
+ config.id2label = id2label
283
+ config.label2id = {v: k for k, v in id2label.items()}
284
+
285
+ # load image processor
286
+ format = "coco_panoptic" if is_panoptic else "coco_detection"
287
+ image_processor = ConditionalDetrImageProcessor(format=format)
288
+
289
+ # prepare image
290
+ img = prepare_img()
291
+ encoding = image_processor(images=img, return_tensors="pt")
292
+ pixel_values = encoding["pixel_values"]
293
+
294
+ logger.info(f"Converting model {model_name}...")
295
+
296
+ # load original model from torch hub
297
+ conditional_detr = torch.hub.load("DeppMeng/ConditionalDETR", model_name, pretrained=True).eval()
298
+ state_dict = conditional_detr.state_dict()
299
+ # rename keys
300
+ for src, dest in rename_keys:
301
+ if is_panoptic:
302
+ src = "conditional_detr." + src
303
+ rename_key(state_dict, src, dest)
304
+ state_dict = rename_backbone_keys(state_dict)
305
+ # query, key and value matrices need special treatment
306
+ read_in_q_k_v(state_dict, is_panoptic=is_panoptic)
307
+ # important: we need to prepend a prefix to each of the base model keys as the head models use different attributes for them
308
+ prefix = "conditional_detr.model." if is_panoptic else "model."
309
+ for key in state_dict.copy():
310
+ if is_panoptic:
311
+ if (
312
+ key.startswith("conditional_detr")
313
+ and not key.startswith("class_labels_classifier")
314
+ and not key.startswith("bbox_predictor")
315
+ ):
316
+ val = state_dict.pop(key)
317
+ state_dict["conditional_detr.model" + key[4:]] = val
318
+ elif "class_labels_classifier" in key or "bbox_predictor" in key:
319
+ val = state_dict.pop(key)
320
+ state_dict["conditional_detr." + key] = val
321
+ elif key.startswith("bbox_attention") or key.startswith("mask_head"):
322
+ continue
323
+ else:
324
+ val = state_dict.pop(key)
325
+ state_dict[prefix + key] = val
326
+ else:
327
+ if not key.startswith("class_labels_classifier") and not key.startswith("bbox_predictor"):
328
+ val = state_dict.pop(key)
329
+ state_dict[prefix + key] = val
330
+ # finally, create HuggingFace model and load state dict
331
+ model = ConditionalDetrForSegmentation(config) if is_panoptic else ConditionalDetrForObjectDetection(config)
332
+ model.load_state_dict(state_dict)
333
+ model.eval()
334
+ model.push_to_hub(repo_id=f"DepuMeng/{model_name}", commit_message="Add model")
335
+ # verify our conversion
336
+ original_outputs = conditional_detr(pixel_values)
337
+ outputs = model(pixel_values)
338
+ assert torch.allclose(outputs.logits, original_outputs["pred_logits"], atol=1e-4)
339
+ assert torch.allclose(outputs.pred_boxes, original_outputs["pred_boxes"], atol=1e-4)
340
+ if is_panoptic:
341
+ assert torch.allclose(outputs.pred_masks, original_outputs["pred_masks"], atol=1e-4)
342
+
343
+ # Save model and image processor
344
+ logger.info(f"Saving PyTorch model and image processor to {pytorch_dump_folder_path}...")
345
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
346
+ model.save_pretrained(pytorch_dump_folder_path)
347
+ image_processor.save_pretrained(pytorch_dump_folder_path)
348
+
349
+
350
+ if __name__ == "__main__":
351
+ parser = argparse.ArgumentParser()
352
+
353
+ parser.add_argument(
354
+ "--model_name",
355
+ default="conditional_detr_resnet50",
356
+ type=str,
357
+ help="Name of the CONDITIONAL_DETR model you'd like to convert.",
358
+ )
359
+ parser.add_argument(
360
+ "--pytorch_dump_folder_path", default=None, type=str, help="Path to the folder to output PyTorch model."
361
+ )
362
+ args = parser.parse_args()
363
+ convert_conditional_detr_checkpoint(args.model_name, args.pytorch_dump_folder_path)
third_party/transformers/src/transformers/models/conditional_detr/image_processing_conditional_detr.py ADDED
@@ -0,0 +1,1083 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/conditional_detr/modular_conditional_detr.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_conditional_detr.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2022 Microsoft Research Asia and The HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ import pathlib
22
+ from typing import Any, Optional
23
+
24
+ import numpy as np
25
+ import torch
26
+ from torch import nn
27
+ from torchvision.io import read_image
28
+ from torchvision.transforms.v2 import functional as tvF
29
+
30
+ from ...image_processing_backends import TorchvisionBackend
31
+ from ...image_processing_utils import BatchFeature, get_size_dict
32
+ from ...image_transforms import (
33
+ center_to_corners_format,
34
+ corners_to_center_format,
35
+ get_size_with_aspect_ratio,
36
+ safe_squeeze,
37
+ )
38
+ from ...image_utils import (
39
+ IMAGENET_DEFAULT_MEAN,
40
+ IMAGENET_DEFAULT_STD,
41
+ AnnotationFormat,
42
+ AnnotationType,
43
+ ChannelDimension,
44
+ ImageInput,
45
+ PILImageResampling,
46
+ SizeDict,
47
+ get_image_size,
48
+ get_image_size_for_max_height_width,
49
+ get_max_height_width,
50
+ validate_annotations,
51
+ )
52
+ from ...processing_utils import ImagesKwargs, Unpack
53
+ from ...utils import TensorType, auto_docstring, logging
54
+
55
+
56
+ logger = logging.get_logger(__name__)
57
+
58
+
59
+ class ConditionalDetrImageProcessorKwargs(ImagesKwargs, total=False):
60
+ r"""
61
+ format (`str`, *optional*, defaults to `AnnotationFormat.COCO_DETECTION`):
62
+ Data format of the annotations. One of "coco_detection" or "coco_panoptic".
63
+ do_convert_annotations (`bool`, *optional*, defaults to `True`):
64
+ Controls whether to convert the annotations to the format expected by the CONDITIONAL_DETR model. Converts the
65
+ bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`.
66
+ Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method.
67
+ """
68
+
69
+ format: str | AnnotationFormat
70
+ do_convert_annotations: bool
71
+
72
+
73
+ SUPPORTED_ANNOTATION_FORMATS = (AnnotationFormat.COCO_DETECTION, AnnotationFormat.COCO_PANOPTIC)
74
+
75
+
76
+ def binary_mask_to_rle(mask):
77
+ """
78
+ Converts given binary mask of shape `(height, width)` to the run-length encoding (RLE) format.
79
+
80
+ Args:
81
+ mask (`torch.Tensor` or `numpy.array`):
82
+ A binary mask tensor of shape `(height, width)` where 0 denotes background and 1 denotes the target
83
+ segment_id or class_id.
84
+ Returns:
85
+ `List`: Run-length encoded list of the binary mask. Refer to COCO API for more information about the RLE
86
+ format.
87
+ """
88
+ from ...utils import is_torch_tensor
89
+
90
+ if is_torch_tensor(mask):
91
+ mask = mask.numpy()
92
+
93
+ pixels = mask.flatten()
94
+ pixels = np.concatenate([[0], pixels, [0]])
95
+ runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
96
+ runs[1::2] -= runs[::2]
97
+ return list(runs)
98
+
99
+
100
+ def convert_segmentation_to_rle(segmentation):
101
+ """
102
+ Converts given segmentation map of shape `(height, width)` to the run-length encoding (RLE) format.
103
+
104
+ Args:
105
+ segmentation (`torch.Tensor` or `numpy.array`):
106
+ A segmentation map of shape `(height, width)` where each value denotes a segment or class id.
107
+ Returns:
108
+ `list[List]`: A list of lists, where each list is the run-length encoding of a segment / class id.
109
+ """
110
+ segment_ids = torch.unique(segmentation)
111
+
112
+ run_length_encodings = []
113
+ for idx in segment_ids:
114
+ mask = torch.where(segmentation == idx, 1, 0)
115
+ rle = binary_mask_to_rle(mask)
116
+ run_length_encodings.append(rle)
117
+
118
+ return run_length_encodings
119
+
120
+
121
+ def remove_low_and_no_objects(masks, scores, labels, object_mask_threshold, num_labels):
122
+ """
123
+ Binarize the given masks using `object_mask_threshold`, it returns the associated values of `masks`, `scores` and
124
+ `labels`.
125
+
126
+ Args:
127
+ masks (`torch.Tensor`):
128
+ A tensor of shape `(num_queries, height, width)`.
129
+ scores (`torch.Tensor`):
130
+ A tensor of shape `(num_queries)`.
131
+ labels (`torch.Tensor`):
132
+ A tensor of shape `(num_queries)`.
133
+ object_mask_threshold (`float`):
134
+ A number between 0 and 1 used to binarize the masks.
135
+ Raises:
136
+ `ValueError`: Raised when the first dimension doesn't match in all input tensors.
137
+ Returns:
138
+ `tuple[`torch.Tensor`, `torch.Tensor`, `torch.Tensor`]`: The `masks`, `scores` and `labels` without the region
139
+ < `object_mask_threshold`.
140
+ """
141
+ if not (masks.shape[0] == scores.shape[0] == labels.shape[0]):
142
+ raise ValueError("mask, scores and labels must have the same shape!")
143
+
144
+ to_keep = labels.ne(num_labels) & (scores > object_mask_threshold)
145
+
146
+ return masks[to_keep], scores[to_keep], labels[to_keep]
147
+
148
+
149
+ def check_segment_validity(mask_labels, mask_probs, k, mask_threshold=0.5, overlap_mask_area_threshold=0.8):
150
+ # Get the mask associated with the k class
151
+ mask_k = mask_labels == k
152
+ mask_k_area = mask_k.sum()
153
+
154
+ # Compute the area of all the stuff in query k
155
+ original_area = (mask_probs[k] >= mask_threshold).sum()
156
+ mask_exists = mask_k_area > 0 and original_area > 0
157
+
158
+ # Eliminate disconnected tiny segments
159
+ if mask_exists:
160
+ area_ratio = mask_k_area / original_area
161
+ if not area_ratio.item() > overlap_mask_area_threshold:
162
+ mask_exists = False
163
+
164
+ return mask_exists, mask_k
165
+
166
+
167
+ def compute_segments(
168
+ mask_probs,
169
+ pred_scores,
170
+ pred_labels,
171
+ mask_threshold: float = 0.5,
172
+ overlap_mask_area_threshold: float = 0.8,
173
+ label_ids_to_fuse: set[int] | None = None,
174
+ target_size: tuple[int, int] | None = None,
175
+ ):
176
+ height = mask_probs.shape[1] if target_size is None else target_size[0]
177
+ width = mask_probs.shape[2] if target_size is None else target_size[1]
178
+
179
+ segmentation = torch.zeros((height, width), dtype=torch.int32, device=mask_probs.device)
180
+ segments: list[dict] = []
181
+
182
+ if target_size is not None:
183
+ mask_probs = nn.functional.interpolate(
184
+ mask_probs.unsqueeze(0), size=target_size, mode="bilinear", align_corners=False
185
+ )[0]
186
+
187
+ current_segment_id = 0
188
+
189
+ # Weigh each mask by its prediction score
190
+ mask_probs *= pred_scores.view(-1, 1, 1)
191
+ mask_labels = mask_probs.argmax(0) # [height, width]
192
+
193
+ # Keep track of instances of each class
194
+ stuff_memory_list: dict[str, int] = {}
195
+ for k in range(pred_labels.shape[0]):
196
+ pred_class = pred_labels[k].item()
197
+ should_fuse = pred_class in label_ids_to_fuse
198
+
199
+ # Check if mask exists and large enough to be a segment
200
+ mask_exists, mask_k = check_segment_validity(
201
+ mask_labels, mask_probs, k, mask_threshold, overlap_mask_area_threshold
202
+ )
203
+
204
+ if mask_exists:
205
+ if pred_class in stuff_memory_list:
206
+ current_segment_id = stuff_memory_list[pred_class]
207
+ else:
208
+ current_segment_id += 1
209
+
210
+ # Add current object segment to final segmentation map
211
+ segmentation[mask_k] = current_segment_id
212
+ segment_score = round(pred_scores[k].item(), 6)
213
+ segments.append(
214
+ {
215
+ "id": current_segment_id,
216
+ "label_id": pred_class,
217
+ "was_fused": should_fuse,
218
+ "score": segment_score,
219
+ }
220
+ )
221
+ if should_fuse:
222
+ stuff_memory_list[pred_class] = current_segment_id
223
+
224
+ return segmentation, segments
225
+
226
+
227
+ # inspired by https://github.com/facebookresearch/conditional_detr/blob/master/datasets/coco.py#L33
228
+ def convert_coco_poly_to_mask(segmentations, height: int, width: int, device: torch.device) -> torch.Tensor:
229
+ """
230
+ Convert a COCO polygon annotation to a mask.
231
+
232
+ Args:
233
+ segmentations (`list[list[float]]`):
234
+ List of polygons, each polygon represented by a list of x-y coordinates.
235
+ height (`int`):
236
+ Height of the mask.
237
+ width (`int`):
238
+ Width of the mask.
239
+ """
240
+ try:
241
+ from pycocotools import mask as coco_mask
242
+ except ImportError:
243
+ raise ImportError("Pycocotools is not installed in your environment.")
244
+
245
+ masks = []
246
+ for polygons in segmentations:
247
+ rles = coco_mask.frPyObjects(polygons, height, width)
248
+ mask = coco_mask.decode(rles)
249
+ if len(mask.shape) < 3:
250
+ mask = mask[..., None]
251
+ mask = torch.as_tensor(mask, dtype=torch.uint8, device=device)
252
+ mask = torch.any(mask, axis=2)
253
+ masks.append(mask)
254
+ if masks:
255
+ masks = torch.stack(masks, axis=0)
256
+ else:
257
+ masks = torch.zeros((0, height, width), dtype=torch.uint8, device=device)
258
+
259
+ return masks
260
+
261
+
262
+ # inspired by https://github.com/facebookresearch/conditional_detr/blob/master/datasets/coco.py#L50
263
+ def prepare_coco_detection_annotation(
264
+ image,
265
+ target,
266
+ return_segmentation_masks: bool = False,
267
+ input_data_format: ChannelDimension | str | None = None,
268
+ ):
269
+ """
270
+ Convert the target in COCO format into the format expected by CONDITIONAL_DETR.
271
+ """
272
+ image_height, image_width = image.size()[-2:]
273
+
274
+ image_id = target["image_id"]
275
+ image_id = torch.as_tensor([image_id], dtype=torch.int64, device=image.device)
276
+
277
+ # Get all COCO annotations for the given image.
278
+ annotations = target["annotations"]
279
+ classes = []
280
+ area = []
281
+ boxes = []
282
+ keypoints = []
283
+ for obj in annotations:
284
+ if "iscrowd" not in obj or obj["iscrowd"] == 0:
285
+ classes.append(obj["category_id"])
286
+ area.append(obj["area"])
287
+ boxes.append(obj["bbox"])
288
+ if "keypoints" in obj:
289
+ keypoints.append(obj["keypoints"])
290
+
291
+ classes = torch.as_tensor(classes, dtype=torch.int64, device=image.device)
292
+ area = torch.as_tensor(area, dtype=torch.float32, device=image.device)
293
+ iscrowd = torch.zeros_like(classes, dtype=torch.int64, device=image.device)
294
+ # guard against no boxes via resizing
295
+ boxes = torch.as_tensor(boxes, dtype=torch.float32, device=image.device).reshape(-1, 4)
296
+ boxes[:, 2:] += boxes[:, :2]
297
+ boxes[:, 0::2] = boxes[:, 0::2].clip(min=0, max=image_width)
298
+ boxes[:, 1::2] = boxes[:, 1::2].clip(min=0, max=image_height)
299
+
300
+ keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0])
301
+
302
+ new_target = {
303
+ "image_id": image_id,
304
+ "class_labels": classes[keep],
305
+ "boxes": boxes[keep],
306
+ "area": area[keep],
307
+ "iscrowd": iscrowd[keep],
308
+ "orig_size": torch.as_tensor([int(image_height), int(image_width)], dtype=torch.int64, device=image.device),
309
+ }
310
+
311
+ if keypoints:
312
+ keypoints = torch.as_tensor(keypoints, dtype=torch.float32, device=image.device)
313
+ # Apply the keep mask here to filter the relevant annotations
314
+ keypoints = keypoints[keep]
315
+ num_keypoints = keypoints.shape[0]
316
+ keypoints = keypoints.reshape((-1, 3)) if num_keypoints else keypoints
317
+ new_target["keypoints"] = keypoints
318
+
319
+ if return_segmentation_masks:
320
+ segmentation_masks = [obj["segmentation"] for obj in annotations]
321
+ masks = convert_coco_poly_to_mask(segmentation_masks, image_height, image_width, device=image.device)
322
+ new_target["masks"] = masks[keep]
323
+
324
+ return new_target
325
+
326
+
327
+ def masks_to_boxes(masks: torch.Tensor) -> torch.Tensor:
328
+ """
329
+ Compute the bounding boxes around the provided panoptic segmentation masks.
330
+
331
+ Args:
332
+ masks: masks in format `[number_masks, height, width]` where N is the number of masks
333
+
334
+ Returns:
335
+ boxes: bounding boxes in format `[number_masks, 4]` in xyxy format
336
+ """
337
+ if masks.numel() == 0:
338
+ return torch.zeros((0, 4), device=masks.device)
339
+
340
+ h, w = masks.shape[-2:]
341
+ y = torch.arange(0, h, dtype=torch.float32, device=masks.device)
342
+ x = torch.arange(0, w, dtype=torch.float32, device=masks.device)
343
+ # see https://github.com/pytorch/pytorch/issues/50276
344
+ y, x = torch.meshgrid(y, x, indexing="ij")
345
+
346
+ x_mask = masks * torch.unsqueeze(x, 0)
347
+ x_max = x_mask.view(x_mask.shape[0], -1).max(-1)[0]
348
+ x_min = (
349
+ torch.where(masks, x.unsqueeze(0), torch.tensor(1e8, device=masks.device)).view(masks.shape[0], -1).min(-1)[0]
350
+ )
351
+
352
+ y_mask = masks * torch.unsqueeze(y, 0)
353
+ y_max = y_mask.view(y_mask.shape[0], -1).max(-1)[0]
354
+ y_min = (
355
+ torch.where(masks, y.unsqueeze(0), torch.tensor(1e8, device=masks.device)).view(masks.shape[0], -1).min(-1)[0]
356
+ )
357
+
358
+ return torch.stack([x_min, y_min, x_max, y_max], 1)
359
+
360
+
361
+ # 2 functions below adapted from https://github.com/cocodataset/panopticapi/blob/master/panopticapi/utils.py
362
+ # Copyright (c) 2018, Alexander Kirillov
363
+ # All rights reserved.
364
+ def rgb_to_id(color):
365
+ """
366
+ Converts RGB color to unique ID.
367
+ """
368
+ if isinstance(color, torch.Tensor) and len(color.shape) == 3:
369
+ if color.dtype == torch.uint8:
370
+ color = color.to(torch.int32)
371
+ return color[:, :, 0] + 256 * color[:, :, 1] + 256 * 256 * color[:, :, 2]
372
+ return int(color[0] + 256 * color[1] + 256 * 256 * color[2])
373
+
374
+
375
+ def prepare_coco_panoptic_annotation(
376
+ image: torch.Tensor,
377
+ target: dict,
378
+ masks_path: str | pathlib.Path,
379
+ return_masks: bool = True,
380
+ input_data_format: ChannelDimension | str = None,
381
+ ) -> dict:
382
+ """
383
+ Prepare a coco panoptic annotation for CONDITIONAL_DETR.
384
+ """
385
+ image_height, image_width = get_image_size(image, channel_dim=input_data_format)
386
+ annotation_path = pathlib.Path(masks_path) / target["file_name"]
387
+
388
+ new_target = {}
389
+ new_target["image_id"] = torch.as_tensor(
390
+ [target["image_id"] if "image_id" in target else target["id"]], dtype=torch.int64, device=image.device
391
+ )
392
+ new_target["size"] = torch.as_tensor([image_height, image_width], dtype=torch.int64, device=image.device)
393
+ new_target["orig_size"] = torch.as_tensor([image_height, image_width], dtype=torch.int64, device=image.device)
394
+
395
+ if "segments_info" in target:
396
+ masks = read_image(annotation_path).permute(1, 2, 0).to(dtype=torch.int32, device=image.device)
397
+ masks = rgb_to_id(masks)
398
+
399
+ ids = torch.as_tensor([segment_info["id"] for segment_info in target["segments_info"]], device=image.device)
400
+ masks = masks == ids[:, None, None]
401
+ masks = masks.to(torch.bool)
402
+ if return_masks:
403
+ new_target["masks"] = masks
404
+ new_target["boxes"] = masks_to_boxes(masks)
405
+ new_target["class_labels"] = torch.as_tensor(
406
+ [segment_info["category_id"] for segment_info in target["segments_info"]],
407
+ dtype=torch.int64,
408
+ device=image.device,
409
+ )
410
+ new_target["iscrowd"] = torch.as_tensor(
411
+ [segment_info["iscrowd"] for segment_info in target["segments_info"]],
412
+ dtype=torch.int64,
413
+ device=image.device,
414
+ )
415
+ new_target["area"] = torch.as_tensor(
416
+ [segment_info["area"] for segment_info in target["segments_info"]],
417
+ dtype=torch.float32,
418
+ device=image.device,
419
+ )
420
+
421
+ return new_target
422
+
423
+
424
+ @auto_docstring
425
+ class ConditionalDetrImageProcessor(TorchvisionBackend):
426
+ valid_kwargs = ConditionalDetrImageProcessorKwargs
427
+ resample = PILImageResampling.BILINEAR
428
+ image_mean = IMAGENET_DEFAULT_MEAN
429
+ image_std = IMAGENET_DEFAULT_STD
430
+ format = AnnotationFormat.COCO_DETECTION
431
+ do_resize = True
432
+ do_rescale = True
433
+ do_normalize = True
434
+ do_pad = True
435
+ size = {"shortest_edge": 800, "longest_edge": 1333}
436
+ default_to_square = False
437
+ model_input_names = ["pixel_values", "pixel_mask"]
438
+
439
+ def __init__(self, **kwargs: Unpack[ConditionalDetrImageProcessorKwargs]) -> None:
440
+ kwargs.setdefault("do_pad", kwargs.pop("pad_and_return_pixel_mask", self.do_pad))
441
+
442
+ size = kwargs.pop("size", None)
443
+ max_size = None if size is None else kwargs.pop("max_size", 1333)
444
+ size = size if size is not None else {"shortest_edge": 800, "longest_edge": 1333}
445
+ # Convert size dict for backwards compat with max_size parameter
446
+ kwargs["size"] = get_size_dict(size, max_size=max_size, default_to_square=False)
447
+
448
+ # Backwards compatibility
449
+ do_convert_annotations = kwargs.get("do_convert_annotations")
450
+ do_normalize = kwargs.get("do_normalize")
451
+ if do_convert_annotations is None and getattr(self, "do_convert_annotations", None) is None:
452
+ self.do_convert_annotations = do_normalize if do_normalize is not None else self.do_normalize
453
+
454
+ super().__init__(**kwargs)
455
+
456
+ def prepare_annotation(
457
+ self,
458
+ image: torch.Tensor,
459
+ target: dict,
460
+ format: AnnotationFormat | None = None,
461
+ return_segmentation_masks: bool | None = None,
462
+ masks_path: str | pathlib.Path | None = None,
463
+ input_data_format: str | ChannelDimension | None = None,
464
+ ) -> dict:
465
+ """
466
+ Prepare an annotation for feeding into CONDITIONAL_DETR model.
467
+ """
468
+ format = format if format is not None else self.format
469
+
470
+ if format == AnnotationFormat.COCO_DETECTION:
471
+ return_segmentation_masks = False if return_segmentation_masks is None else return_segmentation_masks
472
+ target = prepare_coco_detection_annotation(
473
+ image, target, return_segmentation_masks, input_data_format=input_data_format
474
+ )
475
+ elif format == AnnotationFormat.COCO_PANOPTIC:
476
+ return_segmentation_masks = True if return_segmentation_masks is None else return_segmentation_masks
477
+ target = prepare_coco_panoptic_annotation(
478
+ image,
479
+ target,
480
+ masks_path=masks_path,
481
+ return_masks=return_segmentation_masks,
482
+ input_data_format=input_data_format,
483
+ )
484
+ else:
485
+ raise ValueError(f"Format {format} is not supported.")
486
+ return target
487
+
488
+ def resize(
489
+ self,
490
+ image: torch.Tensor,
491
+ size: SizeDict,
492
+ resample: Optional["PILImageResampling | tvF.InterpolationMode | int"] = None,
493
+ **kwargs,
494
+ ) -> torch.Tensor:
495
+ """
496
+ Resize the image to the given size. Size can be `min_size` (scalar) or `(height, width)` tuple. If size is an
497
+ int, smaller edge of the image will be matched to this number.
498
+
499
+ Args:
500
+ image (`torch.Tensor`):
501
+ Image to resize.
502
+ size (`SizeDict`):
503
+ Size of the image's `(height, width)` dimensions after resizing. Available options are:
504
+ - `{"height": int, "width": int}`: The image will be resized to the exact size `(height, width)`.
505
+ Do NOT keep the aspect ratio.
506
+ - `{"shortest_edge": int, "longest_edge": int}`: The image will be resized to a maximum size respecting
507
+ the aspect ratio and keeping the shortest edge less or equal to `shortest_edge` and the longest edge
508
+ less or equal to `longest_edge`.
509
+ - `{"max_height": int, "max_width": int}`: The image will be resized to the maximum size respecting the
510
+ aspect ratio and keeping the height less or equal to `max_height` and the width less or equal to
511
+ `max_width`.
512
+ resample (`PILImageResampling | tvF.InterpolationMode | int`, *optional*, defaults to `PILImageResampling.BILINEAR`):
513
+ Resampling filter to use if resizing the image.
514
+ """
515
+ if size.shortest_edge and size.longest_edge:
516
+ # Resize the image so that the shortest edge or the longest edge is of the given size
517
+ # while maintaining the aspect ratio of the original image.
518
+ new_size = get_size_with_aspect_ratio(image.shape[-2:], size.shortest_edge, size.longest_edge)
519
+ elif size.max_height and size.max_width:
520
+ new_size = get_image_size_for_max_height_width(image.shape[-2:], size.max_height, size.max_width)
521
+ elif size.height and size.width:
522
+ new_size = (size.height, size.width)
523
+ else:
524
+ raise ValueError(
525
+ f"Size must contain 'height' and 'width' keys or 'shortest_edge' and 'longest_edge' keys. Got {size}."
526
+ )
527
+
528
+ image = super().resize(
529
+ image, size=SizeDict(height=new_size[0], width=new_size[1]), resample=resample, **kwargs
530
+ )
531
+ return image
532
+
533
+ def resize_annotation(
534
+ self,
535
+ annotation: dict[str, Any],
536
+ orig_size: tuple[int, int],
537
+ target_size: tuple[int, int],
538
+ threshold: float = 0.5,
539
+ resample: Optional["PILImageResampling | tvF.InterpolationMode | int"] = PILImageResampling.NEAREST,
540
+ ):
541
+ """
542
+ Resizes an annotation to a target size.
543
+
544
+ Args:
545
+ annotation (`dict[str, Any]`):
546
+ The annotation dictionary.
547
+ orig_size (`tuple[int, int]`):
548
+ The original size of the input image.
549
+ target_size (`tuple[int, int]`):
550
+ The target size of the image, as returned by the preprocessing `resize` step.
551
+ threshold (`float`, *optional*, defaults to 0.5):
552
+ The threshold used to binarize the segmentation masks.
553
+ resample (`PILImageResampling | tvF.InterpolationMode | int`, defaults to `tvF.InterpolationMode.NEAREST_EXACT`):
554
+ The resampling filter to use when resizing the masks.
555
+ """
556
+ ratio_height, ratio_width = [target / orig for target, orig in zip(target_size, orig_size)]
557
+
558
+ new_annotation = {}
559
+ new_annotation["size"] = target_size
560
+
561
+ for key, value in annotation.items():
562
+ if key == "boxes":
563
+ boxes = value
564
+ scaled_boxes = boxes * torch.as_tensor(
565
+ [ratio_width, ratio_height, ratio_width, ratio_height], dtype=torch.float32, device=boxes.device
566
+ )
567
+ new_annotation["boxes"] = scaled_boxes
568
+ elif key == "area":
569
+ area = value
570
+ scaled_area = area * (ratio_width * ratio_height)
571
+ new_annotation["area"] = scaled_area
572
+ elif key == "masks":
573
+ masks = value[:, None]
574
+ masks = [
575
+ super(ConditionalDetrImageProcessor, self).resize(
576
+ mask, size=SizeDict(height=target_size[0], width=target_size[1]), resample=resample
577
+ )
578
+ for mask in masks
579
+ ]
580
+ masks = torch.stack(masks).to(torch.float32)
581
+ masks = masks[:, 0] > threshold
582
+ new_annotation["masks"] = masks
583
+ elif key == "size":
584
+ new_annotation["size"] = target_size
585
+ else:
586
+ new_annotation[key] = value
587
+
588
+ return new_annotation
589
+
590
+ def normalize_annotation(self, annotation: dict, image_size: tuple[int, int]) -> dict:
591
+ image_height, image_width = image_size
592
+ norm_annotation = {}
593
+ for key, value in annotation.items():
594
+ if key == "boxes":
595
+ boxes = value
596
+ boxes = corners_to_center_format(boxes)
597
+ boxes /= torch.as_tensor(
598
+ [image_width, image_height, image_width, image_height], dtype=torch.float32, device=boxes.device
599
+ )
600
+ norm_annotation[key] = boxes
601
+ else:
602
+ norm_annotation[key] = value
603
+ return norm_annotation
604
+
605
+ def _update_annotation_for_padded_image(
606
+ self,
607
+ annotation: dict,
608
+ input_image_size: tuple[int, int],
609
+ output_image_size: tuple[int, int],
610
+ padding,
611
+ update_bboxes,
612
+ ) -> dict:
613
+ """
614
+ Update the annotation for a padded image.
615
+ """
616
+ new_annotation = {}
617
+ new_annotation["size"] = output_image_size
618
+ ratio_height, ratio_width = (input / output for output, input in zip(output_image_size, input_image_size))
619
+
620
+ for key, value in annotation.items():
621
+ if key == "masks":
622
+ masks = value
623
+ masks = tvF.pad(
624
+ masks,
625
+ padding,
626
+ fill=0,
627
+ )
628
+ masks = safe_squeeze(masks, 1)
629
+ new_annotation["masks"] = masks
630
+ elif key == "boxes" and update_bboxes:
631
+ boxes = value
632
+ boxes *= torch.as_tensor([ratio_width, ratio_height, ratio_width, ratio_height], device=boxes.device)
633
+ new_annotation["boxes"] = boxes
634
+ elif key == "size":
635
+ new_annotation["size"] = output_image_size
636
+ else:
637
+ new_annotation[key] = value
638
+ return new_annotation
639
+
640
+ def pad(
641
+ self,
642
+ image: torch.Tensor,
643
+ padded_size: tuple[int, int],
644
+ annotation: dict[str, Any] | None = None,
645
+ update_bboxes: bool = True,
646
+ fill: int = 0,
647
+ ):
648
+ original_size = image.size()[-2:]
649
+ padding_bottom = padded_size[0] - original_size[0]
650
+ padding_right = padded_size[1] - original_size[1]
651
+ if padding_bottom < 0 or padding_right < 0:
652
+ raise ValueError(
653
+ f"Padding dimensions are negative. Please make sure that the padded size is larger than the "
654
+ f"original size. Got padded size: {padded_size}, original size: {original_size}."
655
+ )
656
+ if original_size != padded_size:
657
+ padding = [0, 0, padding_right, padding_bottom]
658
+ image = tvF.pad(image, padding, fill=fill)
659
+ if annotation is not None:
660
+ annotation = self._update_annotation_for_padded_image(
661
+ annotation, original_size, padded_size, padding, update_bboxes
662
+ )
663
+
664
+ # Make a pixel mask for the image, where 1 indicates a valid pixel and 0 indicates padding.
665
+ pixel_mask = torch.zeros(padded_size, dtype=torch.int64, device=image.device)
666
+ pixel_mask[: original_size[0], : original_size[1]] = 1
667
+
668
+ return image, pixel_mask, annotation
669
+
670
+ @auto_docstring
671
+ def preprocess(
672
+ self,
673
+ images: ImageInput,
674
+ annotations: AnnotationType | list[AnnotationType] | None = None,
675
+ return_segmentation_masks: bool | None = None,
676
+ masks_path: str | pathlib.Path | None = None,
677
+ **kwargs: Unpack[ConditionalDetrImageProcessorKwargs],
678
+ ) -> BatchFeature:
679
+ r"""
680
+ annotations (`AnnotationType` or `list[AnnotationType]`, *optional*):
681
+ Annotations to transform according to the padding that is applied to the images.
682
+ return_segmentation_masks (`bool`, *optional*, defaults to `self.return_segmentation_masks`):
683
+ Whether to return segmentation masks.
684
+ masks_path (`str` or `pathlib.Path`, *optional*):
685
+ Path to the directory containing the segmentation masks.
686
+ """
687
+ return super().preprocess(images, annotations, return_segmentation_masks, masks_path, **kwargs)
688
+
689
+ def _preprocess(
690
+ self,
691
+ images: list["torch.Tensor"],
692
+ annotations: AnnotationType | list[AnnotationType] | None,
693
+ return_segmentation_masks: bool,
694
+ masks_path: str | pathlib.Path | None,
695
+ do_resize: bool,
696
+ size: SizeDict,
697
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None",
698
+ do_rescale: bool,
699
+ rescale_factor: float,
700
+ do_normalize: bool,
701
+ do_convert_annotations: bool,
702
+ image_mean: float | list[float] | None,
703
+ image_std: float | list[float] | None,
704
+ do_pad: bool,
705
+ pad_size: SizeDict | None,
706
+ format: str | AnnotationFormat | None,
707
+ return_tensors: str | TensorType | None,
708
+ **kwargs,
709
+ ) -> BatchFeature:
710
+ """
711
+ Preprocess an image or a batch of images so that it can be used by the model.
712
+ """
713
+ if annotations is not None and isinstance(annotations, dict):
714
+ annotations = [annotations]
715
+
716
+ if annotations is not None and len(images) != len(annotations):
717
+ raise ValueError(
718
+ f"The number of images ({len(images)}) and annotations ({len(annotations)}) do not match."
719
+ )
720
+
721
+ format = AnnotationFormat(format)
722
+ if annotations is not None:
723
+ validate_annotations(format, SUPPORTED_ANNOTATION_FORMATS, annotations)
724
+
725
+ if (
726
+ masks_path is not None
727
+ and format == AnnotationFormat.COCO_PANOPTIC
728
+ and not isinstance(masks_path, (pathlib.Path, str))
729
+ ):
730
+ raise ValueError(
731
+ "The path to the directory containing the mask PNG files should be provided as a"
732
+ f" `pathlib.Path` or string object, but is {type(masks_path)} instead."
733
+ )
734
+
735
+ data = {}
736
+
737
+ processed_images = []
738
+ processed_annotations = []
739
+ pixel_masks = [] # Initialize pixel_masks here
740
+ for image, annotation in zip(images, annotations if annotations is not None else [None] * len(images)):
741
+ # prepare (COCO annotations as a list of Dict -> CONDITIONAL_DETR target as a single Dict per image)
742
+ if annotations is not None:
743
+ annotation = self.prepare_annotation(
744
+ image,
745
+ annotation,
746
+ format,
747
+ return_segmentation_masks=return_segmentation_masks,
748
+ masks_path=masks_path,
749
+ input_data_format=ChannelDimension.FIRST,
750
+ )
751
+
752
+ if do_resize:
753
+ resized_image = self.resize(image, size=size, resample=resample)
754
+ if annotations is not None:
755
+ annotation = self.resize_annotation(
756
+ annotation,
757
+ orig_size=image.size()[-2:],
758
+ target_size=resized_image.size()[-2:],
759
+ )
760
+ image = resized_image
761
+ # Fused rescale and normalize
762
+ image = self.rescale_and_normalize(image, do_rescale, rescale_factor, do_normalize, image_mean, image_std)
763
+ if do_convert_annotations and annotations is not None:
764
+ annotation = self.normalize_annotation(annotation, get_image_size(image, ChannelDimension.FIRST))
765
+
766
+ processed_images.append(image)
767
+ processed_annotations.append(annotation)
768
+ images = processed_images
769
+ annotations = processed_annotations if annotations is not None else None
770
+
771
+ if do_pad:
772
+ # depends on all resized image shapes so we need another loop
773
+ if pad_size is not None:
774
+ padded_size = (pad_size.height, pad_size.width)
775
+ else:
776
+ padded_size = get_max_height_width(images)
777
+
778
+ padded_images = []
779
+ padded_annotations = []
780
+ for image, annotation in zip(images, annotations if annotations is not None else [None] * len(images)):
781
+ # Pads images and returns their mask: {'pixel_values': ..., 'pixel_mask': ...}
782
+ if padded_size == image.size()[-2:]:
783
+ padded_images.append(image)
784
+ pixel_masks.append(torch.ones(padded_size, dtype=torch.int64, device=image.device))
785
+ padded_annotations.append(annotation)
786
+ continue
787
+ image, pixel_mask, annotation = self.pad(
788
+ image, padded_size, annotation=annotation, update_bboxes=do_convert_annotations
789
+ )
790
+ padded_images.append(image)
791
+ padded_annotations.append(annotation)
792
+ pixel_masks.append(pixel_mask)
793
+ images = padded_images
794
+ annotations = padded_annotations if annotations is not None else None
795
+ data.update({"pixel_mask": torch.stack(pixel_masks, dim=0)})
796
+
797
+ data.update({"pixel_values": torch.stack(images, dim=0)})
798
+ encoded_inputs = BatchFeature(data, tensor_type=return_tensors)
799
+ if annotations is not None:
800
+ encoded_inputs["labels"] = [
801
+ BatchFeature(annotation, tensor_type=return_tensors) for annotation in annotations
802
+ ]
803
+ return encoded_inputs
804
+
805
+ def post_process_object_detection(
806
+ self, outputs, threshold: float = 0.5, target_sizes: TensorType | list[tuple] = None, top_k: int = 100
807
+ ):
808
+ """
809
+ Converts the raw output of [`ConditionalDetrForObjectDetection`] into final bounding boxes in (top_left_x,
810
+ top_left_y, bottom_right_x, bottom_right_y) format. Only supports PyTorch.
811
+
812
+ Args:
813
+ outputs ([`ConditionalDetrObjectDetectionOutput`]):
814
+ Raw outputs of the model.
815
+ threshold (`float`, *optional*):
816
+ Score threshold to keep object detection predictions.
817
+ target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
818
+ Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
819
+ (height, width) of each image in the batch. If left to None, predictions will not be resized.
820
+ top_k (`int`, *optional*, defaults to 100):
821
+ Keep only top k bounding boxes before filtering by thresholding.
822
+
823
+ Returns:
824
+ `list[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image
825
+ in the batch as predicted by the model.
826
+ """
827
+ out_logits, out_bbox = outputs.logits, outputs.pred_boxes
828
+
829
+ if target_sizes is not None:
830
+ if len(out_logits) != len(target_sizes):
831
+ raise ValueError(
832
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
833
+ )
834
+
835
+ prob = out_logits.sigmoid()
836
+ prob = prob.view(out_logits.shape[0], -1)
837
+ k_value = min(top_k, prob.size(1))
838
+ topk_values, topk_indexes = torch.topk(prob, k_value, dim=1)
839
+ scores = topk_values
840
+ topk_boxes = torch.div(topk_indexes, out_logits.shape[2], rounding_mode="floor")
841
+ labels = topk_indexes % out_logits.shape[2]
842
+ boxes = center_to_corners_format(out_bbox)
843
+ boxes = torch.gather(boxes, 1, topk_boxes.unsqueeze(-1).repeat(1, 1, 4))
844
+
845
+ # and from relative [0, 1] to absolute [0, height] coordinates
846
+ if target_sizes is not None:
847
+ if isinstance(target_sizes, list):
848
+ img_h = torch.Tensor([i[0] for i in target_sizes])
849
+ img_w = torch.Tensor([i[1] for i in target_sizes])
850
+ else:
851
+ img_h, img_w = target_sizes.unbind(1)
852
+ scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device)
853
+ boxes = boxes * scale_fct[:, None, :]
854
+
855
+ results = []
856
+ for s, l, b in zip(scores, labels, boxes):
857
+ score = s[s > threshold]
858
+ label = l[s > threshold]
859
+ box = b[s > threshold]
860
+ results.append({"scores": score, "labels": label, "boxes": box})
861
+
862
+ return results
863
+
864
+ def post_process_semantic_segmentation(self, outputs, target_sizes: list[tuple[int, int]] | None = None):
865
+ """
866
+ Converts the output of [`ConditionalDetrForSegmentation`] into semantic segmentation maps. Only supports PyTorch.
867
+
868
+ Args:
869
+ outputs ([`ConditionalDetrForSegmentation`]):
870
+ Raw outputs of the model.
871
+ target_sizes (`list[tuple[int, int]]`, *optional*):
872
+ A list of tuples (`tuple[int, int]`) containing the target size (height, width) of each image in the
873
+ batch. If unset, predictions will not be resized.
874
+ Returns:
875
+ `list[torch.Tensor]`:
876
+ A list of length `batch_size`, where each item is a semantic segmentation map of shape (height, width)
877
+ corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each
878
+ `torch.Tensor` correspond to a semantic class id.
879
+ """
880
+ class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes]
881
+ masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width]
882
+
883
+ # Conditional DETR does not have a null class, so we use all classes
884
+ masks_classes = class_queries_logits.softmax(dim=-1)
885
+ masks_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
886
+
887
+ # Semantic segmentation logits of shape (batch_size, num_classes, height, width)
888
+ segmentation = torch.einsum("bqc, bqhw -> bchw", masks_classes, masks_probs)
889
+ batch_size = class_queries_logits.shape[0]
890
+
891
+ # Resize logits and compute semantic segmentation maps
892
+ if target_sizes is not None:
893
+ if batch_size != len(target_sizes):
894
+ raise ValueError(
895
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
896
+ )
897
+
898
+ semantic_segmentation = []
899
+ for idx in range(batch_size):
900
+ resized_logits = nn.functional.interpolate(
901
+ segmentation[idx].unsqueeze(dim=0), size=target_sizes[idx], mode="bilinear", align_corners=False
902
+ )
903
+ semantic_map = resized_logits[0].argmax(dim=0)
904
+ semantic_segmentation.append(semantic_map)
905
+ else:
906
+ semantic_segmentation = segmentation.argmax(dim=1)
907
+ semantic_segmentation = [semantic_segmentation[i] for i in range(semantic_segmentation.shape[0])]
908
+
909
+ return semantic_segmentation
910
+
911
+ def post_process_instance_segmentation(
912
+ self,
913
+ outputs,
914
+ threshold: float = 0.5,
915
+ mask_threshold: float = 0.5,
916
+ overlap_mask_area_threshold: float = 0.8,
917
+ target_sizes: list[tuple[int, int]] | None = None,
918
+ return_coco_annotation: bool | None = False,
919
+ ) -> list[dict]:
920
+ """
921
+ Converts the output of [`ConditionalDetrForSegmentation`] into instance segmentation predictions. Only supports PyTorch.
922
+
923
+ Args:
924
+ outputs ([`ConditionalDetrForSegmentation`]):
925
+ Raw outputs of the model.
926
+ threshold (`float`, *optional*, defaults to 0.5):
927
+ The probability score threshold to keep predicted instance masks.
928
+ mask_threshold (`float`, *optional*, defaults to 0.5):
929
+ Threshold to use when turning the predicted masks into binary values.
930
+ overlap_mask_area_threshold (`float`, *optional*, defaults to 0.8):
931
+ The overlap mask area threshold to merge or discard small disconnected parts within each binary
932
+ instance mask.
933
+ target_sizes (`list[Tuple]`, *optional*):
934
+ List of length (batch_size), where each list item (`tuple[int, int]]`) corresponds to the requested
935
+ final size (height, width) of each prediction. If unset, predictions will not be resized.
936
+ return_coco_annotation (`bool`, *optional*):
937
+ Defaults to `False`. If set to `True`, segmentation maps are returned in COCO run-length encoding (RLE)
938
+ format.
939
+ Returns:
940
+ `list[Dict]`: A list of dictionaries, one per image, each dictionary containing two keys:
941
+ - **segmentation** -- A tensor of shape `(height, width)` where each pixel represents a `segment_id` or
942
+ `list[List]` run-length encoding (RLE) of the segmentation map if return_coco_annotation is set to
943
+ `True`. Set to `None` if no mask if found above `threshold`.
944
+ - **segments_info** -- A dictionary that contains additional information on each segment.
945
+ - **id** -- An integer representing the `segment_id`.
946
+ - **label_id** -- An integer representing the label / semantic class id corresponding to `segment_id`.
947
+ - **score** -- Prediction score of segment with `segment_id`.
948
+ """
949
+ class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes+1]
950
+ masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width]
951
+
952
+ batch_size = class_queries_logits.shape[0]
953
+ num_labels = class_queries_logits.shape[-1] - 1
954
+
955
+ mask_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
956
+
957
+ # Predicted label and score of each query (batch_size, num_queries)
958
+ pred_scores, pred_labels = nn.functional.softmax(class_queries_logits, dim=-1).max(-1)
959
+
960
+ # Loop over items in batch size
961
+ results: list[dict[str, TensorType]] = []
962
+
963
+ for i in range(batch_size):
964
+ mask_probs_item, pred_scores_item, pred_labels_item = remove_low_and_no_objects(
965
+ mask_probs[i], pred_scores[i], pred_labels[i], threshold, num_labels
966
+ )
967
+
968
+ # No mask found
969
+ if mask_probs_item.shape[0] <= 0:
970
+ height, width = target_sizes[i] if target_sizes is not None else mask_probs_item.shape[1:]
971
+ segmentation = torch.zeros((height, width)) - 1
972
+ results.append({"segmentation": segmentation, "segments_info": []})
973
+ continue
974
+
975
+ # Get segmentation map and segment information of batch item
976
+ target_size = target_sizes[i] if target_sizes is not None else None
977
+ segmentation, segments = compute_segments(
978
+ mask_probs=mask_probs_item,
979
+ pred_scores=pred_scores_item,
980
+ pred_labels=pred_labels_item,
981
+ mask_threshold=mask_threshold,
982
+ overlap_mask_area_threshold=overlap_mask_area_threshold,
983
+ label_ids_to_fuse=[],
984
+ target_size=target_size,
985
+ )
986
+
987
+ # Return segmentation map in run-length encoding (RLE) format
988
+ if return_coco_annotation:
989
+ segmentation = convert_segmentation_to_rle(segmentation)
990
+
991
+ results.append({"segmentation": segmentation, "segments_info": segments})
992
+ return results
993
+
994
+ def post_process_panoptic_segmentation(
995
+ self,
996
+ outputs,
997
+ threshold: float = 0.5,
998
+ mask_threshold: float = 0.5,
999
+ overlap_mask_area_threshold: float = 0.8,
1000
+ label_ids_to_fuse: set[int] | None = None,
1001
+ target_sizes: list[tuple[int, int]] | None = None,
1002
+ ) -> list[dict]:
1003
+ """
1004
+ Converts the output of [`ConditionalDetrForSegmentation`] into image panoptic segmentation predictions. Only supports
1005
+ PyTorch.
1006
+
1007
+ Args:
1008
+ outputs ([`ConditionalDetrForSegmentation`]):
1009
+ The outputs from [`ConditionalDetrForSegmentation`].
1010
+ threshold (`float`, *optional*, defaults to 0.5):
1011
+ The probability score threshold to keep predicted instance masks.
1012
+ mask_threshold (`float`, *optional*, defaults to 0.5):
1013
+ Threshold to use when turning the predicted masks into binary values.
1014
+ overlap_mask_area_threshold (`float`, *optional*, defaults to 0.8):
1015
+ The overlap mask area threshold to merge or discard small disconnected parts within each binary
1016
+ instance mask.
1017
+ label_ids_to_fuse (`Set[int]`, *optional*):
1018
+ The labels in this state will have all their instances be fused together. For instance we could say
1019
+ there can only be one sky in an image, but several persons, so the label ID for sky would be in that
1020
+ set, but not the one for person.
1021
+ target_sizes (`list[Tuple]`, *optional*):
1022
+ List of length (batch_size), where each list item (`tuple[int, int]]`) corresponds to the requested
1023
+ final size (height, width) of each prediction in batch. If unset, predictions will not be resized.
1024
+ Returns:
1025
+ `list[Dict]`: A list of dictionaries, one per image, each dictionary containing two keys:
1026
+ - **segmentation** -- a tensor of shape `(height, width)` where each pixel represents a `segment_id` or
1027
+ `None` if no mask if found above `threshold`. If `target_sizes` is specified, segmentation is resized to
1028
+ the corresponding `target_sizes` entry.
1029
+ - **segments_info** -- A dictionary that contains additional information on each segment.
1030
+ - **id** -- an integer representing the `segment_id`.
1031
+ - **label_id** -- An integer representing the label / semantic class id corresponding to `segment_id`.
1032
+ - **was_fused** -- a boolean, `True` if `label_id` was in `label_ids_to_fuse`, `False` otherwise.
1033
+ Multiple instances of the same class / label were fused and assigned a single `segment_id`.
1034
+ - **score** -- Prediction score of segment with `segment_id`.
1035
+ """
1036
+
1037
+ if label_ids_to_fuse is None:
1038
+ logger.warning_once("`label_ids_to_fuse` unset. No instance will be fused.")
1039
+ label_ids_to_fuse = set()
1040
+
1041
+ class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes+1]
1042
+ masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width]
1043
+
1044
+ batch_size = class_queries_logits.shape[0]
1045
+ num_labels = class_queries_logits.shape[-1] - 1
1046
+
1047
+ mask_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
1048
+
1049
+ # Predicted label and score of each query (batch_size, num_queries)
1050
+ pred_scores, pred_labels = nn.functional.softmax(class_queries_logits, dim=-1).max(-1)
1051
+
1052
+ # Loop over items in batch size
1053
+ results: list[dict[str, TensorType]] = []
1054
+
1055
+ for i in range(batch_size):
1056
+ mask_probs_item, pred_scores_item, pred_labels_item = remove_low_and_no_objects(
1057
+ mask_probs[i], pred_scores[i], pred_labels[i], threshold, num_labels
1058
+ )
1059
+
1060
+ # No mask found
1061
+ if mask_probs_item.shape[0] <= 0:
1062
+ height, width = target_sizes[i] if target_sizes is not None else mask_probs_item.shape[1:]
1063
+ segmentation = torch.zeros((height, width)) - 1
1064
+ results.append({"segmentation": segmentation, "segments_info": []})
1065
+ continue
1066
+
1067
+ # Get segmentation map and segment information of batch item
1068
+ target_size = target_sizes[i] if target_sizes is not None else None
1069
+ segmentation, segments = compute_segments(
1070
+ mask_probs=mask_probs_item,
1071
+ pred_scores=pred_scores_item,
1072
+ pred_labels=pred_labels_item,
1073
+ mask_threshold=mask_threshold,
1074
+ overlap_mask_area_threshold=overlap_mask_area_threshold,
1075
+ label_ids_to_fuse=label_ids_to_fuse,
1076
+ target_size=target_size,
1077
+ )
1078
+
1079
+ results.append({"segmentation": segmentation, "segments_info": segments})
1080
+ return results
1081
+
1082
+
1083
+ __all__ = ["ConditionalDetrImageProcessor"]
third_party/transformers/src/transformers/models/conditional_detr/image_processing_pil_conditional_detr.py ADDED
@@ -0,0 +1,1136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/conditional_detr/modular_conditional_detr.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_conditional_detr.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2022 Microsoft Research Asia and The HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ import pathlib
22
+ from typing import Any, Optional
23
+
24
+ import numpy as np
25
+
26
+ from ...image_processing_backends import PilBackend
27
+ from ...image_processing_utils import BatchFeature
28
+ from ...image_transforms import (
29
+ PaddingMode,
30
+ center_to_corners_format,
31
+ corners_to_center_format,
32
+ get_size_with_aspect_ratio,
33
+ pad,
34
+ resize,
35
+ safe_squeeze,
36
+ )
37
+ from ...image_utils import (
38
+ IMAGENET_DEFAULT_MEAN,
39
+ IMAGENET_DEFAULT_STD,
40
+ AnnotationFormat,
41
+ AnnotationType,
42
+ ChannelDimension,
43
+ ImageInput,
44
+ PILImageResampling,
45
+ SizeDict,
46
+ get_image_size,
47
+ get_image_size_for_max_height_width,
48
+ get_max_height_width,
49
+ validate_annotations,
50
+ )
51
+ from ...processing_utils import ImagesKwargs, Unpack
52
+ from ...utils import TensorType, auto_docstring, is_torch_available, is_vision_available, logging, requires_backends
53
+ from ...utils.import_utils import requires
54
+
55
+
56
+ if is_vision_available():
57
+ import PIL.Image
58
+ if is_torch_available():
59
+ import torch
60
+ from torch import nn
61
+
62
+ logger = logging.get_logger(__name__)
63
+
64
+
65
+ class ConditionalDetrImageProcessorKwargs(ImagesKwargs, total=False):
66
+ r"""
67
+ format (`str`, *optional*, defaults to `AnnotationFormat.COCO_DETECTION`):
68
+ Data format of the annotations. One of "coco_detection" or "coco_panoptic".
69
+ do_convert_annotations (`bool`, *optional*, defaults to `True`):
70
+ Controls whether to convert the annotations to the format expected by the CONDITIONAL_DETR model. Converts the
71
+ bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`.
72
+ Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method.
73
+ """
74
+
75
+ format: str | AnnotationFormat
76
+ do_convert_annotations: bool
77
+
78
+
79
+ SUPPORTED_ANNOTATION_FORMATS = (AnnotationFormat.COCO_DETECTION, AnnotationFormat.COCO_PANOPTIC)
80
+
81
+
82
+ # inspired by https://github.com/facebookresearch/conditional_detr/blob/master/datasets/coco.py#L33
83
+ def convert_coco_poly_to_mask(segmentations, height: int, width: int) -> np.ndarray:
84
+ """
85
+ Convert a COCO polygon annotation to a mask.
86
+
87
+ Args:
88
+ segmentations (`list[list[float]]`):
89
+ List of polygons, each polygon represented by a list of x-y coordinates.
90
+ height (`int`):
91
+ Height of the mask.
92
+ width (`int`):
93
+ Width of the mask.
94
+ """
95
+ try:
96
+ from pycocotools import mask as coco_mask
97
+ except ImportError:
98
+ raise ImportError("Pycocotools is not installed in your environment.")
99
+
100
+ masks = []
101
+ for polygons in segmentations:
102
+ rles = coco_mask.frPyObjects(polygons, height, width)
103
+ mask = coco_mask.decode(rles)
104
+ if len(mask.shape) < 3:
105
+ mask = mask[..., None]
106
+ mask = np.asarray(mask, dtype=np.uint8)
107
+ mask = np.any(mask, axis=2)
108
+ masks.append(mask)
109
+ if masks:
110
+ masks = np.stack(masks, axis=0)
111
+ else:
112
+ masks = np.zeros((0, height, width), dtype=np.uint8)
113
+
114
+ return masks
115
+
116
+
117
+ # inspired by https://github.com/facebookresearch/conditional_detr/blob/master/datasets/coco.py#L50
118
+ def prepare_coco_detection_annotation(
119
+ image,
120
+ target,
121
+ return_segmentation_masks: bool = False,
122
+ input_data_format: ChannelDimension | str | None = None,
123
+ ):
124
+ """
125
+ Convert the target in COCO format into the format expected by CONDITIONAL_DETR.
126
+ """
127
+ image_height, image_width = get_image_size(image, channel_dim=input_data_format)
128
+
129
+ image_id = target["image_id"]
130
+ image_id = np.asarray([image_id], dtype=np.int64)
131
+
132
+ # Get all COCO annotations for the given image.
133
+ annotations = target["annotations"]
134
+ annotations = [obj for obj in annotations if "iscrowd" not in obj or obj["iscrowd"] == 0]
135
+
136
+ classes = [obj["category_id"] for obj in annotations]
137
+ classes = np.asarray(classes, dtype=np.int64)
138
+
139
+ # for conversion to coco api
140
+ area = np.asarray([obj["area"] for obj in annotations], dtype=np.float32)
141
+ iscrowd = np.asarray([obj.get("iscrowd", 0) for obj in annotations], dtype=np.int64)
142
+
143
+ boxes = [obj["bbox"] for obj in annotations]
144
+ # guard against no boxes via resizing
145
+ boxes = np.asarray(boxes, dtype=np.float32).reshape(-1, 4)
146
+ boxes[:, 2:] += boxes[:, :2]
147
+ boxes[:, 0::2] = boxes[:, 0::2].clip(min=0, max=image_width)
148
+ boxes[:, 1::2] = boxes[:, 1::2].clip(min=0, max=image_height)
149
+
150
+ keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0])
151
+
152
+ new_target = {}
153
+ new_target["image_id"] = image_id
154
+ new_target["class_labels"] = classes[keep]
155
+ new_target["boxes"] = boxes[keep]
156
+ new_target["area"] = area[keep]
157
+ new_target["iscrowd"] = iscrowd[keep]
158
+ new_target["orig_size"] = np.asarray([int(image_height), int(image_width)], dtype=np.int64)
159
+
160
+ if annotations and "keypoints" in annotations[0]:
161
+ keypoints = [obj["keypoints"] for obj in annotations]
162
+ # Converting the filtered keypoints list to a numpy array
163
+ keypoints = np.asarray(keypoints, dtype=np.float32)
164
+ # Apply the keep mask here to filter the relevant annotations
165
+ keypoints = keypoints[keep]
166
+ num_keypoints = keypoints.shape[0]
167
+ keypoints = keypoints.reshape((-1, 3)) if num_keypoints else keypoints
168
+ new_target["keypoints"] = keypoints
169
+
170
+ if return_segmentation_masks:
171
+ segmentation_masks = [obj["segmentation"] for obj in annotations]
172
+ masks = convert_coco_poly_to_mask(segmentation_masks, image_height, image_width)
173
+ new_target["masks"] = masks[keep]
174
+
175
+ return new_target
176
+
177
+
178
+ def masks_to_boxes(masks: np.ndarray) -> np.ndarray:
179
+ """
180
+ Compute the bounding boxes around the provided panoptic segmentation masks.
181
+
182
+ Args:
183
+ masks: masks in format `[number_masks, height, width]` where N is the number of masks
184
+
185
+ Returns:
186
+ boxes: bounding boxes in format `[number_masks, 4]` in xyxy format
187
+ """
188
+ if masks.size == 0:
189
+ return np.zeros((0, 4))
190
+
191
+ h, w = masks.shape[-2:]
192
+ y = np.arange(0, h, dtype=np.float32)
193
+ x = np.arange(0, w, dtype=np.float32)
194
+ # see https://github.com/pytorch/pytorch/issues/50276
195
+ y, x = np.meshgrid(y, x, indexing="ij")
196
+
197
+ x_mask = masks * np.expand_dims(x, axis=0)
198
+ x_max = x_mask.reshape(x_mask.shape[0], -1).max(-1)
199
+ x = np.ma.array(x_mask, mask=~(np.array(masks, dtype=bool)))
200
+ x_min = x.filled(fill_value=1e8)
201
+ x_min = x_min.reshape(x_min.shape[0], -1).min(-1)
202
+
203
+ y_mask = masks * np.expand_dims(y, axis=0)
204
+ y_max = y_mask.reshape(x_mask.shape[0], -1).max(-1)
205
+ y = np.ma.array(y_mask, mask=~(np.array(masks, dtype=bool)))
206
+ y_min = y.filled(fill_value=1e8)
207
+ y_min = y_min.reshape(y_min.shape[0], -1).min(-1)
208
+
209
+ return np.stack([x_min, y_min, x_max, y_max], 1)
210
+
211
+
212
+ # 2 functions below adapted from https://github.com/cocodataset/panopticapi/blob/master/panopticapi/utils.py
213
+ # Copyright (c) 2018, Alexander Kirillov
214
+ # All rights reserved.
215
+ def rgb_to_id(color):
216
+ """
217
+ Converts RGB color to unique ID.
218
+ """
219
+ if isinstance(color, np.ndarray) and len(color.shape) == 3:
220
+ if color.dtype == np.uint8:
221
+ color = color.astype(np.int32)
222
+ return color[:, :, 0] + 256 * color[:, :, 1] + 256 * 256 * color[:, :, 2]
223
+ return int(color[0] + 256 * color[1] + 256 * 256 * color[2])
224
+
225
+
226
+ def prepare_coco_panoptic_annotation(
227
+ image: np.ndarray,
228
+ target: dict,
229
+ masks_path: str | pathlib.Path,
230
+ return_masks: bool = True,
231
+ input_data_format: ChannelDimension | str = None,
232
+ ) -> dict:
233
+ """
234
+ Prepare a coco panoptic annotation for CONDITIONAL_DETR.
235
+ """
236
+ image_height, image_width = get_image_size(image, channel_dim=input_data_format)
237
+ annotation_path = pathlib.Path(masks_path) / target["file_name"]
238
+
239
+ new_target = {}
240
+ new_target["image_id"] = np.asarray([target["image_id"] if "image_id" in target else target["id"]], dtype=np.int64)
241
+ new_target["size"] = np.asarray([image_height, image_width], dtype=np.int64)
242
+ new_target["orig_size"] = np.asarray([image_height, image_width], dtype=np.int64)
243
+
244
+ if "segments_info" in target:
245
+ masks = np.asarray(PIL.Image.open(annotation_path), dtype=np.uint32)
246
+ masks = rgb_to_id(masks)
247
+
248
+ ids = np.array([segment_info["id"] for segment_info in target["segments_info"]])
249
+ masks = masks == ids[:, None, None]
250
+ masks = masks.astype(np.uint8)
251
+ if return_masks:
252
+ new_target["masks"] = masks
253
+ new_target["boxes"] = masks_to_boxes(masks)
254
+ new_target["class_labels"] = np.array(
255
+ [segment_info["category_id"] for segment_info in target["segments_info"]], dtype=np.int64
256
+ )
257
+ new_target["iscrowd"] = np.asarray(
258
+ [segment_info["iscrowd"] for segment_info in target["segments_info"]], dtype=np.int64
259
+ )
260
+ new_target["area"] = np.asarray(
261
+ [segment_info["area"] for segment_info in target["segments_info"]], dtype=np.float32
262
+ )
263
+
264
+ return new_target
265
+
266
+
267
+ # Adapted from transformers.models.conditional_detr.image_processing_conditional_detr.binary_mask_to_rle
268
+ def binary_mask_to_rle(mask):
269
+ """
270
+ Converts given binary mask of shape `(height, width)` to the run-length encoding (RLE) format.
271
+
272
+ Args:
273
+ mask (`torch.Tensor` or `numpy.array`):
274
+ A binary mask tensor of shape `(height, width)` where 0 denotes background and 1 denotes the target
275
+ segment_id or class_id.
276
+ Returns:
277
+ `List`: Run-length encoded list of the binary mask. Refer to COCO API for more information about the RLE
278
+ format.
279
+ """
280
+ from ...utils import is_torch_tensor
281
+
282
+ if is_torch_tensor(mask):
283
+ mask = mask.numpy()
284
+
285
+ pixels = mask.flatten()
286
+ pixels = np.concatenate([[0], pixels, [0]])
287
+ runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
288
+ runs[1::2] -= runs[::2]
289
+ return list(runs)
290
+
291
+
292
+ # Adapted from transformers.models.conditional_detr.image_processing_conditional_detr.check_segment_validity
293
+ def check_segment_validity(mask_labels, mask_probs, k, mask_threshold=0.5, overlap_mask_area_threshold=0.8):
294
+ # Get the mask associated with the k class
295
+ mask_k = mask_labels == k
296
+ mask_k_area = mask_k.sum()
297
+
298
+ # Compute the area of all the stuff in query k
299
+ original_area = (mask_probs[k] >= mask_threshold).sum()
300
+ mask_exists = mask_k_area > 0 and original_area > 0
301
+
302
+ # Eliminate disconnected tiny segments
303
+ if mask_exists:
304
+ area_ratio = mask_k_area / original_area
305
+ if not area_ratio.item() > overlap_mask_area_threshold:
306
+ mask_exists = False
307
+
308
+ return mask_exists, mask_k
309
+
310
+
311
+ # Adapted from transformers.models.conditional_detr.image_processing_conditional_detr.compute_segments
312
+ def compute_segments(
313
+ mask_probs,
314
+ pred_scores,
315
+ pred_labels,
316
+ mask_threshold: float = 0.5,
317
+ overlap_mask_area_threshold: float = 0.8,
318
+ label_ids_to_fuse: set[int] | None = None,
319
+ target_size: tuple[int, int] | None = None,
320
+ ):
321
+ import torch
322
+ from torch import nn
323
+
324
+ height = mask_probs.shape[1] if target_size is None else target_size[0]
325
+ width = mask_probs.shape[2] if target_size is None else target_size[1]
326
+
327
+ segmentation = torch.zeros((height, width), dtype=torch.int32, device=mask_probs.device)
328
+ segments: list[dict] = []
329
+
330
+ if target_size is not None:
331
+ mask_probs = nn.functional.interpolate(
332
+ mask_probs.unsqueeze(0), size=target_size, mode="bilinear", align_corners=False
333
+ )[0]
334
+
335
+ current_segment_id = 0
336
+
337
+ # Weigh each mask by its prediction score
338
+ mask_probs *= pred_scores.view(-1, 1, 1)
339
+ mask_labels = mask_probs.argmax(0) # [height, width]
340
+
341
+ # Keep track of instances of each class
342
+ stuff_memory_list: dict[str, int] = {}
343
+ for k in range(pred_labels.shape[0]):
344
+ pred_class = pred_labels[k].item()
345
+ should_fuse = pred_class in label_ids_to_fuse
346
+
347
+ # Check if mask exists and large enough to be a segment
348
+ mask_exists, mask_k = check_segment_validity(
349
+ mask_labels, mask_probs, k, mask_threshold, overlap_mask_area_threshold
350
+ )
351
+
352
+ if mask_exists:
353
+ if pred_class in stuff_memory_list:
354
+ current_segment_id = stuff_memory_list[pred_class]
355
+ else:
356
+ current_segment_id += 1
357
+
358
+ # Add current object segment to final segmentation map
359
+ segmentation[mask_k] = current_segment_id
360
+ segment_score = round(pred_scores[k].item(), 6)
361
+ segments.append(
362
+ {
363
+ "id": current_segment_id,
364
+ "label_id": pred_class,
365
+ "was_fused": should_fuse,
366
+ "score": segment_score,
367
+ }
368
+ )
369
+ if should_fuse:
370
+ stuff_memory_list[pred_class] = current_segment_id
371
+
372
+ return segmentation, segments
373
+
374
+
375
+ # Adapted from transformers.models.conditional_detr.image_processing_conditional_detr.convert_segmentation_to_rle
376
+ def convert_segmentation_to_rle(segmentation):
377
+ """
378
+ Converts given segmentation map of shape `(height, width)` to the run-length encoding (RLE) format.
379
+
380
+ Args:
381
+ segmentation (`torch.Tensor` or `numpy.array`):
382
+ A segmentation map of shape `(height, width)` where each value denotes a segment or class id.
383
+ Returns:
384
+ `list[List]`: A list of lists, where each list is the run-length encoding of a segment / class id.
385
+ """
386
+ import torch
387
+
388
+ segment_ids = torch.unique(segmentation)
389
+
390
+ run_length_encodings = []
391
+ for idx in segment_ids:
392
+ mask = torch.where(segmentation == idx, 1, 0)
393
+ rle = binary_mask_to_rle(mask)
394
+ run_length_encodings.append(rle)
395
+
396
+ return run_length_encodings
397
+
398
+
399
+ # Adapted from transformers.models.conditional_detr.image_processing_conditional_detr.remove_low_and_no_objects
400
+ def remove_low_and_no_objects(masks, scores, labels, object_mask_threshold, num_labels):
401
+ """
402
+ Binarize the given masks using `object_mask_threshold`, it returns the associated values of `masks`, `scores` and
403
+ `labels`.
404
+
405
+ Args:
406
+ masks (`torch.Tensor`):
407
+ A tensor of shape `(num_queries, height, width)`.
408
+ scores (`torch.Tensor`):
409
+ A tensor of shape `(num_queries)`.
410
+ labels (`torch.Tensor`):
411
+ A tensor of shape `(num_queries)`.
412
+ object_mask_threshold (`float`):
413
+ A number between 0 and 1 used to binarize the masks.
414
+ Raises:
415
+ `ValueError`: Raised when the first dimension doesn't match in all input tensors.
416
+ Returns:
417
+ `tuple[`torch.Tensor`, `torch.Tensor`, `torch.Tensor`]`: The `masks`, `scores` and `labels` without the region
418
+ < `object_mask_threshold`.
419
+ """
420
+ if not (masks.shape[0] == scores.shape[0] == labels.shape[0]):
421
+ raise ValueError("mask, scores and labels must have the same shape!")
422
+
423
+ to_keep = labels.ne(num_labels) & (scores > object_mask_threshold)
424
+
425
+ return masks[to_keep], scores[to_keep], labels[to_keep]
426
+
427
+
428
+ @auto_docstring
429
+ class ConditionalDetrImageProcessorPil(PilBackend):
430
+ resample = PILImageResampling.BILINEAR
431
+ image_mean = IMAGENET_DEFAULT_MEAN
432
+ image_std = IMAGENET_DEFAULT_STD
433
+ format = AnnotationFormat.COCO_DETECTION
434
+ do_resize = True
435
+ do_rescale = True
436
+ do_normalize = True
437
+ do_pad = True
438
+ size = {"shortest_edge": 800, "longest_edge": 1333}
439
+ default_to_square = False
440
+ model_input_names = ["pixel_values", "pixel_mask"]
441
+ valid_kwargs = ConditionalDetrImageProcessorKwargs
442
+
443
+ def __init__(self, **kwargs: Unpack[ConditionalDetrImageProcessorKwargs]) -> None:
444
+ kwargs.setdefault("do_pad", kwargs.pop("pad_and_return_pixel_mask", self.do_pad))
445
+
446
+ size = kwargs.pop("size", None)
447
+ max_size = None if size is None else kwargs.pop("max_size", 1333)
448
+ size = size if size is not None else {"shortest_edge": 800, "longest_edge": 1333}
449
+ # Convert size dict for backwards compat with max_size parameter
450
+ if size is not None:
451
+ from ...image_processing_utils import get_size_dict
452
+
453
+ kwargs["size"] = get_size_dict(size, max_size=max_size, default_to_square=False)
454
+
455
+ # Backwards compatibility
456
+ do_convert_annotations = kwargs.get("do_convert_annotations")
457
+ do_normalize = kwargs.get("do_normalize")
458
+ if do_convert_annotations is None and getattr(self, "do_convert_annotations", None) is None:
459
+ self.do_convert_annotations = do_normalize if do_normalize is not None else self.do_normalize
460
+
461
+ super().__init__(**kwargs)
462
+
463
+ def prepare_annotation(
464
+ self,
465
+ image: np.ndarray,
466
+ target: dict,
467
+ format: AnnotationFormat | None = None,
468
+ return_segmentation_masks: bool | None = None,
469
+ masks_path: str | pathlib.Path | None = None,
470
+ input_data_format: str | ChannelDimension | None = None,
471
+ ) -> dict:
472
+ """
473
+ Prepare an annotation for feeding into CONDITIONAL_DETR model.
474
+ """
475
+ format = format if format is not None else self.format
476
+
477
+ if format == AnnotationFormat.COCO_DETECTION:
478
+ return_segmentation_masks = False if return_segmentation_masks is None else return_segmentation_masks
479
+ target = prepare_coco_detection_annotation(
480
+ image, target, return_segmentation_masks, input_data_format=input_data_format
481
+ )
482
+ elif format == AnnotationFormat.COCO_PANOPTIC:
483
+ return_segmentation_masks = True if return_segmentation_masks is None else return_segmentation_masks
484
+ target = prepare_coco_panoptic_annotation(
485
+ image,
486
+ target,
487
+ masks_path=masks_path,
488
+ return_masks=return_segmentation_masks,
489
+ input_data_format=input_data_format,
490
+ )
491
+ else:
492
+ raise ValueError(f"Format {format} is not supported.")
493
+ return target
494
+
495
+ def resize(
496
+ self,
497
+ image: np.ndarray,
498
+ size: SizeDict,
499
+ resample: Optional["PILImageResampling"] = None,
500
+ **kwargs,
501
+ ) -> np.ndarray:
502
+ """
503
+ Resize the image to the given size. Size can be `min_size` (scalar) or `(height, width)` tuple. If size is an
504
+ int, smaller edge of the image will be matched to this number.
505
+
506
+ Args:
507
+ image (`np.ndarray`):
508
+ Image to resize.
509
+ size (`SizeDict`):
510
+ Size of the image's `(height, width)` dimensions after resizing. Available options are:
511
+ - `{"height": int, "width": int}`: The image will be resized to the exact size `(height, width)`.
512
+ Do NOT keep the aspect ratio.
513
+ - `{"shortest_edge": int, "longest_edge": int}`: The image will be resized to a maximum size respecting
514
+ the aspect ratio and keeping the shortest edge less or equal to `shortest_edge` and the longest edge
515
+ less or equal to `longest_edge`.
516
+ - `{"max_height": int, "max_width": int}`: The image will be resized to the maximum size respecting the
517
+ aspect ratio and keeping the height less or equal to `max_height` and the width less or equal to
518
+ `max_width`.
519
+ resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BILINEAR`):
520
+ Resampling filter to use if resizing the image.
521
+ """
522
+ resample = resample if resample is not None else self.resample
523
+
524
+ if size.shortest_edge and size.longest_edge:
525
+ # Resize the image so that the shortest edge or the longest edge is of the given size
526
+ # while maintaining the aspect ratio of the original image.
527
+ new_size = get_size_with_aspect_ratio(
528
+ image.shape[-2:],
529
+ size.shortest_edge,
530
+ size.longest_edge or size.shortest_edge,
531
+ )
532
+ elif size.max_height and size.max_width:
533
+ new_size = get_image_size_for_max_height_width(image.shape[-2:], size.max_height, size.max_width)
534
+ elif size.height and size.width:
535
+ new_size = (size.height, size.width)
536
+ else:
537
+ raise ValueError(
538
+ f"Size must contain 'height' and 'width' keys or 'shortest_edge' and 'longest_edge' keys. Got {size}."
539
+ )
540
+
541
+ image = super().resize(
542
+ image,
543
+ size=SizeDict(height=new_size[0], width=new_size[1]),
544
+ resample=resample,
545
+ **kwargs,
546
+ )
547
+ return image
548
+
549
+ def resize_annotation(
550
+ self,
551
+ annotation: dict[str, Any],
552
+ orig_size: tuple[int, int],
553
+ target_size: tuple[int, int],
554
+ threshold: float = 0.5,
555
+ resample: Optional["PILImageResampling"] = PILImageResampling.NEAREST,
556
+ ):
557
+ """
558
+ Resizes an annotation to a target size.
559
+
560
+ Args:
561
+ annotation (`dict[str, Any]`):
562
+ The annotation dictionary.
563
+ orig_size (`tuple[int, int]`):
564
+ The original size of the input image.
565
+ target_size (`tuple[int, int]`):
566
+ The target size of the image, as returned by the preprocessing `resize` step.
567
+ threshold (`float`, *optional*, defaults to 0.5):
568
+ The threshold used to binarize the segmentation masks.
569
+ resample (`PILImageResampling`, defaults to `PILImageResampling.NEAREST`):
570
+ The resampling filter to use when resizing the masks.
571
+ """
572
+ ratios = tuple(float(s) / float(s_orig) for s, s_orig in zip(target_size, orig_size))
573
+ ratio_height, ratio_width = ratios
574
+
575
+ new_annotation = {}
576
+ new_annotation["size"] = target_size
577
+
578
+ for key, value in annotation.items():
579
+ if key == "boxes":
580
+ boxes = value
581
+ scaled_boxes = boxes * np.asarray(
582
+ [ratio_width, ratio_height, ratio_width, ratio_height], dtype=np.float32
583
+ )
584
+ new_annotation["boxes"] = scaled_boxes
585
+ elif key == "area":
586
+ area = value
587
+ scaled_area = area * (ratio_width * ratio_height)
588
+ new_annotation["area"] = scaled_area
589
+ elif key == "masks":
590
+ masks = value[:, None]
591
+ masks = np.array([resize(mask, target_size, resample=resample) for mask in masks])
592
+ masks = masks.astype(np.float32)
593
+ masks = masks[:, 0] > threshold
594
+ new_annotation["masks"] = masks
595
+ elif key == "size":
596
+ new_annotation["size"] = target_size
597
+ else:
598
+ new_annotation[key] = value
599
+
600
+ return new_annotation
601
+
602
+ def normalize_annotation(self, annotation: dict, image_size: tuple[int, int]) -> dict:
603
+ image_height, image_width = image_size
604
+ norm_annotation = {}
605
+ for key, value in annotation.items():
606
+ if key == "boxes":
607
+ boxes = value
608
+ boxes = corners_to_center_format(boxes)
609
+ boxes /= np.asarray([image_width, image_height, image_width, image_height], dtype=np.float32)
610
+ norm_annotation[key] = boxes
611
+ else:
612
+ norm_annotation[key] = value
613
+ return norm_annotation
614
+
615
+ def _update_annotation_for_padded_image(
616
+ self,
617
+ annotation: dict,
618
+ input_image_size: tuple[int, int],
619
+ output_image_size: tuple[int, int],
620
+ padding,
621
+ update_bboxes,
622
+ ) -> dict:
623
+ """
624
+ Update the annotation for a padded image.
625
+ """
626
+ new_annotation = {}
627
+ new_annotation["size"] = output_image_size
628
+ ratio_height, ratio_width = (input / output for output, input in zip(output_image_size, input_image_size))
629
+
630
+ for key, value in annotation.items():
631
+ if key == "masks":
632
+ masks = value
633
+ masks = pad(
634
+ masks,
635
+ padding,
636
+ mode=PaddingMode.CONSTANT,
637
+ constant_values=0,
638
+ input_data_format=ChannelDimension.FIRST,
639
+ )
640
+ masks = safe_squeeze(masks, 1)
641
+ new_annotation["masks"] = masks
642
+ elif key == "boxes" and update_bboxes:
643
+ boxes = value
644
+ boxes *= np.asarray(
645
+ [
646
+ input_image_size[1] / output_image_size[1],
647
+ input_image_size[0] / output_image_size[0],
648
+ input_image_size[1] / output_image_size[1],
649
+ input_image_size[0] / output_image_size[0],
650
+ ]
651
+ )
652
+ new_annotation["boxes"] = boxes
653
+ elif key == "size":
654
+ new_annotation["size"] = output_image_size
655
+ else:
656
+ new_annotation[key] = value
657
+ return new_annotation
658
+
659
+ def pad(
660
+ self,
661
+ image: np.ndarray,
662
+ padded_size: tuple[int, int],
663
+ annotation: dict[str, Any] | None = None,
664
+ update_bboxes: bool = True,
665
+ fill: int = 0,
666
+ ):
667
+ input_height, input_width = get_image_size(image, channel_dim=ChannelDimension.FIRST)
668
+ output_height, output_width = padded_size
669
+ padding_bottom = output_height - input_height
670
+ padding_right = output_width - input_width
671
+ if padding_bottom < 0 or padding_right < 0:
672
+ raise ValueError(
673
+ f"Padding dimensions are negative. Please make sure that the padded size is larger than the "
674
+ f"original size. Got padded size: {padded_size}, original size: {(input_height, input_width)}."
675
+ )
676
+ if (input_height, input_width) != padded_size:
677
+ padding = ((0, padding_bottom), (0, padding_right))
678
+ image = pad(
679
+ image,
680
+ padding,
681
+ mode=PaddingMode.CONSTANT,
682
+ constant_values=fill,
683
+ data_format=ChannelDimension.FIRST,
684
+ input_data_format=ChannelDimension.FIRST,
685
+ )
686
+ if annotation is not None:
687
+ annotation = self._update_annotation_for_padded_image(
688
+ annotation, (input_height, input_width), (output_height, output_width), padding, update_bboxes
689
+ )
690
+
691
+ # Make a pixel mask for the image, where 1 indicates a valid pixel and 0 indicates padding.
692
+ pixel_mask = np.zeros(padded_size, dtype=np.int64)
693
+ pixel_mask[:input_height, :input_width] = 1
694
+
695
+ return image, pixel_mask, annotation
696
+
697
+ @auto_docstring
698
+ def preprocess(
699
+ self,
700
+ images: ImageInput,
701
+ annotations: AnnotationType | list[AnnotationType] | None = None,
702
+ return_segmentation_masks: bool | None = None,
703
+ masks_path: str | pathlib.Path | None = None,
704
+ **kwargs: Unpack[ConditionalDetrImageProcessorKwargs],
705
+ ) -> BatchFeature:
706
+ r"""
707
+ annotations (`AnnotationType` or `list[AnnotationType]`, *optional*):
708
+ Annotations to transform according to the padding that is applied to the images.
709
+ return_segmentation_masks (`bool`, *optional*, defaults to `self.return_segmentation_masks`):
710
+ Whether to return segmentation masks.
711
+ masks_path (`str` or `pathlib.Path`, *optional*):
712
+ Path to the directory containing the segmentation masks.
713
+ """
714
+ return super().preprocess(images, annotations, return_segmentation_masks, masks_path, **kwargs)
715
+
716
+ def _preprocess(
717
+ self,
718
+ images: list[np.ndarray],
719
+ annotations: AnnotationType | list[AnnotationType] | None,
720
+ return_segmentation_masks: bool,
721
+ masks_path: str | pathlib.Path | None,
722
+ do_resize: bool,
723
+ size: SizeDict,
724
+ resample: "PILImageResampling | None",
725
+ do_rescale: bool,
726
+ rescale_factor: float,
727
+ do_normalize: bool,
728
+ do_convert_annotations: bool,
729
+ image_mean: float | list[float] | None,
730
+ image_std: float | list[float] | None,
731
+ do_pad: bool,
732
+ pad_size: SizeDict | None,
733
+ format: str | AnnotationFormat | None,
734
+ return_tensors: str | TensorType | None,
735
+ **kwargs,
736
+ ) -> BatchFeature:
737
+ """
738
+ Preprocess an image or a batch of images so that it can be used by the model.
739
+ """
740
+ if annotations is not None and isinstance(annotations, dict):
741
+ annotations = [annotations]
742
+
743
+ if annotations is not None and len(images) != len(annotations):
744
+ raise ValueError(
745
+ f"The number of images ({len(images)}) and annotations ({len(annotations)}) do not match."
746
+ )
747
+
748
+ format = AnnotationFormat(format)
749
+ if annotations is not None:
750
+ validate_annotations(format, SUPPORTED_ANNOTATION_FORMATS, annotations)
751
+
752
+ if (
753
+ masks_path is not None
754
+ and format == AnnotationFormat.COCO_PANOPTIC
755
+ and not isinstance(masks_path, (pathlib.Path, str))
756
+ ):
757
+ raise ValueError(
758
+ "The path to the directory containing the mask PNG files should be provided as a"
759
+ f" `pathlib.Path` or string object, but is {type(masks_path)} instead."
760
+ )
761
+
762
+ data = {}
763
+
764
+ # Import torch if needed for tensor conversion
765
+ if return_tensors == "pt":
766
+ if not is_torch_available():
767
+ raise ImportError("PyTorch is required for tensor conversion.")
768
+
769
+ processed_images = []
770
+ processed_annotations = []
771
+ pixel_masks = [] # Initialize pixel_masks here
772
+ for image, annotation in zip(images, annotations if annotations is not None else [None] * len(images)):
773
+ # prepare (COCO annotations as a list of Dict -> CONDITIONAL_DETR target as a single Dict per image)
774
+ if annotations is not None:
775
+ annotation = self.prepare_annotation(
776
+ image,
777
+ annotation,
778
+ format,
779
+ return_segmentation_masks=return_segmentation_masks,
780
+ masks_path=masks_path,
781
+ input_data_format=ChannelDimension.FIRST,
782
+ )
783
+
784
+ if do_resize:
785
+ resized_image = self.resize(image, size=size, resample=resample)
786
+ if annotations is not None:
787
+ annotation = self.resize_annotation(
788
+ annotation,
789
+ orig_size=get_image_size(image, channel_dim=ChannelDimension.FIRST),
790
+ target_size=get_image_size(resized_image, channel_dim=ChannelDimension.FIRST),
791
+ )
792
+ image = resized_image
793
+
794
+ if do_rescale:
795
+ image = self.rescale(image, rescale_factor)
796
+ if do_normalize:
797
+ image = self.normalize(image, image_mean, image_std)
798
+
799
+ if do_convert_annotations and annotations is not None:
800
+ annotation = self.normalize_annotation(annotation, get_image_size(image, ChannelDimension.FIRST))
801
+
802
+ processed_images.append(image)
803
+ processed_annotations.append(annotation)
804
+ images = processed_images
805
+ annotations = processed_annotations if annotations is not None else None
806
+
807
+ if do_pad:
808
+ # depends on all resized image shapes so we need another loop
809
+ if pad_size is not None:
810
+ padded_size = (pad_size.height, pad_size.width)
811
+ else:
812
+ padded_size = get_max_height_width(images, input_data_format=ChannelDimension.FIRST)
813
+
814
+ padded_images = []
815
+ padded_annotations = []
816
+ for image, annotation in zip(images, annotations if annotations is not None else [None] * len(images)):
817
+ # Pads images and returns their mask: {'pixel_values': ..., 'pixel_mask': ...}
818
+ image_height, image_width = get_image_size(image, channel_dim=ChannelDimension.FIRST)
819
+ if padded_size == (image_height, image_width):
820
+ padded_images.append(image)
821
+ pixel_masks.append(np.ones(padded_size, dtype=np.int64))
822
+ padded_annotations.append(annotation)
823
+ continue
824
+ image, pixel_mask, annotation = self.pad(
825
+ image, padded_size, annotation=annotation, update_bboxes=do_convert_annotations
826
+ )
827
+ padded_images.append(image)
828
+ padded_annotations.append(annotation)
829
+ pixel_masks.append(pixel_mask)
830
+ images = padded_images
831
+ annotations = padded_annotations if annotations is not None else None
832
+ data.update({"pixel_mask": pixel_masks})
833
+
834
+ data.update({"pixel_values": images})
835
+ encoded_inputs = BatchFeature(data, tensor_type=return_tensors)
836
+ if annotations is not None:
837
+ encoded_inputs["labels"] = [
838
+ BatchFeature(annotation, tensor_type=return_tensors) for annotation in annotations
839
+ ]
840
+ return encoded_inputs
841
+
842
+ @requires(backends=("torch",))
843
+ def post_process_object_detection(
844
+ self, outputs, threshold: float = 0.5, target_sizes: TensorType | list[tuple] = None, top_k: int = 100
845
+ ):
846
+ """
847
+ Converts the raw output of [`ConditionalDetrForObjectDetection`] into final bounding boxes in (top_left_x,
848
+ top_left_y, bottom_right_x, bottom_right_y) format. Only supports PyTorch.
849
+
850
+ Args:
851
+ outputs ([`ConditionalDetrObjectDetectionOutput`]):
852
+ Raw outputs of the model.
853
+ threshold (`float`, *optional*):
854
+ Score threshold to keep object detection predictions.
855
+ target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
856
+ Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
857
+ (height, width) of each image in the batch. If left to None, predictions will not be resized.
858
+ top_k (`int`, *optional*, defaults to 100):
859
+ Keep only top k bounding boxes before filtering by thresholding.
860
+
861
+ Returns:
862
+ `list[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image
863
+ in the batch as predicted by the model.
864
+ """
865
+ requires_backends(self, ["torch"])
866
+ out_logits, out_bbox = outputs.logits, outputs.pred_boxes
867
+
868
+ if target_sizes is not None:
869
+ if len(out_logits) != len(target_sizes):
870
+ raise ValueError(
871
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
872
+ )
873
+
874
+ prob = out_logits.sigmoid()
875
+ prob = prob.view(out_logits.shape[0], -1)
876
+ k_value = min(top_k, prob.size(1))
877
+ topk_values, topk_indexes = torch.topk(prob, k_value, dim=1)
878
+ scores = topk_values
879
+ topk_boxes = torch.div(topk_indexes, out_logits.shape[2], rounding_mode="floor")
880
+ labels = topk_indexes % out_logits.shape[2]
881
+ boxes = center_to_corners_format(out_bbox)
882
+ boxes = torch.gather(boxes, 1, topk_boxes.unsqueeze(-1).repeat(1, 1, 4))
883
+
884
+ # and from relative [0, 1] to absolute [0, height] coordinates
885
+ if target_sizes is not None:
886
+ if isinstance(target_sizes, list):
887
+ img_h = torch.Tensor([i[0] for i in target_sizes])
888
+ img_w = torch.Tensor([i[1] for i in target_sizes])
889
+ else:
890
+ img_h, img_w = target_sizes.unbind(1)
891
+ scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device)
892
+ boxes = boxes * scale_fct[:, None, :]
893
+
894
+ results = []
895
+ for s, l, b in zip(scores, labels, boxes):
896
+ score = s[s > threshold]
897
+ label = l[s > threshold]
898
+ box = b[s > threshold]
899
+ results.append({"scores": score, "labels": label, "boxes": box})
900
+
901
+ return results
902
+
903
+ @requires(backends=("torch",))
904
+ def post_process_semantic_segmentation(self, outputs, target_sizes: list[tuple[int, int]] | None = None):
905
+ """
906
+ Converts the output of [`ConditionalDetrForSegmentation`] into semantic segmentation maps. Only supports PyTorch.
907
+
908
+ Args:
909
+ outputs ([`ConditionalDetrForSegmentation`]):
910
+ Raw outputs of the model.
911
+ target_sizes (`list[tuple[int, int]]`, *optional*):
912
+ A list of tuples (`tuple[int, int]`) containing the target size (height, width) of each image in the
913
+ batch. If unset, predictions will not be resized.
914
+ Returns:
915
+ `list[torch.Tensor]`:
916
+ A list of length `batch_size`, where each item is a semantic segmentation map of shape (height, width)
917
+ corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each
918
+ `torch.Tensor` correspond to a semantic class id.
919
+ """
920
+ requires_backends(self, ["torch"])
921
+ class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes]
922
+ masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width]
923
+
924
+ # Conditional DETR does not have a null class, so we use all classes
925
+ masks_classes = class_queries_logits.softmax(dim=-1)
926
+ masks_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
927
+
928
+ # Semantic segmentation logits of shape (batch_size, num_classes, height, width)
929
+ segmentation = torch.einsum("bqc, bqhw -> bchw", masks_classes, masks_probs)
930
+ batch_size = class_queries_logits.shape[0]
931
+
932
+ # Resize logits and compute semantic segmentation maps
933
+ if target_sizes is not None:
934
+ if batch_size != len(target_sizes):
935
+ raise ValueError(
936
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
937
+ )
938
+
939
+ semantic_segmentation = []
940
+ for idx in range(batch_size):
941
+ resized_logits = nn.functional.interpolate(
942
+ segmentation[idx].unsqueeze(dim=0), size=target_sizes[idx], mode="bilinear", align_corners=False
943
+ )
944
+ semantic_map = resized_logits[0].argmax(dim=0)
945
+ semantic_segmentation.append(semantic_map)
946
+ else:
947
+ semantic_segmentation = segmentation.argmax(dim=1)
948
+ semantic_segmentation = [semantic_segmentation[i] for i in range(semantic_segmentation.shape[0])]
949
+
950
+ return semantic_segmentation
951
+
952
+ @requires(backends=("torch",))
953
+ def post_process_instance_segmentation(
954
+ self,
955
+ outputs,
956
+ threshold: float = 0.5,
957
+ mask_threshold: float = 0.5,
958
+ overlap_mask_area_threshold: float = 0.8,
959
+ target_sizes: list[tuple[int, int]] | None = None,
960
+ return_coco_annotation: bool | None = False,
961
+ ) -> list[dict]:
962
+ """
963
+ Converts the output of [`ConditionalDetrForSegmentation`] into instance segmentation predictions. Only supports PyTorch.
964
+
965
+ Args:
966
+ outputs ([`ConditionalDetrForSegmentation`]):
967
+ Raw outputs of the model.
968
+ threshold (`float`, *optional*, defaults to 0.5):
969
+ The probability score threshold to keep predicted instance masks.
970
+ mask_threshold (`float`, *optional*, defaults to 0.5):
971
+ Threshold to use when turning the predicted masks into binary values.
972
+ overlap_mask_area_threshold (`float`, *optional*, defaults to 0.8):
973
+ The overlap mask area threshold to merge or discard small disconnected parts within each binary
974
+ instance mask.
975
+ target_sizes (`list[Tuple]`, *optional*):
976
+ List of length (batch_size), where each list item (`tuple[int, int]]`) corresponds to the requested
977
+ final size (height, width) of each prediction. If unset, predictions will not be resized.
978
+ return_coco_annotation (`bool`, *optional*):
979
+ Defaults to `False`. If set to `True`, segmentation maps are returned in COCO run-length encoding (RLE)
980
+ format.
981
+ Returns:
982
+ `list[Dict]`: A list of dictionaries, one per image, each dictionary containing two keys:
983
+ - **segmentation** -- A tensor of shape `(height, width)` where each pixel represents a `segment_id` or
984
+ `list[List]` run-length encoding (RLE) of the segmentation map if return_coco_annotation is set to
985
+ `True`. Set to `None` if no mask if found above `threshold`.
986
+ - **segments_info** -- A dictionary that contains additional information on each segment.
987
+ - **id** -- An integer representing the `segment_id`.
988
+ - **label_id** -- An integer representing the label / semantic class id corresponding to `segment_id`.
989
+ - **score** -- Prediction score of segment with `segment_id`.
990
+ """
991
+ if not is_torch_available():
992
+ raise ImportError("PyTorch is required for post-processing.")
993
+ import torch
994
+ from torch import nn
995
+
996
+ class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes+1]
997
+ masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width]
998
+
999
+ batch_size = class_queries_logits.shape[0]
1000
+ num_labels = class_queries_logits.shape[-1] - 1
1001
+
1002
+ mask_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
1003
+
1004
+ # Predicted label and score of each query (batch_size, num_queries)
1005
+ pred_scores, pred_labels = nn.functional.softmax(class_queries_logits, dim=-1).max(-1)
1006
+
1007
+ # Loop over items in batch size
1008
+ results: list[dict[str, TensorType]] = []
1009
+
1010
+ for i in range(batch_size):
1011
+ mask_probs_item, pred_scores_item, pred_labels_item = remove_low_and_no_objects(
1012
+ mask_probs[i], pred_scores[i], pred_labels[i], threshold, num_labels
1013
+ )
1014
+
1015
+ # No mask found
1016
+ if mask_probs_item.shape[0] <= 0:
1017
+ height, width = target_sizes[i] if target_sizes is not None else mask_probs_item.shape[1:]
1018
+ segmentation = torch.zeros((height, width)) - 1
1019
+ results.append({"segmentation": segmentation, "segments_info": []})
1020
+ continue
1021
+
1022
+ # Get segmentation map and segment information of batch item
1023
+ target_size = target_sizes[i] if target_sizes is not None else None
1024
+ segmentation, segments = compute_segments(
1025
+ mask_probs=mask_probs_item,
1026
+ pred_scores=pred_scores_item,
1027
+ pred_labels=pred_labels_item,
1028
+ mask_threshold=mask_threshold,
1029
+ overlap_mask_area_threshold=overlap_mask_area_threshold,
1030
+ label_ids_to_fuse=[],
1031
+ target_size=target_size,
1032
+ )
1033
+
1034
+ # Return segmentation map in run-length encoding (RLE) format
1035
+ if return_coco_annotation:
1036
+ segmentation = convert_segmentation_to_rle(segmentation)
1037
+
1038
+ results.append({"segmentation": segmentation, "segments_info": segments})
1039
+ return results
1040
+
1041
+ @requires(backends=("torch",))
1042
+ def post_process_panoptic_segmentation(
1043
+ self,
1044
+ outputs,
1045
+ threshold: float = 0.5,
1046
+ mask_threshold: float = 0.5,
1047
+ overlap_mask_area_threshold: float = 0.8,
1048
+ label_ids_to_fuse: set[int] | None = None,
1049
+ target_sizes: list[tuple[int, int]] | None = None,
1050
+ ) -> list[dict]:
1051
+ """
1052
+ Converts the output of [`ConditionalDetrForSegmentation`] into image panoptic segmentation predictions. Only supports
1053
+ PyTorch.
1054
+
1055
+ Args:
1056
+ outputs ([`ConditionalDetrForSegmentation`]):
1057
+ The outputs from [`ConditionalDetrForSegmentation`].
1058
+ threshold (`float`, *optional*, defaults to 0.5):
1059
+ The probability score threshold to keep predicted instance masks.
1060
+ mask_threshold (`float`, *optional*, defaults to 0.5):
1061
+ Threshold to use when turning the predicted masks into binary values.
1062
+ overlap_mask_area_threshold (`float`, *optional*, defaults to 0.8):
1063
+ The overlap mask area threshold to merge or discard small disconnected parts within each binary
1064
+ instance mask.
1065
+ label_ids_to_fuse (`Set[int]`, *optional*):
1066
+ The labels in this state will have all their instances be fused together. For instance we could say
1067
+ there can only be one sky in an image, but several persons, so the label ID for sky would be in that
1068
+ set, but not the one for person.
1069
+ target_sizes (`list[Tuple]`, *optional*):
1070
+ List of length (batch_size), where each list item (`tuple[int, int]]`) corresponds to the requested
1071
+ final size (height, width) of each prediction in batch. If unset, predictions will not be resized.
1072
+ Returns:
1073
+ `list[Dict]`: A list of dictionaries, one per image, each dictionary containing two keys:
1074
+ - **segmentation** -- a tensor of shape `(height, width)` where each pixel represents a `segment_id` or
1075
+ `None` if no mask if found above `threshold`. If `target_sizes` is specified, segmentation is resized to
1076
+ the corresponding `target_sizes` entry.
1077
+ - **segments_info** -- A dictionary that contains additional information on each segment.
1078
+ - **id** -- an integer representing the `segment_id`.
1079
+ - **label_id** -- An integer representing the label / semantic class id corresponding to `segment_id`.
1080
+ - **was_fused** -- a boolean, `True` if `label_id` was in `label_ids_to_fuse`, `False` otherwise.
1081
+ Multiple instances of the same class / label were fused and assigned a single `segment_id`.
1082
+ - **score** -- Prediction score of segment with `segment_id`.
1083
+ """
1084
+
1085
+ if label_ids_to_fuse is None:
1086
+ logger.warning_once("`label_ids_to_fuse` unset. No instance will be fused.")
1087
+ label_ids_to_fuse = set()
1088
+
1089
+ if not is_torch_available():
1090
+ raise ImportError("PyTorch is required for post-processing.")
1091
+ import torch
1092
+ from torch import nn
1093
+
1094
+ class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes+1]
1095
+ masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width]
1096
+
1097
+ batch_size = class_queries_logits.shape[0]
1098
+ num_labels = class_queries_logits.shape[-1] - 1
1099
+
1100
+ mask_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
1101
+
1102
+ # Predicted label and score of each query (batch_size, num_queries)
1103
+ pred_scores, pred_labels = nn.functional.softmax(class_queries_logits, dim=-1).max(-1)
1104
+
1105
+ # Loop over items in batch size
1106
+ results: list[dict[str, TensorType]] = []
1107
+
1108
+ for i in range(batch_size):
1109
+ mask_probs_item, pred_scores_item, pred_labels_item = remove_low_and_no_objects(
1110
+ mask_probs[i], pred_scores[i], pred_labels[i], threshold, num_labels
1111
+ )
1112
+
1113
+ # No mask found
1114
+ if mask_probs_item.shape[0] <= 0:
1115
+ height, width = target_sizes[i] if target_sizes is not None else mask_probs_item.shape[1:]
1116
+ segmentation = torch.zeros((height, width)) - 1
1117
+ results.append({"segmentation": segmentation, "segments_info": []})
1118
+ continue
1119
+
1120
+ # Get segmentation map and segment information of batch item
1121
+ target_size = target_sizes[i] if target_sizes is not None else None
1122
+ segmentation, segments = compute_segments(
1123
+ mask_probs=mask_probs_item,
1124
+ pred_scores=pred_scores_item,
1125
+ pred_labels=pred_labels_item,
1126
+ mask_threshold=mask_threshold,
1127
+ overlap_mask_area_threshold=overlap_mask_area_threshold,
1128
+ label_ids_to_fuse=label_ids_to_fuse,
1129
+ target_size=target_size,
1130
+ )
1131
+
1132
+ results.append({"segmentation": segmentation, "segments_info": segments})
1133
+ return results
1134
+
1135
+
1136
+ __all__ = ["ConditionalDetrImageProcessorPil"]
third_party/transformers/src/transformers/models/conditional_detr/modeling_conditional_detr.py ADDED
@@ -0,0 +1,1827 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/conditional_detr/modular_conditional_detr.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_conditional_detr.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2022 Microsoft Research Asia and The HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ import math
21
+ from collections.abc import Callable
22
+ from dataclasses import dataclass
23
+
24
+ import torch
25
+ from torch import nn
26
+
27
+ from ... import initialization as init
28
+ from ...activations import ACT2FN
29
+ from ...backbone_utils import load_backbone
30
+ from ...masking_utils import create_bidirectional_mask
31
+ from ...modeling_layers import GradientCheckpointingLayer
32
+ from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithCrossAttentions, Seq2SeqModelOutput
33
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
34
+ from ...processing_utils import Unpack
35
+ from ...pytorch_utils import compile_compatible_method_lru_cache
36
+ from ...utils import ModelOutput, TransformersKwargs, auto_docstring
37
+ from ...utils.generic import can_return_tuple, merge_with_config_defaults
38
+ from ...utils.output_capturing import OutputRecorder, capture_outputs
39
+ from .configuration_conditional_detr import ConditionalDetrConfig
40
+
41
+
42
+ @dataclass
43
+ @auto_docstring(
44
+ custom_intro="""
45
+ Base class for outputs of the CONDITIONAL_DETR decoder. This class adds one attribute to BaseModelOutputWithCrossAttentions,
46
+ namely an optional stack of intermediate decoder activations, i.e. the output of each decoder layer, each of them
47
+ gone through a layernorm. This is useful when training the model with auxiliary decoding losses.
48
+ """
49
+ )
50
+ class ConditionalDetrDecoderOutput(BaseModelOutputWithCrossAttentions):
51
+ r"""
52
+ cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` and `config.add_cross_attention=True` is passed or when `config.output_attentions=True`):
53
+ Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
54
+ sequence_length)`. Attentions weights of the decoder's cross-attention layer, after the attention softmax,
55
+ used to compute the weighted average in the cross-attention heads.
56
+ intermediate_hidden_states (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, num_queries, hidden_size)`, *optional*, returned when `config.auxiliary_loss=True`):
57
+ Intermediate decoder activations, i.e. the output of each decoder layer, each of them gone through a
58
+ layernorm.
59
+ reference_points (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, num_queries, 2 (anchor points))`):
60
+ Reference points (reference points of each layer of the decoder).
61
+ """
62
+
63
+ intermediate_hidden_states: torch.FloatTensor | None = None
64
+
65
+ reference_points: tuple[torch.FloatTensor] | None = None
66
+
67
+
68
+ @dataclass
69
+ @auto_docstring(
70
+ custom_intro="""
71
+ Base class for outputs of the CONDITIONAL_DETR encoder-decoder model. This class adds one attribute to Seq2SeqModelOutput,
72
+ namely an optional stack of intermediate decoder activations, i.e. the output of each decoder layer, each of them
73
+ gone through a layernorm. This is useful when training the model with auxiliary decoding losses.
74
+ """
75
+ )
76
+ class ConditionalDetrModelOutput(Seq2SeqModelOutput):
77
+ r"""
78
+ last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
79
+ Sequence of hidden-states at the output of the last layer of the decoder of the model.
80
+ intermediate_hidden_states (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, sequence_length, hidden_size)`, *optional*, returned when `config.auxiliary_loss=True`):
81
+ Intermediate decoder activations, i.e. the output of each decoder layer, each of them gone through a
82
+ layernorm.
83
+ reference_points (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, num_queries, 2 (anchor points))`):
84
+ Reference points (reference points of each layer of the decoder).
85
+ """
86
+
87
+ intermediate_hidden_states: torch.FloatTensor | None = None
88
+
89
+ reference_points: tuple[torch.FloatTensor] | None = None
90
+
91
+
92
+ @dataclass
93
+ @auto_docstring(
94
+ custom_intro="""
95
+ Output type of [`ConditionalDetrForObjectDetection`].
96
+ """
97
+ )
98
+ class ConditionalDetrObjectDetectionOutput(ModelOutput):
99
+ r"""
100
+ loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` are provided)):
101
+ Total loss as a linear combination of a negative log-likehood (cross-entropy) for class prediction and a
102
+ bounding box loss. The latter is defined as a linear combination of the L1 loss and the generalized
103
+ scale-invariant IoU loss.
104
+ loss_dict (`Dict`, *optional*):
105
+ A dictionary containing the individual losses. Useful for logging.
106
+ logits (`torch.FloatTensor` of shape `(batch_size, num_queries, num_classes + 1)`):
107
+ Classification logits (including no-object) for all queries.
108
+ pred_boxes (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`):
109
+ Normalized boxes coordinates for all queries, represented as (center_x, center_y, width, height). These
110
+ values are normalized in [0, 1], relative to the size of each individual image in the batch (disregarding
111
+ possible padding). You can use [`~ConditionalDetrImageProcessor.post_process_object_detection`] to retrieve the
112
+ unnormalized bounding boxes.
113
+ auxiliary_outputs (`list[Dict]`, *optional*):
114
+ Optional, only returned when auxiliary losses are activated (i.e. `config.auxiliary_loss` is set to `True`)
115
+ and labels are provided. It is a list of dictionaries containing the two above keys (`logits` and
116
+ `pred_boxes`) for each decoder layer.
117
+ last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
118
+ Sequence of hidden-states at the output of the last layer of the decoder of the model.
119
+ """
120
+
121
+ loss: torch.FloatTensor | None = None
122
+ loss_dict: dict | None = None
123
+ logits: torch.FloatTensor | None = None
124
+ pred_boxes: torch.FloatTensor | None = None
125
+ auxiliary_outputs: list[dict] | None = None
126
+ last_hidden_state: torch.FloatTensor | None = None
127
+ decoder_hidden_states: tuple[torch.FloatTensor] | None = None
128
+ decoder_attentions: tuple[torch.FloatTensor] | None = None
129
+ cross_attentions: tuple[torch.FloatTensor] | None = None
130
+ encoder_last_hidden_state: torch.FloatTensor | None = None
131
+ encoder_hidden_states: tuple[torch.FloatTensor] | None = None
132
+ encoder_attentions: tuple[torch.FloatTensor] | None = None
133
+
134
+
135
+ @dataclass
136
+ @auto_docstring(
137
+ custom_intro="""
138
+ Output type of [`ConditionalDetrForSegmentation`].
139
+ """
140
+ )
141
+ class ConditionalDetrSegmentationOutput(ModelOutput):
142
+ r"""
143
+ loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` are provided)):
144
+ Total loss as a linear combination of a negative log-likehood (cross-entropy) for class prediction and a
145
+ bounding box loss. The latter is defined as a linear combination of the L1 loss and the generalized
146
+ scale-invariant IoU loss.
147
+ loss_dict (`Dict`, *optional*):
148
+ A dictionary containing the individual losses. Useful for logging.
149
+ logits (`torch.FloatTensor` of shape `(batch_size, num_queries, num_classes + 1)`):
150
+ Classification logits (including no-object) for all queries.
151
+ pred_boxes (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`):
152
+ Normalized boxes coordinates for all queries, represented as (center_x, center_y, width, height). These
153
+ values are normalized in [0, 1], relative to the size of each individual image in the batch (disregarding
154
+ possible padding). You can use [`~ConditionalDetrImageProcessor.post_process_object_detection`] to retrieve the
155
+ unnormalized bounding boxes.
156
+ pred_masks (`torch.FloatTensor` of shape `(batch_size, num_queries, height/4, width/4)`):
157
+ Segmentation masks logits for all queries. See also
158
+ [`~ConditionalDetrImageProcessor.post_process_semantic_segmentation`] or
159
+ [`~ConditionalDetrImageProcessor.post_process_instance_segmentation`]
160
+ [`~ConditionalDetrImageProcessor.post_process_panoptic_segmentation`] to evaluate semantic, instance and panoptic
161
+ segmentation masks respectively.
162
+ auxiliary_outputs (`list[Dict]`, *optional*):
163
+ Optional, only returned when auxiliary losses are activated (i.e. `config.auxiliary_loss` is set to `True`)
164
+ and labels are provided. It is a list of dictionaries containing the two above keys (`logits` and
165
+ `pred_boxes`) for each decoder layer.
166
+ last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
167
+ Sequence of hidden-states at the output of the last layer of the decoder of the model.
168
+ """
169
+
170
+ loss: torch.FloatTensor | None = None
171
+ loss_dict: dict | None = None
172
+ logits: torch.FloatTensor | None = None
173
+ pred_boxes: torch.FloatTensor | None = None
174
+ pred_masks: torch.FloatTensor | None = None
175
+ auxiliary_outputs: list[dict] | None = None
176
+ last_hidden_state: torch.FloatTensor | None = None
177
+ decoder_hidden_states: tuple[torch.FloatTensor] | None = None
178
+ decoder_attentions: tuple[torch.FloatTensor] | None = None
179
+ cross_attentions: tuple[torch.FloatTensor] | None = None
180
+ encoder_last_hidden_state: torch.FloatTensor | None = None
181
+ encoder_hidden_states: tuple[torch.FloatTensor] | None = None
182
+ encoder_attentions: tuple[torch.FloatTensor] | None = None
183
+
184
+
185
+ class ConditionalDetrFrozenBatchNorm2d(nn.Module):
186
+ """
187
+ BatchNorm2d where the batch statistics and the affine parameters are fixed.
188
+
189
+ Copy-paste from torchvision.misc.ops with added eps before rqsrt, without which any other models than
190
+ torchvision.models.resnet[18,34,50,101] produce nans.
191
+ """
192
+
193
+ def __init__(self, n):
194
+ super().__init__()
195
+ self.register_buffer("weight", torch.ones(n))
196
+ self.register_buffer("bias", torch.zeros(n))
197
+ self.register_buffer("running_mean", torch.zeros(n))
198
+ self.register_buffer("running_var", torch.ones(n))
199
+
200
+ def _load_from_state_dict(
201
+ self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs
202
+ ):
203
+ num_batches_tracked_key = prefix + "num_batches_tracked"
204
+ if num_batches_tracked_key in state_dict:
205
+ del state_dict[num_batches_tracked_key]
206
+
207
+ super()._load_from_state_dict(
208
+ state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs
209
+ )
210
+
211
+ def forward(self, x):
212
+ # move reshapes to the beginning
213
+ # to make it user-friendly
214
+ weight = self.weight.reshape(1, -1, 1, 1)
215
+ bias = self.bias.reshape(1, -1, 1, 1)
216
+ running_var = self.running_var.reshape(1, -1, 1, 1)
217
+ running_mean = self.running_mean.reshape(1, -1, 1, 1)
218
+ epsilon = 1e-5
219
+ scale = weight * (running_var + epsilon).rsqrt()
220
+ bias = bias - running_mean * scale
221
+ return x * scale + bias
222
+
223
+
224
+ def replace_batch_norm(model):
225
+ r"""
226
+ Recursively replace all `torch.nn.BatchNorm2d` with `ConditionalDetrFrozenBatchNorm2d`.
227
+
228
+ Args:
229
+ model (torch.nn.Module):
230
+ input model
231
+ """
232
+ for name, module in model.named_children():
233
+ if isinstance(module, nn.BatchNorm2d):
234
+ new_module = ConditionalDetrFrozenBatchNorm2d(module.num_features)
235
+
236
+ if module.weight.device != torch.device("meta"):
237
+ new_module.weight.copy_(module.weight)
238
+ new_module.bias.copy_(module.bias)
239
+ new_module.running_mean.copy_(module.running_mean)
240
+ new_module.running_var.copy_(module.running_var)
241
+
242
+ model._modules[name] = new_module
243
+
244
+ if len(list(module.children())) > 0:
245
+ replace_batch_norm(module)
246
+
247
+
248
+ class ConditionalDetrConvEncoder(nn.Module):
249
+ """
250
+ Convolutional backbone, using either the AutoBackbone API or one from the timm library.
251
+
252
+ nn.BatchNorm2d layers are replaced by ConditionalDetrFrozenBatchNorm2d as defined above.
253
+
254
+ """
255
+
256
+ def __init__(self, config):
257
+ super().__init__()
258
+
259
+ self.config = config
260
+
261
+ backbone = load_backbone(config)
262
+ self.intermediate_channel_sizes = backbone.channels
263
+
264
+ # replace batch norm by frozen batch norm
265
+ with torch.no_grad():
266
+ replace_batch_norm(backbone)
267
+
268
+ # We used to load with timm library directly instead of the AutoBackbone API
269
+ # so we need to unwrap the `backbone._backbone` module to load weights without mismatch
270
+ is_timm_model = False
271
+ if hasattr(backbone, "_backbone"):
272
+ backbone = backbone._backbone
273
+ is_timm_model = True
274
+ self.model = backbone
275
+
276
+ backbone_model_type = config.backbone_config.model_type
277
+ if "resnet" in backbone_model_type:
278
+ for name, parameter in self.model.named_parameters():
279
+ if is_timm_model:
280
+ if "layer2" not in name and "layer3" not in name and "layer4" not in name:
281
+ parameter.requires_grad_(False)
282
+ else:
283
+ if "stage.1" not in name and "stage.2" not in name and "stage.3" not in name:
284
+ parameter.requires_grad_(False)
285
+
286
+ def forward(self, pixel_values: torch.Tensor, pixel_mask: torch.Tensor):
287
+ # send pixel_values through the model to get list of feature maps
288
+ features = self.model(pixel_values)
289
+ if isinstance(features, dict):
290
+ features = features.feature_maps
291
+
292
+ out = []
293
+ for feature_map in features:
294
+ # downsample pixel_mask to match shape of corresponding feature_map
295
+ mask = nn.functional.interpolate(pixel_mask[None].float(), size=feature_map.shape[-2:]).to(torch.bool)[0]
296
+ out.append((feature_map, mask))
297
+ return out
298
+
299
+
300
+ class ConditionalDetrSinePositionEmbedding(nn.Module):
301
+ """
302
+ This is a more standard version of the position embedding, very similar to the one used by the Attention is all you
303
+ need paper, generalized to work on images.
304
+ """
305
+
306
+ def __init__(
307
+ self,
308
+ num_position_features: int = 64,
309
+ temperature: int = 10000,
310
+ normalize: bool = False,
311
+ scale: float | None = None,
312
+ ):
313
+ super().__init__()
314
+ if scale is not None and normalize is False:
315
+ raise ValueError("normalize should be True if scale is passed")
316
+ self.num_position_features = num_position_features
317
+ self.temperature = temperature
318
+ self.normalize = normalize
319
+ self.scale = 2 * math.pi if scale is None else scale
320
+
321
+ @compile_compatible_method_lru_cache(maxsize=1)
322
+ def forward(
323
+ self,
324
+ shape: torch.Size,
325
+ device: torch.device | str,
326
+ dtype: torch.dtype,
327
+ mask: torch.Tensor | None = None,
328
+ ) -> torch.Tensor:
329
+ if mask is None:
330
+ mask = torch.zeros((shape[0], shape[2], shape[3]), device=device, dtype=torch.bool)
331
+ y_embed = mask.cumsum(1, dtype=dtype)
332
+ x_embed = mask.cumsum(2, dtype=dtype)
333
+ if self.normalize:
334
+ eps = 1e-6
335
+ y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale
336
+ x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale
337
+
338
+ dim_t = torch.arange(self.num_position_features, dtype=torch.int64, device=device).to(dtype)
339
+ dim_t = self.temperature ** (2 * torch.div(dim_t, 2, rounding_mode="floor") / self.num_position_features)
340
+
341
+ pos_x = x_embed[:, :, :, None] / dim_t
342
+ pos_y = y_embed[:, :, :, None] / dim_t
343
+ pos_x = torch.stack((pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4).flatten(3)
344
+ pos_y = torch.stack((pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4).flatten(3)
345
+ pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2)
346
+ # Flatten spatial dimensions and permute to (batch_size, sequence_length, hidden_size) format
347
+ # expected by the encoder
348
+ pos = pos.flatten(2).permute(0, 2, 1)
349
+ return pos
350
+
351
+
352
+ class ConditionalDetrLearnedPositionEmbedding(nn.Module):
353
+ """
354
+ This module learns positional embeddings up to a fixed maximum size.
355
+ """
356
+
357
+ def __init__(self, embedding_dim=256):
358
+ super().__init__()
359
+ self.row_embeddings = nn.Embedding(50, embedding_dim)
360
+ self.column_embeddings = nn.Embedding(50, embedding_dim)
361
+
362
+ @compile_compatible_method_lru_cache(maxsize=1)
363
+ def forward(
364
+ self,
365
+ shape: torch.Size,
366
+ device: torch.device | str,
367
+ dtype: torch.dtype,
368
+ mask: torch.Tensor | None = None,
369
+ ):
370
+ height, width = shape[-2:]
371
+ width_values = torch.arange(width, device=device)
372
+ height_values = torch.arange(height, device=device)
373
+ x_emb = self.column_embeddings(width_values)
374
+ y_emb = self.row_embeddings(height_values)
375
+ pos = torch.cat([x_emb.unsqueeze(0).repeat(height, 1, 1), y_emb.unsqueeze(1).repeat(1, width, 1)], dim=-1)
376
+ pos = pos.permute(2, 0, 1)
377
+ pos = pos.unsqueeze(0)
378
+ pos = pos.repeat(shape[0], 1, 1, 1)
379
+ # Flatten spatial dimensions and permute to (batch_size, sequence_length, hidden_size) format
380
+ # expected by the encoder
381
+ pos = pos.flatten(2).permute(0, 2, 1)
382
+ return pos
383
+
384
+
385
+ def eager_attention_forward(
386
+ module: nn.Module,
387
+ query: torch.Tensor,
388
+ key: torch.Tensor,
389
+ value: torch.Tensor,
390
+ attention_mask: torch.Tensor | None,
391
+ scaling: float | None = None,
392
+ dropout: float = 0.0,
393
+ **kwargs: Unpack[TransformersKwargs],
394
+ ):
395
+ if scaling is None:
396
+ scaling = query.size(-1) ** -0.5
397
+
398
+ # Take the dot product between "query" and "key" to get the raw attention scores.
399
+ attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
400
+
401
+ if attention_mask is not None:
402
+ attn_weights = attn_weights + attention_mask
403
+
404
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1)
405
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
406
+
407
+ attn_output = torch.matmul(attn_weights, value)
408
+ attn_output = attn_output.transpose(1, 2).contiguous()
409
+
410
+ return attn_output, attn_weights
411
+
412
+
413
+ class ConditionalDetrSelfAttention(nn.Module):
414
+ """
415
+ Multi-headed self-attention from 'Attention Is All You Need' paper.
416
+
417
+ In CONDITIONAL_DETR, position embeddings are added to both queries and keys (but not values) in self-attention.
418
+ """
419
+
420
+ def __init__(
421
+ self,
422
+ config: ConditionalDetrConfig,
423
+ hidden_size: int,
424
+ num_attention_heads: int,
425
+ dropout: float = 0.0,
426
+ bias: bool = True,
427
+ ):
428
+ super().__init__()
429
+ self.config = config
430
+ self.head_dim = hidden_size // num_attention_heads
431
+ self.scaling = self.head_dim**-0.5
432
+ self.attention_dropout = dropout
433
+ self.is_causal = False
434
+
435
+ self.k_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
436
+ self.v_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
437
+ self.q_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
438
+ self.o_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
439
+
440
+ def forward(
441
+ self,
442
+ hidden_states: torch.Tensor,
443
+ attention_mask: torch.Tensor | None = None,
444
+ position_embeddings: torch.Tensor | None = None,
445
+ **kwargs: Unpack[TransformersKwargs],
446
+ ) -> tuple[torch.Tensor, torch.Tensor]:
447
+ """
448
+ Position embeddings are added to both queries and keys (but not values).
449
+ """
450
+ input_shape = hidden_states.shape[:-1]
451
+ hidden_shape = (*input_shape, -1, self.head_dim)
452
+
453
+ query_key_input = hidden_states + position_embeddings if position_embeddings is not None else hidden_states
454
+
455
+ query_states = self.q_proj(query_key_input).view(hidden_shape).transpose(1, 2)
456
+ key_states = self.k_proj(query_key_input).view(hidden_shape).transpose(1, 2)
457
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
458
+
459
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
460
+ self.config._attn_implementation, eager_attention_forward
461
+ )
462
+
463
+ attn_output, attn_weights = attention_interface(
464
+ self,
465
+ query_states,
466
+ key_states,
467
+ value_states,
468
+ attention_mask,
469
+ dropout=0.0 if not self.training else self.attention_dropout,
470
+ scaling=self.scaling,
471
+ **kwargs,
472
+ )
473
+
474
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
475
+ attn_output = self.o_proj(attn_output)
476
+ return attn_output, attn_weights
477
+
478
+
479
+ class ConditionalDetrDecoderSelfAttention(nn.Module):
480
+ """
481
+ Multi-headed self-attention for Conditional DETR decoder layers.
482
+
483
+ This attention module handles separate content and position projections, which are then combined
484
+ before applying standard self-attention. Position embeddings are added to both queries and keys.
485
+ """
486
+
487
+ def __init__(
488
+ self,
489
+ config: ConditionalDetrConfig,
490
+ hidden_size: int,
491
+ num_attention_heads: int,
492
+ dropout: float | int = 0.0,
493
+ ):
494
+ super().__init__()
495
+ self.config = config
496
+ self.hidden_size = hidden_size
497
+ self.head_dim = hidden_size // num_attention_heads
498
+ self.scaling = self.head_dim**-0.5
499
+ self.attention_dropout = dropout
500
+ self.is_causal = False
501
+
502
+ # Content and position projections
503
+ self.q_content_proj = nn.Linear(hidden_size, hidden_size)
504
+ self.q_pos_proj = nn.Linear(hidden_size, hidden_size)
505
+ self.k_content_proj = nn.Linear(hidden_size, hidden_size)
506
+ self.k_pos_proj = nn.Linear(hidden_size, hidden_size)
507
+ self.v_proj = nn.Linear(hidden_size, hidden_size)
508
+ self.o_proj = nn.Linear(hidden_size, hidden_size)
509
+
510
+ def forward(
511
+ self,
512
+ hidden_states: torch.Tensor,
513
+ query_position_embeddings: torch.Tensor,
514
+ attention_mask: torch.Tensor | None = None,
515
+ **kwargs: Unpack[TransformersKwargs],
516
+ ) -> tuple[torch.Tensor, torch.Tensor]:
517
+ """
518
+ Args:
519
+ hidden_states (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`):
520
+ Input hidden states from the decoder layer.
521
+ query_position_embeddings (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`):
522
+ Position embeddings for queries and keys. Required (unlike standard attention). Processed through
523
+ separate position projections (`q_pos_proj`, `k_pos_proj`) and added to content projections.
524
+ attention_mask (`torch.Tensor` of shape `(batch_size, 1, num_queries, num_queries)`, *optional*):
525
+ Attention mask to avoid attending to padding tokens.
526
+ """
527
+ input_shape = hidden_states.shape[:-1]
528
+ hidden_shape = (*input_shape, -1, self.head_dim)
529
+
530
+ query_states = (
531
+ (self.q_content_proj(hidden_states) + self.q_pos_proj(query_position_embeddings))
532
+ .view(hidden_shape)
533
+ .transpose(1, 2)
534
+ )
535
+ key_states = (
536
+ (self.k_content_proj(hidden_states) + self.k_pos_proj(query_position_embeddings))
537
+ .view(hidden_shape)
538
+ .transpose(1, 2)
539
+ )
540
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
541
+
542
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
543
+ self.config._attn_implementation, eager_attention_forward
544
+ )
545
+
546
+ attn_output, attn_weights = attention_interface(
547
+ self,
548
+ query_states,
549
+ key_states,
550
+ value_states,
551
+ attention_mask,
552
+ dropout=0.0 if not self.training else self.attention_dropout,
553
+ scaling=self.scaling,
554
+ **kwargs,
555
+ )
556
+
557
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
558
+ attn_output = self.o_proj(attn_output)
559
+ return attn_output, attn_weights
560
+
561
+
562
+ class ConditionalDetrDecoderCrossAttention(nn.Module):
563
+ """
564
+ Multi-headed cross-attention for Conditional DETR decoder layers.
565
+
566
+ This attention module handles the special cross-attention logic in Conditional DETR:
567
+ - Separate content and position projections for queries and keys
568
+ - Concatenation of query sine embeddings with queries (doubling query dimension)
569
+ - Concatenation of key position embeddings with keys (doubling key dimension)
570
+ - Output dimension remains hidden_size despite doubled input dimensions
571
+ """
572
+
573
+ def __init__(
574
+ self,
575
+ config: ConditionalDetrConfig,
576
+ hidden_size: int,
577
+ num_attention_heads: int,
578
+ dropout: float | int = 0.0,
579
+ ):
580
+ super().__init__()
581
+ self.config = config
582
+ self.hidden_size = hidden_size
583
+ self.num_attention_heads = num_attention_heads
584
+ self.head_dim = hidden_size // num_attention_heads
585
+ self.attention_dropout = dropout
586
+ self.is_causal = False
587
+
588
+ # Content and position projections
589
+ self.q_content_proj = nn.Linear(hidden_size, hidden_size)
590
+ self.q_pos_proj = nn.Linear(hidden_size, hidden_size)
591
+ self.k_content_proj = nn.Linear(hidden_size, hidden_size)
592
+ self.k_pos_proj = nn.Linear(hidden_size, hidden_size)
593
+ self.v_proj = nn.Linear(hidden_size, hidden_size)
594
+ self.q_pos_sine_proj = nn.Linear(hidden_size, hidden_size)
595
+
596
+ # Output projection: input is hidden_size * 2 (from concatenated q/k), output is hidden_size
597
+ self.o_proj = nn.Linear(hidden_size, hidden_size)
598
+
599
+ # Compute scaling for expanded head_dim (q and k have doubled dimensions after concatenation)
600
+ # This matches the original Conditional DETR implementation where embed_dim * 2 is used
601
+ expanded_head_dim = (hidden_size * 2) // num_attention_heads
602
+ self.scaling = expanded_head_dim**-0.5
603
+
604
+ def forward(
605
+ self,
606
+ hidden_states: torch.Tensor,
607
+ encoder_hidden_states: torch.Tensor,
608
+ query_sine_embed: torch.Tensor,
609
+ encoder_position_embeddings: torch.Tensor,
610
+ query_position_embeddings: torch.Tensor | None = None,
611
+ attention_mask: torch.Tensor | None = None,
612
+ **kwargs: Unpack[TransformersKwargs],
613
+ ) -> tuple[torch.Tensor, torch.Tensor]:
614
+ """
615
+ Args:
616
+ hidden_states (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`):
617
+ Decoder hidden states (queries).
618
+ encoder_hidden_states (`torch.Tensor` of shape `(batch_size, encoder_seq_len, hidden_size)`):
619
+ Encoder output hidden states (keys and values).
620
+ query_sine_embed (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`):
621
+ Sine position embeddings for queries. **Concatenated** (not added) with query content,
622
+ doubling the query dimension.
623
+ encoder_position_embeddings (`torch.Tensor` of shape `(batch_size, encoder_seq_len, hidden_size)`):
624
+ Position embeddings for keys. **Concatenated** (not added) with key content, doubling the key dimension.
625
+ query_position_embeddings (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*):
626
+ Additional position embeddings. When provided (first layer only), **added** to query content
627
+ before concatenation with `query_sine_embed`. Also causes `encoder_position_embeddings` to be
628
+ added to key content before concatenation.
629
+ attention_mask (`torch.Tensor` of shape `(batch_size, 1, num_queries, encoder_seq_len)`, *optional*):
630
+ Attention mask to avoid attending to padding tokens.
631
+ """
632
+ query_input_shape = hidden_states.shape[:-1]
633
+ kv_input_shape = encoder_hidden_states.shape[:-1]
634
+ query_hidden_shape = (*query_input_shape, self.num_attention_heads, self.head_dim)
635
+ kv_hidden_shape = (*kv_input_shape, self.num_attention_heads, self.head_dim)
636
+
637
+ # Apply content and position projections
638
+ query_input = self.q_content_proj(hidden_states)
639
+ key_input = self.k_content_proj(encoder_hidden_states)
640
+ value_states = self.v_proj(encoder_hidden_states)
641
+ key_pos = self.k_pos_proj(encoder_position_embeddings)
642
+
643
+ # Combine content and position embeddings
644
+ if query_position_embeddings is not None:
645
+ query_input = query_input + self.q_pos_proj(query_position_embeddings)
646
+ key_input = key_input + key_pos
647
+
648
+ # Reshape and concatenate position embeddings (doubling head_dim)
649
+ query_input = query_input.view(query_hidden_shape)
650
+ key_input = key_input.view(kv_hidden_shape)
651
+ query_sine_embed = self.q_pos_sine_proj(query_sine_embed).view(query_hidden_shape)
652
+ key_pos = key_pos.view(kv_hidden_shape)
653
+
654
+ query_states = torch.cat([query_input, query_sine_embed], dim=-1).view(*query_input_shape, -1)
655
+ key_states = torch.cat([key_input, key_pos], dim=-1).view(*kv_input_shape, -1)
656
+
657
+ # Reshape for attention computation
658
+ expanded_head_dim = query_states.shape[-1] // self.num_attention_heads
659
+ query_states = query_states.view(*query_input_shape, self.num_attention_heads, expanded_head_dim).transpose(
660
+ 1, 2
661
+ )
662
+ key_states = key_states.view(*kv_input_shape, self.num_attention_heads, expanded_head_dim).transpose(1, 2)
663
+ value_states = value_states.view(kv_hidden_shape).transpose(1, 2)
664
+
665
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
666
+ self.config._attn_implementation, eager_attention_forward
667
+ )
668
+
669
+ attn_output, attn_weights = attention_interface(
670
+ self,
671
+ query_states,
672
+ key_states,
673
+ value_states,
674
+ attention_mask,
675
+ dropout=0.0 if not self.training else self.attention_dropout,
676
+ scaling=self.scaling,
677
+ **kwargs,
678
+ )
679
+
680
+ attn_output = attn_output.reshape(*query_input_shape, -1).contiguous()
681
+ attn_output = self.o_proj(attn_output)
682
+ return attn_output, attn_weights
683
+
684
+
685
+ class ConditionalDetrMLP(nn.Module):
686
+ def __init__(self, config: ConditionalDetrConfig, hidden_size: int, intermediate_size: int):
687
+ super().__init__()
688
+ self.fc1 = nn.Linear(hidden_size, intermediate_size)
689
+ self.fc2 = nn.Linear(intermediate_size, hidden_size)
690
+ self.activation_fn = ACT2FN[config.activation_function]
691
+ self.activation_dropout = config.activation_dropout
692
+ self.dropout = config.dropout
693
+
694
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
695
+ hidden_states = self.activation_fn(self.fc1(hidden_states))
696
+ hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training)
697
+ hidden_states = self.fc2(hidden_states)
698
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
699
+ return hidden_states
700
+
701
+
702
+ class ConditionalDetrEncoderLayer(GradientCheckpointingLayer):
703
+ def __init__(self, config: ConditionalDetrConfig):
704
+ super().__init__()
705
+ self.hidden_size = config.d_model
706
+ self.self_attn = ConditionalDetrSelfAttention(
707
+ config=config,
708
+ hidden_size=self.hidden_size,
709
+ num_attention_heads=config.encoder_attention_heads,
710
+ dropout=config.attention_dropout,
711
+ )
712
+ self.self_attn_layer_norm = nn.LayerNorm(self.hidden_size)
713
+ self.dropout = config.dropout
714
+ self.mlp = ConditionalDetrMLP(config, self.hidden_size, config.encoder_ffn_dim)
715
+ self.final_layer_norm = nn.LayerNorm(self.hidden_size)
716
+
717
+ def forward(
718
+ self,
719
+ hidden_states: torch.Tensor,
720
+ attention_mask: torch.Tensor,
721
+ spatial_position_embeddings: torch.Tensor | None = None,
722
+ **kwargs: Unpack[TransformersKwargs],
723
+ ) -> torch.Tensor:
724
+ """
725
+ Args:
726
+ hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, hidden_size)`
727
+ attention_mask (`torch.FloatTensor`): attention mask of size
728
+ `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative
729
+ values.
730
+ spatial_position_embeddings (`torch.FloatTensor`, *optional*):
731
+ Spatial position embeddings (2D positional encodings of image locations), to be added to both
732
+ the queries and keys in self-attention (but not to values).
733
+ """
734
+ residual = hidden_states
735
+ hidden_states, _ = self.self_attn(
736
+ hidden_states=hidden_states,
737
+ attention_mask=attention_mask,
738
+ position_embeddings=spatial_position_embeddings,
739
+ **kwargs,
740
+ )
741
+
742
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
743
+ hidden_states = residual + hidden_states
744
+ hidden_states = self.self_attn_layer_norm(hidden_states)
745
+
746
+ residual = hidden_states
747
+ hidden_states = self.mlp(hidden_states)
748
+ hidden_states = residual + hidden_states
749
+ hidden_states = self.final_layer_norm(hidden_states)
750
+
751
+ if self.training:
752
+ if not torch.isfinite(hidden_states).all():
753
+ clamp_value = torch.finfo(hidden_states.dtype).max - 1000
754
+ hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value)
755
+
756
+ return hidden_states
757
+
758
+
759
+ class ConditionalDetrDecoderLayer(GradientCheckpointingLayer):
760
+ def __init__(self, config: ConditionalDetrConfig):
761
+ super().__init__()
762
+ self.hidden_size = config.d_model
763
+ self.self_attn = ConditionalDetrDecoderSelfAttention(
764
+ config=config,
765
+ hidden_size=self.hidden_size,
766
+ num_attention_heads=config.decoder_attention_heads,
767
+ dropout=config.attention_dropout,
768
+ )
769
+ self.dropout = config.dropout
770
+
771
+ self.self_attn_layer_norm = nn.LayerNorm(self.hidden_size)
772
+ self.encoder_attn = ConditionalDetrDecoderCrossAttention(
773
+ config=config,
774
+ hidden_size=self.hidden_size,
775
+ num_attention_heads=config.decoder_attention_heads,
776
+ dropout=config.attention_dropout,
777
+ )
778
+ self.encoder_attn_layer_norm = nn.LayerNorm(self.hidden_size)
779
+ self.mlp = ConditionalDetrMLP(config, self.hidden_size, config.decoder_ffn_dim)
780
+ self.final_layer_norm = nn.LayerNorm(self.hidden_size)
781
+
782
+ def forward(
783
+ self,
784
+ hidden_states: torch.Tensor,
785
+ attention_mask: torch.Tensor | None = None,
786
+ spatial_position_embeddings: torch.Tensor | None = None,
787
+ query_position_embeddings: torch.Tensor | None = None,
788
+ query_sine_embed: torch.Tensor | None = None,
789
+ encoder_hidden_states: torch.Tensor | None = None,
790
+ encoder_attention_mask: torch.Tensor | None = None,
791
+ is_first: bool | None = False,
792
+ **kwargs: Unpack[TransformersKwargs],
793
+ ) -> torch.Tensor:
794
+ """
795
+ Args:
796
+ hidden_states (`torch.FloatTensor`): input to the layer of shape `(seq_len, batch, embed_dim)`
797
+ attention_mask (`torch.FloatTensor`): attention mask of size
798
+ `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative
799
+ values.
800
+ spatial_position_embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
801
+ Spatial position embeddings (2D positional encodings) that are added to the queries and keys in each self-attention layer.
802
+ query_position_embeddings (`torch.FloatTensor`, *optional*):
803
+ object_queries that are added to the queries and keys
804
+ in the self-attention layer.
805
+ encoder_hidden_states (`torch.FloatTensor`):
806
+ cross attention input to the layer of shape `(seq_len, batch, embed_dim)`
807
+ encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size
808
+ `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative
809
+ values.
810
+ output_attentions (`bool`, *optional*):
811
+ Whether or not to return the attentions tensors of all attention layers. See `attentions` under
812
+ returned tensors for more detail.
813
+ """
814
+ residual = hidden_states
815
+
816
+ hidden_states, _ = self.self_attn(
817
+ hidden_states=hidden_states,
818
+ query_position_embeddings=query_position_embeddings,
819
+ attention_mask=attention_mask,
820
+ **kwargs,
821
+ )
822
+
823
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
824
+ hidden_states = residual + hidden_states
825
+ hidden_states = self.self_attn_layer_norm(hidden_states)
826
+
827
+ if encoder_hidden_states is not None:
828
+ residual = hidden_states
829
+
830
+ hidden_states, _ = self.encoder_attn(
831
+ hidden_states=hidden_states,
832
+ encoder_hidden_states=encoder_hidden_states,
833
+ attention_mask=encoder_attention_mask,
834
+ query_sine_embed=query_sine_embed,
835
+ encoder_position_embeddings=spatial_position_embeddings,
836
+ # Only pass query_position_embeddings for the first layer
837
+ query_position_embeddings=query_position_embeddings if is_first else None,
838
+ **kwargs,
839
+ )
840
+
841
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
842
+ hidden_states = residual + hidden_states
843
+ hidden_states = self.encoder_attn_layer_norm(hidden_states)
844
+
845
+ # Fully Connected
846
+ residual = hidden_states
847
+ hidden_states = self.mlp(hidden_states)
848
+ hidden_states = residual + hidden_states
849
+ hidden_states = self.final_layer_norm(hidden_states)
850
+
851
+ return hidden_states
852
+
853
+
854
+ class ConditionalDetrMLPPredictionHead(nn.Module):
855
+ """
856
+ Very simple multi-layer perceptron (MLP, also called FFN), used to predict the normalized center coordinates,
857
+ height and width of a bounding box w.r.t. an image.
858
+
859
+ """
860
+
861
+ def __init__(self, input_dim, hidden_dim, output_dim, num_layers):
862
+ super().__init__()
863
+ self.num_layers = num_layers
864
+ h = [hidden_dim] * (num_layers - 1)
865
+ self.layers = nn.ModuleList(nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim]))
866
+
867
+ def forward(self, x):
868
+ for i, layer in enumerate(self.layers):
869
+ x = nn.functional.relu(layer(x)) if i < self.num_layers - 1 else layer(x)
870
+ return x
871
+
872
+
873
+ class ConditionalDetrConvBlock(nn.Module):
874
+ """Basic conv block: Conv3x3 -> GroupNorm -> Activation."""
875
+
876
+ def __init__(self, in_channels: int, out_channels: int, activation: str = "relu"):
877
+ super().__init__()
878
+ self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1)
879
+ self.norm = nn.GroupNorm(min(8, out_channels), out_channels)
880
+ self.activation = ACT2FN[activation]
881
+
882
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
883
+ return self.activation(self.norm(self.conv(x)))
884
+
885
+
886
+ class ConditionalDetrFPNFusionStage(nn.Module):
887
+ """Single FPN fusion stage combining low-resolution features with high-resolution FPN features."""
888
+
889
+ def __init__(self, fpn_channels: int, current_channels: int, output_channels: int, activation: str = "relu"):
890
+ super().__init__()
891
+ self.fpn_adapter = nn.Conv2d(fpn_channels, current_channels, kernel_size=1)
892
+ self.refine = ConditionalDetrConvBlock(current_channels, output_channels, activation)
893
+
894
+ def forward(self, features: torch.Tensor, fpn_features: torch.Tensor) -> torch.Tensor:
895
+ """
896
+ Args:
897
+ features: Current features to upsample, shape (B*Q, current_channels, H_in, W_in)
898
+ fpn_features: FPN features at target resolution, shape (B*Q, fpn_channels, H_out, W_out)
899
+
900
+ Returns:
901
+ Fused and refined features, shape (B*Q, output_channels, H_out, W_out)
902
+ """
903
+ fpn_features = self.fpn_adapter(fpn_features)
904
+ features = nn.functional.interpolate(features, size=fpn_features.shape[-2:], mode="nearest")
905
+ return self.refine(fpn_features + features)
906
+
907
+
908
+ class ConditionalDetrMaskHeadSmallConv(nn.Module):
909
+ """
910
+ Segmentation mask head that generates per-query masks using FPN-based progressive upsampling.
911
+
912
+ Combines attention maps (spatial localization) with encoder features (semantics) and progressively
913
+ upsamples through multiple scales, fusing with FPN features for high-resolution detail.
914
+ """
915
+
916
+ def __init__(
917
+ self,
918
+ input_channels: int,
919
+ fpn_channels: list[int],
920
+ hidden_size: int,
921
+ activation_function: str = "relu",
922
+ ):
923
+ super().__init__()
924
+ if input_channels % 8 != 0:
925
+ raise ValueError(f"input_channels must be divisible by 8, got {input_channels}")
926
+
927
+ self.conv1 = ConditionalDetrConvBlock(input_channels, input_channels, activation_function)
928
+ self.conv2 = ConditionalDetrConvBlock(input_channels, hidden_size // 2, activation_function)
929
+
930
+ # Progressive channel reduction: /2 -> /4 -> /8 -> /16
931
+ self.fpn_stages = nn.ModuleList(
932
+ [
933
+ ConditionalDetrFPNFusionStage(
934
+ fpn_channels[0], hidden_size // 2, hidden_size // 4, activation_function
935
+ ),
936
+ ConditionalDetrFPNFusionStage(
937
+ fpn_channels[1], hidden_size // 4, hidden_size // 8, activation_function
938
+ ),
939
+ ConditionalDetrFPNFusionStage(
940
+ fpn_channels[2], hidden_size // 8, hidden_size // 16, activation_function
941
+ ),
942
+ ]
943
+ )
944
+
945
+ self.output_conv = nn.Conv2d(hidden_size // 16, 1, kernel_size=3, padding=1)
946
+
947
+ def forward(
948
+ self,
949
+ features: torch.Tensor,
950
+ attention_masks: torch.Tensor,
951
+ fpn_features: list[torch.Tensor],
952
+ ) -> torch.Tensor:
953
+ """
954
+ Args:
955
+ features: Encoder output features, shape (batch_size, hidden_size, H, W)
956
+ attention_masks: Cross-attention maps from decoder, shape (batch_size, num_queries, num_heads, H, W)
957
+ fpn_features: List of 3 FPN features from low to high resolution, each (batch_size, C, H, W)
958
+
959
+ Returns:
960
+ Predicted masks, shape (batch_size * num_queries, 1, output_H, output_W)
961
+ """
962
+ num_queries = attention_masks.shape[1]
963
+
964
+ # Expand to (batch_size * num_queries) dimension
965
+ features = features.unsqueeze(1).expand(-1, num_queries, -1, -1, -1).flatten(0, 1)
966
+ attention_masks = attention_masks.flatten(0, 1)
967
+ fpn_features = [
968
+ fpn_feat.unsqueeze(1).expand(-1, num_queries, -1, -1, -1).flatten(0, 1) for fpn_feat in fpn_features
969
+ ]
970
+
971
+ hidden_states = torch.cat([features, attention_masks], dim=1)
972
+ hidden_states = self.conv1(hidden_states)
973
+ hidden_states = self.conv2(hidden_states)
974
+
975
+ for fpn_stage, fpn_feat in zip(self.fpn_stages, fpn_features):
976
+ hidden_states = fpn_stage(hidden_states, fpn_feat)
977
+
978
+ return self.output_conv(hidden_states)
979
+
980
+
981
+ class ConditionalDetrMHAttentionMap(nn.Module):
982
+ """This is a 2D attention module, which only returns the attention softmax (no multiplication by value)"""
983
+
984
+ def __init__(
985
+ self,
986
+ hidden_size: int,
987
+ num_attention_heads: int,
988
+ dropout: float = 0.0,
989
+ bias: bool = True,
990
+ ):
991
+ super().__init__()
992
+ self.head_dim = hidden_size // num_attention_heads
993
+ self.scaling = self.head_dim**-0.5
994
+ self.attention_dropout = dropout
995
+
996
+ self.q_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
997
+ self.k_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
998
+
999
+ def forward(
1000
+ self, query_states: torch.Tensor, key_states: torch.Tensor, attention_mask: torch.Tensor | None = None
1001
+ ):
1002
+ query_hidden_shape = (*query_states.shape[:-1], -1, self.head_dim)
1003
+ key_hidden_shape = (key_states.shape[0], -1, self.head_dim, *key_states.shape[-2:])
1004
+
1005
+ query_states = self.q_proj(query_states).view(query_hidden_shape)
1006
+ key_states = nn.functional.conv2d(
1007
+ key_states, self.k_proj.weight.unsqueeze(-1).unsqueeze(-1), self.k_proj.bias
1008
+ ).view(key_hidden_shape)
1009
+
1010
+ batch_size, num_queries, num_heads, head_dim = query_states.shape
1011
+ _, _, _, height, width = key_states.shape
1012
+ query_shape = (batch_size * num_heads, num_queries, head_dim)
1013
+ key_shape = (batch_size * num_heads, height * width, head_dim)
1014
+ attn_weights_shape = (batch_size, num_heads, num_queries, height, width)
1015
+
1016
+ query = query_states.transpose(1, 2).contiguous().view(query_shape)
1017
+ key = key_states.permute(0, 1, 3, 4, 2).contiguous().view(key_shape)
1018
+
1019
+ attn_weights = (
1020
+ (torch.matmul(query * self.scaling, key.transpose(1, 2))).view(attn_weights_shape).transpose(1, 2)
1021
+ )
1022
+
1023
+ if attention_mask is not None:
1024
+ attn_weights = attn_weights + attention_mask
1025
+
1026
+ attn_weights = nn.functional.softmax(attn_weights.flatten(2), dim=-1).view(attn_weights.size())
1027
+ attn_weights = nn.functional.dropout(attn_weights, p=self.attention_dropout, training=self.training)
1028
+
1029
+ return attn_weights
1030
+
1031
+
1032
+ @auto_docstring
1033
+ class ConditionalDetrPreTrainedModel(PreTrainedModel):
1034
+ config: ConditionalDetrConfig
1035
+ base_model_prefix = "model"
1036
+ main_input_name = "pixel_values"
1037
+ input_modalities = ("image",)
1038
+ _no_split_modules = [r"ConditionalDetrConvEncoder", r"ConditionalDetrEncoderLayer", r"ConditionalDetrDecoderLayer"]
1039
+ supports_gradient_checkpointing = True
1040
+ _supports_sdpa = True
1041
+ _supports_flash_attn = True
1042
+ _supports_attention_backend = True
1043
+ _supports_flex_attn = True # Uses create_bidirectional_masks for attention masking
1044
+ _keys_to_ignore_on_load_unexpected = [
1045
+ r"detr\.model\.backbone\.model\.layer\d+\.0\.downsample\.1\.num_batches_tracked"
1046
+ ]
1047
+
1048
+ @torch.no_grad()
1049
+ def _init_weights(self, module):
1050
+ std = self.config.init_std
1051
+ xavier_std = self.config.init_xavier_std
1052
+
1053
+ if isinstance(module, ConditionalDetrMaskHeadSmallConv):
1054
+ # ConditionalDetrMaskHeadSmallConv uses kaiming initialization for all its Conv2d layers
1055
+ for m in module.modules():
1056
+ if isinstance(m, nn.Conv2d):
1057
+ init.kaiming_uniform_(m.weight, a=1)
1058
+ if m.bias is not None:
1059
+ init.constant_(m.bias, 0)
1060
+ elif isinstance(module, ConditionalDetrMHAttentionMap):
1061
+ init.zeros_(module.k_proj.bias)
1062
+ init.zeros_(module.q_proj.bias)
1063
+ init.xavier_uniform_(module.k_proj.weight, gain=xavier_std)
1064
+ init.xavier_uniform_(module.q_proj.weight, gain=xavier_std)
1065
+ elif isinstance(module, ConditionalDetrLearnedPositionEmbedding):
1066
+ init.uniform_(module.row_embeddings.weight)
1067
+ init.uniform_(module.column_embeddings.weight)
1068
+ elif isinstance(module, (nn.Linear, nn.Conv2d)):
1069
+ init.normal_(module.weight, mean=0.0, std=std)
1070
+ if module.bias is not None:
1071
+ init.zeros_(module.bias)
1072
+ elif isinstance(module, nn.Embedding):
1073
+ init.normal_(module.weight, mean=0.0, std=std)
1074
+ # Here we need the check explicitly, as we slice the weight in the `zeros_` call, so it looses the flag
1075
+ if module.padding_idx is not None and not getattr(module.weight, "_is_hf_initialized", False):
1076
+ init.zeros_(module.weight[module.padding_idx])
1077
+ elif isinstance(module, (nn.LayerNorm, nn.GroupNorm)):
1078
+ init.ones_(module.weight)
1079
+ init.zeros_(module.bias)
1080
+
1081
+
1082
+ class ConditionalDetrEncoder(ConditionalDetrPreTrainedModel):
1083
+ """
1084
+ Transformer encoder that processes a flattened feature map from a vision backbone, composed of a stack of
1085
+ [`ConditionalDetrEncoderLayer`] modules.
1086
+
1087
+ Args:
1088
+ config (`ConditionalDetrConfig`): Model configuration object.
1089
+ """
1090
+
1091
+ _can_record_outputs = {"hidden_states": ConditionalDetrEncoderLayer, "attentions": ConditionalDetrSelfAttention}
1092
+
1093
+ def __init__(self, config: ConditionalDetrConfig):
1094
+ super().__init__(config)
1095
+
1096
+ self.dropout = config.dropout
1097
+ self.layers = nn.ModuleList([ConditionalDetrEncoderLayer(config) for _ in range(config.encoder_layers)])
1098
+
1099
+ # Initialize weights and apply final processing
1100
+ self.post_init()
1101
+
1102
+ @merge_with_config_defaults
1103
+ @capture_outputs
1104
+ def forward(
1105
+ self,
1106
+ inputs_embeds=None,
1107
+ attention_mask=None,
1108
+ spatial_position_embeddings=None,
1109
+ **kwargs: Unpack[TransformersKwargs],
1110
+ ) -> BaseModelOutput:
1111
+ r"""
1112
+ Args:
1113
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
1114
+ Flattened feature map (output of the backbone + projection layer) that is passed to the encoder.
1115
+ attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
1116
+ Mask to avoid performing attention on padding pixel features. Mask values selected in `[0, 1]`:
1117
+
1118
+ - 1 for pixel features that are real (i.e. **not masked**),
1119
+ - 0 for pixel features that are padding (i.e. **masked**).
1120
+
1121
+ [What are attention masks?](../glossary#attention-mask)
1122
+ spatial_position_embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
1123
+ Spatial position embeddings (2D positional encodings) that are added to the queries and keys in each self-attention layer.
1124
+ """
1125
+ hidden_states = inputs_embeds
1126
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
1127
+
1128
+ attention_mask = create_bidirectional_mask(
1129
+ config=self.config,
1130
+ inputs_embeds=inputs_embeds,
1131
+ attention_mask=attention_mask,
1132
+ )
1133
+
1134
+ for encoder_layer in self.layers:
1135
+ # we add spatial_position_embeddings as extra input to the encoder_layer
1136
+ hidden_states = encoder_layer(
1137
+ hidden_states, attention_mask, spatial_position_embeddings=spatial_position_embeddings, **kwargs
1138
+ )
1139
+
1140
+ return BaseModelOutput(last_hidden_state=hidden_states)
1141
+
1142
+
1143
+ # function to generate sine positional embedding for 2d coordinates
1144
+ def gen_sine_position_embeddings(pos_tensor, d_model):
1145
+ scale = 2 * math.pi
1146
+ dim = d_model // 2
1147
+ dim_t = torch.arange(dim, dtype=torch.float32, device=pos_tensor.device)
1148
+ dim_t = 10000 ** (2 * torch.div(dim_t, 2, rounding_mode="floor") / dim)
1149
+ x_embed = pos_tensor[:, :, 0] * scale
1150
+ y_embed = pos_tensor[:, :, 1] * scale
1151
+ pos_x = x_embed[:, :, None] / dim_t
1152
+ pos_y = y_embed[:, :, None] / dim_t
1153
+ pos_x = torch.stack((pos_x[:, :, 0::2].sin(), pos_x[:, :, 1::2].cos()), dim=3).flatten(2)
1154
+ pos_y = torch.stack((pos_y[:, :, 0::2].sin(), pos_y[:, :, 1::2].cos()), dim=3).flatten(2)
1155
+ pos = torch.cat((pos_y, pos_x), dim=2)
1156
+ return pos.to(pos_tensor.dtype)
1157
+
1158
+
1159
+ class ConditionalDetrDecoder(ConditionalDetrPreTrainedModel):
1160
+ """
1161
+ Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`ConditionalDetrDecoderLayer`].
1162
+
1163
+ The decoder updates the query embeddings through multiple self-attention and cross-attention layers.
1164
+
1165
+ Some small tweaks for Conditional DETR:
1166
+
1167
+ - object_queries and query_position_embeddings are added to the forward pass.
1168
+ - if self.config.auxiliary_loss is set to True, also returns a stack of activations from all decoding layers.
1169
+
1170
+ Args:
1171
+ config: ConditionalDetrConfig
1172
+ """
1173
+
1174
+ _can_record_outputs = {
1175
+ "hidden_states": ConditionalDetrDecoderLayer,
1176
+ "attentions": OutputRecorder(ConditionalDetrDecoderSelfAttention, layer_name="self_attn", index=1),
1177
+ "cross_attentions": OutputRecorder(ConditionalDetrDecoderCrossAttention, layer_name="encoder_attn", index=1),
1178
+ }
1179
+
1180
+ def __init__(self, config: ConditionalDetrConfig):
1181
+ super().__init__(config)
1182
+ self.hidden_size = config.d_model
1183
+
1184
+ self.dropout = config.dropout
1185
+ self.layerdrop = config.decoder_layerdrop
1186
+
1187
+ self.layers = nn.ModuleList([ConditionalDetrDecoderLayer(config) for _ in range(config.decoder_layers)])
1188
+ # in Conditional DETR, the decoder uses layernorm after the last decoder layer output
1189
+ self.layernorm = nn.LayerNorm(config.d_model)
1190
+
1191
+ # query_scale is the FFN applied on f to generate transformation T
1192
+ self.query_scale = ConditionalDetrMLPPredictionHead(self.hidden_size, self.hidden_size, self.hidden_size, 2)
1193
+ self.ref_point_head = ConditionalDetrMLPPredictionHead(self.hidden_size, self.hidden_size, 2, 2)
1194
+ for layer_id in range(config.decoder_layers - 1):
1195
+ # Set q_pos_proj to None for layers after the first (only first layer uses query position embeddings)
1196
+ self.layers[layer_id + 1].encoder_attn.q_pos_proj = None
1197
+
1198
+ # Initialize weights and apply final processing
1199
+ self.post_init()
1200
+
1201
+ @merge_with_config_defaults
1202
+ @capture_outputs
1203
+ def forward(
1204
+ self,
1205
+ inputs_embeds=None,
1206
+ attention_mask=None,
1207
+ encoder_hidden_states=None,
1208
+ encoder_attention_mask=None,
1209
+ spatial_position_embeddings=None,
1210
+ object_queries_position_embeddings=None,
1211
+ **kwargs: Unpack[TransformersKwargs],
1212
+ ) -> ConditionalDetrDecoderOutput:
1213
+ r"""
1214
+ Args:
1215
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
1216
+ The query embeddings that are passed into the decoder.
1217
+
1218
+ attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
1219
+ Mask to avoid performing attention on certain queries. Mask values selected in `[0, 1]`:
1220
+
1221
+ - 1 for queries that are **not masked**,
1222
+ - 0 for queries that are **masked**.
1223
+
1224
+ [What are attention masks?](../glossary#attention-mask)
1225
+ encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*):
1226
+ Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention
1227
+ of the decoder.
1228
+ encoder_attention_mask (`torch.LongTensor` of shape `(batch_size, encoder_sequence_length)`, *optional*):
1229
+ Mask to avoid performing cross-attention on padding pixel_values of the encoder. Mask values selected
1230
+ in `[0, 1]`:
1231
+
1232
+ - 1 for pixels that are real (i.e. **not masked**),
1233
+ - 0 for pixels that are padding (i.e. **masked**).
1234
+
1235
+ spatial_position_embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
1236
+ Spatial position embeddings that are added to the queries and keys in each cross-attention layer.
1237
+ object_queries_position_embeddings (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`):
1238
+ , *optional*): Position embeddings that are added to the queries and keys in each self-attention layer.
1239
+ """
1240
+ if inputs_embeds is not None:
1241
+ hidden_states = inputs_embeds
1242
+
1243
+ # expand encoder attention mask
1244
+ if encoder_hidden_states is not None and encoder_attention_mask is not None:
1245
+ # [batch_size, seq_len] -> [batch_size, 1, target_seq_len, source_seq_len]
1246
+ encoder_attention_mask = create_bidirectional_mask(
1247
+ self.config,
1248
+ inputs_embeds,
1249
+ encoder_attention_mask,
1250
+ )
1251
+
1252
+ # optional intermediate hidden states
1253
+ intermediate = () if self.config.auxiliary_loss else None
1254
+
1255
+ reference_points_before_sigmoid = self.ref_point_head(
1256
+ object_queries_position_embeddings
1257
+ ) # [num_queries, batch_size, 2]
1258
+ reference_points = reference_points_before_sigmoid.sigmoid().transpose(0, 1)
1259
+ obj_center = reference_points[..., :2].transpose(0, 1)
1260
+ # get sine embedding for the query vector
1261
+ query_sine_embed_before_transformation = gen_sine_position_embeddings(obj_center, self.config.d_model)
1262
+
1263
+ for idx, decoder_layer in enumerate(self.layers):
1264
+ if self.training:
1265
+ dropout_probability = torch.rand([])
1266
+ if dropout_probability < self.layerdrop:
1267
+ continue
1268
+ if idx == 0:
1269
+ pos_transformation = 1
1270
+ else:
1271
+ pos_transformation = self.query_scale(hidden_states)
1272
+ # apply transformation
1273
+ query_sine_embed = query_sine_embed_before_transformation * pos_transformation
1274
+
1275
+ hidden_states = decoder_layer(
1276
+ hidden_states,
1277
+ None,
1278
+ spatial_position_embeddings,
1279
+ object_queries_position_embeddings,
1280
+ query_sine_embed,
1281
+ encoder_hidden_states, # as a positional argument for gradient checkpointing
1282
+ encoder_attention_mask=encoder_attention_mask,
1283
+ is_first=(idx == 0),
1284
+ **kwargs,
1285
+ )
1286
+
1287
+ if self.config.auxiliary_loss:
1288
+ hidden_states = self.layernorm(hidden_states)
1289
+ intermediate += (hidden_states,)
1290
+
1291
+ # finally, apply layernorm
1292
+ hidden_states = self.layernorm(hidden_states)
1293
+
1294
+ # stack intermediate decoder activations
1295
+ if self.config.auxiliary_loss:
1296
+ intermediate = torch.stack(intermediate)
1297
+
1298
+ return ConditionalDetrDecoderOutput(
1299
+ last_hidden_state=hidden_states,
1300
+ intermediate_hidden_states=intermediate,
1301
+ reference_points=reference_points,
1302
+ )
1303
+
1304
+
1305
+ @auto_docstring(
1306
+ custom_intro="""
1307
+ The bare CONDITIONAL_DETR Model (consisting of a backbone and encoder-decoder Transformer) outputting raw hidden-states without
1308
+ any specific head on top.
1309
+ """
1310
+ )
1311
+ class ConditionalDetrModel(ConditionalDetrPreTrainedModel):
1312
+ def __init__(self, config: ConditionalDetrConfig):
1313
+ super().__init__(config)
1314
+
1315
+ self.backbone = ConditionalDetrConvEncoder(config)
1316
+
1317
+ if config.position_embedding_type == "sine":
1318
+ self.position_embedding = ConditionalDetrSinePositionEmbedding(config.d_model // 2, normalize=True)
1319
+ elif config.position_embedding_type == "learned":
1320
+ self.position_embedding = ConditionalDetrLearnedPositionEmbedding(config.d_model // 2)
1321
+ else:
1322
+ raise ValueError(f"Not supported {config.position_embedding_type}")
1323
+ self.query_position_embeddings = nn.Embedding(config.num_queries, config.d_model)
1324
+ self.input_projection = nn.Conv2d(self.backbone.intermediate_channel_sizes[-1], config.d_model, kernel_size=1)
1325
+
1326
+ self.encoder = ConditionalDetrEncoder(config)
1327
+ self.decoder = ConditionalDetrDecoder(config)
1328
+
1329
+ # Initialize weights and apply final processing
1330
+ self.post_init()
1331
+
1332
+ def freeze_backbone(self):
1333
+ for _, param in self.backbone.model.named_parameters():
1334
+ param.requires_grad_(False)
1335
+
1336
+ def unfreeze_backbone(self):
1337
+ for _, param in self.backbone.model.named_parameters():
1338
+ param.requires_grad_(True)
1339
+
1340
+ @auto_docstring
1341
+ @can_return_tuple
1342
+ def forward(
1343
+ self,
1344
+ pixel_values: torch.FloatTensor,
1345
+ pixel_mask: torch.LongTensor | None = None,
1346
+ decoder_attention_mask: torch.LongTensor | None = None,
1347
+ encoder_outputs: torch.FloatTensor | None = None,
1348
+ inputs_embeds: torch.FloatTensor | None = None,
1349
+ decoder_inputs_embeds: torch.FloatTensor | None = None,
1350
+ **kwargs: Unpack[TransformersKwargs],
1351
+ ) -> ConditionalDetrModelOutput:
1352
+ r"""
1353
+ decoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, num_queries)`, *optional*):
1354
+ Not used by default. Can be used to mask object queries.
1355
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
1356
+ Optionally, instead of passing the flattened feature map (output of the backbone + projection layer), you
1357
+ can choose to directly pass a flattened representation of an image.
1358
+ decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*):
1359
+ Optionally, instead of initializing the queries with a tensor of zeros, you can choose to directly pass an
1360
+ embedded representation.
1361
+
1362
+ Examples:
1363
+
1364
+ ```python
1365
+ >>> from transformers import AutoImageProcessor, AutoModel
1366
+ >>> from PIL import Image
1367
+ >>> import requests
1368
+
1369
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
1370
+ >>> image = Image.open(requests.get(url, stream=True).raw)
1371
+
1372
+ >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/conditional-detr-resnet-50")
1373
+ >>> model = AutoModel.from_pretrained("microsoft/conditional-detr-resnet-50")
1374
+
1375
+ >>> # prepare image for the model
1376
+ >>> inputs = image_processor(images=image, return_tensors="pt")
1377
+
1378
+ >>> # forward pass
1379
+ >>> outputs = model(**inputs)
1380
+
1381
+ >>> # the last hidden states are the final query embeddings of the Transformer decoder
1382
+ >>> # these are of shape (batch_size, num_queries, hidden_size)
1383
+ >>> last_hidden_states = outputs.last_hidden_state
1384
+ >>> list(last_hidden_states.shape)
1385
+ [1, 300, 256]
1386
+ ```"""
1387
+ batch_size, num_channels, height, width = pixel_values.shape
1388
+ device = pixel_values.device
1389
+
1390
+ if pixel_mask is None:
1391
+ pixel_mask = torch.ones(((batch_size, height, width)), device=device)
1392
+
1393
+ # First, sent pixel_values + pixel_mask through Backbone to obtain the features
1394
+ # pixel_values should be of shape (batch_size, num_channels, height, width)
1395
+ # pixel_mask should be of shape (batch_size, height, width)
1396
+ features = self.backbone(pixel_values, pixel_mask)
1397
+
1398
+ # get final feature map and downsampled mask
1399
+ feature_map, mask = features[-1]
1400
+
1401
+ if mask is None:
1402
+ raise ValueError("Backbone does not return downsampled pixel mask")
1403
+
1404
+ # Second, apply 1x1 convolution to reduce the channel dimension to d_model (256 by default)
1405
+ projected_feature_map = self.input_projection(feature_map)
1406
+
1407
+ # Generate position embeddings
1408
+ spatial_position_embeddings = self.position_embedding(
1409
+ shape=feature_map.shape, device=device, dtype=pixel_values.dtype, mask=mask
1410
+ )
1411
+
1412
+ # Third, flatten the feature map of shape NxCxHxW to NxCxHW, and permute it to NxHWxC
1413
+ # In other words, turn their shape into (batch_size, sequence_length, hidden_size)
1414
+ flattened_features = projected_feature_map.flatten(2).permute(0, 2, 1)
1415
+
1416
+ flattened_mask = mask.flatten(1)
1417
+
1418
+ # Fourth, sent flattened_features + flattened_mask + spatial_position_embeddings through encoder
1419
+ # flattened_features is a Tensor of shape (batch_size, height*width, hidden_size)
1420
+ # flattened_mask is a Tensor of shape (batch_size, height*width)
1421
+ if encoder_outputs is None:
1422
+ encoder_outputs = self.encoder(
1423
+ inputs_embeds=flattened_features,
1424
+ attention_mask=flattened_mask,
1425
+ spatial_position_embeddings=spatial_position_embeddings,
1426
+ **kwargs,
1427
+ )
1428
+ # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput
1429
+ elif not isinstance(encoder_outputs, BaseModelOutput):
1430
+ encoder_outputs = BaseModelOutput(
1431
+ last_hidden_state=encoder_outputs[0],
1432
+ hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None,
1433
+ attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None,
1434
+ )
1435
+
1436
+ # Fifth, sent query embeddings through the decoder (which is conditioned on the encoder output)
1437
+ object_queries_position_embeddings = self.query_position_embeddings.weight.unsqueeze(0).repeat(
1438
+ batch_size, 1, 1
1439
+ )
1440
+ queries = torch.zeros_like(object_queries_position_embeddings)
1441
+
1442
+ # decoder outputs consists of (dec_features, dec_hidden, dec_attn)
1443
+ decoder_outputs = self.decoder(
1444
+ inputs_embeds=queries,
1445
+ attention_mask=None,
1446
+ spatial_position_embeddings=spatial_position_embeddings,
1447
+ object_queries_position_embeddings=object_queries_position_embeddings,
1448
+ encoder_hidden_states=encoder_outputs.last_hidden_state,
1449
+ encoder_attention_mask=flattened_mask,
1450
+ **kwargs,
1451
+ )
1452
+
1453
+ return ConditionalDetrModelOutput(
1454
+ last_hidden_state=decoder_outputs.last_hidden_state,
1455
+ decoder_hidden_states=decoder_outputs.hidden_states,
1456
+ decoder_attentions=decoder_outputs.attentions,
1457
+ cross_attentions=decoder_outputs.cross_attentions,
1458
+ encoder_last_hidden_state=encoder_outputs.last_hidden_state,
1459
+ encoder_hidden_states=encoder_outputs.hidden_states,
1460
+ encoder_attentions=encoder_outputs.attentions,
1461
+ intermediate_hidden_states=decoder_outputs.intermediate_hidden_states,
1462
+ reference_points=decoder_outputs.reference_points,
1463
+ )
1464
+
1465
+
1466
+ def inverse_sigmoid(x, eps=1e-5):
1467
+ x = x.clamp(min=0, max=1)
1468
+ x1 = x.clamp(min=eps)
1469
+ x2 = (1 - x).clamp(min=eps)
1470
+ return torch.log(x1 / x2)
1471
+
1472
+
1473
+ @auto_docstring(
1474
+ custom_intro="""
1475
+ CONDITIONAL_DETR Model (consisting of a backbone and encoder-decoder Transformer) with object detection heads on top, for tasks
1476
+ such as COCO detection.
1477
+ """
1478
+ )
1479
+ class ConditionalDetrForObjectDetection(ConditionalDetrPreTrainedModel):
1480
+ def __init__(self, config: ConditionalDetrConfig):
1481
+ super().__init__(config)
1482
+
1483
+ # CONDITIONAL_DETR encoder-decoder model
1484
+ self.model = ConditionalDetrModel(config)
1485
+ self.class_labels_classifier = nn.Linear(config.d_model, config.num_labels)
1486
+ self.bbox_predictor = ConditionalDetrMLPPredictionHead(
1487
+ input_dim=config.d_model, hidden_dim=config.d_model, output_dim=4, num_layers=3
1488
+ )
1489
+
1490
+ # Initialize weights and apply final processing
1491
+ self.post_init()
1492
+
1493
+ @auto_docstring
1494
+ @can_return_tuple
1495
+ def forward(
1496
+ self,
1497
+ pixel_values: torch.FloatTensor,
1498
+ pixel_mask: torch.LongTensor | None = None,
1499
+ decoder_attention_mask: torch.LongTensor | None = None,
1500
+ encoder_outputs: torch.FloatTensor | None = None,
1501
+ inputs_embeds: torch.FloatTensor | None = None,
1502
+ decoder_inputs_embeds: torch.FloatTensor | None = None,
1503
+ labels: list[dict] | None = None,
1504
+ **kwargs: Unpack[TransformersKwargs],
1505
+ ) -> ConditionalDetrObjectDetectionOutput:
1506
+ r"""
1507
+ decoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, num_queries)`, *optional*):
1508
+ Not used by default. Can be used to mask object queries.
1509
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
1510
+ Optionally, instead of passing the flattened feature map (output of the backbone + projection layer), you
1511
+ can choose to directly pass a flattened representation of an image.
1512
+ decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*):
1513
+ Optionally, instead of initializing the queries with a tensor of zeros, you can choose to directly pass an
1514
+ embedded representation.
1515
+ labels (`list[Dict]` of len `(batch_size,)`, *optional*):
1516
+ Labels for computing the bipartite matching loss. List of dicts, each dictionary containing at least the
1517
+ following 2 keys: 'class_labels' and 'boxes' (the class labels and bounding boxes of an image in the batch
1518
+ respectively). The class labels themselves should be a `torch.LongTensor` of len `(number of bounding boxes
1519
+ in the image,)` and the boxes a `torch.FloatTensor` of shape `(number of bounding boxes in the image, 4)`.
1520
+
1521
+ Examples:
1522
+
1523
+ ```python
1524
+ >>> from transformers import AutoImageProcessor, AutoModelForObjectDetection
1525
+ >>> from PIL import Image
1526
+ >>> import requests
1527
+
1528
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
1529
+ >>> image = Image.open(requests.get(url, stream=True).raw)
1530
+
1531
+ >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/conditional-detr-resnet-50")
1532
+ >>> model = AutoModelForObjectDetection.from_pretrained("microsoft/conditional-detr-resnet-50")
1533
+
1534
+ >>> inputs = image_processor(images=image, return_tensors="pt")
1535
+
1536
+ >>> outputs = model(**inputs)
1537
+
1538
+ >>> # convert outputs (bounding boxes and class logits) to Pascal VOC format (xmin, ymin, xmax, ymax)
1539
+ >>> target_sizes = torch.tensor([image.size[::-1]])
1540
+ >>> results = image_processor.post_process_object_detection(outputs, threshold=0.5, target_sizes=target_sizes)[
1541
+ ... 0
1542
+ ... ]
1543
+ >>> for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
1544
+ ... box = [round(i, 2) for i in box.tolist()]
1545
+ ... print(
1546
+ ... f"Detected {model.config.id2label[label.item()]} with confidence "
1547
+ ... f"{round(score.item(), 3)} at location {box}"
1548
+ ... )
1549
+ Detected remote with confidence 0.833 at location [38.31, 72.1, 177.63, 118.45]
1550
+ Detected cat with confidence 0.831 at location [9.2, 51.38, 321.13, 469.0]
1551
+ Detected cat with confidence 0.804 at location [340.3, 16.85, 642.93, 370.95]
1552
+ Detected remote with confidence 0.683 at location [334.48, 73.49, 366.37, 190.01]
1553
+ Detected couch with confidence 0.535 at location [0.52, 1.19, 640.35, 475.1]
1554
+ ```"""
1555
+ # First, sent images through CONDITIONAL_DETR base model to obtain encoder + decoder outputs
1556
+ outputs = self.model(
1557
+ pixel_values,
1558
+ pixel_mask=pixel_mask,
1559
+ decoder_attention_mask=decoder_attention_mask,
1560
+ encoder_outputs=encoder_outputs,
1561
+ inputs_embeds=inputs_embeds,
1562
+ decoder_inputs_embeds=decoder_inputs_embeds,
1563
+ **kwargs,
1564
+ )
1565
+
1566
+ sequence_output = outputs[0]
1567
+
1568
+ # class logits + predicted bounding boxes
1569
+ logits = self.class_labels_classifier(sequence_output)
1570
+
1571
+ reference = outputs.reference_points
1572
+ reference_before_sigmoid = inverse_sigmoid(reference).transpose(0, 1)
1573
+
1574
+ hs = sequence_output
1575
+ tmp = self.bbox_predictor(hs)
1576
+ tmp[..., :2] += reference_before_sigmoid
1577
+ pred_boxes = tmp.sigmoid()
1578
+ # pred_boxes = self.bbox_predictor(sequence_output).sigmoid()
1579
+
1580
+ loss, loss_dict, auxiliary_outputs = None, None, None
1581
+ if labels is not None:
1582
+ outputs_class, outputs_coord = None, None
1583
+ if self.config.auxiliary_loss:
1584
+ outputs_coords = []
1585
+ intermediate = outputs.intermediate_hidden_states
1586
+ outputs_class = self.class_labels_classifier(intermediate)
1587
+ for lvl in range(intermediate.shape[0]):
1588
+ tmp = self.bbox_predictor(intermediate[lvl])
1589
+ tmp[..., :2] += reference_before_sigmoid
1590
+ outputs_coord = tmp.sigmoid()
1591
+ outputs_coords.append(outputs_coord)
1592
+ outputs_coord = torch.stack(outputs_coords)
1593
+ loss, loss_dict, auxiliary_outputs = self.loss_function(
1594
+ logits, labels, self.device, pred_boxes, self.config, outputs_class, outputs_coord
1595
+ )
1596
+
1597
+ return ConditionalDetrObjectDetectionOutput(
1598
+ loss=loss,
1599
+ loss_dict=loss_dict,
1600
+ logits=logits,
1601
+ pred_boxes=pred_boxes,
1602
+ auxiliary_outputs=auxiliary_outputs,
1603
+ last_hidden_state=outputs.last_hidden_state,
1604
+ decoder_hidden_states=outputs.decoder_hidden_states,
1605
+ decoder_attentions=outputs.decoder_attentions,
1606
+ cross_attentions=outputs.cross_attentions,
1607
+ encoder_last_hidden_state=outputs.encoder_last_hidden_state,
1608
+ encoder_hidden_states=outputs.encoder_hidden_states,
1609
+ encoder_attentions=outputs.encoder_attentions,
1610
+ )
1611
+
1612
+ # taken from https://github.com/Atten4Vis/conditionalDETR/blob/master/models/conditional_detr.py
1613
+ def _set_aux_loss(self, outputs_class, outputs_coord):
1614
+ return [{"logits": a, "pred_boxes": b} for a, b in zip(outputs_class[:-1], outputs_coord[:-1])]
1615
+
1616
+
1617
+ @auto_docstring(
1618
+ custom_intro="""
1619
+ CONDITIONAL_DETR Model (consisting of a backbone and encoder-decoder Transformer) with a segmentation head on top, for tasks
1620
+ such as COCO panoptic.
1621
+ """
1622
+ )
1623
+ class ConditionalDetrForSegmentation(ConditionalDetrPreTrainedModel):
1624
+ def __init__(self, config: ConditionalDetrConfig):
1625
+ super().__init__(config)
1626
+
1627
+ # object detection model
1628
+ self.conditional_detr = ConditionalDetrForObjectDetection(config)
1629
+
1630
+ # segmentation head
1631
+ hidden_size, number_of_heads = config.d_model, config.encoder_attention_heads
1632
+ intermediate_channel_sizes = self.conditional_detr.model.backbone.intermediate_channel_sizes
1633
+
1634
+ self.mask_head = ConditionalDetrMaskHeadSmallConv(
1635
+ input_channels=hidden_size + number_of_heads,
1636
+ fpn_channels=intermediate_channel_sizes[::-1][-3:],
1637
+ hidden_size=hidden_size,
1638
+ activation_function=config.activation_function,
1639
+ )
1640
+
1641
+ self.bbox_attention = ConditionalDetrMHAttentionMap(hidden_size, number_of_heads, dropout=0.0)
1642
+ # Initialize weights and apply final processing
1643
+ self.post_init()
1644
+
1645
+ @auto_docstring
1646
+ @can_return_tuple
1647
+ def forward(
1648
+ self,
1649
+ pixel_values: torch.FloatTensor,
1650
+ pixel_mask: torch.LongTensor | None = None,
1651
+ decoder_attention_mask: torch.FloatTensor | None = None,
1652
+ encoder_outputs: torch.FloatTensor | None = None,
1653
+ inputs_embeds: torch.FloatTensor | None = None,
1654
+ decoder_inputs_embeds: torch.FloatTensor | None = None,
1655
+ labels: list[dict] | None = None,
1656
+ **kwargs: Unpack[TransformersKwargs],
1657
+ ) -> tuple[torch.FloatTensor] | ConditionalDetrSegmentationOutput:
1658
+ r"""
1659
+ decoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, num_queries)`, *optional*):
1660
+ Mask to avoid performing attention on certain object queries in the decoder. Mask values selected in `[0, 1]`:
1661
+
1662
+ - 1 for queries that are **not masked**,
1663
+ - 0 for queries that are **masked**.
1664
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
1665
+ Kept for backward compatibility, but cannot be used for segmentation, as segmentation requires
1666
+ multi-scale features from the backbone that are not available when bypassing it with inputs_embeds.
1667
+ decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*):
1668
+ Optionally, instead of initializing the queries with a tensor of zeros, you can choose to directly pass an
1669
+ embedded representation. Useful for tasks that require custom query initialization.
1670
+ labels (`list[Dict]` of len `(batch_size,)`, *optional*):
1671
+ Labels for computing the bipartite matching loss, DICE/F-1 loss and Focal loss. List of dicts, each
1672
+ dictionary containing at least the following 3 keys: 'class_labels', 'boxes' and 'masks' (the class labels,
1673
+ bounding boxes and segmentation masks of an image in the batch respectively). The class labels themselves
1674
+ should be a `torch.LongTensor` of len `(number of bounding boxes in the image,)`, the boxes a
1675
+ `torch.FloatTensor` of shape `(number of bounding boxes in the image, 4)` and the masks a
1676
+ `torch.FloatTensor` of shape `(number of bounding boxes in the image, height, width)`.
1677
+
1678
+ Examples:
1679
+
1680
+ ```python
1681
+ >>> import io
1682
+ >>> import httpx
1683
+ >>> from io import BytesIO
1684
+ >>> from PIL import Image
1685
+ >>> import torch
1686
+ >>> import numpy
1687
+
1688
+ >>> from transformers import AutoImageProcessor, ConditionalDetrForSegmentation
1689
+ >>> from transformers.image_transforms import rgb_to_id
1690
+
1691
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
1692
+ >>> with httpx.stream("GET", url) as response:
1693
+ ... image = Image.open(BytesIO(response.read()))
1694
+
1695
+ >>> image_processor = AutoImageProcessor.from_pretrained("facebook/conditional_detr-resnet-50-panoptic")
1696
+ >>> model = ConditionalDetrForSegmentation.from_pretrained("facebook/conditional_detr-resnet-50-panoptic")
1697
+
1698
+ >>> # prepare image for the model
1699
+ >>> inputs = image_processor(images=image, return_tensors="pt")
1700
+
1701
+ >>> # forward pass
1702
+ >>> outputs = model(**inputs)
1703
+
1704
+ >>> # Use the `post_process_panoptic_segmentation` method of the `image_processor` to retrieve post-processed panoptic segmentation maps
1705
+ >>> # Segmentation results are returned as a list of dictionaries
1706
+ >>> result = image_processor.post_process_panoptic_segmentation(outputs, target_sizes=[(300, 500)])
1707
+
1708
+ >>> # A tensor of shape (height, width) where each value denotes a segment id, filled with -1 if no segment is found
1709
+ >>> panoptic_seg = result[0]["segmentation"]
1710
+ >>> panoptic_seg.shape
1711
+ torch.Size([300, 500])
1712
+ >>> # Get prediction score and segment_id to class_id mapping of each segment
1713
+ >>> panoptic_segments_info = result[0]["segments_info"]
1714
+ >>> len(panoptic_segments_info)
1715
+ 5
1716
+ ```"""
1717
+
1718
+ batch_size, num_channels, height, width = pixel_values.shape
1719
+ device = pixel_values.device
1720
+
1721
+ if pixel_mask is None:
1722
+ pixel_mask = torch.ones((batch_size, height, width), device=device)
1723
+
1724
+ vision_features = self.conditional_detr.model.backbone(pixel_values, pixel_mask)
1725
+ feature_map, mask = vision_features[-1]
1726
+
1727
+ # Apply 1x1 conv to map (batch_size, C, H, W) -> (batch_size, hidden_size, H, W), then flatten to (batch_size, HW, hidden_size)
1728
+ projected_feature_map = self.conditional_detr.model.input_projection(feature_map)
1729
+ flattened_features = projected_feature_map.flatten(2).permute(0, 2, 1)
1730
+ spatial_position_embeddings = self.conditional_detr.model.position_embedding(
1731
+ shape=feature_map.shape, device=device, dtype=pixel_values.dtype, mask=mask
1732
+ )
1733
+ flattened_mask = mask.flatten(1)
1734
+
1735
+ if encoder_outputs is None:
1736
+ encoder_outputs = self.conditional_detr.model.encoder(
1737
+ inputs_embeds=flattened_features,
1738
+ attention_mask=flattened_mask,
1739
+ spatial_position_embeddings=spatial_position_embeddings,
1740
+ **kwargs,
1741
+ )
1742
+
1743
+ object_queries_position_embeddings = self.conditional_detr.model.query_position_embeddings.weight.unsqueeze(
1744
+ 0
1745
+ ).repeat(batch_size, 1, 1)
1746
+
1747
+ # Use decoder_inputs_embeds as queries if provided, otherwise initialize with zeros
1748
+ if decoder_inputs_embeds is not None:
1749
+ queries = decoder_inputs_embeds
1750
+ else:
1751
+ queries = torch.zeros_like(object_queries_position_embeddings)
1752
+
1753
+ decoder_outputs = self.conditional_detr.model.decoder(
1754
+ inputs_embeds=queries,
1755
+ attention_mask=decoder_attention_mask,
1756
+ spatial_position_embeddings=spatial_position_embeddings,
1757
+ object_queries_position_embeddings=object_queries_position_embeddings,
1758
+ encoder_hidden_states=encoder_outputs.last_hidden_state,
1759
+ encoder_attention_mask=flattened_mask,
1760
+ **kwargs,
1761
+ )
1762
+
1763
+ sequence_output = decoder_outputs[0]
1764
+
1765
+ logits = self.conditional_detr.class_labels_classifier(sequence_output)
1766
+ pred_boxes = self.conditional_detr.bbox_predictor(sequence_output).sigmoid()
1767
+
1768
+ height, width = feature_map.shape[-2:]
1769
+ memory = encoder_outputs.last_hidden_state.permute(0, 2, 1).view(
1770
+ batch_size, self.config.d_model, height, width
1771
+ )
1772
+ attention_mask = flattened_mask.view(batch_size, height, width)
1773
+
1774
+ if attention_mask is not None:
1775
+ min_dtype = torch.finfo(memory.dtype).min
1776
+ attention_mask = torch.where(
1777
+ attention_mask.unsqueeze(1).unsqueeze(1),
1778
+ torch.tensor(0.0, device=memory.device, dtype=memory.dtype),
1779
+ min_dtype,
1780
+ )
1781
+
1782
+ bbox_mask = self.bbox_attention(sequence_output, memory, attention_mask=attention_mask)
1783
+
1784
+ seg_masks = self.mask_head(
1785
+ features=projected_feature_map,
1786
+ attention_masks=bbox_mask,
1787
+ fpn_features=[vision_features[2][0], vision_features[1][0], vision_features[0][0]],
1788
+ )
1789
+
1790
+ pred_masks = seg_masks.view(
1791
+ batch_size, self.conditional_detr.config.num_queries, seg_masks.shape[-2], seg_masks.shape[-1]
1792
+ )
1793
+
1794
+ loss, loss_dict, auxiliary_outputs = None, None, None
1795
+ if labels is not None:
1796
+ outputs_class, outputs_coord = None, None
1797
+ if self.config.auxiliary_loss:
1798
+ intermediate = decoder_outputs.intermediate_hidden_states
1799
+ outputs_class = self.conditional_detr.class_labels_classifier(intermediate)
1800
+ outputs_coord = self.conditional_detr.bbox_predictor(intermediate).sigmoid()
1801
+ loss, loss_dict, auxiliary_outputs = self.loss_function(
1802
+ logits, labels, device, pred_boxes, pred_masks, self.config, outputs_class, outputs_coord
1803
+ )
1804
+
1805
+ return ConditionalDetrSegmentationOutput(
1806
+ loss=loss,
1807
+ loss_dict=loss_dict,
1808
+ logits=logits,
1809
+ pred_boxes=pred_boxes,
1810
+ pred_masks=pred_masks,
1811
+ auxiliary_outputs=auxiliary_outputs,
1812
+ last_hidden_state=decoder_outputs.last_hidden_state,
1813
+ decoder_hidden_states=decoder_outputs.hidden_states,
1814
+ decoder_attentions=decoder_outputs.attentions,
1815
+ cross_attentions=decoder_outputs.cross_attentions,
1816
+ encoder_last_hidden_state=encoder_outputs.last_hidden_state,
1817
+ encoder_hidden_states=encoder_outputs.hidden_states,
1818
+ encoder_attentions=encoder_outputs.attentions,
1819
+ )
1820
+
1821
+
1822
+ __all__ = [
1823
+ "ConditionalDetrForObjectDetection",
1824
+ "ConditionalDetrForSegmentation",
1825
+ "ConditionalDetrModel",
1826
+ "ConditionalDetrPreTrainedModel",
1827
+ ]
third_party/transformers/src/transformers/models/conditional_detr/modular_conditional_detr.py ADDED
@@ -0,0 +1,1109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 Microsoft Research Asia and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import math
15
+ from collections.abc import Callable
16
+
17
+ import torch
18
+ from torch import nn
19
+
20
+ from ...image_transforms import (
21
+ center_to_corners_format,
22
+ )
23
+ from ...image_utils import AnnotationFormat
24
+ from ...masking_utils import create_bidirectional_mask
25
+ from ...modeling_outputs import (
26
+ BaseModelOutput,
27
+ )
28
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS
29
+ from ...processing_utils import ImagesKwargs, Unpack
30
+ from ...utils import (
31
+ TensorType,
32
+ TransformersKwargs,
33
+ auto_docstring,
34
+ logging,
35
+ requires_backends,
36
+ )
37
+ from ...utils.generic import can_return_tuple, merge_with_config_defaults
38
+ from ...utils.import_utils import requires
39
+ from ...utils.output_capturing import OutputRecorder, capture_outputs
40
+ from ..deformable_detr.modeling_deformable_detr import inverse_sigmoid
41
+ from ..detr.image_processing_detr import DetrImageProcessor
42
+ from ..detr.image_processing_pil_detr import DetrImageProcessorPil
43
+ from ..detr.modeling_detr import (
44
+ DetrConvEncoder,
45
+ DetrDecoderLayer,
46
+ DetrDecoderOutput,
47
+ DetrEncoder,
48
+ DetrEncoderLayer,
49
+ DetrForObjectDetection,
50
+ DetrForSegmentation,
51
+ DetrLearnedPositionEmbedding,
52
+ DetrMLP,
53
+ DetrMLPPredictionHead,
54
+ DetrModel,
55
+ DetrModelOutput,
56
+ DetrObjectDetectionOutput,
57
+ DetrPreTrainedModel,
58
+ DetrSegmentationOutput,
59
+ DetrSelfAttention,
60
+ DetrSinePositionEmbedding,
61
+ eager_attention_forward,
62
+ )
63
+ from .configuration_conditional_detr import ConditionalDetrConfig
64
+
65
+
66
+ logger = logging.get_logger(__name__)
67
+
68
+
69
+ class ConditionalDetrImageProcessorKwargs(ImagesKwargs, total=False):
70
+ r"""
71
+ format (`str`, *optional*, defaults to `AnnotationFormat.COCO_DETECTION`):
72
+ Data format of the annotations. One of "coco_detection" or "coco_panoptic".
73
+ do_convert_annotations (`bool`, *optional*, defaults to `True`):
74
+ Controls whether to convert the annotations to the format expected by the CONDITIONAL_DETR model. Converts the
75
+ bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`.
76
+ Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method.
77
+ """
78
+
79
+ format: str | AnnotationFormat
80
+ do_convert_annotations: bool
81
+
82
+
83
+ class ConditionalDetrImageProcessor(DetrImageProcessor):
84
+ def post_process_object_detection(
85
+ self, outputs, threshold: float = 0.5, target_sizes: TensorType | list[tuple] = None, top_k: int = 100
86
+ ):
87
+ """
88
+ Converts the raw output of [`ConditionalDetrForObjectDetection`] into final bounding boxes in (top_left_x,
89
+ top_left_y, bottom_right_x, bottom_right_y) format. Only supports PyTorch.
90
+
91
+ Args:
92
+ outputs ([`ConditionalDetrObjectDetectionOutput`]):
93
+ Raw outputs of the model.
94
+ threshold (`float`, *optional*):
95
+ Score threshold to keep object detection predictions.
96
+ target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
97
+ Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
98
+ (height, width) of each image in the batch. If left to None, predictions will not be resized.
99
+ top_k (`int`, *optional*, defaults to 100):
100
+ Keep only top k bounding boxes before filtering by thresholding.
101
+
102
+ Returns:
103
+ `list[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image
104
+ in the batch as predicted by the model.
105
+ """
106
+ out_logits, out_bbox = outputs.logits, outputs.pred_boxes
107
+
108
+ if target_sizes is not None:
109
+ if len(out_logits) != len(target_sizes):
110
+ raise ValueError(
111
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
112
+ )
113
+
114
+ prob = out_logits.sigmoid()
115
+ prob = prob.view(out_logits.shape[0], -1)
116
+ k_value = min(top_k, prob.size(1))
117
+ topk_values, topk_indexes = torch.topk(prob, k_value, dim=1)
118
+ scores = topk_values
119
+ topk_boxes = torch.div(topk_indexes, out_logits.shape[2], rounding_mode="floor")
120
+ labels = topk_indexes % out_logits.shape[2]
121
+ boxes = center_to_corners_format(out_bbox)
122
+ boxes = torch.gather(boxes, 1, topk_boxes.unsqueeze(-1).repeat(1, 1, 4))
123
+
124
+ # and from relative [0, 1] to absolute [0, height] coordinates
125
+ if target_sizes is not None:
126
+ if isinstance(target_sizes, list):
127
+ img_h = torch.Tensor([i[0] for i in target_sizes])
128
+ img_w = torch.Tensor([i[1] for i in target_sizes])
129
+ else:
130
+ img_h, img_w = target_sizes.unbind(1)
131
+ scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device)
132
+ boxes = boxes * scale_fct[:, None, :]
133
+
134
+ results = []
135
+ for s, l, b in zip(scores, labels, boxes):
136
+ score = s[s > threshold]
137
+ label = l[s > threshold]
138
+ box = b[s > threshold]
139
+ results.append({"scores": score, "labels": label, "boxes": box})
140
+
141
+ return results
142
+
143
+ def post_process_semantic_segmentation(self, outputs, target_sizes: list[tuple[int, int]] | None = None):
144
+ """
145
+ Converts the output of [`ConditionalDetrForSegmentation`] into semantic segmentation maps. Only supports PyTorch.
146
+
147
+ Args:
148
+ outputs ([`ConditionalDetrForSegmentation`]):
149
+ Raw outputs of the model.
150
+ target_sizes (`list[tuple[int, int]]`, *optional*):
151
+ A list of tuples (`tuple[int, int]`) containing the target size (height, width) of each image in the
152
+ batch. If unset, predictions will not be resized.
153
+ Returns:
154
+ `list[torch.Tensor]`:
155
+ A list of length `batch_size`, where each item is a semantic segmentation map of shape (height, width)
156
+ corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each
157
+ `torch.Tensor` correspond to a semantic class id.
158
+ """
159
+ class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes]
160
+ masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width]
161
+
162
+ # Conditional DETR does not have a null class, so we use all classes
163
+ masks_classes = class_queries_logits.softmax(dim=-1)
164
+ masks_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
165
+
166
+ # Semantic segmentation logits of shape (batch_size, num_classes, height, width)
167
+ segmentation = torch.einsum("bqc, bqhw -> bchw", masks_classes, masks_probs)
168
+ batch_size = class_queries_logits.shape[0]
169
+
170
+ # Resize logits and compute semantic segmentation maps
171
+ if target_sizes is not None:
172
+ if batch_size != len(target_sizes):
173
+ raise ValueError(
174
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
175
+ )
176
+
177
+ semantic_segmentation = []
178
+ for idx in range(batch_size):
179
+ resized_logits = nn.functional.interpolate(
180
+ segmentation[idx].unsqueeze(dim=0), size=target_sizes[idx], mode="bilinear", align_corners=False
181
+ )
182
+ semantic_map = resized_logits[0].argmax(dim=0)
183
+ semantic_segmentation.append(semantic_map)
184
+ else:
185
+ semantic_segmentation = segmentation.argmax(dim=1)
186
+ semantic_segmentation = [semantic_segmentation[i] for i in range(semantic_segmentation.shape[0])]
187
+
188
+ return semantic_segmentation
189
+
190
+
191
+ class ConditionalDetrImageProcessorPil(DetrImageProcessorPil):
192
+ @requires(backends=("torch",))
193
+ def post_process_object_detection(
194
+ self, outputs, threshold: float = 0.5, target_sizes: TensorType | list[tuple] = None, top_k: int = 100
195
+ ):
196
+ """
197
+ Converts the raw output of [`ConditionalDetrForObjectDetection`] into final bounding boxes in (top_left_x,
198
+ top_left_y, bottom_right_x, bottom_right_y) format. Only supports PyTorch.
199
+
200
+ Args:
201
+ outputs ([`ConditionalDetrObjectDetectionOutput`]):
202
+ Raw outputs of the model.
203
+ threshold (`float`, *optional*):
204
+ Score threshold to keep object detection predictions.
205
+ target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
206
+ Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
207
+ (height, width) of each image in the batch. If left to None, predictions will not be resized.
208
+ top_k (`int`, *optional*, defaults to 100):
209
+ Keep only top k bounding boxes before filtering by thresholding.
210
+
211
+ Returns:
212
+ `list[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image
213
+ in the batch as predicted by the model.
214
+ """
215
+ requires_backends(self, ["torch"])
216
+ out_logits, out_bbox = outputs.logits, outputs.pred_boxes
217
+
218
+ if target_sizes is not None:
219
+ if len(out_logits) != len(target_sizes):
220
+ raise ValueError(
221
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
222
+ )
223
+
224
+ prob = out_logits.sigmoid()
225
+ prob = prob.view(out_logits.shape[0], -1)
226
+ k_value = min(top_k, prob.size(1))
227
+ topk_values, topk_indexes = torch.topk(prob, k_value, dim=1)
228
+ scores = topk_values
229
+ topk_boxes = torch.div(topk_indexes, out_logits.shape[2], rounding_mode="floor")
230
+ labels = topk_indexes % out_logits.shape[2]
231
+ boxes = center_to_corners_format(out_bbox)
232
+ boxes = torch.gather(boxes, 1, topk_boxes.unsqueeze(-1).repeat(1, 1, 4))
233
+
234
+ # and from relative [0, 1] to absolute [0, height] coordinates
235
+ if target_sizes is not None:
236
+ if isinstance(target_sizes, list):
237
+ img_h = torch.Tensor([i[0] for i in target_sizes])
238
+ img_w = torch.Tensor([i[1] for i in target_sizes])
239
+ else:
240
+ img_h, img_w = target_sizes.unbind(1)
241
+ scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device)
242
+ boxes = boxes * scale_fct[:, None, :]
243
+
244
+ results = []
245
+ for s, l, b in zip(scores, labels, boxes):
246
+ score = s[s > threshold]
247
+ label = l[s > threshold]
248
+ box = b[s > threshold]
249
+ results.append({"scores": score, "labels": label, "boxes": box})
250
+
251
+ return results
252
+
253
+ @requires(backends=("torch",))
254
+ def post_process_semantic_segmentation(self, outputs, target_sizes: list[tuple[int, int]] | None = None):
255
+ """
256
+ Converts the output of [`ConditionalDetrForSegmentation`] into semantic segmentation maps. Only supports PyTorch.
257
+
258
+ Args:
259
+ outputs ([`ConditionalDetrForSegmentation`]):
260
+ Raw outputs of the model.
261
+ target_sizes (`list[tuple[int, int]]`, *optional*):
262
+ A list of tuples (`tuple[int, int]`) containing the target size (height, width) of each image in the
263
+ batch. If unset, predictions will not be resized.
264
+ Returns:
265
+ `list[torch.Tensor]`:
266
+ A list of length `batch_size`, where each item is a semantic segmentation map of shape (height, width)
267
+ corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each
268
+ `torch.Tensor` correspond to a semantic class id.
269
+ """
270
+ requires_backends(self, ["torch"])
271
+ class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes]
272
+ masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width]
273
+
274
+ # Conditional DETR does not have a null class, so we use all classes
275
+ masks_classes = class_queries_logits.softmax(dim=-1)
276
+ masks_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
277
+
278
+ # Semantic segmentation logits of shape (batch_size, num_classes, height, width)
279
+ segmentation = torch.einsum("bqc, bqhw -> bchw", masks_classes, masks_probs)
280
+ batch_size = class_queries_logits.shape[0]
281
+
282
+ # Resize logits and compute semantic segmentation maps
283
+ if target_sizes is not None:
284
+ if batch_size != len(target_sizes):
285
+ raise ValueError(
286
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
287
+ )
288
+
289
+ semantic_segmentation = []
290
+ for idx in range(batch_size):
291
+ resized_logits = nn.functional.interpolate(
292
+ segmentation[idx].unsqueeze(dim=0), size=target_sizes[idx], mode="bilinear", align_corners=False
293
+ )
294
+ semantic_map = resized_logits[0].argmax(dim=0)
295
+ semantic_segmentation.append(semantic_map)
296
+ else:
297
+ semantic_segmentation = segmentation.argmax(dim=1)
298
+ semantic_segmentation = [semantic_segmentation[i] for i in range(semantic_segmentation.shape[0])]
299
+
300
+ return semantic_segmentation
301
+
302
+
303
+ class ConditionalDetrDecoderOutput(DetrDecoderOutput):
304
+ r"""
305
+ cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` and `config.add_cross_attention=True` is passed or when `config.output_attentions=True`):
306
+ Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
307
+ sequence_length)`. Attentions weights of the decoder's cross-attention layer, after the attention softmax,
308
+ used to compute the weighted average in the cross-attention heads.
309
+ intermediate_hidden_states (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, num_queries, hidden_size)`, *optional*, returned when `config.auxiliary_loss=True`):
310
+ Intermediate decoder activations, i.e. the output of each decoder layer, each of them gone through a
311
+ layernorm.
312
+ reference_points (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, num_queries, 2 (anchor points))`):
313
+ Reference points (reference points of each layer of the decoder).
314
+ """
315
+
316
+ reference_points: tuple[torch.FloatTensor] | None = None
317
+
318
+
319
+ class ConditionalDetrModelOutput(DetrModelOutput):
320
+ r"""
321
+ last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
322
+ Sequence of hidden-states at the output of the last layer of the decoder of the model.
323
+ intermediate_hidden_states (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, sequence_length, hidden_size)`, *optional*, returned when `config.auxiliary_loss=True`):
324
+ Intermediate decoder activations, i.e. the output of each decoder layer, each of them gone through a
325
+ layernorm.
326
+ reference_points (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, num_queries, 2 (anchor points))`):
327
+ Reference points (reference points of each layer of the decoder).
328
+ """
329
+
330
+ reference_points: tuple[torch.FloatTensor] | None = None
331
+
332
+
333
+ # function to generate sine positional embedding for 2d coordinates
334
+ def gen_sine_position_embeddings(pos_tensor, d_model):
335
+ scale = 2 * math.pi
336
+ dim = d_model // 2
337
+ dim_t = torch.arange(dim, dtype=torch.float32, device=pos_tensor.device)
338
+ dim_t = 10000 ** (2 * torch.div(dim_t, 2, rounding_mode="floor") / dim)
339
+ x_embed = pos_tensor[:, :, 0] * scale
340
+ y_embed = pos_tensor[:, :, 1] * scale
341
+ pos_x = x_embed[:, :, None] / dim_t
342
+ pos_y = y_embed[:, :, None] / dim_t
343
+ pos_x = torch.stack((pos_x[:, :, 0::2].sin(), pos_x[:, :, 1::2].cos()), dim=3).flatten(2)
344
+ pos_y = torch.stack((pos_y[:, :, 0::2].sin(), pos_y[:, :, 1::2].cos()), dim=3).flatten(2)
345
+ pos = torch.cat((pos_y, pos_x), dim=2)
346
+ return pos.to(pos_tensor.dtype)
347
+
348
+
349
+ class ConditionalDetrObjectDetectionOutput(DetrObjectDetectionOutput):
350
+ pass
351
+
352
+
353
+ class ConditionalDetrSegmentationOutput(DetrSegmentationOutput):
354
+ pass
355
+
356
+
357
+ class ConditionalDetrConvEncoder(DetrConvEncoder):
358
+ pass
359
+
360
+
361
+ class ConditionalDetrSinePositionEmbedding(DetrSinePositionEmbedding):
362
+ pass
363
+
364
+
365
+ class ConditionalDetrLearnedPositionEmbedding(DetrLearnedPositionEmbedding):
366
+ pass
367
+
368
+
369
+ class ConditionalDetrSelfAttention(DetrSelfAttention):
370
+ pass
371
+
372
+
373
+ class ConditionalDetrDecoderSelfAttention(nn.Module):
374
+ """
375
+ Multi-headed self-attention for Conditional DETR decoder layers.
376
+
377
+ This attention module handles separate content and position projections, which are then combined
378
+ before applying standard self-attention. Position embeddings are added to both queries and keys.
379
+ """
380
+
381
+ def __init__(
382
+ self,
383
+ config: ConditionalDetrConfig,
384
+ hidden_size: int,
385
+ num_attention_heads: int,
386
+ dropout: float | int = 0.0,
387
+ ):
388
+ super().__init__()
389
+ self.config = config
390
+ self.hidden_size = hidden_size
391
+ self.head_dim = hidden_size // num_attention_heads
392
+ self.scaling = self.head_dim**-0.5
393
+ self.attention_dropout = dropout
394
+ self.is_causal = False
395
+
396
+ # Content and position projections
397
+ self.q_content_proj = nn.Linear(hidden_size, hidden_size)
398
+ self.q_pos_proj = nn.Linear(hidden_size, hidden_size)
399
+ self.k_content_proj = nn.Linear(hidden_size, hidden_size)
400
+ self.k_pos_proj = nn.Linear(hidden_size, hidden_size)
401
+ self.v_proj = nn.Linear(hidden_size, hidden_size)
402
+ self.o_proj = nn.Linear(hidden_size, hidden_size)
403
+
404
+ def forward(
405
+ self,
406
+ hidden_states: torch.Tensor,
407
+ query_position_embeddings: torch.Tensor,
408
+ attention_mask: torch.Tensor | None = None,
409
+ **kwargs: Unpack[TransformersKwargs],
410
+ ) -> tuple[torch.Tensor, torch.Tensor]:
411
+ """
412
+ Args:
413
+ hidden_states (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`):
414
+ Input hidden states from the decoder layer.
415
+ query_position_embeddings (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`):
416
+ Position embeddings for queries and keys. Required (unlike standard attention). Processed through
417
+ separate position projections (`q_pos_proj`, `k_pos_proj`) and added to content projections.
418
+ attention_mask (`torch.Tensor` of shape `(batch_size, 1, num_queries, num_queries)`, *optional*):
419
+ Attention mask to avoid attending to padding tokens.
420
+ """
421
+ input_shape = hidden_states.shape[:-1]
422
+ hidden_shape = (*input_shape, -1, self.head_dim)
423
+
424
+ query_states = (
425
+ (self.q_content_proj(hidden_states) + self.q_pos_proj(query_position_embeddings))
426
+ .view(hidden_shape)
427
+ .transpose(1, 2)
428
+ )
429
+ key_states = (
430
+ (self.k_content_proj(hidden_states) + self.k_pos_proj(query_position_embeddings))
431
+ .view(hidden_shape)
432
+ .transpose(1, 2)
433
+ )
434
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
435
+
436
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
437
+ self.config._attn_implementation, eager_attention_forward
438
+ )
439
+
440
+ attn_output, attn_weights = attention_interface(
441
+ self,
442
+ query_states,
443
+ key_states,
444
+ value_states,
445
+ attention_mask,
446
+ dropout=0.0 if not self.training else self.attention_dropout,
447
+ scaling=self.scaling,
448
+ **kwargs,
449
+ )
450
+
451
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
452
+ attn_output = self.o_proj(attn_output)
453
+ return attn_output, attn_weights
454
+
455
+
456
+ class ConditionalDetrDecoderCrossAttention(nn.Module):
457
+ """
458
+ Multi-headed cross-attention for Conditional DETR decoder layers.
459
+
460
+ This attention module handles the special cross-attention logic in Conditional DETR:
461
+ - Separate content and position projections for queries and keys
462
+ - Concatenation of query sine embeddings with queries (doubling query dimension)
463
+ - Concatenation of key position embeddings with keys (doubling key dimension)
464
+ - Output dimension remains hidden_size despite doubled input dimensions
465
+ """
466
+
467
+ def __init__(
468
+ self,
469
+ config: ConditionalDetrConfig,
470
+ hidden_size: int,
471
+ num_attention_heads: int,
472
+ dropout: float | int = 0.0,
473
+ ):
474
+ super().__init__()
475
+ self.config = config
476
+ self.hidden_size = hidden_size
477
+ self.num_attention_heads = num_attention_heads
478
+ self.head_dim = hidden_size // num_attention_heads
479
+ self.attention_dropout = dropout
480
+ self.is_causal = False
481
+
482
+ # Content and position projections
483
+ self.q_content_proj = nn.Linear(hidden_size, hidden_size)
484
+ self.q_pos_proj = nn.Linear(hidden_size, hidden_size)
485
+ self.k_content_proj = nn.Linear(hidden_size, hidden_size)
486
+ self.k_pos_proj = nn.Linear(hidden_size, hidden_size)
487
+ self.v_proj = nn.Linear(hidden_size, hidden_size)
488
+ self.q_pos_sine_proj = nn.Linear(hidden_size, hidden_size)
489
+
490
+ # Output projection: input is hidden_size * 2 (from concatenated q/k), output is hidden_size
491
+ self.o_proj = nn.Linear(hidden_size, hidden_size)
492
+
493
+ # Compute scaling for expanded head_dim (q and k have doubled dimensions after concatenation)
494
+ # This matches the original Conditional DETR implementation where embed_dim * 2 is used
495
+ expanded_head_dim = (hidden_size * 2) // num_attention_heads
496
+ self.scaling = expanded_head_dim**-0.5
497
+
498
+ def forward(
499
+ self,
500
+ hidden_states: torch.Tensor,
501
+ encoder_hidden_states: torch.Tensor,
502
+ query_sine_embed: torch.Tensor,
503
+ encoder_position_embeddings: torch.Tensor,
504
+ query_position_embeddings: torch.Tensor | None = None,
505
+ attention_mask: torch.Tensor | None = None,
506
+ **kwargs: Unpack[TransformersKwargs],
507
+ ) -> tuple[torch.Tensor, torch.Tensor]:
508
+ """
509
+ Args:
510
+ hidden_states (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`):
511
+ Decoder hidden states (queries).
512
+ encoder_hidden_states (`torch.Tensor` of shape `(batch_size, encoder_seq_len, hidden_size)`):
513
+ Encoder output hidden states (keys and values).
514
+ query_sine_embed (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`):
515
+ Sine position embeddings for queries. **Concatenated** (not added) with query content,
516
+ doubling the query dimension.
517
+ encoder_position_embeddings (`torch.Tensor` of shape `(batch_size, encoder_seq_len, hidden_size)`):
518
+ Position embeddings for keys. **Concatenated** (not added) with key content, doubling the key dimension.
519
+ query_position_embeddings (`torch.Tensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*):
520
+ Additional position embeddings. When provided (first layer only), **added** to query content
521
+ before concatenation with `query_sine_embed`. Also causes `encoder_position_embeddings` to be
522
+ added to key content before concatenation.
523
+ attention_mask (`torch.Tensor` of shape `(batch_size, 1, num_queries, encoder_seq_len)`, *optional*):
524
+ Attention mask to avoid attending to padding tokens.
525
+ """
526
+ query_input_shape = hidden_states.shape[:-1]
527
+ kv_input_shape = encoder_hidden_states.shape[:-1]
528
+ query_hidden_shape = (*query_input_shape, self.num_attention_heads, self.head_dim)
529
+ kv_hidden_shape = (*kv_input_shape, self.num_attention_heads, self.head_dim)
530
+
531
+ # Apply content and position projections
532
+ query_input = self.q_content_proj(hidden_states)
533
+ key_input = self.k_content_proj(encoder_hidden_states)
534
+ value_states = self.v_proj(encoder_hidden_states)
535
+ key_pos = self.k_pos_proj(encoder_position_embeddings)
536
+
537
+ # Combine content and position embeddings
538
+ if query_position_embeddings is not None:
539
+ query_input = query_input + self.q_pos_proj(query_position_embeddings)
540
+ key_input = key_input + key_pos
541
+
542
+ # Reshape and concatenate position embeddings (doubling head_dim)
543
+ query_input = query_input.view(query_hidden_shape)
544
+ key_input = key_input.view(kv_hidden_shape)
545
+ query_sine_embed = self.q_pos_sine_proj(query_sine_embed).view(query_hidden_shape)
546
+ key_pos = key_pos.view(kv_hidden_shape)
547
+
548
+ query_states = torch.cat([query_input, query_sine_embed], dim=-1).view(*query_input_shape, -1)
549
+ key_states = torch.cat([key_input, key_pos], dim=-1).view(*kv_input_shape, -1)
550
+
551
+ # Reshape for attention computation
552
+ expanded_head_dim = query_states.shape[-1] // self.num_attention_heads
553
+ query_states = query_states.view(*query_input_shape, self.num_attention_heads, expanded_head_dim).transpose(
554
+ 1, 2
555
+ )
556
+ key_states = key_states.view(*kv_input_shape, self.num_attention_heads, expanded_head_dim).transpose(1, 2)
557
+ value_states = value_states.view(kv_hidden_shape).transpose(1, 2)
558
+
559
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
560
+ self.config._attn_implementation, eager_attention_forward
561
+ )
562
+
563
+ attn_output, attn_weights = attention_interface(
564
+ self,
565
+ query_states,
566
+ key_states,
567
+ value_states,
568
+ attention_mask,
569
+ dropout=0.0 if not self.training else self.attention_dropout,
570
+ scaling=self.scaling,
571
+ **kwargs,
572
+ )
573
+
574
+ attn_output = attn_output.reshape(*query_input_shape, -1).contiguous()
575
+ attn_output = self.o_proj(attn_output)
576
+ return attn_output, attn_weights
577
+
578
+
579
+ class ConditionalDetrMLP(DetrMLP):
580
+ pass
581
+
582
+
583
+ class ConditionalDetrEncoderLayer(DetrEncoderLayer):
584
+ pass
585
+
586
+
587
+ class ConditionalDetrDecoderLayer(DetrDecoderLayer):
588
+ def __init__(self, config: ConditionalDetrConfig):
589
+ super().__init__()
590
+ self.self_attn = ConditionalDetrDecoderSelfAttention(
591
+ config=config,
592
+ hidden_size=self.hidden_size,
593
+ num_attention_heads=config.decoder_attention_heads,
594
+ dropout=config.attention_dropout,
595
+ )
596
+ self.encoder_attn = ConditionalDetrDecoderCrossAttention(
597
+ config=config,
598
+ hidden_size=self.hidden_size,
599
+ num_attention_heads=config.decoder_attention_heads,
600
+ dropout=config.attention_dropout,
601
+ )
602
+
603
+ def forward(
604
+ self,
605
+ hidden_states: torch.Tensor,
606
+ attention_mask: torch.Tensor | None = None,
607
+ spatial_position_embeddings: torch.Tensor | None = None,
608
+ query_position_embeddings: torch.Tensor | None = None,
609
+ query_sine_embed: torch.Tensor | None = None,
610
+ encoder_hidden_states: torch.Tensor | None = None,
611
+ encoder_attention_mask: torch.Tensor | None = None,
612
+ is_first: bool | None = False,
613
+ **kwargs: Unpack[TransformersKwargs],
614
+ ) -> torch.Tensor:
615
+ """
616
+ Args:
617
+ hidden_states (`torch.FloatTensor`): input to the layer of shape `(seq_len, batch, embed_dim)`
618
+ attention_mask (`torch.FloatTensor`): attention mask of size
619
+ `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative
620
+ values.
621
+ spatial_position_embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
622
+ Spatial position embeddings (2D positional encodings) that are added to the queries and keys in each self-attention layer.
623
+ query_position_embeddings (`torch.FloatTensor`, *optional*):
624
+ object_queries that are added to the queries and keys
625
+ in the self-attention layer.
626
+ encoder_hidden_states (`torch.FloatTensor`):
627
+ cross attention input to the layer of shape `(seq_len, batch, embed_dim)`
628
+ encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size
629
+ `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative
630
+ values.
631
+ output_attentions (`bool`, *optional*):
632
+ Whether or not to return the attentions tensors of all attention layers. See `attentions` under
633
+ returned tensors for more detail.
634
+ """
635
+ residual = hidden_states
636
+
637
+ hidden_states, _ = self.self_attn(
638
+ hidden_states=hidden_states,
639
+ query_position_embeddings=query_position_embeddings,
640
+ attention_mask=attention_mask,
641
+ **kwargs,
642
+ )
643
+
644
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
645
+ hidden_states = residual + hidden_states
646
+ hidden_states = self.self_attn_layer_norm(hidden_states)
647
+
648
+ if encoder_hidden_states is not None:
649
+ residual = hidden_states
650
+
651
+ hidden_states, _ = self.encoder_attn(
652
+ hidden_states=hidden_states,
653
+ encoder_hidden_states=encoder_hidden_states,
654
+ attention_mask=encoder_attention_mask,
655
+ query_sine_embed=query_sine_embed,
656
+ encoder_position_embeddings=spatial_position_embeddings,
657
+ # Only pass query_position_embeddings for the first layer
658
+ query_position_embeddings=query_position_embeddings if is_first else None,
659
+ **kwargs,
660
+ )
661
+
662
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
663
+ hidden_states = residual + hidden_states
664
+ hidden_states = self.encoder_attn_layer_norm(hidden_states)
665
+
666
+ # Fully Connected
667
+ residual = hidden_states
668
+ hidden_states = self.mlp(hidden_states)
669
+ hidden_states = residual + hidden_states
670
+ hidden_states = self.final_layer_norm(hidden_states)
671
+
672
+ return hidden_states
673
+
674
+
675
+ class ConditionalDetrMLPPredictionHead(DetrMLPPredictionHead):
676
+ pass
677
+
678
+
679
+ class ConditionalDetrPreTrainedModel(DetrPreTrainedModel):
680
+ _keys_to_ignore_on_load_unexpected = [
681
+ r"detr\.model\.backbone\.model\.layer\d+\.0\.downsample\.1\.num_batches_tracked"
682
+ ]
683
+
684
+
685
+ class ConditionalDetrEncoder(DetrEncoder):
686
+ pass
687
+
688
+
689
+ class ConditionalDetrDecoder(ConditionalDetrPreTrainedModel):
690
+ """
691
+ Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`ConditionalDetrDecoderLayer`].
692
+
693
+ The decoder updates the query embeddings through multiple self-attention and cross-attention layers.
694
+
695
+ Some small tweaks for Conditional DETR:
696
+
697
+ - object_queries and query_position_embeddings are added to the forward pass.
698
+ - if self.config.auxiliary_loss is set to True, also returns a stack of activations from all decoding layers.
699
+
700
+ Args:
701
+ config: ConditionalDetrConfig
702
+ """
703
+
704
+ _can_record_outputs = {
705
+ "hidden_states": ConditionalDetrDecoderLayer,
706
+ "attentions": OutputRecorder(ConditionalDetrDecoderSelfAttention, layer_name="self_attn", index=1),
707
+ "cross_attentions": OutputRecorder(ConditionalDetrDecoderCrossAttention, layer_name="encoder_attn", index=1),
708
+ }
709
+
710
+ def __init__(self, config: ConditionalDetrConfig):
711
+ super().__init__(config)
712
+ self.hidden_size = config.d_model
713
+
714
+ self.dropout = config.dropout
715
+ self.layerdrop = config.decoder_layerdrop
716
+
717
+ self.layers = nn.ModuleList([ConditionalDetrDecoderLayer(config) for _ in range(config.decoder_layers)])
718
+ # in Conditional DETR, the decoder uses layernorm after the last decoder layer output
719
+ self.layernorm = nn.LayerNorm(config.d_model)
720
+
721
+ # query_scale is the FFN applied on f to generate transformation T
722
+ self.query_scale = ConditionalDetrMLPPredictionHead(self.hidden_size, self.hidden_size, self.hidden_size, 2)
723
+ self.ref_point_head = ConditionalDetrMLPPredictionHead(self.hidden_size, self.hidden_size, 2, 2)
724
+ for layer_id in range(config.decoder_layers - 1):
725
+ # Set q_pos_proj to None for layers after the first (only first layer uses query position embeddings)
726
+ self.layers[layer_id + 1].encoder_attn.q_pos_proj = None
727
+
728
+ # Initialize weights and apply final processing
729
+ self.post_init()
730
+
731
+ @merge_with_config_defaults
732
+ @capture_outputs
733
+ def forward(
734
+ self,
735
+ inputs_embeds=None,
736
+ attention_mask=None,
737
+ encoder_hidden_states=None,
738
+ encoder_attention_mask=None,
739
+ spatial_position_embeddings=None,
740
+ object_queries_position_embeddings=None,
741
+ **kwargs: Unpack[TransformersKwargs],
742
+ ) -> ConditionalDetrDecoderOutput:
743
+ r"""
744
+ Args:
745
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
746
+ The query embeddings that are passed into the decoder.
747
+
748
+ attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
749
+ Mask to avoid performing attention on certain queries. Mask values selected in `[0, 1]`:
750
+
751
+ - 1 for queries that are **not masked**,
752
+ - 0 for queries that are **masked**.
753
+
754
+ [What are attention masks?](../glossary#attention-mask)
755
+ encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*):
756
+ Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention
757
+ of the decoder.
758
+ encoder_attention_mask (`torch.LongTensor` of shape `(batch_size, encoder_sequence_length)`, *optional*):
759
+ Mask to avoid performing cross-attention on padding pixel_values of the encoder. Mask values selected
760
+ in `[0, 1]`:
761
+
762
+ - 1 for pixels that are real (i.e. **not masked**),
763
+ - 0 for pixels that are padding (i.e. **masked**).
764
+
765
+ spatial_position_embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
766
+ Spatial position embeddings that are added to the queries and keys in each cross-attention layer.
767
+ object_queries_position_embeddings (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`):
768
+ , *optional*): Position embeddings that are added to the queries and keys in each self-attention layer.
769
+ """
770
+ if inputs_embeds is not None:
771
+ hidden_states = inputs_embeds
772
+
773
+ # expand encoder attention mask
774
+ if encoder_hidden_states is not None and encoder_attention_mask is not None:
775
+ # [batch_size, seq_len] -> [batch_size, 1, target_seq_len, source_seq_len]
776
+ encoder_attention_mask = create_bidirectional_mask(
777
+ self.config,
778
+ inputs_embeds,
779
+ encoder_attention_mask,
780
+ )
781
+
782
+ # optional intermediate hidden states
783
+ intermediate = () if self.config.auxiliary_loss else None
784
+
785
+ reference_points_before_sigmoid = self.ref_point_head(
786
+ object_queries_position_embeddings
787
+ ) # [num_queries, batch_size, 2]
788
+ reference_points = reference_points_before_sigmoid.sigmoid().transpose(0, 1)
789
+ obj_center = reference_points[..., :2].transpose(0, 1)
790
+ # get sine embedding for the query vector
791
+ query_sine_embed_before_transformation = gen_sine_position_embeddings(obj_center, self.config.d_model)
792
+
793
+ for idx, decoder_layer in enumerate(self.layers):
794
+ if self.training:
795
+ dropout_probability = torch.rand([])
796
+ if dropout_probability < self.layerdrop:
797
+ continue
798
+ if idx == 0:
799
+ pos_transformation = 1
800
+ else:
801
+ pos_transformation = self.query_scale(hidden_states)
802
+ # apply transformation
803
+ query_sine_embed = query_sine_embed_before_transformation * pos_transformation
804
+
805
+ hidden_states = decoder_layer(
806
+ hidden_states,
807
+ None,
808
+ spatial_position_embeddings,
809
+ object_queries_position_embeddings,
810
+ query_sine_embed,
811
+ encoder_hidden_states, # as a positional argument for gradient checkpointing
812
+ encoder_attention_mask=encoder_attention_mask,
813
+ is_first=(idx == 0),
814
+ **kwargs,
815
+ )
816
+
817
+ if self.config.auxiliary_loss:
818
+ hidden_states = self.layernorm(hidden_states)
819
+ intermediate += (hidden_states,)
820
+
821
+ # finally, apply layernorm
822
+ hidden_states = self.layernorm(hidden_states)
823
+
824
+ # stack intermediate decoder activations
825
+ if self.config.auxiliary_loss:
826
+ intermediate = torch.stack(intermediate)
827
+
828
+ return ConditionalDetrDecoderOutput(
829
+ last_hidden_state=hidden_states,
830
+ intermediate_hidden_states=intermediate,
831
+ reference_points=reference_points,
832
+ )
833
+
834
+
835
+ class ConditionalDetrModel(DetrModel):
836
+ def __init__(self, config: ConditionalDetrConfig):
837
+ super().__init__(config)
838
+ self.query_position_embeddings = nn.Embedding(config.num_queries, config.d_model)
839
+
840
+ # Initialize weights and apply final processing
841
+ self.post_init()
842
+
843
+ @auto_docstring
844
+ @can_return_tuple
845
+ def forward(
846
+ self,
847
+ pixel_values: torch.FloatTensor,
848
+ pixel_mask: torch.LongTensor | None = None,
849
+ decoder_attention_mask: torch.LongTensor | None = None,
850
+ encoder_outputs: torch.FloatTensor | None = None,
851
+ inputs_embeds: torch.FloatTensor | None = None,
852
+ decoder_inputs_embeds: torch.FloatTensor | None = None,
853
+ **kwargs: Unpack[TransformersKwargs],
854
+ ) -> ConditionalDetrModelOutput:
855
+ r"""
856
+ decoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, num_queries)`, *optional*):
857
+ Not used by default. Can be used to mask object queries.
858
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
859
+ Optionally, instead of passing the flattened feature map (output of the backbone + projection layer), you
860
+ can choose to directly pass a flattened representation of an image.
861
+ decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*):
862
+ Optionally, instead of initializing the queries with a tensor of zeros, you can choose to directly pass an
863
+ embedded representation.
864
+
865
+ Examples:
866
+
867
+ ```python
868
+ >>> from transformers import AutoImageProcessor, AutoModel
869
+ >>> from PIL import Image
870
+ >>> import requests
871
+
872
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
873
+ >>> image = Image.open(requests.get(url, stream=True).raw)
874
+
875
+ >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/conditional-detr-resnet-50")
876
+ >>> model = AutoModel.from_pretrained("microsoft/conditional-detr-resnet-50")
877
+
878
+ >>> # prepare image for the model
879
+ >>> inputs = image_processor(images=image, return_tensors="pt")
880
+
881
+ >>> # forward pass
882
+ >>> outputs = model(**inputs)
883
+
884
+ >>> # the last hidden states are the final query embeddings of the Transformer decoder
885
+ >>> # these are of shape (batch_size, num_queries, hidden_size)
886
+ >>> last_hidden_states = outputs.last_hidden_state
887
+ >>> list(last_hidden_states.shape)
888
+ [1, 300, 256]
889
+ ```"""
890
+ batch_size, num_channels, height, width = pixel_values.shape
891
+ device = pixel_values.device
892
+
893
+ if pixel_mask is None:
894
+ pixel_mask = torch.ones(((batch_size, height, width)), device=device)
895
+
896
+ # First, sent pixel_values + pixel_mask through Backbone to obtain the features
897
+ # pixel_values should be of shape (batch_size, num_channels, height, width)
898
+ # pixel_mask should be of shape (batch_size, height, width)
899
+ features = self.backbone(pixel_values, pixel_mask)
900
+
901
+ # get final feature map and downsampled mask
902
+ feature_map, mask = features[-1]
903
+
904
+ if mask is None:
905
+ raise ValueError("Backbone does not return downsampled pixel mask")
906
+
907
+ # Second, apply 1x1 convolution to reduce the channel dimension to d_model (256 by default)
908
+ projected_feature_map = self.input_projection(feature_map)
909
+
910
+ # Generate position embeddings
911
+ spatial_position_embeddings = self.position_embedding(
912
+ shape=feature_map.shape, device=device, dtype=pixel_values.dtype, mask=mask
913
+ )
914
+
915
+ # Third, flatten the feature map of shape NxCxHxW to NxCxHW, and permute it to NxHWxC
916
+ # In other words, turn their shape into (batch_size, sequence_length, hidden_size)
917
+ flattened_features = projected_feature_map.flatten(2).permute(0, 2, 1)
918
+
919
+ flattened_mask = mask.flatten(1)
920
+
921
+ # Fourth, sent flattened_features + flattened_mask + spatial_position_embeddings through encoder
922
+ # flattened_features is a Tensor of shape (batch_size, height*width, hidden_size)
923
+ # flattened_mask is a Tensor of shape (batch_size, height*width)
924
+ if encoder_outputs is None:
925
+ encoder_outputs = self.encoder(
926
+ inputs_embeds=flattened_features,
927
+ attention_mask=flattened_mask,
928
+ spatial_position_embeddings=spatial_position_embeddings,
929
+ **kwargs,
930
+ )
931
+ # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput
932
+ elif not isinstance(encoder_outputs, BaseModelOutput):
933
+ encoder_outputs = BaseModelOutput(
934
+ last_hidden_state=encoder_outputs[0],
935
+ hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None,
936
+ attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None,
937
+ )
938
+
939
+ # Fifth, sent query embeddings through the decoder (which is conditioned on the encoder output)
940
+ object_queries_position_embeddings = self.query_position_embeddings.weight.unsqueeze(0).repeat(
941
+ batch_size, 1, 1
942
+ )
943
+ queries = torch.zeros_like(object_queries_position_embeddings)
944
+
945
+ # decoder outputs consists of (dec_features, dec_hidden, dec_attn)
946
+ decoder_outputs = self.decoder(
947
+ inputs_embeds=queries,
948
+ attention_mask=None,
949
+ spatial_position_embeddings=spatial_position_embeddings,
950
+ object_queries_position_embeddings=object_queries_position_embeddings,
951
+ encoder_hidden_states=encoder_outputs.last_hidden_state,
952
+ encoder_attention_mask=flattened_mask,
953
+ **kwargs,
954
+ )
955
+
956
+ return ConditionalDetrModelOutput(
957
+ last_hidden_state=decoder_outputs.last_hidden_state,
958
+ decoder_hidden_states=decoder_outputs.hidden_states,
959
+ decoder_attentions=decoder_outputs.attentions,
960
+ cross_attentions=decoder_outputs.cross_attentions,
961
+ encoder_last_hidden_state=encoder_outputs.last_hidden_state,
962
+ encoder_hidden_states=encoder_outputs.hidden_states,
963
+ encoder_attentions=encoder_outputs.attentions,
964
+ intermediate_hidden_states=decoder_outputs.intermediate_hidden_states,
965
+ reference_points=decoder_outputs.reference_points,
966
+ )
967
+
968
+
969
+ class ConditionalDetrForObjectDetection(DetrForObjectDetection):
970
+ def __init__(self, config: ConditionalDetrConfig):
971
+ super().__init__(config)
972
+ self.class_labels_classifier = nn.Linear(config.d_model, config.num_labels)
973
+
974
+ # taken from https://github.com/Atten4Vis/conditionalDETR/blob/master/models/conditional_detr.py
975
+ def _set_aux_loss(self, outputs_class, outputs_coord):
976
+ return [{"logits": a, "pred_boxes": b} for a, b in zip(outputs_class[:-1], outputs_coord[:-1])]
977
+
978
+ @auto_docstring
979
+ @can_return_tuple
980
+ def forward(
981
+ self,
982
+ pixel_values: torch.FloatTensor,
983
+ pixel_mask: torch.LongTensor | None = None,
984
+ decoder_attention_mask: torch.LongTensor | None = None,
985
+ encoder_outputs: torch.FloatTensor | None = None,
986
+ inputs_embeds: torch.FloatTensor | None = None,
987
+ decoder_inputs_embeds: torch.FloatTensor | None = None,
988
+ labels: list[dict] | None = None,
989
+ **kwargs: Unpack[TransformersKwargs],
990
+ ) -> ConditionalDetrObjectDetectionOutput:
991
+ r"""
992
+ decoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, num_queries)`, *optional*):
993
+ Not used by default. Can be used to mask object queries.
994
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
995
+ Optionally, instead of passing the flattened feature map (output of the backbone + projection layer), you
996
+ can choose to directly pass a flattened representation of an image.
997
+ decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*):
998
+ Optionally, instead of initializing the queries with a tensor of zeros, you can choose to directly pass an
999
+ embedded representation.
1000
+ labels (`list[Dict]` of len `(batch_size,)`, *optional*):
1001
+ Labels for computing the bipartite matching loss. List of dicts, each dictionary containing at least the
1002
+ following 2 keys: 'class_labels' and 'boxes' (the class labels and bounding boxes of an image in the batch
1003
+ respectively). The class labels themselves should be a `torch.LongTensor` of len `(number of bounding boxes
1004
+ in the image,)` and the boxes a `torch.FloatTensor` of shape `(number of bounding boxes in the image, 4)`.
1005
+
1006
+ Examples:
1007
+
1008
+ ```python
1009
+ >>> from transformers import AutoImageProcessor, AutoModelForObjectDetection
1010
+ >>> from PIL import Image
1011
+ >>> import requests
1012
+
1013
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
1014
+ >>> image = Image.open(requests.get(url, stream=True).raw)
1015
+
1016
+ >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/conditional-detr-resnet-50")
1017
+ >>> model = AutoModelForObjectDetection.from_pretrained("microsoft/conditional-detr-resnet-50")
1018
+
1019
+ >>> inputs = image_processor(images=image, return_tensors="pt")
1020
+
1021
+ >>> outputs = model(**inputs)
1022
+
1023
+ >>> # convert outputs (bounding boxes and class logits) to Pascal VOC format (xmin, ymin, xmax, ymax)
1024
+ >>> target_sizes = torch.tensor([image.size[::-1]])
1025
+ >>> results = image_processor.post_process_object_detection(outputs, threshold=0.5, target_sizes=target_sizes)[
1026
+ ... 0
1027
+ ... ]
1028
+ >>> for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
1029
+ ... box = [round(i, 2) for i in box.tolist()]
1030
+ ... print(
1031
+ ... f"Detected {model.config.id2label[label.item()]} with confidence "
1032
+ ... f"{round(score.item(), 3)} at location {box}"
1033
+ ... )
1034
+ Detected remote with confidence 0.833 at location [38.31, 72.1, 177.63, 118.45]
1035
+ Detected cat with confidence 0.831 at location [9.2, 51.38, 321.13, 469.0]
1036
+ Detected cat with confidence 0.804 at location [340.3, 16.85, 642.93, 370.95]
1037
+ Detected remote with confidence 0.683 at location [334.48, 73.49, 366.37, 190.01]
1038
+ Detected couch with confidence 0.535 at location [0.52, 1.19, 640.35, 475.1]
1039
+ ```"""
1040
+ # First, sent images through CONDITIONAL_DETR base model to obtain encoder + decoder outputs
1041
+ outputs = self.model(
1042
+ pixel_values,
1043
+ pixel_mask=pixel_mask,
1044
+ decoder_attention_mask=decoder_attention_mask,
1045
+ encoder_outputs=encoder_outputs,
1046
+ inputs_embeds=inputs_embeds,
1047
+ decoder_inputs_embeds=decoder_inputs_embeds,
1048
+ **kwargs,
1049
+ )
1050
+
1051
+ sequence_output = outputs[0]
1052
+
1053
+ # class logits + predicted bounding boxes
1054
+ logits = self.class_labels_classifier(sequence_output)
1055
+
1056
+ reference = outputs.reference_points
1057
+ reference_before_sigmoid = inverse_sigmoid(reference).transpose(0, 1)
1058
+
1059
+ hs = sequence_output
1060
+ tmp = self.bbox_predictor(hs)
1061
+ tmp[..., :2] += reference_before_sigmoid
1062
+ pred_boxes = tmp.sigmoid()
1063
+ # pred_boxes = self.bbox_predictor(sequence_output).sigmoid()
1064
+
1065
+ loss, loss_dict, auxiliary_outputs = None, None, None
1066
+ if labels is not None:
1067
+ outputs_class, outputs_coord = None, None
1068
+ if self.config.auxiliary_loss:
1069
+ outputs_coords = []
1070
+ intermediate = outputs.intermediate_hidden_states
1071
+ outputs_class = self.class_labels_classifier(intermediate)
1072
+ for lvl in range(intermediate.shape[0]):
1073
+ tmp = self.bbox_predictor(intermediate[lvl])
1074
+ tmp[..., :2] += reference_before_sigmoid
1075
+ outputs_coord = tmp.sigmoid()
1076
+ outputs_coords.append(outputs_coord)
1077
+ outputs_coord = torch.stack(outputs_coords)
1078
+ loss, loss_dict, auxiliary_outputs = self.loss_function(
1079
+ logits, labels, self.device, pred_boxes, self.config, outputs_class, outputs_coord
1080
+ )
1081
+
1082
+ return ConditionalDetrObjectDetectionOutput(
1083
+ loss=loss,
1084
+ loss_dict=loss_dict,
1085
+ logits=logits,
1086
+ pred_boxes=pred_boxes,
1087
+ auxiliary_outputs=auxiliary_outputs,
1088
+ last_hidden_state=outputs.last_hidden_state,
1089
+ decoder_hidden_states=outputs.decoder_hidden_states,
1090
+ decoder_attentions=outputs.decoder_attentions,
1091
+ cross_attentions=outputs.cross_attentions,
1092
+ encoder_last_hidden_state=outputs.encoder_last_hidden_state,
1093
+ encoder_hidden_states=outputs.encoder_hidden_states,
1094
+ encoder_attentions=outputs.encoder_attentions,
1095
+ )
1096
+
1097
+
1098
+ class ConditionalDetrForSegmentation(DetrForSegmentation):
1099
+ pass
1100
+
1101
+
1102
+ __all__ = [
1103
+ "ConditionalDetrImageProcessor",
1104
+ "ConditionalDetrImageProcessorPil",
1105
+ "ConditionalDetrForObjectDetection",
1106
+ "ConditionalDetrForSegmentation",
1107
+ "ConditionalDetrModel",
1108
+ "ConditionalDetrPreTrainedModel",
1109
+ ]
third_party/transformers/src/transformers/models/donut/__init__.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from .configuration_donut_swin import *
22
+ from .image_processing_donut import *
23
+ from .image_processing_pil_donut import *
24
+ from .modeling_donut_swin import *
25
+ from .processing_donut import *
26
+ else:
27
+ import sys
28
+
29
+ _file = globals()["__file__"]
30
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/donut/configuration_donut_swin.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Donut Swin Transformer model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...configuration_utils import PreTrainedConfig
19
+ from ...utils import auto_docstring
20
+
21
+
22
+ @auto_docstring(checkpoint="naver-clova-ix/donut-base")
23
+ @strict
24
+ class DonutSwinConfig(PreTrainedConfig):
25
+ r"""
26
+ window_size (`int`, *optional*, defaults to 7):
27
+ Size of windows.
28
+
29
+ Example:
30
+
31
+ ```python
32
+ >>> from transformers import DonutSwinConfig, DonutSwinModel
33
+
34
+ >>> # Initializing a Donut naver-clova-ix/donut-base style configuration
35
+ >>> configuration = DonutSwinConfig()
36
+
37
+ >>> # Randomly initializing a model from the naver-clova-ix/donut-base style configuration
38
+ >>> model = DonutSwinModel(configuration)
39
+
40
+ >>> # Accessing the model configuration
41
+ >>> configuration = model.config
42
+ ```"""
43
+
44
+ model_type = "donut-swin"
45
+
46
+ attribute_map = {
47
+ "num_attention_heads": "num_heads",
48
+ "num_hidden_layers": "num_layers",
49
+ }
50
+
51
+ image_size: int | list[int] | tuple[int, int] = 224
52
+ patch_size: int | list[int] | tuple[int, int] = 4
53
+ num_channels: int = 3
54
+ embed_dim: int = 96
55
+ depths: list[int] | tuple[int, ...] = (2, 2, 6, 2)
56
+ num_heads: list[int] | tuple[int, ...] = (3, 6, 12, 24)
57
+ window_size: int = 7
58
+ mlp_ratio: float = 4.0
59
+ qkv_bias: bool = True
60
+ hidden_dropout_prob: float | int = 0.0
61
+ attention_probs_dropout_prob: float | int = 0.0
62
+ drop_path_rate: float | int = 0.1
63
+ hidden_act: str = "gelu"
64
+ use_absolute_embeddings: bool = False
65
+ initializer_range: float = 0.02
66
+ layer_norm_eps: float = 1e-5
67
+
68
+ def __post_init__(self, **kwargs):
69
+ self.num_layers = len(self.depths)
70
+ # we set the hidden_size attribute in order to make Swin work with VisionEncoderDecoderModel
71
+ # this indicates the channel dimension after the last stage of the model
72
+ self.hidden_size = int(self.embed_dim * 2 ** (len(self.depths) - 1))
73
+ super().__post_init__(**kwargs)
74
+
75
+
76
+ __all__ = ["DonutSwinConfig"]
third_party/transformers/src/transformers/models/donut/convert_donut_to_pytorch.py ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Inc. team.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Convert Donut checkpoints using the original `donut-python` library. URL: https://github.com/clovaai/donut"""
15
+
16
+ import argparse
17
+
18
+ import torch
19
+ from datasets import load_dataset
20
+ from donut import DonutModel
21
+
22
+ from transformers import (
23
+ DonutImageProcessor,
24
+ DonutProcessor,
25
+ DonutSwinConfig,
26
+ DonutSwinModel,
27
+ MBartConfig,
28
+ MBartForCausalLM,
29
+ VisionEncoderDecoderModel,
30
+ XLMRobertaTokenizerFast,
31
+ )
32
+
33
+
34
+ def get_configs(model):
35
+ original_config = model.config
36
+
37
+ encoder_config = DonutSwinConfig(
38
+ image_size=original_config.input_size,
39
+ patch_size=4,
40
+ depths=original_config.encoder_layer,
41
+ num_heads=[4, 8, 16, 32],
42
+ window_size=original_config.window_size,
43
+ embed_dim=128,
44
+ )
45
+ decoder_config = MBartConfig(
46
+ is_decoder=True,
47
+ is_encoder_decoder=False,
48
+ add_cross_attention=True,
49
+ decoder_layers=original_config.decoder_layer,
50
+ max_position_embeddings=original_config.max_position_embeddings,
51
+ vocab_size=len(
52
+ model.decoder.tokenizer
53
+ ), # several special tokens are added to the vocab of XLMRobertaTokenizer, see repo on the hub (added_tokens.json)
54
+ scale_embedding=True,
55
+ add_final_layer_norm=True,
56
+ )
57
+
58
+ return encoder_config, decoder_config
59
+
60
+
61
+ def rename_key(name):
62
+ if "encoder.model" in name:
63
+ name = name.replace("encoder.model", "encoder")
64
+ if "decoder.model" in name:
65
+ name = name.replace("decoder.model", "decoder")
66
+ if "patch_embed.proj" in name:
67
+ name = name.replace("patch_embed.proj", "embeddings.patch_embeddings.projection")
68
+ if "patch_embed.norm" in name:
69
+ name = name.replace("patch_embed.norm", "embeddings.norm")
70
+ if name.startswith("encoder"):
71
+ if "layers" in name:
72
+ name = "encoder." + name
73
+ if "attn.proj" in name:
74
+ name = name.replace("attn.proj", "attention.output.dense")
75
+ if "attn" in name and "mask" not in name:
76
+ name = name.replace("attn", "attention.self")
77
+ if "norm1" in name:
78
+ name = name.replace("norm1", "layernorm_before")
79
+ if "norm2" in name:
80
+ name = name.replace("norm2", "layernorm_after")
81
+ if "mlp.fc1" in name:
82
+ name = name.replace("mlp.fc1", "intermediate.dense")
83
+ if "mlp.fc2" in name:
84
+ name = name.replace("mlp.fc2", "output.dense")
85
+
86
+ if name == "encoder.norm.weight":
87
+ name = "encoder.layernorm.weight"
88
+ if name == "encoder.norm.bias":
89
+ name = "encoder.layernorm.bias"
90
+
91
+ return name
92
+
93
+
94
+ def convert_state_dict(orig_state_dict, model):
95
+ for key in orig_state_dict.copy():
96
+ val = orig_state_dict.pop(key)
97
+
98
+ if "qkv" in key:
99
+ key_split = key.split(".")
100
+ layer_num = int(key_split[3])
101
+ block_num = int(key_split[5])
102
+ dim = model.encoder.encoder.layers[layer_num].blocks[block_num].attention.self.all_head_size
103
+
104
+ if "weight" in key:
105
+ orig_state_dict[
106
+ f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.query.weight"
107
+ ] = val[:dim, :]
108
+ orig_state_dict[f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.key.weight"] = (
109
+ val[dim : dim * 2, :]
110
+ )
111
+ orig_state_dict[
112
+ f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.value.weight"
113
+ ] = val[-dim:, :]
114
+ else:
115
+ orig_state_dict[f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.query.bias"] = (
116
+ val[:dim]
117
+ )
118
+ orig_state_dict[f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.key.bias"] = (
119
+ val[dim : dim * 2]
120
+ )
121
+ orig_state_dict[f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.value.bias"] = (
122
+ val[-dim:]
123
+ )
124
+ elif "attn_mask" in key or key in ["encoder.model.norm.weight", "encoder.model.norm.bias"]:
125
+ # HuggingFace implementation doesn't use attn_mask buffer
126
+ # and model doesn't use final LayerNorms for the encoder
127
+ pass
128
+ else:
129
+ orig_state_dict[rename_key(key)] = val
130
+
131
+ return orig_state_dict
132
+
133
+
134
+ def convert_donut_checkpoint(model_name, pytorch_dump_folder_path=None, push_to_hub=False):
135
+ # load original model
136
+ original_model = DonutModel.from_pretrained(model_name).eval()
137
+
138
+ # load HuggingFace model
139
+ encoder_config, decoder_config = get_configs(original_model)
140
+ encoder = DonutSwinModel(encoder_config)
141
+ decoder = MBartForCausalLM(decoder_config)
142
+ model = VisionEncoderDecoderModel(encoder=encoder, decoder=decoder)
143
+ model.eval()
144
+
145
+ state_dict = original_model.state_dict()
146
+ new_state_dict = convert_state_dict(state_dict, model)
147
+ model.load_state_dict(new_state_dict)
148
+
149
+ # verify results on scanned document
150
+ dataset = load_dataset("hf-internal-testing/example-documents") # no-script
151
+ image = dataset["test"][0]["image"].convert("RGB")
152
+
153
+ tokenizer = XLMRobertaTokenizerFast.from_pretrained(model_name, from_slow=True)
154
+ image_processor = DonutImageProcessor(
155
+ do_align_long_axis=original_model.config.align_long_axis, size=original_model.config.input_size[::-1]
156
+ )
157
+ processor = DonutProcessor(image_processor, tokenizer)
158
+ pixel_values = processor(image, return_tensors="pt").pixel_values
159
+
160
+ if model_name == "naver-clova-ix/donut-base-finetuned-docvqa":
161
+ task_prompt = "<s_docvqa><s_question>{user_input}</s_question><s_answer>"
162
+ question = "When is the coffee break?"
163
+ task_prompt = task_prompt.replace("{user_input}", question)
164
+ elif model_name == "naver-clova-ix/donut-base-finetuned-rvlcdip":
165
+ task_prompt = "<s_rvlcdip>"
166
+ elif model_name in [
167
+ "naver-clova-ix/donut-base-finetuned-cord-v1",
168
+ "naver-clova-ix/donut-base-finetuned-cord-v1-2560",
169
+ ]:
170
+ task_prompt = "<s_cord>"
171
+ elif model_name == "naver-clova-ix/donut-base-finetuned-cord-v2":
172
+ task_prompt = "s_cord-v2>"
173
+ elif model_name == "naver-clova-ix/donut-base-finetuned-zhtrainticket":
174
+ task_prompt = "<s_zhtrainticket>"
175
+ elif model_name in ["naver-clova-ix/donut-proto", "naver-clova-ix/donut-base"]:
176
+ # use a random prompt
177
+ task_prompt = "hello world"
178
+ else:
179
+ raise ValueError("Model name not supported")
180
+ prompt_tensors = original_model.decoder.tokenizer(task_prompt, add_special_tokens=False, return_tensors="pt")[
181
+ "input_ids"
182
+ ]
183
+
184
+ original_patch_embed = original_model.encoder.model.patch_embed(pixel_values)
185
+ patch_embeddings, _ = model.encoder.embeddings(pixel_values)
186
+ assert torch.allclose(original_patch_embed, patch_embeddings, atol=1e-3)
187
+
188
+ # verify encoder hidden states
189
+ original_last_hidden_state = original_model.encoder(pixel_values)
190
+ last_hidden_state = model.encoder(pixel_values).last_hidden_state
191
+ assert torch.allclose(original_last_hidden_state, last_hidden_state, atol=1e-2)
192
+
193
+ # verify decoder hidden states
194
+ original_logits = original_model(pixel_values, prompt_tensors, None).logits
195
+ logits = model(pixel_values, decoder_input_ids=prompt_tensors).logits
196
+ assert torch.allclose(original_logits, logits, atol=1e-3)
197
+ print("Looks ok!")
198
+
199
+ if pytorch_dump_folder_path is not None:
200
+ print(f"Saving model and processor to {pytorch_dump_folder_path}")
201
+ model.save_pretrained(pytorch_dump_folder_path)
202
+ processor.save_pretrained(pytorch_dump_folder_path)
203
+
204
+ if push_to_hub:
205
+ model.push_to_hub("nielsr/" + model_name.split("/")[-1], commit_message="Update model")
206
+ processor.push_to_hub("nielsr/" + model_name.split("/")[-1], commit_message="Update model")
207
+
208
+
209
+ if __name__ == "__main__":
210
+ parser = argparse.ArgumentParser()
211
+ # Required parameters
212
+ parser.add_argument(
213
+ "--model_name",
214
+ default="naver-clova-ix/donut-base-finetuned-docvqa",
215
+ required=False,
216
+ type=str,
217
+ help="Name of the original model you'd like to convert.",
218
+ )
219
+ parser.add_argument(
220
+ "--pytorch_dump_folder_path",
221
+ default=None,
222
+ required=False,
223
+ type=str,
224
+ help="Path to the output PyTorch model directory.",
225
+ )
226
+ parser.add_argument(
227
+ "--push_to_hub",
228
+ action="store_true",
229
+ help="Whether or not to push the converted model and processor to the Hugging Face hub.",
230
+ )
231
+
232
+ args = parser.parse_args()
233
+ convert_donut_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)
third_party/transformers/src/transformers/models/donut/image_processing_donut.py ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Image processor class for Donut."""
15
+
16
+ import torch
17
+ from torchvision.transforms.v2 import functional as tvF
18
+
19
+ from ...image_processing_backends import TorchvisionBackend
20
+ from ...image_processing_utils import BatchFeature
21
+ from ...image_transforms import group_images_by_shape, reorder_images
22
+ from ...image_utils import (
23
+ IMAGENET_STANDARD_MEAN,
24
+ IMAGENET_STANDARD_STD,
25
+ ImageInput,
26
+ PILImageResampling,
27
+ SizeDict,
28
+ )
29
+ from ...processing_utils import ImagesKwargs, Unpack
30
+ from ...utils import TensorType, auto_docstring
31
+
32
+
33
+ class DonutImageProcessorKwargs(ImagesKwargs, total=False):
34
+ r"""
35
+ do_thumbnail (`bool`, *optional*, defaults to `self.do_thumbnail`):
36
+ Whether to resize the image using thumbnail method.
37
+ do_align_long_axis (`bool`, *optional*, defaults to `self.do_align_long_axis`):
38
+ Whether to align the long axis of the image with the long axis of `size` by rotating by 90 degrees.
39
+ """
40
+
41
+ do_thumbnail: bool
42
+ do_align_long_axis: bool
43
+
44
+
45
+ @auto_docstring
46
+ class DonutImageProcessor(TorchvisionBackend):
47
+ """Torchvision backend for Donut with align_long_axis, thumbnail, and pad_image."""
48
+
49
+ valid_kwargs = DonutImageProcessorKwargs
50
+
51
+ resample = PILImageResampling.BILINEAR
52
+ image_mean = IMAGENET_STANDARD_MEAN
53
+ image_std = IMAGENET_STANDARD_STD
54
+ size = {"height": 2560, "width": 1920}
55
+ do_resize = True
56
+ do_rescale = True
57
+ do_normalize = True
58
+ do_thumbnail = True
59
+ do_align_long_axis = False
60
+ do_pad = True
61
+
62
+ def __init__(self, **kwargs: Unpack[DonutImageProcessorKwargs]):
63
+ size = kwargs.pop("size", None)
64
+ if isinstance(size, (tuple, list)):
65
+ size = size[::-1]
66
+ if size is not None:
67
+ kwargs["size"] = size
68
+ super().__init__(**kwargs)
69
+
70
+ @auto_docstring
71
+ def preprocess(
72
+ self,
73
+ images: ImageInput,
74
+ **kwargs: Unpack[DonutImageProcessorKwargs],
75
+ ) -> BatchFeature:
76
+ kwargs = dict(kwargs)
77
+ if "size" in kwargs:
78
+ size = kwargs["size"]
79
+ if isinstance(size, (tuple, list)):
80
+ kwargs["size"] = size[::-1]
81
+ return super().preprocess(images, **kwargs)
82
+
83
+ def align_long_axis(
84
+ self,
85
+ image: "torch.Tensor",
86
+ size: SizeDict,
87
+ ) -> "torch.Tensor":
88
+ """Align the long axis of the image to the longest axis of the specified size."""
89
+ input_height, input_width = image.shape[-2:]
90
+ output_height, output_width = size.height, size.width
91
+
92
+ if (output_width < output_height and input_width > input_height) or (
93
+ output_width > output_height and input_width < input_height
94
+ ):
95
+ height_dim, width_dim = image.dim() - 2, image.dim() - 1
96
+ image = torch.rot90(image, 3, dims=[height_dim, width_dim])
97
+
98
+ return image
99
+
100
+ def pad_image(
101
+ self,
102
+ image: "torch.Tensor",
103
+ size: SizeDict,
104
+ random_padding: bool = False,
105
+ ) -> "torch.Tensor":
106
+ """Pad the image to the specified size."""
107
+ output_height, output_width = size.height, size.width
108
+ input_height, input_width = image.shape[-2:]
109
+
110
+ delta_width = output_width - input_width
111
+ delta_height = output_height - input_height
112
+
113
+ if random_padding:
114
+ pad_top = torch.randint(0, delta_height + 1, ()).item()
115
+ pad_left = torch.randint(0, delta_width + 1, ()).item()
116
+ else:
117
+ pad_top = delta_height // 2
118
+ pad_left = delta_width // 2
119
+
120
+ pad_bottom = delta_height - pad_top
121
+ pad_right = delta_width - pad_left
122
+
123
+ padding = (pad_left, pad_top, pad_right, pad_bottom)
124
+ return tvF.pad(image, padding)
125
+
126
+ def thumbnail(
127
+ self,
128
+ image: "torch.Tensor",
129
+ size: SizeDict,
130
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None" = None,
131
+ **kwargs,
132
+ ) -> "torch.Tensor":
133
+ """Resize the image to make a thumbnail."""
134
+ input_height, input_width = image.shape[-2:]
135
+ output_height, output_width = size.height, size.width
136
+
137
+ height = min(input_height, output_height)
138
+ width = min(input_width, output_width)
139
+
140
+ if height == input_height and width == input_width:
141
+ return image
142
+
143
+ if input_height > input_width:
144
+ width = int(input_width * height / input_height)
145
+ elif input_width > input_height:
146
+ height = int(input_height * width / input_width)
147
+
148
+ return super().resize(
149
+ image,
150
+ size=SizeDict(width=width, height=height),
151
+ resample=resample,
152
+ **kwargs,
153
+ )
154
+
155
+ def _preprocess(
156
+ self,
157
+ images: list["torch.Tensor"],
158
+ do_resize: bool,
159
+ size: SizeDict,
160
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None",
161
+ do_center_crop: bool,
162
+ crop_size: SizeDict,
163
+ do_rescale: bool,
164
+ rescale_factor: float,
165
+ do_normalize: bool,
166
+ image_mean: float | list[float] | None,
167
+ image_std: float | list[float] | None,
168
+ do_pad: bool | None,
169
+ pad_size: SizeDict | None,
170
+ disable_grouping: bool | None,
171
+ return_tensors: str | TensorType | None,
172
+ do_thumbnail: bool = True,
173
+ do_align_long_axis: bool = False,
174
+ **kwargs,
175
+ ) -> BatchFeature:
176
+ """Custom preprocessing for Donut."""
177
+ grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
178
+ resized_images_grouped = {}
179
+ for shape, stacked_images in grouped_images.items():
180
+ if do_align_long_axis:
181
+ stacked_images = self.align_long_axis(stacked_images, size)
182
+ if do_resize:
183
+ shortest_edge = min(size.height, size.width)
184
+ stacked_images = self.resize(stacked_images, SizeDict(shortest_edge=shortest_edge), resample)
185
+ if do_thumbnail:
186
+ stacked_images = self.thumbnail(stacked_images, size, resample)
187
+ if do_pad:
188
+ stacked_images = self.pad_image(stacked_images, size, random_padding=False)
189
+ resized_images_grouped[shape] = stacked_images
190
+ resized_images = reorder_images(resized_images_grouped, grouped_images_index)
191
+
192
+ grouped_images, grouped_images_index = group_images_by_shape(resized_images, disable_grouping=disable_grouping)
193
+ processed_images_grouped = {}
194
+ for shape, stacked_images in grouped_images.items():
195
+ if do_center_crop:
196
+ stacked_images = self.center_crop(stacked_images, crop_size)
197
+ stacked_images = self.rescale_and_normalize(
198
+ stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std
199
+ )
200
+ processed_images_grouped[shape] = stacked_images
201
+
202
+ processed_images = reorder_images(processed_images_grouped, grouped_images_index)
203
+ return BatchFeature(data={"pixel_values": processed_images}, tensor_type=return_tensors)
204
+
205
+
206
+ __all__ = ["DonutImageProcessor"]
third_party/transformers/src/transformers/models/donut/image_processing_pil_donut.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Image processor class for Donut."""
15
+
16
+ import numpy as np
17
+
18
+ from ...image_processing_backends import PilBackend
19
+ from ...image_processing_utils import BatchFeature
20
+ from ...image_utils import (
21
+ IMAGENET_STANDARD_MEAN,
22
+ IMAGENET_STANDARD_STD,
23
+ ImageInput,
24
+ PILImageResampling,
25
+ SizeDict,
26
+ get_image_size,
27
+ )
28
+ from ...processing_utils import ImagesKwargs, Unpack
29
+ from ...utils import TensorType, auto_docstring
30
+
31
+
32
+ # Adapted from transformers.models.donut.image_processing_donut.DonutImageProcessorKwargs
33
+ class DonutImageProcessorKwargs(ImagesKwargs, total=False):
34
+ r"""
35
+ do_thumbnail (`bool`, *optional*, defaults to `self.do_thumbnail`):
36
+ Whether to resize the image using thumbnail method.
37
+ do_align_long_axis (`bool`, *optional*, defaults to `self.do_align_long_axis`):
38
+ Whether to align the long axis of the image with the long axis of `size` by rotating by 90 degrees.
39
+ """
40
+
41
+ do_thumbnail: bool
42
+ do_align_long_axis: bool
43
+
44
+
45
+ @auto_docstring
46
+ class DonutImageProcessorPil(PilBackend):
47
+ """PIL backend for Donut with align_long_axis, thumbnail, and pad_image."""
48
+
49
+ valid_kwargs = DonutImageProcessorKwargs
50
+
51
+ resample = PILImageResampling.BILINEAR
52
+ image_mean = IMAGENET_STANDARD_MEAN
53
+ image_std = IMAGENET_STANDARD_STD
54
+ size = {"height": 2560, "width": 1920}
55
+ do_resize = True
56
+ do_rescale = True
57
+ do_normalize = True
58
+ do_thumbnail = True
59
+ do_align_long_axis = False
60
+ do_pad = True
61
+
62
+ def __init__(self, **kwargs: Unpack[DonutImageProcessorKwargs]):
63
+ size = kwargs.pop("size", None)
64
+ if isinstance(size, (tuple, list)):
65
+ size = size[::-1]
66
+ if size is not None:
67
+ kwargs["size"] = size
68
+ super().__init__(**kwargs)
69
+
70
+ @auto_docstring
71
+ def preprocess(
72
+ self,
73
+ images: ImageInput,
74
+ **kwargs: Unpack[DonutImageProcessorKwargs],
75
+ ) -> BatchFeature:
76
+ kwargs = dict(kwargs)
77
+ if "size" in kwargs:
78
+ size = kwargs["size"]
79
+ if isinstance(size, (tuple, list)):
80
+ kwargs["size"] = size[::-1]
81
+ return super().preprocess(images, **kwargs)
82
+
83
+ def align_long_axis(
84
+ self,
85
+ image: np.ndarray,
86
+ size: SizeDict,
87
+ ) -> np.ndarray:
88
+ """Align the long axis of the image to the longest axis of the specified size."""
89
+ from ...image_utils import ChannelDimension
90
+
91
+ input_height, input_width = get_image_size(image, channel_dim=ChannelDimension.FIRST)
92
+ output_height, output_width = size.height, size.width
93
+
94
+ if (output_width < output_height and input_width > input_height) or (
95
+ output_width > output_height and input_width < input_height
96
+ ):
97
+ image = np.rot90(image, 3, axes=(1, 2))
98
+
99
+ return image
100
+
101
+ def pad_image(
102
+ self,
103
+ image: np.ndarray,
104
+ size: SizeDict,
105
+ random_padding: bool = False,
106
+ ) -> np.ndarray:
107
+ """Pad the image to the specified size."""
108
+ from ...image_transforms import PaddingMode
109
+ from ...image_transforms import pad as np_pad
110
+ from ...image_utils import ChannelDimension
111
+
112
+ output_height, output_width = size.height, size.width
113
+ input_height, input_width = get_image_size(image, channel_dim=ChannelDimension.FIRST)
114
+
115
+ delta_width = output_width - input_width
116
+ delta_height = output_height - input_height
117
+
118
+ if random_padding:
119
+ pad_top = int(np.random.randint(low=0, high=delta_height + 1))
120
+ pad_left = int(np.random.randint(low=0, high=delta_width + 1))
121
+ else:
122
+ pad_top = delta_height // 2
123
+ pad_left = delta_width // 2
124
+
125
+ pad_bottom = delta_height - pad_top
126
+ pad_right = delta_width - pad_left
127
+
128
+ # pad() expects (height_pad, width_pad) and adds channel dimension
129
+ padding = ((pad_top, pad_bottom), (pad_left, pad_right))
130
+ return np_pad(
131
+ image,
132
+ padding,
133
+ mode=PaddingMode.CONSTANT,
134
+ constant_values=0,
135
+ data_format=ChannelDimension.FIRST,
136
+ input_data_format=ChannelDimension.FIRST,
137
+ )
138
+
139
+ def thumbnail(
140
+ self,
141
+ image: np.ndarray,
142
+ size: SizeDict,
143
+ resample: "PILImageResampling | None" = None,
144
+ **kwargs,
145
+ ) -> np.ndarray:
146
+ """Resize the image to make a thumbnail."""
147
+ from ...image_utils import ChannelDimension
148
+
149
+ input_height, input_width = get_image_size(image, channel_dim=ChannelDimension.FIRST)
150
+ output_height, output_width = size.height, size.width
151
+
152
+ height = min(input_height, output_height)
153
+ width = min(input_width, output_width)
154
+
155
+ if height == input_height and width == input_width:
156
+ return image
157
+
158
+ if input_height > input_width:
159
+ width = int(input_width * height / input_height)
160
+ elif input_width > input_height:
161
+ height = int(input_height * width / input_width)
162
+
163
+ return self.resize(
164
+ image,
165
+ size=SizeDict(width=width, height=height),
166
+ resample=resample or PILImageResampling.BICUBIC,
167
+ )
168
+
169
+ def _preprocess(
170
+ self,
171
+ images: list[np.ndarray],
172
+ do_resize: bool,
173
+ size: SizeDict,
174
+ resample: "PILImageResampling | None",
175
+ do_center_crop: bool,
176
+ crop_size: SizeDict,
177
+ do_rescale: bool,
178
+ rescale_factor: float,
179
+ do_normalize: bool,
180
+ image_mean: float | list[float] | None,
181
+ image_std: float | list[float] | None,
182
+ do_pad: bool | None,
183
+ pad_size: SizeDict | None,
184
+ return_tensors: str | TensorType | None,
185
+ do_thumbnail: bool = True,
186
+ do_align_long_axis: bool = False,
187
+ **kwargs,
188
+ ) -> BatchFeature:
189
+ """Custom preprocessing for Donut."""
190
+ processed_images = []
191
+ for image in images:
192
+ if do_align_long_axis:
193
+ image = self.align_long_axis(image, size)
194
+ if do_resize:
195
+ shortest_edge = min(size.height, size.width)
196
+ image = self.resize(image, SizeDict(shortest_edge=shortest_edge), resample)
197
+ if do_thumbnail:
198
+ image = self.thumbnail(image, size, resample)
199
+ if do_pad:
200
+ image = self.pad_image(image, size, random_padding=False)
201
+ if do_center_crop:
202
+ image = self.center_crop(image, crop_size)
203
+ if do_rescale:
204
+ image = self.rescale(image, rescale_factor)
205
+ if do_normalize:
206
+ image = self.normalize(image, image_mean, image_std)
207
+ processed_images.append(image)
208
+
209
+ return BatchFeature(data={"pixel_values": processed_images}, tensor_type=return_tensors)
210
+
211
+
212
+ __all__ = ["DonutImageProcessorPil"]
third_party/transformers/src/transformers/models/donut/modeling_donut_swin.py ADDED
@@ -0,0 +1,967 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """PyTorch Donut Swin Transformer model.
15
+
16
+ This implementation is identical to a regular Swin Transformer, without final layer norm on top of the final hidden
17
+ states."""
18
+
19
+ import collections.abc
20
+ import math
21
+ from dataclasses import dataclass
22
+
23
+ import torch
24
+ from torch import nn
25
+
26
+ from ... import initialization as init
27
+ from ...activations import ACT2FN
28
+ from ...modeling_layers import GradientCheckpointingLayer
29
+ from ...modeling_utils import PreTrainedModel
30
+ from ...utils import ModelOutput, auto_docstring, logging, torch_int
31
+ from .configuration_donut_swin import DonutSwinConfig
32
+
33
+
34
+ logger = logging.get_logger(__name__)
35
+
36
+
37
+ @dataclass
38
+ @auto_docstring(
39
+ custom_intro="""
40
+ DonutSwin encoder's outputs, with potential hidden states and attentions.
41
+ """
42
+ )
43
+ # Copied from transformers.models.swin.modeling_swin.SwinEncoderOutput with Swin->DonutSwin
44
+ class DonutSwinEncoderOutput(ModelOutput):
45
+ r"""
46
+ reshaped_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
47
+ Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of
48
+ shape `(batch_size, hidden_size, height, width)`.
49
+
50
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to
51
+ include the spatial dimensions.
52
+ """
53
+
54
+ last_hidden_state: torch.FloatTensor | None = None
55
+ hidden_states: tuple[torch.FloatTensor, ...] | None = None
56
+ attentions: tuple[torch.FloatTensor, ...] | None = None
57
+ reshaped_hidden_states: tuple[torch.FloatTensor, ...] | None = None
58
+
59
+
60
+ @dataclass
61
+ @auto_docstring(
62
+ custom_intro="""
63
+ DonutSwin model's outputs that also contains a pooling of the last hidden states.
64
+ """
65
+ )
66
+ # Copied from transformers.models.swin.modeling_swin.SwinModelOutput with Swin->DonutSwin
67
+ class DonutSwinModelOutput(ModelOutput):
68
+ r"""
69
+ pooler_output (`torch.FloatTensor` of shape `(batch_size, hidden_size)`, *optional*, returned when `add_pooling_layer=True` is passed):
70
+ Average pooling of the last layer hidden-state.
71
+ reshaped_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
72
+ Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of
73
+ shape `(batch_size, hidden_size, height, width)`.
74
+
75
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to
76
+ include the spatial dimensions.
77
+ """
78
+
79
+ last_hidden_state: torch.FloatTensor | None = None
80
+ pooler_output: torch.FloatTensor | None = None
81
+ hidden_states: tuple[torch.FloatTensor, ...] | None = None
82
+ attentions: tuple[torch.FloatTensor, ...] | None = None
83
+ reshaped_hidden_states: tuple[torch.FloatTensor, ...] | None = None
84
+
85
+
86
+ @dataclass
87
+ @auto_docstring(
88
+ custom_intro="""
89
+ DonutSwin outputs for image classification.
90
+ """
91
+ )
92
+ # Copied from transformers.models.swin.modeling_swin.SwinImageClassifierOutput with Swin->DonutSwin
93
+ class DonutSwinImageClassifierOutput(ModelOutput):
94
+ r"""
95
+ loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
96
+ Classification (or regression if config.num_labels==1) loss.
97
+ logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`):
98
+ Classification (or regression if config.num_labels==1) scores (before SoftMax).
99
+ reshaped_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
100
+ Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of
101
+ shape `(batch_size, hidden_size, height, width)`.
102
+
103
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to
104
+ include the spatial dimensions.
105
+ """
106
+
107
+ loss: torch.FloatTensor | None = None
108
+ logits: torch.FloatTensor | None = None
109
+ hidden_states: tuple[torch.FloatTensor, ...] | None = None
110
+ attentions: tuple[torch.FloatTensor, ...] | None = None
111
+ reshaped_hidden_states: tuple[torch.FloatTensor, ...] | None = None
112
+
113
+
114
+ # Copied from transformers.models.swin.modeling_swin.window_partition
115
+ def window_partition(input_feature, window_size):
116
+ """
117
+ Partitions the given input into windows.
118
+ """
119
+ batch_size, height, width, num_channels = input_feature.shape
120
+ input_feature = input_feature.view(
121
+ batch_size, height // window_size, window_size, width // window_size, window_size, num_channels
122
+ )
123
+ windows = input_feature.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, num_channels)
124
+ return windows
125
+
126
+
127
+ # Copied from transformers.models.swin.modeling_swin.window_reverse
128
+ def window_reverse(windows, window_size, height, width):
129
+ """
130
+ Merges windows to produce higher resolution features.
131
+ """
132
+ num_channels = windows.shape[-1]
133
+ windows = windows.view(-1, height // window_size, width // window_size, window_size, window_size, num_channels)
134
+ windows = windows.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, height, width, num_channels)
135
+ return windows
136
+
137
+
138
+ # Copied from transformers.models.swin.modeling_swin.SwinEmbeddings with Swin->DonutSwin
139
+ class DonutSwinEmbeddings(nn.Module):
140
+ """
141
+ Construct the patch and position embeddings. Optionally, also the mask token.
142
+ """
143
+
144
+ def __init__(self, config, use_mask_token=False):
145
+ super().__init__()
146
+
147
+ self.patch_embeddings = DonutSwinPatchEmbeddings(config)
148
+ num_patches = self.patch_embeddings.num_patches
149
+ self.patch_grid = self.patch_embeddings.grid_size
150
+ self.mask_token = nn.Parameter(torch.zeros(1, 1, config.embed_dim)) if use_mask_token else None
151
+
152
+ if config.use_absolute_embeddings:
153
+ self.position_embeddings = nn.Parameter(torch.zeros(1, num_patches + 1, config.embed_dim))
154
+ else:
155
+ self.position_embeddings = None
156
+
157
+ self.norm = nn.LayerNorm(config.embed_dim)
158
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
159
+ self.patch_size = config.patch_size
160
+ self.config = config
161
+
162
+ # Copied from transformers.models.vit.modeling_vit.ViTEmbeddings.interpolate_pos_encoding
163
+ def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor:
164
+ """
165
+ This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher resolution
166
+ images. This method is also adapted to support torch.jit tracing.
167
+
168
+ Adapted from:
169
+ - https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174-L194, and
170
+ - https://github.com/facebookresearch/dinov2/blob/e1277af2ba9496fbadf7aec6eba56e8d882d1e35/dinov2/models/vision_transformer.py#L179-L211
171
+ """
172
+
173
+ num_patches = embeddings.shape[1] - 1
174
+ num_positions = self.position_embeddings.shape[1] - 1
175
+
176
+ # always interpolate when tracing to ensure the exported model works for dynamic input shapes
177
+ if not torch.jit.is_tracing() and num_patches == num_positions and height == width:
178
+ return self.position_embeddings
179
+
180
+ class_pos_embed = self.position_embeddings[:, :1]
181
+ patch_pos_embed = self.position_embeddings[:, 1:]
182
+
183
+ dim = embeddings.shape[-1]
184
+
185
+ new_height = height // self.patch_size
186
+ new_width = width // self.patch_size
187
+
188
+ sqrt_num_positions = torch_int(num_positions**0.5)
189
+ patch_pos_embed = patch_pos_embed.reshape(1, sqrt_num_positions, sqrt_num_positions, dim)
190
+ patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2)
191
+
192
+ patch_pos_embed = nn.functional.interpolate(
193
+ patch_pos_embed,
194
+ size=(new_height, new_width),
195
+ mode="bicubic",
196
+ align_corners=False,
197
+ )
198
+
199
+ patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)
200
+
201
+ return torch.cat((class_pos_embed, patch_pos_embed), dim=1)
202
+
203
+ def forward(
204
+ self,
205
+ pixel_values: torch.FloatTensor | None,
206
+ bool_masked_pos: torch.BoolTensor | None = None,
207
+ interpolate_pos_encoding: bool = False,
208
+ ) -> tuple[torch.Tensor]:
209
+ _, num_channels, height, width = pixel_values.shape
210
+ embeddings, output_dimensions = self.patch_embeddings(pixel_values)
211
+ embeddings = self.norm(embeddings)
212
+ batch_size, seq_len, _ = embeddings.size()
213
+
214
+ if bool_masked_pos is not None:
215
+ mask_tokens = self.mask_token.expand(batch_size, seq_len, -1)
216
+ # replace the masked visual tokens by mask_tokens
217
+ mask = bool_masked_pos.unsqueeze(-1).type_as(mask_tokens)
218
+ embeddings = embeddings * (1.0 - mask) + mask_tokens * mask
219
+
220
+ if self.position_embeddings is not None:
221
+ if interpolate_pos_encoding:
222
+ embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width)
223
+ else:
224
+ embeddings = embeddings + self.position_embeddings
225
+
226
+ embeddings = self.dropout(embeddings)
227
+
228
+ return embeddings, output_dimensions
229
+
230
+
231
+ # Copied from transformers.models.swin.modeling_swin.SwinPatchEmbeddings with Swin->DonutSwin
232
+ class DonutSwinPatchEmbeddings(nn.Module):
233
+ """
234
+ This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial
235
+ `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a
236
+ Transformer.
237
+ """
238
+
239
+ def __init__(self, config):
240
+ super().__init__()
241
+ image_size, patch_size = config.image_size, config.patch_size
242
+ num_channels, hidden_size = config.num_channels, config.embed_dim
243
+ image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size)
244
+ patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size)
245
+ num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0])
246
+ self.image_size = image_size
247
+ self.patch_size = patch_size
248
+ self.num_channels = num_channels
249
+ self.num_patches = num_patches
250
+ self.grid_size = (image_size[0] // patch_size[0], image_size[1] // patch_size[1])
251
+
252
+ self.projection = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size)
253
+
254
+ def maybe_pad(self, pixel_values, height, width):
255
+ if width % self.patch_size[1] != 0:
256
+ pad_values = (0, self.patch_size[1] - width % self.patch_size[1])
257
+ pixel_values = nn.functional.pad(pixel_values, pad_values)
258
+ if height % self.patch_size[0] != 0:
259
+ pad_values = (0, 0, 0, self.patch_size[0] - height % self.patch_size[0])
260
+ pixel_values = nn.functional.pad(pixel_values, pad_values)
261
+ return pixel_values
262
+
263
+ def forward(self, pixel_values: torch.FloatTensor | None) -> tuple[torch.Tensor, tuple[int]]:
264
+ _, num_channels, height, width = pixel_values.shape
265
+ # pad the input to be divisible by self.patch_size, if needed
266
+ pixel_values = self.maybe_pad(pixel_values, height, width)
267
+ embeddings = self.projection(pixel_values)
268
+ _, _, height, width = embeddings.shape
269
+ output_dimensions = (height, width)
270
+ embeddings = embeddings.flatten(2).transpose(1, 2)
271
+
272
+ return embeddings, output_dimensions
273
+
274
+
275
+ # Copied from transformers.models.swin.modeling_swin.SwinPatchMerging
276
+ class DonutSwinPatchMerging(nn.Module):
277
+ """
278
+ Patch Merging Layer.
279
+
280
+ Args:
281
+ input_resolution (`tuple[int]`):
282
+ Resolution of input feature.
283
+ dim (`int`):
284
+ Number of input channels.
285
+ norm_layer (`nn.Module`, *optional*, defaults to `nn.LayerNorm`):
286
+ Normalization layer class.
287
+ """
288
+
289
+ def __init__(self, input_resolution: tuple[int], dim: int, norm_layer: nn.Module = nn.LayerNorm) -> None:
290
+ super().__init__()
291
+ self.input_resolution = input_resolution
292
+ self.dim = dim
293
+ self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False)
294
+ self.norm = norm_layer(4 * dim)
295
+
296
+ def maybe_pad(self, input_feature, height, width):
297
+ should_pad = (height % 2 == 1) or (width % 2 == 1)
298
+ if should_pad:
299
+ pad_values = (0, 0, 0, width % 2, 0, height % 2)
300
+ input_feature = nn.functional.pad(input_feature, pad_values)
301
+
302
+ return input_feature
303
+
304
+ def forward(self, input_feature: torch.Tensor, input_dimensions: tuple[int, int]) -> torch.Tensor:
305
+ height, width = input_dimensions
306
+ # `dim` is height * width
307
+ batch_size, dim, num_channels = input_feature.shape
308
+
309
+ input_feature = input_feature.view(batch_size, height, width, num_channels)
310
+ # pad input to be divisible by width and height, if needed
311
+ input_feature = self.maybe_pad(input_feature, height, width)
312
+ # [batch_size, height/2, width/2, num_channels]
313
+ input_feature_0 = input_feature[:, 0::2, 0::2, :]
314
+ # [batch_size, height/2, width/2, num_channels]
315
+ input_feature_1 = input_feature[:, 1::2, 0::2, :]
316
+ # [batch_size, height/2, width/2, num_channels]
317
+ input_feature_2 = input_feature[:, 0::2, 1::2, :]
318
+ # [batch_size, height/2, width/2, num_channels]
319
+ input_feature_3 = input_feature[:, 1::2, 1::2, :]
320
+ # batch_size height/2 width/2 4*num_channels
321
+ input_feature = torch.cat([input_feature_0, input_feature_1, input_feature_2, input_feature_3], -1)
322
+ input_feature = input_feature.view(batch_size, -1, 4 * num_channels) # batch_size height/2*width/2 4*C
323
+
324
+ input_feature = self.norm(input_feature)
325
+ input_feature = self.reduction(input_feature)
326
+
327
+ return input_feature
328
+
329
+
330
+ # Copied from transformers.models.beit.modeling_beit.drop_path
331
+ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = False) -> torch.Tensor:
332
+ """
333
+ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
334
+
335
+ """
336
+ if drop_prob == 0.0 or not training:
337
+ return input
338
+ keep_prob = 1 - drop_prob
339
+ shape = (input.shape[0],) + (1,) * (input.ndim - 1) # work with diff dim tensors, not just 2D ConvNets
340
+ random_tensor = keep_prob + torch.rand(shape, dtype=input.dtype, device=input.device)
341
+ random_tensor.floor_() # binarize
342
+ output = input.div(keep_prob) * random_tensor
343
+ return output
344
+
345
+
346
+ # Copied from transformers.models.swin.modeling_swin.SwinDropPath
347
+ class DonutSwinDropPath(nn.Module):
348
+ """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks)."""
349
+
350
+ def __init__(self, drop_prob: float | None = None) -> None:
351
+ super().__init__()
352
+ self.drop_prob = drop_prob
353
+
354
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
355
+ return drop_path(hidden_states, self.drop_prob, self.training)
356
+
357
+ def extra_repr(self) -> str:
358
+ return f"p={self.drop_prob}"
359
+
360
+
361
+ # Copied from transformers.models.swin.modeling_swin.SwinSelfAttention with Swin->DonutSwin
362
+ class DonutSwinSelfAttention(nn.Module):
363
+ def __init__(self, config, dim, num_heads, window_size):
364
+ super().__init__()
365
+ if dim % num_heads != 0:
366
+ raise ValueError(
367
+ f"The hidden size ({dim}) is not a multiple of the number of attention heads ({num_heads})"
368
+ )
369
+
370
+ self.num_attention_heads = num_heads
371
+ self.attention_head_size = int(dim / num_heads)
372
+ self.all_head_size = self.num_attention_heads * self.attention_head_size
373
+ self.window_size = (
374
+ window_size if isinstance(window_size, collections.abc.Iterable) else (window_size, window_size)
375
+ )
376
+
377
+ self.relative_position_bias_table = nn.Parameter(
378
+ torch.zeros((2 * self.window_size[0] - 1) * (2 * self.window_size[1] - 1), num_heads)
379
+ )
380
+
381
+ self.register_buffer("relative_position_index", self.create_relative_position_index())
382
+
383
+ self.query = nn.Linear(self.all_head_size, self.all_head_size, bias=config.qkv_bias)
384
+ self.key = nn.Linear(self.all_head_size, self.all_head_size, bias=config.qkv_bias)
385
+ self.value = nn.Linear(self.all_head_size, self.all_head_size, bias=config.qkv_bias)
386
+
387
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
388
+
389
+ def forward(
390
+ self,
391
+ hidden_states: torch.Tensor,
392
+ attention_mask: torch.FloatTensor | None = None,
393
+ output_attentions: bool | None = False,
394
+ ) -> tuple[torch.Tensor]:
395
+ batch_size, dim, num_channels = hidden_states.shape
396
+ hidden_shape = (batch_size, dim, -1, self.attention_head_size)
397
+
398
+ query_layer = self.query(hidden_states).view(hidden_shape).transpose(1, 2)
399
+ key_layer = self.key(hidden_states).view(hidden_shape).transpose(1, 2)
400
+ value_layer = self.value(hidden_states).view(hidden_shape).transpose(1, 2)
401
+
402
+ # Take the dot product between "query" and "key" to get the raw attention scores.
403
+ attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))
404
+
405
+ attention_scores = attention_scores / math.sqrt(self.attention_head_size)
406
+
407
+ relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)]
408
+ relative_position_bias = relative_position_bias.view(
409
+ self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1
410
+ )
411
+
412
+ relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous()
413
+ attention_scores = attention_scores + relative_position_bias.unsqueeze(0)
414
+
415
+ if attention_mask is not None:
416
+ # Apply the attention mask is (precomputed for all layers in DonutSwinModel forward() function)
417
+ mask_shape = attention_mask.shape[0]
418
+ attention_scores = attention_scores.view(
419
+ batch_size // mask_shape, mask_shape, self.num_attention_heads, dim, dim
420
+ )
421
+ attention_scores = attention_scores + attention_mask.unsqueeze(1).unsqueeze(0)
422
+ attention_scores = attention_scores.view(-1, self.num_attention_heads, dim, dim)
423
+
424
+ # Normalize the attention scores to probabilities.
425
+ attention_probs = nn.functional.softmax(attention_scores, dim=-1)
426
+
427
+ # This is actually dropping out entire tokens to attend to, which might
428
+ # seem a bit unusual, but is taken from the original Transformer paper.
429
+ attention_probs = self.dropout(attention_probs)
430
+
431
+ context_layer = torch.matmul(attention_probs, value_layer)
432
+ context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
433
+ new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
434
+ context_layer = context_layer.view(new_context_layer_shape)
435
+
436
+ outputs = (context_layer, attention_probs) if output_attentions else (context_layer,)
437
+
438
+ return outputs
439
+
440
+ def create_relative_position_index(self):
441
+ # get pair-wise relative position index for each token inside the window
442
+ coords_h = torch.arange(self.window_size[0])
443
+ coords_w = torch.arange(self.window_size[1])
444
+ coords = torch.stack(torch.meshgrid([coords_h, coords_w], indexing="ij"))
445
+ coords_flatten = torch.flatten(coords, 1)
446
+ relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]
447
+ relative_coords = relative_coords.permute(1, 2, 0).contiguous()
448
+ relative_coords[:, :, 0] += self.window_size[0] - 1
449
+ relative_coords[:, :, 1] += self.window_size[1] - 1
450
+ relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1
451
+ relative_position_index = relative_coords.sum(-1)
452
+ return relative_position_index
453
+
454
+
455
+ # Copied from transformers.models.swin.modeling_swin.SwinSelfOutput
456
+ class DonutSwinSelfOutput(nn.Module):
457
+ def __init__(self, config, dim):
458
+ super().__init__()
459
+ self.dense = nn.Linear(dim, dim)
460
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
461
+
462
+ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
463
+ hidden_states = self.dense(hidden_states)
464
+ hidden_states = self.dropout(hidden_states)
465
+
466
+ return hidden_states
467
+
468
+
469
+ # Copied from transformers.models.swin.modeling_swin.SwinAttention with Swin->DonutSwin
470
+ class DonutSwinAttention(nn.Module):
471
+ def __init__(self, config, dim, num_heads, window_size):
472
+ super().__init__()
473
+ self.self = DonutSwinSelfAttention(config, dim, num_heads, window_size)
474
+ self.output = DonutSwinSelfOutput(config, dim)
475
+
476
+ def forward(
477
+ self,
478
+ hidden_states: torch.Tensor,
479
+ attention_mask: torch.FloatTensor | None = None,
480
+ output_attentions: bool | None = False,
481
+ ) -> tuple[torch.Tensor]:
482
+ self_outputs = self.self(hidden_states, attention_mask, output_attentions)
483
+ attention_output = self.output(self_outputs[0], hidden_states)
484
+ outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them
485
+ return outputs
486
+
487
+
488
+ # Copied from transformers.models.swin.modeling_swin.SwinIntermediate
489
+ class DonutSwinIntermediate(nn.Module):
490
+ def __init__(self, config, dim):
491
+ super().__init__()
492
+ self.dense = nn.Linear(dim, int(config.mlp_ratio * dim))
493
+ if isinstance(config.hidden_act, str):
494
+ self.intermediate_act_fn = ACT2FN[config.hidden_act]
495
+ else:
496
+ self.intermediate_act_fn = config.hidden_act
497
+
498
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
499
+ hidden_states = self.dense(hidden_states)
500
+ hidden_states = self.intermediate_act_fn(hidden_states)
501
+ return hidden_states
502
+
503
+
504
+ # Copied from transformers.models.swin.modeling_swin.SwinOutput
505
+ class DonutSwinOutput(nn.Module):
506
+ def __init__(self, config, dim):
507
+ super().__init__()
508
+ self.dense = nn.Linear(int(config.mlp_ratio * dim), dim)
509
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
510
+
511
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
512
+ hidden_states = self.dense(hidden_states)
513
+ hidden_states = self.dropout(hidden_states)
514
+ return hidden_states
515
+
516
+
517
+ # Copied from transformers.models.swin.modeling_swin.SwinLayer with Swin->DonutSwin
518
+ class DonutSwinLayer(nn.Module):
519
+ def __init__(self, config, dim, input_resolution, num_heads, drop_path_rate=0.0, shift_size=0):
520
+ super().__init__()
521
+ self.chunk_size_feed_forward = config.chunk_size_feed_forward
522
+ self.shift_size = shift_size
523
+ self.window_size = config.window_size
524
+ self.input_resolution = input_resolution
525
+ self.layernorm_before = nn.LayerNorm(dim, eps=config.layer_norm_eps)
526
+ self.attention = DonutSwinAttention(config, dim, num_heads, window_size=self.window_size)
527
+ self.drop_path = DonutSwinDropPath(drop_path_rate) if drop_path_rate > 0.0 else nn.Identity()
528
+ self.layernorm_after = nn.LayerNorm(dim, eps=config.layer_norm_eps)
529
+ self.intermediate = DonutSwinIntermediate(config, dim)
530
+ self.output = DonutSwinOutput(config, dim)
531
+
532
+ def set_shift_and_window_size(self, input_resolution):
533
+ if min(input_resolution) <= self.window_size:
534
+ # if window size is larger than input resolution, we don't partition windows
535
+ self.shift_size = torch_int(0)
536
+ self.window_size = (
537
+ torch.min(torch.tensor(input_resolution)) if torch.jit.is_tracing() else min(input_resolution)
538
+ )
539
+
540
+ def get_attn_mask(self, height, width, dtype, device):
541
+ if self.shift_size > 0:
542
+ # calculate attention mask for SW-MSA
543
+ img_mask = torch.zeros((1, height, width, 1), dtype=dtype, device=device)
544
+ height_slices = (
545
+ slice(0, -self.window_size),
546
+ slice(-self.window_size, -self.shift_size),
547
+ slice(-self.shift_size, None),
548
+ )
549
+ width_slices = (
550
+ slice(0, -self.window_size),
551
+ slice(-self.window_size, -self.shift_size),
552
+ slice(-self.shift_size, None),
553
+ )
554
+ count = 0
555
+ for height_slice in height_slices:
556
+ for width_slice in width_slices:
557
+ img_mask[:, height_slice, width_slice, :] = count
558
+ count += 1
559
+
560
+ mask_windows = window_partition(img_mask, self.window_size)
561
+ mask_windows = mask_windows.view(-1, self.window_size * self.window_size)
562
+ attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2)
563
+ attn_mask = attn_mask.masked_fill(attn_mask != 0, -100.0).masked_fill(attn_mask == 0, 0.0)
564
+ else:
565
+ attn_mask = None
566
+ return attn_mask
567
+
568
+ def maybe_pad(self, hidden_states, height, width):
569
+ pad_right = (self.window_size - width % self.window_size) % self.window_size
570
+ pad_bottom = (self.window_size - height % self.window_size) % self.window_size
571
+ pad_values = (0, 0, 0, pad_right, 0, pad_bottom)
572
+ hidden_states = nn.functional.pad(hidden_states, pad_values)
573
+ return hidden_states, pad_values
574
+
575
+ def forward(
576
+ self,
577
+ hidden_states: torch.Tensor,
578
+ input_dimensions: tuple[int, int],
579
+ output_attentions: bool | None = False,
580
+ always_partition: bool | None = False,
581
+ ) -> tuple[torch.Tensor, torch.Tensor]:
582
+ if not always_partition:
583
+ self.set_shift_and_window_size(input_dimensions)
584
+ else:
585
+ pass
586
+ height, width = input_dimensions
587
+ batch_size, _, channels = hidden_states.size()
588
+ shortcut = hidden_states
589
+
590
+ hidden_states = self.layernorm_before(hidden_states)
591
+
592
+ hidden_states = hidden_states.view(batch_size, height, width, channels)
593
+
594
+ # pad hidden_states to multiples of window size
595
+ hidden_states, pad_values = self.maybe_pad(hidden_states, height, width)
596
+
597
+ _, height_pad, width_pad, _ = hidden_states.shape
598
+ # cyclic shift
599
+ if self.shift_size > 0:
600
+ shifted_hidden_states = torch.roll(hidden_states, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2))
601
+ else:
602
+ shifted_hidden_states = hidden_states
603
+
604
+ # partition windows
605
+ hidden_states_windows = window_partition(shifted_hidden_states, self.window_size)
606
+ hidden_states_windows = hidden_states_windows.view(-1, self.window_size * self.window_size, channels)
607
+ attn_mask = self.get_attn_mask(
608
+ height_pad, width_pad, dtype=hidden_states.dtype, device=hidden_states_windows.device
609
+ )
610
+
611
+ attention_outputs = self.attention(hidden_states_windows, attn_mask, output_attentions=output_attentions)
612
+
613
+ attention_output = attention_outputs[0]
614
+
615
+ attention_windows = attention_output.view(-1, self.window_size, self.window_size, channels)
616
+ shifted_windows = window_reverse(attention_windows, self.window_size, height_pad, width_pad)
617
+
618
+ # reverse cyclic shift
619
+ if self.shift_size > 0:
620
+ attention_windows = torch.roll(shifted_windows, shifts=(self.shift_size, self.shift_size), dims=(1, 2))
621
+ else:
622
+ attention_windows = shifted_windows
623
+
624
+ was_padded = pad_values[3] > 0 or pad_values[5] > 0
625
+ if was_padded:
626
+ attention_windows = attention_windows[:, :height, :width, :].contiguous()
627
+
628
+ attention_windows = attention_windows.view(batch_size, height * width, channels)
629
+
630
+ hidden_states = shortcut + self.drop_path(attention_windows)
631
+
632
+ layer_output = self.layernorm_after(hidden_states)
633
+ layer_output = self.intermediate(layer_output)
634
+ layer_output = hidden_states + self.output(layer_output)
635
+
636
+ layer_outputs = (layer_output, attention_outputs[1]) if output_attentions else (layer_output,)
637
+ return layer_outputs
638
+
639
+
640
+ # Copied from transformers.models.swin.modeling_swin.SwinStage with Swin->DonutSwin
641
+ class DonutSwinStage(GradientCheckpointingLayer):
642
+ def __init__(self, config, dim, input_resolution, depth, num_heads, drop_path, downsample):
643
+ super().__init__()
644
+ self.config = config
645
+ self.dim = dim
646
+ self.blocks = nn.ModuleList(
647
+ [
648
+ DonutSwinLayer(
649
+ config=config,
650
+ dim=dim,
651
+ input_resolution=input_resolution,
652
+ num_heads=num_heads,
653
+ drop_path_rate=drop_path[i],
654
+ shift_size=0 if (i % 2 == 0) else config.window_size // 2,
655
+ )
656
+ for i in range(depth)
657
+ ]
658
+ )
659
+
660
+ # patch merging layer
661
+ if downsample is not None:
662
+ self.downsample = downsample(input_resolution, dim=dim, norm_layer=nn.LayerNorm)
663
+ else:
664
+ self.downsample = None
665
+
666
+ self.pointing = False
667
+
668
+ def forward(
669
+ self,
670
+ hidden_states: torch.Tensor,
671
+ input_dimensions: tuple[int, int],
672
+ output_attentions: bool | None = False,
673
+ always_partition: bool | None = False,
674
+ ) -> tuple[torch.Tensor]:
675
+ height, width = input_dimensions
676
+ for i, layer_module in enumerate(self.blocks):
677
+ layer_outputs = layer_module(hidden_states, input_dimensions, output_attentions, always_partition)
678
+
679
+ hidden_states = layer_outputs[0]
680
+
681
+ hidden_states_before_downsampling = hidden_states
682
+ if self.downsample is not None:
683
+ height_downsampled, width_downsampled = (height + 1) // 2, (width + 1) // 2
684
+ output_dimensions = (height, width, height_downsampled, width_downsampled)
685
+ hidden_states = self.downsample(hidden_states_before_downsampling, input_dimensions)
686
+ else:
687
+ output_dimensions = (height, width, height, width)
688
+
689
+ stage_outputs = (hidden_states, hidden_states_before_downsampling, output_dimensions)
690
+
691
+ if output_attentions:
692
+ stage_outputs += layer_outputs[1:]
693
+ return stage_outputs
694
+
695
+
696
+ # Copied from transformers.models.swin.modeling_swin.SwinEncoder with Swin->DonutSwin
697
+ class DonutSwinEncoder(nn.Module):
698
+ def __init__(self, config, grid_size):
699
+ super().__init__()
700
+ self.num_layers = len(config.depths)
701
+ self.config = config
702
+ dpr = [x.item() for x in torch.linspace(0, config.drop_path_rate, sum(config.depths), device="cpu")]
703
+ self.layers = nn.ModuleList(
704
+ [
705
+ DonutSwinStage(
706
+ config=config,
707
+ dim=int(config.embed_dim * 2**i_layer),
708
+ input_resolution=(grid_size[0] // (2**i_layer), grid_size[1] // (2**i_layer)),
709
+ depth=config.depths[i_layer],
710
+ num_heads=config.num_heads[i_layer],
711
+ drop_path=dpr[sum(config.depths[:i_layer]) : sum(config.depths[: i_layer + 1])],
712
+ downsample=DonutSwinPatchMerging if (i_layer < self.num_layers - 1) else None,
713
+ )
714
+ for i_layer in range(self.num_layers)
715
+ ]
716
+ )
717
+
718
+ self.gradient_checkpointing = False
719
+
720
+ def forward(
721
+ self,
722
+ hidden_states: torch.Tensor,
723
+ input_dimensions: tuple[int, int],
724
+ output_attentions: bool | None = False,
725
+ output_hidden_states: bool | None = False,
726
+ output_hidden_states_before_downsampling: bool | None = False,
727
+ always_partition: bool | None = False,
728
+ return_dict: bool | None = True,
729
+ ) -> tuple | DonutSwinEncoderOutput:
730
+ all_hidden_states = () if output_hidden_states else None
731
+ all_reshaped_hidden_states = () if output_hidden_states else None
732
+ all_self_attentions = () if output_attentions else None
733
+
734
+ if output_hidden_states:
735
+ batch_size, _, hidden_size = hidden_states.shape
736
+ # rearrange b (h w) c -> b c h w
737
+ reshaped_hidden_state = hidden_states.view(batch_size, *input_dimensions, hidden_size)
738
+ reshaped_hidden_state = reshaped_hidden_state.permute(0, 3, 1, 2)
739
+ all_hidden_states += (hidden_states,)
740
+ all_reshaped_hidden_states += (reshaped_hidden_state,)
741
+
742
+ for i, layer_module in enumerate(self.layers):
743
+ layer_outputs = layer_module(hidden_states, input_dimensions, output_attentions, always_partition)
744
+
745
+ hidden_states = layer_outputs[0]
746
+ hidden_states_before_downsampling = layer_outputs[1]
747
+ output_dimensions = layer_outputs[2]
748
+
749
+ input_dimensions = (output_dimensions[-2], output_dimensions[-1])
750
+
751
+ if output_hidden_states and output_hidden_states_before_downsampling:
752
+ batch_size, _, hidden_size = hidden_states_before_downsampling.shape
753
+ # rearrange b (h w) c -> b c h w
754
+ # here we use the original (not downsampled) height and width
755
+ reshaped_hidden_state = hidden_states_before_downsampling.view(
756
+ batch_size, *(output_dimensions[0], output_dimensions[1]), hidden_size
757
+ )
758
+ reshaped_hidden_state = reshaped_hidden_state.permute(0, 3, 1, 2)
759
+ all_hidden_states += (hidden_states_before_downsampling,)
760
+ all_reshaped_hidden_states += (reshaped_hidden_state,)
761
+ elif output_hidden_states and not output_hidden_states_before_downsampling:
762
+ batch_size, _, hidden_size = hidden_states.shape
763
+ # rearrange b (h w) c -> b c h w
764
+ reshaped_hidden_state = hidden_states.view(batch_size, *input_dimensions, hidden_size)
765
+ reshaped_hidden_state = reshaped_hidden_state.permute(0, 3, 1, 2)
766
+ all_hidden_states += (hidden_states,)
767
+ all_reshaped_hidden_states += (reshaped_hidden_state,)
768
+
769
+ if output_attentions:
770
+ all_self_attentions += layer_outputs[3:]
771
+
772
+ if not return_dict:
773
+ return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None)
774
+
775
+ return DonutSwinEncoderOutput(
776
+ last_hidden_state=hidden_states,
777
+ hidden_states=all_hidden_states,
778
+ attentions=all_self_attentions,
779
+ reshaped_hidden_states=all_reshaped_hidden_states,
780
+ )
781
+
782
+
783
+ @auto_docstring
784
+ # Copied from transformers.models.swin.modeling_swin.SwinPreTrainedModel with Swin->DonutSwin,swin->donut
785
+ class DonutSwinPreTrainedModel(PreTrainedModel):
786
+ config: DonutSwinConfig
787
+ base_model_prefix = "donut"
788
+ main_input_name = "pixel_values"
789
+ input_modalities = ("image",)
790
+ supports_gradient_checkpointing = True
791
+ _no_split_modules = ["DonutSwinStage"]
792
+
793
+ @torch.no_grad()
794
+ def _init_weights(self, module):
795
+ """Initialize the weights"""
796
+ super()._init_weights(module)
797
+ if isinstance(module, DonutSwinEmbeddings):
798
+ if module.mask_token is not None:
799
+ init.zeros_(module.mask_token)
800
+ if module.position_embeddings is not None:
801
+ init.zeros_(module.position_embeddings)
802
+ elif isinstance(module, DonutSwinSelfAttention):
803
+ init.zeros_(module.relative_position_bias_table)
804
+ init.copy_(module.relative_position_index, module.create_relative_position_index())
805
+
806
+
807
+ @auto_docstring
808
+ class DonutSwinModel(DonutSwinPreTrainedModel):
809
+ def __init__(self, config, add_pooling_layer=True, use_mask_token=False):
810
+ r"""
811
+ add_pooling_layer (bool, *optional*, defaults to `True`):
812
+ Whether to add a pooling layer
813
+ use_mask_token (`bool`, *optional*, defaults to `False`):
814
+ Whether to use a mask token for masked image modeling.
815
+ """
816
+ super().__init__(config)
817
+ self.config = config
818
+ self.num_layers = len(config.depths)
819
+ self.num_features = int(config.embed_dim * 2 ** (self.num_layers - 1))
820
+
821
+ self.embeddings = DonutSwinEmbeddings(config, use_mask_token=use_mask_token)
822
+ self.encoder = DonutSwinEncoder(config, self.embeddings.patch_grid)
823
+
824
+ self.pooler = nn.AdaptiveAvgPool1d(1) if add_pooling_layer else None
825
+
826
+ # Initialize weights and apply final processing
827
+ self.post_init()
828
+
829
+ def get_input_embeddings(self):
830
+ return self.embeddings.patch_embeddings
831
+
832
+ @auto_docstring
833
+ def forward(
834
+ self,
835
+ pixel_values: torch.FloatTensor | None = None,
836
+ bool_masked_pos: torch.BoolTensor | None = None,
837
+ output_attentions: bool | None = None,
838
+ output_hidden_states: bool | None = None,
839
+ interpolate_pos_encoding: bool = False,
840
+ return_dict: bool | None = None,
841
+ **kwargs,
842
+ ) -> tuple | DonutSwinModelOutput:
843
+ r"""
844
+ bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`):
845
+ Boolean masked positions. Indicates which patches are masked (1) and which aren't (0).
846
+ """
847
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
848
+ output_hidden_states = (
849
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
850
+ )
851
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
852
+
853
+ if pixel_values is None:
854
+ raise ValueError("You have to specify pixel_values")
855
+
856
+ embedding_output, input_dimensions = self.embeddings(
857
+ pixel_values, bool_masked_pos=bool_masked_pos, interpolate_pos_encoding=interpolate_pos_encoding
858
+ )
859
+
860
+ encoder_outputs = self.encoder(
861
+ embedding_output,
862
+ input_dimensions,
863
+ output_attentions=output_attentions,
864
+ output_hidden_states=output_hidden_states,
865
+ return_dict=return_dict,
866
+ )
867
+
868
+ sequence_output = encoder_outputs[0]
869
+
870
+ pooled_output = None
871
+ if self.pooler is not None:
872
+ pooled_output = self.pooler(sequence_output.transpose(1, 2))
873
+ pooled_output = torch.flatten(pooled_output, 1)
874
+
875
+ if not return_dict:
876
+ output = (sequence_output, pooled_output) + encoder_outputs[1:]
877
+
878
+ return output
879
+
880
+ return DonutSwinModelOutput(
881
+ last_hidden_state=sequence_output,
882
+ pooler_output=pooled_output,
883
+ hidden_states=encoder_outputs.hidden_states,
884
+ attentions=encoder_outputs.attentions,
885
+ reshaped_hidden_states=encoder_outputs.reshaped_hidden_states,
886
+ )
887
+
888
+
889
+ @auto_docstring(
890
+ custom_intro="""
891
+ DonutSwin Model transformer with an image classification head on top (a linear layer on top of the final hidden state of
892
+ the [CLS] token) e.g. for ImageNet.
893
+
894
+ <Tip>
895
+
896
+ Note that it's possible to fine-tune DonutSwin on higher resolution images than the ones it has been trained on, by
897
+ setting `interpolate_pos_encoding` to `True` in the forward of the model. This will interpolate the pre-trained
898
+ position embeddings to the higher resolution.
899
+
900
+ </Tip>
901
+ """
902
+ )
903
+ # Copied from transformers.models.swin.modeling_swin.SwinForImageClassification with Swin->DonutSwin,swin->donut
904
+ class DonutSwinForImageClassification(DonutSwinPreTrainedModel):
905
+ def __init__(self, config):
906
+ super().__init__(config)
907
+
908
+ self.num_labels = config.num_labels
909
+ self.donut = DonutSwinModel(config)
910
+
911
+ # Classifier head
912
+ self.classifier = (
913
+ nn.Linear(self.donut.num_features, config.num_labels) if config.num_labels > 0 else nn.Identity()
914
+ )
915
+
916
+ # Initialize weights and apply final processing
917
+ self.post_init()
918
+
919
+ @auto_docstring
920
+ def forward(
921
+ self,
922
+ pixel_values: torch.FloatTensor | None = None,
923
+ labels: torch.LongTensor | None = None,
924
+ output_attentions: bool | None = None,
925
+ output_hidden_states: bool | None = None,
926
+ interpolate_pos_encoding: bool = False,
927
+ return_dict: bool | None = None,
928
+ **kwargs,
929
+ ) -> tuple | DonutSwinImageClassifierOutput:
930
+ r"""
931
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
932
+ Labels for computing the image classification/regression loss. Indices should be in `[0, ...,
933
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
934
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
935
+ """
936
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
937
+
938
+ outputs = self.donut(
939
+ pixel_values,
940
+ output_attentions=output_attentions,
941
+ output_hidden_states=output_hidden_states,
942
+ interpolate_pos_encoding=interpolate_pos_encoding,
943
+ return_dict=return_dict,
944
+ )
945
+
946
+ pooled_output = outputs[1]
947
+
948
+ logits = self.classifier(pooled_output)
949
+
950
+ loss = None
951
+ if labels is not None:
952
+ loss = self.loss_function(labels, logits, self.config)
953
+
954
+ if not return_dict:
955
+ output = (logits,) + outputs[2:]
956
+ return ((loss,) + output) if loss is not None else output
957
+
958
+ return DonutSwinImageClassifierOutput(
959
+ loss=loss,
960
+ logits=logits,
961
+ hidden_states=outputs.hidden_states,
962
+ attentions=outputs.attentions,
963
+ reshaped_hidden_states=outputs.reshaped_hidden_states,
964
+ )
965
+
966
+
967
+ __all__ = ["DonutSwinModel", "DonutSwinPreTrainedModel", "DonutSwinForImageClassification"]
third_party/transformers/src/transformers/models/donut/processing_donut.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Inc. team.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """
15
+ Processor class for Donut.
16
+ """
17
+
18
+ import re
19
+
20
+ from ...image_utils import ImageInput
21
+ from ...processing_utils import ProcessingKwargs, ProcessorMixin, Unpack
22
+ from ...tokenization_utils_base import PreTokenizedInput, TextInput
23
+ from ...utils import auto_docstring, logging
24
+
25
+
26
+ class DonutProcessorKwargs(ProcessingKwargs, total=False):
27
+ _defaults = {}
28
+
29
+
30
+ logger = logging.get_logger(__name__)
31
+
32
+
33
+ @auto_docstring
34
+ class DonutProcessor(ProcessorMixin):
35
+ def __init__(self, image_processor=None, tokenizer=None, **kwargs):
36
+ super().__init__(image_processor, tokenizer)
37
+
38
+ @auto_docstring
39
+ def __call__(
40
+ self,
41
+ images: ImageInput | None = None,
42
+ text: str | list[str] | TextInput | PreTokenizedInput | None = None,
43
+ **kwargs: Unpack[DonutProcessorKwargs],
44
+ ):
45
+ if images is None and text is None:
46
+ raise ValueError("You need to specify either an `images` or `text` input to process.")
47
+
48
+ output_kwargs = self._merge_kwargs(
49
+ DonutProcessorKwargs,
50
+ tokenizer_init_kwargs=self.tokenizer.init_kwargs,
51
+ **kwargs,
52
+ )
53
+
54
+ if images is not None:
55
+ inputs = self.image_processor(images, **output_kwargs["images_kwargs"])
56
+ if text is not None:
57
+ if images is not None:
58
+ output_kwargs["text_kwargs"].setdefault("add_special_tokens", False)
59
+ encodings = self.tokenizer(text, **output_kwargs["text_kwargs"])
60
+
61
+ if text is None:
62
+ return inputs
63
+ elif images is None:
64
+ return encodings
65
+ else:
66
+ inputs["labels"] = encodings["input_ids"] # for BC
67
+ inputs["input_ids"] = encodings["input_ids"]
68
+ return inputs
69
+
70
+ @property
71
+ def model_input_names(self):
72
+ image_processor_input_names = self.image_processor.model_input_names
73
+
74
+ return list(image_processor_input_names + ["input_ids", "labels"])
75
+
76
+ def token2json(self, tokens, is_inner_value=False, added_vocab=None):
77
+ """
78
+ Convert a (generated) token sequence into an ordered JSON format.
79
+ """
80
+ if added_vocab is None:
81
+ added_vocab = self.tokenizer.get_added_vocab()
82
+
83
+ output = {}
84
+
85
+ while tokens:
86
+ # We want r"<s_(.*?)>" but without ReDOS risk, so do it manually in two parts
87
+ potential_start = re.search(r"<s_", tokens, re.IGNORECASE)
88
+ if potential_start is None:
89
+ break
90
+ start_token = tokens[potential_start.start() :]
91
+ if ">" not in start_token:
92
+ break
93
+ start_token = start_token[: start_token.index(">") + 1]
94
+ key = start_token[len("<s_") : -len(">")]
95
+ key_escaped = re.escape(key)
96
+
97
+ end_token = re.search(rf"</s_{key_escaped}>", tokens, re.IGNORECASE)
98
+ if end_token is None:
99
+ tokens = tokens.replace(start_token, "")
100
+ else:
101
+ end_token = end_token.group()
102
+ start_token_escaped = re.escape(start_token)
103
+ end_token_escaped = re.escape(end_token)
104
+ content = re.search(
105
+ f"{start_token_escaped}(.*?){end_token_escaped}", tokens, re.IGNORECASE | re.DOTALL
106
+ )
107
+ if content is not None:
108
+ content = content.group(1).strip()
109
+ if r"<s_" in content and r"</s_" in content: # non-leaf node
110
+ value = self.token2json(content, is_inner_value=True, added_vocab=added_vocab)
111
+ if value:
112
+ if len(value) == 1:
113
+ value = value[0]
114
+ output[key] = value
115
+ else: # leaf nodes
116
+ output[key] = []
117
+ for leaf in content.split(r"<sep/>"):
118
+ leaf = leaf.strip()
119
+ if leaf in added_vocab and leaf[0] == "<" and leaf[-2:] == "/>":
120
+ leaf = leaf[1:-2] # for categorical special tokens
121
+ output[key].append(leaf)
122
+ if len(output[key]) == 1:
123
+ output[key] = output[key][0]
124
+
125
+ tokens = tokens[tokens.find(end_token) + len(end_token) :].strip()
126
+ if tokens[:6] == r"<sep/>": # non-leaf nodes
127
+ return [output] + self.token2json(tokens[6:], is_inner_value=True, added_vocab=added_vocab)
128
+
129
+ if output:
130
+ return [output] if is_inner_value else output
131
+ else:
132
+ return [] if is_inner_value else {"text_sequence": tokens}
133
+
134
+
135
+ __all__ = ["DonutProcessor"]
third_party/transformers/src/transformers/models/ibert/__init__.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from .configuration_ibert import *
22
+ from .modeling_ibert import *
23
+ else:
24
+ import sys
25
+
26
+ _file = globals()["__file__"]
27
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/ibert/configuration_ibert.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The I-BERT Authors (Sehoon Kim, Amir Gholami, Zhewei Yao,
2
+ # Michael Mahoney, Kurt Keutzer - UC Berkeley) and The HuggingFace Inc. team.
3
+ # Copyright (c) 20121, NVIDIA CORPORATION. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """I-BERT configuration"""
17
+
18
+ from huggingface_hub.dataclasses import strict
19
+
20
+ from ...configuration_utils import PreTrainedConfig
21
+ from ...utils import auto_docstring
22
+
23
+
24
+ @auto_docstring(checkpoint="kssteven/ibert-roberta-base")
25
+ @strict
26
+ class IBertConfig(PreTrainedConfig):
27
+ r"""
28
+ type_vocab_size (`int`, *optional*, defaults to 2):
29
+ The vocabulary size of the `token_type_ids` passed when calling [`IBertModel`]
30
+ quant_mode (`bool`, *optional*, defaults to `False`):
31
+ Whether to quantize the model or not.
32
+ force_dequant (`str`, *optional*, defaults to `"none"`):
33
+ Force dequantize specific nonlinear layer. Dequantized layers are then executed with full precision.
34
+ `"none"`, `"gelu"`, `"softmax"`, `"layernorm"` and `"nonlinear"` are supported. As default, it is set as
35
+ `"none"`, which does not dequantize any layers. Please specify `"gelu"`, `"softmax"`, or `"layernorm"` to
36
+ dequantize GELU, Softmax, or LayerNorm, respectively. `"nonlinear"` will dequantize all nonlinear layers,
37
+ i.e., GELU, Softmax, and LayerNorm.
38
+ """
39
+
40
+ model_type = "ibert"
41
+
42
+ vocab_size: int = 30522
43
+ hidden_size: int = 768
44
+ num_hidden_layers: int = 12
45
+ num_attention_heads: int = 12
46
+ intermediate_size: int = 3072
47
+ hidden_act: str = "gelu"
48
+ hidden_dropout_prob: float | int = 0.1
49
+ attention_probs_dropout_prob: float | int = 0.1
50
+ max_position_embeddings: int = 512
51
+ type_vocab_size: int = 2
52
+ initializer_range: float = 0.02
53
+ layer_norm_eps: float = 1e-12
54
+ pad_token_id: int | None = 1
55
+ bos_token_id: int | None = 0
56
+ eos_token_id: int | list[int] | None = 2
57
+ quant_mode: bool = False
58
+ force_dequant: str = "none"
59
+
60
+
61
+ __all__ = ["IBertConfig"]
third_party/transformers/src/transformers/models/ibert/modeling_ibert.py ADDED
@@ -0,0 +1,1201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The I-BERT Authors (Sehoon Kim, Amir Gholami, Zhewei Yao,
2
+ # Michael Mahoney, Kurt Keutzer - UC Berkeley) and The HuggingFace Inc. team.
3
+ # Copyright (c) 20121, NVIDIA CORPORATION. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ """PyTorch I-BERT model."""
18
+
19
+ import math
20
+
21
+ import torch
22
+ from torch import nn
23
+ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
24
+
25
+ from ... import initialization as init
26
+ from ...activations import gelu
27
+ from ...modeling_outputs import (
28
+ BaseModelOutputWithPastAndCrossAttentions,
29
+ BaseModelOutputWithPoolingAndCrossAttentions,
30
+ MaskedLMOutput,
31
+ MultipleChoiceModelOutput,
32
+ QuestionAnsweringModelOutput,
33
+ SequenceClassifierOutput,
34
+ TokenClassifierOutput,
35
+ )
36
+ from ...modeling_utils import PreTrainedModel
37
+ from ...utils import auto_docstring, logging
38
+ from .configuration_ibert import IBertConfig
39
+ from .quant_modules import IntGELU, IntLayerNorm, IntSoftmax, QuantAct, QuantEmbedding, QuantLinear
40
+
41
+
42
+ logger = logging.get_logger(__name__)
43
+
44
+
45
+ class IBertEmbeddings(nn.Module):
46
+ """
47
+ Same as BertEmbeddings with a tiny tweak for positional embeddings indexing.
48
+ """
49
+
50
+ def __init__(self, config):
51
+ super().__init__()
52
+ self.quant_mode = config.quant_mode
53
+ self.embedding_bit = 8
54
+ self.embedding_act_bit = 16
55
+ self.act_bit = 8
56
+ self.ln_input_bit = 22
57
+ self.ln_output_bit = 32
58
+
59
+ self.word_embeddings = QuantEmbedding(
60
+ config.vocab_size,
61
+ config.hidden_size,
62
+ padding_idx=config.pad_token_id,
63
+ weight_bit=self.embedding_bit,
64
+ quant_mode=self.quant_mode,
65
+ )
66
+ self.token_type_embeddings = QuantEmbedding(
67
+ config.type_vocab_size, config.hidden_size, weight_bit=self.embedding_bit, quant_mode=self.quant_mode
68
+ )
69
+
70
+ # position_ids (1, len position emb) is contiguous in memory and exported when serialized
71
+ self.register_buffer(
72
+ "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
73
+ )
74
+
75
+ # End copy
76
+ self.padding_idx = config.pad_token_id
77
+ self.position_embeddings = QuantEmbedding(
78
+ config.max_position_embeddings,
79
+ config.hidden_size,
80
+ padding_idx=self.padding_idx,
81
+ weight_bit=self.embedding_bit,
82
+ quant_mode=self.quant_mode,
83
+ )
84
+
85
+ # Integer-only addition between embeddings
86
+ self.embeddings_act1 = QuantAct(self.embedding_act_bit, quant_mode=self.quant_mode)
87
+ self.embeddings_act2 = QuantAct(self.embedding_act_bit, quant_mode=self.quant_mode)
88
+
89
+ self.LayerNorm = IntLayerNorm(
90
+ config.hidden_size,
91
+ eps=config.layer_norm_eps,
92
+ output_bit=self.ln_output_bit,
93
+ quant_mode=self.quant_mode,
94
+ force_dequant=config.force_dequant,
95
+ )
96
+ self.output_activation = QuantAct(self.act_bit, quant_mode=self.quant_mode)
97
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
98
+
99
+ def forward(
100
+ self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0
101
+ ):
102
+ if position_ids is None:
103
+ if input_ids is not None:
104
+ # Create the position ids from the input token ids. Any padded tokens remain padded.
105
+ position_ids = create_position_ids_from_input_ids(
106
+ input_ids, self.padding_idx, past_key_values_length
107
+ ).to(input_ids.device)
108
+ else:
109
+ position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds)
110
+
111
+ if input_ids is not None:
112
+ input_shape = input_ids.size()
113
+ else:
114
+ input_shape = inputs_embeds.size()[:-1]
115
+
116
+ if token_type_ids is None:
117
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
118
+
119
+ if inputs_embeds is None:
120
+ inputs_embeds, inputs_embeds_scaling_factor = self.word_embeddings(input_ids)
121
+ else:
122
+ inputs_embeds_scaling_factor = None
123
+ token_type_embeddings, token_type_embeddings_scaling_factor = self.token_type_embeddings(token_type_ids)
124
+
125
+ embeddings, embeddings_scaling_factor = self.embeddings_act1(
126
+ inputs_embeds,
127
+ inputs_embeds_scaling_factor,
128
+ identity=token_type_embeddings,
129
+ identity_scaling_factor=token_type_embeddings_scaling_factor,
130
+ )
131
+
132
+ position_embeddings, position_embeddings_scaling_factor = self.position_embeddings(position_ids)
133
+ embeddings, embeddings_scaling_factor = self.embeddings_act1(
134
+ embeddings,
135
+ embeddings_scaling_factor,
136
+ identity=position_embeddings,
137
+ identity_scaling_factor=position_embeddings_scaling_factor,
138
+ )
139
+
140
+ embeddings, embeddings_scaling_factor = self.LayerNorm(embeddings, embeddings_scaling_factor)
141
+ embeddings = self.dropout(embeddings)
142
+ embeddings, embeddings_scaling_factor = self.output_activation(embeddings, embeddings_scaling_factor)
143
+ return embeddings, embeddings_scaling_factor
144
+
145
+ def create_position_ids_from_inputs_embeds(self, inputs_embeds):
146
+ """
147
+ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids.
148
+
149
+ Args:
150
+ inputs_embeds: torch.Tensor
151
+
152
+ Returns: torch.Tensor
153
+ """
154
+ input_shape = inputs_embeds.size()[:-1]
155
+ sequence_length = input_shape[1]
156
+
157
+ position_ids = torch.arange(
158
+ self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device
159
+ )
160
+ return position_ids.unsqueeze(0).expand(input_shape)
161
+
162
+
163
+ class IBertSelfAttention(nn.Module):
164
+ def __init__(self, config):
165
+ super().__init__()
166
+ if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
167
+ raise ValueError(
168
+ f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
169
+ f"heads ({config.num_attention_heads})"
170
+ )
171
+ self.quant_mode = config.quant_mode
172
+ self.weight_bit = 8
173
+ self.bias_bit = 32
174
+ self.act_bit = 8
175
+
176
+ self.num_attention_heads = config.num_attention_heads
177
+ self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
178
+ self.all_head_size = self.num_attention_heads * self.attention_head_size
179
+
180
+ # Q, K, V Linear layers
181
+ self.query = QuantLinear(
182
+ config.hidden_size,
183
+ self.all_head_size,
184
+ bias=True,
185
+ weight_bit=self.weight_bit,
186
+ bias_bit=self.bias_bit,
187
+ quant_mode=self.quant_mode,
188
+ per_channel=True,
189
+ )
190
+ self.key = QuantLinear(
191
+ config.hidden_size,
192
+ self.all_head_size,
193
+ bias=True,
194
+ weight_bit=self.weight_bit,
195
+ bias_bit=self.bias_bit,
196
+ quant_mode=self.quant_mode,
197
+ per_channel=True,
198
+ )
199
+ self.value = QuantLinear(
200
+ config.hidden_size,
201
+ self.all_head_size,
202
+ bias=True,
203
+ weight_bit=self.weight_bit,
204
+ bias_bit=self.bias_bit,
205
+ quant_mode=self.quant_mode,
206
+ per_channel=True,
207
+ )
208
+
209
+ # Requantization (32bit -> 8bit) for Q, K, V activations
210
+ self.query_activation = QuantAct(self.act_bit, quant_mode=self.quant_mode)
211
+ self.key_activation = QuantAct(self.act_bit, quant_mode=self.quant_mode)
212
+ self.value_activation = QuantAct(self.act_bit, quant_mode=self.quant_mode)
213
+ self.output_activation = QuantAct(self.act_bit, quant_mode=self.quant_mode)
214
+
215
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
216
+
217
+ self.softmax = IntSoftmax(self.act_bit, quant_mode=self.quant_mode, force_dequant=config.force_dequant)
218
+
219
+ def forward(
220
+ self,
221
+ hidden_states,
222
+ hidden_states_scaling_factor,
223
+ attention_mask=None,
224
+ output_attentions=False,
225
+ ):
226
+ # Projection
227
+ mixed_query_layer, mixed_query_layer_scaling_factor = self.query(hidden_states, hidden_states_scaling_factor)
228
+ mixed_key_layer, mixed_key_layer_scaling_factor = self.key(hidden_states, hidden_states_scaling_factor)
229
+ mixed_value_layer, mixed_value_layer_scaling_factor = self.value(hidden_states, hidden_states_scaling_factor)
230
+
231
+ # Requantization
232
+ query_layer, query_layer_scaling_factor = self.query_activation(
233
+ mixed_query_layer, mixed_query_layer_scaling_factor
234
+ )
235
+ key_layer, key_layer_scaling_factor = self.key_activation(mixed_key_layer, mixed_key_layer_scaling_factor)
236
+ value_layer, value_layer_scaling_factor = self.value_activation(
237
+ mixed_value_layer, mixed_value_layer_scaling_factor
238
+ )
239
+
240
+ # Transpose
241
+ batch_size, seq_length, _ = hidden_states.shape
242
+ query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose(
243
+ 1, 2
244
+ )
245
+ key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose(1, 2)
246
+ value_layer = value_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose(
247
+ 1, 2
248
+ )
249
+
250
+ # Take the dot product between "query" and "key" to get the raw attention scores.
251
+ attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))
252
+ scale = math.sqrt(self.attention_head_size)
253
+ attention_scores = attention_scores / scale
254
+ if self.quant_mode:
255
+ attention_scores_scaling_factor = query_layer_scaling_factor * key_layer_scaling_factor / scale
256
+ else:
257
+ attention_scores_scaling_factor = None
258
+
259
+ if attention_mask is not None:
260
+ # Apply the attention mask is (precomputed for all layers in IBertModel forward() function)
261
+ attention_scores = attention_scores + attention_mask
262
+
263
+ # Normalize the attention scores to probabilities.
264
+ attention_probs, attention_probs_scaling_factor = self.softmax(
265
+ attention_scores, attention_scores_scaling_factor
266
+ )
267
+
268
+ # This is actually dropping out entire tokens to attend to, which might
269
+ # seem a bit unusual, but is taken from the original Transformer paper.
270
+ attention_probs = self.dropout(attention_probs)
271
+
272
+ context_layer = torch.matmul(attention_probs, value_layer)
273
+ if attention_probs_scaling_factor is not None:
274
+ context_layer_scaling_factor = attention_probs_scaling_factor * value_layer_scaling_factor
275
+ else:
276
+ context_layer_scaling_factor = None
277
+
278
+ context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
279
+ new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
280
+ context_layer = context_layer.view(*new_context_layer_shape)
281
+
282
+ # requantization: 32-bit -> 8-bit
283
+ context_layer, context_layer_scaling_factor = self.output_activation(
284
+ context_layer, context_layer_scaling_factor
285
+ )
286
+
287
+ outputs = (context_layer, attention_probs) if output_attentions else (context_layer,)
288
+ output_scaling_factor = (
289
+ (context_layer_scaling_factor, attention_probs_scaling_factor)
290
+ if output_attentions
291
+ else (context_layer_scaling_factor,)
292
+ )
293
+
294
+ return outputs, output_scaling_factor
295
+
296
+
297
+ class IBertSelfOutput(nn.Module):
298
+ def __init__(self, config):
299
+ super().__init__()
300
+ self.quant_mode = config.quant_mode
301
+ self.act_bit = 8
302
+ self.weight_bit = 8
303
+ self.bias_bit = 32
304
+ self.ln_input_bit = 22
305
+ self.ln_output_bit = 32
306
+
307
+ self.dense = QuantLinear(
308
+ config.hidden_size,
309
+ config.hidden_size,
310
+ bias=True,
311
+ weight_bit=self.weight_bit,
312
+ bias_bit=self.bias_bit,
313
+ quant_mode=self.quant_mode,
314
+ per_channel=True,
315
+ )
316
+ self.ln_input_act = QuantAct(self.ln_input_bit, quant_mode=self.quant_mode)
317
+ self.LayerNorm = IntLayerNorm(
318
+ config.hidden_size,
319
+ eps=config.layer_norm_eps,
320
+ output_bit=self.ln_output_bit,
321
+ quant_mode=self.quant_mode,
322
+ force_dequant=config.force_dequant,
323
+ )
324
+ self.output_activation = QuantAct(self.act_bit, quant_mode=self.quant_mode)
325
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
326
+
327
+ def forward(self, hidden_states, hidden_states_scaling_factor, input_tensor, input_tensor_scaling_factor):
328
+ hidden_states, hidden_states_scaling_factor = self.dense(hidden_states, hidden_states_scaling_factor)
329
+ hidden_states = self.dropout(hidden_states)
330
+ hidden_states, hidden_states_scaling_factor = self.ln_input_act(
331
+ hidden_states,
332
+ hidden_states_scaling_factor,
333
+ identity=input_tensor,
334
+ identity_scaling_factor=input_tensor_scaling_factor,
335
+ )
336
+ hidden_states, hidden_states_scaling_factor = self.LayerNorm(hidden_states, hidden_states_scaling_factor)
337
+
338
+ hidden_states, hidden_states_scaling_factor = self.output_activation(
339
+ hidden_states, hidden_states_scaling_factor
340
+ )
341
+ return hidden_states, hidden_states_scaling_factor
342
+
343
+
344
+ class IBertAttention(nn.Module):
345
+ def __init__(self, config):
346
+ super().__init__()
347
+ self.quant_mode = config.quant_mode
348
+ self.self = IBertSelfAttention(config)
349
+ self.output = IBertSelfOutput(config)
350
+
351
+ def forward(
352
+ self,
353
+ hidden_states,
354
+ hidden_states_scaling_factor,
355
+ attention_mask=None,
356
+ output_attentions=False,
357
+ ):
358
+ self_outputs, self_outputs_scaling_factor = self.self(
359
+ hidden_states,
360
+ hidden_states_scaling_factor,
361
+ attention_mask,
362
+ output_attentions,
363
+ )
364
+ attention_output, attention_output_scaling_factor = self.output(
365
+ self_outputs[0], self_outputs_scaling_factor[0], hidden_states, hidden_states_scaling_factor
366
+ )
367
+ outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them
368
+ outputs_scaling_factor = (attention_output_scaling_factor,) + self_outputs_scaling_factor[1:]
369
+ return outputs, outputs_scaling_factor
370
+
371
+
372
+ class IBertIntermediate(nn.Module):
373
+ def __init__(self, config):
374
+ super().__init__()
375
+ self.quant_mode = config.quant_mode
376
+ self.act_bit = 8
377
+ self.weight_bit = 8
378
+ self.bias_bit = 32
379
+ self.dense = QuantLinear(
380
+ config.hidden_size,
381
+ config.intermediate_size,
382
+ bias=True,
383
+ weight_bit=self.weight_bit,
384
+ bias_bit=self.bias_bit,
385
+ quant_mode=self.quant_mode,
386
+ per_channel=True,
387
+ )
388
+ if config.hidden_act != "gelu":
389
+ raise ValueError("I-BERT only supports 'gelu' for `config.hidden_act`")
390
+ self.intermediate_act_fn = IntGELU(quant_mode=self.quant_mode, force_dequant=config.force_dequant)
391
+ self.output_activation = QuantAct(self.act_bit, quant_mode=self.quant_mode)
392
+
393
+ def forward(self, hidden_states, hidden_states_scaling_factor):
394
+ hidden_states, hidden_states_scaling_factor = self.dense(hidden_states, hidden_states_scaling_factor)
395
+ hidden_states, hidden_states_scaling_factor = self.intermediate_act_fn(
396
+ hidden_states, hidden_states_scaling_factor
397
+ )
398
+
399
+ # Requantization: 32bit -> 8-bit
400
+ hidden_states, hidden_states_scaling_factor = self.output_activation(
401
+ hidden_states, hidden_states_scaling_factor
402
+ )
403
+ return hidden_states, hidden_states_scaling_factor
404
+
405
+
406
+ class IBertOutput(nn.Module):
407
+ def __init__(self, config):
408
+ super().__init__()
409
+ self.quant_mode = config.quant_mode
410
+ self.act_bit = 8
411
+ self.weight_bit = 8
412
+ self.bias_bit = 32
413
+ self.ln_input_bit = 22
414
+ self.ln_output_bit = 32
415
+
416
+ self.dense = QuantLinear(
417
+ config.intermediate_size,
418
+ config.hidden_size,
419
+ bias=True,
420
+ weight_bit=self.weight_bit,
421
+ bias_bit=self.bias_bit,
422
+ quant_mode=self.quant_mode,
423
+ per_channel=True,
424
+ )
425
+ self.ln_input_act = QuantAct(self.ln_input_bit, quant_mode=self.quant_mode)
426
+ self.LayerNorm = IntLayerNorm(
427
+ config.hidden_size,
428
+ eps=config.layer_norm_eps,
429
+ output_bit=self.ln_output_bit,
430
+ quant_mode=self.quant_mode,
431
+ force_dequant=config.force_dequant,
432
+ )
433
+ self.output_activation = QuantAct(self.act_bit, quant_mode=self.quant_mode)
434
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
435
+
436
+ def forward(self, hidden_states, hidden_states_scaling_factor, input_tensor, input_tensor_scaling_factor):
437
+ hidden_states, hidden_states_scaling_factor = self.dense(hidden_states, hidden_states_scaling_factor)
438
+ hidden_states = self.dropout(hidden_states)
439
+ hidden_states, hidden_states_scaling_factor = self.ln_input_act(
440
+ hidden_states,
441
+ hidden_states_scaling_factor,
442
+ identity=input_tensor,
443
+ identity_scaling_factor=input_tensor_scaling_factor,
444
+ )
445
+ hidden_states, hidden_states_scaling_factor = self.LayerNorm(hidden_states, hidden_states_scaling_factor)
446
+
447
+ hidden_states, hidden_states_scaling_factor = self.output_activation(
448
+ hidden_states, hidden_states_scaling_factor
449
+ )
450
+ return hidden_states, hidden_states_scaling_factor
451
+
452
+
453
+ class IBertLayer(nn.Module):
454
+ def __init__(self, config):
455
+ super().__init__()
456
+ self.quant_mode = config.quant_mode
457
+ self.act_bit = 8
458
+
459
+ self.seq_len_dim = 1
460
+ self.attention = IBertAttention(config)
461
+ self.intermediate = IBertIntermediate(config)
462
+ self.output = IBertOutput(config)
463
+
464
+ self.pre_intermediate_act = QuantAct(self.act_bit, quant_mode=self.quant_mode)
465
+ self.pre_output_act = QuantAct(self.act_bit, quant_mode=self.quant_mode)
466
+
467
+ def forward(
468
+ self,
469
+ hidden_states,
470
+ hidden_states_scaling_factor,
471
+ attention_mask=None,
472
+ output_attentions=False,
473
+ ):
474
+ self_attention_outputs, self_attention_outputs_scaling_factor = self.attention(
475
+ hidden_states,
476
+ hidden_states_scaling_factor,
477
+ attention_mask,
478
+ output_attentions=output_attentions,
479
+ )
480
+ attention_output = self_attention_outputs[0]
481
+ attention_output_scaling_factor = self_attention_outputs_scaling_factor[0]
482
+
483
+ outputs = self_attention_outputs[1:] # add self attentions if we output attention weights
484
+
485
+ layer_output, layer_output_scaling_factor = self.feed_forward_chunk(
486
+ attention_output, attention_output_scaling_factor
487
+ )
488
+ outputs = (layer_output,) + outputs
489
+
490
+ return outputs
491
+
492
+ def feed_forward_chunk(self, attention_output, attention_output_scaling_factor):
493
+ attention_output, attention_output_scaling_factor = self.pre_intermediate_act(
494
+ attention_output, attention_output_scaling_factor
495
+ )
496
+ intermediate_output, intermediate_output_scaling_factor = self.intermediate(
497
+ attention_output, attention_output_scaling_factor
498
+ )
499
+
500
+ intermediate_output, intermediate_output_scaling_factor = self.pre_output_act(
501
+ intermediate_output, intermediate_output_scaling_factor
502
+ )
503
+ layer_output, layer_output_scaling_factor = self.output(
504
+ intermediate_output, intermediate_output_scaling_factor, attention_output, attention_output_scaling_factor
505
+ )
506
+ return layer_output, layer_output_scaling_factor
507
+
508
+
509
+ class IBertEncoder(nn.Module):
510
+ def __init__(self, config):
511
+ super().__init__()
512
+ self.config = config
513
+ self.quant_mode = config.quant_mode
514
+ self.layer = nn.ModuleList([IBertLayer(config) for _ in range(config.num_hidden_layers)])
515
+
516
+ def forward(
517
+ self,
518
+ hidden_states,
519
+ hidden_states_scaling_factor,
520
+ attention_mask=None,
521
+ output_attentions=False,
522
+ output_hidden_states=False,
523
+ return_dict=True,
524
+ ):
525
+ all_hidden_states = () if output_hidden_states else None
526
+ all_self_attentions = () if output_attentions else None
527
+ all_cross_attentions = None # `config.add_cross_attention` is not supported
528
+
529
+ for i, layer_module in enumerate(self.layer):
530
+ if output_hidden_states:
531
+ all_hidden_states = all_hidden_states + (hidden_states,)
532
+
533
+ layer_outputs = layer_module(
534
+ hidden_states,
535
+ hidden_states_scaling_factor,
536
+ attention_mask,
537
+ output_attentions,
538
+ )
539
+
540
+ hidden_states = layer_outputs[0]
541
+ if output_attentions:
542
+ all_self_attentions = all_self_attentions + (layer_outputs[1],)
543
+
544
+ if output_hidden_states:
545
+ all_hidden_states = all_hidden_states + (hidden_states,)
546
+
547
+ if not return_dict:
548
+ return tuple(
549
+ v
550
+ for v in [
551
+ hidden_states,
552
+ all_hidden_states,
553
+ all_self_attentions,
554
+ all_cross_attentions,
555
+ ]
556
+ if v is not None
557
+ )
558
+ return BaseModelOutputWithPastAndCrossAttentions(
559
+ last_hidden_state=hidden_states,
560
+ hidden_states=all_hidden_states,
561
+ attentions=all_self_attentions,
562
+ cross_attentions=all_cross_attentions,
563
+ )
564
+
565
+
566
+ class IBertPooler(nn.Module):
567
+ def __init__(self, config):
568
+ super().__init__()
569
+ self.quant_mode = config.quant_mode
570
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
571
+ self.activation = nn.Tanh()
572
+
573
+ def forward(self, hidden_states):
574
+ # We "pool" the model by simply taking the hidden state corresponding
575
+ # to the first token.
576
+ first_token_tensor = hidden_states[:, 0]
577
+ pooled_output = self.dense(first_token_tensor)
578
+ pooled_output = self.activation(pooled_output)
579
+ return pooled_output
580
+
581
+
582
+ @auto_docstring
583
+ class IBertPreTrainedModel(PreTrainedModel):
584
+ config: IBertConfig
585
+ base_model_prefix = "ibert"
586
+
587
+ @torch.no_grad()
588
+ def _init_weights(self, module):
589
+ """Initialize the weights"""
590
+ if isinstance(module, (QuantLinear, nn.Linear)):
591
+ init.normal_(module.weight, mean=0.0, std=self.config.initializer_range)
592
+ if module.bias is not None:
593
+ init.zeros_(module.bias)
594
+ if getattr(module, "weight_integer", None) is not None:
595
+ init.zeros_(module.weight_integer)
596
+ init.zeros_(module.fc_scaling_factor)
597
+ if getattr(module, "bias_integer", None) is not None:
598
+ init.zeros_(module.bias_integer)
599
+ elif isinstance(module, (QuantEmbedding, nn.Embedding)):
600
+ init.normal_(module.weight, mean=0.0, std=self.config.initializer_range)
601
+ # Here we need the check explicitly, as we slice the weight in the `zeros_` call, so it looses the flag
602
+ if module.padding_idx is not None and not getattr(module.weight, "_is_hf_initialized", False):
603
+ init.zeros_(module.weight[module.padding_idx])
604
+ if getattr(module, "weight_scaling_factor", None) is not None:
605
+ init.zeros_(module.weight_scaling_factor)
606
+ init.zeros_(module.weight_integer)
607
+ elif isinstance(module, (IntLayerNorm, nn.LayerNorm)):
608
+ init.zeros_(module.bias)
609
+ init.ones_(module.weight)
610
+ if getattr(module, "shift", None) is not None:
611
+ init.zeros_(module.shift)
612
+ elif isinstance(module, IBertLMHead):
613
+ init.zeros_(module.bias)
614
+ elif isinstance(module, IBertEmbeddings):
615
+ init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
616
+ elif isinstance(module, QuantAct):
617
+ init.constant_(module.x_min, -1e-5)
618
+ init.constant_(module.x_max, 1e-5)
619
+ init.zeros_(module.act_scaling_factor)
620
+
621
+ def resize_token_embeddings(self, new_num_tokens=None):
622
+ raise NotImplementedError("`resize_token_embeddings` is not supported for I-BERT.")
623
+
624
+
625
+ @auto_docstring
626
+ class IBertModel(IBertPreTrainedModel):
627
+ """
628
+
629
+ The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of
630
+ cross-attention is added between the self-attention layers, following the architecture described in [Attention is
631
+ all you need](https://huggingface.co/papers/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit,
632
+ Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin.
633
+
634
+ """
635
+
636
+ def __init__(self, config, add_pooling_layer=True):
637
+ r"""
638
+ add_pooling_layer (bool, *optional*, defaults to `True`):
639
+ Whether to add a pooling layer
640
+ """
641
+ super().__init__(config)
642
+ self.config = config
643
+ self.quant_mode = config.quant_mode
644
+
645
+ self.embeddings = IBertEmbeddings(config)
646
+ self.encoder = IBertEncoder(config)
647
+
648
+ self.pooler = IBertPooler(config) if add_pooling_layer else None
649
+
650
+ # Initialize weights and apply final processing
651
+ self.post_init()
652
+
653
+ def get_input_embeddings(self):
654
+ return self.embeddings.word_embeddings
655
+
656
+ def set_input_embeddings(self, value):
657
+ self.embeddings.word_embeddings = value
658
+
659
+ @auto_docstring
660
+ def forward(
661
+ self,
662
+ input_ids: torch.LongTensor | None = None,
663
+ attention_mask: torch.FloatTensor | None = None,
664
+ token_type_ids: torch.LongTensor | None = None,
665
+ position_ids: torch.LongTensor | None = None,
666
+ inputs_embeds: torch.FloatTensor | None = None,
667
+ output_attentions: bool | None = None,
668
+ output_hidden_states: bool | None = None,
669
+ return_dict: bool | None = None,
670
+ **kwargs,
671
+ ) -> BaseModelOutputWithPoolingAndCrossAttentions | tuple[torch.FloatTensor]:
672
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
673
+ output_hidden_states = (
674
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
675
+ )
676
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
677
+
678
+ if input_ids is not None and inputs_embeds is not None:
679
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
680
+ elif input_ids is not None:
681
+ self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask)
682
+ input_shape = input_ids.size()
683
+ elif inputs_embeds is not None:
684
+ input_shape = inputs_embeds.size()[:-1]
685
+ else:
686
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
687
+
688
+ batch_size, seq_length = input_shape
689
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
690
+
691
+ if attention_mask is None:
692
+ attention_mask = torch.ones(((batch_size, seq_length)), device=device)
693
+ if token_type_ids is None:
694
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
695
+
696
+ # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
697
+ # ourselves in which case we just need to make it broadcastable to all heads.
698
+ extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape)
699
+
700
+ embedding_output, embedding_output_scaling_factor = self.embeddings(
701
+ input_ids=input_ids,
702
+ position_ids=position_ids,
703
+ token_type_ids=token_type_ids,
704
+ inputs_embeds=inputs_embeds,
705
+ )
706
+ encoder_outputs = self.encoder(
707
+ embedding_output,
708
+ embedding_output_scaling_factor,
709
+ attention_mask=extended_attention_mask,
710
+ output_attentions=output_attentions,
711
+ output_hidden_states=output_hidden_states,
712
+ return_dict=return_dict,
713
+ )
714
+ sequence_output = encoder_outputs[0]
715
+ pooled_output = self.pooler(sequence_output) if self.pooler is not None else None
716
+
717
+ if not return_dict:
718
+ return (sequence_output, pooled_output) + encoder_outputs[1:]
719
+
720
+ return BaseModelOutputWithPoolingAndCrossAttentions(
721
+ last_hidden_state=sequence_output,
722
+ pooler_output=pooled_output,
723
+ hidden_states=encoder_outputs.hidden_states,
724
+ attentions=encoder_outputs.attentions,
725
+ cross_attentions=encoder_outputs.cross_attentions,
726
+ )
727
+
728
+
729
+ @auto_docstring
730
+ class IBertForMaskedLM(IBertPreTrainedModel):
731
+ _tied_weights_keys = {
732
+ "lm_head.decoder.weight": "ibert.embeddings.word_embeddings.weight$",
733
+ "lm_head.decoder.bias": "lm_head.bias",
734
+ }
735
+
736
+ def __init__(self, config):
737
+ super().__init__(config)
738
+
739
+ self.ibert = IBertModel(config, add_pooling_layer=False)
740
+ self.lm_head = IBertLMHead(config)
741
+
742
+ # Initialize weights and apply final processing
743
+ self.post_init()
744
+
745
+ def get_output_embeddings(self):
746
+ return self.lm_head.decoder
747
+
748
+ def set_output_embeddings(self, new_embeddings):
749
+ self.lm_head.decoder = new_embeddings
750
+ self.lm_head.bias = new_embeddings.bias
751
+
752
+ @auto_docstring
753
+ def forward(
754
+ self,
755
+ input_ids: torch.LongTensor | None = None,
756
+ attention_mask: torch.FloatTensor | None = None,
757
+ token_type_ids: torch.LongTensor | None = None,
758
+ position_ids: torch.LongTensor | None = None,
759
+ inputs_embeds: torch.FloatTensor | None = None,
760
+ labels: torch.LongTensor | None = None,
761
+ output_attentions: bool | None = None,
762
+ output_hidden_states: bool | None = None,
763
+ return_dict: bool | None = None,
764
+ **kwargs,
765
+ ) -> MaskedLMOutput | tuple[torch.FloatTensor]:
766
+ r"""
767
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
768
+ Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
769
+ config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
770
+ loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
771
+ """
772
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
773
+
774
+ outputs = self.ibert(
775
+ input_ids,
776
+ attention_mask=attention_mask,
777
+ token_type_ids=token_type_ids,
778
+ position_ids=position_ids,
779
+ inputs_embeds=inputs_embeds,
780
+ output_attentions=output_attentions,
781
+ output_hidden_states=output_hidden_states,
782
+ return_dict=return_dict,
783
+ )
784
+ sequence_output = outputs[0]
785
+ prediction_scores = self.lm_head(sequence_output)
786
+
787
+ masked_lm_loss = None
788
+ if labels is not None:
789
+ loss_fct = CrossEntropyLoss()
790
+ masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
791
+
792
+ if not return_dict:
793
+ output = (prediction_scores,) + outputs[2:]
794
+ return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output
795
+
796
+ return MaskedLMOutput(
797
+ loss=masked_lm_loss,
798
+ logits=prediction_scores,
799
+ hidden_states=outputs.hidden_states,
800
+ attentions=outputs.attentions,
801
+ )
802
+
803
+
804
+ class IBertLMHead(nn.Module):
805
+ """I-BERT Head for masked language modeling."""
806
+
807
+ def __init__(self, config):
808
+ super().__init__()
809
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
810
+ self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
811
+
812
+ self.decoder = nn.Linear(config.hidden_size, config.vocab_size)
813
+ self.bias = nn.Parameter(torch.zeros(config.vocab_size))
814
+
815
+ def forward(self, features, **kwargs):
816
+ x = self.dense(features)
817
+ x = gelu(x)
818
+ x = self.layer_norm(x)
819
+
820
+ # project back to size of vocabulary with bias
821
+ x = self.decoder(x)
822
+
823
+ return x
824
+
825
+
826
+ @auto_docstring(
827
+ custom_intro="""
828
+ I-BERT Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled
829
+ output) e.g. for GLUE tasks.
830
+ """
831
+ )
832
+ class IBertForSequenceClassification(IBertPreTrainedModel):
833
+ def __init__(self, config):
834
+ super().__init__(config)
835
+ self.num_labels = config.num_labels
836
+
837
+ self.ibert = IBertModel(config, add_pooling_layer=False)
838
+ self.classifier = IBertClassificationHead(config)
839
+
840
+ # Initialize weights and apply final processing
841
+ self.post_init()
842
+
843
+ @auto_docstring
844
+ def forward(
845
+ self,
846
+ input_ids: torch.LongTensor | None = None,
847
+ attention_mask: torch.FloatTensor | None = None,
848
+ token_type_ids: torch.LongTensor | None = None,
849
+ position_ids: torch.LongTensor | None = None,
850
+ inputs_embeds: torch.FloatTensor | None = None,
851
+ labels: torch.LongTensor | None = None,
852
+ output_attentions: bool | None = None,
853
+ output_hidden_states: bool | None = None,
854
+ return_dict: bool | None = None,
855
+ **kwargs,
856
+ ) -> SequenceClassifierOutput | tuple[torch.FloatTensor]:
857
+ r"""
858
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
859
+ Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
860
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
861
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
862
+ """
863
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
864
+
865
+ outputs = self.ibert(
866
+ input_ids,
867
+ attention_mask=attention_mask,
868
+ token_type_ids=token_type_ids,
869
+ position_ids=position_ids,
870
+ inputs_embeds=inputs_embeds,
871
+ output_attentions=output_attentions,
872
+ output_hidden_states=output_hidden_states,
873
+ return_dict=return_dict,
874
+ )
875
+ sequence_output = outputs[0]
876
+ logits = self.classifier(sequence_output)
877
+
878
+ loss = None
879
+ if labels is not None:
880
+ if self.config.problem_type is None:
881
+ if self.num_labels == 1:
882
+ self.config.problem_type = "regression"
883
+ elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
884
+ self.config.problem_type = "single_label_classification"
885
+ else:
886
+ self.config.problem_type = "multi_label_classification"
887
+
888
+ if self.config.problem_type == "regression":
889
+ loss_fct = MSELoss()
890
+ if self.num_labels == 1:
891
+ loss = loss_fct(logits.squeeze(), labels.squeeze())
892
+ else:
893
+ loss = loss_fct(logits, labels)
894
+ elif self.config.problem_type == "single_label_classification":
895
+ loss_fct = CrossEntropyLoss()
896
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
897
+ elif self.config.problem_type == "multi_label_classification":
898
+ loss_fct = BCEWithLogitsLoss()
899
+ loss = loss_fct(logits, labels)
900
+ if not return_dict:
901
+ output = (logits,) + outputs[2:]
902
+ return ((loss,) + output) if loss is not None else output
903
+
904
+ return SequenceClassifierOutput(
905
+ loss=loss,
906
+ logits=logits,
907
+ hidden_states=outputs.hidden_states,
908
+ attentions=outputs.attentions,
909
+ )
910
+
911
+
912
+ @auto_docstring
913
+ class IBertForMultipleChoice(IBertPreTrainedModel):
914
+ def __init__(self, config):
915
+ super().__init__(config)
916
+
917
+ self.ibert = IBertModel(config)
918
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
919
+ self.classifier = nn.Linear(config.hidden_size, 1)
920
+
921
+ # Initialize weights and apply final processing
922
+ self.post_init()
923
+
924
+ @auto_docstring
925
+ def forward(
926
+ self,
927
+ input_ids: torch.LongTensor | None = None,
928
+ token_type_ids: torch.LongTensor | None = None,
929
+ attention_mask: torch.FloatTensor | None = None,
930
+ labels: torch.LongTensor | None = None,
931
+ position_ids: torch.LongTensor | None = None,
932
+ inputs_embeds: torch.FloatTensor | None = None,
933
+ output_attentions: bool | None = None,
934
+ output_hidden_states: bool | None = None,
935
+ return_dict: bool | None = None,
936
+ **kwargs,
937
+ ) -> MultipleChoiceModelOutput | tuple[torch.FloatTensor]:
938
+ r"""
939
+ input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
940
+ Indices of input sequence tokens in the vocabulary.
941
+
942
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
943
+ [`PreTrainedTokenizer.__call__`] for details.
944
+
945
+ [What are input IDs?](../glossary#input-ids)
946
+ token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
947
+ Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,
948
+ 1]`:
949
+
950
+ - 0 corresponds to a *sentence A* token,
951
+ - 1 corresponds to a *sentence B* token.
952
+
953
+ [What are token type IDs?](../glossary#token-type-ids)
954
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
955
+ Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
956
+ num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
957
+ `input_ids` above)
958
+ position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
959
+ Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
960
+ config.max_position_embeddings - 1]`.
961
+
962
+ [What are position IDs?](../glossary#position-ids)
963
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
964
+ Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
965
+ is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
966
+ model's internal embedding lookup matrix.
967
+ """
968
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
969
+ num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1]
970
+
971
+ flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None
972
+ flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
973
+ flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
974
+ flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
975
+ flat_inputs_embeds = (
976
+ inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1))
977
+ if inputs_embeds is not None
978
+ else None
979
+ )
980
+
981
+ outputs = self.ibert(
982
+ flat_input_ids,
983
+ position_ids=flat_position_ids,
984
+ token_type_ids=flat_token_type_ids,
985
+ attention_mask=flat_attention_mask,
986
+ inputs_embeds=flat_inputs_embeds,
987
+ output_attentions=output_attentions,
988
+ output_hidden_states=output_hidden_states,
989
+ return_dict=return_dict,
990
+ )
991
+ pooled_output = outputs[1]
992
+
993
+ pooled_output = self.dropout(pooled_output)
994
+ logits = self.classifier(pooled_output)
995
+ reshaped_logits = logits.view(-1, num_choices)
996
+
997
+ loss = None
998
+ if labels is not None:
999
+ loss_fct = CrossEntropyLoss()
1000
+ loss = loss_fct(reshaped_logits, labels)
1001
+
1002
+ if not return_dict:
1003
+ output = (reshaped_logits,) + outputs[2:]
1004
+ return ((loss,) + output) if loss is not None else output
1005
+
1006
+ return MultipleChoiceModelOutput(
1007
+ loss=loss,
1008
+ logits=reshaped_logits,
1009
+ hidden_states=outputs.hidden_states,
1010
+ attentions=outputs.attentions,
1011
+ )
1012
+
1013
+
1014
+ @auto_docstring
1015
+ class IBertForTokenClassification(IBertPreTrainedModel):
1016
+ def __init__(self, config):
1017
+ super().__init__(config)
1018
+ self.num_labels = config.num_labels
1019
+
1020
+ self.ibert = IBertModel(config, add_pooling_layer=False)
1021
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
1022
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
1023
+
1024
+ # Initialize weights and apply final processing
1025
+ self.post_init()
1026
+
1027
+ @auto_docstring
1028
+ def forward(
1029
+ self,
1030
+ input_ids: torch.LongTensor | None = None,
1031
+ attention_mask: torch.FloatTensor | None = None,
1032
+ token_type_ids: torch.LongTensor | None = None,
1033
+ position_ids: torch.LongTensor | None = None,
1034
+ inputs_embeds: torch.FloatTensor | None = None,
1035
+ labels: torch.LongTensor | None = None,
1036
+ output_attentions: bool | None = None,
1037
+ output_hidden_states: bool | None = None,
1038
+ return_dict: bool | None = None,
1039
+ **kwargs,
1040
+ ) -> TokenClassifierOutput | tuple[torch.FloatTensor]:
1041
+ r"""
1042
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1043
+ Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
1044
+ """
1045
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1046
+
1047
+ outputs = self.ibert(
1048
+ input_ids,
1049
+ attention_mask=attention_mask,
1050
+ token_type_ids=token_type_ids,
1051
+ position_ids=position_ids,
1052
+ inputs_embeds=inputs_embeds,
1053
+ output_attentions=output_attentions,
1054
+ output_hidden_states=output_hidden_states,
1055
+ return_dict=return_dict,
1056
+ )
1057
+
1058
+ sequence_output = outputs[0]
1059
+
1060
+ sequence_output = self.dropout(sequence_output)
1061
+ logits = self.classifier(sequence_output)
1062
+
1063
+ loss = None
1064
+ if labels is not None:
1065
+ loss_fct = CrossEntropyLoss()
1066
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
1067
+
1068
+ if not return_dict:
1069
+ output = (logits,) + outputs[2:]
1070
+ return ((loss,) + output) if loss is not None else output
1071
+
1072
+ return TokenClassifierOutput(
1073
+ loss=loss,
1074
+ logits=logits,
1075
+ hidden_states=outputs.hidden_states,
1076
+ attentions=outputs.attentions,
1077
+ )
1078
+
1079
+
1080
+ class IBertClassificationHead(nn.Module):
1081
+ """Head for sentence-level classification tasks."""
1082
+
1083
+ def __init__(self, config):
1084
+ super().__init__()
1085
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
1086
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
1087
+ self.out_proj = nn.Linear(config.hidden_size, config.num_labels)
1088
+
1089
+ def forward(self, features, **kwargs):
1090
+ hidden_states = features[:, 0, :] # take <s> token (equiv. to [CLS])
1091
+ hidden_states = self.dropout(hidden_states)
1092
+ hidden_states = self.dense(hidden_states)
1093
+ hidden_states = torch.tanh(hidden_states)
1094
+ hidden_states = self.dropout(hidden_states)
1095
+ hidden_states = self.out_proj(hidden_states)
1096
+ return hidden_states
1097
+
1098
+
1099
+ @auto_docstring
1100
+ class IBertForQuestionAnswering(IBertPreTrainedModel):
1101
+ def __init__(self, config):
1102
+ super().__init__(config)
1103
+ self.num_labels = config.num_labels
1104
+
1105
+ self.ibert = IBertModel(config, add_pooling_layer=False)
1106
+ self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
1107
+
1108
+ # Initialize weights and apply final processing
1109
+ self.post_init()
1110
+
1111
+ @auto_docstring
1112
+ def forward(
1113
+ self,
1114
+ input_ids: torch.LongTensor | None = None,
1115
+ attention_mask: torch.FloatTensor | None = None,
1116
+ token_type_ids: torch.LongTensor | None = None,
1117
+ position_ids: torch.LongTensor | None = None,
1118
+ inputs_embeds: torch.FloatTensor | None = None,
1119
+ start_positions: torch.LongTensor | None = None,
1120
+ end_positions: torch.LongTensor | None = None,
1121
+ output_attentions: bool | None = None,
1122
+ output_hidden_states: bool | None = None,
1123
+ return_dict: bool | None = None,
1124
+ **kwargs,
1125
+ ) -> QuestionAnsweringModelOutput | tuple[torch.FloatTensor]:
1126
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1127
+
1128
+ outputs = self.ibert(
1129
+ input_ids,
1130
+ attention_mask=attention_mask,
1131
+ token_type_ids=token_type_ids,
1132
+ position_ids=position_ids,
1133
+ inputs_embeds=inputs_embeds,
1134
+ output_attentions=output_attentions,
1135
+ output_hidden_states=output_hidden_states,
1136
+ return_dict=return_dict,
1137
+ )
1138
+
1139
+ sequence_output = outputs[0]
1140
+
1141
+ logits = self.qa_outputs(sequence_output)
1142
+ start_logits, end_logits = logits.split(1, dim=-1)
1143
+ start_logits = start_logits.squeeze(-1).contiguous()
1144
+ end_logits = end_logits.squeeze(-1).contiguous()
1145
+
1146
+ total_loss = None
1147
+ if start_positions is not None and end_positions is not None:
1148
+ # If we are on multi-GPU, split add a dimension
1149
+ if len(start_positions.size()) > 1:
1150
+ start_positions = start_positions.squeeze(-1)
1151
+ if len(end_positions.size()) > 1:
1152
+ end_positions = end_positions.squeeze(-1)
1153
+ # sometimes the start/end positions are outside our model inputs, we ignore these terms
1154
+ ignored_index = start_logits.size(1)
1155
+ start_positions = start_positions.clamp(0, ignored_index)
1156
+ end_positions = end_positions.clamp(0, ignored_index)
1157
+
1158
+ loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
1159
+ start_loss = loss_fct(start_logits, start_positions)
1160
+ end_loss = loss_fct(end_logits, end_positions)
1161
+ total_loss = (start_loss + end_loss) / 2
1162
+
1163
+ if not return_dict:
1164
+ output = (start_logits, end_logits) + outputs[2:]
1165
+ return ((total_loss,) + output) if total_loss is not None else output
1166
+
1167
+ return QuestionAnsweringModelOutput(
1168
+ loss=total_loss,
1169
+ start_logits=start_logits,
1170
+ end_logits=end_logits,
1171
+ hidden_states=outputs.hidden_states,
1172
+ attentions=outputs.attentions,
1173
+ )
1174
+
1175
+
1176
+ def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0):
1177
+ """
1178
+ Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols
1179
+ are ignored. This is modified from fairseq's *utils.make_positions*.
1180
+
1181
+ Args:
1182
+ input_ids (`torch.LongTensor`):
1183
+ Indices of input sequence tokens in the vocabulary.
1184
+
1185
+ Returns: torch.Tensor
1186
+ """
1187
+ # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA.
1188
+ mask = input_ids.ne(padding_idx).int()
1189
+ incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask
1190
+ return incremental_indices.long() + padding_idx
1191
+
1192
+
1193
+ __all__ = [
1194
+ "IBertForMaskedLM",
1195
+ "IBertForMultipleChoice",
1196
+ "IBertForQuestionAnswering",
1197
+ "IBertForSequenceClassification",
1198
+ "IBertForTokenClassification",
1199
+ "IBertModel",
1200
+ "IBertPreTrainedModel",
1201
+ ]
third_party/transformers/src/transformers/models/ibert/quant_modules.py ADDED
@@ -0,0 +1,819 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The I-BERT Authors (Sehoon Kim, Amir Gholami, Zhewei Yao,
2
+ # Michael Mahoney, Kurt Keutzer - UC Berkeley) and The HuggingFace Inc. team.
3
+ # Copyright (c) 20121, NVIDIA CORPORATION. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ import decimal
18
+
19
+ import numpy as np
20
+ import torch
21
+ from torch import nn
22
+ from torch.autograd import Function
23
+
24
+ from ...utils import logging
25
+
26
+
27
+ logger = logging.get_logger(__name__)
28
+
29
+
30
+ class QuantEmbedding(nn.Module):
31
+ """
32
+ Quantized version of `torch.nn.Embedding`. Adds quantization-specific arguments on top of `torch.nn.Embedding`.
33
+
34
+ Args:
35
+ weight_bit (`int`, *optional*, defaults to `8`):
36
+ Bitwidth for the quantized weight.
37
+ momentum (`float`, *optional*, defaults to `0.95`):
38
+ Momentum for updating the activation quantization range.
39
+ quant_mode (`bool`, *optional*, defaults to `False`):
40
+ Whether or not the layer is quantized.
41
+ """
42
+
43
+ def __init__(
44
+ self,
45
+ num_embeddings,
46
+ embedding_dim,
47
+ padding_idx=None,
48
+ max_norm=None,
49
+ norm_type=2.0,
50
+ scale_grad_by_freq=False,
51
+ sparse=False,
52
+ _weight=None,
53
+ weight_bit=8,
54
+ momentum=0.95,
55
+ quant_mode=False,
56
+ ):
57
+ super().__init__()
58
+ self.num_ = num_embeddings
59
+ self.dim = embedding_dim
60
+ self.padding_idx = padding_idx
61
+ self.max_norm = max_norm
62
+ self.norm_type = norm_type
63
+ self.scale_grad_by_freq = scale_grad_by_freq
64
+ self.sparse = sparse
65
+
66
+ self.weight = nn.Parameter(torch.zeros([num_embeddings, embedding_dim]))
67
+ self.register_buffer("weight_scaling_factor", torch.zeros(1))
68
+ self.register_buffer("weight_integer", torch.zeros_like(self.weight))
69
+
70
+ self.weight_bit = weight_bit
71
+ self.momentum = momentum
72
+ self.quant_mode = quant_mode
73
+ self.percentile_mode = False
74
+ self.weight_function = SymmetricQuantFunction.apply
75
+
76
+ def forward(self, x, positions=None, incremental_state=None):
77
+ if not self.quant_mode:
78
+ return (
79
+ nn.functional.embedding(
80
+ x,
81
+ self.weight,
82
+ self.padding_idx,
83
+ self.max_norm,
84
+ self.norm_type,
85
+ self.scale_grad_by_freq,
86
+ self.sparse,
87
+ ),
88
+ None,
89
+ )
90
+
91
+ w = self.weight
92
+ w_transform = w.data.detach()
93
+ w_min = w_transform.min().expand(1)
94
+ w_max = w_transform.max().expand(1)
95
+
96
+ self.weight_scaling_factor = symmetric_linear_quantization_params(self.weight_bit, w_min, w_max, False)
97
+ self.weight_integer = self.weight_function(
98
+ self.weight, self.weight_bit, self.percentile_mode, self.weight_scaling_factor
99
+ )
100
+
101
+ emb_int = nn.functional.embedding(
102
+ x,
103
+ self.weight_integer,
104
+ self.padding_idx,
105
+ self.max_norm,
106
+ self.norm_type,
107
+ self.scale_grad_by_freq,
108
+ self.sparse,
109
+ )
110
+ return emb_int * self.weight_scaling_factor, self.weight_scaling_factor
111
+
112
+
113
+ class QuantAct(nn.Module):
114
+ """
115
+ Quantizes the given activation.
116
+
117
+ Args:
118
+ activation_bit (`int`):
119
+ Bitwidth for the quantized activation.
120
+ act_range_momentum (`float`, *optional*, defaults to `0.95`):
121
+ Momentum for updating the activation quantization range.
122
+ per_channel (`bool`, *optional*, defaults to `False`):
123
+ Whether to or not use channel-wise quantization.
124
+ channel_len (`int`, *optional*):
125
+ Specify the channel length when set the *per_channel* True.
126
+ quant_mode (`bool`, *optional*, defaults to `False`):
127
+ Whether or not the layer is quantized.
128
+ """
129
+
130
+ def __init__(self, activation_bit, act_range_momentum=0.95, per_channel=False, channel_len=None, quant_mode=False):
131
+ super().__init__()
132
+
133
+ self.activation_bit = activation_bit
134
+ self.act_range_momentum = act_range_momentum
135
+ self.quant_mode = quant_mode
136
+ self.per_channel = per_channel
137
+ self.percentile = False
138
+ self.act_function = SymmetricQuantFunction.apply
139
+
140
+ if not self.per_channel:
141
+ self.register_buffer("x_min", torch.zeros(1))
142
+ self.register_buffer("x_max", torch.zeros(1))
143
+ self.register_buffer("act_scaling_factor", torch.zeros(1))
144
+ self.x_min -= 1e-5
145
+ self.x_max += 1e-5
146
+ else:
147
+ raise NotImplementedError("per-channel mode is not currently supported for activation.")
148
+
149
+ def __repr__(self):
150
+ return (
151
+ f"{self.__class__.__name__}(activation_bit={self.activation_bit}, "
152
+ f"quant_mode: {self.quant_mode}, Act_min: {self.x_min.item():.2f}, "
153
+ f"Act_max: {self.x_max.item():.2f})"
154
+ )
155
+
156
+ def forward(
157
+ self,
158
+ x,
159
+ pre_act_scaling_factor=None,
160
+ identity=None,
161
+ identity_scaling_factor=None,
162
+ specified_min=None,
163
+ specified_max=None,
164
+ ):
165
+ x_act = x if identity is None else identity + x
166
+ # collect running stats if training
167
+ if self.training:
168
+ assert not self.percentile, "percentile mode is not currently supported for activation."
169
+ assert not self.per_channel, "per-channel mode is not currently supported for activation."
170
+ x_min = x_act.data.min()
171
+ x_max = x_act.data.max()
172
+
173
+ assert x_max.isnan().sum() == 0 and x_min.isnan().sum() == 0, (
174
+ "NaN detected when computing min/max of the activation"
175
+ )
176
+
177
+ # Initialization
178
+ if self.x_min.min() > -1.1e-5 and self.x_max.max() < 1.1e-5:
179
+ self.x_min = self.x_min + x_min
180
+ self.x_max = self.x_max + x_max
181
+
182
+ # exponential moving average (EMA)
183
+ # use momentum to prevent the quantized values change greatly every iteration
184
+ elif self.act_range_momentum == -1:
185
+ self.x_min = torch.min(self.x_min, x_min)
186
+ self.x_max = torch.max(self.x_max, x_max)
187
+ else:
188
+ self.x_min = self.x_min * self.act_range_momentum + x_min * (1 - self.act_range_momentum)
189
+ self.x_max = self.x_max * self.act_range_momentum + x_max * (1 - self.act_range_momentum)
190
+
191
+ if not self.quant_mode:
192
+ return x_act, None
193
+
194
+ x_min = self.x_min if specified_min is None else specified_min
195
+ x_max = self.x_max if specified_max is None else specified_max
196
+
197
+ self.act_scaling_factor = symmetric_linear_quantization_params(
198
+ self.activation_bit, x_min, x_max, per_channel=self.per_channel
199
+ )
200
+
201
+ if pre_act_scaling_factor is None:
202
+ # this is for the input quantization
203
+ quant_act_int = self.act_function(x, self.activation_bit, self.percentile, self.act_scaling_factor)
204
+ else:
205
+ quant_act_int = FixedPointMul.apply(
206
+ x,
207
+ pre_act_scaling_factor,
208
+ self.activation_bit,
209
+ self.act_scaling_factor,
210
+ identity,
211
+ identity_scaling_factor,
212
+ )
213
+
214
+ correct_output_scale = self.act_scaling_factor.view(-1)
215
+
216
+ return quant_act_int * correct_output_scale, self.act_scaling_factor
217
+
218
+
219
+ class QuantLinear(nn.Module):
220
+ """
221
+ Quantized version of `torch.nn.Linear`. Adds quantization-specific arguments on top of `torch.nn.Linear`.
222
+
223
+ Args:
224
+ weight_bit (`int`, *optional*, defaults to `8`):
225
+ Bitwidth for the quantized weight.
226
+ bias_bit (`int`, *optional*, defaults to `32`):
227
+ Bitwidth for the quantized bias.
228
+ per_channel (`bool`, *optional*, defaults to `False`):
229
+ Whether or not to use channel-wise quantization.
230
+ quant_mode (`bool`, *optional*, defaults to `False`):
231
+ Whether or not the layer is quantized.
232
+ """
233
+
234
+ def __init__(
235
+ self, in_features, out_features, bias=True, weight_bit=8, bias_bit=32, per_channel=False, quant_mode=False
236
+ ):
237
+ super().__init__()
238
+ self.in_features = in_features
239
+ self.out_features = out_features
240
+
241
+ self.weight = nn.Parameter(torch.zeros([out_features, in_features]))
242
+ self.register_buffer("weight_integer", torch.zeros_like(self.weight))
243
+ self.register_buffer("fc_scaling_factor", torch.zeros(self.out_features))
244
+ if bias:
245
+ self.bias = nn.Parameter(torch.zeros(out_features))
246
+ self.register_buffer("bias_integer", torch.zeros_like(self.bias))
247
+
248
+ self.weight_bit = weight_bit
249
+ self.quant_mode = quant_mode
250
+ self.per_channel = per_channel
251
+ self.bias_bit = bias_bit
252
+ self.quant_mode = quant_mode
253
+ self.percentile_mode = False
254
+ self.weight_function = SymmetricQuantFunction.apply
255
+
256
+ def __repr__(self):
257
+ s = super().__repr__()
258
+ s = f"({s} weight_bit={self.weight_bit}, quant_mode={self.quant_mode})"
259
+ return s
260
+
261
+ def forward(self, x, prev_act_scaling_factor=None):
262
+ if not self.quant_mode:
263
+ return nn.functional.linear(x, weight=self.weight, bias=self.bias), None
264
+
265
+ # assert that prev_act_scaling_factor is a scalar tensor
266
+ assert prev_act_scaling_factor is not None and prev_act_scaling_factor.shape == (1,), (
267
+ "Input activation to the QuantLinear layer should be globally (non-channel-wise) quantized. "
268
+ "Please add a QuantAct layer with `per_channel = True` before this QuantAct layer"
269
+ )
270
+
271
+ w = self.weight
272
+ w_transform = w.data.detach()
273
+ if self.per_channel:
274
+ w_min, _ = torch.min(w_transform, dim=1, out=None)
275
+ w_max, _ = torch.max(w_transform, dim=1, out=None)
276
+ else:
277
+ w_min = w_transform.min().expand(1)
278
+ w_max = w_transform.max().expand(1)
279
+
280
+ self.fc_scaling_factor = symmetric_linear_quantization_params(self.weight_bit, w_min, w_max, self.per_channel)
281
+ self.weight_integer = self.weight_function(
282
+ self.weight, self.weight_bit, self.percentile_mode, self.fc_scaling_factor
283
+ )
284
+
285
+ bias_scaling_factor = self.fc_scaling_factor * prev_act_scaling_factor
286
+
287
+ if self.bias is not None:
288
+ self.bias_integer = self.weight_function(self.bias, self.bias_bit, False, bias_scaling_factor)
289
+
290
+ prev_act_scaling_factor = prev_act_scaling_factor.view(1, -1)
291
+ x_int = x / prev_act_scaling_factor
292
+
293
+ return (
294
+ nn.functional.linear(x_int, weight=self.weight_integer, bias=self.bias_integer) * bias_scaling_factor,
295
+ bias_scaling_factor,
296
+ )
297
+
298
+
299
+ class IntGELU(nn.Module):
300
+ """
301
+ Quantized version of `torch.nn.GELU`. Adds quantization-specific arguments on top of `torch.nn.GELU`.
302
+
303
+ Args:
304
+ quant_mode (`bool`, *optional*, defaults to `False`):
305
+ Whether or not the layer is quantized.
306
+ force_dequant (`str`, *optional*, defaults to `"none"`):
307
+ Force dequantize the layer if either "gelu" or "nonlinear" is given.
308
+ """
309
+
310
+ def __init__(self, quant_mode=True, force_dequant="none"):
311
+ super().__init__()
312
+ self.quant_mode = quant_mode
313
+
314
+ if force_dequant in ["nonlinear", "gelu"]:
315
+ logger.info("Force dequantize gelu")
316
+ self.quant_mode = False
317
+
318
+ if not self.quant_mode:
319
+ self.activation_fn = nn.GELU()
320
+
321
+ self.k = 1.4142
322
+ self.const = 14 # dummy integer constant
323
+ self.coeff = [-0.2888, -1.769, 1] # a(x+b)**2 + c
324
+ self.coeff[2] /= self.coeff[0]
325
+
326
+ def int_erf(self, x_int, scaling_factor):
327
+ b_int = torch.floor(self.coeff[1] / scaling_factor)
328
+ c_int = torch.floor(self.coeff[2] / scaling_factor**2)
329
+ sign = torch.sign(x_int)
330
+
331
+ abs_int = torch.min(torch.abs(x_int), -b_int)
332
+ y_int = sign * ((abs_int + b_int) ** 2 + c_int)
333
+ scaling_factor = scaling_factor**2 * self.coeff[0]
334
+
335
+ # avoid overflow
336
+ y_int = floor_ste.apply(y_int / 2**self.const)
337
+ scaling_factor = scaling_factor * 2**self.const
338
+
339
+ return y_int, scaling_factor
340
+
341
+ def forward(self, x, scaling_factor=None):
342
+ if not self.quant_mode:
343
+ return self.activation_fn(x), None
344
+
345
+ x_int = x / scaling_factor
346
+ sigmoid_int, sigmoid_scaling_factor = self.int_erf(x_int, scaling_factor / self.k)
347
+
348
+ shift_int = 1.0 // sigmoid_scaling_factor
349
+
350
+ x_int = x_int * (sigmoid_int + shift_int)
351
+ scaling_factor = scaling_factor * sigmoid_scaling_factor / 2
352
+
353
+ return x_int * scaling_factor, scaling_factor
354
+
355
+
356
+ class IntSoftmax(nn.Module):
357
+ """
358
+ Quantized version of `torch.nn.Softmax`. Adds quantization-specific arguments on top of `torch.nn.Softmax`.
359
+
360
+ Args:
361
+ output_bit (`int`):
362
+ Bitwidth for the layer output activation.
363
+ quant_mode (`bool`, *optional*, defaults to `False`):
364
+ Whether or not the layer is quantized.
365
+ force_dequant (`str`, *optional*, defaults to `"none"`):
366
+ Force dequantize the layer if either "softmax" or "nonlinear" is given.
367
+ """
368
+
369
+ def __init__(self, output_bit, quant_mode=False, force_dequant="none"):
370
+ super().__init__()
371
+ self.output_bit = output_bit
372
+ self.max_bit = 32
373
+ self.quant_mode = quant_mode
374
+
375
+ if force_dequant in ["nonlinear", "softmax"]:
376
+ logger.info("Force dequantize softmax")
377
+ self.quant_mode = False
378
+
379
+ self.act = QuantAct(16, quant_mode=self.quant_mode)
380
+ self.x0 = -0.6931 # -ln2
381
+ self.const = 30 # dummy integer constant
382
+ self.coef = [0.35815147, 0.96963238, 1.0] # ax**2 + bx + c
383
+ self.coef[1] /= self.coef[0]
384
+ self.coef[2] /= self.coef[0]
385
+
386
+ def int_polynomial(self, x_int, scaling_factor):
387
+ with torch.no_grad():
388
+ b_int = torch.floor(self.coef[1] / scaling_factor)
389
+ c_int = torch.floor(self.coef[2] / scaling_factor**2)
390
+ z = (x_int + b_int) * x_int + c_int
391
+ scaling_factor = self.coef[0] * scaling_factor**2
392
+ return z, scaling_factor
393
+
394
+ def int_exp(self, x_int, scaling_factor):
395
+ with torch.no_grad():
396
+ x0_int = torch.floor(self.x0 / scaling_factor)
397
+ x_int = torch.max(x_int, self.const * x0_int)
398
+
399
+ q = floor_ste.apply(x_int / x0_int)
400
+ r = x_int - x0_int * q
401
+ exp_int, exp_scaling_factor = self.int_polynomial(r, scaling_factor)
402
+ exp_int = torch.clamp(floor_ste.apply(exp_int * 2 ** (self.const - q)), min=0)
403
+ scaling_factor = exp_scaling_factor / 2**self.const
404
+ return exp_int, scaling_factor
405
+
406
+ def forward(self, x, scaling_factor):
407
+ if not self.quant_mode:
408
+ return nn.functional.softmax(x, dim=-1), None
409
+
410
+ x_int = x / scaling_factor
411
+
412
+ x_int_max, _ = x_int.max(dim=-1, keepdim=True)
413
+ x_int = x_int - x_int_max
414
+ exp_int, exp_scaling_factor = self.int_exp(x_int, scaling_factor)
415
+
416
+ # Avoid overflow
417
+ exp, exp_scaling_factor = self.act(exp_int, exp_scaling_factor)
418
+ exp_int = exp / exp_scaling_factor
419
+
420
+ exp_int_sum = exp_int.sum(dim=-1, keepdim=True)
421
+ factor = floor_ste.apply(2**self.max_bit / exp_int_sum)
422
+ exp_int = floor_ste.apply(exp_int * factor / 2 ** (self.max_bit - self.output_bit))
423
+ scaling_factor = 1 / 2**self.output_bit
424
+ return exp_int * scaling_factor, scaling_factor
425
+
426
+
427
+ class IntLayerNorm(nn.Module):
428
+ """
429
+ Quantized version of `torch.nn.LayerNorm`. Adds quantization-specific arguments on top of `torch.nn.LayerNorm`.
430
+
431
+ Args:
432
+ output_bit (`int`, *optional*, defaults to `8`):
433
+ Bitwidth for the layer output activation.
434
+ quant_mode (`bool`, *optional*, defaults to `False`):
435
+ Whether or not the layer is quantized.
436
+ force_dequant (`str`, *optional*, defaults to `"none"`):
437
+ Force dequantize the layer if either "layernorm" or "nonlinear" is given.
438
+ """
439
+
440
+ def __init__(self, normalized_shape, eps, output_bit=8, quant_mode=False, force_dequant="none"):
441
+ super().__init__()
442
+ self.normalized_shape = normalized_shape
443
+ self.eps = eps
444
+
445
+ self.weight = nn.Parameter(torch.zeros(normalized_shape))
446
+ self.bias = nn.Parameter(torch.zeros(normalized_shape))
447
+
448
+ self.quant_mode = quant_mode
449
+ if force_dequant in ["nonlinear", "layernorm"]:
450
+ logger.info("Force dequantize layernorm")
451
+ self.quant_mode = False
452
+
453
+ self.register_buffer("shift", torch.zeros(1))
454
+ self.output_bit = output_bit
455
+ self.max_bit = 32
456
+ self.dim_sqrt = None
457
+ self.activation = QuantAct(self.output_bit, quant_mode=self.quant_mode)
458
+
459
+ def set_shift(self, y_int):
460
+ with torch.no_grad():
461
+ y_sq_int = y_int**2
462
+ var_int = torch.sum(y_sq_int, axis=2, keepdim=True)
463
+ shift = (torch.log2(torch.sqrt(var_int / 2**self.max_bit)).ceil()).max()
464
+ shift_old = self.shift
465
+ self.shift = torch.max(self.shift, shift)
466
+ logger.info(f"Dynamic shift adjustment: {int(shift_old)} -> {int(self.shift)}")
467
+
468
+ def overflow_fallback(self, y_int):
469
+ """
470
+ This fallback function is called when overflow is detected during training time, and adjusts the `self.shift`
471
+ to avoid overflow in the subsequent runs.
472
+ """
473
+ self.set_shift(y_int) # adjusts `self.shift`
474
+ y_int_shifted = floor_ste.apply(y_int / 2**self.shift)
475
+ y_sq_int = y_int_shifted**2
476
+ var_int = torch.sum(y_sq_int, axis=2, keepdim=True)
477
+ return var_int
478
+
479
+ def forward(self, x, scaling_factor=None):
480
+ if not self.quant_mode:
481
+ mean = x.mean(axis=2, keepdim=True)
482
+ y = x - mean
483
+ var = torch.mean(y**2, axis=2, keepdim=True)
484
+ x = y / torch.sqrt(self.eps + var)
485
+ x = x * self.weight + self.bias
486
+ return x, None
487
+
488
+ # compute sqrt of the feature dimension if it is the first run
489
+ if self.dim_sqrt is None:
490
+ n = torch.tensor(x.shape[2], dtype=torch.float)
491
+ self.dim_sqrt = torch.sqrt(n).to(x.device)
492
+
493
+ # Normalization: computes mean and variance(std)
494
+ x_int = x / scaling_factor
495
+ mean_int = round_ste.apply(x_int.mean(axis=2, keepdim=True))
496
+ y_int = x_int - mean_int
497
+ y_int_shifted = floor_ste.apply(y_int / 2**self.shift)
498
+ y_sq_int = y_int_shifted**2
499
+ var_int = torch.sum(y_sq_int, axis=2, keepdim=True)
500
+
501
+ # overflow handling in training time
502
+ if self.training:
503
+ # if overflow is detected
504
+ if var_int.max() >= 2**self.max_bit:
505
+ var_int = self.overflow_fallback(y_int)
506
+ assert var_int.max() < 2**self.max_bit + 0.1, (
507
+ "Error detected in overflow handling: "
508
+ "`var_int` exceeds `self.max_bit` (the maximum possible bit width)"
509
+ )
510
+
511
+ # To be replaced with integer-sqrt kernel that produces the same output
512
+ std_int = floor_ste.apply(torch.sqrt(var_int)) * 2**self.shift
513
+ factor = floor_ste.apply(2**31 / std_int)
514
+ y_int = floor_ste.apply(y_int * factor / 2)
515
+ scaling_factor = self.dim_sqrt / 2**30
516
+
517
+ # scaling and shifting
518
+ bias = self.bias.data.detach() / (self.weight.data.detach())
519
+ bias_int = floor_ste.apply(bias / scaling_factor)
520
+
521
+ y_int = y_int + bias_int
522
+ scaling_factor = scaling_factor * self.weight
523
+ x = y_int * scaling_factor
524
+
525
+ return x, scaling_factor
526
+
527
+
528
+ def get_percentile_min_max(input, lower_percentile, upper_percentile, output_tensor=False):
529
+ """
530
+ Calculate the percentile max and min values in a given tensor
531
+
532
+ Args:
533
+ input (`torch.Tensor`):
534
+ The target tensor to calculate percentile max and min.
535
+ lower_percentile (`float`):
536
+ If 0.1, means we return the value of the smallest 0.1% value in the tensor as percentile min.
537
+ upper_percentile (`float`):
538
+ If 99.9, means we return the value of the largest 0.1% value in the tensor as percentile max.
539
+ output_tensor (`bool`, *optional*, defaults to `False`):
540
+ If True, this function returns tensors, otherwise it returns values.
541
+
542
+ Returns:
543
+ `Tuple(torch.Tensor, torch.Tensor)`: Percentile min and max value of *input*
544
+ """
545
+ input_length = input.shape[0]
546
+
547
+ lower_index = round(input_length * (1 - lower_percentile * 0.01))
548
+ upper_index = round(input_length * upper_percentile * 0.01)
549
+
550
+ upper_bound = torch.kthvalue(input, k=upper_index).values
551
+
552
+ if lower_percentile == 0:
553
+ lower_bound = upper_bound * 0
554
+ # lower_index += 1
555
+ else:
556
+ lower_bound = -torch.kthvalue(-input, k=lower_index).values
557
+
558
+ if not output_tensor:
559
+ lower_bound = lower_bound.item()
560
+ upper_bound = upper_bound.item()
561
+ return lower_bound, upper_bound
562
+
563
+
564
+ def linear_quantize(input, scale, zero_point, inplace=False):
565
+ """
566
+ Quantize single-precision input tensor to integers with the given scaling factor and zeropoint.
567
+
568
+ Args:
569
+ input (`torch.Tensor`):
570
+ Single-precision input tensor to be quantized.
571
+ scale (`torch.Tensor`):
572
+ Scaling factor for quantization.
573
+ zero_pint (`torch.Tensor`):
574
+ Shift for quantization.
575
+ inplace (`bool`, *optional*, defaults to `False`):
576
+ Whether to compute inplace or not.
577
+
578
+ Returns:
579
+ `torch.Tensor`: Linearly quantized value of *input* according to *scale* and *zero_point*.
580
+ """
581
+ # reshape scale and zeropoint for convolutional weights and activation
582
+ if len(input.shape) == 4:
583
+ scale = scale.view(-1, 1, 1, 1)
584
+ zero_point = zero_point.view(-1, 1, 1, 1)
585
+ # reshape scale and zeropoint for linear weights
586
+ elif len(input.shape) == 2:
587
+ scale = scale.view(-1, 1)
588
+ zero_point = zero_point.view(-1, 1)
589
+ else:
590
+ scale = scale.view(-1)
591
+ zero_point = zero_point.view(-1)
592
+ # quantized = float / scale + zero_point
593
+ if inplace:
594
+ input.mul_(1.0 / scale).add_(zero_point).round_()
595
+ return input
596
+ return torch.round(1.0 / scale * input + zero_point)
597
+
598
+
599
+ def symmetric_linear_quantization_params(num_bits, saturation_min, saturation_max, per_channel=False):
600
+ """
601
+ Compute the scaling factor with the given quantization range for symmetric quantization.
602
+
603
+ Args:
604
+ saturation_min (`torch.Tensor`):
605
+ Lower bound for quantization range.
606
+ saturation_max (`torch.Tensor`):
607
+ Upper bound for quantization range.
608
+ per_channel (`bool`, *optional*, defaults to `False`):
609
+ Whether to or not use channel-wise quantization.
610
+
611
+ Returns:
612
+ `torch.Tensor`: Scaling factor that linearly quantizes the given range between *saturation_min* and
613
+ *saturation_max*.
614
+ """
615
+ # in this part, we do not need any gradient computation,
616
+ # in order to enforce this, we put torch.no_grad()
617
+ with torch.no_grad():
618
+ n = 2 ** (num_bits - 1) - 1
619
+
620
+ if per_channel:
621
+ scale, _ = torch.max(torch.stack([saturation_min.abs(), saturation_max.abs()], dim=1), dim=1)
622
+ scale = torch.clamp(scale, min=1e-8) / n
623
+
624
+ else:
625
+ scale = max(saturation_min.abs(), saturation_max.abs())
626
+ scale = torch.clamp(scale, min=1e-8) / n
627
+
628
+ return scale
629
+
630
+
631
+ class SymmetricQuantFunction(Function):
632
+ """
633
+ Class to quantize the given floating-point values using symmetric quantization with given range and bitwidth.
634
+ """
635
+
636
+ @staticmethod
637
+ def forward(ctx, x, k, percentile_mode, scale):
638
+ """
639
+ Args:
640
+ x (`torch.Tensor`):
641
+ Floating point tensor to be quantized.
642
+ k (`int`):
643
+ Quantization bitwidth.
644
+ percentile_mode (`bool`):
645
+ Whether or not to use percentile calibration.
646
+ scale (`torch.Tensor`):
647
+ Pre-calculated scaling factor for *x*. Note that the current implementation of SymmetricQuantFunction
648
+ requires pre-calculated scaling factor.
649
+
650
+ Returns:
651
+ `torch.Tensor`: Symmetric-quantized value of *input*.
652
+ """
653
+ zero_point = torch.tensor(0.0, device=scale.device)
654
+
655
+ n = 2 ** (k - 1) - 1
656
+ new_quant_x = linear_quantize(x, scale, zero_point, inplace=False)
657
+ new_quant_x = torch.clamp(new_quant_x, -n, n - 1)
658
+
659
+ ctx.scale = scale
660
+ return new_quant_x
661
+
662
+ @staticmethod
663
+ def backward(ctx, grad_output):
664
+ scale = ctx.scale
665
+ if len(grad_output.shape) == 4:
666
+ scale = scale.view(-1, 1, 1, 1)
667
+ # reshape scale and zeropoint for linear weights
668
+ elif len(grad_output.shape) == 2:
669
+ scale = scale.view(-1, 1)
670
+ else:
671
+ scale = scale.view(-1)
672
+
673
+ return grad_output.clone() / scale, None, None, None, None
674
+
675
+
676
+ class floor_ste(Function):
677
+ """
678
+ Straight-through Estimator(STE) for torch.floor()
679
+ """
680
+
681
+ @staticmethod
682
+ def forward(ctx, x):
683
+ return torch.floor(x)
684
+
685
+ @staticmethod
686
+ def backward(ctx, grad_output):
687
+ return grad_output.clone()
688
+
689
+
690
+ class round_ste(Function):
691
+ """
692
+ Straight-through Estimator(STE) for torch.round()
693
+ """
694
+
695
+ @staticmethod
696
+ def forward(ctx, x):
697
+ return torch.round(x)
698
+
699
+ @staticmethod
700
+ def backward(ctx, grad_output):
701
+ return grad_output.clone()
702
+
703
+
704
+ def batch_frexp(inputs, max_bit=31):
705
+ """
706
+ Decompose the scaling factor into mantissa and twos exponent.
707
+
708
+ Args:
709
+ scaling_factor (`torch.Tensor`):
710
+ Target scaling factor to decompose.
711
+
712
+ Returns:
713
+ ``Tuple(torch.Tensor, torch.Tensor)`: mantisa and exponent
714
+ """
715
+
716
+ shape_of_input = inputs.size()
717
+
718
+ # trans the input to be a 1-d tensor
719
+ inputs = inputs.view(-1)
720
+
721
+ output_m, output_e = np.frexp(inputs.cpu().numpy())
722
+ tmp_m = []
723
+ for m in output_m:
724
+ int_m_shifted = int(
725
+ decimal.Decimal(m * (2**max_bit)).quantize(decimal.Decimal(1), rounding=decimal.ROUND_HALF_UP)
726
+ )
727
+ tmp_m.append(int_m_shifted)
728
+ output_m = np.array(tmp_m)
729
+
730
+ output_e = float(max_bit) - output_e
731
+
732
+ return (
733
+ torch.from_numpy(output_m).to(inputs.device).view(shape_of_input),
734
+ torch.from_numpy(output_e).to(inputs.device).view(shape_of_input),
735
+ )
736
+
737
+
738
+ class FixedPointMul(Function):
739
+ """
740
+ Function to perform fixed-point arithmetic that can match integer arithmetic on hardware.
741
+
742
+ Args:
743
+ pre_act (`torch.Tensor`):
744
+ Input tensor.
745
+ pre_act_scaling_factor (`torch.Tensor`):
746
+ Scaling factor of the input tensor *pre_act*.
747
+ bit_num (`int`):
748
+ Quantization bitwidth.
749
+ z_scaling_factor (`torch.Tensor`):
750
+ Scaling factor of the output tensor.
751
+ identity (`torch.Tensor`, *optional*):
752
+ Identity tensor, if exists.
753
+ identity_scaling_factor (`torch.Tensor`, *optional*):
754
+ Scaling factor of the identity tensor *identity*, if exists.
755
+
756
+ Returns:
757
+ `torch.Tensor`: Output tensor(*pre_act* if *identity* is not given, otherwise the addition of *pre_act* and
758
+ *identity*), whose scale is rescaled to *z_scaling_factor*.
759
+ """
760
+
761
+ @staticmethod
762
+ def forward(
763
+ ctx,
764
+ pre_act,
765
+ pre_act_scaling_factor,
766
+ bit_num,
767
+ z_scaling_factor,
768
+ identity=None,
769
+ identity_scaling_factor=None,
770
+ ):
771
+ if len(pre_act_scaling_factor.shape) == 3:
772
+ reshape = lambda x: x # noqa: E731
773
+ else:
774
+ reshape = lambda x: x.view(1, 1, -1) # noqa: E731
775
+ ctx.identity = identity
776
+
777
+ n = 2 ** (bit_num - 1) - 1
778
+
779
+ with torch.no_grad():
780
+ pre_act_scaling_factor = reshape(pre_act_scaling_factor)
781
+ if identity is not None:
782
+ identity_scaling_factor = reshape(identity_scaling_factor)
783
+
784
+ ctx.z_scaling_factor = z_scaling_factor
785
+
786
+ z_int = torch.round(pre_act / pre_act_scaling_factor)
787
+ _A = pre_act_scaling_factor.type(torch.double)
788
+ _B = (z_scaling_factor.type(torch.float)).type(torch.double)
789
+ new_scale = _A / _B
790
+ new_scale = reshape(new_scale)
791
+
792
+ m, e = batch_frexp(new_scale)
793
+
794
+ output = z_int.type(torch.double) * m.type(torch.double)
795
+ output = torch.round(output / (2.0**e))
796
+
797
+ if identity is not None:
798
+ # needs addition of identity activation
799
+ wx_int = torch.round(identity / identity_scaling_factor)
800
+
801
+ _A = identity_scaling_factor.type(torch.double)
802
+ _B = (z_scaling_factor.type(torch.float)).type(torch.double)
803
+ new_scale = _A / _B
804
+ new_scale = reshape(new_scale)
805
+
806
+ m1, e1 = batch_frexp(new_scale)
807
+ output1 = wx_int.type(torch.double) * m1.type(torch.double)
808
+ output1 = torch.round(output1 / (2.0**e1))
809
+
810
+ output = output1 + output
811
+
812
+ return torch.clamp(output.type(torch.float), -n - 1, n)
813
+
814
+ @staticmethod
815
+ def backward(ctx, grad_output):
816
+ identity_grad = None
817
+ if ctx.identity is not None:
818
+ identity_grad = grad_output.clone() / ctx.z_scaling_factor
819
+ return grad_output.clone() / ctx.z_scaling_factor, None, None, None, None, identity_grad, None
third_party/transformers/src/transformers/models/layoutlm/__init__.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from ..bert.tokenization_bert import BertTokenizer as LayoutLMTokenizer
22
+ from ..bert.tokenization_bert import BertTokenizer as LayoutLMTokenizerFast
23
+ from .configuration_layoutlm import *
24
+ from .modeling_layoutlm import *
25
+ else:
26
+ import sys
27
+
28
+ _file = globals()["__file__"]
29
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/layoutlm/configuration_layoutlm.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2010, The Microsoft Research Asia LayoutLM Team authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """LayoutLM model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ... import PreTrainedConfig
19
+ from ...utils import auto_docstring
20
+
21
+
22
+ @auto_docstring(checkpoint="microsoft/layoutlm-base-uncased")
23
+ @strict
24
+ class LayoutLMConfig(PreTrainedConfig):
25
+ r"""
26
+ max_2d_position_embeddings (`int`, *optional*, defaults to 1024):
27
+ The maximum value that the 2D position embedding might ever used. Typically set this to something large
28
+ just in case (e.g., 1024).
29
+
30
+ Examples:
31
+
32
+ ```python
33
+ >>> from transformers import LayoutLMConfig, LayoutLMModel
34
+
35
+ >>> # Initializing a LayoutLM configuration
36
+ >>> configuration = LayoutLMConfig()
37
+
38
+ >>> # Initializing a model (with random weights) from the configuration
39
+ >>> model = LayoutLMModel(configuration)
40
+
41
+ >>> # Accessing the model configuration
42
+ >>> configuration = model.config
43
+ ```"""
44
+
45
+ model_type = "layoutlm"
46
+
47
+ vocab_size: int = 30522
48
+ hidden_size: int = 768
49
+ num_hidden_layers: int = 12
50
+ num_attention_heads: int = 12
51
+ intermediate_size: int = 3072
52
+ hidden_act: str = "gelu"
53
+ hidden_dropout_prob: float | int = 0.1
54
+ attention_probs_dropout_prob: float | int = 0.1
55
+ max_position_embeddings: int = 512
56
+ type_vocab_size: int = 2
57
+ initializer_range: float = 0.02
58
+ layer_norm_eps: float = 1e-12
59
+ pad_token_id: int | None = 0
60
+ eos_token_id: int | list[int] | None = None
61
+ bos_token_id: int | None = None
62
+ use_cache: bool = True
63
+ max_2d_position_embeddings: int = 1024
64
+ tie_word_embeddings: bool = True
65
+
66
+
67
+ __all__ = ["LayoutLMConfig"]
third_party/transformers/src/transformers/models/layoutlm/modeling_layoutlm.py ADDED
@@ -0,0 +1,1012 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 The Microsoft Research Asia LayoutLM Team Authors and the HuggingFace Inc. team.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """PyTorch LayoutLM model."""
15
+
16
+ from collections.abc import Callable
17
+
18
+ import torch
19
+ from torch import nn
20
+ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
21
+
22
+ from ... import initialization as init
23
+ from ...activations import ACT2FN
24
+ from ...modeling_layers import GradientCheckpointingLayer
25
+ from ...modeling_outputs import (
26
+ BaseModelOutput,
27
+ BaseModelOutputWithPooling,
28
+ MaskedLMOutput,
29
+ QuestionAnsweringModelOutput,
30
+ SequenceClassifierOutput,
31
+ TokenClassifierOutput,
32
+ )
33
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
34
+ from ...processing_utils import Unpack
35
+ from ...pytorch_utils import apply_chunking_to_forward
36
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging
37
+ from ...utils.generic import merge_with_config_defaults
38
+ from ...utils.output_capturing import capture_outputs
39
+ from .configuration_layoutlm import LayoutLMConfig
40
+
41
+
42
+ logger = logging.get_logger(__name__)
43
+
44
+
45
+ LayoutLMLayerNorm = nn.LayerNorm
46
+
47
+
48
+ class LayoutLMEmbeddings(nn.Module):
49
+ """Construct the embeddings from word, position and token_type embeddings."""
50
+
51
+ def __init__(self, config):
52
+ super().__init__()
53
+ self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
54
+ self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)
55
+ self.x_position_embeddings = nn.Embedding(config.max_2d_position_embeddings, config.hidden_size)
56
+ self.y_position_embeddings = nn.Embedding(config.max_2d_position_embeddings, config.hidden_size)
57
+ self.h_position_embeddings = nn.Embedding(config.max_2d_position_embeddings, config.hidden_size)
58
+ self.w_position_embeddings = nn.Embedding(config.max_2d_position_embeddings, config.hidden_size)
59
+ self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
60
+
61
+ self.LayerNorm = LayoutLMLayerNorm(config.hidden_size, eps=config.layer_norm_eps)
62
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
63
+
64
+ self.register_buffer(
65
+ "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
66
+ )
67
+
68
+ def forward(
69
+ self,
70
+ input_ids=None,
71
+ bbox=None,
72
+ token_type_ids=None,
73
+ position_ids=None,
74
+ inputs_embeds=None,
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
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
84
+
85
+ if position_ids is None:
86
+ position_ids = self.position_ids[:, :seq_length]
87
+
88
+ if token_type_ids is None:
89
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
90
+
91
+ if inputs_embeds is None:
92
+ inputs_embeds = self.word_embeddings(input_ids)
93
+
94
+ words_embeddings = inputs_embeds
95
+ position_embeddings = self.position_embeddings(position_ids)
96
+ try:
97
+ left_position_embeddings = self.x_position_embeddings(bbox[:, :, 0])
98
+ upper_position_embeddings = self.y_position_embeddings(bbox[:, :, 1])
99
+ right_position_embeddings = self.x_position_embeddings(bbox[:, :, 2])
100
+ lower_position_embeddings = self.y_position_embeddings(bbox[:, :, 3])
101
+ except IndexError as e:
102
+ raise IndexError("The `bbox`coordinate values should be within 0-1000 range.") from e
103
+
104
+ h_position_embeddings = self.h_position_embeddings(bbox[:, :, 3] - bbox[:, :, 1])
105
+ w_position_embeddings = self.w_position_embeddings(bbox[:, :, 2] - bbox[:, :, 0])
106
+ token_type_embeddings = self.token_type_embeddings(token_type_ids)
107
+
108
+ embeddings = (
109
+ words_embeddings
110
+ + position_embeddings
111
+ + left_position_embeddings
112
+ + upper_position_embeddings
113
+ + right_position_embeddings
114
+ + lower_position_embeddings
115
+ + h_position_embeddings
116
+ + w_position_embeddings
117
+ + token_type_embeddings
118
+ )
119
+ embeddings = self.LayerNorm(embeddings)
120
+ embeddings = self.dropout(embeddings)
121
+ return embeddings
122
+
123
+
124
+ # Copied from transformers.models.align.modeling_align.eager_attention_forward
125
+ def eager_attention_forward(
126
+ module: nn.Module,
127
+ query: torch.Tensor,
128
+ key: torch.Tensor,
129
+ value: torch.Tensor,
130
+ attention_mask: torch.Tensor | None,
131
+ scaling: float,
132
+ dropout: float = 0.0,
133
+ **kwargs,
134
+ ):
135
+ attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
136
+ if attention_mask is not None:
137
+ attn_weights = attn_weights + attention_mask
138
+
139
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
140
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
141
+
142
+ attn_output = torch.matmul(attn_weights, value)
143
+ attn_output = attn_output.transpose(1, 2).contiguous()
144
+ return attn_output, attn_weights
145
+
146
+
147
+ # Copied from transformers.models.align.modeling_align.AlignTextSelfAttention with AlignText->LayoutLM
148
+ class LayoutLMSelfAttention(nn.Module):
149
+ def __init__(self, config):
150
+ super().__init__()
151
+ if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
152
+ raise ValueError(
153
+ f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
154
+ f"heads ({config.num_attention_heads})"
155
+ )
156
+
157
+ self.config = config
158
+ self.num_attention_heads = config.num_attention_heads
159
+ self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
160
+ self.all_head_size = self.num_attention_heads * self.attention_head_size
161
+
162
+ self.query = nn.Linear(config.hidden_size, self.all_head_size)
163
+ self.key = nn.Linear(config.hidden_size, self.all_head_size)
164
+ self.value = nn.Linear(config.hidden_size, self.all_head_size)
165
+
166
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
167
+ self.attention_dropout = config.attention_probs_dropout_prob
168
+ self.scaling = self.attention_head_size**-0.5
169
+
170
+ def forward(
171
+ self,
172
+ hidden_states: torch.Tensor,
173
+ attention_mask: torch.FloatTensor | None = None,
174
+ **kwargs: Unpack[TransformersKwargs],
175
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
176
+ input_shape = hidden_states.shape[:-1]
177
+ hidden_shape = (*input_shape, -1, self.attention_head_size)
178
+
179
+ query_states = self.query(hidden_states).view(hidden_shape).transpose(1, 2)
180
+ key_states = self.key(hidden_states).view(hidden_shape).transpose(1, 2)
181
+ value_states = self.value(hidden_states).view(hidden_shape).transpose(1, 2)
182
+
183
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
184
+ self.config._attn_implementation, eager_attention_forward
185
+ )
186
+
187
+ attn_output, attn_weights = attention_interface(
188
+ self,
189
+ query_states,
190
+ key_states,
191
+ value_states,
192
+ attention_mask,
193
+ dropout=0.0 if not self.training else self.attention_dropout,
194
+ scaling=self.scaling,
195
+ **kwargs,
196
+ )
197
+
198
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
199
+ return attn_output, attn_weights
200
+
201
+
202
+ # Copied from transformers.models.bert.modeling_bert.BertSelfOutput with Bert->LayoutLM
203
+ class LayoutLMSelfOutput(nn.Module):
204
+ def __init__(self, config):
205
+ super().__init__()
206
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
207
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
208
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
209
+
210
+ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
211
+ hidden_states = self.dense(hidden_states)
212
+ hidden_states = self.dropout(hidden_states)
213
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
214
+ return hidden_states
215
+
216
+
217
+ # Copied from transformers.models.align.modeling_align.AlignTextAttention with AlignText->LayoutLM
218
+ class LayoutLMAttention(nn.Module):
219
+ def __init__(self, config):
220
+ super().__init__()
221
+ self.self = LayoutLMSelfAttention(config)
222
+ self.output = LayoutLMSelfOutput(config)
223
+
224
+ def forward(
225
+ self,
226
+ hidden_states: torch.Tensor,
227
+ attention_mask: torch.FloatTensor | None = None,
228
+ **kwargs: Unpack[TransformersKwargs],
229
+ ) -> torch.Tensor:
230
+ residual = hidden_states
231
+ hidden_states, _ = self.self(
232
+ hidden_states,
233
+ attention_mask=attention_mask,
234
+ **kwargs,
235
+ )
236
+ hidden_states = self.output(hidden_states, residual)
237
+ return hidden_states
238
+
239
+
240
+ # Copied from transformers.models.bert.modeling_bert.BertIntermediate
241
+ class LayoutLMIntermediate(nn.Module):
242
+ def __init__(self, config):
243
+ super().__init__()
244
+ self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
245
+ if isinstance(config.hidden_act, str):
246
+ self.intermediate_act_fn = ACT2FN[config.hidden_act]
247
+ else:
248
+ self.intermediate_act_fn = config.hidden_act
249
+
250
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
251
+ hidden_states = self.dense(hidden_states)
252
+ hidden_states = self.intermediate_act_fn(hidden_states)
253
+ return hidden_states
254
+
255
+
256
+ # Copied from transformers.models.bert.modeling_bert.BertOutput with Bert->LayoutLM
257
+ class LayoutLMOutput(nn.Module):
258
+ def __init__(self, config):
259
+ super().__init__()
260
+ self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
261
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
262
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
263
+
264
+ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
265
+ hidden_states = self.dense(hidden_states)
266
+ hidden_states = self.dropout(hidden_states)
267
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
268
+ return hidden_states
269
+
270
+
271
+ # Copied from transformers.models.align.modeling_align.AlignTextLayer with AlignText->LayoutLM
272
+ class LayoutLMLayer(GradientCheckpointingLayer):
273
+ def __init__(self, config):
274
+ super().__init__()
275
+ self.chunk_size_feed_forward = config.chunk_size_feed_forward
276
+ self.seq_len_dim = 1
277
+ self.attention = LayoutLMAttention(config)
278
+ self.intermediate = LayoutLMIntermediate(config)
279
+ self.output = LayoutLMOutput(config)
280
+
281
+ def forward(
282
+ self,
283
+ hidden_states: torch.Tensor,
284
+ attention_mask: torch.FloatTensor | None = None,
285
+ **kwargs: Unpack[TransformersKwargs],
286
+ ) -> torch.Tensor:
287
+ hidden_states = self.attention(
288
+ hidden_states,
289
+ attention_mask=attention_mask,
290
+ **kwargs,
291
+ )
292
+
293
+ hidden_states = apply_chunking_to_forward(
294
+ self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, hidden_states
295
+ )
296
+
297
+ return hidden_states
298
+
299
+ def feed_forward_chunk(self, attention_output):
300
+ intermediate_output = self.intermediate(attention_output)
301
+ layer_output = self.output(intermediate_output, attention_output)
302
+ return layer_output
303
+
304
+
305
+ # Copied from transformers.models.align.modeling_align.AlignTextEncoder with AlignText->LayoutLM
306
+ class LayoutLMEncoder(nn.Module):
307
+ def __init__(self, config):
308
+ super().__init__()
309
+ self.config = config
310
+ self.layer = nn.ModuleList([LayoutLMLayer(config) for i in range(config.num_hidden_layers)])
311
+ self.gradient_checkpointing = False
312
+
313
+ def forward(
314
+ self,
315
+ hidden_states: torch.Tensor,
316
+ attention_mask: torch.FloatTensor | None = None,
317
+ **kwargs: Unpack[TransformersKwargs],
318
+ ) -> BaseModelOutput:
319
+ for layer_module in self.layer:
320
+ hidden_states = layer_module(
321
+ hidden_states,
322
+ attention_mask,
323
+ **kwargs,
324
+ )
325
+
326
+ return BaseModelOutput(
327
+ last_hidden_state=hidden_states,
328
+ )
329
+
330
+
331
+ # Copied from transformers.models.bert.modeling_bert.BertPooler
332
+ class LayoutLMPooler(nn.Module):
333
+ def __init__(self, config):
334
+ super().__init__()
335
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
336
+ self.activation = nn.Tanh()
337
+
338
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
339
+ # We "pool" the model by simply taking the hidden state corresponding
340
+ # to the first token.
341
+ first_token_tensor = hidden_states[:, 0]
342
+ pooled_output = self.dense(first_token_tensor)
343
+ pooled_output = self.activation(pooled_output)
344
+ return pooled_output
345
+
346
+
347
+ # Copied from transformers.models.bert.modeling_bert.BertPredictionHeadTransform with Bert->LayoutLM
348
+ class LayoutLMPredictionHeadTransform(nn.Module):
349
+ def __init__(self, config):
350
+ super().__init__()
351
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
352
+ if isinstance(config.hidden_act, str):
353
+ self.transform_act_fn = ACT2FN[config.hidden_act]
354
+ else:
355
+ self.transform_act_fn = config.hidden_act
356
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
357
+
358
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
359
+ hidden_states = self.dense(hidden_states)
360
+ hidden_states = self.transform_act_fn(hidden_states)
361
+ hidden_states = self.LayerNorm(hidden_states)
362
+ return hidden_states
363
+
364
+
365
+ # Copied from transformers.models.bert.modeling_bert.BertLMPredictionHead with Bert->LayoutLM
366
+ class LayoutLMLMPredictionHead(nn.Module):
367
+ def __init__(self, config):
368
+ super().__init__()
369
+ self.transform = LayoutLMPredictionHeadTransform(config)
370
+
371
+ # The output weights are the same as the input embeddings, but there is
372
+ # an output-only bias for each token.
373
+ self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
374
+ self.bias = nn.Parameter(torch.zeros(config.vocab_size))
375
+
376
+ def forward(self, hidden_states):
377
+ hidden_states = self.transform(hidden_states)
378
+ hidden_states = self.decoder(hidden_states)
379
+ return hidden_states
380
+
381
+
382
+ # Copied from transformers.models.bert.modeling_bert.BertOnlyMLMHead with Bert->LayoutLM
383
+ class LayoutLMOnlyMLMHead(nn.Module):
384
+ def __init__(self, config):
385
+ super().__init__()
386
+ self.predictions = LayoutLMLMPredictionHead(config)
387
+
388
+ def forward(self, sequence_output: torch.Tensor) -> torch.Tensor:
389
+ prediction_scores = self.predictions(sequence_output)
390
+ return prediction_scores
391
+
392
+
393
+ @auto_docstring
394
+ class LayoutLMPreTrainedModel(PreTrainedModel):
395
+ config: LayoutLMConfig
396
+ base_model_prefix = "layoutlm"
397
+ supports_gradient_checkpointing = True
398
+ _can_record_outputs = {
399
+ "hidden_states": LayoutLMLayer,
400
+ "attentions": LayoutLMSelfAttention,
401
+ }
402
+
403
+ @torch.no_grad()
404
+ def _init_weights(self, module):
405
+ """Initialize the weights"""
406
+ super()._init_weights(module)
407
+ if isinstance(module, LayoutLMLMPredictionHead):
408
+ init.zeros_(module.bias)
409
+ elif isinstance(module, LayoutLMEmbeddings):
410
+ init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
411
+
412
+
413
+ @auto_docstring
414
+ class LayoutLMModel(LayoutLMPreTrainedModel):
415
+ def __init__(self, config):
416
+ super().__init__(config)
417
+ self.config = config
418
+
419
+ self.embeddings = LayoutLMEmbeddings(config)
420
+ self.encoder = LayoutLMEncoder(config)
421
+ self.pooler = LayoutLMPooler(config)
422
+
423
+ # Initialize weights and apply final processing
424
+ self.post_init()
425
+
426
+ def get_input_embeddings(self):
427
+ return self.embeddings.word_embeddings
428
+
429
+ def set_input_embeddings(self, value):
430
+ self.embeddings.word_embeddings = value
431
+
432
+ @merge_with_config_defaults
433
+ @capture_outputs
434
+ @auto_docstring
435
+ def forward(
436
+ self,
437
+ input_ids: torch.LongTensor | None = None,
438
+ bbox: torch.LongTensor | None = None,
439
+ attention_mask: torch.FloatTensor | None = None,
440
+ token_type_ids: torch.LongTensor | None = None,
441
+ position_ids: torch.LongTensor | None = None,
442
+ inputs_embeds: torch.FloatTensor | None = None,
443
+ **kwargs: Unpack[TransformersKwargs],
444
+ ) -> tuple | BaseModelOutputWithPooling:
445
+ r"""
446
+ bbox (`torch.LongTensor` of shape `(batch_size, sequence_length, 4)`, *optional*):
447
+ Bounding boxes of each input sequence tokens. Selected in the range `[0,
448
+ config.max_2d_position_embeddings-1]`. Each bounding box should be a normalized version in (x0, y0, x1, y1)
449
+ format, where (x0, y0) corresponds to the position of the upper left corner in the bounding box, and (x1,
450
+ y1) represents the position of the lower right corner. See [Overview](#Overview) for normalization.
451
+
452
+ Examples:
453
+
454
+ ```python
455
+ >>> from transformers import AutoTokenizer, LayoutLMModel
456
+ >>> import torch
457
+
458
+ >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/layoutlm-base-uncased")
459
+ >>> model = LayoutLMModel.from_pretrained("microsoft/layoutlm-base-uncased")
460
+
461
+ >>> words = ["Hello", "world"]
462
+ >>> normalized_word_boxes = [637, 773, 693, 782], [698, 773, 733, 782]
463
+
464
+ >>> token_boxes = []
465
+ >>> for word, box in zip(words, normalized_word_boxes):
466
+ ... word_tokens = tokenizer.tokenize(word)
467
+ ... token_boxes.extend([box] * len(word_tokens))
468
+ >>> # add bounding boxes of cls + sep tokens
469
+ >>> token_boxes = [[0, 0, 0, 0]] + token_boxes + [[1000, 1000, 1000, 1000]]
470
+
471
+ >>> encoding = tokenizer(" ".join(words), return_tensors="pt")
472
+ >>> input_ids = encoding["input_ids"]
473
+ >>> attention_mask = encoding["attention_mask"]
474
+ >>> token_type_ids = encoding["token_type_ids"]
475
+ >>> bbox = torch.tensor([token_boxes])
476
+
477
+ >>> outputs = model(
478
+ ... input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids
479
+ ... )
480
+
481
+ >>> last_hidden_states = outputs.last_hidden_state
482
+ ```"""
483
+ if input_ids is not None and inputs_embeds is not None:
484
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
485
+ elif input_ids is not None:
486
+ self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask)
487
+ input_shape = input_ids.size()
488
+ elif inputs_embeds is not None:
489
+ input_shape = inputs_embeds.size()[:-1]
490
+ else:
491
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
492
+
493
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
494
+
495
+ if attention_mask is None:
496
+ attention_mask = torch.ones(input_shape, device=device)
497
+ if token_type_ids is None:
498
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
499
+
500
+ if bbox is None:
501
+ bbox = torch.zeros(input_shape + (4,), dtype=torch.long, device=device)
502
+
503
+ extended_attention_mask = attention_mask.unsqueeze(1).unsqueeze(2)
504
+
505
+ extended_attention_mask = extended_attention_mask.to(dtype=self.dtype)
506
+ extended_attention_mask = (1.0 - extended_attention_mask) * torch.finfo(self.dtype).min
507
+
508
+ embedding_output = self.embeddings(
509
+ input_ids=input_ids,
510
+ bbox=bbox,
511
+ position_ids=position_ids,
512
+ token_type_ids=token_type_ids,
513
+ inputs_embeds=inputs_embeds,
514
+ )
515
+ encoder_outputs = self.encoder(
516
+ embedding_output,
517
+ extended_attention_mask,
518
+ **kwargs,
519
+ )
520
+ sequence_output = encoder_outputs[0]
521
+ pooled_output = self.pooler(sequence_output)
522
+
523
+ return BaseModelOutputWithPooling(
524
+ last_hidden_state=sequence_output,
525
+ pooler_output=pooled_output,
526
+ )
527
+
528
+
529
+ @auto_docstring
530
+ class LayoutLMForMaskedLM(LayoutLMPreTrainedModel):
531
+ _tied_weights_keys = {
532
+ "cls.predictions.decoder.bias": "cls.predictions.bias",
533
+ "cls.predictions.decoder.weight": "layoutlm.embeddings.word_embeddings.weight",
534
+ }
535
+
536
+ def __init__(self, config):
537
+ super().__init__(config)
538
+
539
+ self.layoutlm = LayoutLMModel(config)
540
+ self.cls = LayoutLMOnlyMLMHead(config)
541
+
542
+ # Initialize weights and apply final processing
543
+ self.post_init()
544
+
545
+ def get_input_embeddings(self):
546
+ return self.layoutlm.embeddings.word_embeddings
547
+
548
+ def get_output_embeddings(self):
549
+ return self.cls.predictions.decoder
550
+
551
+ def set_output_embeddings(self, new_embeddings):
552
+ self.cls.predictions.decoder = new_embeddings
553
+ self.cls.predictions.bias = new_embeddings.bias
554
+
555
+ @can_return_tuple
556
+ @auto_docstring
557
+ def forward(
558
+ self,
559
+ input_ids: torch.LongTensor | None = None,
560
+ bbox: torch.LongTensor | None = None,
561
+ attention_mask: torch.FloatTensor | None = None,
562
+ token_type_ids: torch.LongTensor | None = None,
563
+ position_ids: torch.LongTensor | None = None,
564
+ inputs_embeds: torch.FloatTensor | None = None,
565
+ labels: torch.LongTensor | None = None,
566
+ **kwargs: Unpack[TransformersKwargs],
567
+ ) -> tuple | MaskedLMOutput:
568
+ r"""
569
+ bbox (`torch.LongTensor` of shape `(batch_size, sequence_length, 4)`, *optional*):
570
+ Bounding boxes of each input sequence tokens. Selected in the range `[0,
571
+ config.max_2d_position_embeddings-1]`. Each bounding box should be a normalized version in (x0, y0, x1, y1)
572
+ format, where (x0, y0) corresponds to the position of the upper left corner in the bounding box, and (x1,
573
+ y1) represents the position of the lower right corner. See [Overview](#Overview) for normalization.
574
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
575
+ Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
576
+ config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
577
+ loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
578
+
579
+ Examples:
580
+
581
+ ```python
582
+ >>> from transformers import AutoTokenizer, LayoutLMForMaskedLM
583
+ >>> import torch
584
+
585
+ >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/layoutlm-base-uncased")
586
+ >>> model = LayoutLMForMaskedLM.from_pretrained("microsoft/layoutlm-base-uncased")
587
+
588
+ >>> words = ["Hello", "[MASK]"]
589
+ >>> normalized_word_boxes = [637, 773, 693, 782], [698, 773, 733, 782]
590
+
591
+ >>> token_boxes = []
592
+ >>> for word, box in zip(words, normalized_word_boxes):
593
+ ... word_tokens = tokenizer.tokenize(word)
594
+ ... token_boxes.extend([box] * len(word_tokens))
595
+ >>> # add bounding boxes of cls + sep tokens
596
+ >>> token_boxes = [[0, 0, 0, 0]] + token_boxes + [[1000, 1000, 1000, 1000]]
597
+
598
+ >>> encoding = tokenizer(" ".join(words), return_tensors="pt")
599
+ >>> input_ids = encoding["input_ids"]
600
+ >>> attention_mask = encoding["attention_mask"]
601
+ >>> token_type_ids = encoding["token_type_ids"]
602
+ >>> bbox = torch.tensor([token_boxes])
603
+
604
+ >>> labels = tokenizer("Hello world", return_tensors="pt")["input_ids"]
605
+
606
+ >>> outputs = model(
607
+ ... input_ids=input_ids,
608
+ ... bbox=bbox,
609
+ ... attention_mask=attention_mask,
610
+ ... token_type_ids=token_type_ids,
611
+ ... labels=labels,
612
+ ... )
613
+
614
+ >>> loss = outputs.loss
615
+ ```"""
616
+ outputs = self.layoutlm(
617
+ input_ids,
618
+ bbox,
619
+ attention_mask=attention_mask,
620
+ token_type_ids=token_type_ids,
621
+ position_ids=position_ids,
622
+ inputs_embeds=inputs_embeds,
623
+ **kwargs,
624
+ )
625
+
626
+ sequence_output = outputs[0]
627
+ prediction_scores = self.cls(sequence_output)
628
+
629
+ masked_lm_loss = None
630
+ if labels is not None:
631
+ loss_fct = CrossEntropyLoss()
632
+ masked_lm_loss = loss_fct(
633
+ prediction_scores.view(-1, self.config.vocab_size),
634
+ labels.view(-1),
635
+ )
636
+
637
+ return MaskedLMOutput(
638
+ loss=masked_lm_loss,
639
+ logits=prediction_scores,
640
+ hidden_states=outputs.hidden_states,
641
+ attentions=outputs.attentions,
642
+ )
643
+
644
+
645
+ @auto_docstring(
646
+ custom_intro="""
647
+ LayoutLM Model with a sequence classification head on top (a linear layer on top of the pooled output) e.g. for
648
+ document image classification tasks such as the [RVL-CDIP](https://www.cs.cmu.edu/~aharley/rvl-cdip/) dataset.
649
+ """
650
+ )
651
+ class LayoutLMForSequenceClassification(LayoutLMPreTrainedModel):
652
+ def __init__(self, config):
653
+ super().__init__(config)
654
+ self.num_labels = config.num_labels
655
+ self.layoutlm = LayoutLMModel(config)
656
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
657
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
658
+
659
+ # Initialize weights and apply final processing
660
+ self.post_init()
661
+
662
+ def get_input_embeddings(self):
663
+ return self.layoutlm.embeddings.word_embeddings
664
+
665
+ @can_return_tuple
666
+ @auto_docstring
667
+ def forward(
668
+ self,
669
+ input_ids: torch.LongTensor | None = None,
670
+ bbox: torch.LongTensor | None = None,
671
+ attention_mask: torch.FloatTensor | None = None,
672
+ token_type_ids: torch.LongTensor | None = None,
673
+ position_ids: torch.LongTensor | None = None,
674
+ inputs_embeds: torch.FloatTensor | None = None,
675
+ labels: torch.LongTensor | None = None,
676
+ **kwargs: Unpack[TransformersKwargs],
677
+ ) -> tuple | SequenceClassifierOutput:
678
+ r"""
679
+ bbox (`torch.LongTensor` of shape `(batch_size, sequence_length, 4)`, *optional*):
680
+ Bounding boxes of each input sequence tokens. Selected in the range `[0,
681
+ config.max_2d_position_embeddings-1]`. Each bounding box should be a normalized version in (x0, y0, x1, y1)
682
+ format, where (x0, y0) corresponds to the position of the upper left corner in the bounding box, and (x1,
683
+ y1) represents the position of the lower right corner. See [Overview](#Overview) for normalization.
684
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
685
+ Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
686
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
687
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
688
+
689
+ Examples:
690
+
691
+ ```python
692
+ >>> from transformers import AutoTokenizer, LayoutLMForSequenceClassification
693
+ >>> import torch
694
+
695
+ >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/layoutlm-base-uncased")
696
+ >>> model = LayoutLMForSequenceClassification.from_pretrained("microsoft/layoutlm-base-uncased")
697
+
698
+ >>> words = ["Hello", "world"]
699
+ >>> normalized_word_boxes = [637, 773, 693, 782], [698, 773, 733, 782]
700
+
701
+ >>> token_boxes = []
702
+ >>> for word, box in zip(words, normalized_word_boxes):
703
+ ... word_tokens = tokenizer.tokenize(word)
704
+ ... token_boxes.extend([box] * len(word_tokens))
705
+ >>> # add bounding boxes of cls + sep tokens
706
+ >>> token_boxes = [[0, 0, 0, 0]] + token_boxes + [[1000, 1000, 1000, 1000]]
707
+
708
+ >>> encoding = tokenizer(" ".join(words), return_tensors="pt")
709
+ >>> input_ids = encoding["input_ids"]
710
+ >>> attention_mask = encoding["attention_mask"]
711
+ >>> token_type_ids = encoding["token_type_ids"]
712
+ >>> bbox = torch.tensor([token_boxes])
713
+ >>> sequence_label = torch.tensor([1])
714
+
715
+ >>> outputs = model(
716
+ ... input_ids=input_ids,
717
+ ... bbox=bbox,
718
+ ... attention_mask=attention_mask,
719
+ ... token_type_ids=token_type_ids,
720
+ ... labels=sequence_label,
721
+ ... )
722
+
723
+ >>> loss = outputs.loss
724
+ >>> logits = outputs.logits
725
+ ```"""
726
+ outputs = self.layoutlm(
727
+ input_ids=input_ids,
728
+ bbox=bbox,
729
+ attention_mask=attention_mask,
730
+ token_type_ids=token_type_ids,
731
+ position_ids=position_ids,
732
+ inputs_embeds=inputs_embeds,
733
+ **kwargs,
734
+ )
735
+
736
+ pooled_output = outputs[1]
737
+
738
+ pooled_output = self.dropout(pooled_output)
739
+ logits = self.classifier(pooled_output)
740
+
741
+ loss = None
742
+ if labels is not None:
743
+ if self.config.problem_type is None:
744
+ if self.num_labels == 1:
745
+ self.config.problem_type = "regression"
746
+ elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
747
+ self.config.problem_type = "single_label_classification"
748
+ else:
749
+ self.config.problem_type = "multi_label_classification"
750
+
751
+ if self.config.problem_type == "regression":
752
+ loss_fct = MSELoss()
753
+ if self.num_labels == 1:
754
+ loss = loss_fct(logits.squeeze(), labels.squeeze())
755
+ else:
756
+ loss = loss_fct(logits, labels)
757
+ elif self.config.problem_type == "single_label_classification":
758
+ loss_fct = CrossEntropyLoss()
759
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
760
+ elif self.config.problem_type == "multi_label_classification":
761
+ loss_fct = BCEWithLogitsLoss()
762
+ loss = loss_fct(logits, labels)
763
+
764
+ return SequenceClassifierOutput(
765
+ loss=loss,
766
+ logits=logits,
767
+ hidden_states=outputs.hidden_states,
768
+ attentions=outputs.attentions,
769
+ )
770
+
771
+
772
+ @auto_docstring(
773
+ custom_intro="""
774
+ LayoutLM Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for
775
+ sequence labeling (information extraction) tasks such as the [FUNSD](https://guillaumejaume.github.io/FUNSD/)
776
+ dataset and the [SROIE](https://rrc.cvc.uab.es/?ch=13) dataset.
777
+ """
778
+ )
779
+ class LayoutLMForTokenClassification(LayoutLMPreTrainedModel):
780
+ def __init__(self, config):
781
+ super().__init__(config)
782
+ self.num_labels = config.num_labels
783
+ self.layoutlm = LayoutLMModel(config)
784
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
785
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
786
+
787
+ # Initialize weights and apply final processing
788
+ self.post_init()
789
+
790
+ def get_input_embeddings(self):
791
+ return self.layoutlm.embeddings.word_embeddings
792
+
793
+ @can_return_tuple
794
+ @auto_docstring
795
+ def forward(
796
+ self,
797
+ input_ids: torch.LongTensor | None = None,
798
+ bbox: torch.LongTensor | None = None,
799
+ attention_mask: torch.FloatTensor | None = None,
800
+ token_type_ids: torch.LongTensor | None = None,
801
+ position_ids: torch.LongTensor | None = None,
802
+ inputs_embeds: torch.FloatTensor | None = None,
803
+ labels: torch.LongTensor | None = None,
804
+ **kwargs: Unpack[TransformersKwargs],
805
+ ) -> tuple | TokenClassifierOutput:
806
+ r"""
807
+ bbox (`torch.LongTensor` of shape `(batch_size, sequence_length, 4)`, *optional*):
808
+ Bounding boxes of each input sequence tokens. Selected in the range `[0,
809
+ config.max_2d_position_embeddings-1]`. Each bounding box should be a normalized version in (x0, y0, x1, y1)
810
+ format, where (x0, y0) corresponds to the position of the upper left corner in the bounding box, and (x1,
811
+ y1) represents the position of the lower right corner. See [Overview](#Overview) for normalization.
812
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
813
+ Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
814
+
815
+ Examples:
816
+
817
+ ```python
818
+ >>> from transformers import AutoTokenizer, LayoutLMForTokenClassification
819
+ >>> import torch
820
+
821
+ >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/layoutlm-base-uncased")
822
+ >>> model = LayoutLMForTokenClassification.from_pretrained("microsoft/layoutlm-base-uncased")
823
+
824
+ >>> words = ["Hello", "world"]
825
+ >>> normalized_word_boxes = [637, 773, 693, 782], [698, 773, 733, 782]
826
+
827
+ >>> token_boxes = []
828
+ >>> for word, box in zip(words, normalized_word_boxes):
829
+ ... word_tokens = tokenizer.tokenize(word)
830
+ ... token_boxes.extend([box] * len(word_tokens))
831
+ >>> # add bounding boxes of cls + sep tokens
832
+ >>> token_boxes = [[0, 0, 0, 0]] + token_boxes + [[1000, 1000, 1000, 1000]]
833
+
834
+ >>> encoding = tokenizer(" ".join(words), return_tensors="pt")
835
+ >>> input_ids = encoding["input_ids"]
836
+ >>> attention_mask = encoding["attention_mask"]
837
+ >>> token_type_ids = encoding["token_type_ids"]
838
+ >>> bbox = torch.tensor([token_boxes])
839
+ >>> token_labels = torch.tensor([1, 1, 0, 0]).unsqueeze(0) # batch size of 1
840
+
841
+ >>> outputs = model(
842
+ ... input_ids=input_ids,
843
+ ... bbox=bbox,
844
+ ... attention_mask=attention_mask,
845
+ ... token_type_ids=token_type_ids,
846
+ ... labels=token_labels,
847
+ ... )
848
+
849
+ >>> loss = outputs.loss
850
+ >>> logits = outputs.logits
851
+ ```"""
852
+ outputs = self.layoutlm(
853
+ input_ids=input_ids,
854
+ bbox=bbox,
855
+ attention_mask=attention_mask,
856
+ token_type_ids=token_type_ids,
857
+ position_ids=position_ids,
858
+ inputs_embeds=inputs_embeds,
859
+ **kwargs,
860
+ )
861
+
862
+ sequence_output = outputs[0]
863
+
864
+ sequence_output = self.dropout(sequence_output)
865
+ logits = self.classifier(sequence_output)
866
+
867
+ loss = None
868
+ if labels is not None:
869
+ loss_fct = CrossEntropyLoss()
870
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
871
+
872
+ return TokenClassifierOutput(
873
+ loss=loss,
874
+ logits=logits,
875
+ hidden_states=outputs.hidden_states,
876
+ attentions=outputs.attentions,
877
+ )
878
+
879
+
880
+ @auto_docstring
881
+ class LayoutLMForQuestionAnswering(LayoutLMPreTrainedModel):
882
+ def __init__(self, config, has_visual_segment_embedding=True):
883
+ r"""
884
+ has_visual_segment_embedding (`bool`, *optional*, defaults to `True`):
885
+ Whether or not to add visual segment embeddings.
886
+ """
887
+ super().__init__(config)
888
+ self.num_labels = config.num_labels
889
+
890
+ self.layoutlm = LayoutLMModel(config)
891
+ self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
892
+
893
+ # Initialize weights and apply final processing
894
+ self.post_init()
895
+
896
+ def get_input_embeddings(self):
897
+ return self.layoutlm.embeddings.word_embeddings
898
+
899
+ @can_return_tuple
900
+ @auto_docstring
901
+ def forward(
902
+ self,
903
+ input_ids: torch.LongTensor | None = None,
904
+ bbox: torch.LongTensor | None = None,
905
+ attention_mask: torch.FloatTensor | None = None,
906
+ token_type_ids: torch.LongTensor | None = None,
907
+ position_ids: torch.LongTensor | None = None,
908
+ inputs_embeds: torch.FloatTensor | None = None,
909
+ start_positions: torch.LongTensor | None = None,
910
+ end_positions: torch.LongTensor | None = None,
911
+ **kwargs: Unpack[TransformersKwargs],
912
+ ) -> tuple | QuestionAnsweringModelOutput:
913
+ r"""
914
+ bbox (`torch.LongTensor` of shape `(batch_size, sequence_length, 4)`, *optional*):
915
+ Bounding boxes of each input sequence tokens. Selected in the range `[0,
916
+ config.max_2d_position_embeddings-1]`. Each bounding box should be a normalized version in (x0, y0, x1, y1)
917
+ format, where (x0, y0) corresponds to the position of the upper left corner in the bounding box, and (x1,
918
+ y1) represents the position of the lower right corner. See [Overview](#Overview) for normalization.
919
+
920
+ Example:
921
+
922
+ In the example below, we prepare a question + context pair for the LayoutLM model. It will give us a prediction
923
+ of what it thinks the answer is (the span of the answer within the texts parsed from the image).
924
+
925
+ ```python
926
+ >>> from transformers import AutoTokenizer, LayoutLMForQuestionAnswering
927
+ >>> from datasets import load_dataset
928
+ >>> import torch
929
+
930
+ >>> tokenizer = AutoTokenizer.from_pretrained("impira/layoutlm-document-qa", add_prefix_space=True)
931
+ >>> model = LayoutLMForQuestionAnswering.from_pretrained("impira/layoutlm-document-qa", revision="1e3ebac")
932
+
933
+ >>> dataset = load_dataset("nielsr/funsd", split="train")
934
+ >>> example = dataset[0]
935
+ >>> question = "what's his name?"
936
+ >>> words = example["words"]
937
+ >>> boxes = example["bboxes"]
938
+
939
+ >>> encoding = tokenizer(
940
+ ... question.split(), words, is_split_into_words=True, return_token_type_ids=True, return_tensors="pt"
941
+ ... )
942
+ >>> bbox = []
943
+ >>> for i, s, w in zip(encoding.input_ids[0], encoding.sequence_ids(0), encoding.word_ids(0)):
944
+ ... if s == 1:
945
+ ... bbox.append(boxes[w])
946
+ ... elif i == tokenizer.sep_token_id:
947
+ ... bbox.append([1000] * 4)
948
+ ... else:
949
+ ... bbox.append([0] * 4)
950
+ >>> encoding["bbox"] = torch.tensor([bbox])
951
+
952
+ >>> word_ids = encoding.word_ids(0)
953
+ >>> outputs = model(**encoding)
954
+ >>> loss = outputs.loss
955
+ >>> start_scores = outputs.start_logits
956
+ >>> end_scores = outputs.end_logits
957
+ >>> start, end = word_ids[start_scores.argmax(-1)], word_ids[end_scores.argmax(-1)]
958
+ >>> print(" ".join(words[start : end + 1]))
959
+ M. Hamann P. Harper, P. Martinez
960
+ ```"""
961
+
962
+ outputs = self.layoutlm(
963
+ input_ids=input_ids,
964
+ bbox=bbox,
965
+ attention_mask=attention_mask,
966
+ token_type_ids=token_type_ids,
967
+ position_ids=position_ids,
968
+ inputs_embeds=inputs_embeds,
969
+ **kwargs,
970
+ )
971
+
972
+ sequence_output = outputs[0]
973
+
974
+ logits = self.qa_outputs(sequence_output)
975
+ start_logits, end_logits = logits.split(1, dim=-1)
976
+ start_logits = start_logits.squeeze(-1).contiguous()
977
+ end_logits = end_logits.squeeze(-1).contiguous()
978
+
979
+ total_loss = None
980
+ if start_positions is not None and end_positions is not None:
981
+ # If we are on multi-GPU, split add a dimension
982
+ if len(start_positions.size()) > 1:
983
+ start_positions = start_positions.squeeze(-1)
984
+ if len(end_positions.size()) > 1:
985
+ end_positions = end_positions.squeeze(-1)
986
+ # sometimes the start/end positions are outside our model inputs, we ignore these terms
987
+ ignored_index = start_logits.size(1)
988
+ start_positions = start_positions.clamp(0, ignored_index)
989
+ end_positions = end_positions.clamp(0, ignored_index)
990
+
991
+ loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
992
+ start_loss = loss_fct(start_logits, start_positions)
993
+ end_loss = loss_fct(end_logits, end_positions)
994
+ total_loss = (start_loss + end_loss) / 2
995
+
996
+ return QuestionAnsweringModelOutput(
997
+ loss=total_loss,
998
+ start_logits=start_logits,
999
+ end_logits=end_logits,
1000
+ hidden_states=outputs.hidden_states,
1001
+ attentions=outputs.attentions,
1002
+ )
1003
+
1004
+
1005
+ __all__ = [
1006
+ "LayoutLMForMaskedLM",
1007
+ "LayoutLMForSequenceClassification",
1008
+ "LayoutLMForTokenClassification",
1009
+ "LayoutLMForQuestionAnswering",
1010
+ "LayoutLMModel",
1011
+ "LayoutLMPreTrainedModel",
1012
+ ]
third_party/transformers/src/transformers/models/led/__init__.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from ..roberta.tokenization_roberta import RobertaTokenizer as LEDTokenizer
22
+ from .configuration_led import *
23
+ from .modeling_led import *
24
+ else:
25
+ import sys
26
+
27
+ _file = globals()["__file__"]
28
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/led/configuration_led.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 Iz Beltagy, Matthew E. Peters, Arman Cohan and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """LED model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...configuration_utils import PreTrainedConfig
19
+ from ...utils import auto_docstring
20
+
21
+
22
+ @auto_docstring(checkpoint="allenai/led-base-16384")
23
+ @strict
24
+ class LEDConfig(PreTrainedConfig):
25
+ r"""
26
+ max_encoder_position_embeddings (`int`, *optional*, defaults to 16384):
27
+ The maximum sequence length that the encoder might ever be used with.
28
+ max_decoder_position_embeddings (`int`, *optional*, defaults to 16384):
29
+ The maximum sequence length that the decoder might ever be used with.
30
+ attention_window (`int` or `list[int]`, *optional*, defaults to 512):
31
+ Size of an attention window around each token. If an `int`, use the same size for all layers. To specify a
32
+ different window size for each layer, use a `list[int]` where `len(attention_window) == num_hidden_layers`.
33
+
34
+ Example:
35
+
36
+ ```python
37
+ >>> from transformers import LEDModel, LEDConfig
38
+
39
+ >>> # Initializing a LED allenai/led-base-16384 style configuration
40
+ >>> configuration = LEDConfig()
41
+
42
+ >>> # Initializing a model from the allenai/led-base-16384 style configuration
43
+ >>> model = LEDModel(configuration)
44
+
45
+ >>> # Accessing the model configuration
46
+ >>> configuration = model.config
47
+ ```"""
48
+
49
+ model_type = "led"
50
+ attribute_map = {
51
+ "num_attention_heads": "encoder_attention_heads",
52
+ "hidden_size": "d_model",
53
+ "attention_probs_dropout_prob": "attention_dropout",
54
+ "initializer_range": "init_std",
55
+ "num_hidden_layers": "encoder_layers",
56
+ }
57
+
58
+ vocab_size: int = 50265
59
+ max_encoder_position_embeddings: int = 16384
60
+ max_decoder_position_embeddings: int = 1024
61
+ encoder_layers: int = 12
62
+ encoder_ffn_dim: int = 4096
63
+ encoder_attention_heads: int = 16
64
+ decoder_layers: int = 12
65
+ decoder_ffn_dim: int = 4096
66
+ decoder_attention_heads: int = 16
67
+ encoder_layerdrop: float | int = 0.0
68
+ decoder_layerdrop: float | int = 0.0
69
+ use_cache: bool = True
70
+ is_encoder_decoder: bool = True
71
+ activation_function: str = "gelu"
72
+ d_model: int = 1024
73
+ dropout: float | int = 0.1
74
+ attention_dropout: float | int = 0.0
75
+ activation_dropout: float | int = 0.0
76
+ init_std: float = 0.02
77
+ decoder_start_token_id: int = 2
78
+ classifier_dropout: float | int = 0.0
79
+ pad_token_id: int | None = 1
80
+ bos_token_id: int | None = 0
81
+ eos_token_id: int | list[int] | None = 2
82
+ attention_window: list[int] | int = 512
83
+ tie_word_embeddings: bool = True
84
+
85
+
86
+ __all__ = ["LEDConfig"]
third_party/transformers/src/transformers/models/led/modeling_led.py ADDED
The diff for this file is too large to render. See raw diff
 
third_party/transformers/src/transformers/models/lfm2_moe/__init__.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from typing import TYPE_CHECKING
16
+
17
+ from ...utils import _LazyModule
18
+ from ...utils.import_utils import define_import_structure
19
+
20
+
21
+ if TYPE_CHECKING:
22
+ from .configuration_lfm2_moe import *
23
+ from .modeling_lfm2_moe import *
24
+ else:
25
+ import sys
26
+
27
+ _file = globals()["__file__"]
28
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/lfm2_moe/configuration_lfm2_moe.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...configuration_utils import PreTrainedConfig
19
+ from ...utils import auto_docstring
20
+
21
+
22
+ @auto_docstring(checkpoint="LiquidAI/LFM2-8B-A1B")
23
+ @strict
24
+ class Lfm2MoeConfig(PreTrainedConfig):
25
+ r"""
26
+ conv_bias (`bool`, *optional*, defaults to `False`):
27
+ Whether to use bias in the conv layers.
28
+ conv_L_cache (`int`, *optional*, defaults to 3):
29
+ L_cache dim in the conv layers.
30
+ num_dense_layers (`int`, *optional*, defaults to 2):
31
+ Number of dense Lfm2MoeMLP layers in shallow layers(embed->dense->dense->...->dense->moe->moe...->lm_head).
32
+ use_expert_bias (`bool`, *optional*, defaults to `True`):
33
+ Whether to use the expert bias on the routing weights.
34
+
35
+ ```python
36
+ >>> from transformers import Lfm2MoeModel, Lfm2MoeConfig
37
+
38
+ >>> # Initializing a LFM2 Moe model
39
+ >>> configuration = Lfm2MoeConfig()
40
+
41
+ >>> # Initializing a model from the LFM2-8B-A1B style configuration
42
+ >>> model = Lfm2MoeModel(configuration)
43
+
44
+ >>> # Accessing the model configuration
45
+ >>> configuration = model.config
46
+ ```
47
+ """
48
+
49
+ model_type = "lfm2_moe"
50
+ keys_to_ignore_at_inference = ["past_key_values"]
51
+ default_theta = 1000000.0
52
+
53
+ vocab_size: int = 65536
54
+ hidden_size: int = 2048
55
+ intermediate_size: int = 7168
56
+ moe_intermediate_size: int = 1792
57
+ num_hidden_layers: int = 32
58
+ pad_token_id: int | None = 0
59
+ bos_token_id: int | None = 1
60
+ eos_token_id: int | list[int] | None = 2
61
+ tie_word_embeddings: bool = True
62
+ rope_parameters: dict | None = None
63
+ max_position_embeddings: int = 128_000
64
+ initializer_range: float = 0.02
65
+ use_cache: bool = True
66
+ norm_eps: float = 0.00001
67
+ num_attention_heads: int = 32
68
+ num_key_value_heads: int = 8
69
+ conv_bias: bool = False
70
+ conv_L_cache: int = 3
71
+ num_dense_layers: int = 2
72
+ num_experts_per_tok: int = 4
73
+ num_experts: int = 32
74
+ use_expert_bias: bool = True
75
+ routed_scaling_factor: float = 1.0
76
+ norm_topk_prob: bool = True
77
+ layer_types: list[str] | None = None
78
+
79
+ def __post_init__(self, **kwargs):
80
+ self.tie_word_embeddings = kwargs.pop("tie_embedding", self.tie_word_embeddings)
81
+ super().__post_init__(**kwargs)
82
+
83
+
84
+ __all__ = ["Lfm2MoeConfig"]
third_party/transformers/src/transformers/models/lfm2_moe/modeling_lfm2_moe.py ADDED
@@ -0,0 +1,704 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/lfm2_moe/modular_lfm2_moe.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_lfm2_moe.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 The HuggingFace Team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ from collections.abc import Callable
22
+ from typing import Optional
23
+
24
+ import torch
25
+ import torch.nn.functional as F
26
+ from torch import nn
27
+
28
+ from ... import initialization as init
29
+ from ...cache_utils import Cache, DynamicCache
30
+ from ...generation import GenerationMixin
31
+ from ...integrations import (
32
+ use_experts_implementation,
33
+ use_kernel_forward_from_hub,
34
+ use_kernel_func_from_hub,
35
+ use_kernelized_func,
36
+ )
37
+ from ...masking_utils import create_causal_mask
38
+ from ...modeling_layers import GradientCheckpointingLayer
39
+ from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast, MoeModelOutputWithPast
40
+ from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
41
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
42
+ from ...processing_utils import Unpack
43
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple
44
+ from ...utils.generic import maybe_autocast, merge_with_config_defaults
45
+ from ...utils.import_utils import is_causal_conv1d_available, is_torchdynamo_compiling
46
+ from ...utils.output_capturing import capture_outputs
47
+ from .configuration_lfm2_moe import Lfm2MoeConfig
48
+
49
+
50
+ if is_causal_conv1d_available():
51
+ from causal_conv1d import causal_conv1d_fn, causal_conv1d_update
52
+ else:
53
+ causal_conv1d_fn, causal_conv1d_update = None, None
54
+
55
+
56
+ @use_kernel_forward_from_hub("RMSNorm")
57
+ class Lfm2MoeRMSNorm(nn.Module):
58
+ def __init__(self, hidden_size, eps: float = 1e-6) -> None:
59
+ """
60
+ Lfm2MoeRMSNorm is equivalent to T5LayerNorm
61
+ """
62
+ super().__init__()
63
+ self.weight = nn.Parameter(torch.ones(hidden_size))
64
+ self.variance_epsilon = eps
65
+
66
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
67
+ input_dtype = hidden_states.dtype
68
+ hidden_states = hidden_states.to(torch.float32)
69
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
70
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
71
+ return self.weight * hidden_states.to(input_dtype)
72
+
73
+ def extra_repr(self):
74
+ return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
75
+
76
+
77
+ class Lfm2MoeRotaryEmbedding(nn.Module):
78
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
79
+
80
+ def __init__(self, config: Lfm2MoeConfig, device=None):
81
+ super().__init__()
82
+ self.max_seq_len_cached = config.max_position_embeddings
83
+ self.original_max_seq_len = config.max_position_embeddings
84
+
85
+ self.config = config
86
+
87
+ self.rope_type = self.config.rope_parameters["rope_type"]
88
+ rope_init_fn: Callable = self.compute_default_rope_parameters
89
+ if self.rope_type != "default":
90
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
91
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
92
+
93
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
94
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
95
+
96
+ @staticmethod
97
+ def compute_default_rope_parameters(
98
+ config: Lfm2MoeConfig | None = None,
99
+ device: Optional["torch.device"] = None,
100
+ seq_len: int | None = None,
101
+ ) -> tuple["torch.Tensor", float]:
102
+ """
103
+ Computes the inverse frequencies according to the original RoPE implementation
104
+ Args:
105
+ config ([`~transformers.PreTrainedConfig`]):
106
+ The model configuration.
107
+ device (`torch.device`):
108
+ The device to use for initialization of the inverse frequencies.
109
+ seq_len (`int`, *optional*):
110
+ The current sequence length. Unused for this type of RoPE.
111
+ Returns:
112
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
113
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
114
+ """
115
+ base = config.rope_parameters["rope_theta"]
116
+ dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
117
+
118
+ attention_factor = 1.0 # Unused in this type of RoPE
119
+
120
+ # Compute the inverse frequencies
121
+ inv_freq = 1.0 / (
122
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
123
+ )
124
+ return inv_freq, attention_factor
125
+
126
+ @torch.no_grad()
127
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
128
+ def forward(self, x, position_ids):
129
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
130
+ position_ids_expanded = position_ids[:, None, :].float()
131
+
132
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
133
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
134
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
135
+ emb = torch.cat((freqs, freqs), dim=-1)
136
+ cos = emb.cos() * self.attention_scaling
137
+ sin = emb.sin() * self.attention_scaling
138
+
139
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
140
+
141
+
142
+ class Lfm2MoeMLP(nn.Module):
143
+ def __init__(self, config: Lfm2MoeConfig, intermediate_size: int | None = None):
144
+ super().__init__()
145
+ self.hidden_size = config.hidden_size
146
+ self.intermediate_size = config.intermediate_size if intermediate_size is None else intermediate_size
147
+ self.w1 = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
148
+ self.w3 = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
149
+ self.w2 = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
150
+
151
+ def forward(self, x):
152
+ return self.w2(F.silu(self.w1(x)) * self.w3(x))
153
+
154
+
155
+ @use_experts_implementation
156
+ class Lfm2MoeExperts(nn.Module):
157
+ """Collection of expert weights stored as 3D tensors."""
158
+
159
+ def __init__(self, config):
160
+ super().__init__()
161
+ self.num_experts = config.num_experts
162
+ self.hidden_dim = config.hidden_size
163
+ self.intermediate_dim = config.moe_intermediate_size
164
+ self.gate_up_proj = nn.Parameter(torch.empty(self.num_experts, 2 * self.intermediate_dim, self.hidden_dim))
165
+ self.down_proj = nn.Parameter(torch.empty(self.num_experts, self.hidden_dim, self.intermediate_dim))
166
+ self.act_fn = F.silu
167
+
168
+ def forward(
169
+ self,
170
+ hidden_states: torch.Tensor,
171
+ top_k_index: torch.Tensor,
172
+ top_k_weights: torch.Tensor,
173
+ ) -> torch.Tensor:
174
+ final_hidden_states = torch.zeros_like(hidden_states)
175
+ with torch.no_grad():
176
+ expert_mask = torch.nn.functional.one_hot(top_k_index, num_classes=self.num_experts)
177
+ expert_mask = expert_mask.permute(2, 1, 0)
178
+ expert_hit = torch.greater(expert_mask.sum(dim=(-1, -2)), 0).nonzero()
179
+
180
+ for expert_idx in expert_hit:
181
+ expert_idx = expert_idx[0]
182
+ if expert_idx == self.num_experts:
183
+ continue
184
+ top_k_pos, token_idx = torch.where(expert_mask[expert_idx])
185
+ current_state = hidden_states[token_idx]
186
+ gate, up = nn.functional.linear(current_state, self.gate_up_proj[expert_idx]).chunk(2, dim=-1)
187
+ current_hidden_states = self.act_fn(gate) * up
188
+ current_hidden_states = nn.functional.linear(current_hidden_states, self.down_proj[expert_idx])
189
+ current_hidden_states = current_hidden_states * top_k_weights[token_idx, top_k_pos, None]
190
+ final_hidden_states.index_add_(0, token_idx, current_hidden_states.to(final_hidden_states.dtype))
191
+
192
+ return final_hidden_states
193
+
194
+
195
+ class Lfm2MoeSparseMoeBlock(nn.Module):
196
+ def __init__(self, config):
197
+ super().__init__()
198
+ self.top_k = config.num_experts_per_tok
199
+ self.routed_scaling_factor = config.routed_scaling_factor
200
+ self.norm_topk_prob = config.norm_topk_prob
201
+ self.use_expert_bias = config.use_expert_bias
202
+
203
+ self.gate = nn.Linear(config.hidden_size, config.num_experts, bias=False)
204
+ self.experts = Lfm2MoeExperts(config)
205
+ if self.use_expert_bias:
206
+ self.register_buffer("expert_bias", torch.zeros(config.num_experts, dtype=torch.float32))
207
+
208
+ def route_tokens_to_experts(self, router_logits):
209
+ routing_weights = router_logits.sigmoid()
210
+ if self.use_expert_bias:
211
+ scores_for_routing = routing_weights + self.expert_bias
212
+ _, selected_experts = torch.topk(scores_for_routing, k=self.top_k, dim=-1)
213
+ routing_weights = torch.gather(routing_weights, dim=1, index=selected_experts).type_as(router_logits)
214
+ else:
215
+ routing_weights, selected_experts = torch.topk(routing_weights, k=self.top_k, dim=-1)
216
+
217
+ if self.norm_topk_prob:
218
+ routing_weights = routing_weights / (routing_weights.sum(dim=-1, keepdim=True) + 1e-6)
219
+ routing_weights = routing_weights * self.routed_scaling_factor
220
+ return selected_experts, routing_weights
221
+
222
+ def forward(self, hidden_states: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
223
+ batch_size, sequence_length, hidden_dim = hidden_states.shape
224
+ hidden_states_reshaped = hidden_states.view(-1, hidden_dim)
225
+ router_logits = self.gate(hidden_states_reshaped)
226
+ selected_experts, routing_weights = self.route_tokens_to_experts(router_logits)
227
+ final_hidden_states = self.experts(hidden_states_reshaped, selected_experts, routing_weights)
228
+ return final_hidden_states.reshape(batch_size, sequence_length, hidden_dim)
229
+
230
+
231
+ def rotate_half(x):
232
+ """Rotates half the hidden dims of the input."""
233
+ x1 = x[..., : x.shape[-1] // 2]
234
+ x2 = x[..., x.shape[-1] // 2 :]
235
+ return torch.cat((-x2, x1), dim=-1)
236
+
237
+
238
+ @use_kernel_func_from_hub("rotary_pos_emb")
239
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
240
+ """Applies Rotary Position Embedding to the query and key tensors.
241
+
242
+ Args:
243
+ q (`torch.Tensor`): The query tensor.
244
+ k (`torch.Tensor`): The key tensor.
245
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
246
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
247
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
248
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
249
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
250
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
251
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
252
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
253
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
254
+ Returns:
255
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
256
+ """
257
+ cos = cos.unsqueeze(unsqueeze_dim)
258
+ sin = sin.unsqueeze(unsqueeze_dim)
259
+ q_embed = (q * cos) + (rotate_half(q) * sin)
260
+ k_embed = (k * cos) + (rotate_half(k) * sin)
261
+ return q_embed, k_embed
262
+
263
+
264
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
265
+ """
266
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
267
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
268
+ """
269
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
270
+ if n_rep == 1:
271
+ return hidden_states
272
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
273
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
274
+
275
+
276
+ def eager_attention_forward(
277
+ module: nn.Module,
278
+ query: torch.Tensor,
279
+ key: torch.Tensor,
280
+ value: torch.Tensor,
281
+ attention_mask: torch.Tensor | None,
282
+ scaling: float,
283
+ dropout: float = 0.0,
284
+ **kwargs: Unpack[TransformersKwargs],
285
+ ):
286
+ key_states = repeat_kv(key, module.num_key_value_groups)
287
+ value_states = repeat_kv(value, module.num_key_value_groups)
288
+
289
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
290
+ if attention_mask is not None:
291
+ attn_weights = attn_weights + attention_mask
292
+
293
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
294
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
295
+ attn_output = torch.matmul(attn_weights, value_states)
296
+ attn_output = attn_output.transpose(1, 2).contiguous()
297
+
298
+ return attn_output, attn_weights
299
+
300
+
301
+ @use_kernelized_func(apply_rotary_pos_emb)
302
+ class Lfm2MoeAttention(nn.Module):
303
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
304
+
305
+ def __init__(self, config: Lfm2MoeConfig, layer_idx: int):
306
+ super().__init__()
307
+ self.config = config
308
+ self.layer_idx = layer_idx
309
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
310
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
311
+ self.scaling = self.head_dim**-0.5
312
+ self.is_causal = True
313
+ self.q_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=False)
314
+ self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False)
315
+ self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False)
316
+ self.out_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=False)
317
+ self.q_layernorm = Lfm2MoeRMSNorm(self.head_dim, eps=config.norm_eps)
318
+ self.k_layernorm = Lfm2MoeRMSNorm(self.head_dim, eps=config.norm_eps)
319
+
320
+ def forward(
321
+ self,
322
+ hidden_states: torch.Tensor,
323
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
324
+ attention_mask: torch.Tensor | None,
325
+ past_key_values: Cache | None = None,
326
+ **kwargs,
327
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
328
+ input_shape = hidden_states.shape[:-1]
329
+ hidden_shape = (*input_shape, -1, self.head_dim)
330
+
331
+ query_states = self.q_layernorm(self.q_proj(hidden_states).view(*hidden_shape)).transpose(1, 2)
332
+ key_states = self.k_layernorm(self.k_proj(hidden_states).view(*hidden_shape)).transpose(1, 2)
333
+ value_states = self.v_proj(hidden_states).view(*hidden_shape).transpose(1, 2)
334
+
335
+ cos, sin = position_embeddings
336
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
337
+
338
+ if past_key_values is not None:
339
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
340
+
341
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
342
+ self.config._attn_implementation, eager_attention_forward
343
+ )
344
+
345
+ attn_output, attn_weights = attention_interface(
346
+ self,
347
+ query_states,
348
+ key_states,
349
+ value_states,
350
+ attention_mask,
351
+ dropout=0.0,
352
+ scaling=self.scaling,
353
+ **kwargs,
354
+ )
355
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
356
+ output = self.out_proj(attn_output)
357
+ return output, attn_weights
358
+
359
+
360
+ def apply_mask_to_padding_states(hidden_states, attention_mask):
361
+ """
362
+ Tunes out the hidden states for padding tokens, see https://github.com/state-spaces/mamba/issues/66
363
+ """
364
+ # NOTE: attention mask is a 2D boolean tensor
365
+ if attention_mask is not None and attention_mask.shape[1] > 1 and attention_mask.shape[0] > 1:
366
+ dtype = hidden_states.dtype
367
+ hidden_states = (hidden_states * attention_mask[:, :, None]).to(dtype)
368
+
369
+ return hidden_states
370
+
371
+
372
+ kernel_modules = (causal_conv1d_fn, causal_conv1d_update)
373
+ is_fast_path_available = all(kernel_modules)
374
+
375
+
376
+ class Lfm2MoeShortConv(nn.Module):
377
+ def __init__(
378
+ self,
379
+ config: Lfm2MoeConfig,
380
+ layer_idx: int,
381
+ ):
382
+ super().__init__()
383
+ self.config = config
384
+ self.layer_idx = layer_idx
385
+ self.L_cache = config.conv_L_cache
386
+ self.bias = config.conv_bias
387
+
388
+ self.conv = nn.Conv1d(
389
+ in_channels=config.hidden_size,
390
+ out_channels=config.hidden_size,
391
+ kernel_size=self.L_cache,
392
+ groups=config.hidden_size,
393
+ bias=self.bias,
394
+ padding=self.L_cache - 1,
395
+ )
396
+ self.in_proj = nn.Linear(config.hidden_size, 3 * config.hidden_size, bias=self.bias)
397
+ self.out_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=self.bias)
398
+
399
+ def cuda_kernels_forward(
400
+ self,
401
+ x: torch.Tensor,
402
+ past_key_values: Cache | None = None,
403
+ attention_mask: torch.Tensor | None = None,
404
+ ):
405
+ x = apply_mask_to_padding_states(x, attention_mask)
406
+ BCx = self.in_proj(x).transpose(-1, -2)
407
+ B, C, x = BCx.chunk(3, dim=-2)
408
+
409
+ Bx = B * x
410
+
411
+ conv_weights = self.conv.weight.view(self.conv.weight.size(0), self.conv.weight.size(2))
412
+ if past_key_values is not None and past_key_values.has_previous_state(self.layer_idx):
413
+ conv_out = causal_conv1d_update(
414
+ Bx.squeeze(-1),
415
+ past_key_values.layers[self.layer_idx].conv_states,
416
+ conv_weights,
417
+ self.conv.bias,
418
+ None,
419
+ )
420
+ conv_out = conv_out.unsqueeze(-1)
421
+ else:
422
+ if past_key_values is not None:
423
+ conv_state = nn.functional.pad(Bx, (self.L_cache - Bx.shape[-1], 0))
424
+ conv_state = past_key_values.update_conv_state(conv_state, self.layer_idx)
425
+
426
+ conv_out = causal_conv1d_fn(Bx, conv_weights, self.conv.bias, activation=None)
427
+
428
+ y = C * conv_out
429
+ y = self.out_proj(y.transpose(-1, -2).contiguous())
430
+ return y
431
+
432
+ def slow_forward(
433
+ self,
434
+ x: torch.Tensor,
435
+ past_key_values: Cache | None = None,
436
+ attention_mask: torch.Tensor | None = None,
437
+ ):
438
+ seqlen = x.shape[1]
439
+
440
+ x = apply_mask_to_padding_states(x, attention_mask)
441
+ BCx = self.in_proj(x).transpose(-1, -2)
442
+ B, C, x = BCx.chunk(3, dim=-2)
443
+
444
+ Bx = B * x
445
+
446
+ if past_key_values is not None and past_key_values.has_previous_state(self.layer_idx):
447
+ conv_state = past_key_values.update_conv_state(Bx, self.layer_idx)
448
+ conv_out = torch.sum(conv_state.to(Bx.device) * self.conv.weight[:, 0, :], dim=-1)
449
+ if self.bias:
450
+ conv_out += self.conv.bias
451
+
452
+ conv_out = conv_out.unsqueeze(-1)
453
+ else:
454
+ if past_key_values is not None:
455
+ conv_state = nn.functional.pad(Bx, (self.L_cache - Bx.shape[-1], 0))
456
+ conv_state = past_key_values.update_conv_state(conv_state, self.layer_idx)
457
+
458
+ conv_out = self.conv(Bx)[..., :seqlen]
459
+
460
+ y = C * conv_out
461
+ y = y.transpose(-1, -2).contiguous()
462
+ y = self.out_proj(y)
463
+ return y
464
+
465
+ def forward(
466
+ self,
467
+ hidden_states: torch.Tensor,
468
+ past_key_values: Cache | None = None,
469
+ attention_mask: torch.Tensor | None = None,
470
+ ):
471
+ if is_fast_path_available and "cuda" in hidden_states.device.type and not is_torchdynamo_compiling():
472
+ return self.cuda_kernels_forward(hidden_states, past_key_values, attention_mask)
473
+ return self.slow_forward(hidden_states, past_key_values, attention_mask)
474
+
475
+
476
+ class Lfm2MoeDecoderLayer(GradientCheckpointingLayer):
477
+ def __init__(self, config: Lfm2MoeConfig, layer_idx: int):
478
+ super().__init__()
479
+ self.is_attention_layer = config.layer_types[layer_idx] == "full_attention"
480
+
481
+ if self.is_attention_layer:
482
+ self.self_attn = Lfm2MoeAttention(config, layer_idx)
483
+ else:
484
+ self.conv = Lfm2MoeShortConv(config, layer_idx)
485
+ self.feed_forward = (
486
+ Lfm2MoeMLP(config, intermediate_size=config.intermediate_size)
487
+ if layer_idx < config.num_dense_layers
488
+ else Lfm2MoeSparseMoeBlock(config)
489
+ )
490
+ self.operator_norm = Lfm2MoeRMSNorm(config.hidden_size, eps=config.norm_eps)
491
+ self.ffn_norm = Lfm2MoeRMSNorm(config.hidden_size, eps=config.norm_eps)
492
+
493
+ def forward(
494
+ self,
495
+ hidden_states: torch.Tensor,
496
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
497
+ attention_mask: torch.Tensor | None = None,
498
+ position_ids: torch.LongTensor | None = None,
499
+ past_key_values: Cache | None = None,
500
+ **kwargs,
501
+ ) -> torch.Tensor:
502
+ residual = hidden_states
503
+ if self.is_attention_layer:
504
+ hidden_states, _ = self.self_attn(
505
+ hidden_states=self.operator_norm(hidden_states),
506
+ position_embeddings=position_embeddings,
507
+ attention_mask=attention_mask,
508
+ position_ids=position_ids,
509
+ past_key_values=past_key_values,
510
+ **kwargs,
511
+ )
512
+ else:
513
+ hidden_states = self.conv(
514
+ hidden_states=self.operator_norm(hidden_states),
515
+ past_key_values=past_key_values,
516
+ attention_mask=attention_mask,
517
+ )
518
+ hidden_states = hidden_states + residual
519
+ hidden_states = hidden_states + self.feed_forward(self.ffn_norm(hidden_states))
520
+
521
+ return hidden_states
522
+
523
+
524
+ @auto_docstring
525
+ class Lfm2MoePreTrainedModel(PreTrainedModel):
526
+ config: Lfm2MoeConfig
527
+ base_model_prefix = "model"
528
+ supports_gradient_checkpointing = True
529
+ _no_split_modules = ["Lfm2MoeDecoderLayer"]
530
+ _skip_keys_device_placement = ["past_key_values"]
531
+ _supports_flash_attn = True
532
+ _supports_sdpa = True
533
+ _supports_flex_attn = True
534
+ _can_compile_fullgraph = False # uses a non-compilable cache class
535
+ _supports_attention_backend = True
536
+ _can_record_outputs = {
537
+ "hidden_states": Lfm2MoeDecoderLayer,
538
+ "attentions": Lfm2MoeAttention,
539
+ }
540
+
541
+ @torch.no_grad()
542
+ def _init_weights(self, module):
543
+ super()._init_weights(module)
544
+ if isinstance(module, Lfm2MoeExperts):
545
+ init.normal_(module.gate_up_proj, mean=0.0, std=self.config.initializer_range)
546
+ init.normal_(module.down_proj, mean=0.0, std=self.config.initializer_range)
547
+ elif isinstance(module, Lfm2MoeSparseMoeBlock):
548
+ if module.use_expert_bias:
549
+ init.zeros_(module.expert_bias)
550
+
551
+
552
+ @auto_docstring
553
+ class Lfm2MoeModel(Lfm2MoePreTrainedModel):
554
+ def __init__(self, config: Lfm2MoeConfig):
555
+ super().__init__(config)
556
+ self.padding_idx = config.pad_token_id
557
+ self.vocab_size = config.vocab_size
558
+
559
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
560
+ self.layers = nn.ModuleList(
561
+ [Lfm2MoeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
562
+ )
563
+ self.gradient_checkpointing = False
564
+ self.pos_emb = Lfm2MoeRotaryEmbedding(config)
565
+ self.embedding_norm = Lfm2MoeRMSNorm(config.hidden_size, eps=config.norm_eps)
566
+
567
+ # Initialize weights and apply final processing
568
+ self.post_init()
569
+
570
+ @merge_with_config_defaults
571
+ @capture_outputs
572
+ @auto_docstring
573
+ def forward(
574
+ self,
575
+ input_ids: torch.LongTensor | None = None,
576
+ attention_mask: torch.Tensor | None = None,
577
+ position_ids: torch.LongTensor | None = None,
578
+ past_key_values: Cache | None = None,
579
+ inputs_embeds: torch.FloatTensor | None = None,
580
+ use_cache: bool | None = None,
581
+ **kwargs: Unpack[TransformersKwargs],
582
+ ) -> MoeModelOutputWithPast:
583
+ if (input_ids is None) ^ (inputs_embeds is not None):
584
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
585
+
586
+ if inputs_embeds is None:
587
+ inputs_embeds = self.embed_tokens(input_ids)
588
+
589
+ if use_cache and past_key_values is None:
590
+ past_key_values = DynamicCache(config=self.config)
591
+
592
+ if position_ids is None:
593
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
594
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
595
+ position_ids = position_ids.unsqueeze(0)
596
+
597
+ causal_mask = create_causal_mask(
598
+ config=self.config,
599
+ inputs_embeds=inputs_embeds,
600
+ attention_mask=attention_mask,
601
+ past_key_values=past_key_values,
602
+ position_ids=position_ids,
603
+ )
604
+ # Skip masking for decoding stage. We check shape here to be compile-friendly
605
+ linear_attention = attention_mask if inputs_embeds.shape[1] != 1 else None
606
+
607
+ hidden_states = inputs_embeds
608
+ position_embeddings = self.pos_emb(hidden_states, position_ids=position_ids)
609
+
610
+ # decoder layers
611
+ for i, decoder_layer in enumerate(self.layers[: self.config.num_hidden_layers]):
612
+ layer_mask = causal_mask if self.config.layer_types[i] == "full_attention" else linear_attention
613
+ hidden_states = decoder_layer(
614
+ hidden_states,
615
+ attention_mask=layer_mask,
616
+ position_ids=position_ids,
617
+ past_key_values=past_key_values,
618
+ position_embeddings=position_embeddings,
619
+ **kwargs,
620
+ )
621
+
622
+ hidden_states = self.embedding_norm(hidden_states)
623
+
624
+ return MoeModelOutputWithPast(
625
+ last_hidden_state=hidden_states,
626
+ past_key_values=past_key_values,
627
+ )
628
+
629
+
630
+ @auto_docstring
631
+ class Lfm2MoeForCausalLM(Lfm2MoePreTrainedModel, GenerationMixin):
632
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
633
+ _tp_plan = {"lm_head": "colwise_gather_output"}
634
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
635
+
636
+ def __init__(self, config):
637
+ super().__init__(config)
638
+ self.model = Lfm2MoeModel(config)
639
+ self.vocab_size = config.vocab_size
640
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
641
+
642
+ # Initialize weights and apply final processing
643
+ self.post_init()
644
+
645
+ @can_return_tuple
646
+ @auto_docstring
647
+ def forward(
648
+ self,
649
+ input_ids: torch.LongTensor | None = None,
650
+ attention_mask: torch.Tensor | None = None,
651
+ position_ids: torch.LongTensor | None = None,
652
+ past_key_values: Cache | None = None,
653
+ inputs_embeds: torch.FloatTensor | None = None,
654
+ labels: torch.LongTensor | None = None,
655
+ use_cache: bool | None = None,
656
+ logits_to_keep: int | torch.Tensor = 0,
657
+ **kwargs: Unpack[TransformersKwargs],
658
+ ) -> CausalLMOutputWithPast:
659
+ r"""
660
+ Example:
661
+
662
+ ```python
663
+ >>> from transformers import AutoTokenizer, Lfm2MoeForCausalLM
664
+
665
+ >>> model = Lfm2MoeForCausalLM.from_pretrained("meta-lfm2_moe/Lfm2Moe-2-7b-hf")
666
+ >>> tokenizer = AutoTokenizer.from_pretrained("meta-lfm2_moe/Lfm2Moe-2-7b-hf")
667
+
668
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
669
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
670
+
671
+ >>> # Generate
672
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
673
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
674
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
675
+ ```"""
676
+ outputs: BaseModelOutputWithPast = self.model(
677
+ input_ids=input_ids,
678
+ attention_mask=attention_mask,
679
+ position_ids=position_ids,
680
+ past_key_values=past_key_values,
681
+ inputs_embeds=inputs_embeds,
682
+ use_cache=use_cache,
683
+ **kwargs,
684
+ )
685
+
686
+ hidden_states = outputs.last_hidden_state
687
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
688
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
689
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
690
+
691
+ loss = None
692
+ if labels is not None:
693
+ loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
694
+
695
+ return CausalLMOutputWithPast(
696
+ loss=loss,
697
+ logits=logits,
698
+ past_key_values=outputs.past_key_values,
699
+ hidden_states=outputs.hidden_states,
700
+ attentions=outputs.attentions,
701
+ )
702
+
703
+
704
+ __all__ = ["Lfm2MoeForCausalLM", "Lfm2MoeModel", "Lfm2MoePreTrainedModel"]
third_party/transformers/src/transformers/models/lfm2_moe/modular_lfm2_moe.py ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import torch
16
+ import torch.nn.functional as F
17
+ from torch import nn
18
+
19
+ from ... import initialization as init
20
+ from ...cache_utils import Cache, DynamicCache
21
+ from ...masking_utils import create_causal_mask
22
+ from ...modeling_outputs import MoeModelOutputWithPast
23
+ from ...modeling_utils import PreTrainedModel
24
+ from ...processing_utils import Unpack
25
+ from ...utils import TransformersKwargs, logging
26
+ from ...utils.import_utils import is_causal_conv1d_available
27
+ from ..lfm2.modeling_lfm2 import (
28
+ Lfm2Attention,
29
+ Lfm2DecoderLayer,
30
+ Lfm2MLP,
31
+ Lfm2RotaryEmbedding,
32
+ Lfm2ShortConv,
33
+ )
34
+ from ..llama.modeling_llama import LlamaForCausalLM, LlamaPreTrainedModel, LlamaRMSNorm
35
+ from ..mixtral.modeling_mixtral import MixtralModel
36
+ from ..qwen2_moe.modeling_qwen2_moe import Qwen2MoeExperts
37
+ from .configuration_lfm2_moe import Lfm2MoeConfig
38
+
39
+
40
+ if is_causal_conv1d_available():
41
+ from causal_conv1d import causal_conv1d_fn, causal_conv1d_update
42
+ else:
43
+ causal_conv1d_fn, causal_conv1d_update = None, None
44
+
45
+
46
+ kernel_modules = (causal_conv1d_fn, causal_conv1d_update)
47
+ is_fast_path_available = all(kernel_modules)
48
+
49
+
50
+ logger = logging.get_logger(__name__)
51
+
52
+
53
+ class Lfm2MoeRMSNorm(LlamaRMSNorm):
54
+ pass
55
+
56
+
57
+ class Lfm2MoeRotaryEmbedding(Lfm2RotaryEmbedding):
58
+ pass
59
+
60
+
61
+ class Lfm2MoeMLP(Lfm2MLP):
62
+ def __init__(self, config: Lfm2MoeConfig, intermediate_size: int | None = None):
63
+ nn.Module.__init__(self)
64
+ self.hidden_size = config.hidden_size
65
+ self.intermediate_size = config.intermediate_size if intermediate_size is None else intermediate_size
66
+ self.w1 = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
67
+ self.w3 = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
68
+ self.w2 = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
69
+
70
+
71
+ class Lfm2MoeExperts(Qwen2MoeExperts):
72
+ def __init__(self, config):
73
+ super().__init__(config)
74
+ self.act_fn = F.silu
75
+
76
+
77
+ class Lfm2MoeSparseMoeBlock(nn.Module):
78
+ def __init__(self, config):
79
+ super().__init__()
80
+ self.top_k = config.num_experts_per_tok
81
+ self.routed_scaling_factor = config.routed_scaling_factor
82
+ self.norm_topk_prob = config.norm_topk_prob
83
+ self.use_expert_bias = config.use_expert_bias
84
+
85
+ self.gate = nn.Linear(config.hidden_size, config.num_experts, bias=False)
86
+ self.experts = Lfm2MoeExperts(config)
87
+ if self.use_expert_bias:
88
+ self.register_buffer("expert_bias", torch.zeros(config.num_experts, dtype=torch.float32))
89
+
90
+ def route_tokens_to_experts(self, router_logits):
91
+ routing_weights = router_logits.sigmoid()
92
+ if self.use_expert_bias:
93
+ scores_for_routing = routing_weights + self.expert_bias
94
+ _, selected_experts = torch.topk(scores_for_routing, k=self.top_k, dim=-1)
95
+ routing_weights = torch.gather(routing_weights, dim=1, index=selected_experts).type_as(router_logits)
96
+ else:
97
+ routing_weights, selected_experts = torch.topk(routing_weights, k=self.top_k, dim=-1)
98
+
99
+ if self.norm_topk_prob:
100
+ routing_weights = routing_weights / (routing_weights.sum(dim=-1, keepdim=True) + 1e-6)
101
+ routing_weights = routing_weights * self.routed_scaling_factor
102
+ return selected_experts, routing_weights
103
+
104
+ def forward(self, hidden_states: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
105
+ batch_size, sequence_length, hidden_dim = hidden_states.shape
106
+ hidden_states_reshaped = hidden_states.view(-1, hidden_dim)
107
+ router_logits = self.gate(hidden_states_reshaped)
108
+ selected_experts, routing_weights = self.route_tokens_to_experts(router_logits)
109
+ final_hidden_states = self.experts(hidden_states_reshaped, selected_experts, routing_weights)
110
+ return final_hidden_states.reshape(batch_size, sequence_length, hidden_dim)
111
+
112
+
113
+ class Lfm2MoeAttention(Lfm2Attention):
114
+ pass
115
+
116
+
117
+ class Lfm2MoeShortConv(Lfm2ShortConv):
118
+ pass
119
+
120
+
121
+ class Lfm2MoeDecoderLayer(Lfm2DecoderLayer):
122
+ def __init__(self, config: Lfm2MoeConfig, layer_idx: int):
123
+ super().__init__(config, layer_idx)
124
+ self.feed_forward = (
125
+ Lfm2MoeMLP(config, intermediate_size=config.intermediate_size)
126
+ if layer_idx < config.num_dense_layers
127
+ else Lfm2MoeSparseMoeBlock(config)
128
+ )
129
+
130
+
131
+ class Lfm2MoePreTrainedModel(LlamaPreTrainedModel):
132
+ _can_compile_fullgraph = False # uses a non-compilable cache class
133
+
134
+ @torch.no_grad()
135
+ def _init_weights(self, module):
136
+ PreTrainedModel._init_weights(self, module)
137
+ if isinstance(module, Lfm2MoeExperts):
138
+ init.normal_(module.gate_up_proj, mean=0.0, std=self.config.initializer_range)
139
+ init.normal_(module.down_proj, mean=0.0, std=self.config.initializer_range)
140
+ elif isinstance(module, Lfm2MoeSparseMoeBlock):
141
+ if module.use_expert_bias:
142
+ init.zeros_(module.expert_bias)
143
+
144
+
145
+ class Lfm2MoeModel(MixtralModel):
146
+ def __init__(self, config: Lfm2MoeConfig):
147
+ super().__init__(config)
148
+ self.pos_emb = Lfm2MoeRotaryEmbedding(config)
149
+ self.embedding_norm = Lfm2MoeRMSNorm(config.hidden_size, eps=config.norm_eps)
150
+ del self.norm
151
+ del self.rotary_emb
152
+
153
+ def forward(
154
+ self,
155
+ input_ids: torch.LongTensor | None = None,
156
+ attention_mask: torch.Tensor | None = None,
157
+ position_ids: torch.LongTensor | None = None,
158
+ past_key_values: Cache | None = None,
159
+ inputs_embeds: torch.FloatTensor | None = None,
160
+ use_cache: bool | None = None,
161
+ **kwargs: Unpack[TransformersKwargs],
162
+ ) -> MoeModelOutputWithPast:
163
+ if (input_ids is None) ^ (inputs_embeds is not None):
164
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
165
+
166
+ if inputs_embeds is None:
167
+ inputs_embeds = self.embed_tokens(input_ids)
168
+
169
+ if use_cache and past_key_values is None:
170
+ past_key_values = DynamicCache(config=self.config)
171
+
172
+ if position_ids is None:
173
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
174
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
175
+ position_ids = position_ids.unsqueeze(0)
176
+
177
+ causal_mask = create_causal_mask(
178
+ config=self.config,
179
+ inputs_embeds=inputs_embeds,
180
+ attention_mask=attention_mask,
181
+ past_key_values=past_key_values,
182
+ position_ids=position_ids,
183
+ )
184
+ # Skip masking for decoding stage. We check shape here to be compile-friendly
185
+ linear_attention = attention_mask if inputs_embeds.shape[1] != 1 else None
186
+
187
+ hidden_states = inputs_embeds
188
+ position_embeddings = self.pos_emb(hidden_states, position_ids=position_ids)
189
+
190
+ # decoder layers
191
+ for i, decoder_layer in enumerate(self.layers[: self.config.num_hidden_layers]):
192
+ layer_mask = causal_mask if self.config.layer_types[i] == "full_attention" else linear_attention
193
+ hidden_states = decoder_layer(
194
+ hidden_states,
195
+ attention_mask=layer_mask,
196
+ position_ids=position_ids,
197
+ past_key_values=past_key_values,
198
+ position_embeddings=position_embeddings,
199
+ **kwargs,
200
+ )
201
+
202
+ hidden_states = self.embedding_norm(hidden_states)
203
+
204
+ return MoeModelOutputWithPast(
205
+ last_hidden_state=hidden_states,
206
+ past_key_values=past_key_values,
207
+ )
208
+
209
+
210
+ class Lfm2MoeForCausalLM(LlamaForCausalLM):
211
+ pass
212
+
213
+
214
+ __all__ = ["Lfm2MoeForCausalLM", "Lfm2MoeModel", "Lfm2MoePreTrainedModel"]
third_party/transformers/src/transformers/models/lfm2_vl/__init__.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from .configuration_lfm2_vl import *
22
+ from .image_processing_lfm2_vl import *
23
+ from .modeling_lfm2_vl import *
24
+ from .processing_lfm2_vl import *
25
+ else:
26
+ import sys
27
+
28
+ _file = globals()["__file__"]
29
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/lfm2_vl/configuration_lfm2_vl.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """PyTorch LFM2-VL model."""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...configuration_utils import PreTrainedConfig
19
+ from ...utils import auto_docstring
20
+ from ..auto import CONFIG_MAPPING, AutoConfig
21
+
22
+
23
+ @auto_docstring(checkpoint="LiquidAI/LFM2-VL-1.6B")
24
+ @strict
25
+ class Lfm2VlConfig(PreTrainedConfig):
26
+ r"""
27
+ projector_use_layernorm (`bool`, *optional*, defaults to `True`):
28
+ Whether to use layernorm in the multimodal projector.
29
+ downsample_factor (`int`, *optional*, defaults to 2):
30
+ The downsample_factor factor of the vision backbone.
31
+ """
32
+
33
+ model_type = "lfm2_vl"
34
+ sub_configs = {"text_config": AutoConfig, "vision_config": AutoConfig}
35
+
36
+ vision_config: dict | PreTrainedConfig | None = None
37
+ text_config: dict | PreTrainedConfig | None = None
38
+ image_token_id: int = 396
39
+ projector_hidden_act: str = "gelu"
40
+ projector_hidden_size: int = 2560
41
+ projector_bias: bool = True
42
+ projector_use_layernorm: bool = True
43
+ downsample_factor: int = 2
44
+ tie_word_embeddings: bool = True
45
+
46
+ def __post_init__(self, **kwargs):
47
+ if isinstance(self.vision_config, dict):
48
+ self.vision_config["model_type"] = self.vision_config.get("model_type", "siglip2_vision_model")
49
+ self.vision_config = CONFIG_MAPPING[self.vision_config["model_type"]](**self.vision_config)
50
+ elif self.vision_config is None:
51
+ self.vision_config = CONFIG_MAPPING["siglip2_vision_model"]()
52
+
53
+ if isinstance(self.text_config, dict):
54
+ self.text_config["model_type"] = self.text_config.get("model_type", "lfm2")
55
+ self.text_config = CONFIG_MAPPING[self.text_config["model_type"]](**self.text_config)
56
+ elif self.text_config is None:
57
+ self.text_config = CONFIG_MAPPING["lfm2"]()
58
+
59
+ self.tie_word_embeddings = kwargs.pop("tie_embedding", self.tie_word_embeddings)
60
+ super().__post_init__(**kwargs)
61
+
62
+
63
+ __all__ = ["Lfm2VlConfig"]
third_party/transformers/src/transformers/models/lfm2_vl/image_processing_lfm2_vl.py ADDED
@@ -0,0 +1,561 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import math
15
+ from functools import lru_cache
16
+
17
+ import torch
18
+ from torchvision.transforms.v2 import functional as tvF
19
+
20
+ from ...image_processing_backends import TorchvisionBackend
21
+ from ...image_processing_utils import BatchFeature
22
+ from ...image_transforms import group_images_by_shape, reorder_images, split_to_tiles
23
+ from ...image_utils import (
24
+ IMAGENET_STANDARD_MEAN,
25
+ IMAGENET_STANDARD_STD,
26
+ PILImageResampling,
27
+ SizeDict,
28
+ )
29
+ from ...processing_utils import ImagesKwargs, Unpack
30
+ from ...utils import (
31
+ TensorType,
32
+ auto_docstring,
33
+ logging,
34
+ )
35
+
36
+
37
+ logger = logging.get_logger(__name__)
38
+
39
+
40
+ def round_by_factor(number: float, factor: int) -> int:
41
+ """Returns the closest integer to 'number' that is divisible by 'factor'."""
42
+ return round(number / factor) * factor
43
+
44
+
45
+ def find_closest_aspect_ratio(
46
+ aspect_ratio: float,
47
+ target_ratios: list[tuple[int, int]],
48
+ width: int,
49
+ height: int,
50
+ image_size: int,
51
+ ) -> tuple[int, int]:
52
+ """Find the closest aspect ratio from target_ratios to match the input aspect ratio.
53
+
54
+ Args:
55
+ aspect_ratio: The aspect ratio to match (width/height).
56
+ target_ratios: List of possible aspect ratios as tuples of (width, height) integers.
57
+ width: Original image width in pixels.
58
+ height: Original image height in pixels.
59
+ image_size: Base size for calculating target area.
60
+
61
+ Returns:
62
+ tuple[int, int]: The best matching ratio as (width, height) integers.
63
+ """
64
+ best_ratio_diff = float("inf")
65
+ best_ratio = (1, 1)
66
+ area = width * height
67
+
68
+ for ratio in target_ratios:
69
+ target_aspect_ratio = ratio[0] / ratio[1]
70
+ ratio_diff = abs(aspect_ratio - target_aspect_ratio)
71
+
72
+ # update best ratio if we found a closer match
73
+ if ratio_diff < best_ratio_diff:
74
+ best_ratio_diff = ratio_diff
75
+ best_ratio = ratio
76
+ # if equally close, prefer the ratio that better matches the original image area
77
+ elif ratio_diff == best_ratio_diff:
78
+ target_area = image_size * image_size * ratio[0] * ratio[1]
79
+ if area > 0.5 * target_area:
80
+ best_ratio = ratio
81
+
82
+ return best_ratio
83
+
84
+
85
+ # copied from Siglip2ImageProcessor
86
+ @lru_cache(maxsize=256)
87
+ def get_image_size_for_max_num_patches(
88
+ image_height: int, image_width: int, patch_size: int, max_num_patches: int, eps: float = 1e-5
89
+ ) -> tuple[int, int]:
90
+ """
91
+ Determine image size based on max number of patches, ensure dimensions are divisible by patch size and image is at least 1 patch.
92
+
93
+ Args:
94
+ image_height (`int`):
95
+ Original image height.
96
+ image_width (`int`):
97
+ Original image width.
98
+ patch_size (`int`):
99
+ Patch size for processing.
100
+ max_num_patches (`int`):
101
+ Maximum number of patches.
102
+ eps (`float`):
103
+ Small threshold for binary search.
104
+
105
+ Returns:
106
+ Tuple: (target_height, target_width)
107
+ """
108
+
109
+ def get_scaled_image_size(scale: float, size: int, patch_size: int) -> int:
110
+ scaled_size = size * scale
111
+ scaled_size = math.ceil(scaled_size / patch_size) * patch_size # make divisible by patch_size
112
+ scaled_size = max(patch_size, scaled_size) # ensure at least 1 patch
113
+ return int(scaled_size)
114
+
115
+ # Binary search for optimal scale
116
+ scale_min, scale_max = eps / 10, 100.0
117
+ while (scale_max - scale_min) >= eps:
118
+ scale = (scale_min + scale_max) / 2
119
+ target_height = get_scaled_image_size(scale, image_height, patch_size)
120
+ target_width = get_scaled_image_size(scale, image_width, patch_size)
121
+ num_patches = (target_height / patch_size) * (target_width / patch_size)
122
+
123
+ if num_patches <= max_num_patches:
124
+ scale_min = scale
125
+ else:
126
+ scale_max = scale
127
+
128
+ scale = scale_min
129
+ target_height = get_scaled_image_size(scale, image_height, patch_size)
130
+ target_width = get_scaled_image_size(scale, image_width, patch_size)
131
+ return target_height, target_width
132
+
133
+
134
+ def convert_image_to_patches(images: "torch.Tensor", patch_size: int) -> "torch.Tensor":
135
+ """
136
+ Convert 3D array image of shape (image_height, image_width, num_channels) into 2D array of patches of shape
137
+ (num_patches_height * num_patches_width, patch_size * patch_size * num_channels).
138
+ """
139
+ batch_size, num_channels, image_height, image_width = images.shape
140
+ num_patches_height = image_height // patch_size
141
+ num_patches_width = image_width // patch_size
142
+ patched_image = images.reshape(
143
+ batch_size, num_channels, num_patches_height, patch_size, num_patches_width, patch_size
144
+ )
145
+ patched_image = patched_image.permute(0, 2, 4, 3, 5, 1)
146
+ patched_image = patched_image.reshape(batch_size, num_patches_height * num_patches_width, -1)
147
+ return patched_image
148
+
149
+
150
+ def pad_along_first_dim(
151
+ images: "torch.Tensor", target_length: int, pad_value: int = 0
152
+ ) -> tuple["torch.Tensor", "torch.Tensor"]:
153
+ """
154
+ Pad the array along the first dimension.
155
+ """
156
+ current_length = images.shape[1]
157
+ padding_length = target_length - current_length
158
+ pixel_mask = torch.ones((target_length,), dtype=torch.int32)
159
+ if padding_length > 0:
160
+ paddings = (0, 0, 0, padding_length, 0, 0)
161
+ images = torch.nn.functional.pad(images, paddings, mode="constant", value=pad_value)
162
+ pixel_mask[-padding_length:] = 0
163
+ return images, pixel_mask
164
+
165
+
166
+ class Lfm2VlImageProcessorKwargs(ImagesKwargs, total=False):
167
+ """
168
+ downsample_factor (`int`, *optional*, defaults to `2`):
169
+ The downsampling factor for images used when resizing the image.
170
+ do_image_splitting (`bool`, *optional*, defaults to `True`):
171
+ Whether to split large images into a grid of smaller tiles. When enabled, images exceeding the maximum token
172
+ limit are divided into multiple tiles based on `min_tiles` and `max_tiles` constraints.
173
+ min_tiles (`int`, *optional*, defaults to `2`):
174
+ Minimum number of tiles (width × height) to use when splitting an image into a grid. The grid configuration
175
+ is chosen to maintain the original aspect ratio while staying within the `min_tiles` and `max_tiles` range.
176
+ max_tiles (`int`, *optional*, defaults to `10`):
177
+ Maximum number of tiles (width × height) to use when splitting an image into a grid. The grid configuration
178
+ is chosen to maintain the original aspect ratio while staying within the `min_tiles` and `max_tiles` range.
179
+ use_thumbnail (`bool`, *optional*, defaults to `True`):
180
+ Whether to include a thumbnail version of the image when splitting into tiles. The thumbnail provides a
181
+ low-resolution overview of the entire image and is added as an additional patch when the grid has more than
182
+ one tile.
183
+ min_image_tokens (`int`, *optional*, defaults to `64`):
184
+ Minimum number of image tokens (patches) to generate for an image. Images smaller than this threshold will
185
+ be upscaled to meet the minimum token requirement.
186
+ max_image_tokens (`int`, *optional*, defaults to `256`):
187
+ Maximum number of image tokens (patches) allowed for a single image. Images exceeding this limit will be
188
+ split into multiple tiles or downscaled accordingly.
189
+ encoder_patch_size (`int`, *optional*, defaults to `16`):
190
+ The patch size used by the vision encoder. Images are divided into patches of this size, and both height
191
+ and width must be divisible by this value (after accounting for the downsampling factor).
192
+ tile_size (`int`, *optional*, defaults to `512`):
193
+ The size of each tile when splitting large images into a grid. Each tile will be resized to this dimension
194
+ before being processed into patches.
195
+ max_pixels_tolerance (`float`, *optional*, defaults to `2.0`):
196
+ Tolerance factor for determining if an image is too large. An image is considered too large if its pixel
197
+ count exceeds `max_image_tokens * encoder_patch_size^2 * downsample_factor^2 * max_pixels_tolerance`.
198
+ return_row_col_info (`bool`, *optional*, defaults to `False`):
199
+ Whether to return row and column information for each image in the batch. When enabled, the output includes
200
+ `image_rows`, `image_cols`, and `image_sizes` fields indicating the grid layout and dimensions of processed images.
201
+ """
202
+
203
+ downsample_factor: int
204
+ do_image_splitting: bool
205
+ min_tiles: int
206
+ max_tiles: int
207
+ use_thumbnail: bool
208
+ min_image_tokens: int
209
+ max_image_tokens: int
210
+ encoder_patch_size: int
211
+ tile_size: int
212
+ max_pixels_tolerance: float
213
+ do_pad: bool
214
+ return_row_col_info: bool
215
+
216
+
217
+ @auto_docstring
218
+ class Lfm2VlImageProcessor(TorchvisionBackend):
219
+ downsample_factor = 2
220
+ do_image_splitting = True
221
+ min_tiles = 2
222
+ max_tiles = 10
223
+ use_thumbnail = True
224
+ min_image_tokens = 64
225
+ max_image_tokens = 256
226
+ encoder_patch_size = 16
227
+ tile_size = 512
228
+ max_pixels_tolerance = 2.0
229
+ do_resize = True
230
+ size = {"height": 512, "width": 512}
231
+ resample = PILImageResampling.BILINEAR
232
+ do_rescale = True
233
+ rescale_factor = 1 / 255
234
+ do_normalize = True
235
+ do_pad = True
236
+ return_row_col_info = False
237
+ image_mean = IMAGENET_STANDARD_MEAN
238
+ image_std = IMAGENET_STANDARD_STD
239
+ valid_kwargs = Lfm2VlImageProcessorKwargs
240
+ model_input_names = ["pixel_values", "pixel_attention_mask", "spatial_shapes"]
241
+
242
+ def __init__(self, **kwargs: Unpack[Lfm2VlImageProcessorKwargs]):
243
+ super().__init__(**kwargs)
244
+
245
+ max_thumbnail_image_patches = self.max_image_tokens * self.downsample_factor**2
246
+ tile_size_patches = (self.tile_size // self.encoder_patch_size) ** 2 if self.do_image_splitting else 0
247
+ self.max_num_patches = max(
248
+ max_thumbnail_image_patches,
249
+ tile_size_patches,
250
+ )
251
+
252
+ @lru_cache(maxsize=256)
253
+ def _target_ratios(self, min_tiles: int, max_tiles: int) -> list[tuple[int, int]]:
254
+ ratios = [
255
+ (w, h)
256
+ for n in range(min_tiles, max_tiles + 1)
257
+ for w in range(1, n + 1)
258
+ for h in range(1, n + 1)
259
+ if min_tiles <= w * h <= max_tiles
260
+ ]
261
+ return sorted(set(ratios), key=lambda x: x[0] * x[1])
262
+
263
+ def _get_grid_layout(
264
+ self,
265
+ height: int,
266
+ width: int,
267
+ min_tiles: int,
268
+ max_tiles: int,
269
+ tile_size: int,
270
+ ) -> tuple[int, int]:
271
+ aspect_ratio = width / height
272
+ target_ratios = self._target_ratios(min_tiles, max_tiles)
273
+
274
+ # find best matching grid configuration
275
+ grid_width, grid_height = find_closest_aspect_ratio(aspect_ratio, target_ratios, width, height, tile_size)
276
+
277
+ target_width = tile_size * grid_width
278
+ target_height = tile_size * grid_height
279
+ total_patches = grid_width * grid_height
280
+
281
+ return grid_width, grid_height, target_width, target_height, total_patches
282
+
283
+ def crop_image_to_patches(
284
+ self,
285
+ image: "torch.Tensor",
286
+ min_tiles: int,
287
+ max_tiles: int,
288
+ tile_size: int,
289
+ use_thumbnail: bool,
290
+ thumbnail_size: tuple[int],
291
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None" = None,
292
+ antialias: bool = True,
293
+ **kwargs,
294
+ ) -> "torch.Tensor":
295
+ """
296
+ Processes a high resolution image into patches.
297
+ This method splits a high resolution image into a grid of smaller patches while trying to maintain
298
+ the original aspect ratio. It finds the optimal grid configuration within the specified tile constraints.
299
+ """
300
+ batch_size, num_channels, height, width = image.shape
301
+ grid_width, grid_height, target_width, target_height, total_patches = self._get_grid_layout(
302
+ height, width, min_tiles=min_tiles, max_tiles=max_tiles, tile_size=tile_size
303
+ )
304
+
305
+ resized_image = super().resize(
306
+ image, SizeDict(height=target_height, width=target_width), resample=resample, antialias=antialias
307
+ )
308
+
309
+ # split the image into patches
310
+ processed_images = split_to_tiles(resized_image, num_tiles_height=grid_height, num_tiles_width=grid_width)
311
+
312
+ # Re-order processed images to a nested image structure, so it can be reordered back correctly
313
+ # Note that the images can't be stacked because the thumbnail image is of bigger size than patches
314
+ # Each image in sublist will be of shape (1, C, H, W)
315
+ processed_images = list(processed_images)
316
+
317
+ if use_thumbnail and grid_width * grid_height != 1:
318
+ total_patches += 1
319
+ thumbnail_image = super().resize(
320
+ image,
321
+ SizeDict(height=thumbnail_size[0], width=thumbnail_size[1]),
322
+ resample=resample,
323
+ antialias=antialias,
324
+ )
325
+ for i in range(batch_size):
326
+ processed_images[i] = list(processed_images[i]) + list(thumbnail_image[i][None, ...])
327
+
328
+ return processed_images, grid_width, grid_height
329
+
330
+ # Adapted from Qwen-VL with minor differences
331
+ def smart_resize(
332
+ self,
333
+ height: int,
334
+ width: int,
335
+ downsample_factor: int,
336
+ min_image_tokens: int,
337
+ max_image_tokens: int,
338
+ encoder_patch_size: int,
339
+ ) -> tuple[int, int]:
340
+ """
341
+ Rescales the image so that the following conditions are met:
342
+ 1. Both dimensions (height and width) are divisible by 'encoder_patch_size' * 'downsample_factor'.
343
+ This ensures no padding is needed in the downsampling step.
344
+ 2. The total number of pixels is within the range ['smart_resize_min_pixels', 'smart_resize_max_pixels'].
345
+ 3. The aspect ratio of the image is maintained as closely as possible.
346
+ """
347
+ total_factor = encoder_patch_size * downsample_factor
348
+ smart_resize_min_pixels = min_image_tokens * encoder_patch_size**2 * downsample_factor**2
349
+ smart_resize_max_pixels = max_image_tokens * encoder_patch_size**2 * downsample_factor**2
350
+
351
+ h_bar = max(total_factor, round_by_factor(height, total_factor))
352
+ w_bar = max(total_factor, round_by_factor(width, total_factor))
353
+
354
+ if h_bar * w_bar > smart_resize_max_pixels:
355
+ beta = math.sqrt((height * width) / smart_resize_max_pixels)
356
+ math.floor(height / beta / total_factor) * total_factor
357
+ h_bar = max(total_factor, math.floor(height / beta / total_factor) * total_factor)
358
+ w_bar = max(total_factor, math.floor(width / beta / total_factor) * total_factor)
359
+ elif h_bar * w_bar < smart_resize_min_pixels:
360
+ beta = math.sqrt(smart_resize_min_pixels / (height * width))
361
+ h_bar = math.ceil(height * beta / total_factor) * total_factor
362
+ w_bar = math.ceil(width * beta / total_factor) * total_factor
363
+
364
+ return w_bar, h_bar
365
+
366
+ def _is_image_too_large(
367
+ self,
368
+ height: int,
369
+ width: int,
370
+ max_image_tokens: int,
371
+ encoder_patch_size: int,
372
+ downsample_factor: int,
373
+ max_pixels_tolerance: float,
374
+ ) -> bool:
375
+ """Check if the image is too large to be processed as one tile."""
376
+ total_factor = encoder_patch_size * downsample_factor
377
+
378
+ h_bar = max(encoder_patch_size, round_by_factor(height, total_factor))
379
+ w_bar = max(encoder_patch_size, round_by_factor(width, total_factor))
380
+ return h_bar * w_bar > max_image_tokens * encoder_patch_size**2 * downsample_factor**2 * max_pixels_tolerance
381
+
382
+ def resize_and_split(
383
+ self,
384
+ images: "torch.Tensor",
385
+ downsample_factor: int,
386
+ min_tiles: int,
387
+ max_tiles: int,
388
+ use_thumbnail: bool,
389
+ min_image_tokens: int,
390
+ max_image_tokens: int,
391
+ encoder_patch_size: int,
392
+ tile_size: int,
393
+ max_pixels_tolerance: float,
394
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None",
395
+ ) -> tuple[list["torch.Tensor"], list[list[int]], list[list[int]], list[list[tuple[int, int]]]]:
396
+ batch_size, _, height, width = images.shape
397
+ do_image_splitting = not min_tiles == max_tiles == 1
398
+ is_image_large = self._is_image_too_large(
399
+ height=height,
400
+ width=width,
401
+ max_image_tokens=max_image_tokens,
402
+ encoder_patch_size=encoder_patch_size,
403
+ downsample_factor=downsample_factor,
404
+ max_pixels_tolerance=max_pixels_tolerance,
405
+ )
406
+
407
+ new_width, new_height = self.smart_resize(
408
+ height=height,
409
+ width=width,
410
+ downsample_factor=downsample_factor,
411
+ min_image_tokens=min_image_tokens,
412
+ max_image_tokens=max_image_tokens,
413
+ encoder_patch_size=encoder_patch_size,
414
+ )
415
+
416
+ # Big image will be cropped into patches and small images are just resized
417
+ if is_image_large and do_image_splitting:
418
+ images, num_cols, num_rows = self.crop_image_to_patches(
419
+ images,
420
+ min_tiles=min_tiles,
421
+ max_tiles=max_tiles,
422
+ tile_size=tile_size,
423
+ thumbnail_size=(new_height, new_width),
424
+ use_thumbnail=use_thumbnail,
425
+ resample=resample,
426
+ )
427
+ else:
428
+ num_rows = num_cols = 1
429
+ images = super().resize(images, SizeDict(height=new_height, width=new_width), resample=resample)
430
+ # Make a list and treat it as single crop per image so it can be re-grouped back correctly
431
+ images = [[image] for image in images]
432
+
433
+ num_rows = [num_rows] * batch_size
434
+ num_cols = [num_cols] * batch_size
435
+ image_sizes = [[new_height, new_width]] * batch_size
436
+ return images, num_rows, num_cols, image_sizes
437
+
438
+ def _preprocess(
439
+ self,
440
+ images: list["torch.Tensor"],
441
+ do_resize: bool,
442
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None",
443
+ do_rescale: bool,
444
+ rescale_factor: float,
445
+ do_normalize: bool,
446
+ image_mean: float | list[float],
447
+ image_std: float | list[float],
448
+ downsample_factor: int,
449
+ do_image_splitting: bool,
450
+ min_tiles: int,
451
+ max_tiles: int,
452
+ use_thumbnail: bool,
453
+ min_image_tokens: int,
454
+ max_image_tokens: int,
455
+ encoder_patch_size: int,
456
+ tile_size: int,
457
+ max_pixels_tolerance: float,
458
+ do_pad: bool,
459
+ return_row_col_info: bool,
460
+ return_tensors: str | TensorType | None,
461
+ disable_grouping: bool | None,
462
+ **kwargs,
463
+ ) -> BatchFeature:
464
+ if not do_image_splitting:
465
+ min_tiles = 1
466
+ max_tiles = 1
467
+ logger.debug(
468
+ "Image splitting is disabled, setting min_tiles and max_tiles to 1. Set do_image_splitting=True to enable splitting."
469
+ )
470
+
471
+ if do_image_splitting and min_tiles > max_tiles:
472
+ raise ValueError("min_tiles must be less than or equal to max_tiles")
473
+
474
+ max_thumbnail_image_patches = max_image_tokens * downsample_factor**2
475
+ tile_size_patches = (tile_size // encoder_patch_size) ** 2 if do_image_splitting else 0
476
+ max_num_patches = max(
477
+ max_thumbnail_image_patches,
478
+ tile_size_patches,
479
+ )
480
+
481
+ grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
482
+ resized_images_grouped = {}
483
+ resized_image_sizes = {}
484
+ rows_grouped, cols_grouped = {}, {}
485
+ for shape, stacked_images in grouped_images.items():
486
+ num_rows = [1] * stacked_images.shape[0]
487
+ num_cols = [1] * stacked_images.shape[0]
488
+ height, width = stacked_images.shape[-2:]
489
+ image_sizes = [[height, width]] * stacked_images.shape[0]
490
+ do_resize = True
491
+
492
+ if do_resize:
493
+ stacked_images, num_rows, num_cols, image_sizes = self.resize_and_split(
494
+ stacked_images,
495
+ downsample_factor=downsample_factor,
496
+ min_tiles=min_tiles,
497
+ max_tiles=max_tiles,
498
+ use_thumbnail=use_thumbnail,
499
+ min_image_tokens=min_image_tokens,
500
+ max_image_tokens=max_image_tokens,
501
+ encoder_patch_size=encoder_patch_size,
502
+ tile_size=tile_size,
503
+ max_pixels_tolerance=max_pixels_tolerance,
504
+ resample=resample,
505
+ )
506
+
507
+ rows_grouped[shape] = num_rows
508
+ cols_grouped[shape] = num_cols
509
+ resized_image_sizes[shape] = image_sizes
510
+ resized_images_grouped[shape] = stacked_images
511
+ resized_images = reorder_images(resized_images_grouped, grouped_images_index)
512
+ batch_rows = reorder_images(rows_grouped, grouped_images_index)
513
+ batch_cols = reorder_images(cols_grouped, grouped_images_index)
514
+ resized_image_sizes = reorder_images(resized_image_sizes, grouped_images_index)
515
+
516
+ grouped_images, grouped_images_index = group_images_by_shape(
517
+ resized_images, disable_grouping=disable_grouping, is_nested=True
518
+ )
519
+
520
+ processed_images_grouped = {}
521
+ processed_masks, processed_spatial_shapes = {}, {}
522
+ for shape, stacked_images in grouped_images.items():
523
+ # Fused rescale and normalize
524
+ stacked_images = self.rescale_and_normalize(
525
+ stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std
526
+ )
527
+ batch_size, *_, height, width = stacked_images.shape
528
+ num_patches_height = height // encoder_patch_size
529
+ num_patches_width = width // encoder_patch_size
530
+
531
+ stacked_images = convert_image_to_patches(stacked_images, encoder_patch_size)
532
+ processed_spatial_shapes[shape] = [[num_patches_height, num_patches_width]] * batch_size
533
+
534
+ if do_pad:
535
+ stacked_images, pixel_mask = pad_along_first_dim(stacked_images, max_num_patches)
536
+ processed_masks[shape] = [pixel_mask] * batch_size
537
+
538
+ processed_images_grouped[shape] = stacked_images
539
+
540
+ processed_images = reorder_images(processed_images_grouped, grouped_images_index, is_nested=True)
541
+ data = {"pixel_values": torch.cat([torch.stack(images) for images in processed_images])}
542
+
543
+ if do_pad:
544
+ processed_masks = reorder_images(processed_masks, grouped_images_index, is_nested=True)
545
+ processed_spatial_shapes = reorder_images(processed_spatial_shapes, grouped_images_index, is_nested=True)
546
+ processed_masks = torch.cat([torch.stack(masks) for masks in processed_masks])
547
+ processed_spatial_shapes = torch.cat(
548
+ [torch.tensor(spatial_shape) for spatial_shape in processed_spatial_shapes]
549
+ )
550
+ data.update({"pixel_attention_mask": processed_masks, "spatial_shapes": processed_spatial_shapes})
551
+
552
+ if return_row_col_info:
553
+ data["image_rows"] = batch_rows
554
+ data["image_cols"] = batch_cols
555
+ data["image_sizes"] = resized_image_sizes
556
+
557
+ encoding = BatchFeature(data=data, tensor_type=return_tensors)
558
+ return encoding
559
+
560
+
561
+ __all__ = ["Lfm2VlImageProcessor"]
third_party/transformers/src/transformers/models/lfm2_vl/modeling_lfm2_vl.py ADDED
@@ -0,0 +1,482 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/lfm2_vl/modular_lfm2_vl.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_lfm2_vl.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 the HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ from dataclasses import dataclass
22
+
23
+ import torch
24
+ from torch import nn
25
+
26
+ from ...activations import ACT2FN
27
+ from ...cache_utils import Cache
28
+ from ...generation import GenerationMixin
29
+ from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling, ModelOutput
30
+ from ...modeling_utils import PreTrainedModel
31
+ from ...processing_utils import Unpack
32
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, torch_compilable_check
33
+ from ..auto import AutoModel
34
+ from .configuration_lfm2_vl import Lfm2VlConfig
35
+
36
+
37
+ class Lfm2VlMultiModalProjector(nn.Module):
38
+ def __init__(self, config: Lfm2VlConfig):
39
+ super().__init__()
40
+ in_channels = config.vision_config.hidden_size * (config.downsample_factor**2)
41
+ self.factor = config.downsample_factor
42
+ self.use_layer_norm = config.projector_use_layernorm
43
+ self.layer_norm = nn.LayerNorm(in_channels) if config.projector_use_layernorm else None
44
+ self.linear_1 = nn.Linear(
45
+ in_channels,
46
+ config.projector_hidden_size,
47
+ bias=config.projector_bias,
48
+ )
49
+ self.act = ACT2FN[config.projector_hidden_act]
50
+ self.linear_2 = nn.Linear(
51
+ config.projector_hidden_size,
52
+ config.text_config.hidden_size,
53
+ bias=config.projector_bias,
54
+ )
55
+
56
+ def forward(self, image_features: torch.Tensor):
57
+ image_features = self.pixel_unshuffle(image_features)
58
+ if self.use_layer_norm:
59
+ image_features = self.layer_norm(image_features)
60
+ hidden_states = self.linear_1(image_features)
61
+ hidden_states = self.act(hidden_states)
62
+ hidden_states = self.linear_2(hidden_states)
63
+ return hidden_states
64
+
65
+ def pixel_unshuffle(self, hidden_states: torch.Tensor):
66
+ batch_size, width, height, channels = hidden_states.size()
67
+ hidden_states = hidden_states.reshape(batch_size, width, height // self.factor, channels * self.factor)
68
+ hidden_states = hidden_states.permute(0, 2, 1, 3)
69
+ hidden_states = hidden_states.reshape(
70
+ batch_size, height // self.factor, width // self.factor, channels * self.factor**2
71
+ )
72
+ hidden_states = hidden_states.permute(0, 2, 1, 3)
73
+ return hidden_states
74
+
75
+
76
+ @auto_docstring
77
+ class Lfm2VlPreTrainedModel(PreTrainedModel):
78
+ config: Lfm2VlConfig
79
+ base_model_prefix = "model"
80
+ input_modalities = ("image", "text")
81
+ supports_gradient_checkpointing = True
82
+ _skip_keys_device_placement = "past_key_values"
83
+
84
+ _supports_flash_attn = True
85
+ _supports_sdpa = True
86
+ _can_compile_fullgraph = False
87
+ _supports_flex_attn = True
88
+ _supports_attention_backend = True
89
+
90
+
91
+ @dataclass
92
+ @auto_docstring(
93
+ custom_intro="""
94
+ Base class for Lfm2Vl causal language model (or autoregressive) outputs.
95
+ """
96
+ )
97
+ class Lfm2VlCausalLMOutputWithPast(ModelOutput):
98
+ r"""
99
+ loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
100
+ Language modeling loss (for next-token prediction).
101
+ logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
102
+ Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
103
+ past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
104
+ It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
105
+
106
+ Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
107
+ `past_key_values` input) to speed up sequential decoding.
108
+ image_hidden_states (`torch.FloatTensor`, *optional*):
109
+ A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`.
110
+ image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state.
111
+ """
112
+
113
+ loss: torch.FloatTensor | None = None
114
+ logits: torch.FloatTensor | None = None
115
+ past_key_values: Cache | None = None
116
+ hidden_states: tuple[torch.FloatTensor] | None = None
117
+ attentions: tuple[torch.FloatTensor] | None = None
118
+ image_hidden_states: torch.FloatTensor | None = None
119
+
120
+
121
+ @dataclass
122
+ @auto_docstring(
123
+ custom_intro="""
124
+ Base class for Lfm2Vl outputs, with hidden states and attentions.
125
+ """
126
+ )
127
+ class Lfm2VlModelOutputWithPast(BaseModelOutputWithPast):
128
+ r"""
129
+ past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
130
+ It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
131
+
132
+ Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
133
+ `past_key_values` input) to speed up sequential decoding.
134
+ image_hidden_states (`torch.FloatTensor`, *optional*):
135
+ A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`.
136
+ image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state.
137
+ """
138
+
139
+ image_hidden_states: torch.FloatTensor | None = None
140
+
141
+
142
+ @auto_docstring(
143
+ custom_intro="""
144
+ The Lfm2Vl model which consists of a vision backbone and a language model, without a language modeling head.
145
+ """
146
+ )
147
+ class Lfm2VlModel(Lfm2VlPreTrainedModel):
148
+ def __init__(self, config: Lfm2VlConfig):
149
+ super().__init__(config)
150
+ self.vision_tower = AutoModel.from_config(config.vision_config)
151
+
152
+ self.multi_modal_projector = Lfm2VlMultiModalProjector(config)
153
+ self.language_model = AutoModel.from_config(config.text_config)
154
+ self.post_init()
155
+
156
+ def get_input_embeddings(self):
157
+ return self.language_model.get_input_embeddings()
158
+
159
+ def set_input_embeddings(self, value):
160
+ self.language_model.set_input_embeddings(value)
161
+
162
+ @can_return_tuple
163
+ @auto_docstring(
164
+ custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection."
165
+ )
166
+ def get_image_features(
167
+ self,
168
+ pixel_values: torch.FloatTensor,
169
+ spatial_shapes: torch.Tensor,
170
+ pixel_attention_mask: torch.Tensor,
171
+ **kwargs: Unpack[TransformersKwargs],
172
+ ) -> tuple | BaseModelOutputWithPooling:
173
+ r"""
174
+ pixel_values (`torch.FloatTensor]` of shape `(batch_size, channels, height, width)`):
175
+ The tensors corresponding to the input images.
176
+ spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`):
177
+ The spatial shapes of the input images.
178
+ pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`):
179
+ The pixel attention mask of the input images.
180
+ """
181
+ image_outputs = self.vision_tower(
182
+ pixel_values=pixel_values,
183
+ spatial_shapes=spatial_shapes,
184
+ pixel_attention_mask=pixel_attention_mask,
185
+ return_dict=True,
186
+ **kwargs,
187
+ )
188
+ last_hidden_state = image_outputs.last_hidden_state
189
+
190
+ img_feature_lengths = pixel_attention_mask.sum(dim=1)
191
+ image_features = []
192
+
193
+ for img_idx in range(last_hidden_state.size(0)):
194
+ feature = last_hidden_state[img_idx]
195
+ # unpad the image representation
196
+ feature = feature[: img_feature_lengths[img_idx], :].unsqueeze(0)
197
+
198
+ # reshape to original height and width
199
+ feature_org_h, feature_org_w = spatial_shapes[img_idx]
200
+ feature = feature.reshape(1, feature_org_h, feature_org_w, -1)
201
+
202
+ # project the image representation
203
+ img_embedding = self.multi_modal_projector(feature)
204
+
205
+ # flatten here to handle variable length in naflex
206
+ img_embedding = img_embedding.reshape(-1, img_embedding.size(-1))
207
+ image_features.append(img_embedding)
208
+
209
+ image_outputs.pooler_output = image_features
210
+ return image_outputs
211
+
212
+ def get_placeholder_mask(
213
+ self, input_ids: torch.LongTensor, inputs_embeds: torch.FloatTensor, image_features: torch.FloatTensor
214
+ ):
215
+ """
216
+ Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is
217
+ equal to the length of multimodal features. If the lengths are different, an error is raised.
218
+ """
219
+ if input_ids is None:
220
+ special_image_mask = inputs_embeds == self.get_input_embeddings()(
221
+ torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
222
+ )
223
+ special_image_mask = special_image_mask.all(-1)
224
+ else:
225
+ special_image_mask = input_ids == self.config.image_token_id
226
+
227
+ n_image_tokens = special_image_mask.sum()
228
+ special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
229
+ n_image_features = image_features.shape[0]
230
+ torch_compilable_check(
231
+ inputs_embeds[special_image_mask].numel() == image_features.numel(),
232
+ f"Image features and image tokens do not match, tokens: {n_image_tokens}, features: {n_image_features}",
233
+ )
234
+ return special_image_mask
235
+
236
+ @can_return_tuple
237
+ @auto_docstring
238
+ def forward(
239
+ self,
240
+ input_ids: torch.LongTensor | None = None,
241
+ attention_mask: torch.Tensor | None = None,
242
+ position_ids: torch.LongTensor | None = None,
243
+ pixel_values: torch.FloatTensor | None = None,
244
+ spatial_shapes: torch.Tensor | None = None,
245
+ pixel_attention_mask: torch.Tensor | None = None,
246
+ past_key_values: Cache | None = None,
247
+ inputs_embeds: torch.FloatTensor | None = None,
248
+ use_cache: bool | None = None,
249
+ **kwargs: Unpack[TransformersKwargs],
250
+ ) -> tuple | Lfm2VlModelOutputWithPast:
251
+ r"""
252
+ spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*):
253
+ The spatial shapes of the input images.
254
+ pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*):
255
+ The pixel attention mask of the input images.
256
+ """
257
+
258
+ if (input_ids is None) ^ (inputs_embeds is not None):
259
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
260
+
261
+ if inputs_embeds is None:
262
+ inputs_embeds = self.get_input_embeddings()(input_ids)
263
+
264
+ if pixel_values is not None:
265
+ image_features = self.get_image_features(
266
+ pixel_values=pixel_values,
267
+ spatial_shapes=spatial_shapes,
268
+ pixel_attention_mask=pixel_attention_mask,
269
+ return_dict=True,
270
+ ).pooler_output
271
+ image_features = torch.cat(image_features, dim=0).to(inputs_embeds.device, inputs_embeds.dtype)
272
+ special_image_mask = self.get_placeholder_mask(
273
+ input_ids=input_ids,
274
+ inputs_embeds=inputs_embeds,
275
+ image_features=image_features,
276
+ )
277
+ inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_features)
278
+
279
+ outputs = self.language_model(
280
+ attention_mask=attention_mask,
281
+ position_ids=position_ids,
282
+ past_key_values=past_key_values,
283
+ inputs_embeds=inputs_embeds,
284
+ use_cache=use_cache,
285
+ **kwargs,
286
+ )
287
+
288
+ return Lfm2VlModelOutputWithPast(
289
+ last_hidden_state=outputs.last_hidden_state,
290
+ past_key_values=outputs.past_key_values,
291
+ hidden_states=outputs.hidden_states,
292
+ attentions=outputs.attentions,
293
+ image_hidden_states=image_features if pixel_values is not None else None,
294
+ )
295
+
296
+
297
+ @auto_docstring(
298
+ custom_intro="""
299
+ The LFM2_VL model which consists of a vision backbone and a language model.
300
+ """
301
+ )
302
+ class Lfm2VlForConditionalGeneration(Lfm2VlPreTrainedModel, GenerationMixin):
303
+ _tied_weights_keys = {"lm_head.weight": "model.language_model.embed_tokens.weight"}
304
+
305
+ def __init__(self, config: Lfm2VlConfig):
306
+ super().__init__(config)
307
+ self.model = Lfm2VlModel(config)
308
+ self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False)
309
+ self.post_init()
310
+
311
+ def get_input_embeddings(self):
312
+ return self.model.get_input_embeddings()
313
+
314
+ def set_input_embeddings(self, value):
315
+ self.model.set_input_embeddings(value)
316
+
317
+ def get_output_embeddings(self) -> nn.Module:
318
+ return self.lm_head
319
+
320
+ @auto_docstring
321
+ def get_image_features(
322
+ self,
323
+ pixel_values: torch.FloatTensor,
324
+ spatial_shapes: torch.Tensor,
325
+ pixel_attention_mask: torch.Tensor,
326
+ **kwargs: Unpack[TransformersKwargs],
327
+ ) -> tuple | BaseModelOutputWithPooling:
328
+ r"""
329
+ pixel_values (`torch.FloatTensor]` of shape `(batch_size, channels, height, width)`):
330
+ The tensors corresponding to the input images.
331
+ spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`):
332
+ The spatial shapes of the input images.
333
+ pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`):
334
+ The pixel attention mask of the input images.
335
+ """
336
+ return self.model.get_image_features(
337
+ pixel_values=pixel_values,
338
+ spatial_shapes=spatial_shapes,
339
+ pixel_attention_mask=pixel_attention_mask,
340
+ **kwargs,
341
+ )
342
+
343
+ @can_return_tuple
344
+ def forward(
345
+ self,
346
+ input_ids: torch.LongTensor | None = None,
347
+ pixel_values: torch.FloatTensor | None = None,
348
+ spatial_shapes: torch.Tensor | None = None,
349
+ pixel_attention_mask: torch.Tensor | None = None,
350
+ attention_mask: torch.Tensor | None = None,
351
+ position_ids: torch.LongTensor | None = None,
352
+ past_key_values: Cache | None = None,
353
+ inputs_embeds: torch.FloatTensor | None = None,
354
+ labels: torch.LongTensor | None = None,
355
+ use_cache: bool | None = None,
356
+ logits_to_keep: int | torch.Tensor = 0,
357
+ **kwargs: Unpack[TransformersKwargs],
358
+ ) -> tuple | Lfm2VlCausalLMOutputWithPast:
359
+ r"""
360
+ pixel_values (`torch.FloatTensor` of shape `(batch_size, channels, height, width)`, *optional*):
361
+ The input image tensors.
362
+ spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*):
363
+ The spatial shapes of the input images.
364
+ pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*):
365
+ The pixel attention mask of the input images.
366
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
367
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
368
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
369
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
370
+
371
+ Example:
372
+
373
+ ```python
374
+ >>> from PIL import Image
375
+ >>> import httpx
376
+ >>> from io import BytesIO
377
+ >>> from transformers import AutoProcessor, AutoModelForImageTextToText
378
+ >>> from transformers.image_utils import load_image
379
+
380
+ >>> model = AutoModelForImageTextToText.from_pretrained(
381
+ ... "LiquidAI/LFM2-VL-1.6B",
382
+ ... )
383
+ >>> processor = AutoProcessor.from_pretrained(
384
+ ... "LiquidAI/LFM2-VL-1.6B",
385
+ ... )
386
+
387
+ >>> url = "https://www.ilankelman.org/stopsigns/australia.jpg"
388
+ >>> image = load_image(url)
389
+
390
+ >>> conversation = [
391
+ ... {
392
+ ... "role": "user",
393
+ ... "content": [
394
+ ... {"type": "image", "image": image},
395
+ ... {"type": "text", "text": "What is in this image?"},
396
+ ... ],
397
+ ... },
398
+ ... ]
399
+
400
+ >>> inputs = processor.apply_chat_template(
401
+ ... conversation,
402
+ ... add_generation_prompt=True,
403
+ ... tokenize=True,
404
+ ... return_dict=True,
405
+ ... return_tensors="pt"
406
+ ... )
407
+
408
+ >>> # Generate
409
+ >>> outputs = model.generate(**inputs, max_new_tokens=45)
410
+ >>> processor.batch_decode(outputs, skip_special_tokens=True)[0]
411
+ 'This image depicts a vibrant street scene in what appears to be a Chinatown or similar cultural area. The focal point is a large red stop sign with white lettering, mounted on a pole.'
412
+ ```"""
413
+ outputs = self.model(
414
+ input_ids=input_ids,
415
+ pixel_values=pixel_values,
416
+ spatial_shapes=spatial_shapes,
417
+ pixel_attention_mask=pixel_attention_mask,
418
+ attention_mask=attention_mask,
419
+ position_ids=position_ids,
420
+ past_key_values=past_key_values,
421
+ inputs_embeds=inputs_embeds,
422
+ use_cache=use_cache,
423
+ **kwargs,
424
+ )
425
+
426
+ hidden_states = outputs[0]
427
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
428
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
429
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
430
+
431
+ loss = None
432
+ if labels is not None:
433
+ loss = self.loss_function(
434
+ logits=logits,
435
+ labels=labels,
436
+ vocab_size=self.config.text_config.vocab_size,
437
+ **kwargs,
438
+ )
439
+
440
+ return Lfm2VlCausalLMOutputWithPast(
441
+ loss=loss,
442
+ logits=logits,
443
+ past_key_values=outputs.past_key_values,
444
+ hidden_states=outputs.hidden_states,
445
+ attentions=outputs.attentions,
446
+ image_hidden_states=outputs.image_hidden_states,
447
+ )
448
+
449
+ def prepare_inputs_for_generation(
450
+ self,
451
+ input_ids,
452
+ past_key_values=None,
453
+ inputs_embeds=None,
454
+ pixel_values=None,
455
+ attention_mask=None,
456
+ logits_to_keep=None,
457
+ is_first_iteration=False,
458
+ **kwargs,
459
+ ):
460
+ # Overwritten -- in specific circumstances we don't want to forward image inputs to the model
461
+
462
+ model_inputs = super().prepare_inputs_for_generation(
463
+ input_ids,
464
+ past_key_values=past_key_values,
465
+ inputs_embeds=inputs_embeds,
466
+ attention_mask=attention_mask,
467
+ logits_to_keep=logits_to_keep,
468
+ is_first_iteration=is_first_iteration,
469
+ **kwargs,
470
+ )
471
+
472
+ if is_first_iteration or not kwargs.get("use_cache", True):
473
+ # Pixel values are used only in the first iteration if available
474
+ # In subsequent iterations, they are already merged with text and cached
475
+ # NOTE: first iteration doesn't have to be prefill, it can be the first
476
+ # iteration with a question and cached system prompt (continue generate from cache)
477
+ model_inputs["pixel_values"] = pixel_values
478
+
479
+ return model_inputs
480
+
481
+
482
+ __all__ = ["Lfm2VlForConditionalGeneration", "Lfm2VlPreTrainedModel", "Lfm2VlModel"]
third_party/transformers/src/transformers/models/lfm2_vl/modular_lfm2_vl.py ADDED
@@ -0,0 +1,359 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """PyTorch Lfm2-VL model."""
15
+
16
+ import torch
17
+ from torch import nn
18
+
19
+ from ...activations import ACT2FN
20
+ from ...cache_utils import Cache
21
+ from ...modeling_outputs import BaseModelOutputWithPooling
22
+ from ...processing_utils import Unpack
23
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging, torch_compilable_check
24
+ from ..llava.modeling_llava import (
25
+ LlavaCausalLMOutputWithPast,
26
+ LlavaForConditionalGeneration,
27
+ LlavaModel,
28
+ LlavaModelOutputWithPast,
29
+ LlavaPreTrainedModel,
30
+ )
31
+ from .configuration_lfm2_vl import Lfm2VlConfig
32
+
33
+
34
+ logger = logging.get_logger(__name__)
35
+
36
+
37
+ class Lfm2VlMultiModalProjector(nn.Module):
38
+ def __init__(self, config: Lfm2VlConfig):
39
+ super().__init__()
40
+ in_channels = config.vision_config.hidden_size * (config.downsample_factor**2)
41
+ self.factor = config.downsample_factor
42
+ self.use_layer_norm = config.projector_use_layernorm
43
+ self.layer_norm = nn.LayerNorm(in_channels) if config.projector_use_layernorm else None
44
+ self.linear_1 = nn.Linear(
45
+ in_channels,
46
+ config.projector_hidden_size,
47
+ bias=config.projector_bias,
48
+ )
49
+ self.act = ACT2FN[config.projector_hidden_act]
50
+ self.linear_2 = nn.Linear(
51
+ config.projector_hidden_size,
52
+ config.text_config.hidden_size,
53
+ bias=config.projector_bias,
54
+ )
55
+
56
+ def forward(self, image_features: torch.Tensor):
57
+ image_features = self.pixel_unshuffle(image_features)
58
+ if self.use_layer_norm:
59
+ image_features = self.layer_norm(image_features)
60
+ hidden_states = self.linear_1(image_features)
61
+ hidden_states = self.act(hidden_states)
62
+ hidden_states = self.linear_2(hidden_states)
63
+ return hidden_states
64
+
65
+ def pixel_unshuffle(self, hidden_states: torch.Tensor):
66
+ batch_size, width, height, channels = hidden_states.size()
67
+ hidden_states = hidden_states.reshape(batch_size, width, height // self.factor, channels * self.factor)
68
+ hidden_states = hidden_states.permute(0, 2, 1, 3)
69
+ hidden_states = hidden_states.reshape(
70
+ batch_size, height // self.factor, width // self.factor, channels * self.factor**2
71
+ )
72
+ hidden_states = hidden_states.permute(0, 2, 1, 3)
73
+ return hidden_states
74
+
75
+
76
+ class Lfm2VlPreTrainedModel(LlavaPreTrainedModel):
77
+ _can_compile_fullgraph = False
78
+ base_model_prefix = "model"
79
+
80
+
81
+ class Lfm2VlCausalLMOutputWithPast(LlavaCausalLMOutputWithPast):
82
+ pass
83
+
84
+
85
+ class Lfm2VlModelOutputWithPast(LlavaModelOutputWithPast):
86
+ pass
87
+
88
+
89
+ class Lfm2VlModel(LlavaModel):
90
+ def __init__(self, config: Lfm2VlConfig):
91
+ super().__init__(config)
92
+
93
+ @can_return_tuple
94
+ @auto_docstring(
95
+ custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection."
96
+ )
97
+ def get_image_features(
98
+ self,
99
+ pixel_values: torch.FloatTensor,
100
+ spatial_shapes: torch.Tensor,
101
+ pixel_attention_mask: torch.Tensor,
102
+ **kwargs: Unpack[TransformersKwargs],
103
+ ) -> tuple | BaseModelOutputWithPooling:
104
+ r"""
105
+ pixel_values (`torch.FloatTensor]` of shape `(batch_size, channels, height, width)`):
106
+ The tensors corresponding to the input images.
107
+ spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`):
108
+ The spatial shapes of the input images.
109
+ pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`):
110
+ The pixel attention mask of the input images.
111
+ """
112
+ image_outputs = self.vision_tower(
113
+ pixel_values=pixel_values,
114
+ spatial_shapes=spatial_shapes,
115
+ pixel_attention_mask=pixel_attention_mask,
116
+ return_dict=True,
117
+ **kwargs,
118
+ )
119
+ last_hidden_state = image_outputs.last_hidden_state
120
+
121
+ img_feature_lengths = pixel_attention_mask.sum(dim=1)
122
+ image_features = []
123
+
124
+ for img_idx in range(last_hidden_state.size(0)):
125
+ feature = last_hidden_state[img_idx]
126
+ # unpad the image representation
127
+ feature = feature[: img_feature_lengths[img_idx], :].unsqueeze(0)
128
+
129
+ # reshape to original height and width
130
+ feature_org_h, feature_org_w = spatial_shapes[img_idx]
131
+ feature = feature.reshape(1, feature_org_h, feature_org_w, -1)
132
+
133
+ # project the image representation
134
+ img_embedding = self.multi_modal_projector(feature)
135
+
136
+ # flatten here to handle variable length in naflex
137
+ img_embedding = img_embedding.reshape(-1, img_embedding.size(-1))
138
+ image_features.append(img_embedding)
139
+
140
+ image_outputs.pooler_output = image_features
141
+ return image_outputs
142
+
143
+ def get_placeholder_mask(
144
+ self, input_ids: torch.LongTensor, inputs_embeds: torch.FloatTensor, image_features: torch.FloatTensor
145
+ ):
146
+ """
147
+ Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is
148
+ equal to the length of multimodal features. If the lengths are different, an error is raised.
149
+ """
150
+ if input_ids is None:
151
+ special_image_mask = inputs_embeds == self.get_input_embeddings()(
152
+ torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
153
+ )
154
+ special_image_mask = special_image_mask.all(-1)
155
+ else:
156
+ special_image_mask = input_ids == self.config.image_token_id
157
+
158
+ n_image_tokens = special_image_mask.sum()
159
+ special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
160
+ n_image_features = image_features.shape[0]
161
+ torch_compilable_check(
162
+ inputs_embeds[special_image_mask].numel() == image_features.numel(),
163
+ f"Image features and image tokens do not match, tokens: {n_image_tokens}, features: {n_image_features}",
164
+ )
165
+ return special_image_mask
166
+
167
+ @can_return_tuple
168
+ @auto_docstring
169
+ def forward(
170
+ self,
171
+ input_ids: torch.LongTensor | None = None,
172
+ attention_mask: torch.Tensor | None = None,
173
+ position_ids: torch.LongTensor | None = None,
174
+ pixel_values: torch.FloatTensor | None = None,
175
+ spatial_shapes: torch.Tensor | None = None,
176
+ pixel_attention_mask: torch.Tensor | None = None,
177
+ past_key_values: Cache | None = None,
178
+ inputs_embeds: torch.FloatTensor | None = None,
179
+ use_cache: bool | None = None,
180
+ **kwargs: Unpack[TransformersKwargs],
181
+ ) -> tuple | Lfm2VlModelOutputWithPast:
182
+ r"""
183
+ spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*):
184
+ The spatial shapes of the input images.
185
+ pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*):
186
+ The pixel attention mask of the input images.
187
+ """
188
+
189
+ if (input_ids is None) ^ (inputs_embeds is not None):
190
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
191
+
192
+ if inputs_embeds is None:
193
+ inputs_embeds = self.get_input_embeddings()(input_ids)
194
+
195
+ if pixel_values is not None:
196
+ image_features = self.get_image_features(
197
+ pixel_values=pixel_values,
198
+ spatial_shapes=spatial_shapes,
199
+ pixel_attention_mask=pixel_attention_mask,
200
+ return_dict=True,
201
+ ).pooler_output
202
+ image_features = torch.cat(image_features, dim=0).to(inputs_embeds.device, inputs_embeds.dtype)
203
+ special_image_mask = self.get_placeholder_mask(
204
+ input_ids=input_ids,
205
+ inputs_embeds=inputs_embeds,
206
+ image_features=image_features,
207
+ )
208
+ inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_features)
209
+
210
+ outputs = self.language_model(
211
+ attention_mask=attention_mask,
212
+ position_ids=position_ids,
213
+ past_key_values=past_key_values,
214
+ inputs_embeds=inputs_embeds,
215
+ use_cache=use_cache,
216
+ **kwargs,
217
+ )
218
+
219
+ return Lfm2VlModelOutputWithPast(
220
+ last_hidden_state=outputs.last_hidden_state,
221
+ past_key_values=outputs.past_key_values,
222
+ hidden_states=outputs.hidden_states,
223
+ attentions=outputs.attentions,
224
+ image_hidden_states=image_features if pixel_values is not None else None,
225
+ )
226
+
227
+
228
+ class Lfm2VlForConditionalGeneration(LlavaForConditionalGeneration):
229
+ @auto_docstring
230
+ def get_image_features(
231
+ self,
232
+ pixel_values: torch.FloatTensor,
233
+ spatial_shapes: torch.Tensor,
234
+ pixel_attention_mask: torch.Tensor,
235
+ **kwargs: Unpack[TransformersKwargs],
236
+ ) -> tuple | BaseModelOutputWithPooling:
237
+ r"""
238
+ pixel_values (`torch.FloatTensor]` of shape `(batch_size, channels, height, width)`):
239
+ The tensors corresponding to the input images.
240
+ spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`):
241
+ The spatial shapes of the input images.
242
+ pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`):
243
+ The pixel attention mask of the input images.
244
+ """
245
+ return self.model.get_image_features(
246
+ pixel_values=pixel_values,
247
+ spatial_shapes=spatial_shapes,
248
+ pixel_attention_mask=pixel_attention_mask,
249
+ **kwargs,
250
+ )
251
+
252
+ @can_return_tuple
253
+ def forward(
254
+ self,
255
+ input_ids: torch.LongTensor | None = None,
256
+ pixel_values: torch.FloatTensor | None = None,
257
+ spatial_shapes: torch.Tensor | None = None,
258
+ pixel_attention_mask: torch.Tensor | None = None,
259
+ attention_mask: torch.Tensor | None = None,
260
+ position_ids: torch.LongTensor | None = None,
261
+ past_key_values: Cache | None = None,
262
+ inputs_embeds: torch.FloatTensor | None = None,
263
+ labels: torch.LongTensor | None = None,
264
+ use_cache: bool | None = None,
265
+ logits_to_keep: int | torch.Tensor = 0,
266
+ **kwargs: Unpack[TransformersKwargs],
267
+ ) -> tuple | Lfm2VlCausalLMOutputWithPast:
268
+ r"""
269
+ pixel_values (`torch.FloatTensor` of shape `(batch_size, channels, height, width)`, *optional*):
270
+ The input image tensors.
271
+ spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*):
272
+ The spatial shapes of the input images.
273
+ pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*):
274
+ The pixel attention mask of the input images.
275
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
276
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
277
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
278
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
279
+
280
+ Example:
281
+
282
+ ```python
283
+ >>> from PIL import Image
284
+ >>> import httpx
285
+ >>> from io import BytesIO
286
+ >>> from transformers import AutoProcessor, AutoModelForImageTextToText
287
+ >>> from transformers.image_utils import load_image
288
+
289
+ >>> model = AutoModelForImageTextToText.from_pretrained(
290
+ ... "LiquidAI/LFM2-VL-1.6B",
291
+ ... )
292
+ >>> processor = AutoProcessor.from_pretrained(
293
+ ... "LiquidAI/LFM2-VL-1.6B",
294
+ ... )
295
+
296
+ >>> url = "https://www.ilankelman.org/stopsigns/australia.jpg"
297
+ >>> image = load_image(url)
298
+
299
+ >>> conversation = [
300
+ ... {
301
+ ... "role": "user",
302
+ ... "content": [
303
+ ... {"type": "image", "image": image},
304
+ ... {"type": "text", "text": "What is in this image?"},
305
+ ... ],
306
+ ... },
307
+ ... ]
308
+
309
+ >>> inputs = processor.apply_chat_template(
310
+ ... conversation,
311
+ ... add_generation_prompt=True,
312
+ ... tokenize=True,
313
+ ... return_dict=True,
314
+ ... return_tensors="pt"
315
+ ... )
316
+
317
+ >>> # Generate
318
+ >>> outputs = model.generate(**inputs, max_new_tokens=45)
319
+ >>> processor.batch_decode(outputs, skip_special_tokens=True)[0]
320
+ 'This image depicts a vibrant street scene in what appears to be a Chinatown or similar cultural area. The focal point is a large red stop sign with white lettering, mounted on a pole.'
321
+ ```"""
322
+ outputs = self.model(
323
+ input_ids=input_ids,
324
+ pixel_values=pixel_values,
325
+ spatial_shapes=spatial_shapes,
326
+ pixel_attention_mask=pixel_attention_mask,
327
+ attention_mask=attention_mask,
328
+ position_ids=position_ids,
329
+ past_key_values=past_key_values,
330
+ inputs_embeds=inputs_embeds,
331
+ use_cache=use_cache,
332
+ **kwargs,
333
+ )
334
+
335
+ hidden_states = outputs[0]
336
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
337
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
338
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
339
+
340
+ loss = None
341
+ if labels is not None:
342
+ loss = self.loss_function(
343
+ logits=logits,
344
+ labels=labels,
345
+ vocab_size=self.config.text_config.vocab_size,
346
+ **kwargs,
347
+ )
348
+
349
+ return Lfm2VlCausalLMOutputWithPast(
350
+ loss=loss,
351
+ logits=logits,
352
+ past_key_values=outputs.past_key_values,
353
+ hidden_states=outputs.hidden_states,
354
+ attentions=outputs.attentions,
355
+ image_hidden_states=outputs.image_hidden_states,
356
+ )
357
+
358
+
359
+ __all__ = ["Lfm2VlForConditionalGeneration", "Lfm2VlPreTrainedModel", "Lfm2VlModel"]
third_party/transformers/src/transformers/models/lfm2_vl/processing_lfm2_vl.py ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import math
15
+
16
+ from ...feature_extraction_utils import BatchFeature
17
+ from ...image_utils import ImageInput, make_nested_list_of_images
18
+ from ...processing_utils import (
19
+ ProcessingKwargs,
20
+ ProcessorMixin,
21
+ TextKwargs,
22
+ Unpack,
23
+ )
24
+ from ...tokenization_utils_base import BatchEncoding, TextInput
25
+ from ...utils import auto_docstring, logging
26
+
27
+
28
+ logger = logging.get_logger(__name__)
29
+
30
+
31
+ class Lfm2VlTextKwargs(TextKwargs, total=False):
32
+ """
33
+ use_image_special_tokens (`bool`, *optional*, defaults to `True`):
34
+ Whether to use special image tokens (`<|image_start|>` and `<|image_end|>`) to delimit image sequences
35
+ in the text. When enabled, images are wrapped with these tokens to clearly mark image boundaries.
36
+ When disabled, only the image token itself is used without delimiters.
37
+ """
38
+
39
+ use_image_special_tokens: bool | None
40
+
41
+
42
+ class Lfm2VlProcessorKwargs(ProcessingKwargs, total=False):
43
+ text_kwargs: Lfm2VlTextKwargs
44
+ _defaults = {
45
+ "images_kwargs": {
46
+ "return_row_col_info": True,
47
+ },
48
+ "text_kwargs": {
49
+ "use_image_special_tokens": True,
50
+ "add_special_tokens": False,
51
+ "padding": False,
52
+ "is_split_into_words": False,
53
+ },
54
+ }
55
+
56
+
57
+ @auto_docstring
58
+ class Lfm2VlProcessor(ProcessorMixin):
59
+ def __init__(
60
+ self,
61
+ image_processor,
62
+ tokenizer,
63
+ chat_template: str | None = None,
64
+ **kwargs,
65
+ ):
66
+ self.image_token = getattr(tokenizer, "image_token", "<image>")
67
+ self.image_token_id = (
68
+ tokenizer.image_token_id
69
+ if hasattr(tokenizer, "image_token_id")
70
+ else tokenizer.convert_tokens_to_ids(self.image_token)
71
+ )
72
+ self.image_start_token = getattr(tokenizer, "image_start_token", "<|image_start|>")
73
+ self.image_end_token = getattr(tokenizer, "image_end_token", "<|image_end|>")
74
+ self.image_thumbnail_token = getattr(tokenizer, "image_thumbnail_token", "<|img_thumbnail|>")
75
+ super().__init__(image_processor, tokenizer, chat_template=chat_template, **kwargs)
76
+
77
+ @auto_docstring
78
+ def __call__(
79
+ self,
80
+ images: ImageInput | list[ImageInput] | list[list[ImageInput]] | None = None,
81
+ text: TextInput | list[TextInput] | None = None,
82
+ **kwargs: Unpack[Lfm2VlProcessorKwargs],
83
+ ) -> BatchEncoding:
84
+ if text is None and images is None:
85
+ raise ValueError("You must provide one of `text` or `images`.")
86
+
87
+ if images is not None and text is None:
88
+ raise ValueError(
89
+ "You must provide `text` when `images` is provided. Minimal text consists of a single image token."
90
+ )
91
+
92
+ output_kwargs = self._merge_kwargs(
93
+ Lfm2VlProcessorKwargs,
94
+ tokenizer_init_kwargs=self.tokenizer.init_kwargs,
95
+ **kwargs,
96
+ )
97
+
98
+ if isinstance(text, str):
99
+ text = [text]
100
+ elif not isinstance(text, list) and not isinstance(text[0], str):
101
+ raise TypeError("Invalid input text. Please provide a string, or a list of strings")
102
+
103
+ n_images_in_text = [sample.count(self.image_token) for sample in text]
104
+ if sum(n_images_in_text) > 0 and images is None:
105
+ raise ValueError(f"We detected {sum(n_images_in_text)} tokens in the text but no images were passed")
106
+
107
+ inputs = {}
108
+ use_image_special_tokens = output_kwargs["text_kwargs"].pop("use_image_special_tokens")
109
+
110
+ if images is not None:
111
+ images = self.image_processor.fetch_images(images)
112
+ batched_images = make_nested_list_of_images(images)
113
+ vision_inputs = self.image_processor(batched_images, **output_kwargs["images_kwargs"])
114
+
115
+ n_images_in_images = [len(sublist) for sublist in batched_images]
116
+ if n_images_in_images != n_images_in_text:
117
+ raise ValueError(
118
+ f"The number of images in the text {n_images_in_text} and images {n_images_in_images} should be the same."
119
+ )
120
+
121
+ text = self.expand_text_with_placeholders(
122
+ text,
123
+ batched_images,
124
+ image_rows=vision_inputs.pop("image_rows"),
125
+ image_cols=vision_inputs.pop("image_cols"),
126
+ image_sizes=vision_inputs.pop("image_sizes"),
127
+ use_image_special_tokens=use_image_special_tokens,
128
+ **output_kwargs["images_kwargs"],
129
+ )
130
+ inputs.update(vision_inputs)
131
+
132
+ return_tensors = output_kwargs["text_kwargs"].pop("return_tensors", None)
133
+
134
+ text_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"])
135
+ inputs.update(text_inputs)
136
+
137
+ return BatchFeature(inputs, tensor_type=return_tensors)
138
+
139
+ def expand_text_with_placeholders(
140
+ self,
141
+ text: list[str],
142
+ images: list[list[ImageInput]],
143
+ image_rows: list[list[int]],
144
+ image_cols: list[list[int]],
145
+ image_sizes: list[list[int]],
146
+ use_image_special_tokens: bool,
147
+ **images_kwargs,
148
+ ) -> list[str]:
149
+ use_thumbnail = images_kwargs.get("use_thumbnail", self.image_processor.use_thumbnail)
150
+ image_data = iter(zip(image_rows, image_cols, image_sizes))
151
+
152
+ prompt_strings = []
153
+ for sample_text, sample_images in zip(text, images):
154
+ text_parts = sample_text.split(self.image_token)
155
+ result_parts = []
156
+
157
+ for i, _ in enumerate(sample_images):
158
+ result_parts.append(text_parts[i])
159
+
160
+ rows, cols, image_size = next(image_data)
161
+ tokens_per_tile, tokens_for_image = self._get_image_num_tokens(image_size, **images_kwargs)
162
+ image_tokens = self._build_image_tokens(
163
+ rows,
164
+ cols,
165
+ tokens_per_tile,
166
+ tokens_for_image,
167
+ use_thumbnail,
168
+ use_image_special_tokens,
169
+ )
170
+ result_parts.append(image_tokens)
171
+
172
+ # Add remaining text after the last image
173
+ if len(sample_images) < len(text_parts):
174
+ result_parts.append(text_parts[-1])
175
+
176
+ prompt_strings.append("".join(result_parts))
177
+
178
+ return prompt_strings
179
+
180
+ def _build_image_tokens(
181
+ self,
182
+ rows: int,
183
+ cols: int,
184
+ tokens_per_tile: int,
185
+ tokens_for_image: int,
186
+ use_thumbnail: bool,
187
+ use_image_special_tokens: bool,
188
+ ) -> str:
189
+ """Build the expanded token string for a single image."""
190
+ parts = []
191
+
192
+ if use_image_special_tokens:
193
+ parts.append(self.image_start_token)
194
+
195
+ is_multi_tile = rows > 1 or cols > 1
196
+ if is_multi_tile:
197
+ for row in range(rows):
198
+ for col in range(cols):
199
+ if use_image_special_tokens:
200
+ parts.append(f"<|img_row_{row + 1}_col_{col + 1}|>")
201
+ parts.append(self.image_token * tokens_per_tile)
202
+
203
+ if use_thumbnail:
204
+ if use_image_special_tokens:
205
+ parts.append(self.image_thumbnail_token)
206
+ parts.append(self.image_token * tokens_for_image)
207
+ else:
208
+ parts.append(self.image_token * tokens_for_image)
209
+
210
+ if use_image_special_tokens:
211
+ parts.append(self.image_end_token)
212
+
213
+ return "".join(parts)
214
+
215
+ def _compute_tokens_per_tile(self, tile_size: int, encoder_patch_size: int, downsample_factor: int) -> int:
216
+ """Compute the number of tokens for a single tile."""
217
+ num_patches = tile_size // encoder_patch_size
218
+ downsampled_patches = math.ceil(num_patches / downsample_factor)
219
+ return downsampled_patches * downsampled_patches
220
+
221
+ def _compute_tokens_for_image(self, image_size: list[int], encoder_patch_size: int, downsample_factor: int) -> int:
222
+ """Compute the number of tokens for a resized image (used for single-tile or thumbnail)."""
223
+ image_height, image_width = image_size
224
+ patches_h = math.ceil((image_height // encoder_patch_size) / downsample_factor)
225
+ patches_w = math.ceil((image_width // encoder_patch_size) / downsample_factor)
226
+ return patches_h * patches_w
227
+
228
+ def _get_image_num_tokens(self, image_size: list[int], **images_kwargs) -> tuple[int, int]:
229
+ """
230
+ Compute token counts for image processing.
231
+
232
+ Returns:
233
+ tuple[int, int]: (tokens_per_tile, tokens_for_image)
234
+ - tokens_per_tile: tokens for each tile in multi-tile mode
235
+ - tokens_for_image: tokens for the resized image (single-tile) or thumbnail (multi-tile)
236
+ """
237
+ tile_size = images_kwargs.get("tile_size", self.image_processor.tile_size)
238
+ downsample_factor = images_kwargs.get("downsample_factor", self.image_processor.downsample_factor)
239
+ encoder_patch_size = images_kwargs.get("encoder_patch_size", self.image_processor.encoder_patch_size)
240
+
241
+ tokens_per_tile = self._compute_tokens_per_tile(tile_size, encoder_patch_size, downsample_factor)
242
+ tokens_for_image = self._compute_tokens_for_image(image_size, encoder_patch_size, downsample_factor)
243
+
244
+ return tokens_per_tile, tokens_for_image
245
+
246
+ def batch_decode(self, *args, **kwargs):
247
+ """
248
+ This method forwards all its arguments to LFM2Tokeniser's [`~PreTrainedTokenizer.batch_decode`]. Please
249
+ refer to the docstring of this method for more information.
250
+ """
251
+ batched_decode_output = self.tokenizer.batch_decode(*args, **kwargs)
252
+ return batched_decode_output
253
+
254
+ def decode(self, *args, **kwargs):
255
+ """
256
+ This method forwards all its arguments to LFM2Tokeniser's [`~PreTrainedTokenizer.decode`]. Please refer to
257
+ the docstring of this method for more information.
258
+ """
259
+ decode_output = self.tokenizer.decode(*args, **kwargs)
260
+ return decode_output
261
+
262
+ @property
263
+ def model_input_names(self):
264
+ tokenizer_input_names = self.tokenizer.model_input_names
265
+ image_processor_input_names = self.image_processor.model_input_names
266
+
267
+ # LFM2-VL has no dedicated tokenizer class and uses the Base class with default model input names
268
+ tokenizer_input_names = [name for name in tokenizer_input_names if name != "token_type_ids"]
269
+ return list(tokenizer_input_names + image_processor_input_names)
270
+
271
+
272
+ __all__ = ["Lfm2VlProcessor"]
third_party/transformers/src/transformers/models/minimax_m2/__init__.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from typing import TYPE_CHECKING
16
+
17
+ from ...utils import _LazyModule
18
+ from ...utils.import_utils import define_import_structure
19
+
20
+
21
+ if TYPE_CHECKING:
22
+ from .configuration_minimax_m2 import *
23
+ from .modeling_minimax_m2 import *
24
+ else:
25
+ import sys
26
+
27
+ _file = globals()["__file__"]
28
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/minimax_m2/configuration_minimax_m2.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/minimax_m2/modular_minimax_m2.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_minimax_m2.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 the MiniMax AI Team and HuggingFace Team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+
22
+ from huggingface_hub.dataclasses import strict
23
+
24
+ from ...configuration_utils import PreTrainedConfig
25
+ from ...modeling_rope_utils import RopeParameters
26
+ from ...utils import auto_docstring
27
+
28
+
29
+ @auto_docstring(checkpoint="MiniMaxAI/MiniMax-Text-01-hf")
30
+ @strict
31
+ class MiniMaxM2Config(PreTrainedConfig):
32
+ r"""
33
+ Example:
34
+
35
+ ```python
36
+ >>> from transformers import MiniMaxM2Model, MiniMaxM2Config
37
+
38
+ >>> # Initializing a MiniMaxM2 style configuration
39
+ >>> configuration = MiniMaxM2Config()
40
+
41
+ >>> # Initializing a model from the MiniMaxM2 style configuration
42
+ >>> model = MiniMaxM2Model(configuration)
43
+
44
+ >>> # Accessing the model configuration
45
+ >>> configuration = model.config
46
+ ```"""
47
+
48
+ model_type = "minimax_m2"
49
+ keys_to_ignore_at_inference = ["past_key_values"]
50
+ base_model_tp_plan = {
51
+ "layers.*.self_attn.q_proj": "colwise_gather_output",
52
+ "layers.*.self_attn.k_proj": "colwise_gather_output",
53
+ "layers.*.self_attn.v_proj": "colwise_gather_output",
54
+ "layers.*.self_attn.o_proj": "rowwise_split_input",
55
+ "layers.*.mlp.experts.gate_up_proj": "packed_colwise",
56
+ "layers.*.mlp.experts.down_proj": "rowwise",
57
+ "layers.*.mlp.experts": "moe_tp_experts",
58
+ }
59
+ base_model_pp_plan = {
60
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
61
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
62
+ "norm": (["hidden_states"], ["hidden_states"]),
63
+ }
64
+ attribute_map = {
65
+ "num_experts": "num_local_experts",
66
+ }
67
+ default_theta = 5000000.0
68
+
69
+ vocab_size: int = 200064
70
+ hidden_size: int = 3072
71
+ intermediate_size: int = 1536
72
+ num_hidden_layers: int = 62
73
+ num_attention_heads: int = 48
74
+ num_key_value_heads: int = 8
75
+ head_dim: int = 128
76
+ hidden_act: str = "silu"
77
+ max_position_embeddings: int = 196608
78
+ initializer_range: float = 0.02
79
+ rms_norm_eps: float = 1e-06
80
+ use_cache: bool = True
81
+ pad_token_id: int | None = None
82
+ bos_token_id: int | None = 200034
83
+ eos_token_id: int | list[int] | None = 200020
84
+ tie_word_embeddings: bool = False
85
+ attention_dropout: float | int = 0.0
86
+ num_experts_per_tok: int = 8
87
+ num_local_experts: int = 256
88
+ output_router_logits: bool = False
89
+ router_aux_loss_coef: float = 0.001
90
+ router_jitter_noise: float = 0.0
91
+ rope_parameters: RopeParameters | dict | None = None
92
+
93
+
94
+ __all__ = ["MiniMaxM2Config"]
third_party/transformers/src/transformers/models/minimax_m2/modeling_minimax_m2.py ADDED
@@ -0,0 +1,691 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/minimax_m2/modular_minimax_m2.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_minimax_m2.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 the MiniMax AI Team and HuggingFace Team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+
22
+ from collections.abc import Callable
23
+ from typing import Optional
24
+
25
+ import torch
26
+ import torch.nn.functional as F
27
+ from torch import nn
28
+
29
+ from ... import initialization as init
30
+ from ...activations import ACT2FN
31
+ from ...cache_utils import Cache, DynamicCache
32
+ from ...generation import GenerationMixin
33
+ from ...integrations import use_experts_implementation, use_kernel_forward_from_hub, use_kernelized_func
34
+ from ...masking_utils import create_causal_mask
35
+ from ...modeling_layers import GradientCheckpointingLayer
36
+ from ...modeling_outputs import MoeCausalLMOutputWithPast, MoeModelOutputWithPast
37
+ from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
38
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
39
+ from ...processing_utils import Unpack
40
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple
41
+ from ...utils.generic import maybe_autocast, merge_with_config_defaults
42
+ from ...utils.output_capturing import OutputRecorder, capture_outputs
43
+ from .configuration_minimax_m2 import MiniMaxM2Config
44
+
45
+
46
+ class MiniMaxM2TopKRouter(nn.Module):
47
+ def __init__(self, config):
48
+ super().__init__()
49
+ self.top_k = config.num_experts_per_tok
50
+ self.num_experts = config.num_local_experts
51
+ self.hidden_dim = config.hidden_size
52
+ self.weight = nn.Parameter(torch.empty(self.num_experts, self.hidden_dim))
53
+
54
+ def forward(self, hidden_states, e_score_correction_bias):
55
+ hidden_states = hidden_states.reshape(-1, self.hidden_dim)
56
+ router_logits = F.linear(hidden_states.to(self.weight.dtype), self.weight) # (seq_len, num_experts)
57
+ # Main difference to other Moe, using Sigmoid activation instead of Softmax
58
+ routing_weights = nn.functional.sigmoid(router_logits.float())
59
+ scores_for_choice = routing_weights + e_score_correction_bias
60
+ _, top_k_index = torch.topk(scores_for_choice, self.top_k, dim=-1, sorted=False)
61
+ top_k_weights = routing_weights.gather(1, top_k_index)
62
+ top_k_weights /= top_k_weights.sum(dim=-1, keepdim=True)
63
+ router_scores = top_k_weights
64
+ return router_logits, router_scores, top_k_index
65
+
66
+
67
+ @use_experts_implementation
68
+ class MiniMaxM2Experts(nn.Module):
69
+ """Collection of expert weights stored as 3D tensors."""
70
+
71
+ def __init__(self, config: MiniMaxM2Config):
72
+ super().__init__()
73
+ self.num_experts = config.num_local_experts
74
+ self.hidden_dim = config.hidden_size
75
+ self.intermediate_dim = config.intermediate_size
76
+ self.gate_up_proj = nn.Parameter(torch.empty(self.num_experts, 2 * self.intermediate_dim, self.hidden_dim))
77
+ self.down_proj = nn.Parameter(torch.empty(self.num_experts, self.hidden_dim, self.intermediate_dim))
78
+ self.act_fn = ACT2FN[config.hidden_act]
79
+
80
+ def forward(
81
+ self,
82
+ hidden_states: torch.Tensor,
83
+ top_k_index: torch.Tensor,
84
+ top_k_weights: torch.Tensor,
85
+ ) -> torch.Tensor:
86
+ final_hidden_states = torch.zeros_like(hidden_states)
87
+ with torch.no_grad():
88
+ expert_mask = torch.nn.functional.one_hot(top_k_index, num_classes=self.num_experts)
89
+ expert_mask = expert_mask.permute(2, 1, 0)
90
+ expert_hit = torch.greater(expert_mask.sum(dim=(-1, -2)), 0).nonzero()
91
+
92
+ for expert_idx in expert_hit:
93
+ expert_idx = expert_idx[0]
94
+ if expert_idx == self.num_experts:
95
+ continue
96
+ top_k_pos, token_idx = torch.where(expert_mask[expert_idx])
97
+ current_state = hidden_states[token_idx]
98
+ gate, up = nn.functional.linear(current_state, self.gate_up_proj[expert_idx]).chunk(2, dim=-1)
99
+ current_hidden_states = self.act_fn(gate) * up
100
+ current_hidden_states = nn.functional.linear(current_hidden_states, self.down_proj[expert_idx])
101
+ current_hidden_states = current_hidden_states * top_k_weights[token_idx, top_k_pos, None]
102
+ final_hidden_states.index_add_(0, token_idx, current_hidden_states.to(final_hidden_states.dtype))
103
+
104
+ return final_hidden_states
105
+
106
+
107
+ class MiniMaxM2SparseMoeBlock(nn.Module):
108
+ def __init__(self, config):
109
+ super().__init__()
110
+ self.top_k = config.num_experts_per_tok
111
+ self.jitter_noise = config.router_jitter_noise
112
+ self.gate = MiniMaxM2TopKRouter(config)
113
+ self.experts = MiniMaxM2Experts(config)
114
+ self.register_buffer("e_score_correction_bias", torch.zeros(config.num_local_experts))
115
+
116
+ def forward(self, hidden_states: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
117
+ batch_size, sequence_length, hidden_dim = hidden_states.shape
118
+ if self.training and self.jitter_noise > 0:
119
+ hidden_states *= torch.empty_like(hidden_states).uniform_(1.0 - self.jitter_noise, 1.0 + self.jitter_noise)
120
+ hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
121
+ _, top_k_weights, top_k_index = self.gate(hidden_states, self.e_score_correction_bias)
122
+ hidden_states = self.experts(hidden_states, top_k_index, top_k_weights)
123
+ hidden_states = hidden_states.reshape(batch_size, sequence_length, hidden_dim)
124
+ return hidden_states
125
+
126
+
127
+ @use_kernel_forward_from_hub("RMSNorm")
128
+ class MiniMaxM2RMSNorm(nn.Module):
129
+ def __init__(self, hidden_size, eps: float = 1e-6) -> None:
130
+ """
131
+ MiniMaxM2RMSNorm is equivalent to T5LayerNorm
132
+ """
133
+ super().__init__()
134
+ self.weight = nn.Parameter(torch.ones(hidden_size))
135
+ self.variance_epsilon = eps
136
+
137
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
138
+ input_dtype = hidden_states.dtype
139
+ hidden_states = hidden_states.to(torch.float32)
140
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
141
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
142
+ return self.weight * hidden_states.to(input_dtype)
143
+
144
+ def extra_repr(self):
145
+ return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
146
+
147
+
148
+ class MiniMaxM2RotaryEmbedding(nn.Module):
149
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
150
+
151
+ def __init__(self, config: MiniMaxM2Config, device=None):
152
+ super().__init__()
153
+ self.max_seq_len_cached = config.max_position_embeddings
154
+ self.original_max_seq_len = config.max_position_embeddings
155
+
156
+ self.config = config
157
+
158
+ self.rope_type = self.config.rope_parameters["rope_type"]
159
+ rope_init_fn: Callable = self.compute_default_rope_parameters
160
+ if self.rope_type != "default":
161
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
162
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
163
+
164
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
165
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
166
+
167
+ @staticmethod
168
+ def compute_default_rope_parameters(
169
+ config: MiniMaxM2Config | None = None,
170
+ device: Optional["torch.device"] = None,
171
+ seq_len: int | None = None,
172
+ ) -> tuple["torch.Tensor", float]:
173
+ """
174
+ Computes the inverse frequencies according to the original RoPE implementation
175
+ Args:
176
+ config ([`~transformers.PreTrainedConfig`]):
177
+ The model configuration.
178
+ device (`torch.device`):
179
+ The device to use for initialization of the inverse frequencies.
180
+ seq_len (`int`, *optional*):
181
+ The current sequence length. Unused for this type of RoPE.
182
+ Returns:
183
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
184
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
185
+ """
186
+ base = config.rope_parameters["rope_theta"]
187
+ partial_rotary_factor = config.rope_parameters.get("partial_rotary_factor", 1.0)
188
+ head_dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
189
+ dim = int(head_dim * partial_rotary_factor)
190
+
191
+ attention_factor = 1.0 # Unused in this type of RoPE
192
+
193
+ # Compute the inverse frequencies
194
+ inv_freq = 1.0 / (
195
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
196
+ )
197
+ return inv_freq, attention_factor
198
+
199
+ @torch.no_grad()
200
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
201
+ def forward(self, x, position_ids):
202
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
203
+ position_ids_expanded = position_ids[:, None, :].float()
204
+
205
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
206
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
207
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
208
+ emb = torch.cat((freqs, freqs), dim=-1)
209
+ cos = emb.cos() * self.attention_scaling
210
+ sin = emb.sin() * self.attention_scaling
211
+
212
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
213
+
214
+
215
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
216
+ """
217
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
218
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
219
+ """
220
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
221
+ if n_rep == 1:
222
+ return hidden_states
223
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
224
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
225
+
226
+
227
+ def eager_attention_forward(
228
+ module: nn.Module,
229
+ query: torch.Tensor,
230
+ key: torch.Tensor,
231
+ value: torch.Tensor,
232
+ attention_mask: torch.Tensor | None,
233
+ scaling: float,
234
+ dropout: float = 0.0,
235
+ **kwargs: Unpack[TransformersKwargs],
236
+ ):
237
+ key_states = repeat_kv(key, module.num_key_value_groups)
238
+ value_states = repeat_kv(value, module.num_key_value_groups)
239
+
240
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
241
+ if attention_mask is not None:
242
+ attn_weights = attn_weights + attention_mask
243
+
244
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
245
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
246
+ attn_output = torch.matmul(attn_weights, value_states)
247
+ attn_output = attn_output.transpose(1, 2).contiguous()
248
+
249
+ return attn_output, attn_weights
250
+
251
+
252
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
253
+ """Applies Rotary Position Embedding to the query and key tensors.
254
+
255
+ Args:
256
+ q (`torch.Tensor`): The query tensor.
257
+ k (`torch.Tensor`): The key tensor.
258
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
259
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
260
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
261
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
262
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
263
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
264
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
265
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
266
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
267
+ Returns:
268
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
269
+ """
270
+ cos = cos.unsqueeze(unsqueeze_dim)
271
+ sin = sin.unsqueeze(unsqueeze_dim)
272
+
273
+ # Keep half or full tensor for later concatenation
274
+ rotary_dim = cos.shape[-1]
275
+ q_rot, q_pass = q[..., :rotary_dim], q[..., rotary_dim:]
276
+ k_rot, k_pass = k[..., :rotary_dim], k[..., rotary_dim:]
277
+
278
+ # Apply rotary embeddings on the first half or full tensor
279
+ q_embed = (q_rot * cos) + (rotate_half(q_rot) * sin)
280
+ k_embed = (k_rot * cos) + (rotate_half(k_rot) * sin)
281
+
282
+ # Concatenate back to full shape
283
+ q_embed = torch.cat([q_embed, q_pass], dim=-1)
284
+ k_embed = torch.cat([k_embed, k_pass], dim=-1)
285
+ return q_embed, k_embed
286
+
287
+
288
+ def rotate_half(x):
289
+ """Rotates half the hidden dims of the input."""
290
+ x1 = x[..., : x.shape[-1] // 2]
291
+ x2 = x[..., x.shape[-1] // 2 :]
292
+ return torch.cat((-x2, x1), dim=-1)
293
+
294
+
295
+ @use_kernelized_func(apply_rotary_pos_emb)
296
+ class MiniMaxM2Attention(nn.Module):
297
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
298
+
299
+ def __init__(self, config: MiniMaxM2Config, layer_idx: int):
300
+ super().__init__()
301
+ self.config = config
302
+ self.layer_idx = layer_idx
303
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
304
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
305
+ self.scaling = self.head_dim**-0.5
306
+ self.attention_dropout = config.attention_dropout
307
+ self.is_causal = True
308
+ self.q_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=False)
309
+ self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False)
310
+ self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False)
311
+ self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=False)
312
+ self.q_norm = MiniMaxM2RMSNorm(config.num_attention_heads * self.head_dim, config.rms_norm_eps)
313
+ self.k_norm = MiniMaxM2RMSNorm(config.num_key_value_heads * self.head_dim, config.rms_norm_eps)
314
+
315
+ def forward(
316
+ self,
317
+ hidden_states: torch.Tensor,
318
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
319
+ attention_mask: torch.Tensor | None,
320
+ past_key_values: Cache | None = None,
321
+ **kwargs: Unpack[TransformersKwargs],
322
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
323
+ input_shape = hidden_states.shape[:-1]
324
+ hidden_shape = (*input_shape, -1, self.head_dim)
325
+
326
+ query_states = self.q_norm(self.q_proj(hidden_states))
327
+ key_states = self.k_norm(self.k_proj(hidden_states))
328
+ value_states = self.v_proj(hidden_states)
329
+
330
+ query_states = query_states.view(hidden_shape).transpose(1, 2)
331
+ key_states = key_states.view(hidden_shape).transpose(1, 2)
332
+ value_states = value_states.view(hidden_shape).transpose(1, 2)
333
+
334
+ cos, sin = position_embeddings
335
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
336
+
337
+ if past_key_values is not None:
338
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
339
+
340
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
341
+ self.config._attn_implementation, eager_attention_forward
342
+ )
343
+
344
+ attn_output, attn_weights = attention_interface(
345
+ self,
346
+ query_states,
347
+ key_states,
348
+ value_states,
349
+ attention_mask,
350
+ dropout=0.0 if not self.training else self.attention_dropout,
351
+ scaling=self.scaling,
352
+ **kwargs,
353
+ )
354
+
355
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
356
+ attn_output = self.o_proj(attn_output)
357
+ return attn_output, attn_weights
358
+
359
+
360
+ class MiniMaxM2DecoderLayer(GradientCheckpointingLayer):
361
+ def __init__(self, config: MiniMaxM2Config, layer_idx: int):
362
+ super().__init__()
363
+ self.hidden_size = config.hidden_size
364
+
365
+ self.self_attn = MiniMaxM2Attention(config, layer_idx)
366
+
367
+ self.mlp = MiniMaxM2SparseMoeBlock(config)
368
+ self.input_layernorm = MiniMaxM2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
369
+ self.post_attention_layernorm = MiniMaxM2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
370
+
371
+ def forward(
372
+ self,
373
+ hidden_states: torch.Tensor,
374
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
375
+ attention_mask: torch.Tensor | None = None,
376
+ position_ids: torch.LongTensor | None = None,
377
+ past_key_values: Cache | None = None,
378
+ **kwargs: Unpack[TransformersKwargs],
379
+ ) -> torch.Tensor:
380
+ residual = hidden_states
381
+ hidden_states = self.input_layernorm(hidden_states)
382
+ hidden_states, _ = self.self_attn(
383
+ hidden_states=hidden_states,
384
+ position_embeddings=position_embeddings,
385
+ attention_mask=attention_mask,
386
+ position_ids=position_ids,
387
+ past_key_values=past_key_values,
388
+ **kwargs,
389
+ )
390
+ hidden_states = residual + hidden_states
391
+ residual = hidden_states
392
+ hidden_states = self.post_attention_layernorm(hidden_states)
393
+ hidden_states = self.mlp(hidden_states)
394
+ hidden_states = residual + hidden_states
395
+ return hidden_states
396
+
397
+
398
+ @auto_docstring
399
+ class MiniMaxM2PreTrainedModel(PreTrainedModel):
400
+ config: MiniMaxM2Config
401
+ base_model_prefix = "model"
402
+ supports_gradient_checkpointing = True
403
+ _no_split_modules = ["MiniMaxM2DecoderLayer"]
404
+ _skip_keys_device_placement = ["past_key_values"]
405
+ _supports_flash_attn = True
406
+ _supports_sdpa = True
407
+ _supports_flex_attn = True
408
+
409
+ _can_compile_fullgraph = True
410
+ _supports_attention_backend = True
411
+ _can_record_outputs = {
412
+ "router_logits": OutputRecorder(MiniMaxM2TopKRouter, index=0),
413
+ "hidden_states": MiniMaxM2DecoderLayer,
414
+ "attentions": MiniMaxM2Attention,
415
+ }
416
+
417
+ @torch.no_grad()
418
+ def _init_weights(self, module):
419
+ super()._init_weights(module)
420
+ std = self.config.initializer_range
421
+ if isinstance(module, MiniMaxM2Experts):
422
+ init.normal_(module.gate_up_proj, mean=0.0, std=std)
423
+ init.normal_(module.down_proj, mean=0.0, std=std)
424
+ elif isinstance(module, MiniMaxM2TopKRouter):
425
+ init.normal_(module.weight, mean=0.0, std=std)
426
+ elif isinstance(module, MiniMaxM2SparseMoeBlock):
427
+ init.zeros_(module.e_score_correction_bias)
428
+
429
+
430
+ @auto_docstring
431
+ class MiniMaxM2Model(MiniMaxM2PreTrainedModel):
432
+ def __init__(self, config: MiniMaxM2Config):
433
+ super().__init__(config)
434
+ self.padding_idx = config.pad_token_id
435
+ self.vocab_size = config.vocab_size
436
+
437
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
438
+ self.layers = nn.ModuleList(
439
+ [MiniMaxM2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
440
+ )
441
+ self.norm = MiniMaxM2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
442
+ self.rotary_emb = MiniMaxM2RotaryEmbedding(config=config)
443
+ self.gradient_checkpointing = False
444
+
445
+ # Initialize weights and apply final processing
446
+ self.post_init()
447
+
448
+ @merge_with_config_defaults
449
+ @capture_outputs
450
+ @auto_docstring
451
+ def forward(
452
+ self,
453
+ input_ids: torch.LongTensor | None = None,
454
+ attention_mask: torch.Tensor | None = None,
455
+ position_ids: torch.LongTensor | None = None,
456
+ past_key_values: Cache | None = None,
457
+ inputs_embeds: torch.FloatTensor | None = None,
458
+ use_cache: bool | None = None,
459
+ **kwargs: Unpack[TransformersKwargs],
460
+ ) -> MoeModelOutputWithPast:
461
+ if (input_ids is None) ^ (inputs_embeds is not None):
462
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
463
+
464
+ if use_cache and past_key_values is None:
465
+ past_key_values = DynamicCache(config=self.config)
466
+
467
+ if inputs_embeds is None:
468
+ inputs_embeds = self.embed_tokens(input_ids)
469
+
470
+ if position_ids is None:
471
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
472
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
473
+ position_ids = position_ids.unsqueeze(0)
474
+
475
+ # No sliding window opposed to mixtral
476
+ causal_mask = create_causal_mask(
477
+ config=self.config,
478
+ inputs_embeds=inputs_embeds,
479
+ attention_mask=attention_mask,
480
+ past_key_values=past_key_values,
481
+ position_ids=position_ids,
482
+ )
483
+
484
+ hidden_states = inputs_embeds
485
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
486
+
487
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
488
+ hidden_states = decoder_layer(
489
+ hidden_states,
490
+ attention_mask=causal_mask,
491
+ position_ids=position_ids,
492
+ past_key_values=past_key_values,
493
+ use_cache=use_cache,
494
+ position_embeddings=position_embeddings,
495
+ **kwargs,
496
+ )
497
+
498
+ hidden_states = self.norm(hidden_states)
499
+
500
+ return MoeModelOutputWithPast( # only diff with Mistral is the output type, we need MoE
501
+ last_hidden_state=hidden_states,
502
+ past_key_values=past_key_values,
503
+ )
504
+
505
+
506
+ def load_balancing_loss_func(
507
+ gate_logits: torch.Tensor | tuple[torch.Tensor] | None,
508
+ num_experts: int | None = None,
509
+ top_k=2,
510
+ attention_mask: torch.Tensor | None = None,
511
+ ) -> torch.Tensor | int:
512
+ r"""
513
+ Computes auxiliary load balancing loss as in Switch Transformer - implemented in Pytorch.
514
+
515
+ See Switch Transformer (https://huggingface.co/papers/2101.03961) for more details. This function implements the loss
516
+ function presented in equations (4) - (6) of the paper. It aims at penalizing cases where the routing between
517
+ experts is too unbalanced.
518
+
519
+ Args:
520
+ gate_logits:
521
+ Logits from the `gate`, should be a tuple of model.config.num_hidden_layers tensors of
522
+ shape [batch_size X sequence_length, num_experts].
523
+ num_experts:
524
+ Number of experts
525
+ top_k:
526
+ The number of experts to route per-token, can be also interpreted as the `top-k` routing
527
+ parameter.
528
+ attention_mask (`torch.Tensor`, *optional*):
529
+ The attention_mask used in forward function
530
+ shape [batch_size X sequence_length] if not None.
531
+
532
+ Returns:
533
+ The auxiliary loss.
534
+ """
535
+ if gate_logits is None or not isinstance(gate_logits, tuple):
536
+ return 0
537
+
538
+ if isinstance(gate_logits, tuple):
539
+ compute_device = gate_logits[0].device
540
+ concatenated_gate_logits = torch.cat([layer_gate.to(compute_device) for layer_gate in gate_logits], dim=0)
541
+
542
+ routing_weights = torch.nn.functional.softmax(concatenated_gate_logits, dim=-1)
543
+
544
+ _, selected_experts = torch.topk(routing_weights, top_k, dim=-1)
545
+
546
+ expert_mask = torch.nn.functional.one_hot(selected_experts, num_experts)
547
+
548
+ if attention_mask is None:
549
+ # Compute the percentage of tokens routed to each experts
550
+ tokens_per_expert = torch.mean(expert_mask.float(), dim=0)
551
+
552
+ # Compute the average probability of routing to these experts
553
+ router_prob_per_expert = torch.mean(routing_weights, dim=0)
554
+ else:
555
+ batch_size, sequence_length = attention_mask.shape
556
+ num_hidden_layers = concatenated_gate_logits.shape[0] // (batch_size * sequence_length)
557
+
558
+ # Compute the mask that masks all padding tokens as 0 with the same shape of expert_mask
559
+ expert_attention_mask = (
560
+ attention_mask[None, :, :, None, None]
561
+ .expand((num_hidden_layers, batch_size, sequence_length, top_k, num_experts))
562
+ .reshape(-1, top_k, num_experts)
563
+ .to(compute_device)
564
+ )
565
+
566
+ # Compute the percentage of tokens routed to each experts
567
+ tokens_per_expert = torch.sum(expert_mask.float() * expert_attention_mask, dim=0) / torch.sum(
568
+ expert_attention_mask, dim=0
569
+ )
570
+
571
+ # Compute the mask that masks all padding tokens as 0 with the same shape of tokens_per_expert
572
+ router_per_expert_attention_mask = (
573
+ attention_mask[None, :, :, None]
574
+ .expand((num_hidden_layers, batch_size, sequence_length, num_experts))
575
+ .reshape(-1, num_experts)
576
+ .to(compute_device)
577
+ )
578
+
579
+ # Compute the average probability of routing to these experts
580
+ router_prob_per_expert = torch.sum(routing_weights * router_per_expert_attention_mask, dim=0) / torch.sum(
581
+ router_per_expert_attention_mask, dim=0
582
+ )
583
+
584
+ overall_loss = torch.sum(tokens_per_expert * router_prob_per_expert.unsqueeze(0))
585
+ return overall_loss * num_experts
586
+
587
+
588
+ @auto_docstring
589
+ class MiniMaxM2ForCausalLM(MiniMaxM2PreTrainedModel, GenerationMixin):
590
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
591
+ _tp_plan = {"lm_head": "colwise_gather_output"}
592
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
593
+
594
+ def __init__(self, config):
595
+ super().__init__(config)
596
+ self.model = MiniMaxM2Model(config)
597
+ self.vocab_size = config.vocab_size
598
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
599
+ self.router_aux_loss_coef = config.router_aux_loss_coef
600
+ self.num_experts = config.num_local_experts
601
+ self.num_experts_per_tok = config.num_experts_per_tok
602
+
603
+ # Initialize weights and apply final processing
604
+ self.post_init()
605
+
606
+ @can_return_tuple
607
+ @auto_docstring
608
+ def forward(
609
+ self,
610
+ input_ids: torch.LongTensor | None = None,
611
+ attention_mask: torch.Tensor | None = None,
612
+ position_ids: torch.LongTensor | None = None,
613
+ past_key_values: Cache | None = None,
614
+ inputs_embeds: torch.FloatTensor | None = None,
615
+ labels: torch.LongTensor | None = None,
616
+ use_cache: bool | None = None,
617
+ output_router_logits: bool | None = None,
618
+ logits_to_keep: int | torch.Tensor = 0,
619
+ **kwargs: Unpack[TransformersKwargs],
620
+ ) -> MoeCausalLMOutputWithPast:
621
+ r"""
622
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
623
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
624
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
625
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
626
+
627
+ Example:
628
+
629
+ ```python
630
+ >>> from transformers import AutoTokenizer, MiniMaxM2ForCausalLM
631
+
632
+ >>> model = MiniMaxM2ForCausalLM.from_pretrained("mistralai/MiniMaxM2-8x7B-v0.1")
633
+ >>> tokenizer = AutoTokenizer.from_pretrained("mistralai/MiniMaxM2-8x7B-v0.1")
634
+
635
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
636
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
637
+
638
+ >>> # Generate
639
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
640
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
641
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
642
+ ```"""
643
+
644
+ output_router_logits = (
645
+ output_router_logits if output_router_logits is not None else self.config.output_router_logits
646
+ )
647
+
648
+ # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn)
649
+ outputs: MoeModelOutputWithPast = self.model(
650
+ input_ids=input_ids,
651
+ attention_mask=attention_mask,
652
+ position_ids=position_ids,
653
+ past_key_values=past_key_values,
654
+ inputs_embeds=inputs_embeds,
655
+ use_cache=use_cache,
656
+ output_router_logits=output_router_logits,
657
+ **kwargs,
658
+ )
659
+
660
+ hidden_states = outputs.last_hidden_state
661
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
662
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
663
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
664
+
665
+ loss = None
666
+ if labels is not None:
667
+ loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)
668
+
669
+ aux_loss = None
670
+ if output_router_logits:
671
+ aux_loss = load_balancing_loss_func(
672
+ outputs.router_logits,
673
+ self.num_experts,
674
+ self.num_experts_per_tok,
675
+ attention_mask,
676
+ )
677
+ if labels is not None:
678
+ loss += self.router_aux_loss_coef * aux_loss.to(loss.device) # make sure to reside in the same device
679
+
680
+ return MoeCausalLMOutputWithPast(
681
+ loss=loss,
682
+ aux_loss=aux_loss,
683
+ logits=logits,
684
+ past_key_values=outputs.past_key_values,
685
+ hidden_states=outputs.hidden_states,
686
+ attentions=outputs.attentions,
687
+ router_logits=outputs.router_logits,
688
+ )
689
+
690
+
691
+ __all__ = ["MiniMaxM2ForCausalLM", "MiniMaxM2Model", "MiniMaxM2PreTrainedModel"]
third_party/transformers/src/transformers/models/minimax_m2/modular_minimax_m2.py ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the MiniMax AI Team and HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ import torch
17
+ import torch.nn.functional as F
18
+ from huggingface_hub.dataclasses import strict
19
+ from torch import nn
20
+
21
+ from ... import initialization as init
22
+ from ...cache_utils import Cache, DynamicCache
23
+ from ...configuration_utils import PreTrainedConfig
24
+ from ...masking_utils import create_causal_mask
25
+ from ...modeling_outputs import MoeModelOutputWithPast
26
+ from ...modeling_rope_utils import RopeParameters
27
+ from ...modeling_utils import PreTrainedModel
28
+ from ...processing_utils import Unpack
29
+ from ...utils import TransformersKwargs, auto_docstring
30
+ from ...utils.generic import merge_with_config_defaults
31
+ from ...utils.output_capturing import capture_outputs
32
+ from ..flex_olmo.modeling_flex_olmo import FlexOlmoAttention
33
+ from ..glm4_moe.modeling_glm4_moe import (
34
+ Glm4MoeRotaryEmbedding,
35
+ apply_rotary_pos_emb, # noqa: F401
36
+ )
37
+ from ..mixtral.modeling_mixtral import (
38
+ MixtralExperts,
39
+ MixtralForCausalLM,
40
+ MixtralModel,
41
+ MixtralPreTrainedModel,
42
+ MixtralRMSNorm,
43
+ MixtralSparseMoeBlock,
44
+ MixtralTopKRouter,
45
+ )
46
+
47
+
48
+ @auto_docstring(checkpoint="MiniMaxAI/MiniMax-Text-01-hf")
49
+ @strict
50
+ class MiniMaxM2Config(PreTrainedConfig):
51
+ r"""
52
+ Example:
53
+
54
+ ```python
55
+ >>> from transformers import MiniMaxM2Model, MiniMaxM2Config
56
+
57
+ >>> # Initializing a MiniMaxM2 style configuration
58
+ >>> configuration = MiniMaxM2Config()
59
+
60
+ >>> # Initializing a model from the MiniMaxM2 style configuration
61
+ >>> model = MiniMaxM2Model(configuration)
62
+
63
+ >>> # Accessing the model configuration
64
+ >>> configuration = model.config
65
+ ```"""
66
+
67
+ model_type = "minimax_m2"
68
+ keys_to_ignore_at_inference = ["past_key_values"]
69
+ base_model_tp_plan = {
70
+ "layers.*.self_attn.q_proj": "colwise_gather_output",
71
+ "layers.*.self_attn.k_proj": "colwise_gather_output",
72
+ "layers.*.self_attn.v_proj": "colwise_gather_output",
73
+ "layers.*.self_attn.o_proj": "rowwise_split_input",
74
+ "layers.*.mlp.experts.gate_up_proj": "packed_colwise",
75
+ "layers.*.mlp.experts.down_proj": "rowwise",
76
+ "layers.*.mlp.experts": "moe_tp_experts",
77
+ }
78
+ base_model_pp_plan = {
79
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
80
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
81
+ "norm": (["hidden_states"], ["hidden_states"]),
82
+ }
83
+ attribute_map = {
84
+ "num_experts": "num_local_experts",
85
+ }
86
+ default_theta = 5000000.0
87
+
88
+ vocab_size: int = 200064
89
+ hidden_size: int = 3072
90
+ intermediate_size: int = 1536
91
+ num_hidden_layers: int = 62
92
+ num_attention_heads: int = 48
93
+ num_key_value_heads: int = 8
94
+ head_dim: int = 128
95
+ hidden_act: str = "silu"
96
+ max_position_embeddings: int = 196608
97
+ initializer_range: float = 0.02
98
+ rms_norm_eps: float = 1e-06
99
+ use_cache: bool = True
100
+ pad_token_id: int | None = None
101
+ bos_token_id: int | None = 200034
102
+ eos_token_id: int | list[int] | None = 200020
103
+ tie_word_embeddings: bool = False
104
+ attention_dropout: float | int = 0.0
105
+ num_experts_per_tok: int = 8
106
+ num_local_experts: int = 256
107
+ output_router_logits: bool = False
108
+ router_aux_loss_coef: float = 0.001
109
+ router_jitter_noise: float = 0.0
110
+ rope_parameters: RopeParameters | dict | None = None
111
+
112
+
113
+ class MiniMaxM2TopKRouter(MixtralTopKRouter):
114
+ def forward(self, hidden_states, e_score_correction_bias):
115
+ hidden_states = hidden_states.reshape(-1, self.hidden_dim)
116
+ router_logits = F.linear(hidden_states.to(self.weight.dtype), self.weight) # (seq_len, num_experts)
117
+ # Main difference to other Moe, using Sigmoid activation instead of Softmax
118
+ routing_weights = nn.functional.sigmoid(router_logits.float())
119
+ scores_for_choice = routing_weights + e_score_correction_bias
120
+ _, top_k_index = torch.topk(scores_for_choice, self.top_k, dim=-1, sorted=False)
121
+ top_k_weights = routing_weights.gather(1, top_k_index)
122
+ top_k_weights /= top_k_weights.sum(dim=-1, keepdim=True)
123
+ router_scores = top_k_weights
124
+ return router_logits, router_scores, top_k_index
125
+
126
+
127
+ class MiniMaxM2Experts(MixtralExperts):
128
+ pass
129
+
130
+
131
+ class MiniMaxM2SparseMoeBlock(MixtralSparseMoeBlock):
132
+ def __init__(self, config):
133
+ super().__init__()
134
+ self.register_buffer("e_score_correction_bias", torch.zeros(config.num_local_experts))
135
+
136
+ def forward(self, hidden_states: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
137
+ batch_size, sequence_length, hidden_dim = hidden_states.shape
138
+ if self.training and self.jitter_noise > 0:
139
+ hidden_states *= torch.empty_like(hidden_states).uniform_(1.0 - self.jitter_noise, 1.0 + self.jitter_noise)
140
+ hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
141
+ _, top_k_weights, top_k_index = self.gate(hidden_states, self.e_score_correction_bias)
142
+ hidden_states = self.experts(hidden_states, top_k_index, top_k_weights)
143
+ hidden_states = hidden_states.reshape(batch_size, sequence_length, hidden_dim)
144
+ return hidden_states
145
+
146
+
147
+ class MiniMaxM2RMSNorm(MixtralRMSNorm):
148
+ pass
149
+
150
+
151
+ class MiniMaxM2RotaryEmbedding(Glm4MoeRotaryEmbedding):
152
+ pass
153
+
154
+
155
+ class MiniMaxM2Attention(FlexOlmoAttention):
156
+ def __init__(self, config: MiniMaxM2Config, layer_idx: int):
157
+ super().__init__(config, layer_idx)
158
+ self.q_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=False)
159
+ self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False)
160
+ self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False)
161
+ self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=False)
162
+
163
+
164
+ class MiniMaxM2PreTrainedModel(MixtralPreTrainedModel):
165
+ @torch.no_grad()
166
+ def _init_weights(self, module):
167
+ PreTrainedModel._init_weights(self, module)
168
+ std = self.config.initializer_range
169
+ if isinstance(module, MiniMaxM2Experts):
170
+ init.normal_(module.gate_up_proj, mean=0.0, std=std)
171
+ init.normal_(module.down_proj, mean=0.0, std=std)
172
+ elif isinstance(module, MiniMaxM2TopKRouter):
173
+ init.normal_(module.weight, mean=0.0, std=std)
174
+ elif isinstance(module, MiniMaxM2SparseMoeBlock):
175
+ init.zeros_(module.e_score_correction_bias)
176
+
177
+
178
+ class MiniMaxM2Model(MixtralModel):
179
+ @merge_with_config_defaults
180
+ @capture_outputs
181
+ @auto_docstring
182
+ def forward(
183
+ self,
184
+ input_ids: torch.LongTensor | None = None,
185
+ attention_mask: torch.Tensor | None = None,
186
+ position_ids: torch.LongTensor | None = None,
187
+ past_key_values: Cache | None = None,
188
+ inputs_embeds: torch.FloatTensor | None = None,
189
+ use_cache: bool | None = None,
190
+ **kwargs: Unpack[TransformersKwargs],
191
+ ) -> MoeModelOutputWithPast:
192
+ if (input_ids is None) ^ (inputs_embeds is not None):
193
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
194
+
195
+ if use_cache and past_key_values is None:
196
+ past_key_values = DynamicCache(config=self.config)
197
+
198
+ if inputs_embeds is None:
199
+ inputs_embeds = self.embed_tokens(input_ids)
200
+
201
+ if position_ids is None:
202
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
203
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
204
+ position_ids = position_ids.unsqueeze(0)
205
+
206
+ # No sliding window opposed to mixtral
207
+ causal_mask = create_causal_mask(
208
+ config=self.config,
209
+ inputs_embeds=inputs_embeds,
210
+ attention_mask=attention_mask,
211
+ past_key_values=past_key_values,
212
+ position_ids=position_ids,
213
+ )
214
+
215
+ hidden_states = inputs_embeds
216
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
217
+
218
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
219
+ hidden_states = decoder_layer(
220
+ hidden_states,
221
+ attention_mask=causal_mask,
222
+ position_ids=position_ids,
223
+ past_key_values=past_key_values,
224
+ use_cache=use_cache,
225
+ position_embeddings=position_embeddings,
226
+ **kwargs,
227
+ )
228
+
229
+ hidden_states = self.norm(hidden_states)
230
+
231
+ return MoeModelOutputWithPast( # only diff with Mistral is the output type, we need MoE
232
+ last_hidden_state=hidden_states,
233
+ past_key_values=past_key_values,
234
+ )
235
+
236
+
237
+ class MiniMaxM2ForCausalLM(MixtralForCausalLM):
238
+ pass
239
+
240
+
241
+ __all__ = [
242
+ "MiniMaxM2Config",
243
+ "MiniMaxM2ForCausalLM",
244
+ "MiniMaxM2Model", # noqa: F822
245
+ "MiniMaxM2PreTrainedModel", # noqa: F822
246
+ ]
third_party/transformers/src/transformers/models/mixtral/__init__.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 Mixtral AI and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from .configuration_mixtral import *
22
+ from .modeling_mixtral import *
23
+ else:
24
+ import sys
25
+
26
+ _file = globals()["__file__"]
27
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/mixtral/configuration_mixtral.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 Mixtral AI and the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Mixtral model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...configuration_utils import PreTrainedConfig
19
+ from ...modeling_rope_utils import RopeParameters
20
+ from ...utils import auto_docstring
21
+
22
+
23
+ @auto_docstring(checkpoint="mistralai/Mixtral-8x7B-v0.1")
24
+ @strict
25
+ class MixtralConfig(PreTrainedConfig):
26
+ r"""
27
+ Example:
28
+
29
+ ```python
30
+ >>> from transformers import MixtralModel, MixtralConfig
31
+
32
+ >>> # Initializing a Mixtral 7B style configuration
33
+ >>> configuration = MixtralConfig()
34
+
35
+ >>> # Initializing a model from the Mixtral 7B style configuration
36
+ >>> model = MixtralModel(configuration)
37
+
38
+ >>> # Accessing the model configuration
39
+ >>> configuration = model.config
40
+ ```"""
41
+
42
+ model_type = "mixtral"
43
+ keys_to_ignore_at_inference = ["past_key_values"]
44
+ default_theta = 1000000.0
45
+ base_model_tp_plan = {
46
+ "layers.*.self_attn.q_proj": "colwise",
47
+ "layers.*.self_attn.k_proj": "colwise",
48
+ "layers.*.self_attn.v_proj": "colwise",
49
+ "layers.*.self_attn.o_proj": "rowwise",
50
+ "layers.*.mlp.experts.gate_up_proj": "packed_colwise",
51
+ "layers.*.mlp.experts.down_proj": "rowwise",
52
+ "layers.*.mlp.experts": "moe_tp_experts",
53
+ }
54
+ base_model_pp_plan = {
55
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
56
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
57
+ "norm": (["hidden_states"], ["hidden_states"]),
58
+ }
59
+ attribute_map = {"num_experts": "num_local_experts"}
60
+
61
+ vocab_size: int = 32000
62
+ hidden_size: int = 4096
63
+ intermediate_size: int = 14336
64
+ num_hidden_layers: int = 32
65
+ num_attention_heads: int = 32
66
+ num_key_value_heads: int = 8
67
+ head_dim: int | None = None
68
+ hidden_act: str = "silu"
69
+ max_position_embeddings: int = 4096 * 32
70
+ initializer_range: float = 0.02
71
+ rms_norm_eps: float = 1e-5
72
+ use_cache: bool = True
73
+ pad_token_id: int | None = None
74
+ bos_token_id: int | None = 1
75
+ eos_token_id: int | list[int] | None = 2
76
+ tie_word_embeddings: bool = False
77
+ sliding_window: int | None = None
78
+ attention_dropout: float | int = 0.0
79
+ num_experts_per_tok: int = 2
80
+ num_local_experts: int = 8
81
+ output_router_logits: bool = False
82
+ router_aux_loss_coef: float = 0.001
83
+ router_jitter_noise: float = 0.0
84
+ rope_parameters: RopeParameters | dict | None = None
85
+
86
+ def __post_init__(self, **kwargs):
87
+ if self.num_key_value_heads is None:
88
+ self.num_key_value_heads = self.num_attention_heads
89
+
90
+ super().__post_init__(**kwargs)
91
+
92
+
93
+ __all__ = ["MixtralConfig"]
third_party/transformers/src/transformers/models/mixtral/convert_mixtral_weights_to_hf.py ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 Mistral AI and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import argparse
15
+ import json
16
+ import os
17
+
18
+ import torch
19
+
20
+ from transformers import (
21
+ MixtralConfig,
22
+ MixtralForCausalLM,
23
+ )
24
+
25
+
26
+ """
27
+ Sample usage:
28
+
29
+ ```
30
+ python src/transformers/models/mixtral/convert_mixtral_weights_to_hf.py \
31
+ --input_dir /path/to/downloaded/mixtral/weights --model_size 7B --output_dir /output/path
32
+ ```
33
+
34
+ Thereafter, models can be loaded via:
35
+
36
+ ```py
37
+ from transformers import MixtralForCausalLM
38
+
39
+ model = MixtralForCausalLM.from_pretrained("/output/path")
40
+ ```
41
+
42
+ Important note: you need to be able to host the whole model in RAM to execute this script (even if the biggest versions
43
+ come in several checkpoints they each contain a part of each weight of the model, so we need to load them all in RAM).
44
+ """
45
+
46
+
47
+ def compute_intermediate_size(n, ffn_dim_multiplier=1, multiple_of=256):
48
+ return multiple_of * ((int(ffn_dim_multiplier * int(8 * n / 3)) + multiple_of - 1) // multiple_of)
49
+
50
+
51
+ def read_json(path):
52
+ with open(path, "r") as f:
53
+ return json.load(f)
54
+
55
+
56
+ def write_json(text, path):
57
+ with open(path, "w") as f:
58
+ json.dump(text, f)
59
+
60
+
61
+ def write_model(model_path, input_base_path, model_size):
62
+ os.makedirs(model_path, exist_ok=True)
63
+
64
+ params = read_json(os.path.join(input_base_path, "params.json"))
65
+ num_shards = 1
66
+
67
+ # For some reason this is a string in the params.json
68
+ sliding_window = int(params["sliding_window"]) if "sliding_window" in params else None
69
+ n_layers = params["num_hidden_layers"]
70
+ n_heads = params["num_attention_heads"]
71
+ n_heads_per_shard = n_heads // num_shards
72
+ dim = params["hidden_size"]
73
+ dims_per_head = dim // n_heads
74
+ base = params.get("rope_theta", 10000.0)
75
+ max_position_embeddings = 4096 * 8
76
+ num_local_experts = params["num_local_experts"]
77
+ ffn_dim = params["intermediate_size"]
78
+
79
+ vocab_size = params["vocab_size"]
80
+
81
+ if "num_key_value_heads" in params:
82
+ num_key_value_heads = params["num_key_value_heads"] # for GQA / MQA
83
+ num_local_key_value_heads = num_key_value_heads // num_shards
84
+ key_value_dim = dims_per_head * num_local_key_value_heads
85
+ else: # compatibility with other checkpoints
86
+ num_key_value_heads = n_heads
87
+ num_local_key_value_heads = n_heads_per_shard
88
+ key_value_dim = dim
89
+
90
+ # permute for sliced rotary
91
+ def permute(w, n_heads=n_heads, dim1=dim, dim2=dim):
92
+ return w.view(n_heads, dim1 // n_heads // 2, 2, dim2).transpose(1, 2).reshape(dim1, dim2)
93
+
94
+ print(f"Fetching all parameters from the checkpoint at {input_base_path}.")
95
+ # Load weights
96
+ loaded = [
97
+ torch.load(os.path.join(input_base_path, f"consolidated.{i:02d}.pt"), map_location="cpu", weights_only=True)
98
+ for i in range(8)
99
+ ]
100
+
101
+ merged_state_dict = {}
102
+ for state_dict in loaded:
103
+ merged_state_dict.update(state_dict)
104
+
105
+ state_dict = {}
106
+
107
+ for layer_i in range(n_layers):
108
+ # Sharded
109
+ # Note that attention.w{q,k,v,o}, feed_fordward.w[1,2,3], attention_norm.weight and ffn_norm.weight share
110
+ # the same storage object, saving attention_norm and ffn_norm will save other weights too, which is
111
+ # redundant as other weights will be stitched from multiple shards. To avoid that, they are cloned.
112
+
113
+ state_dict.update(
114
+ {
115
+ f"model.layers.{layer_i}.input_layernorm.weight": merged_state_dict[
116
+ f"layers.{layer_i}.attention_norm.weight"
117
+ ].clone(),
118
+ f"model.layers.{layer_i}.post_attention_layernorm.weight": merged_state_dict[
119
+ f"layers.{layer_i}.ffn_norm.weight"
120
+ ].clone(),
121
+ }
122
+ )
123
+
124
+ state_dict[f"model.layers.{layer_i}.self_attn.q_proj.weight"] = permute(
125
+ merged_state_dict[f"layers.{layer_i}.attention.wq.weight"]
126
+ .view(n_heads_per_shard, dims_per_head, dim)
127
+ .reshape(dim, dim)
128
+ )
129
+ state_dict[f"model.layers.{layer_i}.self_attn.k_proj.weight"] = permute(
130
+ merged_state_dict[f"layers.{layer_i}.attention.wk.weight"]
131
+ .view(num_local_key_value_heads, dims_per_head, dim)
132
+ .reshape(key_value_dim, dim),
133
+ num_key_value_heads,
134
+ key_value_dim,
135
+ dim,
136
+ )
137
+ state_dict[f"model.layers.{layer_i}.self_attn.v_proj.weight"] = (
138
+ merged_state_dict[f"layers.{layer_i}.attention.wv.weight"]
139
+ .view(num_local_key_value_heads, dims_per_head, dim)
140
+ .reshape(key_value_dim, dim)
141
+ )
142
+
143
+ state_dict[f"model.layers.{layer_i}.self_attn.o_proj.weight"] = merged_state_dict[
144
+ f"layers.{layer_i}.attention.wo.weight"
145
+ ]
146
+
147
+ w1 = merged_state_dict[f"layers.{layer_i}.block_sparse_moe.w1"]
148
+ w2 = merged_state_dict[f"layers.{layer_i}.block_sparse_moe.w2"]
149
+ w3 = merged_state_dict[f"layers.{layer_i}.block_sparse_moe.w3"]
150
+
151
+ experts_w1 = [
152
+ w1[ffn_dim * expert_idx : ffn_dim * (expert_idx + 1), :].clone(memory_format=torch.contiguous_format)
153
+ for expert_idx in range(num_local_experts)
154
+ ]
155
+
156
+ for idx, expert_block in enumerate(experts_w1):
157
+ expert_key = f"model.layers.{layer_i}.block_sparse_moe.experts.{idx}.w1"
158
+ state_dict[expert_key + ".weight"] = expert_block.clone()
159
+
160
+ experts_w2 = [
161
+ w2[ffn_dim * expert_idx : ffn_dim * (expert_idx + 1), :].clone(memory_format=torch.contiguous_format)
162
+ for expert_idx in range(num_local_experts)
163
+ ]
164
+
165
+ for idx, expert_block in enumerate(experts_w2):
166
+ expert_key = f"model.layers.{layer_i}.block_sparse_moe.experts.{idx}.w2"
167
+ state_dict[expert_key + ".weight"] = expert_block.T.clone(memory_format=torch.contiguous_format)
168
+
169
+ experts_w3 = [
170
+ w3[ffn_dim * expert_idx : ffn_dim * (expert_idx + 1), :].clone(memory_format=torch.contiguous_format)
171
+ for expert_idx in range(num_local_experts)
172
+ ]
173
+
174
+ for idx, expert_block in enumerate(experts_w3):
175
+ expert_key = f"model.layers.{layer_i}.block_sparse_moe.experts.{idx}.w3"
176
+ state_dict[expert_key + ".weight"] = expert_block.clone()
177
+
178
+ state_dict[f"model.layers.{layer_i}.block_sparse_moe.gate.weight"] = merged_state_dict[
179
+ f"layers.{layer_i}.block_sparse_moe.gate.weight"
180
+ ]
181
+
182
+ state_dict.update(
183
+ {
184
+ "model.norm.weight": merged_state_dict["norm.weight"],
185
+ "model.embed_tokens.weight": merged_state_dict["tok_embeddings.weight"],
186
+ "lm_head.weight": merged_state_dict["output.weight"],
187
+ }
188
+ )
189
+
190
+ config = MixtralConfig(
191
+ hidden_size=dim,
192
+ intermediate_size=ffn_dim,
193
+ num_attention_heads=params["num_attention_heads"],
194
+ num_hidden_layers=params["num_hidden_layers"],
195
+ rms_norm_eps=params["rms_norm_eps"],
196
+ num_key_value_heads=num_key_value_heads,
197
+ vocab_size=vocab_size,
198
+ rope_theta=base,
199
+ max_position_embeddings=max_position_embeddings,
200
+ sliding_window=sliding_window,
201
+ num_local_experts=num_local_experts,
202
+ )
203
+
204
+ print("Loading the checkpoint in a Mixtral model.")
205
+ with torch.device("meta"):
206
+ model = MixtralForCausalLM(config)
207
+ # Avoid saving this as part of the config.
208
+ del model.config._name_or_path
209
+ model.config.dtype = torch.float16
210
+ print("Saving in the Transformers format.")
211
+
212
+ model.load_state_dict(state_dict, strict=True, assign=True)
213
+
214
+ for n, p in model.named_parameters():
215
+ assert p.device.type != "meta", f"{n} has not been loaded!"
216
+
217
+ model.save_pretrained(model_path)
218
+
219
+
220
+ def main():
221
+ parser = argparse.ArgumentParser()
222
+ parser.add_argument(
223
+ "--input_dir",
224
+ help="Location of Mixtral weights, which contains tokenizer.model and model folders",
225
+ required=True,
226
+ )
227
+ parser.add_argument(
228
+ "--model_size",
229
+ choices=["7B"],
230
+ help="'f' models correspond to the finetuned versions, and are specific to the Mixtral official release. For more details on Mixtral, check out the original repo: https://huggingface.co/mistral-ai",
231
+ default="7B",
232
+ )
233
+ parser.add_argument("--output_dir", help="Location to write HF model", required=True)
234
+ args = parser.parse_args()
235
+ write_model(
236
+ model_path=args.output_dir,
237
+ input_base_path=args.input_dir,
238
+ model_size=args.model_size,
239
+ )
240
+
241
+
242
+ if __name__ == "__main__":
243
+ main()
third_party/transformers/src/transformers/models/mixtral/modeling_mixtral.py ADDED
@@ -0,0 +1,702 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/mixtral/modular_mixtral.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_mixtral.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2023 Mistral AI and the HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
10
+ # and OPT implementations in this library. It has been modified from its
11
+ # original forms to accommodate minor architectural differences compared
12
+ # to GPT-NeoX and OPT used by the Meta AI team that trained the model.
13
+ #
14
+ # Licensed under the Apache License, Version 2.0 (the "License");
15
+ # you may not use this file except in compliance with the License.
16
+ # You may obtain a copy of the License at
17
+ #
18
+ # http://www.apache.org/licenses/LICENSE-2.0
19
+ #
20
+ # Unless required by applicable law or agreed to in writing, software
21
+ # distributed under the License is distributed on an "AS IS" BASIS,
22
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ # See the License for the specific language governing permissions and
24
+ # limitations under the License.
25
+
26
+ from collections.abc import Callable
27
+ from typing import Optional
28
+
29
+ import torch
30
+ import torch.nn.functional as F
31
+ from torch import nn
32
+
33
+ from ... import initialization as init
34
+ from ...activations import ACT2FN
35
+ from ...cache_utils import Cache, DynamicCache
36
+ from ...generation import GenerationMixin
37
+ from ...integrations import (
38
+ use_experts_implementation,
39
+ use_kernel_forward_from_hub,
40
+ use_kernel_func_from_hub,
41
+ use_kernelized_func,
42
+ )
43
+ from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask
44
+ from ...modeling_flash_attention_utils import FlashAttentionKwargs
45
+ from ...modeling_layers import (
46
+ GenericForQuestionAnswering,
47
+ GenericForSequenceClassification,
48
+ GenericForTokenClassification,
49
+ GradientCheckpointingLayer,
50
+ )
51
+ from ...modeling_outputs import MoeCausalLMOutputWithPast, MoeModelOutputWithPast
52
+ from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
53
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
54
+ from ...processing_utils import Unpack
55
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple
56
+ from ...utils.generic import maybe_autocast, merge_with_config_defaults
57
+ from ...utils.output_capturing import OutputRecorder, capture_outputs
58
+ from .configuration_mixtral import MixtralConfig
59
+
60
+
61
+ @use_experts_implementation
62
+ class MixtralExperts(nn.Module):
63
+ """Collection of expert weights stored as 3D tensors."""
64
+
65
+ def __init__(self, config: MixtralConfig):
66
+ super().__init__()
67
+ self.num_experts = config.num_local_experts
68
+ self.hidden_dim = config.hidden_size
69
+ self.intermediate_dim = config.intermediate_size
70
+ self.gate_up_proj = nn.Parameter(torch.empty(self.num_experts, 2 * self.intermediate_dim, self.hidden_dim))
71
+ self.down_proj = nn.Parameter(torch.empty(self.num_experts, self.hidden_dim, self.intermediate_dim))
72
+ self.act_fn = ACT2FN[config.hidden_act]
73
+
74
+ def forward(
75
+ self,
76
+ hidden_states: torch.Tensor,
77
+ top_k_index: torch.Tensor,
78
+ top_k_weights: torch.Tensor,
79
+ ) -> torch.Tensor:
80
+ final_hidden_states = torch.zeros_like(hidden_states)
81
+ with torch.no_grad():
82
+ expert_mask = torch.nn.functional.one_hot(top_k_index, num_classes=self.num_experts)
83
+ expert_mask = expert_mask.permute(2, 1, 0)
84
+ expert_hit = torch.greater(expert_mask.sum(dim=(-1, -2)), 0).nonzero()
85
+
86
+ for expert_idx in expert_hit:
87
+ expert_idx = expert_idx[0]
88
+ if expert_idx == self.num_experts:
89
+ continue
90
+ top_k_pos, token_idx = torch.where(expert_mask[expert_idx])
91
+ current_state = hidden_states[token_idx]
92
+ gate, up = nn.functional.linear(current_state, self.gate_up_proj[expert_idx]).chunk(2, dim=-1)
93
+ current_hidden_states = self.act_fn(gate) * up
94
+ current_hidden_states = nn.functional.linear(current_hidden_states, self.down_proj[expert_idx])
95
+ current_hidden_states = current_hidden_states * top_k_weights[token_idx, top_k_pos, None]
96
+ final_hidden_states.index_add_(0, token_idx, current_hidden_states.to(final_hidden_states.dtype))
97
+
98
+ return final_hidden_states
99
+
100
+
101
+ class MixtralTopKRouter(nn.Module):
102
+ def __init__(self, config):
103
+ super().__init__()
104
+ self.top_k = config.num_experts_per_tok
105
+ self.num_experts = config.num_local_experts
106
+ self.hidden_dim = config.hidden_size
107
+ self.weight = nn.Parameter(torch.empty(self.num_experts, self.hidden_dim))
108
+
109
+ def forward(self, hidden_states):
110
+ hidden_states = hidden_states.reshape(-1, self.hidden_dim)
111
+ router_logits = F.linear(hidden_states, self.weight) # (seq_len, num_experts)
112
+ router_logits = torch.nn.functional.softmax(router_logits.float(), dim=-1)
113
+ router_top_value, router_indices = torch.topk(router_logits, self.top_k, dim=-1) # (seq_len, top_k)
114
+ router_top_value /= router_top_value.sum(dim=-1, keepdim=True)
115
+ router_scores = router_top_value
116
+ return router_logits, router_scores, router_indices
117
+
118
+
119
+ class MixtralSparseMoeBlock(nn.Module):
120
+ def __init__(self, config):
121
+ super().__init__()
122
+ self.top_k = config.num_experts_per_tok
123
+ self.jitter_noise = config.router_jitter_noise
124
+ self.gate = MixtralTopKRouter(config)
125
+ self.experts = MixtralExperts(config)
126
+
127
+ def forward(self, hidden_states: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
128
+ batch_size, sequence_length, hidden_dim = hidden_states.shape
129
+ if self.training and self.jitter_noise > 0:
130
+ hidden_states *= torch.empty_like(hidden_states).uniform_(1.0 - self.jitter_noise, 1.0 + self.jitter_noise)
131
+ hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
132
+ _, top_k_weights, top_k_index = self.gate(hidden_states)
133
+ hidden_states = self.experts(hidden_states, top_k_index, top_k_weights)
134
+ hidden_states = hidden_states.reshape(batch_size, sequence_length, hidden_dim)
135
+ return hidden_states
136
+
137
+
138
+ @use_kernel_forward_from_hub("RMSNorm")
139
+ class MixtralRMSNorm(nn.Module):
140
+ def __init__(self, hidden_size, eps: float = 1e-6) -> None:
141
+ """
142
+ MixtralRMSNorm is equivalent to T5LayerNorm
143
+ """
144
+ super().__init__()
145
+ self.weight = nn.Parameter(torch.ones(hidden_size))
146
+ self.variance_epsilon = eps
147
+
148
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
149
+ input_dtype = hidden_states.dtype
150
+ hidden_states = hidden_states.to(torch.float32)
151
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
152
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
153
+ return self.weight * hidden_states.to(input_dtype)
154
+
155
+ def extra_repr(self):
156
+ return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
157
+
158
+
159
+ class MixtralRotaryEmbedding(nn.Module):
160
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
161
+
162
+ def __init__(self, config: MixtralConfig, device=None):
163
+ super().__init__()
164
+ self.max_seq_len_cached = config.max_position_embeddings
165
+ self.original_max_seq_len = config.max_position_embeddings
166
+
167
+ self.config = config
168
+
169
+ self.rope_type = self.config.rope_parameters["rope_type"]
170
+ rope_init_fn: Callable = self.compute_default_rope_parameters
171
+ if self.rope_type != "default":
172
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
173
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
174
+
175
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
176
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
177
+
178
+ @staticmethod
179
+ def compute_default_rope_parameters(
180
+ config: MixtralConfig | None = None,
181
+ device: Optional["torch.device"] = None,
182
+ seq_len: int | None = None,
183
+ ) -> tuple["torch.Tensor", float]:
184
+ """
185
+ Computes the inverse frequencies according to the original RoPE implementation
186
+ Args:
187
+ config ([`~transformers.PreTrainedConfig`]):
188
+ The model configuration.
189
+ device (`torch.device`):
190
+ The device to use for initialization of the inverse frequencies.
191
+ seq_len (`int`, *optional*):
192
+ The current sequence length. Unused for this type of RoPE.
193
+ Returns:
194
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
195
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
196
+ """
197
+ base = config.rope_parameters["rope_theta"]
198
+ dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
199
+
200
+ attention_factor = 1.0 # Unused in this type of RoPE
201
+
202
+ # Compute the inverse frequencies
203
+ inv_freq = 1.0 / (
204
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
205
+ )
206
+ return inv_freq, attention_factor
207
+
208
+ @torch.no_grad()
209
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
210
+ def forward(self, x, position_ids):
211
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
212
+ position_ids_expanded = position_ids[:, None, :].float()
213
+
214
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
215
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
216
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
217
+ emb = torch.cat((freqs, freqs), dim=-1)
218
+ cos = emb.cos() * self.attention_scaling
219
+ sin = emb.sin() * self.attention_scaling
220
+
221
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
222
+
223
+
224
+ def rotate_half(x):
225
+ """Rotates half the hidden dims of the input."""
226
+ x1 = x[..., : x.shape[-1] // 2]
227
+ x2 = x[..., x.shape[-1] // 2 :]
228
+ return torch.cat((-x2, x1), dim=-1)
229
+
230
+
231
+ @use_kernel_func_from_hub("rotary_pos_emb")
232
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
233
+ """Applies Rotary Position Embedding to the query and key tensors.
234
+
235
+ Args:
236
+ q (`torch.Tensor`): The query tensor.
237
+ k (`torch.Tensor`): The key tensor.
238
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
239
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
240
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
241
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
242
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
243
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
244
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
245
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
246
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
247
+ Returns:
248
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
249
+ """
250
+ cos = cos.unsqueeze(unsqueeze_dim)
251
+ sin = sin.unsqueeze(unsqueeze_dim)
252
+ q_embed = (q * cos) + (rotate_half(q) * sin)
253
+ k_embed = (k * cos) + (rotate_half(k) * sin)
254
+ return q_embed, k_embed
255
+
256
+
257
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
258
+ """
259
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
260
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
261
+ """
262
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
263
+ if n_rep == 1:
264
+ return hidden_states
265
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
266
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
267
+
268
+
269
+ def eager_attention_forward(
270
+ module: nn.Module,
271
+ query: torch.Tensor,
272
+ key: torch.Tensor,
273
+ value: torch.Tensor,
274
+ attention_mask: torch.Tensor | None,
275
+ scaling: float,
276
+ dropout: float = 0.0,
277
+ **kwargs: Unpack[TransformersKwargs],
278
+ ):
279
+ key_states = repeat_kv(key, module.num_key_value_groups)
280
+ value_states = repeat_kv(value, module.num_key_value_groups)
281
+
282
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
283
+ if attention_mask is not None:
284
+ attn_weights = attn_weights + attention_mask
285
+
286
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
287
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
288
+ attn_output = torch.matmul(attn_weights, value_states)
289
+ attn_output = attn_output.transpose(1, 2).contiguous()
290
+
291
+ return attn_output, attn_weights
292
+
293
+
294
+ @use_kernelized_func(apply_rotary_pos_emb)
295
+ class MixtralAttention(nn.Module):
296
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
297
+
298
+ def __init__(self, config: MixtralConfig, layer_idx: int):
299
+ super().__init__()
300
+ self.config = config
301
+ self.layer_idx = layer_idx
302
+ self.head_dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
303
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
304
+ self.scaling = self.head_dim**-0.5
305
+ self.attention_dropout = config.attention_dropout
306
+ self.is_causal = True
307
+ self.q_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=False)
308
+ self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False)
309
+ self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False)
310
+ self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=False)
311
+
312
+ def forward(
313
+ self,
314
+ hidden_states: torch.Tensor,
315
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
316
+ attention_mask: torch.Tensor | None,
317
+ past_key_values: Cache | None = None,
318
+ **kwargs: Unpack[FlashAttentionKwargs],
319
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
320
+ input_shape = hidden_states.shape[:-1]
321
+ hidden_shape = (*input_shape, -1, self.head_dim)
322
+
323
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
324
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
325
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
326
+
327
+ cos, sin = position_embeddings
328
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
329
+
330
+ if past_key_values is not None:
331
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
332
+
333
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
334
+ self.config._attn_implementation, eager_attention_forward
335
+ )
336
+
337
+ attn_output, attn_weights = attention_interface(
338
+ self,
339
+ query_states,
340
+ key_states,
341
+ value_states,
342
+ attention_mask,
343
+ dropout=0.0 if not self.training else self.attention_dropout,
344
+ scaling=self.scaling,
345
+ sliding_window=getattr(self.config, "sliding_window", None), # main diff with Llama
346
+ **kwargs,
347
+ )
348
+
349
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
350
+ attn_output = self.o_proj(attn_output)
351
+ return attn_output, attn_weights
352
+
353
+
354
+ class MixtralDecoderLayer(GradientCheckpointingLayer):
355
+ def __init__(self, config: MixtralConfig, layer_idx: int):
356
+ super().__init__()
357
+ self.hidden_size = config.hidden_size
358
+
359
+ self.self_attn = MixtralAttention(config, layer_idx)
360
+
361
+ self.mlp = MixtralSparseMoeBlock(config)
362
+ self.input_layernorm = MixtralRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
363
+ self.post_attention_layernorm = MixtralRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
364
+
365
+ def forward(
366
+ self,
367
+ hidden_states: torch.Tensor,
368
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
369
+ attention_mask: torch.Tensor | None = None,
370
+ position_ids: torch.LongTensor | None = None,
371
+ past_key_values: Cache | None = None,
372
+ **kwargs: Unpack[TransformersKwargs],
373
+ ) -> torch.Tensor:
374
+ residual = hidden_states
375
+ hidden_states = self.input_layernorm(hidden_states)
376
+ hidden_states, _ = self.self_attn(
377
+ hidden_states=hidden_states,
378
+ position_embeddings=position_embeddings,
379
+ attention_mask=attention_mask,
380
+ position_ids=position_ids,
381
+ past_key_values=past_key_values,
382
+ **kwargs,
383
+ )
384
+ hidden_states = residual + hidden_states
385
+ residual = hidden_states
386
+ hidden_states = self.post_attention_layernorm(hidden_states)
387
+ hidden_states = self.mlp(hidden_states)
388
+ hidden_states = residual + hidden_states
389
+ return hidden_states
390
+
391
+
392
+ @auto_docstring
393
+ class MixtralPreTrainedModel(PreTrainedModel):
394
+ config: MixtralConfig
395
+ base_model_prefix = "model"
396
+ supports_gradient_checkpointing = True
397
+ _no_split_modules = ["MixtralDecoderLayer"]
398
+ _skip_keys_device_placement = ["past_key_values"]
399
+ _supports_flash_attn = True
400
+ _supports_sdpa = True
401
+ _supports_flex_attn = True
402
+
403
+ _can_compile_fullgraph = True
404
+ _supports_attention_backend = True
405
+ _can_record_outputs = {
406
+ "router_logits": OutputRecorder(MixtralTopKRouter, index=0),
407
+ "hidden_states": MixtralDecoderLayer,
408
+ "attentions": MixtralAttention,
409
+ }
410
+
411
+ @torch.no_grad()
412
+ def _init_weights(self, module):
413
+ super()._init_weights(module)
414
+ std = self.config.initializer_range
415
+ if isinstance(module, MixtralExperts):
416
+ init.normal_(module.gate_up_proj, mean=0.0, std=std)
417
+ init.normal_(module.down_proj, mean=0.0, std=std)
418
+ elif isinstance(module, MixtralTopKRouter):
419
+ init.normal_(module.weight, mean=0.0, std=std)
420
+
421
+
422
+ @auto_docstring
423
+ class MixtralModel(MixtralPreTrainedModel):
424
+ def __init__(self, config: MixtralConfig):
425
+ super().__init__(config)
426
+ self.padding_idx = config.pad_token_id
427
+ self.vocab_size = config.vocab_size
428
+
429
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
430
+ self.layers = nn.ModuleList(
431
+ [MixtralDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
432
+ )
433
+ self.norm = MixtralRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
434
+ self.rotary_emb = MixtralRotaryEmbedding(config=config)
435
+ self.gradient_checkpointing = False
436
+
437
+ # Initialize weights and apply final processing
438
+ self.post_init()
439
+
440
+ @merge_with_config_defaults
441
+ @capture_outputs
442
+ @auto_docstring
443
+ def forward(
444
+ self,
445
+ input_ids: torch.LongTensor | None = None,
446
+ attention_mask: torch.Tensor | None = None,
447
+ position_ids: torch.LongTensor | None = None,
448
+ past_key_values: Cache | None = None,
449
+ inputs_embeds: torch.FloatTensor | None = None,
450
+ use_cache: bool | None = None,
451
+ **kwargs: Unpack[TransformersKwargs],
452
+ ) -> MoeModelOutputWithPast:
453
+ if (input_ids is None) ^ (inputs_embeds is not None):
454
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
455
+
456
+ if use_cache and past_key_values is None:
457
+ past_key_values = DynamicCache(config=self.config)
458
+
459
+ if inputs_embeds is None:
460
+ inputs_embeds = self.embed_tokens(input_ids)
461
+
462
+ if position_ids is None:
463
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
464
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
465
+ position_ids = position_ids.unsqueeze(0)
466
+
467
+ mask_function = create_causal_mask if self.config.sliding_window is None else create_sliding_window_causal_mask
468
+ causal_mask = mask_function(
469
+ config=self.config,
470
+ inputs_embeds=inputs_embeds,
471
+ attention_mask=attention_mask,
472
+ past_key_values=past_key_values,
473
+ position_ids=position_ids,
474
+ )
475
+
476
+ hidden_states = inputs_embeds
477
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
478
+
479
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
480
+ hidden_states = decoder_layer(
481
+ hidden_states,
482
+ attention_mask=causal_mask,
483
+ position_ids=position_ids,
484
+ past_key_values=past_key_values,
485
+ use_cache=use_cache,
486
+ position_embeddings=position_embeddings,
487
+ **kwargs,
488
+ )
489
+
490
+ hidden_states = self.norm(hidden_states)
491
+
492
+ return MoeModelOutputWithPast( # only diff with Mistral is the output type, we need MoE
493
+ last_hidden_state=hidden_states,
494
+ past_key_values=past_key_values,
495
+ )
496
+
497
+
498
+ def load_balancing_loss_func(
499
+ gate_logits: torch.Tensor | tuple[torch.Tensor] | None,
500
+ num_experts: int | None = None,
501
+ top_k=2,
502
+ attention_mask: torch.Tensor | None = None,
503
+ ) -> torch.Tensor | int:
504
+ r"""
505
+ Computes auxiliary load balancing loss as in Switch Transformer - implemented in Pytorch.
506
+
507
+ See Switch Transformer (https://huggingface.co/papers/2101.03961) for more details. This function implements the loss
508
+ function presented in equations (4) - (6) of the paper. It aims at penalizing cases where the routing between
509
+ experts is too unbalanced.
510
+
511
+ Args:
512
+ gate_logits:
513
+ Logits from the `gate`, should be a tuple of model.config.num_hidden_layers tensors of
514
+ shape [batch_size X sequence_length, num_experts].
515
+ num_experts:
516
+ Number of experts
517
+ top_k:
518
+ The number of experts to route per-token, can be also interpreted as the `top-k` routing
519
+ parameter.
520
+ attention_mask (`torch.Tensor`, *optional*):
521
+ The attention_mask used in forward function
522
+ shape [batch_size X sequence_length] if not None.
523
+
524
+ Returns:
525
+ The auxiliary loss.
526
+ """
527
+ if gate_logits is None or not isinstance(gate_logits, tuple):
528
+ return 0
529
+
530
+ if isinstance(gate_logits, tuple):
531
+ compute_device = gate_logits[0].device
532
+ concatenated_gate_logits = torch.cat([layer_gate.to(compute_device) for layer_gate in gate_logits], dim=0)
533
+
534
+ routing_weights = torch.nn.functional.softmax(concatenated_gate_logits, dim=-1)
535
+
536
+ _, selected_experts = torch.topk(routing_weights, top_k, dim=-1)
537
+
538
+ expert_mask = torch.nn.functional.one_hot(selected_experts, num_experts)
539
+
540
+ if attention_mask is None:
541
+ # Compute the percentage of tokens routed to each experts
542
+ tokens_per_expert = torch.mean(expert_mask.float(), dim=0)
543
+
544
+ # Compute the average probability of routing to these experts
545
+ router_prob_per_expert = torch.mean(routing_weights, dim=0)
546
+ else:
547
+ batch_size, sequence_length = attention_mask.shape
548
+ num_hidden_layers = concatenated_gate_logits.shape[0] // (batch_size * sequence_length)
549
+
550
+ # Compute the mask that masks all padding tokens as 0 with the same shape of expert_mask
551
+ expert_attention_mask = (
552
+ attention_mask[None, :, :, None, None]
553
+ .expand((num_hidden_layers, batch_size, sequence_length, top_k, num_experts))
554
+ .reshape(-1, top_k, num_experts)
555
+ .to(compute_device)
556
+ )
557
+
558
+ # Compute the percentage of tokens routed to each experts
559
+ tokens_per_expert = torch.sum(expert_mask.float() * expert_attention_mask, dim=0) / torch.sum(
560
+ expert_attention_mask, dim=0
561
+ )
562
+
563
+ # Compute the mask that masks all padding tokens as 0 with the same shape of tokens_per_expert
564
+ router_per_expert_attention_mask = (
565
+ attention_mask[None, :, :, None]
566
+ .expand((num_hidden_layers, batch_size, sequence_length, num_experts))
567
+ .reshape(-1, num_experts)
568
+ .to(compute_device)
569
+ )
570
+
571
+ # Compute the average probability of routing to these experts
572
+ router_prob_per_expert = torch.sum(routing_weights * router_per_expert_attention_mask, dim=0) / torch.sum(
573
+ router_per_expert_attention_mask, dim=0
574
+ )
575
+
576
+ overall_loss = torch.sum(tokens_per_expert * router_prob_per_expert.unsqueeze(0))
577
+ return overall_loss * num_experts
578
+
579
+
580
+ @auto_docstring
581
+ class MixtralForCausalLM(MixtralPreTrainedModel, GenerationMixin):
582
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
583
+ _tp_plan = {"lm_head": "colwise_gather_output"}
584
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
585
+
586
+ def __init__(self, config):
587
+ super().__init__(config)
588
+ self.model = MixtralModel(config)
589
+ self.vocab_size = config.vocab_size
590
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
591
+ self.router_aux_loss_coef = config.router_aux_loss_coef
592
+ self.num_experts = config.num_local_experts
593
+ self.num_experts_per_tok = config.num_experts_per_tok
594
+
595
+ # Initialize weights and apply final processing
596
+ self.post_init()
597
+
598
+ @can_return_tuple
599
+ @auto_docstring
600
+ def forward(
601
+ self,
602
+ input_ids: torch.LongTensor | None = None,
603
+ attention_mask: torch.Tensor | None = None,
604
+ position_ids: torch.LongTensor | None = None,
605
+ past_key_values: Cache | None = None,
606
+ inputs_embeds: torch.FloatTensor | None = None,
607
+ labels: torch.LongTensor | None = None,
608
+ use_cache: bool | None = None,
609
+ output_router_logits: bool | None = None,
610
+ logits_to_keep: int | torch.Tensor = 0,
611
+ **kwargs: Unpack[TransformersKwargs],
612
+ ) -> MoeCausalLMOutputWithPast:
613
+ r"""
614
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
615
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
616
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
617
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
618
+
619
+ Example:
620
+
621
+ ```python
622
+ >>> from transformers import AutoTokenizer, MixtralForCausalLM
623
+
624
+ >>> model = MixtralForCausalLM.from_pretrained("mistralai/Mixtral-8x7B-v0.1")
625
+ >>> tokenizer = AutoTokenizer.from_pretrained("mistralai/Mixtral-8x7B-v0.1")
626
+
627
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
628
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
629
+
630
+ >>> # Generate
631
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
632
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
633
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
634
+ ```"""
635
+
636
+ output_router_logits = (
637
+ output_router_logits if output_router_logits is not None else self.config.output_router_logits
638
+ )
639
+
640
+ # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn)
641
+ outputs: MoeModelOutputWithPast = self.model(
642
+ input_ids=input_ids,
643
+ attention_mask=attention_mask,
644
+ position_ids=position_ids,
645
+ past_key_values=past_key_values,
646
+ inputs_embeds=inputs_embeds,
647
+ use_cache=use_cache,
648
+ output_router_logits=output_router_logits,
649
+ **kwargs,
650
+ )
651
+
652
+ hidden_states = outputs.last_hidden_state
653
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
654
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
655
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
656
+
657
+ loss = None
658
+ if labels is not None:
659
+ loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)
660
+
661
+ aux_loss = None
662
+ if output_router_logits:
663
+ aux_loss = load_balancing_loss_func(
664
+ outputs.router_logits,
665
+ self.num_experts,
666
+ self.num_experts_per_tok,
667
+ attention_mask,
668
+ )
669
+ if labels is not None:
670
+ loss += self.router_aux_loss_coef * aux_loss.to(loss.device) # make sure to reside in the same device
671
+
672
+ return MoeCausalLMOutputWithPast(
673
+ loss=loss,
674
+ aux_loss=aux_loss,
675
+ logits=logits,
676
+ past_key_values=outputs.past_key_values,
677
+ hidden_states=outputs.hidden_states,
678
+ attentions=outputs.attentions,
679
+ router_logits=outputs.router_logits,
680
+ )
681
+
682
+
683
+ class MixtralForSequenceClassification(GenericForSequenceClassification, MixtralPreTrainedModel):
684
+ pass
685
+
686
+
687
+ class MixtralForTokenClassification(GenericForTokenClassification, MixtralPreTrainedModel):
688
+ pass
689
+
690
+
691
+ class MixtralForQuestionAnswering(GenericForQuestionAnswering, MixtralPreTrainedModel):
692
+ pass
693
+
694
+
695
+ __all__ = [
696
+ "MixtralForCausalLM",
697
+ "MixtralForQuestionAnswering",
698
+ "MixtralModel",
699
+ "MixtralPreTrainedModel",
700
+ "MixtralForSequenceClassification",
701
+ "MixtralForTokenClassification",
702
+ ]
third_party/transformers/src/transformers/models/mixtral/modular_mixtral.py ADDED
@@ -0,0 +1,448 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 Mistral AI and the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
4
+ # and OPT implementations in this library. It has been modified from its
5
+ # original forms to accommodate minor architectural differences compared
6
+ # to GPT-NeoX and OPT used by the Meta AI team that trained the model.
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ """PyTorch Mixtral model."""
20
+
21
+ import torch
22
+ import torch.nn.functional as F
23
+ from torch import nn
24
+
25
+ from ... import initialization as init
26
+ from ...activations import ACT2FN
27
+ from ...cache_utils import Cache, DynamicCache
28
+ from ...integrations import use_experts_implementation
29
+ from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask
30
+ from ...modeling_layers import GradientCheckpointingLayer
31
+ from ...modeling_outputs import MoeCausalLMOutputWithPast, MoeModelOutputWithPast
32
+ from ...modeling_utils import PreTrainedModel
33
+ from ...processing_utils import Unpack
34
+ from ...utils import TransformersKwargs, logging
35
+ from ...utils.output_capturing import OutputRecorder
36
+ from ..mistral.modeling_mistral import (
37
+ MistralAttention,
38
+ MistralForCausalLM,
39
+ MistralForQuestionAnswering,
40
+ MistralForSequenceClassification,
41
+ MistralForTokenClassification,
42
+ MistralModel,
43
+ MistralPreTrainedModel,
44
+ MistralRMSNorm,
45
+ MistralRotaryEmbedding,
46
+ )
47
+ from .configuration_mixtral import MixtralConfig
48
+
49
+
50
+ logger = logging.get_logger(__name__)
51
+
52
+
53
+ def load_balancing_loss_func(
54
+ gate_logits: torch.Tensor | tuple[torch.Tensor] | None,
55
+ num_experts: int | None = None,
56
+ top_k=2,
57
+ attention_mask: torch.Tensor | None = None,
58
+ ) -> torch.Tensor | int:
59
+ r"""
60
+ Computes auxiliary load balancing loss as in Switch Transformer - implemented in Pytorch.
61
+
62
+ See Switch Transformer (https://huggingface.co/papers/2101.03961) for more details. This function implements the loss
63
+ function presented in equations (4) - (6) of the paper. It aims at penalizing cases where the routing between
64
+ experts is too unbalanced.
65
+
66
+ Args:
67
+ gate_logits:
68
+ Logits from the `gate`, should be a tuple of model.config.num_hidden_layers tensors of
69
+ shape [batch_size X sequence_length, num_experts].
70
+ num_experts:
71
+ Number of experts
72
+ top_k:
73
+ The number of experts to route per-token, can be also interpreted as the `top-k` routing
74
+ parameter.
75
+ attention_mask (`torch.Tensor`, *optional*):
76
+ The attention_mask used in forward function
77
+ shape [batch_size X sequence_length] if not None.
78
+
79
+ Returns:
80
+ The auxiliary loss.
81
+ """
82
+ if gate_logits is None or not isinstance(gate_logits, tuple):
83
+ return 0
84
+
85
+ if isinstance(gate_logits, tuple):
86
+ compute_device = gate_logits[0].device
87
+ concatenated_gate_logits = torch.cat([layer_gate.to(compute_device) for layer_gate in gate_logits], dim=0)
88
+
89
+ routing_weights = torch.nn.functional.softmax(concatenated_gate_logits, dim=-1)
90
+
91
+ _, selected_experts = torch.topk(routing_weights, top_k, dim=-1)
92
+
93
+ expert_mask = torch.nn.functional.one_hot(selected_experts, num_experts)
94
+
95
+ if attention_mask is None:
96
+ # Compute the percentage of tokens routed to each experts
97
+ tokens_per_expert = torch.mean(expert_mask.float(), dim=0)
98
+
99
+ # Compute the average probability of routing to these experts
100
+ router_prob_per_expert = torch.mean(routing_weights, dim=0)
101
+ else:
102
+ batch_size, sequence_length = attention_mask.shape
103
+ num_hidden_layers = concatenated_gate_logits.shape[0] // (batch_size * sequence_length)
104
+
105
+ # Compute the mask that masks all padding tokens as 0 with the same shape of expert_mask
106
+ expert_attention_mask = (
107
+ attention_mask[None, :, :, None, None]
108
+ .expand((num_hidden_layers, batch_size, sequence_length, top_k, num_experts))
109
+ .reshape(-1, top_k, num_experts)
110
+ .to(compute_device)
111
+ )
112
+
113
+ # Compute the percentage of tokens routed to each experts
114
+ tokens_per_expert = torch.sum(expert_mask.float() * expert_attention_mask, dim=0) / torch.sum(
115
+ expert_attention_mask, dim=0
116
+ )
117
+
118
+ # Compute the mask that masks all padding tokens as 0 with the same shape of tokens_per_expert
119
+ router_per_expert_attention_mask = (
120
+ attention_mask[None, :, :, None]
121
+ .expand((num_hidden_layers, batch_size, sequence_length, num_experts))
122
+ .reshape(-1, num_experts)
123
+ .to(compute_device)
124
+ )
125
+
126
+ # Compute the average probability of routing to these experts
127
+ router_prob_per_expert = torch.sum(routing_weights * router_per_expert_attention_mask, dim=0) / torch.sum(
128
+ router_per_expert_attention_mask, dim=0
129
+ )
130
+
131
+ overall_loss = torch.sum(tokens_per_expert * router_prob_per_expert.unsqueeze(0))
132
+ return overall_loss * num_experts
133
+
134
+
135
+ @use_experts_implementation
136
+ class MixtralExperts(nn.Module):
137
+ """Collection of expert weights stored as 3D tensors."""
138
+
139
+ def __init__(self, config: MixtralConfig):
140
+ super().__init__()
141
+ self.num_experts = config.num_local_experts
142
+ self.hidden_dim = config.hidden_size
143
+ self.intermediate_dim = config.intermediate_size
144
+ self.gate_up_proj = nn.Parameter(torch.empty(self.num_experts, 2 * self.intermediate_dim, self.hidden_dim))
145
+ self.down_proj = nn.Parameter(torch.empty(self.num_experts, self.hidden_dim, self.intermediate_dim))
146
+ self.act_fn = ACT2FN[config.hidden_act]
147
+
148
+ def forward(
149
+ self,
150
+ hidden_states: torch.Tensor,
151
+ top_k_index: torch.Tensor,
152
+ top_k_weights: torch.Tensor,
153
+ ) -> torch.Tensor:
154
+ final_hidden_states = torch.zeros_like(hidden_states)
155
+ with torch.no_grad():
156
+ expert_mask = torch.nn.functional.one_hot(top_k_index, num_classes=self.num_experts)
157
+ expert_mask = expert_mask.permute(2, 1, 0)
158
+ expert_hit = torch.greater(expert_mask.sum(dim=(-1, -2)), 0).nonzero()
159
+
160
+ for expert_idx in expert_hit:
161
+ expert_idx = expert_idx[0]
162
+ if expert_idx == self.num_experts:
163
+ continue
164
+ top_k_pos, token_idx = torch.where(expert_mask[expert_idx])
165
+ current_state = hidden_states[token_idx]
166
+ gate, up = nn.functional.linear(current_state, self.gate_up_proj[expert_idx]).chunk(2, dim=-1)
167
+ current_hidden_states = self.act_fn(gate) * up
168
+ current_hidden_states = nn.functional.linear(current_hidden_states, self.down_proj[expert_idx])
169
+ current_hidden_states = current_hidden_states * top_k_weights[token_idx, top_k_pos, None]
170
+ final_hidden_states.index_add_(0, token_idx, current_hidden_states.to(final_hidden_states.dtype))
171
+
172
+ return final_hidden_states
173
+
174
+
175
+ class MixtralTopKRouter(nn.Module):
176
+ def __init__(self, config):
177
+ super().__init__()
178
+ self.top_k = config.num_experts_per_tok
179
+ self.num_experts = config.num_local_experts
180
+ self.hidden_dim = config.hidden_size
181
+ self.weight = nn.Parameter(torch.empty(self.num_experts, self.hidden_dim))
182
+
183
+ def forward(self, hidden_states):
184
+ hidden_states = hidden_states.reshape(-1, self.hidden_dim)
185
+ router_logits = F.linear(hidden_states, self.weight) # (seq_len, num_experts)
186
+ router_logits = torch.nn.functional.softmax(router_logits.float(), dim=-1)
187
+ router_top_value, router_indices = torch.topk(router_logits, self.top_k, dim=-1) # (seq_len, top_k)
188
+ router_top_value /= router_top_value.sum(dim=-1, keepdim=True)
189
+ router_scores = router_top_value
190
+ return router_logits, router_scores, router_indices
191
+
192
+
193
+ class MixtralSparseMoeBlock(nn.Module):
194
+ def __init__(self, config):
195
+ super().__init__()
196
+ self.top_k = config.num_experts_per_tok
197
+ self.jitter_noise = config.router_jitter_noise
198
+ self.gate = MixtralTopKRouter(config)
199
+ self.experts = MixtralExperts(config)
200
+
201
+ def forward(self, hidden_states: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
202
+ batch_size, sequence_length, hidden_dim = hidden_states.shape
203
+ if self.training and self.jitter_noise > 0:
204
+ hidden_states *= torch.empty_like(hidden_states).uniform_(1.0 - self.jitter_noise, 1.0 + self.jitter_noise)
205
+ hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
206
+ _, top_k_weights, top_k_index = self.gate(hidden_states)
207
+ hidden_states = self.experts(hidden_states, top_k_index, top_k_weights)
208
+ hidden_states = hidden_states.reshape(batch_size, sequence_length, hidden_dim)
209
+ return hidden_states
210
+
211
+
212
+ class MixtralRMSNorm(MistralRMSNorm):
213
+ pass
214
+
215
+
216
+ class MixtralRotaryEmbedding(MistralRotaryEmbedding):
217
+ pass
218
+
219
+
220
+ class MixtralAttention(MistralAttention):
221
+ pass
222
+
223
+
224
+ class MixtralDecoderLayer(GradientCheckpointingLayer):
225
+ def __init__(self, config: MixtralConfig, layer_idx: int):
226
+ super().__init__()
227
+ self.hidden_size = config.hidden_size
228
+
229
+ self.self_attn = MixtralAttention(config, layer_idx)
230
+
231
+ self.mlp = MixtralSparseMoeBlock(config)
232
+ self.input_layernorm = MixtralRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
233
+ self.post_attention_layernorm = MixtralRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
234
+
235
+ def forward(
236
+ self,
237
+ hidden_states: torch.Tensor,
238
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
239
+ attention_mask: torch.Tensor | None = None,
240
+ position_ids: torch.LongTensor | None = None,
241
+ past_key_values: Cache | None = None,
242
+ **kwargs: Unpack[TransformersKwargs],
243
+ ) -> torch.Tensor:
244
+ residual = hidden_states
245
+ hidden_states = self.input_layernorm(hidden_states)
246
+ hidden_states, _ = self.self_attn(
247
+ hidden_states=hidden_states,
248
+ position_embeddings=position_embeddings,
249
+ attention_mask=attention_mask,
250
+ position_ids=position_ids,
251
+ past_key_values=past_key_values,
252
+ **kwargs,
253
+ )
254
+ hidden_states = residual + hidden_states
255
+ residual = hidden_states
256
+ hidden_states = self.post_attention_layernorm(hidden_states)
257
+ hidden_states = self.mlp(hidden_states)
258
+ hidden_states = residual + hidden_states
259
+ return hidden_states
260
+
261
+
262
+ class MixtralPreTrainedModel(MistralPreTrainedModel):
263
+ _can_record_outputs = {
264
+ "router_logits": OutputRecorder(MixtralTopKRouter, index=0),
265
+ "hidden_states": MixtralDecoderLayer,
266
+ "attentions": MixtralAttention,
267
+ }
268
+
269
+ @torch.no_grad()
270
+ def _init_weights(self, module):
271
+ PreTrainedModel._init_weights(self, module)
272
+ std = self.config.initializer_range
273
+ if isinstance(module, MixtralExperts):
274
+ init.normal_(module.gate_up_proj, mean=0.0, std=std)
275
+ init.normal_(module.down_proj, mean=0.0, std=std)
276
+ elif isinstance(module, MixtralTopKRouter):
277
+ init.normal_(module.weight, mean=0.0, std=std)
278
+
279
+
280
+ class MixtralModel(MistralModel):
281
+ def forward(
282
+ self,
283
+ input_ids: torch.LongTensor | None = None,
284
+ attention_mask: torch.Tensor | None = None,
285
+ position_ids: torch.LongTensor | None = None,
286
+ past_key_values: Cache | None = None,
287
+ inputs_embeds: torch.FloatTensor | None = None,
288
+ use_cache: bool | None = None,
289
+ **kwargs: Unpack[TransformersKwargs],
290
+ ) -> MoeModelOutputWithPast:
291
+ if (input_ids is None) ^ (inputs_embeds is not None):
292
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
293
+
294
+ if use_cache and past_key_values is None:
295
+ past_key_values = DynamicCache(config=self.config)
296
+
297
+ if inputs_embeds is None:
298
+ inputs_embeds = self.embed_tokens(input_ids)
299
+
300
+ if position_ids is None:
301
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
302
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
303
+ position_ids = position_ids.unsqueeze(0)
304
+
305
+ mask_function = create_causal_mask if self.config.sliding_window is None else create_sliding_window_causal_mask
306
+ causal_mask = mask_function(
307
+ config=self.config,
308
+ inputs_embeds=inputs_embeds,
309
+ attention_mask=attention_mask,
310
+ past_key_values=past_key_values,
311
+ position_ids=position_ids,
312
+ )
313
+
314
+ hidden_states = inputs_embeds
315
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
316
+
317
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
318
+ hidden_states = decoder_layer(
319
+ hidden_states,
320
+ attention_mask=causal_mask,
321
+ position_ids=position_ids,
322
+ past_key_values=past_key_values,
323
+ use_cache=use_cache,
324
+ position_embeddings=position_embeddings,
325
+ **kwargs,
326
+ )
327
+
328
+ hidden_states = self.norm(hidden_states)
329
+
330
+ return MoeModelOutputWithPast( # only diff with Mistral is the output type, we need MoE
331
+ last_hidden_state=hidden_states,
332
+ past_key_values=past_key_values,
333
+ )
334
+
335
+
336
+ class MixtralForCausalLM(MistralForCausalLM):
337
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
338
+
339
+ def __init__(self, config):
340
+ super().__init__(config)
341
+ self.model = MixtralModel(config)
342
+ self.router_aux_loss_coef = config.router_aux_loss_coef
343
+ self.num_experts = config.num_local_experts
344
+ self.num_experts_per_tok = config.num_experts_per_tok
345
+
346
+ def forward(
347
+ self,
348
+ input_ids: torch.LongTensor | None = None,
349
+ attention_mask: torch.Tensor | None = None,
350
+ position_ids: torch.LongTensor | None = None,
351
+ past_key_values: Cache | None = None,
352
+ inputs_embeds: torch.FloatTensor | None = None,
353
+ labels: torch.LongTensor | None = None,
354
+ use_cache: bool | None = None,
355
+ output_router_logits: bool | None = None,
356
+ logits_to_keep: int | torch.Tensor = 0,
357
+ **kwargs: Unpack[TransformersKwargs],
358
+ ) -> MoeCausalLMOutputWithPast:
359
+ r"""
360
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
361
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
362
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
363
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
364
+
365
+ Example:
366
+
367
+ ```python
368
+ >>> from transformers import AutoTokenizer, MixtralForCausalLM
369
+
370
+ >>> model = MixtralForCausalLM.from_pretrained("mistralai/Mixtral-8x7B-v0.1")
371
+ >>> tokenizer = AutoTokenizer.from_pretrained("mistralai/Mixtral-8x7B-v0.1")
372
+
373
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
374
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
375
+
376
+ >>> # Generate
377
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
378
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
379
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
380
+ ```"""
381
+
382
+ output_router_logits = (
383
+ output_router_logits if output_router_logits is not None else self.config.output_router_logits
384
+ )
385
+
386
+ # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn)
387
+ outputs: MoeModelOutputWithPast = self.model(
388
+ input_ids=input_ids,
389
+ attention_mask=attention_mask,
390
+ position_ids=position_ids,
391
+ past_key_values=past_key_values,
392
+ inputs_embeds=inputs_embeds,
393
+ use_cache=use_cache,
394
+ output_router_logits=output_router_logits,
395
+ **kwargs,
396
+ )
397
+
398
+ hidden_states = outputs.last_hidden_state
399
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
400
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
401
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
402
+
403
+ loss = None
404
+ if labels is not None:
405
+ loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)
406
+
407
+ aux_loss = None
408
+ if output_router_logits:
409
+ aux_loss = load_balancing_loss_func(
410
+ outputs.router_logits,
411
+ self.num_experts,
412
+ self.num_experts_per_tok,
413
+ attention_mask,
414
+ )
415
+ if labels is not None:
416
+ loss += self.router_aux_loss_coef * aux_loss.to(loss.device) # make sure to reside in the same device
417
+
418
+ return MoeCausalLMOutputWithPast(
419
+ loss=loss,
420
+ aux_loss=aux_loss,
421
+ logits=logits,
422
+ past_key_values=outputs.past_key_values,
423
+ hidden_states=outputs.hidden_states,
424
+ attentions=outputs.attentions,
425
+ router_logits=outputs.router_logits,
426
+ )
427
+
428
+
429
+ class MixtralForSequenceClassification(MistralForSequenceClassification):
430
+ pass
431
+
432
+
433
+ class MixtralForTokenClassification(MistralForTokenClassification):
434
+ pass
435
+
436
+
437
+ class MixtralForQuestionAnswering(MistralForQuestionAnswering):
438
+ pass
439
+
440
+
441
+ __all__ = [
442
+ "MixtralForCausalLM",
443
+ "MixtralForQuestionAnswering",
444
+ "MixtralModel",
445
+ "MixtralPreTrainedModel",
446
+ "MixtralForSequenceClassification",
447
+ "MixtralForTokenClassification",
448
+ ]
third_party/transformers/src/transformers/models/mra/__init__.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from .configuration_mra import *
22
+ from .modeling_mra import *
23
+ else:
24
+ import sys
25
+
26
+ _file = globals()["__file__"]
27
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/mra/configuration_mra.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """MRA model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...configuration_utils import PreTrainedConfig
19
+ from ...utils import auto_docstring
20
+
21
+
22
+ @auto_docstring(checkpoint="uw-madison/mra-base-512-4")
23
+ @strict
24
+ class MraConfig(PreTrainedConfig):
25
+ r"""
26
+ block_per_row (`int`, *optional*, defaults to 4):
27
+ Used to set the budget for the high resolution scale.
28
+ approx_mode (`str`, *optional*, defaults to `"full"`):
29
+ Controls whether both low and high resolution approximations are used. Set to `"full"` for both low and
30
+ high resolution and `"sparse"` for only low resolution.
31
+ initial_prior_first_n_blocks (`int`, *optional*, defaults to 0):
32
+ The initial number of blocks for which high resolution is used.
33
+ initial_prior_diagonal_n_blocks (`int`, *optional*, defaults to 0):
34
+ The number of diagonal blocks for which high resolution is used.
35
+
36
+ Example:
37
+
38
+ ```python
39
+ >>> from transformers import MraConfig, MraModel
40
+
41
+ >>> # Initializing a Mra uw-madison/mra-base-512-4 style configuration
42
+ >>> configuration = MraConfig()
43
+
44
+ >>> # Initializing a model (with random weights) from the uw-madison/mra-base-512-4 style configuration
45
+ >>> model = MraModel(configuration)
46
+
47
+ >>> # Accessing the model configuration
48
+ >>> configuration = model.config
49
+ ```"""
50
+
51
+ model_type = "mra"
52
+
53
+ vocab_size: int = 50265
54
+ hidden_size: int = 768
55
+ num_hidden_layers: int = 12
56
+ num_attention_heads: int = 12
57
+ intermediate_size: int = 3072
58
+ hidden_act: str = "gelu"
59
+ hidden_dropout_prob: float | int = 0.1
60
+ attention_probs_dropout_prob: float | int = 0.1
61
+ max_position_embeddings: int = 512
62
+ type_vocab_size: int = 1
63
+ initializer_range: float = 0.02
64
+ layer_norm_eps: float = 1e-5
65
+ block_per_row: int = 4
66
+ approx_mode: str = "full"
67
+ initial_prior_first_n_blocks: int = 0
68
+ initial_prior_diagonal_n_blocks: int = 0
69
+ pad_token_id: int | None = 1
70
+ bos_token_id: int | None = 0
71
+ eos_token_id: int | list[int] | None = 2
72
+ add_cross_attention: bool = False
73
+ tie_word_embeddings: bool = True
74
+
75
+
76
+ __all__ = ["MraConfig"]
third_party/transformers/src/transformers/models/mra/convert_mra_pytorch_to_pytorch.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 The HuggingFace Inc. team.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Convert MRA checkpoints from the original repository. URL: https://github.com/mlpen/mra-attention"""
15
+
16
+ import argparse
17
+
18
+ import torch
19
+
20
+ from transformers import MraConfig, MraForMaskedLM
21
+
22
+
23
+ def rename_key(orig_key):
24
+ if "model" in orig_key:
25
+ orig_key = orig_key.replace("model.", "")
26
+ if "norm1" in orig_key:
27
+ orig_key = orig_key.replace("norm1", "attention.output.LayerNorm")
28
+ if "norm2" in orig_key:
29
+ orig_key = orig_key.replace("norm2", "output.LayerNorm")
30
+ if "norm" in orig_key:
31
+ orig_key = orig_key.replace("norm", "LayerNorm")
32
+ if "transformer" in orig_key:
33
+ layer_num = orig_key.split(".")[0].split("_")[-1]
34
+ orig_key = orig_key.replace(f"transformer_{layer_num}", f"encoder.layer.{layer_num}")
35
+ if "mha.attn" in orig_key:
36
+ orig_key = orig_key.replace("mha.attn", "attention.self")
37
+ if "mha" in orig_key:
38
+ orig_key = orig_key.replace("mha", "attention")
39
+ if "W_q" in orig_key:
40
+ orig_key = orig_key.replace("W_q", "self.query")
41
+ if "W_k" in orig_key:
42
+ orig_key = orig_key.replace("W_k", "self.key")
43
+ if "W_v" in orig_key:
44
+ orig_key = orig_key.replace("W_v", "self.value")
45
+ if "ff.0" in orig_key:
46
+ orig_key = orig_key.replace("ff.0", "intermediate.dense")
47
+ if "ff.2" in orig_key:
48
+ orig_key = orig_key.replace("ff.2", "output.dense")
49
+ if "ff" in orig_key:
50
+ orig_key = orig_key.replace("ff", "output.dense")
51
+ if "mlm_class" in orig_key:
52
+ orig_key = orig_key.replace("mlm.mlm_class", "cls.predictions.decoder")
53
+ if "mlm" in orig_key:
54
+ orig_key = orig_key.replace("mlm", "cls.predictions.transform")
55
+ if "backbone.backbone.encoders" in orig_key:
56
+ orig_key = orig_key.replace("backbone.backbone.encoders", "encoder.layer")
57
+ if "cls" not in orig_key:
58
+ orig_key = "mra." + orig_key
59
+
60
+ return orig_key
61
+
62
+
63
+ def convert_checkpoint_helper(max_position_embeddings, orig_state_dict):
64
+ for key in orig_state_dict.copy():
65
+ val = orig_state_dict.pop(key)
66
+
67
+ if ("pooler" in key) or ("sen_class" in key):
68
+ continue
69
+ else:
70
+ orig_state_dict[rename_key(key)] = val
71
+
72
+ orig_state_dict["cls.predictions.bias"] = orig_state_dict["cls.predictions.decoder.bias"]
73
+ orig_state_dict["mra.embeddings.position_ids"] = torch.arange(max_position_embeddings).expand((1, -1)) + 2
74
+
75
+ return orig_state_dict
76
+
77
+
78
+ def convert_mra_checkpoint(checkpoint_path, mra_config_file, pytorch_dump_path):
79
+ orig_state_dict = torch.load(checkpoint_path, map_location="cpu", weights_only=True)["model_state_dict"]
80
+ config = MraConfig.from_json_file(mra_config_file)
81
+ model = MraForMaskedLM(config)
82
+
83
+ new_state_dict = convert_checkpoint_helper(config.max_position_embeddings, orig_state_dict)
84
+
85
+ print(model.load_state_dict(new_state_dict))
86
+ model.eval()
87
+ model.save_pretrained(pytorch_dump_path)
88
+
89
+ print(f"Checkpoint successfully converted. Model saved at {pytorch_dump_path}")
90
+
91
+
92
+ if __name__ == "__main__":
93
+ parser = argparse.ArgumentParser()
94
+ # Required parameters
95
+ parser.add_argument(
96
+ "--pytorch_model_path", default=None, type=str, required=True, help="Path to Mra pytorch checkpoint."
97
+ )
98
+ parser.add_argument(
99
+ "--config_file",
100
+ default=None,
101
+ type=str,
102
+ required=True,
103
+ help="The json file for Mra model config.",
104
+ )
105
+ parser.add_argument(
106
+ "--pytorch_dump_path", default=None, type=str, required=True, help="Path to the output PyTorch model."
107
+ )
108
+ args = parser.parse_args()
109
+ convert_mra_checkpoint(args.pytorch_model_path, args.config_file, args.pytorch_dump_path)
third_party/transformers/src/transformers/models/mra/modeling_mra.py ADDED
@@ -0,0 +1,1332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 University of Wisconsin-Madison and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """PyTorch MRA model."""
15
+
16
+ import math
17
+
18
+ import torch
19
+ from torch import nn
20
+ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
21
+
22
+ from ... import initialization as init
23
+ from ...activations import ACT2FN
24
+ from ...modeling_layers import GradientCheckpointingLayer
25
+ from ...modeling_outputs import (
26
+ BaseModelOutputWithCrossAttentions,
27
+ MaskedLMOutput,
28
+ MultipleChoiceModelOutput,
29
+ QuestionAnsweringModelOutput,
30
+ SequenceClassifierOutput,
31
+ TokenClassifierOutput,
32
+ )
33
+ from ...modeling_utils import PreTrainedModel
34
+ from ...pytorch_utils import apply_chunking_to_forward
35
+ from ...utils import (
36
+ auto_docstring,
37
+ is_cuda_platform,
38
+ is_kernels_available,
39
+ is_ninja_available,
40
+ is_torch_cuda_available,
41
+ logging,
42
+ )
43
+ from .configuration_mra import MraConfig
44
+
45
+
46
+ logger = logging.get_logger(__name__)
47
+
48
+ mra_cuda_kernel = None
49
+
50
+
51
+ def load_cuda_kernels():
52
+ global mra_cuda_kernel
53
+ if not is_kernels_available():
54
+ raise ImportError("kernels is not installed, please install it with `pip install kernels`")
55
+ from ...integrations.hub_kernels import get_kernel
56
+
57
+ mra_cuda_kernel = get_kernel("kernels-community/mra")
58
+
59
+
60
+ def sparse_max(sparse_qk_prod, indices, query_num_block, key_num_block):
61
+ """
62
+ Computes maximum values for softmax stability.
63
+ """
64
+ if len(sparse_qk_prod.size()) != 4:
65
+ raise ValueError("sparse_qk_prod must be a 4-dimensional tensor.")
66
+
67
+ if len(indices.size()) != 2:
68
+ raise ValueError("indices must be a 2-dimensional tensor.")
69
+
70
+ if sparse_qk_prod.size(2) != 32:
71
+ raise ValueError("The size of the second dimension of sparse_qk_prod must be 32.")
72
+
73
+ if sparse_qk_prod.size(3) != 32:
74
+ raise ValueError("The size of the third dimension of sparse_qk_prod must be 32.")
75
+
76
+ index_vals = sparse_qk_prod.max(dim=-2).values.transpose(-1, -2)
77
+ index_vals = index_vals.contiguous()
78
+
79
+ indices = indices.int()
80
+ indices = indices.contiguous()
81
+
82
+ max_vals, max_vals_scatter = mra_cuda_kernel.index_max(index_vals, indices, query_num_block, key_num_block)
83
+ max_vals_scatter = max_vals_scatter.transpose(-1, -2)[:, :, None, :]
84
+
85
+ return max_vals, max_vals_scatter
86
+
87
+
88
+ def sparse_mask(mask, indices, block_size=32):
89
+ """
90
+ Converts attention mask to a sparse mask for high resolution logits.
91
+ """
92
+ if len(mask.size()) != 2:
93
+ raise ValueError("mask must be a 2-dimensional tensor.")
94
+
95
+ if len(indices.size()) != 2:
96
+ raise ValueError("indices must be a 2-dimensional tensor.")
97
+
98
+ if mask.shape[0] != indices.shape[0]:
99
+ raise ValueError("mask and indices must have the same size in the zero-th dimension.")
100
+
101
+ batch_size, seq_len = mask.shape
102
+ num_block = seq_len // block_size
103
+
104
+ batch_idx = torch.arange(indices.size(0), dtype=torch.long, device=indices.device)
105
+ mask = mask.reshape(batch_size, num_block, block_size)
106
+ mask = mask[batch_idx[:, None], (indices % num_block).long(), :]
107
+
108
+ return mask
109
+
110
+
111
+ def mm_to_sparse(dense_query, dense_key, indices, block_size=32):
112
+ """
113
+ Performs Sampled Dense Matrix Multiplication.
114
+ """
115
+ batch_size, query_size, dim = dense_query.size()
116
+ _, key_size, dim = dense_key.size()
117
+
118
+ if query_size % block_size != 0:
119
+ raise ValueError("query_size (size of first dimension of dense_query) must be divisible by block_size.")
120
+
121
+ if key_size % block_size != 0:
122
+ raise ValueError("key_size (size of first dimension of dense_key) must be divisible by block_size.")
123
+
124
+ dense_query = dense_query.reshape(batch_size, query_size // block_size, block_size, dim).transpose(-1, -2)
125
+ dense_key = dense_key.reshape(batch_size, key_size // block_size, block_size, dim).transpose(-1, -2)
126
+
127
+ if len(dense_query.size()) != 4:
128
+ raise ValueError("dense_query must be a 4-dimensional tensor.")
129
+
130
+ if len(dense_key.size()) != 4:
131
+ raise ValueError("dense_key must be a 4-dimensional tensor.")
132
+
133
+ if len(indices.size()) != 2:
134
+ raise ValueError("indices must be a 2-dimensional tensor.")
135
+
136
+ if dense_query.size(3) != 32:
137
+ raise ValueError("The third dimension of dense_query must be 32.")
138
+
139
+ if dense_key.size(3) != 32:
140
+ raise ValueError("The third dimension of dense_key must be 32.")
141
+
142
+ dense_query = dense_query.contiguous()
143
+ dense_key = dense_key.contiguous()
144
+
145
+ indices = indices.int()
146
+ indices = indices.contiguous()
147
+
148
+ return mra_cuda_kernel.mm_to_sparse(dense_query, dense_key, indices.int())
149
+
150
+
151
+ def sparse_dense_mm(sparse_query, indices, dense_key, query_num_block, block_size=32):
152
+ """
153
+ Performs matrix multiplication of a sparse matrix with a dense matrix.
154
+ """
155
+ batch_size, key_size, dim = dense_key.size()
156
+
157
+ if key_size % block_size != 0:
158
+ raise ValueError("key_size (size of first dimension of dense_key) must be divisible by block_size.")
159
+
160
+ if sparse_query.size(2) != block_size:
161
+ raise ValueError("The size of the second dimension of sparse_query must be equal to the block_size.")
162
+
163
+ if sparse_query.size(3) != block_size:
164
+ raise ValueError("The size of the third dimension of sparse_query must be equal to the block_size.")
165
+
166
+ dense_key = dense_key.reshape(batch_size, key_size // block_size, block_size, dim).transpose(-1, -2)
167
+
168
+ if len(sparse_query.size()) != 4:
169
+ raise ValueError("sparse_query must be a 4-dimensional tensor.")
170
+
171
+ if len(dense_key.size()) != 4:
172
+ raise ValueError("dense_key must be a 4-dimensional tensor.")
173
+
174
+ if len(indices.size()) != 2:
175
+ raise ValueError("indices must be a 2-dimensional tensor.")
176
+
177
+ if dense_key.size(3) != 32:
178
+ raise ValueError("The size of the third dimension of dense_key must be 32.")
179
+
180
+ sparse_query = sparse_query.contiguous()
181
+
182
+ indices = indices.int()
183
+ indices = indices.contiguous()
184
+ dense_key = dense_key.contiguous()
185
+
186
+ dense_qk_prod = mra_cuda_kernel.sparse_dense_mm(sparse_query, indices, dense_key, query_num_block)
187
+ dense_qk_prod = dense_qk_prod.transpose(-1, -2).reshape(batch_size, query_num_block * block_size, dim)
188
+ return dense_qk_prod
189
+
190
+
191
+ def transpose_indices(indices, dim_1_block, dim_2_block):
192
+ return ((indices % dim_2_block) * dim_1_block + torch.div(indices, dim_2_block, rounding_mode="floor")).long()
193
+
194
+
195
+ class MraSampledDenseMatMul(torch.autograd.Function):
196
+ @staticmethod
197
+ def forward(ctx, dense_query, dense_key, indices, block_size):
198
+ sparse_qk_prod = mm_to_sparse(dense_query, dense_key, indices, block_size)
199
+ ctx.save_for_backward(dense_query, dense_key, indices)
200
+ ctx.block_size = block_size
201
+ return sparse_qk_prod
202
+
203
+ @staticmethod
204
+ def backward(ctx, grad):
205
+ dense_query, dense_key, indices = ctx.saved_tensors
206
+ block_size = ctx.block_size
207
+ query_num_block = dense_query.size(1) // block_size
208
+ key_num_block = dense_key.size(1) // block_size
209
+ indices_T = transpose_indices(indices, query_num_block, key_num_block)
210
+ grad_key = sparse_dense_mm(grad.transpose(-1, -2), indices_T, dense_query, key_num_block)
211
+ grad_query = sparse_dense_mm(grad, indices, dense_key, query_num_block)
212
+ return grad_query, grad_key, None, None
213
+
214
+ @staticmethod
215
+ def operator_call(dense_query, dense_key, indices, block_size=32):
216
+ return MraSampledDenseMatMul.apply(dense_query, dense_key, indices, block_size)
217
+
218
+
219
+ class MraSparseDenseMatMul(torch.autograd.Function):
220
+ @staticmethod
221
+ def forward(ctx, sparse_query, indices, dense_key, query_num_block):
222
+ sparse_qk_prod = sparse_dense_mm(sparse_query, indices, dense_key, query_num_block)
223
+ ctx.save_for_backward(sparse_query, indices, dense_key)
224
+ ctx.query_num_block = query_num_block
225
+ return sparse_qk_prod
226
+
227
+ @staticmethod
228
+ def backward(ctx, grad):
229
+ sparse_query, indices, dense_key = ctx.saved_tensors
230
+ query_num_block = ctx.query_num_block
231
+ key_num_block = dense_key.size(1) // sparse_query.size(-1)
232
+ indices_T = transpose_indices(indices, query_num_block, key_num_block)
233
+ grad_key = sparse_dense_mm(sparse_query.transpose(-1, -2), indices_T, grad, key_num_block)
234
+ grad_query = mm_to_sparse(grad, dense_key, indices)
235
+ return grad_query, None, grad_key, None
236
+
237
+ @staticmethod
238
+ def operator_call(sparse_query, indices, dense_key, query_num_block):
239
+ return MraSparseDenseMatMul.apply(sparse_query, indices, dense_key, query_num_block)
240
+
241
+
242
+ class MraReduceSum:
243
+ @staticmethod
244
+ def operator_call(sparse_query, indices, query_num_block, key_num_block):
245
+ batch_size, num_block, block_size, _ = sparse_query.size()
246
+
247
+ if len(sparse_query.size()) != 4:
248
+ raise ValueError("sparse_query must be a 4-dimensional tensor.")
249
+
250
+ if len(indices.size()) != 2:
251
+ raise ValueError("indices must be a 2-dimensional tensor.")
252
+
253
+ _, _, block_size, _ = sparse_query.size()
254
+ batch_size, num_block = indices.size()
255
+
256
+ sparse_query = sparse_query.sum(dim=2).reshape(batch_size * num_block, block_size)
257
+
258
+ batch_idx = torch.arange(indices.size(0), dtype=torch.long, device=indices.device)
259
+ global_idxes = (
260
+ torch.div(indices, key_num_block, rounding_mode="floor").long() + batch_idx[:, None] * query_num_block
261
+ ).reshape(batch_size * num_block)
262
+ temp = torch.zeros(
263
+ (batch_size * query_num_block, block_size), dtype=sparse_query.dtype, device=sparse_query.device
264
+ )
265
+ output = temp.index_add(0, global_idxes, sparse_query).reshape(batch_size, query_num_block, block_size)
266
+
267
+ output = output.reshape(batch_size, query_num_block * block_size)
268
+ return output
269
+
270
+
271
+ def get_low_resolution_logit(query, key, block_size, mask=None, value=None):
272
+ """
273
+ Compute low resolution approximation.
274
+ """
275
+ batch_size, seq_len, head_dim = query.size()
276
+
277
+ num_block_per_row = seq_len // block_size
278
+
279
+ value_hat = None
280
+ if mask is not None:
281
+ token_count = mask.reshape(batch_size, num_block_per_row, block_size).sum(dim=-1)
282
+ query_hat = query.reshape(batch_size, num_block_per_row, block_size, head_dim).sum(dim=-2) / (
283
+ token_count[:, :, None] + 1e-6
284
+ )
285
+ key_hat = key.reshape(batch_size, num_block_per_row, block_size, head_dim).sum(dim=-2) / (
286
+ token_count[:, :, None] + 1e-6
287
+ )
288
+ if value is not None:
289
+ value_hat = value.reshape(batch_size, num_block_per_row, block_size, head_dim).sum(dim=-2) / (
290
+ token_count[:, :, None] + 1e-6
291
+ )
292
+ else:
293
+ token_count = block_size * torch.ones(batch_size, num_block_per_row, dtype=torch.float, device=query.device)
294
+ query_hat = query.reshape(batch_size, num_block_per_row, block_size, head_dim).mean(dim=-2)
295
+ key_hat = key.reshape(batch_size, num_block_per_row, block_size, head_dim).mean(dim=-2)
296
+ if value is not None:
297
+ value_hat = value.reshape(batch_size, num_block_per_row, block_size, head_dim).mean(dim=-2)
298
+
299
+ low_resolution_logit = torch.matmul(query_hat, key_hat.transpose(-1, -2)) / math.sqrt(head_dim)
300
+
301
+ low_resolution_logit_row_max = low_resolution_logit.max(dim=-1, keepdims=True).values
302
+
303
+ if mask is not None:
304
+ low_resolution_logit = (
305
+ low_resolution_logit - 1e4 * ((token_count[:, None, :] * token_count[:, :, None]) < 0.5).float()
306
+ )
307
+
308
+ return low_resolution_logit, token_count, low_resolution_logit_row_max, value_hat
309
+
310
+
311
+ def get_block_idxes(
312
+ low_resolution_logit, num_blocks, approx_mode, initial_prior_first_n_blocks, initial_prior_diagonal_n_blocks
313
+ ):
314
+ """
315
+ Compute the indices of the subset of components to be used in the approximation.
316
+ """
317
+ batch_size, total_blocks_per_row, _ = low_resolution_logit.shape
318
+
319
+ if initial_prior_diagonal_n_blocks > 0:
320
+ offset = initial_prior_diagonal_n_blocks // 2
321
+ temp_mask = torch.ones(total_blocks_per_row, total_blocks_per_row, device=low_resolution_logit.device)
322
+ diagonal_mask = torch.tril(torch.triu(temp_mask, diagonal=-offset), diagonal=offset)
323
+ low_resolution_logit = low_resolution_logit + diagonal_mask[None, :, :] * 5e3
324
+
325
+ if initial_prior_first_n_blocks > 0:
326
+ low_resolution_logit[:, :initial_prior_first_n_blocks, :] = (
327
+ low_resolution_logit[:, :initial_prior_first_n_blocks, :] + 5e3
328
+ )
329
+ low_resolution_logit[:, :, :initial_prior_first_n_blocks] = (
330
+ low_resolution_logit[:, :, :initial_prior_first_n_blocks] + 5e3
331
+ )
332
+
333
+ top_k_vals = torch.topk(
334
+ low_resolution_logit.reshape(batch_size, -1), num_blocks, dim=-1, largest=True, sorted=False
335
+ )
336
+ indices = top_k_vals.indices
337
+
338
+ if approx_mode == "full":
339
+ threshold = top_k_vals.values.min(dim=-1).values
340
+ high_resolution_mask = (low_resolution_logit >= threshold[:, None, None]).float()
341
+ elif approx_mode == "sparse":
342
+ high_resolution_mask = None
343
+ else:
344
+ raise ValueError(f"{approx_mode} is not a valid approx_model value.")
345
+
346
+ return indices, high_resolution_mask
347
+
348
+
349
+ def mra2_attention(
350
+ query,
351
+ key,
352
+ value,
353
+ mask,
354
+ num_blocks,
355
+ approx_mode,
356
+ block_size=32,
357
+ initial_prior_first_n_blocks=0,
358
+ initial_prior_diagonal_n_blocks=0,
359
+ ):
360
+ """
361
+ Use Mra to approximate self-attention.
362
+ """
363
+ if mra_cuda_kernel is None:
364
+ return torch.zeros_like(query).requires_grad_()
365
+
366
+ batch_size, num_head, seq_len, head_dim = query.size()
367
+ meta_batch = batch_size * num_head
368
+
369
+ if seq_len % block_size != 0:
370
+ raise ValueError("sequence length must be divisible by the block_size.")
371
+
372
+ num_block_per_row = seq_len // block_size
373
+
374
+ query = query.reshape(meta_batch, seq_len, head_dim)
375
+ key = key.reshape(meta_batch, seq_len, head_dim)
376
+ value = value.reshape(meta_batch, seq_len, head_dim)
377
+
378
+ if mask is not None:
379
+ query = query * mask[:, :, None]
380
+ key = key * mask[:, :, None]
381
+ value = value * mask[:, :, None]
382
+
383
+ if approx_mode == "full":
384
+ low_resolution_logit, token_count, low_resolution_logit_row_max, value_hat = get_low_resolution_logit(
385
+ query, key, block_size, mask, value
386
+ )
387
+ elif approx_mode == "sparse":
388
+ with torch.no_grad():
389
+ low_resolution_logit, token_count, low_resolution_logit_row_max, _ = get_low_resolution_logit(
390
+ query, key, block_size, mask
391
+ )
392
+ else:
393
+ raise Exception('approx_mode must be "full" or "sparse"')
394
+
395
+ with torch.no_grad():
396
+ low_resolution_logit_normalized = low_resolution_logit - low_resolution_logit_row_max
397
+ indices, high_resolution_mask = get_block_idxes(
398
+ low_resolution_logit_normalized,
399
+ num_blocks,
400
+ approx_mode,
401
+ initial_prior_first_n_blocks,
402
+ initial_prior_diagonal_n_blocks,
403
+ )
404
+
405
+ high_resolution_logit = MraSampledDenseMatMul.operator_call(
406
+ query, key, indices, block_size=block_size
407
+ ) / math.sqrt(head_dim)
408
+ max_vals, max_vals_scatter = sparse_max(high_resolution_logit, indices, num_block_per_row, num_block_per_row)
409
+ high_resolution_logit = high_resolution_logit - max_vals_scatter
410
+ if mask is not None:
411
+ high_resolution_logit = high_resolution_logit - 1e4 * (1 - sparse_mask(mask, indices)[:, :, :, None])
412
+ high_resolution_attn = torch.exp(high_resolution_logit)
413
+ high_resolution_attn_out = MraSparseDenseMatMul.operator_call(
414
+ high_resolution_attn, indices, value, num_block_per_row
415
+ )
416
+ high_resolution_normalizer = MraReduceSum.operator_call(
417
+ high_resolution_attn, indices, num_block_per_row, num_block_per_row
418
+ )
419
+
420
+ if approx_mode == "full":
421
+ low_resolution_attn = (
422
+ torch.exp(low_resolution_logit - low_resolution_logit_row_max - 1e4 * high_resolution_mask)
423
+ * token_count[:, None, :]
424
+ )
425
+
426
+ low_resolution_attn_out = (
427
+ torch.matmul(low_resolution_attn, value_hat)[:, :, None, :]
428
+ .repeat(1, 1, block_size, 1)
429
+ .reshape(meta_batch, seq_len, head_dim)
430
+ )
431
+ low_resolution_normalizer = (
432
+ low_resolution_attn.sum(dim=-1)[:, :, None].repeat(1, 1, block_size).reshape(meta_batch, seq_len)
433
+ )
434
+
435
+ log_correction = low_resolution_logit_row_max.repeat(1, 1, block_size).reshape(meta_batch, seq_len) - max_vals
436
+ if mask is not None:
437
+ log_correction = log_correction * mask
438
+
439
+ low_resolution_corr = torch.exp(log_correction * (log_correction <= 0).float())
440
+ low_resolution_attn_out = low_resolution_attn_out * low_resolution_corr[:, :, None]
441
+ low_resolution_normalizer = low_resolution_normalizer * low_resolution_corr
442
+
443
+ high_resolution_corr = torch.exp(-log_correction * (log_correction > 0).float())
444
+ high_resolution_attn_out = high_resolution_attn_out * high_resolution_corr[:, :, None]
445
+ high_resolution_normalizer = high_resolution_normalizer * high_resolution_corr
446
+
447
+ context_layer = (high_resolution_attn_out + low_resolution_attn_out) / (
448
+ high_resolution_normalizer[:, :, None] + low_resolution_normalizer[:, :, None] + 1e-6
449
+ )
450
+
451
+ elif approx_mode == "sparse":
452
+ context_layer = high_resolution_attn_out / (high_resolution_normalizer[:, :, None] + 1e-6)
453
+ else:
454
+ raise Exception('config.approx_mode must be "full" or "sparse"')
455
+
456
+ if mask is not None:
457
+ context_layer = context_layer * mask[:, :, None]
458
+
459
+ context_layer = context_layer.reshape(batch_size, num_head, seq_len, head_dim)
460
+
461
+ return context_layer
462
+
463
+
464
+ class MraEmbeddings(nn.Module):
465
+ """Construct the embeddings from word, position and token_type embeddings."""
466
+
467
+ def __init__(self, config):
468
+ super().__init__()
469
+ self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
470
+ self.position_embeddings = nn.Embedding(config.max_position_embeddings + 2, config.hidden_size)
471
+ self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
472
+
473
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
474
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
475
+
476
+ # position_ids (1, len position emb) is contiguous in memory and exported when serialized
477
+ self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)) + 2)
478
+ self.register_buffer(
479
+ "token_type_ids",
480
+ torch.zeros(self.position_ids.size(), dtype=torch.long, device=self.position_ids.device),
481
+ persistent=False,
482
+ )
483
+
484
+ def forward(self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None):
485
+ if input_ids is not None:
486
+ input_shape = input_ids.size()
487
+ else:
488
+ input_shape = inputs_embeds.size()[:-1]
489
+
490
+ seq_length = input_shape[1]
491
+
492
+ if position_ids is None:
493
+ position_ids = self.position_ids[:, :seq_length]
494
+
495
+ # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs
496
+ # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves
497
+ # issue #5664
498
+ if token_type_ids is None:
499
+ if hasattr(self, "token_type_ids"):
500
+ buffered_token_type_ids = self.token_type_ids[:, :seq_length]
501
+ buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length)
502
+ token_type_ids = buffered_token_type_ids_expanded
503
+ else:
504
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
505
+
506
+ if inputs_embeds is None:
507
+ inputs_embeds = self.word_embeddings(input_ids)
508
+ token_type_embeddings = self.token_type_embeddings(token_type_ids)
509
+ embeddings = inputs_embeds + token_type_embeddings
510
+
511
+ position_embeddings = self.position_embeddings(position_ids)
512
+ embeddings += position_embeddings
513
+
514
+ embeddings = self.LayerNorm(embeddings)
515
+ embeddings = self.dropout(embeddings)
516
+ return embeddings
517
+
518
+
519
+ class MraSelfAttention(nn.Module):
520
+ def __init__(self, config):
521
+ super().__init__()
522
+ if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
523
+ raise ValueError(
524
+ f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
525
+ f"heads ({config.num_attention_heads})"
526
+ )
527
+
528
+ kernel_loaded = mra_cuda_kernel is not None
529
+ if is_torch_cuda_available() and is_cuda_platform() and is_ninja_available() and not kernel_loaded:
530
+ try:
531
+ load_cuda_kernels()
532
+ except Exception as e:
533
+ logger.warning(f"Could not load the custom kernel for multi-scale deformable attention: {e}")
534
+
535
+ self.num_attention_heads = config.num_attention_heads
536
+ self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
537
+ self.all_head_size = self.num_attention_heads * self.attention_head_size
538
+
539
+ self.query = nn.Linear(config.hidden_size, self.all_head_size)
540
+ self.key = nn.Linear(config.hidden_size, self.all_head_size)
541
+ self.value = nn.Linear(config.hidden_size, self.all_head_size)
542
+
543
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
544
+
545
+ self.num_block = (config.max_position_embeddings // 32) * config.block_per_row
546
+ self.num_block = min(self.num_block, int((config.max_position_embeddings // 32) ** 2))
547
+
548
+ self.approx_mode = config.approx_mode
549
+ self.initial_prior_first_n_blocks = config.initial_prior_first_n_blocks
550
+ self.initial_prior_diagonal_n_blocks = config.initial_prior_diagonal_n_blocks
551
+
552
+ def forward(self, hidden_states, attention_mask=None):
553
+ batch_size, seq_len, _ = hidden_states.shape
554
+ query_layer = (
555
+ self.query(hidden_states)
556
+ .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
557
+ .transpose(1, 2)
558
+ )
559
+ key_layer = (
560
+ self.key(hidden_states)
561
+ .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
562
+ .transpose(1, 2)
563
+ )
564
+ value_layer = (
565
+ self.value(hidden_states)
566
+ .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
567
+ .transpose(1, 2)
568
+ )
569
+
570
+ # revert changes made by get_extended_attention_mask
571
+ attention_mask = 1.0 + attention_mask / 10000.0
572
+ attention_mask = (
573
+ attention_mask.squeeze()
574
+ .repeat(1, self.num_attention_heads, 1)
575
+ .reshape(batch_size * self.num_attention_heads, seq_len)
576
+ .int()
577
+ )
578
+
579
+ # The CUDA kernels are most efficient with inputs whose size is a multiple of a GPU's warp size (32). Inputs
580
+ # smaller than this are padded with zeros.
581
+ gpu_warp_size = 32
582
+
583
+ if self.attention_head_size < gpu_warp_size:
584
+ pad_size = batch_size, self.num_attention_heads, seq_len, gpu_warp_size - self.attention_head_size
585
+
586
+ query_layer = torch.cat([query_layer, torch.zeros(pad_size, device=query_layer.device)], dim=-1)
587
+ key_layer = torch.cat([key_layer, torch.zeros(pad_size, device=key_layer.device)], dim=-1)
588
+ value_layer = torch.cat([value_layer, torch.zeros(pad_size, device=value_layer.device)], dim=-1)
589
+
590
+ context_layer = mra2_attention(
591
+ query_layer.float(),
592
+ key_layer.float(),
593
+ value_layer.float(),
594
+ attention_mask.float(),
595
+ self.num_block,
596
+ approx_mode=self.approx_mode,
597
+ initial_prior_first_n_blocks=self.initial_prior_first_n_blocks,
598
+ initial_prior_diagonal_n_blocks=self.initial_prior_diagonal_n_blocks,
599
+ )
600
+
601
+ if self.attention_head_size < gpu_warp_size:
602
+ context_layer = context_layer[:, :, :, : self.attention_head_size]
603
+
604
+ context_layer = context_layer.reshape(batch_size, self.num_attention_heads, seq_len, self.attention_head_size)
605
+
606
+ context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
607
+ new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
608
+ context_layer = context_layer.view(*new_context_layer_shape)
609
+
610
+ outputs = (context_layer,)
611
+
612
+ return outputs
613
+
614
+
615
+ # Copied from transformers.models.bert.modeling_bert.BertSelfOutput
616
+ class MraSelfOutput(nn.Module):
617
+ def __init__(self, config):
618
+ super().__init__()
619
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
620
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
621
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
622
+
623
+ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
624
+ hidden_states = self.dense(hidden_states)
625
+ hidden_states = self.dropout(hidden_states)
626
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
627
+ return hidden_states
628
+
629
+
630
+ class MraAttention(nn.Module):
631
+ def __init__(self, config):
632
+ super().__init__()
633
+ self.self = MraSelfAttention(config)
634
+ self.output = MraSelfOutput(config)
635
+
636
+ def forward(self, hidden_states, attention_mask=None):
637
+ self_outputs = self.self(hidden_states, attention_mask)
638
+ attention_output = self.output(self_outputs[0], hidden_states)
639
+ outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them
640
+ return outputs
641
+
642
+
643
+ # Copied from transformers.models.bert.modeling_bert.BertIntermediate
644
+ class MraIntermediate(nn.Module):
645
+ def __init__(self, config):
646
+ super().__init__()
647
+ self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
648
+ if isinstance(config.hidden_act, str):
649
+ self.intermediate_act_fn = ACT2FN[config.hidden_act]
650
+ else:
651
+ self.intermediate_act_fn = config.hidden_act
652
+
653
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
654
+ hidden_states = self.dense(hidden_states)
655
+ hidden_states = self.intermediate_act_fn(hidden_states)
656
+ return hidden_states
657
+
658
+
659
+ # Copied from transformers.models.bert.modeling_bert.BertOutput
660
+ class MraOutput(nn.Module):
661
+ def __init__(self, config):
662
+ super().__init__()
663
+ self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
664
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
665
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
666
+
667
+ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
668
+ hidden_states = self.dense(hidden_states)
669
+ hidden_states = self.dropout(hidden_states)
670
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
671
+ return hidden_states
672
+
673
+
674
+ class MraLayer(GradientCheckpointingLayer):
675
+ def __init__(self, config):
676
+ super().__init__()
677
+ self.chunk_size_feed_forward = config.chunk_size_feed_forward
678
+ self.seq_len_dim = 1
679
+ self.attention = MraAttention(config)
680
+ self.add_cross_attention = config.add_cross_attention
681
+ self.intermediate = MraIntermediate(config)
682
+ self.output = MraOutput(config)
683
+
684
+ def forward(self, hidden_states, attention_mask=None):
685
+ self_attention_outputs = self.attention(hidden_states, attention_mask)
686
+ attention_output = self_attention_outputs[0]
687
+
688
+ outputs = self_attention_outputs[1:] # add self attentions if we output attention weights
689
+
690
+ layer_output = apply_chunking_to_forward(
691
+ self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output
692
+ )
693
+ outputs = (layer_output,) + outputs
694
+
695
+ return outputs
696
+
697
+ def feed_forward_chunk(self, attention_output):
698
+ intermediate_output = self.intermediate(attention_output)
699
+ layer_output = self.output(intermediate_output, attention_output)
700
+ return layer_output
701
+
702
+
703
+ class MraEncoder(nn.Module):
704
+ def __init__(self, config):
705
+ super().__init__()
706
+ self.config = config
707
+ self.layer = nn.ModuleList([MraLayer(config) for _ in range(config.num_hidden_layers)])
708
+ self.gradient_checkpointing = False
709
+
710
+ def forward(
711
+ self,
712
+ hidden_states,
713
+ attention_mask=None,
714
+ output_hidden_states=False,
715
+ return_dict=True,
716
+ ):
717
+ all_hidden_states = () if output_hidden_states else None
718
+
719
+ for i, layer_module in enumerate(self.layer):
720
+ if output_hidden_states:
721
+ all_hidden_states = all_hidden_states + (hidden_states,)
722
+
723
+ layer_outputs = layer_module(hidden_states, attention_mask)
724
+
725
+ hidden_states = layer_outputs[0]
726
+
727
+ if output_hidden_states:
728
+ all_hidden_states = all_hidden_states + (hidden_states,)
729
+
730
+ if not return_dict:
731
+ return tuple(v for v in [hidden_states, all_hidden_states] if v is not None)
732
+ return BaseModelOutputWithCrossAttentions(
733
+ last_hidden_state=hidden_states,
734
+ hidden_states=all_hidden_states,
735
+ )
736
+
737
+
738
+ # Copied from transformers.models.bert.modeling_bert.BertPredictionHeadTransform
739
+ class MraPredictionHeadTransform(nn.Module):
740
+ def __init__(self, config):
741
+ super().__init__()
742
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
743
+ if isinstance(config.hidden_act, str):
744
+ self.transform_act_fn = ACT2FN[config.hidden_act]
745
+ else:
746
+ self.transform_act_fn = config.hidden_act
747
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
748
+
749
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
750
+ hidden_states = self.dense(hidden_states)
751
+ hidden_states = self.transform_act_fn(hidden_states)
752
+ hidden_states = self.LayerNorm(hidden_states)
753
+ return hidden_states
754
+
755
+
756
+ # Copied from transformers.models.bert.modeling_bert.BertLMPredictionHead with Bert->Mra
757
+ class MraLMPredictionHead(nn.Module):
758
+ def __init__(self, config):
759
+ super().__init__()
760
+ self.transform = MraPredictionHeadTransform(config)
761
+
762
+ # The output weights are the same as the input embeddings, but there is
763
+ # an output-only bias for each token.
764
+ self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
765
+ self.bias = nn.Parameter(torch.zeros(config.vocab_size))
766
+
767
+ def forward(self, hidden_states):
768
+ hidden_states = self.transform(hidden_states)
769
+ hidden_states = self.decoder(hidden_states)
770
+ return hidden_states
771
+
772
+
773
+ # Copied from transformers.models.bert.modeling_bert.BertOnlyMLMHead with Bert->Mra
774
+ class MraOnlyMLMHead(nn.Module):
775
+ def __init__(self, config):
776
+ super().__init__()
777
+ self.predictions = MraLMPredictionHead(config)
778
+
779
+ def forward(self, sequence_output: torch.Tensor) -> torch.Tensor:
780
+ prediction_scores = self.predictions(sequence_output)
781
+ return prediction_scores
782
+
783
+
784
+ @auto_docstring
785
+ # Copied from transformers.models.yoso.modeling_yoso.YosoPreTrainedModel with Yoso->Mra,yoso->mra
786
+ class MraPreTrainedModel(PreTrainedModel):
787
+ config: MraConfig
788
+ base_model_prefix = "mra"
789
+ supports_gradient_checkpointing = True
790
+
791
+ @torch.no_grad()
792
+ def _init_weights(self, module: nn.Module):
793
+ """Initialize the weights"""
794
+ super()._init_weights(module)
795
+ if isinstance(module, MraLMPredictionHead):
796
+ init.zeros_(module.bias)
797
+ elif isinstance(module, MraEmbeddings):
798
+ init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)) + 2)
799
+ init.zeros_(module.token_type_ids)
800
+
801
+
802
+ @auto_docstring
803
+ class MraModel(MraPreTrainedModel):
804
+ def __init__(self, config):
805
+ super().__init__(config)
806
+ self.config = config
807
+
808
+ self.embeddings = MraEmbeddings(config)
809
+ self.encoder = MraEncoder(config)
810
+
811
+ # Initialize weights and apply final processing
812
+ self.post_init()
813
+
814
+ def get_input_embeddings(self):
815
+ return self.embeddings.word_embeddings
816
+
817
+ def set_input_embeddings(self, value):
818
+ self.embeddings.word_embeddings = value
819
+
820
+ @auto_docstring
821
+ def forward(
822
+ self,
823
+ input_ids: torch.Tensor | None = None,
824
+ attention_mask: torch.Tensor | None = None,
825
+ token_type_ids: torch.Tensor | None = None,
826
+ position_ids: torch.Tensor | None = None,
827
+ inputs_embeds: torch.Tensor | None = None,
828
+ output_hidden_states: bool | None = None,
829
+ return_dict: bool | None = None,
830
+ **kwargs,
831
+ ) -> tuple | BaseModelOutputWithCrossAttentions:
832
+ output_hidden_states = (
833
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
834
+ )
835
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
836
+
837
+ if input_ids is not None and inputs_embeds is not None:
838
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
839
+ elif input_ids is not None:
840
+ self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask)
841
+ input_shape = input_ids.size()
842
+ elif inputs_embeds is not None:
843
+ input_shape = inputs_embeds.size()[:-1]
844
+ else:
845
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
846
+
847
+ batch_size, seq_length = input_shape
848
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
849
+
850
+ if attention_mask is None:
851
+ attention_mask = torch.ones(((batch_size, seq_length)), device=device)
852
+
853
+ if token_type_ids is None:
854
+ if hasattr(self.embeddings, "token_type_ids"):
855
+ buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length]
856
+ buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length)
857
+ token_type_ids = buffered_token_type_ids_expanded
858
+ else:
859
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
860
+
861
+ # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
862
+ # ourselves in which case we just need to make it broadcastable to all heads.
863
+ extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape)
864
+
865
+ embedding_output = self.embeddings(
866
+ input_ids=input_ids,
867
+ position_ids=position_ids,
868
+ token_type_ids=token_type_ids,
869
+ inputs_embeds=inputs_embeds,
870
+ )
871
+ encoder_outputs = self.encoder(
872
+ embedding_output,
873
+ attention_mask=extended_attention_mask,
874
+ output_hidden_states=output_hidden_states,
875
+ return_dict=return_dict,
876
+ )
877
+ sequence_output = encoder_outputs[0]
878
+
879
+ if not return_dict:
880
+ return (sequence_output,) + encoder_outputs[1:]
881
+
882
+ return BaseModelOutputWithCrossAttentions(
883
+ last_hidden_state=sequence_output,
884
+ hidden_states=encoder_outputs.hidden_states,
885
+ attentions=encoder_outputs.attentions,
886
+ cross_attentions=encoder_outputs.cross_attentions,
887
+ )
888
+
889
+
890
+ @auto_docstring
891
+ class MraForMaskedLM(MraPreTrainedModel):
892
+ _tied_weights_keys = {
893
+ "cls.predictions.decoder.bias": "cls.predictions.bias",
894
+ "cls.predictions.decoder.weight": "mra.embeddings.word_embeddings.weight",
895
+ }
896
+
897
+ def __init__(self, config):
898
+ super().__init__(config)
899
+
900
+ self.mra = MraModel(config)
901
+ self.cls = MraOnlyMLMHead(config)
902
+
903
+ # Initialize weights and apply final processing
904
+ self.post_init()
905
+
906
+ def get_output_embeddings(self):
907
+ return self.cls.predictions.decoder
908
+
909
+ def set_output_embeddings(self, new_embeddings):
910
+ self.cls.predictions.decoder = new_embeddings
911
+ self.cls.predictions.bias = new_embeddings.bias
912
+
913
+ @auto_docstring
914
+ def forward(
915
+ self,
916
+ input_ids: torch.Tensor | None = None,
917
+ attention_mask: torch.Tensor | None = None,
918
+ token_type_ids: torch.Tensor | None = None,
919
+ position_ids: torch.Tensor | None = None,
920
+ inputs_embeds: torch.Tensor | None = None,
921
+ labels: torch.Tensor | None = None,
922
+ output_hidden_states: bool | None = None,
923
+ return_dict: bool | None = None,
924
+ **kwargs,
925
+ ) -> tuple | MaskedLMOutput:
926
+ r"""
927
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
928
+ Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
929
+ config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
930
+ loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
931
+ """
932
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
933
+
934
+ outputs = self.mra(
935
+ input_ids,
936
+ attention_mask=attention_mask,
937
+ token_type_ids=token_type_ids,
938
+ position_ids=position_ids,
939
+ inputs_embeds=inputs_embeds,
940
+ output_hidden_states=output_hidden_states,
941
+ return_dict=return_dict,
942
+ )
943
+
944
+ sequence_output = outputs[0]
945
+ prediction_scores = self.cls(sequence_output)
946
+
947
+ masked_lm_loss = None
948
+ if labels is not None:
949
+ loss_fct = CrossEntropyLoss() # -100 index = padding token
950
+ masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
951
+
952
+ if not return_dict:
953
+ output = (prediction_scores,) + outputs[1:]
954
+ return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output
955
+
956
+ return MaskedLMOutput(
957
+ loss=masked_lm_loss,
958
+ logits=prediction_scores,
959
+ hidden_states=outputs.hidden_states,
960
+ attentions=outputs.attentions,
961
+ )
962
+
963
+
964
+ # Copied from transformers.models.yoso.modeling_yoso.YosoClassificationHead with Yoso->Mra
965
+ class MraClassificationHead(nn.Module):
966
+ """Head for sentence-level classification tasks."""
967
+
968
+ def __init__(self, config):
969
+ super().__init__()
970
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
971
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
972
+ self.out_proj = nn.Linear(config.hidden_size, config.num_labels)
973
+
974
+ self.config = config
975
+
976
+ def forward(self, features, **kwargs):
977
+ x = features[:, 0, :] # take <s> token (equiv. to [CLS])
978
+ x = self.dropout(x)
979
+ x = self.dense(x)
980
+ x = ACT2FN[self.config.hidden_act](x)
981
+ x = self.dropout(x)
982
+ x = self.out_proj(x)
983
+ return x
984
+
985
+
986
+ @auto_docstring(
987
+ custom_intro="""
988
+ MRA Model transformer with a sequence classification/regression head on top (a linear layer on top of
989
+ the pooled output) e.g. for GLUE tasks.
990
+ """
991
+ )
992
+ class MraForSequenceClassification(MraPreTrainedModel):
993
+ def __init__(self, config):
994
+ super().__init__(config)
995
+ self.num_labels = config.num_labels
996
+ self.mra = MraModel(config)
997
+ self.classifier = MraClassificationHead(config)
998
+
999
+ # Initialize weights and apply final processing
1000
+ self.post_init()
1001
+
1002
+ @auto_docstring
1003
+ def forward(
1004
+ self,
1005
+ input_ids: torch.Tensor | None = None,
1006
+ attention_mask: torch.Tensor | None = None,
1007
+ token_type_ids: torch.Tensor | None = None,
1008
+ position_ids: torch.Tensor | None = None,
1009
+ inputs_embeds: torch.Tensor | None = None,
1010
+ labels: torch.Tensor | None = None,
1011
+ output_hidden_states: bool | None = None,
1012
+ return_dict: bool | None = None,
1013
+ **kwargs,
1014
+ ) -> tuple | SequenceClassifierOutput:
1015
+ r"""
1016
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
1017
+ Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
1018
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
1019
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
1020
+ """
1021
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1022
+
1023
+ outputs = self.mra(
1024
+ input_ids,
1025
+ attention_mask=attention_mask,
1026
+ token_type_ids=token_type_ids,
1027
+ position_ids=position_ids,
1028
+ inputs_embeds=inputs_embeds,
1029
+ output_hidden_states=output_hidden_states,
1030
+ return_dict=return_dict,
1031
+ )
1032
+
1033
+ sequence_output = outputs[0]
1034
+ logits = self.classifier(sequence_output)
1035
+
1036
+ loss = None
1037
+ if labels is not None:
1038
+ if self.config.problem_type is None:
1039
+ if self.num_labels == 1:
1040
+ self.config.problem_type = "regression"
1041
+ elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
1042
+ self.config.problem_type = "single_label_classification"
1043
+ else:
1044
+ self.config.problem_type = "multi_label_classification"
1045
+
1046
+ if self.config.problem_type == "regression":
1047
+ loss_fct = MSELoss()
1048
+ if self.num_labels == 1:
1049
+ loss = loss_fct(logits.squeeze(), labels.squeeze())
1050
+ else:
1051
+ loss = loss_fct(logits, labels)
1052
+ elif self.config.problem_type == "single_label_classification":
1053
+ loss_fct = CrossEntropyLoss()
1054
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
1055
+ elif self.config.problem_type == "multi_label_classification":
1056
+ loss_fct = BCEWithLogitsLoss()
1057
+ loss = loss_fct(logits, labels)
1058
+ if not return_dict:
1059
+ output = (logits,) + outputs[1:]
1060
+ return ((loss,) + output) if loss is not None else output
1061
+
1062
+ return SequenceClassifierOutput(
1063
+ loss=loss,
1064
+ logits=logits,
1065
+ hidden_states=outputs.hidden_states,
1066
+ attentions=outputs.attentions,
1067
+ )
1068
+
1069
+
1070
+ @auto_docstring
1071
+ class MraForMultipleChoice(MraPreTrainedModel):
1072
+ def __init__(self, config):
1073
+ super().__init__(config)
1074
+
1075
+ self.mra = MraModel(config)
1076
+ self.pre_classifier = nn.Linear(config.hidden_size, config.hidden_size)
1077
+ self.classifier = nn.Linear(config.hidden_size, 1)
1078
+
1079
+ # Initialize weights and apply final processing
1080
+ self.post_init()
1081
+
1082
+ @auto_docstring
1083
+ def forward(
1084
+ self,
1085
+ input_ids: torch.Tensor | None = None,
1086
+ attention_mask: torch.Tensor | None = None,
1087
+ token_type_ids: torch.Tensor | None = None,
1088
+ position_ids: torch.Tensor | None = None,
1089
+ inputs_embeds: torch.Tensor | None = None,
1090
+ labels: torch.Tensor | None = None,
1091
+ output_hidden_states: bool | None = None,
1092
+ return_dict: bool | None = None,
1093
+ **kwargs,
1094
+ ) -> tuple | MultipleChoiceModelOutput:
1095
+ r"""
1096
+ input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
1097
+ Indices of input sequence tokens in the vocabulary.
1098
+
1099
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
1100
+ [`PreTrainedTokenizer.__call__`] for details.
1101
+
1102
+ [What are input IDs?](../glossary#input-ids)
1103
+ token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
1104
+ Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,
1105
+ 1]`:
1106
+
1107
+ - 0 corresponds to a *sentence A* token,
1108
+ - 1 corresponds to a *sentence B* token.
1109
+
1110
+ [What are token type IDs?](../glossary#token-type-ids)
1111
+ position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
1112
+ Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
1113
+ config.max_position_embeddings - 1]`.
1114
+
1115
+ [What are position IDs?](../glossary#position-ids)
1116
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
1117
+ Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
1118
+ is useful if you want more control over how to convert *input_ids* indices into associated vectors than the
1119
+ model's internal embedding lookup matrix.
1120
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
1121
+ Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
1122
+ num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
1123
+ `input_ids` above)
1124
+ """
1125
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1126
+ num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1]
1127
+
1128
+ input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None
1129
+ attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
1130
+ token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
1131
+ position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
1132
+ inputs_embeds = (
1133
+ inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1))
1134
+ if inputs_embeds is not None
1135
+ else None
1136
+ )
1137
+
1138
+ outputs = self.mra(
1139
+ input_ids,
1140
+ attention_mask=attention_mask,
1141
+ token_type_ids=token_type_ids,
1142
+ position_ids=position_ids,
1143
+ inputs_embeds=inputs_embeds,
1144
+ output_hidden_states=output_hidden_states,
1145
+ return_dict=return_dict,
1146
+ )
1147
+
1148
+ hidden_state = outputs[0] # (bs * num_choices, seq_len, dim)
1149
+ pooled_output = hidden_state[:, 0] # (bs * num_choices, dim)
1150
+ pooled_output = self.pre_classifier(pooled_output) # (bs * num_choices, dim)
1151
+ pooled_output = nn.ReLU()(pooled_output) # (bs * num_choices, dim)
1152
+ logits = self.classifier(pooled_output)
1153
+
1154
+ reshaped_logits = logits.view(-1, num_choices)
1155
+
1156
+ loss = None
1157
+ if labels is not None:
1158
+ loss_fct = CrossEntropyLoss()
1159
+ loss = loss_fct(reshaped_logits, labels)
1160
+
1161
+ if not return_dict:
1162
+ output = (reshaped_logits,) + outputs[1:]
1163
+ return ((loss,) + output) if loss is not None else output
1164
+
1165
+ return MultipleChoiceModelOutput(
1166
+ loss=loss,
1167
+ logits=reshaped_logits,
1168
+ hidden_states=outputs.hidden_states,
1169
+ attentions=outputs.attentions,
1170
+ )
1171
+
1172
+
1173
+ @auto_docstring
1174
+ class MraForTokenClassification(MraPreTrainedModel):
1175
+ def __init__(self, config):
1176
+ super().__init__(config)
1177
+ self.num_labels = config.num_labels
1178
+
1179
+ self.mra = MraModel(config)
1180
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
1181
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
1182
+
1183
+ # Initialize weights and apply final processing
1184
+ self.post_init()
1185
+
1186
+ @auto_docstring
1187
+ def forward(
1188
+ self,
1189
+ input_ids: torch.Tensor | None = None,
1190
+ attention_mask: torch.Tensor | None = None,
1191
+ token_type_ids: torch.Tensor | None = None,
1192
+ position_ids: torch.Tensor | None = None,
1193
+ inputs_embeds: torch.Tensor | None = None,
1194
+ labels: torch.Tensor | None = None,
1195
+ output_hidden_states: bool | None = None,
1196
+ return_dict: bool | None = None,
1197
+ **kwargs,
1198
+ ) -> tuple | TokenClassifierOutput:
1199
+ r"""
1200
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1201
+ Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
1202
+ """
1203
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1204
+
1205
+ outputs = self.mra(
1206
+ input_ids,
1207
+ attention_mask=attention_mask,
1208
+ token_type_ids=token_type_ids,
1209
+ position_ids=position_ids,
1210
+ inputs_embeds=inputs_embeds,
1211
+ output_hidden_states=output_hidden_states,
1212
+ return_dict=return_dict,
1213
+ )
1214
+
1215
+ sequence_output = outputs[0]
1216
+
1217
+ sequence_output = self.dropout(sequence_output)
1218
+ logits = self.classifier(sequence_output)
1219
+
1220
+ loss = None
1221
+ if labels is not None:
1222
+ loss_fct = CrossEntropyLoss()
1223
+ # Only keep active parts of the loss
1224
+ if attention_mask is not None:
1225
+ active_loss = attention_mask.view(-1) == 1
1226
+ active_logits = logits.view(-1, self.num_labels)
1227
+ active_labels = torch.where(
1228
+ active_loss, labels.view(-1), torch.tensor(loss_fct.ignore_index).type_as(labels)
1229
+ )
1230
+ loss = loss_fct(active_logits, active_labels)
1231
+ else:
1232
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
1233
+
1234
+ if not return_dict:
1235
+ output = (logits,) + outputs[1:]
1236
+ return ((loss,) + output) if loss is not None else output
1237
+
1238
+ return TokenClassifierOutput(
1239
+ loss=loss,
1240
+ logits=logits,
1241
+ hidden_states=outputs.hidden_states,
1242
+ attentions=outputs.attentions,
1243
+ )
1244
+
1245
+
1246
+ @auto_docstring
1247
+ class MraForQuestionAnswering(MraPreTrainedModel):
1248
+ def __init__(self, config):
1249
+ super().__init__(config)
1250
+
1251
+ config.num_labels = 2
1252
+ self.num_labels = config.num_labels
1253
+
1254
+ self.mra = MraModel(config)
1255
+ self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
1256
+
1257
+ # Initialize weights and apply final processing
1258
+ self.post_init()
1259
+
1260
+ @auto_docstring
1261
+ def forward(
1262
+ self,
1263
+ input_ids: torch.Tensor | None = None,
1264
+ attention_mask: torch.Tensor | None = None,
1265
+ token_type_ids: torch.Tensor | None = None,
1266
+ position_ids: torch.Tensor | None = None,
1267
+ inputs_embeds: torch.Tensor | None = None,
1268
+ start_positions: torch.Tensor | None = None,
1269
+ end_positions: torch.Tensor | None = None,
1270
+ output_hidden_states: bool | None = None,
1271
+ return_dict: bool | None = None,
1272
+ **kwargs,
1273
+ ) -> tuple | QuestionAnsweringModelOutput:
1274
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1275
+
1276
+ outputs = self.mra(
1277
+ input_ids,
1278
+ attention_mask=attention_mask,
1279
+ token_type_ids=token_type_ids,
1280
+ position_ids=position_ids,
1281
+ inputs_embeds=inputs_embeds,
1282
+ output_hidden_states=output_hidden_states,
1283
+ return_dict=return_dict,
1284
+ )
1285
+
1286
+ sequence_output = outputs[0]
1287
+
1288
+ logits = self.qa_outputs(sequence_output)
1289
+ start_logits, end_logits = logits.split(1, dim=-1)
1290
+ start_logits = start_logits.squeeze(-1)
1291
+ end_logits = end_logits.squeeze(-1)
1292
+
1293
+ total_loss = None
1294
+ if start_positions is not None and end_positions is not None:
1295
+ # If we are on multi-GPU, split add a dimension
1296
+ if len(start_positions.size()) > 1:
1297
+ start_positions = start_positions.squeeze(-1)
1298
+ if len(end_positions.size()) > 1:
1299
+ end_positions = end_positions.squeeze(-1)
1300
+ # sometimes the start/end positions are outside our model inputs, we ignore these terms
1301
+ ignored_index = start_logits.size(1)
1302
+ start_positions = start_positions.clamp(0, ignored_index)
1303
+ end_positions = end_positions.clamp(0, ignored_index)
1304
+
1305
+ loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
1306
+ start_loss = loss_fct(start_logits, start_positions)
1307
+ end_loss = loss_fct(end_logits, end_positions)
1308
+ total_loss = (start_loss + end_loss) / 2
1309
+
1310
+ if not return_dict:
1311
+ output = (start_logits, end_logits) + outputs[1:]
1312
+ return ((total_loss,) + output) if total_loss is not None else output
1313
+
1314
+ return QuestionAnsweringModelOutput(
1315
+ loss=total_loss,
1316
+ start_logits=start_logits,
1317
+ end_logits=end_logits,
1318
+ hidden_states=outputs.hidden_states,
1319
+ attentions=outputs.attentions,
1320
+ )
1321
+
1322
+
1323
+ __all__ = [
1324
+ "MraForMaskedLM",
1325
+ "MraForMultipleChoice",
1326
+ "MraForQuestionAnswering",
1327
+ "MraForSequenceClassification",
1328
+ "MraForTokenClassification",
1329
+ "MraLayer",
1330
+ "MraModel",
1331
+ "MraPreTrainedModel",
1332
+ ]
third_party/transformers/src/transformers/models/nemotron_h/__init__.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from .configuration_nemotron_h import *
22
+ from .modeling_nemotron_h import *
23
+ else:
24
+ import sys
25
+
26
+ _file = globals()["__file__"]
27
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)