Orangerl commited on
Commit
e6d950a
·
verified ·
1 Parent(s): ba0e049

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/apertus/__init__.py +31 -0
  2. third_party/transformers/src/transformers/models/apertus/configuration_apertus.py +99 -0
  3. third_party/transformers/src/transformers/models/apertus/modeling_apertus.py +505 -0
  4. third_party/transformers/src/transformers/models/apertus/modular_apertus.py +268 -0
  5. third_party/transformers/src/transformers/models/arcee/__init__.py +27 -0
  6. third_party/transformers/src/transformers/models/arcee/configuration_arcee.py +100 -0
  7. third_party/transformers/src/transformers/models/arcee/modeling_arcee.py +520 -0
  8. third_party/transformers/src/transformers/models/arcee/modular_arcee.py +117 -0
  9. third_party/transformers/src/transformers/models/aya_vision/__init__.py +28 -0
  10. third_party/transformers/src/transformers/models/aya_vision/configuration_aya_vision.py +80 -0
  11. third_party/transformers/src/transformers/models/aya_vision/modeling_aya_vision.py +446 -0
  12. third_party/transformers/src/transformers/models/aya_vision/modular_aya_vision.py +262 -0
  13. third_party/transformers/src/transformers/models/aya_vision/processing_aya_vision.py +208 -0
  14. third_party/transformers/src/transformers/models/blt/__init__.py +28 -0
  15. third_party/transformers/src/transformers/models/blt/configuration_blt.py +286 -0
  16. third_party/transformers/src/transformers/models/blt/convert_blt_weights_to_hf.py +487 -0
  17. third_party/transformers/src/transformers/models/blt/modeling_blt.py +1463 -0
  18. third_party/transformers/src/transformers/models/blt/modular_blt.py +1195 -0
  19. third_party/transformers/src/transformers/models/byt5/__init__.py +26 -0
  20. third_party/transformers/src/transformers/models/byt5/convert_byt5_original_tf_checkpoint_to_pytorch.py +167 -0
  21. third_party/transformers/src/transformers/models/byt5/tokenization_byt5.py +234 -0
  22. third_party/transformers/src/transformers/models/clip/__init__.py +31 -0
  23. third_party/transformers/src/transformers/models/clip/configuration_clip.py +248 -0
  24. third_party/transformers/src/transformers/models/clip/convert_clip_original_pytorch_to_hf.py +155 -0
  25. third_party/transformers/src/transformers/models/clip/image_processing_clip.py +45 -0
  26. third_party/transformers/src/transformers/models/clip/image_processing_pil_clip.py +45 -0
  27. third_party/transformers/src/transformers/models/clip/modeling_clip.py +1148 -0
  28. third_party/transformers/src/transformers/models/clip/processing_clip.py +28 -0
  29. third_party/transformers/src/transformers/models/clip/tokenization_clip.py +142 -0
  30. third_party/transformers/src/transformers/models/deberta_v2/__init__.py +28 -0
  31. third_party/transformers/src/transformers/models/deberta_v2/configuration_deberta_v2.py +94 -0
  32. third_party/transformers/src/transformers/models/deberta_v2/modeling_deberta_v2.py +1361 -0
  33. third_party/transformers/src/transformers/models/deberta_v2/tokenization_deberta_v2.py +169 -0
  34. third_party/transformers/src/transformers/models/depth_anything/__init__.py +27 -0
  35. third_party/transformers/src/transformers/models/depth_anything/configuration_depth_anything.py +99 -0
  36. third_party/transformers/src/transformers/models/depth_anything/convert_depth_anything_to_hf.py +370 -0
  37. third_party/transformers/src/transformers/models/depth_anything/convert_distill_any_depth_to_hf.py +249 -0
  38. third_party/transformers/src/transformers/models/depth_anything/modeling_depth_anything.py +416 -0
  39. third_party/transformers/src/transformers/models/dpr/__init__.py +29 -0
  40. third_party/transformers/src/transformers/models/dpr/configuration_dpr.py +63 -0
  41. third_party/transformers/src/transformers/models/dpr/convert_dpr_original_checkpoint_to_pytorch.py +145 -0
  42. third_party/transformers/src/transformers/models/dpr/modeling_dpr.py +576 -0
  43. third_party/transformers/src/transformers/models/dpr/tokenization_dpr.py +330 -0
  44. third_party/transformers/src/transformers/models/dpr/tokenization_dpr_fast.py +318 -0
  45. third_party/transformers/src/transformers/models/dpt/__init__.py +29 -0
  46. third_party/transformers/src/transformers/models/dpt/configuration_dpt.py +158 -0
  47. third_party/transformers/src/transformers/models/dpt/convert_dinov2_depth_to_hf.py +384 -0
  48. third_party/transformers/src/transformers/models/dpt/convert_dpt_beit_to_hf.py +306 -0
  49. third_party/transformers/src/transformers/models/dpt/convert_dpt_hybrid_to_pytorch.py +316 -0
  50. third_party/transformers/src/transformers/models/dpt/convert_dpt_swinv2_to_hf.py +322 -0
third_party/transformers/src/transformers/models/apertus/__init__.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Inc. team and the Swiss AI Initiative. All rights reserved.
2
+ #
3
+ # This code is based on HuggingFace's LLaMA implementation in this library.
4
+ # It has been modified from its original forms to accommodate the architectural
5
+ # differences made by the Swiss AI Initiative that trained the model.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ from typing import TYPE_CHECKING
19
+
20
+ from ...utils import _LazyModule
21
+ from ...utils.import_utils import define_import_structure
22
+
23
+
24
+ if TYPE_CHECKING:
25
+ from .configuration_apertus import *
26
+ from .modeling_apertus import *
27
+ else:
28
+ import sys
29
+
30
+ _file = globals()["__file__"]
31
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/apertus/configuration_apertus.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/apertus/modular_apertus.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_apertus.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 the HuggingFace Inc. team and the Swiss AI Initiative. 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 huggingface_hub.dataclasses import strict
22
+
23
+ from ...configuration_utils import PreTrainedConfig
24
+ from ...modeling_rope_utils import RopeParameters
25
+ from ...utils import auto_docstring
26
+
27
+
28
+ @auto_docstring(checkpoint="swiss-ai/Apertus-8B-Instruct-2509")
29
+ @strict
30
+ class ApertusConfig(PreTrainedConfig):
31
+ r"""
32
+ ```python
33
+ >>> from transformers import ApertusModel, ApertusConfig
34
+
35
+ >>> # Initializing a Apertus-8B style configuration
36
+ >>> configuration = ApertusConfig()
37
+
38
+ >>> # Initializing a model from the Apertus-8B style configuration
39
+ >>> model = ApertusModel(configuration)
40
+
41
+ >>> # Accessing the model configuration
42
+ >>> configuration = model.config
43
+ ```"""
44
+
45
+ model_type = "apertus"
46
+ keys_to_ignore_at_inference = ["past_key_values"]
47
+ default_theta = 12000000.0
48
+ base_model_tp_plan = {
49
+ "layers.*.self_attn.q_proj": "colwise",
50
+ "layers.*.self_attn.k_proj": "colwise",
51
+ "layers.*.self_attn.v_proj": "colwise",
52
+ "layers.*.self_attn.q_norm": "replicated_with_grad_allreduce",
53
+ "layers.*.self_attn.k_norm": "replicated_with_grad_allreduce",
54
+ "layers.*.self_attn.o_proj": "rowwise",
55
+ "layers.*.mlp.up_proj": "colwise",
56
+ "layers.*.mlp.down_proj": "rowwise",
57
+ }
58
+ base_model_pp_plan = {
59
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
60
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
61
+ "norm": (["hidden_states"], ["hidden_states"]),
62
+ }
63
+
64
+ vocab_size: int = 131072
65
+ hidden_size: int = 4096
66
+ intermediate_size: int = 14336
67
+ num_hidden_layers: int = 32
68
+ num_attention_heads: int = 32
69
+ num_key_value_heads: int | None = None
70
+ hidden_act: str = "xielu"
71
+ max_position_embeddings: int = 65536
72
+ initializer_range: float = 0.02
73
+ rms_norm_eps: float = 1e-5
74
+ use_cache: bool = True
75
+ pad_token_id: int | None = 3
76
+ bos_token_id: int | None = 1
77
+ eos_token_id: int | list[int] | None = 2
78
+ tie_word_embeddings: bool = False
79
+ rope_parameters: RopeParameters | dict | None = None
80
+ attention_bias: bool = False
81
+ attention_dropout: float | int = 0.0
82
+
83
+ def __post_init__(self, **kwargs):
84
+ if self.num_key_value_heads is None:
85
+ self.num_key_value_heads = self.num_attention_heads
86
+
87
+ if self.rope_parameters is None:
88
+ self.rope_parameters = {
89
+ "rope_type": "llama3",
90
+ "rope_theta": 12000000.0,
91
+ "factor": 8.0,
92
+ "original_max_position_embeddings": 8192,
93
+ "low_freq_factor": 1.0,
94
+ "high_freq_factor": 4.0,
95
+ }
96
+ super().__post_init__(**kwargs)
97
+
98
+
99
+ __all__ = ["ApertusConfig"]
third_party/transformers/src/transformers/models/apertus/modeling_apertus.py ADDED
@@ -0,0 +1,505 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/apertus/modular_apertus.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_apertus.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 the HuggingFace Inc. team and the Swiss AI Initiative. 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
+ from torch import nn
26
+
27
+ from ...activations import ACT2CLS, ACT2FN
28
+ from ...cache_utils import Cache, DynamicCache
29
+ from ...generation import GenerationMixin
30
+ from ...integrations import use_kernel_forward_from_hub, use_kernel_func_from_hub, use_kernelized_func
31
+ from ...masking_utils import create_causal_mask
32
+ from ...modeling_layers import GenericForTokenClassification, 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_apertus import ApertusConfig
41
+
42
+
43
+ class ApertusMLP(nn.Module):
44
+ def __init__(self, config):
45
+ super().__init__()
46
+ self.config = config
47
+ self.hidden_size = config.hidden_size
48
+ self.intermediate_size = config.intermediate_size
49
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
50
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
51
+ self.act_fn = ACT2FN[config.hidden_act]
52
+ if config.hidden_act == "xielu":
53
+ self.act_fn = ACT2CLS["xielu"](dtype=config.dtype)
54
+
55
+ def forward(self, x):
56
+ return self.down_proj(self.act_fn(self.up_proj(x)))
57
+
58
+
59
+ @use_kernel_forward_from_hub("RMSNorm")
60
+ class ApertusRMSNorm(nn.Module):
61
+ def __init__(self, hidden_size, eps: float = 1e-6) -> None:
62
+ """
63
+ ApertusRMSNorm is equivalent to T5LayerNorm
64
+ """
65
+ super().__init__()
66
+ self.weight = nn.Parameter(torch.ones(hidden_size))
67
+ self.variance_epsilon = eps
68
+
69
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
70
+ input_dtype = hidden_states.dtype
71
+ hidden_states = hidden_states.to(torch.float32)
72
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
73
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
74
+ return self.weight * hidden_states.to(input_dtype)
75
+
76
+ def extra_repr(self):
77
+ return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
78
+
79
+
80
+ class ApertusRotaryEmbedding(nn.Module):
81
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
82
+
83
+ def __init__(self, config: ApertusConfig, device=None):
84
+ super().__init__()
85
+ self.max_seq_len_cached = config.max_position_embeddings
86
+ self.original_max_seq_len = config.max_position_embeddings
87
+
88
+ self.config = config
89
+
90
+ self.rope_type = self.config.rope_parameters["rope_type"]
91
+ rope_init_fn: Callable = self.compute_default_rope_parameters
92
+ if self.rope_type != "default":
93
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
94
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
95
+
96
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
97
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
98
+
99
+ @staticmethod
100
+ def compute_default_rope_parameters(
101
+ config: ApertusConfig | None = None,
102
+ device: Optional["torch.device"] = None,
103
+ seq_len: int | None = None,
104
+ ) -> tuple["torch.Tensor", float]:
105
+ """
106
+ Computes the inverse frequencies according to the original RoPE implementation
107
+ Args:
108
+ config ([`~transformers.PreTrainedConfig`]):
109
+ The model configuration.
110
+ device (`torch.device`):
111
+ The device to use for initialization of the inverse frequencies.
112
+ seq_len (`int`, *optional*):
113
+ The current sequence length. Unused for this type of RoPE.
114
+ Returns:
115
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
116
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
117
+ """
118
+ base = config.rope_parameters["rope_theta"]
119
+ dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
120
+
121
+ attention_factor = 1.0 # Unused in this type of RoPE
122
+
123
+ # Compute the inverse frequencies
124
+ inv_freq = 1.0 / (
125
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
126
+ )
127
+ return inv_freq, attention_factor
128
+
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).to(x.device)
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.cat((freqs, freqs), dim=-1)
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
+ def rotate_half(x):
146
+ """Rotates half the hidden dims of the input."""
147
+ x1 = x[..., : x.shape[-1] // 2]
148
+ x2 = x[..., x.shape[-1] // 2 :]
149
+ return torch.cat((-x2, x1), dim=-1)
150
+
151
+
152
+ @use_kernel_func_from_hub("rotary_pos_emb")
153
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
154
+ """Applies Rotary Position Embedding to the query and key tensors.
155
+
156
+ Args:
157
+ q (`torch.Tensor`): The query tensor.
158
+ k (`torch.Tensor`): The key tensor.
159
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
160
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
161
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
162
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
163
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
164
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
165
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
166
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
167
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
168
+ Returns:
169
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
170
+ """
171
+ cos = cos.unsqueeze(unsqueeze_dim)
172
+ sin = sin.unsqueeze(unsqueeze_dim)
173
+ q_embed = (q * cos) + (rotate_half(q) * sin)
174
+ k_embed = (k * cos) + (rotate_half(k) * sin)
175
+ return q_embed, k_embed
176
+
177
+
178
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
179
+ """
180
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
181
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
182
+ """
183
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
184
+ if n_rep == 1:
185
+ return hidden_states
186
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
187
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
188
+
189
+
190
+ def eager_attention_forward(
191
+ module: nn.Module,
192
+ query: torch.Tensor,
193
+ key: torch.Tensor,
194
+ value: torch.Tensor,
195
+ attention_mask: torch.Tensor | None,
196
+ scaling: float,
197
+ dropout: float = 0.0,
198
+ **kwargs: Unpack[TransformersKwargs],
199
+ ):
200
+ key_states = repeat_kv(key, module.num_key_value_groups)
201
+ value_states = repeat_kv(value, module.num_key_value_groups)
202
+
203
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
204
+ if attention_mask is not None:
205
+ attn_weights = attn_weights + attention_mask
206
+
207
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
208
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
209
+ attn_output = torch.matmul(attn_weights, value_states)
210
+ attn_output = attn_output.transpose(1, 2).contiguous()
211
+
212
+ return attn_output, attn_weights
213
+
214
+
215
+ @use_kernelized_func(apply_rotary_pos_emb)
216
+ class ApertusAttention(nn.Module):
217
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
218
+
219
+ def __init__(self, config: ApertusConfig, layer_idx: int | None = None):
220
+ super().__init__()
221
+ self.config = config
222
+ self.layer_idx = layer_idx
223
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
224
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
225
+ self.scaling = self.head_dim**-0.5
226
+ self.attention_dropout = config.attention_dropout
227
+ self.is_causal = True
228
+
229
+ self.q_proj = nn.Linear(
230
+ config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
231
+ )
232
+ self.k_proj = nn.Linear(
233
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
234
+ )
235
+ self.v_proj = nn.Linear(
236
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
237
+ )
238
+ self.o_proj = nn.Linear(
239
+ config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
240
+ )
241
+ self.q_norm = ApertusRMSNorm(self.head_dim, config.rms_norm_eps)
242
+ self.k_norm = ApertusRMSNorm(self.head_dim, config.rms_norm_eps)
243
+
244
+ def forward(
245
+ self,
246
+ hidden_states: torch.Tensor,
247
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
248
+ attention_mask: torch.Tensor | None,
249
+ past_key_values: Cache | None = None,
250
+ **kwargs: Unpack[TransformersKwargs],
251
+ ) -> tuple[torch.Tensor, torch.Tensor]:
252
+ input_shape = hidden_states.shape[:-1]
253
+ hidden_shape = (*input_shape, -1, self.head_dim)
254
+
255
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
256
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
257
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
258
+ query_states = self.q_norm(query_states)
259
+ key_states = self.k_norm(key_states)
260
+
261
+ cos, sin = position_embeddings
262
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
263
+
264
+ if past_key_values is not None:
265
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
266
+
267
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
268
+ self.config._attn_implementation, eager_attention_forward
269
+ )
270
+
271
+ attn_output, attn_weights = attention_interface(
272
+ self,
273
+ query_states,
274
+ key_states,
275
+ value_states,
276
+ attention_mask,
277
+ dropout=0.0 if not self.training else self.attention_dropout,
278
+ scaling=self.scaling,
279
+ **kwargs,
280
+ )
281
+
282
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
283
+ attn_output = self.o_proj(attn_output)
284
+ return attn_output, attn_weights
285
+
286
+
287
+ class ApertusDecoderLayer(GradientCheckpointingLayer):
288
+ def __init__(self, config: ApertusConfig, layer_idx: int):
289
+ super().__init__()
290
+ self.hidden_size = config.hidden_size
291
+
292
+ self.self_attn = ApertusAttention(config=config, layer_idx=layer_idx)
293
+
294
+ self.mlp = ApertusMLP(config)
295
+ self.attention_layernorm = ApertusRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
296
+ self.feedforward_layernorm = ApertusRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
297
+
298
+ def forward(
299
+ self,
300
+ hidden_states: torch.Tensor,
301
+ attention_mask: torch.Tensor | None = None,
302
+ position_ids: torch.LongTensor | None = None,
303
+ past_key_values: Cache | None = None,
304
+ use_cache: bool | None = False,
305
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
306
+ **kwargs: Unpack[TransformersKwargs],
307
+ ) -> torch.Tensor:
308
+ residual = hidden_states
309
+ hidden_states = self.attention_layernorm(hidden_states)
310
+ hidden_states, _ = self.self_attn(
311
+ hidden_states=hidden_states,
312
+ attention_mask=attention_mask,
313
+ position_ids=position_ids,
314
+ past_key_values=past_key_values,
315
+ use_cache=use_cache,
316
+ position_embeddings=position_embeddings,
317
+ **kwargs,
318
+ )
319
+ hidden_states = residual + hidden_states
320
+
321
+ # Fully Connected
322
+ residual = hidden_states
323
+ hidden_states = self.feedforward_layernorm(hidden_states)
324
+ hidden_states = self.mlp(hidden_states)
325
+ hidden_states = residual + hidden_states
326
+ return hidden_states
327
+
328
+
329
+ @auto_docstring
330
+ class ApertusPreTrainedModel(PreTrainedModel):
331
+ config: ApertusConfig
332
+ base_model_prefix = "model"
333
+ supports_gradient_checkpointing = True
334
+ _no_split_modules = ["ApertusDecoderLayer"]
335
+ _skip_keys_device_placement = ["past_key_values"]
336
+ _supports_flash_attn = True
337
+ _supports_sdpa = True
338
+ _supports_flex_attn = True
339
+
340
+ _can_compile_fullgraph = True
341
+ _supports_attention_backend = True
342
+ _can_record_outputs = {
343
+ "hidden_states": ApertusDecoderLayer,
344
+ "attentions": ApertusAttention,
345
+ }
346
+
347
+
348
+ @auto_docstring
349
+ class ApertusModel(ApertusPreTrainedModel):
350
+ def __init__(self, config: ApertusConfig):
351
+ super().__init__(config)
352
+ self.padding_idx = config.pad_token_id
353
+ self.vocab_size = config.vocab_size
354
+
355
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
356
+ self.layers = nn.ModuleList(
357
+ [ApertusDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
358
+ )
359
+ self.norm = ApertusRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
360
+ self.rotary_emb = ApertusRotaryEmbedding(config=config)
361
+ self.gradient_checkpointing = False
362
+
363
+ # Initialize weights and apply final processing
364
+ self.post_init()
365
+
366
+ @merge_with_config_defaults
367
+ @capture_outputs
368
+ @auto_docstring
369
+ def forward(
370
+ self,
371
+ input_ids: torch.LongTensor | None = None,
372
+ attention_mask: torch.Tensor | None = None,
373
+ position_ids: torch.LongTensor | None = None,
374
+ past_key_values: Cache | None = None,
375
+ inputs_embeds: torch.FloatTensor | None = None,
376
+ use_cache: bool | None = None,
377
+ **kwargs: Unpack[TransformersKwargs],
378
+ ) -> BaseModelOutputWithPast:
379
+ if (input_ids is None) ^ (inputs_embeds is not None):
380
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
381
+
382
+ if inputs_embeds is None:
383
+ inputs_embeds: torch.Tensor = self.embed_tokens(input_ids)
384
+
385
+ if use_cache and past_key_values is None:
386
+ past_key_values = DynamicCache(config=self.config)
387
+
388
+ if position_ids is None:
389
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
390
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
391
+ position_ids = position_ids.unsqueeze(0)
392
+
393
+ causal_mask = create_causal_mask(
394
+ config=self.config,
395
+ inputs_embeds=inputs_embeds,
396
+ attention_mask=attention_mask,
397
+ past_key_values=past_key_values,
398
+ position_ids=position_ids,
399
+ )
400
+
401
+ hidden_states = inputs_embeds
402
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
403
+
404
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
405
+ hidden_states = decoder_layer(
406
+ hidden_states,
407
+ attention_mask=causal_mask,
408
+ position_embeddings=position_embeddings,
409
+ position_ids=position_ids,
410
+ past_key_values=past_key_values,
411
+ use_cache=use_cache,
412
+ **kwargs,
413
+ )
414
+
415
+ hidden_states = self.norm(hidden_states)
416
+ return BaseModelOutputWithPast(
417
+ last_hidden_state=hidden_states,
418
+ past_key_values=past_key_values,
419
+ )
420
+
421
+
422
+ @auto_docstring
423
+ class ApertusForCausalLM(ApertusPreTrainedModel, GenerationMixin):
424
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
425
+ _tp_plan = {"lm_head": "colwise_gather_output"}
426
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
427
+
428
+ def __init__(self, config):
429
+ super().__init__(config)
430
+ self.model = ApertusModel(config)
431
+ self.vocab_size = config.vocab_size
432
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
433
+
434
+ # Initialize weights and apply final processing
435
+ self.post_init()
436
+
437
+ @can_return_tuple
438
+ @auto_docstring
439
+ def forward(
440
+ self,
441
+ input_ids: torch.LongTensor | None = None,
442
+ attention_mask: torch.Tensor | None = None,
443
+ position_ids: torch.LongTensor | None = None,
444
+ past_key_values: Cache | None = None,
445
+ inputs_embeds: torch.FloatTensor | None = None,
446
+ labels: torch.LongTensor | None = None,
447
+ use_cache: bool | None = None,
448
+ logits_to_keep: int | torch.Tensor = 0,
449
+ **kwargs: Unpack[TransformersKwargs],
450
+ ) -> CausalLMOutputWithPast:
451
+ r"""
452
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
453
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
454
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
455
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
456
+
457
+ Example:
458
+
459
+ ```python
460
+ >>> from transformers import AutoTokenizer, ApertusForCausalLM
461
+
462
+ >>> model = ApertusForCausalLM.from_pretrained("swiss-ai/Apertus-8B-Instruct-2509")
463
+ >>> tokenizer = AutoTokenizer.from_pretrained("swiss-ai/Apertus-8B-Instruct-2509")
464
+
465
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
466
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
467
+
468
+ >>> # Generate
469
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
470
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
471
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
472
+ ```"""
473
+ outputs: BaseModelOutputWithPast = self.model(
474
+ input_ids=input_ids,
475
+ attention_mask=attention_mask,
476
+ position_ids=position_ids,
477
+ past_key_values=past_key_values,
478
+ inputs_embeds=inputs_embeds,
479
+ use_cache=use_cache,
480
+ **kwargs,
481
+ )
482
+
483
+ hidden_states = outputs.last_hidden_state
484
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
485
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
486
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
487
+
488
+ loss = None
489
+ if labels is not None:
490
+ loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
491
+
492
+ return CausalLMOutputWithPast(
493
+ loss=loss,
494
+ logits=logits,
495
+ past_key_values=outputs.past_key_values,
496
+ hidden_states=outputs.hidden_states,
497
+ attentions=outputs.attentions,
498
+ )
499
+
500
+
501
+ class ApertusForTokenClassification(GenericForTokenClassification, ApertusPreTrainedModel):
502
+ pass
503
+
504
+
505
+ __all__ = ["ApertusModel", "ApertusForCausalLM", "ApertusForTokenClassification", "ApertusPreTrainedModel"]
third_party/transformers/src/transformers/models/apertus/modular_apertus.py ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the HuggingFace Inc. team and the Swiss AI Initiative. 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
+ from huggingface_hub.dataclasses import strict
19
+ from torch import nn
20
+
21
+ from ...activations import ACT2CLS
22
+ from ...cache_utils import Cache
23
+ from ...configuration_utils import PreTrainedConfig
24
+ from ...modeling_rope_utils import RopeParameters
25
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS
26
+ from ...processing_utils import Unpack
27
+ from ...utils import TransformersKwargs, auto_docstring, logging
28
+ from ..llama.modeling_llama import (
29
+ LlamaAttention,
30
+ LlamaDecoderLayer,
31
+ LlamaForCausalLM,
32
+ LlamaForTokenClassification,
33
+ LlamaModel,
34
+ LlamaPreTrainedModel,
35
+ LlamaRMSNorm,
36
+ LlamaRotaryEmbedding,
37
+ apply_rotary_pos_emb,
38
+ eager_attention_forward,
39
+ )
40
+ from ..nemotron.modeling_nemotron import NemotronMLP
41
+
42
+
43
+ logger = logging.get_logger(__name__)
44
+
45
+
46
+ @auto_docstring(checkpoint="swiss-ai/Apertus-8B-Instruct-2509")
47
+ @strict
48
+ class ApertusConfig(PreTrainedConfig):
49
+ r"""
50
+ ```python
51
+ >>> from transformers import ApertusModel, ApertusConfig
52
+
53
+ >>> # Initializing a Apertus-8B style configuration
54
+ >>> configuration = ApertusConfig()
55
+
56
+ >>> # Initializing a model from the Apertus-8B style configuration
57
+ >>> model = ApertusModel(configuration)
58
+
59
+ >>> # Accessing the model configuration
60
+ >>> configuration = model.config
61
+ ```"""
62
+
63
+ model_type = "apertus"
64
+ keys_to_ignore_at_inference = ["past_key_values"]
65
+ default_theta = 12000000.0
66
+ base_model_tp_plan = {
67
+ "layers.*.self_attn.q_proj": "colwise",
68
+ "layers.*.self_attn.k_proj": "colwise",
69
+ "layers.*.self_attn.v_proj": "colwise",
70
+ "layers.*.self_attn.q_norm": "replicated_with_grad_allreduce",
71
+ "layers.*.self_attn.k_norm": "replicated_with_grad_allreduce",
72
+ "layers.*.self_attn.o_proj": "rowwise",
73
+ "layers.*.mlp.up_proj": "colwise",
74
+ "layers.*.mlp.down_proj": "rowwise",
75
+ }
76
+ base_model_pp_plan = {
77
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
78
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
79
+ "norm": (["hidden_states"], ["hidden_states"]),
80
+ }
81
+
82
+ vocab_size: int = 131072
83
+ hidden_size: int = 4096
84
+ intermediate_size: int = 14336
85
+ num_hidden_layers: int = 32
86
+ num_attention_heads: int = 32
87
+ num_key_value_heads: int | None = None
88
+ hidden_act: str = "xielu"
89
+ max_position_embeddings: int = 65536
90
+ initializer_range: float = 0.02
91
+ rms_norm_eps: float = 1e-5
92
+ use_cache: bool = True
93
+ pad_token_id: int | None = 3
94
+ bos_token_id: int | None = 1
95
+ eos_token_id: int | list[int] | None = 2
96
+ tie_word_embeddings: bool = False
97
+ rope_parameters: RopeParameters | dict | None = None
98
+ attention_bias: bool = False
99
+ attention_dropout: float | int = 0.0
100
+
101
+ def __post_init__(self, **kwargs):
102
+ if self.num_key_value_heads is None:
103
+ self.num_key_value_heads = self.num_attention_heads
104
+
105
+ if self.rope_parameters is None:
106
+ self.rope_parameters = {
107
+ "rope_type": "llama3",
108
+ "rope_theta": 12000000.0,
109
+ "factor": 8.0,
110
+ "original_max_position_embeddings": 8192,
111
+ "low_freq_factor": 1.0,
112
+ "high_freq_factor": 4.0,
113
+ }
114
+ super().__post_init__(**kwargs)
115
+
116
+
117
+ class ApertusMLP(NemotronMLP):
118
+ def __init__(self, config):
119
+ super().__init__(config)
120
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
121
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
122
+ if config.hidden_act == "xielu":
123
+ self.act_fn = ACT2CLS["xielu"](dtype=config.dtype)
124
+
125
+
126
+ class ApertusRMSNorm(LlamaRMSNorm):
127
+ pass
128
+
129
+
130
+ class ApertusRotaryEmbedding(LlamaRotaryEmbedding):
131
+ pass
132
+
133
+
134
+ class ApertusAttention(LlamaAttention):
135
+ def __init__(self, config: ApertusConfig, layer_idx: int | None = None):
136
+ super().__init__(config, layer_idx)
137
+ self.q_norm = ApertusRMSNorm(self.head_dim, config.rms_norm_eps)
138
+ self.k_norm = ApertusRMSNorm(self.head_dim, config.rms_norm_eps)
139
+
140
+ def forward(
141
+ self,
142
+ hidden_states: torch.Tensor,
143
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
144
+ attention_mask: torch.Tensor | None,
145
+ past_key_values: Cache | None = None,
146
+ **kwargs: Unpack[TransformersKwargs],
147
+ ) -> tuple[torch.Tensor, torch.Tensor]:
148
+ input_shape = hidden_states.shape[:-1]
149
+ hidden_shape = (*input_shape, -1, self.head_dim)
150
+
151
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
152
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
153
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
154
+ query_states = self.q_norm(query_states)
155
+ key_states = self.k_norm(key_states)
156
+
157
+ cos, sin = position_embeddings
158
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
159
+
160
+ if past_key_values is not None:
161
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
162
+
163
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
164
+ self.config._attn_implementation, eager_attention_forward
165
+ )
166
+
167
+ attn_output, attn_weights = attention_interface(
168
+ self,
169
+ query_states,
170
+ key_states,
171
+ value_states,
172
+ attention_mask,
173
+ dropout=0.0 if not self.training else self.attention_dropout,
174
+ scaling=self.scaling,
175
+ **kwargs,
176
+ )
177
+
178
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
179
+ attn_output = self.o_proj(attn_output)
180
+ return attn_output, attn_weights
181
+
182
+
183
+ class ApertusDecoderLayer(LlamaDecoderLayer):
184
+ def __init__(self, config: ApertusConfig, layer_idx: int):
185
+ super().__init__(config, layer_idx)
186
+ self.attention_layernorm = ApertusRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
187
+ self.feedforward_layernorm = ApertusRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
188
+
189
+ del self.input_layernorm
190
+ del self.post_attention_layernorm
191
+
192
+ def forward(
193
+ self,
194
+ hidden_states: torch.Tensor,
195
+ attention_mask: torch.Tensor | None = None,
196
+ position_ids: torch.LongTensor | None = None,
197
+ past_key_values: Cache | None = None,
198
+ use_cache: bool | None = False,
199
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
200
+ **kwargs: Unpack[TransformersKwargs],
201
+ ) -> torch.Tensor:
202
+ residual = hidden_states
203
+ hidden_states = self.attention_layernorm(hidden_states)
204
+ hidden_states, _ = self.self_attn(
205
+ hidden_states=hidden_states,
206
+ attention_mask=attention_mask,
207
+ position_ids=position_ids,
208
+ past_key_values=past_key_values,
209
+ use_cache=use_cache,
210
+ position_embeddings=position_embeddings,
211
+ **kwargs,
212
+ )
213
+ hidden_states = residual + hidden_states
214
+
215
+ # Fully Connected
216
+ residual = hidden_states
217
+ hidden_states = self.feedforward_layernorm(hidden_states)
218
+ hidden_states = self.mlp(hidden_states)
219
+ hidden_states = residual + hidden_states
220
+ return hidden_states
221
+
222
+
223
+ class ApertusPreTrainedModel(LlamaPreTrainedModel):
224
+ pass
225
+
226
+
227
+ class ApertusModel(LlamaModel):
228
+ pass
229
+
230
+
231
+ class ApertusForCausalLM(LlamaForCausalLM):
232
+ def forward(self, **super_kwargs):
233
+ r"""
234
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
235
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
236
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
237
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
238
+
239
+ Example:
240
+
241
+ ```python
242
+ >>> from transformers import AutoTokenizer, ApertusForCausalLM
243
+
244
+ >>> model = ApertusForCausalLM.from_pretrained("swiss-ai/Apertus-8B-Instruct-2509")
245
+ >>> tokenizer = AutoTokenizer.from_pretrained("swiss-ai/Apertus-8B-Instruct-2509")
246
+
247
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
248
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
249
+
250
+ >>> # Generate
251
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
252
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
253
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
254
+ ```"""
255
+ return super().forward(**super_kwargs)
256
+
257
+
258
+ class ApertusForTokenClassification(LlamaForTokenClassification):
259
+ pass
260
+
261
+
262
+ __all__ = [
263
+ "ApertusConfig",
264
+ "ApertusModel",
265
+ "ApertusForCausalLM",
266
+ "ApertusForTokenClassification",
267
+ "ApertusPreTrainedModel",
268
+ ]
third_party/transformers/src/transformers/models/arcee/__init__.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Arcee 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_arcee import *
22
+ from .modeling_arcee 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/arcee/configuration_arcee.py ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/arcee/modular_arcee.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_arcee.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 Arcee AI 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
+ from huggingface_hub.dataclasses import strict
22
+
23
+ from transformers.utils import auto_docstring
24
+
25
+ from ...configuration_utils import PreTrainedConfig
26
+ from ...modeling_rope_utils import RopeParameters
27
+
28
+
29
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
30
+ @strict
31
+ class ArceeConfig(PreTrainedConfig):
32
+ r"""
33
+ ```python
34
+ >>> from transformers import ArceeModel, ArceeConfig
35
+
36
+ >>> # Initializing an Arcee AFM-4.5B-Base style configuration
37
+ >>> configuration = ArceeConfig()
38
+
39
+ >>> # Initializing a model from the AFM-4.5B-Base style configuration
40
+ >>> model = ArceeModel(configuration)
41
+
42
+ >>> # Accessing the model configuration
43
+ >>> configuration = model.config
44
+ ```"""
45
+
46
+ model_type = "arcee"
47
+ keys_to_ignore_at_inference = ["past_key_values"]
48
+ base_model_tp_plan = {
49
+ "layers.*.self_attn.q_proj": "colwise",
50
+ "layers.*.self_attn.k_proj": "colwise",
51
+ "layers.*.self_attn.v_proj": "colwise",
52
+ "layers.*.self_attn.o_proj": "rowwise",
53
+ "layers.*.mlp.up_proj": "colwise",
54
+ "layers.*.mlp.down_proj": "rowwise",
55
+ }
56
+ base_model_pp_plan = {
57
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
58
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
59
+ "norm": (["hidden_states"], ["hidden_states"]),
60
+ }
61
+
62
+ vocab_size: int = 32000
63
+ hidden_size: int = 2560
64
+ intermediate_size: int = 18432
65
+ num_hidden_layers: int = 32
66
+ num_attention_heads: int = 32
67
+ num_key_value_heads: int | None = None
68
+ hidden_act: str = "relu2"
69
+ max_position_embeddings: int = 4096
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 = 128000
75
+ eos_token_id: int | list[int] | None = 128001
76
+ tie_word_embeddings: bool = False
77
+ rope_parameters: RopeParameters | dict | None = None
78
+ attention_bias: bool = False
79
+ attention_dropout: float | int = 0.0
80
+ mlp_bias: bool = False
81
+ head_dim: int | None = None
82
+
83
+ def __post_init__(self, **kwargs):
84
+ if self.head_dim is None:
85
+ self.head_dim = self.hidden_size // self.num_attention_heads
86
+ if self.num_key_value_heads is None:
87
+ self.num_key_value_heads = self.num_attention_heads
88
+
89
+ super().__post_init__(**kwargs)
90
+
91
+ def validate_architecture(self):
92
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
93
+ if self.hidden_size % self.num_attention_heads != 0:
94
+ raise ValueError(
95
+ f"The hidden size ({self.hidden_size}) is not a multiple of the number of attention "
96
+ f"heads ({self.num_attention_heads})."
97
+ )
98
+
99
+
100
+ __all__ = ["ArceeConfig"]
third_party/transformers/src/transformers/models/arcee/modeling_arcee.py ADDED
@@ -0,0 +1,520 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/arcee/modular_arcee.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_arcee.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 Arcee AI 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
+ from collections.abc import Callable
22
+ from typing import Optional
23
+
24
+ import torch
25
+ from torch import nn
26
+
27
+ from transformers.utils import auto_docstring
28
+
29
+ from ...activations import ACT2FN
30
+ from ...cache_utils import Cache, DynamicCache
31
+ from ...generation import GenerationMixin
32
+ from ...integrations import use_kernel_forward_from_hub, use_kernel_func_from_hub, use_kernelized_func
33
+ from ...masking_utils import create_causal_mask
34
+ from ...modeling_layers import (
35
+ GenericForQuestionAnswering,
36
+ GenericForSequenceClassification,
37
+ GenericForTokenClassification,
38
+ GradientCheckpointingLayer,
39
+ )
40
+ from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
41
+ from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
42
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
43
+ from ...processing_utils import Unpack
44
+ from ...utils import TransformersKwargs, can_return_tuple
45
+ from ...utils.generic import maybe_autocast, merge_with_config_defaults
46
+ from ...utils.output_capturing import capture_outputs
47
+ from .configuration_arcee import ArceeConfig
48
+
49
+
50
+ class ArceeMLP(nn.Module):
51
+ def __init__(self, config):
52
+ super().__init__()
53
+ self.config = config
54
+ self.hidden_size = config.hidden_size
55
+ self.intermediate_size = config.intermediate_size
56
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=config.mlp_bias)
57
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=config.mlp_bias)
58
+ self.act_fn = ACT2FN[config.hidden_act]
59
+
60
+ def forward(self, x):
61
+ return self.down_proj(self.act_fn(self.up_proj(x)))
62
+
63
+
64
+ @use_kernel_forward_from_hub("RMSNorm")
65
+ class ArceeRMSNorm(nn.Module):
66
+ def __init__(self, hidden_size, eps: float = 1e-6) -> None:
67
+ """
68
+ ArceeRMSNorm is equivalent to T5LayerNorm
69
+ """
70
+ super().__init__()
71
+ self.weight = nn.Parameter(torch.ones(hidden_size))
72
+ self.variance_epsilon = eps
73
+
74
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
75
+ input_dtype = hidden_states.dtype
76
+ hidden_states = hidden_states.to(torch.float32)
77
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
78
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
79
+ return self.weight * hidden_states.to(input_dtype)
80
+
81
+ def extra_repr(self):
82
+ return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
83
+
84
+
85
+ class ArceeRotaryEmbedding(nn.Module):
86
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
87
+
88
+ def __init__(self, config: ArceeConfig, device=None):
89
+ super().__init__()
90
+ self.max_seq_len_cached = config.max_position_embeddings
91
+ self.original_max_seq_len = config.max_position_embeddings
92
+
93
+ self.config = config
94
+
95
+ self.rope_type = self.config.rope_parameters["rope_type"]
96
+ rope_init_fn: Callable = self.compute_default_rope_parameters
97
+ if self.rope_type != "default":
98
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
99
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
100
+
101
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
102
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
103
+
104
+ @staticmethod
105
+ def compute_default_rope_parameters(
106
+ config: ArceeConfig | None = None,
107
+ device: Optional["torch.device"] = None,
108
+ seq_len: int | None = None,
109
+ ) -> tuple["torch.Tensor", float]:
110
+ """
111
+ Computes the inverse frequencies according to the original RoPE implementation
112
+ Args:
113
+ config ([`~transformers.PreTrainedConfig`]):
114
+ The model configuration.
115
+ device (`torch.device`):
116
+ The device to use for initialization of the inverse frequencies.
117
+ seq_len (`int`, *optional*):
118
+ The current sequence length. Unused for this type of RoPE.
119
+ Returns:
120
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
121
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
122
+ """
123
+ base = config.rope_parameters["rope_theta"]
124
+ dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
125
+
126
+ attention_factor = 1.0 # Unused in this type of RoPE
127
+
128
+ # Compute the inverse frequencies
129
+ inv_freq = 1.0 / (
130
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
131
+ )
132
+ return inv_freq, attention_factor
133
+
134
+ @torch.no_grad()
135
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
136
+ def forward(self, x, position_ids):
137
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
138
+ position_ids_expanded = position_ids[:, None, :].float()
139
+
140
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
141
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
142
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
143
+ emb = torch.cat((freqs, freqs), dim=-1)
144
+ cos = emb.cos() * self.attention_scaling
145
+ sin = emb.sin() * self.attention_scaling
146
+
147
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
148
+
149
+
150
+ def rotate_half(x):
151
+ """Rotates half the hidden dims of the input."""
152
+ x1 = x[..., : x.shape[-1] // 2]
153
+ x2 = x[..., x.shape[-1] // 2 :]
154
+ return torch.cat((-x2, x1), dim=-1)
155
+
156
+
157
+ @use_kernel_func_from_hub("rotary_pos_emb")
158
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
159
+ """Applies Rotary Position Embedding to the query and key tensors.
160
+
161
+ Args:
162
+ q (`torch.Tensor`): The query tensor.
163
+ k (`torch.Tensor`): The key tensor.
164
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
165
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
166
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
167
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
168
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
169
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
170
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
171
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
172
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
173
+ Returns:
174
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
175
+ """
176
+ cos = cos.unsqueeze(unsqueeze_dim)
177
+ sin = sin.unsqueeze(unsqueeze_dim)
178
+ q_embed = (q * cos) + (rotate_half(q) * sin)
179
+ k_embed = (k * cos) + (rotate_half(k) * sin)
180
+ return q_embed, k_embed
181
+
182
+
183
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
184
+ """
185
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
186
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
187
+ """
188
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
189
+ if n_rep == 1:
190
+ return hidden_states
191
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
192
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
193
+
194
+
195
+ def eager_attention_forward(
196
+ module: nn.Module,
197
+ query: torch.Tensor,
198
+ key: torch.Tensor,
199
+ value: torch.Tensor,
200
+ attention_mask: torch.Tensor | None,
201
+ scaling: float,
202
+ dropout: float = 0.0,
203
+ **kwargs: Unpack[TransformersKwargs],
204
+ ):
205
+ key_states = repeat_kv(key, module.num_key_value_groups)
206
+ value_states = repeat_kv(value, module.num_key_value_groups)
207
+
208
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
209
+ if attention_mask is not None:
210
+ attn_weights = attn_weights + attention_mask
211
+
212
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
213
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
214
+ attn_output = torch.matmul(attn_weights, value_states)
215
+ attn_output = attn_output.transpose(1, 2).contiguous()
216
+
217
+ return attn_output, attn_weights
218
+
219
+
220
+ @use_kernelized_func(apply_rotary_pos_emb)
221
+ class ArceeAttention(nn.Module):
222
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
223
+
224
+ def __init__(self, config: ArceeConfig, layer_idx: int):
225
+ super().__init__()
226
+ self.config = config
227
+ self.layer_idx = layer_idx
228
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
229
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
230
+ self.scaling = self.head_dim**-0.5
231
+ self.attention_dropout = config.attention_dropout
232
+ self.is_causal = True
233
+
234
+ self.q_proj = nn.Linear(
235
+ config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
236
+ )
237
+ self.k_proj = nn.Linear(
238
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
239
+ )
240
+ self.v_proj = nn.Linear(
241
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
242
+ )
243
+ self.o_proj = nn.Linear(
244
+ config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
245
+ )
246
+
247
+ def forward(
248
+ self,
249
+ hidden_states: torch.Tensor,
250
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
251
+ attention_mask: torch.Tensor | None = None,
252
+ past_key_values: Cache | None = None,
253
+ **kwargs: Unpack[TransformersKwargs],
254
+ ) -> tuple[torch.Tensor, torch.Tensor]:
255
+ input_shape = hidden_states.shape[:-1]
256
+ hidden_shape = (*input_shape, -1, self.head_dim)
257
+
258
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
259
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
260
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
261
+
262
+ cos, sin = position_embeddings
263
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
264
+
265
+ if past_key_values is not None:
266
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
267
+
268
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
269
+ self.config._attn_implementation, eager_attention_forward
270
+ )
271
+
272
+ attn_output, attn_weights = attention_interface(
273
+ self,
274
+ query_states,
275
+ key_states,
276
+ value_states,
277
+ attention_mask,
278
+ dropout=0.0 if not self.training else self.attention_dropout,
279
+ scaling=self.scaling,
280
+ **kwargs,
281
+ )
282
+
283
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
284
+ attn_output = self.o_proj(attn_output)
285
+ return attn_output, attn_weights
286
+
287
+
288
+ class ArceeDecoderLayer(GradientCheckpointingLayer):
289
+ def __init__(self, config: ArceeConfig, layer_idx: int):
290
+ super().__init__()
291
+ self.hidden_size = config.hidden_size
292
+
293
+ self.self_attn = ArceeAttention(config=config, layer_idx=layer_idx)
294
+
295
+ self.mlp = ArceeMLP(config)
296
+ self.input_layernorm = ArceeRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
297
+ self.post_attention_layernorm = ArceeRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
298
+
299
+ def forward(
300
+ self,
301
+ hidden_states: torch.Tensor,
302
+ attention_mask: torch.Tensor | None = None,
303
+ position_ids: torch.LongTensor | None = None,
304
+ past_key_values: Cache | None = None,
305
+ use_cache: bool | None = False,
306
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
307
+ **kwargs: Unpack[TransformersKwargs],
308
+ ) -> torch.Tensor:
309
+ residual = hidden_states
310
+ hidden_states = self.input_layernorm(hidden_states)
311
+ # Self Attention
312
+ hidden_states, _ = self.self_attn(
313
+ hidden_states=hidden_states,
314
+ attention_mask=attention_mask,
315
+ position_ids=position_ids,
316
+ past_key_values=past_key_values,
317
+ use_cache=use_cache,
318
+ position_embeddings=position_embeddings,
319
+ **kwargs,
320
+ )
321
+ hidden_states = residual + hidden_states
322
+
323
+ # Fully Connected
324
+ residual = hidden_states
325
+ hidden_states = self.post_attention_layernorm(hidden_states)
326
+ hidden_states = self.mlp(hidden_states)
327
+ hidden_states = residual + hidden_states
328
+ return hidden_states
329
+
330
+
331
+ @auto_docstring
332
+ class ArceePreTrainedModel(PreTrainedModel):
333
+ config: ArceeConfig
334
+ base_model_prefix = "model"
335
+ supports_gradient_checkpointing = True
336
+ _no_split_modules = ["ArceeDecoderLayer"]
337
+ _skip_keys_device_placement = ["past_key_values"]
338
+ _supports_flash_attn = True
339
+ _supports_sdpa = True
340
+ _supports_flex_attn = True
341
+
342
+ _can_compile_fullgraph = True
343
+ _supports_attention_backend = True
344
+ _can_record_outputs = {
345
+ "hidden_states": ArceeDecoderLayer,
346
+ "attentions": ArceeAttention,
347
+ }
348
+
349
+
350
+ @auto_docstring
351
+ class ArceeModel(ArceePreTrainedModel):
352
+ def __init__(self, config: ArceeConfig):
353
+ super().__init__(config)
354
+ self.padding_idx = config.pad_token_id
355
+ self.vocab_size = config.vocab_size
356
+
357
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
358
+ self.layers = nn.ModuleList(
359
+ [ArceeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
360
+ )
361
+ self.norm = ArceeRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
362
+ self.rotary_emb = ArceeRotaryEmbedding(config=config)
363
+ self.gradient_checkpointing = False
364
+
365
+ # Initialize weights and apply final processing
366
+ self.post_init()
367
+
368
+ @merge_with_config_defaults
369
+ @capture_outputs
370
+ @auto_docstring
371
+ def forward(
372
+ self,
373
+ input_ids: torch.LongTensor | None = None,
374
+ attention_mask: torch.Tensor | None = None,
375
+ position_ids: torch.LongTensor | None = None,
376
+ past_key_values: Cache | None = None,
377
+ inputs_embeds: torch.FloatTensor | None = None,
378
+ use_cache: bool | None = None,
379
+ **kwargs: Unpack[TransformersKwargs],
380
+ ) -> BaseModelOutputWithPast:
381
+ if (input_ids is None) ^ (inputs_embeds is not None):
382
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
383
+
384
+ if inputs_embeds is None:
385
+ inputs_embeds: torch.Tensor = self.embed_tokens(input_ids)
386
+
387
+ if use_cache and past_key_values is None:
388
+ past_key_values = DynamicCache(config=self.config)
389
+
390
+ if position_ids is None:
391
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
392
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
393
+ position_ids = position_ids.unsqueeze(0)
394
+
395
+ causal_mask = create_causal_mask(
396
+ config=self.config,
397
+ inputs_embeds=inputs_embeds,
398
+ attention_mask=attention_mask,
399
+ past_key_values=past_key_values,
400
+ position_ids=position_ids,
401
+ )
402
+
403
+ hidden_states = inputs_embeds
404
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
405
+
406
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
407
+ hidden_states = decoder_layer(
408
+ hidden_states,
409
+ attention_mask=causal_mask,
410
+ position_embeddings=position_embeddings,
411
+ position_ids=position_ids,
412
+ past_key_values=past_key_values,
413
+ use_cache=use_cache,
414
+ **kwargs,
415
+ )
416
+
417
+ hidden_states = self.norm(hidden_states)
418
+ return BaseModelOutputWithPast(
419
+ last_hidden_state=hidden_states,
420
+ past_key_values=past_key_values,
421
+ )
422
+
423
+
424
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
425
+ class ArceeForCausalLM(ArceePreTrainedModel, GenerationMixin):
426
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
427
+ _tp_plan = {"lm_head": "colwise_gather_output"}
428
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
429
+
430
+ def __init__(self, config):
431
+ super().__init__(config)
432
+ self.model = ArceeModel(config)
433
+ self.vocab_size = config.vocab_size
434
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
435
+
436
+ # Initialize weights and apply final processing
437
+ self.post_init()
438
+
439
+ @can_return_tuple
440
+ @auto_docstring
441
+ def forward(
442
+ self,
443
+ input_ids: torch.LongTensor | None = None,
444
+ attention_mask: torch.Tensor | None = None,
445
+ position_ids: torch.LongTensor | None = None,
446
+ past_key_values: Cache | None = None,
447
+ inputs_embeds: torch.FloatTensor | None = None,
448
+ labels: torch.LongTensor | None = None,
449
+ use_cache: bool | None = None,
450
+ logits_to_keep: int | torch.Tensor = 0,
451
+ **kwargs: Unpack[TransformersKwargs],
452
+ ) -> CausalLMOutputWithPast:
453
+ r"""
454
+ Example:
455
+
456
+ ```python
457
+ >>> from transformers import AutoTokenizer, ArceeForCausalLM
458
+
459
+ >>> model = ArceeForCausalLM.from_pretrained("meta-arcee/Arcee-2-7b-hf")
460
+ >>> tokenizer = AutoTokenizer.from_pretrained("meta-arcee/Arcee-2-7b-hf")
461
+
462
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
463
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
464
+
465
+ >>> # Generate
466
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
467
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
468
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
469
+ ```"""
470
+ outputs: BaseModelOutputWithPast = self.model(
471
+ input_ids=input_ids,
472
+ attention_mask=attention_mask,
473
+ position_ids=position_ids,
474
+ past_key_values=past_key_values,
475
+ inputs_embeds=inputs_embeds,
476
+ use_cache=use_cache,
477
+ **kwargs,
478
+ )
479
+
480
+ hidden_states = outputs.last_hidden_state
481
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
482
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
483
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
484
+
485
+ loss = None
486
+ if labels is not None:
487
+ loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
488
+
489
+ return CausalLMOutputWithPast(
490
+ loss=loss,
491
+ logits=logits,
492
+ past_key_values=outputs.past_key_values,
493
+ hidden_states=outputs.hidden_states,
494
+ attentions=outputs.attentions,
495
+ )
496
+
497
+
498
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
499
+ class ArceeForSequenceClassification(GenericForSequenceClassification, ArceePreTrainedModel):
500
+ pass
501
+
502
+
503
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
504
+ class ArceeForQuestionAnswering(GenericForQuestionAnswering, ArceePreTrainedModel):
505
+ base_model_prefix = "transformer" # For BC, where `transformer` was used instead of `model`
506
+
507
+
508
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
509
+ class ArceeForTokenClassification(GenericForTokenClassification, ArceePreTrainedModel):
510
+ pass
511
+
512
+
513
+ __all__ = [
514
+ "ArceeForCausalLM",
515
+ "ArceeForQuestionAnswering",
516
+ "ArceeForSequenceClassification",
517
+ "ArceeForTokenClassification",
518
+ "ArceeModel",
519
+ "ArceePreTrainedModel",
520
+ ]
third_party/transformers/src/transformers/models/arcee/modular_arcee.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Arcee 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
+ """PyTorch Arcee model."""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from transformers.utils import auto_docstring, logging
19
+
20
+ from ...modeling_rope_utils import RopeParameters
21
+ from ..llama.configuration_llama import LlamaConfig
22
+ from ..llama.modeling_llama import (
23
+ LlamaForCausalLM,
24
+ LlamaForQuestionAnswering,
25
+ LlamaForSequenceClassification,
26
+ LlamaForTokenClassification,
27
+ )
28
+ from ..nemotron.modeling_nemotron import NemotronMLP
29
+
30
+
31
+ logger = logging.get_logger(__name__)
32
+
33
+
34
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
35
+ @strict
36
+ class ArceeConfig(LlamaConfig):
37
+ r"""
38
+ ```python
39
+ >>> from transformers import ArceeModel, ArceeConfig
40
+
41
+ >>> # Initializing an Arcee AFM-4.5B-Base style configuration
42
+ >>> configuration = ArceeConfig()
43
+
44
+ >>> # Initializing a model from the AFM-4.5B-Base style configuration
45
+ >>> model = ArceeModel(configuration)
46
+
47
+ >>> # Accessing the model configuration
48
+ >>> configuration = model.config
49
+ ```"""
50
+
51
+ model_type = "arcee"
52
+ base_model_tp_plan = {
53
+ "layers.*.self_attn.q_proj": "colwise",
54
+ "layers.*.self_attn.k_proj": "colwise",
55
+ "layers.*.self_attn.v_proj": "colwise",
56
+ "layers.*.self_attn.o_proj": "rowwise",
57
+ "layers.*.mlp.up_proj": "colwise",
58
+ "layers.*.mlp.down_proj": "rowwise",
59
+ }
60
+
61
+ vocab_size: int = 32000
62
+ hidden_size: int = 2560
63
+ intermediate_size: int = 18432
64
+ num_hidden_layers: int = 32
65
+ num_attention_heads: int = 32
66
+ num_key_value_heads: int | None = None
67
+ hidden_act: str = "relu2"
68
+ max_position_embeddings: int = 4096
69
+ initializer_range: float = 0.02
70
+ rms_norm_eps: float = 1e-5
71
+ use_cache: bool = True
72
+ pad_token_id: int | None = None
73
+ bos_token_id: int | None = 128000
74
+ eos_token_id: int | list[int] | None = 128001
75
+ tie_word_embeddings: bool = False
76
+ rope_parameters: RopeParameters | dict | None = None
77
+ attention_bias: bool = False
78
+ attention_dropout: float | int = 0.0
79
+ mlp_bias: bool = False
80
+ head_dim: int | None = None
81
+
82
+ pretraining_tp = AttributeError()
83
+
84
+
85
+ class ArceeMLP(NemotronMLP):
86
+ pass
87
+
88
+
89
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
90
+ class ArceeForCausalLM(LlamaForCausalLM):
91
+ pass
92
+
93
+
94
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
95
+ class ArceeForSequenceClassification(LlamaForSequenceClassification):
96
+ pass
97
+
98
+
99
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
100
+ class ArceeForQuestionAnswering(LlamaForQuestionAnswering):
101
+ pass
102
+
103
+
104
+ @auto_docstring(checkpoint="arcee-ai/AFM-4.5B")
105
+ class ArceeForTokenClassification(LlamaForTokenClassification):
106
+ pass
107
+
108
+
109
+ __all__ = [
110
+ "ArceeConfig",
111
+ "ArceeForCausalLM",
112
+ "ArceeForQuestionAnswering",
113
+ "ArceeForSequenceClassification",
114
+ "ArceeForTokenClassification",
115
+ "ArceeModel", # noqa: F822
116
+ "ArceePreTrainedModel", # noqa: F822
117
+ ]
third_party/transformers/src/transformers/models/aya_vision/__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 .configuration_aya_vision import *
22
+ from .modeling_aya_vision import *
23
+ from .processing_aya_vision 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/aya_vision/configuration_aya_vision.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Cohere 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
+ """AyaVision model configuration"""
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="CohereForAI/aya-vision-8b")
24
+ @strict
25
+ class AyaVisionConfig(PreTrainedConfig):
26
+ r"""
27
+ downsample_factor (`int`, *optional*, defaults to 2):
28
+ The downsample factor to apply to the vision features.
29
+ adapter_layer_norm_eps (`float`, *optional*, defaults to 1e-06):
30
+ The epsilon value used for layer normalization in the adapter.
31
+ """
32
+
33
+ model_type = "aya_vision"
34
+ attribute_map = {
35
+ "image_token_id": "image_token_index",
36
+ }
37
+ sub_configs = {"text_config": AutoConfig, "vision_config": AutoConfig}
38
+
39
+ vision_config: dict | PreTrainedConfig | None = None
40
+ text_config: dict | PreTrainedConfig | None = None
41
+ vision_feature_select_strategy: str = "full"
42
+ vision_feature_layer: int | list[int] = -1
43
+ downsample_factor: int = 2
44
+ adapter_layer_norm_eps: float = 1e-6
45
+ image_token_index: int = 255036
46
+ tie_word_embeddings: bool = True
47
+
48
+ def __post_init__(self, **kwargs):
49
+ if isinstance(self.vision_config, dict):
50
+ self.vision_config["model_type"] = self.vision_config.get("model_type", "siglip_vision_model")
51
+ self.vision_config = CONFIG_MAPPING[self.vision_config["model_type"]](**self.vision_config)
52
+ elif self.vision_config is None:
53
+ self.vision_config = CONFIG_MAPPING["siglip_vision_model"](
54
+ hidden_size=1152,
55
+ intermediate_size=4304,
56
+ patch_size=14,
57
+ image_size=384,
58
+ num_hidden_layers=26,
59
+ num_attention_heads=14,
60
+ vision_use_head=False,
61
+ )
62
+
63
+ if isinstance(self.text_config, dict):
64
+ self.text_config["model_type"] = self.text_config.get("model_type", "cohere2")
65
+ self.text_config = CONFIG_MAPPING[self.text_config["model_type"]](**self.text_config)
66
+ elif self.text_config is None:
67
+ self.text_config = CONFIG_MAPPING["cohere2"]()
68
+
69
+ super().__post_init__(**kwargs)
70
+
71
+ def validate_architecture(self):
72
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
73
+ if self.vision_feature_select_strategy not in ["default", "full"]:
74
+ raise ValueError(
75
+ "vision_feature_select_strategy should be one of 'default', 'full'."
76
+ f"Got: {self.vision_feature_select_strategy}"
77
+ )
78
+
79
+
80
+ __all__ = ["AyaVisionConfig"]
third_party/transformers/src/transformers/models/aya_vision/modeling_aya_vision.py ADDED
@@ -0,0 +1,446 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/aya_vision/modular_aya_vision.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_aya_vision.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 the Cohere 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, torch_compilable_check
33
+ from ...utils.generic import can_return_tuple, merge_with_config_defaults
34
+ from ..auto import AutoModel
35
+ from .configuration_aya_vision import AyaVisionConfig
36
+
37
+
38
+ class AyaVisionMultiModalProjector(nn.Module):
39
+ def __init__(self, config: AyaVisionConfig):
40
+ super().__init__()
41
+ self.config = config
42
+ self.downsample_factor = config.downsample_factor
43
+ self.alignment_intermediate_size = getattr(
44
+ config, "alignment_intermediate_size", config.text_config.hidden_size
45
+ )
46
+ self.layernorm = nn.LayerNorm(
47
+ config.vision_config.hidden_size * (config.downsample_factor**2), eps=config.adapter_layer_norm_eps
48
+ )
49
+
50
+ self.linear_1 = nn.Linear(
51
+ config.vision_config.hidden_size * (config.downsample_factor**2),
52
+ self.alignment_intermediate_size,
53
+ bias=True,
54
+ )
55
+
56
+ self.act = ACT2FN["silu"] # SwiGLU uses SiLU activation
57
+ # For SwiGLU, project down to half size since we split intermediate dim
58
+ self.linear_2 = nn.Linear(self.alignment_intermediate_size // 2, config.text_config.hidden_size, bias=True)
59
+
60
+ def forward(self, image_features):
61
+ image_features = self.pixel_shuffle(image_features)
62
+ image_features = self.layernorm(image_features)
63
+ hidden_states = self.linear_1(image_features)
64
+
65
+ # Split along last dimension and apply SwiGLU
66
+ x, gate = hidden_states.chunk(2, dim=-1)
67
+ hidden_states = self.act(gate) * x
68
+
69
+ hidden_states = self.linear_2(hidden_states)
70
+ return hidden_states
71
+
72
+ def pixel_shuffle(self, image_features): # B, S, D
73
+ batch_size, seq_length, feature_dim = image_features.shape
74
+ height = width = int(seq_length**0.5)
75
+ image_features = image_features.reshape(image_features.shape[0], width, height, -1)
76
+ channels = image_features.shape[-1]
77
+ image_features = image_features.reshape(
78
+ batch_size, width, int(height / self.downsample_factor), int(channels * self.downsample_factor)
79
+ )
80
+ image_features = image_features.permute(0, 2, 1, 3)
81
+ image_features = image_features.reshape(
82
+ batch_size, int(height / self.downsample_factor), int(width / self.downsample_factor), -1
83
+ )
84
+ image_features = image_features.permute(0, 2, 1, 3)
85
+ return image_features
86
+
87
+
88
+ @auto_docstring
89
+ class AyaVisionPreTrainedModel(PreTrainedModel):
90
+ config: AyaVisionConfig
91
+ base_model_prefix = "model"
92
+ input_modalities = ("image", "text")
93
+ supports_gradient_checkpointing = True
94
+ _skip_keys_device_placement = "past_key_values"
95
+
96
+ _supports_flash_attn = True
97
+ _supports_sdpa = True
98
+ _can_compile_fullgraph = False
99
+ _supports_flex_attn = True
100
+ _supports_attention_backend = True
101
+
102
+
103
+ @dataclass
104
+ @auto_docstring(
105
+ custom_intro="""
106
+ Base class for AyaVision causal language model (or autoregressive) outputs.
107
+ """
108
+ )
109
+ class AyaVisionCausalLMOutputWithPast(ModelOutput):
110
+ r"""
111
+ loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
112
+ Language modeling loss (for next-token prediction).
113
+ logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
114
+ Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
115
+ past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
116
+ It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
117
+
118
+ Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
119
+ `past_key_values` input) to speed up sequential decoding.
120
+ image_hidden_states (`torch.FloatTensor`, *optional*):
121
+ A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`.
122
+ image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state.
123
+ """
124
+
125
+ loss: torch.FloatTensor | None = None
126
+ logits: torch.FloatTensor | None = None
127
+ past_key_values: Cache | None = None
128
+ hidden_states: tuple[torch.FloatTensor] | None = None
129
+ attentions: tuple[torch.FloatTensor] | None = None
130
+ image_hidden_states: torch.FloatTensor | None = None
131
+
132
+
133
+ @dataclass
134
+ @auto_docstring(
135
+ custom_intro="""
136
+ Base class for AyaVision outputs, with hidden states and attentions.
137
+ """
138
+ )
139
+ class AyaVisionModelOutputWithPast(BaseModelOutputWithPast):
140
+ r"""
141
+ past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
142
+ It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
143
+
144
+ Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
145
+ `past_key_values` input) to speed up sequential decoding.
146
+ image_hidden_states (`torch.FloatTensor`, *optional*):
147
+ A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`.
148
+ image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state.
149
+ """
150
+
151
+ image_hidden_states: torch.FloatTensor | None = None
152
+
153
+
154
+ @auto_docstring(
155
+ custom_intro="""
156
+ The AyaVision model which consists of a vision backbone and a language model, without a language modeling head.
157
+ """
158
+ )
159
+ class AyaVisionModel(AyaVisionPreTrainedModel):
160
+ def __init__(self, config: AyaVisionConfig):
161
+ super().__init__(config)
162
+ self.vision_tower = AutoModel.from_config(config.vision_config)
163
+
164
+ self.multi_modal_projector = AyaVisionMultiModalProjector(config)
165
+ self.language_model = AutoModel.from_config(config.text_config)
166
+ self.post_init()
167
+
168
+ def get_input_embeddings(self):
169
+ return self.language_model.get_input_embeddings()
170
+
171
+ def set_input_embeddings(self, value):
172
+ self.language_model.set_input_embeddings(value)
173
+
174
+ @merge_with_config_defaults
175
+ @can_return_tuple
176
+ @auto_docstring(
177
+ custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection."
178
+ )
179
+ def get_image_features(
180
+ self,
181
+ pixel_values: torch.FloatTensor,
182
+ vision_feature_layer: int | list[int] | list[int] | None = None,
183
+ vision_feature_select_strategy: str | None = None,
184
+ output_hidden_states: bool | None = None,
185
+ **kwargs: Unpack[TransformersKwargs],
186
+ ) -> tuple | BaseModelOutputWithPooling:
187
+ kwargs = {k: v for k, v in kwargs.items() if v is not None}
188
+ # this is not memory efficient at all (output_hidden_states=True) will save all the hidden states.
189
+ image_outputs = self.vision_tower(
190
+ pixel_values,
191
+ output_hidden_states=True, # Ignore arg on purpose
192
+ return_dict=True,
193
+ **kwargs,
194
+ )
195
+
196
+ # If we have one vision feature layer, return the corresponding hidden states,
197
+ # otherwise, select the hidden states of each feature layer and concatenate them
198
+ if isinstance(vision_feature_layer, int):
199
+ selected_image_feature = image_outputs.hidden_states[vision_feature_layer]
200
+ if vision_feature_select_strategy == "default":
201
+ selected_image_feature = selected_image_feature[:, 1:]
202
+ else:
203
+ hs_pool = [image_outputs.hidden_states[layer_idx] for layer_idx in vision_feature_layer]
204
+ # For default; crop CLS from each hidden state in the hidden state pool
205
+ if vision_feature_select_strategy == "default":
206
+ hs_pool = [hs[:, 1:] for hs in hs_pool]
207
+ selected_image_feature = torch.cat(hs_pool, dim=-1)
208
+
209
+ image_outputs.pooler_output = self.multi_modal_projector(selected_image_feature)
210
+
211
+ return image_outputs
212
+
213
+ def get_placeholder_mask(
214
+ self, input_ids: torch.LongTensor, inputs_embeds: torch.FloatTensor, image_features: torch.FloatTensor
215
+ ):
216
+ """
217
+ Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is
218
+ equal to the length of multimodal features. If the lengths are different, an error is raised.
219
+ """
220
+ if input_ids is None:
221
+ special_image_mask = inputs_embeds == self.get_input_embeddings()(
222
+ torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
223
+ )
224
+ special_image_mask = special_image_mask.all(-1)
225
+ else:
226
+ special_image_mask = input_ids == self.config.image_token_id
227
+
228
+ n_image_tokens = special_image_mask.sum()
229
+ n_image_features = image_features.shape[0] * image_features.shape[1]
230
+ special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
231
+ torch_compilable_check(
232
+ inputs_embeds[special_image_mask].numel() == image_features.numel(),
233
+ f"Image features and image tokens do not match, tokens: {n_image_tokens}, features: {n_image_features}",
234
+ )
235
+ return special_image_mask
236
+
237
+ @can_return_tuple
238
+ @auto_docstring
239
+ def forward(
240
+ self,
241
+ input_ids: torch.LongTensor | None = None,
242
+ pixel_values: torch.FloatTensor | None = None,
243
+ attention_mask: torch.Tensor | None = None,
244
+ position_ids: torch.LongTensor | None = None,
245
+ past_key_values: Cache | None = None,
246
+ inputs_embeds: torch.FloatTensor | None = None,
247
+ vision_feature_layer: int | list[int] | list[int] | None = None,
248
+ vision_feature_select_strategy: str | None = None,
249
+ use_cache: bool | None = None,
250
+ **kwargs: Unpack[TransformersKwargs],
251
+ ) -> tuple | AyaVisionModelOutputWithPast:
252
+ if (input_ids is None) ^ (inputs_embeds is not None):
253
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
254
+
255
+ if inputs_embeds is None:
256
+ inputs_embeds = self.get_input_embeddings()(input_ids)
257
+
258
+ if pixel_values is not None:
259
+ image_features = self.get_image_features(
260
+ pixel_values=pixel_values,
261
+ vision_feature_layer=vision_feature_layer,
262
+ vision_feature_select_strategy=vision_feature_select_strategy,
263
+ return_dict=True,
264
+ ).pooler_output
265
+ image_features = image_features.to(inputs_embeds.device, inputs_embeds.dtype)
266
+ special_image_mask = self.get_placeholder_mask(
267
+ input_ids, inputs_embeds=inputs_embeds, image_features=image_features
268
+ )
269
+ inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_features)
270
+
271
+ outputs = self.language_model(
272
+ attention_mask=attention_mask,
273
+ position_ids=position_ids,
274
+ past_key_values=past_key_values,
275
+ inputs_embeds=inputs_embeds,
276
+ use_cache=use_cache,
277
+ **kwargs,
278
+ )
279
+
280
+ return AyaVisionModelOutputWithPast(
281
+ last_hidden_state=outputs.last_hidden_state,
282
+ past_key_values=outputs.past_key_values,
283
+ hidden_states=outputs.hidden_states,
284
+ attentions=outputs.attentions,
285
+ image_hidden_states=image_features if pixel_values is not None else None,
286
+ )
287
+
288
+
289
+ @auto_docstring(
290
+ custom_intro="""
291
+ The AYA_VISION model which consists of a vision backbone and a language model.
292
+ """
293
+ )
294
+ class AyaVisionForConditionalGeneration(AyaVisionPreTrainedModel, GenerationMixin):
295
+ _tied_weights_keys = {"lm_head.weight": "model.language_model.embed_tokens.weight"}
296
+
297
+ def __init__(self, config: AyaVisionConfig):
298
+ super().__init__(config)
299
+ self.model = AyaVisionModel(config)
300
+ self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False)
301
+ self.post_init()
302
+
303
+ def get_input_embeddings(self):
304
+ return self.model.get_input_embeddings()
305
+
306
+ def set_input_embeddings(self, value):
307
+ self.model.set_input_embeddings(value)
308
+
309
+ def get_output_embeddings(self) -> nn.Module:
310
+ return self.lm_head
311
+
312
+ @auto_docstring
313
+ def get_image_features(
314
+ self,
315
+ pixel_values: torch.FloatTensor,
316
+ vision_feature_layer: int | list[int] | list[int] | None = None,
317
+ vision_feature_select_strategy: str | None = None,
318
+ **kwargs: Unpack[TransformersKwargs],
319
+ ) -> tuple | BaseModelOutputWithPooling:
320
+ return self.model.get_image_features(
321
+ pixel_values=pixel_values,
322
+ vision_feature_layer=vision_feature_layer,
323
+ vision_feature_select_strategy=vision_feature_select_strategy,
324
+ **kwargs,
325
+ )
326
+
327
+ @can_return_tuple
328
+ @auto_docstring
329
+ def forward(
330
+ self,
331
+ input_ids: torch.LongTensor | None = None,
332
+ pixel_values: torch.FloatTensor | None = None,
333
+ attention_mask: torch.Tensor | None = None,
334
+ position_ids: torch.LongTensor | None = None,
335
+ past_key_values: Cache | None = None,
336
+ inputs_embeds: torch.FloatTensor | None = None,
337
+ vision_feature_layer: int | list[int] | list[int] | None = None,
338
+ vision_feature_select_strategy: str | None = None,
339
+ labels: torch.LongTensor | None = None,
340
+ logits_to_keep: int | torch.Tensor = 0,
341
+ image_sizes: torch.Tensor | None = None,
342
+ **kwargs: Unpack[TransformersKwargs],
343
+ ) -> tuple | AyaVisionCausalLMOutputWithPast:
344
+ r"""
345
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
346
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
347
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
348
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
349
+
350
+ Example:
351
+
352
+ ```python
353
+ >>> from transformers import AutoProcessor, AyaVisionForConditionalGeneration
354
+ >>> import torch
355
+
356
+ >>> torch_device = "cuda:0"
357
+ >>> processor = AutoProcessor.from_pretrained("CohereForAI/aya-vision-8b", use_fast=True)
358
+ >>> model = AyaVisionForConditionalGeneration.from_pretrained("CohereForAI/aya-vision-8b", device_map=torch_device)
359
+
360
+ >>> messages = [
361
+ ... {
362
+ ... "role": "user",
363
+ ... "content": [
364
+ ... {
365
+ ... "type": "image",
366
+ ... "url": "https://pbs.twimg.com/media/Fx7YvfQWYAIp6rZ?format=jpg&name=medium",
367
+ ... },
368
+ ... {"type": "text", "text": "चित्र में लिखा पाठ क्या कहता है?"},
369
+ ... ],
370
+ ... }
371
+ ... ]
372
+
373
+ >>> inputs = processor.apply_chat_template(
374
+ ... messages, padding=True, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", device=torch_device
375
+ ... ).to(model.device)
376
+
377
+ >>> gen_tokens = model.generate(**inputs, max_new_tokens=300, do_sample=True, temperature=0.3)
378
+ >>> processor.tokenizer.decode(gen_tokens[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
379
+ ```"""
380
+ outputs = self.model(
381
+ input_ids=input_ids,
382
+ pixel_values=pixel_values,
383
+ attention_mask=attention_mask,
384
+ position_ids=position_ids,
385
+ past_key_values=past_key_values,
386
+ inputs_embeds=inputs_embeds,
387
+ vision_feature_layer=vision_feature_layer,
388
+ vision_feature_select_strategy=vision_feature_select_strategy,
389
+ image_sizes=image_sizes,
390
+ **kwargs,
391
+ )
392
+
393
+ hidden_states = outputs[0]
394
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
395
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
396
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
397
+
398
+ loss = None
399
+ if labels is not None:
400
+ loss = self.loss_function(
401
+ logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size, **kwargs
402
+ )
403
+
404
+ return AyaVisionCausalLMOutputWithPast(
405
+ loss=loss,
406
+ logits=logits,
407
+ past_key_values=outputs.past_key_values,
408
+ hidden_states=outputs.hidden_states,
409
+ attentions=outputs.attentions,
410
+ image_hidden_states=outputs.image_hidden_states,
411
+ )
412
+
413
+ def prepare_inputs_for_generation(
414
+ self,
415
+ input_ids,
416
+ past_key_values=None,
417
+ inputs_embeds=None,
418
+ pixel_values=None,
419
+ attention_mask=None,
420
+ logits_to_keep=None,
421
+ is_first_iteration=False,
422
+ **kwargs,
423
+ ):
424
+ # Overwritten -- in specific circumstances we don't want to forward image inputs to the model
425
+
426
+ model_inputs = super().prepare_inputs_for_generation(
427
+ input_ids,
428
+ past_key_values=past_key_values,
429
+ inputs_embeds=inputs_embeds,
430
+ attention_mask=attention_mask,
431
+ logits_to_keep=logits_to_keep,
432
+ is_first_iteration=is_first_iteration,
433
+ **kwargs,
434
+ )
435
+
436
+ if is_first_iteration or not kwargs.get("use_cache", True):
437
+ # Pixel values are used only in the first iteration if available
438
+ # In subsequent iterations, they are already merged with text and cached
439
+ # NOTE: first iteration doesn't have to be prefill, it can be the first
440
+ # iteration with a question and cached system prompt (continue generate from cache)
441
+ model_inputs["pixel_values"] = pixel_values
442
+
443
+ return model_inputs
444
+
445
+
446
+ __all__ = ["AyaVisionForConditionalGeneration", "AyaVisionPreTrainedModel", "AyaVisionModel"]
third_party/transformers/src/transformers/models/aya_vision/modular_aya_vision.py ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the Cohere 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 AyaVision model."""
15
+
16
+ import torch
17
+ from torch import nn
18
+
19
+ from transformers.models.llava.modeling_llava import (
20
+ LlavaCausalLMOutputWithPast,
21
+ LlavaForConditionalGeneration,
22
+ LlavaModel,
23
+ LlavaModelOutputWithPast,
24
+ LlavaPreTrainedModel,
25
+ )
26
+
27
+ from ...activations import ACT2FN
28
+ from ...cache_utils import Cache
29
+ from ...modeling_outputs import BaseModelOutputWithPooling
30
+ from ...processing_utils import Unpack
31
+ from ...utils import TransformersKwargs, auto_docstring, logging
32
+ from ...utils.generic import can_return_tuple, merge_with_config_defaults
33
+ from .configuration_aya_vision import AyaVisionConfig
34
+
35
+
36
+ logger = logging.get_logger(__name__)
37
+
38
+
39
+ class AyaVisionMultiModalProjector(nn.Module):
40
+ def __init__(self, config: AyaVisionConfig):
41
+ super().__init__()
42
+ self.config = config
43
+ self.downsample_factor = config.downsample_factor
44
+ self.alignment_intermediate_size = getattr(
45
+ config, "alignment_intermediate_size", config.text_config.hidden_size
46
+ )
47
+ self.layernorm = nn.LayerNorm(
48
+ config.vision_config.hidden_size * (config.downsample_factor**2), eps=config.adapter_layer_norm_eps
49
+ )
50
+
51
+ self.linear_1 = nn.Linear(
52
+ config.vision_config.hidden_size * (config.downsample_factor**2),
53
+ self.alignment_intermediate_size,
54
+ bias=True,
55
+ )
56
+
57
+ self.act = ACT2FN["silu"] # SwiGLU uses SiLU activation
58
+ # For SwiGLU, project down to half size since we split intermediate dim
59
+ self.linear_2 = nn.Linear(self.alignment_intermediate_size // 2, config.text_config.hidden_size, bias=True)
60
+
61
+ def forward(self, image_features):
62
+ image_features = self.pixel_shuffle(image_features)
63
+ image_features = self.layernorm(image_features)
64
+ hidden_states = self.linear_1(image_features)
65
+
66
+ # Split along last dimension and apply SwiGLU
67
+ x, gate = hidden_states.chunk(2, dim=-1)
68
+ hidden_states = self.act(gate) * x
69
+
70
+ hidden_states = self.linear_2(hidden_states)
71
+ return hidden_states
72
+
73
+ def pixel_shuffle(self, image_features): # B, S, D
74
+ batch_size, seq_length, feature_dim = image_features.shape
75
+ height = width = int(seq_length**0.5)
76
+ image_features = image_features.reshape(image_features.shape[0], width, height, -1)
77
+ channels = image_features.shape[-1]
78
+ image_features = image_features.reshape(
79
+ batch_size, width, int(height / self.downsample_factor), int(channels * self.downsample_factor)
80
+ )
81
+ image_features = image_features.permute(0, 2, 1, 3)
82
+ image_features = image_features.reshape(
83
+ batch_size, int(height / self.downsample_factor), int(width / self.downsample_factor), -1
84
+ )
85
+ image_features = image_features.permute(0, 2, 1, 3)
86
+ return image_features
87
+
88
+
89
+ class AyaVisionPreTrainedModel(LlavaPreTrainedModel):
90
+ _can_compile_fullgraph = False
91
+
92
+
93
+ class AyaVisionCausalLMOutputWithPast(LlavaCausalLMOutputWithPast):
94
+ pass
95
+
96
+
97
+ class AyaVisionModelOutputWithPast(LlavaModelOutputWithPast):
98
+ pass
99
+
100
+
101
+ class AyaVisionModel(LlavaModel):
102
+ # Unlike LLaVA, the model doesn't have to deal with Pixtral-style image states
103
+ @merge_with_config_defaults
104
+ @can_return_tuple
105
+ @auto_docstring(
106
+ custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection."
107
+ )
108
+ def get_image_features(
109
+ self,
110
+ pixel_values: torch.FloatTensor,
111
+ vision_feature_layer: int | list[int] | list[int] | None = None,
112
+ vision_feature_select_strategy: str | None = None,
113
+ output_hidden_states: bool | None = None,
114
+ **kwargs: Unpack[TransformersKwargs],
115
+ ) -> tuple | BaseModelOutputWithPooling:
116
+ kwargs = {k: v for k, v in kwargs.items() if v is not None}
117
+ # this is not memory efficient at all (output_hidden_states=True) will save all the hidden states.
118
+ image_outputs = self.vision_tower(
119
+ pixel_values,
120
+ output_hidden_states=True, # Ignore arg on purpose
121
+ return_dict=True,
122
+ **kwargs,
123
+ )
124
+
125
+ # If we have one vision feature layer, return the corresponding hidden states,
126
+ # otherwise, select the hidden states of each feature layer and concatenate them
127
+ if isinstance(vision_feature_layer, int):
128
+ selected_image_feature = image_outputs.hidden_states[vision_feature_layer]
129
+ if vision_feature_select_strategy == "default":
130
+ selected_image_feature = selected_image_feature[:, 1:]
131
+ else:
132
+ hs_pool = [image_outputs.hidden_states[layer_idx] for layer_idx in vision_feature_layer]
133
+ # For default; crop CLS from each hidden state in the hidden state pool
134
+ if vision_feature_select_strategy == "default":
135
+ hs_pool = [hs[:, 1:] for hs in hs_pool]
136
+ selected_image_feature = torch.cat(hs_pool, dim=-1)
137
+
138
+ image_outputs.pooler_output = self.multi_modal_projector(selected_image_feature)
139
+
140
+ return image_outputs
141
+
142
+ @can_return_tuple
143
+ @auto_docstring
144
+ def forward(
145
+ self,
146
+ input_ids: torch.LongTensor | None = None,
147
+ pixel_values: torch.FloatTensor | None = None,
148
+ attention_mask: torch.Tensor | None = None,
149
+ position_ids: torch.LongTensor | None = None,
150
+ past_key_values: Cache | None = None,
151
+ inputs_embeds: torch.FloatTensor | None = None,
152
+ vision_feature_layer: int | list[int] | list[int] | None = None,
153
+ vision_feature_select_strategy: str | None = None,
154
+ use_cache: bool | None = None,
155
+ **kwargs: Unpack[TransformersKwargs],
156
+ ) -> tuple | AyaVisionModelOutputWithPast:
157
+ if (input_ids is None) ^ (inputs_embeds is not None):
158
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
159
+
160
+ if inputs_embeds is None:
161
+ inputs_embeds = self.get_input_embeddings()(input_ids)
162
+
163
+ if pixel_values is not None:
164
+ image_features = self.get_image_features(
165
+ pixel_values=pixel_values,
166
+ vision_feature_layer=vision_feature_layer,
167
+ vision_feature_select_strategy=vision_feature_select_strategy,
168
+ return_dict=True,
169
+ ).pooler_output
170
+ image_features = image_features.to(inputs_embeds.device, inputs_embeds.dtype)
171
+ special_image_mask = self.get_placeholder_mask(
172
+ input_ids, inputs_embeds=inputs_embeds, image_features=image_features
173
+ )
174
+ inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_features)
175
+
176
+ outputs = self.language_model(
177
+ attention_mask=attention_mask,
178
+ position_ids=position_ids,
179
+ past_key_values=past_key_values,
180
+ inputs_embeds=inputs_embeds,
181
+ use_cache=use_cache,
182
+ **kwargs,
183
+ )
184
+
185
+ return AyaVisionModelOutputWithPast(
186
+ last_hidden_state=outputs.last_hidden_state,
187
+ past_key_values=outputs.past_key_values,
188
+ hidden_states=outputs.hidden_states,
189
+ attentions=outputs.attentions,
190
+ image_hidden_states=image_features if pixel_values is not None else None,
191
+ )
192
+
193
+
194
+ class AyaVisionForConditionalGeneration(LlavaForConditionalGeneration):
195
+ def forward(
196
+ self,
197
+ input_ids: torch.LongTensor | None = None,
198
+ pixel_values: torch.FloatTensor | None = None,
199
+ attention_mask: torch.Tensor | None = None,
200
+ position_ids: torch.LongTensor | None = None,
201
+ past_key_values: Cache | None = None,
202
+ inputs_embeds: torch.FloatTensor | None = None,
203
+ vision_feature_layer: int | list[int] | list[int] | None = None,
204
+ vision_feature_select_strategy: str | None = None,
205
+ labels: torch.LongTensor | None = None,
206
+ logits_to_keep: int | torch.Tensor = 0,
207
+ image_sizes: torch.Tensor | None = None,
208
+ **kwargs: Unpack[TransformersKwargs],
209
+ ) -> tuple | AyaVisionCausalLMOutputWithPast:
210
+ r"""
211
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
212
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
213
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
214
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
215
+
216
+ Example:
217
+
218
+ ```python
219
+ >>> from transformers import AutoProcessor, AyaVisionForConditionalGeneration
220
+ >>> import torch
221
+
222
+ >>> torch_device = "cuda:0"
223
+ >>> processor = AutoProcessor.from_pretrained("CohereForAI/aya-vision-8b", use_fast=True)
224
+ >>> model = AyaVisionForConditionalGeneration.from_pretrained("CohereForAI/aya-vision-8b", device_map=torch_device)
225
+
226
+ >>> messages = [
227
+ ... {
228
+ ... "role": "user",
229
+ ... "content": [
230
+ ... {
231
+ ... "type": "image",
232
+ ... "url": "https://pbs.twimg.com/media/Fx7YvfQWYAIp6rZ?format=jpg&name=medium",
233
+ ... },
234
+ ... {"type": "text", "text": "चित्र में लिखा पाठ क्या कहता है?"},
235
+ ... ],
236
+ ... }
237
+ ... ]
238
+
239
+ >>> inputs = processor.apply_chat_template(
240
+ ... messages, padding=True, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", device=torch_device
241
+ ... ).to(model.device)
242
+
243
+ >>> gen_tokens = model.generate(**inputs, max_new_tokens=300, do_sample=True, temperature=0.3)
244
+ >>> processor.tokenizer.decode(gen_tokens[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
245
+ ```"""
246
+ super().forward(
247
+ input_ids=input_ids,
248
+ pixel_values=pixel_values,
249
+ attention_mask=attention_mask,
250
+ position_ids=position_ids,
251
+ past_key_values=past_key_values,
252
+ inputs_embeds=inputs_embeds,
253
+ vision_feature_layer=vision_feature_layer,
254
+ vision_feature_select_strategy=vision_feature_select_strategy,
255
+ labels=labels,
256
+ logits_to_keep=logits_to_keep,
257
+ image_sizes=image_sizes,
258
+ **kwargs,
259
+ )
260
+
261
+
262
+ __all__ = ["AyaVisionForConditionalGeneration", "AyaVisionPreTrainedModel", "AyaVisionModel"]
third_party/transformers/src/transformers/models/aya_vision/processing_aya_vision.py ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 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
+
15
+
16
+ from ...image_processing_utils import BatchFeature
17
+ from ...image_utils import ImageInput, make_flat_list_of_images
18
+ from ...processing_utils import MultiModalData, ProcessingKwargs, ProcessorMixin, Unpack
19
+ from ...tokenization_utils_base import PreTokenizedInput, TextInput
20
+ from ...utils import auto_docstring
21
+
22
+
23
+ class AyaVisionProcessorKwargs(ProcessingKwargs, total=False):
24
+ _defaults = {
25
+ "text_kwargs": {
26
+ "padding_side": "left",
27
+ "padding": True,
28
+ "return_mm_token_type_ids": False,
29
+ },
30
+ "images_kwargs": {
31
+ "crop_to_patches": True,
32
+ },
33
+ }
34
+
35
+
36
+ @auto_docstring
37
+ class AyaVisionProcessor(ProcessorMixin):
38
+ def __init__(
39
+ self,
40
+ image_processor=None,
41
+ tokenizer=None,
42
+ patch_size: int = 28,
43
+ img_size: int = 364,
44
+ image_token="<image>", # set the default and let users change if they have peculiar special tokens in rare cases
45
+ downsample_factor: int = 1,
46
+ start_of_img_token="<|START_OF_IMG|>",
47
+ end_of_img_token="<|END_OF_IMG|>",
48
+ img_patch_token="<|IMG_PATCH|>",
49
+ img_line_break_token="<|IMG_LINE_BREAK|>",
50
+ tile_token="TILE",
51
+ tile_global_token="TILE_GLOBAL",
52
+ chat_template=None,
53
+ **kwargs,
54
+ ):
55
+ r"""
56
+ patch_size (`int`, *optional*, defaults to 28):
57
+ The size of image patches for tokenization.
58
+ img_size (`int`, *optional*, defaults to 364):
59
+ The size of the image to be tokenized. This should correspond to the size given to the image processor.
60
+ image_token (`str`, *optional*, defaults to `"<image>"`):
61
+ The token to be used to represent an image in the text.
62
+ downsample_factor (`int`, *optional*, defaults to 1):
63
+ The factor by which to scale the patch size.
64
+ start_of_img_token (`str`, *optional*, defaults to `"<|START_OF_IMG|>"`):
65
+ The token to be used to represent the start of an image in the text.
66
+ end_of_img_token (`str`, *optional*, defaults to `"<|END_OF_IMG|>"`):
67
+ The token to be used to represent the end of an image in the text.
68
+ img_patch_token (`str`, *optional*, defaults to `"<|IMG_PATCH|>"`):
69
+ The token to be used to represent an image patch in the text.
70
+ img_line_break_token (`str`, *optional*, defaults to `"<|IMG_LINE_BREAK|>"`):
71
+ The token to be used to represent a line break in the text.
72
+ tile_token (`str`, *optional*, defaults to `"TILE"`):
73
+ The token to be used to represent an image patch in the text.
74
+ tile_global_token (`str`, *optional*, defaults to `"TILE_GLOBAL"`):
75
+ The token to be used to represent the cover image in the text.
76
+ """
77
+ super().__init__(image_processor, tokenizer, chat_template=chat_template)
78
+
79
+ self.image_token = image_token
80
+ self.patch_size = patch_size * downsample_factor
81
+ self.img_size = img_size
82
+
83
+ self.start_of_img_token = start_of_img_token
84
+ self.end_of_img_token = end_of_img_token
85
+ self.img_patch_token = img_patch_token
86
+ self.img_line_break_token = img_line_break_token
87
+ self.tile_token = tile_token
88
+ self.tile_global_token = tile_global_token
89
+ self.image_token_id = tokenizer.convert_tokens_to_ids(self.img_patch_token)
90
+ self.image_ids = tokenizer.convert_tokens_to_ids(
91
+ [img_patch_token, tile_token, tile_global_token, start_of_img_token, end_of_img_token]
92
+ )
93
+
94
+ def _prompt_split_image(self, num_patches):
95
+ """
96
+ Create a structured string representation of image tokens
97
+
98
+ Args:
99
+ num_patches: Number of patches in the image
100
+
101
+ Returns:
102
+ String with appropriate image tokens
103
+ """
104
+
105
+ img_patches_per_tile = (self.img_size // self.patch_size) ** 2
106
+ img_string = f"{self.start_of_img_token}"
107
+ if num_patches > 1:
108
+ for idx in range(1, num_patches):
109
+ img_string += f"{self.tile_token}_{idx}" + f"{self.img_patch_token}" * img_patches_per_tile
110
+
111
+ img_string += f"{self.tile_global_token}" + f"{self.img_patch_token}" * img_patches_per_tile
112
+ img_string += f"{self.end_of_img_token}"
113
+ return img_string
114
+
115
+ @auto_docstring
116
+ def __call__(
117
+ self,
118
+ images: ImageInput | None = None,
119
+ text: TextInput | PreTokenizedInput | list[TextInput] | list[PreTokenizedInput] | None = None,
120
+ **kwargs: Unpack[AyaVisionProcessorKwargs],
121
+ ) -> BatchFeature:
122
+ r"""
123
+ Returns:
124
+ [`BatchFeature`]: A [`BatchFeature`] with the following fields:
125
+
126
+ - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`.
127
+ - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when
128
+ `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not
129
+ `None`).
130
+ - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`.
131
+ """
132
+ if text is None:
133
+ raise ValueError("You have to specify text.")
134
+
135
+ output_kwargs = self._merge_kwargs(
136
+ AyaVisionProcessorKwargs,
137
+ tokenizer_init_kwargs=self.tokenizer.init_kwargs,
138
+ **kwargs,
139
+ )
140
+
141
+ if not isinstance(text, (list, tuple)):
142
+ text = [text]
143
+
144
+ # Process images
145
+ image_inputs = {}
146
+ if images is not None:
147
+ images = self.image_processor.fetch_images(images)
148
+ images = make_flat_list_of_images(images)
149
+ image_inputs = self.image_processor(images=images, **output_kwargs["images_kwargs"])
150
+ num_patches = image_inputs.pop("num_patches")
151
+ image_index = 0
152
+ processed_text = []
153
+ for prompt in text:
154
+ new_prompt = prompt
155
+ while "<image>" in new_prompt:
156
+ # Replace the image placeholder with structured image tokens
157
+ image_tokens = self._prompt_split_image(num_patches[image_index])
158
+ new_prompt = new_prompt.replace("<image>", image_tokens, 1)
159
+ image_index += 1
160
+ processed_text.append(new_prompt)
161
+
162
+ if image_index != len(images):
163
+ raise ValueError("Number of image placeholders in the prompt does not match the number of images.")
164
+
165
+ text = processed_text
166
+
167
+ return_tensors = output_kwargs["text_kwargs"].pop("return_tensors", None)
168
+ return_mm_token_type_ids = output_kwargs["text_kwargs"].pop("return_mm_token_type_ids", False)
169
+ text_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"], return_tensors=None)
170
+
171
+ if return_mm_token_type_ids:
172
+ text_inputs["mm_token_type_ids"] = self.create_mm_token_type_ids(text_inputs["input_ids"])
173
+ return BatchFeature(data={**text_inputs, **image_inputs}, tensor_type=return_tensors)
174
+
175
+ def _get_num_multimodal_tokens(self, image_sizes=None, **kwargs):
176
+ """
177
+ Computes the number of placeholder tokens needed for multimodal inputs with the given sizes.
178
+
179
+ Args:
180
+ image_sizes (`list[list[int]]`, *optional*):
181
+ The input sizes formatted as (height, width) per each image.
182
+
183
+ Returns:
184
+ `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided
185
+ input modalities, along with other useful data.
186
+ """
187
+
188
+ vision_data = {}
189
+ if image_sizes is not None:
190
+ images_kwargs = AyaVisionProcessorKwargs._defaults.get("images_kwargs", {})
191
+ images_kwargs.update(kwargs)
192
+
193
+ num_image_patches = [
194
+ self.image_processor.get_number_of_image_patches(*image_size, images_kwargs)
195
+ for image_size in image_sizes
196
+ ]
197
+
198
+ token_per_patch = (self.img_size // self.patch_size) ** 2
199
+ num_image_tokens = [
200
+ token_per_patch + 3 + sum(token_per_patch + 1 for _ in range(1, num_patches))
201
+ for num_patches in num_image_patches
202
+ ] # Add +3 and +1 for BOI/EOI and image tile tokens
203
+ vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches})
204
+
205
+ return MultiModalData(**vision_data)
206
+
207
+
208
+ __all__ = ["AyaVisionProcessor"]
third_party/transformers/src/transformers/models/blt/__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
+ 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_blt import *
22
+ from .modeling_blt import *
23
+ from .tokenization_blt 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/blt/configuration_blt.py ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ """Blt 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, logging
21
+
22
+
23
+ logger = logging.get_logger(__name__)
24
+
25
+
26
+ @auto_docstring(checkpoint="itazap/blt-1b-hf")
27
+ @strict
28
+ class BltLocalEncoderConfig(PreTrainedConfig):
29
+ r"""
30
+ cross_attn_all_layers (`bool`, *optional*, defaults to `True`):
31
+ Whether all attention layers have cross attention.
32
+ cross_attn_k (`int`, *optional*, defaults to 2):
33
+ Number of cross-attention heads used in the model.
34
+ hidden_size_global (`int`, *int*, defaults to 2048):
35
+ Hidden size of the global transformer layer.
36
+ """
37
+
38
+ model_type = "blt_local_encoder"
39
+ default_theta = 500000.0
40
+
41
+ vocab_size: int = 260
42
+ cross_attn_all_layers: bool | None = False
43
+ cross_attn_k: int | None = 2
44
+ hidden_size_global: int | None = 2048
45
+ hidden_size: int = 1024
46
+ num_attention_heads: int = 16
47
+ num_key_value_heads: int | None = None
48
+ num_hidden_layers: int = 1
49
+ rms_norm_eps: float = 1e-5
50
+ dropout: float | int | None = 0.0
51
+ max_position_embeddings: int = 24576
52
+ rope_parameters: RopeParameters | dict | None = None
53
+ hidden_act: str = "silu"
54
+ intermediate_size: int | None = None
55
+ initializer_range: float = 0.02
56
+
57
+ def __post_init__(self, **kwargs):
58
+ self.num_key_value_heads = self.num_key_value_heads or self.num_attention_heads
59
+ self.intermediate_size = self.intermediate_size or int(8 * self.hidden_size / 3)
60
+ self.tie_word_embeddings = False
61
+ super().__post_init__(**kwargs)
62
+
63
+
64
+ @auto_docstring(checkpoint="itazap/blt-1b-hf")
65
+ @strict
66
+ class BltLocalDecoderConfig(PreTrainedConfig):
67
+ r"""
68
+ cross_attn_all_layers (`bool`, *optional*, defaults to `True`):
69
+ Whether all attention layers have cross attention.
70
+ cross_attn_k (`int`, *optional*, defaults to 2):
71
+ Number of cross-attention heads used in the model.
72
+ hidden_size_global (`int`, *int*, defaults to 2048):
73
+ Hidden size of the global transformer layer.
74
+ """
75
+
76
+ model_type = "blt_local_decoder"
77
+ default_theta = 500000.0
78
+
79
+ vocab_size: int = 260
80
+ cross_attn_all_layers: bool | None = True
81
+ cross_attn_k: int | None = 2
82
+ hidden_size_global: int | None = 2048
83
+ hidden_size: int = 1024
84
+ num_attention_heads: int = 16
85
+ num_key_value_heads: int | None = None
86
+ num_hidden_layers: int = 9
87
+ rms_norm_eps: float = 1e-5
88
+ dropout: float | int | None = 0.0
89
+ max_position_embeddings: int = 24576
90
+ rope_parameters: RopeParameters | dict | None = None
91
+ hidden_act: str = "silu"
92
+ intermediate_size: int = 2816
93
+ initializer_range: float = 0.02
94
+ pad_token_id: int | None = None
95
+ bos_token_id: int | None = None
96
+ eos_token_id: int | list[int] | None = None
97
+ tie_word_embeddings: bool = False
98
+
99
+ def __post_init__(self, **kwargs):
100
+ self.num_key_value_heads = self.num_key_value_heads or self.num_attention_heads
101
+ self.head_dim = self.hidden_size // self.num_attention_heads
102
+ self.intermediate_size = self.intermediate_size or int(8 * self.hidden_size / 3)
103
+ self.tie_word_embeddings = False # Force-set to False for BC
104
+ super().__post_init__(**kwargs)
105
+
106
+
107
+ @auto_docstring(checkpoint="itazap/blt-1b-hf")
108
+ @strict
109
+ class BltGlobalTransformerConfig(PreTrainedConfig):
110
+ model_type = "blt_global_transformer"
111
+ default_theta = 500000.0
112
+
113
+ hidden_size: int = 2048
114
+ num_attention_heads: int = 16
115
+ num_key_value_heads: int | None = None
116
+ num_hidden_layers: int = 25
117
+ rms_norm_eps: float = 1e-5
118
+ dropout: float | int | None = 0.0
119
+ max_position_embeddings: int = 4096
120
+ rope_parameters: RopeParameters | dict | None = None
121
+ hidden_act: str = "silu"
122
+ intermediate_size: int = 5632
123
+ initializer_range: float = 0.02
124
+ tie_word_embeddings: bool = False
125
+
126
+ def __post_init__(self, **kwargs):
127
+ self.num_key_value_heads = self.num_key_value_heads or self.num_attention_heads
128
+ self.head_dim = self.hidden_size // self.num_attention_heads
129
+ self.intermediate_size = self.intermediate_size or int(8 * self.hidden_size / 3)
130
+ self.tie_word_embeddings = False
131
+
132
+ super().__post_init__(**kwargs)
133
+
134
+
135
+ @auto_docstring(checkpoint="itazap/blt-1b-hf")
136
+ @strict
137
+ class BltPatcherConfig(PreTrainedConfig):
138
+ model_type = "blt_patcher"
139
+
140
+ vocab_size: int = 260
141
+ hidden_size: int = 768
142
+ num_hidden_layers: int = 14
143
+ num_attention_heads: int = 12
144
+ num_key_value_heads: int | None = None
145
+ max_position_embeddings: int = 8192
146
+ rms_norm_eps: float = 1e-5
147
+ dropout: float | int | None = 0.0
148
+ intermediate_size: int = 2048
149
+ rope_parameters: RopeParameters | dict | None = None
150
+ initializer_range: float = 0.02
151
+ tie_word_embeddings: bool = False
152
+
153
+ def __post_init__(self, **kwargs):
154
+ self.num_key_value_heads = self.num_key_value_heads or self.num_attention_heads
155
+ self.head_dim = self.hidden_size // self.num_attention_heads
156
+ self.intermediate_size = self.intermediate_size or int(8 * self.hidden_size / 3)
157
+ self.tie_word_embeddings = False
158
+ self.hidden_act = "silu" # Blt uses silu activation
159
+
160
+ super().__post_init__(**kwargs)
161
+
162
+
163
+ @auto_docstring(checkpoint="itazap/blt-1b-hf")
164
+ @strict
165
+ class BltConfig(PreTrainedConfig):
166
+ r"""
167
+ patch_in_forward (`bool`, *optional*, defaults to `True`):
168
+ Whether to perform patching during the forward pass.
169
+ patch_size (`int`, *optional*, defaults to 4):
170
+ Size of the patches used in the patching mechanism.
171
+ patching_mode (`str`, *optional*, defaults to `"entropy"`):
172
+ The mode used for patching, such as entropy-based patching.
173
+ patching_threshold (`float`, *optional*, defaults to 1.34):
174
+ Threshold value used for determining when to apply patches.
175
+ patching_batch_size (`int`, *optional*, defaults to 1):
176
+ Batch size used during the patching process.
177
+ max_patch_length (`int`, *optional*):
178
+ Maximum length of patches that can be generated.
179
+ cross_attn_k (`int`, *optional*, defaults to 2):
180
+ Number of cross-attention heads used in the model.
181
+ encoder_hash_byte_group_size (`list`, *optional*):
182
+ List of byte group sizes used in the encoder hash function.
183
+ encoder_hash_byte_group_vocab (`int`, *optional*, defaults to 500002):
184
+ Vocabulary size for the encoder hash byte groups.
185
+ encoder_hash_byte_group_nb_functions (`int`, *optional*, defaults to 1):
186
+ Number of hash functions used in the encoder byte grouping.
187
+ patcher_config (`BltPatcherConfig`, *optional*):
188
+ Configuration for the patcher component of the model.
189
+ global_config (`BltGlobalTransformerConfig`, *optional*):
190
+ Configuration for the global transformer component of the model.
191
+
192
+ Example:
193
+ ```python
194
+ >>> from transformers import BltModel, BltConfig
195
+
196
+ >>> # Initializing a Blt configuration
197
+ >>> configuration = BltConfig()
198
+
199
+ >>> # Initializing a model from the configuration
200
+ >>> model = BltModel(configuration)
201
+
202
+ >>> # Accessing the model configuration
203
+ >>> configuration = model.config
204
+ ```"""
205
+
206
+ model_type = "blt"
207
+ keys_to_ignore_at_inference = ["past_key_values"]
208
+ default_theta = 500000.0
209
+ sub_configs = {
210
+ "patcher_config": BltPatcherConfig,
211
+ "encoder_config": BltLocalEncoderConfig,
212
+ "decoder_config": BltLocalDecoderConfig,
213
+ "global_config": BltGlobalTransformerConfig,
214
+ }
215
+
216
+ vocab_size: int = 260
217
+ max_position_embeddings: int = 4096
218
+ patch_in_forward: bool | None = True
219
+ patch_size: int | None = 4
220
+ patching_mode: str | None = "entropy"
221
+ patching_threshold: float | None = 1.335442066192627
222
+ patching_batch_size: int | None = 1
223
+ max_patch_length: int | None = None
224
+ cross_attn_k: int | None = 2
225
+ encoder_hash_byte_group_size: list[int] | None = None
226
+ encoder_hash_byte_group_vocab: int | None = 500002
227
+ encoder_hash_byte_group_nb_functions: int | None = 1
228
+ patcher_config: dict | PreTrainedConfig | None = None
229
+ encoder_config: dict | PreTrainedConfig | None = None
230
+ decoder_config: dict | PreTrainedConfig | None = None
231
+ global_config: dict | PreTrainedConfig | None = None
232
+ tie_word_embeddings: bool = False
233
+ pad_token_id: int | None = None
234
+ bos_token_id: int | None = None
235
+ eos_token_id: int | list[int] | None = None
236
+ initializer_range: float = 0.02
237
+ rope_parameters: RopeParameters | dict | None = None
238
+
239
+ def __post_init__(self, **kwargs):
240
+ self.encoder_hash_byte_group_size = self.encoder_hash_byte_group_size or [3, 4, 5, 6, 7, 8]
241
+
242
+ # Initialize component configurations
243
+ if self.patcher_config is None:
244
+ self.patcher_config = BltPatcherConfig(initializer_range=self.initializer_range)
245
+ logger.info("patcher_config is None, using default Blt patcher config")
246
+ elif isinstance(self.patcher_config, dict):
247
+ self.patcher_config.setdefault("initializer_range", self.initializer_range)
248
+ self.patcher_config = BltPatcherConfig(**self.patcher_config)
249
+
250
+ if self.encoder_config is None:
251
+ self.encoder_config = BltLocalEncoderConfig(initializer_range=self.initializer_range)
252
+ logger.info("encoder_config is None, using default Blt encoder config")
253
+ elif isinstance(self.encoder_config, dict):
254
+ self.encoder_config.setdefault("initializer_range", self.initializer_range)
255
+ self.encoder_config = BltLocalEncoderConfig(**self.encoder_config)
256
+
257
+ if self.decoder_config is None:
258
+ self.decoder_config = BltLocalDecoderConfig(initializer_range=self.initializer_range)
259
+ logger.info("decoder_config is None, using default Blt decoder config")
260
+ elif isinstance(self.decoder_config, dict):
261
+ self.decoder_config.setdefault("initializer_range", self.initializer_range)
262
+ self.decoder_config = BltLocalDecoderConfig(**self.decoder_config)
263
+
264
+ if self.global_config is None:
265
+ self.global_config = BltGlobalTransformerConfig(initializer_range=self.initializer_range)
266
+ logger.info("global_config is None, using default Blt global config")
267
+ elif isinstance(self.global_config, dict):
268
+ self.global_config.setdefault("initializer_range", self.initializer_range)
269
+ self.global_config = BltGlobalTransformerConfig(**self.global_config)
270
+
271
+ # Determine if token embedding projection is needed based on dimension mismatch (7b)
272
+ encoder_cross_output_size = self.encoder_config.hidden_size * self.cross_attn_k
273
+ self.global_config.encoder_cross_output_size = (
274
+ encoder_cross_output_size if encoder_cross_output_size != self.global_config.hidden_size else None
275
+ )
276
+
277
+ super().__post_init__(**kwargs)
278
+
279
+
280
+ __all__ = [
281
+ "BltConfig",
282
+ "BltPatcherConfig",
283
+ "BltLocalEncoderConfig",
284
+ "BltLocalDecoderConfig",
285
+ "BltGlobalTransformerConfig",
286
+ ]
third_party/transformers/src/transformers/models/blt/convert_blt_weights_to_hf.py ADDED
@@ -0,0 +1,487 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import json
3
+ import logging
4
+ import os
5
+ from typing import Any
6
+
7
+ import torch
8
+ from huggingface_hub import hf_hub_download, upload_folder
9
+ from safetensors.torch import load_file, save_file
10
+ from tokenizers import Tokenizer, decoders, pre_tokenizers, processors
11
+ from tokenizers.models import BPE
12
+
13
+ from transformers import PreTrainedTokenizerFast
14
+ from transformers.convert_slow_tokenizer import bytes_to_unicode
15
+ from transformers.utils import logging as transformers_logging
16
+
17
+
18
+ logger = transformers_logging.get_logger(__name__)
19
+ transformers_logging.set_verbosity_info()
20
+
21
+
22
+ def merge_configurations(config_path: str, entropy_params_path: str) -> dict[str, Any]:
23
+ logger.info("Merging configurations")
24
+
25
+ with open(config_path, "r") as f:
26
+ main_config = json.load(f)
27
+
28
+ with open(entropy_params_path, "r") as f:
29
+ entropy_data = json.load(f)
30
+
31
+ entropy_model_params = entropy_data.get("entropy_model", {})
32
+ patcher_args = entropy_data.get("data", {}).get("patcher_args", {})
33
+
34
+ unified_config = main_config.copy()["args"]
35
+
36
+ for key in ["vocab_size", "dim", "n_layers", "n_heads", "max_seqlen"]:
37
+ if key in unified_config and not isinstance(unified_config[key], int):
38
+ unified_config[key] = int(unified_config[key])
39
+
40
+ patch_size = patcher_args.get("patch_size", 8)
41
+ if isinstance(patch_size, float):
42
+ patch_size = int(patch_size)
43
+
44
+ # Create patcher config
45
+ patcher_hidden_size = int(entropy_model_params.get("dim", 512))
46
+ patcher_multiple_of = int(entropy_model_params.get("multiple_of", 256))
47
+ patcher_intermediate_size = patcher_multiple_of * (
48
+ (int(8 * patcher_hidden_size / 3) + patcher_multiple_of - 1) // patcher_multiple_of
49
+ )
50
+
51
+ patcher_config = {
52
+ "vocab_size": int(entropy_model_params.get("vocab_size", 256)),
53
+ "hidden_size": patcher_hidden_size,
54
+ "num_hidden_layers": int(entropy_model_params.get("n_layers", 8)),
55
+ "num_attention_heads": int(entropy_model_params.get("n_heads", 8)),
56
+ "num_key_value_heads": int(entropy_model_params.get("n_kv_heads"))
57
+ if entropy_model_params.get("n_kv_heads") is not None
58
+ else None,
59
+ "max_position_embeddings": int(entropy_model_params.get("max_seqlen", 1024)),
60
+ "norm_eps": entropy_model_params.get("norm_eps", 1e-5),
61
+ "dropout": entropy_model_params.get("dropout", 0.0),
62
+ "rope_theta": entropy_model_params.get("rope_theta", 10000.0),
63
+ "attn_impl": entropy_model_params.get("attn_impl", "sdpa"),
64
+ "attn_bias_type": entropy_model_params.get("attn_bias_type", "causal"),
65
+ "intermediate_size": patcher_intermediate_size,
66
+ }
67
+
68
+ # Create encoder config
69
+ encoder_hidden_size = unified_config.get("dim_local_encoder", 1024)
70
+ encoder_multiple_of = unified_config.get("multiple_of", 256)
71
+ encoder_intermediate_size = encoder_multiple_of * (
72
+ (int(8 * encoder_hidden_size / 3) + encoder_multiple_of - 1) // encoder_multiple_of
73
+ )
74
+
75
+ encoder_config = {
76
+ "vocab_size": unified_config.get("vocab_size", 256),
77
+ "cross_attn_all_layers": unified_config.get("cross_attn_all_layers_encoder", False),
78
+ "cross_attn_k": unified_config.get("cross_attn_k", 2),
79
+ "hidden_size_global": unified_config.get("dim_global", 2048),
80
+ "pm_size": unified_config.get("pm_size", 0),
81
+ "hidden_size": encoder_hidden_size,
82
+ "num_attention_heads": unified_config.get("n_heads_local_encoder", 16),
83
+ "num_key_value_heads": unified_config.get("n_kv_heads"),
84
+ "num_hidden_layers": unified_config.get("n_layers_local_encoder", 1),
85
+ "norm_eps": unified_config.get("norm_eps", 1e-5),
86
+ "dropout": unified_config.get("dropout", 0.0),
87
+ "max_position_embeddings": unified_config.get("max_encoder_seq_length")
88
+ or unified_config.get("max_seqlen", 1024),
89
+ "rope_theta": unified_config.get("rope_theta", 10000.0),
90
+ "rope_parameters": {"rope_type": "default"},
91
+ "hidden_act": unified_config.get("hidden_act", "silu"),
92
+ "_attn_implementation": unified_config.get("_attn_implementation", "sdpa"),
93
+ "intermediate_size": encoder_intermediate_size,
94
+ }
95
+
96
+ # Create decoder config
97
+ decoder_hidden_size = unified_config.get("dim_local_decoder", 1024)
98
+ decoder_multiple_of = unified_config.get("multiple_of", 256)
99
+ decoder_intermediate_size = decoder_multiple_of * (
100
+ (int(8 * decoder_hidden_size / 3) + decoder_multiple_of - 1) // decoder_multiple_of
101
+ )
102
+
103
+ decoder_config = {
104
+ "vocab_size": unified_config.get("vocab_size", 256),
105
+ "cross_attn_all_layers": unified_config.get("cross_attn_all_layers_decoder", False),
106
+ "cross_attn_k": unified_config.get("cross_attn_k", 2),
107
+ "hidden_size_global": unified_config.get("dim_global", 2048),
108
+ "hidden_size": decoder_hidden_size,
109
+ "num_attention_heads": unified_config.get("n_heads_local_decoder", 16),
110
+ "num_key_value_heads": unified_config.get("n_kv_heads"),
111
+ "num_hidden_layers": unified_config.get("n_layers_local_decoder", 9),
112
+ "norm_eps": unified_config.get("norm_eps", 1e-5),
113
+ "dropout": unified_config.get("dropout", 0.0),
114
+ "max_position_embeddings": unified_config.get("max_encoder_seq_length")
115
+ or unified_config.get("max_seqlen", 1024),
116
+ "rope_theta": unified_config.get("rope_theta", 10000.0),
117
+ "rope_parameters": {"rope_type": "default"},
118
+ "hidden_act": unified_config.get("hidden_act", "silu"),
119
+ "_attn_implementation": unified_config.get("_attn_implementation", "sdpa"),
120
+ "intermediate_size": decoder_intermediate_size,
121
+ }
122
+
123
+ # Create global transformer config
124
+ global_hidden_size = unified_config.get("dim_global", 2048)
125
+ global_multiple_of = unified_config.get("multiple_of", 256)
126
+ global_intermediate_size = global_multiple_of * (
127
+ (int(8 * global_hidden_size / 3) + global_multiple_of - 1) // global_multiple_of
128
+ )
129
+
130
+ global_config = {
131
+ "hidden_size": global_hidden_size,
132
+ "num_attention_heads": unified_config.get("n_heads_global", 16),
133
+ "num_key_value_heads": unified_config.get("n_kv_heads_global"),
134
+ "num_hidden_layers": unified_config.get("n_layers_global", 25),
135
+ "norm_eps": unified_config.get("norm_eps", 1e-5),
136
+ "dropout": unified_config.get("dropout", 0.0),
137
+ "max_position_embeddings": unified_config.get("max_seqlen", 1024),
138
+ "rope_theta": unified_config.get("rope_theta", 10000.0),
139
+ "rope_parameters": {"rope_type": "default"},
140
+ "hidden_act": unified_config.get("hidden_act", "silu"),
141
+ "_attn_implementation": unified_config.get("_attn_implementation", "sdpa"),
142
+ "intermediate_size": global_intermediate_size,
143
+ }
144
+
145
+ # Create main config with sub-configs
146
+ main_config_dict = {
147
+ "model_type": "blt",
148
+ "vocab_size": unified_config.get("vocab_size", 256),
149
+ "max_position_embeddings": unified_config.get("max_seqlen", 1024),
150
+ "patch_in_forward": True,
151
+ "realtime_patching": True,
152
+ "patching_mode": "entropy",
153
+ "patch_size": patch_size,
154
+ "patching_threshold": patcher_args.get("threshold", 0.5),
155
+ "patching_threshold_add": patcher_args.get("threshold_add", 0.0),
156
+ "max_patch_length": patcher_args.get("max_patch_length"),
157
+ "patching_batch_size": patcher_args.get("patching_batch_size", 1),
158
+ "patching_device": patcher_args.get("patching_device", "cuda"),
159
+ "monotonicity": patcher_args.get("monotonicity", False),
160
+ "cross_attn_k": unified_config.get("cross_attn_k", 2),
161
+ "encoder_hash_byte_group_size": unified_config.get("encoder_hash_byte_group_size"),
162
+ "encoder_hash_byte_group_vocab": unified_config.get("encoder_hash_byte_group_vocab", 30000),
163
+ "encoder_hash_byte_group_nb_functions": unified_config.get("encoder_hash_byte_group_nb_functions", 3),
164
+ "pm_size": unified_config.get("pm_size", 0),
165
+ "patcher_config": patcher_config,
166
+ "encoder_config": encoder_config,
167
+ "decoder_config": decoder_config,
168
+ "global_config": global_config,
169
+ }
170
+
171
+ main_config_dict["tie_word_embeddings"] = False
172
+
173
+ logger.info(f"Merged configuration with {len(main_config_dict)} parameters")
174
+ return main_config_dict
175
+
176
+
177
+ def apply_weight_mapping(state_dict: dict[str, torch.Tensor]) -> dict[str, torch.Tensor]:
178
+ component_mappings = {
179
+ ".attention.": ".self_attn.",
180
+ ".feed_forward.": ".mlp.",
181
+ ".attention_norm.": ".input_layernorm.",
182
+ ".ffn_norm.": ".post_attention_layernorm.",
183
+ ".tok_embeddings.": ".embed_tokens.",
184
+ ".cross_attn_norm_q.": ".q_norm.",
185
+ ".cross_attn_norm_kv.": ".k_norm.",
186
+ ".w1.": ".gate_proj.",
187
+ ".w2.": ".down_proj.",
188
+ ".w3.": ".up_proj.",
189
+ ".wq.": ".q_proj.",
190
+ ".wk.": ".k_proj.",
191
+ ".wv.": ".v_proj.",
192
+ ".wo.": ".o_proj.",
193
+ ".output.": ".lm_head.",
194
+ }
195
+
196
+ new_state_dict = {}
197
+
198
+ for old_key, tensor in state_dict.items():
199
+ new_key = old_key
200
+
201
+ for old_pattern, new_pattern in component_mappings.items():
202
+ if old_pattern in new_key:
203
+ new_key = new_key.replace(old_pattern, new_pattern)
204
+
205
+ new_state_dict[new_key] = tensor
206
+
207
+ return new_state_dict
208
+
209
+
210
+ def convert_hash_embeddings_to_fused(
211
+ unified_weights: dict[str, torch.Tensor], config: dict[str, Any]
212
+ ) -> dict[str, torch.Tensor]:
213
+ """Convert ModuleList hash embeddings to nn.embedding format"""
214
+ original_keys_format = [
215
+ key
216
+ for key in unified_weights.keys()
217
+ if "encoder_hash_tok_embedding." in key and ".weight" in key and key.split(".")[-2].isdigit()
218
+ ]
219
+
220
+ num_embeddings = config.get("encoder_hash_byte_group_nb_functions", 1) * len(
221
+ config.get("encoder_hash_byte_group_size", [3, 4, 5, 6, 7, 8])
222
+ )
223
+ vocab_size = config.get("encoder_hash_byte_group_vocab", 500002)
224
+ hidden_size = config.get("encoder_config", {}).get("hidden_size", 1024)
225
+
226
+ fused_weight = torch.zeros(vocab_size * num_embeddings, hidden_size)
227
+
228
+ sorted_keys = sorted(original_keys_format, key=lambda k: int(k.split(".")[-2]))
229
+
230
+ for i, old_key in enumerate(sorted_keys):
231
+ start_idx = i * vocab_size
232
+ end_idx = (i + 1) * vocab_size
233
+ fused_weight[start_idx:end_idx] = unified_weights[old_key]
234
+ logger.info(f"Copied {old_key} to indices {start_idx}:{end_idx}")
235
+ del unified_weights[old_key]
236
+
237
+ fused_key = "model.encoder_hash_tok_embedding.weight"
238
+ unified_weights[fused_key] = fused_weight
239
+
240
+ return unified_weights
241
+
242
+
243
+ def merge_weights(weights_path: str, entropy_weights_path: str) -> dict[str, torch.Tensor]:
244
+ main_weights = load_file(weights_path)
245
+
246
+ entropy_weights = torch.load(entropy_weights_path, map_location="cpu", weights_only=True)
247
+
248
+ if "model" in entropy_weights:
249
+ entropy_weights = entropy_weights["model"]
250
+ elif "state_dict" in entropy_weights:
251
+ entropy_weights = entropy_weights["state_dict"]
252
+
253
+ unified_weights = main_weights.copy()
254
+
255
+ for key, tensor in entropy_weights.items():
256
+ patcher_key = f"patcher.{key}"
257
+ unified_weights[patcher_key] = tensor
258
+
259
+ unified_weights = apply_weight_mapping(unified_weights)
260
+
261
+ decoder_lm_head_key = "local_decoder.lm_head.weight"
262
+ top_lm_head_key = "lm_head.weight"
263
+ unified_weights[top_lm_head_key] = unified_weights[decoder_lm_head_key]
264
+ del unified_weights[decoder_lm_head_key]
265
+
266
+ prefixed_weights = {}
267
+ for key, tensor in unified_weights.items():
268
+ if key == top_lm_head_key:
269
+ prefixed_weights[key] = tensor
270
+ elif not key.startswith("model."):
271
+ prefixed_weights[f"model.{key}"] = tensor
272
+ else:
273
+ prefixed_weights[key] = tensor
274
+
275
+ unified_weights = prefixed_weights
276
+
277
+ return unified_weights
278
+
279
+
280
+ def create_tokenizer_config(output_dir: str, config: dict[str, Any]):
281
+ tokenizer_config = {
282
+ "tokenizer_class": "PreTrainedTokenizerFast",
283
+ "vocab_size": config.get("vocab_size", 256),
284
+ "model_max_length": config.get("max_seqlen", 1024),
285
+ "model_input_names": ["input_ids", "attention_mask"],
286
+ "add_bos_token": True,
287
+ "add_eos_token": True,
288
+ "bos_token": "<s>",
289
+ "eos_token": "</s>",
290
+ "pad_token": "<pad>",
291
+ "unk_token": "<unk>",
292
+ }
293
+
294
+ tokenizer_path = os.path.join(output_dir, "tokenizer_config.json")
295
+ with open(tokenizer_path, "w") as f:
296
+ json.dump(tokenizer_config, f, indent=2)
297
+
298
+
299
+ def create_tokenizer_json(output_dir: str, config: dict[str, Any]):
300
+ byte_encoder = bytes_to_unicode()
301
+
302
+ vocab: dict[str, int] = {}
303
+ vocab["<boe>"] = 0
304
+ vocab["<s>"] = 1
305
+ vocab["</s>"] = 2
306
+ vocab["<pad>"] = 3
307
+
308
+ offset = 4
309
+ for byte_val, unicode_char in byte_encoder.items():
310
+ vocab[unicode_char] = byte_val + offset
311
+
312
+ backend = Tokenizer(
313
+ BPE(vocab=vocab, merges=[], continuing_subword_prefix="", end_of_word_suffix="", fuse_unk=False)
314
+ )
315
+ backend.pre_tokenizer = pre_tokenizers.ByteLevel(add_prefix_space=False)
316
+ backend.decoder = decoders.ByteLevel()
317
+
318
+ bos = config.get("bos_token", "<s>")
319
+ backend.post_processor = processors.TemplateProcessing(
320
+ single=f"{bos}:0 $A:0",
321
+ pair=f"{bos}:0 $A:0 $B:1",
322
+ special_tokens=[(bos, 1)],
323
+ )
324
+
325
+ tokenizer = PreTrainedTokenizerFast(
326
+ tokenizer_object=backend,
327
+ bos_token=config.get("bos_token", "<s>"),
328
+ eos_token=config.get("eos_token", "</s>"),
329
+ pad_token=config.get("pad_token", "<pad>"),
330
+ unk_token=config.get("unk_token", "<unk>"),
331
+ )
332
+
333
+ tokenizer.add_bos_token = bool(config.get("add_bos_token", True))
334
+ tokenizer.add_eos_token = bool(config.get("add_eos_token", True))
335
+
336
+ tokenizer.save_pretrained(output_dir)
337
+ logger.info(f"Saved tokenizer.json to {os.path.join(output_dir, 'tokenizer.json')}")
338
+
339
+
340
+ def push_to_hub(
341
+ local_dir: str,
342
+ repo_id: str,
343
+ commit_message: str = "Upload converted Blt model",
344
+ private: bool = False,
345
+ token: str | None = None,
346
+ ) -> None:
347
+ try:
348
+ upload_folder(
349
+ folder_path=local_dir,
350
+ repo_id=repo_id,
351
+ commit_message=commit_message,
352
+ repo_type="model",
353
+ token=token,
354
+ )
355
+ logger.info(f"Successfully pushed model to {repo_id}")
356
+
357
+ except Exception as e:
358
+ logger.error(f"Failed to push model to Hub: {e}")
359
+ raise
360
+
361
+
362
+ def convert_hf_blt_to_unified(
363
+ model_id: str,
364
+ output_dir: str,
365
+ config_name: str = "config.json",
366
+ weights_name: str = "model.bin",
367
+ cache_dir: str | None = None,
368
+ push_to_hub_repo: str | None = None,
369
+ hub_private: bool = False,
370
+ hub_token: str | None = None,
371
+ ) -> None:
372
+ # Download model files
373
+ config_path = hf_hub_download(repo_id=model_id, filename="config.json", cache_dir=cache_dir)
374
+ weights_path = hf_hub_download(repo_id=model_id, filename="model.safetensors", cache_dir=cache_dir)
375
+ entropy_params_path = hf_hub_download(repo_id=model_id, filename="entropy_model/params.json", cache_dir=cache_dir)
376
+ entropy_weights_path = hf_hub_download(
377
+ repo_id=model_id, filename="entropy_model/consolidated.pth", cache_dir=cache_dir
378
+ )
379
+
380
+ unified_config = merge_configurations(config_path, entropy_params_path)
381
+ unified_weights = merge_weights(weights_path, entropy_weights_path)
382
+
383
+ unified_weights = convert_hash_embeddings_to_fused(unified_weights, unified_config)
384
+
385
+ os.makedirs(output_dir, exist_ok=True)
386
+
387
+ config_path = os.path.join(output_dir, config_name)
388
+ with open(config_path, "w") as f:
389
+ json.dump(unified_config, f, indent=2)
390
+
391
+ if weights_name.endswith(".bin"):
392
+ weights_name = weights_name.replace(".bin", ".safetensors")
393
+
394
+ weights_path = os.path.join(output_dir, weights_name)
395
+ save_file(unified_weights, weights_path)
396
+
397
+ create_tokenizer_json(output_dir=output_dir, config=unified_config)
398
+
399
+ create_tokenizer_config(output_dir, unified_config)
400
+
401
+ logger.info(f"Conversion completed, model saved to: {output_dir}")
402
+
403
+ if push_to_hub_repo:
404
+ push_to_hub(
405
+ local_dir=output_dir,
406
+ repo_id=push_to_hub_repo,
407
+ commit_message="Upload Blt model converted",
408
+ private=hub_private,
409
+ token=hub_token,
410
+ )
411
+
412
+
413
+ def main():
414
+ parser = argparse.ArgumentParser(
415
+ description="Convert Blt models from HuggingFace Hub format to unified format",
416
+ formatter_class=argparse.RawDescriptionHelpFormatter,
417
+ )
418
+
419
+ parser.add_argument(
420
+ "--model_id",
421
+ type=str,
422
+ default="facebook/blt-7b",
423
+ )
424
+ parser.add_argument(
425
+ "--output_dir",
426
+ type=str,
427
+ default="./blt_converted",
428
+ )
429
+ parser.add_argument(
430
+ "--config_name",
431
+ type=str,
432
+ default="config.json",
433
+ )
434
+ parser.add_argument(
435
+ "--weights_name",
436
+ type=str,
437
+ default="model.bin",
438
+ )
439
+ parser.add_argument(
440
+ "--cache_dir",
441
+ type=str,
442
+ default=None,
443
+ )
444
+ parser.add_argument(
445
+ "--debug",
446
+ action="store_true",
447
+ default=True,
448
+ )
449
+ parser.add_argument(
450
+ "--push_to_hub",
451
+ type=str,
452
+ default=None,
453
+ )
454
+ parser.add_argument(
455
+ "--hub_private",
456
+ action="store_true",
457
+ default=False,
458
+ )
459
+ parser.add_argument(
460
+ "--hub_token",
461
+ type=str,
462
+ default="hf_token",
463
+ )
464
+
465
+ args = parser.parse_args()
466
+
467
+ transformers_logging.set_verbosity_debug()
468
+ logging.basicConfig(level=logging.DEBUG)
469
+
470
+ try:
471
+ convert_hf_blt_to_unified(
472
+ model_id=args.model_id,
473
+ output_dir=args.output_dir,
474
+ config_name=args.config_name,
475
+ weights_name=args.weights_name,
476
+ cache_dir=args.cache_dir,
477
+ push_to_hub_repo=False, # args.push_to_hub,
478
+ hub_private=args.hub_private,
479
+ hub_token=args.hub_token,
480
+ )
481
+ except Exception as e:
482
+ logger.error(f"Conversion failed: {e}")
483
+ raise
484
+
485
+
486
+ if __name__ == "__main__":
487
+ main()
third_party/transformers/src/transformers/models/blt/modeling_blt.py ADDED
@@ -0,0 +1,1463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/blt/modular_blt.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_blt.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 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 collections.abc import Callable
22
+ from typing import Optional
23
+
24
+ import torch
25
+ import torch.distributions
26
+ import torch.nn as nn
27
+ import torch.nn.functional as F
28
+
29
+ from ... import initialization as init
30
+ from ...activations import ACT2FN
31
+ from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
32
+ from ...generation import GenerationMixin
33
+ from ...masking_utils import create_causal_mask
34
+ from ...modeling_flash_attention_utils import FlashAttentionKwargs
35
+ from ...modeling_layers import GradientCheckpointingLayer
36
+ from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
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.deprecation import deprecate_kwarg
42
+ from ...utils.generic import maybe_autocast, merge_with_config_defaults
43
+ from ...utils.output_capturing import OutputRecorder, capture_outputs
44
+ from .configuration_blt import (
45
+ BltConfig,
46
+ BltGlobalTransformerConfig,
47
+ BltLocalDecoderConfig,
48
+ BltLocalEncoderConfig,
49
+ BltPatcherConfig,
50
+ )
51
+
52
+
53
+ class BltMLP(nn.Module):
54
+ def __init__(self, config):
55
+ super().__init__()
56
+ self.config = config
57
+ self.hidden_size = config.hidden_size
58
+ self.intermediate_size = config.intermediate_size
59
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
60
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
61
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
62
+ # Ignore copy
63
+ self.act_fn = ACT2FN[config.hidden_act]
64
+
65
+ def forward(self, x):
66
+ down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
67
+ return down_proj
68
+
69
+
70
+ class BltRMSNorm(nn.Module):
71
+ def __init__(self, hidden_size, eps: float = 1e-6) -> None:
72
+ """
73
+ BltRMSNorm is equivalent to T5LayerNorm
74
+ """
75
+ super().__init__()
76
+ self.weight = nn.Parameter(torch.ones(hidden_size))
77
+ self.variance_epsilon = eps
78
+
79
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
80
+ input_dtype = hidden_states.dtype
81
+ hidden_states = hidden_states.to(torch.float32)
82
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
83
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
84
+ return self.weight * hidden_states.to(input_dtype)
85
+
86
+ def extra_repr(self):
87
+ return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
88
+
89
+
90
+ class BltRotaryEmbedding(nn.Module):
91
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
92
+
93
+ def __init__(self, config: BltConfig, device=None):
94
+ super().__init__()
95
+ self.max_seq_len_cached = config.max_position_embeddings
96
+ self.original_max_seq_len = config.max_position_embeddings
97
+
98
+ self.config = config
99
+
100
+ self.rope_type = self.config.rope_parameters["rope_type"]
101
+ rope_init_fn: Callable = self.compute_default_rope_parameters
102
+ if self.rope_type != "default":
103
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
104
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
105
+
106
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
107
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
108
+
109
+ @staticmethod
110
+ def compute_default_rope_parameters(
111
+ config: BltConfig | None = None,
112
+ device: Optional["torch.device"] = None,
113
+ seq_len: int | None = None,
114
+ ) -> tuple["torch.Tensor", float]:
115
+ """
116
+ Computes the inverse frequencies according to the original RoPE implementation
117
+ Args:
118
+ config ([`~transformers.PreTrainedConfig`]):
119
+ The model configuration.
120
+ device (`torch.device`):
121
+ The device to use for initialization of the inverse frequencies.
122
+ seq_len (`int`, *optional*):
123
+ The current sequence length. Unused for this type of RoPE.
124
+ Returns:
125
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
126
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
127
+ """
128
+ base = config.rope_parameters["rope_theta"]
129
+ dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
130
+
131
+ attention_factor = 1.0 # Unused in this type of RoPE
132
+
133
+ # Compute the inverse frequencies
134
+ inv_freq = 1.0 / (
135
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
136
+ )
137
+ return inv_freq, attention_factor
138
+
139
+ @torch.no_grad()
140
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
141
+ def forward(self, x, position_ids):
142
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1)
143
+ position_ids_expanded = position_ids[:, None, :].float()
144
+
145
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
146
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
147
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
148
+ emb = torch.repeat_interleave(freqs, 2, dim=-1) # diff from Llama: we interleave() instead of cat()
149
+ cos = emb.cos() * self.attention_scaling
150
+ sin = emb.sin() * self.attention_scaling
151
+
152
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
153
+
154
+
155
+ # Modified from transformers.models.llama.modeling_llama.LlamaDecoderLayer
156
+ class BltTransformerLayer(GradientCheckpointingLayer):
157
+ def __init__(self, config, layer_idx: int):
158
+ super().__init__()
159
+ self.hidden_size = config.hidden_size
160
+
161
+ self.self_attn = BltSelfAttention(config=config, layer_idx=layer_idx)
162
+ self.mlp = BltMLP(config)
163
+ self.input_layernorm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
164
+ self.post_attention_layernorm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
165
+
166
+ self.layer_idx = layer_idx
167
+
168
+ def forward(
169
+ self,
170
+ hidden_states: torch.Tensor,
171
+ cross_attention_states: torch.Tensor | None = None,
172
+ cross_attention_mask: torch.Tensor | None = None,
173
+ attention_mask: torch.Tensor | None = None,
174
+ full_text_row_masked_out_mask: tuple[torch.Tensor, torch.Tensor] | None = None,
175
+ position_ids: torch.LongTensor | None = None,
176
+ past_key_values: Cache | None = None,
177
+ use_cache: bool | None = False,
178
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
179
+ **kwargs: Unpack[FlashAttentionKwargs],
180
+ ) -> tuple[torch.FloatTensor, tuple[torch.FloatTensor, torch.FloatTensor] | None]:
181
+ """
182
+ Args:
183
+ hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
184
+ attention_mask (`torch.FloatTensor`, *optional*):
185
+ attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1,
186
+ query_sequence_length, key_sequence_length)` if default attention is used.
187
+
188
+ use_cache (`bool`, *optional*):
189
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
190
+ (see `past_key_values`).
191
+ past_key_values (`Cache`, *optional*): cached past key and value projection states
192
+ position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*):
193
+ Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`,
194
+ with `head_dim` being the embedding dimension of each attention head.
195
+ kwargs (`dict`, *optional*):
196
+ Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code
197
+ into the model
198
+ """
199
+ residual = hidden_states
200
+
201
+ hidden_states = self.input_layernorm(hidden_states)
202
+
203
+ # Self Attention
204
+ hidden_states, self_attn_weights = self.self_attn(
205
+ hidden_states=hidden_states,
206
+ attention_mask=attention_mask,
207
+ position_ids=position_ids,
208
+ past_key_values=past_key_values,
209
+ use_cache=use_cache,
210
+ position_embeddings=position_embeddings,
211
+ **kwargs,
212
+ )
213
+ hidden_states = residual + hidden_states
214
+
215
+ # Fully Connected
216
+ residual = hidden_states
217
+ hidden_states = self.post_attention_layernorm(hidden_states)
218
+ hidden_states = self.mlp(hidden_states)
219
+ hidden_states = residual + hidden_states
220
+
221
+ return hidden_states
222
+
223
+
224
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
225
+ """
226
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
227
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
228
+ """
229
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
230
+ if n_rep == 1:
231
+ return hidden_states
232
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
233
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
234
+
235
+
236
+ def eager_attention_forward(
237
+ module: nn.Module,
238
+ query: torch.Tensor,
239
+ key: torch.Tensor,
240
+ value: torch.Tensor,
241
+ attention_mask: torch.Tensor | None,
242
+ scaling: float,
243
+ dropout: float = 0.0,
244
+ **kwargs: Unpack[TransformersKwargs],
245
+ ):
246
+ key_states = repeat_kv(key, module.num_key_value_groups)
247
+ value_states = repeat_kv(value, module.num_key_value_groups)
248
+
249
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
250
+ if attention_mask is not None:
251
+ attn_weights = attn_weights + attention_mask
252
+
253
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
254
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
255
+ attn_output = torch.matmul(attn_weights, value_states)
256
+ attn_output = attn_output.transpose(1, 2).contiguous()
257
+
258
+ return attn_output, attn_weights
259
+
260
+
261
+ def rotate_half(x):
262
+ # Split and rotate. Note that this function is different from e.g. Llama.
263
+ x1 = x[..., ::2]
264
+ x2 = x[..., 1::2]
265
+ rot_x = torch.stack([-x2, x1], dim=-1).flatten(-2)
266
+ return rot_x
267
+
268
+
269
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
270
+ """Applies Rotary Position Embedding to the query and key tensors.
271
+
272
+ Args:
273
+ q (`torch.Tensor`): The query tensor.
274
+ k (`torch.Tensor`): The key tensor.
275
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
276
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
277
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
278
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
279
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
280
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
281
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
282
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
283
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
284
+ Returns:
285
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
286
+ """
287
+ cos = cos.unsqueeze(unsqueeze_dim)
288
+ sin = sin.unsqueeze(unsqueeze_dim)
289
+ q_embed = (q * cos) + (rotate_half(q) * sin)
290
+ k_embed = (k * cos) + (rotate_half(k) * sin)
291
+ return q_embed, k_embed
292
+
293
+
294
+ class BltSelfAttention(nn.Module):
295
+ def __init__(self, config: BltConfig, layer_idx: int):
296
+ super().__init__()
297
+ self.config = config
298
+ self.num_heads = config.num_attention_heads
299
+ self.dropout = config.dropout
300
+ self.hidden_size = config.hidden_size
301
+ self.num_key_value_heads = config.num_key_value_heads
302
+ self.head_dim = config.hidden_size // self.num_heads
303
+ self.num_key_value_groups = self.num_heads // self.num_key_value_heads
304
+ self.scaling = self.head_dim**-0.5
305
+
306
+ self.layer_idx = layer_idx
307
+ self.is_causal = True
308
+
309
+ self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
310
+ self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False)
311
+ self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False)
312
+ self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False)
313
+
314
+ def forward(
315
+ self,
316
+ hidden_states: torch.Tensor,
317
+ attention_mask: torch.Tensor,
318
+ position_embeddings: torch.Tensor,
319
+ past_key_values=None,
320
+ **kwargs,
321
+ ):
322
+ bsz, q_len, _ = hidden_states.size()
323
+
324
+ query_states = self.q_proj(hidden_states)
325
+ key_states = self.k_proj(hidden_states)
326
+ value_states = self.v_proj(hidden_states)
327
+
328
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
329
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
330
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
331
+
332
+ cos, sin = position_embeddings
333
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
334
+
335
+ if past_key_values is not None:
336
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
337
+
338
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
339
+ self.config._attn_implementation, eager_attention_forward
340
+ )
341
+
342
+ attn_output, attn_weights = attention_interface(
343
+ self,
344
+ query_states,
345
+ key_states,
346
+ value_states,
347
+ attention_mask,
348
+ dropout=0.0 if not self.training else self.dropout,
349
+ scaling=self.scaling,
350
+ **kwargs,
351
+ )
352
+
353
+ attn_output = attn_output.reshape(bsz, q_len, -1).contiguous()
354
+ attn_output = self.o_proj(attn_output)
355
+
356
+ return attn_output, attn_weights
357
+
358
+
359
+ class BltCrossAttention(nn.Module):
360
+ """Cross-attention module for Blt, following transformers style"""
361
+
362
+ def __init__(self, config: BltConfig, layer_idx: int, hidden_size: int | None = None):
363
+ super().__init__()
364
+ self.config = config
365
+ self.num_heads = self.config.num_attention_heads
366
+ self.num_key_value_heads = self.config.num_key_value_heads
367
+ self.dropout = config.dropout
368
+ self.hidden_size = config.hidden_size
369
+ self.head_dim = config.hidden_size // self.num_heads
370
+ self.layer_idx = layer_idx
371
+ self.num_key_value_groups = self.num_heads // self.num_key_value_heads
372
+ self.scaling = self.head_dim**-0.5
373
+
374
+ self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
375
+ self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False)
376
+ self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False)
377
+ self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False)
378
+ self.q_norm = BltRMSNorm(self.hidden_size, eps=config.rms_norm_eps)
379
+ self.k_norm = BltRMSNorm(self.hidden_size, eps=config.rms_norm_eps)
380
+ self.is_causal = False
381
+
382
+ def forward(
383
+ self,
384
+ hidden_states: torch.Tensor,
385
+ cross_attention_states: torch.Tensor | None = None,
386
+ attention_mask: torch.Tensor | None = None,
387
+ **kwargs: Unpack[TransformersKwargs],
388
+ ) -> tuple[torch.Tensor, torch.Tensor | None, tuple[torch.Tensor] | None]:
389
+ """Input shape: Batch x Time x Channel"""
390
+ bsz, q_len, _ = hidden_states.size()
391
+ query_states = self.q_norm(hidden_states)
392
+ query_states = self.q_proj(query_states)
393
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
394
+
395
+ cross_attention_states = self.k_norm(cross_attention_states)
396
+ key_states = self.k_proj(cross_attention_states)
397
+ value_states = self.v_proj(cross_attention_states)
398
+ key_states = key_states.view(bsz, -1, self.num_key_value_heads, self.head_dim).transpose(1, 2)
399
+ value_states = value_states.view(bsz, -1, self.num_key_value_heads, self.head_dim).transpose(1, 2)
400
+
401
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
402
+ self.config._attn_implementation, eager_attention_forward
403
+ )
404
+
405
+ attn_output, attn_weights = attention_interface(
406
+ self,
407
+ query_states,
408
+ key_states,
409
+ value_states,
410
+ attention_mask,
411
+ dropout=0.0 if not self.training else self.dropout,
412
+ scaling=self.scaling,
413
+ **kwargs,
414
+ )
415
+ attn_output = attn_output.reshape(bsz, q_len, -1).contiguous()
416
+ attn_output = self.o_proj(attn_output)
417
+ attn_output = attn_output + hidden_states
418
+ return attn_output, attn_weights
419
+
420
+
421
+ @auto_docstring
422
+ class BltPreTrainedModel(PreTrainedModel):
423
+ config: BltConfig
424
+ base_model_prefix = "model"
425
+ input_modalities = ("image", "text")
426
+ supports_gradient_checkpointing = True
427
+ _no_split_modules = ["BltTransformerLayer"]
428
+ _can_compile_fullgraph = False # static cache cannot have different shapes for each layer
429
+ _supports_sdpa = True
430
+ _supports_flash_attn = False
431
+ _supports_flex_attn = False
432
+ _supports_attention_backend = False
433
+ _can_record_outputs = {
434
+ "hidden_states": OutputRecorder(BltTransformerLayer, index=0),
435
+ "attentions": OutputRecorder(BltSelfAttention, index=1),
436
+ }
437
+
438
+ @torch.no_grad()
439
+ def _init_weights(self, module):
440
+ """
441
+ Initialize BLT weights following the original ByteLatentTransformer:
442
+
443
+ - Most weights are drawn from a truncated normal.
444
+ - Scale is ~ 1 / sqrt(model_dim) (or 1 / sqrt(hidden_dim) for FFN outputs).
445
+ - Norm layers are set to weight = 1, bias = 0.
446
+ """
447
+ class_name = module.__class__.__name__
448
+
449
+ # Norms: RMSNorm / LayerNorm
450
+ if isinstance(module, (BltRMSNorm, nn.LayerNorm)) or "RMSNorm" in class_name or "LayerNorm" in class_name:
451
+ if getattr(module, "weight", None) is not None:
452
+ init.ones_(module.weight)
453
+ if getattr(module, "bias", None) is not None:
454
+ init.zeros_(module.bias)
455
+ return
456
+
457
+ # Embeddings (encoder / patcher / hash embeddings)
458
+ if isinstance(module, nn.Embedding):
459
+ hidden_size = getattr(self.config, "hidden_size", None)
460
+ if hidden_size is None and hasattr(self.config, "encoder_config"):
461
+ hidden_size = getattr(self.config.encoder_config, "hidden_size", None)
462
+ if hidden_size is None:
463
+ hidden_size = module.embedding_dim
464
+
465
+ std = hidden_size**-0.5
466
+ init.trunc_normal_(
467
+ module.weight,
468
+ mean=0.0,
469
+ std=std,
470
+ a=-3 * std,
471
+ b=3 * std,
472
+ )
473
+ if module.padding_idx is not None:
474
+ init.zeros_(module.weight[module.padding_idx])
475
+ return
476
+
477
+ # Self-attention / cross-attention projections
478
+ if isinstance(module, (BltSelfAttention, BltCrossAttention)) or class_name in (
479
+ "MllamaTextSelfAttention",
480
+ "MllamaTextCrossAttention",
481
+ ):
482
+ dim = getattr(self.config, "hidden_size", None)
483
+ if dim is None and hasattr(module, "hidden_size"):
484
+ dim = module.hidden_size
485
+ if dim is None:
486
+ for name in ("q_proj", "k_proj", "v_proj", "o_proj", "dense"):
487
+ proj = getattr(module, name, None)
488
+ if proj is not None and hasattr(proj, "weight"):
489
+ dim = proj.weight.shape[-1]
490
+ break
491
+ if dim is None:
492
+ return
493
+
494
+ std = dim**-0.5
495
+
496
+ # Input projections (q, k, v)
497
+ for proj_name in ("q_proj", "k_proj", "v_proj"):
498
+ proj = getattr(module, proj_name, None)
499
+ if proj is not None and hasattr(proj, "weight"):
500
+ init.trunc_normal_(
501
+ proj.weight,
502
+ mean=0.0,
503
+ std=std,
504
+ a=-3 * std,
505
+ b=3 * std,
506
+ )
507
+ if getattr(proj, "bias", None) is not None:
508
+ init.zeros_(proj.bias)
509
+
510
+ # Output projection: o_proj or dense
511
+ o_proj = getattr(module, "o_proj", getattr(module, "dense", None))
512
+ if o_proj is not None and hasattr(o_proj, "weight"):
513
+ init.trunc_normal_(
514
+ o_proj.weight,
515
+ mean=0.0,
516
+ std=std,
517
+ a=-3 * std,
518
+ b=3 * std,
519
+ )
520
+ if getattr(o_proj, "bias", None) is not None:
521
+ init.zeros_(o_proj.bias)
522
+ return
523
+
524
+ # MLP / FFN blocks
525
+ if isinstance(module, BltMLP) or class_name == "MllamaTextMLP":
526
+ hidden_size = getattr(self.config, "hidden_size", None)
527
+ if hidden_size is None and hasattr(self.config, "decoder_config"):
528
+ hidden_size = getattr(self.config.decoder_config, "hidden_size", None)
529
+ if hidden_size is None and hasattr(self.config, "encoder_config"):
530
+ hidden_size = getattr(self.config.encoder_config, "hidden_size", None)
531
+
532
+ # Input-side std
533
+ in_std = None
534
+ if hidden_size is not None:
535
+ in_std = hidden_size**-0.5
536
+
537
+ gate_proj = getattr(module, "gate_proj", getattr(module, "fc1", None))
538
+ up_proj = getattr(module, "up_proj", None)
539
+ down_proj = getattr(module, "down_proj", getattr(module, "fc2", None))
540
+
541
+ # gate / input projections
542
+ for proj in (gate_proj, up_proj):
543
+ if proj is not None and hasattr(proj, "weight"):
544
+ std = in_std or (proj.weight.shape[1] ** -0.5)
545
+ init.trunc_normal_(
546
+ proj.weight,
547
+ mean=0.0,
548
+ std=std,
549
+ a=-3 * std,
550
+ b=3 * std,
551
+ )
552
+ if getattr(proj, "bias", None) is not None:
553
+ init.zeros_(proj.bias)
554
+
555
+ # output/ down projections
556
+ if down_proj is not None and hasattr(down_proj, "weight"):
557
+ hidden_dim = down_proj.weight.shape[1]
558
+ out_std = hidden_dim**-0.5
559
+ init.trunc_normal_(
560
+ down_proj.weight,
561
+ mean=0.0,
562
+ std=out_std,
563
+ a=-3 * out_std,
564
+ b=3 * out_std,
565
+ )
566
+ if getattr(down_proj, "bias", None) is not None:
567
+ init.zeros_(down_proj.bias)
568
+ return
569
+
570
+ # Generic Linear layers (projections, lm_head, etc.)
571
+ if isinstance(module, nn.Linear):
572
+ fan_in = module.in_features
573
+ std = fan_in**-0.5
574
+ init.trunc_normal_(
575
+ module.weight,
576
+ mean=0.0,
577
+ std=std,
578
+ a=-3 * std,
579
+ b=3 * std,
580
+ )
581
+ if module.bias is not None:
582
+ init.zeros_(module.bias)
583
+ return
584
+
585
+ if isinstance(module, BltRotaryEmbedding):
586
+ rope_fn = (
587
+ ROPE_INIT_FUNCTIONS[module.rope_type]
588
+ if module.rope_type != "default"
589
+ else module.compute_default_rope_parameters
590
+ )
591
+ buffer_value, _ = rope_fn(module.config)
592
+ init.copy_(module.inv_freq, buffer_value)
593
+ init.copy_(module.original_inv_freq, buffer_value)
594
+
595
+
596
+ class BltLocalEncoder(BltPreTrainedModel):
597
+ config: BltLocalEncoderConfig
598
+ _can_record_outputs = {
599
+ "encoder_attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="local_encoder"),
600
+ }
601
+
602
+ def __init__(self, config: BltLocalEncoderConfig):
603
+ super().__init__(config)
604
+ self.gradient_checkpointing = False
605
+ self.config = config
606
+ self.layers = nn.ModuleList(
607
+ [BltTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
608
+ )
609
+ self.rotary_emb = BltRotaryEmbedding(config=config)
610
+ self.patch_embedding_projection = nn.Linear(
611
+ in_features=config.hidden_size,
612
+ out_features=config.hidden_size * config.cross_attn_k,
613
+ bias=False,
614
+ )
615
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
616
+ self.cross_attn_layers = nn.ModuleList()
617
+ layers_to_add = config.num_hidden_layers if config.cross_attn_all_layers else 1
618
+ for layer_idx in range(layers_to_add):
619
+ self.cross_attn_layers.append(
620
+ BltCrossAttention(config=config, layer_idx=layer_idx, hidden_size=config.hidden_size)
621
+ )
622
+
623
+ self.post_init()
624
+
625
+ def forward(
626
+ self,
627
+ input_ids: torch.LongTensor | None = None,
628
+ inputs_embeds: torch.Tensor | None = None,
629
+ patch_embeds: torch.Tensor | None = None,
630
+ attention_mask: torch.Tensor | None = None,
631
+ position_ids: torch.LongTensor | None = None,
632
+ past_key_values: Cache | None = None,
633
+ encoder_attention_mask: torch.Tensor | None = None,
634
+ num_patches: int | None = None,
635
+ patch_ids: torch.Tensor | None = None,
636
+ **kwargs: Unpack[TransformersKwargs],
637
+ ):
638
+ if inputs_embeds is None:
639
+ inputs_embeds = self.embed_tokens(input_ids)
640
+
641
+ batch_size = inputs_embeds.shape[0]
642
+ hidden_states = F.dropout(inputs_embeds, p=self.config.dropout, training=self.training)
643
+
644
+ if position_ids is None:
645
+ position_ids = (
646
+ torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1)
647
+ )
648
+
649
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
650
+ hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training)
651
+
652
+ for idx, layer in enumerate(self.layers):
653
+ hidden_states = layer(
654
+ hidden_states,
655
+ position_embeddings=position_embeddings,
656
+ attention_mask=attention_mask,
657
+ past_key_values=past_key_values,
658
+ **kwargs,
659
+ )
660
+ if idx == len(self.layers) - 1 or self.config.cross_attn_all_layers:
661
+ patch_embeds = self.patch_reduce(hidden_states, num_patches, patch_ids)
662
+ patch_embeds = self.patch_embedding_projection(patch_embeds)
663
+ patch_embeds = patch_embeds.reshape(
664
+ batch_size, patch_embeds.shape[1] * self.config.cross_attn_k, self.config.hidden_size
665
+ )
666
+ layer_idx = idx if self.config.cross_attn_all_layers else 0
667
+ cross_attention_output, _ = self.cross_attn_layers[layer_idx](
668
+ hidden_states=patch_embeds,
669
+ cross_attention_states=hidden_states,
670
+ attention_mask=encoder_attention_mask,
671
+ **kwargs,
672
+ )
673
+ patch_embeds = patch_embeds + cross_attention_output
674
+ encoder_cross_states = patch_embeds
675
+ return hidden_states, encoder_cross_states
676
+
677
+ def patch_reduce(self, hidden_states, max_num_patches, patch_ids):
678
+ """
679
+ Reduce variable length patches to single embedding per patch
680
+ Note: this works with variable number of patches for different sequences in the batch
681
+ It handles variable length patches by assuming that patch_lengths will be 0 for any
682
+ extra patches on the *right*. Since there can be a variable number of patches
683
+ this function also return the number of patches for each sequence in the batch.
684
+ Any embeddings on the right that are not allocated to a patch
685
+ (i.e. if the sum(patch_lengths[i]) < seq_len for any i)
686
+ will be sent to a dummy patch, which is trimmed before returning.
687
+ """
688
+ batch_size = hidden_states.shape[0]
689
+ embedding_dim = hidden_states.shape[-1]
690
+
691
+ patch_ids = patch_ids.unsqueeze(-1).expand(-1, -1, hidden_states.shape[-1])
692
+
693
+ reduced_embeddings = torch.zeros(
694
+ (batch_size, max_num_patches, embedding_dim), dtype=hidden_states.dtype, device=hidden_states.device
695
+ )
696
+
697
+ reduced_embeddings = reduced_embeddings.scatter_reduce(
698
+ src=hidden_states,
699
+ dim=1,
700
+ index=patch_ids,
701
+ reduce="amax",
702
+ include_self=False,
703
+ )
704
+ reduced_embeddings = reduced_embeddings[:, :max_num_patches, :]
705
+
706
+ return reduced_embeddings
707
+
708
+
709
+ class BltLocalDecoder(BltPreTrainedModel):
710
+ config: BltLocalDecoderConfig
711
+
712
+ def __init__(self, config: BltLocalDecoderConfig):
713
+ super().__init__(config)
714
+ self.gradient_checkpointing = False
715
+ self.config = config
716
+ self.cross_attn_decoder = True
717
+ self.layers = nn.ModuleList(
718
+ [BltTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
719
+ )
720
+ self.rotary_emb = BltRotaryEmbedding(config=config)
721
+ self.patch_embedding_projection = nn.Linear(
722
+ in_features=config.hidden_size_global,
723
+ out_features=config.hidden_size * config.cross_attn_k,
724
+ bias=False,
725
+ )
726
+ self.norm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
727
+ self.cross_attn_layers = nn.ModuleList()
728
+ layers_to_add = config.num_hidden_layers if config.cross_attn_all_layers else 1
729
+ for layer_idx in range(layers_to_add):
730
+ self.cross_attn_layers.append(
731
+ BltCrossAttention(config=config, layer_idx=layer_idx, hidden_size=config.hidden_size)
732
+ )
733
+
734
+ self.post_init()
735
+
736
+ def forward(
737
+ self,
738
+ input_ids: torch.LongTensor | None = None,
739
+ inputs_embeds: torch.Tensor | None = None,
740
+ patch_embeds: torch.Tensor | None = None,
741
+ attention_mask: torch.Tensor | None = None,
742
+ position_ids: torch.LongTensor | None = None,
743
+ past_key_values: Cache | None = None,
744
+ encoder_attention_mask: torch.Tensor | None = None,
745
+ **kwargs: Unpack[TransformersKwargs],
746
+ ):
747
+ batch_size = inputs_embeds.shape[0]
748
+ hidden_states = inputs_embeds
749
+ patch_embeds = self.patch_embedding_projection(patch_embeds)
750
+ patch_embeds = patch_embeds.reshape(
751
+ batch_size, patch_embeds.shape[1] * self.config.cross_attn_k, self.config.hidden_size
752
+ )
753
+
754
+ if patch_embeds is not None and not self.cross_attn_decoder:
755
+ hidden_states = hidden_states + patch_embeds
756
+
757
+ if position_ids is None:
758
+ position_ids = (
759
+ torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1)
760
+ )
761
+
762
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
763
+ hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training)
764
+
765
+ for i, layer in enumerate(self.layers):
766
+ if i == 0 or self.config.cross_attn_all_layers:
767
+ cross_attention_output, _ = self.cross_attn_layers[i](
768
+ hidden_states=hidden_states,
769
+ cross_attention_states=patch_embeds,
770
+ attention_mask=encoder_attention_mask,
771
+ **kwargs,
772
+ )
773
+ hidden_states = hidden_states + cross_attention_output
774
+ hidden_states = layer(
775
+ hidden_states,
776
+ position_embeddings=position_embeddings,
777
+ attention_mask=attention_mask,
778
+ past_key_values=past_key_values,
779
+ **kwargs,
780
+ )
781
+ logits = self.norm(hidden_states)
782
+ return logits
783
+
784
+
785
+ class BltGlobalTransformer(BltPreTrainedModel):
786
+ config: BltGlobalTransformerConfig
787
+ _can_record_outputs = {
788
+ "global_attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="global_transformer"),
789
+ }
790
+
791
+ def __init__(self, config: BltGlobalTransformerConfig):
792
+ super().__init__(config)
793
+ self.config = config
794
+ self.layers = nn.ModuleList()
795
+ for layer_idx in range(config.num_hidden_layers):
796
+ self.layers.append(BltTransformerLayer(config, layer_idx))
797
+ self.rotary_emb = BltRotaryEmbedding(config=config)
798
+
799
+ # Create token embedding projection (use nn.Identity() when no projection needed)
800
+ if getattr(config, "encoder_cross_output_size", None) is not None:
801
+ self.token_embedding_projection = nn.Linear(
802
+ config.encoder_cross_output_size, config.hidden_size, bias=False
803
+ )
804
+ else:
805
+ self.token_embedding_projection = nn.Identity()
806
+
807
+ self.post_init()
808
+
809
+ @deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
810
+ def forward(
811
+ self,
812
+ inputs_embeds: torch.Tensor,
813
+ attention_mask: torch.Tensor | None = None,
814
+ position_ids: torch.LongTensor | None = None,
815
+ past_key_values: Cache | None = None,
816
+ **kwargs: Unpack[TransformersKwargs],
817
+ ):
818
+ batch_size, seq_len, _ = inputs_embeds.shape
819
+ hidden_states = self.token_embedding_projection(inputs_embeds)
820
+ hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training)
821
+ if position_ids is None:
822
+ position_ids = (
823
+ torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1)
824
+ )
825
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
826
+ for i, layer in enumerate(self.layers):
827
+ hidden_states = layer(
828
+ hidden_states,
829
+ position_embeddings=position_embeddings,
830
+ attention_mask=attention_mask,
831
+ past_key_values=past_key_values,
832
+ **kwargs,
833
+ )
834
+ return hidden_states
835
+
836
+
837
+ def process_patch_lengths(patch_lengths: torch.Tensor, max_patch_length: int | None) -> torch.Tensor:
838
+ """
839
+ Splits patch lengths into smaller segments if they exceed `max_patch_length`.
840
+ Pads the result to uniform length across the batch.
841
+
842
+ Args:
843
+ patch_lengths (torch.Tensor): [batch_size, num_patches] tensor of patch lengths.
844
+ max_patch_length (int, optional): Maximum allowed length per patch.
845
+
846
+ Returns:
847
+ torch.Tensor: [batch_size, max_len] tensor of split and padded patch lengths.
848
+ """
849
+ if max_patch_length is None:
850
+ return patch_lengths
851
+
852
+ batch_size = patch_lengths.size(0)
853
+ processed = []
854
+
855
+ for seq in patch_lengths:
856
+ splits = []
857
+ for length in seq[seq > 0]:
858
+ length = length.item()
859
+ full_chunks, remainder = divmod(length, max_patch_length)
860
+ splits.extend([max_patch_length] * full_chunks)
861
+ if remainder:
862
+ splits.append(remainder)
863
+ processed.append(splits)
864
+
865
+ # Find max length to pad to
866
+ max_len = max(len(splits) for splits in processed)
867
+ padded = torch.zeros((batch_size, max_len), dtype=patch_lengths.dtype, device=patch_lengths.device)
868
+
869
+ for i, splits in enumerate(processed):
870
+ if splits:
871
+ padded[i, : len(splits)] = torch.tensor(splits, dtype=patch_lengths.dtype, device=patch_lengths.device)
872
+
873
+ # Trim zero columns
874
+ if (padded != 0).any(dim=0).sum() < padded.shape[1]:
875
+ last_nonzero = (padded != 0).any(dim=0).nonzero().max().item() + 1
876
+ padded = padded[:, :last_nonzero]
877
+
878
+ return padded
879
+
880
+
881
+ class BltPatcher(BltPreTrainedModel):
882
+ config: BltPatcherConfig
883
+
884
+ def __init__(self, config: BltPatcherConfig):
885
+ super().__init__(config)
886
+ self.rotary_emb = BltRotaryEmbedding(config=self.config)
887
+ self.layers = nn.ModuleList()
888
+ for layer_idx in range(self.config.num_hidden_layers):
889
+ self.layers.append(BltTransformerLayer(self.config, layer_idx))
890
+ self.embed_tokens = nn.Embedding(self.config.vocab_size, self.config.hidden_size)
891
+ self.norm = BltRMSNorm(self.config.hidden_size, eps=self.config.rms_norm_eps)
892
+ self.lm_head = nn.Linear(
893
+ self.config.hidden_size,
894
+ self.config.vocab_size,
895
+ bias=False,
896
+ )
897
+
898
+ self.post_init()
899
+
900
+ def forward(
901
+ self,
902
+ input_ids: torch.LongTensor | None = None,
903
+ attention_mask: torch.Tensor | None = None,
904
+ position_ids: torch.LongTensor | None = None,
905
+ past_key_values: Cache | None = None,
906
+ inputs_embeds: torch.FloatTensor | None = None,
907
+ use_cache: bool | None = None,
908
+ patch_size: int | None = None,
909
+ threshold: float | None = None,
910
+ max_patch_length: int | None = None,
911
+ **kwargs: Unpack[TransformersKwargs],
912
+ ):
913
+ if (input_ids is None) ^ (inputs_embeds is not None):
914
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
915
+
916
+ if inputs_embeds is None:
917
+ inputs_embeds = self.embed_tokens(input_ids)
918
+
919
+ if use_cache and past_key_values is None:
920
+ past_key_values = DynamicCache(config=self.config)
921
+
922
+ if position_ids is None:
923
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
924
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
925
+ position_ids = position_ids.unsqueeze(0)
926
+
927
+ causal_mask = create_causal_mask(
928
+ config=self.config,
929
+ inputs_embeds=inputs_embeds,
930
+ attention_mask=attention_mask,
931
+ past_key_values=past_key_values,
932
+ position_ids=position_ids,
933
+ )
934
+
935
+ hidden_states = inputs_embeds
936
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
937
+
938
+ for layer in self.layers:
939
+ hidden_states = layer(hidden_states, position_embeddings=position_embeddings, attention_mask=causal_mask)
940
+
941
+ logits = self.lm_head(self.norm(hidden_states))
942
+ prediction_entropies = torch.distributions.Categorical(logits=logits).entropy()
943
+
944
+ batch_size, sequence_length = inputs_embeds.shape[:2]
945
+ if patch_size is not None:
946
+ patch_lengths = self.patch_lengths_from_entropies(
947
+ entropies=prediction_entropies,
948
+ sequence_length=sequence_length,
949
+ patch_size=patch_size,
950
+ threshold=threshold,
951
+ )
952
+ else:
953
+ patch_lengths = torch.ones(
954
+ (batch_size, sequence_length), dtype=inputs_embeds.dtype, device=inputs_embeds.device
955
+ )
956
+ patch_lengths = process_patch_lengths(patch_lengths, max_patch_length)
957
+ return prediction_entropies, patch_lengths, logits
958
+
959
+ @staticmethod
960
+ def patch_lengths_from_entropies(
961
+ entropies,
962
+ sequence_length,
963
+ patch_size=None,
964
+ threshold=None,
965
+ ):
966
+ """
967
+ Computes patch lengths from token entropies.
968
+
969
+ Depending on whether a threshold is provided, the function uses either:
970
+ - Thresholding the entropy values (when `threshold` is set).
971
+ """
972
+
973
+ batch_size = entropies.shape[0]
974
+
975
+ # Always include token 0 and 1 as starting tokens
976
+ init_tokens = (
977
+ torch.tensor([0, 1], dtype=torch.long, device=entropies.device).unsqueeze(0).repeat(batch_size, 1)
978
+ )
979
+ offset = init_tokens.shape[1]
980
+
981
+ # Ignore first token entropy (BOS)
982
+ entropies = entropies[:, 1:]
983
+
984
+ # Threshold the entropy values to define patch start points
985
+ patch_mask = entropies > threshold
986
+
987
+ seq_len = patch_mask.shape[1]
988
+
989
+ # Create patch IDs (token indices), and add a sentinel to ensure alignment
990
+ token_indices = torch.arange(seq_len, device=entropies.device).unsqueeze(0).expand(batch_size, -1)
991
+ sentinel = torch.full_like(token_indices, seq_len)
992
+ padded_indices = torch.cat([token_indices, sentinel], dim=1)
993
+
994
+ # Pad mask with inverse to align sentinel correctly
995
+ padded_mask = torch.cat([patch_mask, ~patch_mask], dim=1)
996
+
997
+ # Select indices where mask is True
998
+ patch_starts = padded_indices[padded_mask].reshape(batch_size, seq_len)
999
+ max_valid_patches = patch_mask.sum(dim=1).max()
1000
+ patch_starts = patch_starts[:, :max_valid_patches]
1001
+
1002
+ # Offset patch starts to account for the two initial tokens
1003
+ patch_start_ids = torch.cat((init_tokens, patch_starts + offset), dim=1)
1004
+
1005
+ # Compute patch end positions by shifting start positions
1006
+ last_token = torch.full_like(patch_start_ids[:, :1], sequence_length - 1)
1007
+ patch_ends = torch.cat((patch_start_ids[:, 1:] - 1, last_token), dim=1)
1008
+
1009
+ patch_lengths = patch_ends - patch_start_ids + 1
1010
+
1011
+ return patch_lengths
1012
+
1013
+
1014
+ def rolling_polynomial_hash(token_tensor, prime: int = 1000000007):
1015
+ """
1016
+ A polynomial rolling hash algorithm that converts sequences
1017
+ of tokens into hash values. The hash is computed as:
1018
+ hash = (token_0 * prime^0 + token_1 * prime^1 + ... + token_n * prime^n)
1019
+
1020
+ The rolling hash allows the model to efficiently
1021
+ identify and encode recurring byte-level patterns in the input text.
1022
+
1023
+ Args:
1024
+ token_tensor (torch.Tensor): [batch_size, seq_len, group_size] containing token IDs to hash
1025
+ prime (int): Prime number used as the base for the polynomial hash.
1026
+
1027
+ Returns:
1028
+ torch.Tensor: Hash values of shape [batch_size, seq_len] where each value
1029
+ represents the hash of the corresponding token group
1030
+
1031
+ Example:
1032
+ >>> tokens = torch.tensor([[1, 2, 3], [4, 5, 6]])
1033
+ >>> hashes = rolling_polynomial_hash(tokens, prime=31)
1034
+ >>> # hash[0] = 1*31^0 + 2*31^1 + 3*31^2
1035
+ >>> # hash[1] = 4*31^0 + 5*31^1 + 6*31^2
1036
+ """
1037
+ prime_tensor = torch.tensor(prime, dtype=torch.int64, device=token_tensor.device)
1038
+ powers = torch.arange(token_tensor.shape[-1], device=token_tensor.device)
1039
+ prime_powers = prime_tensor**powers
1040
+ return torch.sum(token_tensor * prime_powers, dim=-1)
1041
+
1042
+
1043
+ def byte_group_hash_function(
1044
+ token_ids: torch.Tensor, group_size: int = 2, prime: int = 1000000007, max_hash: int = 30000
1045
+ ):
1046
+ """Hash token groups and map to range [0, max_hash]."""
1047
+ with torch.no_grad():
1048
+ batch_size, seq_len = token_ids.shape
1049
+ # Add padding for sliding window
1050
+ padding = torch.zeros(batch_size, group_size - 1, dtype=torch.int64, device=token_ids.device)
1051
+ padded_tokens = torch.cat([padding, token_ids], dim=1)
1052
+
1053
+ # Create sliding windows and compute hashes
1054
+ windows = padded_tokens.unfold(1, group_size, 1)
1055
+ hashes = rolling_polynomial_hash(windows, prime)
1056
+ hash_values = hashes % max_hash
1057
+
1058
+ return hash_values
1059
+
1060
+
1061
+ def compute_hash_embeddings(
1062
+ local_encoder_tokens: torch.Tensor,
1063
+ local_encoder,
1064
+ encoder_hash_tok_embedding: nn.Embedding,
1065
+ encoder_hash_byte_group_nb_functions: int,
1066
+ encoder_hash_byte_group_size: list,
1067
+ encoder_hash_byte_group_vocab: int,
1068
+ ) -> torch.Tensor:
1069
+ """Compute token embeddings enhanced with hash-based embeddings."""
1070
+ # Available primes for hash functions
1071
+ primes = [
1072
+ 1000000007,
1073
+ 5915587277,
1074
+ 1500450271,
1075
+ 3267000013,
1076
+ 5754853343,
1077
+ 4093082899,
1078
+ 9576890767,
1079
+ 3628273133,
1080
+ 2860486313,
1081
+ 5463458053,
1082
+ 3367900313,
1083
+ ]
1084
+
1085
+ embeddings = local_encoder.embed_tokens(local_encoder_tokens)
1086
+ embedding_idx = 0
1087
+ for func_nb in range(encoder_hash_byte_group_nb_functions):
1088
+ prime = primes[func_nb % len(primes)] # Cycle through primes if more functions than primes
1089
+ for group_size in encoder_hash_byte_group_size:
1090
+ hash_ids = byte_group_hash_function(local_encoder_tokens, group_size, prime, encoder_hash_byte_group_vocab)
1091
+ # Apply offset to get the correct slice of the fused embedding
1092
+ offset_hash_ids = hash_ids + embedding_idx * encoder_hash_byte_group_vocab
1093
+ embeddings += encoder_hash_tok_embedding(offset_hash_ids).to(embeddings.device)
1094
+ embedding_idx += 1
1095
+
1096
+ return embeddings
1097
+
1098
+
1099
+ def _prepare_patch_cross_attention_mask(
1100
+ patch_ids: torch.Tensor,
1101
+ num_patches: int,
1102
+ sequence_length: int,
1103
+ patches_as_queries: bool = False,
1104
+ cross_attn_k: int = 1,
1105
+ dtype: torch.dtype = torch.float32,
1106
+ ) -> tuple[torch.Tensor, torch.Tensor]:
1107
+ """
1108
+ Prepare cross-attention mask for patch-based attention, following mllama's robust approach.
1109
+
1110
+ This function creates masks that control which patches can attend to which other patches,
1111
+ with support for query/key role swapping and cross-attention multipliers.
1112
+
1113
+ Args:
1114
+ patch_ids (torch.Tensor): Tensor of shape [batch_size, seq_len] containing patch ids.
1115
+ num_patches (int): Total number of patches.
1116
+ sequence_length (int): Length of the sequence.
1117
+ patches_as_queries (bool): If True, patches are used as queries, otherwise as keys.
1118
+ cross_attn_k (int): Cross-attention multiplier for repeating patches.
1119
+ dtype (torch.dtype): Data type for the output mask.
1120
+
1121
+ Returns:
1122
+ Tuple[torch.Tensor, torch.Tensor]:
1123
+ - cross_attention_mask: 4D tensor [batch_size, 1, q_len, kv_len]
1124
+ """
1125
+ batch_size, seq_len = patch_ids.shape
1126
+ device = patch_ids.device
1127
+
1128
+ # Determine query and key lengths based on configuration
1129
+ if patches_as_queries:
1130
+ q_len = num_patches * cross_attn_k
1131
+ kv_len = sequence_length
1132
+ # Create patch-to-sequence mapping
1133
+ q_patch_ids = (
1134
+ torch.arange(num_patches, device=device)
1135
+ .unsqueeze(0)
1136
+ .unsqueeze(-1)
1137
+ .expand(batch_size, num_patches, seq_len)
1138
+ )
1139
+ kv_patch_ids = patch_ids.unsqueeze(1).expand(batch_size, num_patches, seq_len)
1140
+ else:
1141
+ q_len = sequence_length
1142
+ kv_len = num_patches * cross_attn_k
1143
+ # Create sequence-to-patch mapping
1144
+ q_patch_ids = patch_ids.unsqueeze(-1).expand(batch_size, seq_len, num_patches)
1145
+ kv_patch_ids = (
1146
+ torch.arange(num_patches, device=device).unsqueeze(0).unsqueeze(0).expand(batch_size, seq_len, num_patches)
1147
+ )
1148
+
1149
+ # Create base attention mask - boolean mask where True means "should attend"
1150
+ # Exact patch matching
1151
+ cross_attention_mask = q_patch_ids == kv_patch_ids
1152
+
1153
+ # Handle cross_attn_k multiplier by repeating along appropriate dimension
1154
+ repeat_dim = 1 if patches_as_queries else -1
1155
+ cross_attention_mask = cross_attention_mask.repeat_interleave(cross_attn_k, dim=repeat_dim)
1156
+
1157
+ # Validate dimensions
1158
+ expected_shape = (batch_size, q_len, kv_len)
1159
+ if cross_attention_mask.shape != expected_shape:
1160
+ raise ValueError(
1161
+ f"Cross attention mask shape {cross_attention_mask.shape} doesn't match expected {expected_shape}"
1162
+ )
1163
+
1164
+ # Reshape so it can be used by attn module - add head dimension
1165
+ cross_attention_mask = cross_attention_mask.unsqueeze(1) # [batch_size, 1, q_len, kv_len]
1166
+
1167
+ # Invert the mask (following mllama pattern exactly)
1168
+ # True -> 0.0 (attend), False -> 1.0 (will become -inf)
1169
+ inverted_cross_attn_mask = 1.0 - cross_attention_mask.to(dtype)
1170
+ cross_attention_mask = inverted_cross_attn_mask.masked_fill(
1171
+ inverted_cross_attn_mask.to(torch.bool), torch.finfo(dtype).min
1172
+ )
1173
+
1174
+ return cross_attention_mask
1175
+
1176
+
1177
+ class BltModel(BltPreTrainedModel):
1178
+ def __init__(self, config: BltConfig):
1179
+ super().__init__(config)
1180
+ self.gradient_checkpointing = False
1181
+
1182
+ self.config = config
1183
+ self.local_encoder = BltLocalEncoder(config.encoder_config)
1184
+ self.global_transformer = BltGlobalTransformer(config.global_config)
1185
+ self.local_decoder = BltLocalDecoder(config.decoder_config)
1186
+ num_embeddings = config.encoder_hash_byte_group_nb_functions * len(config.encoder_hash_byte_group_size)
1187
+ total_vocab_size = config.encoder_hash_byte_group_vocab * num_embeddings
1188
+ self.encoder_hash_tok_embedding = nn.Embedding(total_vocab_size, config.encoder_config.hidden_size)
1189
+ if self.config.patch_in_forward:
1190
+ self.patcher = BltPatcher(config.patcher_config)
1191
+ self.patcher.eval()
1192
+ for param in self.patcher.parameters():
1193
+ param.requires_grad = False
1194
+ else:
1195
+ self.patcher = None
1196
+ self.post_init()
1197
+
1198
+ @merge_with_config_defaults
1199
+ @capture_outputs
1200
+ def forward(
1201
+ self,
1202
+ input_ids: torch.LongTensor | None = None,
1203
+ patch_lengths: torch.Tensor | None = None,
1204
+ attention_mask: torch.Tensor | None = None,
1205
+ position_ids: torch.LongTensor | None = None,
1206
+ past_key_values: Cache | None = None,
1207
+ inputs_embeds: torch.FloatTensor | None = None,
1208
+ use_cache: bool | None = None,
1209
+ **kwargs: Unpack[TransformersKwargs],
1210
+ ) -> tuple | BaseModelOutputWithPast:
1211
+ if (input_ids is None) ^ (inputs_embeds is not None):
1212
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
1213
+
1214
+ if use_cache:
1215
+ if past_key_values is None:
1216
+ past_key_values = EncoderDecoderCache(
1217
+ DynamicCache(config=self.config), DynamicCache(config=self.config)
1218
+ )
1219
+ elif not isinstance(past_key_values, EncoderDecoderCache):
1220
+ # BLT uses an encoder-decoder cache even though it is not en encoder-decoder model. Create a cross-cache
1221
+ # if not yet created by the user
1222
+ past_key_values = EncoderDecoderCache(past_key_values, DynamicCache(config=self.config))
1223
+
1224
+ # Extract input embeddings as early as possible
1225
+ if inputs_embeds is not None:
1226
+ encoder_embeds = inputs_embeds
1227
+ batch_size, sequence_length, _ = inputs_embeds.shape
1228
+ else:
1229
+ batch_size, sequence_length = input_ids.shape
1230
+ encoder_embeds = compute_hash_embeddings(
1231
+ input_ids,
1232
+ self.local_encoder,
1233
+ self.encoder_hash_tok_embedding,
1234
+ self.config.encoder_hash_byte_group_nb_functions,
1235
+ self.config.encoder_hash_byte_group_size,
1236
+ self.config.encoder_hash_byte_group_vocab,
1237
+ )
1238
+
1239
+ if patch_lengths is None:
1240
+ if self.config.patching_mode == "entropy" and self.patcher is not None:
1241
+ if input_ids is None:
1242
+ raise ValueError("input_ids is required for entropy-based patching")
1243
+ _, patch_lengths, _ = self.patcher(
1244
+ input_ids,
1245
+ patch_size=self.config.patch_size,
1246
+ threshold=self.config.patching_threshold,
1247
+ max_patch_length=self.config.max_patch_length,
1248
+ patching_batch_size=self.config.patching_batch_size,
1249
+ device=input_ids.device,
1250
+ )
1251
+ else:
1252
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
1253
+ dtype = input_ids.dtype if input_ids is not None else inputs_embeds.dtype
1254
+ patch_lengths = process_patch_lengths(
1255
+ torch.ones((batch_size, sequence_length + 1), dtype=dtype, device=device),
1256
+ self.config.max_patch_length,
1257
+ )
1258
+ patch_ids = self._patch_ids_from_lengths(patch_lengths, sequence_length)
1259
+
1260
+ if position_ids is None:
1261
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
1262
+ position_ids = torch.arange(encoder_embeds.shape[1], device=encoder_embeds.device) + past_seen_tokens
1263
+ position_ids = position_ids.unsqueeze(0)
1264
+
1265
+ causal_mask = create_causal_mask(
1266
+ config=self.config,
1267
+ inputs_embeds=encoder_embeds,
1268
+ attention_mask=attention_mask,
1269
+ past_key_values=past_key_values.self_attention_cache if past_key_values is not None else None,
1270
+ position_ids=position_ids,
1271
+ )
1272
+
1273
+ cross_attn_mask_enc = _prepare_patch_cross_attention_mask(
1274
+ patch_ids=patch_ids,
1275
+ num_patches=patch_lengths.shape[1],
1276
+ sequence_length=sequence_length,
1277
+ patches_as_queries=True,
1278
+ cross_attn_k=self.config.cross_attn_k,
1279
+ dtype=encoder_embeds.dtype,
1280
+ )
1281
+ encoder_hidden_states, encoder_cross_states = self.local_encoder(
1282
+ input_ids=input_ids,
1283
+ inputs_embeds=encoder_embeds,
1284
+ attention_mask=causal_mask,
1285
+ position_ids=position_ids,
1286
+ encoder_attention_mask=cross_attn_mask_enc,
1287
+ num_patches=patch_lengths.shape[1],
1288
+ patch_ids=patch_ids,
1289
+ past_key_values=past_key_values.self_attention_cache if past_key_values is not None else None,
1290
+ **kwargs,
1291
+ )
1292
+ encoder_cross_states = encoder_cross_states.view(batch_size, patch_lengths.shape[1], -1)
1293
+ global_position_ids = torch.arange(0, encoder_cross_states.shape[1], device=encoder_cross_states.device)
1294
+ global_position_ids = global_position_ids.unsqueeze(0)
1295
+ global_causal_mask = create_causal_mask(
1296
+ config=self.config,
1297
+ inputs_embeds=encoder_cross_states,
1298
+ attention_mask=None,
1299
+ past_key_values=None,
1300
+ position_ids=None,
1301
+ )
1302
+
1303
+ global_hidden_states = self.global_transformer(
1304
+ inputs_embeds=encoder_cross_states,
1305
+ attention_mask=global_causal_mask,
1306
+ position_ids=global_position_ids,
1307
+ **kwargs,
1308
+ )
1309
+ decoder_patch_ids = self._patch_ids_from_lengths(patch_lengths[:, 1:], sequence_length)
1310
+ cross_attn_mask_dec = _prepare_patch_cross_attention_mask(
1311
+ patch_ids=decoder_patch_ids,
1312
+ num_patches=patch_lengths.shape[1],
1313
+ sequence_length=sequence_length,
1314
+ patches_as_queries=False,
1315
+ cross_attn_k=self.config.cross_attn_k,
1316
+ dtype=encoder_embeds.dtype,
1317
+ )
1318
+ output = self.local_decoder(
1319
+ input_ids=input_ids,
1320
+ inputs_embeds=encoder_hidden_states,
1321
+ patch_embeds=global_hidden_states,
1322
+ attention_mask=causal_mask,
1323
+ position_ids=position_ids,
1324
+ past_key_values=past_key_values.cross_attention_cache if past_key_values is not None else None,
1325
+ encoder_attention_mask=cross_attn_mask_dec,
1326
+ **kwargs,
1327
+ )
1328
+ return BaseModelOutputWithPast(
1329
+ last_hidden_state=output,
1330
+ past_key_values=past_key_values,
1331
+ )
1332
+
1333
+ def get_input_embeddings(self):
1334
+ return self.local_encoder.embed_tokens
1335
+
1336
+ def set_input_embeddings(self, value):
1337
+ self.local_encoder.embed_tokens = value
1338
+
1339
+ def _patch_ids_from_lengths(self, patch_lengths: torch.Tensor, seq_len: int) -> torch.Tensor:
1340
+ batch_size = patch_lengths.shape[0]
1341
+ patch_starts = torch.cat(
1342
+ [
1343
+ torch.zeros(batch_size, 1, dtype=patch_lengths.dtype, device=patch_lengths.device),
1344
+ patch_lengths.cumsum(dim=-1)[:, :-1],
1345
+ ],
1346
+ dim=-1,
1347
+ )
1348
+ token_positions = torch.arange(seq_len, device=patch_lengths.device)
1349
+ return (patch_starts.unsqueeze(1) <= token_positions.unsqueeze(0).unsqueeze(-1)).sum(dim=-1) - 1
1350
+
1351
+
1352
+ @auto_docstring(
1353
+ custom_intro="""
1354
+ The Blt Text Model with a language modeling head on top.
1355
+ """
1356
+ )
1357
+ class BltForCausalLM(BltPreTrainedModel, GenerationMixin):
1358
+ config: BltConfig
1359
+ _can_compile_fullgraph = False
1360
+ base_model_prefix = "model"
1361
+ _tied_weights_keys = {"model.local_encoder.embed_tokens.weight": "lm_head.weight"}
1362
+
1363
+ def __init__(self, config: BltConfig):
1364
+ super().__init__(config)
1365
+ self.text_config = config.get_text_config()
1366
+ self.vocab_size = config.vocab_size
1367
+ self.model = BltModel(config)
1368
+ self.lm_head = nn.Linear(config.decoder_config.hidden_size, config.vocab_size, bias=False)
1369
+
1370
+ self.post_init()
1371
+
1372
+ @can_return_tuple
1373
+ @auto_docstring
1374
+ def forward(
1375
+ self,
1376
+ input_ids: torch.LongTensor | None = None,
1377
+ attention_mask: torch.Tensor | None = None,
1378
+ position_ids: torch.LongTensor | None = None,
1379
+ cross_attention_states: torch.LongTensor | None = None, # Keep for compatibility
1380
+ cross_attention_mask: torch.LongTensor | None = None,
1381
+ full_text_row_masked_out_mask: tuple[torch.Tensor, torch.Tensor] | None = None,
1382
+ past_key_values: Cache | None = None,
1383
+ inputs_embeds: torch.FloatTensor | None = None,
1384
+ labels: torch.LongTensor | None = None,
1385
+ use_cache: bool | None = None,
1386
+ logits_to_keep: int | torch.Tensor = 0,
1387
+ **kwargs: Unpack[TransformersKwargs],
1388
+ ) -> tuple | CausalLMOutputWithPast:
1389
+ r"""
1390
+ cross_attention_states (`torch.FloatTensor`, *optional*):
1391
+ Output of the vision model, used for cross-attention. This tensor contains the processed image features that
1392
+ the language model will attend to.
1393
+ cross_attention_mask (`torch.Tensor` of shape `(batch_size, seq_length, max_num_images, max_num_tiles)`, *optional*):
1394
+ Cross-attention mask to control the interaction between text tokens and image tiles.
1395
+ This 4D tensor defines which image tiles each text token should attend to.
1396
+
1397
+ For each text token (in seq_length):
1398
+ - 1 indicates the token **should attend** to the corresponding image tile
1399
+ - 0 indicates the token **should not attend** to the corresponding image tile
1400
+ full_text_row_masked_out_mask (`tuple[torch.Tensor, torch.Tensor]`, *optional*):
1401
+ A tuple containing two tensors that mask out rows in the cross-attention mechanism:
1402
+ - The first tensor has shape `(batch_size, 1, seq_length, 1)` and contains values of 0 or 1.
1403
+ A value of 0 indicates that the corresponding text token's entire row in the cross-attention
1404
+ matrix should be masked out (all image tokens ignored).
1405
+ - The second tensor has the same shape and is used internally to apply the masking during
1406
+ the forward pass of cross-attention layers.
1407
+ This mask is derived from the cross_attention_mask and is used to handle cases where a text token
1408
+ should not attend to any image token.
1409
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1410
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
1411
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
1412
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
1413
+
1414
+ Example:
1415
+
1416
+ ```python
1417
+ >>> from transformers import AutoTokenizer, BltForCausalLM
1418
+
1419
+ >>> model = BltForCausalLM.from_pretrained("itazap/blt-1b-hf")
1420
+ >>> tokenizer = AutoTokenizer.from_pretrained("itazap/blt-1b-hf")
1421
+
1422
+ >>> prompt = "If I had to write a haiku, it would be:"
1423
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
1424
+
1425
+ >>> # Generate
1426
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=40, do_sample=True, temperature=0.6)
1427
+ >>> result = tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
1428
+ >>> print(result)
1429
+ If I had to write a haiku, it would be: "Snowflakes gently fall" - simple, yet peaceful.
1430
+ I love the idea of snowflakes gently falling, each one
1431
+ ```
1432
+ """
1433
+ # Call parent forward but exclude cross_attention_states from model call
1434
+ outputs = self.model(
1435
+ input_ids=input_ids,
1436
+ attention_mask=attention_mask,
1437
+ position_ids=position_ids,
1438
+ cross_attention_mask=cross_attention_mask,
1439
+ full_text_row_masked_out_mask=full_text_row_masked_out_mask,
1440
+ past_key_values=past_key_values,
1441
+ inputs_embeds=inputs_embeds,
1442
+ use_cache=use_cache,
1443
+ **kwargs,
1444
+ )
1445
+
1446
+ hidden_states = outputs.last_hidden_state
1447
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
1448
+ logits = self.lm_head(hidden_states[:, slice_indices, :]).float()
1449
+
1450
+ loss = None
1451
+ if labels is not None:
1452
+ loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)
1453
+
1454
+ return CausalLMOutputWithPast(
1455
+ loss=loss,
1456
+ logits=logits,
1457
+ past_key_values=outputs.past_key_values,
1458
+ hidden_states=outputs.hidden_states,
1459
+ attentions=outputs.attentions,
1460
+ )
1461
+
1462
+
1463
+ __all__ = ["BltPreTrainedModel", "BltModel", "BltPatcher", "BltForCausalLM"]
third_party/transformers/src/transformers/models/blt/modular_blt.py ADDED
@@ -0,0 +1,1195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 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
+ """Blt modular model, inheriting from Mllama where appropriate."""
15
+
16
+ from collections.abc import Callable
17
+
18
+ import torch
19
+ import torch.distributions
20
+ import torch.nn as nn
21
+ import torch.nn.functional as F
22
+
23
+ from ... import initialization as init
24
+ from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
25
+ from ...generation import GenerationMixin
26
+ from ...masking_utils import create_causal_mask
27
+ from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
28
+ from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
29
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS
30
+ from ...processing_utils import Unpack
31
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging
32
+ from ...utils.deprecation import deprecate_kwarg
33
+ from ...utils.generic import maybe_autocast, merge_with_config_defaults
34
+ from ...utils.output_capturing import OutputRecorder, capture_outputs
35
+ from ..cohere2.modeling_cohere2 import rotate_half # noqa: F401
36
+ from ..llama.modeling_llama import LlamaRotaryEmbedding
37
+ from ..mllama.modeling_mllama import (
38
+ MllamaPreTrainedModel,
39
+ MllamaSelfAttentionDecoderLayer,
40
+ MllamaTextCrossAttention,
41
+ MllamaTextMLP,
42
+ MllamaTextRMSNorm,
43
+ MllamaTextSelfAttention,
44
+ eager_attention_forward,
45
+ )
46
+ from .configuration_blt import (
47
+ BltConfig,
48
+ BltGlobalTransformerConfig,
49
+ BltLocalDecoderConfig,
50
+ BltLocalEncoderConfig,
51
+ BltPatcherConfig,
52
+ )
53
+
54
+
55
+ logger = logging.get_logger(__name__)
56
+
57
+
58
+ def rolling_polynomial_hash(token_tensor, prime: int = 1000000007):
59
+ """
60
+ A polynomial rolling hash algorithm that converts sequences
61
+ of tokens into hash values. The hash is computed as:
62
+ hash = (token_0 * prime^0 + token_1 * prime^1 + ... + token_n * prime^n)
63
+
64
+ The rolling hash allows the model to efficiently
65
+ identify and encode recurring byte-level patterns in the input text.
66
+
67
+ Args:
68
+ token_tensor (torch.Tensor): [batch_size, seq_len, group_size] containing token IDs to hash
69
+ prime (int): Prime number used as the base for the polynomial hash.
70
+
71
+ Returns:
72
+ torch.Tensor: Hash values of shape [batch_size, seq_len] where each value
73
+ represents the hash of the corresponding token group
74
+
75
+ Example:
76
+ >>> tokens = torch.tensor([[1, 2, 3], [4, 5, 6]])
77
+ >>> hashes = rolling_polynomial_hash(tokens, prime=31)
78
+ >>> # hash[0] = 1*31^0 + 2*31^1 + 3*31^2
79
+ >>> # hash[1] = 4*31^0 + 5*31^1 + 6*31^2
80
+ """
81
+ prime_tensor = torch.tensor(prime, dtype=torch.int64, device=token_tensor.device)
82
+ powers = torch.arange(token_tensor.shape[-1], device=token_tensor.device)
83
+ prime_powers = prime_tensor**powers
84
+ return torch.sum(token_tensor * prime_powers, dim=-1)
85
+
86
+
87
+ def byte_group_hash_function(
88
+ token_ids: torch.Tensor, group_size: int = 2, prime: int = 1000000007, max_hash: int = 30000
89
+ ):
90
+ """Hash token groups and map to range [0, max_hash]."""
91
+ with torch.no_grad():
92
+ batch_size, seq_len = token_ids.shape
93
+ # Add padding for sliding window
94
+ padding = torch.zeros(batch_size, group_size - 1, dtype=torch.int64, device=token_ids.device)
95
+ padded_tokens = torch.cat([padding, token_ids], dim=1)
96
+
97
+ # Create sliding windows and compute hashes
98
+ windows = padded_tokens.unfold(1, group_size, 1)
99
+ hashes = rolling_polynomial_hash(windows, prime)
100
+ hash_values = hashes % max_hash
101
+
102
+ return hash_values
103
+
104
+
105
+ def compute_hash_embeddings(
106
+ local_encoder_tokens: torch.Tensor,
107
+ local_encoder,
108
+ encoder_hash_tok_embedding: nn.Embedding,
109
+ encoder_hash_byte_group_nb_functions: int,
110
+ encoder_hash_byte_group_size: list,
111
+ encoder_hash_byte_group_vocab: int,
112
+ ) -> torch.Tensor:
113
+ """Compute token embeddings enhanced with hash-based embeddings."""
114
+ # Available primes for hash functions
115
+ primes = [
116
+ 1000000007,
117
+ 5915587277,
118
+ 1500450271,
119
+ 3267000013,
120
+ 5754853343,
121
+ 4093082899,
122
+ 9576890767,
123
+ 3628273133,
124
+ 2860486313,
125
+ 5463458053,
126
+ 3367900313,
127
+ ]
128
+
129
+ embeddings = local_encoder.embed_tokens(local_encoder_tokens)
130
+ embedding_idx = 0
131
+ for func_nb in range(encoder_hash_byte_group_nb_functions):
132
+ prime = primes[func_nb % len(primes)] # Cycle through primes if more functions than primes
133
+ for group_size in encoder_hash_byte_group_size:
134
+ hash_ids = byte_group_hash_function(local_encoder_tokens, group_size, prime, encoder_hash_byte_group_vocab)
135
+ # Apply offset to get the correct slice of the fused embedding
136
+ offset_hash_ids = hash_ids + embedding_idx * encoder_hash_byte_group_vocab
137
+ embeddings += encoder_hash_tok_embedding(offset_hash_ids).to(embeddings.device)
138
+ embedding_idx += 1
139
+
140
+ return embeddings
141
+
142
+
143
+ def _prepare_patch_cross_attention_mask(
144
+ patch_ids: torch.Tensor,
145
+ num_patches: int,
146
+ sequence_length: int,
147
+ patches_as_queries: bool = False,
148
+ cross_attn_k: int = 1,
149
+ dtype: torch.dtype = torch.float32,
150
+ ) -> tuple[torch.Tensor, torch.Tensor]:
151
+ """
152
+ Prepare cross-attention mask for patch-based attention, following mllama's robust approach.
153
+
154
+ This function creates masks that control which patches can attend to which other patches,
155
+ with support for query/key role swapping and cross-attention multipliers.
156
+
157
+ Args:
158
+ patch_ids (torch.Tensor): Tensor of shape [batch_size, seq_len] containing patch ids.
159
+ num_patches (int): Total number of patches.
160
+ sequence_length (int): Length of the sequence.
161
+ patches_as_queries (bool): If True, patches are used as queries, otherwise as keys.
162
+ cross_attn_k (int): Cross-attention multiplier for repeating patches.
163
+ dtype (torch.dtype): Data type for the output mask.
164
+
165
+ Returns:
166
+ Tuple[torch.Tensor, torch.Tensor]:
167
+ - cross_attention_mask: 4D tensor [batch_size, 1, q_len, kv_len]
168
+ """
169
+ batch_size, seq_len = patch_ids.shape
170
+ device = patch_ids.device
171
+
172
+ # Determine query and key lengths based on configuration
173
+ if patches_as_queries:
174
+ q_len = num_patches * cross_attn_k
175
+ kv_len = sequence_length
176
+ # Create patch-to-sequence mapping
177
+ q_patch_ids = (
178
+ torch.arange(num_patches, device=device)
179
+ .unsqueeze(0)
180
+ .unsqueeze(-1)
181
+ .expand(batch_size, num_patches, seq_len)
182
+ )
183
+ kv_patch_ids = patch_ids.unsqueeze(1).expand(batch_size, num_patches, seq_len)
184
+ else:
185
+ q_len = sequence_length
186
+ kv_len = num_patches * cross_attn_k
187
+ # Create sequence-to-patch mapping
188
+ q_patch_ids = patch_ids.unsqueeze(-1).expand(batch_size, seq_len, num_patches)
189
+ kv_patch_ids = (
190
+ torch.arange(num_patches, device=device).unsqueeze(0).unsqueeze(0).expand(batch_size, seq_len, num_patches)
191
+ )
192
+
193
+ # Create base attention mask - boolean mask where True means "should attend"
194
+ # Exact patch matching
195
+ cross_attention_mask = q_patch_ids == kv_patch_ids
196
+
197
+ # Handle cross_attn_k multiplier by repeating along appropriate dimension
198
+ repeat_dim = 1 if patches_as_queries else -1
199
+ cross_attention_mask = cross_attention_mask.repeat_interleave(cross_attn_k, dim=repeat_dim)
200
+
201
+ # Validate dimensions
202
+ expected_shape = (batch_size, q_len, kv_len)
203
+ if cross_attention_mask.shape != expected_shape:
204
+ raise ValueError(
205
+ f"Cross attention mask shape {cross_attention_mask.shape} doesn't match expected {expected_shape}"
206
+ )
207
+
208
+ # Reshape so it can be used by attn module - add head dimension
209
+ cross_attention_mask = cross_attention_mask.unsqueeze(1) # [batch_size, 1, q_len, kv_len]
210
+
211
+ # Invert the mask (following mllama pattern exactly)
212
+ # True -> 0.0 (attend), False -> 1.0 (will become -inf)
213
+ inverted_cross_attn_mask = 1.0 - cross_attention_mask.to(dtype)
214
+ cross_attention_mask = inverted_cross_attn_mask.masked_fill(
215
+ inverted_cross_attn_mask.to(torch.bool), torch.finfo(dtype).min
216
+ )
217
+
218
+ return cross_attention_mask
219
+
220
+
221
+ def process_patch_lengths(patch_lengths: torch.Tensor, max_patch_length: int | None) -> torch.Tensor:
222
+ """
223
+ Splits patch lengths into smaller segments if they exceed `max_patch_length`.
224
+ Pads the result to uniform length across the batch.
225
+
226
+ Args:
227
+ patch_lengths (torch.Tensor): [batch_size, num_patches] tensor of patch lengths.
228
+ max_patch_length (int, optional): Maximum allowed length per patch.
229
+
230
+ Returns:
231
+ torch.Tensor: [batch_size, max_len] tensor of split and padded patch lengths.
232
+ """
233
+ if max_patch_length is None:
234
+ return patch_lengths
235
+
236
+ batch_size = patch_lengths.size(0)
237
+ processed = []
238
+
239
+ for seq in patch_lengths:
240
+ splits = []
241
+ for length in seq[seq > 0]:
242
+ length = length.item()
243
+ full_chunks, remainder = divmod(length, max_patch_length)
244
+ splits.extend([max_patch_length] * full_chunks)
245
+ if remainder:
246
+ splits.append(remainder)
247
+ processed.append(splits)
248
+
249
+ # Find max length to pad to
250
+ max_len = max(len(splits) for splits in processed)
251
+ padded = torch.zeros((batch_size, max_len), dtype=patch_lengths.dtype, device=patch_lengths.device)
252
+
253
+ for i, splits in enumerate(processed):
254
+ if splits:
255
+ padded[i, : len(splits)] = torch.tensor(splits, dtype=patch_lengths.dtype, device=patch_lengths.device)
256
+
257
+ # Trim zero columns
258
+ if (padded != 0).any(dim=0).sum() < padded.shape[1]:
259
+ last_nonzero = (padded != 0).any(dim=0).nonzero().max().item() + 1
260
+ padded = padded[:, :last_nonzero]
261
+
262
+ return padded
263
+
264
+
265
+ class BltMLP(MllamaTextMLP):
266
+ pass
267
+
268
+
269
+ class BltRMSNorm(MllamaTextRMSNorm):
270
+ pass
271
+
272
+
273
+ class BltRotaryEmbedding(LlamaRotaryEmbedding):
274
+ @torch.no_grad()
275
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
276
+ def forward(self, x, position_ids):
277
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1)
278
+ position_ids_expanded = position_ids[:, None, :].float()
279
+
280
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
281
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
282
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
283
+ emb = torch.repeat_interleave(freqs, 2, dim=-1) # diff from Llama: we interleave() instead of cat()
284
+ cos = emb.cos() * self.attention_scaling
285
+ sin = emb.sin() * self.attention_scaling
286
+
287
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
288
+
289
+
290
+ class BltTransformerLayer(MllamaSelfAttentionDecoderLayer):
291
+ def __init__(self, config, layer_idx: int):
292
+ super().__init__()
293
+
294
+ self.self_attn = BltSelfAttention(config=config, layer_idx=layer_idx)
295
+ self.mlp = BltMLP(config)
296
+ self.input_layernorm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
297
+ self.post_attention_layernorm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
298
+
299
+
300
+ class BltSelfAttention(MllamaTextSelfAttention):
301
+ def __init__(self, config: BltConfig, layer_idx: int):
302
+ super().__init__(config, layer_idx)
303
+
304
+
305
+ class BltCrossAttention(MllamaTextCrossAttention):
306
+ """Cross-attention module for Blt, following transformers style"""
307
+
308
+ def __init__(self, config: BltConfig, layer_idx: int, hidden_size: int | None = None):
309
+ super().__init__()
310
+ self.is_causal = False
311
+ self.q_norm = BltRMSNorm(self.hidden_size, eps=config.rms_norm_eps)
312
+ self.k_norm = BltRMSNorm(self.hidden_size, eps=config.rms_norm_eps)
313
+
314
+ def forward(
315
+ self,
316
+ hidden_states: torch.Tensor,
317
+ cross_attention_states: torch.Tensor | None = None,
318
+ attention_mask: torch.Tensor | None = None,
319
+ **kwargs: Unpack[TransformersKwargs],
320
+ ):
321
+ bsz, q_len, _ = hidden_states.size()
322
+ query_states = self.q_norm(hidden_states)
323
+ query_states = self.q_proj(query_states)
324
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
325
+
326
+ cross_attention_states = self.k_norm(cross_attention_states)
327
+ key_states = self.k_proj(cross_attention_states)
328
+ value_states = self.v_proj(cross_attention_states)
329
+ key_states = key_states.view(bsz, -1, self.num_key_value_heads, self.head_dim).transpose(1, 2)
330
+ value_states = value_states.view(bsz, -1, self.num_key_value_heads, self.head_dim).transpose(1, 2)
331
+
332
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
333
+ self.config._attn_implementation, eager_attention_forward
334
+ )
335
+
336
+ attn_output, attn_weights = attention_interface(
337
+ self,
338
+ query_states,
339
+ key_states,
340
+ value_states,
341
+ attention_mask,
342
+ dropout=0.0 if not self.training else self.dropout,
343
+ scaling=self.scaling,
344
+ **kwargs,
345
+ )
346
+ attn_output = attn_output.reshape(bsz, q_len, -1).contiguous()
347
+ attn_output = self.o_proj(attn_output)
348
+ attn_output = attn_output + hidden_states
349
+ return attn_output, attn_weights
350
+
351
+
352
+ @auto_docstring
353
+ class BltPreTrainedModel(MllamaPreTrainedModel):
354
+ config: BltConfig
355
+ _supports_attention_backend = False
356
+ _supports_flash_attn = False
357
+ _supports_flex_attn = False
358
+ _no_split_modules = ["BltTransformerLayer"]
359
+ _can_record_outputs = {
360
+ "hidden_states": OutputRecorder(BltTransformerLayer, index=0),
361
+ "attentions": OutputRecorder(BltSelfAttention, index=1),
362
+ }
363
+
364
+ # Weight initialization is adapted from:
365
+ # - https://github.com/facebookresearch/blt/blob/main/bytelatent/model/blt.py
366
+ # - https://github.com/pytorch/torchtitan/blob/main/torchtitan/experiments/transformers_modeling_backend/model/model.py
367
+ #
368
+ # Both implementations use truncated normal initialization with std ~ 1 / sqrt(d_model)
369
+ # (or 1 / sqrt(hidden_dim) for FFN outputs), and unit initialization for normalization layers.
370
+ # We follow the same scheme here, but expressed in the Transformers APIs.
371
+
372
+ @torch.no_grad()
373
+ def _init_weights(self, module):
374
+ """
375
+ Initialize BLT weights following the original ByteLatentTransformer:
376
+
377
+ - Most weights are drawn from a truncated normal.
378
+ - Scale is ~ 1 / sqrt(model_dim) (or 1 / sqrt(hidden_dim) for FFN outputs).
379
+ - Norm layers are set to weight = 1, bias = 0.
380
+ """
381
+ class_name = module.__class__.__name__
382
+
383
+ # Norms: RMSNorm / LayerNorm
384
+ if isinstance(module, (BltRMSNorm, nn.LayerNorm)) or "RMSNorm" in class_name or "LayerNorm" in class_name:
385
+ if getattr(module, "weight", None) is not None:
386
+ init.ones_(module.weight)
387
+ if getattr(module, "bias", None) is not None:
388
+ init.zeros_(module.bias)
389
+ return
390
+
391
+ # Embeddings (encoder / patcher / hash embeddings)
392
+ if isinstance(module, nn.Embedding):
393
+ hidden_size = getattr(self.config, "hidden_size", None)
394
+ if hidden_size is None and hasattr(self.config, "encoder_config"):
395
+ hidden_size = getattr(self.config.encoder_config, "hidden_size", None)
396
+ if hidden_size is None:
397
+ hidden_size = module.embedding_dim
398
+
399
+ std = hidden_size**-0.5
400
+ init.trunc_normal_(
401
+ module.weight,
402
+ mean=0.0,
403
+ std=std,
404
+ a=-3 * std,
405
+ b=3 * std,
406
+ )
407
+ if module.padding_idx is not None:
408
+ init.zeros_(module.weight[module.padding_idx])
409
+ return
410
+
411
+ # Self-attention / cross-attention projections
412
+ if isinstance(module, (BltSelfAttention, BltCrossAttention)) or class_name in (
413
+ "MllamaTextSelfAttention",
414
+ "MllamaTextCrossAttention",
415
+ ):
416
+ dim = getattr(self.config, "hidden_size", None)
417
+ if dim is None and hasattr(module, "hidden_size"):
418
+ dim = module.hidden_size
419
+ if dim is None:
420
+ for name in ("q_proj", "k_proj", "v_proj", "o_proj", "dense"):
421
+ proj = getattr(module, name, None)
422
+ if proj is not None and hasattr(proj, "weight"):
423
+ dim = proj.weight.shape[-1]
424
+ break
425
+ if dim is None:
426
+ return
427
+
428
+ std = dim**-0.5
429
+
430
+ # Input projections (q, k, v)
431
+ for proj_name in ("q_proj", "k_proj", "v_proj"):
432
+ proj = getattr(module, proj_name, None)
433
+ if proj is not None and hasattr(proj, "weight"):
434
+ init.trunc_normal_(
435
+ proj.weight,
436
+ mean=0.0,
437
+ std=std,
438
+ a=-3 * std,
439
+ b=3 * std,
440
+ )
441
+ if getattr(proj, "bias", None) is not None:
442
+ init.zeros_(proj.bias)
443
+
444
+ # Output projection: o_proj or dense
445
+ o_proj = getattr(module, "o_proj", getattr(module, "dense", None))
446
+ if o_proj is not None and hasattr(o_proj, "weight"):
447
+ init.trunc_normal_(
448
+ o_proj.weight,
449
+ mean=0.0,
450
+ std=std,
451
+ a=-3 * std,
452
+ b=3 * std,
453
+ )
454
+ if getattr(o_proj, "bias", None) is not None:
455
+ init.zeros_(o_proj.bias)
456
+ return
457
+
458
+ # MLP / FFN blocks
459
+ if isinstance(module, BltMLP) or class_name == "MllamaTextMLP":
460
+ hidden_size = getattr(self.config, "hidden_size", None)
461
+ if hidden_size is None and hasattr(self.config, "decoder_config"):
462
+ hidden_size = getattr(self.config.decoder_config, "hidden_size", None)
463
+ if hidden_size is None and hasattr(self.config, "encoder_config"):
464
+ hidden_size = getattr(self.config.encoder_config, "hidden_size", None)
465
+
466
+ # Input-side std
467
+ in_std = None
468
+ if hidden_size is not None:
469
+ in_std = hidden_size**-0.5
470
+
471
+ gate_proj = getattr(module, "gate_proj", getattr(module, "fc1", None))
472
+ up_proj = getattr(module, "up_proj", None)
473
+ down_proj = getattr(module, "down_proj", getattr(module, "fc2", None))
474
+
475
+ # gate / input projections
476
+ for proj in (gate_proj, up_proj):
477
+ if proj is not None and hasattr(proj, "weight"):
478
+ std = in_std or (proj.weight.shape[1] ** -0.5)
479
+ init.trunc_normal_(
480
+ proj.weight,
481
+ mean=0.0,
482
+ std=std,
483
+ a=-3 * std,
484
+ b=3 * std,
485
+ )
486
+ if getattr(proj, "bias", None) is not None:
487
+ init.zeros_(proj.bias)
488
+
489
+ # output/ down projections
490
+ if down_proj is not None and hasattr(down_proj, "weight"):
491
+ hidden_dim = down_proj.weight.shape[1]
492
+ out_std = hidden_dim**-0.5
493
+ init.trunc_normal_(
494
+ down_proj.weight,
495
+ mean=0.0,
496
+ std=out_std,
497
+ a=-3 * out_std,
498
+ b=3 * out_std,
499
+ )
500
+ if getattr(down_proj, "bias", None) is not None:
501
+ init.zeros_(down_proj.bias)
502
+ return
503
+
504
+ # Generic Linear layers (projections, lm_head, etc.)
505
+ if isinstance(module, nn.Linear):
506
+ fan_in = module.in_features
507
+ std = fan_in**-0.5
508
+ init.trunc_normal_(
509
+ module.weight,
510
+ mean=0.0,
511
+ std=std,
512
+ a=-3 * std,
513
+ b=3 * std,
514
+ )
515
+ if module.bias is not None:
516
+ init.zeros_(module.bias)
517
+ return
518
+
519
+ if isinstance(module, BltRotaryEmbedding):
520
+ rope_fn = (
521
+ ROPE_INIT_FUNCTIONS[module.rope_type]
522
+ if module.rope_type != "default"
523
+ else module.compute_default_rope_parameters
524
+ )
525
+ buffer_value, _ = rope_fn(module.config)
526
+ init.copy_(module.inv_freq, buffer_value)
527
+ init.copy_(module.original_inv_freq, buffer_value)
528
+
529
+
530
+ class BltLocalEncoder(BltPreTrainedModel):
531
+ config: BltLocalEncoderConfig
532
+ _can_record_outputs = {
533
+ "encoder_attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="local_encoder"),
534
+ }
535
+
536
+ def __init__(self, config: BltLocalEncoderConfig):
537
+ super().__init__(config)
538
+ self.gradient_checkpointing = False
539
+ self.config = config
540
+ self.layers = nn.ModuleList(
541
+ [BltTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
542
+ )
543
+ self.rotary_emb = BltRotaryEmbedding(config=config)
544
+ self.patch_embedding_projection = nn.Linear(
545
+ in_features=config.hidden_size,
546
+ out_features=config.hidden_size * config.cross_attn_k,
547
+ bias=False,
548
+ )
549
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
550
+ self.cross_attn_layers = nn.ModuleList()
551
+ layers_to_add = config.num_hidden_layers if config.cross_attn_all_layers else 1
552
+ for layer_idx in range(layers_to_add):
553
+ self.cross_attn_layers.append(
554
+ BltCrossAttention(config=config, layer_idx=layer_idx, hidden_size=config.hidden_size)
555
+ )
556
+
557
+ self.post_init()
558
+
559
+ def forward(
560
+ self,
561
+ input_ids: torch.LongTensor | None = None,
562
+ inputs_embeds: torch.Tensor | None = None,
563
+ patch_embeds: torch.Tensor | None = None,
564
+ attention_mask: torch.Tensor | None = None,
565
+ position_ids: torch.LongTensor | None = None,
566
+ past_key_values: Cache | None = None,
567
+ encoder_attention_mask: torch.Tensor | None = None,
568
+ num_patches: int | None = None,
569
+ patch_ids: torch.Tensor | None = None,
570
+ **kwargs: Unpack[TransformersKwargs],
571
+ ):
572
+ if inputs_embeds is None:
573
+ inputs_embeds = self.embed_tokens(input_ids)
574
+
575
+ batch_size = inputs_embeds.shape[0]
576
+ hidden_states = F.dropout(inputs_embeds, p=self.config.dropout, training=self.training)
577
+
578
+ if position_ids is None:
579
+ position_ids = (
580
+ torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1)
581
+ )
582
+
583
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
584
+ hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training)
585
+
586
+ for idx, layer in enumerate(self.layers):
587
+ hidden_states = layer(
588
+ hidden_states,
589
+ position_embeddings=position_embeddings,
590
+ attention_mask=attention_mask,
591
+ past_key_values=past_key_values,
592
+ **kwargs,
593
+ )
594
+ if idx == len(self.layers) - 1 or self.config.cross_attn_all_layers:
595
+ patch_embeds = self.patch_reduce(hidden_states, num_patches, patch_ids)
596
+ patch_embeds = self.patch_embedding_projection(patch_embeds)
597
+ patch_embeds = patch_embeds.reshape(
598
+ batch_size, patch_embeds.shape[1] * self.config.cross_attn_k, self.config.hidden_size
599
+ )
600
+ layer_idx = idx if self.config.cross_attn_all_layers else 0
601
+ cross_attention_output, _ = self.cross_attn_layers[layer_idx](
602
+ hidden_states=patch_embeds,
603
+ cross_attention_states=hidden_states,
604
+ attention_mask=encoder_attention_mask,
605
+ **kwargs,
606
+ )
607
+ patch_embeds = patch_embeds + cross_attention_output
608
+ encoder_cross_states = patch_embeds
609
+ return hidden_states, encoder_cross_states
610
+
611
+ def patch_reduce(self, hidden_states, max_num_patches, patch_ids):
612
+ """
613
+ Reduce variable length patches to single embedding per patch
614
+ Note: this works with variable number of patches for different sequences in the batch
615
+ It handles variable length patches by assuming that patch_lengths will be 0 for any
616
+ extra patches on the *right*. Since there can be a variable number of patches
617
+ this function also return the number of patches for each sequence in the batch.
618
+ Any embeddings on the right that are not allocated to a patch
619
+ (i.e. if the sum(patch_lengths[i]) < seq_len for any i)
620
+ will be sent to a dummy patch, which is trimmed before returning.
621
+ """
622
+ batch_size = hidden_states.shape[0]
623
+ embedding_dim = hidden_states.shape[-1]
624
+
625
+ patch_ids = patch_ids.unsqueeze(-1).expand(-1, -1, hidden_states.shape[-1])
626
+
627
+ reduced_embeddings = torch.zeros(
628
+ (batch_size, max_num_patches, embedding_dim), dtype=hidden_states.dtype, device=hidden_states.device
629
+ )
630
+
631
+ reduced_embeddings = reduced_embeddings.scatter_reduce(
632
+ src=hidden_states,
633
+ dim=1,
634
+ index=patch_ids,
635
+ reduce="amax",
636
+ include_self=False,
637
+ )
638
+ reduced_embeddings = reduced_embeddings[:, :max_num_patches, :]
639
+
640
+ return reduced_embeddings
641
+
642
+
643
+ class BltLocalDecoder(BltPreTrainedModel):
644
+ config: BltLocalDecoderConfig
645
+
646
+ def __init__(self, config: BltLocalDecoderConfig):
647
+ super().__init__(config)
648
+ self.gradient_checkpointing = False
649
+ self.config = config
650
+ self.cross_attn_decoder = True
651
+ self.layers = nn.ModuleList(
652
+ [BltTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
653
+ )
654
+ self.rotary_emb = BltRotaryEmbedding(config=config)
655
+ self.patch_embedding_projection = nn.Linear(
656
+ in_features=config.hidden_size_global,
657
+ out_features=config.hidden_size * config.cross_attn_k,
658
+ bias=False,
659
+ )
660
+ self.norm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
661
+ self.cross_attn_layers = nn.ModuleList()
662
+ layers_to_add = config.num_hidden_layers if config.cross_attn_all_layers else 1
663
+ for layer_idx in range(layers_to_add):
664
+ self.cross_attn_layers.append(
665
+ BltCrossAttention(config=config, layer_idx=layer_idx, hidden_size=config.hidden_size)
666
+ )
667
+
668
+ self.post_init()
669
+
670
+ def forward(
671
+ self,
672
+ input_ids: torch.LongTensor | None = None,
673
+ inputs_embeds: torch.Tensor | None = None,
674
+ patch_embeds: torch.Tensor | None = None,
675
+ attention_mask: torch.Tensor | None = None,
676
+ position_ids: torch.LongTensor | None = None,
677
+ past_key_values: Cache | None = None,
678
+ encoder_attention_mask: torch.Tensor | None = None,
679
+ **kwargs: Unpack[TransformersKwargs],
680
+ ):
681
+ batch_size = inputs_embeds.shape[0]
682
+ hidden_states = inputs_embeds
683
+ patch_embeds = self.patch_embedding_projection(patch_embeds)
684
+ patch_embeds = patch_embeds.reshape(
685
+ batch_size, patch_embeds.shape[1] * self.config.cross_attn_k, self.config.hidden_size
686
+ )
687
+
688
+ if patch_embeds is not None and not self.cross_attn_decoder:
689
+ hidden_states = hidden_states + patch_embeds
690
+
691
+ if position_ids is None:
692
+ position_ids = (
693
+ torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1)
694
+ )
695
+
696
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
697
+ hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training)
698
+
699
+ for i, layer in enumerate(self.layers):
700
+ if i == 0 or self.config.cross_attn_all_layers:
701
+ cross_attention_output, _ = self.cross_attn_layers[i](
702
+ hidden_states=hidden_states,
703
+ cross_attention_states=patch_embeds,
704
+ attention_mask=encoder_attention_mask,
705
+ **kwargs,
706
+ )
707
+ hidden_states = hidden_states + cross_attention_output
708
+ hidden_states = layer(
709
+ hidden_states,
710
+ position_embeddings=position_embeddings,
711
+ attention_mask=attention_mask,
712
+ past_key_values=past_key_values,
713
+ **kwargs,
714
+ )
715
+ logits = self.norm(hidden_states)
716
+ return logits
717
+
718
+
719
+ class BltGlobalTransformer(BltPreTrainedModel):
720
+ config: BltGlobalTransformerConfig
721
+ _can_record_outputs = {
722
+ "global_attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="global_transformer"),
723
+ }
724
+
725
+ def __init__(self, config: BltGlobalTransformerConfig):
726
+ super().__init__(config)
727
+ self.config = config
728
+ self.layers = nn.ModuleList()
729
+ for layer_idx in range(config.num_hidden_layers):
730
+ self.layers.append(BltTransformerLayer(config, layer_idx))
731
+ self.rotary_emb = BltRotaryEmbedding(config=config)
732
+
733
+ # Create token embedding projection (use nn.Identity() when no projection needed)
734
+ if getattr(config, "encoder_cross_output_size", None) is not None:
735
+ self.token_embedding_projection = nn.Linear(
736
+ config.encoder_cross_output_size, config.hidden_size, bias=False
737
+ )
738
+ else:
739
+ self.token_embedding_projection = nn.Identity()
740
+
741
+ self.post_init()
742
+
743
+ @deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
744
+ def forward(
745
+ self,
746
+ inputs_embeds: torch.Tensor,
747
+ attention_mask: torch.Tensor | None = None,
748
+ position_ids: torch.LongTensor | None = None,
749
+ past_key_values: Cache | None = None,
750
+ **kwargs: Unpack[TransformersKwargs],
751
+ ):
752
+ batch_size, seq_len, _ = inputs_embeds.shape
753
+ hidden_states = self.token_embedding_projection(inputs_embeds)
754
+ hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training)
755
+ if position_ids is None:
756
+ position_ids = (
757
+ torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1)
758
+ )
759
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
760
+ for i, layer in enumerate(self.layers):
761
+ hidden_states = layer(
762
+ hidden_states,
763
+ position_embeddings=position_embeddings,
764
+ attention_mask=attention_mask,
765
+ past_key_values=past_key_values,
766
+ **kwargs,
767
+ )
768
+ return hidden_states
769
+
770
+
771
+ class BltPatcher(BltPreTrainedModel):
772
+ config: BltPatcherConfig
773
+
774
+ def __init__(self, config: BltPatcherConfig):
775
+ super().__init__(config)
776
+ self.rotary_emb = BltRotaryEmbedding(config=self.config)
777
+ self.layers = nn.ModuleList()
778
+ for layer_idx in range(self.config.num_hidden_layers):
779
+ self.layers.append(BltTransformerLayer(self.config, layer_idx))
780
+ self.embed_tokens = nn.Embedding(self.config.vocab_size, self.config.hidden_size)
781
+ self.norm = BltRMSNorm(self.config.hidden_size, eps=self.config.rms_norm_eps)
782
+ self.lm_head = nn.Linear(
783
+ self.config.hidden_size,
784
+ self.config.vocab_size,
785
+ bias=False,
786
+ )
787
+
788
+ self.post_init()
789
+
790
+ def forward(
791
+ self,
792
+ input_ids: torch.LongTensor | None = None,
793
+ attention_mask: torch.Tensor | None = None,
794
+ position_ids: torch.LongTensor | None = None,
795
+ past_key_values: Cache | None = None,
796
+ inputs_embeds: torch.FloatTensor | None = None,
797
+ use_cache: bool | None = None,
798
+ patch_size: int | None = None,
799
+ threshold: float | None = None,
800
+ max_patch_length: int | None = None,
801
+ **kwargs: Unpack[TransformersKwargs],
802
+ ):
803
+ if (input_ids is None) ^ (inputs_embeds is not None):
804
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
805
+
806
+ if inputs_embeds is None:
807
+ inputs_embeds = self.embed_tokens(input_ids)
808
+
809
+ if use_cache and past_key_values is None:
810
+ past_key_values = DynamicCache(config=self.config)
811
+
812
+ if position_ids is None:
813
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
814
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
815
+ position_ids = position_ids.unsqueeze(0)
816
+
817
+ causal_mask = create_causal_mask(
818
+ config=self.config,
819
+ inputs_embeds=inputs_embeds,
820
+ attention_mask=attention_mask,
821
+ past_key_values=past_key_values,
822
+ position_ids=position_ids,
823
+ )
824
+
825
+ hidden_states = inputs_embeds
826
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
827
+
828
+ for layer in self.layers:
829
+ hidden_states = layer(hidden_states, position_embeddings=position_embeddings, attention_mask=causal_mask)
830
+
831
+ logits = self.lm_head(self.norm(hidden_states))
832
+ prediction_entropies = torch.distributions.Categorical(logits=logits).entropy()
833
+
834
+ batch_size, sequence_length = inputs_embeds.shape[:2]
835
+ if patch_size is not None:
836
+ patch_lengths = self.patch_lengths_from_entropies(
837
+ entropies=prediction_entropies,
838
+ sequence_length=sequence_length,
839
+ patch_size=patch_size,
840
+ threshold=threshold,
841
+ )
842
+ else:
843
+ patch_lengths = torch.ones(
844
+ (batch_size, sequence_length), dtype=inputs_embeds.dtype, device=inputs_embeds.device
845
+ )
846
+ patch_lengths = process_patch_lengths(patch_lengths, max_patch_length)
847
+ return prediction_entropies, patch_lengths, logits
848
+
849
+ @staticmethod
850
+ def patch_lengths_from_entropies(
851
+ entropies,
852
+ sequence_length,
853
+ patch_size=None,
854
+ threshold=None,
855
+ ):
856
+ """
857
+ Computes patch lengths from token entropies.
858
+
859
+ Depending on whether a threshold is provided, the function uses either:
860
+ - Thresholding the entropy values (when `threshold` is set).
861
+ """
862
+
863
+ batch_size = entropies.shape[0]
864
+
865
+ # Always include token 0 and 1 as starting tokens
866
+ init_tokens = (
867
+ torch.tensor([0, 1], dtype=torch.long, device=entropies.device).unsqueeze(0).repeat(batch_size, 1)
868
+ )
869
+ offset = init_tokens.shape[1]
870
+
871
+ # Ignore first token entropy (BOS)
872
+ entropies = entropies[:, 1:]
873
+
874
+ # Threshold the entropy values to define patch start points
875
+ patch_mask = entropies > threshold
876
+
877
+ seq_len = patch_mask.shape[1]
878
+
879
+ # Create patch IDs (token indices), and add a sentinel to ensure alignment
880
+ token_indices = torch.arange(seq_len, device=entropies.device).unsqueeze(0).expand(batch_size, -1)
881
+ sentinel = torch.full_like(token_indices, seq_len)
882
+ padded_indices = torch.cat([token_indices, sentinel], dim=1)
883
+
884
+ # Pad mask with inverse to align sentinel correctly
885
+ padded_mask = torch.cat([patch_mask, ~patch_mask], dim=1)
886
+
887
+ # Select indices where mask is True
888
+ patch_starts = padded_indices[padded_mask].reshape(batch_size, seq_len)
889
+ max_valid_patches = patch_mask.sum(dim=1).max()
890
+ patch_starts = patch_starts[:, :max_valid_patches]
891
+
892
+ # Offset patch starts to account for the two initial tokens
893
+ patch_start_ids = torch.cat((init_tokens, patch_starts + offset), dim=1)
894
+
895
+ # Compute patch end positions by shifting start positions
896
+ last_token = torch.full_like(patch_start_ids[:, :1], sequence_length - 1)
897
+ patch_ends = torch.cat((patch_start_ids[:, 1:] - 1, last_token), dim=1)
898
+
899
+ patch_lengths = patch_ends - patch_start_ids + 1
900
+
901
+ return patch_lengths
902
+
903
+
904
+ class BltModel(BltPreTrainedModel):
905
+ def __init__(self, config: BltConfig):
906
+ super().__init__(config)
907
+ self.gradient_checkpointing = False
908
+
909
+ self.config = config
910
+ self.local_encoder = BltLocalEncoder(config.encoder_config)
911
+ self.global_transformer = BltGlobalTransformer(config.global_config)
912
+ self.local_decoder = BltLocalDecoder(config.decoder_config)
913
+ num_embeddings = config.encoder_hash_byte_group_nb_functions * len(config.encoder_hash_byte_group_size)
914
+ total_vocab_size = config.encoder_hash_byte_group_vocab * num_embeddings
915
+ self.encoder_hash_tok_embedding = nn.Embedding(total_vocab_size, config.encoder_config.hidden_size)
916
+ if self.config.patch_in_forward:
917
+ self.patcher = BltPatcher(config.patcher_config)
918
+ self.patcher.eval()
919
+ for param in self.patcher.parameters():
920
+ param.requires_grad = False
921
+ else:
922
+ self.patcher = None
923
+ self.post_init()
924
+
925
+ @merge_with_config_defaults
926
+ @capture_outputs
927
+ def forward(
928
+ self,
929
+ input_ids: torch.LongTensor | None = None,
930
+ patch_lengths: torch.Tensor | None = None,
931
+ attention_mask: torch.Tensor | None = None,
932
+ position_ids: torch.LongTensor | None = None,
933
+ past_key_values: Cache | None = None,
934
+ inputs_embeds: torch.FloatTensor | None = None,
935
+ use_cache: bool | None = None,
936
+ **kwargs: Unpack[TransformersKwargs],
937
+ ) -> tuple | BaseModelOutputWithPast:
938
+ if (input_ids is None) ^ (inputs_embeds is not None):
939
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
940
+
941
+ if use_cache:
942
+ if past_key_values is None:
943
+ past_key_values = EncoderDecoderCache(
944
+ DynamicCache(config=self.config), DynamicCache(config=self.config)
945
+ )
946
+ elif not isinstance(past_key_values, EncoderDecoderCache):
947
+ # BLT uses an encoder-decoder cache even though it is not en encoder-decoder model. Create a cross-cache
948
+ # if not yet created by the user
949
+ past_key_values = EncoderDecoderCache(past_key_values, DynamicCache(config=self.config))
950
+
951
+ # Extract input embeddings as early as possible
952
+ if inputs_embeds is not None:
953
+ encoder_embeds = inputs_embeds
954
+ batch_size, sequence_length, _ = inputs_embeds.shape
955
+ else:
956
+ batch_size, sequence_length = input_ids.shape
957
+ encoder_embeds = compute_hash_embeddings(
958
+ input_ids,
959
+ self.local_encoder,
960
+ self.encoder_hash_tok_embedding,
961
+ self.config.encoder_hash_byte_group_nb_functions,
962
+ self.config.encoder_hash_byte_group_size,
963
+ self.config.encoder_hash_byte_group_vocab,
964
+ )
965
+
966
+ if patch_lengths is None:
967
+ if self.config.patching_mode == "entropy" and self.patcher is not None:
968
+ if input_ids is None:
969
+ raise ValueError("input_ids is required for entropy-based patching")
970
+ _, patch_lengths, _ = self.patcher(
971
+ input_ids,
972
+ patch_size=self.config.patch_size,
973
+ threshold=self.config.patching_threshold,
974
+ max_patch_length=self.config.max_patch_length,
975
+ patching_batch_size=self.config.patching_batch_size,
976
+ device=input_ids.device,
977
+ )
978
+ else:
979
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
980
+ dtype = input_ids.dtype if input_ids is not None else inputs_embeds.dtype
981
+ patch_lengths = process_patch_lengths(
982
+ torch.ones((batch_size, sequence_length + 1), dtype=dtype, device=device),
983
+ self.config.max_patch_length,
984
+ )
985
+ patch_ids = self._patch_ids_from_lengths(patch_lengths, sequence_length)
986
+
987
+ if position_ids is None:
988
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
989
+ position_ids = torch.arange(encoder_embeds.shape[1], device=encoder_embeds.device) + past_seen_tokens
990
+ position_ids = position_ids.unsqueeze(0)
991
+
992
+ causal_mask = create_causal_mask(
993
+ config=self.config,
994
+ inputs_embeds=encoder_embeds,
995
+ attention_mask=attention_mask,
996
+ past_key_values=past_key_values.self_attention_cache if past_key_values is not None else None,
997
+ position_ids=position_ids,
998
+ )
999
+
1000
+ cross_attn_mask_enc = _prepare_patch_cross_attention_mask(
1001
+ patch_ids=patch_ids,
1002
+ num_patches=patch_lengths.shape[1],
1003
+ sequence_length=sequence_length,
1004
+ patches_as_queries=True,
1005
+ cross_attn_k=self.config.cross_attn_k,
1006
+ dtype=encoder_embeds.dtype,
1007
+ )
1008
+ encoder_hidden_states, encoder_cross_states = self.local_encoder(
1009
+ input_ids=input_ids,
1010
+ inputs_embeds=encoder_embeds,
1011
+ attention_mask=causal_mask,
1012
+ position_ids=position_ids,
1013
+ encoder_attention_mask=cross_attn_mask_enc,
1014
+ num_patches=patch_lengths.shape[1],
1015
+ patch_ids=patch_ids,
1016
+ past_key_values=past_key_values.self_attention_cache if past_key_values is not None else None,
1017
+ **kwargs,
1018
+ )
1019
+ encoder_cross_states = encoder_cross_states.view(batch_size, patch_lengths.shape[1], -1)
1020
+ global_position_ids = torch.arange(0, encoder_cross_states.shape[1], device=encoder_cross_states.device)
1021
+ global_position_ids = global_position_ids.unsqueeze(0)
1022
+ global_causal_mask = create_causal_mask(
1023
+ config=self.config,
1024
+ inputs_embeds=encoder_cross_states,
1025
+ attention_mask=None,
1026
+ past_key_values=None,
1027
+ position_ids=None,
1028
+ )
1029
+
1030
+ global_hidden_states = self.global_transformer(
1031
+ inputs_embeds=encoder_cross_states,
1032
+ attention_mask=global_causal_mask,
1033
+ position_ids=global_position_ids,
1034
+ **kwargs,
1035
+ )
1036
+ decoder_patch_ids = self._patch_ids_from_lengths(patch_lengths[:, 1:], sequence_length)
1037
+ cross_attn_mask_dec = _prepare_patch_cross_attention_mask(
1038
+ patch_ids=decoder_patch_ids,
1039
+ num_patches=patch_lengths.shape[1],
1040
+ sequence_length=sequence_length,
1041
+ patches_as_queries=False,
1042
+ cross_attn_k=self.config.cross_attn_k,
1043
+ dtype=encoder_embeds.dtype,
1044
+ )
1045
+ output = self.local_decoder(
1046
+ input_ids=input_ids,
1047
+ inputs_embeds=encoder_hidden_states,
1048
+ patch_embeds=global_hidden_states,
1049
+ attention_mask=causal_mask,
1050
+ position_ids=position_ids,
1051
+ past_key_values=past_key_values.cross_attention_cache if past_key_values is not None else None,
1052
+ encoder_attention_mask=cross_attn_mask_dec,
1053
+ **kwargs,
1054
+ )
1055
+ return BaseModelOutputWithPast(
1056
+ last_hidden_state=output,
1057
+ past_key_values=past_key_values,
1058
+ )
1059
+
1060
+ def get_input_embeddings(self):
1061
+ return self.local_encoder.embed_tokens
1062
+
1063
+ def set_input_embeddings(self, value):
1064
+ self.local_encoder.embed_tokens = value
1065
+
1066
+ def _patch_ids_from_lengths(self, patch_lengths: torch.Tensor, seq_len: int) -> torch.Tensor:
1067
+ batch_size = patch_lengths.shape[0]
1068
+ patch_starts = torch.cat(
1069
+ [
1070
+ torch.zeros(batch_size, 1, dtype=patch_lengths.dtype, device=patch_lengths.device),
1071
+ patch_lengths.cumsum(dim=-1)[:, :-1],
1072
+ ],
1073
+ dim=-1,
1074
+ )
1075
+ token_positions = torch.arange(seq_len, device=patch_lengths.device)
1076
+ return (patch_starts.unsqueeze(1) <= token_positions.unsqueeze(0).unsqueeze(-1)).sum(dim=-1) - 1
1077
+
1078
+
1079
+ @auto_docstring(
1080
+ custom_intro="""
1081
+ The Blt Text Model with a language modeling head on top.
1082
+ """
1083
+ )
1084
+ class BltForCausalLM(BltPreTrainedModel, GenerationMixin):
1085
+ config: BltConfig
1086
+ _can_compile_fullgraph = False
1087
+ base_model_prefix = "model"
1088
+ _tied_weights_keys = {"model.local_encoder.embed_tokens.weight": "lm_head.weight"}
1089
+
1090
+ def __init__(self, config: BltConfig):
1091
+ super().__init__(config)
1092
+ self.text_config = config.get_text_config()
1093
+ self.vocab_size = config.vocab_size
1094
+ self.model = BltModel(config)
1095
+ self.lm_head = nn.Linear(config.decoder_config.hidden_size, config.vocab_size, bias=False)
1096
+
1097
+ self.post_init()
1098
+
1099
+ @can_return_tuple
1100
+ @auto_docstring
1101
+ def forward(
1102
+ self,
1103
+ input_ids: torch.LongTensor | None = None,
1104
+ attention_mask: torch.Tensor | None = None,
1105
+ position_ids: torch.LongTensor | None = None,
1106
+ cross_attention_states: torch.LongTensor | None = None, # Keep for compatibility
1107
+ cross_attention_mask: torch.LongTensor | None = None,
1108
+ full_text_row_masked_out_mask: tuple[torch.Tensor, torch.Tensor] | None = None,
1109
+ past_key_values: Cache | None = None,
1110
+ inputs_embeds: torch.FloatTensor | None = None,
1111
+ labels: torch.LongTensor | None = None,
1112
+ use_cache: bool | None = None,
1113
+ logits_to_keep: int | torch.Tensor = 0,
1114
+ **kwargs: Unpack[TransformersKwargs],
1115
+ ) -> tuple | CausalLMOutputWithPast:
1116
+ r"""
1117
+ cross_attention_states (`torch.FloatTensor`, *optional*):
1118
+ Output of the vision model, used for cross-attention. This tensor contains the processed image features that
1119
+ the language model will attend to.
1120
+ cross_attention_mask (`torch.Tensor` of shape `(batch_size, seq_length, max_num_images, max_num_tiles)`, *optional*):
1121
+ Cross-attention mask to control the interaction between text tokens and image tiles.
1122
+ This 4D tensor defines which image tiles each text token should attend to.
1123
+
1124
+ For each text token (in seq_length):
1125
+ - 1 indicates the token **should attend** to the corresponding image tile
1126
+ - 0 indicates the token **should not attend** to the corresponding image tile
1127
+ full_text_row_masked_out_mask (`tuple[torch.Tensor, torch.Tensor]`, *optional*):
1128
+ A tuple containing two tensors that mask out rows in the cross-attention mechanism:
1129
+ - The first tensor has shape `(batch_size, 1, seq_length, 1)` and contains values of 0 or 1.
1130
+ A value of 0 indicates that the corresponding text token's entire row in the cross-attention
1131
+ matrix should be masked out (all image tokens ignored).
1132
+ - The second tensor has the same shape and is used internally to apply the masking during
1133
+ the forward pass of cross-attention layers.
1134
+ This mask is derived from the cross_attention_mask and is used to handle cases where a text token
1135
+ should not attend to any image token.
1136
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1137
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
1138
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
1139
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
1140
+
1141
+ Example:
1142
+
1143
+ ```python
1144
+ >>> from transformers import AutoTokenizer, BltForCausalLM
1145
+
1146
+ >>> model = BltForCausalLM.from_pretrained("itazap/blt-1b-hf")
1147
+ >>> tokenizer = AutoTokenizer.from_pretrained("itazap/blt-1b-hf")
1148
+
1149
+ >>> prompt = "If I had to write a haiku, it would be:"
1150
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
1151
+
1152
+ >>> # Generate
1153
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=40, do_sample=True, temperature=0.6)
1154
+ >>> result = tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
1155
+ >>> print(result)
1156
+ If I had to write a haiku, it would be: "Snowflakes gently fall" - simple, yet peaceful.
1157
+ I love the idea of snowflakes gently falling, each one
1158
+ ```
1159
+ """
1160
+ # Call parent forward but exclude cross_attention_states from model call
1161
+ outputs = self.model(
1162
+ input_ids=input_ids,
1163
+ attention_mask=attention_mask,
1164
+ position_ids=position_ids,
1165
+ cross_attention_mask=cross_attention_mask,
1166
+ full_text_row_masked_out_mask=full_text_row_masked_out_mask,
1167
+ past_key_values=past_key_values,
1168
+ inputs_embeds=inputs_embeds,
1169
+ use_cache=use_cache,
1170
+ **kwargs,
1171
+ )
1172
+
1173
+ hidden_states = outputs.last_hidden_state
1174
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
1175
+ logits = self.lm_head(hidden_states[:, slice_indices, :]).float()
1176
+
1177
+ loss = None
1178
+ if labels is not None:
1179
+ loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)
1180
+
1181
+ return CausalLMOutputWithPast(
1182
+ loss=loss,
1183
+ logits=logits,
1184
+ past_key_values=outputs.past_key_values,
1185
+ hidden_states=outputs.hidden_states,
1186
+ attentions=outputs.attentions,
1187
+ )
1188
+
1189
+
1190
+ __all__ = [
1191
+ "BltPreTrainedModel",
1192
+ "BltModel",
1193
+ "BltPatcher",
1194
+ "BltForCausalLM",
1195
+ ]
third_party/transformers/src/transformers/models/byt5/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 .tokenization_byt5 import *
22
+ else:
23
+ import sys
24
+
25
+ _file = globals()["__file__"]
26
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/byt5/convert_byt5_original_tf_checkpoint_to_pytorch.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 The T5 authors and 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 T5 checkpoint."""
15
+
16
+ import argparse
17
+ import os
18
+
19
+ import torch
20
+
21
+ from transformers import T5Config, T5ForConditionalGeneration
22
+ from transformers.utils import logging
23
+
24
+
25
+ logger = logging.get_logger(__name__)
26
+ logging.set_verbosity_info()
27
+
28
+
29
+ def load_tf_weights_in_t5(model, config, tf_checkpoint_path):
30
+ """Load tf checkpoints in a pytorch model."""
31
+ try:
32
+ import re
33
+
34
+ import numpy as np
35
+ import tensorflow as tf
36
+ except ImportError:
37
+ logger.error(
38
+ "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see "
39
+ "https://www.tensorflow.org/install/ for installation instructions."
40
+ )
41
+ raise
42
+ tf_path = os.path.abspath(tf_checkpoint_path)
43
+ logger.info(f"Converting TensorFlow checkpoint from {tf_path}")
44
+ # Load weights from TF model
45
+ init_vars = tf.train.list_variables(tf_path)
46
+ names = []
47
+ tf_weights = {}
48
+ for name, shape in init_vars:
49
+ logger.info(f"Loading TF weight {name} with shape {shape}")
50
+ array = tf.train.load_variable(tf_path, name)
51
+ names.append(name)
52
+ tf_weights[name] = array
53
+
54
+ for txt_name in names:
55
+ name = txt_name.split("/")
56
+ # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v
57
+ # which are not required for using pretrained model
58
+ if any(
59
+ n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"]
60
+ for n in name
61
+ ):
62
+ logger.info(f"Skipping {'/'.join(name)}")
63
+ tf_weights.pop(txt_name, None)
64
+ continue
65
+ if "_slot_" in name[-1]:
66
+ logger.info(f"Skipping {'/'.join(name)}")
67
+ tf_weights.pop(txt_name, None)
68
+ continue
69
+ pointer = model
70
+ array = tf_weights[txt_name]
71
+
72
+ for m_name in name:
73
+ if re.fullmatch(r"[A-Za-z]+_\d+", m_name):
74
+ scope_names = re.split(r"_(\d+)", m_name)
75
+ else:
76
+ scope_names = [m_name]
77
+ if scope_names[0] in ["kernel", "scale", "embedding"]:
78
+ pointer = getattr(pointer, "weight")
79
+ elif scope_names[0] == "self_attention":
80
+ pointer = getattr(pointer, "layer")
81
+ pointer = pointer[0]
82
+ elif scope_names[0] == "enc_dec_attention":
83
+ pointer = getattr(pointer, "layer")
84
+ pointer = pointer[1]
85
+ elif scope_names[0] == "dense_relu_dense":
86
+ pointer = getattr(pointer, "layer")
87
+ pointer = pointer[2]
88
+ elif scope_names[0] == "rms_norm":
89
+ if hasattr(pointer, "layer_norm"):
90
+ pointer = getattr(pointer, "layer_norm")
91
+ elif hasattr(pointer, "final_layer_norm"):
92
+ pointer = getattr(pointer, "final_layer_norm")
93
+ elif scope_names[0] == "scale":
94
+ pointer = getattr(pointer, "weight")
95
+ elif scope_names[0] == "output_bias" or scope_names[0] == "beta":
96
+ pointer = getattr(pointer, "bias")
97
+ elif scope_names[0] == "squad":
98
+ pointer = getattr(pointer, "classifier")
99
+ elif scope_names[0] == "decoder" and name[1] == "logits":
100
+ continue
101
+ elif scope_names[0] == "logits":
102
+ pointer = getattr(pointer, "lm_head")
103
+ elif scope_names[0] == "wi" and len(scope_names) > 1 and scope_names[1].isdigit():
104
+ pointer = getattr(pointer, f"wi_{scope_names[1]}")
105
+ continue
106
+ else:
107
+ try:
108
+ pointer = getattr(pointer, scope_names[0])
109
+ except AttributeError:
110
+ logger.info(f"Skipping {'/'.join(name)}")
111
+ continue
112
+ if len(scope_names) >= 2:
113
+ num = int(scope_names[1])
114
+ pointer = pointer[num]
115
+ if scope_names[0] not in ["kernel", "scale", "embedding"]:
116
+ pointer = getattr(pointer, "weight")
117
+ if scope_names[0] != "embedding":
118
+ logger.info(f"Transposing numpy weight of shape {array.shape} for {name}")
119
+ array = np.transpose(array)
120
+ try:
121
+ if pointer.shape != array.shape:
122
+ raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched")
123
+ except AssertionError as e:
124
+ e.args += (pointer.shape, array.shape)
125
+ raise
126
+ logger.info(f"Initialize PyTorch weight {name}")
127
+ pointer.data = torch.from_numpy(array.astype(np.float32))
128
+ tf_weights.pop(txt_name, None)
129
+
130
+ logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}.")
131
+ return model
132
+
133
+
134
+ def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, config_file, pytorch_dump_path):
135
+ # Initialise PyTorch model
136
+ config = T5Config.from_json_file(config_file)
137
+ print(f"Building PyTorch model from configuration: {config}")
138
+ model = T5ForConditionalGeneration(config)
139
+
140
+ # Load weights from tf checkpoint
141
+ load_tf_weights_in_t5(model, config, tf_checkpoint_path)
142
+
143
+ # Save pytorch-model
144
+ print(f"Save PyTorch model to {pytorch_dump_path}")
145
+ model.save_pretrained(pytorch_dump_path)
146
+
147
+
148
+ if __name__ == "__main__":
149
+ parser = argparse.ArgumentParser()
150
+ # Required parameters
151
+ parser.add_argument(
152
+ "--tf_checkpoint_path", default=None, type=str, required=True, help="Path to the TensorFlow checkpoint path."
153
+ )
154
+ parser.add_argument(
155
+ "--config_file",
156
+ default=None,
157
+ type=str,
158
+ required=True,
159
+ help=(
160
+ "The config json file corresponding to the pre-trained T5 model. \nThis specifies the model architecture."
161
+ ),
162
+ )
163
+ parser.add_argument(
164
+ "--pytorch_dump_path", default=None, type=str, required=True, help="Path to the output PyTorch model."
165
+ )
166
+ args = parser.parse_args()
167
+ convert_tf_checkpoint_to_pytorch(args.tf_checkpoint_path, args.config_file, args.pytorch_dump_path)
third_party/transformers/src/transformers/models/byt5/tokenization_byt5.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 T5 Authors and 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
+ """Tokenization class for model ByT5."""
15
+
16
+ import warnings
17
+
18
+ from ...tokenization_python import AddedToken, PreTrainedTokenizer
19
+ from ...utils import logging
20
+
21
+
22
+ logger = logging.get_logger(__name__)
23
+
24
+
25
+ class ByT5Tokenizer(PreTrainedTokenizer):
26
+ """
27
+ Construct a ByT5 tokenizer. ByT5 simply uses raw bytes utf-8 encoding.
28
+
29
+ This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to
30
+ this superclass for more information regarding those methods.
31
+
32
+ Args:
33
+ eos_token (`str`, *optional*, defaults to `"</s>"`):
34
+ The end of sequence token.
35
+
36
+ <Tip>
37
+
38
+ When building a sequence using special tokens, this is not the token that is used for the end of sequence.
39
+ The token used is the `sep_token`.
40
+
41
+ </Tip>
42
+
43
+ unk_token (`str`, *optional*, defaults to `"<unk>"`):
44
+ The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
45
+ token instead.
46
+ pad_token (`str`, *optional*, defaults to `"<pad>"`):
47
+ The token used for padding, for example when batching sequences of different lengths.
48
+ extra_ids (`int`, *optional*, defaults to 125):
49
+ Add a number of extra ids added to the end of the vocabulary for use as sentinels. These tokens are
50
+ accessible as "<extra_id_{%d}>" where "{%d}" is a number between 0 and extra_ids-1. Extra tokens are
51
+ indexed from the end of the vocabulary up to beginning ("<extra_id_0>" is the last token in the vocabulary
52
+ like in ByT5 preprocessing see
53
+ [here](https://github.com/google-research/text-to-text-transfer-transformer/blob/9fd7b14a769417be33bc6c850f9598764913c833/t5/data/preprocessors.py#L2117)).
54
+ additional_special_tokens (`list[str]`, *optional*):
55
+ Additional special tokens used by the tokenizer.
56
+ """
57
+
58
+ model_input_names = ["input_ids", "attention_mask"]
59
+
60
+ def __init__(
61
+ self,
62
+ eos_token="</s>",
63
+ unk_token="<unk>",
64
+ pad_token="<pad>",
65
+ extra_ids=125,
66
+ additional_special_tokens=None,
67
+ **kwargs,
68
+ ) -> None:
69
+ # Add extra_ids to the special token list
70
+ if extra_ids > 0 and additional_special_tokens is None:
71
+ additional_special_tokens = [f"<extra_id_{i}>" for i in range(extra_ids)]
72
+ elif extra_ids > 0 and additional_special_tokens is not None and len(additional_special_tokens) > 0:
73
+ # Check that we have the right number of extra_id special tokens
74
+ extra_tokens = len(set(filter(lambda x: bool("extra_id" in str(x)), additional_special_tokens)))
75
+ if extra_tokens != extra_ids:
76
+ raise ValueError(
77
+ f"Both extra_ids ({extra_ids}) and additional_special_tokens ({additional_special_tokens}) are"
78
+ " provided to ByT5Tokenizer. In this case the additional_special_tokens must include the"
79
+ " extra_ids tokens"
80
+ )
81
+
82
+ pad_token = AddedToken(pad_token, lstrip=True, rstrip=True) if isinstance(pad_token, str) else pad_token
83
+ # we force left and right stripping for backward compatibility. The byt5tests depend on this.
84
+ eos_token = AddedToken(eos_token, lstrip=True, rstrip=True) if isinstance(eos_token, str) else eos_token
85
+ unk_token = AddedToken(unk_token, lstrip=True, rstrip=True) if isinstance(unk_token, str) else unk_token
86
+ # unk token needs to be in the vocab with correct index
87
+ self._added_tokens_decoder = {0: pad_token, 1: eos_token, 2: unk_token}
88
+ self.offset = len(self._added_tokens_decoder)
89
+ self._utf_vocab_size = 2**8 # utf is 8 bits
90
+ super().__init__(
91
+ eos_token=eos_token,
92
+ unk_token=unk_token,
93
+ pad_token=pad_token,
94
+ extra_ids=0,
95
+ additional_special_tokens=additional_special_tokens, # TODO extra ids are not used :sweatywmile:
96
+ **kwargs,
97
+ )
98
+
99
+ @property
100
+ def vocab_size(self):
101
+ return self._utf_vocab_size
102
+
103
+ def get_vocab(self):
104
+ vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size + self.offset)}
105
+ vocab.update(self.added_tokens_encoder)
106
+ return vocab
107
+
108
+ def get_special_tokens_mask(
109
+ self, token_ids_0: list[int], token_ids_1: list[int] | None = None, already_has_special_tokens: bool = False
110
+ ) -> list[int]:
111
+ """
112
+ Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding
113
+ special tokens using the tokenizer `prepare_for_model` method.
114
+
115
+ Args:
116
+ token_ids_0 (`list[int]`):
117
+ List of IDs.
118
+ token_ids_1 (`list[int]`, *optional*):
119
+ Optional second list of IDs for sequence pairs.
120
+ already_has_special_tokens (`bool`, *optional*, defaults to `False`):
121
+ Whether or not the token list is already formatted with special tokens for the model.
122
+
123
+ Returns:
124
+ `list[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token.
125
+ """
126
+ if already_has_special_tokens:
127
+ return super().get_special_tokens_mask(
128
+ token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True
129
+ )
130
+
131
+ # normal case: some special tokens
132
+ if token_ids_1 is None:
133
+ return ([0] * len(token_ids_0)) + [1]
134
+ return ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1]
135
+
136
+ def _add_eos_if_not_present(self, token_ids: list[int]) -> list[int]:
137
+ """Do not add eos again if user already added it."""
138
+ if len(token_ids) > 0 and token_ids[-1] == self.eos_token_id:
139
+ warnings.warn(
140
+ f"This sequence already has {self.eos_token}. In future versions this behavior may lead to duplicated"
141
+ " eos tokens being added."
142
+ )
143
+ return token_ids
144
+ else:
145
+ return token_ids + [self.eos_token_id]
146
+
147
+ def create_token_type_ids_from_sequences(
148
+ self, token_ids_0: list[int], token_ids_1: list[int] | None = None
149
+ ) -> list[int]:
150
+ """
151
+ Create a mask from the two sequences passed to be used in a sequence-pair classification task. ByT5 does not
152
+ make use of token type ids, therefore a list of zeros is returned.
153
+
154
+ Args:
155
+ token_ids_0 (`list[int]`):
156
+ List of IDs.
157
+ token_ids_1 (`list[int]`, *optional*):
158
+ Optional second list of IDs for sequence pairs.
159
+
160
+ Returns:
161
+ `list[int]`: List of zeros.
162
+ """
163
+ eos = [self.eos_token_id]
164
+
165
+ if token_ids_1 is None:
166
+ return len(token_ids_0 + eos) * [0]
167
+ return len(token_ids_0 + eos + token_ids_1 + eos) * [0]
168
+
169
+ def build_inputs_with_special_tokens(
170
+ self, token_ids_0: list[int], token_ids_1: list[int] | None = None
171
+ ) -> list[int]:
172
+ """
173
+ Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and
174
+ adding special tokens. A sequence has the following format:
175
+
176
+ - single sequence: `X </s>`
177
+ - pair of sequences: `A </s> B </s>`
178
+
179
+ Args:
180
+ token_ids_0 (`list[int]`):
181
+ List of IDs to which the special tokens will be added.
182
+ token_ids_1 (`list[int]`, *optional*):
183
+ Optional second list of IDs for sequence pairs.
184
+
185
+ Returns:
186
+ `list[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens.
187
+ """
188
+ token_ids_0 = self._add_eos_if_not_present(token_ids_0)
189
+ if token_ids_1 is None:
190
+ return token_ids_0
191
+ else:
192
+ token_ids_1 = self._add_eos_if_not_present(token_ids_1)
193
+ return token_ids_0 + token_ids_1
194
+
195
+ def _tokenize(self, text: str) -> list[str]:
196
+ """Take as input a string and return a list of strings (tokens) for words/sub-words"""
197
+ tokens = [chr(i) for i in text.encode("utf-8")]
198
+ return tokens
199
+
200
+ def _convert_token_to_id(self, token):
201
+ """Converts a token (str) in an id using the vocab."""
202
+
203
+ if len(token) != 1:
204
+ token_id = None
205
+ else:
206
+ token_id = ord(token) + self.offset
207
+
208
+ return token_id
209
+
210
+ def _convert_id_to_token(self, index):
211
+ """Converts an index (integer) in a token (str) using the vocab."""
212
+ token = chr(index - self.offset)
213
+ return token
214
+
215
+ def convert_tokens_to_string(self, tokens):
216
+ """Converts a sequence of tokens (string) in a single string."""
217
+ bstring = b""
218
+ for token in tokens:
219
+ if token in self.added_tokens_decoder:
220
+ tok_string = self.added_tokens_decoder[token].encode("utf-8")
221
+ elif token in self.added_tokens_encoder:
222
+ tok_string = token.encode("utf-8")
223
+ else:
224
+ tok_string = bytes([ord(token)])
225
+ bstring += tok_string
226
+ string = bstring.decode("utf-8", errors="ignore")
227
+ return string
228
+
229
+ # ByT5Tokenizer has no vocab file
230
+ def save_vocabulary(self, save_directory: str, filename_prefix: str | None = None) -> tuple[str]:
231
+ return ()
232
+
233
+
234
+ __all__ = ["ByT5Tokenizer"]
third_party/transformers/src/transformers/models/clip/__init__.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_clip import *
22
+ from .image_processing_clip import *
23
+ from .image_processing_pil_clip import *
24
+ from .modeling_clip import *
25
+ from .processing_clip import *
26
+ from .tokenization_clip import *
27
+ else:
28
+ import sys
29
+
30
+ _file = globals()["__file__"]
31
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/clip/configuration_clip.py ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 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
+ """CLIP model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...configuration_utils import PreTrainedConfig
19
+ from ...utils import auto_docstring, logging
20
+
21
+
22
+ logger = logging.get_logger(__name__)
23
+
24
+
25
+ @auto_docstring(checkpoint="openai/clip-vit-base-patch32")
26
+ @strict
27
+ class CLIPTextConfig(PreTrainedConfig):
28
+ r"""
29
+ Example:
30
+
31
+ ```python
32
+ >>> from transformers import CLIPTextConfig, CLIPTextModel
33
+
34
+ >>> # Initializing a CLIPTextConfig with openai/clip-vit-base-patch32 style configuration
35
+ >>> configuration = CLIPTextConfig()
36
+
37
+ >>> # Initializing a CLIPTextModel (with random weights) from the openai/clip-vit-base-patch32 style configuration
38
+ >>> model = CLIPTextModel(configuration)
39
+
40
+ >>> # Accessing the model configuration
41
+ >>> configuration = model.config
42
+ ```"""
43
+
44
+ model_type = "clip_text_model"
45
+ base_config_key = "text_config"
46
+
47
+ vocab_size: int = 49408
48
+ hidden_size: int = 512
49
+ intermediate_size: int = 2048
50
+ projection_dim: int | None = 512
51
+ num_hidden_layers: int = 12
52
+ num_attention_heads: int = 8
53
+ max_position_embeddings: int = 77
54
+ hidden_act: str = "quick_gelu"
55
+ layer_norm_eps: float | None = 1e-5
56
+ attention_dropout: int | float | None = 0.0
57
+ initializer_range: float = 0.02
58
+ initializer_factor: float | None = 1.0
59
+
60
+ # This differs from `CLIPTokenizer`'s default and from openai/clip
61
+ # See https://github.com/huggingface/transformers/pull/24773#issuecomment-1632287538
62
+ pad_token_id: int | None = 1
63
+ bos_token_id: int | None = 49406
64
+ eos_token_id: int | list[int] | None = 49407
65
+
66
+ def validate_architecture(self):
67
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
68
+ if self.hidden_size % self.num_attention_heads != 0:
69
+ raise ValueError(
70
+ f"The hidden size ({self.hidden_size}) is not a multiple of the number of attention "
71
+ f"heads ({self.num_attention_heads})."
72
+ )
73
+
74
+
75
+ @auto_docstring(checkpoint="openai/clip-vit-base-patch32")
76
+ @strict
77
+ class CLIPVisionConfig(PreTrainedConfig):
78
+ r"""
79
+ Example:
80
+
81
+ ```python
82
+ >>> from transformers import CLIPVisionConfig, CLIPVisionModel
83
+
84
+ >>> # Initializing a CLIPVisionConfig with openai/clip-vit-base-patch32 style configuration
85
+ >>> configuration = CLIPVisionConfig()
86
+
87
+ >>> # Initializing a CLIPVisionModel (with random weights) from the openai/clip-vit-base-patch32 style configuration
88
+ >>> model = CLIPVisionModel(configuration)
89
+
90
+ >>> # Accessing the model configuration
91
+ >>> configuration = model.config
92
+ ```"""
93
+
94
+ model_type = "clip_vision_model"
95
+ base_config_key = "vision_config"
96
+
97
+ hidden_size: int = 768
98
+ intermediate_size: int = 3072
99
+ projection_dim: int | None = 512
100
+ num_hidden_layers: int = 12
101
+ num_attention_heads: int = 12
102
+ num_channels: int | None = 3
103
+ image_size: int | None = 224
104
+ patch_size: int | None = 32
105
+ hidden_act: str = "quick_gelu"
106
+ layer_norm_eps: float | None = 1e-5
107
+ attention_dropout: int | float | None = 0.0
108
+ initializer_range: float = 0.02
109
+ initializer_factor: float | None = 1.0
110
+
111
+ def validate_architecture(self):
112
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
113
+ if self.hidden_size % self.num_attention_heads != 0:
114
+ raise ValueError(
115
+ f"The hidden size ({self.hidden_size}) is not a multiple of the number of attention "
116
+ f"heads ({self.num_attention_heads})."
117
+ )
118
+
119
+
120
+ @auto_docstring(checkpoint="openai/clip-vit-base-patch32")
121
+ @strict
122
+ class CLIPConfig(PreTrainedConfig):
123
+ r"""
124
+ text_config (`dict`, *optional*):
125
+ Dictionary of configuration options used to initialize [`CLIPTextConfig`].
126
+ vision_config (`dict`, *optional*):
127
+ Dictionary of configuration options used to initialize [`CLIPVisionConfig`].
128
+ logit_scale_init_value (`float | int`, *optional*, defaults to 2.6592):
129
+ The initial value of the *logit_scale* parameter. Default is used as per the original CLIP implementation.
130
+
131
+ Example:
132
+
133
+ ```python
134
+ >>> from transformers import CLIPConfig, CLIPModel
135
+
136
+ >>> # Initializing a CLIPConfig with openai/clip-vit-base-patch32 style configuration
137
+ >>> configuration = CLIPConfig()
138
+
139
+ >>> # Initializing a CLIPModel (with random weights) from the openai/clip-vit-base-patch32 style configuration
140
+ >>> model = CLIPModel(configuration)
141
+
142
+ >>> # Accessing the model configuration
143
+ >>> configuration = model.config
144
+
145
+ >>> # We can also initialize a CLIPConfig from a CLIPTextConfig and a CLIPVisionConfig
146
+ >>> from transformers import CLIPTextConfig, CLIPVisionConfig
147
+
148
+ >>> # Initializing a CLIPText and CLIPVision configuration
149
+ >>> config_text = CLIPTextConfig()
150
+ >>> config_vision = CLIPVisionConfig()
151
+
152
+ >>> config = CLIPConfig(text_config=config_text, vision_config=config_vision)
153
+ ```"""
154
+
155
+ model_type = "clip"
156
+ sub_configs = {"text_config": CLIPTextConfig, "vision_config": CLIPVisionConfig}
157
+
158
+ text_config: dict | CLIPTextConfig | None = None
159
+ vision_config: dict | CLIPVisionConfig | None = None
160
+ projection_dim: int | None = 512
161
+ logit_scale_init_value: float | int | None = 2.6592
162
+ initializer_factor: float | None = 1.0
163
+
164
+ def __post_init__(self, **kwargs):
165
+ if self.text_config is None:
166
+ text_config = {}
167
+ logger.info("`text_config` is `None`. Initializing the `CLIPTextConfig` with default values.")
168
+ elif isinstance(self.text_config, CLIPTextConfig):
169
+ text_config = self.text_config.to_dict()
170
+ else:
171
+ text_config = self.text_config
172
+
173
+ if self.vision_config is None:
174
+ vision_config = {}
175
+ logger.info("`vision_config` is `None`. initializing the `CLIPVisionConfig` with default values.")
176
+ elif isinstance(self.vision_config, CLIPVisionConfig):
177
+ vision_config = self.vision_config.to_dict()
178
+ else:
179
+ vision_config = self.vision_config
180
+
181
+ # For backward compatibility check keyword args
182
+ # Instead of simply assigning `[text|vision]_config_dict` to `[text|vision]_config`, we use the values in
183
+ # `[text|vision]_config_dict` to update the values in `[text|vision]_config`. The values should be same in most
184
+ # cases, but we don't want to break anything regarding `_config_dict` that existed before commit `8827e1b2`.
185
+ text_config_dict = kwargs.pop("text_config_dict", None)
186
+ vision_config_dict = kwargs.pop("vision_config_dict", None)
187
+
188
+ if text_config_dict is not None:
189
+ # This is the complete result when using `text_config_dict`.
190
+ _text_config_dict = CLIPTextConfig(**text_config_dict).to_dict()
191
+
192
+ # Give a warning if the values exist in both `_text_config_dict` and `text_config` but being different.
193
+ for key, value in _text_config_dict.items():
194
+ if key in text_config and value != text_config[key] and key != "transformers_version":
195
+ # If specified in `text_config_dict`
196
+ if key in text_config_dict:
197
+ message = (
198
+ f"`{key}` is found in both `text_config_dict` and `text_config` but with different values. "
199
+ f'The value `text_config_dict["{key}"]` will be used instead.'
200
+ )
201
+ # If inferred from default argument values (just to be super careful)
202
+ else:
203
+ message = (
204
+ f"`text_config_dict` is provided which will be used to initialize `CLIPTextConfig`. The "
205
+ f'value `text_config["{key}"]` will be overridden.'
206
+ )
207
+ logger.info(message)
208
+
209
+ # Update all values in `text_config` with the ones in `_text_config_dict`.
210
+ text_config.update(_text_config_dict)
211
+
212
+ if vision_config_dict is not None:
213
+ # This is the complete result when using `vision_config_dict`.
214
+ _vision_config_dict = CLIPVisionConfig(**vision_config_dict).to_dict()
215
+ # convert keys to string instead of integer
216
+ if "id2label" in _vision_config_dict:
217
+ _vision_config_dict["id2label"] = {
218
+ str(key): value for key, value in _vision_config_dict["id2label"].items()
219
+ }
220
+
221
+ # Give a warning if the values exist in both `_vision_config_dict` and `vision_config` but being different.
222
+ for key, value in _vision_config_dict.items():
223
+ if key in vision_config and value != vision_config[key] and key != "transformers_version":
224
+ # If specified in `vision_config_dict`
225
+ if key in vision_config_dict:
226
+ message = (
227
+ f"`{key}` is found in both `vision_config_dict` and `vision_config` but with different "
228
+ f'values. The value `vision_config_dict["{key}"]` will be used instead.'
229
+ )
230
+ # If inferred from default argument values (just to be super careful)
231
+ else:
232
+ message = (
233
+ f"`vision_config_dict` is provided which will be used to initialize `CLIPVisionConfig`. "
234
+ f'The value `vision_config["{key}"]` will be overridden.'
235
+ )
236
+ logger.info(message)
237
+
238
+ # Update all values in `vision_config` with the ones in `_vision_config_dict`.
239
+ vision_config.update(_vision_config_dict)
240
+
241
+ # Finally we can convert back our unified text/vision configs to `PretrainedConfig`
242
+ self.text_config = CLIPTextConfig(**text_config)
243
+ self.vision_config = CLIPVisionConfig(**vision_config)
244
+
245
+ super().__post_init__(**kwargs)
246
+
247
+
248
+ __all__ = ["CLIPConfig", "CLIPTextConfig", "CLIPVisionConfig"]
third_party/transformers/src/transformers/models/clip/convert_clip_original_pytorch_to_hf.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 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
+
15
+ import argparse
16
+
17
+ import torch
18
+ from clip import load
19
+
20
+ from transformers import CLIPConfig, CLIPModel
21
+
22
+
23
+ def copy_attn_layer(hf_attn_layer, pt_attn_layer):
24
+ q_proj, k_proj, v_proj = pt_attn_layer.in_proj_weight.chunk(3, dim=0)
25
+ q_proj_bias, k_proj_bias, v_proj_bias = pt_attn_layer.in_proj_bias.chunk(3, dim=0)
26
+
27
+ out_proj_weights = pt_attn_layer.out_proj.weight
28
+ out_proj_bias = pt_attn_layer.out_proj.bias
29
+
30
+ hf_attn_layer.q_proj.weight.data = q_proj
31
+ hf_attn_layer.q_proj.bias.data = q_proj_bias
32
+
33
+ hf_attn_layer.k_proj.weight.data = k_proj
34
+ hf_attn_layer.k_proj.bias.data = k_proj_bias
35
+
36
+ hf_attn_layer.v_proj.weight.data = v_proj
37
+ hf_attn_layer.v_proj.bias.data = v_proj_bias
38
+
39
+ hf_attn_layer.out_proj.weight = out_proj_weights
40
+ hf_attn_layer.out_proj.bias = out_proj_bias
41
+
42
+
43
+ def copy_mlp(hf_mlp, pt_mlp):
44
+ copy_linear(hf_mlp.fc1, pt_mlp.c_fc)
45
+ copy_linear(hf_mlp.fc2, pt_mlp.c_proj)
46
+
47
+
48
+ def copy_linear(hf_linear, pt_linear):
49
+ hf_linear.weight = pt_linear.weight
50
+ hf_linear.bias = pt_linear.bias
51
+
52
+
53
+ def copy_layer(hf_layer, pt_layer):
54
+ # copy layer norms
55
+ copy_linear(hf_layer.layer_norm1, pt_layer.ln_1)
56
+ copy_linear(hf_layer.layer_norm2, pt_layer.ln_2)
57
+
58
+ # copy MLP
59
+ copy_mlp(hf_layer.mlp, pt_layer.mlp)
60
+
61
+ # copy attn
62
+ copy_attn_layer(hf_layer.self_attn, pt_layer.attn)
63
+
64
+
65
+ def copy_layers(hf_layers, pt_layers):
66
+ for hf_layer, pt_layer in zip(hf_layers, pt_layers):
67
+ copy_layer(hf_layer, pt_layer)
68
+
69
+
70
+ def copy_encoder(hf_encoder, pt_model):
71
+ # copy embeds
72
+ hf_encoder.embeddings.token_embedding.weight = pt_model.token_embedding.weight
73
+ hf_encoder.embeddings.position_embedding.weight.data = pt_model.positional_embedding
74
+
75
+ # copy layer norm
76
+ copy_linear(hf_encoder.final_layer_norm, pt_model.ln_final)
77
+
78
+ # copy hidden layers
79
+ copy_layers(hf_encoder.encoder.layers, pt_model.transformer.resblocks)
80
+
81
+
82
+ def copy_text_model_and_projection(hf_model, pt_model):
83
+ # copy projection
84
+ hf_model.text_projection.weight.data = pt_model.text_projection.data.T.contiguous()
85
+
86
+ # copy text encoder
87
+ copy_encoder(hf_model.text_model, pt_model)
88
+
89
+
90
+ def copy_vison_model_and_projection(hf_model, pt_model):
91
+ # copy projection
92
+ hf_model.visual_projection.weight.data = pt_model.visual.proj.data.T.contiguous()
93
+
94
+ # copy layer norms
95
+ copy_linear(hf_model.vision_model.pre_layrnorm, pt_model.visual.ln_pre)
96
+ copy_linear(hf_model.vision_model.post_layernorm, pt_model.visual.ln_post)
97
+
98
+ # copy embeds
99
+ hf_model.vision_model.embeddings.patch_embedding.weight.data = pt_model.visual.conv1.weight.data
100
+ hf_model.vision_model.embeddings.class_embedding = pt_model.visual.class_embedding
101
+ hf_model.vision_model.embeddings.position_embedding.weight.data = pt_model.visual.positional_embedding.data
102
+
103
+ # copy encoder
104
+ copy_layers(hf_model.vision_model.encoder.layers, pt_model.visual.transformer.resblocks)
105
+
106
+
107
+ @torch.no_grad()
108
+ def convert_clip_checkpoint(checkpoint_path, pytorch_dump_folder_path, config_path=None):
109
+ """
110
+ Copy/paste/tweak model's weights to transformers design.
111
+ """
112
+ if config_path is not None:
113
+ config = CLIPConfig.from_pretrained(config_path)
114
+ else:
115
+ config = CLIPConfig(projection_dim=512, text_config={}, vision_config={})
116
+
117
+ hf_model = CLIPModel(config).eval()
118
+
119
+ pt_model, _ = load(checkpoint_path, device="cpu", jit=False)
120
+ pt_model = pt_model.eval()
121
+
122
+ copy_text_model_and_projection(hf_model, pt_model)
123
+ copy_vison_model_and_projection(hf_model, pt_model)
124
+ hf_model.logit_scale = pt_model.logit_scale
125
+
126
+ # Use `eos_token` so the example is more meaningful
127
+ input_ids = torch.tensor(
128
+ [
129
+ [config.text_config.bos_token_id]
130
+ + list(range(3, 77))
131
+ + [config.text_config.eos_token_id]
132
+ + [config.text_config.pad_token_id]
133
+ ]
134
+ )
135
+ pixel_values = torch.randn(1, 3, 224, 224)
136
+
137
+ hf_outputs = hf_model(input_ids=input_ids, pixel_values=pixel_values, return_dict=True)
138
+ hf_logits_per_image = hf_outputs.logits_per_image
139
+ hf_logits_per_text = hf_outputs.logits_per_text
140
+ pt_logits_per_image, pt_logits_per_text = pt_model(pixel_values, input_ids)
141
+
142
+ assert torch.allclose(hf_logits_per_image, pt_logits_per_image, atol=1e-3)
143
+ assert torch.allclose(hf_logits_per_text, pt_logits_per_text, atol=1e-3)
144
+
145
+ hf_model.save_pretrained(pytorch_dump_folder_path)
146
+
147
+
148
+ if __name__ == "__main__":
149
+ parser = argparse.ArgumentParser()
150
+ parser.add_argument("--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.")
151
+ parser.add_argument("--checkpoint_path", default=None, type=str, help="Path to OpenAI checkpoint")
152
+ parser.add_argument("--config_path", default=None, type=str, help="Path to hf config.json of model to convert")
153
+ args = parser.parse_args()
154
+
155
+ convert_clip_checkpoint(args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path)
third_party/transformers/src/transformers/models/clip/image_processing_clip.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 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 CLIP."""
15
+
16
+ from ...image_processing_backends import TorchvisionBackend
17
+ from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling
18
+ from ...processing_utils import ImagesKwargs, Unpack
19
+ from ...utils import auto_docstring
20
+
21
+
22
+ @auto_docstring
23
+ class CLIPImageProcessor(TorchvisionBackend):
24
+ resample = PILImageResampling.BICUBIC
25
+ image_mean = OPENAI_CLIP_MEAN
26
+ image_std = OPENAI_CLIP_STD
27
+ size = {"shortest_edge": 224}
28
+ default_to_square = False
29
+ crop_size = {"height": 224, "width": 224}
30
+ do_resize = True
31
+ do_center_crop = True
32
+ do_rescale = True
33
+ do_normalize = True
34
+ do_convert_rgb = True
35
+
36
+ def __init__(self, **kwargs: Unpack[ImagesKwargs]):
37
+ # for backwards compatibility of KOSMOS-2
38
+ if "use_square_size" in kwargs and kwargs["use_square_size"]:
39
+ kwargs["size"] = {"height": self.size["shortest_edge"], "width": self.size["shortest_edge"]}
40
+ kwargs.pop("use_square_size")
41
+
42
+ super().__init__(**kwargs)
43
+
44
+
45
+ __all__ = ["CLIPImageProcessor"]
third_party/transformers/src/transformers/models/clip/image_processing_pil_clip.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 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 CLIP."""
15
+
16
+ from ...image_processing_backends import PilBackend
17
+ from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling
18
+ from ...processing_utils import ImagesKwargs, Unpack
19
+ from ...utils import auto_docstring
20
+
21
+
22
+ @auto_docstring
23
+ class CLIPImageProcessorPil(PilBackend):
24
+ resample = PILImageResampling.BICUBIC
25
+ image_mean = OPENAI_CLIP_MEAN
26
+ image_std = OPENAI_CLIP_STD
27
+ size = {"shortest_edge": 224}
28
+ default_to_square = False
29
+ crop_size = {"height": 224, "width": 224}
30
+ do_resize = True
31
+ do_center_crop = True
32
+ do_rescale = True
33
+ do_normalize = True
34
+ do_convert_rgb = True
35
+
36
+ def __init__(self, **kwargs: Unpack[ImagesKwargs]):
37
+ # for backwards compatibility of KOSMOS-2
38
+ if "use_square_size" in kwargs and kwargs["use_square_size"]:
39
+ kwargs["size"] = {"height": self.size["shortest_edge"], "width": self.size["shortest_edge"]}
40
+ kwargs.pop("use_square_size")
41
+
42
+ super().__init__(**kwargs)
43
+
44
+
45
+ __all__ = ["CLIPImageProcessorPil"]
third_party/transformers/src/transformers/models/clip/modeling_clip.py ADDED
@@ -0,0 +1,1148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The OpenAI Team Authors and 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
+ """PyTorch CLIP model."""
15
+
16
+ from collections.abc import Callable
17
+ from dataclasses import dataclass
18
+ from typing import Any
19
+
20
+ import torch
21
+ from torch import nn
22
+
23
+ from ... import initialization as init
24
+ from ...activations import ACT2FN
25
+ from ...masking_utils import create_causal_mask
26
+ from ...modeling_layers import GradientCheckpointingLayer
27
+ from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, ImageClassifierOutput
28
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
29
+ from ...processing_utils import Unpack
30
+ from ...utils import (
31
+ ModelOutput,
32
+ TransformersKwargs,
33
+ auto_docstring,
34
+ logging,
35
+ torch_int,
36
+ )
37
+ from ...utils.generic import can_return_tuple, merge_with_config_defaults
38
+ from ...utils.output_capturing import capture_outputs
39
+ from .configuration_clip import CLIPConfig, CLIPTextConfig, CLIPVisionConfig
40
+
41
+
42
+ logger = logging.get_logger(__name__)
43
+
44
+
45
+ # contrastive loss function, adapted from
46
+ # https://sachinruk.github.io/blog/2021-03-07-clip.html
47
+ def contrastive_loss(logits: torch.Tensor) -> torch.Tensor:
48
+ return nn.functional.cross_entropy(logits, torch.arange(len(logits), device=logits.device))
49
+
50
+
51
+ def clip_loss(similarity: torch.Tensor) -> torch.Tensor:
52
+ caption_loss = contrastive_loss(similarity)
53
+ image_loss = contrastive_loss(similarity.t())
54
+ return (caption_loss + image_loss) / 2.0
55
+
56
+
57
+ def _get_vector_norm(tensor: torch.Tensor) -> torch.Tensor:
58
+ """
59
+ This method is equivalent to tensor.norm(p=2, dim=-1, keepdim=True) and used to make
60
+ model `executorch` exportable. See issue https://github.com/pytorch/executorch/issues/3566
61
+ """
62
+ square_tensor = torch.pow(tensor, 2)
63
+ sum_tensor = torch.sum(square_tensor, dim=-1, keepdim=True)
64
+ normed_tensor = torch.pow(sum_tensor, 0.5)
65
+ return normed_tensor
66
+
67
+
68
+ @dataclass
69
+ @auto_docstring(
70
+ custom_intro="""
71
+ Base class for vision model's outputs that also contains image embeddings of the pooling of the last hidden states.
72
+ """
73
+ )
74
+ class CLIPVisionModelOutput(ModelOutput):
75
+ r"""
76
+ image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`):
77
+ The image embeddings obtained by applying the projection layer to the pooler_output.
78
+ """
79
+
80
+ image_embeds: torch.FloatTensor | None = None
81
+ last_hidden_state: torch.FloatTensor | None = None
82
+ hidden_states: tuple[torch.FloatTensor, ...] | None = None
83
+ attentions: tuple[torch.FloatTensor, ...] | None = None
84
+
85
+
86
+ @dataclass
87
+ @auto_docstring(
88
+ custom_intro="""
89
+ Base class for text model's outputs that also contains a pooling of the last hidden states.
90
+ """
91
+ )
92
+ class CLIPTextModelOutput(ModelOutput):
93
+ r"""
94
+ text_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`):
95
+ The text embeddings obtained by applying the projection layer to the pooler_output.
96
+ """
97
+
98
+ text_embeds: torch.FloatTensor | None = None
99
+ last_hidden_state: torch.FloatTensor | None = None
100
+ hidden_states: tuple[torch.FloatTensor, ...] | None = None
101
+ attentions: tuple[torch.FloatTensor, ...] | None = None
102
+
103
+
104
+ @dataclass
105
+ @auto_docstring
106
+ class CLIPOutput(ModelOutput):
107
+ r"""
108
+ loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `return_loss` is `True`):
109
+ Contrastive loss for image-text similarity.
110
+ logits_per_image (`torch.FloatTensor` of shape `(image_batch_size, text_batch_size)`):
111
+ The scaled dot product scores between `image_embeds` and `text_embeds`. This represents the image-text
112
+ similarity scores.
113
+ logits_per_text (`torch.FloatTensor` of shape `(text_batch_size, image_batch_size)`):
114
+ The scaled dot product scores between `text_embeds` and `image_embeds`. This represents the text-image
115
+ similarity scores.
116
+ text_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim`):
117
+ The text embeddings obtained by applying the projection layer to the pooled output of [`CLIPTextModel`].
118
+ image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim`):
119
+ The image embeddings obtained by applying the projection layer to the pooled output of [`CLIPVisionModel`].
120
+ text_model_output (`BaseModelOutputWithPooling`):
121
+ The output of the [`CLIPTextModel`].
122
+ vision_model_output (`BaseModelOutputWithPooling`):
123
+ The output of the [`CLIPVisionModel`].
124
+ """
125
+
126
+ loss: torch.FloatTensor | None = None
127
+ logits_per_image: torch.FloatTensor | None = None
128
+ logits_per_text: torch.FloatTensor | None = None
129
+ text_embeds: torch.FloatTensor | None = None
130
+ image_embeds: torch.FloatTensor | None = None
131
+ text_model_output: BaseModelOutputWithPooling = None
132
+ vision_model_output: BaseModelOutputWithPooling = None
133
+
134
+ def to_tuple(self) -> tuple[Any]:
135
+ return tuple(v.to_tuple() if isinstance(v, ModelOutput) else v for v in self.values())
136
+
137
+
138
+ class CLIPVisionEmbeddings(nn.Module):
139
+ def __init__(self, config: CLIPVisionConfig):
140
+ super().__init__()
141
+ self.config = config
142
+ self.embed_dim = config.hidden_size
143
+ self.image_size = config.image_size
144
+ self.patch_size = config.patch_size
145
+
146
+ self.class_embedding = nn.Parameter(torch.randn(self.embed_dim))
147
+
148
+ self.patch_embedding = nn.Conv2d(
149
+ in_channels=config.num_channels,
150
+ out_channels=self.embed_dim,
151
+ kernel_size=self.patch_size,
152
+ stride=self.patch_size,
153
+ bias=False,
154
+ )
155
+
156
+ self.num_patches = (self.image_size // self.patch_size) ** 2
157
+ self.num_positions = self.num_patches + 1
158
+ self.position_embedding = nn.Embedding(self.num_positions, self.embed_dim)
159
+ self.register_buffer("position_ids", torch.arange(self.num_positions).expand((1, -1)), persistent=False)
160
+
161
+ def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor:
162
+ """
163
+ This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher resolution
164
+ images. This method is also adapted to support torch.jit tracing.
165
+
166
+ Adapted from:
167
+ - https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174-L194, and
168
+ - https://github.com/facebookresearch/dinov2/blob/e1277af2ba9496fbadf7aec6eba56e8d882d1e35/dinov2/models/vision_transformer.py#L179-L211
169
+ """
170
+
171
+ num_patches = embeddings.shape[1] - 1
172
+ position_embedding = self.position_embedding.weight.unsqueeze(0)
173
+ num_positions = position_embedding.shape[1] - 1
174
+
175
+ # always interpolate when tracing to ensure the exported model works for dynamic input shapes
176
+ if not torch.jit.is_tracing() and num_patches == num_positions and height == width:
177
+ return self.position_embedding(self.position_ids)
178
+
179
+ class_pos_embed = position_embedding[:, :1]
180
+ patch_pos_embed = position_embedding[:, 1:]
181
+
182
+ dim = embeddings.shape[-1]
183
+
184
+ new_height = height // self.patch_size
185
+ new_width = width // self.patch_size
186
+
187
+ sqrt_num_positions = torch_int(num_positions**0.5)
188
+ patch_pos_embed = patch_pos_embed.reshape(1, sqrt_num_positions, sqrt_num_positions, dim)
189
+ patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2)
190
+
191
+ patch_pos_embed = nn.functional.interpolate(
192
+ patch_pos_embed,
193
+ size=(new_height, new_width),
194
+ mode="bicubic",
195
+ align_corners=False,
196
+ )
197
+
198
+ patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)
199
+
200
+ return torch.cat((class_pos_embed, patch_pos_embed), dim=1)
201
+
202
+ def forward(self, pixel_values: torch.FloatTensor, interpolate_pos_encoding=False) -> torch.Tensor:
203
+ batch_size, _, height, width = pixel_values.shape
204
+ if not interpolate_pos_encoding and (height != self.image_size or width != self.image_size):
205
+ raise ValueError(
206
+ f"Input image size ({height}*{width}) doesn't match model ({self.image_size}*{self.image_size})."
207
+ )
208
+ target_dtype = self.patch_embedding.weight.dtype
209
+ patch_embeds = self.patch_embedding(pixel_values.to(dtype=target_dtype)) # shape = [*, width, grid, grid]
210
+ patch_embeds = patch_embeds.flatten(2).transpose(1, 2)
211
+
212
+ class_embeds = self.class_embedding.expand(batch_size, 1, -1)
213
+ embeddings = torch.cat([class_embeds, patch_embeds], dim=1)
214
+ if interpolate_pos_encoding:
215
+ embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width)
216
+ else:
217
+ embeddings = embeddings + self.position_embedding(self.position_ids)
218
+ return embeddings
219
+
220
+
221
+ class CLIPTextEmbeddings(nn.Module):
222
+ def __init__(self, config: CLIPTextConfig):
223
+ super().__init__()
224
+ embed_dim = config.hidden_size
225
+
226
+ self.token_embedding = nn.Embedding(config.vocab_size, embed_dim)
227
+ self.position_embedding = nn.Embedding(config.max_position_embeddings, embed_dim)
228
+
229
+ # position_ids (1, len position emb) is contiguous in memory and exported when serialized
230
+ self.register_buffer(
231
+ "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
232
+ )
233
+
234
+ def forward(
235
+ self,
236
+ input_ids: torch.LongTensor | None = None,
237
+ position_ids: torch.LongTensor | None = None,
238
+ inputs_embeds: torch.FloatTensor | None = None,
239
+ ) -> torch.Tensor:
240
+ seq_length = input_ids.shape[-1] if input_ids is not None else inputs_embeds.shape[-2]
241
+ max_position_embedding = self.position_embedding.weight.shape[0]
242
+
243
+ if seq_length > max_position_embedding:
244
+ raise ValueError(
245
+ f"Sequence length must be less than max_position_embeddings (got `sequence length`: "
246
+ f"{seq_length} and max_position_embeddings: {max_position_embedding}"
247
+ )
248
+
249
+ if position_ids is None:
250
+ position_ids = self.position_ids[:, :seq_length]
251
+
252
+ if inputs_embeds is None:
253
+ inputs_embeds = self.token_embedding(input_ids)
254
+
255
+ position_embeddings = self.position_embedding(position_ids)
256
+ embeddings = inputs_embeds + position_embeddings
257
+
258
+ return embeddings
259
+
260
+
261
+ def eager_attention_forward(
262
+ module: nn.Module,
263
+ query: torch.Tensor,
264
+ key: torch.Tensor,
265
+ value: torch.Tensor,
266
+ attention_mask: torch.Tensor | None,
267
+ scaling: float,
268
+ dropout: float = 0.0,
269
+ **kwargs: Unpack[TransformersKwargs],
270
+ ):
271
+ attn_weights = torch.matmul(query, key.transpose(-1, -2)) * scaling
272
+ if attention_mask is not None:
273
+ attn_weights = attn_weights + attention_mask
274
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
275
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
276
+
277
+ attn_output = torch.matmul(attn_weights, value)
278
+ attn_output = attn_output.transpose(1, 2).contiguous()
279
+ return attn_output, attn_weights
280
+
281
+
282
+ class CLIPAttention(nn.Module):
283
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
284
+
285
+ def __init__(self, config: CLIPVisionConfig | CLIPTextConfig):
286
+ super().__init__()
287
+ self.config = config
288
+ self.embed_dim = config.hidden_size
289
+ self.num_heads = config.num_attention_heads
290
+ self.head_dim = self.embed_dim // self.num_heads
291
+ self.scale = self.head_dim**-0.5
292
+ self.dropout = config.attention_dropout
293
+ self.is_causal = False
294
+
295
+ self.k_proj = nn.Linear(self.embed_dim, self.embed_dim)
296
+ self.v_proj = nn.Linear(self.embed_dim, self.embed_dim)
297
+ self.q_proj = nn.Linear(self.embed_dim, self.embed_dim)
298
+ self.out_proj = nn.Linear(self.embed_dim, self.embed_dim)
299
+
300
+ def forward(
301
+ self,
302
+ hidden_states: torch.Tensor,
303
+ attention_mask: torch.Tensor | None = None,
304
+ **kwargs: Unpack[TransformersKwargs],
305
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
306
+ """Input shape: Batch x Time x Channel"""
307
+
308
+ batch_size, seq_length, embed_dim = hidden_states.shape
309
+
310
+ queries = self.q_proj(hidden_states)
311
+ keys = self.k_proj(hidden_states)
312
+ values = self.v_proj(hidden_states)
313
+
314
+ queries = queries.view(batch_size, seq_length, -1, self.head_dim).transpose(1, 2)
315
+ keys = keys.view(batch_size, seq_length, -1, self.head_dim).transpose(1, 2)
316
+ values = values.view(batch_size, seq_length, -1, self.head_dim).transpose(1, 2)
317
+
318
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
319
+ self.config._attn_implementation, eager_attention_forward
320
+ )
321
+
322
+ attn_output, attn_weights = attention_interface(
323
+ self,
324
+ queries,
325
+ keys,
326
+ values,
327
+ attention_mask,
328
+ scaling=self.scale,
329
+ dropout=0.0 if not self.training else self.dropout,
330
+ **kwargs,
331
+ )
332
+
333
+ attn_output = attn_output.reshape(batch_size, seq_length, -1).contiguous()
334
+ attn_output = self.out_proj(attn_output)
335
+
336
+ return attn_output, attn_weights
337
+
338
+
339
+ class CLIPMLP(nn.Module):
340
+ def __init__(self, config):
341
+ super().__init__()
342
+ self.config = config
343
+ self.activation_fn = ACT2FN[config.hidden_act]
344
+ self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size)
345
+ self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size)
346
+
347
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
348
+ hidden_states = self.fc1(hidden_states)
349
+ hidden_states = self.activation_fn(hidden_states)
350
+ hidden_states = self.fc2(hidden_states)
351
+ return hidden_states
352
+
353
+
354
+ class CLIPEncoderLayer(GradientCheckpointingLayer):
355
+ def __init__(self, config: CLIPVisionConfig | CLIPTextConfig):
356
+ super().__init__()
357
+ self.embed_dim = config.hidden_size
358
+ self.self_attn = CLIPAttention(config)
359
+ self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps)
360
+ self.mlp = CLIPMLP(config)
361
+ self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps)
362
+
363
+ def forward(
364
+ self,
365
+ hidden_states: torch.Tensor,
366
+ attention_mask: torch.Tensor,
367
+ **kwargs: Unpack[TransformersKwargs],
368
+ ) -> torch.FloatTensor:
369
+ residual = hidden_states
370
+
371
+ hidden_states = self.layer_norm1(hidden_states)
372
+ hidden_states, _ = self.self_attn(
373
+ hidden_states=hidden_states,
374
+ attention_mask=attention_mask,
375
+ **kwargs,
376
+ )
377
+ hidden_states = residual + hidden_states
378
+
379
+ residual = hidden_states
380
+ hidden_states = self.layer_norm2(hidden_states)
381
+ hidden_states = self.mlp(hidden_states)
382
+ hidden_states = residual + hidden_states
383
+
384
+ return hidden_states
385
+
386
+
387
+ @auto_docstring
388
+ class CLIPPreTrainedModel(PreTrainedModel):
389
+ config: CLIPConfig
390
+ base_model_prefix = "clip"
391
+ input_modalities = ("image", "text")
392
+ supports_gradient_checkpointing = True
393
+ _supports_sdpa = True
394
+ _supports_flash_attn = True
395
+ _supports_flex_attn = True
396
+ _supports_attention_backend = True
397
+ _can_record_outputs = {
398
+ "hidden_states": CLIPEncoderLayer,
399
+ "attentions": CLIPAttention,
400
+ }
401
+
402
+ @torch.no_grad()
403
+ def _init_weights(self, module):
404
+ """Initialize the weights"""
405
+ factor = self.config.initializer_factor
406
+ if isinstance(module, CLIPTextEmbeddings):
407
+ init.normal_(module.token_embedding.weight, mean=0.0, std=factor * 0.02)
408
+ init.normal_(module.position_embedding.weight, mean=0.0, std=factor * 0.02)
409
+ init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
410
+ elif isinstance(module, CLIPVisionEmbeddings):
411
+ factor = self.config.initializer_factor
412
+ init.normal_(module.class_embedding, mean=0.0, std=module.embed_dim**-0.5 * factor)
413
+ init.normal_(module.patch_embedding.weight, std=module.config.initializer_range * factor)
414
+ init.normal_(module.position_embedding.weight, std=module.config.initializer_range * factor)
415
+ init.copy_(module.position_ids, torch.arange(module.num_positions).expand((1, -1)))
416
+ elif isinstance(module, CLIPAttention):
417
+ factor = self.config.initializer_factor
418
+ in_proj_std = (module.embed_dim**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor
419
+ out_proj_std = (module.embed_dim**-0.5) * factor
420
+ init.normal_(module.q_proj.weight, std=in_proj_std)
421
+ init.normal_(module.k_proj.weight, std=in_proj_std)
422
+ init.normal_(module.v_proj.weight, std=in_proj_std)
423
+ init.normal_(module.out_proj.weight, std=out_proj_std)
424
+ elif isinstance(module, CLIPMLP):
425
+ factor = self.config.initializer_factor
426
+ in_proj_std = (module.config.hidden_size**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor
427
+ fc_std = (2 * module.config.hidden_size) ** -0.5 * factor
428
+ init.normal_(module.fc1.weight, std=fc_std)
429
+ init.normal_(module.fc2.weight, std=in_proj_std)
430
+ elif isinstance(module, CLIPModel):
431
+ init.normal_(
432
+ module.text_projection.weight,
433
+ std=module.text_embed_dim**-0.5 * self.config.initializer_factor,
434
+ )
435
+ init.normal_(
436
+ module.visual_projection.weight,
437
+ std=module.vision_embed_dim**-0.5 * self.config.initializer_factor,
438
+ )
439
+ elif isinstance(module, CLIPVisionModelWithProjection):
440
+ init.normal_(
441
+ module.visual_projection.weight,
442
+ std=self.config.hidden_size**-0.5 * self.config.initializer_factor,
443
+ )
444
+ elif isinstance(module, CLIPTextModelWithProjection):
445
+ init.normal_(
446
+ module.text_projection.weight,
447
+ std=self.config.hidden_size**-0.5 * self.config.initializer_factor,
448
+ )
449
+ elif isinstance(module, CLIPForImageClassification):
450
+ init.normal_(
451
+ module.classifier.weight,
452
+ std=self.config.vision_config.hidden_size**-0.5 * self.config.initializer_factor,
453
+ )
454
+
455
+ if isinstance(module, nn.LayerNorm):
456
+ init.zeros_(module.bias)
457
+ init.ones_(module.weight)
458
+ if isinstance(module, nn.Linear) and module.bias is not None:
459
+ init.zeros_(module.bias)
460
+
461
+
462
+ class CLIPEncoder(nn.Module):
463
+ """
464
+ Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a
465
+ [`CLIPEncoderLayer`].
466
+
467
+ Args:
468
+ config: CLIPConfig
469
+ """
470
+
471
+ def __init__(self, config: CLIPConfig):
472
+ super().__init__()
473
+ self.config = config
474
+ self.layers = nn.ModuleList([CLIPEncoderLayer(config) for _ in range(config.num_hidden_layers)])
475
+ self.gradient_checkpointing = False
476
+
477
+ def forward(
478
+ self,
479
+ inputs_embeds,
480
+ attention_mask: torch.Tensor | None = None,
481
+ **kwargs: Unpack[TransformersKwargs],
482
+ ) -> BaseModelOutput:
483
+ r"""
484
+ Args:
485
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
486
+ Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation.
487
+ This is useful if you want more control over how to convert `input_ids` indices into associated vectors
488
+ than the model's internal embedding lookup matrix.
489
+ attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
490
+ Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
491
+
492
+ - 1 for tokens that are **not masked**,
493
+ - 0 for tokens that are **masked**.
494
+
495
+ [What are attention masks?](../glossary#attention-mask)
496
+ """
497
+ hidden_states = inputs_embeds
498
+ for encoder_layer in self.layers:
499
+ hidden_states = encoder_layer(
500
+ hidden_states,
501
+ attention_mask,
502
+ **kwargs,
503
+ )
504
+
505
+ return BaseModelOutput(
506
+ last_hidden_state=hidden_states,
507
+ )
508
+
509
+
510
+ class CLIPTextTransformer(CLIPPreTrainedModel):
511
+ config: CLIPTextConfig
512
+ input_modalities = ("text",)
513
+
514
+ _no_split_modules = ["CLIPTextEmbeddings", "CLIPEncoderLayer"]
515
+
516
+ def __init__(self, config: CLIPTextConfig):
517
+ super().__init__(config)
518
+ self.config = config
519
+ embed_dim = config.hidden_size
520
+ self.embeddings = CLIPTextEmbeddings(config)
521
+ self.encoder = CLIPEncoder(config)
522
+ self.final_layer_norm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps)
523
+
524
+ # For `pooled_output` computation
525
+ self.eos_token_id = config.eos_token_id
526
+ self.post_init()
527
+
528
+ @merge_with_config_defaults
529
+ @capture_outputs(tie_last_hidden_states=False)
530
+ @auto_docstring
531
+ def forward(
532
+ self,
533
+ input_ids: torch.Tensor | None = None,
534
+ attention_mask: torch.Tensor | None = None,
535
+ position_ids: torch.Tensor | None = None,
536
+ **kwargs: Unpack[TransformersKwargs],
537
+ ) -> BaseModelOutputWithPooling:
538
+ if input_ids is None:
539
+ raise ValueError("You have to specify input_ids")
540
+
541
+ input_shape = input_ids.size()
542
+ input_ids = input_ids.view(-1, input_shape[-1])
543
+
544
+ hidden_states = self.embeddings(input_ids=input_ids, position_ids=position_ids)
545
+
546
+ attention_mask = create_causal_mask(
547
+ config=self.config,
548
+ inputs_embeds=hidden_states,
549
+ attention_mask=attention_mask,
550
+ past_key_values=None,
551
+ )
552
+
553
+ kwargs.pop("is_causal", None)
554
+ encoder_outputs: BaseModelOutput = self.encoder(
555
+ inputs_embeds=hidden_states,
556
+ attention_mask=attention_mask,
557
+ is_causal=True,
558
+ **kwargs,
559
+ )
560
+
561
+ last_hidden_state = encoder_outputs.last_hidden_state
562
+ last_hidden_state = self.final_layer_norm(last_hidden_state)
563
+
564
+ if self.eos_token_id == 2:
565
+ # The `eos_token_id` was incorrect before PR #24773: Let's keep what have been done here.
566
+ # A CLIP model with such `eos_token_id` in the config can't work correctly with extra new tokens added
567
+ # ------------------------------------------------------------
568
+ # text_embeds.shape = [batch_size, sequence_length, transformer.width]
569
+ # take features from the eot embedding (eot_token is the highest number in each sequence)
570
+ # casting to torch.int for onnx compatibility: argmax doesn't support int64 inputs with opset 14
571
+ pooled_output = last_hidden_state[
572
+ torch.arange(last_hidden_state.shape[0], device=last_hidden_state.device),
573
+ input_ids.to(dtype=torch.int, device=last_hidden_state.device).argmax(dim=-1),
574
+ ]
575
+ else:
576
+ # The config gets updated `eos_token_id` from PR #24773 (so the use of extra new tokens is possible)
577
+ pooled_output = last_hidden_state[
578
+ torch.arange(last_hidden_state.shape[0], device=last_hidden_state.device),
579
+ # We need to get the first position of `eos_token_id` value (`pad_token_ids` might equal to `eos_token_id`)
580
+ # Note: we assume each sequence (along batch dim.) contains an `eos_token_id` (e.g. prepared by the tokenizer)
581
+ (input_ids.to(dtype=torch.int, device=last_hidden_state.device) == self.eos_token_id)
582
+ .int()
583
+ .argmax(dim=-1),
584
+ ]
585
+
586
+ return BaseModelOutputWithPooling(
587
+ last_hidden_state=last_hidden_state,
588
+ pooler_output=pooled_output,
589
+ )
590
+
591
+
592
+ @auto_docstring(
593
+ custom_intro="""
594
+ The text model from CLIP without any head or projection on top.
595
+ """
596
+ )
597
+ class CLIPTextModel(CLIPPreTrainedModel):
598
+ config: CLIPTextConfig
599
+ input_modalities = ("text",)
600
+
601
+ _no_split_modules = ["CLIPTextEmbeddings", "CLIPEncoderLayer"]
602
+
603
+ def __init__(self, config: CLIPTextConfig):
604
+ super().__init__(config)
605
+ self.text_model = CLIPTextTransformer(config)
606
+ # Initialize weights and apply final processing
607
+ self.post_init()
608
+
609
+ def get_input_embeddings(self) -> nn.Module:
610
+ return self.text_model.embeddings.token_embedding
611
+
612
+ def set_input_embeddings(self, value):
613
+ self.text_model.embeddings.token_embedding = value
614
+
615
+ @auto_docstring
616
+ def forward(
617
+ self,
618
+ input_ids: torch.Tensor | None = None,
619
+ attention_mask: torch.Tensor | None = None,
620
+ position_ids: torch.Tensor | None = None,
621
+ **kwargs: Unpack[TransformersKwargs],
622
+ ) -> BaseModelOutputWithPooling:
623
+ r"""
624
+ Examples:
625
+
626
+ ```python
627
+ >>> from transformers import AutoTokenizer, CLIPTextModel
628
+
629
+ >>> model = CLIPTextModel.from_pretrained("openai/clip-vit-base-patch32")
630
+ >>> tokenizer = AutoTokenizer.from_pretrained("openai/clip-vit-base-patch32")
631
+
632
+ >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt")
633
+
634
+ >>> outputs = model(**inputs)
635
+ >>> last_hidden_state = outputs.last_hidden_state
636
+ >>> pooled_output = outputs.pooler_output # pooled (EOS token) states
637
+ ```"""
638
+
639
+ return self.text_model(
640
+ input_ids=input_ids,
641
+ attention_mask=attention_mask,
642
+ position_ids=position_ids,
643
+ **kwargs,
644
+ )
645
+
646
+
647
+ class CLIPVisionTransformer(CLIPPreTrainedModel):
648
+ config: CLIPVisionConfig
649
+ main_input_name = "pixel_values"
650
+ input_modalities = ("image",)
651
+ _no_split_modules = ["CLIPEncoderLayer"]
652
+
653
+ def __init__(self, config: CLIPVisionConfig):
654
+ super().__init__(config)
655
+ self.config = config
656
+ embed_dim = config.hidden_size
657
+
658
+ self.embeddings = CLIPVisionEmbeddings(config)
659
+ self.pre_layrnorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps)
660
+ self.encoder = CLIPEncoder(config)
661
+ self.post_layernorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps)
662
+ self.post_init()
663
+
664
+ @merge_with_config_defaults
665
+ @capture_outputs(tie_last_hidden_states=False)
666
+ @auto_docstring
667
+ def forward(
668
+ self,
669
+ pixel_values: torch.FloatTensor | None = None,
670
+ interpolate_pos_encoding: bool | None = False,
671
+ **kwargs: Unpack[TransformersKwargs],
672
+ ) -> BaseModelOutputWithPooling:
673
+ if pixel_values is None:
674
+ raise ValueError("You have to specify pixel_values")
675
+
676
+ hidden_states = self.embeddings(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding)
677
+ hidden_states = self.pre_layrnorm(hidden_states)
678
+
679
+ encoder_outputs: BaseModelOutput = self.encoder(
680
+ inputs_embeds=hidden_states,
681
+ **kwargs,
682
+ )
683
+
684
+ last_hidden_state = encoder_outputs.last_hidden_state
685
+ pooled_output = last_hidden_state[:, 0, :]
686
+ pooled_output = self.post_layernorm(pooled_output)
687
+
688
+ return BaseModelOutputWithPooling(
689
+ last_hidden_state=last_hidden_state,
690
+ pooler_output=pooled_output,
691
+ )
692
+
693
+
694
+ @auto_docstring(
695
+ custom_intro="""
696
+ The vision model from CLIP without any head or projection on top.
697
+ """
698
+ )
699
+ class CLIPVisionModel(CLIPPreTrainedModel):
700
+ config: CLIPVisionConfig
701
+ main_input_name = "pixel_values"
702
+ input_modalities = ("image",)
703
+ _no_split_modules = ["CLIPEncoderLayer"]
704
+
705
+ def __init__(self, config: CLIPVisionConfig):
706
+ super().__init__(config)
707
+ self.vision_model = CLIPVisionTransformer(config)
708
+ # Initialize weights and apply final processing
709
+ self.post_init()
710
+
711
+ def get_input_embeddings(self) -> nn.Module:
712
+ return self.vision_model.embeddings.patch_embedding
713
+
714
+ @auto_docstring
715
+ def forward(
716
+ self,
717
+ pixel_values: torch.FloatTensor | None = None,
718
+ interpolate_pos_encoding: bool = False,
719
+ **kwargs: Unpack[TransformersKwargs],
720
+ ) -> BaseModelOutputWithPooling:
721
+ r"""
722
+ Example:
723
+
724
+ ```python
725
+ >>> from PIL import Image
726
+ >>> import httpx
727
+ >>> from io import BytesIO
728
+ >>> from transformers import AutoProcessor, CLIPVisionModel
729
+
730
+ >>> model = CLIPVisionModel.from_pretrained("openai/clip-vit-base-patch32")
731
+ >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32")
732
+
733
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
734
+ >>> with httpx.stream("GET", url) as response:
735
+ ... image = Image.open(BytesIO(response.read()))
736
+
737
+ >>> inputs = processor(images=image, return_tensors="pt")
738
+
739
+ >>> outputs = model(**inputs)
740
+ >>> last_hidden_state = outputs.last_hidden_state
741
+ >>> pooled_output = outputs.pooler_output # pooled CLS states
742
+ ```"""
743
+
744
+ return self.vision_model(
745
+ pixel_values=pixel_values,
746
+ interpolate_pos_encoding=interpolate_pos_encoding,
747
+ **kwargs,
748
+ )
749
+
750
+
751
+ @auto_docstring
752
+ class CLIPModel(CLIPPreTrainedModel):
753
+ config: CLIPConfig
754
+ _no_split_modules = ["CLIPTextEmbeddings", "CLIPEncoderLayer", "CLIPVisionEmbeddings"]
755
+
756
+ def __init__(self, config: CLIPConfig):
757
+ super().__init__(config)
758
+
759
+ if not isinstance(config.text_config, CLIPTextConfig):
760
+ raise TypeError(
761
+ "config.text_config is expected to be of type CLIPTextConfig but is of type"
762
+ f" {type(config.text_config)}."
763
+ )
764
+
765
+ if not isinstance(config.vision_config, CLIPVisionConfig):
766
+ raise TypeError(
767
+ "config.vision_config is expected to be of type CLIPVisionConfig but is of type"
768
+ f" {type(config.vision_config)}."
769
+ )
770
+
771
+ text_config = config.text_config
772
+ vision_config = config.vision_config
773
+
774
+ self.projection_dim = config.projection_dim
775
+ self.text_embed_dim = text_config.hidden_size
776
+ self.vision_embed_dim = vision_config.hidden_size
777
+
778
+ text_model = CLIPTextModel._from_config(text_config)
779
+ self.text_model = text_model.text_model
780
+
781
+ vision_model = CLIPVisionModel._from_config(vision_config)
782
+ self.vision_model = vision_model.vision_model
783
+
784
+ self.visual_projection = nn.Linear(self.vision_embed_dim, self.projection_dim, bias=False)
785
+ self.text_projection = nn.Linear(self.text_embed_dim, self.projection_dim, bias=False)
786
+ self.logit_scale = nn.Parameter(torch.tensor(self.config.logit_scale_init_value))
787
+
788
+ # Initialize weights and apply final processing
789
+ self.post_init()
790
+
791
+ @can_return_tuple
792
+ @auto_docstring
793
+ def get_text_features(
794
+ self,
795
+ input_ids: torch.Tensor,
796
+ attention_mask: torch.Tensor | None = None,
797
+ position_ids: torch.Tensor | None = None,
798
+ **kwargs: Unpack[TransformersKwargs],
799
+ ) -> tuple | BaseModelOutputWithPooling:
800
+ r"""
801
+ Examples:
802
+
803
+ ```python
804
+ >>> import torch
805
+ >>> from transformers import AutoTokenizer, CLIPModel
806
+
807
+ >>> model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
808
+ >>> tokenizer = AutoTokenizer.from_pretrained("openai/clip-vit-base-patch32")
809
+
810
+ >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt")
811
+
812
+ >>> with torch.inference_mode():
813
+ ... text_features = model.get_text_features(**inputs)
814
+ ```"""
815
+ text_outputs: BaseModelOutputWithPooling = self.text_model(
816
+ input_ids=input_ids,
817
+ attention_mask=attention_mask,
818
+ position_ids=position_ids,
819
+ return_dict=True,
820
+ **kwargs,
821
+ )
822
+ pooled_output = text_outputs.pooler_output
823
+ text_outputs.pooler_output = self.text_projection(pooled_output)
824
+
825
+ return text_outputs
826
+
827
+ @can_return_tuple
828
+ @auto_docstring
829
+ def get_image_features(
830
+ self,
831
+ pixel_values: torch.FloatTensor,
832
+ interpolate_pos_encoding: bool = False,
833
+ **kwargs: Unpack[TransformersKwargs],
834
+ ) -> tuple | BaseModelOutputWithPooling:
835
+ r"""
836
+ Examples:
837
+
838
+ ```python
839
+ >>> import torch
840
+ >>> from transformers import AutoProcessor, CLIPModel
841
+ >>> from transformers.image_utils import load_image
842
+
843
+ >>> model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
844
+ >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32")
845
+
846
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
847
+ >>> image = load_image(url)
848
+
849
+ >>> inputs = processor(images=image, return_tensors="pt")
850
+
851
+ >>> with torch.inference_mode():
852
+ ... image_features = model.get_image_features(**inputs)
853
+ ```"""
854
+ vision_outputs: BaseModelOutputWithPooling = self.vision_model(
855
+ pixel_values=pixel_values,
856
+ interpolate_pos_encoding=interpolate_pos_encoding,
857
+ return_dict=True,
858
+ **kwargs,
859
+ )
860
+ pooled_output = vision_outputs.pooler_output
861
+ vision_outputs.pooler_output = self.visual_projection(pooled_output)
862
+
863
+ return vision_outputs
864
+
865
+ @can_return_tuple
866
+ @auto_docstring
867
+ def forward(
868
+ self,
869
+ input_ids: torch.LongTensor | None = None,
870
+ pixel_values: torch.FloatTensor | None = None,
871
+ attention_mask: torch.Tensor | None = None,
872
+ position_ids: torch.LongTensor | None = None,
873
+ return_loss: bool | None = None,
874
+ interpolate_pos_encoding: bool = False,
875
+ **kwargs: Unpack[TransformersKwargs],
876
+ ) -> CLIPOutput:
877
+ r"""
878
+ return_loss (`bool`, *optional*):
879
+ Whether or not to return the contrastive loss.
880
+
881
+ Examples:
882
+
883
+ ```python
884
+ >>> import torch
885
+ >>> from transformers import AutoProcessor, CLIPModel
886
+ >>> from transformers.image_utils import load_image
887
+
888
+ >>> model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
889
+ >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32")
890
+
891
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
892
+ >>> image = load_image(url)
893
+
894
+ >>> inputs = processor(
895
+ ... text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="pt", padding=True
896
+ ... )
897
+
898
+ >>> with torch.inference_mode():
899
+ ... outputs = model(**inputs)
900
+ >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score
901
+ >>> probs = logits_per_image.softmax(dim=1) # we can take the softmax to get the label probabilities
902
+ ```"""
903
+ vision_outputs: BaseModelOutputWithPooling = self.vision_model(
904
+ pixel_values=pixel_values,
905
+ interpolate_pos_encoding=interpolate_pos_encoding,
906
+ **kwargs,
907
+ )
908
+
909
+ text_outputs: BaseModelOutputWithPooling = self.text_model(
910
+ input_ids=input_ids,
911
+ attention_mask=attention_mask,
912
+ position_ids=position_ids,
913
+ **kwargs,
914
+ )
915
+
916
+ image_embeds = vision_outputs.pooler_output
917
+ image_embeds = self.visual_projection(image_embeds)
918
+
919
+ text_embeds = text_outputs.pooler_output
920
+ text_embeds = self.text_projection(text_embeds)
921
+
922
+ # normalized features
923
+ image_embeds = image_embeds / _get_vector_norm(image_embeds)
924
+ text_embeds = text_embeds / _get_vector_norm(text_embeds)
925
+
926
+ # cosine similarity as logits
927
+ logits_per_text = torch.matmul(text_embeds, image_embeds.t().to(text_embeds.device))
928
+ logits_per_text = logits_per_text * self.logit_scale.exp().to(text_embeds.device)
929
+
930
+ logits_per_image = logits_per_text.t()
931
+
932
+ loss = None
933
+ if return_loss:
934
+ loss = clip_loss(logits_per_text)
935
+
936
+ return CLIPOutput(
937
+ loss=loss,
938
+ logits_per_image=logits_per_image,
939
+ logits_per_text=logits_per_text,
940
+ text_embeds=text_embeds,
941
+ image_embeds=image_embeds,
942
+ text_model_output=text_outputs,
943
+ vision_model_output=vision_outputs,
944
+ )
945
+
946
+
947
+ @auto_docstring
948
+ class CLIPTextModelWithProjection(CLIPPreTrainedModel):
949
+ config: CLIPTextConfig
950
+ input_modalities = ("text",)
951
+
952
+ _no_split_modules = ["CLIPTextEmbeddings", "CLIPEncoderLayer"]
953
+
954
+ def __init__(self, config: CLIPTextConfig):
955
+ super().__init__(config)
956
+
957
+ text_model = CLIPTextModel._from_config(config)
958
+ self.text_model = text_model.text_model
959
+
960
+ self.text_projection = nn.Linear(config.hidden_size, config.projection_dim, bias=False)
961
+
962
+ # Initialize weights and apply final processing
963
+ self.post_init()
964
+
965
+ def get_input_embeddings(self) -> nn.Module:
966
+ return self.text_model.embeddings.token_embedding
967
+
968
+ def set_input_embeddings(self, value):
969
+ self.text_model.embeddings.token_embedding = value
970
+
971
+ @can_return_tuple
972
+ @auto_docstring
973
+ def forward(
974
+ self,
975
+ input_ids: torch.Tensor | None = None,
976
+ attention_mask: torch.Tensor | None = None,
977
+ position_ids: torch.Tensor | None = None,
978
+ **kwargs: Unpack[TransformersKwargs],
979
+ ) -> CLIPTextModelOutput:
980
+ r"""
981
+ Examples:
982
+
983
+ ```python
984
+ >>> import torch
985
+ >>> from transformers import AutoTokenizer, CLIPTextModelWithProjection
986
+
987
+ >>> model = CLIPTextModelWithProjection.from_pretrained("openai/clip-vit-base-patch32")
988
+ >>> tokenizer = AutoTokenizer.from_pretrained("openai/clip-vit-base-patch32")
989
+
990
+ >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt")
991
+
992
+ >>> with torch.inference_mode():
993
+ ... outputs = model(**inputs)
994
+ >>> text_embeds = outputs.text_embeds
995
+ ```"""
996
+
997
+ text_outputs: BaseModelOutputWithPooling = self.text_model(
998
+ input_ids=input_ids,
999
+ attention_mask=attention_mask,
1000
+ position_ids=position_ids,
1001
+ **kwargs,
1002
+ )
1003
+ pooled_output = text_outputs.pooler_output
1004
+ text_embeds = self.text_projection(pooled_output)
1005
+
1006
+ return CLIPTextModelOutput(
1007
+ text_embeds=text_embeds,
1008
+ last_hidden_state=text_outputs.last_hidden_state,
1009
+ hidden_states=text_outputs.hidden_states,
1010
+ attentions=text_outputs.attentions,
1011
+ )
1012
+
1013
+
1014
+ @auto_docstring
1015
+ class CLIPVisionModelWithProjection(CLIPPreTrainedModel):
1016
+ config: CLIPVisionConfig
1017
+ main_input_name = "pixel_values"
1018
+ input_modalities = ("image",)
1019
+
1020
+ def __init__(self, config: CLIPVisionConfig):
1021
+ super().__init__(config)
1022
+
1023
+ vision_model = CLIPVisionModel._from_config(config)
1024
+ self.vision_model = vision_model.vision_model
1025
+
1026
+ self.visual_projection = nn.Linear(config.hidden_size, config.projection_dim, bias=False)
1027
+
1028
+ # Initialize weights and apply final processing
1029
+ self.post_init()
1030
+
1031
+ def get_input_embeddings(self) -> nn.Module:
1032
+ return self.vision_model.embeddings.patch_embedding
1033
+
1034
+ @can_return_tuple
1035
+ @auto_docstring
1036
+ def forward(
1037
+ self,
1038
+ pixel_values: torch.FloatTensor | None = None,
1039
+ interpolate_pos_encoding: bool = False,
1040
+ **kwargs: Unpack[TransformersKwargs],
1041
+ ) -> CLIPVisionModelOutput:
1042
+ r"""
1043
+ Examples:
1044
+
1045
+ ```python
1046
+ >>> import torch
1047
+ >>> from transformers import AutoProcessor, CLIPVisionModelWithProjection
1048
+ >>> from transformers.image_utils import load_image
1049
+
1050
+ >>> model = CLIPVisionModelWithProjection.from_pretrained("openai/clip-vit-base-patch32")
1051
+ >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32")
1052
+
1053
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
1054
+ >>> image = load_image(url)
1055
+
1056
+ >>> inputs = processor(images=image, return_tensors="pt")
1057
+
1058
+ >>> with torch.inference_mode():
1059
+ ... outputs = model(**inputs)
1060
+ >>> image_embeds = outputs.image_embeds
1061
+ ```"""
1062
+
1063
+ vision_outputs: BaseModelOutputWithPooling = self.vision_model(
1064
+ pixel_values=pixel_values,
1065
+ interpolate_pos_encoding=interpolate_pos_encoding,
1066
+ **kwargs,
1067
+ )
1068
+ pooled_output = vision_outputs.pooler_output
1069
+ image_embeds = self.visual_projection(pooled_output)
1070
+
1071
+ return CLIPVisionModelOutput(
1072
+ image_embeds=image_embeds,
1073
+ last_hidden_state=vision_outputs.last_hidden_state,
1074
+ hidden_states=vision_outputs.hidden_states,
1075
+ attentions=vision_outputs.attentions,
1076
+ )
1077
+
1078
+
1079
+ @auto_docstring(
1080
+ custom_intro="""
1081
+ CLIP vision encoder with an image classification head on top (a linear layer on top of the pooled final hidden states of
1082
+ the patch tokens) e.g. for ImageNet.
1083
+ """
1084
+ )
1085
+ class CLIPForImageClassification(CLIPPreTrainedModel):
1086
+ main_input_name = "pixel_values"
1087
+ input_modalities = ("image",)
1088
+
1089
+ def __init__(self, config: CLIPConfig) -> None:
1090
+ super().__init__(config)
1091
+
1092
+ self.num_labels = config.num_labels
1093
+ vision_model = CLIPVisionModel._from_config(config.vision_config)
1094
+ self.vision_model = vision_model.vision_model
1095
+
1096
+ # Classifier head
1097
+ self.classifier = (
1098
+ nn.Linear(config.vision_config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity()
1099
+ )
1100
+
1101
+ # Initialize weights and apply final processing
1102
+ self.post_init()
1103
+
1104
+ @can_return_tuple
1105
+ @auto_docstring
1106
+ def forward(
1107
+ self,
1108
+ pixel_values: torch.Tensor | None = None,
1109
+ labels: torch.Tensor | None = None,
1110
+ **kwargs: Unpack[TransformersKwargs],
1111
+ ) -> ImageClassifierOutput:
1112
+ r"""
1113
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
1114
+ Labels for computing the image classification/regression loss. Indices should be in `[0, ...,
1115
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
1116
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
1117
+ """
1118
+ outputs: BaseModelOutputWithPooling = self.vision_model(
1119
+ pixel_values,
1120
+ **kwargs,
1121
+ )
1122
+
1123
+ sequence_output = outputs.last_hidden_state
1124
+
1125
+ sequence_output = torch.mean(sequence_output[:, 1:, :], dim=1)
1126
+ logits = self.classifier(sequence_output)
1127
+
1128
+ loss = None
1129
+ if labels is not None:
1130
+ loss = self.loss_function(labels, logits, self.config)
1131
+
1132
+ return ImageClassifierOutput(
1133
+ loss=loss,
1134
+ logits=logits,
1135
+ hidden_states=outputs.hidden_states,
1136
+ attentions=outputs.attentions,
1137
+ )
1138
+
1139
+
1140
+ __all__ = [
1141
+ "CLIPModel",
1142
+ "CLIPPreTrainedModel",
1143
+ "CLIPTextModel",
1144
+ "CLIPTextModelWithProjection",
1145
+ "CLIPVisionModel",
1146
+ "CLIPVisionModelWithProjection",
1147
+ "CLIPForImageClassification",
1148
+ ]
third_party/transformers/src/transformers/models/clip/processing_clip.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 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
+ Image/Text processor class for CLIP
16
+ """
17
+
18
+ from ...processing_utils import ProcessorMixin
19
+ from ...utils import auto_docstring
20
+
21
+
22
+ @auto_docstring
23
+ class CLIPProcessor(ProcessorMixin):
24
+ def __init__(self, image_processor=None, tokenizer=None, **kwargs):
25
+ super().__init__(image_processor, tokenizer)
26
+
27
+
28
+ __all__ = ["CLIPProcessor"]
third_party/transformers/src/transformers/models/clip/tokenization_clip.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The Open AI 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
+ """Tokenization classes for CLIP."""
15
+
16
+ from tokenizers import Regex, Tokenizer, decoders, normalizers, pre_tokenizers, processors
17
+ from tokenizers.models import BPE
18
+
19
+ from ...tokenization_utils_tokenizers import TokenizersBackend
20
+ from ...utils import logging
21
+
22
+
23
+ logger = logging.get_logger(__name__)
24
+
25
+ VOCAB_FILES_NAMES = {"vocab_file": "vocab.json", "merges_file": "merges.txt", "tokenizer_file": "tokenizer.json"}
26
+
27
+
28
+ class CLIPTokenizer(TokenizersBackend):
29
+ """
30
+ Construct a CLIP tokenizer (backed by HuggingFace's *tokenizers* library). Based on byte-level
31
+ Byte-Pair-Encoding.
32
+
33
+ This tokenizer inherits from [`TokenizersBackend`] which contains most of the main methods. Users should
34
+ refer to this superclass for more information regarding those methods.
35
+
36
+ Args:
37
+ vocab (`str`, `dict` or `list`, *optional*):
38
+ Vocabulary dict to use for the tokenizer.
39
+ merges (`str` or `list`, *optional*):
40
+ Merges list to use for the BPE tokenizer.
41
+ unk_token (`str`, *optional*, defaults to `"<|endoftext|>"`):
42
+ The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
43
+ token instead.
44
+ bos_token (`str`, *optional*, defaults to `"<|startoftext|>"`):
45
+ The beginning of sequence token.
46
+ eos_token (`str`, *optional*, defaults to `"<|endoftext|>"`):
47
+ The end of sequence token.
48
+ pad_token (`str`, *optional*, defaults to `"<|endoftext|>"`):
49
+ The token used for padding, for example when batching sequences of different lengths.
50
+ """
51
+
52
+ vocab_files_names = VOCAB_FILES_NAMES
53
+ model_input_names = ["input_ids", "attention_mask"]
54
+ model = BPE
55
+
56
+ def __init__(
57
+ self,
58
+ vocab: str | dict[str, int] | None = None,
59
+ merges: str | list[str] | None = None,
60
+ unk_token: str = "<|endoftext|>",
61
+ bos_token: str = "<|startoftext|>",
62
+ eos_token: str = "<|endoftext|>",
63
+ pad_token: str = "<|endoftext|>",
64
+ **kwargs,
65
+ ):
66
+ _vocab = (
67
+ vocab
68
+ if vocab is not None
69
+ else {
70
+ str(bos_token): 0,
71
+ str(eos_token): 1,
72
+ str(pad_token): 2,
73
+ }
74
+ )
75
+
76
+ self._merges = merges or []
77
+
78
+ self._tokenizer = Tokenizer(
79
+ BPE(
80
+ vocab=_vocab,
81
+ merges=self._merges,
82
+ dropout=None,
83
+ continuing_subword_prefix="",
84
+ end_of_word_suffix="</w>",
85
+ fuse_unk=False,
86
+ unk_token=str(unk_token),
87
+ )
88
+ )
89
+
90
+ self._tokenizer.normalizer = normalizers.Sequence(
91
+ [normalizers.NFC(), normalizers.Replace(Regex(r"\s+"), " "), normalizers.Lowercase()]
92
+ )
93
+
94
+ self._tokenizer.pre_tokenizer = pre_tokenizers.Sequence(
95
+ [
96
+ pre_tokenizers.Split(
97
+ Regex(
98
+ r"""<\|startoftext\|>|<\|endoftext\|>|'s|'t|'re|'ve|'m|'ll|'d|[\p{L}]+|[\p{N}]|[^\s\p{L}\p{N}]+"""
99
+ ),
100
+ behavior="removed",
101
+ invert=True,
102
+ ),
103
+ pre_tokenizers.ByteLevel(add_prefix_space=False),
104
+ ]
105
+ )
106
+
107
+ self._tokenizer.decoder = decoders.ByteLevel()
108
+
109
+ super().__init__(
110
+ unk_token=unk_token,
111
+ bos_token=bos_token,
112
+ eos_token=eos_token,
113
+ pad_token=pad_token,
114
+ **kwargs,
115
+ )
116
+
117
+ self._tokenizer.post_processor = processors.RobertaProcessing(
118
+ sep=(str(eos_token), self.eos_token_id),
119
+ cls=(str(bos_token), self.bos_token_id),
120
+ add_prefix_space=False,
121
+ trim_offsets=False,
122
+ )
123
+
124
+ # Very ugly hack to enable padding to have a correct decoding see https://github.com/huggingface/tokenizers/issues/872
125
+ self._wrap_decode_method_backend_tokenizer()
126
+
127
+ def _wrap_decode_method_backend_tokenizer(self):
128
+ orig_decode_method = self.backend_tokenizer.decode
129
+
130
+ ## define this as a local variable to avoid circular reference
131
+ ## See: https://github.com/huggingface/transformers/issues/30930
132
+ end_of_word_suffix = self.backend_tokenizer.model.end_of_word_suffix
133
+
134
+ def new_decode_method(*args, **kwargs):
135
+ text = orig_decode_method(*args, **kwargs)
136
+ text = text.replace(end_of_word_suffix, " ").strip()
137
+ return text
138
+
139
+ self.backend_tokenizer.decode = new_decode_method
140
+
141
+
142
+ __all__ = ["CLIPTokenizer"]
third_party/transformers/src/transformers/models/deberta_v2/__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 .configuration_deberta_v2 import *
22
+ from .modeling_deberta_v2 import *
23
+ from .tokenization_deberta_v2 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/deberta_v2/configuration_deberta_v2.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020, Microsoft 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
+ """DeBERTa-v2 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="microsoft/deberta-v2-xlarge")
23
+ @strict
24
+ class DebertaV2Config(PreTrainedConfig):
25
+ r"""
26
+ relative_attention (`bool`, *optional*, defaults to `True`):
27
+ Whether use relative position encoding.
28
+ max_relative_positions (`int`, *optional*, defaults to -1):
29
+ The range of relative positions `[-max_position_embeddings, max_position_embeddings]`. Use the same value
30
+ as `max_position_embeddings`.
31
+ position_biased_input (`bool`, *optional*, defaults to `True`):
32
+ Whether add absolute position embedding to content embedding.
33
+ pos_att_type (`list[str]`, *optional*):
34
+ The type of relative position attention, it can be a combination of `["p2c", "c2p"]`, e.g. `["p2c"]`,
35
+ `["p2c", "c2p"]`, `["p2c", "c2p"]`.
36
+ pooler_dropout (`float`, *optional*, defaults to `0`):
37
+ Dropout rate in the pooler module.
38
+ pooler_hidden_act (`str`, *optional*, defaults to `"gelu"`):
39
+ Activation function used in the dropout module.
40
+ legacy (`bool`, *optional*, defaults to `True`):
41
+ Whether or not the model should use the legacy `LegacyDebertaOnlyMLMHead`, which does not work properly
42
+ for mask infilling tasks.
43
+
44
+ Example:
45
+
46
+ ```python
47
+ >>> from transformers import DebertaV2Config, DebertaV2Model
48
+
49
+ >>> # Initializing a DeBERTa-v2 microsoft/deberta-v2-xlarge style configuration
50
+ >>> configuration = DebertaV2Config()
51
+
52
+ >>> # Initializing a model (with random weights) from the microsoft/deberta-v2-xlarge style configuration
53
+ >>> model = DebertaV2Model(configuration)
54
+
55
+ >>> # Accessing the model configuration
56
+ >>> configuration = model.config
57
+ ```"""
58
+
59
+ model_type = "deberta-v2"
60
+
61
+ vocab_size: int = 128100
62
+ hidden_size: int = 1536
63
+ num_hidden_layers: int = 24
64
+ num_attention_heads: int = 24
65
+ intermediate_size: int = 6144
66
+ hidden_act: str = "gelu"
67
+ hidden_dropout_prob: float | int = 0.1
68
+ attention_probs_dropout_prob: float | int = 0.1
69
+ max_position_embeddings: int = 512
70
+ type_vocab_size: int = 0
71
+ initializer_range: float = 0.02
72
+ layer_norm_eps: float = 1e-7
73
+ relative_attention: bool = False
74
+ max_relative_positions: int = -1
75
+ pad_token_id: int | None = 0
76
+ bos_token_id: int | None = None
77
+ eos_token_id: int | list[int] | None = None
78
+ position_biased_input: bool = True
79
+ pos_att_type: str | list[str] | None = None
80
+ pooler_dropout: float | int = 0.0
81
+ pooler_hidden_act: str = "gelu"
82
+ legacy: bool = True
83
+ tie_word_embeddings: bool = True
84
+
85
+ def __post_init__(self, **kwargs):
86
+ # Backwards compatibility
87
+ if isinstance(self.pos_att_type, str):
88
+ self.pos_att_type = [x.strip() for x in self.pos_att_type.lower().split("|")]
89
+
90
+ self.pooler_hidden_size = kwargs.get("pooler_hidden_size", self.hidden_size)
91
+ super().__post_init__(**kwargs)
92
+
93
+
94
+ __all__ = ["DebertaV2Config"]
third_party/transformers/src/transformers/models/deberta_v2/modeling_deberta_v2.py ADDED
@@ -0,0 +1,1361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 Microsoft and the Hugging Face 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 DeBERTa-v2 model."""
15
+
16
+ from collections.abc import Sequence
17
+
18
+ import torch
19
+ from torch import nn
20
+ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, LayerNorm, 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
+ MaskedLMOutput,
28
+ MultipleChoiceModelOutput,
29
+ QuestionAnsweringModelOutput,
30
+ SequenceClassifierOutput,
31
+ TokenClassifierOutput,
32
+ )
33
+ from ...modeling_utils import PreTrainedModel
34
+ from ...utils import auto_docstring, logging
35
+ from .configuration_deberta_v2 import DebertaV2Config
36
+
37
+
38
+ logger = logging.get_logger(__name__)
39
+
40
+
41
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaSelfOutput with DebertaLayerNorm->LayerNorm
42
+ class DebertaV2SelfOutput(nn.Module):
43
+ def __init__(self, config):
44
+ super().__init__()
45
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
46
+ self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps)
47
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
48
+
49
+ def forward(self, hidden_states, input_tensor):
50
+ hidden_states = self.dense(hidden_states)
51
+ hidden_states = self.dropout(hidden_states)
52
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
53
+ return hidden_states
54
+
55
+
56
+ @torch.jit.script
57
+ def make_log_bucket_position(relative_pos, bucket_size: int, max_position: int):
58
+ sign = torch.sign(relative_pos)
59
+ mid = bucket_size // 2
60
+ abs_pos = torch.where(
61
+ (relative_pos < mid) & (relative_pos > -mid),
62
+ torch.tensor(mid - 1).type_as(relative_pos),
63
+ torch.abs(relative_pos),
64
+ )
65
+ log_pos = (
66
+ torch.ceil(torch.log(abs_pos / mid) / torch.log(torch.tensor((max_position - 1) / mid)) * (mid - 1)) + mid
67
+ )
68
+ bucket_pos = torch.where(abs_pos <= mid, relative_pos.type_as(log_pos), log_pos * sign)
69
+ return bucket_pos
70
+
71
+
72
+ def build_relative_position(query_layer, key_layer, bucket_size: int = -1, max_position: int = -1):
73
+ """
74
+ Build relative position according to the query and key
75
+
76
+ We assume the absolute position of query \\(P_q\\) is range from (0, query_size) and the absolute position of key
77
+ \\(P_k\\) is range from (0, key_size), The relative positions from query to key is \\(R_{q \\rightarrow k} = P_q -
78
+ P_k\\)
79
+
80
+ Args:
81
+ query_size (int): the length of query
82
+ key_size (int): the length of key
83
+ bucket_size (int): the size of position bucket
84
+ max_position (int): the maximum allowed absolute position
85
+ device (`torch.device`): the device on which tensors will be created.
86
+
87
+ Return:
88
+ `torch.LongTensor`: A tensor with shape [1, query_size, key_size]
89
+ """
90
+ query_size = query_layer.size(-2)
91
+ key_size = key_layer.size(-2)
92
+
93
+ q_ids = torch.arange(query_size, dtype=torch.long, device=query_layer.device)
94
+ k_ids = torch.arange(key_size, dtype=torch.long, device=key_layer.device)
95
+ rel_pos_ids = q_ids[:, None] - k_ids[None, :]
96
+ if bucket_size > 0 and max_position > 0:
97
+ rel_pos_ids = make_log_bucket_position(rel_pos_ids, bucket_size, max_position)
98
+ rel_pos_ids = rel_pos_ids.to(torch.long)
99
+ rel_pos_ids = rel_pos_ids[:query_size, :]
100
+ rel_pos_ids = rel_pos_ids.unsqueeze(0)
101
+ return rel_pos_ids
102
+
103
+
104
+ @torch.jit.script
105
+ def c2p_dynamic_expand(c2p_pos, query_layer, relative_pos):
106
+ return c2p_pos.expand([query_layer.size(0), query_layer.size(1), query_layer.size(2), relative_pos.size(-1)])
107
+
108
+
109
+ @torch.jit.script
110
+ def p2c_dynamic_expand(c2p_pos, query_layer, key_layer):
111
+ return c2p_pos.expand([query_layer.size(0), query_layer.size(1), key_layer.size(-2), key_layer.size(-2)])
112
+
113
+
114
+ @torch.jit.script
115
+ def pos_dynamic_expand(pos_index, p2c_att, key_layer):
116
+ return pos_index.expand(p2c_att.size()[:2] + (pos_index.size(-2), key_layer.size(-2)))
117
+
118
+
119
+ @torch.jit.script
120
+ def scaled_size_sqrt(query_layer: torch.Tensor, scale_factor: int):
121
+ return torch.sqrt(torch.tensor(query_layer.size(-1), dtype=torch.float) * scale_factor)
122
+
123
+
124
+ @torch.jit.script
125
+ def build_rpos(query_layer, key_layer, relative_pos, position_buckets: int, max_relative_positions: int):
126
+ if key_layer.size(-2) != query_layer.size(-2):
127
+ return build_relative_position(
128
+ key_layer,
129
+ key_layer,
130
+ bucket_size=position_buckets,
131
+ max_position=max_relative_positions,
132
+ )
133
+ else:
134
+ return relative_pos
135
+
136
+
137
+ class DisentangledSelfAttention(nn.Module):
138
+ """
139
+ Disentangled self-attention module
140
+
141
+ Parameters:
142
+ config (`DebertaV2Config`):
143
+ A model config class instance with the configuration to build a new model. The schema is similar to
144
+ *BertConfig*, for more details, please refer [`DebertaV2Config`]
145
+
146
+ """
147
+
148
+ def __init__(self, config):
149
+ super().__init__()
150
+ if config.hidden_size % config.num_attention_heads != 0:
151
+ raise ValueError(
152
+ f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
153
+ f"heads ({config.num_attention_heads})"
154
+ )
155
+ self.num_attention_heads = config.num_attention_heads
156
+ _attention_head_size = config.hidden_size // config.num_attention_heads
157
+ self.attention_head_size = getattr(config, "attention_head_size", _attention_head_size)
158
+ self.all_head_size = self.num_attention_heads * self.attention_head_size
159
+ self.query_proj = nn.Linear(config.hidden_size, self.all_head_size, bias=True)
160
+ self.key_proj = nn.Linear(config.hidden_size, self.all_head_size, bias=True)
161
+ self.value_proj = nn.Linear(config.hidden_size, self.all_head_size, bias=True)
162
+
163
+ self.share_att_key = getattr(config, "share_att_key", False)
164
+ self.pos_att_type = config.pos_att_type if config.pos_att_type is not None else []
165
+ self.relative_attention = getattr(config, "relative_attention", False)
166
+
167
+ if self.relative_attention:
168
+ self.position_buckets = getattr(config, "position_buckets", -1)
169
+ self.max_relative_positions = getattr(config, "max_relative_positions", -1)
170
+ if self.max_relative_positions < 1:
171
+ self.max_relative_positions = config.max_position_embeddings
172
+ self.pos_ebd_size = self.max_relative_positions
173
+ if self.position_buckets > 0:
174
+ self.pos_ebd_size = self.position_buckets
175
+
176
+ self.pos_dropout = nn.Dropout(config.hidden_dropout_prob)
177
+
178
+ if not self.share_att_key:
179
+ if "c2p" in self.pos_att_type:
180
+ self.pos_key_proj = nn.Linear(config.hidden_size, self.all_head_size, bias=True)
181
+ if "p2c" in self.pos_att_type:
182
+ self.pos_query_proj = nn.Linear(config.hidden_size, self.all_head_size)
183
+
184
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
185
+
186
+ def transpose_for_scores(self, x, attention_heads) -> torch.Tensor:
187
+ new_x_shape = x.size()[:-1] + (attention_heads, -1)
188
+ x = x.view(new_x_shape)
189
+ return x.permute(0, 2, 1, 3).contiguous().view(-1, x.size(1), x.size(-1))
190
+
191
+ def forward(
192
+ self,
193
+ hidden_states,
194
+ attention_mask,
195
+ output_attentions=False,
196
+ query_states=None,
197
+ relative_pos=None,
198
+ rel_embeddings=None,
199
+ ):
200
+ """
201
+ Call the module
202
+
203
+ Args:
204
+ hidden_states (`torch.FloatTensor`):
205
+ Input states to the module usually the output from previous layer, it will be the Q,K and V in
206
+ *Attention(Q,K,V)*
207
+
208
+ attention_mask (`torch.BoolTensor`):
209
+ An attention mask matrix of shape [*B*, *N*, *N*] where *B* is the batch size, *N* is the maximum
210
+ sequence length in which element [i,j] = *1* means the *i* th token in the input can attend to the *j*
211
+ th token.
212
+
213
+ output_attentions (`bool`, *optional*):
214
+ Whether return the attention matrix.
215
+
216
+ query_states (`torch.FloatTensor`, *optional*):
217
+ The *Q* state in *Attention(Q,K,V)*.
218
+
219
+ relative_pos (`torch.LongTensor`):
220
+ The relative position encoding between the tokens in the sequence. It's of shape [*B*, *N*, *N*] with
221
+ values ranging in [*-max_relative_positions*, *max_relative_positions*].
222
+
223
+ rel_embeddings (`torch.FloatTensor`):
224
+ The embedding of relative distances. It's a tensor of shape [\\(2 \\times
225
+ \\text{max_relative_positions}\\), *hidden_size*].
226
+
227
+
228
+ """
229
+ if query_states is None:
230
+ query_states = hidden_states
231
+ query_layer = self.transpose_for_scores(self.query_proj(query_states), self.num_attention_heads)
232
+ key_layer = self.transpose_for_scores(self.key_proj(hidden_states), self.num_attention_heads)
233
+ value_layer = self.transpose_for_scores(self.value_proj(hidden_states), self.num_attention_heads)
234
+
235
+ rel_att = None
236
+ # Take the dot product between "query" and "key" to get the raw attention scores.
237
+ scale_factor = 1
238
+ if "c2p" in self.pos_att_type:
239
+ scale_factor += 1
240
+ if "p2c" in self.pos_att_type:
241
+ scale_factor += 1
242
+ scale = scaled_size_sqrt(query_layer, scale_factor)
243
+ attention_scores = torch.bmm(query_layer, key_layer.transpose(-1, -2) / scale.to(dtype=query_layer.dtype))
244
+ if self.relative_attention:
245
+ rel_embeddings = self.pos_dropout(rel_embeddings)
246
+ rel_att = self.disentangled_attention_bias(
247
+ query_layer, key_layer, relative_pos, rel_embeddings, scale_factor
248
+ )
249
+
250
+ if rel_att is not None:
251
+ attention_scores = attention_scores + rel_att
252
+ attention_scores = attention_scores.view(
253
+ -1, self.num_attention_heads, attention_scores.size(-2), attention_scores.size(-1)
254
+ )
255
+
256
+ attention_mask = attention_mask.bool()
257
+ attention_scores = attention_scores.masked_fill(~(attention_mask), torch.finfo(query_layer.dtype).min)
258
+ # bsz x height x length x dimension
259
+ attention_probs = nn.functional.softmax(attention_scores, dim=-1)
260
+
261
+ attention_probs = self.dropout(attention_probs)
262
+ context_layer = torch.bmm(
263
+ attention_probs.view(-1, attention_probs.size(-2), attention_probs.size(-1)), value_layer
264
+ )
265
+ context_layer = (
266
+ context_layer.view(-1, self.num_attention_heads, context_layer.size(-2), context_layer.size(-1))
267
+ .permute(0, 2, 1, 3)
268
+ .contiguous()
269
+ )
270
+ new_context_layer_shape = context_layer.size()[:-2] + (-1,)
271
+ context_layer = context_layer.view(new_context_layer_shape)
272
+ if not output_attentions:
273
+ return (context_layer, None)
274
+ return (context_layer, attention_probs)
275
+
276
+ def disentangled_attention_bias(self, query_layer, key_layer, relative_pos, rel_embeddings, scale_factor):
277
+ if relative_pos is None:
278
+ relative_pos = build_relative_position(
279
+ query_layer,
280
+ key_layer,
281
+ bucket_size=self.position_buckets,
282
+ max_position=self.max_relative_positions,
283
+ )
284
+ if relative_pos.dim() == 2:
285
+ relative_pos = relative_pos.unsqueeze(0).unsqueeze(0)
286
+ elif relative_pos.dim() == 3:
287
+ relative_pos = relative_pos.unsqueeze(1)
288
+ # bsz x height x query x key
289
+ elif relative_pos.dim() != 4:
290
+ raise ValueError(f"Relative position ids must be of dim 2 or 3 or 4. {relative_pos.dim()}")
291
+
292
+ att_span = self.pos_ebd_size
293
+ relative_pos = relative_pos.to(device=query_layer.device, dtype=torch.long)
294
+
295
+ rel_embeddings = rel_embeddings[0 : att_span * 2, :].unsqueeze(0)
296
+ if self.share_att_key:
297
+ pos_query_layer = self.transpose_for_scores(
298
+ self.query_proj(rel_embeddings), self.num_attention_heads
299
+ ).repeat(query_layer.size(0) // self.num_attention_heads, 1, 1)
300
+ pos_key_layer = self.transpose_for_scores(self.key_proj(rel_embeddings), self.num_attention_heads).repeat(
301
+ query_layer.size(0) // self.num_attention_heads, 1, 1
302
+ )
303
+ else:
304
+ if "c2p" in self.pos_att_type:
305
+ pos_key_layer = self.transpose_for_scores(
306
+ self.pos_key_proj(rel_embeddings), self.num_attention_heads
307
+ ).repeat(query_layer.size(0) // self.num_attention_heads, 1, 1) # .split(self.all_head_size, dim=-1)
308
+ if "p2c" in self.pos_att_type:
309
+ pos_query_layer = self.transpose_for_scores(
310
+ self.pos_query_proj(rel_embeddings), self.num_attention_heads
311
+ ).repeat(query_layer.size(0) // self.num_attention_heads, 1, 1) # .split(self.all_head_size, dim=-1)
312
+
313
+ score = 0
314
+ # content->position
315
+ if "c2p" in self.pos_att_type:
316
+ scale = scaled_size_sqrt(pos_key_layer, scale_factor)
317
+ c2p_att = torch.bmm(query_layer, pos_key_layer.transpose(-1, -2))
318
+ c2p_pos = torch.clamp(relative_pos + att_span, 0, att_span * 2 - 1)
319
+ c2p_att = torch.gather(
320
+ c2p_att,
321
+ dim=-1,
322
+ index=c2p_pos.squeeze(0).expand([query_layer.size(0), query_layer.size(1), relative_pos.size(-1)]),
323
+ )
324
+ score += c2p_att / scale.to(dtype=c2p_att.dtype)
325
+
326
+ # position->content
327
+ if "p2c" in self.pos_att_type:
328
+ scale = scaled_size_sqrt(pos_query_layer, scale_factor)
329
+ r_pos = build_rpos(
330
+ query_layer,
331
+ key_layer,
332
+ relative_pos,
333
+ self.max_relative_positions,
334
+ self.position_buckets,
335
+ )
336
+ p2c_pos = torch.clamp(-r_pos + att_span, 0, att_span * 2 - 1)
337
+ p2c_att = torch.bmm(key_layer, pos_query_layer.transpose(-1, -2))
338
+ p2c_att = torch.gather(
339
+ p2c_att,
340
+ dim=-1,
341
+ index=p2c_pos.squeeze(0).expand([query_layer.size(0), key_layer.size(-2), key_layer.size(-2)]),
342
+ ).transpose(-1, -2)
343
+ score += p2c_att / scale.to(dtype=p2c_att.dtype)
344
+
345
+ return score
346
+
347
+
348
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaAttention with Deberta->DebertaV2
349
+ class DebertaV2Attention(nn.Module):
350
+ def __init__(self, config):
351
+ super().__init__()
352
+ self.self = DisentangledSelfAttention(config)
353
+ self.output = DebertaV2SelfOutput(config)
354
+ self.config = config
355
+
356
+ def forward(
357
+ self,
358
+ hidden_states,
359
+ attention_mask,
360
+ output_attentions: bool = False,
361
+ query_states=None,
362
+ relative_pos=None,
363
+ rel_embeddings=None,
364
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
365
+ self_output, att_matrix = self.self(
366
+ hidden_states,
367
+ attention_mask,
368
+ output_attentions,
369
+ query_states=query_states,
370
+ relative_pos=relative_pos,
371
+ rel_embeddings=rel_embeddings,
372
+ )
373
+ if query_states is None:
374
+ query_states = hidden_states
375
+ attention_output = self.output(self_output, query_states)
376
+
377
+ if output_attentions:
378
+ return (attention_output, att_matrix)
379
+ else:
380
+ return (attention_output, None)
381
+
382
+
383
+ # Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->DebertaV2
384
+ class DebertaV2Intermediate(nn.Module):
385
+ def __init__(self, config):
386
+ super().__init__()
387
+ self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
388
+ if isinstance(config.hidden_act, str):
389
+ self.intermediate_act_fn = ACT2FN[config.hidden_act]
390
+ else:
391
+ self.intermediate_act_fn = config.hidden_act
392
+
393
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
394
+ hidden_states = self.dense(hidden_states)
395
+ hidden_states = self.intermediate_act_fn(hidden_states)
396
+ return hidden_states
397
+
398
+
399
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaOutput with DebertaLayerNorm->LayerNorm
400
+ class DebertaV2Output(nn.Module):
401
+ def __init__(self, config):
402
+ super().__init__()
403
+ self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
404
+ self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps)
405
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
406
+ self.config = config
407
+
408
+ def forward(self, hidden_states, input_tensor):
409
+ hidden_states = self.dense(hidden_states)
410
+ hidden_states = self.dropout(hidden_states)
411
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
412
+ return hidden_states
413
+
414
+
415
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaLayer with Deberta->DebertaV2
416
+ class DebertaV2Layer(GradientCheckpointingLayer):
417
+ def __init__(self, config):
418
+ super().__init__()
419
+ self.attention = DebertaV2Attention(config)
420
+ self.intermediate = DebertaV2Intermediate(config)
421
+ self.output = DebertaV2Output(config)
422
+
423
+ def forward(
424
+ self,
425
+ hidden_states,
426
+ attention_mask,
427
+ query_states=None,
428
+ relative_pos=None,
429
+ rel_embeddings=None,
430
+ output_attentions: bool = False,
431
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
432
+ attention_output, att_matrix = self.attention(
433
+ hidden_states,
434
+ attention_mask,
435
+ output_attentions=output_attentions,
436
+ query_states=query_states,
437
+ relative_pos=relative_pos,
438
+ rel_embeddings=rel_embeddings,
439
+ )
440
+ intermediate_output = self.intermediate(attention_output)
441
+ layer_output = self.output(intermediate_output, attention_output)
442
+
443
+ if output_attentions:
444
+ return (layer_output, att_matrix)
445
+ else:
446
+ return (layer_output, None)
447
+
448
+
449
+ class ConvLayer(nn.Module):
450
+ def __init__(self, config):
451
+ super().__init__()
452
+ kernel_size = getattr(config, "conv_kernel_size", 3)
453
+ groups = getattr(config, "conv_groups", 1)
454
+ self.conv_act = getattr(config, "conv_act", "tanh")
455
+ self.conv = nn.Conv1d(
456
+ config.hidden_size, config.hidden_size, kernel_size, padding=(kernel_size - 1) // 2, groups=groups
457
+ )
458
+ self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps)
459
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
460
+ self.config = config
461
+
462
+ def forward(self, hidden_states, residual_states, input_mask):
463
+ out = self.conv(hidden_states.permute(0, 2, 1).contiguous()).permute(0, 2, 1).contiguous()
464
+ rmask = (1 - input_mask).bool()
465
+ out.masked_fill_(rmask.unsqueeze(-1).expand(out.size()), 0)
466
+ out = ACT2FN[self.conv_act](self.dropout(out))
467
+
468
+ layer_norm_input = residual_states + out
469
+ output = self.LayerNorm(layer_norm_input).to(layer_norm_input)
470
+
471
+ if input_mask is None:
472
+ output_states = output
473
+ else:
474
+ if input_mask.dim() != layer_norm_input.dim():
475
+ if input_mask.dim() == 4:
476
+ input_mask = input_mask.squeeze(1).squeeze(1)
477
+ input_mask = input_mask.unsqueeze(2)
478
+
479
+ input_mask = input_mask.to(output.dtype)
480
+ output_states = output * input_mask
481
+
482
+ return output_states
483
+
484
+
485
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaEmbeddings with DebertaLayerNorm->LayerNorm,Deberta->DebertaV2
486
+ class DebertaV2Embeddings(nn.Module):
487
+ """Construct the embeddings from word, position and token_type embeddings."""
488
+
489
+ def __init__(self, config):
490
+ super().__init__()
491
+ pad_token_id = getattr(config, "pad_token_id", 0)
492
+ self.embedding_size = getattr(config, "embedding_size", config.hidden_size)
493
+ self.word_embeddings = nn.Embedding(config.vocab_size, self.embedding_size, padding_idx=pad_token_id)
494
+
495
+ self.position_biased_input = getattr(config, "position_biased_input", True)
496
+ if not self.position_biased_input:
497
+ self.position_embeddings = None
498
+ else:
499
+ self.position_embeddings = nn.Embedding(config.max_position_embeddings, self.embedding_size)
500
+
501
+ if config.type_vocab_size > 0:
502
+ self.token_type_embeddings = nn.Embedding(config.type_vocab_size, self.embedding_size)
503
+ else:
504
+ self.token_type_embeddings = None
505
+
506
+ if self.embedding_size != config.hidden_size:
507
+ self.embed_proj = nn.Linear(self.embedding_size, config.hidden_size, bias=False)
508
+ else:
509
+ self.embed_proj = None
510
+
511
+ self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps)
512
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
513
+ self.config = config
514
+
515
+ # position_ids (1, len position emb) is contiguous in memory and exported when serialized
516
+ self.register_buffer(
517
+ "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
518
+ )
519
+
520
+ def forward(self, input_ids=None, token_type_ids=None, position_ids=None, mask=None, inputs_embeds=None):
521
+ if input_ids is not None:
522
+ input_shape = input_ids.size()
523
+ else:
524
+ input_shape = inputs_embeds.size()[:-1]
525
+
526
+ seq_length = input_shape[1]
527
+
528
+ if position_ids is None:
529
+ position_ids = self.position_ids[:, :seq_length]
530
+
531
+ if token_type_ids is None:
532
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
533
+
534
+ if inputs_embeds is None:
535
+ inputs_embeds = self.word_embeddings(input_ids)
536
+
537
+ if self.position_embeddings is not None:
538
+ position_embeddings = self.position_embeddings(position_ids.long())
539
+ else:
540
+ position_embeddings = torch.zeros_like(inputs_embeds)
541
+
542
+ embeddings = inputs_embeds
543
+ if self.position_biased_input:
544
+ embeddings = embeddings + position_embeddings
545
+ if self.token_type_embeddings is not None:
546
+ token_type_embeddings = self.token_type_embeddings(token_type_ids)
547
+ embeddings = embeddings + token_type_embeddings
548
+
549
+ if self.embed_proj is not None:
550
+ embeddings = self.embed_proj(embeddings)
551
+
552
+ embeddings = self.LayerNorm(embeddings)
553
+
554
+ if mask is not None:
555
+ if mask.dim() != embeddings.dim():
556
+ if mask.dim() == 4:
557
+ mask = mask.squeeze(1).squeeze(1)
558
+ mask = mask.unsqueeze(2)
559
+ mask = mask.to(embeddings.dtype)
560
+
561
+ embeddings = embeddings * mask
562
+
563
+ embeddings = self.dropout(embeddings)
564
+ return embeddings
565
+
566
+
567
+ class DebertaV2Encoder(nn.Module):
568
+ """Modified BertEncoder with relative position bias support"""
569
+
570
+ def __init__(self, config):
571
+ super().__init__()
572
+
573
+ self.layer = nn.ModuleList([DebertaV2Layer(config) for _ in range(config.num_hidden_layers)])
574
+ self.relative_attention = getattr(config, "relative_attention", False)
575
+
576
+ if self.relative_attention:
577
+ self.max_relative_positions = getattr(config, "max_relative_positions", -1)
578
+ if self.max_relative_positions < 1:
579
+ self.max_relative_positions = config.max_position_embeddings
580
+
581
+ self.position_buckets = getattr(config, "position_buckets", -1)
582
+ pos_ebd_size = self.max_relative_positions * 2
583
+
584
+ if self.position_buckets > 0:
585
+ pos_ebd_size = self.position_buckets * 2
586
+
587
+ self.rel_embeddings = nn.Embedding(pos_ebd_size, config.hidden_size)
588
+
589
+ self.norm_rel_ebd = [x.strip() for x in getattr(config, "norm_rel_ebd", "none").lower().split("|")]
590
+
591
+ if "layer_norm" in self.norm_rel_ebd:
592
+ self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps, elementwise_affine=True)
593
+
594
+ self.conv = ConvLayer(config) if getattr(config, "conv_kernel_size", 0) > 0 else None
595
+ self.gradient_checkpointing = False
596
+
597
+ def get_rel_embedding(self):
598
+ rel_embeddings = self.rel_embeddings.weight if self.relative_attention else None
599
+ if rel_embeddings is not None and ("layer_norm" in self.norm_rel_ebd):
600
+ rel_embeddings = self.LayerNorm(rel_embeddings)
601
+ return rel_embeddings
602
+
603
+ def get_attention_mask(self, attention_mask):
604
+ if attention_mask.dim() <= 2:
605
+ extended_attention_mask = attention_mask.unsqueeze(1).unsqueeze(2)
606
+ attention_mask = extended_attention_mask * extended_attention_mask.squeeze(-2).unsqueeze(-1)
607
+ elif attention_mask.dim() == 3:
608
+ attention_mask = attention_mask.unsqueeze(1)
609
+
610
+ return attention_mask
611
+
612
+ def get_rel_pos(self, hidden_states, query_states=None, relative_pos=None):
613
+ if self.relative_attention and relative_pos is None:
614
+ if query_states is not None:
615
+ relative_pos = build_relative_position(
616
+ query_states,
617
+ hidden_states,
618
+ bucket_size=self.position_buckets,
619
+ max_position=self.max_relative_positions,
620
+ )
621
+ else:
622
+ relative_pos = build_relative_position(
623
+ hidden_states,
624
+ hidden_states,
625
+ bucket_size=self.position_buckets,
626
+ max_position=self.max_relative_positions,
627
+ )
628
+ return relative_pos
629
+
630
+ def forward(
631
+ self,
632
+ hidden_states,
633
+ attention_mask,
634
+ output_hidden_states=True,
635
+ output_attentions=False,
636
+ query_states=None,
637
+ relative_pos=None,
638
+ return_dict=True,
639
+ ):
640
+ if attention_mask.dim() <= 2:
641
+ input_mask = attention_mask
642
+ else:
643
+ input_mask = attention_mask.sum(-2) > 0
644
+ attention_mask = self.get_attention_mask(attention_mask)
645
+ relative_pos = self.get_rel_pos(hidden_states, query_states, relative_pos)
646
+
647
+ all_hidden_states: tuple[torch.Tensor] | None = (hidden_states,) if output_hidden_states else None
648
+ all_attentions = () if output_attentions else None
649
+
650
+ next_kv = hidden_states
651
+ rel_embeddings = self.get_rel_embedding()
652
+ for i, layer_module in enumerate(self.layer):
653
+ output_states, attn_weights = layer_module(
654
+ next_kv,
655
+ attention_mask,
656
+ query_states=query_states,
657
+ relative_pos=relative_pos,
658
+ rel_embeddings=rel_embeddings,
659
+ output_attentions=output_attentions,
660
+ )
661
+
662
+ if output_attentions:
663
+ all_attentions = all_attentions + (attn_weights,)
664
+
665
+ if i == 0 and self.conv is not None:
666
+ output_states = self.conv(hidden_states, output_states, input_mask)
667
+
668
+ if output_hidden_states:
669
+ all_hidden_states = all_hidden_states + (output_states,)
670
+
671
+ if query_states is not None:
672
+ query_states = output_states
673
+ if isinstance(hidden_states, Sequence):
674
+ next_kv = hidden_states[i + 1] if i + 1 < len(self.layer) else None
675
+ else:
676
+ next_kv = output_states
677
+
678
+ if not return_dict:
679
+ return tuple(v for v in [output_states, all_hidden_states, all_attentions] if v is not None)
680
+ return BaseModelOutput(
681
+ last_hidden_state=output_states, hidden_states=all_hidden_states, attentions=all_attentions
682
+ )
683
+
684
+
685
+ @auto_docstring
686
+ class DebertaV2PreTrainedModel(PreTrainedModel):
687
+ config: DebertaV2Config
688
+ base_model_prefix = "deberta"
689
+ _keys_to_ignore_on_load_unexpected = ["position_embeddings"]
690
+ supports_gradient_checkpointing = True
691
+
692
+ @torch.no_grad()
693
+ def _init_weights(self, module):
694
+ """Initialize the weights."""
695
+ super()._init_weights(module)
696
+ if isinstance(module, (LegacyDebertaV2LMPredictionHead, DebertaV2LMPredictionHead)):
697
+ init.zeros_(module.bias)
698
+ elif isinstance(module, DebertaV2Embeddings):
699
+ init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
700
+
701
+
702
+ @auto_docstring
703
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaModel with Deberta->DebertaV2
704
+ class DebertaV2Model(DebertaV2PreTrainedModel):
705
+ def __init__(self, config):
706
+ super().__init__(config)
707
+
708
+ self.embeddings = DebertaV2Embeddings(config)
709
+ self.encoder = DebertaV2Encoder(config)
710
+ self.z_steps = 0
711
+ self.config = config
712
+ # Initialize weights and apply final processing
713
+ self.post_init()
714
+
715
+ def get_input_embeddings(self):
716
+ return self.embeddings.word_embeddings
717
+
718
+ def set_input_embeddings(self, new_embeddings):
719
+ self.embeddings.word_embeddings = new_embeddings
720
+
721
+ @auto_docstring
722
+ def forward(
723
+ self,
724
+ input_ids: torch.Tensor | None = None,
725
+ attention_mask: torch.Tensor | None = None,
726
+ token_type_ids: torch.Tensor | None = None,
727
+ position_ids: torch.Tensor | None = None,
728
+ inputs_embeds: torch.Tensor | None = None,
729
+ output_attentions: bool | None = None,
730
+ output_hidden_states: bool | None = None,
731
+ return_dict: bool | None = None,
732
+ **kwargs,
733
+ ) -> tuple | BaseModelOutput:
734
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
735
+ output_hidden_states = (
736
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
737
+ )
738
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
739
+
740
+ if input_ids is not None and inputs_embeds is not None:
741
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
742
+ elif input_ids is not None:
743
+ self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask)
744
+ input_shape = input_ids.size()
745
+ elif inputs_embeds is not None:
746
+ input_shape = inputs_embeds.size()[:-1]
747
+ else:
748
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
749
+
750
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
751
+
752
+ if attention_mask is None:
753
+ attention_mask = torch.ones(input_shape, device=device)
754
+ if token_type_ids is None:
755
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
756
+
757
+ embedding_output = self.embeddings(
758
+ input_ids=input_ids,
759
+ token_type_ids=token_type_ids,
760
+ position_ids=position_ids,
761
+ mask=attention_mask,
762
+ inputs_embeds=inputs_embeds,
763
+ )
764
+
765
+ encoder_outputs = self.encoder(
766
+ embedding_output,
767
+ attention_mask,
768
+ output_hidden_states=True,
769
+ output_attentions=output_attentions,
770
+ return_dict=return_dict,
771
+ )
772
+ encoded_layers = encoder_outputs[1]
773
+
774
+ if self.z_steps > 1:
775
+ hidden_states = encoded_layers[-2]
776
+ layers = [self.encoder.layer[-1] for _ in range(self.z_steps)]
777
+ query_states = encoded_layers[-1]
778
+ rel_embeddings = self.encoder.get_rel_embedding()
779
+ attention_mask = self.encoder.get_attention_mask(attention_mask)
780
+ rel_pos = self.encoder.get_rel_pos(embedding_output)
781
+ for layer in layers[1:]:
782
+ query_states = layer(
783
+ hidden_states,
784
+ attention_mask,
785
+ output_attentions=False,
786
+ query_states=query_states,
787
+ relative_pos=rel_pos,
788
+ rel_embeddings=rel_embeddings,
789
+ )
790
+ encoded_layers.append(query_states)
791
+
792
+ sequence_output = encoded_layers[-1]
793
+
794
+ if not return_dict:
795
+ return (sequence_output,) + encoder_outputs[(1 if output_hidden_states else 2) :]
796
+
797
+ return BaseModelOutput(
798
+ last_hidden_state=sequence_output,
799
+ hidden_states=encoder_outputs.hidden_states if output_hidden_states else None,
800
+ attentions=encoder_outputs.attentions,
801
+ )
802
+
803
+
804
+ # Copied from transformers.models.deberta.modeling_deberta.LegacyDebertaPredictionHeadTransform with Deberta->DebertaV2
805
+ class LegacyDebertaV2PredictionHeadTransform(nn.Module):
806
+ def __init__(self, config):
807
+ super().__init__()
808
+ self.embedding_size = getattr(config, "embedding_size", config.hidden_size)
809
+
810
+ self.dense = nn.Linear(config.hidden_size, self.embedding_size)
811
+ if isinstance(config.hidden_act, str):
812
+ self.transform_act_fn = ACT2FN[config.hidden_act]
813
+ else:
814
+ self.transform_act_fn = config.hidden_act
815
+ self.LayerNorm = nn.LayerNorm(self.embedding_size, eps=config.layer_norm_eps)
816
+
817
+ def forward(self, hidden_states):
818
+ hidden_states = self.dense(hidden_states)
819
+ hidden_states = self.transform_act_fn(hidden_states)
820
+ hidden_states = self.LayerNorm(hidden_states)
821
+ return hidden_states
822
+
823
+
824
+ class LegacyDebertaV2LMPredictionHead(nn.Module):
825
+ def __init__(self, config):
826
+ super().__init__()
827
+ self.transform = LegacyDebertaV2PredictionHeadTransform(config)
828
+
829
+ self.embedding_size = getattr(config, "embedding_size", config.hidden_size)
830
+ # The output weights are the same as the input embeddings, but there is
831
+ # an output-only bias for each token.
832
+ self.decoder = nn.Linear(self.embedding_size, config.vocab_size)
833
+
834
+ self.bias = nn.Parameter(torch.zeros(config.vocab_size))
835
+
836
+ def forward(self, hidden_states):
837
+ hidden_states = self.transform(hidden_states)
838
+ hidden_states = self.decoder(hidden_states)
839
+ return hidden_states
840
+
841
+
842
+ class LegacyDebertaV2OnlyMLMHead(nn.Module):
843
+ def __init__(self, config):
844
+ super().__init__()
845
+ self.predictions = LegacyDebertaV2LMPredictionHead(config)
846
+
847
+ def forward(self, sequence_output):
848
+ prediction_scores = self.predictions(sequence_output)
849
+ return prediction_scores
850
+
851
+
852
+ class DebertaV2LMPredictionHead(nn.Module):
853
+ """https://github.com/microsoft/DeBERTa/blob/master/DeBERTa/deberta/bert.py#L270"""
854
+
855
+ def __init__(self, config):
856
+ super().__init__()
857
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
858
+
859
+ if isinstance(config.hidden_act, str):
860
+ self.transform_act_fn = ACT2FN[config.hidden_act]
861
+ else:
862
+ self.transform_act_fn = config.hidden_act
863
+
864
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps, elementwise_affine=True)
865
+
866
+ self.bias = nn.Parameter(torch.zeros(config.vocab_size))
867
+
868
+ # note that the input embeddings must be passed as an argument
869
+ def forward(self, hidden_states, word_embeddings):
870
+ hidden_states = self.dense(hidden_states)
871
+ hidden_states = self.transform_act_fn(hidden_states)
872
+ hidden_states = self.LayerNorm(hidden_states)
873
+ hidden_states = torch.matmul(hidden_states, word_embeddings.weight.t()) + self.bias
874
+ return hidden_states
875
+
876
+
877
+ class DebertaV2OnlyMLMHead(nn.Module):
878
+ def __init__(self, config):
879
+ super().__init__()
880
+ self.lm_head = DebertaV2LMPredictionHead(config)
881
+
882
+ # note that the input embeddings must be passed as an argument
883
+ def forward(self, sequence_output, word_embeddings):
884
+ prediction_scores = self.lm_head(sequence_output, word_embeddings)
885
+ return prediction_scores
886
+
887
+
888
+ @auto_docstring
889
+ class DebertaV2ForMaskedLM(DebertaV2PreTrainedModel):
890
+ _tied_weights_keys = {
891
+ "cls.predictions.decoder.bias": "cls.predictions.bias",
892
+ "cls.predictions.decoder.weight": "deberta.embeddings.word_embeddings.weight",
893
+ }
894
+ _keys_to_ignore_on_load_unexpected = [r"mask_predictions.*"]
895
+
896
+ def __init__(self, config):
897
+ super().__init__(config)
898
+ self.legacy = config.legacy
899
+ self.deberta = DebertaV2Model(config)
900
+ if self.legacy:
901
+ self.cls = LegacyDebertaV2OnlyMLMHead(config)
902
+ else:
903
+ self._tied_weights_keys = {
904
+ "lm_predictions.lm_head.weight": "deberta.embeddings.word_embeddings.weight",
905
+ }
906
+ self.lm_predictions = DebertaV2OnlyMLMHead(config)
907
+ # Initialize weights and apply final processing
908
+ self.post_init()
909
+
910
+ def get_output_embeddings(self):
911
+ if self.legacy:
912
+ return self.cls.predictions.decoder
913
+ else:
914
+ return self.lm_predictions.lm_head.dense
915
+
916
+ def set_output_embeddings(self, new_embeddings):
917
+ if self.legacy:
918
+ self.cls.predictions.decoder = new_embeddings
919
+ self.cls.predictions.bias = new_embeddings.bias
920
+ else:
921
+ self.lm_predictions.lm_head.dense = new_embeddings
922
+ self.lm_predictions.lm_head.bias = new_embeddings.bias
923
+
924
+ @auto_docstring
925
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaForMaskedLM.forward with Deberta->DebertaV2
926
+ def forward(
927
+ self,
928
+ input_ids: torch.Tensor | None = None,
929
+ attention_mask: torch.Tensor | None = None,
930
+ token_type_ids: torch.Tensor | None = None,
931
+ position_ids: torch.Tensor | None = None,
932
+ inputs_embeds: torch.Tensor | None = None,
933
+ labels: torch.Tensor | None = None,
934
+ output_attentions: bool | None = None,
935
+ output_hidden_states: bool | None = None,
936
+ return_dict: bool | None = None,
937
+ **kwargs,
938
+ ) -> tuple | MaskedLMOutput:
939
+ r"""
940
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
941
+ Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
942
+ config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
943
+ loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
944
+ """
945
+
946
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
947
+
948
+ outputs = self.deberta(
949
+ input_ids,
950
+ attention_mask=attention_mask,
951
+ token_type_ids=token_type_ids,
952
+ position_ids=position_ids,
953
+ inputs_embeds=inputs_embeds,
954
+ output_attentions=output_attentions,
955
+ output_hidden_states=output_hidden_states,
956
+ return_dict=return_dict,
957
+ )
958
+
959
+ sequence_output = outputs[0]
960
+ if self.legacy:
961
+ prediction_scores = self.cls(sequence_output)
962
+ else:
963
+ prediction_scores = self.lm_predictions(sequence_output, self.deberta.embeddings.word_embeddings)
964
+
965
+ masked_lm_loss = None
966
+ if labels is not None:
967
+ loss_fct = CrossEntropyLoss() # -100 index = padding token
968
+ masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
969
+
970
+ if not return_dict:
971
+ output = (prediction_scores,) + outputs[1:]
972
+ return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output
973
+
974
+ return MaskedLMOutput(
975
+ loss=masked_lm_loss,
976
+ logits=prediction_scores,
977
+ hidden_states=outputs.hidden_states,
978
+ attentions=outputs.attentions,
979
+ )
980
+
981
+
982
+ # Copied from transformers.models.deberta.modeling_deberta.ContextPooler
983
+ class ContextPooler(nn.Module):
984
+ def __init__(self, config):
985
+ super().__init__()
986
+ self.dense = nn.Linear(config.pooler_hidden_size, config.pooler_hidden_size)
987
+ self.dropout = nn.Dropout(config.pooler_dropout)
988
+ self.config = config
989
+
990
+ def forward(self, hidden_states):
991
+ # We "pool" the model by simply taking the hidden state corresponding
992
+ # to the first token.
993
+
994
+ context_token = hidden_states[:, 0]
995
+ context_token = self.dropout(context_token)
996
+ pooled_output = self.dense(context_token)
997
+ pooled_output = ACT2FN[self.config.pooler_hidden_act](pooled_output)
998
+ return pooled_output
999
+
1000
+ @property
1001
+ def output_dim(self):
1002
+ return self.config.hidden_size
1003
+
1004
+
1005
+ @auto_docstring(
1006
+ custom_intro="""
1007
+ DeBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the
1008
+ pooled output) e.g. for GLUE tasks.
1009
+ """
1010
+ )
1011
+ class DebertaV2ForSequenceClassification(DebertaV2PreTrainedModel):
1012
+ def __init__(self, config):
1013
+ super().__init__(config)
1014
+
1015
+ num_labels = getattr(config, "num_labels", 2)
1016
+ self.num_labels = num_labels
1017
+
1018
+ self.deberta = DebertaV2Model(config)
1019
+ self.pooler = ContextPooler(config)
1020
+ output_dim = self.pooler.output_dim
1021
+
1022
+ self.classifier = nn.Linear(output_dim, num_labels)
1023
+ drop_out = getattr(config, "cls_dropout", None)
1024
+ drop_out = self.config.hidden_dropout_prob if drop_out is None else drop_out
1025
+ self.dropout = nn.Dropout(drop_out)
1026
+
1027
+ # Initialize weights and apply final processing
1028
+ self.post_init()
1029
+
1030
+ def get_input_embeddings(self):
1031
+ return self.deberta.get_input_embeddings()
1032
+
1033
+ def set_input_embeddings(self, new_embeddings):
1034
+ self.deberta.set_input_embeddings(new_embeddings)
1035
+
1036
+ @auto_docstring
1037
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaForSequenceClassification.forward with Deberta->DebertaV2
1038
+ def forward(
1039
+ self,
1040
+ input_ids: torch.Tensor | None = None,
1041
+ attention_mask: torch.Tensor | None = None,
1042
+ token_type_ids: torch.Tensor | None = None,
1043
+ position_ids: torch.Tensor | None = None,
1044
+ inputs_embeds: torch.Tensor | None = None,
1045
+ labels: torch.Tensor | None = None,
1046
+ output_attentions: bool | None = None,
1047
+ output_hidden_states: bool | None = None,
1048
+ return_dict: bool | None = None,
1049
+ **kwargs,
1050
+ ) -> tuple | SequenceClassifierOutput:
1051
+ r"""
1052
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
1053
+ Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
1054
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
1055
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
1056
+ """
1057
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1058
+
1059
+ outputs = self.deberta(
1060
+ input_ids,
1061
+ token_type_ids=token_type_ids,
1062
+ attention_mask=attention_mask,
1063
+ position_ids=position_ids,
1064
+ inputs_embeds=inputs_embeds,
1065
+ output_attentions=output_attentions,
1066
+ output_hidden_states=output_hidden_states,
1067
+ return_dict=return_dict,
1068
+ )
1069
+
1070
+ encoder_layer = outputs[0]
1071
+ pooled_output = self.pooler(encoder_layer)
1072
+ pooled_output = self.dropout(pooled_output)
1073
+ logits = self.classifier(pooled_output)
1074
+
1075
+ loss = None
1076
+ if labels is not None:
1077
+ if self.config.problem_type is None:
1078
+ if self.num_labels == 1:
1079
+ # regression task
1080
+ loss_fn = nn.MSELoss()
1081
+ logits = logits.view(-1).to(labels.dtype)
1082
+ loss = loss_fn(logits, labels.view(-1))
1083
+ elif labels.dim() == 1 or labels.size(-1) == 1:
1084
+ label_index = (labels >= 0).nonzero()
1085
+ labels = labels.long()
1086
+ if label_index.size(0) > 0:
1087
+ labeled_logits = torch.gather(
1088
+ logits, 0, label_index.expand(label_index.size(0), logits.size(1))
1089
+ )
1090
+ labels = torch.gather(labels, 0, label_index.view(-1))
1091
+ loss_fct = CrossEntropyLoss()
1092
+ loss = loss_fct(labeled_logits.view(-1, self.num_labels).float(), labels.view(-1))
1093
+ else:
1094
+ loss = torch.tensor(0).to(logits)
1095
+ else:
1096
+ log_softmax = nn.LogSoftmax(-1)
1097
+ loss = -((log_softmax(logits) * labels).sum(-1)).mean()
1098
+ elif self.config.problem_type == "regression":
1099
+ loss_fct = MSELoss()
1100
+ if self.num_labels == 1:
1101
+ loss = loss_fct(logits.squeeze(), labels.squeeze())
1102
+ else:
1103
+ loss = loss_fct(logits, labels)
1104
+ elif self.config.problem_type == "single_label_classification":
1105
+ loss_fct = CrossEntropyLoss()
1106
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
1107
+ elif self.config.problem_type == "multi_label_classification":
1108
+ loss_fct = BCEWithLogitsLoss()
1109
+ loss = loss_fct(logits, labels)
1110
+ if not return_dict:
1111
+ output = (logits,) + outputs[1:]
1112
+ return ((loss,) + output) if loss is not None else output
1113
+
1114
+ return SequenceClassifierOutput(
1115
+ loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions
1116
+ )
1117
+
1118
+
1119
+ @auto_docstring
1120
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaForTokenClassification with Deberta->DebertaV2
1121
+ class DebertaV2ForTokenClassification(DebertaV2PreTrainedModel):
1122
+ def __init__(self, config):
1123
+ super().__init__(config)
1124
+ self.num_labels = config.num_labels
1125
+
1126
+ self.deberta = DebertaV2Model(config)
1127
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
1128
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
1129
+
1130
+ # Initialize weights and apply final processing
1131
+ self.post_init()
1132
+
1133
+ @auto_docstring
1134
+ def forward(
1135
+ self,
1136
+ input_ids: torch.Tensor | None = None,
1137
+ attention_mask: torch.Tensor | None = None,
1138
+ token_type_ids: torch.Tensor | None = None,
1139
+ position_ids: torch.Tensor | None = None,
1140
+ inputs_embeds: torch.Tensor | None = None,
1141
+ labels: torch.Tensor | None = None,
1142
+ output_attentions: bool | None = None,
1143
+ output_hidden_states: bool | None = None,
1144
+ return_dict: bool | None = None,
1145
+ **kwargs,
1146
+ ) -> tuple | TokenClassifierOutput:
1147
+ r"""
1148
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1149
+ Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
1150
+ """
1151
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1152
+
1153
+ outputs = self.deberta(
1154
+ input_ids,
1155
+ attention_mask=attention_mask,
1156
+ token_type_ids=token_type_ids,
1157
+ position_ids=position_ids,
1158
+ inputs_embeds=inputs_embeds,
1159
+ output_attentions=output_attentions,
1160
+ output_hidden_states=output_hidden_states,
1161
+ return_dict=return_dict,
1162
+ )
1163
+
1164
+ sequence_output = outputs[0]
1165
+
1166
+ sequence_output = self.dropout(sequence_output)
1167
+ logits = self.classifier(sequence_output)
1168
+
1169
+ loss = None
1170
+ if labels is not None:
1171
+ loss_fct = CrossEntropyLoss()
1172
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
1173
+
1174
+ if not return_dict:
1175
+ output = (logits,) + outputs[1:]
1176
+ return ((loss,) + output) if loss is not None else output
1177
+
1178
+ return TokenClassifierOutput(
1179
+ loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions
1180
+ )
1181
+
1182
+
1183
+ @auto_docstring
1184
+ class DebertaV2ForQuestionAnswering(DebertaV2PreTrainedModel):
1185
+ def __init__(self, config):
1186
+ super().__init__(config)
1187
+ self.num_labels = config.num_labels
1188
+
1189
+ self.deberta = DebertaV2Model(config)
1190
+ self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
1191
+
1192
+ # Initialize weights and apply final processing
1193
+ self.post_init()
1194
+
1195
+ @auto_docstring
1196
+ # Copied from transformers.models.deberta.modeling_deberta.DebertaForQuestionAnswering.forward with Deberta->DebertaV2
1197
+ def forward(
1198
+ self,
1199
+ input_ids: torch.Tensor | None = None,
1200
+ attention_mask: torch.Tensor | None = None,
1201
+ token_type_ids: torch.Tensor | None = None,
1202
+ position_ids: torch.Tensor | None = None,
1203
+ inputs_embeds: torch.Tensor | None = None,
1204
+ start_positions: torch.Tensor | None = None,
1205
+ end_positions: torch.Tensor | None = None,
1206
+ output_attentions: bool | None = None,
1207
+ output_hidden_states: bool | None = None,
1208
+ return_dict: bool | None = None,
1209
+ **kwargs,
1210
+ ) -> tuple | QuestionAnsweringModelOutput:
1211
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1212
+
1213
+ outputs = self.deberta(
1214
+ input_ids,
1215
+ attention_mask=attention_mask,
1216
+ token_type_ids=token_type_ids,
1217
+ position_ids=position_ids,
1218
+ inputs_embeds=inputs_embeds,
1219
+ output_attentions=output_attentions,
1220
+ output_hidden_states=output_hidden_states,
1221
+ return_dict=return_dict,
1222
+ )
1223
+
1224
+ sequence_output = outputs[0]
1225
+
1226
+ logits = self.qa_outputs(sequence_output)
1227
+ start_logits, end_logits = logits.split(1, dim=-1)
1228
+ start_logits = start_logits.squeeze(-1).contiguous()
1229
+ end_logits = end_logits.squeeze(-1).contiguous()
1230
+
1231
+ total_loss = None
1232
+ if start_positions is not None and end_positions is not None:
1233
+ # If we are on multi-GPU, split add a dimension
1234
+ if len(start_positions.size()) > 1:
1235
+ start_positions = start_positions.squeeze(-1)
1236
+ if len(end_positions.size()) > 1:
1237
+ end_positions = end_positions.squeeze(-1)
1238
+ # sometimes the start/end positions are outside our model inputs, we ignore these terms
1239
+ ignored_index = start_logits.size(1)
1240
+ start_positions = start_positions.clamp(0, ignored_index)
1241
+ end_positions = end_positions.clamp(0, ignored_index)
1242
+
1243
+ loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
1244
+ start_loss = loss_fct(start_logits, start_positions)
1245
+ end_loss = loss_fct(end_logits, end_positions)
1246
+ total_loss = (start_loss + end_loss) / 2
1247
+
1248
+ if not return_dict:
1249
+ output = (start_logits, end_logits) + outputs[1:]
1250
+ return ((total_loss,) + output) if total_loss is not None else output
1251
+
1252
+ return QuestionAnsweringModelOutput(
1253
+ loss=total_loss,
1254
+ start_logits=start_logits,
1255
+ end_logits=end_logits,
1256
+ hidden_states=outputs.hidden_states,
1257
+ attentions=outputs.attentions,
1258
+ )
1259
+
1260
+
1261
+ @auto_docstring
1262
+ class DebertaV2ForMultipleChoice(DebertaV2PreTrainedModel):
1263
+ def __init__(self, config):
1264
+ super().__init__(config)
1265
+
1266
+ num_labels = getattr(config, "num_labels", 2)
1267
+ self.num_labels = num_labels
1268
+
1269
+ self.deberta = DebertaV2Model(config)
1270
+ self.pooler = ContextPooler(config)
1271
+ output_dim = self.pooler.output_dim
1272
+
1273
+ self.classifier = nn.Linear(output_dim, 1)
1274
+ drop_out = getattr(config, "cls_dropout", None)
1275
+ drop_out = self.config.hidden_dropout_prob if drop_out is None else drop_out
1276
+ self.dropout = nn.Dropout(drop_out)
1277
+
1278
+ self.post_init()
1279
+
1280
+ def get_input_embeddings(self):
1281
+ return self.deberta.get_input_embeddings()
1282
+
1283
+ def set_input_embeddings(self, new_embeddings):
1284
+ self.deberta.set_input_embeddings(new_embeddings)
1285
+
1286
+ @auto_docstring
1287
+ def forward(
1288
+ self,
1289
+ input_ids: torch.Tensor | None = None,
1290
+ attention_mask: torch.Tensor | None = None,
1291
+ token_type_ids: torch.Tensor | None = None,
1292
+ position_ids: torch.Tensor | None = None,
1293
+ inputs_embeds: torch.Tensor | None = None,
1294
+ labels: torch.Tensor | None = None,
1295
+ output_attentions: bool | None = None,
1296
+ output_hidden_states: bool | None = None,
1297
+ return_dict: bool | None = None,
1298
+ **kwargs,
1299
+ ) -> tuple | MultipleChoiceModelOutput:
1300
+ r"""
1301
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
1302
+ Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
1303
+ num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
1304
+ `input_ids` above)
1305
+ """
1306
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1307
+ num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1]
1308
+
1309
+ flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None
1310
+ flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
1311
+ flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
1312
+ flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
1313
+ flat_inputs_embeds = (
1314
+ inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1))
1315
+ if inputs_embeds is not None
1316
+ else None
1317
+ )
1318
+
1319
+ outputs = self.deberta(
1320
+ flat_input_ids,
1321
+ position_ids=flat_position_ids,
1322
+ token_type_ids=flat_token_type_ids,
1323
+ attention_mask=flat_attention_mask,
1324
+ inputs_embeds=flat_inputs_embeds,
1325
+ output_attentions=output_attentions,
1326
+ output_hidden_states=output_hidden_states,
1327
+ return_dict=return_dict,
1328
+ )
1329
+
1330
+ encoder_layer = outputs[0]
1331
+ pooled_output = self.pooler(encoder_layer)
1332
+ pooled_output = self.dropout(pooled_output)
1333
+ logits = self.classifier(pooled_output)
1334
+ reshaped_logits = logits.view(-1, num_choices)
1335
+
1336
+ loss = None
1337
+ if labels is not None:
1338
+ loss_fct = CrossEntropyLoss()
1339
+ loss = loss_fct(reshaped_logits, labels)
1340
+
1341
+ if not return_dict:
1342
+ output = (reshaped_logits,) + outputs[1:]
1343
+ return ((loss,) + output) if loss is not None else output
1344
+
1345
+ return MultipleChoiceModelOutput(
1346
+ loss=loss,
1347
+ logits=reshaped_logits,
1348
+ hidden_states=outputs.hidden_states,
1349
+ attentions=outputs.attentions,
1350
+ )
1351
+
1352
+
1353
+ __all__ = [
1354
+ "DebertaV2ForMaskedLM",
1355
+ "DebertaV2ForMultipleChoice",
1356
+ "DebertaV2ForQuestionAnswering",
1357
+ "DebertaV2ForSequenceClassification",
1358
+ "DebertaV2ForTokenClassification",
1359
+ "DebertaV2Model",
1360
+ "DebertaV2PreTrainedModel",
1361
+ ]
third_party/transformers/src/transformers/models/deberta_v2/tokenization_deberta_v2.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 Microsoft 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
+ """Tokenization class for model DeBERTa-v2."""
15
+
16
+ from tokenizers import Regex, Tokenizer, decoders, normalizers, pre_tokenizers, processors
17
+ from tokenizers.models import Unigram
18
+
19
+ from ...tokenization_utils_tokenizers import TokenizersBackend
20
+ from ...utils import logging
21
+
22
+
23
+ logger = logging.get_logger(__name__)
24
+
25
+ VOCAB_FILES_NAMES = {"vocab_file": "spm.model", "tokenizer_file": "tokenizer.json"}
26
+
27
+
28
+ class DebertaV2Tokenizer(TokenizersBackend):
29
+ """
30
+ Construct a DeBERTa-v2 tokenizer (backed by HuggingFace's *tokenizers* library). Based on Unigram tokenization.
31
+
32
+ This tokenizer inherits from [`TokenizersBackend`] which contains most of the main methods. Users should
33
+ refer to this superclass for more information regarding those methods.
34
+
35
+ Args:
36
+ vocab_file (`str`, *optional*):
37
+ Path to the vocabulary file (SentencePiece model file). Not used directly but kept for compatibility.
38
+ vocab (`str`, `dict` or `list`, *optional*):
39
+ List of tuples (piece, score) for the vocabulary.
40
+ precompiled_charsmap (`bytes`, *optional*):
41
+ Precompiled character map for normalization.
42
+ do_lower_case (`bool`, *optional*, defaults to `False`):
43
+ Whether or not to lowercase the input when tokenizing.
44
+ split_by_punct (`bool`, *optional*, defaults to `False`):
45
+ Whether to split by punctuation.
46
+ bos_token (`str`, *optional*, defaults to `"[CLS]"`):
47
+ The beginning of sequence token.
48
+ eos_token (`str`, *optional*, defaults to `"[SEP]"`):
49
+ The end of sequence token.
50
+ unk_token (`str`, *optional*, defaults to `"[UNK]"`):
51
+ The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
52
+ token instead.
53
+ sep_token (`str`, *optional*, defaults to `"[SEP]"`):
54
+ The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
55
+ sequence classification or for a text and a question for question answering. It is also used as the last
56
+ token of a sequence built with special tokens.
57
+ pad_token (`str`, *optional*, defaults to `"[PAD]"`):
58
+ The token used for padding, for example when batching sequences of different lengths.
59
+ cls_token (`str`, *optional*, defaults to `"[CLS]"`):
60
+ The classifier token which is used when doing sequence classification (classification of the whole sequence
61
+ instead of per-token classification). It is the first token of the sequence when built with special tokens.
62
+ mask_token (`str`, *optional*, defaults to `"[MASK]"`):
63
+ The token used for masking values. This is the token used when training this model with masked language
64
+ modeling. This is the token which the model will try to predict.
65
+ add_prefix_space (`bool`, *optional*, defaults to `True`):
66
+ Whether or not to add an initial space to the input. This allows to treat the leading word just as any
67
+ other word.
68
+ unk_id (`int`, *optional*, defaults to index of `unk_token` in vocab):
69
+ The ID of the unknown token in the vocabulary.
70
+ """
71
+
72
+ vocab_files_names = VOCAB_FILES_NAMES
73
+ model_input_names = ["input_ids", "attention_mask", "token_type_ids"]
74
+ model = Unigram
75
+
76
+ def __init__(
77
+ self,
78
+ vocab: str | dict | list | None = None,
79
+ do_lower_case=False,
80
+ split_by_punct=False,
81
+ bos_token="[CLS]",
82
+ eos_token="[SEP]",
83
+ unk_token="[UNK]",
84
+ sep_token="[SEP]",
85
+ pad_token="[PAD]",
86
+ cls_token="[CLS]",
87
+ mask_token="[MASK]",
88
+ add_prefix_space=True,
89
+ unk_id=1,
90
+ **kwargs,
91
+ ):
92
+ self.do_lower_case = do_lower_case
93
+ self.split_by_punct = split_by_punct
94
+ self.add_prefix_space = add_prefix_space
95
+
96
+ if vocab is None:
97
+ vocab = [
98
+ (str(pad_token), 0.0),
99
+ (str(unk_token), 0.0),
100
+ (str(bos_token), 0.0),
101
+ (str(eos_token), 0.0),
102
+ (str(sep_token), 0.0),
103
+ (str(cls_token), 0.0),
104
+ (str(mask_token), 0.0),
105
+ ]
106
+ unk_id = 1
107
+ elif isinstance(vocab, list):
108
+ unk_id = vocab.index((str(unk_token), 0.0)) if (str(unk_token), 0.0) in vocab else unk_id
109
+
110
+ self._vocab = vocab
111
+ self._tokenizer = Tokenizer(
112
+ Unigram(
113
+ self._vocab,
114
+ unk_id=unk_id,
115
+ byte_fallback=False,
116
+ )
117
+ )
118
+
119
+ list_normalizers = []
120
+ if do_lower_case:
121
+ list_normalizers.append(normalizers.Lowercase())
122
+
123
+ list_normalizers.extend(
124
+ [
125
+ normalizers.Replace(Regex(r"\s{2,}|[\n\r\t]"), " "),
126
+ normalizers.NFC(),
127
+ normalizers.Strip(left=False, right=True),
128
+ ]
129
+ )
130
+ self._tokenizer.normalizer = normalizers.Sequence(list_normalizers)
131
+
132
+ list_pretokenizers = []
133
+ if split_by_punct:
134
+ list_pretokenizers.append(pre_tokenizers.Punctuation(behavior="isolated"))
135
+
136
+ prepend_scheme = "always" if add_prefix_space else "first"
137
+ list_pretokenizers.append(pre_tokenizers.Metaspace(replacement="▁", prepend_scheme=prepend_scheme))
138
+
139
+ self._tokenizer.pre_tokenizer = pre_tokenizers.Sequence(list_pretokenizers)
140
+ self._tokenizer.decoder = decoders.Metaspace(replacement="▁", prepend_scheme=prepend_scheme)
141
+ super().__init__(
142
+ bos_token=bos_token,
143
+ eos_token=eos_token,
144
+ unk_token=unk_token,
145
+ sep_token=sep_token,
146
+ cls_token=cls_token,
147
+ pad_token=pad_token,
148
+ mask_token=mask_token,
149
+ unk_id=unk_id,
150
+ do_lower_case=do_lower_case,
151
+ split_by_punct=split_by_punct,
152
+ add_prefix_space=add_prefix_space,
153
+ **kwargs,
154
+ )
155
+
156
+ cls_token_id = self.cls_token_id if self.cls_token_id is not None else 0
157
+ sep_token_id = self.sep_token_id if self.sep_token_id is not None else 0
158
+
159
+ self._tokenizer.post_processor = processors.TemplateProcessing(
160
+ single=f"{str(self.cls_token)}:0 $A:0 {str(self.sep_token)}:0",
161
+ pair=f"{str(self.cls_token)}:0 $A:0 {str(self.sep_token)}:0 $B:1 {str(self.sep_token)}:1",
162
+ special_tokens=[
163
+ (str(self.cls_token), cls_token_id),
164
+ (str(self.sep_token), sep_token_id),
165
+ ],
166
+ )
167
+
168
+
169
+ __all__ = ["DebertaV2Tokenizer"]
third_party/transformers/src/transformers/models/depth_anything/__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_depth_anything import *
22
+ from .modeling_depth_anything 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/depth_anything/configuration_depth_anything.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ """DepthAnything 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.configuration_auto import AutoConfig
22
+
23
+
24
+ @auto_docstring(checkpoint="LiheYoung/depth-anything-small-hf")
25
+ @strict
26
+ class DepthAnythingConfig(PreTrainedConfig):
27
+ r"""
28
+ reassemble_hidden_size (`int`, *optional*, defaults to 384):
29
+ The number of input channels of the reassemble layers.
30
+ reassemble_factors (`list[int]`, *optional*, defaults to `[4, 2, 1, 0.5]`):
31
+ The up/downsampling factors of the reassemble layers.
32
+ neck_hidden_sizes (`list[str]`, *optional*, defaults to `[48, 96, 192, 384]`):
33
+ The hidden sizes to project to for the feature maps of the backbone.
34
+ fusion_hidden_size (`int`, *optional*, defaults to 64):
35
+ The number of channels before fusion.
36
+ head_in_index (`int`, *optional*, defaults to -1):
37
+ The index of the features to use in the depth estimation head.
38
+ head_hidden_size (`int`, *optional*, defaults to 32):
39
+ The number of output channels in the second convolution of the depth estimation head.
40
+ depth_estimation_type (`str`, *optional*, defaults to `"relative"`):
41
+ The type of depth estimation to use. Can be one of `["relative", "metric"]`.
42
+ max_depth (`float`, *optional*):
43
+ The maximum depth to use for the "metric" depth estimation head. 20 should be used for indoor models
44
+ and 80 for outdoor models. For "relative" depth estimation, this value is ignored.
45
+
46
+ Example:
47
+
48
+ ```python
49
+ >>> from transformers import DepthAnythingConfig, DepthAnythingForDepthEstimation
50
+
51
+ >>> # Initializing a DepthAnything small style configuration
52
+ >>> configuration = DepthAnythingConfig()
53
+
54
+ >>> # Initializing a model from the DepthAnything small style configuration
55
+ >>> model = DepthAnythingForDepthEstimation(configuration)
56
+
57
+ >>> # Accessing the model configuration
58
+ >>> configuration = model.config
59
+ ```"""
60
+
61
+ model_type = "depth_anything"
62
+ sub_configs = {"backbone_config": AutoConfig}
63
+
64
+ backbone_config: dict | PreTrainedConfig | None = None
65
+ patch_size: int | list[int] | tuple[int, int] = 14
66
+ initializer_range: float = 0.02
67
+ reassemble_hidden_size: int = 384
68
+ reassemble_factors: list[int | float] | tuple[int | float, ...] = (4, 2, 1, 0.5)
69
+ neck_hidden_sizes: list[int] | tuple[int, ...] = (48, 96, 192, 384)
70
+ fusion_hidden_size: int = 64
71
+ head_in_index: int = -1
72
+ head_hidden_size: int = 32
73
+ depth_estimation_type: str = "relative"
74
+ max_depth: int | None = None
75
+
76
+ def __post_init__(self, **kwargs):
77
+ self.backbone_config, kwargs = consolidate_backbone_kwargs_to_config(
78
+ backbone_config=self.backbone_config,
79
+ default_config_type="dinov2",
80
+ default_config_kwargs={
81
+ "image_size": 518,
82
+ "hidden_size": 384,
83
+ "num_attention_heads": 6,
84
+ "out_indices": [9, 10, 11, 12],
85
+ "reshape_hidden_states": False,
86
+ },
87
+ **kwargs,
88
+ )
89
+
90
+ self.max_depth = self.max_depth if self.max_depth else 1
91
+ super().__post_init__(**kwargs)
92
+
93
+ def validate_architecture(self):
94
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
95
+ if self.depth_estimation_type not in ["relative", "metric"]:
96
+ raise ValueError("depth_estimation_type must be one of ['relative', 'metric']")
97
+
98
+
99
+ __all__ = ["DepthAnythingConfig"]
third_party/transformers/src/transformers/models/depth_anything/convert_depth_anything_to_hf.py ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 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 Depth Anything checkpoints from the original repository. URL:
15
+ https://github.com/LiheYoung/Depth-Anything"""
16
+
17
+ import argparse
18
+ from io import BytesIO
19
+ from pathlib import Path
20
+
21
+ import httpx
22
+ import torch
23
+ from huggingface_hub import hf_hub_download
24
+ from PIL import Image
25
+
26
+ from transformers import DepthAnythingConfig, DepthAnythingForDepthEstimation, Dinov2Config, DPTImageProcessor
27
+ from transformers.utils import logging
28
+
29
+
30
+ logging.set_verbosity_info()
31
+ logger = logging.get_logger(__name__)
32
+
33
+
34
+ def get_dpt_config(model_name):
35
+ if "small" in model_name:
36
+ out_indices = [3, 6, 9, 12] if "v2" in model_name else [9, 10, 11, 12]
37
+ backbone_config = Dinov2Config.from_pretrained(
38
+ "facebook/dinov2-small", out_indices=out_indices, apply_layernorm=True, reshape_hidden_states=False
39
+ )
40
+ fusion_hidden_size = 64
41
+ neck_hidden_sizes = [48, 96, 192, 384]
42
+ elif "base" in model_name:
43
+ out_indices = [3, 6, 9, 12] if "v2" in model_name else [9, 10, 11, 12]
44
+ backbone_config = Dinov2Config.from_pretrained(
45
+ "facebook/dinov2-base", out_indices=out_indices, apply_layernorm=True, reshape_hidden_states=False
46
+ )
47
+ fusion_hidden_size = 128
48
+ neck_hidden_sizes = [96, 192, 384, 768]
49
+ elif "large" in model_name:
50
+ out_indices = [5, 12, 18, 24] if "v2" in model_name else [21, 22, 23, 24]
51
+ backbone_config = Dinov2Config.from_pretrained(
52
+ "facebook/dinov2-large", out_indices=out_indices, apply_layernorm=True, reshape_hidden_states=False
53
+ )
54
+ fusion_hidden_size = 256
55
+ neck_hidden_sizes = [256, 512, 1024, 1024]
56
+ else:
57
+ raise NotImplementedError(f"Model not supported: {model_name}")
58
+
59
+ if "metric" in model_name:
60
+ depth_estimation_type = "metric"
61
+ max_depth = 20 if "indoor" in model_name else 80
62
+ else:
63
+ depth_estimation_type = "relative"
64
+ max_depth = None
65
+
66
+ config = DepthAnythingConfig(
67
+ reassemble_hidden_size=backbone_config.hidden_size,
68
+ patch_size=backbone_config.patch_size,
69
+ backbone_config=backbone_config,
70
+ fusion_hidden_size=fusion_hidden_size,
71
+ neck_hidden_sizes=neck_hidden_sizes,
72
+ depth_estimation_type=depth_estimation_type,
73
+ max_depth=max_depth,
74
+ )
75
+
76
+ return config
77
+
78
+
79
+ def create_rename_keys(config):
80
+ rename_keys = []
81
+
82
+ # fmt: off
83
+ # stem
84
+ rename_keys.append(("pretrained.cls_token", "backbone.embeddings.cls_token"))
85
+ rename_keys.append(("pretrained.mask_token", "backbone.embeddings.mask_token"))
86
+ rename_keys.append(("pretrained.pos_embed", "backbone.embeddings.position_embeddings"))
87
+ rename_keys.append(("pretrained.patch_embed.proj.weight", "backbone.embeddings.patch_embeddings.projection.weight"))
88
+ rename_keys.append(("pretrained.patch_embed.proj.bias", "backbone.embeddings.patch_embeddings.projection.bias"))
89
+
90
+ # Transformer encoder
91
+ for i in range(config.backbone_config.num_hidden_layers):
92
+ rename_keys.append((f"pretrained.blocks.{i}.ls1.gamma", f"backbone.encoder.layer.{i}.layer_scale1.lambda1"))
93
+ rename_keys.append((f"pretrained.blocks.{i}.ls2.gamma", f"backbone.encoder.layer.{i}.layer_scale2.lambda1"))
94
+ rename_keys.append((f"pretrained.blocks.{i}.norm1.weight", f"backbone.encoder.layer.{i}.norm1.weight"))
95
+ rename_keys.append((f"pretrained.blocks.{i}.norm1.bias", f"backbone.encoder.layer.{i}.norm1.bias"))
96
+ rename_keys.append((f"pretrained.blocks.{i}.norm2.weight", f"backbone.encoder.layer.{i}.norm2.weight"))
97
+ rename_keys.append((f"pretrained.blocks.{i}.norm2.bias", f"backbone.encoder.layer.{i}.norm2.bias"))
98
+ rename_keys.append((f"pretrained.blocks.{i}.mlp.fc1.weight", f"backbone.encoder.layer.{i}.mlp.fc1.weight"))
99
+ rename_keys.append((f"pretrained.blocks.{i}.mlp.fc1.bias", f"backbone.encoder.layer.{i}.mlp.fc1.bias"))
100
+ rename_keys.append((f"pretrained.blocks.{i}.mlp.fc2.weight", f"backbone.encoder.layer.{i}.mlp.fc2.weight"))
101
+ rename_keys.append((f"pretrained.blocks.{i}.mlp.fc2.bias", f"backbone.encoder.layer.{i}.mlp.fc2.bias"))
102
+ rename_keys.append((f"pretrained.blocks.{i}.attn.proj.weight", f"backbone.encoder.layer.{i}.attention.output.dense.weight"))
103
+ rename_keys.append((f"pretrained.blocks.{i}.attn.proj.bias", f"backbone.encoder.layer.{i}.attention.output.dense.bias"))
104
+
105
+ # Head
106
+ rename_keys.append(("pretrained.norm.weight", "backbone.layernorm.weight"))
107
+ rename_keys.append(("pretrained.norm.bias", "backbone.layernorm.bias"))
108
+
109
+ # activation postprocessing (readout projections + resize blocks)
110
+ # Depth Anything does not use CLS token => readout_projects not required
111
+
112
+ for i in range(4):
113
+ rename_keys.append((f"depth_head.projects.{i}.weight", f"neck.reassemble_stage.layers.{i}.projection.weight"))
114
+ rename_keys.append((f"depth_head.projects.{i}.bias", f"neck.reassemble_stage.layers.{i}.projection.bias"))
115
+
116
+ if i != 2:
117
+ rename_keys.append((f"depth_head.resize_layers.{i}.weight", f"neck.reassemble_stage.layers.{i}.resize.weight"))
118
+ rename_keys.append((f"depth_head.resize_layers.{i}.bias", f"neck.reassemble_stage.layers.{i}.resize.bias"))
119
+
120
+ # refinenet (tricky here)
121
+ mapping = {1:3, 2:2, 3:1, 4:0}
122
+
123
+ for i in range(1, 5):
124
+ j = mapping[i]
125
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.out_conv.weight", f"neck.fusion_stage.layers.{j}.projection.weight"))
126
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.out_conv.bias", f"neck.fusion_stage.layers.{j}.projection.bias"))
127
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.resConfUnit1.conv1.weight", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution1.weight"))
128
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.resConfUnit1.conv1.bias", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution1.bias"))
129
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.resConfUnit1.conv2.weight", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution2.weight"))
130
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.resConfUnit1.conv2.bias", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution2.bias"))
131
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.resConfUnit2.conv1.weight", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution1.weight"))
132
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.resConfUnit2.conv1.bias", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution1.bias"))
133
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.resConfUnit2.conv2.weight", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution2.weight"))
134
+ rename_keys.append((f"depth_head.scratch.refinenet{i}.resConfUnit2.conv2.bias", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution2.bias"))
135
+
136
+ # scratch convolutions
137
+ for i in range(4):
138
+ rename_keys.append((f"depth_head.scratch.layer{i+1}_rn.weight", f"neck.convs.{i}.weight"))
139
+
140
+ # head
141
+ rename_keys.append(("depth_head.scratch.output_conv1.weight", "head.conv1.weight"))
142
+ rename_keys.append(("depth_head.scratch.output_conv1.bias", "head.conv1.bias"))
143
+ rename_keys.append(("depth_head.scratch.output_conv2.0.weight", "head.conv2.weight"))
144
+ rename_keys.append(("depth_head.scratch.output_conv2.0.bias", "head.conv2.bias"))
145
+ rename_keys.append(("depth_head.scratch.output_conv2.2.weight", "head.conv3.weight"))
146
+ rename_keys.append(("depth_head.scratch.output_conv2.2.bias", "head.conv3.bias"))
147
+
148
+ return rename_keys
149
+
150
+
151
+ # we split up the matrix of each encoder layer into queries, keys and values
152
+ def read_in_q_k_v(state_dict, config):
153
+ hidden_size = config.backbone_config.hidden_size
154
+ for i in range(config.backbone_config.num_hidden_layers):
155
+ # read in weights + bias of input projection layer (in original implementation, this is a single matrix + bias)
156
+ in_proj_weight = state_dict.pop(f"pretrained.blocks.{i}.attn.qkv.weight")
157
+ in_proj_bias = state_dict.pop(f"pretrained.blocks.{i}.attn.qkv.bias")
158
+ # next, add query, keys and values (in that order) to the state dict
159
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[:hidden_size, :]
160
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.query.bias"] = in_proj_bias[:hidden_size]
161
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[
162
+ hidden_size : hidden_size * 2, :
163
+ ]
164
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.key.bias"] = in_proj_bias[
165
+ hidden_size : hidden_size * 2
166
+ ]
167
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[-hidden_size:, :]
168
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.value.bias"] = in_proj_bias[-hidden_size:]
169
+
170
+
171
+ def rename_key(dct, old, new):
172
+ val = dct.pop(old)
173
+ dct[new] = val
174
+
175
+
176
+ # We will verify our results on an image of cute cats
177
+ def prepare_img():
178
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
179
+ with httpx.stream("GET", url) as response:
180
+ image = Image.open(BytesIO(response.read()))
181
+ return image
182
+
183
+
184
+ name_to_checkpoint = {
185
+ "depth-anything-small": "pytorch_model.bin",
186
+ "depth-anything-base": "pytorch_model.bin",
187
+ "depth-anything-large": "pytorch_model.bin",
188
+ "depth-anything-v2-small": "depth_anything_v2_vits.pth",
189
+ "depth-anything-v2-base": "depth_anything_v2_vitb.pth",
190
+ "depth-anything-v2-large": "depth_anything_v2_vitl.pth",
191
+ "depth-anything-v2-metric-indoor-small": "depth_anything_v2_metric_hypersim_vits.pth",
192
+ "depth-anything-v2-metric-indoor-base": "depth_anything_v2_metric_hypersim_vitb.pth",
193
+ "depth-anything-v2-metric-indoor-large": "depth_anything_v2_metric_hypersim_vitl.pth",
194
+ "depth-anything-v2-metric-outdoor-small": "depth_anything_v2_metric_vkitti_vits.pth",
195
+ "depth-anything-v2-metric-outdoor-base": "depth_anything_v2_metric_vkitti_vitb.pth",
196
+ "depth-anything-v2-metric-outdoor-large": "depth_anything_v2_metric_vkitti_vitl.pth",
197
+ # v2-giant pending
198
+ }
199
+
200
+
201
+ @torch.no_grad()
202
+ def convert_dpt_checkpoint(model_name, pytorch_dump_folder_path, push_to_hub, verify_logits):
203
+ """
204
+ Copy/paste/tweak model's weights to our DPT structure.
205
+ """
206
+
207
+ # define DPT configuration
208
+ config = get_dpt_config(model_name)
209
+
210
+ model_name_to_repo = {
211
+ "depth-anything-small": "LiheYoung/depth_anything_vits14",
212
+ "depth-anything-base": "LiheYoung/depth_anything_vitb14",
213
+ "depth-anything-large": "LiheYoung/depth_anything_vitl14",
214
+ "depth-anything-v2-small": "depth-anything/Depth-Anything-V2-Small",
215
+ "depth-anything-v2-base": "depth-anything/Depth-Anything-V2-Base",
216
+ "depth-anything-v2-large": "depth-anything/Depth-Anything-V2-Large",
217
+ "depth-anything-v2-metric-indoor-small": "depth-anything/Depth-Anything-V2-Metric-Hypersim-Small",
218
+ "depth-anything-v2-metric-indoor-base": "depth-anything/Depth-Anything-V2-Metric-Hypersim-Base",
219
+ "depth-anything-v2-metric-indoor-large": "depth-anything/Depth-Anything-V2-Metric-Hypersim-Large",
220
+ "depth-anything-v2-metric-outdoor-small": "depth-anything/Depth-Anything-V2-Metric-VKITTI-Small",
221
+ "depth-anything-v2-metric-outdoor-base": "depth-anything/Depth-Anything-V2-Metric-VKITTI-Base",
222
+ "depth-anything-v2-metric-outdoor-large": "depth-anything/Depth-Anything-V2-Metric-VKITTI-Large",
223
+ }
224
+
225
+ # load original state_dict
226
+ repo_id = model_name_to_repo[model_name]
227
+ filename = name_to_checkpoint[model_name]
228
+ filepath = hf_hub_download(
229
+ repo_id=repo_id,
230
+ filename=f"{filename}",
231
+ )
232
+
233
+ state_dict = torch.load(filepath, map_location="cpu", weights_only=True)
234
+ # rename keys
235
+ rename_keys = create_rename_keys(config)
236
+ for src, dest in rename_keys:
237
+ rename_key(state_dict, src, dest)
238
+ # read in qkv matrices
239
+ read_in_q_k_v(state_dict, config)
240
+
241
+ # load HuggingFace model
242
+ model = DepthAnythingForDepthEstimation(config)
243
+ model.load_state_dict(state_dict)
244
+ model.eval()
245
+
246
+ processor = DPTImageProcessor(
247
+ do_resize=True,
248
+ size={"height": 518, "width": 518},
249
+ ensure_multiple_of=14,
250
+ keep_aspect_ratio=True,
251
+ do_rescale=True,
252
+ do_normalize=True,
253
+ image_mean=[0.485, 0.456, 0.406],
254
+ image_std=[0.229, 0.224, 0.225],
255
+ )
256
+
257
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
258
+ with httpx.stream("GET", url) as response:
259
+ image = Image.open(BytesIO(response.read()))
260
+
261
+ pixel_values = processor(image, return_tensors="pt").pixel_values
262
+
263
+ # Verify forward pass
264
+ with torch.no_grad():
265
+ outputs = model(pixel_values)
266
+ predicted_depth = outputs.predicted_depth
267
+
268
+ print("Shape of predicted depth:", predicted_depth.shape)
269
+ print("First values:", predicted_depth[0, :3, :3])
270
+
271
+ # assert logits
272
+ if verify_logits:
273
+ expected_shape = torch.Size([1, 518, 686])
274
+ if model_name == "depth-anything-small":
275
+ expected_slice = torch.tensor(
276
+ [[8.8204, 8.6468, 8.6195], [8.3313, 8.6027, 8.7526], [8.6526, 8.6866, 8.7453]],
277
+ )
278
+ elif model_name == "depth-anything-base":
279
+ expected_slice = torch.tensor(
280
+ [[26.3997, 26.3004, 26.3928], [26.2260, 26.2092, 26.3427], [26.0719, 26.0483, 26.1254]],
281
+ )
282
+ elif model_name == "depth-anything-large":
283
+ expected_slice = torch.tensor(
284
+ [[87.9968, 87.7493, 88.2704], [87.1927, 87.6611, 87.3640], [86.7789, 86.9469, 86.7991]]
285
+ )
286
+ elif model_name == "depth-anything-v2-small":
287
+ expected_slice = torch.tensor(
288
+ [[2.6751, 2.6211, 2.6571], [2.5820, 2.6138, 2.6271], [2.6160, 2.6141, 2.6306]]
289
+ )
290
+ elif model_name == "depth-anything-v2-base":
291
+ expected_slice = torch.tensor(
292
+ [[4.3576, 4.3723, 4.3908], [4.3231, 4.3146, 4.3611], [4.3016, 4.3170, 4.3121]]
293
+ )
294
+ elif model_name == "depth-anything-v2-large":
295
+ expected_slice = torch.tensor(
296
+ [[162.2751, 161.8504, 162.8788], [160.3138, 160.8050, 161.9835], [159.3812, 159.9884, 160.0768]]
297
+ )
298
+ elif model_name == "depth-anything-v2-metric-indoor-small":
299
+ expected_slice = torch.tensor(
300
+ [[1.3349, 1.2946, 1.2801], [1.2793, 1.2337, 1.2899], [1.2629, 1.2218, 1.2476]]
301
+ )
302
+ elif model_name == "depth-anything-v2-metric-indoor-base":
303
+ expected_slice = torch.tensor(
304
+ [[1.4601, 1.3824, 1.4904], [1.5031, 1.4349, 1.4274], [1.4570, 1.4578, 1.4200]]
305
+ )
306
+ elif model_name == "depth-anything-v2-metric-indoor-large":
307
+ expected_slice = torch.tensor(
308
+ [[1.5040, 1.5019, 1.5218], [1.5087, 1.5195, 1.5149], [1.5437, 1.5128, 1.5252]]
309
+ )
310
+ elif model_name == "depth-anything-v2-metric-outdoor-small":
311
+ expected_slice = torch.tensor(
312
+ [[9.5804, 8.0339, 7.7386], [7.9890, 7.2464, 7.7149], [7.7021, 7.2330, 7.3304]]
313
+ )
314
+ elif model_name == "depth-anything-v2-metric-outdoor-base":
315
+ expected_slice = torch.tensor(
316
+ [[10.2916, 9.0933, 8.8622], [9.1964, 9.3393, 9.0644], [8.9618, 9.4201, 9.2262]]
317
+ )
318
+ elif model_name == "depth-anything-v2-metric-outdoor-large":
319
+ expected_slice = torch.tensor(
320
+ [[14.0137, 13.3627, 13.1080], [13.2522, 13.3943, 13.3705], [13.0581, 13.4505, 13.3925]]
321
+ )
322
+ else:
323
+ raise ValueError("Not supported")
324
+
325
+ assert predicted_depth.shape == torch.Size(expected_shape)
326
+ assert torch.allclose(predicted_depth[0, :3, :3], expected_slice, atol=1e-4)
327
+ print("Looks ok!")
328
+
329
+ if pytorch_dump_folder_path is not None:
330
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
331
+ print(f"Saving model and processor to {pytorch_dump_folder_path}")
332
+ model.save_pretrained(pytorch_dump_folder_path)
333
+ processor.save_pretrained(pytorch_dump_folder_path)
334
+
335
+ if push_to_hub:
336
+ print("Pushing model and processor to hub...")
337
+ model.push_to_hub(repo_id=f"{model_name.title()}-hf")
338
+ processor.push_to_hub(repo_id=f"{model_name.title()}-hf")
339
+
340
+
341
+ if __name__ == "__main__":
342
+ parser = argparse.ArgumentParser()
343
+ # Required parameters
344
+ parser.add_argument(
345
+ "--model_name",
346
+ default="depth-anything-small",
347
+ type=str,
348
+ choices=name_to_checkpoint.keys(),
349
+ help="Name of the model you'd like to convert.",
350
+ )
351
+ parser.add_argument(
352
+ "--pytorch_dump_folder_path",
353
+ default=None,
354
+ type=str,
355
+ help="Path to the output PyTorch model directory.",
356
+ )
357
+ parser.add_argument(
358
+ "--push_to_hub",
359
+ action="store_true",
360
+ help="Whether to push the model to the hub after conversion.",
361
+ )
362
+ parser.add_argument(
363
+ "--verify_logits",
364
+ action="store_false",
365
+ required=False,
366
+ help="Whether to verify the logits after conversion.",
367
+ )
368
+
369
+ args = parser.parse_args()
370
+ convert_dpt_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub, args.verify_logits)
third_party/transformers/src/transformers/models/depth_anything/convert_distill_any_depth_to_hf.py ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 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 Distill Any Depth checkpoints from the original repository. URL:
15
+ https://github.com/Westlake-AGI-Lab/Distill-Any-Depth"""
16
+
17
+ import argparse
18
+ import re
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
+ from safetensors.torch import load_file
27
+
28
+ from transformers import DepthAnythingConfig, DepthAnythingForDepthEstimation, Dinov2Config, DPTImageProcessor
29
+ from transformers.utils import logging
30
+
31
+
32
+ logging.set_verbosity_info()
33
+ logger = logging.get_logger(__name__)
34
+
35
+
36
+ ORIGINAL_TO_CONVERTED_KEY_MAPPING = {
37
+ r"(backbone|pretrained)\.cls_token": r"backbone.embeddings.cls_token",
38
+ r"(backbone|pretrained)\.mask_token": r"backbone.embeddings.mask_token",
39
+ r"(backbone|pretrained)\.pos_embed": r"backbone.embeddings.position_embeddings",
40
+ r"(backbone|pretrained)\.patch_embed\.proj\.(weight|bias)": r"backbone.embeddings.patch_embeddings.projection.\2",
41
+ r"(backbone|pretrained)\.norm\.(weight|bias)": r"backbone.layernorm.\2",
42
+ r"(backbone|pretrained)(\.blocks(\.\d+)?)?\.(\d+)\.attn\.proj\.(weight|bias)": r"backbone.encoder.layer.\4.attention.output.dense.\5",
43
+ r"(backbone|pretrained)(\.blocks(\.\d+)?)?\.(\d+)\.ls(1|2)\.gamma": r"backbone.encoder.layer.\4.layer_scale\5.lambda1",
44
+ r"(backbone|pretrained)(\.blocks(\.\d+)?)?\.(\d+)\.mlp\.fc(1|2)\.(weight|bias)": r"backbone.encoder.layer.\4.mlp.fc\5.\6",
45
+ r"(backbone|pretrained)(\.blocks(\.\d+)?)?\.(\d+)\.norm(1|2)\.(weight|bias)": r"backbone.encoder.layer.\4.norm\5.\6",
46
+ r"depth_head\.projects\.(\d+)\.(weight|bias)": r"neck.reassemble_stage.layers.\1.projection.\2",
47
+ r"depth_head\.resize_layers\.(?!2)(\d+)\.(weight|bias)": r"neck.reassemble_stage.layers.\1.resize.\2",
48
+ r"depth_head\.scratch\.layer(\d+)_rn\.weight": lambda m: f"neck.convs.{int(m[1]) - 1}.weight",
49
+ r"depth_head\.scratch\.output_conv(\d+)(?:\.(\d+))?\.(weight|bias)": lambda m: (
50
+ f"head.conv{int(m[1]) + (int(m[2]) // 2 if m[2] else 0)}.{m[3]}" if m[1] == "2" else f"head.conv{m[1]}.{m[3]}"
51
+ ),
52
+ r"depth_head\.scratch\.refinenet(\d+)\.out_conv\.(weight|bias)": lambda m: f"neck.fusion_stage.layers.{3 - (int(m[1]) - 1)}.projection.{m[2]}",
53
+ r"depth_head\.scratch\.refinenet(\d+)\.resConfUnit(\d+)\.conv(\d+)\.(weight|bias)": lambda m: f"neck.fusion_stage.layers.{3 - (int(m[1]) - 1)}.residual_layer{m[2]}.convolution{m[3]}.{m[4]}",
54
+ }
55
+
56
+
57
+ def get_dpt_config(model_name):
58
+ if "small" in model_name:
59
+ out_indices = [3, 6, 9, 12]
60
+ backbone_config = Dinov2Config.from_pretrained(
61
+ "facebook/dinov2-small", out_indices=out_indices, apply_layernorm=True, reshape_hidden_states=False
62
+ )
63
+ fusion_hidden_size = 64
64
+ neck_hidden_sizes = [48, 96, 192, 384]
65
+ elif "base" in model_name:
66
+ out_indices = [3, 6, 9, 12]
67
+ backbone_config = Dinov2Config.from_pretrained(
68
+ "facebook/dinov2-base", out_indices=out_indices, apply_layernorm=True, reshape_hidden_states=False
69
+ )
70
+ fusion_hidden_size = 128
71
+ neck_hidden_sizes = [96, 192, 384, 768]
72
+ elif "large" in model_name:
73
+ out_indices = [5, 12, 18, 24]
74
+ backbone_config = Dinov2Config.from_pretrained(
75
+ "facebook/dinov2-large", out_indices=out_indices, apply_layernorm=True, reshape_hidden_states=False
76
+ )
77
+ fusion_hidden_size = 256
78
+ neck_hidden_sizes = [256, 512, 1024, 1024]
79
+ else:
80
+ raise NotImplementedError(f"Model not supported: {model_name}")
81
+
82
+ depth_estimation_type = "relative"
83
+ max_depth = None
84
+
85
+ config = DepthAnythingConfig(
86
+ reassemble_hidden_size=backbone_config.hidden_size,
87
+ patch_size=backbone_config.patch_size,
88
+ backbone_config=backbone_config,
89
+ fusion_hidden_size=fusion_hidden_size,
90
+ neck_hidden_sizes=neck_hidden_sizes,
91
+ depth_estimation_type=depth_estimation_type,
92
+ max_depth=max_depth,
93
+ )
94
+
95
+ return config
96
+
97
+
98
+ def convert_key_pattern(key, mapping):
99
+ for pattern, replacement in mapping.items():
100
+ match = re.fullmatch(pattern, key)
101
+ if match:
102
+ if callable(replacement):
103
+ return replacement(match)
104
+ return re.sub(pattern, replacement, key)
105
+ return None
106
+
107
+
108
+ def convert_keys(state_dict, config):
109
+ new_state_dict = {}
110
+ qkv_pattern = r"(backbone|pretrained)(\.blocks(\.\d+)?)?\.(\d+)\.attn\.qkv\.(weight|bias)"
111
+ qkv_keys = [k for k in list(state_dict.keys()) if re.match(qkv_pattern, k)]
112
+ for old_key in qkv_keys:
113
+ value = state_dict.pop(old_key)
114
+ match = re.match(qkv_pattern, old_key)
115
+ _, _, _, layer, attr = match.groups()
116
+ hidden_size = config.backbone_config.hidden_size
117
+ q = value[:hidden_size]
118
+ k = value[hidden_size : hidden_size * 2]
119
+ v = value[-hidden_size:]
120
+
121
+ for proj, tensor in zip(["query", "key", "value"], [q, k, v]):
122
+ new_key = f"backbone.encoder.layer.{layer}.attention.attention.{proj}.{attr}"
123
+ new_state_dict[new_key] = tensor
124
+
125
+ for old_key in list(state_dict.keys()):
126
+ value = state_dict.pop(old_key)
127
+ new_key = convert_key_pattern(old_key, ORIGINAL_TO_CONVERTED_KEY_MAPPING)
128
+
129
+ new_state_dict[new_key] = value
130
+
131
+ return new_state_dict
132
+
133
+
134
+ def prepare_img():
135
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
136
+ with httpx.stream("GET", url) as response:
137
+ image = Image.open(BytesIO(response.read()))
138
+ return image
139
+
140
+
141
+ name_to_checkpoint = {
142
+ "distill-any-depth-small": "small/model.safetensors",
143
+ "distill-any-depth-base": "base/model.safetensors",
144
+ "distill-any-depth-large": "large/model.safetensors",
145
+ }
146
+
147
+
148
+ @torch.no_grad()
149
+ def convert_dpt_checkpoint(model_name, pytorch_dump_folder_path, push_to_hub, verify_logits):
150
+ config = get_dpt_config(model_name)
151
+
152
+ repo_id = "xingyang1/Distill-Any-Depth"
153
+ filepath = hf_hub_download(repo_id=repo_id, filename=name_to_checkpoint[model_name])
154
+ state_dict = load_file(filepath)
155
+
156
+ converted_state_dict = convert_keys(state_dict, config)
157
+
158
+ model = DepthAnythingForDepthEstimation(config)
159
+ model.load_state_dict(converted_state_dict)
160
+ model.eval()
161
+
162
+ processor = DPTImageProcessor(
163
+ do_resize=True,
164
+ size={"height": 518, "width": 518},
165
+ ensure_multiple_of=14,
166
+ keep_aspect_ratio=True,
167
+ do_rescale=True,
168
+ do_normalize=True,
169
+ image_mean=[0.485, 0.456, 0.406],
170
+ image_std=[0.229, 0.224, 0.225],
171
+ )
172
+
173
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
174
+ with httpx.stream("GET", url) as response:
175
+ image = Image.open(BytesIO(response.read()))
176
+
177
+ pixel_values = processor(image, return_tensors="pt").pixel_values
178
+
179
+ with torch.no_grad():
180
+ outputs = model(pixel_values)
181
+ predicted_depth = outputs.predicted_depth
182
+
183
+ print("Shape of predicted depth:", predicted_depth.shape)
184
+ print("First values:", predicted_depth[0, :3, :3])
185
+
186
+ if verify_logits:
187
+ print("Verifying logits...")
188
+ expected_shape = torch.Size([1, 518, 686])
189
+
190
+ if model_name == "distill-any-depth-small":
191
+ expected_slice = torch.tensor(
192
+ [[2.5653, 2.5249, 2.5570], [2.4897, 2.5235, 2.5355], [2.5255, 2.5261, 2.5422]]
193
+ )
194
+ elif model_name == "distill-any-depth-base":
195
+ expected_slice = torch.tensor(
196
+ [[4.8976, 4.9075, 4.9403], [4.8872, 4.8906, 4.9448], [4.8712, 4.8898, 4.8838]]
197
+ )
198
+ elif model_name == "distill-any-depth-large":
199
+ expected_slice = torch.tensor(
200
+ [[55.1067, 51.1828, 51.6803], [51.9098, 50.7529, 51.4494], [50.1745, 50.5491, 50.8818]]
201
+ )
202
+ else:
203
+ raise ValueError("Not supported")
204
+
205
+ assert predicted_depth.shape == torch.Size(expected_shape)
206
+ assert torch.allclose(predicted_depth[0, :3, :3], expected_slice, atol=1e-4)
207
+ print("Looks ok!")
208
+
209
+ if pytorch_dump_folder_path is not None:
210
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
211
+ print(f"Saving model and processor to {pytorch_dump_folder_path}")
212
+ model.save_pretrained(pytorch_dump_folder_path)
213
+ processor.save_pretrained(pytorch_dump_folder_path)
214
+
215
+ if push_to_hub:
216
+ print("Pushing model and processor to hub...")
217
+ model.push_to_hub(repo_id=f"{model_name.title()}-hf")
218
+ processor.push_to_hub(repo_id=f"{model_name.title()}-hf")
219
+
220
+
221
+ if __name__ == "__main__":
222
+ parser = argparse.ArgumentParser()
223
+ parser.add_argument(
224
+ "--model_name",
225
+ default="distill-any-depth-small",
226
+ type=str,
227
+ choices=name_to_checkpoint.keys(),
228
+ help="Name of the model you'd like to convert.",
229
+ )
230
+ parser.add_argument(
231
+ "--pytorch_dump_folder_path",
232
+ default=None,
233
+ type=str,
234
+ help="Path to the output PyTorch model directory.",
235
+ )
236
+ parser.add_argument(
237
+ "--push_to_hub",
238
+ action="store_true",
239
+ help="Whether to push the model to the hub after conversion.",
240
+ )
241
+ parser.add_argument(
242
+ "--verify_logits",
243
+ action="store_true",
244
+ required=False,
245
+ help="Whether to verify the logits after conversion.",
246
+ )
247
+
248
+ args = parser.parse_args()
249
+ convert_dpt_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub, args.verify_logits)
third_party/transformers/src/transformers/models/depth_anything/modeling_depth_anything.py ADDED
@@ -0,0 +1,416 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 TikTok 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 Depth Anything model."""
15
+
16
+ import torch
17
+ from torch import nn
18
+
19
+ from ...backbone_utils import load_backbone
20
+ from ...modeling_outputs import DepthEstimatorOutput
21
+ from ...modeling_utils import PreTrainedModel
22
+ from ...utils import auto_docstring, logging
23
+ from .configuration_depth_anything import DepthAnythingConfig
24
+
25
+
26
+ logger = logging.get_logger(__name__)
27
+
28
+ # General docstring
29
+
30
+
31
+ class DepthAnythingReassembleLayer(nn.Module):
32
+ def __init__(self, config, channels, factor):
33
+ super().__init__()
34
+ self.projection = nn.Conv2d(in_channels=config.reassemble_hidden_size, out_channels=channels, kernel_size=1)
35
+
36
+ # up/down sampling depending on factor
37
+ if factor > 1:
38
+ self.resize = nn.ConvTranspose2d(channels, channels, kernel_size=factor, stride=factor, padding=0)
39
+ elif factor == 1:
40
+ self.resize = nn.Identity()
41
+ elif factor < 1:
42
+ # so should downsample
43
+ self.resize = nn.Conv2d(channels, channels, kernel_size=3, stride=int(1 / factor), padding=1)
44
+
45
+ # Copied from transformers.models.dpt.modeling_dpt.DPTReassembleLayer.forward
46
+ def forward(self, hidden_state):
47
+ hidden_state = self.projection(hidden_state)
48
+ hidden_state = self.resize(hidden_state)
49
+
50
+ return hidden_state
51
+
52
+
53
+ class DepthAnythingReassembleStage(nn.Module):
54
+ """
55
+ This class reassembles the hidden states of the backbone into image-like feature representations at various
56
+ resolutions.
57
+
58
+ This happens in 3 stages:
59
+ 1. Take the patch embeddings and reshape them to image-like feature representations.
60
+ 2. Project the channel dimension of the hidden states according to `config.neck_hidden_sizes`.
61
+ 3. Resizing the spatial dimensions (height, width).
62
+
63
+ Args:
64
+ config (`[DepthAnythingConfig]`):
65
+ Model configuration class defining the model architecture.
66
+ """
67
+
68
+ def __init__(self, config):
69
+ super().__init__()
70
+
71
+ self.config = config
72
+ self.layers = nn.ModuleList()
73
+ for channels, factor in zip(config.neck_hidden_sizes, config.reassemble_factors):
74
+ self.layers.append(DepthAnythingReassembleLayer(config, channels=channels, factor=factor))
75
+
76
+ def forward(self, hidden_states: list[torch.Tensor], patch_height=None, patch_width=None) -> list[torch.Tensor]:
77
+ """
78
+ Args:
79
+ hidden_states (`list[torch.FloatTensor]`, each of shape `(batch_size, sequence_length + 1, hidden_size)`):
80
+ List of hidden states from the backbone.
81
+ """
82
+ out = []
83
+
84
+ for i, hidden_state in enumerate(hidden_states):
85
+ # reshape to (batch_size, num_channels, height, width)
86
+ hidden_state = hidden_state[:, 1:]
87
+ batch_size, _, num_channels = hidden_state.shape
88
+ hidden_state = hidden_state.reshape(batch_size, patch_height, patch_width, num_channels)
89
+ hidden_state = hidden_state.permute(0, 3, 1, 2).contiguous()
90
+ hidden_state = self.layers[i](hidden_state)
91
+ out.append(hidden_state)
92
+
93
+ return out
94
+
95
+
96
+ class DepthAnythingPreActResidualLayer(nn.Module):
97
+ """
98
+ ResidualConvUnit, pre-activate residual unit.
99
+
100
+ Args:
101
+ config (`[DepthAnythingConfig]`):
102
+ Model configuration class defining the model architecture.
103
+ """
104
+
105
+ def __init__(self, config):
106
+ super().__init__()
107
+
108
+ self.activation1 = nn.ReLU()
109
+ self.convolution1 = nn.Conv2d(
110
+ config.fusion_hidden_size,
111
+ config.fusion_hidden_size,
112
+ kernel_size=3,
113
+ stride=1,
114
+ padding=1,
115
+ bias=True,
116
+ )
117
+
118
+ self.activation2 = nn.ReLU()
119
+ self.convolution2 = nn.Conv2d(
120
+ config.fusion_hidden_size,
121
+ config.fusion_hidden_size,
122
+ kernel_size=3,
123
+ stride=1,
124
+ padding=1,
125
+ bias=True,
126
+ )
127
+
128
+ def forward(self, hidden_state: torch.Tensor) -> torch.Tensor:
129
+ residual = hidden_state
130
+ hidden_state = self.activation1(hidden_state)
131
+ hidden_state = self.convolution1(hidden_state)
132
+ hidden_state = self.activation2(hidden_state)
133
+ hidden_state = self.convolution2(hidden_state)
134
+
135
+ return hidden_state + residual
136
+
137
+
138
+ class DepthAnythingFeatureFusionLayer(nn.Module):
139
+ """Feature fusion layer, merges feature maps from different stages.
140
+
141
+ Args:
142
+ config (`[DepthAnythingConfig]`):
143
+ Model configuration class defining the model architecture.
144
+ """
145
+
146
+ def __init__(self, config):
147
+ super().__init__()
148
+
149
+ self.projection = nn.Conv2d(config.fusion_hidden_size, config.fusion_hidden_size, kernel_size=1, bias=True)
150
+
151
+ self.residual_layer1 = DepthAnythingPreActResidualLayer(config)
152
+ self.residual_layer2 = DepthAnythingPreActResidualLayer(config)
153
+
154
+ def forward(self, hidden_state, residual=None, size=None):
155
+ if residual is not None:
156
+ if hidden_state.shape != residual.shape:
157
+ residual = nn.functional.interpolate(
158
+ residual, size=(hidden_state.shape[2], hidden_state.shape[3]), mode="bilinear", align_corners=False
159
+ )
160
+ hidden_state = hidden_state + self.residual_layer1(residual)
161
+
162
+ hidden_state = self.residual_layer2(hidden_state)
163
+
164
+ modifier = {"scale_factor": 2} if size is None else {"size": size}
165
+
166
+ hidden_state = nn.functional.interpolate(
167
+ hidden_state,
168
+ **modifier,
169
+ mode="bilinear",
170
+ align_corners=True,
171
+ )
172
+ hidden_state = self.projection(hidden_state)
173
+
174
+ return hidden_state
175
+
176
+
177
+ class DepthAnythingFeatureFusionStage(nn.Module):
178
+ # Copied from transformers.models.dpt.modeling_dpt.DPTFeatureFusionStage.__init__ with DPT->DepthAnything
179
+ def __init__(self, config: DepthAnythingConfig):
180
+ super().__init__()
181
+ self.layers = nn.ModuleList()
182
+ for _ in range(len(config.neck_hidden_sizes)):
183
+ self.layers.append(DepthAnythingFeatureFusionLayer(config))
184
+
185
+ def forward(self, hidden_states, size=None):
186
+ # reversing the hidden_states, we start from the last
187
+ hidden_states = hidden_states[::-1]
188
+
189
+ fused_hidden_states = []
190
+ fused_hidden_state = None
191
+
192
+ for idx, (hidden_state, layer) in enumerate(zip(hidden_states, self.layers)):
193
+ size = hidden_states[idx + 1].shape[2:] if idx != (len(hidden_states) - 1) else None
194
+
195
+ if fused_hidden_state is None:
196
+ # first layer only uses the last hidden_state
197
+ fused_hidden_state = layer(hidden_state, size=size)
198
+ else:
199
+ fused_hidden_state = layer(fused_hidden_state, hidden_state, size=size)
200
+
201
+ fused_hidden_states.append(fused_hidden_state)
202
+
203
+ return fused_hidden_states
204
+
205
+
206
+ # Modified from transformers.models.dpt.modeling_dpt.DPTPreTrainedModel with DPT->DepthAnything,dpt->depth_anything
207
+ # avoiding sdpa and flash_attn_2 support, it's done in the backend
208
+ @auto_docstring
209
+ class DepthAnythingPreTrainedModel(PreTrainedModel):
210
+ config: DepthAnythingConfig
211
+ base_model_prefix = "depth_anything"
212
+ main_input_name = "pixel_values"
213
+ input_modalities = ("image",)
214
+ supports_gradient_checkpointing = True
215
+
216
+
217
+ class DepthAnythingNeck(nn.Module):
218
+ """
219
+ DepthAnythingNeck. A neck is a module that is normally used between the backbone and the head. It takes a list of tensors as
220
+ input and produces another list of tensors as output. For DepthAnything, it includes 2 stages:
221
+
222
+ * DepthAnythingReassembleStage
223
+ * DepthAnythingFeatureFusionStage.
224
+
225
+ Args:
226
+ config (dict): config dict.
227
+ """
228
+
229
+ def __init__(self, config):
230
+ super().__init__()
231
+ self.config = config
232
+
233
+ self.reassemble_stage = DepthAnythingReassembleStage(config)
234
+
235
+ self.convs = nn.ModuleList()
236
+ for channel in config.neck_hidden_sizes:
237
+ self.convs.append(nn.Conv2d(channel, config.fusion_hidden_size, kernel_size=3, padding=1, bias=False))
238
+
239
+ # fusion
240
+ self.fusion_stage = DepthAnythingFeatureFusionStage(config)
241
+
242
+ def forward(self, hidden_states: list[torch.Tensor], patch_height=None, patch_width=None) -> list[torch.Tensor]:
243
+ """
244
+ Args:
245
+ hidden_states (`list[torch.FloatTensor]`, each of shape `(batch_size, sequence_length, hidden_size)` or `(batch_size, hidden_size, height, width)`):
246
+ List of hidden states from the backbone.
247
+ """
248
+ if not isinstance(hidden_states, (tuple, list)):
249
+ raise TypeError("hidden_states should be a tuple or list of tensors")
250
+
251
+ if len(hidden_states) != len(self.config.neck_hidden_sizes):
252
+ raise ValueError("The number of hidden states should be equal to the number of neck hidden sizes.")
253
+
254
+ # postprocess hidden states
255
+ hidden_states = self.reassemble_stage(hidden_states, patch_height, patch_width)
256
+
257
+ features = [self.convs[i](feature) for i, feature in enumerate(hidden_states)]
258
+
259
+ # fusion blocks
260
+ output = self.fusion_stage(features)
261
+
262
+ return output
263
+
264
+
265
+ class DepthAnythingDepthEstimationHead(nn.Module):
266
+ """
267
+ Output head consisting of 3 convolutional layers. It progressively halves the feature dimension and upsamples
268
+ the predictions to the input resolution after the first convolutional layer (details can be found in the DPT paper's
269
+ supplementary material). The final activation function is either ReLU or Sigmoid, depending on the depth estimation
270
+ type (relative or metric). For metric depth estimation, the output is scaled by the maximum depth used during pretraining.
271
+ """
272
+
273
+ def __init__(self, config):
274
+ super().__init__()
275
+
276
+ self.head_in_index = config.head_in_index
277
+ self.patch_size = config.patch_size
278
+
279
+ features = config.fusion_hidden_size
280
+ self.conv1 = nn.Conv2d(features, features // 2, kernel_size=3, stride=1, padding=1)
281
+ self.conv2 = nn.Conv2d(features // 2, config.head_hidden_size, kernel_size=3, stride=1, padding=1)
282
+ self.activation1 = nn.ReLU()
283
+ self.conv3 = nn.Conv2d(config.head_hidden_size, 1, kernel_size=1, stride=1, padding=0)
284
+ if config.depth_estimation_type == "relative":
285
+ self.activation2 = nn.ReLU()
286
+ elif config.depth_estimation_type == "metric":
287
+ self.activation2 = nn.Sigmoid()
288
+ else:
289
+ raise ValueError(f"Unknown depth estimation type: {config.depth_estimation_type}")
290
+ self.max_depth = config.max_depth
291
+
292
+ def forward(self, hidden_states: list[torch.Tensor], patch_height, patch_width) -> torch.Tensor:
293
+ hidden_states = hidden_states[self.head_in_index]
294
+
295
+ predicted_depth = self.conv1(hidden_states)
296
+ predicted_depth = nn.functional.interpolate(
297
+ predicted_depth,
298
+ (int(patch_height * self.patch_size), int(patch_width * self.patch_size)),
299
+ mode="bilinear",
300
+ align_corners=True,
301
+ )
302
+ predicted_depth = self.conv2(predicted_depth)
303
+ predicted_depth = self.activation1(predicted_depth)
304
+ predicted_depth = self.conv3(predicted_depth)
305
+ predicted_depth = self.activation2(predicted_depth) * self.max_depth
306
+ predicted_depth = predicted_depth.squeeze(dim=1) # shape (batch_size, height, width)
307
+
308
+ return predicted_depth
309
+
310
+
311
+ @auto_docstring(
312
+ custom_intro="""
313
+ Depth Anything Model with a depth estimation head on top (consisting of 3 convolutional layers) e.g. for KITTI, NYUv2.
314
+ """
315
+ )
316
+ class DepthAnythingForDepthEstimation(DepthAnythingPreTrainedModel):
317
+ _no_split_modules = ["DPTViTEmbeddings"]
318
+
319
+ def __init__(self, config):
320
+ super().__init__(config)
321
+
322
+ self.backbone = load_backbone(config)
323
+ self.neck = DepthAnythingNeck(config)
324
+ self.head = DepthAnythingDepthEstimationHead(config)
325
+
326
+ # Initialize weights and apply final processing
327
+ self.post_init()
328
+
329
+ @auto_docstring
330
+ def forward(
331
+ self,
332
+ pixel_values: torch.FloatTensor,
333
+ labels: torch.LongTensor | None = None,
334
+ output_attentions: bool | None = None,
335
+ output_hidden_states: bool | None = None,
336
+ return_dict: bool | None = None,
337
+ **kwargs,
338
+ ) -> tuple[torch.Tensor] | DepthEstimatorOutput:
339
+ r"""
340
+ labels (`torch.LongTensor` of shape `(batch_size, height, width)`, *optional*):
341
+ Ground truth depth estimation maps for computing the loss.
342
+
343
+ Examples:
344
+ ```python
345
+ >>> from transformers import AutoImageProcessor, AutoModelForDepthEstimation
346
+ >>> import torch
347
+ >>> import numpy as np
348
+ >>> from PIL import Image
349
+ >>> import httpx
350
+ >>> from io import BytesIO
351
+
352
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
353
+ >>> with httpx.stream("GET", url) as response:
354
+ ... image = Image.open(BytesIO(response.read()))
355
+
356
+ >>> image_processor = AutoImageProcessor.from_pretrained("LiheYoung/depth-anything-small-hf")
357
+ >>> model = AutoModelForDepthEstimation.from_pretrained("LiheYoung/depth-anything-small-hf")
358
+
359
+ >>> # prepare image for the model
360
+ >>> inputs = image_processor(images=image, return_tensors="pt")
361
+
362
+ >>> with torch.no_grad():
363
+ ... outputs = model(**inputs)
364
+
365
+ >>> # interpolate to original size
366
+ >>> post_processed_output = image_processor.post_process_depth_estimation(
367
+ ... outputs,
368
+ ... target_sizes=[(image.height, image.width)],
369
+ ... )
370
+
371
+ >>> # visualize the prediction
372
+ >>> predicted_depth = post_processed_output[0]["predicted_depth"]
373
+ >>> depth = predicted_depth * 255 / predicted_depth.max()
374
+ >>> depth = depth.detach().cpu().numpy()
375
+ >>> depth = Image.fromarray(depth.astype("uint8"))
376
+ ```"""
377
+ loss = None
378
+ if labels is not None:
379
+ raise NotImplementedError("Training is not implemented yet")
380
+
381
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
382
+ output_hidden_states = (
383
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
384
+ )
385
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
386
+
387
+ outputs = self.backbone.forward_with_filtered_kwargs(
388
+ pixel_values, output_hidden_states=output_hidden_states, output_attentions=output_attentions
389
+ )
390
+ hidden_states = outputs.feature_maps
391
+
392
+ _, _, height, width = pixel_values.shape
393
+ patch_size = self.config.patch_size
394
+ patch_height = height // patch_size
395
+ patch_width = width // patch_size
396
+
397
+ hidden_states = self.neck(hidden_states, patch_height, patch_width)
398
+
399
+ predicted_depth = self.head(hidden_states, patch_height, patch_width)
400
+
401
+ if not return_dict:
402
+ if output_hidden_states:
403
+ output = (predicted_depth,) + outputs[1:]
404
+ else:
405
+ output = (predicted_depth,) + outputs[2:]
406
+ return ((loss,) + output) if loss is not None else output
407
+
408
+ return DepthEstimatorOutput(
409
+ loss=loss,
410
+ predicted_depth=predicted_depth,
411
+ hidden_states=outputs.hidden_states if output_hidden_states else None,
412
+ attentions=outputs.attentions,
413
+ )
414
+
415
+
416
+ __all__ = ["DepthAnythingForDepthEstimation", "DepthAnythingPreTrainedModel"]
third_party/transformers/src/transformers/models/dpr/__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_dpr import *
22
+ from .modeling_dpr import *
23
+ from .tokenization_dpr import *
24
+ from .tokenization_dpr_fast 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/dpr/configuration_dpr.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2010, DPR authors, The Hugging Face 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
+ """DPR 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="facebook/dpr-ctx_encoder-single-nq-base")
23
+ @strict
24
+ class DPRConfig(PreTrainedConfig):
25
+ r"""
26
+ Example:
27
+
28
+ ```python
29
+ >>> from transformers import DPRConfig, DPRContextEncoder
30
+
31
+ >>> # Initializing a DPR facebook/dpr-ctx_encoder-single-nq-base style configuration
32
+ >>> configuration = DPRConfig()
33
+
34
+ >>> # Initializing a model (with random weights) from the facebook/dpr-ctx_encoder-single-nq-base style configuration
35
+ >>> model = DPRContextEncoder(configuration)
36
+
37
+ >>> # Accessing the model configuration
38
+ >>> configuration = model.config
39
+ ```"""
40
+
41
+ model_type = "dpr"
42
+
43
+ vocab_size: int = 30522
44
+ hidden_size: int = 768
45
+ num_hidden_layers: int = 12
46
+ num_attention_heads: int = 12
47
+ intermediate_size: int = 3072
48
+ hidden_act: str = "gelu"
49
+ hidden_dropout_prob: float | int = 0.1
50
+ attention_probs_dropout_prob: float | int = 0.1
51
+ max_position_embeddings: int = 512
52
+ type_vocab_size: int = 2
53
+ initializer_range: float = 0.02
54
+ layer_norm_eps: float = 1e-12
55
+ pad_token_id: int | None = 0
56
+ bos_token_id: int | None = None
57
+ eos_token_id: int | list[int] | None = None
58
+ projection_dim: int = 0
59
+ is_decoder: bool = False
60
+ add_cross_attention: bool = False
61
+
62
+
63
+ __all__ = ["DPRConfig"]
third_party/transformers/src/transformers/models/dpr/convert_dpr_original_checkpoint_to_pytorch.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 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 argparse
16
+ import collections
17
+ from pathlib import Path
18
+
19
+ import torch
20
+ from torch.serialization import default_restore_location
21
+
22
+ from transformers import BertConfig, DPRConfig, DPRContextEncoder, DPRQuestionEncoder, DPRReader
23
+
24
+
25
+ CheckpointState = collections.namedtuple(
26
+ "CheckpointState", ["model_dict", "optimizer_dict", "scheduler_dict", "offset", "epoch", "encoder_params"]
27
+ )
28
+
29
+
30
+ def load_states_from_checkpoint(model_file: str) -> CheckpointState:
31
+ print(f"Reading saved model from {model_file}")
32
+ state_dict = torch.load(
33
+ model_file, map_location=lambda s, l: default_restore_location(s, "cpu"), weights_only=True
34
+ )
35
+ return CheckpointState(**state_dict)
36
+
37
+
38
+ class DPRState:
39
+ def __init__(self, src_file: Path):
40
+ self.src_file = src_file
41
+
42
+ def load_dpr_model(self):
43
+ raise NotImplementedError
44
+
45
+ @staticmethod
46
+ def from_type(comp_type: str, *args, **kwargs) -> "DPRState":
47
+ if comp_type.startswith("c"):
48
+ return DPRContextEncoderState(*args, **kwargs)
49
+ if comp_type.startswith("q"):
50
+ return DPRQuestionEncoderState(*args, **kwargs)
51
+ if comp_type.startswith("r"):
52
+ return DPRReaderState(*args, **kwargs)
53
+ else:
54
+ raise ValueError("Component type must be either 'ctx_encoder', 'question_encoder' or 'reader'.")
55
+
56
+
57
+ class DPRContextEncoderState(DPRState):
58
+ def load_dpr_model(self):
59
+ model = DPRContextEncoder(DPRConfig(**BertConfig.get_config_dict("google-bert/bert-base-uncased")[0]))
60
+ print(f"Loading DPR biencoder from {self.src_file}")
61
+ saved_state = load_states_from_checkpoint(self.src_file)
62
+ encoder, prefix = model.ctx_encoder, "ctx_model."
63
+ # Fix changes from https://github.com/huggingface/transformers/commit/614fef1691edb806de976756d4948ecbcd0c0ca3
64
+ state_dict = {"bert_model.embeddings.position_ids": model.ctx_encoder.bert_model.embeddings.position_ids}
65
+ for key, value in saved_state.model_dict.items():
66
+ if key.startswith(prefix):
67
+ key = key[len(prefix) :]
68
+ if not key.startswith("encode_proj."):
69
+ key = "bert_model." + key
70
+ state_dict[key] = value
71
+ encoder.load_state_dict(state_dict)
72
+ return model
73
+
74
+
75
+ class DPRQuestionEncoderState(DPRState):
76
+ def load_dpr_model(self):
77
+ model = DPRQuestionEncoder(DPRConfig(**BertConfig.get_config_dict("google-bert/bert-base-uncased")[0]))
78
+ print(f"Loading DPR biencoder from {self.src_file}")
79
+ saved_state = load_states_from_checkpoint(self.src_file)
80
+ encoder, prefix = model.question_encoder, "question_model."
81
+ # Fix changes from https://github.com/huggingface/transformers/commit/614fef1691edb806de976756d4948ecbcd0c0ca3
82
+ state_dict = {"bert_model.embeddings.position_ids": model.question_encoder.bert_model.embeddings.position_ids}
83
+ for key, value in saved_state.model_dict.items():
84
+ if key.startswith(prefix):
85
+ key = key[len(prefix) :]
86
+ if not key.startswith("encode_proj."):
87
+ key = "bert_model." + key
88
+ state_dict[key] = value
89
+ encoder.load_state_dict(state_dict)
90
+ return model
91
+
92
+
93
+ class DPRReaderState(DPRState):
94
+ def load_dpr_model(self):
95
+ model = DPRReader(DPRConfig(**BertConfig.get_config_dict("google-bert/bert-base-uncased")[0]))
96
+ print(f"Loading DPR reader from {self.src_file}")
97
+ saved_state = load_states_from_checkpoint(self.src_file)
98
+ # Fix changes from https://github.com/huggingface/transformers/commit/614fef1691edb806de976756d4948ecbcd0c0ca3
99
+ state_dict = {
100
+ "encoder.bert_model.embeddings.position_ids": model.span_predictor.encoder.bert_model.embeddings.position_ids
101
+ }
102
+ for key, value in saved_state.model_dict.items():
103
+ if key.startswith("encoder.") and not key.startswith("encoder.encode_proj"):
104
+ key = "encoder.bert_model." + key[len("encoder.") :]
105
+ state_dict[key] = value
106
+ model.span_predictor.load_state_dict(state_dict)
107
+ return model
108
+
109
+
110
+ def convert(comp_type: str, src_file: Path, dest_dir: Path):
111
+ dest_dir = Path(dest_dir)
112
+ dest_dir.mkdir(exist_ok=True)
113
+
114
+ dpr_state = DPRState.from_type(comp_type, src_file=src_file)
115
+ model = dpr_state.load_dpr_model()
116
+ model.save_pretrained(dest_dir)
117
+ model.from_pretrained(dest_dir) # sanity check
118
+
119
+
120
+ if __name__ == "__main__":
121
+ parser = argparse.ArgumentParser()
122
+ # Required parameters
123
+ parser.add_argument(
124
+ "--type", type=str, help="Type of the component to convert: 'ctx_encoder', 'question_encoder' or 'reader'."
125
+ )
126
+ parser.add_argument(
127
+ "--src",
128
+ type=str,
129
+ help=(
130
+ "Path to the dpr checkpoint file. They can be downloaded from the official DPR repo"
131
+ " https://github.com/facebookresearch/DPR. Note that in the official repo, both encoders are stored in the"
132
+ " 'retriever' checkpoints."
133
+ ),
134
+ )
135
+ parser.add_argument("--dest", type=str, default=None, help="Path to the output PyTorch model directory.")
136
+ args = parser.parse_args()
137
+
138
+ src_file = Path(args.src)
139
+ dest_dir = f"converted-{src_file.name}" if args.dest is None else args.dest
140
+ dest_dir = Path(dest_dir)
141
+ assert src_file.exists()
142
+ assert args.type is not None, (
143
+ "Please specify the component type of the DPR model to convert: 'ctx_encoder', 'question_encoder' or 'reader'."
144
+ )
145
+ convert(args.type, src_file, dest_dir)
third_party/transformers/src/transformers/models/dpr/modeling_dpr.py ADDED
@@ -0,0 +1,576 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 DPR Authors, The Hugging Face 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 DPR model for Open Domain Question Answering."""
15
+
16
+ from dataclasses import dataclass
17
+
18
+ import torch
19
+ from torch import Tensor, nn
20
+
21
+ from ...modeling_outputs import BaseModelOutputWithPooling
22
+ from ...modeling_utils import PreTrainedModel
23
+ from ...utils import (
24
+ ModelOutput,
25
+ auto_docstring,
26
+ logging,
27
+ )
28
+ from ..bert.modeling_bert import BertModel
29
+ from .configuration_dpr import DPRConfig
30
+
31
+
32
+ logger = logging.get_logger(__name__)
33
+
34
+
35
+ ##########
36
+ # Outputs
37
+ ##########
38
+
39
+
40
+ @dataclass
41
+ @auto_docstring(
42
+ custom_intro="""
43
+ Class for outputs of [`DPRQuestionEncoder`].
44
+ """
45
+ )
46
+ class DPRContextEncoderOutput(ModelOutput):
47
+ r"""
48
+ pooler_output (`torch.FloatTensor` of shape `(batch_size, embeddings_size)`):
49
+ The DPR encoder outputs the *pooler_output* that corresponds to the context representation. Last layer
50
+ hidden-state of the first token of the sequence (classification token) further processed by a Linear layer.
51
+ This output is to be used to embed contexts for nearest neighbors queries with questions embeddings.
52
+ """
53
+
54
+ pooler_output: torch.FloatTensor
55
+ hidden_states: tuple[torch.FloatTensor, ...] | None = None
56
+ attentions: tuple[torch.FloatTensor, ...] | None = None
57
+
58
+
59
+ @dataclass
60
+ @auto_docstring(
61
+ custom_intro="""
62
+ Class for outputs of [`DPRQuestionEncoder`].
63
+ """
64
+ )
65
+ class DPRQuestionEncoderOutput(ModelOutput):
66
+ r"""
67
+ pooler_output (`torch.FloatTensor` of shape `(batch_size, embeddings_size)`):
68
+ The DPR encoder outputs the *pooler_output* that corresponds to the question representation. Last layer
69
+ hidden-state of the first token of the sequence (classification token) further processed by a Linear layer.
70
+ This output is to be used to embed questions for nearest neighbors queries with context embeddings.
71
+ """
72
+
73
+ pooler_output: torch.FloatTensor
74
+ hidden_states: tuple[torch.FloatTensor, ...] | None = None
75
+ attentions: tuple[torch.FloatTensor, ...] | None = None
76
+
77
+
78
+ @dataclass
79
+ @auto_docstring(
80
+ custom_intro="""
81
+ Class for outputs of [`DPRQuestionEncoder`].
82
+ """
83
+ )
84
+ class DPRReaderOutput(ModelOutput):
85
+ r"""
86
+ start_logits (`torch.FloatTensor` of shape `(n_passages, sequence_length)`):
87
+ Logits of the start index of the span for each passage.
88
+ end_logits (`torch.FloatTensor` of shape `(n_passages, sequence_length)`):
89
+ Logits of the end index of the span for each passage.
90
+ relevance_logits (`torch.FloatTensor` of shape `(n_passages, )`):
91
+ Outputs of the QA classifier of the DPRReader that corresponds to the scores of each passage to answer the
92
+ question, compared to all the other passages.
93
+ """
94
+
95
+ start_logits: torch.FloatTensor
96
+ end_logits: torch.FloatTensor | None = None
97
+ relevance_logits: torch.FloatTensor | None = None
98
+ hidden_states: tuple[torch.FloatTensor, ...] | None = None
99
+ attentions: tuple[torch.FloatTensor, ...] | None = None
100
+
101
+
102
+ @auto_docstring
103
+ class DPRPreTrainedModel(PreTrainedModel):
104
+ _supports_sdpa = True
105
+
106
+
107
+ class DPREncoder(DPRPreTrainedModel):
108
+ base_model_prefix = "bert_model"
109
+
110
+ def __init__(self, config: DPRConfig):
111
+ super().__init__(config)
112
+ self.bert_model = BertModel(config, add_pooling_layer=False)
113
+ if self.bert_model.config.hidden_size <= 0:
114
+ raise ValueError("Encoder hidden_size can't be zero")
115
+ self.projection_dim = config.projection_dim
116
+ if self.projection_dim > 0:
117
+ self.encode_proj = nn.Linear(self.bert_model.config.hidden_size, config.projection_dim)
118
+ # Initialize weights and apply final processing
119
+ self.post_init()
120
+
121
+ def forward(
122
+ self,
123
+ input_ids: Tensor,
124
+ attention_mask: Tensor | None = None,
125
+ token_type_ids: Tensor | None = None,
126
+ inputs_embeds: Tensor | None = None,
127
+ output_attentions: bool = False,
128
+ output_hidden_states: bool = False,
129
+ return_dict: bool = False,
130
+ **kwargs,
131
+ ) -> BaseModelOutputWithPooling | tuple[Tensor, ...]:
132
+ outputs = self.bert_model(
133
+ input_ids=input_ids,
134
+ attention_mask=attention_mask,
135
+ token_type_ids=token_type_ids,
136
+ inputs_embeds=inputs_embeds,
137
+ output_attentions=output_attentions,
138
+ output_hidden_states=output_hidden_states,
139
+ return_dict=return_dict,
140
+ )
141
+ sequence_output = outputs[0]
142
+ pooled_output = sequence_output[:, 0, :]
143
+
144
+ if self.projection_dim > 0:
145
+ pooled_output = self.encode_proj(pooled_output)
146
+
147
+ if not return_dict:
148
+ return (sequence_output, pooled_output) + outputs[2:]
149
+
150
+ return BaseModelOutputWithPooling(
151
+ last_hidden_state=sequence_output,
152
+ pooler_output=pooled_output,
153
+ hidden_states=outputs.hidden_states,
154
+ attentions=outputs.attentions,
155
+ )
156
+
157
+ @property
158
+ def embeddings_size(self) -> int:
159
+ if self.projection_dim > 0:
160
+ return self.encode_proj.out_features
161
+ return self.bert_model.config.hidden_size
162
+
163
+
164
+ class DPRSpanPredictor(DPRPreTrainedModel):
165
+ base_model_prefix = "encoder"
166
+
167
+ def __init__(self, config: DPRConfig):
168
+ super().__init__(config)
169
+ self.encoder = DPREncoder(config)
170
+ self.qa_outputs = nn.Linear(self.encoder.embeddings_size, 2)
171
+ self.qa_classifier = nn.Linear(self.encoder.embeddings_size, 1)
172
+ # Initialize weights and apply final processing
173
+ self.post_init()
174
+
175
+ def forward(
176
+ self,
177
+ input_ids: Tensor,
178
+ attention_mask: Tensor,
179
+ inputs_embeds: Tensor | None = None,
180
+ output_attentions: bool = False,
181
+ output_hidden_states: bool = False,
182
+ return_dict: bool = False,
183
+ **kwargs,
184
+ ) -> DPRReaderOutput | tuple[Tensor, ...]:
185
+ # notations: N - number of questions in a batch, M - number of passages per questions, L - sequence length
186
+ n_passages, sequence_length = input_ids.size() if input_ids is not None else inputs_embeds.size()[:2]
187
+ # feed encoder
188
+ outputs = self.encoder(
189
+ input_ids,
190
+ attention_mask=attention_mask,
191
+ inputs_embeds=inputs_embeds,
192
+ output_attentions=output_attentions,
193
+ output_hidden_states=output_hidden_states,
194
+ return_dict=return_dict,
195
+ )
196
+ sequence_output = outputs[0]
197
+
198
+ # compute logits
199
+ logits = self.qa_outputs(sequence_output)
200
+ start_logits, end_logits = logits.split(1, dim=-1)
201
+ start_logits = start_logits.squeeze(-1).contiguous()
202
+ end_logits = end_logits.squeeze(-1).contiguous()
203
+ relevance_logits = self.qa_classifier(sequence_output[:, 0, :])
204
+
205
+ # resize
206
+ start_logits = start_logits.view(n_passages, sequence_length)
207
+ end_logits = end_logits.view(n_passages, sequence_length)
208
+ relevance_logits = relevance_logits.view(n_passages)
209
+
210
+ if not return_dict:
211
+ return (start_logits, end_logits, relevance_logits) + outputs[2:]
212
+
213
+ return DPRReaderOutput(
214
+ start_logits=start_logits,
215
+ end_logits=end_logits,
216
+ relevance_logits=relevance_logits,
217
+ hidden_states=outputs.hidden_states,
218
+ attentions=outputs.attentions,
219
+ )
220
+
221
+
222
+ ##################
223
+ # PreTrainedModel
224
+ ##################
225
+
226
+
227
+ class DPRPretrainedContextEncoder(DPRPreTrainedModel):
228
+ """
229
+ An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
230
+ models.
231
+ """
232
+
233
+ config: DPRConfig
234
+ base_model_prefix = "ctx_encoder"
235
+
236
+
237
+ class DPRPretrainedQuestionEncoder(DPRPreTrainedModel):
238
+ """
239
+ An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
240
+ models.
241
+ """
242
+
243
+ config: DPRConfig
244
+ base_model_prefix = "question_encoder"
245
+
246
+
247
+ class DPRPretrainedReader(DPRPreTrainedModel):
248
+ """
249
+ An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
250
+ models.
251
+ """
252
+
253
+ config: DPRConfig
254
+ base_model_prefix = "span_predictor"
255
+
256
+
257
+ ###############
258
+ # Actual Models
259
+ ###############
260
+
261
+
262
+ @auto_docstring(
263
+ custom_intro="""
264
+ The bare DPRContextEncoder transformer outputting pooler outputs as context representations.
265
+ """
266
+ )
267
+ class DPRContextEncoder(DPRPretrainedContextEncoder):
268
+ def __init__(self, config: DPRConfig):
269
+ super().__init__(config)
270
+ self.config = config
271
+ self.ctx_encoder = DPREncoder(config)
272
+ # Initialize weights and apply final processing
273
+ self.post_init()
274
+
275
+ @auto_docstring
276
+ def forward(
277
+ self,
278
+ input_ids: Tensor | None = None,
279
+ attention_mask: Tensor | None = None,
280
+ token_type_ids: Tensor | None = None,
281
+ inputs_embeds: Tensor | None = None,
282
+ output_attentions: bool | None = None,
283
+ output_hidden_states: bool | None = None,
284
+ return_dict: bool | None = None,
285
+ **kwargs,
286
+ ) -> DPRContextEncoderOutput | tuple[Tensor, ...]:
287
+ r"""
288
+ input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
289
+ Indices of input sequence tokens in the vocabulary. To match pretraining, DPR input sequence should be
290
+ formatted with [CLS] and [SEP] tokens as follows:
291
+
292
+ (a) For sequence pairs (for a pair title+text for example):
293
+
294
+ ```
295
+ tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP]
296
+ token_type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1
297
+ ```
298
+
299
+ (b) For single sequences (for a question for example):
300
+
301
+ ```
302
+ tokens: [CLS] the dog is hairy . [SEP]
303
+ token_type_ids: 0 0 0 0 0 0 0
304
+ ```
305
+
306
+ DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right
307
+ rather than the left.
308
+
309
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
310
+ [`PreTrainedTokenizer.__call__`] for details.
311
+
312
+ [What are input IDs?](../glossary#input-ids)
313
+
314
+ Examples:
315
+
316
+ ```python
317
+ >>> from transformers import DPRContextEncoder, DPRContextEncoderTokenizer
318
+
319
+ >>> tokenizer = DPRContextEncoderTokenizer.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
320
+ >>> model = DPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
321
+ >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="pt")["input_ids"]
322
+ >>> embeddings = model(input_ids).pooler_output
323
+ ```"""
324
+
325
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
326
+ output_hidden_states = (
327
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
328
+ )
329
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
330
+
331
+ if input_ids is not None and inputs_embeds is not None:
332
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
333
+ elif input_ids is not None:
334
+ input_shape = input_ids.size()
335
+ elif inputs_embeds is not None:
336
+ input_shape = inputs_embeds.size()[:-1]
337
+ else:
338
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
339
+
340
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
341
+
342
+ if attention_mask is None:
343
+ attention_mask = (
344
+ torch.ones(input_shape, device=device)
345
+ if input_ids is None
346
+ else (input_ids != self.config.pad_token_id)
347
+ )
348
+ if token_type_ids is None:
349
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
350
+
351
+ outputs = self.ctx_encoder(
352
+ input_ids=input_ids,
353
+ attention_mask=attention_mask,
354
+ token_type_ids=token_type_ids,
355
+ inputs_embeds=inputs_embeds,
356
+ output_attentions=output_attentions,
357
+ output_hidden_states=output_hidden_states,
358
+ return_dict=return_dict,
359
+ )
360
+
361
+ if not return_dict:
362
+ return outputs[1:]
363
+ return DPRContextEncoderOutput(
364
+ pooler_output=outputs.pooler_output, hidden_states=outputs.hidden_states, attentions=outputs.attentions
365
+ )
366
+
367
+
368
+ @auto_docstring(
369
+ custom_intro="""
370
+ The bare DPRQuestionEncoder transformer outputting pooler outputs as question representations.
371
+ """
372
+ )
373
+ class DPRQuestionEncoder(DPRPretrainedQuestionEncoder):
374
+ def __init__(self, config: DPRConfig):
375
+ super().__init__(config)
376
+ self.config = config
377
+ self.question_encoder = DPREncoder(config)
378
+ # Initialize weights and apply final processing
379
+ self.post_init()
380
+
381
+ @auto_docstring
382
+ def forward(
383
+ self,
384
+ input_ids: Tensor | None = None,
385
+ attention_mask: Tensor | None = None,
386
+ token_type_ids: Tensor | None = None,
387
+ inputs_embeds: Tensor | None = None,
388
+ output_attentions: bool | None = None,
389
+ output_hidden_states: bool | None = None,
390
+ return_dict: bool | None = None,
391
+ **kwargs,
392
+ ) -> DPRQuestionEncoderOutput | tuple[Tensor, ...]:
393
+ r"""
394
+ input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
395
+ Indices of input sequence tokens in the vocabulary. To match pretraining, DPR input sequence should be
396
+ formatted with [CLS] and [SEP] tokens as follows:
397
+
398
+ (a) For sequence pairs (for a pair title+text for example):
399
+
400
+ ```
401
+ tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP]
402
+ token_type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1
403
+ ```
404
+
405
+ (b) For single sequences (for a question for example):
406
+
407
+ ```
408
+ tokens: [CLS] the dog is hairy . [SEP]
409
+ token_type_ids: 0 0 0 0 0 0 0
410
+ ```
411
+
412
+ DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right
413
+ rather than the left.
414
+
415
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
416
+ [`PreTrainedTokenizer.__call__`] for details.
417
+
418
+ [What are input IDs?](../glossary#input-ids)
419
+
420
+ Examples:
421
+
422
+ ```python
423
+ >>> from transformers import DPRQuestionEncoder, DPRQuestionEncoderTokenizer
424
+
425
+ >>> tokenizer = DPRQuestionEncoderTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
426
+ >>> model = DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
427
+ >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="pt")["input_ids"]
428
+ >>> embeddings = model(input_ids).pooler_output
429
+ ```
430
+ """
431
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
432
+ output_hidden_states = (
433
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
434
+ )
435
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
436
+
437
+ if input_ids is not None and inputs_embeds is not None:
438
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
439
+ elif input_ids is not None:
440
+ self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask)
441
+ input_shape = input_ids.size()
442
+ elif inputs_embeds is not None:
443
+ input_shape = inputs_embeds.size()[:-1]
444
+ else:
445
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
446
+
447
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
448
+
449
+ if attention_mask is None:
450
+ attention_mask = (
451
+ torch.ones(input_shape, device=device)
452
+ if input_ids is None
453
+ else (input_ids != self.config.pad_token_id)
454
+ )
455
+ if token_type_ids is None:
456
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
457
+
458
+ outputs = self.question_encoder(
459
+ input_ids=input_ids,
460
+ attention_mask=attention_mask,
461
+ token_type_ids=token_type_ids,
462
+ inputs_embeds=inputs_embeds,
463
+ output_attentions=output_attentions,
464
+ output_hidden_states=output_hidden_states,
465
+ return_dict=return_dict,
466
+ )
467
+
468
+ if not return_dict:
469
+ return outputs[1:]
470
+ return DPRQuestionEncoderOutput(
471
+ pooler_output=outputs.pooler_output, hidden_states=outputs.hidden_states, attentions=outputs.attentions
472
+ )
473
+
474
+
475
+ @auto_docstring(
476
+ custom_intro="""
477
+ The bare DPRReader transformer outputting span predictions.
478
+ """
479
+ )
480
+ class DPRReader(DPRPretrainedReader):
481
+ def __init__(self, config: DPRConfig):
482
+ super().__init__(config)
483
+ self.config = config
484
+ self.span_predictor = DPRSpanPredictor(config)
485
+ # Initialize weights and apply final processing
486
+ self.post_init()
487
+
488
+ @auto_docstring
489
+ def forward(
490
+ self,
491
+ input_ids: Tensor | None = None,
492
+ attention_mask: Tensor | None = None,
493
+ inputs_embeds: Tensor | None = None,
494
+ output_attentions: bool | None = None,
495
+ output_hidden_states: bool | None = None,
496
+ return_dict: bool | None = None,
497
+ **kwargs,
498
+ ) -> DPRReaderOutput | tuple[Tensor, ...]:
499
+ r"""
500
+ input_ids (`tuple[torch.LongTensor]` of shapes `(n_passages, sequence_length)`):
501
+ Indices of input sequence tokens in the vocabulary. It has to be a sequence triplet with 1) the question
502
+ and 2) the passages titles and 3) the passages texts To match pretraining, DPR `input_ids` sequence should
503
+ be formatted with [CLS] and [SEP] with the format:
504
+
505
+ `[CLS] <question token ids> [SEP] <titles ids> [SEP] <texts ids>`
506
+
507
+ DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right
508
+ rather than the left.
509
+
510
+ Indices can be obtained using [`DPRReaderTokenizer`]. See this class documentation for more details.
511
+
512
+ [What are input IDs?](../glossary#input-ids)
513
+ inputs_embeds (`torch.FloatTensor` of shape `(n_passages, sequence_length, hidden_size)`, *optional*):
514
+ Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
515
+ is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
516
+ model's internal embedding lookup matrix.
517
+
518
+ Examples:
519
+
520
+ ```python
521
+ >>> from transformers import DPRReader, DPRReaderTokenizer
522
+
523
+ >>> tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base")
524
+ >>> model = DPRReader.from_pretrained("facebook/dpr-reader-single-nq-base")
525
+ >>> encoded_inputs = tokenizer(
526
+ ... questions=["What is love ?"],
527
+ ... titles=["Haddaway"],
528
+ ... texts=["'What Is Love' is a song recorded by the artist Haddaway"],
529
+ ... return_tensors="pt",
530
+ ... )
531
+ >>> outputs = model(**encoded_inputs)
532
+ >>> start_logits = outputs.start_logits
533
+ >>> end_logits = outputs.end_logits
534
+ >>> relevance_logits = outputs.relevance_logits
535
+ ```
536
+ """
537
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
538
+ output_hidden_states = (
539
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
540
+ )
541
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
542
+
543
+ if input_ids is not None and inputs_embeds is not None:
544
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
545
+ elif input_ids is not None:
546
+ self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask)
547
+ input_shape = input_ids.size()
548
+ elif inputs_embeds is not None:
549
+ input_shape = inputs_embeds.size()[:-1]
550
+ else:
551
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
552
+
553
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
554
+
555
+ if attention_mask is None:
556
+ attention_mask = torch.ones(input_shape, device=device)
557
+
558
+ return self.span_predictor(
559
+ input_ids,
560
+ attention_mask,
561
+ inputs_embeds=inputs_embeds,
562
+ output_attentions=output_attentions,
563
+ output_hidden_states=output_hidden_states,
564
+ return_dict=return_dict,
565
+ )
566
+
567
+
568
+ __all__ = [
569
+ "DPRContextEncoder",
570
+ "DPRPretrainedContextEncoder",
571
+ "DPRPreTrainedModel",
572
+ "DPRPretrainedQuestionEncoder",
573
+ "DPRPretrainedReader",
574
+ "DPRQuestionEncoder",
575
+ "DPRReader",
576
+ ]
third_party/transformers/src/transformers/models/dpr/tokenization_dpr.py ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 The HuggingFace Inc. team, The Hugging Face 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
+ """Tokenization classes for DPR."""
15
+
16
+ import collections
17
+
18
+ from ...tokenization_utils_base import BatchEncoding
19
+ from ...utils import TensorType, add_end_docstrings, add_start_docstrings, logging
20
+ from ..bert.tokenization_bert import BertTokenizer
21
+
22
+
23
+ logger = logging.get_logger(__name__)
24
+
25
+ VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"}
26
+
27
+
28
+ class DPRContextEncoderTokenizer(BertTokenizer):
29
+ r"""
30
+ Construct a DPRContextEncoder tokenizer.
31
+
32
+ [`DPRContextEncoderTokenizer`] is identical to [`BertTokenizer`] and runs end-to-end tokenization: punctuation
33
+ splitting and wordpiece.
34
+
35
+ Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning parameters.
36
+ """
37
+
38
+ vocab_files_names = VOCAB_FILES_NAMES
39
+
40
+ def __init__(self, *args, do_lower_case=False, **kwargs):
41
+ super().__init__(*args, **kwargs)
42
+ self.do_lower_case = do_lower_case
43
+
44
+
45
+ class DPRQuestionEncoderTokenizer(BertTokenizer):
46
+ r"""
47
+ Constructs a DPRQuestionEncoder tokenizer.
48
+
49
+ [`DPRQuestionEncoderTokenizer`] is identical to [`BertTokenizer`] and runs end-to-end tokenization: punctuation
50
+ splitting and wordpiece.
51
+
52
+ Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning parameters.
53
+ """
54
+
55
+ vocab_files_names = VOCAB_FILES_NAMES
56
+
57
+ def __init__(self, *args, do_lower_case=False, **kwargs):
58
+ super().__init__(*args, **kwargs)
59
+ self.do_lower_case = do_lower_case
60
+
61
+
62
+ DPRSpanPrediction = collections.namedtuple(
63
+ "DPRSpanPrediction", ["span_score", "relevance_score", "doc_id", "start_index", "end_index", "text"]
64
+ )
65
+
66
+ DPRReaderOutput = collections.namedtuple("DPRReaderOutput", ["start_logits", "end_logits", "relevance_logits"])
67
+
68
+
69
+ CUSTOM_DPR_READER_DOCSTRING = r"""
70
+ Return a dictionary with the token ids of the input strings and other information to give to `.decode_best_spans`.
71
+ It converts the strings of a question and different passages (title and text) in a sequence of IDs (integers),
72
+ using the tokenizer and vocabulary. The resulting `input_ids` is a matrix of size `(n_passages, sequence_length)`
73
+ with the format:
74
+
75
+ ```
76
+ [CLS] <question token ids> [SEP] <titles ids> [SEP] <texts ids>
77
+ ```
78
+
79
+ Args:
80
+ questions (`str` or `list[str]`):
81
+ The questions to be encoded. You can specify one question for many passages. In this case, the question
82
+ will be duplicated like `[questions] * n_passages`. Otherwise you have to specify as many questions as in
83
+ `titles` or `texts`.
84
+ titles (`str` or `list[str]`):
85
+ The passages titles to be encoded. This can be a string or a list of strings if there are several passages.
86
+ texts (`str` or `list[str]`):
87
+ The passages texts to be encoded. This can be a string or a list of strings if there are several passages.
88
+ padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`):
89
+ Activates and controls padding. Accepts the following values:
90
+
91
+ - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single sequence
92
+ if provided).
93
+ - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum
94
+ acceptable input length for the model if that argument is not provided.
95
+ - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different
96
+ lengths).
97
+ truncation (`bool`, `str` or [`~tokenization_utils_base.TruncationStrategy`], *optional*, defaults to `False`):
98
+ Activates and controls truncation. Accepts the following values:
99
+
100
+ - `True` or `'longest_first'`: Truncate to a maximum length specified with the argument `max_length` or to
101
+ the maximum acceptable input length for the model if that argument is not provided. This will truncate
102
+ token by token, removing a token from the longest sequence in the pair if a pair of sequences (or a batch
103
+ of pairs) is provided.
104
+ - `'only_first'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum
105
+ acceptable input length for the model if that argument is not provided. This will only truncate the first
106
+ sequence of a pair if a pair of sequences (or a batch of pairs) is provided.
107
+ - `'only_second'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum
108
+ acceptable input length for the model if that argument is not provided. This will only truncate the
109
+ second sequence of a pair if a pair of sequences (or a batch of pairs) is provided.
110
+ - `False` or `'do_not_truncate'` (default): No truncation (i.e., can output batch with sequence lengths
111
+ greater than the model maximum admissible input size).
112
+ max_length (`int`, *optional*):
113
+ Controls the maximum length to use by one of the truncation/padding parameters.
114
+
115
+ If left unset or set to `None`, this will use the predefined model maximum length if a maximum length
116
+ is required by one of the truncation/padding parameters. If the model has no specific maximum input
117
+ length (like XLNet) truncation/padding to a maximum length will be deactivated.
118
+ return_tensors (`str` or [`~utils.TensorType`], *optional*):
119
+ If set, will return tensors instead of list of python integers. Acceptable values are:
120
+
121
+ - `'pt'`: Return PyTorch `torch.Tensor` objects.
122
+ - `'np'`: Return Numpy `np.ndarray` objects.
123
+ return_attention_mask (`bool`, *optional*):
124
+ Whether or not to return the attention mask. If not set, will return the attention mask according to the
125
+ specific tokenizer's default, defined by the `return_outputs` attribute.
126
+
127
+ [What are attention masks?](../glossary#attention-mask)
128
+
129
+ Returns:
130
+ `dict[str, list[list[int]]]`: A dictionary with the following keys:
131
+
132
+ - `input_ids`: List of token ids to be fed to a model.
133
+ - `attention_mask`: List of indices specifying which tokens should be attended to by the model.
134
+ """
135
+
136
+
137
+ @add_start_docstrings(CUSTOM_DPR_READER_DOCSTRING)
138
+ class CustomDPRReaderTokenizerMixin:
139
+ def __call__(
140
+ self,
141
+ questions,
142
+ titles: str | None = None,
143
+ texts: str | None = None,
144
+ padding: bool | str = False,
145
+ truncation: bool | str = False,
146
+ max_length: int | None = None,
147
+ return_tensors: str | TensorType | None = None,
148
+ return_attention_mask: bool | None = None,
149
+ **kwargs,
150
+ ) -> BatchEncoding:
151
+ if titles is None and texts is None:
152
+ return super().__call__(
153
+ questions,
154
+ padding=padding,
155
+ truncation=truncation,
156
+ max_length=max_length,
157
+ return_tensors=return_tensors,
158
+ return_attention_mask=return_attention_mask,
159
+ **kwargs,
160
+ )
161
+ elif titles is None or texts is None:
162
+ text_pair = titles if texts is None else texts
163
+ return super().__call__(
164
+ questions,
165
+ text_pair,
166
+ padding=padding,
167
+ truncation=truncation,
168
+ max_length=max_length,
169
+ return_tensors=return_tensors,
170
+ return_attention_mask=return_attention_mask,
171
+ **kwargs,
172
+ )
173
+ titles = titles if not isinstance(titles, str) else [titles]
174
+ texts = texts if not isinstance(texts, str) else [texts]
175
+ n_passages = len(titles)
176
+ questions = questions if not isinstance(questions, str) else [questions] * n_passages
177
+ if len(titles) != len(texts):
178
+ raise ValueError(
179
+ f"There should be as many titles than texts but got {len(titles)} titles and {len(texts)} texts."
180
+ )
181
+ encoded_question_and_titles = super().__call__(questions, titles, padding=False, truncation=False)["input_ids"]
182
+ encoded_texts = super().__call__(texts, add_special_tokens=False, padding=False, truncation=False)["input_ids"]
183
+ encoded_inputs = {
184
+ "input_ids": [
185
+ (encoded_question_and_title + encoded_text)[:max_length]
186
+ if max_length is not None and truncation
187
+ else encoded_question_and_title + encoded_text
188
+ for encoded_question_and_title, encoded_text in zip(encoded_question_and_titles, encoded_texts)
189
+ ]
190
+ }
191
+ if return_attention_mask is not False:
192
+ attention_mask = []
193
+ for input_ids in encoded_inputs["input_ids"]:
194
+ attention_mask.append([int(input_id != self.pad_token_id) for input_id in input_ids])
195
+ encoded_inputs["attention_mask"] = attention_mask
196
+ return self.pad(encoded_inputs, padding=padding, max_length=max_length, return_tensors=return_tensors)
197
+
198
+ def decode_best_spans(
199
+ self,
200
+ reader_input: BatchEncoding,
201
+ reader_output: DPRReaderOutput,
202
+ num_spans: int = 16,
203
+ max_answer_length: int = 64,
204
+ num_spans_per_passage: int = 4,
205
+ ) -> list[DPRSpanPrediction]:
206
+ """
207
+ Get the span predictions for the extractive Q&A model.
208
+
209
+ Returns: *List* of *DPRReaderOutput* sorted by descending *(relevance_score, span_score)*. Each
210
+ *DPRReaderOutput* is a *Tuple* with:
211
+
212
+ - **span_score**: `float` that corresponds to the score given by the reader for this span compared to other
213
+ spans in the same passage. It corresponds to the sum of the start and end logits of the span.
214
+ - **relevance_score**: `float` that corresponds to the score of the each passage to answer the question,
215
+ compared to all the other passages. It corresponds to the output of the QA classifier of the DPRReader.
216
+ - **doc_id**: `int` the id of the passage. - **start_index**: `int` the start index of the span
217
+ (inclusive). - **end_index**: `int` the end index of the span (inclusive).
218
+
219
+ Examples:
220
+
221
+ ```python
222
+ >>> from transformers import DPRReader, DPRReaderTokenizer
223
+
224
+ >>> tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base")
225
+ >>> model = DPRReader.from_pretrained("facebook/dpr-reader-single-nq-base")
226
+ >>> encoded_inputs = tokenizer(
227
+ ... questions=["What is love ?"],
228
+ ... titles=["Haddaway"],
229
+ ... texts=["'What Is Love' is a song recorded by the artist Haddaway"],
230
+ ... return_tensors="pt",
231
+ ... )
232
+ >>> outputs = model(**encoded_inputs)
233
+ >>> predicted_spans = tokenizer.decode_best_spans(encoded_inputs, outputs)
234
+ >>> print(predicted_spans[0].text) # best span
235
+ a song
236
+ ```"""
237
+ input_ids = reader_input["input_ids"]
238
+ start_logits, end_logits, relevance_logits = reader_output[:3]
239
+ n_passages = len(relevance_logits)
240
+ sorted_docs = sorted(range(n_passages), reverse=True, key=relevance_logits.__getitem__)
241
+ nbest_spans_predictions: list[DPRReaderOutput] = []
242
+ for doc_id in sorted_docs:
243
+ sequence_ids = list(input_ids[doc_id])
244
+ # assuming question & title information is at the beginning of the sequence
245
+ passage_offset = sequence_ids.index(self.sep_token_id, 2) + 1 # second sep id
246
+ if sequence_ids[-1] == self.pad_token_id:
247
+ sequence_len = sequence_ids.index(self.pad_token_id)
248
+ else:
249
+ sequence_len = len(sequence_ids)
250
+
251
+ best_spans = self._get_best_spans(
252
+ start_logits=start_logits[doc_id][passage_offset:sequence_len],
253
+ end_logits=end_logits[doc_id][passage_offset:sequence_len],
254
+ max_answer_length=max_answer_length,
255
+ top_spans=num_spans_per_passage,
256
+ )
257
+ for start_index, end_index in best_spans:
258
+ start_index += passage_offset
259
+ end_index += passage_offset
260
+ nbest_spans_predictions.append(
261
+ DPRSpanPrediction(
262
+ span_score=start_logits[doc_id][start_index] + end_logits[doc_id][end_index],
263
+ relevance_score=relevance_logits[doc_id],
264
+ doc_id=doc_id,
265
+ start_index=start_index,
266
+ end_index=end_index,
267
+ text=self.decode(sequence_ids[start_index : end_index + 1]),
268
+ )
269
+ )
270
+ if len(nbest_spans_predictions) >= num_spans:
271
+ break
272
+ return nbest_spans_predictions[:num_spans]
273
+
274
+ def _get_best_spans(
275
+ self,
276
+ start_logits: list[int],
277
+ end_logits: list[int],
278
+ max_answer_length: int,
279
+ top_spans: int,
280
+ ) -> list[DPRSpanPrediction]:
281
+ """
282
+ Finds the best answer span for the extractive Q&A model for one passage. It returns the best span by descending
283
+ `span_score` order and keeping max `top_spans` spans. Spans longer that `max_answer_length` are ignored.
284
+ """
285
+ scores = []
286
+ for start_index, start_score in enumerate(start_logits):
287
+ for answer_length, end_score in enumerate(end_logits[start_index : start_index + max_answer_length]):
288
+ scores.append(((start_index, start_index + answer_length), start_score + end_score))
289
+ scores = sorted(scores, key=lambda x: x[1], reverse=True)
290
+ chosen_span_intervals = []
291
+ for (start_index, end_index), score in scores:
292
+ if start_index > end_index:
293
+ raise ValueError(f"Wrong span indices: [{start_index}:{end_index}]")
294
+ length = end_index - start_index + 1
295
+ if length > max_answer_length:
296
+ raise ValueError(f"Span is too long: {length} > {max_answer_length}")
297
+ if any(
298
+ start_index <= prev_start_index <= prev_end_index <= end_index
299
+ or prev_start_index <= start_index <= end_index <= prev_end_index
300
+ for (prev_start_index, prev_end_index) in chosen_span_intervals
301
+ ):
302
+ continue
303
+ chosen_span_intervals.append((start_index, end_index))
304
+
305
+ if len(chosen_span_intervals) == top_spans:
306
+ break
307
+ return chosen_span_intervals
308
+
309
+
310
+ @add_end_docstrings(CUSTOM_DPR_READER_DOCSTRING)
311
+ class DPRReaderTokenizer(CustomDPRReaderTokenizerMixin, BertTokenizer):
312
+ r"""
313
+ Construct a DPRReader tokenizer.
314
+
315
+ [`DPRReaderTokenizer`] is almost identical to [`BertTokenizer`] and runs end-to-end tokenization: punctuation
316
+ splitting and wordpiece. The difference is that is has three inputs strings: question, titles and texts that are
317
+ combined to be fed to the [`DPRReader`] model.
318
+
319
+ Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning parameters.
320
+ """
321
+
322
+ vocab_files_names = VOCAB_FILES_NAMES
323
+ model_input_names = ["input_ids", "attention_mask"]
324
+
325
+ def __init__(self, *args, do_lower_case=False, **kwargs):
326
+ super().__init__(*args, **kwargs)
327
+ self.do_lower_case = do_lower_case
328
+
329
+
330
+ __all__ = ["DPRContextEncoderTokenizer", "DPRQuestionEncoderTokenizer", "DPRReaderOutput", "DPRReaderTokenizer"]
third_party/transformers/src/transformers/models/dpr/tokenization_dpr_fast.py ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 The HuggingFace Inc. team, The Hugging Face 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
+ """Tokenization classes for DPR."""
15
+
16
+ import collections
17
+
18
+ from ...tokenization_utils_base import BatchEncoding
19
+ from ...utils import TensorType, add_end_docstrings, add_start_docstrings, logging
20
+ from ..bert.tokenization_bert import BertTokenizer
21
+ from .tokenization_dpr import DPRContextEncoderTokenizer, DPRQuestionEncoderTokenizer, DPRReaderTokenizer
22
+
23
+
24
+ logger = logging.get_logger(__name__)
25
+
26
+ VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"}
27
+
28
+
29
+ class DPRContextEncoderTokenizerFast(BertTokenizer):
30
+ r"""
31
+ Construct a "fast" DPRContextEncoder tokenizer (backed by HuggingFace's *tokenizers* library).
32
+
33
+ [`DPRContextEncoderTokenizerFast`] is identical to [`BertTokenizer`] and runs end-to-end tokenization:
34
+ punctuation splitting and wordpiece.
35
+
36
+ Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning parameters.
37
+ """
38
+
39
+ vocab_files_names = VOCAB_FILES_NAMES
40
+ slow_tokenizer_class = DPRContextEncoderTokenizer
41
+
42
+
43
+ class DPRQuestionEncoderTokenizerFast(BertTokenizer):
44
+ r"""
45
+ Constructs a "fast" DPRQuestionEncoder tokenizer (backed by HuggingFace's *tokenizers* library).
46
+
47
+ [`DPRQuestionEncoderTokenizerFast`] is identical to [`BertTokenizer`] and runs end-to-end tokenization:
48
+ punctuation splitting and wordpiece.
49
+
50
+ Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning parameters.
51
+ """
52
+
53
+ vocab_files_names = VOCAB_FILES_NAMES
54
+ slow_tokenizer_class = DPRQuestionEncoderTokenizer
55
+
56
+
57
+ DPRSpanPrediction = collections.namedtuple(
58
+ "DPRSpanPrediction", ["span_score", "relevance_score", "doc_id", "start_index", "end_index", "text"]
59
+ )
60
+
61
+ DPRReaderOutput = collections.namedtuple("DPRReaderOutput", ["start_logits", "end_logits", "relevance_logits"])
62
+
63
+
64
+ CUSTOM_DPR_READER_DOCSTRING = r"""
65
+ Return a dictionary with the token ids of the input strings and other information to give to `.decode_best_spans`.
66
+ It converts the strings of a question and different passages (title and text) in a sequence of IDs (integers),
67
+ using the tokenizer and vocabulary. The resulting `input_ids` is a matrix of size `(n_passages, sequence_length)`
68
+ with the format:
69
+
70
+ [CLS] <question token ids> [SEP] <titles ids> [SEP] <texts ids>
71
+
72
+ Args:
73
+ questions (`str` or `list[str]`):
74
+ The questions to be encoded. You can specify one question for many passages. In this case, the question
75
+ will be duplicated like `[questions] * n_passages`. Otherwise you have to specify as many questions as in
76
+ `titles` or `texts`.
77
+ titles (`str` or `list[str]`):
78
+ The passages titles to be encoded. This can be a string or a list of strings if there are several passages.
79
+ texts (`str` or `list[str]`):
80
+ The passages texts to be encoded. This can be a string or a list of strings if there are several passages.
81
+ padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`):
82
+ Activates and controls padding. Accepts the following values:
83
+
84
+ - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single sequence
85
+ if provided).
86
+ - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum
87
+ acceptable input length for the model if that argument is not provided.
88
+ - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different
89
+ lengths).
90
+ truncation (`bool`, `str` or [`~tokenization_utils_base.TruncationStrategy`], *optional*, defaults to `False`):
91
+ Activates and controls truncation. Accepts the following values:
92
+
93
+ - `True` or `'longest_first'`: Truncate to a maximum length specified with the argument `max_length` or to
94
+ the maximum acceptable input length for the model if that argument is not provided. This will truncate
95
+ token by token, removing a token from the longest sequence in the pair if a pair of sequences (or a batch
96
+ of pairs) is provided.
97
+ - `'only_first'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum
98
+ acceptable input length for the model if that argument is not provided. This will only truncate the first
99
+ sequence of a pair if a pair of sequences (or a batch of pairs) is provided.
100
+ - `'only_second'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum
101
+ acceptable input length for the model if that argument is not provided. This will only truncate the
102
+ second sequence of a pair if a pair of sequences (or a batch of pairs) is provided.
103
+ - `False` or `'do_not_truncate'` (default): No truncation (i.e., can output batch with sequence lengths
104
+ greater than the model maximum admissible input size).
105
+ max_length (`int`, *optional*):
106
+ Controls the maximum length to use by one of the truncation/padding parameters.
107
+
108
+ If left unset or set to `None`, this will use the predefined model maximum length if a maximum length
109
+ is required by one of the truncation/padding parameters. If the model has no specific maximum input
110
+ length (like XLNet) truncation/padding to a maximum length will be deactivated.
111
+ return_tensors (`str` or [`~utils.TensorType`], *optional*):
112
+ If set, will return tensors instead of list of python integers. Acceptable values are:
113
+
114
+ - `'pt'`: Return PyTorch `torch.Tensor` objects.
115
+ - `'np'`: Return Numpy `np.ndarray` objects.
116
+ return_attention_mask (`bool`, *optional*):
117
+ Whether or not to return the attention mask. If not set, will return the attention mask according to the
118
+ specific tokenizer's default, defined by the `return_outputs` attribute.
119
+
120
+ [What are attention masks?](../glossary#attention-mask)
121
+
122
+ Return:
123
+ `dict[str, list[list[int]]]`: A dictionary with the following keys:
124
+
125
+ - `input_ids`: List of token ids to be fed to a model.
126
+ - `attention_mask`: List of indices specifying which tokens should be attended to by the model.
127
+ """
128
+
129
+
130
+ @add_start_docstrings(CUSTOM_DPR_READER_DOCSTRING)
131
+ class CustomDPRReaderTokenizerMixin:
132
+ def __call__(
133
+ self,
134
+ questions,
135
+ titles: str | None = None,
136
+ texts: str | None = None,
137
+ padding: bool | str = False,
138
+ truncation: bool | str = False,
139
+ max_length: int | None = None,
140
+ return_tensors: str | TensorType | None = None,
141
+ return_attention_mask: bool | None = None,
142
+ **kwargs,
143
+ ) -> BatchEncoding:
144
+ if titles is None and texts is None:
145
+ return super().__call__(
146
+ questions,
147
+ padding=padding,
148
+ truncation=truncation,
149
+ max_length=max_length,
150
+ return_tensors=return_tensors,
151
+ return_attention_mask=return_attention_mask,
152
+ **kwargs,
153
+ )
154
+ elif titles is None or texts is None:
155
+ text_pair = titles if texts is None else texts
156
+ return super().__call__(
157
+ questions,
158
+ text_pair,
159
+ padding=padding,
160
+ truncation=truncation,
161
+ max_length=max_length,
162
+ return_tensors=return_tensors,
163
+ return_attention_mask=return_attention_mask,
164
+ **kwargs,
165
+ )
166
+ titles = titles if not isinstance(titles, str) else [titles]
167
+ texts = texts if not isinstance(texts, str) else [texts]
168
+ n_passages = len(titles)
169
+ questions = questions if not isinstance(questions, str) else [questions] * n_passages
170
+ assert len(titles) == len(texts), (
171
+ f"There should be as many titles than texts but got {len(titles)} titles and {len(texts)} texts."
172
+ )
173
+ encoded_question_and_titles = super().__call__(questions, titles, padding=False, truncation=False)["input_ids"]
174
+ encoded_texts = super().__call__(texts, add_special_tokens=False, padding=False, truncation=False)["input_ids"]
175
+ encoded_inputs = {
176
+ "input_ids": [
177
+ (encoded_question_and_title + encoded_text)[:max_length]
178
+ if max_length is not None and truncation
179
+ else encoded_question_and_title + encoded_text
180
+ for encoded_question_and_title, encoded_text in zip(encoded_question_and_titles, encoded_texts)
181
+ ]
182
+ }
183
+ if return_attention_mask is not False:
184
+ attention_mask = []
185
+ for input_ids in encoded_inputs["input_ids"]:
186
+ attention_mask.append([int(input_id != self.pad_token_id) for input_id in input_ids])
187
+ encoded_inputs["attention_mask"] = attention_mask
188
+ return self.pad(encoded_inputs, padding=padding, max_length=max_length, return_tensors=return_tensors)
189
+
190
+ def decode_best_spans(
191
+ self,
192
+ reader_input: BatchEncoding,
193
+ reader_output: DPRReaderOutput,
194
+ num_spans: int = 16,
195
+ max_answer_length: int = 64,
196
+ num_spans_per_passage: int = 4,
197
+ ) -> list[DPRSpanPrediction]:
198
+ """
199
+ Get the span predictions for the extractive Q&A model.
200
+
201
+ Returns: *List* of *DPRReaderOutput* sorted by descending *(relevance_score, span_score)*. Each
202
+ *DPRReaderOutput* is a *Tuple* with:
203
+
204
+ - **span_score**: `float` that corresponds to the score given by the reader for this span compared to other
205
+ spans in the same passage. It corresponds to the sum of the start and end logits of the span.
206
+ - **relevance_score**: `float` that corresponds to the score of the each passage to answer the question,
207
+ compared to all the other passages. It corresponds to the output of the QA classifier of the DPRReader.
208
+ - **doc_id**: `int` the id of the passage. - ***start_index**: `int` the start index of the span
209
+ (inclusive). - **end_index**: `int` the end index of the span (inclusive).
210
+
211
+ Examples:
212
+
213
+ ```python
214
+ >>> from transformers import DPRReader, DPRReaderTokenizer
215
+
216
+ >>> tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base")
217
+ >>> model = DPRReader.from_pretrained("facebook/dpr-reader-single-nq-base")
218
+ >>> encoded_inputs = tokenizer(
219
+ ... questions=["What is love ?"],
220
+ ... titles=["Haddaway"],
221
+ ... texts=["'What Is Love' is a song recorded by the artist Haddaway"],
222
+ ... return_tensors="pt",
223
+ ... )
224
+ >>> outputs = model(**encoded_inputs)
225
+ >>> predicted_spans = tokenizer.decode_best_spans(encoded_inputs, outputs)
226
+ >>> print(predicted_spans[0].text) # best span
227
+ a song
228
+ ```"""
229
+ input_ids = reader_input["input_ids"]
230
+ start_logits, end_logits, relevance_logits = reader_output[:3]
231
+ n_passages = len(relevance_logits)
232
+ sorted_docs = sorted(range(n_passages), reverse=True, key=relevance_logits.__getitem__)
233
+ nbest_spans_predictions: list[DPRReaderOutput] = []
234
+ for doc_id in sorted_docs:
235
+ sequence_ids = list(input_ids[doc_id])
236
+ # assuming question & title information is at the beginning of the sequence
237
+ passage_offset = sequence_ids.index(self.sep_token_id, 2) + 1 # second sep id
238
+ if sequence_ids[-1] == self.pad_token_id:
239
+ sequence_len = sequence_ids.index(self.pad_token_id)
240
+ else:
241
+ sequence_len = len(sequence_ids)
242
+
243
+ best_spans = self._get_best_spans(
244
+ start_logits=start_logits[doc_id][passage_offset:sequence_len],
245
+ end_logits=end_logits[doc_id][passage_offset:sequence_len],
246
+ max_answer_length=max_answer_length,
247
+ top_spans=num_spans_per_passage,
248
+ )
249
+ for start_index, end_index in best_spans:
250
+ start_index += passage_offset
251
+ end_index += passage_offset
252
+ nbest_spans_predictions.append(
253
+ DPRSpanPrediction(
254
+ span_score=start_logits[doc_id][start_index] + end_logits[doc_id][end_index],
255
+ relevance_score=relevance_logits[doc_id],
256
+ doc_id=doc_id,
257
+ start_index=start_index,
258
+ end_index=end_index,
259
+ text=self.decode(sequence_ids[start_index : end_index + 1]),
260
+ )
261
+ )
262
+ if len(nbest_spans_predictions) >= num_spans:
263
+ break
264
+ return nbest_spans_predictions[:num_spans]
265
+
266
+ def _get_best_spans(
267
+ self,
268
+ start_logits: list[int],
269
+ end_logits: list[int],
270
+ max_answer_length: int,
271
+ top_spans: int,
272
+ ) -> list[DPRSpanPrediction]:
273
+ """
274
+ Finds the best answer span for the extractive Q&A model for one passage. It returns the best span by descending
275
+ `span_score` order and keeping max `top_spans` spans. Spans longer that `max_answer_length` are ignored.
276
+ """
277
+ scores = []
278
+ for start_index, start_score in enumerate(start_logits):
279
+ for answer_length, end_score in enumerate(end_logits[start_index : start_index + max_answer_length]):
280
+ scores.append(((start_index, start_index + answer_length), start_score + end_score))
281
+ scores = sorted(scores, key=lambda x: x[1], reverse=True)
282
+ chosen_span_intervals = []
283
+ for (start_index, end_index), score in scores:
284
+ assert start_index <= end_index, f"Wrong span indices: [{start_index}:{end_index}]"
285
+ length = end_index - start_index + 1
286
+ assert length <= max_answer_length, f"Span is too long: {length} > {max_answer_length}"
287
+ if any(
288
+ start_index <= prev_start_index <= prev_end_index <= end_index
289
+ or prev_start_index <= start_index <= end_index <= prev_end_index
290
+ for (prev_start_index, prev_end_index) in chosen_span_intervals
291
+ ):
292
+ continue
293
+ chosen_span_intervals.append((start_index, end_index))
294
+
295
+ if len(chosen_span_intervals) == top_spans:
296
+ break
297
+ return chosen_span_intervals
298
+
299
+
300
+ @add_end_docstrings(CUSTOM_DPR_READER_DOCSTRING)
301
+ class DPRReaderTokenizerFast(CustomDPRReaderTokenizerMixin, BertTokenizer):
302
+ r"""
303
+ Constructs a "fast" DPRReader tokenizer (backed by HuggingFace's *tokenizers* library).
304
+
305
+ [`DPRReaderTokenizerFast`] is almost identical to [`BertTokenizer`] and runs end-to-end tokenization:
306
+ punctuation splitting and wordpiece. The difference is that is has three inputs strings: question, titles and texts
307
+ that are combined to be fed to the [`DPRReader`] model.
308
+
309
+ Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning parameters.
310
+
311
+ """
312
+
313
+ vocab_files_names = VOCAB_FILES_NAMES
314
+ model_input_names = ["input_ids", "attention_mask"]
315
+ slow_tokenizer_class = DPRReaderTokenizer
316
+
317
+
318
+ __all__ = ["DPRContextEncoderTokenizerFast", "DPRQuestionEncoderTokenizerFast", "DPRReaderTokenizerFast"]
third_party/transformers/src/transformers/models/dpt/__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_dpt import *
22
+ from .image_processing_dpt import *
23
+ from .image_processing_pil_dpt import *
24
+ from .modeling_dpt 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/dpt/configuration_dpt.py ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ """DPT 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.configuration_auto import AutoConfig
22
+
23
+
24
+ @auto_docstring(checkpoint="Intel/dpt-large")
25
+ @strict
26
+ class DPTConfig(PreTrainedConfig):
27
+ r"""
28
+ is_hybrid (`bool`, *optional*, defaults to `False`):
29
+ Whether to use a hybrid backbone. Useful in the context of loading DPT-Hybrid models.
30
+ backbone_out_indices (`list[int]`, *optional*, defaults to `[2, 5, 8, 11]`):
31
+ Indices of the intermediate hidden states to use from backbone.
32
+ readout_type (`str`, *optional*, defaults to `"project"`):
33
+ The readout type to use when processing the readout token (CLS token) of the intermediate hidden states of
34
+ the ViT backbone. Can be one of [`"ignore"`, `"add"`, `"project"`].
35
+ - "ignore" simply ignores the CLS token.
36
+ - "add" passes the information from the CLS token to all other tokens by adding the representations.
37
+ - "project" passes information to the other tokens by concatenating the readout to all other tokens before
38
+ projecting the
39
+ representation to the original feature dimension D using a linear layer followed by a GELU non-linearity.
40
+ reassemble_factors (`list[int]`, *optional*, defaults to `[4, 2, 1, 0.5]`):
41
+ The up/downsampling factors of the reassemble layers.
42
+ neck_hidden_sizes (`list[str]`, *optional*, defaults to `[96, 192, 384, 768]`):
43
+ The hidden sizes to project to for the feature maps of the backbone.
44
+ fusion_hidden_size (`int`, *optional*, defaults to 256):
45
+ The number of channels before fusion.
46
+ head_in_index (`int`, *optional*, defaults to -1):
47
+ The index of the features to use in the heads.
48
+ use_batch_norm_in_fusion_residual (`bool`, *optional*, defaults to `False`):
49
+ Whether to use batch normalization in the pre-activate residual units of the fusion blocks.
50
+ use_bias_in_fusion_residual (`bool`, *optional*, defaults to `True`):
51
+ Whether to use bias in the pre-activate residual units of the fusion blocks.
52
+ add_projection (`bool`, *optional*, defaults to `False`):
53
+ Whether to add a projection layer before the depth estimation head.
54
+ use_auxiliary_head (`bool`, *optional*, defaults to `True`):
55
+ Whether to use an auxiliary head during training.
56
+ auxiliary_loss_weight (`float`, *optional*, defaults to 0.4):
57
+ Weight of the cross-entropy loss of the auxiliary head.
58
+ semantic_classifier_dropout (`float`, *optional*, defaults to 0.1):
59
+ The dropout ratio for the semantic classification head.
60
+ backbone_featmap_shape (`list[int]`, *optional*, defaults to `[1, 1024, 24, 24]`):
61
+ Used only for the `hybrid` embedding type. The shape of the feature maps of the backbone.
62
+ neck_ignore_stages (`list[int]`, *optional*, defaults to `[0, 1]`):
63
+ Used only for the `hybrid` embedding type. The stages of the readout layers to ignore.
64
+ pooler_output_size (`int`, *optional*):
65
+ Dimensionality of the pooler layer. If None, defaults to `hidden_size`.
66
+ pooler_act (`str`, *optional*, defaults to `"tanh"`):
67
+ The activation function to be used by the pooler.
68
+
69
+ Example:
70
+
71
+ ```python
72
+ >>> from transformers import DPTModel, DPTConfig
73
+
74
+ >>> # Initializing a DPT dpt-large style configuration
75
+ >>> configuration = DPTConfig()
76
+
77
+ >>> # Initializing a model from the dpt-large style configuration
78
+ >>> model = DPTModel(configuration)
79
+
80
+ >>> # Accessing the model configuration
81
+ >>> configuration = model.config
82
+ ```"""
83
+
84
+ model_type = "dpt"
85
+ sub_configs = {"backbone_config": AutoConfig}
86
+
87
+ # NOTE: some values are typed as `None` on purpose
88
+ # DPT creates one of: backbone or the general model only
89
+ # so official checkpoint saved them as `None`
90
+ hidden_size: int = 768
91
+ num_hidden_layers: None | int = 12
92
+ num_attention_heads: int | None = 12
93
+ intermediate_size: int | None = 3072
94
+ hidden_act: str = "gelu"
95
+ hidden_dropout_prob: float | int | None = 0.0
96
+ attention_probs_dropout_prob: float | int | None = 0.0
97
+ initializer_range: float = 0.02
98
+ layer_norm_eps: float | None = 1e-12
99
+ image_size: int | list[int] | tuple[int, int] | None = 384
100
+ patch_size: int | list[int] | tuple[int, int] | None = 16
101
+ num_channels: int | None = 3
102
+ is_hybrid: bool = False
103
+ qkv_bias: bool | None = True
104
+ backbone_out_indices: list[int] | tuple[int, ...] | None = (2, 5, 8, 11)
105
+ readout_type: str = "project"
106
+ reassemble_factors: list[int | float] | tuple[int | float, ...] = (4, 2, 1, 0.5)
107
+ neck_hidden_sizes: list[int] | tuple[int, ...] = (96, 192, 384, 768)
108
+ fusion_hidden_size: int = 256
109
+ head_in_index: int = -1
110
+ use_batch_norm_in_fusion_residual: bool | None = False
111
+ use_bias_in_fusion_residual: bool | None = None
112
+ add_projection: bool = False
113
+ use_auxiliary_head: bool | None = True
114
+ auxiliary_loss_weight: float = 0.4
115
+ semantic_loss_ignore_index: int = 255
116
+ semantic_classifier_dropout: float | int = 0.1
117
+ backbone_featmap_shape: list[int] | tuple[int, ...] | None = (1, 1024, 24, 24)
118
+ neck_ignore_stages: list[int] | tuple[int, ...] = (0, 1)
119
+ backbone_config: dict | PreTrainedConfig | None = None
120
+ pooler_output_size: int | None = None
121
+ pooler_act: str = "tanh"
122
+
123
+ def __post_init__(self, **kwargs):
124
+ if self.readout_type not in ["ignore", "add", "project"]:
125
+ raise ValueError("Readout_type must be one of ['ignore', 'add', 'project']")
126
+
127
+ if self.is_hybrid:
128
+ if isinstance(self.backbone_config, dict):
129
+ self.backbone_config.setdefault("model_type", "bit")
130
+
131
+ self.backbone_config, kwargs = consolidate_backbone_kwargs_to_config(
132
+ backbone_config=self.backbone_config,
133
+ default_config_type="bit",
134
+ default_config_kwargs={
135
+ "global_padding": "same",
136
+ "layer_type": "bottleneck",
137
+ "depths": [3, 4, 9],
138
+ "out_features": ["stage1", "stage2", "stage3"],
139
+ "embedding_dynamic_padding": True,
140
+ },
141
+ **kwargs,
142
+ )
143
+ if self.readout_type != "project":
144
+ raise ValueError("Readout type must be 'project' when using `DPT-hybrid` mode.")
145
+ elif kwargs.get("backbone") is not None or self.backbone_config is not None:
146
+ self.backbone_config, kwargs = consolidate_backbone_kwargs_to_config(
147
+ backbone_config=self.backbone_config,
148
+ **kwargs,
149
+ )
150
+ self.backbone_out_indices = None
151
+
152
+ self.backbone_featmap_shape = self.backbone_featmap_shape if self.is_hybrid else None
153
+ self.neck_ignore_stages = self.neck_ignore_stages if self.is_hybrid else []
154
+ self.pooler_output_size = self.pooler_output_size if self.pooler_output_size else self.hidden_size
155
+ super().__post_init__(**kwargs)
156
+
157
+
158
+ __all__ = ["DPTConfig"]
third_party/transformers/src/transformers/models/dpt/convert_dinov2_depth_to_hf.py ADDED
@@ -0,0 +1,384 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 DINOv2 + DPT checkpoints from the original repository. URL:
15
+ https://github.com/facebookresearch/dinov2/tree/main"""
16
+
17
+ import argparse
18
+ import itertools
19
+ import math
20
+ from io import BytesIO
21
+ from pathlib import Path
22
+
23
+ import httpx
24
+ import torch
25
+ from PIL import Image
26
+ from torchvision import transforms
27
+
28
+ from transformers import Dinov2Config, DPTConfig, DPTForDepthEstimation, DPTImageProcessor
29
+ from transformers.utils import logging
30
+
31
+
32
+ logging.set_verbosity_info()
33
+ logger = logging.get_logger(__name__)
34
+
35
+
36
+ def get_dpt_config(model_name):
37
+ if "small" in model_name:
38
+ # equivalent to stage 3, stage 6, stage 9, stage 12
39
+ backbone_config = Dinov2Config.from_pretrained(
40
+ "facebook/dinov2-small", out_indices=[3, 6, 9, 12], apply_layernorm=False, reshape_hidden_states=False
41
+ )
42
+ neck_hidden_sizes = [48, 96, 192, 384]
43
+ elif "base" in model_name:
44
+ backbone_config = Dinov2Config.from_pretrained(
45
+ "facebook/dinov2-base", out_indices=[3, 6, 9, 12], apply_layernorm=False, reshape_hidden_states=False
46
+ )
47
+ neck_hidden_sizes = [96, 192, 384, 768]
48
+ elif "large" in model_name:
49
+ backbone_config = Dinov2Config.from_pretrained(
50
+ "facebook/dinov2-large", out_indices=[5, 12, 18, 24], apply_layernorm=False, reshape_hidden_states=False
51
+ )
52
+ neck_hidden_sizes = [128, 256, 512, 1024]
53
+ elif "giant" in model_name:
54
+ backbone_config = Dinov2Config.from_pretrained(
55
+ "facebook/dinov2-giant", out_indices=[10, 20, 30, 40], apply_layernorm=False, reshape_hidden_states=False
56
+ )
57
+ neck_hidden_sizes = [192, 384, 768, 1536]
58
+ else:
59
+ raise NotImplementedError("To do")
60
+
61
+ config = DPTConfig(
62
+ backbone_config=backbone_config,
63
+ neck_hidden_sizes=neck_hidden_sizes,
64
+ use_bias_in_fusion_residual=False,
65
+ add_projection=True,
66
+ )
67
+
68
+ return config
69
+
70
+
71
+ # here we list all DPT keys to be renamed (original name on the left, our name on the right)
72
+ def create_rename_keys_dpt(config):
73
+ rename_keys = []
74
+
75
+ # fmt: off
76
+ # activation postprocessing (projections, readout projections + resize blocks)
77
+ for i in range(4):
78
+ rename_keys.append((f"decode_head.reassemble_blocks.projects.{i}.conv.weight", f"neck.reassemble_stage.layers.{i}.projection.weight"))
79
+ rename_keys.append((f"decode_head.reassemble_blocks.projects.{i}.conv.bias", f"neck.reassemble_stage.layers.{i}.projection.bias"))
80
+
81
+ rename_keys.append((f"decode_head.reassemble_blocks.readout_projects.{i}.0.weight", f"neck.reassemble_stage.readout_projects.{i}.0.weight"))
82
+ rename_keys.append((f"decode_head.reassemble_blocks.readout_projects.{i}.0.bias", f"neck.reassemble_stage.readout_projects.{i}.0.bias"))
83
+
84
+ if i != 2:
85
+ rename_keys.append((f"decode_head.reassemble_blocks.resize_layers.{i}.weight", f"neck.reassemble_stage.layers.{i}.resize.weight"))
86
+ rename_keys.append((f"decode_head.reassemble_blocks.resize_layers.{i}.bias", f"neck.reassemble_stage.layers.{i}.resize.bias"))
87
+
88
+ # fusion layers
89
+ for i in range(4):
90
+ rename_keys.append((f"decode_head.fusion_blocks.{i}.project.conv.weight", f"neck.fusion_stage.layers.{i}.projection.weight"))
91
+ rename_keys.append((f"decode_head.fusion_blocks.{i}.project.conv.bias", f"neck.fusion_stage.layers.{i}.projection.bias"))
92
+ if i != 0:
93
+ rename_keys.append((f"decode_head.fusion_blocks.{i}.res_conv_unit1.conv1.conv.weight", f"neck.fusion_stage.layers.{i}.residual_layer1.convolution1.weight"))
94
+ rename_keys.append((f"decode_head.fusion_blocks.{i}.res_conv_unit1.conv2.conv.weight", f"neck.fusion_stage.layers.{i}.residual_layer1.convolution2.weight"))
95
+ rename_keys.append((f"decode_head.fusion_blocks.{i}.res_conv_unit2.conv1.conv.weight", f"neck.fusion_stage.layers.{i}.residual_layer2.convolution1.weight"))
96
+ rename_keys.append((f"decode_head.fusion_blocks.{i}.res_conv_unit2.conv2.conv.weight", f"neck.fusion_stage.layers.{i}.residual_layer2.convolution2.weight"))
97
+
98
+ # neck convolutions
99
+ for i in range(4):
100
+ rename_keys.append((f"decode_head.convs.{i}.conv.weight", f"neck.convs.{i}.weight"))
101
+
102
+ # head
103
+ rename_keys.append(("decode_head.project.conv.weight", "head.projection.weight"))
104
+ rename_keys.append(("decode_head.project.conv.bias", "head.projection.bias"))
105
+
106
+ for i in range(0, 5, 2):
107
+ rename_keys.append((f"decode_head.conv_depth.head.{i}.weight", f"head.head.{i}.weight"))
108
+ rename_keys.append((f"decode_head.conv_depth.head.{i}.bias", f"head.head.{i}.bias"))
109
+ # fmt: on
110
+
111
+ return rename_keys
112
+
113
+
114
+ # here we list all backbone keys to be renamed (original name on the left, our name on the right)
115
+ def create_rename_keys_backbone(config):
116
+ rename_keys = []
117
+
118
+ # fmt: off
119
+ # patch embedding layer
120
+ rename_keys.append(("cls_token", "backbone.embeddings.cls_token"))
121
+ rename_keys.append(("mask_token", "backbone.embeddings.mask_token"))
122
+ rename_keys.append(("pos_embed", "backbone.embeddings.position_embeddings"))
123
+ rename_keys.append(("patch_embed.proj.weight", "backbone.embeddings.patch_embeddings.projection.weight"))
124
+ rename_keys.append(("patch_embed.proj.bias", "backbone.embeddings.patch_embeddings.projection.bias"))
125
+
126
+ # Transformer encoder
127
+ for i in range(config.backbone_config.num_hidden_layers):
128
+ # layernorms
129
+ rename_keys.append((f"blocks.{i}.norm1.weight", f"backbone.encoder.layer.{i}.norm1.weight"))
130
+ rename_keys.append((f"blocks.{i}.norm1.bias", f"backbone.encoder.layer.{i}.norm1.bias"))
131
+ rename_keys.append((f"blocks.{i}.norm2.weight", f"backbone.encoder.layer.{i}.norm2.weight"))
132
+ rename_keys.append((f"blocks.{i}.norm2.bias", f"backbone.encoder.layer.{i}.norm2.bias"))
133
+ # MLP
134
+ if config.backbone_config.use_swiglu_ffn:
135
+ rename_keys.append((f"blocks.{i}.mlp.w12.weight", f"backbone.encoder.layer.{i}.mlp.w12.weight"))
136
+ rename_keys.append((f"blocks.{i}.mlp.w12.bias", f"backbone.encoder.layer.{i}.mlp.w12.bias"))
137
+ rename_keys.append((f"blocks.{i}.mlp.w3.weight", f"backbone.encoder.layer.{i}.mlp.w3.weight"))
138
+ rename_keys.append((f"blocks.{i}.mlp.w3.bias", f"backbone.encoder.layer.{i}.mlp.w3.bias"))
139
+ else:
140
+ rename_keys.append((f"blocks.{i}.mlp.fc1.weight", f"backbone.encoder.layer.{i}.mlp.fc1.weight"))
141
+ rename_keys.append((f"blocks.{i}.mlp.fc1.bias", f"backbone.encoder.layer.{i}.mlp.fc1.bias"))
142
+ rename_keys.append((f"blocks.{i}.mlp.fc2.weight", f"backbone.encoder.layer.{i}.mlp.fc2.weight"))
143
+ rename_keys.append((f"blocks.{i}.mlp.fc2.bias", f"backbone.encoder.layer.{i}.mlp.fc2.bias"))
144
+ # layerscale
145
+ rename_keys.append((f"blocks.{i}.ls1.gamma", f"backbone.encoder.layer.{i}.layer_scale1.lambda1"))
146
+ rename_keys.append((f"blocks.{i}.ls2.gamma", f"backbone.encoder.layer.{i}.layer_scale2.lambda1"))
147
+ # attention projection layer
148
+ rename_keys.append((f"blocks.{i}.attn.proj.weight", f"backbone.encoder.layer.{i}.attention.output.dense.weight"))
149
+ rename_keys.append((f"blocks.{i}.attn.proj.bias", f"backbone.encoder.layer.{i}.attention.output.dense.bias"))
150
+ # fmt: on
151
+
152
+ rename_keys.append(("norm.weight", "backbone.layernorm.weight"))
153
+ rename_keys.append(("norm.bias", "backbone.layernorm.bias"))
154
+
155
+ return rename_keys
156
+
157
+
158
+ # we split up the matrix of each encoder layer into queries, keys and values
159
+ def read_in_q_k_v(state_dict, config):
160
+ for i in range(config.backbone_config.num_hidden_layers):
161
+ # read in weights + bias of input projection layer (in timm, this is a single matrix + bias)
162
+ in_proj_weight = state_dict.pop(f"blocks.{i}.attn.qkv.weight")
163
+ in_proj_bias = state_dict.pop(f"blocks.{i}.attn.qkv.bias")
164
+ hidden_size = config.backbone_config.hidden_size
165
+ # next, add query, keys and values (in that order) to the state dict
166
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[:hidden_size, :]
167
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.query.bias"] = in_proj_bias[:hidden_size]
168
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[
169
+ hidden_size : hidden_size * 2, :
170
+ ]
171
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.key.bias"] = in_proj_bias[
172
+ hidden_size : hidden_size * 2
173
+ ]
174
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[-hidden_size:, :]
175
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.value.bias"] = in_proj_bias[-hidden_size:]
176
+
177
+
178
+ def rename_key(dct, old, new):
179
+ val = dct.pop(old)
180
+ dct[new] = val
181
+
182
+
183
+ # We will verify our results on an image of cute cats
184
+ def prepare_img():
185
+ url = "https://dl.fbaipublicfiles.com/dinov2/images/example.jpg"
186
+ with httpx.stream("GET", url) as response:
187
+ image = Image.open(BytesIO(response.read()))
188
+ return image
189
+
190
+
191
+ name_to_url = {
192
+ "dpt-dinov2-small-nyu": "https://dl.fbaipublicfiles.com/dinov2/dinov2_vits14/dinov2_vits14_nyu_dpt_head.pth",
193
+ "dpt-dinov2-small-kitti": "https://dl.fbaipublicfiles.com/dinov2/dinov2_vits14/dinov2_vits14_kitti_dpt_head.pth",
194
+ "dpt-dinov2-base-nyu": "https://dl.fbaipublicfiles.com/dinov2/dinov2_vitb14/dinov2_vitb14_nyu_dpt_head.pth",
195
+ "dpt-dinov2-base-kitti": "https://dl.fbaipublicfiles.com/dinov2/dinov2_vitb14/dinov2_vitb14_kitti_dpt_head.pth",
196
+ "dpt-dinov2-large-nyu": "https://dl.fbaipublicfiles.com/dinov2/dinov2_vitl14/dinov2_vitl14_nyu_dpt_head.pth",
197
+ "dpt-dinov2-large-kitti": "https://dl.fbaipublicfiles.com/dinov2/dinov2_vitl14/dinov2_vitl14_kitti_dpt_head.pth",
198
+ "dpt-dinov2-giant-nyu": "https://dl.fbaipublicfiles.com/dinov2/dinov2_vitg14/dinov2_vitg14_nyu_dpt_head.pth",
199
+ "dpt-dinov2-giant-kitti": "https://dl.fbaipublicfiles.com/dinov2/dinov2_vitg14/dinov2_vitg14_kitti_dpt_head.pth",
200
+ }
201
+
202
+
203
+ def get_original_pixel_values(image):
204
+ class CenterPadding:
205
+ def __init__(self, multiple):
206
+ super().__init__()
207
+ self.multiple = multiple
208
+
209
+ def _get_pad(self, size):
210
+ new_size = math.ceil(size / self.multiple) * self.multiple
211
+ pad_size = new_size - size
212
+ pad_size_left = pad_size // 2
213
+ pad_size_right = pad_size - pad_size_left
214
+ return pad_size_left, pad_size_right
215
+
216
+ def __call__(self, img):
217
+ pads = list(itertools.chain.from_iterable(self._get_pad(m) for m in img.shape[-2:][::-1]))
218
+ output = torch.nn.functional.pad(img, pads)
219
+ return output
220
+
221
+ def __repr__(self):
222
+ return self.__class__.__name__ + "()"
223
+
224
+ def make_depth_transform() -> transforms.Compose:
225
+ return transforms.Compose(
226
+ [
227
+ transforms.ToTensor(),
228
+ lambda x: 255.0 * x[:3], # Discard alpha component and scale by 255
229
+ transforms.Normalize(
230
+ mean=(123.675, 116.28, 103.53),
231
+ std=(58.395, 57.12, 57.375),
232
+ ),
233
+ CenterPadding(multiple=14),
234
+ ]
235
+ )
236
+
237
+ transform = make_depth_transform()
238
+ original_pixel_values = transform(image).unsqueeze(0)
239
+
240
+ return original_pixel_values
241
+
242
+
243
+ @torch.no_grad()
244
+ def convert_dpt_checkpoint(model_name, pytorch_dump_folder_path, push_to_hub, verify_logits):
245
+ """
246
+ Copy/paste/tweak model's weights to our DPT structure.
247
+ """
248
+
249
+ # define DPT configuration based on URL
250
+ checkpoint_url = name_to_url[model_name]
251
+ config = get_dpt_config(model_name)
252
+
253
+ # load original DPT state_dict from URL
254
+ print("URL:", checkpoint_url)
255
+ dpt_state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu")["state_dict"]
256
+ # rename keys
257
+ rename_keys = create_rename_keys_dpt(config)
258
+ for src, dest in rename_keys:
259
+ rename_key(dpt_state_dict, src, dest)
260
+
261
+ # load original backbone state_dict from URL
262
+ if "small" in model_name:
263
+ original_model = torch.hub.load("facebookresearch/dinov2", "dinov2_vits14")
264
+ elif "base" in model_name:
265
+ original_model = torch.hub.load("facebookresearch/dinov2", "dinov2_vitb14")
266
+ elif "large" in model_name:
267
+ original_model = torch.hub.load("facebookresearch/dinov2", "dinov2_vitl14")
268
+ elif "giant" in model_name:
269
+ original_model = torch.hub.load("facebookresearch/dinov2", "dinov2_vitg14")
270
+ else:
271
+ raise NotImplementedError("To do")
272
+ original_model.eval()
273
+ backbone_state_dict = original_model.state_dict()
274
+
275
+ # rename keys
276
+ rename_keys = create_rename_keys_backbone(config)
277
+ for src, dest in rename_keys:
278
+ rename_key(backbone_state_dict, src, dest)
279
+
280
+ # read in qkv matrices
281
+ read_in_q_k_v(backbone_state_dict, config)
282
+
283
+ for key, val in backbone_state_dict.copy().items():
284
+ val = backbone_state_dict.pop(key)
285
+ if "w12" in key:
286
+ key = key.replace("w12", "weights_in")
287
+ if "w3" in key:
288
+ key = key.replace("w3", "weights_out")
289
+ backbone_state_dict[key] = val
290
+
291
+ # merge state_dicts
292
+ state_dict = {**backbone_state_dict, **dpt_state_dict}
293
+
294
+ # load HuggingFace model
295
+ model = DPTForDepthEstimation(config)
296
+ missing_keys, unexpected_keys = model.load_state_dict(state_dict, strict=False)
297
+ print("Missing keys:", missing_keys)
298
+ print("Unexpected keys:", unexpected_keys)
299
+ assert missing_keys == [
300
+ "neck.fusion_stage.layers.0.residual_layer1.convolution1.weight",
301
+ "neck.fusion_stage.layers.0.residual_layer1.convolution2.weight",
302
+ ]
303
+ model.eval()
304
+
305
+ # Verify image processor
306
+ processor = DPTImageProcessor(
307
+ do_resize=False,
308
+ do_rescale=False,
309
+ do_pad=True,
310
+ size_divisor=14,
311
+ do_normalize=True,
312
+ image_mean=(123.675, 116.28, 103.53),
313
+ image_std=(58.395, 57.12, 57.375),
314
+ )
315
+
316
+ image = prepare_img()
317
+ pixel_values = processor(image, return_tensors="pt").pixel_values.float()
318
+ original_pixel_values = get_original_pixel_values(image)
319
+
320
+ assert torch.allclose(pixel_values, original_pixel_values)
321
+
322
+ # Verify forward pass
323
+ with torch.no_grad():
324
+ outputs = model(pixel_values)
325
+
326
+ predicted_depth = outputs.predicted_depth
327
+
328
+ print("Shape of predicted depth:", predicted_depth.shape)
329
+ print("First values of predicted depth:", predicted_depth[0, :3, :3])
330
+
331
+ # assert logits
332
+ if verify_logits:
333
+ if model_name == "dpt-dinov2-small-nyu":
334
+ expected_shape = torch.Size([1, 576, 736])
335
+ expected_slice = torch.tensor(
336
+ [[3.3576, 3.4741, 3.4345], [3.4324, 3.5012, 3.2775], [3.2560, 3.3563, 3.2354]]
337
+ )
338
+
339
+ assert predicted_depth.shape == torch.Size(expected_shape)
340
+ assert torch.allclose(predicted_depth[0, :3, :3], expected_slice, atol=1e-5)
341
+ print("Looks ok!")
342
+
343
+ if pytorch_dump_folder_path is not None:
344
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
345
+ print(f"Saving model and processor to {pytorch_dump_folder_path}")
346
+ model.save_pretrained(pytorch_dump_folder_path)
347
+ processor.save_pretrained(pytorch_dump_folder_path)
348
+
349
+ if push_to_hub:
350
+ print("Pushing model and processor to hub...")
351
+ model.push_to_hub(repo_id=f"facebook/{model_name}")
352
+ processor.push_to_hub(repo_id=f"facebook/{model_name}")
353
+
354
+
355
+ if __name__ == "__main__":
356
+ parser = argparse.ArgumentParser()
357
+ # Required parameters
358
+ parser.add_argument(
359
+ "--model_name",
360
+ default="dpt-dinov2-small-nyu",
361
+ type=str,
362
+ choices=name_to_url.keys(),
363
+ help="Name of the model you'd like to convert.",
364
+ )
365
+ parser.add_argument(
366
+ "--pytorch_dump_folder_path",
367
+ default=None,
368
+ type=str,
369
+ help="Path to the output PyTorch model directory.",
370
+ )
371
+ parser.add_argument(
372
+ "--push_to_hub",
373
+ action="store_true",
374
+ help="Whether to push the model to the hub after conversion.",
375
+ )
376
+ parser.add_argument(
377
+ "--verify_logits",
378
+ action="store_true",
379
+ required=False,
380
+ help="Path to the output PyTorch model directory.",
381
+ )
382
+
383
+ args = parser.parse_args()
384
+ convert_dpt_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub, args.verify_logits)
third_party/transformers/src/transformers/models/dpt/convert_dpt_beit_to_hf.py ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 DPT 3.1 checkpoints from the MiDaS repository. URL: https://github.com/isl-org/MiDaS"""
15
+
16
+ import argparse
17
+ from io import BytesIO
18
+ from pathlib import Path
19
+
20
+ import httpx
21
+ import torch
22
+ from PIL import Image
23
+
24
+ from transformers import BeitConfig, DPTConfig, DPTForDepthEstimation, DPTImageProcessor
25
+ from transformers.utils import logging
26
+
27
+
28
+ logging.set_verbosity_info()
29
+ logger = logging.get_logger(__name__)
30
+
31
+
32
+ def get_dpt_config(model_name):
33
+ hidden_size = 768
34
+ num_hidden_layers = 12
35
+ num_attention_heads = 12
36
+ intermediate_size = 3072
37
+ out_features = ["stage3", "stage6", "stage9", "stage12"] # beit-base-384 uses [2, 5, 8, 11]
38
+
39
+ if "large" in model_name:
40
+ hidden_size = 1024
41
+ num_hidden_layers = 24
42
+ num_attention_heads = 16
43
+ intermediate_size = 4096
44
+ out_features = ["stage6", "stage12", "stage18", "stage24"] # beit-large-512 uses [5, 11, 17, 23]
45
+
46
+ if "512" in model_name:
47
+ image_size = 512
48
+ elif "384" in model_name:
49
+ image_size = 384
50
+ else:
51
+ raise ValueError("Model not supported")
52
+
53
+ backbone_config = BeitConfig(
54
+ image_size=image_size,
55
+ num_hidden_layers=num_hidden_layers,
56
+ hidden_size=hidden_size,
57
+ intermediate_size=intermediate_size,
58
+ num_attention_heads=num_attention_heads,
59
+ use_relative_position_bias=True,
60
+ reshape_hidden_states=False,
61
+ out_features=out_features,
62
+ )
63
+
64
+ neck_hidden_sizes = [256, 512, 1024, 1024] if "large" in model_name else [96, 192, 384, 768]
65
+ config = DPTConfig(backbone_config=backbone_config, neck_hidden_sizes=neck_hidden_sizes)
66
+
67
+ return config, image_size
68
+
69
+
70
+ # here we list all keys to be renamed (original name on the left, our name on the right)
71
+ def create_rename_keys(config):
72
+ rename_keys = []
73
+
74
+ # fmt: off
75
+ # stem
76
+ rename_keys.append(("pretrained.model.cls_token", "backbone.embeddings.cls_token"))
77
+ rename_keys.append(("pretrained.model.patch_embed.proj.weight", "backbone.embeddings.patch_embeddings.projection.weight"))
78
+ rename_keys.append(("pretrained.model.patch_embed.proj.bias", "backbone.embeddings.patch_embeddings.projection.bias"))
79
+
80
+ # Transformer encoder
81
+ for i in range(config.backbone_config.num_hidden_layers):
82
+ rename_keys.append((f"pretrained.model.blocks.{i}.gamma_1", f"backbone.encoder.layer.{i}.lambda_1"))
83
+ rename_keys.append((f"pretrained.model.blocks.{i}.gamma_2", f"backbone.encoder.layer.{i}.lambda_2"))
84
+ rename_keys.append((f"pretrained.model.blocks.{i}.norm1.weight", f"backbone.encoder.layer.{i}.layernorm_before.weight"))
85
+ rename_keys.append((f"pretrained.model.blocks.{i}.norm1.bias", f"backbone.encoder.layer.{i}.layernorm_before.bias"))
86
+ rename_keys.append((f"pretrained.model.blocks.{i}.norm2.weight", f"backbone.encoder.layer.{i}.layernorm_after.weight"))
87
+ rename_keys.append((f"pretrained.model.blocks.{i}.norm2.bias", f"backbone.encoder.layer.{i}.layernorm_after.bias"))
88
+ rename_keys.append((f"pretrained.model.blocks.{i}.mlp.fc1.weight", f"backbone.encoder.layer.{i}.intermediate.dense.weight"))
89
+ rename_keys.append((f"pretrained.model.blocks.{i}.mlp.fc1.bias", f"backbone.encoder.layer.{i}.intermediate.dense.bias"))
90
+ rename_keys.append((f"pretrained.model.blocks.{i}.mlp.fc2.weight", f"backbone.encoder.layer.{i}.output.dense.weight"))
91
+ rename_keys.append((f"pretrained.model.blocks.{i}.mlp.fc2.bias", f"backbone.encoder.layer.{i}.output.dense.bias"))
92
+ rename_keys.append((f"pretrained.model.blocks.{i}.attn.proj.weight", f"backbone.encoder.layer.{i}.attention.output.dense.weight"))
93
+ rename_keys.append((f"pretrained.model.blocks.{i}.attn.proj.bias", f"backbone.encoder.layer.{i}.attention.output.dense.bias"))
94
+ rename_keys.append((f"pretrained.model.blocks.{i}.attn.relative_position_bias_table", f"backbone.encoder.layer.{i}.attention.attention.relative_position_bias.relative_position_bias_table"))
95
+ rename_keys.append((f"pretrained.model.blocks.{i}.attn.relative_position_index", f"backbone.encoder.layer.{i}.attention.attention.relative_position_bias.relative_position_index"))
96
+
97
+ # activation postprocessing (readout projections + resize blocks)
98
+ for i in range(4):
99
+ rename_keys.append((f"pretrained.act_postprocess{i+1}.0.project.0.weight", f"neck.reassemble_stage.readout_projects.{i}.0.weight"))
100
+ rename_keys.append((f"pretrained.act_postprocess{i+1}.0.project.0.bias", f"neck.reassemble_stage.readout_projects.{i}.0.bias"))
101
+
102
+ rename_keys.append((f"pretrained.act_postprocess{i+1}.3.weight", f"neck.reassemble_stage.layers.{i}.projection.weight"))
103
+ rename_keys.append((f"pretrained.act_postprocess{i+1}.3.bias", f"neck.reassemble_stage.layers.{i}.projection.bias"))
104
+
105
+ if i != 2:
106
+ rename_keys.append((f"pretrained.act_postprocess{i+1}.4.weight", f"neck.reassemble_stage.layers.{i}.resize.weight"))
107
+ rename_keys.append((f"pretrained.act_postprocess{i+1}.4.bias", f"neck.reassemble_stage.layers.{i}.resize.bias"))
108
+
109
+ # refinenet (tricky here)
110
+ mapping = {1:3, 2:2, 3:1, 4:0}
111
+
112
+ for i in range(1, 5):
113
+ j = mapping[i]
114
+ rename_keys.append((f"scratch.refinenet{i}.out_conv.weight", f"neck.fusion_stage.layers.{j}.projection.weight"))
115
+ rename_keys.append((f"scratch.refinenet{i}.out_conv.bias", f"neck.fusion_stage.layers.{j}.projection.bias"))
116
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit1.conv1.weight", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution1.weight"))
117
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit1.conv1.bias", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution1.bias"))
118
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit1.conv2.weight", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution2.weight"))
119
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit1.conv2.bias", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution2.bias"))
120
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit2.conv1.weight", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution1.weight"))
121
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit2.conv1.bias", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution1.bias"))
122
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit2.conv2.weight", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution2.weight"))
123
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit2.conv2.bias", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution2.bias"))
124
+
125
+ # scratch convolutions
126
+ for i in range(4):
127
+ rename_keys.append((f"scratch.layer{i+1}_rn.weight", f"neck.convs.{i}.weight"))
128
+
129
+ # head
130
+ for i in range(0, 5, 2):
131
+ rename_keys.append((f"scratch.output_conv.{i}.weight", f"head.head.{i}.weight"))
132
+ rename_keys.append((f"scratch.output_conv.{i}.bias", f"head.head.{i}.bias"))
133
+
134
+ return rename_keys
135
+
136
+
137
+ def remove_ignore_keys_(state_dict):
138
+ ignore_keys = ["pretrained.model.head.weight", "pretrained.model.head.bias"]
139
+ for k in ignore_keys:
140
+ state_dict.pop(k, None)
141
+
142
+
143
+ # we split up the matrix of each encoder layer into queries, keys and values
144
+ def read_in_q_k_v(state_dict, config):
145
+ hidden_size = config.backbone_config.hidden_size
146
+ for i in range(config.backbone_config.num_hidden_layers):
147
+ # read in weights + bias of input projection layer (in original implementation, this is a single matrix + bias)
148
+ in_proj_weight = state_dict.pop(f"pretrained.model.blocks.{i}.attn.qkv.weight")
149
+ q_bias = state_dict.pop(f"pretrained.model.blocks.{i}.attn.q_bias")
150
+ v_bias = state_dict.pop(f"pretrained.model.blocks.{i}.attn.v_bias")
151
+ # next, add query, keys and values (in that order) to the state dict
152
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[:hidden_size, :]
153
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.query.bias"] = q_bias
154
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[
155
+ hidden_size : hidden_size * 2, :
156
+ ]
157
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[-hidden_size:, :]
158
+ state_dict[f"backbone.encoder.layer.{i}.attention.attention.value.bias"] = v_bias
159
+
160
+
161
+ def rename_key(dct, old, new):
162
+ val = dct.pop(old)
163
+ dct[new] = val
164
+
165
+
166
+ # We will verify our results on an image of cute cats
167
+ def prepare_img():
168
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
169
+ with httpx.stream("GET", url) as response:
170
+ image = Image.open(BytesIO(response.read()))
171
+ return image
172
+
173
+
174
+ @torch.no_grad()
175
+ def convert_dpt_checkpoint(model_name, pytorch_dump_folder_path, push_to_hub):
176
+ """
177
+ Copy/paste/tweak model's weights to our DPT structure.
178
+ """
179
+
180
+ name_to_url = {
181
+ "dpt-beit-large-512": "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_512.pt",
182
+ "dpt-beit-large-384": "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_384.pt",
183
+ "dpt-beit-base-384": "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_base_384.pt",
184
+ }
185
+
186
+ # define DPT configuration based on URL
187
+ checkpoint_url = name_to_url[model_name]
188
+ config, image_size = get_dpt_config(model_name)
189
+ # load original state_dict from URL
190
+ state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu")
191
+ # remove certain keys
192
+ remove_ignore_keys_(state_dict)
193
+ # rename keys
194
+ rename_keys = create_rename_keys(config)
195
+ for src, dest in rename_keys:
196
+ rename_key(state_dict, src, dest)
197
+ # read in qkv matrices
198
+ read_in_q_k_v(state_dict, config)
199
+
200
+ # load HuggingFace model
201
+ model = DPTForDepthEstimation(config)
202
+ missing_keys, unexpected_keys = model.load_state_dict(state_dict, strict=False)
203
+ print("Missing keys:", missing_keys)
204
+ print("Unexpected keys:", unexpected_keys)
205
+ assert missing_keys == []
206
+ # assert unexpected_keys == ["pretrained.model.fc_norm.weight", "pretrained.model.fc_norm.bias"]
207
+ model.eval()
208
+
209
+ # Check outputs on an image
210
+ # We set `keep_aspect_ratio=False` as our current BEiT does not support arbitrary window sizes
211
+ processor = DPTImageProcessor(
212
+ size={"height": image_size, "width": image_size}, keep_aspect_ratio=False, ensure_multiple_of=32
213
+ )
214
+
215
+ image = prepare_img()
216
+ pixel_values = processor(image, return_tensors="pt").pixel_values
217
+
218
+ print("First values of pixel values:", pixel_values[0, 0, :3, :3])
219
+ print("Mean of pixel values:", pixel_values.mean().item())
220
+ print("Shape of pixel values:", pixel_values.shape)
221
+
222
+ from PIL import Image
223
+ from torchvision import transforms
224
+
225
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
226
+ with httpx.stream("GET", url) as response:
227
+ image = Image.open(BytesIO(response.read()))
228
+
229
+ transforms = transforms.Compose(
230
+ [
231
+ transforms.Resize((image_size, image_size)),
232
+ transforms.ToTensor(),
233
+ ]
234
+ )
235
+ pixel_values = transforms(image).unsqueeze(0)
236
+
237
+ # forward pass
238
+ with torch.no_grad():
239
+ outputs = model(pixel_values)
240
+
241
+ predicted_depth = outputs.predicted_depth
242
+
243
+ print("Shape of predicted depth:", predicted_depth.shape)
244
+ print("First values of predicted depth:", predicted_depth[0, :3, :3])
245
+
246
+ # assert logits
247
+ # TODO there's still a small difference with the original logits
248
+ if model_name == "dpt-beit-large-512":
249
+ # OK, checked
250
+ expected_shape = torch.Size([1, 512, 512])
251
+ expected_slice = torch.tensor(
252
+ [[2804.6260, 2792.5708, 2812.9263], [2772.0288, 2780.1118, 2796.2529], [2748.1094, 2766.6558, 2766.9834]]
253
+ )
254
+ elif model_name == "dpt-beit-large-384":
255
+ # OK, checked
256
+ expected_shape = torch.Size([1, 384, 384])
257
+ expected_slice = torch.tensor(
258
+ [[1783.2273, 1780.5729, 1792.6453], [1759.9817, 1765.5359, 1778.5002], [1739.1633, 1754.7903, 1757.1990]],
259
+ )
260
+ elif model_name == "dpt-beit-base-384":
261
+ # OK, checked
262
+ expected_shape = torch.Size([1, 384, 384])
263
+ expected_slice = torch.tensor(
264
+ [[2898.4482, 2891.3750, 2904.8079], [2858.6685, 2877.2615, 2894.4507], [2842.1235, 2854.1023, 2861.6328]],
265
+ )
266
+
267
+ assert predicted_depth.shape == torch.Size(expected_shape)
268
+ assert torch.allclose(predicted_depth[0, :3, :3], expected_slice)
269
+ print("Looks ok!")
270
+
271
+ if pytorch_dump_folder_path is not None:
272
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
273
+ print(f"Saving model and processor to {pytorch_dump_folder_path}")
274
+ model.save_pretrained(pytorch_dump_folder_path)
275
+ processor.save_pretrained(pytorch_dump_folder_path)
276
+
277
+ if push_to_hub:
278
+ print("Pushing model and processor to hub...")
279
+ model.push_to_hub(repo_id=f"nielsr/{model_name}")
280
+ processor.push_to_hub(repo_id=f"nielsr/{model_name}")
281
+
282
+
283
+ if __name__ == "__main__":
284
+ parser = argparse.ArgumentParser()
285
+ # Required parameters
286
+ parser.add_argument(
287
+ "--model_name",
288
+ default="dpt-beit-large-512",
289
+ type=str,
290
+ choices=["dpt-beit-large-512", "dpt-beit-large-384", "dpt-beit-base-384"],
291
+ help="Name of the model you'd like to convert.",
292
+ )
293
+ parser.add_argument(
294
+ "--pytorch_dump_folder_path",
295
+ default=None,
296
+ type=str,
297
+ help="Path to the output PyTorch model directory.",
298
+ )
299
+ parser.add_argument(
300
+ "--push_to_hub",
301
+ action="store_true",
302
+ help="Whether to push the model to the hub after conversion.",
303
+ )
304
+
305
+ args = parser.parse_args()
306
+ convert_dpt_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)
third_party/transformers/src/transformers/models/dpt/convert_dpt_hybrid_to_pytorch.py ADDED
@@ -0,0 +1,316 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 DPT checkpoints from the original repository. URL: https://github.com/isl-org/DPT"""
15
+
16
+ import argparse
17
+ import json
18
+ from io import BytesIO
19
+ from pathlib import Path
20
+
21
+ import httpx
22
+ import torch
23
+ from huggingface_hub import hf_hub_download
24
+ from PIL import Image
25
+
26
+ from transformers import DPTConfig, DPTForDepthEstimation, DPTForSemanticSegmentation, DPTImageProcessor
27
+ from transformers.utils import logging
28
+
29
+
30
+ logging.set_verbosity_info()
31
+ logger = logging.get_logger(__name__)
32
+
33
+
34
+ def get_dpt_config(checkpoint_url):
35
+ config = DPTConfig(embedding_type="hybrid")
36
+
37
+ if "large" in checkpoint_url:
38
+ config.hidden_size = 1024
39
+ config.intermediate_size = 4096
40
+ config.num_hidden_layers = 24
41
+ config.num_attention_heads = 16
42
+ config.backbone_out_indices = [5, 11, 17, 23]
43
+ config.neck_hidden_sizes = [256, 512, 1024, 1024]
44
+ expected_shape = (1, 384, 384)
45
+
46
+ if "nyu" in checkpoint_url or "midas" in checkpoint_url:
47
+ config.hidden_size = 768
48
+ config.reassemble_factors = [1, 1, 1, 0.5]
49
+ config.neck_hidden_sizes = [256, 512, 768, 768]
50
+ config.num_labels = 150
51
+ config.patch_size = 16
52
+ expected_shape = (1, 384, 384)
53
+ config.use_batch_norm_in_fusion_residual = False
54
+ config.readout_type = "project"
55
+
56
+ if "ade" in checkpoint_url:
57
+ config.use_batch_norm_in_fusion_residual = True
58
+ config.hidden_size = 768
59
+ config.reassemble_stage = [1, 1, 1, 0.5]
60
+ config.num_labels = 150
61
+ config.patch_size = 16
62
+ repo_id = "huggingface/label-files"
63
+ filename = "ade20k-id2label.json"
64
+ id2label = json.loads(Path(hf_hub_download(repo_id, filename, repo_type="dataset")).read_text())
65
+ id2label = {int(k): v for k, v in id2label.items()}
66
+ config.id2label = id2label
67
+ config.label2id = {v: k for k, v in id2label.items()}
68
+ expected_shape = [1, 150, 480, 480]
69
+
70
+ return config, expected_shape
71
+
72
+
73
+ def remove_ignore_keys_(state_dict):
74
+ ignore_keys = ["pretrained.model.head.weight", "pretrained.model.head.bias"]
75
+ for k in ignore_keys:
76
+ state_dict.pop(k, None)
77
+
78
+
79
+ def rename_key(name):
80
+ if (
81
+ "pretrained.model" in name
82
+ and "cls_token" not in name
83
+ and "pos_embed" not in name
84
+ and "patch_embed" not in name
85
+ ):
86
+ name = name.replace("pretrained.model", "dpt.encoder")
87
+ if "pretrained.model" in name:
88
+ name = name.replace("pretrained.model", "dpt.embeddings")
89
+ if "patch_embed" in name:
90
+ name = name.replace("patch_embed", "")
91
+ if "pos_embed" in name:
92
+ name = name.replace("pos_embed", "position_embeddings")
93
+ if "attn.proj" in name:
94
+ name = name.replace("attn.proj", "attention.output.dense")
95
+ if "proj" in name and "project" not in name:
96
+ name = name.replace("proj", "projection")
97
+ if "blocks" in name:
98
+ name = name.replace("blocks", "layer")
99
+ if "mlp.fc1" in name:
100
+ name = name.replace("mlp.fc1", "intermediate.dense")
101
+ if "mlp.fc2" in name:
102
+ name = name.replace("mlp.fc2", "output.dense")
103
+ if "norm1" in name and "backbone" not in name:
104
+ name = name.replace("norm1", "layernorm_before")
105
+ if "norm2" in name and "backbone" not in name:
106
+ name = name.replace("norm2", "layernorm_after")
107
+ if "scratch.output_conv" in name:
108
+ name = name.replace("scratch.output_conv", "head")
109
+ if "scratch" in name:
110
+ name = name.replace("scratch", "neck")
111
+ if "layer1_rn" in name:
112
+ name = name.replace("layer1_rn", "convs.0")
113
+ if "layer2_rn" in name:
114
+ name = name.replace("layer2_rn", "convs.1")
115
+ if "layer3_rn" in name:
116
+ name = name.replace("layer3_rn", "convs.2")
117
+ if "layer4_rn" in name:
118
+ name = name.replace("layer4_rn", "convs.3")
119
+ if "refinenet" in name:
120
+ layer_idx = int(name[len("neck.refinenet") : len("neck.refinenet") + 1])
121
+ # tricky here: we need to map 4 to 0, 3 to 1, 2 to 2 and 1 to 3
122
+ name = name.replace(f"refinenet{layer_idx}", f"fusion_stage.layers.{abs(layer_idx - 4)}")
123
+ if "out_conv" in name:
124
+ name = name.replace("out_conv", "projection")
125
+ if "resConfUnit1" in name:
126
+ name = name.replace("resConfUnit1", "residual_layer1")
127
+ if "resConfUnit2" in name:
128
+ name = name.replace("resConfUnit2", "residual_layer2")
129
+ if "conv1" in name:
130
+ name = name.replace("conv1", "convolution1")
131
+ if "conv2" in name:
132
+ name = name.replace("conv2", "convolution2")
133
+ # readout blocks
134
+ if "pretrained.act_postprocess1.0.project.0" in name:
135
+ name = name.replace("pretrained.act_postprocess1.0.project.0", "neck.reassemble_stage.readout_projects.0.0")
136
+ if "pretrained.act_postprocess2.0.project.0" in name:
137
+ name = name.replace("pretrained.act_postprocess2.0.project.0", "neck.reassemble_stage.readout_projects.1.0")
138
+ if "pretrained.act_postprocess3.0.project.0" in name:
139
+ name = name.replace("pretrained.act_postprocess3.0.project.0", "neck.reassemble_stage.readout_projects.2.0")
140
+ if "pretrained.act_postprocess4.0.project.0" in name:
141
+ name = name.replace("pretrained.act_postprocess4.0.project.0", "neck.reassemble_stage.readout_projects.3.0")
142
+
143
+ # resize blocks
144
+ if "pretrained.act_postprocess1.3" in name:
145
+ name = name.replace("pretrained.act_postprocess1.3", "neck.reassemble_stage.layers.0.projection")
146
+ if "pretrained.act_postprocess1.4" in name:
147
+ name = name.replace("pretrained.act_postprocess1.4", "neck.reassemble_stage.layers.0.resize")
148
+ if "pretrained.act_postprocess2.3" in name:
149
+ name = name.replace("pretrained.act_postprocess2.3", "neck.reassemble_stage.layers.1.projection")
150
+ if "pretrained.act_postprocess2.4" in name:
151
+ name = name.replace("pretrained.act_postprocess2.4", "neck.reassemble_stage.layers.1.resize")
152
+ if "pretrained.act_postprocess3.3" in name:
153
+ name = name.replace("pretrained.act_postprocess3.3", "neck.reassemble_stage.layers.2.projection")
154
+ if "pretrained.act_postprocess4.3" in name:
155
+ name = name.replace("pretrained.act_postprocess4.3", "neck.reassemble_stage.layers.3.projection")
156
+ if "pretrained.act_postprocess4.4" in name:
157
+ name = name.replace("pretrained.act_postprocess4.4", "neck.reassemble_stage.layers.3.resize")
158
+ if "pretrained" in name:
159
+ name = name.replace("pretrained", "dpt")
160
+ if "bn" in name:
161
+ name = name.replace("bn", "batch_norm")
162
+ if "head" in name:
163
+ name = name.replace("head", "head.head")
164
+ if "encoder.norm" in name:
165
+ name = name.replace("encoder.norm", "layernorm")
166
+ if "auxlayer" in name:
167
+ name = name.replace("auxlayer", "auxiliary_head.head")
168
+ if "backbone" in name:
169
+ name = name.replace("backbone", "backbone.bit.encoder")
170
+
171
+ if ".." in name:
172
+ name = name.replace("..", ".")
173
+
174
+ if "stem.conv" in name:
175
+ name = name.replace("stem.conv", "bit.embedder.convolution")
176
+ if "blocks" in name:
177
+ name = name.replace("blocks", "layers")
178
+ if "convolution" in name and "backbone" in name:
179
+ name = name.replace("convolution", "conv")
180
+ if "layer" in name and "backbone" in name:
181
+ name = name.replace("layer", "layers")
182
+ if "backbone.bit.encoder.bit" in name:
183
+ name = name.replace("backbone.bit.encoder.bit", "backbone.bit")
184
+ if "embedder.conv" in name:
185
+ name = name.replace("embedder.conv", "embedder.convolution")
186
+ if "backbone.bit.encoder.stem.norm" in name:
187
+ name = name.replace("backbone.bit.encoder.stem.norm", "backbone.bit.embedder.norm")
188
+ return name
189
+
190
+
191
+ # we split up the matrix of each encoder layer into queries, keys and values
192
+ def read_in_q_k_v(state_dict, config):
193
+ for i in range(config.num_hidden_layers):
194
+ # read in weights + bias of input projection layer (in timm, this is a single matrix + bias)
195
+ in_proj_weight = state_dict.pop(f"dpt.encoder.layer.{i}.attn.qkv.weight")
196
+ in_proj_bias = state_dict.pop(f"dpt.encoder.layer.{i}.attn.qkv.bias")
197
+ # next, add query, keys and values (in that order) to the state dict
198
+ state_dict[f"dpt.encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[: config.hidden_size, :]
199
+ state_dict[f"dpt.encoder.layer.{i}.attention.attention.query.bias"] = in_proj_bias[: config.hidden_size]
200
+ state_dict[f"dpt.encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[
201
+ config.hidden_size : config.hidden_size * 2, :
202
+ ]
203
+ state_dict[f"dpt.encoder.layer.{i}.attention.attention.key.bias"] = in_proj_bias[
204
+ config.hidden_size : config.hidden_size * 2
205
+ ]
206
+ state_dict[f"dpt.encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[
207
+ -config.hidden_size :, :
208
+ ]
209
+ state_dict[f"dpt.encoder.layer.{i}.attention.attention.value.bias"] = in_proj_bias[-config.hidden_size :]
210
+
211
+
212
+ # We will verify our results on an image of cute cats
213
+ def prepare_img():
214
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
215
+ with httpx.stream("GET", url) as response:
216
+ image = Image.open(BytesIO(response.read()))
217
+ return image
218
+
219
+
220
+ @torch.no_grad()
221
+ def convert_dpt_checkpoint(checkpoint_url, pytorch_dump_folder_path, push_to_hub, model_name, show_prediction):
222
+ """
223
+ Copy/paste/tweak model's weights to our DPT structure.
224
+ """
225
+
226
+ # define DPT configuration based on URL
227
+ config, expected_shape = get_dpt_config(checkpoint_url)
228
+ # load original state_dict from URL
229
+ # state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu")
230
+ state_dict = torch.load(checkpoint_url, map_location="cpu", weights_only=True)
231
+ # remove certain keys
232
+ remove_ignore_keys_(state_dict)
233
+ # rename keys
234
+ for key in state_dict.copy():
235
+ val = state_dict.pop(key)
236
+ state_dict[rename_key(key)] = val
237
+ # read in qkv matrices
238
+ read_in_q_k_v(state_dict, config)
239
+
240
+ # load HuggingFace model
241
+ model = DPTForSemanticSegmentation(config) if "ade" in checkpoint_url else DPTForDepthEstimation(config)
242
+ model.load_state_dict(state_dict)
243
+ model.eval()
244
+
245
+ # Check outputs on an image
246
+ size = 480 if "ade" in checkpoint_url else 384
247
+ image_processor = DPTImageProcessor(size=size)
248
+
249
+ image = prepare_img()
250
+ encoding = image_processor(image, return_tensors="pt")
251
+
252
+ # forward pass
253
+ outputs = model(**encoding).logits if "ade" in checkpoint_url else model(**encoding).predicted_depth
254
+
255
+ if show_prediction:
256
+ prediction = (
257
+ torch.nn.functional.interpolate(
258
+ outputs.unsqueeze(1),
259
+ size=(image.size[1], image.size[0]),
260
+ mode="bicubic",
261
+ align_corners=False,
262
+ )
263
+ .squeeze()
264
+ .cpu()
265
+ .numpy()
266
+ )
267
+
268
+ Image.fromarray((prediction / prediction.max()) * 255).show()
269
+
270
+ if pytorch_dump_folder_path is not None:
271
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
272
+ print(f"Saving model to {pytorch_dump_folder_path}")
273
+ model.save_pretrained(pytorch_dump_folder_path)
274
+ print(f"Saving image processor to {pytorch_dump_folder_path}")
275
+ image_processor.save_pretrained(pytorch_dump_folder_path)
276
+
277
+ if push_to_hub:
278
+ model.push_to_hub("ybelkada/dpt-hybrid-midas")
279
+ image_processor.push_to_hub("ybelkada/dpt-hybrid-midas")
280
+
281
+
282
+ if __name__ == "__main__":
283
+ parser = argparse.ArgumentParser()
284
+ # Required parameters
285
+ parser.add_argument(
286
+ "--checkpoint_url",
287
+ default="https://github.com/intel-isl/DPT/releases/download/1_0/dpt_large-midas-2f21e586.pt",
288
+ type=str,
289
+ help="URL of the original DPT checkpoint you'd like to convert.",
290
+ )
291
+ parser.add_argument(
292
+ "--pytorch_dump_folder_path",
293
+ default=None,
294
+ type=str,
295
+ required=False,
296
+ help="Path to the output PyTorch model directory.",
297
+ )
298
+ parser.add_argument(
299
+ "--push_to_hub",
300
+ action="store_true",
301
+ )
302
+ parser.add_argument(
303
+ "--model_name",
304
+ default="dpt-large",
305
+ type=str,
306
+ help="Name of the model, in case you're pushing to the hub.",
307
+ )
308
+ parser.add_argument(
309
+ "--show_prediction",
310
+ action="store_true",
311
+ )
312
+
313
+ args = parser.parse_args()
314
+ convert_dpt_checkpoint(
315
+ args.checkpoint_url, args.pytorch_dump_folder_path, args.push_to_hub, args.model_name, args.show_prediction
316
+ )
third_party/transformers/src/transformers/models/dpt/convert_dpt_swinv2_to_hf.py ADDED
@@ -0,0 +1,322 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 DPT 3.1 checkpoints from the MiDaS repository. URL: https://github.com/isl-org/MiDaS"""
15
+
16
+ import argparse
17
+ from io import BytesIO
18
+ from pathlib import Path
19
+
20
+ import httpx
21
+ import torch
22
+ from PIL import Image
23
+
24
+ from transformers import DPTConfig, DPTForDepthEstimation, DPTImageProcessor, Swinv2Config
25
+ from transformers.utils import logging
26
+
27
+
28
+ logging.set_verbosity_info()
29
+ logger = logging.get_logger(__name__)
30
+
31
+
32
+ def get_dpt_config(model_name):
33
+ if "tiny" in model_name:
34
+ embed_dim = 96
35
+ depths = (2, 2, 6, 2)
36
+ num_heads = (3, 6, 12, 24)
37
+ window_size = 16
38
+ # note: for Swinv2-tiny authors used the window_size = 16 variant
39
+ # as seen here: https://github.com/isl-org/MiDaS/blob/bdc4ed64c095e026dc0a2f17cabb14d58263decb/midas/backbones/swin2.py#L26
40
+ pretrained_window_sizes = (0, 0, 0, 0)
41
+ elif "base" in model_name:
42
+ embed_dim = 128
43
+ depths = (2, 2, 18, 2)
44
+ num_heads = (4, 8, 16, 32)
45
+ window_size = 24
46
+ pretrained_window_sizes = (12, 12, 12, 6)
47
+ elif "large" in model_name:
48
+ embed_dim = 192
49
+ depths = (2, 2, 18, 2)
50
+ num_heads = (6, 12, 24, 48)
51
+ window_size = 24
52
+ pretrained_window_sizes = (12, 12, 12, 6)
53
+
54
+ if "384" in model_name:
55
+ image_size = 384
56
+ elif "256" in model_name:
57
+ image_size = 256
58
+ else:
59
+ raise ValueError("Model not supported, to do")
60
+
61
+ backbone_config = Swinv2Config(
62
+ image_size=image_size,
63
+ embed_dim=embed_dim,
64
+ depths=depths,
65
+ window_size=window_size,
66
+ pretrained_window_sizes=pretrained_window_sizes,
67
+ num_heads=num_heads,
68
+ out_features=["stage1", "stage2", "stage3", "stage4"],
69
+ )
70
+
71
+ if model_name == "dpt-swinv2-tiny-256":
72
+ neck_hidden_sizes = [96, 192, 384, 768]
73
+ elif model_name == "dpt-swinv2-base-384":
74
+ neck_hidden_sizes = [128, 256, 512, 1024]
75
+ elif model_name == "dpt-swinv2-large-384":
76
+ neck_hidden_sizes = [192, 384, 768, 1536]
77
+
78
+ config = DPTConfig(backbone_config=backbone_config, neck_hidden_sizes=neck_hidden_sizes)
79
+
80
+ return config, image_size
81
+
82
+
83
+ # here we list all keys to be renamed (original name on the left, our name on the right)
84
+ def create_rename_keys(config):
85
+ rename_keys = []
86
+
87
+ # fmt: off
88
+ # stem
89
+ rename_keys.append(("pretrained.model.patch_embed.proj.weight", "backbone.embeddings.patch_embeddings.projection.weight"))
90
+ rename_keys.append(("pretrained.model.patch_embed.proj.bias", "backbone.embeddings.patch_embeddings.projection.bias"))
91
+ rename_keys.append(("pretrained.model.patch_embed.norm.weight", "backbone.embeddings.norm.weight"))
92
+ rename_keys.append(("pretrained.model.patch_embed.norm.bias", "backbone.embeddings.norm.bias"))
93
+
94
+ # transformer encoder
95
+ for i in range(len(config.backbone_config.depths)):
96
+ for j in range(config.backbone_config.depths[i]):
97
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.attn.logit_scale", f"backbone.encoder.layers.{i}.blocks.{j}.attention.self.logit_scale"))
98
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.attn.cpb_mlp.0.weight", f"backbone.encoder.layers.{i}.blocks.{j}.attention.self.continuous_position_bias_mlp.0.weight"))
99
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.attn.cpb_mlp.0.bias", f"backbone.encoder.layers.{i}.blocks.{j}.attention.self.continuous_position_bias_mlp.0.bias"))
100
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.attn.cpb_mlp.2.weight", f"backbone.encoder.layers.{i}.blocks.{j}.attention.self.continuous_position_bias_mlp.2.weight"))
101
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.attn.q_bias", f"backbone.encoder.layers.{i}.blocks.{j}.attention.self.query.bias"))
102
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.attn.v_bias", f"backbone.encoder.layers.{i}.blocks.{j}.attention.self.value.bias"))
103
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.attn.proj.weight", f"backbone.encoder.layers.{i}.blocks.{j}.attention.output.dense.weight"))
104
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.attn.proj.bias", f"backbone.encoder.layers.{i}.blocks.{j}.attention.output.dense.bias"))
105
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.norm1.weight", f"backbone.encoder.layers.{i}.blocks.{j}.layernorm_before.weight"))
106
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.norm1.bias", f"backbone.encoder.layers.{i}.blocks.{j}.layernorm_before.bias"))
107
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.mlp.fc1.weight", f"backbone.encoder.layers.{i}.blocks.{j}.intermediate.dense.weight"))
108
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.mlp.fc1.bias", f"backbone.encoder.layers.{i}.blocks.{j}.intermediate.dense.bias"))
109
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.mlp.fc2.weight", f"backbone.encoder.layers.{i}.blocks.{j}.output.dense.weight"))
110
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.mlp.fc2.bias", f"backbone.encoder.layers.{i}.blocks.{j}.output.dense.bias"))
111
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.norm2.weight", f"backbone.encoder.layers.{i}.blocks.{j}.layernorm_after.weight"))
112
+ rename_keys.append((f"pretrained.model.layers.{i}.blocks.{j}.norm2.bias", f"backbone.encoder.layers.{i}.blocks.{j}.layernorm_after.bias"))
113
+
114
+ # downsample parameters
115
+ if i in [0,1,2]:
116
+ rename_keys.append((f"pretrained.model.layers.{i}.downsample.reduction.weight", f"backbone.encoder.layers.{i}.downsample.reduction.weight"))
117
+ rename_keys.append((f"pretrained.model.layers.{i}.downsample.norm.weight", f"backbone.encoder.layers.{i}.downsample.norm.weight"))
118
+ rename_keys.append((f"pretrained.model.layers.{i}.downsample.norm.bias", f"backbone.encoder.layers.{i}.downsample.norm.bias"))
119
+
120
+ # note: non-Transformer backbones like Swinv2, LeViT et al don't require activation postprocessing (readout projections + resize blocks)
121
+
122
+ # refinenet (tricky here)
123
+ mapping = {1:3, 2:2, 3:1, 4:0}
124
+
125
+ for i in range(1, 5):
126
+ j = mapping[i]
127
+ rename_keys.append((f"scratch.refinenet{i}.out_conv.weight", f"neck.fusion_stage.layers.{j}.projection.weight"))
128
+ rename_keys.append((f"scratch.refinenet{i}.out_conv.bias", f"neck.fusion_stage.layers.{j}.projection.bias"))
129
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit1.conv1.weight", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution1.weight"))
130
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit1.conv1.bias", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution1.bias"))
131
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit1.conv2.weight", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution2.weight"))
132
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit1.conv2.bias", f"neck.fusion_stage.layers.{j}.residual_layer1.convolution2.bias"))
133
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit2.conv1.weight", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution1.weight"))
134
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit2.conv1.bias", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution1.bias"))
135
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit2.conv2.weight", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution2.weight"))
136
+ rename_keys.append((f"scratch.refinenet{i}.resConfUnit2.conv2.bias", f"neck.fusion_stage.layers.{j}.residual_layer2.convolution2.bias"))
137
+
138
+ # scratch convolutions
139
+ for i in range(4):
140
+ rename_keys.append((f"scratch.layer{i+1}_rn.weight", f"neck.convs.{i}.weight"))
141
+
142
+ # head
143
+ for i in range(0, 5, 2):
144
+ rename_keys.append((f"scratch.output_conv.{i}.weight", f"head.head.{i}.weight"))
145
+ rename_keys.append((f"scratch.output_conv.{i}.bias", f"head.head.{i}.bias"))
146
+
147
+ return rename_keys
148
+
149
+
150
+ def remove_ignore_keys_(state_dict):
151
+ ignore_keys = ["pretrained.model.head.weight", "pretrained.model.head.bias"]
152
+ for k in ignore_keys:
153
+ state_dict.pop(k, None)
154
+
155
+
156
+ # we split up the matrix of each encoder layer into queries, keys and values
157
+ def read_in_q_k_v(state_dict, config, model):
158
+ for i in range(len(config.backbone_config.depths)):
159
+ for j in range(config.backbone_config.depths[i]):
160
+ dim = model.backbone.encoder.layers[i].blocks[j].attention.self.all_head_size
161
+ # read in weights + bias of input projection layer (in original implementation, this is a single matrix + bias)
162
+ in_proj_weight = state_dict.pop(f"pretrained.model.layers.{i}.blocks.{j}.attn.qkv.weight")
163
+ # next, add query, keys and values (in that order) to the state dict
164
+ state_dict[f"backbone.encoder.layers.{i}.blocks.{j}.attention.self.query.weight"] = in_proj_weight[:dim, :]
165
+ state_dict[f"backbone.encoder.layers.{i}.blocks.{j}.attention.self.key.weight"] = in_proj_weight[
166
+ dim : dim * 2, :
167
+ ]
168
+ state_dict[f"backbone.encoder.layers.{i}.blocks.{j}.attention.self.value.weight"] = in_proj_weight[
169
+ -dim:, :
170
+ ]
171
+
172
+
173
+ def rename_key(dct, old, new):
174
+ val = dct.pop(old)
175
+ dct[new] = val
176
+
177
+
178
+ # We will verify our results on an image of cute cats
179
+ def prepare_img():
180
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
181
+ with httpx.stream("GET", url) as response:
182
+ image = Image.open(BytesIO(response.read()))
183
+ return image
184
+
185
+
186
+ @torch.no_grad()
187
+ def convert_dpt_checkpoint(model_name, pytorch_dump_folder_path, verify_logits, push_to_hub):
188
+ """
189
+ Copy/paste/tweak model's weights to our DPT structure.
190
+ """
191
+
192
+ name_to_url = {
193
+ "dpt-swinv2-tiny-256": "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_tiny_256.pt",
194
+ "dpt-swinv2-base-384": "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_base_384.pt",
195
+ "dpt-swinv2-large-384": "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_large_384.pt",
196
+ }
197
+
198
+ # define DPT configuration based on URL
199
+ checkpoint_url = name_to_url[model_name]
200
+ config, image_size = get_dpt_config(model_name)
201
+ # load original state_dict from URL
202
+ state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu")
203
+
204
+ # load HuggingFace model
205
+ model = DPTForDepthEstimation(config)
206
+
207
+ # remove certain keys
208
+ remove_ignore_keys_(state_dict)
209
+ # rename keys
210
+ rename_keys = create_rename_keys(config)
211
+ for src, dest in rename_keys:
212
+ rename_key(state_dict, src, dest)
213
+ # read in qkv matrices
214
+ read_in_q_k_v(state_dict, config, model)
215
+
216
+ missing_keys, unexpected_keys = model.load_state_dict(state_dict, strict=False)
217
+ print("Missing keys:", missing_keys)
218
+ print("Unexpected keys:", unexpected_keys)
219
+ model.eval()
220
+
221
+ # Check outputs on an image
222
+ processor = DPTImageProcessor(size={"height": image_size, "width": image_size})
223
+
224
+ image = prepare_img()
225
+ processor(image, return_tensors="pt")
226
+
227
+ if verify_logits:
228
+ from torchvision import transforms
229
+
230
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
231
+ with httpx.stream("GET", url) as response:
232
+ image = Image.open(BytesIO(response.read()))
233
+ transforms = transforms.Compose(
234
+ [
235
+ transforms.Resize((image_size, image_size)),
236
+ transforms.ToTensor(),
237
+ ]
238
+ )
239
+ pixel_values = transforms(image).unsqueeze(0)
240
+
241
+ # forward pass
242
+ with torch.no_grad():
243
+ outputs = model(pixel_values)
244
+
245
+ predicted_depth = outputs.predicted_depth
246
+
247
+ print("Shape of predicted depth:", predicted_depth.shape)
248
+ print("First values of predicted depth:", predicted_depth[0, :3, :3])
249
+
250
+ # assert logits
251
+ if model_name == "dpt-swinv2-base-384":
252
+ # OK, checked
253
+ expected_shape = torch.Size([1, 384, 384])
254
+ expected_slice = torch.tensor(
255
+ [
256
+ [1998.5575, 1997.3887, 2009.2981],
257
+ [1952.8607, 1979.6488, 2001.0854],
258
+ [1953.7697, 1961.7711, 1968.8904],
259
+ ],
260
+ )
261
+ elif model_name == "dpt-swinv2-tiny-256":
262
+ # OK, checked
263
+ expected_shape = torch.Size([1, 256, 256])
264
+ expected_slice = torch.tensor(
265
+ [[978.9163, 976.5215, 978.5349], [974.1859, 971.7249, 975.8046], [971.3419, 970.3118, 971.6830]],
266
+ )
267
+ elif model_name == "dpt-swinv2-large-384":
268
+ # OK, checked
269
+ expected_shape = torch.Size([1, 384, 384])
270
+ expected_slice = torch.tensor(
271
+ [
272
+ [1203.7206, 1200.1495, 1197.8234],
273
+ [1196.2484, 1183.5033, 1186.4640],
274
+ [1178.8131, 1182.3260, 1174.3975],
275
+ ],
276
+ )
277
+
278
+ assert predicted_depth.shape == torch.Size(expected_shape)
279
+ assert torch.allclose(predicted_depth[0, :3, :3], expected_slice)
280
+ print("Looks ok!")
281
+
282
+ if pytorch_dump_folder_path is not None:
283
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
284
+ print(f"Saving model and processor to {pytorch_dump_folder_path}")
285
+ model.save_pretrained(pytorch_dump_folder_path)
286
+ processor.save_pretrained(pytorch_dump_folder_path)
287
+
288
+ if push_to_hub:
289
+ print("Pushing model and processor to hub...")
290
+ model.push_to_hub(repo_id=f"Intel/{model_name}")
291
+ processor.push_to_hub(repo_id=f"Intel/{model_name}")
292
+
293
+
294
+ if __name__ == "__main__":
295
+ parser = argparse.ArgumentParser()
296
+ # Required parameters
297
+ parser.add_argument(
298
+ "--model_name",
299
+ default="dpt-swinv2-base-384",
300
+ type=str,
301
+ choices=["dpt-swinv2-tiny-256", "dpt-swinv2-base-384", "dpt-swinv2-large-384"],
302
+ help="Name of the model you'd like to convert.",
303
+ )
304
+ parser.add_argument(
305
+ "--pytorch_dump_folder_path",
306
+ default=None,
307
+ type=str,
308
+ help="Path to the output PyTorch model directory.",
309
+ )
310
+ parser.add_argument(
311
+ "--verify_logits",
312
+ action="store_true",
313
+ help="Whether to verify logits after conversion.",
314
+ )
315
+ parser.add_argument(
316
+ "--push_to_hub",
317
+ action="store_true",
318
+ help="Whether to push the model to the hub after conversion.",
319
+ )
320
+
321
+ args = parser.parse_args()
322
+ convert_dpt_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.verify_logits, args.push_to_hub)