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

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/__init__.py +852 -0
  2. third_party/transformers/src/transformers/debug_utils.py +348 -0
  3. third_party/transformers/src/transformers/distributed/__init__.py +33 -0
  4. third_party/transformers/src/transformers/distributed/configuration_utils.py +110 -0
  5. third_party/transformers/src/transformers/hyperparameter_search.py +123 -0
  6. third_party/transformers/src/transformers/masking_utils.py +1608 -0
  7. third_party/transformers/src/transformers/model_debugging_utils.py +455 -0
  8. third_party/transformers/src/transformers/modeling_flash_attention_utils.py +807 -0
  9. third_party/transformers/src/transformers/modeling_layers.py +288 -0
  10. third_party/transformers/src/transformers/models/__init__.py +472 -0
  11. third_party/transformers/src/transformers/models/beit/__init__.py +29 -0
  12. third_party/transformers/src/transformers/models/beit/configuration_beit.py +117 -0
  13. third_party/transformers/src/transformers/models/beit/convert_beit_unilm_to_pytorch.py +375 -0
  14. third_party/transformers/src/transformers/models/beit/image_processing_beit.py +228 -0
  15. third_party/transformers/src/transformers/models/beit/image_processing_pil_beit.py +209 -0
  16. third_party/transformers/src/transformers/models/beit/modeling_beit.py +1470 -0
  17. third_party/transformers/src/transformers/models/cohere2/__init__.py +27 -0
  18. third_party/transformers/src/transformers/models/cohere2/configuration_cohere2.py +107 -0
  19. third_party/transformers/src/transformers/models/cohere_asr/__init__.py +30 -0
  20. third_party/transformers/src/transformers/models/cohere_asr/configuration_cohere_asr.py +101 -0
  21. third_party/transformers/src/transformers/models/cohere_asr/feature_extraction_cohere_asr.py +374 -0
  22. third_party/transformers/src/transformers/models/cohere_asr/modeling_cohere_asr.py +658 -0
  23. third_party/transformers/src/transformers/models/cohere_asr/modular_cohere_asr.py +525 -0
  24. third_party/transformers/src/transformers/models/cohere_asr/processing_cohere_asr.py +188 -0
  25. third_party/transformers/src/transformers/models/deepseek_vl_hybrid/__init__.py +30 -0
  26. third_party/transformers/src/transformers/models/deepseek_vl_hybrid/configuration_deepseek_vl_hybrid.py +92 -0
  27. third_party/transformers/src/transformers/models/deepseek_vl_hybrid/convert_deepseek_vl_hybrid_weights_to_hf.py +386 -0
  28. third_party/transformers/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py +297 -0
  29. third_party/transformers/src/transformers/models/deepseek_vl_hybrid/image_processing_pil_deepseek_vl_hybrid.py +261 -0
  30. third_party/transformers/src/transformers/models/deepseek_vl_hybrid/modeling_deepseek_vl_hybrid.py +539 -0
  31. third_party/transformers/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py +787 -0
  32. third_party/transformers/src/transformers/models/deepseek_vl_hybrid/processing_deepseek_vl_hybrid.py +119 -0
  33. third_party/transformers/src/transformers/models/diffllama/__init__.py +27 -0
  34. third_party/transformers/src/transformers/models/diffllama/configuration_diffllama.py +80 -0
  35. third_party/transformers/src/transformers/models/diffllama/modeling_diffllama.py +753 -0
  36. third_party/transformers/src/transformers/models/diffllama/modular_diffllama.py +417 -0
  37. third_party/transformers/src/transformers/models/encodec/__init__.py +28 -0
  38. third_party/transformers/src/transformers/models/encodec/configuration_encodec.py +155 -0
  39. third_party/transformers/src/transformers/models/encodec/convert_encodec_checkpoint_to_pytorch.py +364 -0
  40. third_party/transformers/src/transformers/models/encodec/feature_extraction_encodec.py +205 -0
  41. third_party/transformers/src/transformers/models/encodec/modeling_encodec.py +822 -0
  42. third_party/transformers/src/transformers/models/herbert/__init__.py +26 -0
  43. third_party/transformers/src/transformers/models/herbert/tokenization_herbert.py +111 -0
  44. third_party/transformers/src/transformers/models/maskformer/__init__.py +32 -0
  45. third_party/transformers/src/transformers/models/maskformer/configuration_maskformer.py +226 -0
  46. third_party/transformers/src/transformers/models/maskformer/configuration_maskformer_swin.py +82 -0
  47. third_party/transformers/src/transformers/models/maskformer/convert_maskformer_original_pytorch_checkpoint_to_pytorch.py +724 -0
  48. third_party/transformers/src/transformers/models/maskformer/convert_maskformer_resnet_to_pytorch.py +403 -0
  49. third_party/transformers/src/transformers/models/maskformer/convert_maskformer_swin_to_pytorch.py +346 -0
  50. third_party/transformers/src/transformers/models/maskformer/image_processing_maskformer.py +806 -0
third_party/transformers/src/transformers/__init__.py ADDED
@@ -0,0 +1,852 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ # When adding a new object to this init, remember to add it twice: once inside the `_import_structure` dictionary and
16
+ # once inside the `if TYPE_CHECKING` branch. The `TYPE_CHECKING` should have import statements as usual, but they are
17
+ # only there for type checking. The `_import_structure` is a dictionary submodule to list of object names, and is used
18
+ # to defer the actual importing for when the objects are requested. This way `import transformers` provides the names
19
+ # in the namespace without actually importing anything (and especially none of the backends).
20
+
21
+ __version__ = "5.6.0.dev0"
22
+
23
+ import importlib
24
+ import sys
25
+ import types
26
+ from pathlib import Path
27
+ from typing import TYPE_CHECKING
28
+
29
+ # Check the dependencies satisfy the minimal versions required.
30
+ from . import dependency_versions_check
31
+ from .utils import (
32
+ OptionalDependencyNotAvailable,
33
+ _LazyModule,
34
+ is_essentia_available,
35
+ is_g2p_en_available,
36
+ is_librosa_available,
37
+ is_mistral_common_available,
38
+ is_mlx_available,
39
+ is_numba_available,
40
+ is_pretty_midi_available,
41
+ )
42
+
43
+ # Note: the following symbols are deliberately exported with `as`
44
+ # so that mypy, pylint or other static linters can recognize them,
45
+ # given that they are not exported using `__all__` in this file.
46
+ from .utils import is_bitsandbytes_available as is_bitsandbytes_available
47
+ from .utils import is_scipy_available as is_scipy_available
48
+ from .utils import is_sentencepiece_available as is_sentencepiece_available
49
+ from .utils import is_speech_available as is_speech_available
50
+ from .utils import is_timm_available as is_timm_available
51
+ from .utils import is_tokenizers_available as is_tokenizers_available
52
+ from .utils import is_torch_available as is_torch_available
53
+ from .utils import is_torchaudio_available as is_torchaudio_available
54
+ from .utils import is_torchvision_available as is_torchvision_available
55
+ from .utils import is_vision_available as is_vision_available
56
+ from .utils import logging as logging
57
+ from .utils.import_utils import define_import_structure
58
+
59
+
60
+ logger = logging.get_logger(__name__) # pylint: disable=invalid-name
61
+
62
+ # Base objects, independent of any specific backend
63
+ _import_structure = {
64
+ "audio_utils": [],
65
+ "cli": [],
66
+ "configuration_utils": ["PreTrainedConfig", "PretrainedConfig"],
67
+ "convert_slow_tokenizers_checkpoints_to_fast": [],
68
+ "data": [
69
+ "DataProcessor",
70
+ "InputExample",
71
+ "InputFeatures",
72
+ "SingleSentenceClassificationProcessor",
73
+ "SquadExample",
74
+ "SquadFeatures",
75
+ "SquadV1Processor",
76
+ "SquadV2Processor",
77
+ "glue_compute_metrics",
78
+ "glue_convert_examples_to_features",
79
+ "glue_output_modes",
80
+ "glue_processors",
81
+ "glue_tasks_num_labels",
82
+ "squad_convert_examples_to_features",
83
+ "xnli_compute_metrics",
84
+ "xnli_output_modes",
85
+ "xnli_processors",
86
+ "xnli_tasks_num_labels",
87
+ ],
88
+ "data.data_collator": [
89
+ "DataCollator",
90
+ "DataCollatorForLanguageModeling",
91
+ "DataCollatorForMultipleChoice",
92
+ "DataCollatorForPermutationLanguageModeling",
93
+ "DataCollatorForSeq2Seq",
94
+ "DataCollatorForSOP",
95
+ "DataCollatorForTokenClassification",
96
+ "DataCollatorForWholeWordMask",
97
+ "DataCollatorWithFlattening",
98
+ "DataCollatorWithPadding",
99
+ "DefaultDataCollator",
100
+ "default_data_collator",
101
+ ],
102
+ "data.metrics": [],
103
+ "data.processors": [],
104
+ "debug_utils": [],
105
+ "dependency_versions_check": [],
106
+ "dependency_versions_table": [],
107
+ "dynamic_module_utils": [],
108
+ "feature_extraction_sequence_utils": ["SequenceFeatureExtractor"],
109
+ "feature_extraction_utils": ["BatchFeature", "FeatureExtractionMixin"],
110
+ "file_utils": [],
111
+ "generation": [
112
+ "AsyncTextIteratorStreamer",
113
+ "CompileConfig",
114
+ "ContinuousBatchingConfig",
115
+ "GenerationConfig",
116
+ "TextIteratorStreamer",
117
+ "TextStreamer",
118
+ "WatermarkingConfig",
119
+ ],
120
+ "hf_argparser": ["HfArgumentParser"],
121
+ "hyperparameter_search": [],
122
+ "image_processing_utils_fast": [],
123
+ "image_transforms": [],
124
+ "integrations": [
125
+ "is_clearml_available",
126
+ "is_comet_available",
127
+ "is_dvclive_available",
128
+ "is_neptune_available",
129
+ "is_optuna_available",
130
+ "is_ray_available",
131
+ "is_ray_tune_available",
132
+ "is_swanlab_available",
133
+ "is_tensorboard_available",
134
+ "is_trackio_available",
135
+ "is_wandb_available",
136
+ ],
137
+ "loss": [],
138
+ "pipelines": [
139
+ "AnyToAnyPipeline",
140
+ "AudioClassificationPipeline",
141
+ "AutomaticSpeechRecognitionPipeline",
142
+ "CsvPipelineDataFormat",
143
+ "DepthEstimationPipeline",
144
+ "DocumentQuestionAnsweringPipeline",
145
+ "FeatureExtractionPipeline",
146
+ "FillMaskPipeline",
147
+ "ImageClassificationPipeline",
148
+ "ImageFeatureExtractionPipeline",
149
+ "ImageSegmentationPipeline",
150
+ "ImageTextToTextPipeline",
151
+ "JsonPipelineDataFormat",
152
+ "KeypointMatchingPipeline",
153
+ "MaskGenerationPipeline",
154
+ "NerPipeline",
155
+ "ObjectDetectionPipeline",
156
+ "PipedPipelineDataFormat",
157
+ "Pipeline",
158
+ "PipelineDataFormat",
159
+ "TableQuestionAnsweringPipeline",
160
+ "TextClassificationPipeline",
161
+ "TextGenerationPipeline",
162
+ "TextToAudioPipeline",
163
+ "TokenClassificationPipeline",
164
+ "VideoClassificationPipeline",
165
+ "ZeroShotAudioClassificationPipeline",
166
+ "ZeroShotClassificationPipeline",
167
+ "ZeroShotImageClassificationPipeline",
168
+ "ZeroShotObjectDetectionPipeline",
169
+ "pipeline",
170
+ ],
171
+ "processing_utils": [
172
+ "AudioKwargs",
173
+ "ImagesKwargs",
174
+ "ProcessingKwargs",
175
+ "ProcessorMixin",
176
+ "TextKwargs",
177
+ "VideosKwargs",
178
+ ],
179
+ "quantizers": [],
180
+ "testing_utils": [],
181
+ "tokenization_python": ["PreTrainedTokenizer", "PythonBackend"],
182
+ "tokenization_utils": [],
183
+ "tokenization_utils_base": [
184
+ "AddedToken",
185
+ "BatchEncoding",
186
+ "CharSpan",
187
+ "PreTrainedTokenizerBase",
188
+ "TokenSpan",
189
+ ],
190
+ "tokenization_utils_fast": [],
191
+ "tokenization_utils_sentencepiece": ["SentencePieceBackend"],
192
+ "trainer_callback": [
193
+ "DefaultFlowCallback",
194
+ "EarlyStoppingCallback",
195
+ "PrinterCallback",
196
+ "ProgressCallback",
197
+ "TrainerCallback",
198
+ "TrainerControl",
199
+ "TrainerState",
200
+ ],
201
+ "trainer_utils": [
202
+ "EvalPrediction",
203
+ "IntervalStrategy",
204
+ "SchedulerType",
205
+ "enable_full_determinism",
206
+ "set_seed",
207
+ ],
208
+ "training_args": ["TrainingArguments"],
209
+ "training_args_seq2seq": ["Seq2SeqTrainingArguments"],
210
+ "utils": [
211
+ "CONFIG_NAME",
212
+ "MODEL_CARD_NAME",
213
+ "SPIECE_UNDERLINE",
214
+ "WEIGHTS_NAME",
215
+ "TensorType",
216
+ "add_end_docstrings",
217
+ "add_start_docstrings",
218
+ "is_apex_available",
219
+ "is_av_available",
220
+ "is_bitsandbytes_available",
221
+ "is_datasets_available",
222
+ "is_faiss_available",
223
+ "is_matplotlib_available",
224
+ "is_mlx_available",
225
+ "is_phonemizer_available",
226
+ "is_psutil_available",
227
+ "is_py3nvml_available",
228
+ "is_pyctcdecode_available",
229
+ "is_sacremoses_available",
230
+ "is_scipy_available",
231
+ "is_sentencepiece_available",
232
+ "is_sklearn_available",
233
+ "is_speech_available",
234
+ "is_timm_available",
235
+ "is_tokenizers_available",
236
+ "is_torch_available",
237
+ "is_torch_hpu_available",
238
+ "is_torch_mlu_available",
239
+ "is_torch_musa_available",
240
+ "is_torch_neuroncore_available",
241
+ "is_torch_npu_available",
242
+ "is_torchvision_available",
243
+ "is_torch_xla_available",
244
+ "is_torch_xpu_available",
245
+ "is_vision_available",
246
+ "logging",
247
+ ],
248
+ "utils.import_utils": ["requires_backends"],
249
+ "utils.kernel_config": ["KernelConfig"],
250
+ "utils.quantization_config": [
251
+ "AqlmConfig",
252
+ "AutoRoundConfig",
253
+ "AwqConfig",
254
+ "BitNetQuantConfig",
255
+ "BitsAndBytesConfig",
256
+ "CompressedTensorsConfig",
257
+ "EetqConfig",
258
+ "FbgemmFp8Config",
259
+ "FineGrainedFP8Config",
260
+ "FourOverSixConfig",
261
+ "FPQuantConfig",
262
+ "GPTQConfig",
263
+ "HiggsConfig",
264
+ "HqqConfig",
265
+ "MetalConfig",
266
+ "Mxfp4Config",
267
+ "QuantoConfig",
268
+ "QuarkConfig",
269
+ "SinqConfig",
270
+ "SpQRConfig",
271
+ "TorchAoConfig",
272
+ "VptqConfig",
273
+ ],
274
+ "video_utils": [],
275
+ }
276
+
277
+ # tokenizers-backed objects
278
+ try:
279
+ if not is_tokenizers_available():
280
+ raise OptionalDependencyNotAvailable()
281
+ except OptionalDependencyNotAvailable:
282
+ from .utils import dummy_tokenizers_objects
283
+
284
+ _import_structure["utils.dummy_tokenizers_objects"] = [
285
+ name for name in dir(dummy_tokenizers_objects) if not name.startswith("_")
286
+ ]
287
+ else:
288
+ # Fast tokenizers structure
289
+ _import_structure["tokenization_utils_tokenizers"] = [
290
+ "PreTrainedTokenizerFast",
291
+ "TokenizersBackend",
292
+ ]
293
+
294
+
295
+ try:
296
+ if not (is_sentencepiece_available() and is_tokenizers_available()):
297
+ raise OptionalDependencyNotAvailable()
298
+ except OptionalDependencyNotAvailable:
299
+ from .utils import dummy_sentencepiece_and_tokenizers_objects
300
+
301
+ _import_structure["utils.dummy_sentencepiece_and_tokenizers_objects"] = [
302
+ name for name in dir(dummy_sentencepiece_and_tokenizers_objects) if not name.startswith("_")
303
+ ]
304
+ else:
305
+ _import_structure["convert_slow_tokenizer"] = [
306
+ "SLOW_TO_FAST_CONVERTERS",
307
+ "convert_slow_tokenizer",
308
+ ]
309
+
310
+ try:
311
+ if not (is_mistral_common_available()):
312
+ raise OptionalDependencyNotAvailable()
313
+ except OptionalDependencyNotAvailable:
314
+ from .utils import dummy_mistral_common_objects
315
+
316
+ _import_structure["utils.dummy_mistral_common_objects"] = [
317
+ name for name in dir(dummy_mistral_common_objects) if not name.startswith("_")
318
+ ]
319
+ else:
320
+ _import_structure["tokenization_mistral_common"] = ["MistralCommonBackend"]
321
+
322
+ # Vision-specific objects
323
+ try:
324
+ if not is_vision_available():
325
+ raise OptionalDependencyNotAvailable()
326
+ except OptionalDependencyNotAvailable:
327
+ from .utils import dummy_vision_objects
328
+
329
+ _import_structure["utils.dummy_vision_objects"] = [
330
+ name for name in dir(dummy_vision_objects) if not name.startswith("_")
331
+ ]
332
+ else:
333
+ _import_structure["image_processing_backends"] = ["PilBackend"]
334
+ _import_structure["image_processing_base"] = ["ImageProcessingMixin"]
335
+ _import_structure["image_processing_utils"] = ["BaseImageProcessor"]
336
+ _import_structure["image_utils"] = ["ImageFeatureExtractionMixin"]
337
+
338
+ try:
339
+ if not is_torchvision_available():
340
+ raise OptionalDependencyNotAvailable()
341
+ except OptionalDependencyNotAvailable:
342
+ from .utils import dummy_torchvision_objects
343
+
344
+ _import_structure["utils.dummy_torchvision_objects"] = [
345
+ name for name in dir(dummy_torchvision_objects) if not name.startswith("_")
346
+ ]
347
+ else:
348
+ _import_structure.setdefault("image_processing_backends", [])
349
+ _import_structure["image_processing_backends"] += ["TorchvisionBackend"]
350
+ _import_structure["video_processing_utils"] = ["BaseVideoProcessor"]
351
+
352
+ # PyTorch-backed objects
353
+ try:
354
+ if not is_torch_available():
355
+ raise OptionalDependencyNotAvailable()
356
+ except OptionalDependencyNotAvailable:
357
+ from .utils import dummy_pt_objects
358
+
359
+ _import_structure["utils.dummy_pt_objects"] = [name for name in dir(dummy_pt_objects) if not name.startswith("_")]
360
+ else:
361
+ _import_structure["model_debugging_utils"] = [
362
+ "model_addition_debugger_context",
363
+ ]
364
+ _import_structure["activations"] = []
365
+ _import_structure["cache_utils"] = [
366
+ "CacheLayerMixin",
367
+ "DynamicLayer",
368
+ "StaticLayer",
369
+ "StaticSlidingWindowLayer",
370
+ "QuantoQuantizedLayer",
371
+ "HQQQuantizedLayer",
372
+ "Cache",
373
+ "DynamicCache",
374
+ "EncoderDecoderCache",
375
+ "QuantizedCache",
376
+ "StaticCache",
377
+ ]
378
+ _import_structure["data.datasets"] = [
379
+ "GlueDataset",
380
+ "GlueDataTrainingArguments",
381
+ "SquadDataset",
382
+ "SquadDataTrainingArguments",
383
+ ]
384
+ _import_structure["generation"].extend(
385
+ [
386
+ "AlternatingCodebooksLogitsProcessor",
387
+ "BayesianDetectorConfig",
388
+ "BayesianDetectorModel",
389
+ "ClassifierFreeGuidanceLogitsProcessor",
390
+ "ContinuousBatchingManager",
391
+ "ContinuousMixin",
392
+ "EncoderNoRepeatNGramLogitsProcessor",
393
+ "EncoderRepetitionPenaltyLogitsProcessor",
394
+ "EosTokenCriteria",
395
+ "EpsilonLogitsWarper",
396
+ "MinPLogitsWarper",
397
+ "EtaLogitsWarper",
398
+ "ExponentialDecayLengthPenalty",
399
+ "ForcedBOSTokenLogitsProcessor",
400
+ "ForcedEOSTokenLogitsProcessor",
401
+ "GenerationMixin",
402
+ "InfNanRemoveLogitsProcessor",
403
+ "LogitNormalization",
404
+ "LogitsProcessor",
405
+ "LogitsProcessorList",
406
+ "MaxLengthCriteria",
407
+ "MaxTimeCriteria",
408
+ "MinLengthLogitsProcessor",
409
+ "MinNewTokensLengthLogitsProcessor",
410
+ "NoBadWordsLogitsProcessor",
411
+ "NoRepeatNGramLogitsProcessor",
412
+ "PrefixConstrainedLogitsProcessor",
413
+ "RepetitionPenaltyLogitsProcessor",
414
+ "SequenceBiasLogitsProcessor",
415
+ "StoppingCriteria",
416
+ "StoppingCriteriaList",
417
+ "StopStringCriteria",
418
+ "SuppressTokensAtBeginLogitsProcessor",
419
+ "SuppressTokensLogitsProcessor",
420
+ "SynthIDTextWatermarkDetector",
421
+ "SynthIDTextWatermarkingConfig",
422
+ "SynthIDTextWatermarkLogitsProcessor",
423
+ "TemperatureLogitsWarper",
424
+ "TopHLogitsWarper",
425
+ "TopKLogitsWarper",
426
+ "TopPLogitsWarper",
427
+ "TypicalLogitsWarper",
428
+ "UnbatchedClassifierFreeGuidanceLogitsProcessor",
429
+ "WatermarkDetector",
430
+ "WatermarkLogitsProcessor",
431
+ "WhisperTimeStampLogitsProcessor",
432
+ ]
433
+ )
434
+
435
+ # PyTorch domain libraries integration
436
+ _import_structure["integrations.executorch"] = [
437
+ "TorchExportableModuleWithStaticCache",
438
+ "convert_and_export_with_cache",
439
+ ]
440
+
441
+ _import_structure["core_model_loading"] = [
442
+ "Chunk",
443
+ "Concatenate",
444
+ "ConversionOps",
445
+ "MergeModulelist",
446
+ "PermuteForRope",
447
+ "SplitModulelist",
448
+ "WeightConverter",
449
+ ]
450
+ _import_structure["modeling_flash_attention_utils"] = []
451
+ _import_structure["modeling_layers"] = ["GradientCheckpointingLayer"]
452
+ _import_structure["modeling_outputs"] = []
453
+ _import_structure["backbone_utils"] = ["BackboneConfigMixin", "BackboneMixin"]
454
+ _import_structure["modeling_rope_utils"] = ["ROPE_INIT_FUNCTIONS", "dynamic_rope_update", "RopeParameters"]
455
+ _import_structure["modeling_utils"] = ["PreTrainedModel", "AttentionInterface"]
456
+ _import_structure["masking_utils"] = ["AttentionMaskInterface"]
457
+ _import_structure["optimization"] = [
458
+ "Adafactor",
459
+ "get_constant_schedule",
460
+ "get_constant_schedule_with_warmup",
461
+ "get_cosine_schedule_with_warmup",
462
+ "get_cosine_with_hard_restarts_schedule_with_warmup",
463
+ "get_cosine_with_min_lr_schedule_with_warmup",
464
+ "get_cosine_with_min_lr_schedule_with_warmup_lr_rate",
465
+ "get_greedy_schedule",
466
+ "get_inverse_sqrt_schedule",
467
+ "get_linear_schedule_with_warmup",
468
+ "get_polynomial_decay_schedule_with_warmup",
469
+ "get_reduce_on_plateau_schedule",
470
+ "get_scheduler",
471
+ "get_wsd_schedule",
472
+ "GreedyLR",
473
+ ]
474
+ _import_structure["pytorch_utils"] = ["Conv1D", "apply_chunking_to_forward"]
475
+ _import_structure["time_series_utils"] = []
476
+ _import_structure["trainer"] = ["Trainer"]
477
+ _import_structure["trainer_pt_utils"] = ["torch_distributed_zero_first"]
478
+ _import_structure["trainer_seq2seq"] = ["Seq2SeqTrainer"]
479
+
480
+
481
+ # Direct imports for type-checking
482
+ if TYPE_CHECKING:
483
+ # All modeling imports
484
+ # Models
485
+ from .backbone_utils import BackboneConfigMixin, BackboneMixin
486
+ from .cache_utils import Cache as Cache
487
+ from .cache_utils import DynamicCache as DynamicCache
488
+ from .cache_utils import DynamicLayer as DynamicLayer
489
+ from .cache_utils import EncoderDecoderCache as EncoderDecoderCache
490
+ from .cache_utils import HQQQuantizedLayer as HQQQuantizedLayer
491
+ from .cache_utils import QuantizedCache as QuantizedCache
492
+ from .cache_utils import QuantoQuantizedLayer as QuantoQuantizedLayer
493
+ from .cache_utils import StaticCache as StaticCache
494
+ from .cache_utils import StaticLayer as StaticLayer
495
+ from .cache_utils import StaticSlidingWindowLayer as StaticSlidingWindowLayer
496
+ from .configuration_utils import PreTrainedConfig as PreTrainedConfig
497
+ from .configuration_utils import PretrainedConfig as PretrainedConfig
498
+ from .convert_slow_tokenizer import SLOW_TO_FAST_CONVERTERS as SLOW_TO_FAST_CONVERTERS
499
+ from .convert_slow_tokenizer import convert_slow_tokenizer as convert_slow_tokenizer
500
+ from .core_model_loading import Chunk as Chunk
501
+ from .core_model_loading import Concatenate as Concatenate
502
+ from .core_model_loading import ConversionOps as ConversionOps
503
+ from .core_model_loading import MergeModulelist as MergeModulelist
504
+ from .core_model_loading import PermuteForRope as PermuteForRope
505
+ from .core_model_loading import SplitModulelist as SplitModulelist
506
+ from .core_model_loading import WeightConverter as WeightConverter
507
+
508
+ # Data
509
+ from .data import DataProcessor as DataProcessor
510
+ from .data import InputExample as InputExample
511
+ from .data import InputFeatures as InputFeatures
512
+ from .data import SingleSentenceClassificationProcessor as SingleSentenceClassificationProcessor
513
+ from .data import SquadExample as SquadExample
514
+ from .data import SquadFeatures as SquadFeatures
515
+ from .data import SquadV1Processor as SquadV1Processor
516
+ from .data import SquadV2Processor as SquadV2Processor
517
+ from .data import glue_compute_metrics as glue_compute_metrics
518
+ from .data import glue_convert_examples_to_features as glue_convert_examples_to_features
519
+ from .data import glue_output_modes as glue_output_modes
520
+ from .data import glue_processors as glue_processors
521
+ from .data import glue_tasks_num_labels as glue_tasks_num_labels
522
+ from .data import squad_convert_examples_to_features as squad_convert_examples_to_features
523
+ from .data import xnli_compute_metrics as xnli_compute_metrics
524
+ from .data import xnli_output_modes as xnli_output_modes
525
+ from .data import xnli_processors as xnli_processors
526
+ from .data import xnli_tasks_num_labels as xnli_tasks_num_labels
527
+ from .data.data_collator import DataCollator as DataCollator
528
+ from .data.data_collator import DataCollatorForLanguageModeling as DataCollatorForLanguageModeling
529
+ from .data.data_collator import DataCollatorForMultipleChoice as DataCollatorForMultipleChoice
530
+ from .data.data_collator import (
531
+ DataCollatorForPermutationLanguageModeling as DataCollatorForPermutationLanguageModeling,
532
+ )
533
+ from .data.data_collator import DataCollatorForSeq2Seq as DataCollatorForSeq2Seq
534
+ from .data.data_collator import DataCollatorForSOP as DataCollatorForSOP
535
+ from .data.data_collator import DataCollatorForTokenClassification as DataCollatorForTokenClassification
536
+ from .data.data_collator import DataCollatorForWholeWordMask as DataCollatorForWholeWordMask
537
+ from .data.data_collator import DataCollatorWithFlattening as DataCollatorWithFlattening
538
+ from .data.data_collator import DataCollatorWithPadding as DataCollatorWithPadding
539
+ from .data.data_collator import DefaultDataCollator as DefaultDataCollator
540
+ from .data.data_collator import default_data_collator as default_data_collator
541
+ from .data.datasets import GlueDataset as GlueDataset
542
+ from .data.datasets import GlueDataTrainingArguments as GlueDataTrainingArguments
543
+ from .data.datasets import SquadDataset as SquadDataset
544
+ from .data.datasets import SquadDataTrainingArguments as SquadDataTrainingArguments
545
+ from .feature_extraction_sequence_utils import SequenceFeatureExtractor as SequenceFeatureExtractor
546
+
547
+ # Feature Extractor
548
+ from .feature_extraction_utils import BatchFeature as BatchFeature
549
+ from .feature_extraction_utils import FeatureExtractionMixin as FeatureExtractionMixin
550
+
551
+ # Generation
552
+ from .generation import AlternatingCodebooksLogitsProcessor as AlternatingCodebooksLogitsProcessor
553
+ from .generation import AsyncTextIteratorStreamer as AsyncTextIteratorStreamer
554
+ from .generation import BayesianDetectorConfig as BayesianDetectorConfig
555
+ from .generation import BayesianDetectorModel as BayesianDetectorModel
556
+ from .generation import ClassifierFreeGuidanceLogitsProcessor as ClassifierFreeGuidanceLogitsProcessor
557
+ from .generation import CompileConfig as CompileConfig
558
+ from .generation import ContinuousBatchingConfig as ContinuousBatchingConfig
559
+ from .generation import ContinuousBatchingManager as ContinuousBatchingManager
560
+ from .generation import ContinuousMixin as ContinuousMixin
561
+ from .generation import EncoderNoRepeatNGramLogitsProcessor as EncoderNoRepeatNGramLogitsProcessor
562
+ from .generation import EncoderRepetitionPenaltyLogitsProcessor as EncoderRepetitionPenaltyLogitsProcessor
563
+ from .generation import EosTokenCriteria as EosTokenCriteria
564
+ from .generation import EpsilonLogitsWarper as EpsilonLogitsWarper
565
+ from .generation import EtaLogitsWarper as EtaLogitsWarper
566
+ from .generation import ExponentialDecayLengthPenalty as ExponentialDecayLengthPenalty
567
+ from .generation import ForcedBOSTokenLogitsProcessor as ForcedBOSTokenLogitsProcessor
568
+ from .generation import ForcedEOSTokenLogitsProcessor as ForcedEOSTokenLogitsProcessor
569
+ from .generation import GenerationConfig as GenerationConfig
570
+ from .generation import GenerationMixin as GenerationMixin
571
+ from .generation import InfNanRemoveLogitsProcessor as InfNanRemoveLogitsProcessor
572
+ from .generation import LogitNormalization as LogitNormalization
573
+ from .generation import LogitsProcessor as LogitsProcessor
574
+ from .generation import LogitsProcessorList as LogitsProcessorList
575
+ from .generation import MaxLengthCriteria as MaxLengthCriteria
576
+ from .generation import MaxTimeCriteria as MaxTimeCriteria
577
+ from .generation import MinLengthLogitsProcessor as MinLengthLogitsProcessor
578
+ from .generation import MinNewTokensLengthLogitsProcessor as MinNewTokensLengthLogitsProcessor
579
+ from .generation import MinPLogitsWarper as MinPLogitsWarper
580
+ from .generation import NoBadWordsLogitsProcessor as NoBadWordsLogitsProcessor
581
+ from .generation import NoRepeatNGramLogitsProcessor as NoRepeatNGramLogitsProcessor
582
+ from .generation import PrefixConstrainedLogitsProcessor as PrefixConstrainedLogitsProcessor
583
+ from .generation import RepetitionPenaltyLogitsProcessor as RepetitionPenaltyLogitsProcessor
584
+ from .generation import SequenceBiasLogitsProcessor as SequenceBiasLogitsProcessor
585
+ from .generation import StoppingCriteria as StoppingCriteria
586
+ from .generation import StoppingCriteriaList as StoppingCriteriaList
587
+ from .generation import StopStringCriteria as StopStringCriteria
588
+ from .generation import SuppressTokensAtBeginLogitsProcessor as SuppressTokensAtBeginLogitsProcessor
589
+ from .generation import SuppressTokensLogitsProcessor as SuppressTokensLogitsProcessor
590
+ from .generation import SynthIDTextWatermarkDetector as SynthIDTextWatermarkDetector
591
+ from .generation import SynthIDTextWatermarkingConfig as SynthIDTextWatermarkingConfig
592
+ from .generation import SynthIDTextWatermarkLogitsProcessor as SynthIDTextWatermarkLogitsProcessor
593
+ from .generation import TemperatureLogitsWarper as TemperatureLogitsWarper
594
+ from .generation import TextIteratorStreamer as TextIteratorStreamer
595
+ from .generation import TextStreamer as TextStreamer
596
+ from .generation import TopHLogitsWarper as TopHLogitsWarper
597
+ from .generation import TopKLogitsWarper as TopKLogitsWarper
598
+ from .generation import TopPLogitsWarper as TopPLogitsWarper
599
+ from .generation import TypicalLogitsWarper as TypicalLogitsWarper
600
+ from .generation import (
601
+ UnbatchedClassifierFreeGuidanceLogitsProcessor as UnbatchedClassifierFreeGuidanceLogitsProcessor,
602
+ )
603
+ from .generation import WatermarkDetector as WatermarkDetector
604
+ from .generation import WatermarkingConfig as WatermarkingConfig
605
+ from .generation import WatermarkLogitsProcessor as WatermarkLogitsProcessor
606
+ from .generation import WhisperTimeStampLogitsProcessor as WhisperTimeStampLogitsProcessor
607
+ from .hf_argparser import HfArgumentParser as HfArgumentParser
608
+ from .image_processing_backends import PilBackend as PilBackend
609
+ from .image_processing_backends import TorchvisionBackend as TorchvisionBackend
610
+ from .image_processing_base import ImageProcessingMixin as ImageProcessingMixin
611
+ from .image_processing_utils import BaseImageProcessor as BaseImageProcessor
612
+ from .image_utils import ImageFeatureExtractionMixin as ImageFeatureExtractionMixin
613
+
614
+ # Integrations
615
+ from .integrations import is_clearml_available as is_clearml_available
616
+ from .integrations import is_comet_available as is_comet_available
617
+ from .integrations import is_dvclive_available as is_dvclive_available
618
+ from .integrations import is_neptune_available as is_neptune_available
619
+ from .integrations import is_optuna_available as is_optuna_available
620
+ from .integrations import is_ray_available as is_ray_available
621
+ from .integrations import is_ray_tune_available as is_ray_tune_available
622
+ from .integrations import is_swanlab_available as is_swanlab_available
623
+ from .integrations import is_tensorboard_available as is_tensorboard_available
624
+ from .integrations import is_trackio_available as is_trackio_available
625
+ from .integrations import is_wandb_available as is_wandb_available
626
+ from .integrations.executorch import TorchExportableModuleWithStaticCache as TorchExportableModuleWithStaticCache
627
+ from .integrations.executorch import convert_and_export_with_cache as convert_and_export_with_cache
628
+ from .masking_utils import AttentionMaskInterface as AttentionMaskInterface
629
+ from .model_debugging_utils import model_addition_debugger_context as model_addition_debugger_context
630
+ from .modeling_layers import GradientCheckpointingLayer as GradientCheckpointingLayer
631
+ from .modeling_rope_utils import ROPE_INIT_FUNCTIONS as ROPE_INIT_FUNCTIONS
632
+ from .modeling_rope_utils import RopeParameters as RopeParameters
633
+ from .modeling_rope_utils import dynamic_rope_update as dynamic_rope_update
634
+ from .modeling_utils import AttentionInterface as AttentionInterface
635
+ from .modeling_utils import PreTrainedModel as PreTrainedModel
636
+ from .models import *
637
+ from .models.timm_wrapper import TimmWrapperImageProcessor as TimmWrapperImageProcessor
638
+
639
+ # Optimization
640
+ from .optimization import Adafactor as Adafactor
641
+ from .optimization import GreedyLR as GreedyLR
642
+ from .optimization import get_constant_schedule as get_constant_schedule
643
+ from .optimization import get_constant_schedule_with_warmup as get_constant_schedule_with_warmup
644
+ from .optimization import get_cosine_schedule_with_warmup as get_cosine_schedule_with_warmup
645
+ from .optimization import (
646
+ get_cosine_with_hard_restarts_schedule_with_warmup as get_cosine_with_hard_restarts_schedule_with_warmup,
647
+ )
648
+ from .optimization import (
649
+ get_cosine_with_min_lr_schedule_with_warmup as get_cosine_with_min_lr_schedule_with_warmup,
650
+ )
651
+ from .optimization import (
652
+ get_cosine_with_min_lr_schedule_with_warmup_lr_rate as get_cosine_with_min_lr_schedule_with_warmup_lr_rate,
653
+ )
654
+ from .optimization import get_greedy_schedule as get_greedy_schedule
655
+ from .optimization import get_inverse_sqrt_schedule as get_inverse_sqrt_schedule
656
+ from .optimization import get_linear_schedule_with_warmup as get_linear_schedule_with_warmup
657
+ from .optimization import get_polynomial_decay_schedule_with_warmup as get_polynomial_decay_schedule_with_warmup
658
+ from .optimization import get_scheduler as get_scheduler
659
+ from .optimization import get_wsd_schedule as get_wsd_schedule
660
+
661
+ # Pipelines
662
+ from .pipelines import AnyToAnyPipeline as AnyToAnyPipeline
663
+ from .pipelines import AudioClassificationPipeline as AudioClassificationPipeline
664
+ from .pipelines import AutomaticSpeechRecognitionPipeline as AutomaticSpeechRecognitionPipeline
665
+ from .pipelines import CsvPipelineDataFormat as CsvPipelineDataFormat
666
+ from .pipelines import DepthEstimationPipeline as DepthEstimationPipeline
667
+ from .pipelines import DocumentQuestionAnsweringPipeline as DocumentQuestionAnsweringPipeline
668
+ from .pipelines import FeatureExtractionPipeline as FeatureExtractionPipeline
669
+ from .pipelines import FillMaskPipeline as FillMaskPipeline
670
+ from .pipelines import ImageClassificationPipeline as ImageClassificationPipeline
671
+ from .pipelines import ImageFeatureExtractionPipeline as ImageFeatureExtractionPipeline
672
+ from .pipelines import ImageSegmentationPipeline as ImageSegmentationPipeline
673
+ from .pipelines import ImageTextToTextPipeline as ImageTextToTextPipeline
674
+ from .pipelines import JsonPipelineDataFormat as JsonPipelineDataFormat
675
+ from .pipelines import KeypointMatchingPipeline as KeypointMatchingPipeline
676
+ from .pipelines import MaskGenerationPipeline as MaskGenerationPipeline
677
+ from .pipelines import NerPipeline as NerPipeline
678
+ from .pipelines import ObjectDetectionPipeline as ObjectDetectionPipeline
679
+ from .pipelines import PipedPipelineDataFormat as PipedPipelineDataFormat
680
+ from .pipelines import Pipeline as Pipeline
681
+ from .pipelines import PipelineDataFormat as PipelineDataFormat
682
+ from .pipelines import TableQuestionAnsweringPipeline as TableQuestionAnsweringPipeline
683
+ from .pipelines import TextClassificationPipeline as TextClassificationPipeline
684
+ from .pipelines import TextGenerationPipeline as TextGenerationPipeline
685
+ from .pipelines import TextToAudioPipeline as TextToAudioPipeline
686
+ from .pipelines import TokenClassificationPipeline as TokenClassificationPipeline
687
+ from .pipelines import VideoClassificationPipeline as VideoClassificationPipeline
688
+ from .pipelines import ZeroShotAudioClassificationPipeline as ZeroShotAudioClassificationPipeline
689
+ from .pipelines import ZeroShotClassificationPipeline as ZeroShotClassificationPipeline
690
+ from .pipelines import ZeroShotImageClassificationPipeline as ZeroShotImageClassificationPipeline
691
+ from .pipelines import ZeroShotObjectDetectionPipeline as ZeroShotObjectDetectionPipeline
692
+ from .pipelines import pipeline as pipeline
693
+ from .processing_utils import AudioKwargs as AudioKwargs
694
+ from .processing_utils import ImagesKwargs as ImagesKwargs
695
+ from .processing_utils import ProcessingKwargs as ProcessingKwargs
696
+ from .processing_utils import ProcessorMixin as ProcessorMixin
697
+ from .processing_utils import TextKwargs as TextKwargs
698
+ from .processing_utils import VideosKwargs as VideosKwargs
699
+ from .pytorch_utils import Conv1D as Conv1D
700
+ from .pytorch_utils import apply_chunking_to_forward as apply_chunking_to_forward
701
+
702
+ # Tokenization
703
+ from .tokenization_python import PreTrainedTokenizer as PreTrainedTokenizer
704
+ from .tokenization_python import PythonBackend as PythonBackend
705
+ from .tokenization_utils_base import AddedToken as AddedToken
706
+ from .tokenization_utils_base import BatchEncoding as BatchEncoding
707
+ from .tokenization_utils_base import CharSpan as CharSpan
708
+ from .tokenization_utils_base import PreTrainedTokenizerBase as PreTrainedTokenizerBase
709
+ from .tokenization_utils_base import TokenSpan as TokenSpan
710
+
711
+ # Tokenization
712
+ from .tokenization_utils_sentencepiece import SentencePieceBackend as SentencePieceBackend
713
+ from .tokenization_utils_tokenizers import PreTrainedTokenizerFast as PreTrainedTokenizerFast
714
+ from .tokenization_utils_tokenizers import (
715
+ TokenizersBackend as TokenizersBackend,
716
+ )
717
+
718
+ # Trainer
719
+ from .trainer import Trainer as Trainer
720
+ from .trainer_callback import DefaultFlowCallback as DefaultFlowCallback
721
+ from .trainer_callback import EarlyStoppingCallback as EarlyStoppingCallback
722
+ from .trainer_callback import PrinterCallback as PrinterCallback
723
+ from .trainer_callback import ProgressCallback as ProgressCallback
724
+ from .trainer_callback import TrainerCallback as TrainerCallback
725
+ from .trainer_callback import TrainerControl as TrainerControl
726
+ from .trainer_callback import TrainerState as TrainerState
727
+ from .trainer_pt_utils import torch_distributed_zero_first as torch_distributed_zero_first
728
+ from .trainer_seq2seq import Seq2SeqTrainer as Seq2SeqTrainer
729
+ from .trainer_utils import EvalPrediction as EvalPrediction
730
+ from .trainer_utils import IntervalStrategy as IntervalStrategy
731
+ from .trainer_utils import SchedulerType as SchedulerType
732
+ from .trainer_utils import enable_full_determinism as enable_full_determinism
733
+ from .trainer_utils import set_seed as set_seed
734
+ from .training_args import TrainingArguments as TrainingArguments
735
+ from .training_args_seq2seq import Seq2SeqTrainingArguments as Seq2SeqTrainingArguments
736
+
737
+ # Files and general utilities
738
+ from .utils import CONFIG_NAME as CONFIG_NAME
739
+ from .utils import MODEL_CARD_NAME as MODEL_CARD_NAME
740
+ from .utils import SPIECE_UNDERLINE as SPIECE_UNDERLINE
741
+ from .utils import WEIGHTS_NAME as WEIGHTS_NAME
742
+ from .utils import TensorType as TensorType
743
+ from .utils import add_end_docstrings as add_end_docstrings
744
+ from .utils import add_start_docstrings as add_start_docstrings
745
+ from .utils import is_apex_available as is_apex_available
746
+ from .utils import is_av_available as is_av_available
747
+ from .utils import is_datasets_available as is_datasets_available
748
+ from .utils import is_faiss_available as is_faiss_available
749
+ from .utils import is_matplotlib_available as is_matplotlib_available
750
+ from .utils import is_phonemizer_available as is_phonemizer_available
751
+ from .utils import is_psutil_available as is_psutil_available
752
+ from .utils import is_py3nvml_available as is_py3nvml_available
753
+ from .utils import is_pyctcdecode_available as is_pyctcdecode_available
754
+ from .utils import is_sacremoses_available as is_sacremoses_available
755
+ from .utils import is_sklearn_available as is_sklearn_available
756
+ from .utils import is_torch_hpu_available as is_torch_hpu_available
757
+ from .utils import is_torch_mlu_available as is_torch_mlu_available
758
+ from .utils import is_torch_musa_available as is_torch_musa_available
759
+ from .utils import is_torch_neuroncore_available as is_torch_neuroncore_available
760
+ from .utils import is_torch_npu_available as is_torch_npu_available
761
+ from .utils import is_torch_xla_available as is_torch_xla_available
762
+ from .utils import is_torch_xpu_available as is_torch_xpu_available
763
+ from .utils.import_utils import requires_backends
764
+ from .utils.kernel_config import KernelConfig as KernelConfig
765
+
766
+ # Quantization config
767
+ from .utils.quantization_config import AqlmConfig as AqlmConfig
768
+ from .utils.quantization_config import AutoRoundConfig as AutoRoundConfig
769
+ from .utils.quantization_config import AwqConfig as AwqConfig
770
+ from .utils.quantization_config import BitNetQuantConfig as BitNetQuantConfig
771
+ from .utils.quantization_config import BitsAndBytesConfig as BitsAndBytesConfig
772
+ from .utils.quantization_config import CompressedTensorsConfig as CompressedTensorsConfig
773
+ from .utils.quantization_config import EetqConfig as EetqConfig
774
+ from .utils.quantization_config import FbgemmFp8Config as FbgemmFp8Config
775
+ from .utils.quantization_config import FineGrainedFP8Config as FineGrainedFP8Config
776
+ from .utils.quantization_config import FourOverSixConfig as FourOverSixConfig
777
+ from .utils.quantization_config import FPQuantConfig as FPQuantConfig
778
+ from .utils.quantization_config import GPTQConfig as GPTQConfig
779
+ from .utils.quantization_config import HiggsConfig as HiggsConfig
780
+ from .utils.quantization_config import HqqConfig as HqqConfig
781
+ from .utils.quantization_config import MetalConfig as MetalConfig
782
+ from .utils.quantization_config import QuantoConfig as QuantoConfig
783
+ from .utils.quantization_config import QuarkConfig as QuarkConfig
784
+ from .utils.quantization_config import SinqConfig as SinqConfig
785
+ from .utils.quantization_config import SpQRConfig as SpQRConfig
786
+ from .utils.quantization_config import TorchAoConfig as TorchAoConfig
787
+ from .utils.quantization_config import VptqConfig as VptqConfig
788
+ from .video_processing_utils import BaseVideoProcessor as BaseVideoProcessor
789
+ else:
790
+ _import_structure = {k: set(v) for k, v in _import_structure.items()}
791
+
792
+ import_structure = define_import_structure(Path(__file__).parent / "models", prefix="models")
793
+ import_structure[frozenset({})].update(_import_structure)
794
+
795
+ sys.modules[__name__] = _LazyModule(
796
+ __name__,
797
+ globals()["__file__"],
798
+ import_structure,
799
+ module_spec=__spec__,
800
+ extra_objects={"__version__": __version__},
801
+ )
802
+
803
+ def _create_module_alias(alias: str, target: str) -> None:
804
+ """
805
+ Lazily redirect legacy module paths to their replacements without importing heavy deps.
806
+ """
807
+ module = types.ModuleType(alias)
808
+ module.__doc__ = f"Alias module for backward compatibility with `{target}`."
809
+ # Set __file__ explicitly so that inspect.py's hasattr(module, '__file__') check
810
+ # never falls through to __getattr__ and triggers a premature (possibly circular) import.
811
+ module.__file__ = None
812
+
813
+ def _get_target():
814
+ return importlib.import_module(target, __name__)
815
+
816
+ module.__getattr__ = lambda name: getattr(_get_target(), name)
817
+ module.__dir__ = lambda: dir(_get_target())
818
+
819
+ sys.modules[alias] = module
820
+ setattr(sys.modules[__name__], alias.rsplit(".", 1)[-1], module)
821
+
822
+ _create_module_alias(f"{__name__}.tokenization_utils_fast", ".tokenization_utils_tokenizers")
823
+ _create_module_alias(f"{__name__}.tokenization_utils", ".tokenization_utils_sentencepiece")
824
+ _create_module_alias(f"{__name__}.image_processing_utils_fast", ".image_processing_backends")
825
+
826
+ for _proc_file in sorted((Path(__file__).parent / "models").rglob("image_processing_*.py")):
827
+ _model = _proc_file.parent.name
828
+ _module = _proc_file.stem
829
+ _target = f".models.{_model}.{_module}"
830
+ _create_module_alias(f"{__name__}.models.{_model}.{_module}_fast", _target)
831
+
832
+ # Also map XImageProcessorFast -> XImageProcessor for backward compat with old class names.
833
+ def getattr_factory(target):
834
+ def _getattr(name):
835
+ new_name = name.removesuffix("Fast")
836
+ logger.warning(
837
+ "Accessing `%s` from `%s`. Returning `%s` instead. Behavior may be "
838
+ "different and this alias will be removed in future versions.",
839
+ name,
840
+ target,
841
+ new_name,
842
+ )
843
+ return getattr(importlib.import_module(target, __name__), new_name)
844
+
845
+ return _getattr
846
+
847
+ sys.modules[f"{__name__}.models.{_model}.{_module}_fast"].__getattr__ = getattr_factory(_target)
848
+
849
+ if not is_torch_available():
850
+ logger.warning_advice(
851
+ "PyTorch was not found. Models won't be available and only tokenizers, configuration and file/data utilities can be used."
852
+ )
third_party/transformers/src/transformers/debug_utils.py ADDED
@@ -0,0 +1,348 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 collections
16
+
17
+ from .utils import ExplicitEnum, is_torch_available, logging
18
+
19
+
20
+ if is_torch_available():
21
+ import torch
22
+
23
+
24
+ logger = logging.get_logger(__name__)
25
+
26
+
27
+ class DebugUnderflowOverflow:
28
+ """
29
+ This debug class helps detect and understand where the model starts getting very large or very small, and more
30
+ importantly `nan` or `inf` weight and activation elements.
31
+
32
+ There are 2 working modes:
33
+
34
+ 1. Underflow/overflow detection (default)
35
+ 2. Specific batch absolute min/max tracing without detection
36
+
37
+ Mode 1: Underflow/overflow detection
38
+
39
+ To activate the underflow/overflow detection, initialize the object with the model :
40
+
41
+ ```python
42
+ debug_overflow = DebugUnderflowOverflow(model)
43
+ ```
44
+
45
+ then run the training as normal and if `nan` or `inf` gets detected in at least one of the weight, input or output
46
+ elements this module will throw an exception and will print `max_frames_to_save` frames that lead to this event,
47
+ each frame reporting
48
+
49
+ 1. the fully qualified module name plus the class name whose `forward` was run
50
+ 2. the absolute min and max value of all elements for each module weights, and the inputs and output
51
+
52
+ For example, here is the header and the last few frames in detection report for `google/mt5-small` run in fp16
53
+ mixed precision :
54
+
55
+ ```
56
+ Detected inf/nan during batch_number=0
57
+ Last 21 forward frames:
58
+ abs min abs max metadata
59
+ [...]
60
+ encoder.block.2.layer.1.DenseReluDense.wi_0 Linear
61
+ 2.17e-07 4.50e+00 weight
62
+ 1.79e-06 4.65e+00 input[0]
63
+ 2.68e-06 3.70e+01 output
64
+ encoder.block.2.layer.1.DenseReluDense.wi_1 Linear
65
+ 8.08e-07 2.66e+01 weight
66
+ 1.79e-06 4.65e+00 input[0]
67
+ 1.27e-04 2.37e+02 output
68
+ encoder.block.2.layer.1.DenseReluDense.wo Linear
69
+ 1.01e-06 6.44e+00 weight
70
+ 0.00e+00 9.74e+03 input[0]
71
+ 3.18e-04 6.27e+04 output
72
+ encoder.block.2.layer.1.DenseReluDense T5DenseGatedGeluDense
73
+ 1.79e-06 4.65e+00 input[0]
74
+ 3.18e-04 6.27e+04 output
75
+ encoder.block.2.layer.1.dropout Dropout
76
+ 3.18e-04 6.27e+04 input[0]
77
+ 0.00e+00 inf output
78
+ ```
79
+
80
+ You can see here, that `T5DenseGatedGeluDense.forward` resulted in output activations, whose absolute max value was
81
+ around 62.7K, which is very close to fp16's top limit of 64K. In the next frame we have `Dropout` which
82
+ renormalizes the weights, after it zeroed some of the elements, which pushes the absolute max value to more than
83
+ 64K, and we get an overflow.
84
+
85
+ As you can see it's the previous frames that we need to look into when the numbers start going into very large for
86
+ fp16 numbers.
87
+
88
+ The tracking is done in a forward hook, which gets invoked immediately after `forward` has completed.
89
+
90
+ By default the last 21 frames are printed. You can change the default to adjust for your needs. For example :
91
+
92
+ ```python
93
+ debug_overflow = DebugUnderflowOverflow(model, max_frames_to_save=100)
94
+ ```
95
+
96
+ To validate that you have set up this debugging feature correctly, and you intend to use it in a training that
97
+ may take hours to complete, first run it with normal tracing enabled for one of a few batches as explained in
98
+ the next section.
99
+
100
+
101
+ Mode 2. Specific batch absolute min/max tracing without detection
102
+
103
+ The second work mode is per-batch tracing with the underflow/overflow detection feature turned off.
104
+
105
+ Let's say you want to watch the absolute min and max values for all the ingredients of each `forward` call of a
106
+ given batch, and only do that for batches 1 and 3. Then you instantiate this class as :
107
+
108
+ ```python
109
+ debug_overflow = DebugUnderflowOverflow(model, trace_batch_nums=[1, 3])
110
+ ```
111
+
112
+ And now full batches 1 and 3 will be traced using the same format as explained above. Batches are 0-indexed.
113
+
114
+ This is helpful if you know that the program starts misbehaving after a certain batch number, so you can
115
+ fast-forward right to that area.
116
+
117
+
118
+ Early stopping:
119
+
120
+ You can also specify the batch number after which to stop the training, with :
121
+
122
+ ```python
123
+ debug_overflow = DebugUnderflowOverflow(model, trace_batch_nums=[1, 3], abort_after_batch_num=3)
124
+ ```
125
+
126
+ This feature is mainly useful in the tracing mode, but you can use it for any mode.
127
+
128
+
129
+ **Performance**:
130
+
131
+ As this module measures absolute `min`/``max` of each weight of the model on every forward it'll slow the training
132
+ down. Therefore remember to turn it off once the debugging needs have been met.
133
+
134
+ Args:
135
+ model (`nn.Module`):
136
+ The model to debug.
137
+ max_frames_to_save (`int`, *optional*, defaults to 21):
138
+ How many frames back to record
139
+ trace_batch_nums(`list[int]`, *optional*, defaults to `[]`):
140
+ Which batch numbers to trace (turns detection off)
141
+ abort_after_batch_num (`int``, *optional*):
142
+ Whether to abort after a certain batch number has finished
143
+ """
144
+
145
+ def __init__(self, model, max_frames_to_save=21, trace_batch_nums=None, abort_after_batch_num=None):
146
+ if trace_batch_nums is None:
147
+ trace_batch_nums = []
148
+ self.model = model
149
+ self.trace_batch_nums = trace_batch_nums
150
+ self.abort_after_batch_num = abort_after_batch_num
151
+
152
+ # keep a LIFO buffer of frames to dump as soon as inf/nan is encountered to give context to the problem emergence
153
+ self.frames = collections.deque([], max_frames_to_save)
154
+ self.frame = []
155
+ self.batch_number = 0
156
+ self.total_calls = 0
157
+ self.detected_overflow = False
158
+ self.prefix = " "
159
+
160
+ self.analyse_model()
161
+
162
+ self.register_forward_hook()
163
+
164
+ def save_frame(self, frame=None):
165
+ if frame is not None:
166
+ self.expand_frame(frame)
167
+ self.frames.append("\n".join(self.frame))
168
+ self.frame = [] # start a new frame
169
+
170
+ def expand_frame(self, line):
171
+ self.frame.append(line)
172
+
173
+ def trace_frames(self):
174
+ print("\n".join(self.frames))
175
+ self.frames = []
176
+
177
+ def reset_saved_frames(self):
178
+ self.frames = []
179
+
180
+ def dump_saved_frames(self):
181
+ print(f"\nDetected inf/nan during batch_number={self.batch_number}")
182
+ print(f"Last {len(self.frames)} forward frames:")
183
+ print(f"{'abs min':8} {'abs max':8} metadata")
184
+ print("\n".join(self.frames))
185
+ print("\n\n")
186
+ self.frames = []
187
+
188
+ def analyse_model(self):
189
+ # extract the fully qualified module names, to be able to report at run time. e.g.:
190
+ # encoder.block.2.layer.0.SelfAttention.o
191
+ #
192
+ # for shared weights only the first shared module name will be registered
193
+ self.module_names = {m: name for name, m in self.model.named_modules()}
194
+ # self.longest_module_name = max(len(v) for v in self.module_names.values())
195
+
196
+ def analyse_variable(self, var, ctx):
197
+ if torch.is_tensor(var):
198
+ self.expand_frame(get_abs_min_max(var, ctx))
199
+ if detect_overflow(var, ctx):
200
+ self.detected_overflow = True
201
+ elif var is None:
202
+ self.expand_frame(f"{'None':>17} {ctx}")
203
+ else:
204
+ self.expand_frame(f"{'not a tensor':>17} {ctx}")
205
+
206
+ def batch_start_frame(self):
207
+ self.expand_frame(f"\n\n{self.prefix} *** Starting batch number={self.batch_number} ***")
208
+ self.expand_frame(f"{'abs min':8} {'abs max':8} metadata")
209
+
210
+ def batch_end_frame(self):
211
+ self.expand_frame(f"{self.prefix} *** Finished batch number={self.batch_number - 1} ***\n\n")
212
+
213
+ def create_frame(self, module, input, output):
214
+ self.expand_frame(f"{self.prefix} {self.module_names[module]} {module.__class__.__name__}")
215
+
216
+ # params
217
+ for name, p in module.named_parameters(recurse=False):
218
+ self.analyse_variable(p, name)
219
+
220
+ # inputs
221
+ if isinstance(input, tuple):
222
+ for i, x in enumerate(input):
223
+ self.analyse_variable(x, f"input[{i}]")
224
+ else:
225
+ self.analyse_variable(input, "input")
226
+
227
+ # outputs
228
+ if isinstance(output, tuple):
229
+ for i, x in enumerate(output):
230
+ # possibly a tuple of tuples
231
+ if isinstance(x, tuple):
232
+ for j, y in enumerate(x):
233
+ self.analyse_variable(y, f"output[{i}][{j}]")
234
+ else:
235
+ self.analyse_variable(x, f"output[{i}]")
236
+ else:
237
+ self.analyse_variable(output, "output")
238
+
239
+ self.save_frame()
240
+
241
+ def register_forward_hook(self):
242
+ self.model.apply(self._register_forward_hook)
243
+
244
+ def _register_forward_hook(self, module):
245
+ module.register_forward_hook(self.forward_hook)
246
+
247
+ def forward_hook(self, module, input, output):
248
+ # - input is a tuple of packed inputs (could be non-Tensors)
249
+ # - output could be a Tensor or a tuple of Tensors and non-Tensors
250
+
251
+ last_frame_of_batch = False
252
+
253
+ trace_mode = self.batch_number in self.trace_batch_nums
254
+ if trace_mode:
255
+ self.reset_saved_frames()
256
+
257
+ if self.total_calls == 0:
258
+ self.batch_start_frame()
259
+ self.total_calls += 1
260
+
261
+ # count batch numbers - the very first forward hook of the batch will be called when the
262
+ # batch completes - i.e. it gets called very last - we know this batch has finished
263
+ if module == self.model:
264
+ self.batch_number += 1
265
+ last_frame_of_batch = True
266
+
267
+ self.create_frame(module, input, output)
268
+
269
+ # if last_frame_of_batch:
270
+ # self.batch_end_frame()
271
+
272
+ if trace_mode:
273
+ self.trace_frames()
274
+
275
+ if last_frame_of_batch:
276
+ self.batch_start_frame()
277
+
278
+ if self.detected_overflow and not trace_mode:
279
+ self.dump_saved_frames()
280
+
281
+ # now we can abort, as it's pointless to continue running
282
+ raise ValueError(
283
+ "DebugUnderflowOverflow: inf/nan detected, aborting as there is no point running further. "
284
+ "Please scroll up above this traceback to see the activation values prior to this event."
285
+ )
286
+
287
+ # abort after certain batch if requested to do so
288
+ if self.abort_after_batch_num is not None and self.batch_number > self.abort_after_batch_num:
289
+ raise ValueError(
290
+ f"DebugUnderflowOverflow: aborting after {self.batch_number} batches due to"
291
+ f" `abort_after_batch_num={self.abort_after_batch_num}` arg"
292
+ )
293
+
294
+
295
+ def get_abs_min_max(var, ctx):
296
+ abs_var = var.abs()
297
+ return f"{abs_var.min():8.2e} {abs_var.max():8.2e} {ctx}"
298
+
299
+
300
+ def detect_overflow(var, ctx):
301
+ """
302
+ Report whether the tensor contains any `nan` or `inf` entries.
303
+
304
+ This is useful for detecting overflows/underflows and best to call right after the function that did some math that
305
+ modified the tensor in question.
306
+
307
+ This function contains a few other helper features that you can enable and tweak directly if you want to track
308
+ various other things.
309
+
310
+ Args:
311
+ var: the tensor variable to check
312
+ ctx: the message to print as a context
313
+
314
+ Return:
315
+ `True` if `inf` or `nan` was detected, `False` otherwise
316
+ """
317
+ detected = False
318
+ if torch.isnan(var).any().item():
319
+ detected = True
320
+ print(f"{ctx} has nans")
321
+ if torch.isinf(var).any().item():
322
+ detected = True
323
+ print(f"{ctx} has infs")
324
+
325
+ # if needed to monitor large elements can enable the following
326
+ if 0: # and detected:
327
+ n100 = var[torch.ge(var.abs(), 100)]
328
+ if n100.numel() > 0:
329
+ print(f"{ctx}: n100={n100.numel()}")
330
+ n1000 = var[torch.ge(var.abs(), 1000)]
331
+ if n1000.numel() > 0:
332
+ print(f"{ctx}: n1000={n1000.numel()}")
333
+ n10000 = var[torch.ge(var.abs(), 10000)]
334
+ if n10000.numel() > 0:
335
+ print(f"{ctx}: n10000={n10000.numel()}")
336
+
337
+ if 0:
338
+ print(f"min={var.min():9.2e} max={var.max():9.2e}")
339
+
340
+ if 0:
341
+ print(f"min={var.min():9.2e} max={var.max():9.2e} var={var.var():9.2e} mean={var.mean():9.2e} ({ctx})")
342
+
343
+ return detected
344
+
345
+
346
+ class DebugOption(ExplicitEnum):
347
+ UNDERFLOW_OVERFLOW = "underflow_overflow"
348
+ TPU_METRICS_DEBUG = "tpu_metrics_debug"
third_party/transformers/src/transformers/distributed/__init__.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from typing import TYPE_CHECKING
16
+
17
+ from ..utils import _LazyModule
18
+
19
+
20
+ _import_structure = {
21
+ "configuration_utils": ["DistributedConfig"],
22
+ }
23
+
24
+
25
+ if TYPE_CHECKING:
26
+ from .configuration_utils import (
27
+ DistributedConfig,
28
+ )
29
+
30
+ else:
31
+ import sys
32
+
33
+ sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__)
third_party/transformers/src/transformers/distributed/configuration_utils.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import copy
16
+ import json
17
+ import os
18
+ from dataclasses import dataclass
19
+ from typing import Any
20
+
21
+
22
+ @dataclass
23
+ class DistributedConfig:
24
+ """
25
+ Base class for distributed configs
26
+ """
27
+
28
+ enable_expert_parallel: bool = False
29
+ # TODO: add tp_plan, pp_plan, device_mesh etc..
30
+
31
+ @classmethod
32
+ def from_dict(cls, config_dict, **kwargs):
33
+ """
34
+ Constructs a DistributedConfig instance from a dictionary of parameters.
35
+ Args:
36
+ config_dict (Dict[str, Any]): Dictionary containing configuration parameters.
37
+ **kwargs: Additional keyword arguments to override dictionary values.
38
+ Returns:
39
+ DistributedConfig: Instance of DistributedConfig constructed from the dictionary.
40
+ """
41
+ config = cls(**config_dict)
42
+ to_remove = []
43
+ for key, value in kwargs.items():
44
+ if hasattr(config, key):
45
+ setattr(config, key, value)
46
+ to_remove.append(key)
47
+ for key in to_remove:
48
+ kwargs.pop(key, None)
49
+ return config
50
+
51
+ # Copied from transformers.utils.quantization_config.QuantizationConfigMixin.to_json_file
52
+ def to_json_file(self, json_file_path: str | os.PathLike):
53
+ """
54
+ Save this instance to a JSON file.
55
+ Args:
56
+ json_file_path (`str` or `os.PathLike`):
57
+ Path to the JSON file in which this configuration instance's parameters will be saved.
58
+ use_diff (`bool`, *optional*, defaults to `True`):
59
+ If set to `True`, only the difference between the config instance and the default
60
+ `QuantizationConfig()` is serialized to JSON file.
61
+ """
62
+ with open(json_file_path, "w", encoding="utf-8") as writer:
63
+ config_dict = self.to_dict()
64
+ json_string = json.dumps(config_dict, indent=2, sort_keys=True) + "\n"
65
+
66
+ writer.write(json_string)
67
+
68
+ def to_dict(self) -> dict[str, Any]:
69
+ """
70
+ Serializes this instance to a Python dictionary. Returns:
71
+ `Dict[str, Any]`: Dictionary of all the attributes that make up this configuration instance.
72
+ """
73
+ return copy.deepcopy(self.__dict__)
74
+
75
+ # Copied from transformers.utils.quantization_config.QuantizationConfigMixin.__iter__
76
+ def __iter__(self):
77
+ """allows `dict(obj)` for situations where obj may be a dict or QuantizationConfigMixin"""
78
+ yield from copy.deepcopy(self.__dict__).items()
79
+
80
+ # Copied from transformers.utils.quantization_config.QuantizationConfigMixin.__repr__
81
+ def __repr__(self):
82
+ return f"{self.__class__.__name__} {self.to_json_string()}"
83
+
84
+ def to_json_string(self):
85
+ """
86
+ Serializes this instance to a JSON formatted string.
87
+ Returns:
88
+ str: JSON formatted string representing the configuration instance.
89
+ """
90
+ return json.dumps(self.__dict__, indent=2) + "\n"
91
+
92
+ def update(self, **kwargs):
93
+ """
94
+ Updates attributes of this class instance with attributes from `kwargs` if they match existing attributes,
95
+ returning all the unused kwargs.
96
+ Args:
97
+ kwargs (`Dict[str, Any]`):
98
+ Dictionary of attributes to tentatively update this class.
99
+ Returns:
100
+ `Dict[str, Any]`: Dictionary containing all the key-value pairs that were not used to update the instance.
101
+ """
102
+ to_remove = []
103
+ for key, value in kwargs.items():
104
+ if hasattr(self, key):
105
+ setattr(self, key, value)
106
+ to_remove.append(key)
107
+
108
+ # Remove all the attributes that were updated, without modifying the input dict
109
+ unused_kwargs = {key: value for key, value in kwargs.items() if key not in to_remove}
110
+ return unused_kwargs
third_party/transformers/src/transformers/hyperparameter_search.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023-present 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
+ from .integrations import (
16
+ is_optuna_available,
17
+ is_ray_tune_available,
18
+ is_wandb_available,
19
+ run_hp_search_optuna,
20
+ run_hp_search_ray,
21
+ run_hp_search_wandb,
22
+ )
23
+ from .trainer_utils import (
24
+ HPSearchBackend,
25
+ default_hp_space_optuna,
26
+ default_hp_space_ray,
27
+ default_hp_space_wandb,
28
+ )
29
+ from .utils import logging
30
+
31
+
32
+ logger = logging.get_logger(__name__)
33
+
34
+
35
+ class HyperParamSearchBackendBase:
36
+ name: str
37
+ pip_package: str | None = None
38
+
39
+ @staticmethod
40
+ def is_available():
41
+ raise NotImplementedError
42
+
43
+ def run(self, trainer, n_trials: int, direction: str, **kwargs):
44
+ raise NotImplementedError
45
+
46
+ def default_hp_space(self, trial):
47
+ raise NotImplementedError
48
+
49
+ def ensure_available(self):
50
+ if not self.is_available():
51
+ raise RuntimeError(
52
+ f"You picked the {self.name} backend, but it is not installed. Run {self.pip_install()}."
53
+ )
54
+
55
+ @classmethod
56
+ def pip_install(cls):
57
+ return f"`pip install {cls.pip_package or cls.name}`"
58
+
59
+
60
+ class OptunaBackend(HyperParamSearchBackendBase):
61
+ name = "optuna"
62
+
63
+ @staticmethod
64
+ def is_available():
65
+ return is_optuna_available()
66
+
67
+ def run(self, trainer, n_trials: int, direction: str, **kwargs):
68
+ return run_hp_search_optuna(trainer, n_trials, direction, **kwargs)
69
+
70
+ def default_hp_space(self, trial):
71
+ return default_hp_space_optuna(trial)
72
+
73
+
74
+ class RayTuneBackend(HyperParamSearchBackendBase):
75
+ name = "ray"
76
+ pip_package = "'ray[tune]'"
77
+
78
+ @staticmethod
79
+ def is_available():
80
+ return is_ray_tune_available()
81
+
82
+ def run(self, trainer, n_trials: int, direction: str, **kwargs):
83
+ return run_hp_search_ray(trainer, n_trials, direction, **kwargs)
84
+
85
+ def default_hp_space(self, trial):
86
+ return default_hp_space_ray(trial)
87
+
88
+
89
+ class WandbBackend(HyperParamSearchBackendBase):
90
+ name = "wandb"
91
+
92
+ @staticmethod
93
+ def is_available():
94
+ return is_wandb_available()
95
+
96
+ def run(self, trainer, n_trials: int, direction: str, **kwargs):
97
+ return run_hp_search_wandb(trainer, n_trials, direction, **kwargs)
98
+
99
+ def default_hp_space(self, trial):
100
+ return default_hp_space_wandb(trial)
101
+
102
+
103
+ ALL_HYPERPARAMETER_SEARCH_BACKENDS = {
104
+ HPSearchBackend(backend.name): backend for backend in [OptunaBackend, RayTuneBackend, WandbBackend]
105
+ }
106
+
107
+
108
+ def default_hp_search_backend() -> str:
109
+ available_backends = [backend for backend in ALL_HYPERPARAMETER_SEARCH_BACKENDS.values() if backend.is_available()]
110
+ if len(available_backends) > 0:
111
+ name = available_backends[0].name
112
+ if len(available_backends) > 1:
113
+ logger.info(
114
+ f"{len(available_backends)} hyperparameter search backends available. Using {name} as the default."
115
+ )
116
+ return name
117
+ raise RuntimeError(
118
+ "No hyperparameter search backend available.\n"
119
+ + "\n".join(
120
+ f" - To install {backend.name} run {backend.pip_install()}"
121
+ for backend in ALL_HYPERPARAMETER_SEARCH_BACKENDS.values()
122
+ )
123
+ )
third_party/transformers/src/transformers/masking_utils.py ADDED
@@ -0,0 +1,1608 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ import itertools
15
+ from collections.abc import Callable
16
+
17
+ import torch
18
+ import torch.nn.functional as F
19
+
20
+ from .cache_utils import Cache
21
+ from .configuration_utils import PreTrainedConfig
22
+ from .utils import is_torch_xpu_available, logging
23
+ from .utils.deprecation import deprecate_kwarg
24
+ from .utils.generic import GeneralInterface, is_flash_attention_requested
25
+ from .utils.import_utils import is_torch_flex_attn_available, is_torch_greater_or_equal, is_tracing
26
+
27
+
28
+ if is_torch_flex_attn_available():
29
+ from torch.nn.attention.flex_attention import _DEFAULT_SPARSE_BLOCK_SIZE as flex_default_block_size
30
+ from torch.nn.attention.flex_attention import BlockMask, create_block_mask
31
+ else:
32
+ # Register a fake type to avoid crashing for annotations and `isinstance` checks
33
+ BlockMask = torch.Tensor
34
+
35
+ _is_torch_greater_or_equal_than_2_5 = is_torch_greater_or_equal("2.5", accept_dev=True)
36
+ _is_torch_greater_or_equal_than_2_6 = is_torch_greater_or_equal("2.6", accept_dev=True)
37
+ _is_torch_xpu_available = is_torch_xpu_available()
38
+
39
+ if _is_torch_greater_or_equal_than_2_6:
40
+ from torch._dynamo._trace_wrapped_higher_order_op import TransformGetItemToIndex
41
+
42
+
43
+ logger = logging.get_logger(__name__)
44
+
45
+
46
+ def and_masks(*mask_functions: Callable) -> Callable:
47
+ """Returns a mask function that is the intersection of provided mask functions"""
48
+ if not all(callable(arg) for arg in mask_functions):
49
+ raise RuntimeError(f"All inputs should be callable mask_functions: {mask_functions}")
50
+
51
+ def and_mask(batch_idx, head_idx, q_idx, kv_idx):
52
+ result = q_idx.new_ones((), dtype=torch.bool)
53
+ for mask in mask_functions:
54
+ result = result & mask(batch_idx, head_idx, q_idx, kv_idx).to(result.device)
55
+ return result
56
+
57
+ return and_mask
58
+
59
+
60
+ def or_masks(*mask_functions: Callable) -> Callable:
61
+ """Returns a mask function that is the union of provided mask functions"""
62
+ if not all(callable(arg) for arg in mask_functions):
63
+ raise RuntimeError(f"All inputs should be callable mask_functions: {mask_functions}")
64
+
65
+ def or_mask(batch_idx, head_idx, q_idx, kv_idx):
66
+ result = q_idx.new_zeros((), dtype=torch.bool)
67
+ for mask in mask_functions:
68
+ result = result | mask(batch_idx, head_idx, q_idx, kv_idx).to(result.device)
69
+ return result
70
+
71
+ return or_mask
72
+
73
+
74
+ def causal_mask_function(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool:
75
+ """
76
+ This creates a basic lower-diagonal causal mask.
77
+ """
78
+ return kv_idx <= q_idx
79
+
80
+
81
+ def bidirectional_mask_function(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool:
82
+ """
83
+ This creates a full bidirectional mask.
84
+
85
+ NOTE: It is important to keep an index-based version for non-vmap expansion.
86
+ """
87
+ return q_idx >= 0
88
+
89
+
90
+ def sliding_window_overlay(sliding_window: int) -> Callable:
91
+ """
92
+ This is an overlay depicting a sliding window pattern. Add it on top of a causal mask for a proper sliding
93
+ window mask.
94
+ """
95
+
96
+ def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool:
97
+ return kv_idx > q_idx - sliding_window
98
+
99
+ return inner_mask
100
+
101
+
102
+ def chunked_overlay(chunk_size: int, left_padding: torch.Tensor) -> Callable:
103
+ """
104
+ This is an overlay depicting a chunked attention pattern. Add it on top of a causal mask for a proper chunked
105
+ attention mask.
106
+ """
107
+
108
+ def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool:
109
+ return (kv_idx - left_padding[batch_idx]) // chunk_size == (q_idx - left_padding[batch_idx]) // chunk_size
110
+
111
+ return inner_mask
112
+
113
+
114
+ def sliding_window_causal_mask_function(sliding_window: int) -> Callable:
115
+ """
116
+ This return the mask_function function to create a sliding window mask.
117
+ """
118
+ return and_masks(sliding_window_overlay(sliding_window), causal_mask_function)
119
+
120
+
121
+ def sliding_window_bidirectional_overlay(sliding_window: int) -> Callable:
122
+ """
123
+ This is an overlay depicting a bidirectional sliding window pattern.
124
+ """
125
+
126
+ def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool:
127
+ """A token can attend to any other token if their absolute distance is within
128
+ the (inclusive) sliding window size (distance <= sliding_window)."""
129
+ return abs(q_idx - kv_idx) <= sliding_window
130
+
131
+ return inner_mask
132
+
133
+
134
+ def sliding_window_bidirectional_mask_function(sliding_window: int) -> Callable:
135
+ """
136
+ This return the mask_function function to create a bidirectional sliding window mask.
137
+ """
138
+ return and_masks(sliding_window_bidirectional_overlay(sliding_window), bidirectional_mask_function)
139
+
140
+
141
+ def chunked_causal_mask_function(chunk_size: int, left_padding: torch.Tensor) -> Callable:
142
+ """
143
+ This return the mask_function function to create a chunked attention mask.
144
+ """
145
+ return and_masks(chunked_overlay(chunk_size, left_padding), causal_mask_function)
146
+
147
+
148
+ def padding_mask_function(padding_mask: torch.Tensor) -> Callable:
149
+ """
150
+ This return the mask_function function corresponding to a 2D padding mask.
151
+ """
152
+
153
+ def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool:
154
+ # Note that here the mask should ALWAYS be at least of the max `kv_index` size in the dimension 1. This is because
155
+ # we cannot pad it here in the mask_function as we don't know the final size, and we cannot try/except, as it is not
156
+ # vectorizable on accelerator devices
157
+ return padding_mask[batch_idx, kv_idx]
158
+
159
+ return inner_mask
160
+
161
+
162
+ def packed_sequence_mask_function(packed_sequence_mask: torch.Tensor) -> Callable:
163
+ """
164
+ This return the mask_function function corresponding to a 2D packed sequence mask.
165
+ """
166
+
167
+ def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool:
168
+ return packed_sequence_mask[batch_idx, q_idx] == packed_sequence_mask[batch_idx, kv_idx]
169
+
170
+ return inner_mask
171
+
172
+
173
+ def add_offsets_to_mask_function(mask_function: Callable, q_offset: int, kv_offset: int) -> Callable:
174
+ """
175
+ This function adds the correct offsets to the `q_idx` and `kv_idx` as the torch API can only accept lengths,
176
+ not start and end indices.
177
+ """
178
+
179
+ def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool:
180
+ return mask_function(batch_idx, head_idx, q_idx + q_offset, kv_idx + kv_offset)
181
+
182
+ return inner_mask
183
+
184
+
185
+ def prepare_padding_mask(attention_mask: torch.Tensor | None, kv_length: int, kv_offset: int) -> torch.Tensor | None:
186
+ """
187
+ From the 2D attention mask, prepare the correct padding mask to use by potentially padding it.
188
+ """
189
+ local_padding_mask = attention_mask
190
+ if attention_mask is not None:
191
+ # Pad it if necessary
192
+ if (padding_length := kv_length + kv_offset - attention_mask.shape[-1]) > 0:
193
+ local_padding_mask = torch.nn.functional.pad(attention_mask, (0, padding_length))
194
+ return local_padding_mask
195
+
196
+
197
+ def _can_skip_causal_mask_xpu(
198
+ padding_mask: torch.Tensor | None,
199
+ query_length: int,
200
+ kv_length: int,
201
+ local_attention_size: int | None,
202
+ ) -> bool:
203
+ """
204
+ XPU-specific logic for determining if we can skip causal mask creation.
205
+
206
+ For XPU devices, we have special handling:
207
+ - Single query tokens (query_length == 1) use the same logic as CUDA
208
+ - Multi-query tokens can skip if padding_mask is provided and correctly structured
209
+ The mask must have all True values in the query window and all False after
210
+ """
211
+
212
+ if is_tracing(padding_mask):
213
+ return False
214
+
215
+ # Check local attention constraint (same as CUDA)
216
+ if local_attention_size is not None and kv_length >= local_attention_size:
217
+ return False
218
+
219
+ if padding_mask is None:
220
+ # Without padding mask, can skip if single query token or full causal attention
221
+ return query_length == 1 or kv_length == query_length
222
+
223
+ # XPU allows skipping under additional conditions when padding_mask is provided
224
+ if query_length == 1:
225
+ # Single query token: skip only if no padding tokens present
226
+ return padding_mask.all()
227
+
228
+ # XPU-specific: check if query window is all True and rest is all False
229
+ # This allows XPU to optimize the 1st token in static cache
230
+ return padding_mask[:, :query_length].all() and not padding_mask[:, query_length:].any()
231
+
232
+
233
+ def _ignore_causal_mask_sdpa(
234
+ padding_mask: torch.Tensor | None,
235
+ query_length: int,
236
+ kv_length: int,
237
+ kv_offset: int,
238
+ local_attention_size: int | None = None,
239
+ ) -> bool:
240
+ """
241
+ Detects whether the causal mask can be ignored in case PyTorch's SDPA is used, rather relying on SDPA's `is_causal` argument.
242
+
243
+ In case no token is masked in the 2D `padding_mask` argument, if `query_length == 1` or
244
+ `key_value_length == query_length`, we rather rely on SDPA `is_causal` argument to use causal/non-causal masks,
245
+ allowing to dispatch to the flash attention kernel (that can otherwise not be used if a custom `attn_mask` is
246
+ passed).
247
+ """
248
+ if padding_mask is not None and padding_mask.shape[-1] > kv_length:
249
+ mask_indices = torch.arange(kv_length, device=padding_mask.device)
250
+ mask_indices += kv_offset
251
+ padding_mask = padding_mask[:, mask_indices]
252
+
253
+ if _is_torch_xpu_available:
254
+ # XPU devices have special handling for mask skipping:
255
+ # - Single query tokens use the same logic as CUDA
256
+ # - Multi-query tokens can skip if padding_mask is provided and correctly structured
257
+ # (all True in query window, all False after)
258
+ return _can_skip_causal_mask_xpu(padding_mask, query_length, kv_length, local_attention_size)
259
+ # When using `torch.export` or `torch.onnx.dynamo_export`, we must pass an example input, and `is_causal` behavior is
260
+ # hard-coded to the forward. If a user exports a model with query_length > 1, the exported model will hard-code `is_causal=True`
261
+ # which is in general wrong (see https://github.com/pytorch/pytorch/issues/108108). Thus, we only set
262
+ # `ignore_causal_mask = True` if we are not tracing
263
+ if (
264
+ not is_tracing(padding_mask)
265
+ # only cases when lower and upper diags are the same, see https://github.com/pytorch/pytorch/issues/108108
266
+ and (query_length == 1 or kv_length == query_length)
267
+ # in this case we need to add special patterns to the mask so cannot be skipped otherwise
268
+ and (local_attention_size is None or kv_length < local_attention_size)
269
+ # In this case, we need to add padding to the mask, so cannot be skipped otherwise
270
+ and (padding_mask is None or padding_mask.all())
271
+ ):
272
+ return True
273
+
274
+ return False
275
+
276
+
277
+ def _can_skip_bidirectional_mask_xpu(
278
+ padding_mask: torch.Tensor | None,
279
+ kv_length: int,
280
+ local_attention_size: int | None,
281
+ ) -> bool:
282
+ """
283
+ XPU-specific logic for determining if we can skip bidirectional mask creation.
284
+
285
+ For XPU devices, we have special handling:
286
+ - Skip if no padding and no local attention constraint
287
+ """
288
+
289
+ if is_tracing(padding_mask):
290
+ return False
291
+
292
+ # Check local attention constraint (same as CUDA)
293
+ if local_attention_size is not None and kv_length >= local_attention_size:
294
+ return False
295
+
296
+ if padding_mask is None:
297
+ # Without padding mask, can always skip for full bidirectional attention
298
+ return True
299
+
300
+ # Skip only if no padding tokens present
301
+ return padding_mask.all()
302
+
303
+
304
+ def _ignore_bidirectional_mask_sdpa(
305
+ padding_mask: torch.Tensor | None,
306
+ kv_length: int,
307
+ local_attention_size: int | None = None,
308
+ ) -> bool:
309
+ """
310
+ Detects whether the bidirectional mask can be ignored in case PyTorch's SDPA is used.
311
+
312
+ In case no token is masked in the 2D `padding_mask` argument and no local attention constraint applies
313
+ (i.e. `local_attention_size` is None or `kv_length < local_attention_size`), we skip mask creation,
314
+ allowing to dispatch to the flash attention kernel (that can otherwise not be used if a custom `attn_mask` is
315
+ passed).
316
+ """
317
+ if _is_torch_xpu_available:
318
+ # XPU devices have special handling for mask skipping:
319
+ # - Skip if no padding and no local attention constraint
320
+ return _can_skip_bidirectional_mask_xpu(padding_mask, kv_length, local_attention_size)
321
+
322
+ # When using `torch.export` or `torch.onnx.dynamo_export`, we need to avoid to check the contents of the mask;
323
+ # otherwise, we will encounter dynamic control flows
324
+ if (
325
+ not is_tracing(padding_mask)
326
+ and (padding_mask is None or padding_mask.all())
327
+ # in this case we need to add special patterns to the mask so cannot be skipped otherwise
328
+ and (local_attention_size is None or kv_length < local_attention_size)
329
+ ):
330
+ return True
331
+
332
+ return False
333
+
334
+
335
+ def _vmap_expansion_sdpa(mask_function: Callable) -> Callable:
336
+ """
337
+ Used to vmap our mask_functions over the all 4 dimensions (b_idx, h_idx, q_idx, kv_idx) of the inputs.
338
+ Using vmap here allows us to keep the performance of vectorized ops, while having a single set of primitive
339
+ functions between attention interfaces (i.e. between flex and sdpa/eager, FA2 being a bit different).
340
+ """
341
+ # We vmap the function over all 4 dimensions, broadcasting [b_idx, h_idx, q_idx, kv_idx]
342
+ dimensions = [(None, None, None, 0), (None, None, 0, None), (None, 0, None, None), (0, None, None, None)]
343
+ for dims in dimensions:
344
+ mask_function = torch.vmap(mask_function, in_dims=dims, out_dims=0)
345
+ return mask_function
346
+
347
+
348
+ def _non_vmap_expansion_sdpa(
349
+ batch_indices: torch.Tensor, head_indices: torch.Tensor, q_indices: torch.Tensor, kv_indices: torch.Tensor
350
+ ):
351
+ """
352
+ Used to broadcast our mask_functions over the all 4 dimensions (b_idx, h_idx, q_idx, kv_idx) of the inputs.
353
+ Allows the usage of any index-based mask function without relying on vmap.
354
+
355
+ NOTE: This is limited to index based functions only and is not guaranteed to work otherwise.
356
+
357
+ Reference:
358
+ - https://github.com/huggingface/optimum-onnx/blob/c123e8f4fab61b54a8e0e31ce74462bcacca576e/optimum/exporters/onnx/model_patcher.py#L362-L365
359
+ """
360
+ batch_indices = batch_indices[:, None, None, None]
361
+ head_indices = head_indices[None, :, None, None]
362
+ q_indices = q_indices[None, None, :, None]
363
+ kv_indices = kv_indices[None, None, None, :]
364
+ return batch_indices, head_indices, q_indices, kv_indices
365
+
366
+
367
+ def sdpa_mask(
368
+ batch_size: int,
369
+ q_length: int,
370
+ kv_length: int,
371
+ q_offset: int = 0,
372
+ kv_offset: int = 0,
373
+ mask_function: Callable = causal_mask_function,
374
+ attention_mask: torch.Tensor | None = None,
375
+ local_size: int | None = None,
376
+ allow_is_causal_skip: bool = True,
377
+ allow_is_bidirectional_skip: bool = False,
378
+ allow_torch_fix: bool = True,
379
+ use_vmap: bool = False,
380
+ device: torch.device | str = "cpu",
381
+ **kwargs,
382
+ ) -> torch.Tensor | None:
383
+ """
384
+ Create a 4D boolean mask of shape `(batch_size, 1, query_length, kv_length)` where a value of True indicates that
385
+ the element should take part in the attention computation, and False that it should not.
386
+ This function can only be used with torch>=2.5, as the context manager is otherwise not available.
387
+
388
+ Args:
389
+ batch_size (`int`):
390
+ The batch size of the input sequence.
391
+ q_length (`int`):
392
+ The size that the query states will have during the attention computation.
393
+ kv_length (`int`):
394
+ The size that the key and value states will have during the attention computation.
395
+ kv_offset (`int`, optional):
396
+ An optional offset to indicate at which first position the key and values states will refer to.
397
+ q_offset (`int`, optional):
398
+ An optional offset to indicate at which first position the query states will refer to.
399
+ mask_function (`Callable`):
400
+ The mask factory function describing the mask pattern.
401
+ attention_mask (`torch.Tensor`, optional):
402
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, number_of_seen_tokens+q_length)
403
+ local_size (`int`, optional):
404
+ The size of the local attention, if we do not use full attention. This is used only if `allow_is_causal_skip=True`
405
+ to try to skip mask creation if possible.
406
+ allow_is_causal_skip (`bool`, optional):
407
+ Whether to allow to return `None` for the mask under conditions where we can use the `is_causal` argument in
408
+ `torch.sdpa` instead. Default to `True`.
409
+ allow_is_bidirectional_skip (`bool`, optional):
410
+ Whether to allow to return `None` for the mask under conditions where we do not have to add any bias,
411
+ i.e. full attention without any padding. Default to `False`.
412
+ allow_torch_fix (`bool`, optional):
413
+ Whether to update the mask in case a query is not attending to any tokens, to solve a bug in torch's older
414
+ versions. We need an arg to skip it when using eager. By default `True`.
415
+ use_vmap (`bool`, optional):
416
+ Whether to use `vmap` during the mask construction or not. Allows powerful custom patterns that may not be
417
+ index-based (for the cost of speed performance). By default `False`.
418
+ device (`torch.device` or `str`, optional):
419
+ An optional device to create the mask on.
420
+
421
+
422
+ ## Creating a simple causal mask:
423
+
424
+ To create the following causal mask:
425
+
426
+ 0 ■ ⬚ ⬚ ⬚ ⬚
427
+ 1 ■ ■ ⬚ ⬚ ⬚
428
+ 2 ■ ■ ■ ⬚ ⬚
429
+ 3 ■ ■ ■ ■ ⬚
430
+ 4 ■ ■ ■ ■ ■
431
+
432
+ You can do
433
+
434
+ ```python
435
+ >>> sdpa_mask(batch_size=1, q_length=5, kv_length=5)
436
+ >>> tensor([[[[ True, False, False, False, False],
437
+ [ True, True, False, False, False],
438
+ [ True, True, True, False, False],
439
+ [ True, True, True, True, False],
440
+ [ True, True, True, True, True]]]])
441
+ ```
442
+
443
+ ## Creating a sliding window mask:
444
+
445
+ To create the following sliding window mask (`sliding_window=3`):
446
+
447
+ 0 ■ ⬚ ⬚ ⬚ ⬚
448
+ 1 ■ ■ ⬚ ⬚ ⬚
449
+ 2 ■ ■ ■ ⬚ ⬚
450
+ 3 ⬚ ■ ■ ■ ⬚
451
+ 4 ⬚ ⬚ ■ ■ ■
452
+
453
+ You can do
454
+
455
+ ```python
456
+ >>> sdpa_mask(batch_size=1, q_length=5, kv_length=5, mask_function=sliding_window_causal_mask_function(3))
457
+ >>> tensor([[[[ True, False, False, False, False],
458
+ [ True, True, False, False, False],
459
+ [ True, True, True, False, False],
460
+ [False, True, True, True, False],
461
+ [False, False, True, True, True]]]])
462
+ ```
463
+
464
+ ## Creating a chunked attention mask
465
+
466
+ To create the following chunked attention mask (`chunk_size=3`):
467
+
468
+ 0 ■ ⬚ ⬚ ⬚ ⬚
469
+ 1 ■ ■ ⬚ ⬚ ⬚
470
+ 2 ■ ■ ■ ⬚ ⬚
471
+ 3 ⬚ ⬚ ⬚ ■ ⬚
472
+ 4 ⬚ ⬚ ⬚ ■ ■
473
+
474
+ You can do
475
+
476
+ ```python
477
+ >>> sdpa_mask(batch_size=1, q_length=5, kv_length=5, mask_function=chunked_causal_mask_function(3, torch.zeros(1, dtype=int)))
478
+ >>> tensor([[[[ True, False, False, False, False],
479
+ [ True, True, False, False, False],
480
+ [ True, True, True, False, False],
481
+ [False, False, False, True, False],
482
+ [False, False, False, True, True]]]])
483
+ ```
484
+
485
+ """
486
+ # For BC on `cache_positions` that used to be an arg at the position of `q_length`
487
+ if isinstance(q_length, torch.Tensor):
488
+ logger.warning_once(
489
+ "`cache_position` is deprecated as an arg, and will be removed in Transformers v5.6. Please use `q_length` and "
490
+ "`q_offset` instead, similarly to `kv_length` and `kv_offset`"
491
+ )
492
+ q_length, q_offset = q_length.shape[0], q_length[0].to(device)
493
+
494
+ # Potentially pad the 2D mask
495
+ padding_mask = prepare_padding_mask(attention_mask, kv_length, kv_offset)
496
+
497
+ # Under specific conditions, we can avoid materializing the mask
498
+ # 1. Causal masks can rely on the `is_causal` argument
499
+ # 2. Bidirectional do not need any further processing (no bias)
500
+ if allow_is_causal_skip and _ignore_causal_mask_sdpa(padding_mask, q_length, kv_length, kv_offset, local_size):
501
+ return None
502
+ if allow_is_bidirectional_skip and _ignore_bidirectional_mask_sdpa(padding_mask, kv_length, local_size):
503
+ return None
504
+
505
+ # Potentially add the padding 2D mask
506
+ if padding_mask is not None:
507
+ mask_function = and_masks(mask_function, padding_mask_function(padding_mask))
508
+
509
+ batch_arange = torch.arange(batch_size, device=device)
510
+ head_arange = torch.arange(1, device=device)
511
+ q_arange = torch.arange(q_length, device=device) + q_offset
512
+ kv_arange = torch.arange(kv_length, device=device) + kv_offset
513
+
514
+ # Actual mask creation
515
+ # Option 1: Fast non-vmap mask creation (default)
516
+ if not use_vmap:
517
+ # Apply mask function element-wise through broadcasting
518
+ attention_mask = mask_function(*_non_vmap_expansion_sdpa(batch_arange, head_arange, q_arange, kv_arange))
519
+ # Expand the mask to match batch size and query length if they weren't used in the mask function
520
+ attention_mask = attention_mask.expand(batch_size, -1, q_length, kv_length)
521
+
522
+ # Option 2: Vmap mask creation (torch>=2.6 and custom patterns)
523
+ elif _is_torch_greater_or_equal_than_2_6:
524
+ # This creates the 4D mask easily. Note that we need this context manager as vmap cannot handle slicing a tensor from
525
+ # scalar tensor (it internally calls `.item()` which vmap does not allow, but this context works around it
526
+ # We don't need to add an offset to the mask_function either, as we vmap directly the correct indices for k and kv indices
527
+ with TransformGetItemToIndex():
528
+ attention_mask = _vmap_expansion_sdpa(mask_function)(batch_arange, head_arange, q_arange, kv_arange)
529
+
530
+ # Option 3: Error out since it indicates that the user did something custom, which they shouldn't have (torch<2.6)
531
+ else:
532
+ raise ValueError(
533
+ "The vmap functionality for mask creation is only supported from torch>=2.6. "
534
+ "Please update your torch version or use `use_vmap=False` with index-based masks."
535
+ )
536
+
537
+ # Due to a bug in versions of torch<2.5, we need to update the mask in case a query is not attending to any
538
+ # tokens (due to padding). See details in https://github.com/pytorch/pytorch/issues/110213
539
+ if not _is_torch_greater_or_equal_than_2_5 and allow_torch_fix:
540
+ attention_mask = attention_mask | torch.all(~attention_mask, dim=-1, keepdim=True)
541
+
542
+ return attention_mask
543
+
544
+
545
+ def eager_mask(
546
+ batch_size: int,
547
+ q_length: int,
548
+ kv_length: int,
549
+ q_offset: int = 0,
550
+ kv_offset: int = 0,
551
+ mask_function: Callable = causal_mask_function,
552
+ attention_mask: torch.Tensor | None = None,
553
+ dtype: torch.dtype = torch.float32,
554
+ allow_is_bidirectional_skip: bool = False,
555
+ use_vmap: bool = False,
556
+ device: torch.device | str = "cpu",
557
+ **kwargs,
558
+ ) -> torch.Tensor:
559
+ """
560
+ Create a 4D float mask of shape `(batch_size, 1, query_length, kv_length)` where a value of 0 indicates that
561
+ the element should take part in the attention computation, and -inf (minimum value for the given `dtype`) that
562
+ it should not.
563
+
564
+ Args:
565
+ batch_size (`int`):
566
+ The batch size of the input sequence.
567
+ q_length (`int`):
568
+ The size that the query states will have during the attention computation.
569
+ kv_length (`int`):
570
+ The size that the key and value states will have during the attention computation.
571
+ q_offset (`int`, optional):
572
+ An optional offset to indicate at which first position the query states will refer to.
573
+ kv_offset (`int`, optional):
574
+ An optional offset to indicate at which first position the key and values states will refer to.
575
+ mask_function (`Callable`):
576
+ The mask factory function describing the mask pattern.
577
+ attention_mask (`torch.Tensor`, optional):
578
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, number_of_seen_tokens+q_length)
579
+ dtype (`torch.dtype`, optional):
580
+ The dtype to use for the mask. By default, `torch.float32`.
581
+ allow_is_bidirectional_skip (`bool`, optional):
582
+ Whether to allow to return `None` for the mask under conditions where we do not have to add any bias,
583
+ i.e. full attention without any padding. Default to `False`.
584
+ use_vmap (`bool`, optional):
585
+ Whether to use `vmap` during the mask construction or not. Allows powerful custom patterns that may not be
586
+ index-based (for the cost of speed performance). By default `False`.
587
+ device (`torch.device` or `str`, optional):
588
+ An optional device to create the mask on.
589
+ """
590
+ # The masks for eager attention are simply boolean mask from sdpa, casted to 0 and -inf
591
+ _ = kwargs.pop("allow_is_causal_skip", None)
592
+ _ = kwargs.pop("allow_torch_fix", None)
593
+ mask = sdpa_mask(
594
+ batch_size=batch_size,
595
+ q_length=q_length,
596
+ kv_length=kv_length,
597
+ q_offset=q_offset,
598
+ kv_offset=kv_offset,
599
+ mask_function=mask_function,
600
+ attention_mask=attention_mask,
601
+ allow_is_causal_skip=False,
602
+ allow_is_bidirectional_skip=allow_is_bidirectional_skip,
603
+ allow_torch_fix=False,
604
+ use_vmap=use_vmap,
605
+ device=device,
606
+ **kwargs,
607
+ )
608
+ # only bidirectional masks can be skipped, otherwise we convert bool -> float
609
+ if mask is not None:
610
+ min_dtype = torch.finfo(dtype).min
611
+ # we need 0s where the tokens should be taken into account, and -inf otherwise (mask is already of boolean type)
612
+ mask = torch.where(mask, torch.tensor(0.0, device=mask.device, dtype=dtype), min_dtype)
613
+ return mask
614
+
615
+
616
+ def flash_attention_mask(
617
+ batch_size: int,
618
+ q_length: int,
619
+ kv_length: int,
620
+ q_offset: int = 0,
621
+ kv_offset: int = 0,
622
+ mask_function: Callable = causal_mask_function,
623
+ attention_mask: torch.Tensor | None = None,
624
+ **kwargs,
625
+ ):
626
+ """
627
+ Create the attention mask necessary to use FA2. Since FA2 is un-padded by definition, here we simply return
628
+ `None` if the mask is fully causal, or we return the 2D mask which will then be used to extract the seq_lens.
629
+ We just slice it in case of sliding window.
630
+
631
+ Args:
632
+ batch_size (`int`):
633
+ The batch size of the input sequence.
634
+ q_length (`int`):
635
+ The size that the query states will have during the attention computation.
636
+ kv_length (`int`):
637
+ The size that the key and value states will have during the attention computation.
638
+ q_offset (`int`, optional):
639
+ An optional offset to indicate at which first position the query states will refer to.
640
+ kv_offset (`int`, optional):
641
+ An optional offset to indicate at which first position the key and values states will refer to.
642
+ mask_function (`Callable`):
643
+ The mask factory function describing the mask pattern.
644
+ attention_mask (`torch.Tensor`, optional):
645
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, number_of_seen_tokens+q_length)
646
+ """
647
+ if attention_mask is not None:
648
+ # Here we need to slice from the right if using sliding or chunked (for full attention, this is equivalent to doing nothing)
649
+ attention_mask = attention_mask[:, -kv_length:]
650
+ # We only return an actual mask if there is at least 1 padding token, otherwise we return `None` and use `is_causal` in FA2
651
+ # (note that the attention_mask is a boolean dtype here)
652
+ if attention_mask.all():
653
+ attention_mask = None
654
+
655
+ return attention_mask
656
+
657
+
658
+ def flex_attention_mask(
659
+ batch_size: int,
660
+ q_length: int,
661
+ kv_length: int,
662
+ q_offset: int = 0,
663
+ kv_offset: int = 0,
664
+ mask_function: Callable = causal_mask_function,
665
+ attention_mask: torch.Tensor | None = None,
666
+ device: torch.device | str = "cpu",
667
+ **kwargs,
668
+ ) -> BlockMask:
669
+ """
670
+ Create a 4D block mask which is a compressed representation of the full 4D block causal mask. BlockMask is essential
671
+ for performant computation of flex attention. See: https://pytorch.org/blog/flexattention/
672
+
673
+ Args:
674
+ batch_size (`int`):
675
+ The batch size of the input sequence.
676
+ q_length (`int`):
677
+ The size that the query states will have during the attention computation.
678
+ kv_length (`int`):
679
+ The size that the key and value states will have during the attention computation.
680
+ q_offset (`int`, optional):
681
+ An optional offset to indicate at which first position the query states will refer to.
682
+ kv_offset (`int`, optional):
683
+ An optional offset to indicate at which first position the key and values states will refer to.
684
+ mask_function (`Callable`):
685
+ The mask factory function describing the mask pattern.
686
+ attention_mask (`torch.Tensor`, optional):
687
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, number_of_seen_tokens+q_length)
688
+ device (`torch.device` or `str`, optional):
689
+ An optional device to create the mask on.
690
+ """
691
+ # For BC on `cache_positions` that used to be an arg at the position of `q_length`
692
+ if isinstance(q_length, torch.Tensor):
693
+ logger.warning_once(
694
+ "`cache_position` is deprecated as an arg, and will be removed in Transformers v5.6. Please use `q_length` and "
695
+ "`q_offset` instead, similarly to `kv_length` and `kv_offset`"
696
+ )
697
+ q_length, q_offset = q_length.shape[0], q_length[0].to(device)
698
+
699
+ # Potentially add the padding 2D mask
700
+ if attention_mask is not None:
701
+ # Older torch (2.5.x) cannot handle sequences not in multiples of 128 (default block size)
702
+ # Hence we pad to multiples of this as a minimum to ensure this
703
+ pad_len = ((attention_mask.shape[1] // flex_default_block_size) + 1) * flex_default_block_size
704
+ pad_len = pad_len - attention_mask.shape[1]
705
+ if not _is_torch_greater_or_equal_than_2_6 and pad_len > 0:
706
+ attention_mask = torch.nn.functional.pad(attention_mask, value=0, pad=(0, pad_len))
707
+
708
+ padding_mask = prepare_padding_mask(attention_mask, kv_length, kv_offset)
709
+ mask_function = and_masks(mask_function, padding_mask_function(padding_mask))
710
+
711
+ # Add the offsets on top (because flex interface only allows length, not start and end indices)
712
+ mask_function = add_offsets_to_mask_function(mask_function, q_offset, kv_offset)
713
+
714
+ # Finally create the block mask
715
+ block_mask = create_block_mask(
716
+ mask_mod=mask_function,
717
+ B=batch_size,
718
+ H=None,
719
+ Q_LEN=q_length,
720
+ KV_LEN=kv_length,
721
+ device=device,
722
+ _compile=_is_torch_greater_or_equal_than_2_6,
723
+ )
724
+ return block_mask
725
+
726
+
727
+ class AttentionMaskInterface(GeneralInterface):
728
+ # Class instance object, so that a call to `register` can be reflected into all other files correctly, even if
729
+ # a new instance is created (in order to locally override a given function)
730
+ _global_mapping = {
731
+ "sdpa": sdpa_mask,
732
+ "eager": eager_mask,
733
+ "flash_attention_2": flash_attention_mask,
734
+ "flash_attention_3": flash_attention_mask,
735
+ "flash_attention_4": flash_attention_mask,
736
+ "flex_attention": flex_attention_mask,
737
+ }
738
+
739
+
740
+ # Global AttentionMaskInterface shared by all models which do not need to overwrite any of the existing ones
741
+ ALL_MASK_ATTENTION_FUNCTIONS: AttentionMaskInterface = AttentionMaskInterface()
742
+
743
+
744
+ def find_packed_sequence_indices(position_ids: torch.Tensor) -> torch.Tensor | None:
745
+ """
746
+ Find the indices of the sequence to which each new query token in the sequence belongs when using packed
747
+ tensor format (i.e. several sequences packed in the same batch dimension).
748
+
749
+ Args:
750
+ position_ids (`torch.Tensor`)
751
+ A 2D tensor of shape (batch_size, query_length) indicating the positions of each token in the sequences.
752
+
753
+ Returns:
754
+ A 2D tensor where each similar integer indicates that the tokens belong to the same sequence. For example, if we
755
+ pack 3 sequences of 2, 3 and 1 tokens respectively along a single batch dim, this will return [[0, 0, 1, 1, 1, 2]].
756
+
757
+ If the there is only one sequence in each batch item (and we don't compile), then we return `None` indicating
758
+ no packed sequences. This is the same as [[0, 0, 0, 0, 0, 0]] for the example above.
759
+ """
760
+ # What separate different sequences is when 2 consecutive positions_ids are separated by more than 1. So
761
+ # taking the diff (by prepending the first value - 1 to keep correct indexing) and applying cumsum to the result
762
+ # gives exactly the sequence indices
763
+ # Note that we assume that a single sequence cannot span several batch dimensions, i.e. 1 single sequence
764
+ # cannot be part of the end of the first batch dim and the start of the 2nd one for example
765
+ first_dummy_value = position_ids[:, :1] - 1 # We just need the diff on this first value to be 1
766
+ position_diff = torch.diff(position_ids, prepend=first_dummy_value, dim=-1)
767
+ packed_sequence_mask = (position_diff != 1).cumsum(-1)
768
+
769
+ # Sadly this is a dynamic control flow, so we cannot enable this check on anything compile related
770
+ if not is_tracing(packed_sequence_mask) and (packed_sequence_mask[:, -1] == 0).all():
771
+ return None
772
+
773
+ return packed_sequence_mask
774
+
775
+
776
+ @deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
777
+ def _preprocess_mask_arguments(
778
+ config: PreTrainedConfig,
779
+ inputs_embeds: torch.Tensor,
780
+ attention_mask: torch.Tensor | BlockMask | None,
781
+ past_key_values: Cache | None,
782
+ position_ids: torch.Tensor | None,
783
+ layer_idx: int | None,
784
+ encoder_hidden_states: torch.Tensor | None = None,
785
+ ) -> tuple[bool, torch.Tensor | BlockMask | None, int, int]:
786
+ """
787
+ Perform some common pre-processing of the mask arguments we get from the modeling code. Mostly determine the
788
+ key-value length and offsets, and if we should early exit or not.
789
+
790
+ Args:
791
+ config (`PreTrainedConfig`):
792
+ The model config.
793
+ inputs_embeds (`torch.Tensor`):
794
+ The input embeddings of shape (batch_size, query_length, hidden_dim). This is used only to infer the
795
+ batch size, query length and dtype.
796
+ attention_mask (`torch.Tensor`, optional):
797
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, number_of_seen_tokens+q_length).
798
+ It can also be an already prepared 4D mask, in which case it is returned as-is.
799
+ past_key_values (`Cache`, optional):
800
+ The past key values, if we use a cache.
801
+ position_ids (`torch.Tensor`, optional)
802
+ A 2D tensor of shape (batch_size, query_length) indicating the positions of each token in the sequences.
803
+ layer_idx (`int`, optional):
804
+ If `past_key_values` is not None, this is the layer index of the cache from which to get the key-value
805
+ length and offset. Indeed, for hybrid caches, different layers may return different lengths.
806
+ encoder_hidden_states (`torch.Tensor`, optional):
807
+ The input embeddings of shape (batch_size, kv_length, hidden_dim). If provided, it is used instead of
808
+ `inputs_embeds` to infer the kv length.
809
+
810
+ Returns:
811
+ early_exit (`bool`):
812
+ Whether we should early exit mask creation, and return the mask as-is.
813
+ attention_mask (`torch.Tensor` or `BlockMask` or `None`):
814
+ The attention mask to either return immediately, or to use in downstream mask creation.
815
+ packed_sequence_mask (`torch.Tensor`, optional):
816
+ In case we detected packed sequence format, this is a tensor where each similar integer indicates that
817
+ the tokens belong to the same sequence.
818
+ q_length (`int`):
819
+ The size that the query states will have during the attention computation.
820
+ kv_length (`int`):
821
+ The size that the key and value states will have during the attention computation.
822
+ q_offset (`int`, optional):
823
+ An optional offset to indicate at which first position the query states will refer to.
824
+ kv_offset (`int`):
825
+ An offset to indicate at which first position the key and values states will refer to.
826
+ """
827
+ # If the mask is already 4D, simply return as-is (it was already prepared, or it is custom)
828
+ if isinstance(attention_mask, (torch.Tensor, BlockMask)) and len(attention_mask.shape) == 4:
829
+ return True, attention_mask, None, None, None, None, None
830
+
831
+ # For TGI/vLLM backends, or other custom attention without equivalent mask creation: we don't need a mask!
832
+ # Note: it's not ideal to check the `_global_mapping` attribute instead of the object itself, however otherwise
833
+ # full graph dynamo tracing (i.e. torch.export or compile with `fullgraph=True`) will fail on Python<3.11
834
+ # with `torch._dynamo.exc.Unsupported: 'inline in skipfiles:Mapping.__contains__ | __contains__, skipped
835
+ # according trace_rules.lookup SKIP_DIRS'` -- can be removed when we require Python>=3.11
836
+ if config._attn_implementation not in ALL_MASK_ATTENTION_FUNCTIONS._global_mapping:
837
+ return True, None, None, None, None, None, None
838
+
839
+ # Move the mask to correct device, and potentially switch dtype for efficiency
840
+ if attention_mask is not None and attention_mask.ndim == 2:
841
+ attention_mask = attention_mask.to(device=inputs_embeds.device, dtype=torch.bool)
842
+
843
+ q_length = inputs_embeds.shape[1]
844
+ # If using a cache, it can give all information about mask sizes based on seen tokens
845
+ if past_key_values is not None:
846
+ q_offset = past_key_values.get_seq_length()
847
+ # To avoid graph breaks, StaticLayer return a tensor instead of int -> this has no impact on the ops, but we
848
+ # need the correct device
849
+ q_offset = q_offset.to(inputs_embeds.device) if isinstance(q_offset, torch.Tensor) else q_offset
850
+ kv_length, kv_offset = past_key_values.get_mask_sizes(q_length, layer_idx)
851
+ # Otherwise, we infer based on our input
852
+ else:
853
+ q_offset = 0
854
+ # 1. Rely on input directly
855
+ if attention_mask is None:
856
+ # For encoder-decoders, use encoder_hidden_states to infer kv_length if provided
857
+ kv_length = encoder_hidden_states.shape[1] if encoder_hidden_states is not None else q_length
858
+ kv_offset = 0
859
+ # 2. Rely on the mask instead - needed for special cases like prefix tuning in PEFT
860
+ #
861
+ # This is a very unique and special case where an encoder utilizes a cache and expects its length
862
+ # to be accounted for (usually, they should never use a cache). In general, the mask should always
863
+ # match with the input sizes nonetheless (i.e. it does not affect others).
864
+ # Conclusion: "prefix tuning is evil"
865
+ else:
866
+ kv_length, kv_offset = attention_mask.shape[-1], 0
867
+
868
+ # We check the position_ids for potential packed sequence format (only if the 2D attention mask is explicitly None,
869
+ # and we don't have past_key_values, i.e. generally a training setup)
870
+ packed_sequence_mask = None
871
+ if position_ids is not None and attention_mask is None and past_key_values is None:
872
+ batch_size = inputs_embeds.shape[0]
873
+ # The position ids are sometimes just unsqueezed, without being expanded
874
+ if batch_size != position_ids.shape[0]:
875
+ position_ids = position_ids.expand(batch_size, -1)
876
+ packed_sequence_mask = find_packed_sequence_indices(position_ids)
877
+
878
+ return False, attention_mask, packed_sequence_mask, q_length, kv_length, q_offset, kv_offset
879
+
880
+
881
+ @deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
882
+ def create_causal_mask(
883
+ config: PreTrainedConfig,
884
+ inputs_embeds: torch.Tensor,
885
+ attention_mask: torch.Tensor | None,
886
+ cache_position: torch.Tensor | None = None, # not used anymore but kept for BC
887
+ *,
888
+ past_key_values: Cache | None,
889
+ position_ids: torch.Tensor | None = None,
890
+ or_mask_function: Callable | None = None,
891
+ and_mask_function: Callable | None = None,
892
+ ) -> torch.Tensor | BlockMask | None:
893
+ """
894
+ Create a standard causal mask based on the attention implementation used (stored in the config). If `past_key_values`
895
+ has an hybrid cache structure, this function will return the mask corresponding to one of the "full_attention" layers (to align
896
+ to what is needed in the `modeling_xxx.py` files).
897
+
898
+ Args:
899
+ config (`PreTrainedConfig`):
900
+ The model config.
901
+ inputs_embeds (`torch.Tensor`):
902
+ The input embeddings of shape (batch_size, query_length, hidden_dim). This is used only to infer the
903
+ batch size, query length and dtype.
904
+ attention_mask (`torch.Tensor`, optional):
905
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, number_of_seen_tokens+q_length).
906
+ It can also be an already prepared 4D mask, in which case it is returned as-is.
907
+ cache_position (`torch.Tensor`):
908
+ Deprecated and unused.
909
+ past_key_values (`Cache`, optional):
910
+ The past key values, if we use a cache.
911
+ position_ids (`torch.Tensor`, optional)
912
+ A 2D tensor of shape (batch_size, query_length) indicating the positions of each token in the sequences.
913
+ or_mask_function (`Callable`, optional):
914
+ An optional mask function to combine with the causal mask function (by doing the union of both). This is
915
+ useful to easily overlay another mask on top of the causal one, for example for image tokens handling.
916
+ and_mask_function (`Callable`, optional):
917
+ An optional mask function to combine with the causal mask function (by doing the intersection of both). This is
918
+ useful to easily overlay another mask on top of the causal one, for example for image tokens handling.
919
+ """
920
+ # Power feature: if `is_causal` is False, then fallback to bi-directional mask for bi-directional attention.
921
+ # It allows to use decoder-only models with bi-directional attention as well
922
+ if not getattr(config, "is_causal", True):
923
+ return create_bidirectional_mask(
924
+ config,
925
+ inputs_embeds,
926
+ attention_mask,
927
+ past_key_values=past_key_values,
928
+ or_mask_function=or_mask_function,
929
+ and_mask_function=and_mask_function,
930
+ )
931
+
932
+ # If we have an hybrid cache structure, here we want to create the mask for the full layers
933
+ if hasattr(past_key_values, "is_sliding") and False in past_key_values.is_sliding:
934
+ layer_idx = past_key_values.is_sliding.index(False)
935
+ else:
936
+ layer_idx = 0
937
+
938
+ early_exit, attention_mask, packed_sequence_mask, q_length, kv_length, q_offset, kv_offset = (
939
+ _preprocess_mask_arguments(config, inputs_embeds, attention_mask, past_key_values, position_ids, layer_idx)
940
+ )
941
+ if early_exit:
942
+ return attention_mask
943
+
944
+ batch_size, dtype, device = inputs_embeds.shape[0], inputs_embeds.dtype, inputs_embeds.device
945
+ mask_factory_function = causal_mask_function
946
+ mask_interface = ALL_MASK_ATTENTION_FUNCTIONS[config._attn_implementation]
947
+
948
+ # Defaulting to using non-vmap based mask creations except when detecting
949
+ # users passing custom mask functions (as we cannot guarantee that they
950
+ # are properly index-based as required by our implementation).
951
+ use_vmap = False
952
+
953
+ # Do not allow skip if we are compiling (this is to match BC)
954
+ # TODO: cyril -> probably revisit and remove this, but a lot of tests rely on it
955
+ if _is_torch_xpu_available:
956
+ # Do not allow skip if we are compiling for decoding, but for prefill, we still allow skip to optimization the perf of 1st token generation
957
+ allow_is_causal_skip = not (getattr(past_key_values, "is_compileable", False) and q_length == 1)
958
+ else:
959
+ allow_is_causal_skip = not getattr(past_key_values, "is_compileable", False)
960
+
961
+ # Allow slight deviations from causal mask
962
+ # Note that it is very important to apply this before any other deviations of the mask (such as packed sequence mask,
963
+ # padding mask, etc) as the resulting mask may otherwise not be correct!
964
+ if or_mask_function is not None:
965
+ if not _is_torch_greater_or_equal_than_2_6:
966
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
967
+ mask_factory_function = or_masks(mask_factory_function, or_mask_function)
968
+ allow_is_causal_skip = False
969
+ use_vmap = True
970
+ if and_mask_function is not None:
971
+ if not _is_torch_greater_or_equal_than_2_6:
972
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
973
+ mask_factory_function = and_masks(mask_factory_function, and_mask_function)
974
+ allow_is_causal_skip = False
975
+ use_vmap = True
976
+
977
+ # If we detected packing format
978
+ if packed_sequence_mask is not None:
979
+ mask_factory_function = and_masks(mask_factory_function, packed_sequence_mask_function(packed_sequence_mask))
980
+ allow_is_causal_skip = False
981
+
982
+ # We now create the mask
983
+ causal_mask = mask_interface(
984
+ batch_size=batch_size,
985
+ q_length=q_length,
986
+ kv_length=kv_length,
987
+ q_offset=q_offset,
988
+ kv_offset=kv_offset,
989
+ mask_function=mask_factory_function,
990
+ attention_mask=attention_mask,
991
+ allow_is_causal_skip=allow_is_causal_skip, # additional kwarg for sdpa
992
+ dtype=dtype, # Additional kwarg for eager
993
+ config=config, # Pass the config as well, in case someone wants to easily have their own mask_interface
994
+ use_vmap=use_vmap, # Short-circuit to non-vmap expansions for the mask
995
+ device=device,
996
+ )
997
+ return causal_mask
998
+
999
+
1000
+ @deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
1001
+ def create_bidirectional_mask(
1002
+ config: PreTrainedConfig,
1003
+ inputs_embeds: torch.Tensor,
1004
+ attention_mask: torch.Tensor | None,
1005
+ encoder_hidden_states: torch.Tensor | None = None,
1006
+ past_key_values: Cache | None = None,
1007
+ or_mask_function: Callable | None = None,
1008
+ and_mask_function: Callable | None = None,
1009
+ ) -> torch.Tensor | BlockMask | None:
1010
+ """
1011
+ Create a standard bidirectional mask based on the attention implementation used (stored in the config).
1012
+
1013
+ Args:
1014
+ config (`PreTrainedConfig`):
1015
+ The model config.
1016
+ inputs_embeds (`torch.Tensor`):
1017
+ The input embeddings of shape (batch_size, query_length, hidden_dim). This is only used to infer metadata
1018
+ such as the batch size, query length, dtype, and device.
1019
+ past_key_values (`Cache`, optional):
1020
+ The past key values, if we use a cache.
1021
+ attention_mask (`torch.Tensor`, optional):
1022
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, kv_length).
1023
+ It can also be an already prepared 4D mask of shape (batch_size, 1, query_length, kv_length),
1024
+ in which case it is returned as-is.
1025
+ encoder_hidden_states (`torch.Tensor`, optional):
1026
+ The input embeddings of shape (batch_size, kv_length, hidden_dim). If provided, it is used instead of
1027
+ `inputs_embeds` to infer the batch size, kv length and dtype.
1028
+ or_mask_function (`Callable`, optional):
1029
+ An optional mask function to combine with the base mask function (by doing the union of both). This is
1030
+ useful to easily overlay another mask on top, for example for image tokens handling.
1031
+ and_mask_function (`Callable`, optional):
1032
+ An optional mask function to combine with the base mask function (by doing the intersection of both). This is
1033
+ useful to easily overlay another mask on top, for example for image tokens handling.
1034
+ """
1035
+ # We ignore a few irrelevant arguments at the end as we do not have a (growing) cache here
1036
+ early_exit, attention_mask, _, q_length, kv_length, q_offset, kv_offset = _preprocess_mask_arguments(
1037
+ config, inputs_embeds, attention_mask, past_key_values, None, 0, encoder_hidden_states
1038
+ )
1039
+ if early_exit:
1040
+ return attention_mask
1041
+
1042
+ embeds = encoder_hidden_states if encoder_hidden_states is not None else inputs_embeds
1043
+ batch_size, dtype, device = embeds.shape[0], embeds.dtype, embeds.device
1044
+ mask_factory_function = bidirectional_mask_function
1045
+ mask_interface = ALL_MASK_ATTENTION_FUNCTIONS[config._attn_implementation]
1046
+
1047
+ # Allow skipping the mask creation except we have additional masking operators (and/or masks)
1048
+ allow_is_bidirectional_skip = True
1049
+ # Defaulting to using non-vmap based mask creations except when detecting
1050
+ # users passing custom mask functions (as we cannot guarantee that they
1051
+ # are properly index-based as required by our implementation).
1052
+ use_vmap = False
1053
+
1054
+ # Allow slight deviations from the base mask
1055
+ # Note that it is very important to apply this before any other deviations of the mask (such as packed sequence mask,
1056
+ # padding mask, etc) as the resulting mask may otherwise not be correct!
1057
+ if or_mask_function is not None:
1058
+ if not _is_torch_greater_or_equal_than_2_6:
1059
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
1060
+ mask_factory_function = or_masks(mask_factory_function, or_mask_function)
1061
+ allow_is_bidirectional_skip = False
1062
+ use_vmap = True
1063
+ if and_mask_function is not None:
1064
+ if not _is_torch_greater_or_equal_than_2_6:
1065
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
1066
+ mask_factory_function = and_masks(mask_factory_function, and_mask_function)
1067
+ allow_is_bidirectional_skip = False
1068
+ use_vmap = True
1069
+
1070
+ # We now create the mask
1071
+ attention_mask = mask_interface(
1072
+ batch_size=batch_size,
1073
+ q_length=q_length,
1074
+ kv_length=kv_length,
1075
+ q_offset=q_offset,
1076
+ kv_offset=kv_offset,
1077
+ mask_function=mask_factory_function,
1078
+ attention_mask=attention_mask,
1079
+ # Additional kwargs for sdpa
1080
+ allow_is_causal_skip=False,
1081
+ allow_is_bidirectional_skip=allow_is_bidirectional_skip,
1082
+ dtype=dtype, # Additional kwarg for eager
1083
+ config=config, # Pass the config as well, in case someone wants to easily have their own mask_interface
1084
+ use_vmap=use_vmap, # Short-circuit to non-vmap expansions for the mask
1085
+ device=device,
1086
+ )
1087
+ return attention_mask
1088
+
1089
+
1090
+ @deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
1091
+ def create_sliding_window_causal_mask(
1092
+ config: PreTrainedConfig,
1093
+ inputs_embeds: torch.Tensor,
1094
+ attention_mask: torch.Tensor | None,
1095
+ cache_position: torch.Tensor | None = None, # not used anymore but kept for BC
1096
+ *,
1097
+ past_key_values: Cache | None,
1098
+ position_ids: torch.Tensor | None = None,
1099
+ or_mask_function: Callable | None = None,
1100
+ and_mask_function: Callable | None = None,
1101
+ ) -> torch.Tensor | BlockMask | None:
1102
+ """
1103
+ Create a sliding window causal mask based on the attention implementation used (stored in the config). This type
1104
+ of attention pattern was mostly democratized by Mistral. If `past_key_values` has an hybrid cache structure, this
1105
+ function will return the mask corresponding to one of the "sliding_attention" layers (to align to what is needed in the
1106
+ `modeling_xxx.py` files).
1107
+
1108
+ Args:
1109
+ config (`PreTrainedConfig`):
1110
+ The model config.
1111
+ inputs_embeds (`torch.Tensor`):
1112
+ The input embeddings of shape (batch_size, query_length, hidden_dim). This is used only to infer the
1113
+ batch size, query length and dtype.
1114
+ attention_mask (`torch.Tensor`, optional):
1115
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, number_of_seen_tokens+q_length).
1116
+ It can also be an already prepared 4D mask, in which case it is returned as-is.
1117
+ cache_position (`torch.Tensor`):
1118
+ Deprecated and unused.
1119
+ past_key_values (`Cache`, optional):
1120
+ The past key values, if we use a cache.
1121
+ position_ids (`torch.Tensor`, optional)
1122
+ A 2D tensor of shape (batch_size, query_length) indicating the positions of each token in the sequences.
1123
+ or_mask_function (`Callable`, optional):
1124
+ An optional mask function to combine with the sliding causal mask function (by doing the union of both). This is
1125
+ useful to easily overlay another mask on top of the sliding causal one, for example for image tokens handling.
1126
+ and_mask_function (`Callable`, optional):
1127
+ An optional mask function to combine with the sliding causal mask function (by doing the intersection of both). This is
1128
+ useful to easily overlay another mask on top of the sliding causal one, for example for image tokens handling.
1129
+ """
1130
+ # Power feature: if `is_causal` is False, then fallback to bi-directional mask for bi-directional attention
1131
+ # It allows to use decoder-only models with bi-directional attention as well
1132
+ if not getattr(config, "is_causal", True):
1133
+ return create_bidirectional_sliding_window_mask(
1134
+ config,
1135
+ inputs_embeds,
1136
+ attention_mask,
1137
+ past_key_values=past_key_values,
1138
+ or_mask_function=or_mask_function,
1139
+ and_mask_function=and_mask_function,
1140
+ )
1141
+
1142
+ # If we have an hybrid cache structure, here we want to create the mask for the sliding layers
1143
+ if hasattr(past_key_values, "is_sliding") and True in past_key_values.is_sliding:
1144
+ layer_idx = past_key_values.is_sliding.index(True)
1145
+ else:
1146
+ layer_idx = 0
1147
+
1148
+ early_exit, attention_mask, packed_sequence_mask, q_length, kv_length, q_offset, kv_offset = (
1149
+ _preprocess_mask_arguments(config, inputs_embeds, attention_mask, past_key_values, position_ids, layer_idx)
1150
+ )
1151
+ if early_exit:
1152
+ return attention_mask
1153
+
1154
+ sliding_window = getattr(config, "sliding_window", None)
1155
+ if sliding_window is None:
1156
+ raise ValueError("Could not find a `sliding_window` argument in the config, or it is not set")
1157
+
1158
+ batch_size, dtype, device = inputs_embeds.shape[0], inputs_embeds.dtype, inputs_embeds.device
1159
+ mask_factory_function = sliding_window_causal_mask_function(sliding_window)
1160
+ mask_interface = ALL_MASK_ATTENTION_FUNCTIONS[config._attn_implementation]
1161
+
1162
+ # Defaulting to using non-vmap based mask creations except when detecting
1163
+ # users passing custom mask functions (as we cannot guarantee that they
1164
+ # are properly index-based as required by our implementation).
1165
+ use_vmap = False
1166
+ # Do not allow skip if we are compiling (this is to match BC)
1167
+ # TODO: cyril -> probably revisit and remove this, but a lot of tests rely on it
1168
+ allow_is_causal_skip = not getattr(past_key_values, "is_compileable", False)
1169
+
1170
+ # Allow slight deviations from causal mask
1171
+ # Note that it is very important to apply this before any other deviations of the mask (such as packed sequence mask,
1172
+ # padding mask, etc) as the resulting mask may otherwise not be correct!
1173
+ if or_mask_function is not None:
1174
+ if not _is_torch_greater_or_equal_than_2_6:
1175
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
1176
+ mask_factory_function = or_masks(mask_factory_function, or_mask_function)
1177
+ allow_is_causal_skip = False
1178
+ use_vmap = True
1179
+ if and_mask_function is not None:
1180
+ if not _is_torch_greater_or_equal_than_2_6:
1181
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
1182
+ mask_factory_function = and_masks(mask_factory_function, and_mask_function)
1183
+ allow_is_causal_skip = False
1184
+ use_vmap = True
1185
+
1186
+ # If we detected packing format
1187
+ if packed_sequence_mask is not None:
1188
+ mask_factory_function = and_masks(mask_factory_function, packed_sequence_mask_function(packed_sequence_mask))
1189
+ allow_is_causal_skip = False
1190
+
1191
+ # We now create the mask
1192
+ causal_mask = mask_interface(
1193
+ batch_size=batch_size,
1194
+ q_length=q_length,
1195
+ kv_length=kv_length,
1196
+ q_offset=q_offset,
1197
+ kv_offset=kv_offset,
1198
+ mask_function=mask_factory_function,
1199
+ attention_mask=attention_mask,
1200
+ allow_is_causal_skip=allow_is_causal_skip, # additional kwarg for sdpa
1201
+ local_size=sliding_window, # Additional kwarg for sdpa
1202
+ dtype=dtype, # Additional kwarg for eager
1203
+ config=config, # Pass the config as well, in case someone wants to easily have their own mask_interface
1204
+ use_vmap=use_vmap, # Short-circuit to non-vmap expansions for the mask
1205
+ device=device,
1206
+ )
1207
+ return causal_mask
1208
+
1209
+
1210
+ @deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
1211
+ def create_bidirectional_sliding_window_mask(
1212
+ config: PreTrainedConfig,
1213
+ inputs_embeds: torch.Tensor,
1214
+ attention_mask: torch.Tensor | None,
1215
+ past_key_values: Cache | None = None,
1216
+ or_mask_function: Callable | None = None,
1217
+ and_mask_function: Callable | None = None,
1218
+ ) -> torch.Tensor | BlockMask | None:
1219
+ """
1220
+ Create a standard bidirectional sliding window mask based on the attention implementation used (stored in the config).
1221
+
1222
+ Args:
1223
+ config (`PreTrainedConfig`):
1224
+ The model config.
1225
+ inputs_embeds (`torch.Tensor`):
1226
+ The input embeddings of shape (batch_size, query_length, hidden_dim). This is only used to infer metadata
1227
+ such as the batch size, query length, dtype, and device.
1228
+ past_key_values (`Cache`, optional):
1229
+ The past key values, if we use a cache.
1230
+ attention_mask (`torch.Tensor`, optional):
1231
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, kv_length).
1232
+ It can also be an already prepared 4D mask of shape (batch_size, 1, query_length, kv_length),
1233
+ in which case it is returned as-is.
1234
+ or_mask_function (`Callable`, optional):
1235
+ An optional mask function to combine with the base mask function (by doing the union of both). This is
1236
+ useful to easily overlay another mask on top, for example for image tokens handling.
1237
+ and_mask_function (`Callable`, optional):
1238
+ An optional mask function to combine with the base mask function (by doing the intersection of both). This is
1239
+ useful to easily overlay another mask on top, for example for image tokens handling.
1240
+ """
1241
+ # We ignore a few irrelevant arguments at the end as we do not have a (growing) cache here
1242
+ early_exit, attention_mask, _, q_length, kv_length, q_offset, kv_offset = _preprocess_mask_arguments(
1243
+ config, inputs_embeds, attention_mask, past_key_values, None, 0
1244
+ )
1245
+ if early_exit:
1246
+ return attention_mask
1247
+
1248
+ sliding_window = getattr(config, "sliding_window", None)
1249
+ if sliding_window is None:
1250
+ raise ValueError("Could not find a `sliding_window` argument in the config, or it is not set")
1251
+
1252
+ batch_size, dtype, device = inputs_embeds.shape[0], inputs_embeds.dtype, inputs_embeds.device
1253
+ mask_factory_function = sliding_window_bidirectional_mask_function(sliding_window)
1254
+ mask_interface = ALL_MASK_ATTENTION_FUNCTIONS[config._attn_implementation]
1255
+
1256
+ use_vmap = False
1257
+ allow_is_bidirectional_skip = True
1258
+
1259
+ if or_mask_function is not None:
1260
+ if not _is_torch_greater_or_equal_than_2_6:
1261
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
1262
+ mask_factory_function = or_masks(mask_factory_function, or_mask_function)
1263
+ allow_is_bidirectional_skip = False
1264
+ use_vmap = True
1265
+ if and_mask_function is not None:
1266
+ if not _is_torch_greater_or_equal_than_2_6:
1267
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
1268
+ mask_factory_function = and_masks(mask_factory_function, and_mask_function)
1269
+ allow_is_bidirectional_skip = False
1270
+ use_vmap = True
1271
+
1272
+ attention_mask = mask_interface(
1273
+ batch_size=batch_size,
1274
+ q_length=q_length,
1275
+ kv_length=kv_length,
1276
+ q_offset=q_offset,
1277
+ kv_offset=kv_offset,
1278
+ mask_function=mask_factory_function,
1279
+ attention_mask=attention_mask,
1280
+ allow_is_causal_skip=False,
1281
+ allow_is_bidirectional_skip=allow_is_bidirectional_skip,
1282
+ local_size=sliding_window, # Additional kwarg for sdpa
1283
+ dtype=dtype, # Additional kwarg for eager
1284
+ config=config, # Pass the config as well, in case someone wants to easily have their own mask_interface
1285
+ use_vmap=use_vmap, # Short-circuit to non-vmap expansions for the mask
1286
+ device=device,
1287
+ )
1288
+ return attention_mask
1289
+
1290
+
1291
+ @deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
1292
+ def create_chunked_causal_mask(
1293
+ config: PreTrainedConfig,
1294
+ inputs_embeds: torch.Tensor,
1295
+ attention_mask: torch.Tensor | None,
1296
+ cache_position: torch.Tensor | None = None, # not used anymore but kept for BC
1297
+ *,
1298
+ past_key_values: Cache | None,
1299
+ position_ids: torch.Tensor | None = None,
1300
+ or_mask_function: Callable | None = None,
1301
+ and_mask_function: Callable | None = None,
1302
+ ) -> torch.Tensor | BlockMask | None:
1303
+ """
1304
+ Create a chunked attention causal mask based on the attention implementation used (stored in the config). This type
1305
+ of attention pattern was mostly democratized by Llama4. If `past_key_values` has an hybrid cache structure, this
1306
+ function will return the mask corresponding to one of the "chunked_attention" layers (to align to what is needed in the
1307
+ `modeling_xxx.py` files).
1308
+
1309
+ Args:
1310
+ config (`PreTrainedConfig`):
1311
+ The model config.
1312
+ inputs_embeds (`torch.Tensor`):
1313
+ The input embeddings of shape (batch_size, query_length, hidden_dim). This is used only to infer the
1314
+ batch size, query length and dtype.
1315
+ attention_mask (`torch.Tensor`, optional):
1316
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, number_of_seen_tokens+q_length).
1317
+ It can also be an already prepared 4D mask, in which case it is returned as-is.
1318
+ cache_position (`torch.Tensor`):
1319
+ Deprecated and unused.
1320
+ past_key_values (`Cache`, optional):
1321
+ The past key values, if we use a cache.
1322
+ position_ids (`torch.Tensor`, optional)
1323
+ A 2D tensor of shape (batch_size, query_length) indicating the positions of each token in the sequences.
1324
+ or_mask_function (`Callable`, optional):
1325
+ An optional mask function to combine with the chunked causal mask function (by doing the union of both). This is
1326
+ useful to easily overlay another mask on top of the chunked causal one, for example for image tokens handling.
1327
+ and_mask_function (`Callable`, optional):
1328
+ An optional mask function to combine with the chunked causal mask function (by doing the intersection of both). This is
1329
+ useful to easily overlay another mask on top of the chunked causal one, for example for image tokens handling.
1330
+ """
1331
+ # If we have an hybrid cache structure, here we want to create the mask for the sliding layers
1332
+ if hasattr(past_key_values, "is_sliding") and True in past_key_values.is_sliding:
1333
+ layer_idx = past_key_values.is_sliding.index(True)
1334
+ else:
1335
+ layer_idx = 0
1336
+
1337
+ early_exit, attention_mask, packed_sequence_mask, q_length, kv_length, q_offset, kv_offset = (
1338
+ _preprocess_mask_arguments(config, inputs_embeds, attention_mask, past_key_values, position_ids, layer_idx)
1339
+ )
1340
+ if early_exit:
1341
+ return attention_mask
1342
+
1343
+ chunk_size = getattr(config, "attention_chunk_size", None)
1344
+ if chunk_size is None:
1345
+ raise ValueError("Could not find an `attention_chunk_size` argument in the config, or it is not set")
1346
+
1347
+ # Raise if using chunked attention on context too large with FA
1348
+ if is_flash_attention_requested(config) and kv_length + kv_offset > chunk_size:
1349
+ raise ValueError(
1350
+ "Flash attention cannot handle chunked attention, and the key-value length is larger than the chunk size so the "
1351
+ "chunked pattern cannot be respected. You should use another `attn_implementation` when instantiating the model"
1352
+ )
1353
+
1354
+ batch_size, dtype, device = inputs_embeds.shape[0], inputs_embeds.dtype, inputs_embeds.device
1355
+ # For chunked attention and batched inputs, we need to take the number of left padding tokens into account
1356
+ # to start the chunk from the actual start of the sequence for the padded sequence
1357
+ if attention_mask is not None:
1358
+ # Only count the left padding tokens, not all of them
1359
+ left_padding_tokens = (attention_mask.cumsum(dim=-1) == torch.zeros_like(attention_mask)).sum(dim=-1)
1360
+ else:
1361
+ left_padding_tokens = torch.zeros(batch_size, device=device, dtype=int)
1362
+ mask_factory_function = chunked_causal_mask_function(chunk_size, left_padding_tokens)
1363
+ mask_interface = ALL_MASK_ATTENTION_FUNCTIONS[config._attn_implementation]
1364
+
1365
+ # Defaulting to using non-vmap based mask creations except when detecting
1366
+ # users passing custom mask functions (as we cannot guarantee that they
1367
+ # are properly index-based as required by our implementation).
1368
+ use_vmap = False
1369
+ # Do not allow skip if we are compiling (this is to match BC)
1370
+ # TODO: cyril -> probably revisit and remove this, but a lot of tests rely on it
1371
+ allow_is_causal_skip = not getattr(past_key_values, "is_compileable", False)
1372
+
1373
+ # Allow slight deviations from causal mask
1374
+ # Note that it is very important to apply this before any other deviations of the mask (such as packed sequence mask,
1375
+ # padding mask, etc) as the resulting mask may otherwise not be correct!
1376
+ if or_mask_function is not None:
1377
+ if not _is_torch_greater_or_equal_than_2_6:
1378
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
1379
+ mask_factory_function = or_masks(mask_factory_function, or_mask_function)
1380
+ allow_is_causal_skip = False
1381
+ use_vmap = True
1382
+ if and_mask_function is not None:
1383
+ if not _is_torch_greater_or_equal_than_2_6:
1384
+ raise ValueError("Using `or_mask_function` or `and_mask_function` arguments require torch>=2.6")
1385
+ mask_factory_function = and_masks(mask_factory_function, and_mask_function)
1386
+ allow_is_causal_skip = False
1387
+ use_vmap = True
1388
+
1389
+ # If we detected packing format
1390
+ if packed_sequence_mask is not None:
1391
+ mask_factory_function = and_masks(mask_factory_function, packed_sequence_mask_function(packed_sequence_mask))
1392
+ allow_is_causal_skip = False
1393
+
1394
+ # We now create the mask
1395
+ causal_mask = mask_interface(
1396
+ batch_size=batch_size,
1397
+ q_length=q_length,
1398
+ kv_length=kv_length,
1399
+ q_offset=q_offset,
1400
+ kv_offset=kv_offset,
1401
+ mask_function=mask_factory_function,
1402
+ attention_mask=attention_mask,
1403
+ allow_is_causal_skip=allow_is_causal_skip, # additional kwarg for sdpa
1404
+ local_size=chunk_size, # Additional kwarg for sdpa
1405
+ dtype=dtype, # Additional kwarg for eager
1406
+ config=config, # Pass the config as well, in case someone wants to easily have their own mask_interface
1407
+ use_vmap=use_vmap, # Short-circuit to non-vmap expansions for the mask
1408
+ device=device,
1409
+ )
1410
+ return causal_mask
1411
+
1412
+
1413
+ LAYER_PATTERN_TO_MASK_FUNCTION_MAPPING = {
1414
+ "full_attention": create_causal_mask,
1415
+ "sliding_attention": create_sliding_window_causal_mask,
1416
+ "chunked_attention": create_chunked_causal_mask,
1417
+ }
1418
+
1419
+
1420
+ @deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
1421
+ def create_masks_for_generate(
1422
+ config: PreTrainedConfig,
1423
+ inputs_embeds: torch.Tensor,
1424
+ attention_mask: torch.Tensor | None,
1425
+ past_key_values: Cache | None,
1426
+ position_ids: torch.Tensor | None = None,
1427
+ or_mask_function: Callable | None = None,
1428
+ and_mask_function: Callable | None = None,
1429
+ **kwargs,
1430
+ ):
1431
+ """
1432
+ This function mimics how we create the masks in the `modeling_xxx.py` files, and is used in places like `generate`
1433
+ in order to easily create the masks in advance, when we compile the forwards with Static caches.
1434
+
1435
+ Args:
1436
+ config (`PreTrainedConfig`):
1437
+ The model config.
1438
+ inputs_embeds (`torch.Tensor`):
1439
+ The input embeddings of shape (batch_size, query_length, hidden_dim). This is used only to infer the
1440
+ batch size, query length and dtype.
1441
+ attention_mask (`torch.Tensor`, optional):
1442
+ The 2D attention mask corresponding to padded tokens of shape (batch_size, number_of_seen_tokens+q_length).
1443
+ It can also be an already prepared 4D mask, in which case it is returned as-is.
1444
+ past_key_values (`Cache`, optional):
1445
+ The past key values, if we use a cache.
1446
+ position_ids (`torch.Tensor`, optional)
1447
+ A 2D tensor of shape (batch_size, query_length) indicating the positions of each token in the sequences.
1448
+ or_mask_function (`Callable`, optional):
1449
+ An optional mask function to combine with the other mask function (by doing the union of both). This is
1450
+ useful to easily overlay another mask on top of the causal one, for example for image tokens handling.
1451
+ and_mask_function (`Callable`, optional):
1452
+ An optional mask function to combine with the other mask function (by doing the intersection of both). This is
1453
+ useful to easily overlay another mask on top of the causal one, for example for image tokens handling.
1454
+ """
1455
+ # The attribute reside in the text config for composite models
1456
+ effective_config = config.get_text_config()
1457
+ # Prepare the mask args
1458
+ mask_kwargs = {
1459
+ "config": effective_config,
1460
+ "inputs_embeds": inputs_embeds,
1461
+ "attention_mask": attention_mask,
1462
+ "past_key_values": past_key_values,
1463
+ "position_ids": position_ids,
1464
+ "or_mask_function": or_mask_function,
1465
+ "and_mask_function": and_mask_function,
1466
+ }
1467
+
1468
+ # If the attribute exist, we need several masks
1469
+ if hasattr(effective_config, "layer_types"):
1470
+ causal_masks = {}
1471
+ for layer_pattern in set(effective_config.layer_types):
1472
+ causal_masks[layer_pattern] = LAYER_PATTERN_TO_MASK_FUNCTION_MAPPING[layer_pattern](**mask_kwargs)
1473
+ return causal_masks
1474
+ # In this case, all layers are sliding
1475
+ elif getattr(effective_config, "sliding_window", None) is not None:
1476
+ return create_sliding_window_causal_mask(**mask_kwargs)
1477
+ # In this case, all layers are chunked
1478
+ elif getattr(effective_config, "attention_chunk_size", None) is not None:
1479
+ return create_chunked_causal_mask(**mask_kwargs)
1480
+ # All layers use standard causal attention
1481
+ return create_causal_mask(**mask_kwargs)
1482
+
1483
+
1484
+ # Below are utilities to pretty-print the different masks
1485
+ # Print the matrix with words as row labels
1486
+ GREEN = "\033[92m"
1487
+ YELLOW = "\033[93m"
1488
+ RESET = "\033[0m"
1489
+ BLACK_SQUARE = "■"
1490
+ WHITE_SQUARE = "⬚"
1491
+ GREY_SQUARE = "∙"
1492
+ LOW_TRIANGLE = "⬕"
1493
+ UPPER_TRIANGLE = "⬔"
1494
+
1495
+
1496
+ def get_style(style):
1497
+ if style == "majong":
1498
+ BLACK_SQUARE = "🀞" # Full block (represents "on" or active)
1499
+ BLACK_SQUARE = "🀙" # Full block (represents "on" or active)
1500
+ WHITE_SQUARE = "🀆" # "▒" # Light shade (represents "off" or inactive)
1501
+ LOW_TRIANGLE = "🀛" # Lower left triangle (stylized indication)
1502
+ UPPER_TRIANGLE = "🀛" # Upper left triangle (stylized indication)
1503
+ else:
1504
+ BLACK_SQUARE = "█" # Full block (represents "on" or active)
1505
+ WHITE_SQUARE = "░" # "▒" # Light shade (represents "off" or inactive)
1506
+ LOW_TRIANGLE = "▙" # Lower left triangle (stylized indication))
1507
+ UPPER_TRIANGLE = "▜" # Upper left triangle (stylized indication)
1508
+
1509
+ return BLACK_SQUARE, WHITE_SQUARE, LOW_TRIANGLE, UPPER_TRIANGLE
1510
+
1511
+
1512
+ # LOW_TRIANGLE = UPPER_TRIANGLE = "⟍" # Upper right triangle (stylized indication)
1513
+
1514
+ YELLOW_SQUARE = f"{YELLOW}{BLACK_SQUARE}{RESET}"
1515
+ GREEN_SQUARE = f"{GREEN}{BLACK_SQUARE}{RESET}"
1516
+
1517
+
1518
+ def tensor_to_mask_visual(original_tensor: torch.Tensor, grid_size=(20, 40), style="majong") -> str:
1519
+ BLACK_SQUARE, WHITE_SQUARE, LOW_TRIANGLE, UPPER_TRIANGLE = get_style(style)
1520
+ h, w = original_tensor.shape
1521
+ max_h, max_w = grid_size
1522
+ if not (h < max_h and w < max_w):
1523
+ # Preserve aspect ratio within max grid size
1524
+ aspect_ratio = 2 * w / h
1525
+ if aspect_ratio > 1:
1526
+ w = max_w
1527
+ h = min(max_h, max(1, round(max_w / aspect_ratio)))
1528
+ else:
1529
+ h = max_h
1530
+ w = max(1, round(max_h * aspect_ratio))
1531
+
1532
+ # Step 1: Rescale tensor by average pooling
1533
+ tensor = original_tensor.unsqueeze(0).unsqueeze(0) # Add batch and channel dimensions
1534
+ tensor = F.adaptive_avg_pool2d(tensor, output_size=(h, w))[0, 0] # Remove extra dims
1535
+ else:
1536
+ tensor = original_tensor
1537
+
1538
+ # Step 3: Build the string representation
1539
+ result = []
1540
+ for i in range(h):
1541
+ row = ""
1542
+ for j in range(w):
1543
+ if tensor[i, j] == 1:
1544
+ row += BLACK_SQUARE
1545
+ elif tensor[i, j] == 0:
1546
+ row += WHITE_SQUARE
1547
+ else:
1548
+ if j > 0:
1549
+ if tensor[i, j - 1] == 1:
1550
+ row += LOW_TRIANGLE
1551
+ elif tensor[i, j - 1] == 0:
1552
+ row += UPPER_TRIANGLE
1553
+ else:
1554
+ row += BLACK_SQUARE if tensor[i, j] == 1 else WHITE_SQUARE
1555
+ else:
1556
+ row += (
1557
+ BLACK_SQUARE
1558
+ if tensor[i, j] == 1
1559
+ else (
1560
+ WHITE_SQUARE
1561
+ if tensor[i, j] == 0
1562
+ else (UPPER_TRIANGLE if tensor[i, j + 1] == 1 else LOW_TRIANGLE)
1563
+ )
1564
+ )
1565
+ result.append(row)
1566
+
1567
+ return "\n".join(result)
1568
+
1569
+
1570
+ class AttentionMask(torch.Tensor):
1571
+ def __new__(cls, data, style=None):
1572
+ # Create a new instance of AttentionMask as a Tensor
1573
+ cls.style = style
1574
+ return torch.Tensor._make_subclass(cls, data, require_grad=False)
1575
+
1576
+ def __init__(self, data):
1577
+ # You can initialize any additional metadata here if needed
1578
+ pass
1579
+
1580
+ def to_string(self, grid_size=(20, 40), limit=4):
1581
+ """Returns a string representation of the block mask."""
1582
+ dense_mask = self
1583
+ *batch_dims, num_rows, num_cols = dense_mask.shape
1584
+ total_vis = []
1585
+
1586
+ for idx, batch_idx in enumerate(itertools.product(*[range(i) for i in batch_dims])):
1587
+ if idx == limit:
1588
+ total_vis.append("...")
1589
+ total_vis.append("To print out more, set AttentionMask.to_string(limit=N)")
1590
+ total_vis.append("You can also index (AttentionMask[batch, head]) to choose a specific batch or head")
1591
+ break
1592
+ block_vis = tensor_to_mask_visual(dense_mask[batch_idx], grid_size=grid_size, style=self.style)
1593
+ total_vis.append(block_vis)
1594
+
1595
+ total_vis.append(f"torch.Tensor(shape={tuple(self.shape)}, dtype={self.dtype})")
1596
+ return "\n".join(total_vis)
1597
+
1598
+ def __repr__(self):
1599
+ return self.to_string()
1600
+
1601
+ def __str__(self):
1602
+ return self.to_string()
1603
+
1604
+ @classmethod
1605
+ def from_tensor(cls, tensor: torch.Tensor, style: str | None = None) -> "AttentionMask":
1606
+ res = cls(tensor)
1607
+ res.style = style
1608
+ return res
third_party/transformers/src/transformers/model_debugging_utils.py ADDED
@@ -0,0 +1,455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Inc. team.
2
+ # All rights reserved.
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
+
16
+ import functools
17
+ import json
18
+ import os
19
+ import re
20
+ from contextlib import contextmanager, redirect_stdout
21
+ from io import StringIO
22
+
23
+ from .utils import logging
24
+ from .utils.import_utils import is_torch_available, requires
25
+
26
+
27
+ if is_torch_available():
28
+ import torch
29
+ from safetensors.torch import save_file
30
+
31
+ _torch_distributed_available = False
32
+ # Note to code inspectors: this toolbox is intended for people who add models to `transformers`.
33
+ if torch.distributed.is_available():
34
+ import torch.distributed.tensor
35
+
36
+ _torch_distributed_available = True
37
+ else:
38
+ _torch_distributed_available = False
39
+
40
+
41
+ logger = logging.get_logger(__name__)
42
+
43
+
44
+ def _is_rank_zero():
45
+ """Return True if rank=0 or we aren't running distributed."""
46
+ if not (_torch_distributed_available and torch.distributed.is_initialized()):
47
+ return True
48
+ return torch.distributed.get_rank() == 0
49
+
50
+
51
+ MEMORY_ADDRESS_REGEX = re.compile(r"object at 0x[0-9A-Fa-f]+")
52
+
53
+
54
+ def _sanitize_repr_for_diff(x_str: str) -> str:
55
+ """
56
+ Replace memory addresses in an object's repr with a stable placeholder
57
+ so that beautiful JSON diffs won't be ruined by ephemeral addresses.
58
+ """
59
+ return MEMORY_ADDRESS_REGEX.sub("object at 0xXXXXXXXX", x_str)
60
+
61
+
62
+ def _dtensor_repr(x):
63
+ """Return a stable string representation for a DTensor-like object."""
64
+ if _is_rank_zero():
65
+ return f"DTensor (rank0) -> {repr(x._local_tensor)}"
66
+ return "DTensor(non-rank0)"
67
+
68
+
69
+ def _serialize_tensor_like_io(
70
+ value, debug_path: str | None = None, use_repr: bool = True, path_to_value: str | None = None
71
+ ):
72
+ """
73
+ Converts Tensors and DTensors to a JSON-serializable dictionary representation.
74
+
75
+ Args:
76
+ value: Any Python object, often including torch Tensors, lists, dicts, etc.
77
+ debug_path (`str`, *optional*, defaults to `None`): Directory to dump debug JSON and SafeTensors files.
78
+ use_repr (bool, *optional*, defaults to `True`): Whether to save a `repr()`-ized version of the tensor as the
79
+ `value` property in the asscoiated FULL_TENSORS.json file, or to store the full tensors in separate
80
+ SafeTensors file and store the relative path to that file in the `value` property in the dictionary.
81
+ path_to_value (`str`, *optional*, defaults to `None`): The file name for the SafeTensors file holding the full
82
+ tensor value if `use_repr=False`.
83
+
84
+ Returns:
85
+ A nested Python structure (list, dict, or sanitized string) that is safe to json.dump.
86
+ """
87
+ torch.set_printoptions(sci_mode=True)
88
+
89
+ if use_repr:
90
+ value_out = _repr_to_list(value)
91
+ elif path_to_value:
92
+ if not path_to_value.endswith(".safetensors"):
93
+ path_to_value += ".safetensors"
94
+
95
+ filepath = os.path.join(debug_path, path_to_value) if debug_path else path_to_value
96
+ save_file({"data": value.contiguous().detach().cpu()}, filepath)
97
+ value_out = f"./{path_to_value}"
98
+ else:
99
+ raise ValueError(f"{use_repr=} and {path_to_value=} cannot both be falsy.")
100
+
101
+ out = {
102
+ "shape": repr(value.shape),
103
+ "dtype": repr(value.dtype),
104
+ "value": value_out,
105
+ }
106
+ if value.dtype in {torch.float16, torch.float32, torch.bfloat16}:
107
+ out.update(
108
+ {
109
+ "mean": _sanitize_repr_for_diff(repr(value.mean())),
110
+ "std": _sanitize_repr_for_diff(repr(value.std())),
111
+ "min": _sanitize_repr_for_diff(repr(value.min())),
112
+ "max": _sanitize_repr_for_diff(repr(value.max())),
113
+ }
114
+ )
115
+ return out
116
+
117
+
118
+ def _serialize_io(value, debug_path: str | None = None, use_repr: bool = True, path_to_value: str | None = None):
119
+ """
120
+ Recursively build a JSON-serializable Python structure from `value`.
121
+ Tensors and DTensors become either sanitized repr strings, or are saved to disk as SafeTensors files and their
122
+ relative paths are recorded in the returned Python structure.
123
+ Lists/tuples/dicts are recursed into.
124
+ All memory addresses are replaced with a stable placeholder.
125
+
126
+ Args:
127
+ value: Any Python object, often including torch Tensors, lists, dicts, etc.
128
+ debug_path (`str`, *optional*, defaults to `None`): Directory to dump debug JSON and SafeTensors files.
129
+ use_repr (bool, *optional*, defaults to `True`): Whether to save a `repr()`-ized version of the tensors as the
130
+ `value` property in the asscoiated FULL_TENSORS.json file, or to store full tensors in separate SafeTensors
131
+ files and store the relative path to that file in the `value` property.
132
+ path_to_value (`str`, *optional*, defaults to `None`): The file name for the SafeTensors file holding the full
133
+ tensor value if `use_repr=False`.
134
+
135
+ Returns:
136
+ A nested Python structure (list, dict, or sanitized string) that is safe to json.dump.
137
+ """
138
+ if isinstance(value, (list, tuple)):
139
+ return [
140
+ _serialize_io(v, debug_path=debug_path, use_repr=use_repr, path_to_value=f"{path_to_value}_{i}")
141
+ for i, v in enumerate(value)
142
+ ]
143
+
144
+ if isinstance(value, dict):
145
+ return {
146
+ k: _serialize_io(v, debug_path=debug_path, use_repr=use_repr, path_to_value=f"{path_to_value}_{k}")
147
+ for k, v in value.items()
148
+ }
149
+
150
+ if hasattr(value, "_local_tensor"):
151
+ return _serialize_tensor_like_io(
152
+ value._local_tensor, debug_path=debug_path, use_repr=use_repr, path_to_value=path_to_value
153
+ )
154
+
155
+ if isinstance(value, torch.Tensor):
156
+ return _serialize_tensor_like_io(value, debug_path=debug_path, use_repr=use_repr, path_to_value=path_to_value)
157
+
158
+ return _sanitize_repr_for_diff(repr(value))
159
+
160
+
161
+ def _repr_to_list(value: torch.Tensor):
162
+ """
163
+ Converts a tensor into a sanitized multi-line string representation.
164
+
165
+ Args:
166
+ value (`torch.Tensor`): The tensor to represent.
167
+
168
+ Returns:
169
+ `list[str]`: List of string lines representing the tensor.
170
+ """
171
+ torch.set_printoptions(sci_mode=True, linewidth=120)
172
+ with StringIO() as buf, redirect_stdout(buf):
173
+ print(value) # to redirected stdout to avoid line splits
174
+ raw = buf.getvalue()
175
+ return _sanitize_repr_for_diff(raw).splitlines()
176
+
177
+
178
+ def prune_outputs_if_children(node):
179
+ # if there are children, remove this node's "outputs"
180
+ # so we only see outputs at the leaf level
181
+ if node.get("children"):
182
+ node.pop("outputs", None)
183
+ for child in node["children"]:
184
+ prune_outputs_if_children(child)
185
+
186
+
187
+ LAYER_SUFFIX_RE = re.compile(r"(.*)\.(\d+)$") # should be generic enough, ends with a number
188
+
189
+
190
+ def is_layer_block(node):
191
+ """
192
+ Checks whether a node represents a layer block with submodules.
193
+
194
+ Args:
195
+ node (`dict`): A node from the call tree.
196
+
197
+ Returns:
198
+ `bool`: Whether the node is a layer block.
199
+ """
200
+ match = LAYER_SUFFIX_RE.match(node.get("module_path", ""))
201
+ if not match or not node.get("children"):
202
+ return False
203
+ number = match.group(2)
204
+ return any(f".{number}." in child.get("module_path", "") for child in node["children"])
205
+
206
+
207
+ def prune_intermediate_layers(node):
208
+ """
209
+ Recursively removes intermediate layers from the tree to improve readability.
210
+ Keeps at least the first and last layers if many consecutive layers are present.
211
+
212
+ Args:
213
+ node (`dict`): The root or subnode to prune recursively.
214
+ """
215
+ if not node.get("children"):
216
+ return
217
+ layer_blocks = [(i, child) for i, child in enumerate(node["children"]) if is_layer_block(child)]
218
+
219
+ if len(layer_blocks) > 2:
220
+ to_remove = [i for i, _ in layer_blocks[1:-1]]
221
+ node["children"] = [child for i, child in enumerate(node["children"]) if i not in to_remove]
222
+
223
+ for child in node["children"]:
224
+ prune_intermediate_layers(child)
225
+
226
+
227
+ def log_model_debug_trace(debug_path: str | None, model):
228
+ if debug_path:
229
+ try:
230
+ os.makedirs(debug_path, exist_ok=True)
231
+ base = os.path.join(debug_path, model._debugger_module_dump_name + "_debug_tree")
232
+ except Exception as e:
233
+ raise ValueError(f"Unexpected or existing debug_path={debug_path}.") from e
234
+ else:
235
+ base = model._debugger_module_dump_name + "_debug_tree"
236
+
237
+ logger.info(f"Writing model trace at {base}.json")
238
+ full_path = base + "_FULL_TENSORS.json"
239
+ summary_path = base + "_SUMMARY.json"
240
+
241
+ prune_outputs_if_children(model._call_tree)
242
+
243
+ with open(full_path, "w") as f:
244
+ json.dump(model._call_tree, f, indent=2)
245
+
246
+ # summary-only version for readability - traversing the tree again #TODO optimize?
247
+ def strip_values(node):
248
+ def clean(val):
249
+ if isinstance(val, dict):
250
+ val.pop("value", None)
251
+ for v in val.values():
252
+ clean(v)
253
+ elif isinstance(val, list):
254
+ for item in val:
255
+ clean(item)
256
+
257
+ clean(node.get("inputs", {}))
258
+ clean(node.get("outputs", {}))
259
+
260
+ for child in node.get("children", []):
261
+ strip_values(child)
262
+
263
+ tree_copy = json.loads(json.dumps(model._call_tree)) # deep copy
264
+ strip_values(tree_copy)
265
+
266
+ with open(summary_path, "w") as f:
267
+ json.dump(tree_copy, f, indent=2)
268
+
269
+
270
+ def _attach_debugger_logic(
271
+ model,
272
+ debug_path: str = ".",
273
+ do_prune_layers: bool = True,
274
+ use_repr: bool = True,
275
+ ):
276
+ """
277
+ Attaches a debugging wrapper to every module in the model.
278
+
279
+ This records structured inputs and outputs during the forward pass into a call tree.
280
+
281
+ Args:
282
+ model (`PreTrainedModel`, `nn.Module`): Model to wrap.
283
+ debug_path (`str`): Optional directory to dump debug JSON files.
284
+ do_prune_layers (`bool`, *optional*, defaults to `True`): Whether to prune intermediate layers.
285
+ use_repr (bool, *optional*, defaults to `True`): Whether to save a `repr()`-ized version of the tensors as the
286
+ `value` property in the associated FULL_TENSORS.json file, or to store full tensors in separate SafeTensors
287
+ files and store the relative path to that file in the `value` property.
288
+ """
289
+ class_name = model.__class__.__name__
290
+
291
+ # Prepare data structures on the model object
292
+ model._call_tree = {"module_path": class_name, "inputs": None, "outputs": None, "children": []}
293
+ model._debugger_model_call_stack = []
294
+ model._debugger_module_dump_name = class_name # used for final JSON filename
295
+
296
+ if debug_path:
297
+ try:
298
+ os.makedirs(debug_path, exist_ok=True)
299
+ except Exception as e:
300
+ raise ValueError(f"Unexpected or existing debug_path={debug_path}.") from e
301
+
302
+ def wrap_forward(module, full_path):
303
+ orig_forward = module.forward
304
+
305
+ @functools.wraps(orig_forward)
306
+ def wrapped_forward(*inps, **kws):
307
+ if _is_rank_zero():
308
+ dict_inputs = {"args": inps, "kwargs": kws}
309
+ dict_inputs = {k: dict_inputs[k] for k in dict_inputs if len(dict_inputs[k]) > 0}
310
+ node = {
311
+ "module_path": full_path,
312
+ "inputs": _serialize_io(
313
+ dict_inputs,
314
+ debug_path=debug_path,
315
+ use_repr=use_repr,
316
+ path_to_value=f"{full_path}_inputs",
317
+ ),
318
+ "outputs": None,
319
+ "children": [],
320
+ }
321
+ model._debugger_model_call_stack.append(node)
322
+ with torch.no_grad():
323
+ out = orig_forward(*inps, **kws)
324
+
325
+ if _is_rank_zero():
326
+ if sum(1 for _ in module.named_children()) > 0:
327
+ node["outputs"] = None
328
+ else:
329
+ node["outputs"] = _serialize_io(
330
+ out,
331
+ debug_path=debug_path,
332
+ use_repr=use_repr,
333
+ path_to_value=f"{full_path}_outputs",
334
+ )
335
+
336
+ finished = model._debugger_model_call_stack.pop()
337
+ # prune empty vertices here as well (mostly empty children nodes)
338
+ if not finished["children"]:
339
+ finished.pop("children")
340
+
341
+ if model._debugger_model_call_stack:
342
+ model._debugger_model_call_stack[-1]["children"].append(finished)
343
+ return out
344
+
345
+ module.forward = wrapped_forward
346
+
347
+ # wrap all submodules
348
+ for name, submodule in model.named_modules():
349
+ if name == "":
350
+ continue
351
+ wrap_forward(submodule, f"{class_name}.{name}")
352
+
353
+ # wrap top-level forward
354
+ real_top_forward = model.forward
355
+
356
+ @functools.wraps(real_top_forward)
357
+ def top_wrapped_forward(*inps, **kws):
358
+ if _is_rank_zero():
359
+ top_node = {
360
+ "module_path": f"{class_name} (top-level)",
361
+ "inputs": _serialize_io(
362
+ {"args": inps, "kwargs": kws},
363
+ debug_path=debug_path,
364
+ use_repr=use_repr,
365
+ path_to_value=f"{class_name}_inputs",
366
+ ),
367
+ "outputs": None,
368
+ "children": [],
369
+ }
370
+ model._debugger_model_call_stack.append(top_node)
371
+
372
+ out = real_top_forward(*inps, **kws)
373
+ if _is_rank_zero() and model._debugger_model_call_stack:
374
+ top_node["outputs"] = _serialize_io(
375
+ out,
376
+ debug_path=debug_path,
377
+ use_repr=use_repr,
378
+ path_to_value=f"{class_name}_outputs",
379
+ )
380
+ finished = model._debugger_model_call_stack.pop()
381
+ model._call_tree["inputs"] = finished["inputs"]
382
+ model._call_tree["outputs"] = finished["outputs"]
383
+ model._call_tree["children"] = finished["children"]
384
+ # prune empty stuff for visibility
385
+ [model._call_tree.pop(k, None) for k in list(model._call_tree.keys()) if not model._call_tree[k]]
386
+
387
+ # prune layers that are not 0 or last
388
+ if do_prune_layers:
389
+ prune_intermediate_layers(model._call_tree)
390
+ # Write final JSON trace here
391
+ log_model_debug_trace(debug_path=debug_path, model=model)
392
+ return out
393
+
394
+ model.forward = top_wrapped_forward
395
+
396
+
397
+ @requires(backends=("torch",))
398
+ @contextmanager
399
+ def model_addition_debugger_context(
400
+ model,
401
+ debug_path: str | None = None,
402
+ do_prune_layers: bool = True,
403
+ use_repr: bool = True,
404
+ ):
405
+ """
406
+ # Model addition debugger - context manager for model adders
407
+ This context manager is a power user tool intended for model adders.
408
+
409
+ It tracks all forward calls within a model forward and logs a slice of each input and output on a nested JSON file.
410
+ If `use_repr=True` (the default), the JSON file will record a `repr()`-ized version of the tensors as a list of
411
+ strings. If `use_repr=False`, the full tensors will be stored in separate SafeTensors files and the JSON file will
412
+ provide a relative path to that file.
413
+
414
+ To note, this context manager enforces `torch.no_grad()`.
415
+
416
+ ## Usage
417
+
418
+ add the context manager to a model to debug
419
+
420
+ ```python
421
+ import torch
422
+
423
+ from PIL import Image
424
+ from transformers import LlavaProcessor, LlavaForConditionalGeneration, model_addition_debugger_context
425
+
426
+ torch.random.manual_seed(673)
427
+
428
+ # load pretrained model and processor
429
+ model_id = "llava-hf/llava-1.5-7b-hf"
430
+ processor = LlavaProcessor.from_pretrained(model_id)
431
+ model = LlavaForConditionalGeneration.from_pretrained(model_id)
432
+
433
+ # create random image input
434
+ random_image = Image.fromarray(torch.randint(0, 256, (224, 224, 3), dtype=torch.uint8).numpy())
435
+
436
+ # prompt
437
+ prompt = "<image>Describe this image."
438
+
439
+ # process inputs
440
+ inputs = processor(text=prompt, images=random_image, return_tensors="pt")
441
+
442
+ # call forward method (not .generate!)
443
+ with model_addition_debugger_context(model, debug_path="Your_debug_path", do_prune_layers=False):
444
+ output = model.forward(**inputs)
445
+ ```
446
+
447
+ """
448
+ orig_forwards = {m: m.forward for _, m in model.named_modules()}
449
+ orig_forwards[model] = model.forward
450
+ _attach_debugger_logic(model, debug_path, do_prune_layers, use_repr)
451
+ try:
452
+ yield model
453
+ finally:
454
+ for module_instance, forward_method in orig_forwards.items():
455
+ module_instance.forward = forward_method
third_party/transformers/src/transformers/modeling_flash_attention_utils.py ADDED
@@ -0,0 +1,807 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The Fairseq Authors and the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import importlib
15
+ import inspect
16
+ import os
17
+ from collections.abc import Callable
18
+ from functools import partial
19
+ from typing import TypedDict
20
+
21
+ import torch
22
+ import torch.nn.functional as F
23
+
24
+ from .utils import (
25
+ is_flash_attn_2_available,
26
+ is_flash_attn_3_available,
27
+ is_flash_attn_4_available,
28
+ is_torch_cuda_available,
29
+ is_torch_mlu_available,
30
+ is_torch_npu_available,
31
+ is_torch_xpu_available,
32
+ logging,
33
+ )
34
+ from .utils.import_utils import PACKAGE_DISTRIBUTION_MAPPING, is_tracing
35
+
36
+
37
+ logger = logging.get_logger(__name__)
38
+
39
+
40
+ # TODO Deprecate when all models have the attention interface
41
+ def flash_attn_supports_top_left_mask():
42
+ if is_flash_attn_2_available() or is_flash_attn_3_available() or is_flash_attn_4_available():
43
+ return False
44
+
45
+ from .integrations.npu_flash_attention import is_npu_fa2_top_left_aligned_causal_mask
46
+
47
+ return is_npu_fa2_top_left_aligned_causal_mask()
48
+
49
+
50
+ # TODO Deprecate when all models have the attention interface
51
+ def is_flash_attn_available():
52
+ return (
53
+ is_flash_attn_4_available()
54
+ or is_flash_attn_3_available()
55
+ or is_flash_attn_2_available()
56
+ or is_torch_npu_available()
57
+ or is_torch_xpu_available()
58
+ )
59
+
60
+
61
+ # Mapping from flash attention implementations to their kernel fallback repositories
62
+ FLASH_ATTN_KERNEL_FALLBACK = {
63
+ "flash_attention_2": "kernels-community/flash-attn2",
64
+ "flash_attention_3": "kernels-community/vllm-flash-attn3",
65
+ "flash_attention_4": "kernels-community/flash-attn4",
66
+ }
67
+
68
+
69
+ # Meta information on each mainline FA compatibility:
70
+ # 1. The import structure and availability
71
+ # 2. Device support (with custom ones that use other workarounds, e.g. kernels)
72
+ # 3. Supported major cuda devices, e.g. Hopper, Blackwell. Mostly found in the newest FA versions
73
+ FLASH_ATTENTION_COMPATIBILITY_MATRIX = {
74
+ 2: {
75
+ "flash_attn_version": 2,
76
+ "general_availability_check": is_flash_attn_2_available,
77
+ "pkg_availability_check": lambda *args, **kwargs: importlib.util.find_spec("flash_attn") is not None
78
+ and "flash-attn" in [pkg.replace("_", "-") for pkg in PACKAGE_DISTRIBUTION_MAPPING["flash_attn"]],
79
+ "supported_devices": (
80
+ (is_torch_cuda_available, "cuda"),
81
+ (is_torch_mlu_available, "mlu"),
82
+ (is_torch_npu_available, "npu"),
83
+ (is_torch_xpu_available, "xpu"),
84
+ ),
85
+ "custom_supported_devices": (
86
+ (is_torch_npu_available, "Detect using FlashAttention2 on Ascend NPU."),
87
+ (
88
+ is_torch_xpu_available,
89
+ f"Detect using FlashAttention2 (via kernel `{FLASH_ATTN_KERNEL_FALLBACK['flash_attention_2']}`) on XPU.",
90
+ ),
91
+ ),
92
+ },
93
+ 3: {
94
+ "flash_attn_version": 3,
95
+ "general_availability_check": is_flash_attn_3_available,
96
+ "pkg_availability_check": lambda *args, **kwargs: importlib.util.find_spec("flash_attn_interface") is not None
97
+ and "flash-attn-3" in [pkg.replace("_", "-") for pkg in PACKAGE_DISTRIBUTION_MAPPING["flash_attn_interface"]],
98
+ "supported_devices": ((is_torch_cuda_available, "cuda"),),
99
+ "cuda_min_major_version": 8, # Ampere
100
+ },
101
+ 4: {
102
+ "flash_attn_version": 4,
103
+ "general_availability_check": is_flash_attn_4_available,
104
+ "pkg_availability_check": lambda *args, **kwargs: importlib.util.find_spec("flash_attn") is not None
105
+ and "flash-attn-4" in [pkg.replace("_", "-") for pkg in PACKAGE_DISTRIBUTION_MAPPING["flash_attn"]],
106
+ "supported_devices": ((is_torch_cuda_available, "cuda"),),
107
+ "cuda_min_major_version": 9, # Hopper
108
+ },
109
+ }
110
+
111
+
112
+ # `globals()` is not compatible with dynamo, hence we have do define them in global scope ourselves
113
+ _loaded_implementation = None
114
+ _flash_fn = None
115
+ _flash_varlen_fn = None
116
+ _flash_with_kvcache_fn = None
117
+ _pad_fn = None
118
+ _unpad_fn = None
119
+
120
+ # function that processes kwargs, generalized to handle any supported kwarg within the function
121
+ _process_flash_kwargs_fn = None
122
+ # exceptions where hf API doesn't match the original flash attention API
123
+ _hf_api_to_flash_mapping = {
124
+ "dropout": "dropout_p",
125
+ "sliding_window": "window_size",
126
+ }
127
+ # alternative names within the different flash attention APIs, e.g. for attention sinks
128
+ _flash_api_alternative_names = {"s_aux": "learnable_sink"}
129
+
130
+
131
+ def _lazy_imports(
132
+ implementation: str | None, attention_wrapper: Callable | None = None, allow_all_kernels: bool = False
133
+ ):
134
+ """
135
+ Lazy loads the respective flash attention implementations.
136
+
137
+ Return:
138
+ flash_attn_func: The base flash attention function.
139
+ flash_attn_varlen_func: The flash attention function supporting variable sequence lengths,
140
+ e.g. for padding-free training.
141
+ pad_input: The function to pad inputs into one sequence and returning the respective kwargs.
142
+ unpad_input: The function to unpad outputs based on the kwargs (from pad_input).
143
+ """
144
+ is_fa2 = is_flash_attn_2_available()
145
+ is_fa3 = is_flash_attn_3_available()
146
+ is_fa4 = is_flash_attn_4_available()
147
+
148
+ pad_input, unpad_input = _pad_input, _unpad_input
149
+
150
+ is_paged = implementation.startswith("paged|")
151
+ implementation = implementation.split("|")[1] if is_paged else implementation
152
+
153
+ if (implementation == "flash_attention_2" and is_fa2) or (
154
+ implementation is None and is_fa2 and not is_fa3 and not is_fa4
155
+ ):
156
+ from flash_attn import flash_attn_func, flash_attn_varlen_func, flash_attn_with_kvcache
157
+ from flash_attn.bert_padding import pad_input, unpad_input
158
+ elif is_torch_npu_available():
159
+ # Package `flash-attn` is unavailable on Ascend NPU, which will cause ImportError
160
+ # Flash-Attention2 related apis for Ascend NPU must be imported from `.integrations.npu_flash_attention` module
161
+ from .integrations.npu_flash_attention import npu_flash_attn_func as flash_attn_func
162
+ from .integrations.npu_flash_attention import npu_flash_attn_varlen_func as flash_attn_varlen_func
163
+ from .integrations.npu_flash_attention import npu_flash_attn_with_kvcache as flash_attn_with_kvcache
164
+ else:
165
+ if implementation == "flash_attention_3" or (implementation is None and is_fa3 and not is_fa4):
166
+ from flash_attn_interface import flash_attn_func, flash_attn_varlen_func, flash_attn_with_kvcache
167
+ elif implementation == "flash_attention_4" or (implementation is None and is_fa4):
168
+ from flash_attn.cute import flash_attn_func, flash_attn_varlen_func
169
+
170
+ flash_attn_with_kvcache = None # not supported yet
171
+ # Kernels fallback
172
+ else:
173
+ from .integrations.hub_kernels import load_and_register_attn_kernel
174
+
175
+ # Map standard attention names to hub kernel repos
176
+ kernel_repo = FLASH_ATTN_KERNEL_FALLBACK.get(implementation, implementation)
177
+ # We want to explicitly register the name with `paged|` if found
178
+ kernel_implementation = f"paged|{implementation}" if is_paged else kernel_repo
179
+ kernel = load_and_register_attn_kernel(
180
+ kernel_implementation, attention_wrapper, allow_all_kernels=allow_all_kernels
181
+ )
182
+
183
+ flash_attn_func = getattr(kernel, "flash_attn_func", None)
184
+ flash_attn_varlen_func = getattr(kernel, "flash_attn_varlen_func", None)
185
+ flash_attn_with_kvcache = getattr(kernel, "flash_attn_with_kvcache", None)
186
+ if flash_attn_varlen_func is None:
187
+ raise ValueError(
188
+ f"Could not find the currently requested flash attention implementation at `{implementation}`."
189
+ "Make sure that you request a valid kernel from the hub, e.g. `kernels-community/flash-attn2`."
190
+ )
191
+ if flash_attn_func is None:
192
+ logger.warning(
193
+ f"The loaded flash attention implementation at `{implementation}` only supports varlen, i.e. "
194
+ "it can only be used with continuous batching and does not support the full functionality for "
195
+ "the base transformers generation methods."
196
+ )
197
+ if flash_attn_with_kvcache is None:
198
+ logger.warning(
199
+ f"The loaded flash attention implementation at `{implementation}` does not support block tables, so"
200
+ " the full performances of continuous batching will not be achieved, only the varlen path will be "
201
+ "used."
202
+ )
203
+
204
+ return flash_attn_func, flash_attn_varlen_func, flash_attn_with_kvcache, pad_input, unpad_input
205
+
206
+
207
+ def _lazy_define_process_function(flash_function):
208
+ """
209
+ Depending on the version and kernel some features are not supported. Due to limitations in
210
+ `torch.compile`, we opt to statically type which (optional) kwarg parameters are supported
211
+ within `_process_flash_attention_kwargs`.
212
+
213
+ NOTE: While all supported kwargs are marked as `True`, everything else is marked as `False`.
214
+ This might be confusing for kwargs that we use in any case, e.g. `is_causal`.
215
+ """
216
+
217
+ flash_parameters = inspect.signature(flash_function).parameters
218
+ process_parameters = inspect.signature(_process_flash_attention_kwargs).parameters
219
+
220
+ supports_mapping = {}
221
+ for param in process_parameters:
222
+ fa_param = _hf_api_to_flash_mapping.get(param, param)
223
+ supports_mapping[fa_param] = fa_param in flash_parameters
224
+
225
+ if (fa_alternative_name := _flash_api_alternative_names.get(param, param)) != fa_param:
226
+ supports_mapping[fa_alternative_name] = fa_alternative_name in flash_parameters
227
+
228
+ return partial(_process_flash_attention_kwargs, supports_mapping=supports_mapping)
229
+
230
+
231
+ def lazy_import_flash_attention(
232
+ implementation: str | None, attention_wrapper: Callable | None = None, allow_all_kernels: bool = False
233
+ ):
234
+ """
235
+ Lazily import flash attention and return the respective functions + flags.
236
+
237
+ NOTE: For fullgraph, this needs to be called before compile, while no fullgraph can
238
+ work without preloading. See `load_and_register_attn_kernel` in `integrations.hub_kernels`.
239
+ """
240
+ global _loaded_implementation
241
+ if implementation is None and _loaded_implementation is None:
242
+ raise ValueError("Could not find any flash attn implementation based on your environment.")
243
+
244
+ global _flash_fn, _flash_varlen_fn, _flash_with_kvcache_fn, _pad_fn, _unpad_fn, _process_flash_kwargs_fn
245
+ if implementation is not None and _loaded_implementation != implementation:
246
+ _loaded_implementation = implementation
247
+
248
+ _flash_fn, _flash_varlen_fn, _flash_with_kvcache_fn, _pad_fn, _unpad_fn = _lazy_imports(
249
+ implementation, attention_wrapper, allow_all_kernels=allow_all_kernels
250
+ )
251
+ _process_flash_kwargs_fn = _lazy_define_process_function(_flash_varlen_fn)
252
+
253
+ return (_flash_fn, _flash_varlen_fn, _flash_with_kvcache_fn, _pad_fn, _unpad_fn), _process_flash_kwargs_fn
254
+
255
+
256
+ def lazy_import_paged_flash_attention(implementation: str | None, allow_all_kernels: bool = False):
257
+ """
258
+ Same as `lazy_import_flash_attention` but explicitly wrapping it with the paged implementation.
259
+ """
260
+ from .integrations.flash_paged import paged_attention_forward
261
+
262
+ (_, flash_attn_varlen_func, flash_attn_with_kvcache_fn, _, _), _ = lazy_import_flash_attention(
263
+ implementation, attention_wrapper=paged_attention_forward, allow_all_kernels=allow_all_kernels
264
+ )
265
+ return flash_attn_varlen_func, flash_attn_with_kvcache_fn
266
+
267
+
268
+ def _index_first_axis(tensor, indices):
269
+ """
270
+ A local implementation of the PyTorch indexing operation `tensor[indices]` on the first axis,
271
+ after flattening the first two dimensions of the tensor. This is functionally equivalent to
272
+ FA2's `index_first_axis` and replaces the need to import it.
273
+ """
274
+ # The input tensor is expected to be of shape (batch, seq_len, ...). We flatten the first
275
+ # two dimensions to get (total_tokens, ...) before indexing.
276
+ reshaped_tensor = tensor.reshape(-1, *tensor.shape[2:])
277
+ return reshaped_tensor[indices]
278
+
279
+
280
+ def _unpad_input(hidden_states, attention_mask, unused_mask=None):
281
+ """
282
+ unpad_input function for flash attention variants that do not have them within their pkg themselves, e.g. fa3.
283
+
284
+ Arguments:
285
+ hidden_states: (batch, seqlen, ...)
286
+ attention_mask: (batch, seqlen), bool / int, 1 means valid and 0 means not valid.
287
+ unused_mask: (batch, seqlen), bool / int, 1 means the element is allocated but unused.
288
+
289
+ Return:
290
+ hidden_states: (total_nnz, ...), where total_nnz = number of tokens selected in attention_mask + unused_mask.
291
+ indices: (total_nnz), the indices of masked tokens from the flattened input sequence.
292
+ cu_seqlens: (batch + 1), the cumulative sequence lengths, used to index into hidden_states.
293
+ max_seqlen_in_batch: int
294
+ seqused: (batch), returns the number of tokens selected in attention_mask + unused_mask.
295
+ """
296
+ all_masks = (attention_mask + unused_mask) if unused_mask is not None else attention_mask
297
+ seqlens_in_batch = all_masks.sum(dim=-1, dtype=torch.int32)
298
+ used_seqlens_in_batch = attention_mask.sum(dim=-1, dtype=torch.int32)
299
+ indices = torch.nonzero(all_masks.flatten(), as_tuple=False).flatten()
300
+ max_seqlen_in_batch = seqlens_in_batch.max()
301
+ cu_seqlens = F.pad(torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.int32), (1, 0))
302
+
303
+ return (
304
+ _index_first_axis(hidden_states, indices),
305
+ indices,
306
+ cu_seqlens,
307
+ max_seqlen_in_batch,
308
+ used_seqlens_in_batch,
309
+ )
310
+
311
+
312
+ def _pad_input(hidden_states, indices, batch, seqlen):
313
+ """
314
+ pad_input function for flash attention variants that do not have them within their pkg themselves, e.g. fa3.
315
+
316
+ Arguments:
317
+ hidden_states: (total_nnz, ...), where total_nnz = number of tokens in selected in attention_mask.
318
+ indices: (total_nnz), the indices that represent the non-masked tokens of the original padded input sequence.
319
+ batch: int, batch size for the padded sequence.
320
+ seqlen: int, maximum sequence length for the padded sequence.
321
+
322
+ Return:
323
+ hidden_states: (batch, seqlen, ...)
324
+ """
325
+ dim = hidden_states.shape[1:]
326
+ output = torch.zeros((batch * seqlen), *dim, device=hidden_states.device, dtype=hidden_states.dtype)
327
+ output[indices] = hidden_states
328
+ return output.view(batch, seqlen, *dim)
329
+
330
+
331
+ def _get_unpad_data(attention_mask: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor, int]:
332
+ """
333
+ Retrieves indexing data required to repad unpadded (ragged) tensors.
334
+
335
+ Arguments:
336
+ attention_mask (`torch.Tensor`):
337
+ Boolean or int tensor of shape (batch_size, sequence_length), 1 means valid and 0 means not valid.
338
+
339
+ Return:
340
+ indices (`torch.Tensor`):
341
+ The indices of non-masked tokens from the flattened input sequence.
342
+ cu_seqlens (`torch.Tensor`):
343
+ The cumulative sequence lengths, used to index into ragged (unpadded) tensors. `cu_seqlens` shape is (batch_size + 1,).
344
+ max_seqlen_in_batch (`int`):
345
+ Maximum sequence length in batch.
346
+ """
347
+ seqlens_in_batch = attention_mask.sum(dim=-1, dtype=torch.int32)
348
+ indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten()
349
+ max_seqlen_in_batch = seqlens_in_batch.max()
350
+ cu_seqlens = F.pad(torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.int32), (1, 0))
351
+ return (
352
+ indices,
353
+ cu_seqlens,
354
+ max_seqlen_in_batch,
355
+ )
356
+
357
+
358
+ def _upad_input(
359
+ query_layer: torch.Tensor,
360
+ key_layer: torch.Tensor,
361
+ value_layer: torch.Tensor,
362
+ attention_mask: torch.Tensor,
363
+ query_length: int,
364
+ unpad_input_func,
365
+ ):
366
+ """
367
+ Unpads query, key, and values tensors, using a single dimension for all tokens even though they belong to different batches.
368
+ This function is used instead of `flash_attn.bert_padding.unpad_input` in order to avoid the recomputation of the same intermediary
369
+ tensors for query, key, value tensors.
370
+
371
+ Arguments:
372
+ query_layer (`torch.Tensor`):
373
+ Query state with padding. Shape: (batch_size, query_length, num_heads, head_dim).
374
+ key_layer (`torch.Tensor`):
375
+ Key state with padding. Shape: (batch_size, kv_seq_len, num_key_value_heads, head_dim).
376
+ value_layer (`torch.Tensor`):
377
+ Value state with padding. Shape: (batch_size, kv_seq_len, num_key_value_heads, head_dim).
378
+ attention_mask (`torch.Tensor`):
379
+ Boolean or int tensor of shape (batch_size, sequence_length), 1 means valid and 0 means not valid.
380
+ query_length (`int`):
381
+ Target length.
382
+ unpad_input_func:
383
+ The function to use for unpadding the input tensors.
384
+
385
+ Return:
386
+ query_layer (`torch.Tensor`):
387
+ Query state without padding. Shape: (total_target_length, num_heads, head_dim).
388
+ key_layer (`torch.Tensor`):
389
+ Key state with padding. Shape: (total_source_length, num_key_value_heads, head_dim).
390
+ value_layer (`torch.Tensor`):
391
+ Value state with padding. Shape: (total_source_length, num_key_value_heads, head_dim).
392
+ indices_q (`torch.Tensor`):
393
+ The indices of non-masked tokens from the flattened input target sequence.
394
+ (cu_seqlens_q, cu_seqlens_k) (`tuple[int]`):
395
+ The cumulative sequence lengths for the target (query) and source (key, value), used to index into ragged (unpadded) tensors. `cu_seqlens` shape is (batch_size + 1,).
396
+ (max_seqlen_in_batch_q, max_seqlen_in_batch_k) (`tuple[int]`):
397
+ Maximum sequence length in batch (`max_seqlen_in_batch_q` for the target sequence i.e. query, `max_seqlen_in_batch_k` for the source sequence i.e. key/value).
398
+ """
399
+ indices_k, cu_seqlens_k, max_seqlen_in_batch_k = _get_unpad_data(attention_mask)
400
+
401
+ # With static caches, the k/v states may be larger than the mask -> we need to slice them to avoid generating garbage
402
+ # It's a bit of an anti-pattern, but otherwise we silently compute wrong attentions scores
403
+ if key_layer.shape[1] > (seq_len := attention_mask.shape[-1]):
404
+ key_layer, value_layer = key_layer[:, :seq_len, :, :], value_layer[:, :seq_len, :, :]
405
+
406
+ batch_size, kv_seq_len, num_key_value_heads, head_dim = key_layer.shape
407
+
408
+ key_layer = _index_first_axis(key_layer, indices_k)
409
+ value_layer = _index_first_axis(value_layer, indices_k)
410
+ if query_length == kv_seq_len:
411
+ query_layer = _index_first_axis(query_layer, indices_k)
412
+ cu_seqlens_q = cu_seqlens_k
413
+ max_seqlen_in_batch_q = max_seqlen_in_batch_k
414
+ indices_q = indices_k
415
+ elif query_length == 1:
416
+ max_seqlen_in_batch_q = 1
417
+ cu_seqlens_q = torch.arange(
418
+ batch_size + 1, dtype=torch.int32, device=query_layer.device
419
+ ) # There is a memcpy here, that is very bad.
420
+ indices_q = cu_seqlens_q[:-1]
421
+ query_layer = query_layer.squeeze(1)
422
+ else:
423
+ # The -q_len: slice assumes left padding.
424
+ attention_mask = attention_mask[:, -query_length:]
425
+ query_layer, indices_q, cu_seqlens_q, max_seqlen_in_batch_q, *_ = unpad_input_func(query_layer, attention_mask)
426
+
427
+ return (
428
+ query_layer,
429
+ key_layer,
430
+ value_layer,
431
+ indices_q,
432
+ (cu_seqlens_q, cu_seqlens_k),
433
+ (max_seqlen_in_batch_q, max_seqlen_in_batch_k),
434
+ )
435
+
436
+
437
+ def prepare_fa_kwargs_from_position_ids(position_ids):
438
+ """
439
+ This function returns all the necessary kwargs to call `flash_attn_varlen_func` extracted from position_ids.
440
+
441
+ Arguments:
442
+ position_ids (`torch.Tensor`):
443
+ Boolean or int tensor of shape (batch_size, sequence_length), 1 means valid and 0 means not valid.
444
+
445
+ Return:
446
+ (cu_seqlens_q, cu_seqlens_k) (`tuple[int]`):
447
+ The cumulative sequence lengths for the target (query) and source (key, value), used to index into
448
+ ragged (unpadded) tensors. `cu_seqlens` shape is (batch_size + 1,).
449
+ (max_seqlen_in_batch_q, max_seqlen_in_batch_k) (`tuple[int]`):
450
+ Maximum sequence length in batch (`max_seqlen_in_batch_q` for the target sequence i.e. query,
451
+ `max_seqlen_in_batch_k` for the source sequence i.e. key/value).
452
+ """
453
+ tensor_kwargs = {"dtype": torch.int32, "device": position_ids.device}
454
+
455
+ position_ids = position_ids.reshape(-1)
456
+ indices_q = (position_ids == 0).nonzero().view(-1)
457
+
458
+ cu_seq_lens_q = torch.cat(
459
+ (
460
+ indices_q.to(**tensor_kwargs),
461
+ torch.tensor(position_ids.size(), **tensor_kwargs),
462
+ )
463
+ )
464
+ cu_seq_lens_k = cu_seq_lens_q
465
+
466
+ # https://github.com/Dao-AILab/flash-attention/blob/2dd8078adc1d9b74e315ee99718c0dea0de8eeb6/flash_attn/flash_attn_interface.py#L1423-L1424
467
+ # We should use cu_seq_lens instead of position_ids to get the max length since position_ids is not always increasing
468
+ # for some models (e.g. qwen2-vl).
469
+ max_length_q = cu_seq_lens_q.diff().max()
470
+ max_length_k = max_length_q
471
+
472
+ return (cu_seq_lens_q, cu_seq_lens_k), (max_length_q, max_length_k)
473
+
474
+
475
+ def _prepare_from_posids(query, key, value, position_ids):
476
+ """
477
+ This function returns necessary arguments to call `flash_attn_varlen_func`.
478
+ All three query, key, value states will be flattened.
479
+ Cumulative lengths of each examples in the batch will be extracted from position_ids.
480
+ NOTE: ideally cumulative lengths should be prepared at the data collator stage
481
+
482
+ Arguments:
483
+ query (`torch.Tensor`):
484
+ Query state with padding. Shape: (batch_size, query_length, num_heads, head_dim).
485
+ key (`torch.Tensor`):
486
+ Key state with padding. Shape: (batch_size, kv_seq_len, num_key_value_heads, head_dim).
487
+ value (`torch.Tensor`):
488
+ Value state with padding. Shape: (batch_size, kv_seq_len, num_key_value_heads, head_dim).
489
+ position_ids (`torch.Tensor`):
490
+ Boolean or int tensor of shape (batch_size, sequence_length), 1 means valid and 0 means not valid.
491
+
492
+ Return:
493
+ query (`torch.Tensor`):
494
+ Query state without padding. Shape: (total_target_length, num_heads, head_dim).
495
+ key (`torch.Tensor`):
496
+ Key state with padding. Shape: (total_source_length, num_key_value_heads, head_dim).
497
+ value (`torch.Tensor`):
498
+ Value state with padding. Shape: (total_source_length, num_key_value_heads, head_dim).
499
+ (cu_seqlens_q, cu_seqlens_k) (`tuple[int]`):
500
+ The cumulative sequence lengths for the target (query) and source (key, value), used to index into ragged (unpadded) tensors. `cu_seqlens` shape is (batch_size + 1,).
501
+ (max_seqlen_in_batch_q, max_seqlen_in_batch_k) (`tuple[int]`):
502
+ Maximum sequence length in batch (`max_seqlen_in_batch_q` for the target sequence i.e. query, `max_seqlen_in_batch_k` for the source sequence i.e. key/value).
503
+ """
504
+ query = query.contiguous().view(-1, query.size(-2), query.size(-1))
505
+ key = key.contiguous().view(-1, key.size(-2), key.size(-1))
506
+ value = value.contiguous().view(-1, value.size(-2), value.size(-1))
507
+
508
+ (cu_seq_lens_q, cu_seq_lens_k), (max_length_q, max_length_k) = prepare_fa_kwargs_from_position_ids(position_ids)
509
+
510
+ return (query, key, value, (cu_seq_lens_q, cu_seq_lens_k), (max_length_q, max_length_k))
511
+
512
+
513
+ def _is_packed_sequence(position_ids, batch_size):
514
+ """
515
+ Check the position ids whether packed sequences are indicated or not
516
+ 1. Position ids exist
517
+ 2. Flattened sequences only are supported
518
+ 3. Compile-friendly `not (torch.diff(position_ids, dim=-1) >= 0).all()`, i.e. we have multiple increasing sequences
519
+ """
520
+ if position_ids is None:
521
+ return False
522
+
523
+ increasing_position_sequences = (
524
+ torch.arange(position_ids.shape[1], device=position_ids.device) + position_ids.min()
525
+ )
526
+ return batch_size == 1 and (increasing_position_sequences - position_ids).abs().sum().bool()
527
+
528
+
529
+ def fa_peft_integration_check(
530
+ q: torch.Tensor,
531
+ k: torch.Tensor,
532
+ v: torch.Tensor,
533
+ target_dtype: torch.dtype | None = None,
534
+ ):
535
+ """
536
+ PEFT usually casts the layer norms in float32 for training stability reasons
537
+ therefore the input hidden states gets silently casted in float32. Hence, we need
538
+ cast them back in float16 / bfloat16 just to be sure everything works as expected.
539
+ This might slowdown training & inference so it is recommended to not cast the LayerNorms!
540
+ """
541
+ if target_dtype and q.dtype == torch.float32:
542
+ logger.warning_once(f"Casting fp32 inputs back to {target_dtype} for flash-attn compatibility.")
543
+ q, k, v = q.to(target_dtype), k.to(target_dtype), v.to(target_dtype)
544
+ return q, k, v
545
+
546
+
547
+ class FlashAttentionKwargs(TypedDict, total=False):
548
+ """
549
+ Keyword arguments for Flash Attention with Compile.
550
+
551
+ Attributes:
552
+ cu_seq_lens_q (`torch.LongTensor`, *optional*)
553
+ Gets cumulative sequence length for query state.
554
+ cu_seq_lens_k (`torch.LongTensor`, *optional*)
555
+ Gets cumulative sequence length for key state.
556
+ max_length_q (`int`, *optional*):
557
+ Maximum sequence length for query state.
558
+ max_length_k (`int`, *optional*):
559
+ Maximum sequence length for key state.
560
+ """
561
+
562
+ cu_seq_lens_q: torch.LongTensor | None
563
+ cu_seq_lens_k: torch.LongTensor | None
564
+ max_length_q: int | None
565
+ max_length_k: int | None
566
+
567
+
568
+ def _process_flash_attention_kwargs(
569
+ query_length: int,
570
+ key_length: int,
571
+ is_causal: bool,
572
+ dropout: float = 0.0,
573
+ softmax_scale: float | None = None,
574
+ sliding_window: int | None = None,
575
+ use_top_left_mask: bool = False,
576
+ softcap: float | None = None,
577
+ deterministic: bool | None = None,
578
+ s_aux: torch.Tensor | None = None,
579
+ max_seqlen_q: int | torch.IntTensor | None = None,
580
+ max_seqlen_k: int | torch.IntTensor | None = None,
581
+ supports_mapping: dict[str, bool] | None = None,
582
+ **kwargs,
583
+ ):
584
+ """
585
+ Returns a set of kwargs that are passed down to the according flash attention function based on
586
+ requested features and whether it is supported - depends on the version and kernel implementation
587
+ which is dynamically configured at `lazy_import_flash_attention`. The (un)supported features can be
588
+ inspected in `supports_mapping`, see `_lazy_define_process_function` for more details.
589
+
590
+ Args:
591
+ query_length (`int`):
592
+ Length of the query states
593
+ key_length (`int`):
594
+ Length of the key states
595
+ is_causal (`bool`):
596
+ Whether we perform causal (decoder) attention or full attention.
597
+ dropout (`float`):
598
+ Attention dropout.
599
+ softmax_scale (`float`, *optional*):
600
+ The scaling of QK^T before applying softmax. Default to `1 / sqrt(head_dim)`.
601
+ sliding_window (`int`, *optional*):
602
+ The size of the sliding window, i.e. we look at a max of `sliding_window` tokens back.
603
+ use_top_left_mask (`bool`):
604
+ Deprecated behavior of older versions of flash attention requiring different masking.
605
+ softcap (`float`, *optional*):
606
+ Softcap for the attention logits, used e.g. in gemma2.
607
+ deterministic (`bool`, *optional*):
608
+ Determines if the deterministic option introduced in flash_attn>=2.4.1 is enabled.
609
+ s_aux (`torch.Tensor`, *optional*):
610
+ Attention sink auxiliary that adds a `bias` to the attention calculation via an additional head.
611
+ max_seqlen_q (`Union[int, torch.IntTensor]`, *optional*):
612
+ The maximum sequence length in the query tensor during a varlen forward.
613
+ max_seqlen_k (`Union[int, torch.IntTensor]`, *optional*):
614
+ The maximum sequence length in the key/value tensor during a varlen forward.
615
+ Return:
616
+ flash_kwargs (`dict`):
617
+ A dict of kwargs that are requested and supported.
618
+ """
619
+ flash_kwargs = {
620
+ "causal": is_causal and not (use_top_left_mask and query_length == 1),
621
+ "softmax_scale": softmax_scale,
622
+ }
623
+
624
+ if supports_mapping["dropout_p"]:
625
+ flash_kwargs["dropout_p"] = dropout
626
+
627
+ if supports_mapping["window_size"] and sliding_window is not None and key_length > sliding_window:
628
+ # The flash attention API sets inclusive boundaries, i.e. (4, 0) would take 4 tokens to the left
629
+ # and the current token for a total size of 5. However, we usually define our window sizes by
630
+ # their total window size (when causal). Encoder models as of now seldom use SWA and when they
631
+ # do, they must align with this symmetric logic, i.e. for a total of `2*sliding_window + 1`.
632
+ flash_kwargs["window_size"] = (sliding_window - 1, sliding_window - 1)
633
+
634
+ if supports_mapping["deterministic"]:
635
+ flash_kwargs["deterministic"] = (
636
+ deterministic if deterministic is not None else os.getenv("FLASH_ATTENTION_DETERMINISTIC", "0") == "1"
637
+ )
638
+
639
+ if supports_mapping["softcap"] and softcap is not None:
640
+ flash_kwargs["softcap"] = softcap
641
+
642
+ if ((legacy_sink_param := supports_mapping["s_aux"]) or supports_mapping["learnable_sink"]) and s_aux is not None:
643
+ if legacy_sink_param:
644
+ flash_kwargs["s_aux"] = s_aux # e.g. FA3 (vllm)
645
+ else:
646
+ flash_kwargs["learnable_sink"] = s_aux # FA4
647
+
648
+ # There is a limitation of the flash attention API, as the function `flash_attn_varlen_func`
649
+ # may require `max_length_q`, `max_length_k` to be passed as `int` and not `torch.Tensor`.
650
+ #
651
+ # You can either set
652
+ # - Env: `TORCHDYNAMO_CAPTURE_SCALAR_OUTPUTS=1`
653
+ # - Before compiling: `torch._dynamo.config.capture_scalar_outputs = True`
654
+ # to allow torch compile to handle scalar outputs in those cases.
655
+ same_max_seqlen = max_seqlen_q is max_seqlen_k # to avoid 2x device syncs
656
+ if supports_mapping["max_seqlen_q"] and max_seqlen_q is not None:
657
+ if not isinstance(max_seqlen_q, int) and is_tracing(max_seqlen_q):
658
+ max_seqlen_q = max_seqlen_q.item()
659
+ flash_kwargs["max_seqlen_q"] = max_seqlen_q
660
+
661
+ if supports_mapping["max_seqlen_k"] and max_seqlen_k is not None:
662
+ if same_max_seqlen and flash_kwargs["max_seqlen_q"] is not None:
663
+ max_seqlen_k = flash_kwargs["max_seqlen_q"]
664
+ elif not isinstance(max_seqlen_k, int) and is_tracing(max_seqlen_k):
665
+ max_seqlen_k = max_seqlen_k.item()
666
+ flash_kwargs["max_seqlen_k"] = max_seqlen_k
667
+
668
+ return flash_kwargs
669
+
670
+
671
+ def _flash_attention_forward(
672
+ query_states: torch.Tensor,
673
+ key_states: torch.Tensor,
674
+ value_states: torch.Tensor,
675
+ attention_mask: torch.Tensor | None,
676
+ query_length: int,
677
+ is_causal: bool,
678
+ dropout: float = 0.0,
679
+ position_ids: torch.Tensor | None = None,
680
+ softmax_scale: float | None = None,
681
+ sliding_window: int | None = None,
682
+ use_top_left_mask: bool = False,
683
+ softcap: float | None = None,
684
+ deterministic: bool | None = None,
685
+ cu_seq_lens_q: torch.LongTensor | None = None,
686
+ cu_seq_lens_k: torch.LongTensor | None = None,
687
+ max_length_q: int | None = None,
688
+ max_length_k: int | None = None,
689
+ target_dtype: torch.dtype | None = None,
690
+ attn_implementation: str | None = None,
691
+ **kwargs,
692
+ ):
693
+ """
694
+ Calls the forward method of Flash Attention - if the input hidden states contain at least one padding token
695
+ first unpad the input, then computes the attention scores and pad the final attention scores.
696
+
697
+ (Optional) kwargs are described further in `_process_flash_attention_kwargs` and `FlashAttentionKwargs`.
698
+
699
+ Args:
700
+ query_states (`torch.Tensor`):
701
+ Input query states to be passed to Flash Attention API
702
+ key_states (`torch.Tensor`):
703
+ Input key states to be passed to Flash Attention API
704
+ value_states (`torch.Tensor`):
705
+ Input value states to be passed to Flash Attention API
706
+ attention_mask (`torch.Tensor`, *optional*):
707
+ The padding mask - corresponds to a tensor of size `(batch_size, seq_len)` where 0 stands for the
708
+ position of padding tokens and 1 for the position of non-padding tokens.
709
+ attn_implementation (`str`, *optional*):
710
+ The attention implementation to use. If None, will default to the one based on the environment.
711
+ """
712
+ (flash_fn, flash_varlen_fn, _, pad_fn, unpad_fn), process_flash_kwargs_fn = lazy_import_flash_attention(
713
+ attn_implementation
714
+ )
715
+
716
+ # PEFT possibly silently casts tensors to fp32, this potentially reconverts to correct dtype or is a no op
717
+ query_states, key_states, value_states = fa_peft_integration_check(
718
+ query_states, key_states, value_states, target_dtype
719
+ )
720
+
721
+ # Extract the flash attention kwargs that have been requested (and are supported by the implementation)
722
+ flash_kwargs = partial(
723
+ process_flash_kwargs_fn,
724
+ query_length=query_length,
725
+ key_length=key_states.size(1),
726
+ is_causal=is_causal,
727
+ dropout=dropout,
728
+ softmax_scale=softmax_scale,
729
+ sliding_window=sliding_window,
730
+ use_top_left_mask=use_top_left_mask,
731
+ softcap=softcap,
732
+ deterministic=deterministic,
733
+ **kwargs,
734
+ )
735
+
736
+ # We will use `flash_varlen_fn` to prevent cross-example attention and also allow padding free approach under two cases:
737
+ # Case 1. If position ids is provided and the position ids indicate packed sequences, see `_is_packed_sequence`.
738
+ # Case 2. Some models pass directly pre-computed `cu_seqlens` so we don't need to infer it from position ids. It is safe to
739
+ # use `flash_varlen_fn` knowing we already have all necessary the kwargs.
740
+ #
741
+ # NOTE: it is user's responsibility to take care of flattening `position_ids` if that's needed by the model.
742
+ # See #39121 for more information.
743
+ is_fa_with_position_ids = _is_packed_sequence(position_ids, batch_size=query_states.size(0))
744
+ is_fa_with_varlen_kwargs = all(
745
+ kwarg is not None for kwarg in (cu_seq_lens_q, cu_seq_lens_k, max_length_q, max_length_k)
746
+ )
747
+
748
+ # Contains at least one padding token in the sequence
749
+ if attention_mask is not None:
750
+ q, k, v, indices_q, (cu_seq_lens_q, cu_seq_lens_k), (max_length_q, max_length_k) = _upad_input(
751
+ query_states, key_states, value_states, attention_mask, query_length, unpad_fn
752
+ )
753
+
754
+ # TODO for now this is required to work with
755
+ # https://huggingface.co/kernels-community/metal-flash-sdpa/blob/main/torch-ext/metal_flash_sdpa/__init__.py
756
+ if "mps" in str(q.device):
757
+ cu_seq_lens_k = cu_seq_lens_k.clone()
758
+
759
+ out_unpad = flash_varlen_fn(
760
+ q,
761
+ k,
762
+ v,
763
+ cu_seqlens_q=cu_seq_lens_q,
764
+ cu_seqlens_k=cu_seq_lens_k,
765
+ **flash_kwargs(max_seqlen_q=max_length_q, max_seqlen_k=max_length_k),
766
+ )
767
+ if isinstance(out_unpad, tuple):
768
+ out_unpad = out_unpad[0]
769
+
770
+ out = pad_fn(out_unpad, indices_q, query_states.size(0), query_length)
771
+
772
+ # Padding free, i.e. sequences flattened into one total sequence
773
+ elif is_fa_with_varlen_kwargs or is_fa_with_position_ids:
774
+ if cu_seq_lens_q is None or cu_seq_lens_k is None:
775
+ q, k, v, (cu_seq_lens_q, cu_seq_lens_k), (max_length_q, max_length_k) = _prepare_from_posids(
776
+ query_states, key_states, value_states, position_ids
777
+ )
778
+ else:
779
+ q = query_states.reshape(-1, query_states.size(-2), query_states.size(-1))
780
+ k = key_states.reshape(-1, key_states.size(-2), key_states.size(-1))
781
+ v = value_states.reshape(-1, value_states.size(-2), value_states.size(-1))
782
+
783
+ # TODO for now this is required to work with
784
+ # https://huggingface.co/kernels-community/metal-flash-sdpa/blob/main/torch-ext/metal_flash_sdpa/__init__.py
785
+ if "mps" in str(q.device):
786
+ cu_seq_lens_k = cu_seq_lens_k.clone()
787
+
788
+ out = flash_varlen_fn(
789
+ q,
790
+ k,
791
+ v,
792
+ cu_seqlens_q=cu_seq_lens_q,
793
+ cu_seqlens_k=cu_seq_lens_k,
794
+ **flash_kwargs(max_seqlen_q=max_length_q, max_seqlen_k=max_length_k),
795
+ )
796
+ if isinstance(out, tuple):
797
+ out = out[0]
798
+
799
+ out = out.view(query_states.size(0), -1, out.size(-2), out.size(-1))
800
+
801
+ # No padding
802
+ else:
803
+ out = flash_fn(query_states, key_states, value_states, **flash_kwargs())
804
+ if isinstance(out, tuple):
805
+ out = out[0]
806
+
807
+ return out
third_party/transformers/src/transformers/modeling_layers.py ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 functools import partial
15
+
16
+ import torch
17
+ import torch.nn as nn
18
+
19
+ from .cache_utils import Cache
20
+ from .modeling_outputs import (
21
+ BaseModelOutputWithPast,
22
+ QuestionAnsweringModelOutput,
23
+ SequenceClassifierOutputWithPast,
24
+ TokenClassifierOutput,
25
+ )
26
+ from .models.auto import AutoModel
27
+ from .processing_utils import Unpack
28
+ from .utils import TransformersKwargs, auto_docstring, can_return_tuple, logging
29
+
30
+
31
+ logger = logging.get_logger(__name__)
32
+
33
+
34
+ class GradientCheckpointingLayer(nn.Module):
35
+ """Base class for layers with gradient checkpointing.
36
+
37
+ This class enables gradient checkpointing functionality for a layer. By default, gradient checkpointing is disabled
38
+ (`gradient_checkpointing = False`). When `model.set_gradient_checkpointing()` is called, gradient checkpointing is
39
+ enabled by setting `gradient_checkpointing = True` and assigning a checkpointing function to `_gradient_checkpointing_func`.
40
+
41
+ Important:
42
+
43
+ When using gradient checkpointing with `use_reentrant=True`, inputs that require gradients (e.g. hidden states)
44
+ must be passed as positional arguments (`*args`) rather than keyword arguments to properly propagate gradients.
45
+
46
+ Example:
47
+
48
+ ```python
49
+ >>> # Correct - hidden_states passed as positional arg
50
+ >>> out = self.layer(hidden_states, attention_mask=attention_mask)
51
+
52
+ >>> # Incorrect - hidden_states passed as keyword arg
53
+ >>> out = self.layer(hidden_states=hidden_states, attention_mask=attention_mask)
54
+ ```
55
+ """
56
+
57
+ gradient_checkpointing = False
58
+
59
+ def __call__(self, *args, **kwargs):
60
+ if self.gradient_checkpointing and self.training:
61
+ do_warn = False
62
+ layer_name = self.__class__.__name__
63
+ message = f"Caching is incompatible with gradient checkpointing in {layer_name}. Setting"
64
+
65
+ if "use_cache" in kwargs and kwargs["use_cache"]:
66
+ kwargs["use_cache"] = False
67
+ message += " `use_cache=False`,"
68
+ do_warn = True
69
+
70
+ # different names for the same thing in different layers
71
+ # TODO cyril: this one without `S` can be removed after deprecation cycle
72
+ if "past_key_value" in kwargs and kwargs["past_key_value"] is not None:
73
+ kwargs["past_key_value"] = None
74
+ message += " `past_key_value=None`,"
75
+ do_warn = True
76
+
77
+ if "past_key_values" in kwargs and kwargs["past_key_values"] is not None:
78
+ kwargs["past_key_values"] = None
79
+ message += " `past_key_values=None`,"
80
+ do_warn = True
81
+
82
+ if "layer_past" in kwargs and kwargs["layer_past"] is not None:
83
+ kwargs["layer_past"] = None
84
+ message += " `layer_past=None`,"
85
+ do_warn = True
86
+
87
+ # warn if anything was changed
88
+ if do_warn:
89
+ message = message.rstrip(",") + "."
90
+ logger.warning_once(message)
91
+
92
+ return self._gradient_checkpointing_func(partial(super().__call__, **kwargs), *args)
93
+ return super().__call__(*args, **kwargs)
94
+
95
+
96
+ @auto_docstring
97
+ class GenericForSequenceClassification:
98
+ base_model_prefix = "model"
99
+
100
+ def __init__(self, config):
101
+ super().__init__(config)
102
+ self.num_labels = config.num_labels
103
+ # Similar to `self.model = AutoModel.from_config(config)` but allows to change the base model name if needed in the child class
104
+ setattr(self, self.base_model_prefix, AutoModel.from_config(config))
105
+ self.score = nn.Linear(config.hidden_size, self.num_labels, bias=False)
106
+
107
+ # Initialize weights and apply final processing
108
+ self.post_init()
109
+
110
+ @can_return_tuple
111
+ @auto_docstring
112
+ def forward(
113
+ self,
114
+ input_ids: torch.LongTensor | None = None,
115
+ attention_mask: torch.Tensor | None = None,
116
+ position_ids: torch.LongTensor | None = None,
117
+ past_key_values: Cache | None = None,
118
+ inputs_embeds: torch.FloatTensor | None = None,
119
+ labels: torch.LongTensor | None = None,
120
+ use_cache: bool | None = None,
121
+ **kwargs: Unpack[TransformersKwargs],
122
+ ) -> SequenceClassifierOutputWithPast:
123
+ transformer_outputs: BaseModelOutputWithPast = getattr(self, self.base_model_prefix)(
124
+ input_ids,
125
+ attention_mask=attention_mask,
126
+ position_ids=position_ids,
127
+ past_key_values=past_key_values,
128
+ inputs_embeds=inputs_embeds,
129
+ use_cache=use_cache,
130
+ **kwargs,
131
+ )
132
+ hidden_states = transformer_outputs.last_hidden_state
133
+ logits = self.score(hidden_states)
134
+
135
+ if input_ids is not None:
136
+ batch_size = input_ids.shape[0]
137
+ else:
138
+ batch_size = inputs_embeds.shape[0]
139
+
140
+ if self.config.pad_token_id is None and batch_size != 1:
141
+ raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.")
142
+ if self.config.pad_token_id is None:
143
+ last_non_pad_token = -1
144
+ elif input_ids is not None:
145
+ # To handle both left- and right- padding, we take the rightmost token that is not equal to pad_token_id
146
+ non_pad_mask = (input_ids != self.config.pad_token_id).to(logits.device, torch.int32)
147
+ token_indices = torch.arange(input_ids.shape[-1], device=logits.device, dtype=torch.int32)
148
+ last_non_pad_token = (token_indices * non_pad_mask).argmax(-1)
149
+ else:
150
+ last_non_pad_token = -1
151
+ logger.warning_once(
152
+ f"{self.__class__.__name__} will not detect padding tokens in `inputs_embeds`. Results may be "
153
+ "unexpected if using padding tokens in conjunction with `inputs_embeds.`"
154
+ )
155
+
156
+ pooled_logits = logits[torch.arange(batch_size, device=logits.device), last_non_pad_token]
157
+
158
+ loss = None
159
+ if labels is not None:
160
+ loss = self.loss_function(logits=logits, labels=labels, pooled_logits=pooled_logits, config=self.config)
161
+
162
+ return SequenceClassifierOutputWithPast(
163
+ loss=loss,
164
+ logits=pooled_logits,
165
+ past_key_values=transformer_outputs.past_key_values,
166
+ hidden_states=transformer_outputs.hidden_states,
167
+ attentions=transformer_outputs.attentions,
168
+ )
169
+
170
+
171
+ @auto_docstring
172
+ class GenericForQuestionAnswering:
173
+ base_model_prefix = "model"
174
+
175
+ def __init__(self, config):
176
+ super().__init__(config)
177
+ # Similar to `self.model = AutoModel.from_config(config)` but allows to change the base model name if needed in the child class
178
+ setattr(self, self.base_model_prefix, AutoModel.from_config(config))
179
+ self.qa_outputs = nn.Linear(config.hidden_size, 2)
180
+
181
+ # Initialize weights and apply final processing
182
+ self.post_init()
183
+
184
+ def get_input_embeddings(self):
185
+ return getattr(self, self.base_model_prefix).embed_tokens
186
+
187
+ def set_input_embeddings(self, value):
188
+ getattr(self, self.base_model_prefix).embed_tokens = value
189
+
190
+ @can_return_tuple
191
+ @auto_docstring
192
+ def forward(
193
+ self,
194
+ input_ids: torch.LongTensor | None = None,
195
+ attention_mask: torch.Tensor | None = None,
196
+ position_ids: torch.LongTensor | None = None,
197
+ past_key_values: Cache | None = None,
198
+ inputs_embeds: torch.FloatTensor | None = None,
199
+ start_positions: torch.LongTensor | None = None,
200
+ end_positions: torch.LongTensor | None = None,
201
+ **kwargs: Unpack[TransformersKwargs],
202
+ ) -> QuestionAnsweringModelOutput:
203
+ outputs: BaseModelOutputWithPast = getattr(self, self.base_model_prefix)(
204
+ input_ids,
205
+ attention_mask=attention_mask,
206
+ position_ids=position_ids,
207
+ past_key_values=past_key_values,
208
+ inputs_embeds=inputs_embeds,
209
+ **kwargs,
210
+ )
211
+
212
+ sequence_output = outputs.last_hidden_state
213
+
214
+ logits = self.qa_outputs(sequence_output)
215
+ start_logits, end_logits = logits.split(1, dim=-1)
216
+ start_logits = start_logits.squeeze(-1).contiguous()
217
+ end_logits = end_logits.squeeze(-1).contiguous()
218
+
219
+ loss = None
220
+ if start_positions is not None and end_positions is not None:
221
+ loss = self.loss_function(start_logits, end_logits, start_positions, end_positions, **kwargs)
222
+
223
+ return QuestionAnsweringModelOutput(
224
+ loss=loss,
225
+ start_logits=start_logits,
226
+ end_logits=end_logits,
227
+ hidden_states=outputs.hidden_states,
228
+ attentions=outputs.attentions,
229
+ )
230
+
231
+
232
+ @auto_docstring
233
+ class GenericForTokenClassification:
234
+ base_model_prefix = "model"
235
+
236
+ def __init__(self, config):
237
+ super().__init__(config)
238
+ self.num_labels = config.num_labels
239
+ # Similar to `self.model = AutoModel.from_config(config)` but allows to change the base model name if needed in the child class
240
+ setattr(self, self.base_model_prefix, AutoModel.from_config(config))
241
+ if getattr(config, "classifier_dropout", None) is not None:
242
+ classifier_dropout = config.classifier_dropout
243
+ elif getattr(config, "hidden_dropout", None) is not None:
244
+ classifier_dropout = config.hidden_dropout
245
+ else:
246
+ classifier_dropout = 0.1
247
+ self.dropout = nn.Dropout(classifier_dropout)
248
+ self.score = nn.Linear(config.hidden_size, config.num_labels)
249
+
250
+ # Initialize weights and apply final processing
251
+ self.post_init()
252
+
253
+ @can_return_tuple
254
+ @auto_docstring
255
+ def forward(
256
+ self,
257
+ input_ids: torch.LongTensor | None = None,
258
+ attention_mask: torch.Tensor | None = None,
259
+ position_ids: torch.LongTensor | None = None,
260
+ past_key_values: Cache | None = None,
261
+ inputs_embeds: torch.FloatTensor | None = None,
262
+ labels: torch.LongTensor | None = None,
263
+ use_cache: bool | None = None,
264
+ **kwargs: Unpack[TransformersKwargs],
265
+ ) -> TokenClassifierOutput:
266
+ outputs: BaseModelOutputWithPast = getattr(self, self.base_model_prefix)(
267
+ input_ids,
268
+ attention_mask=attention_mask,
269
+ position_ids=position_ids,
270
+ past_key_values=past_key_values,
271
+ inputs_embeds=inputs_embeds,
272
+ use_cache=use_cache,
273
+ **kwargs,
274
+ )
275
+ sequence_output = outputs.last_hidden_state
276
+ sequence_output = self.dropout(sequence_output)
277
+ logits = self.score(sequence_output)
278
+
279
+ loss = None
280
+ if labels is not None:
281
+ loss = self.loss_function(logits, labels, self.config)
282
+
283
+ return TokenClassifierOutput(
284
+ loss=loss,
285
+ logits=logits,
286
+ hidden_states=outputs.hidden_states,
287
+ attentions=outputs.attentions,
288
+ )
third_party/transformers/src/transformers/models/__init__.py ADDED
@@ -0,0 +1,472 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 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 .afmoe import *
22
+ from .aimv2 import *
23
+ from .albert import *
24
+ from .align import *
25
+ from .altclip import *
26
+ from .apertus import *
27
+ from .arcee import *
28
+ from .aria import *
29
+ from .audio_spectrogram_transformer import *
30
+ from .audioflamingo3 import *
31
+ from .auto import *
32
+ from .autoformer import *
33
+ from .aya_vision import *
34
+ from .bamba import *
35
+ from .bark import *
36
+ from .bart import *
37
+ from .barthez import *
38
+ from .bartpho import *
39
+ from .beit import *
40
+ from .bert import *
41
+ from .bert_generation import *
42
+ from .bert_japanese import *
43
+ from .bertweet import *
44
+ from .big_bird import *
45
+ from .bigbird_pegasus import *
46
+ from .biogpt import *
47
+ from .bit import *
48
+ from .bitnet import *
49
+ from .blenderbot import *
50
+ from .blenderbot_small import *
51
+ from .blip import *
52
+ from .blip_2 import *
53
+ from .bloom import *
54
+ from .blt import *
55
+ from .bridgetower import *
56
+ from .bros import *
57
+ from .byt5 import *
58
+ from .camembert import *
59
+ from .canine import *
60
+ from .chameleon import *
61
+ from .chinese_clip import *
62
+ from .chmv2 import *
63
+ from .clap import *
64
+ from .clip import *
65
+ from .clipseg import *
66
+ from .clvp import *
67
+ from .code_llama import *
68
+ from .codegen import *
69
+ from .cohere import *
70
+ from .cohere2 import *
71
+ from .cohere2_vision import *
72
+ from .cohere_asr import *
73
+ from .colmodernvbert import *
74
+ from .colpali import *
75
+ from .colqwen2 import *
76
+ from .conditional_detr import *
77
+ from .convbert import *
78
+ from .convnext import *
79
+ from .convnextv2 import *
80
+ from .cpm import *
81
+ from .cpmant import *
82
+ from .csm import *
83
+ from .ctrl import *
84
+ from .cvt import *
85
+ from .cwm import *
86
+ from .d_fine import *
87
+ from .dab_detr import *
88
+ from .dac import *
89
+ from .data2vec import *
90
+ from .dbrx import *
91
+ from .deberta import *
92
+ from .deberta_v2 import *
93
+ from .decision_transformer import *
94
+ from .deepseek_v2 import *
95
+ from .deepseek_v3 import *
96
+ from .deepseek_vl import *
97
+ from .deepseek_vl_hybrid import *
98
+ from .deformable_detr import *
99
+ from .deit import *
100
+ from .deprecated import *
101
+ from .depth_anything import *
102
+ from .depth_pro import *
103
+ from .detr import *
104
+ from .dia import *
105
+ from .dialogpt import *
106
+ from .diffllama import *
107
+ from .dinat import *
108
+ from .dinov2 import *
109
+ from .dinov2_with_registers import *
110
+ from .dinov3_convnext import *
111
+ from .dinov3_vit import *
112
+ from .distilbert import *
113
+ from .dit import *
114
+ from .doge import *
115
+ from .donut import *
116
+ from .dots1 import *
117
+ from .dpr import *
118
+ from .dpt import *
119
+ from .edgetam import *
120
+ from .edgetam_video import *
121
+ from .efficientloftr import *
122
+ from .efficientnet import *
123
+ from .electra import *
124
+ from .emu3 import *
125
+ from .encodec import *
126
+ from .encoder_decoder import *
127
+ from .eomt import *
128
+ from .eomt_dinov3 import *
129
+ from .ernie import *
130
+ from .ernie4_5 import *
131
+ from .ernie4_5_moe import *
132
+ from .ernie4_5_vl_moe import *
133
+ from .esm import *
134
+ from .evolla import *
135
+ from .exaone4 import *
136
+ from .exaone_moe import *
137
+ from .falcon import *
138
+ from .falcon_h1 import *
139
+ from .falcon_mamba import *
140
+ from .fast_vlm import *
141
+ from .fastspeech2_conformer import *
142
+ from .flaubert import *
143
+ from .flava import *
144
+ from .flex_olmo import *
145
+ from .florence2 import *
146
+ from .fnet import *
147
+ from .focalnet import *
148
+ from .fsmt import *
149
+ from .funnel import *
150
+ from .fuyu import *
151
+ from .gemma import *
152
+ from .gemma2 import *
153
+ from .gemma3 import *
154
+ from .gemma3n import *
155
+ from .gemma4 import *
156
+ from .git import *
157
+ from .glm import *
158
+ from .glm4 import *
159
+ from .glm4_moe import *
160
+ from .glm4_moe_lite import *
161
+ from .glm4v import *
162
+ from .glm4v_moe import *
163
+ from .glm46v import *
164
+ from .glm_image import *
165
+ from .glm_moe_dsa import *
166
+ from .glm_ocr import *
167
+ from .glmasr import *
168
+ from .glpn import *
169
+ from .got_ocr2 import *
170
+ from .gpt2 import *
171
+ from .gpt_bigcode import *
172
+ from .gpt_neo import *
173
+ from .gpt_neox import *
174
+ from .gpt_neox_japanese import *
175
+ from .gpt_oss import *
176
+ from .gpt_sw3 import *
177
+ from .gptj import *
178
+ from .granite import *
179
+ from .granite_speech import *
180
+ from .granitemoe import *
181
+ from .granitemoehybrid import *
182
+ from .granitemoeshared import *
183
+ from .grounding_dino import *
184
+ from .groupvit import *
185
+ from .helium import *
186
+ from .herbert import *
187
+ from .hgnet_v2 import *
188
+ from .hiera import *
189
+ from .higgs_audio_v2 import *
190
+ from .higgs_audio_v2_tokenizer import *
191
+ from .hubert import *
192
+ from .hunyuan_v1_dense import *
193
+ from .hunyuan_v1_moe import *
194
+ from .ibert import *
195
+ from .idefics import *
196
+ from .idefics2 import *
197
+ from .idefics3 import *
198
+ from .ijepa import *
199
+ from .imagegpt import *
200
+ from .informer import *
201
+ from .instructblip import *
202
+ from .instructblipvideo import *
203
+ from .internvl import *
204
+ from .jais2 import *
205
+ from .jamba import *
206
+ from .janus import *
207
+ from .jetmoe import *
208
+ from .jina_embeddings_v3 import *
209
+ from .kosmos2 import *
210
+ from .kosmos2_5 import *
211
+ from .kyutai_speech_to_text import *
212
+ from .lasr import *
213
+ from .layoutlm import *
214
+ from .layoutlmv2 import *
215
+ from .layoutlmv3 import *
216
+ from .layoutxlm import *
217
+ from .led import *
218
+ from .levit import *
219
+ from .lfm2 import *
220
+ from .lfm2_moe import *
221
+ from .lfm2_vl import *
222
+ from .lightglue import *
223
+ from .lilt import *
224
+ from .llama import *
225
+ from .llama4 import *
226
+ from .llava import *
227
+ from .llava_next import *
228
+ from .llava_next_video import *
229
+ from .llava_onevision import *
230
+ from .longcat_flash import *
231
+ from .longformer import *
232
+ from .longt5 import *
233
+ from .luke import *
234
+ from .lw_detr import *
235
+ from .lxmert import *
236
+ from .m2m_100 import *
237
+ from .mamba import *
238
+ from .mamba2 import *
239
+ from .marian import *
240
+ from .markuplm import *
241
+ from .mask2former import *
242
+ from .maskformer import *
243
+ from .mbart import *
244
+ from .mbart50 import *
245
+ from .megatron_bert import *
246
+ from .megatron_gpt2 import *
247
+ from .metaclip_2 import *
248
+ from .mgp_str import *
249
+ from .mimi import *
250
+ from .minimax import *
251
+ from .minimax_m2 import *
252
+ from .ministral import *
253
+ from .ministral3 import *
254
+ from .mistral import *
255
+ from .mistral3 import *
256
+ from .mistral4 import *
257
+ from .mixtral import *
258
+ from .mlcd import *
259
+ from .mllama import *
260
+ from .mluke import *
261
+ from .mm_grounding_dino import *
262
+ from .mobilebert import *
263
+ from .mobilenet_v1 import *
264
+ from .mobilenet_v2 import *
265
+ from .mobilevit import *
266
+ from .mobilevitv2 import *
267
+ from .modernbert import *
268
+ from .modernbert_decoder import *
269
+ from .modernvbert import *
270
+ from .moonshine import *
271
+ from .moonshine_streaming import *
272
+ from .moshi import *
273
+ from .mpnet import *
274
+ from .mpt import *
275
+ from .mra import *
276
+ from .mt5 import *
277
+ from .musicflamingo import *
278
+ from .musicgen import *
279
+ from .musicgen_melody import *
280
+ from .mvp import *
281
+ from .myt5 import *
282
+ from .nanochat import *
283
+ from .nemotron import *
284
+ from .nemotron_h import *
285
+ from .nllb import *
286
+ from .nllb_moe import *
287
+ from .nomic_bert import *
288
+ from .nougat import *
289
+ from .nystromformer import *
290
+ from .olmo import *
291
+ from .olmo2 import *
292
+ from .olmo3 import *
293
+ from .olmo_hybrid import *
294
+ from .olmoe import *
295
+ from .omdet_turbo import *
296
+ from .oneformer import *
297
+ from .openai import *
298
+ from .opt import *
299
+ from .ovis2 import *
300
+ from .owlv2 import *
301
+ from .owlvit import *
302
+ from .paddleocr_vl import *
303
+ from .paligemma import *
304
+ from .parakeet import *
305
+ from .patchtsmixer import *
306
+ from .patchtst import *
307
+ from .pe_audio import *
308
+ from .pe_audio_video import *
309
+ from .pe_video import *
310
+ from .pegasus import *
311
+ from .pegasus_x import *
312
+ from .perceiver import *
313
+ from .perception_lm import *
314
+ from .persimmon import *
315
+ from .phi import *
316
+ from .phi3 import *
317
+ from .phi4_multimodal import *
318
+ from .phimoe import *
319
+ from .phobert import *
320
+ from .pi0 import *
321
+ from .pi0_fast import *
322
+ from .pix2struct import *
323
+ from .pixio import *
324
+ from .pixtral import *
325
+ from .plbart import *
326
+ from .poolformer import *
327
+ from .pop2piano import *
328
+ from .pp_chart2table import *
329
+ from .pp_doclayout_v2 import *
330
+ from .pp_doclayout_v3 import *
331
+ from .pp_lcnet import *
332
+ from .pp_lcnet_v3 import *
333
+ from .pp_ocrv5_mobile_det import *
334
+ from .pp_ocrv5_server_det import *
335
+ from .prompt_depth_anything import *
336
+ from .prophetnet import *
337
+ from .pvt import *
338
+ from .pvt_v2 import *
339
+ from .qwen2 import *
340
+ from .qwen2_5_omni import *
341
+ from .qwen2_5_vl import *
342
+ from .qwen2_audio import *
343
+ from .qwen2_moe import *
344
+ from .qwen2_vl import *
345
+ from .qwen3 import *
346
+ from .qwen3_5 import *
347
+ from .qwen3_5_moe import *
348
+ from .qwen3_moe import *
349
+ from .qwen3_next import *
350
+ from .qwen3_omni_moe import *
351
+ from .qwen3_vl import *
352
+ from .qwen3_vl_moe import *
353
+ from .rag import *
354
+ from .recurrent_gemma import *
355
+ from .reformer import *
356
+ from .regnet import *
357
+ from .rembert import *
358
+ from .resnet import *
359
+ from .roberta import *
360
+ from .roberta_prelayernorm import *
361
+ from .roc_bert import *
362
+ from .roformer import *
363
+ from .rt_detr import *
364
+ from .rt_detr_v2 import *
365
+ from .rwkv import *
366
+ from .sam import *
367
+ from .sam2 import *
368
+ from .sam2_video import *
369
+ from .sam3 import *
370
+ from .sam3_tracker import *
371
+ from .sam3_tracker_video import *
372
+ from .sam3_video import *
373
+ from .sam_hq import *
374
+ from .seamless_m4t import *
375
+ from .seamless_m4t_v2 import *
376
+ from .seed_oss import *
377
+ from .segformer import *
378
+ from .seggpt import *
379
+ from .sew import *
380
+ from .sew_d import *
381
+ from .shieldgemma2 import *
382
+ from .siglip import *
383
+ from .siglip2 import *
384
+ from .slanext import *
385
+ from .smollm3 import *
386
+ from .smolvlm import *
387
+ from .solar_open import *
388
+ from .speech_encoder_decoder import *
389
+ from .speech_to_text import *
390
+ from .speecht5 import *
391
+ from .splinter import *
392
+ from .squeezebert import *
393
+ from .stablelm import *
394
+ from .starcoder2 import *
395
+ from .superglue import *
396
+ from .superpoint import *
397
+ from .swiftformer import *
398
+ from .swin import *
399
+ from .swin2sr import *
400
+ from .swinv2 import *
401
+ from .switch_transformers import *
402
+ from .t5 import *
403
+ from .t5gemma import *
404
+ from .t5gemma2 import *
405
+ from .table_transformer import *
406
+ from .tapas import *
407
+ from .textnet import *
408
+ from .time_series_transformer import *
409
+ from .timesfm import *
410
+ from .timesfm2_5 import *
411
+ from .timesformer import *
412
+ from .timm_backbone import *
413
+ from .timm_wrapper import *
414
+ from .trocr import *
415
+ from .tvp import *
416
+ from .udop import *
417
+ from .umt5 import *
418
+ from .unispeech import *
419
+ from .unispeech_sat import *
420
+ from .univnet import *
421
+ from .upernet import *
422
+ from .uvdoc import *
423
+ from .vaultgemma import *
424
+ from .vibevoice_asr import *
425
+ from .video_llama_3 import *
426
+ from .video_llava import *
427
+ from .videomae import *
428
+ from .videomt import *
429
+ from .vilt import *
430
+ from .vipllava import *
431
+ from .vision_encoder_decoder import *
432
+ from .vision_text_dual_encoder import *
433
+ from .visual_bert import *
434
+ from .vit import *
435
+ from .vit_mae import *
436
+ from .vit_msn import *
437
+ from .vitdet import *
438
+ from .vitmatte import *
439
+ from .vitpose import *
440
+ from .vitpose_backbone import *
441
+ from .vits import *
442
+ from .vivit import *
443
+ from .vjepa2 import *
444
+ from .voxtral import *
445
+ from .voxtral_realtime import *
446
+ from .wav2vec2 import *
447
+ from .wav2vec2_bert import *
448
+ from .wav2vec2_conformer import *
449
+ from .wav2vec2_phoneme import *
450
+ from .wav2vec2_with_lm import *
451
+ from .wavlm import *
452
+ from .whisper import *
453
+ from .x_clip import *
454
+ from .xcodec import *
455
+ from .xglm import *
456
+ from .xlm import *
457
+ from .xlm_roberta import *
458
+ from .xlm_roberta_xl import *
459
+ from .xlnet import *
460
+ from .xlstm import *
461
+ from .xmod import *
462
+ from .yolos import *
463
+ from .yoso import *
464
+ from .youtu import *
465
+ from .zamba import *
466
+ from .zamba2 import *
467
+ from .zoedepth import *
468
+ else:
469
+ import sys
470
+
471
+ _file = globals()["__file__"]
472
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/beit/__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_beit import *
22
+ from .image_processing_beit import *
23
+ from .image_processing_pil_beit import *
24
+ from .modeling_beit 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/beit/configuration_beit.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Microsoft Research 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
+ """BEiT model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...backbone_utils import BackboneConfigMixin
19
+ from ...configuration_utils import PreTrainedConfig
20
+ from ...utils import auto_docstring
21
+
22
+
23
+ @auto_docstring(checkpoint="microsoft/beit-base-patch16-224-pt22k")
24
+ @strict
25
+ class BeitConfig(BackboneConfigMixin, PreTrainedConfig):
26
+ r"""
27
+ use_mask_token (`bool`, *optional*, defaults to `False`):
28
+ Whether to use a mask token for masked image modeling.
29
+ use_relative_position_bias (`bool`, *optional*, defaults to `False`):
30
+ Whether to use T5-style relative position embeddings in the self-attention layers.
31
+ use_shared_relative_position_bias (`bool`, *optional*, defaults to `False`):
32
+ Whether to use the same relative position embeddings across all self-attention layers of the Transformer.
33
+ use_mean_pooling (`bool`, *optional*, defaults to `True`):
34
+ Whether to mean pool the final hidden states of the patches instead of using the final hidden state of the
35
+ CLS token, before applying the classification head.
36
+ pool_scales (`tuple[int]`, *optional*, defaults to `[1, 2, 3, 6]`):
37
+ Pooling scales used in Pooling Pyramid Module applied on the last feature map.
38
+ use_auxiliary_head (`bool`, *optional*, defaults to `True`):
39
+ Whether to use an auxiliary head during training.
40
+ auxiliary_loss_weight (`float`, *optional*, defaults to 0.4):
41
+ Weight of the cross-entropy loss of the auxiliary head.
42
+ auxiliary_channels (`int`, *optional*, defaults to 256):
43
+ Number of channels to use in the auxiliary head.
44
+ auxiliary_num_convs (`int`, *optional*, defaults to 1):
45
+ Number of convolutional layers to use in the auxiliary head.
46
+ auxiliary_concat_input (`bool`, *optional*, defaults to `False`):
47
+ Whether to concatenate the output of the auxiliary head with the input before the classification layer.
48
+ add_fpn (`bool`, *optional*, defaults to `False`):
49
+ Whether to add a FPN as part of the backbone. Only relevant for [`BeitBackbone`].
50
+ reshape_hidden_states (`bool`, *optional*, defaults to `True`):
51
+ Whether to reshape the feature maps to 4D tensors of shape `(batch_size, hidden_size, height, width)` in
52
+ case the model is used as backbone. If `False`, the feature maps will be 3D tensors of shape `(batch_size,
53
+ seq_len, hidden_size)`. Only relevant for [`BeitBackbone`].
54
+
55
+ Example:
56
+
57
+ ```python
58
+ >>> from transformers import BeitConfig, BeitModel
59
+
60
+ >>> # Initializing a BEiT beit-base-patch16-224-pt22k style configuration
61
+ >>> configuration = BeitConfig()
62
+
63
+ >>> # Initializing a model (with random weights) from the beit-base-patch16-224-pt22k style configuration
64
+ >>> model = BeitModel(configuration)
65
+
66
+ >>> # Accessing the model configuration
67
+ >>> configuration = model.config
68
+ ```"""
69
+
70
+ model_type = "beit"
71
+
72
+ vocab_size: int = 8192
73
+ hidden_size: int = 768
74
+ num_hidden_layers: int = 12
75
+ num_attention_heads: int = 12
76
+ intermediate_size: int = 3072
77
+ hidden_act: str = "gelu"
78
+ hidden_dropout_prob: float | int = 0.0
79
+ attention_probs_dropout_prob: float | int = 0.0
80
+ initializer_range: float = 0.02
81
+ layer_norm_eps: float = 1e-12
82
+ image_size: int | list[int] | tuple[int, int] = 224
83
+ patch_size: int | list[int] | tuple[int, int] = 16
84
+ num_channels: int = 3
85
+ use_mask_token: bool = False
86
+ use_absolute_position_embeddings: bool = False
87
+ use_relative_position_bias: bool = False
88
+ use_shared_relative_position_bias: bool = False
89
+ layer_scale_init_value: float = 0.1
90
+ drop_path_rate: float | int = 0.1
91
+ use_mean_pooling: bool = True
92
+ pool_scales: list[int] | tuple[int, ...] = (1, 2, 3, 6)
93
+ use_auxiliary_head: bool = True
94
+ auxiliary_loss_weight: float = 0.4
95
+ auxiliary_channels: int = 256
96
+ auxiliary_num_convs: int = 1
97
+ auxiliary_concat_input: bool = False
98
+ semantic_loss_ignore_index: int = 255
99
+ _out_features: list[str] | None = None
100
+ _out_indices: list[int] | None = None
101
+ add_fpn: bool = False
102
+ reshape_hidden_states: bool = True
103
+
104
+ def __post_init__(self, **kwargs):
105
+ if "segmentation_indices" in kwargs and kwargs.get("out_indices") is None:
106
+ kwargs["out_indices"] = kwargs.pop("segmentation_indices")
107
+
108
+ # backbone attributes
109
+ self.stage_names = ["stem"] + [f"stage{idx}" for idx in range(1, self.num_hidden_layers + 1)]
110
+ self.set_output_features_output_indices(
111
+ out_indices=kwargs.pop("out_indices", None), out_features=kwargs.pop("out_features", None)
112
+ )
113
+
114
+ super().__post_init__(**kwargs)
115
+
116
+
117
+ __all__ = ["BeitConfig"]
third_party/transformers/src/transformers/models/beit/convert_beit_unilm_to_pytorch.py ADDED
@@ -0,0 +1,375 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ """Convert BEiT checkpoints from the unilm repository."""
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 datasets import load_dataset
24
+ from huggingface_hub import hf_hub_download
25
+ from PIL import Image
26
+
27
+ from transformers import (
28
+ BeitConfig,
29
+ BeitForImageClassification,
30
+ BeitForMaskedImageModeling,
31
+ BeitForSemanticSegmentation,
32
+ BeitImageProcessor,
33
+ )
34
+ from transformers.image_utils import PILImageResampling
35
+ from transformers.utils import logging
36
+
37
+
38
+ logging.set_verbosity_info()
39
+ logger = logging.get_logger(__name__)
40
+
41
+
42
+ # here we list all keys to be renamed (original name on the left, our name on the right)
43
+ def create_rename_keys(config, has_lm_head=False, is_semantic=False):
44
+ prefix = "backbone." if is_semantic else ""
45
+
46
+ rename_keys = []
47
+ for i in range(config.num_hidden_layers):
48
+ # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
49
+ rename_keys.append((f"{prefix}blocks.{i}.norm1.weight", f"beit.encoder.layer.{i}.layernorm_before.weight"))
50
+ rename_keys.append((f"{prefix}blocks.{i}.norm1.bias", f"beit.encoder.layer.{i}.layernorm_before.bias"))
51
+ rename_keys.append(
52
+ (f"{prefix}blocks.{i}.attn.proj.weight", f"beit.encoder.layer.{i}.attention.output.dense.weight")
53
+ )
54
+ rename_keys.append(
55
+ (f"{prefix}blocks.{i}.attn.proj.bias", f"beit.encoder.layer.{i}.attention.output.dense.bias")
56
+ )
57
+ rename_keys.append((f"{prefix}blocks.{i}.norm2.weight", f"beit.encoder.layer.{i}.layernorm_after.weight"))
58
+ rename_keys.append((f"{prefix}blocks.{i}.norm2.bias", f"beit.encoder.layer.{i}.layernorm_after.bias"))
59
+ rename_keys.append((f"{prefix}blocks.{i}.mlp.fc1.weight", f"beit.encoder.layer.{i}.intermediate.dense.weight"))
60
+ rename_keys.append((f"{prefix}blocks.{i}.mlp.fc1.bias", f"beit.encoder.layer.{i}.intermediate.dense.bias"))
61
+ rename_keys.append((f"{prefix}blocks.{i}.mlp.fc2.weight", f"beit.encoder.layer.{i}.output.dense.weight"))
62
+ rename_keys.append((f"{prefix}blocks.{i}.mlp.fc2.bias", f"beit.encoder.layer.{i}.output.dense.bias"))
63
+
64
+ # projection layer + position embeddings
65
+ rename_keys.extend(
66
+ [
67
+ (f"{prefix}cls_token", "beit.embeddings.cls_token"),
68
+ (f"{prefix}patch_embed.proj.weight", "beit.embeddings.patch_embeddings.projection.weight"),
69
+ (f"{prefix}patch_embed.proj.bias", "beit.embeddings.patch_embeddings.projection.bias"),
70
+ ]
71
+ )
72
+
73
+ if has_lm_head:
74
+ # mask token + shared relative position bias + layernorm
75
+ rename_keys.extend(
76
+ [
77
+ ("mask_token", "beit.embeddings.mask_token"),
78
+ (
79
+ "rel_pos_bias.relative_position_bias_table",
80
+ "beit.encoder.relative_position_bias.relative_position_bias_table",
81
+ ),
82
+ (
83
+ "rel_pos_bias.relative_position_index",
84
+ "beit.encoder.relative_position_bias.relative_position_index",
85
+ ),
86
+ ("norm.weight", "layernorm.weight"),
87
+ ("norm.bias", "layernorm.bias"),
88
+ ]
89
+ )
90
+ elif is_semantic:
91
+ # semantic segmentation classification heads
92
+ rename_keys.extend(
93
+ [
94
+ ("decode_head.conv_seg.weight", "decode_head.classifier.weight"),
95
+ ("decode_head.conv_seg.bias", "decode_head.classifier.bias"),
96
+ ("auxiliary_head.conv_seg.weight", "auxiliary_head.classifier.weight"),
97
+ ("auxiliary_head.conv_seg.bias", "auxiliary_head.classifier.bias"),
98
+ ]
99
+ )
100
+ else:
101
+ # layernorm + classification head
102
+ rename_keys.extend(
103
+ [
104
+ ("fc_norm.weight", "beit.pooler.layernorm.weight"),
105
+ ("fc_norm.bias", "beit.pooler.layernorm.bias"),
106
+ ("head.weight", "classifier.weight"),
107
+ ("head.bias", "classifier.bias"),
108
+ ]
109
+ )
110
+
111
+ return rename_keys
112
+
113
+
114
+ # we split up the matrix of each encoder layer into queries, keys and values
115
+ def read_in_q_k_v(state_dict, config, has_lm_head=False, is_semantic=False):
116
+ for i in range(config.num_hidden_layers):
117
+ prefix = "backbone." if is_semantic else ""
118
+ # queries, keys and values
119
+ in_proj_weight = state_dict.pop(f"{prefix}blocks.{i}.attn.qkv.weight")
120
+ q_bias = state_dict.pop(f"{prefix}blocks.{i}.attn.q_bias")
121
+ v_bias = state_dict.pop(f"{prefix}blocks.{i}.attn.v_bias")
122
+
123
+ state_dict[f"beit.encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[
124
+ : config.hidden_size, :
125
+ ]
126
+ state_dict[f"beit.encoder.layer.{i}.attention.attention.query.bias"] = q_bias
127
+ state_dict[f"beit.encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[
128
+ config.hidden_size : config.hidden_size * 2, :
129
+ ]
130
+ state_dict[f"beit.encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[
131
+ -config.hidden_size :, :
132
+ ]
133
+ state_dict[f"beit.encoder.layer.{i}.attention.attention.value.bias"] = v_bias
134
+
135
+ # gamma_1 and gamma_2
136
+ # we call them lambda because otherwise they are renamed when using .from_pretrained
137
+ gamma_1 = state_dict.pop(f"{prefix}blocks.{i}.gamma_1")
138
+ gamma_2 = state_dict.pop(f"{prefix}blocks.{i}.gamma_2")
139
+
140
+ state_dict[f"beit.encoder.layer.{i}.lambda_1"] = gamma_1
141
+ state_dict[f"beit.encoder.layer.{i}.lambda_2"] = gamma_2
142
+
143
+ # relative_position bias table + index
144
+ if not has_lm_head:
145
+ # each layer has its own relative position bias
146
+ table = state_dict.pop(f"{prefix}blocks.{i}.attn.relative_position_bias_table")
147
+ index = state_dict.pop(f"{prefix}blocks.{i}.attn.relative_position_index")
148
+
149
+ state_dict[
150
+ f"beit.encoder.layer.{i}.attention.attention.relative_position_bias.relative_position_bias_table"
151
+ ] = table
152
+ state_dict[
153
+ f"beit.encoder.layer.{i}.attention.attention.relative_position_bias.relative_position_index"
154
+ ] = index
155
+
156
+
157
+ def rename_key(dct, old, new):
158
+ val = dct.pop(old)
159
+ dct[new] = val
160
+
161
+
162
+ # We will verify our results on an image of cute cats
163
+ def prepare_img():
164
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
165
+ with httpx.stream("GET", url) as response:
166
+ image = Image.open(BytesIO(response.read()))
167
+ return image
168
+
169
+
170
+ @torch.no_grad()
171
+ def convert_beit_checkpoint(checkpoint_url, pytorch_dump_folder_path):
172
+ """
173
+ Copy/paste/tweak model's weights to our BEiT structure.
174
+ """
175
+
176
+ # define default BEiT configuration
177
+ config = BeitConfig()
178
+ has_lm_head = False
179
+ is_semantic = False
180
+ repo_id = "huggingface/label-files"
181
+ # set config parameters based on URL
182
+ if checkpoint_url[-9:-4] == "pt22k":
183
+ # masked image modeling
184
+ config.use_shared_relative_position_bias = True
185
+ config.use_mask_token = True
186
+ has_lm_head = True
187
+ elif checkpoint_url[-9:-4] == "ft22k":
188
+ # intermediate fine-tuning on ImageNet-22k
189
+ config.use_relative_position_bias = True
190
+ config.num_labels = 21841
191
+ filename = "imagenet-22k-id2label.json"
192
+ id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r"))
193
+ id2label = {int(k): v for k, v in id2label.items()}
194
+ # this dataset contains 21843 labels but the model only has 21841
195
+ # we delete the classes as mentioned in https://github.com/google-research/big_transfer/issues/18
196
+ del id2label[9205]
197
+ del id2label[15027]
198
+ config.id2label = id2label
199
+ config.label2id = {v: k for k, v in id2label.items()}
200
+ elif checkpoint_url[-8:-4] == "to1k":
201
+ # fine-tuning on ImageNet-1k
202
+ config.use_relative_position_bias = True
203
+ config.num_labels = 1000
204
+ filename = "imagenet-1k-id2label.json"
205
+ id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r"))
206
+ id2label = {int(k): v for k, v in id2label.items()}
207
+ config.id2label = id2label
208
+ config.label2id = {v: k for k, v in id2label.items()}
209
+ if "384" in checkpoint_url:
210
+ config.image_size = 384
211
+ if "512" in checkpoint_url:
212
+ config.image_size = 512
213
+ elif "ade20k" in checkpoint_url:
214
+ # fine-tuning
215
+ config.use_relative_position_bias = True
216
+ config.num_labels = 150
217
+ filename = "ade20k-id2label.json"
218
+ id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r"))
219
+ id2label = {int(k): v for k, v in id2label.items()}
220
+ config.id2label = id2label
221
+ config.label2id = {v: k for k, v in id2label.items()}
222
+ config.image_size = 640
223
+ is_semantic = True
224
+ else:
225
+ raise ValueError("Checkpoint not supported, URL should either end with 'pt22k', 'ft22k', 'to1k' or 'ade20k'")
226
+
227
+ # size of the architecture
228
+ if "base" in checkpoint_url:
229
+ if "ade20k" in checkpoint_url:
230
+ config.out_indices = [3, 5, 7, 11]
231
+ elif "large" in checkpoint_url:
232
+ config.hidden_size = 1024
233
+ config.intermediate_size = 4096
234
+ config.num_hidden_layers = 24
235
+ config.num_attention_heads = 16
236
+ if "ade20k" in checkpoint_url:
237
+ config.image_size = 640
238
+ config.out_indices = [7, 11, 15, 23]
239
+ else:
240
+ raise ValueError("Should either find 'base' or 'large' in checkpoint URL")
241
+
242
+ # load state_dict of original model, remove and rename some keys
243
+ state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu", check_hash=True)
244
+ state_dict = state_dict["model"] if "ade20k" not in checkpoint_url else state_dict["state_dict"]
245
+
246
+ rename_keys = create_rename_keys(config, has_lm_head=has_lm_head, is_semantic=is_semantic)
247
+ for src, dest in rename_keys:
248
+ rename_key(state_dict, src, dest)
249
+ read_in_q_k_v(state_dict, config, has_lm_head=has_lm_head, is_semantic=is_semantic)
250
+ if is_semantic:
251
+ # add prefix to decoder keys
252
+ for key, val in state_dict.copy().items():
253
+ val = state_dict.pop(key)
254
+ if key.startswith("backbone.fpn"):
255
+ key = key.replace("backbone.fpn", "fpn")
256
+ state_dict[key] = val
257
+
258
+ # load HuggingFace model
259
+ if checkpoint_url[-9:-4] == "pt22k":
260
+ model = BeitForMaskedImageModeling(config)
261
+ elif "ade20k" in checkpoint_url:
262
+ model = BeitForSemanticSegmentation(config)
263
+ else:
264
+ model = BeitForImageClassification(config)
265
+ model.eval()
266
+ model.load_state_dict(state_dict)
267
+
268
+ # Check outputs on an image
269
+ if is_semantic:
270
+ image_processor = BeitImageProcessor(size=config.image_size, do_center_crop=False)
271
+ ds = load_dataset("hf-internal-testing/fixtures_ade20k", split="test")
272
+ image = Image.open(ds[0]["file"])
273
+ else:
274
+ image_processor = BeitImageProcessor(
275
+ size=config.image_size, resample=PILImageResampling.BILINEAR, do_center_crop=False
276
+ )
277
+ image = prepare_img()
278
+
279
+ encoding = image_processor(images=image, return_tensors="pt")
280
+ pixel_values = encoding["pixel_values"]
281
+
282
+ outputs = model(pixel_values)
283
+ logits = outputs.logits
284
+
285
+ # verify logits
286
+ expected_shape = torch.Size([1, 1000])
287
+ if checkpoint_url[:-4].endswith("beit_base_patch16_224_pt22k"):
288
+ expected_shape = torch.Size([1, 196, 8192])
289
+ elif checkpoint_url[:-4].endswith("beit_large_patch16_224_pt22k"):
290
+ expected_shape = torch.Size([1, 196, 8192])
291
+ elif checkpoint_url[:-4].endswith("beit_base_patch16_224_pt22k_ft22k"):
292
+ expected_shape = torch.Size([1, 21841])
293
+ expected_logits = torch.tensor([2.2288, 2.4671, 0.7395])
294
+ expected_class_idx = 2397
295
+ elif checkpoint_url[:-4].endswith("beit_large_patch16_224_pt22k_ft22k"):
296
+ expected_shape = torch.Size([1, 21841])
297
+ expected_logits = torch.tensor([1.6881, -0.2787, 0.5901])
298
+ expected_class_idx = 2396
299
+ elif checkpoint_url[:-4].endswith("beit_base_patch16_224_pt22k_ft1k"):
300
+ expected_logits = torch.tensor([0.1241, 0.0798, -0.6569])
301
+ expected_class_idx = 285
302
+ elif checkpoint_url[:-4].endswith("beit_base_patch16_224_pt22k_ft22kto1k"):
303
+ expected_logits = torch.tensor([-1.2385, -1.0987, -1.0108])
304
+ expected_class_idx = 281
305
+ elif checkpoint_url[:-4].endswith("beit_base_patch16_384_pt22k_ft22kto1k"):
306
+ expected_logits = torch.tensor([-1.5303, -0.9484, -0.3147])
307
+ expected_class_idx = 761
308
+ elif checkpoint_url[:-4].endswith("beit_large_patch16_224_pt22k_ft1k"):
309
+ expected_logits = torch.tensor([0.4610, -0.0928, 0.2086])
310
+ expected_class_idx = 761
311
+ elif checkpoint_url[:-4].endswith("beit_large_patch16_224_pt22k_ft22kto1k"):
312
+ expected_logits = torch.tensor([-0.4804, 0.6257, -0.1837])
313
+ expected_class_idx = 761
314
+ elif checkpoint_url[:-4].endswith("beit_large_patch16_384_pt22k_ft22kto1k"):
315
+ expected_logits = torch.tensor([[-0.5122, 0.5117, -0.2113]])
316
+ expected_class_idx = 761
317
+ elif checkpoint_url[:-4].endswith("beit_large_patch16_512_pt22k_ft22kto1k"):
318
+ expected_logits = torch.tensor([-0.3062, 0.7261, 0.4852])
319
+ expected_class_idx = 761
320
+ elif checkpoint_url[:-4].endswith("beit_base_patch16_640_pt22k_ft22ktoade20k"):
321
+ expected_shape = (1, 150, 160, 160)
322
+ expected_logits = torch.tensor(
323
+ [
324
+ [[-4.9225, -2.3954, -3.0522], [-2.8822, -1.0046, -1.7561], [-2.9549, -1.3228, -2.1347]],
325
+ [[-5.8168, -3.4129, -4.0778], [-3.8651, -2.2214, -3.0277], [-3.8356, -2.4643, -3.3535]],
326
+ [[-0.0078, 3.9952, 4.0754], [2.9856, 4.6944, 5.0035], [3.2413, 4.7813, 4.9969]],
327
+ ]
328
+ )
329
+ elif checkpoint_url[:-4].endswith("beit_large_patch16_640_pt22k_ft22ktoade20k"):
330
+ expected_shape = (1, 150, 160, 160)
331
+ expected_logits = torch.tensor(
332
+ [
333
+ [[-4.3305, -2.3049, -3.0161], [-2.9591, -1.5305, -2.2251], [-3.4198, -1.8004, -2.9062]],
334
+ [[-5.8922, -3.7435, -4.3978], [-4.2063, -2.7872, -3.4755], [-4.2791, -3.1874, -4.1681]],
335
+ [[0.9895, 4.3467, 4.7663], [4.2476, 5.6830, 6.1518], [4.5550, 6.2495, 6.5154]],
336
+ ]
337
+ )
338
+ else:
339
+ raise ValueError("Can't verify logits as model is not supported")
340
+
341
+ if logits.shape != expected_shape:
342
+ raise ValueError(f"Shape of logits not as expected. {logits.shape=}, {expected_shape=}")
343
+ if not has_lm_head:
344
+ if is_semantic:
345
+ if not torch.allclose(logits[0, :3, :3, :3], expected_logits, atol=1e-3):
346
+ raise ValueError("First elements of logits not as expected")
347
+ else:
348
+ print("Predicted class idx:", logits.argmax(-1).item())
349
+
350
+ if not torch.allclose(logits[0, :3], expected_logits, atol=1e-3):
351
+ raise ValueError("First elements of logits not as expected")
352
+ if logits.argmax(-1).item() != expected_class_idx:
353
+ raise ValueError("Predicted class index not as expected")
354
+
355
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
356
+ print(f"Saving model to {pytorch_dump_folder_path}")
357
+ model.save_pretrained(pytorch_dump_folder_path)
358
+ print(f"Saving image processor to {pytorch_dump_folder_path}")
359
+ image_processor.save_pretrained(pytorch_dump_folder_path)
360
+
361
+
362
+ if __name__ == "__main__":
363
+ parser = argparse.ArgumentParser()
364
+
365
+ parser.add_argument(
366
+ "--checkpoint_url",
367
+ default="https://conversationhub.blob.core.windows.net/beit-share-public/beit/beit_base_patch16_224_pt22k_ft22kto1k.pth",
368
+ type=str,
369
+ help="URL to the original PyTorch checkpoint (.pth file).",
370
+ )
371
+ parser.add_argument(
372
+ "--pytorch_dump_folder_path", default=None, type=str, help="Path to the folder to output PyTorch model."
373
+ )
374
+ args = parser.parse_args()
375
+ convert_beit_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path)
third_party/transformers/src/transformers/models/beit/image_processing_beit.py ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ """Image processor class for BEiT."""
15
+
16
+ from typing import Union
17
+
18
+ import torch
19
+ import torch.nn.functional as F
20
+ from torchvision.transforms.v2 import functional as tvF
21
+
22
+ from ...image_processing_backends import TorchvisionBackend
23
+ from ...image_processing_utils import BatchFeature
24
+ from ...image_transforms import group_images_by_shape, reorder_images
25
+ from ...image_utils import (
26
+ IMAGENET_STANDARD_MEAN,
27
+ IMAGENET_STANDARD_STD,
28
+ ChannelDimension,
29
+ ImageInput,
30
+ PILImageResampling,
31
+ SizeDict,
32
+ )
33
+ from ...processing_utils import ImagesKwargs, Unpack
34
+ from ...utils import TensorType, auto_docstring, is_torch_available
35
+
36
+
37
+ class BeitImageProcessorKwargs(ImagesKwargs, total=False):
38
+ r"""
39
+ do_reduce_labels (`bool`, *optional*, defaults to `self.do_reduce_labels`):
40
+ Whether or not to reduce all label values of segmentation maps by 1. Usually used for datasets where 0
41
+ is used for background, and background itself is not included in all classes of a dataset (e.g.
42
+ ADE20k). The background label will be replaced by 255.
43
+ """
44
+
45
+ do_reduce_labels: bool
46
+
47
+
48
+ @auto_docstring
49
+ class BeitImageProcessor(TorchvisionBackend):
50
+ """PIL backend for BEiT with reduce_label support."""
51
+
52
+ valid_kwargs = BeitImageProcessorKwargs
53
+
54
+ resample = PILImageResampling.BICUBIC
55
+ image_mean = IMAGENET_STANDARD_MEAN
56
+ image_std = IMAGENET_STANDARD_STD
57
+ size = {"height": 224, "width": 224}
58
+ default_to_square = True
59
+ crop_size = {"height": 224, "width": 224}
60
+ do_resize = True
61
+ do_center_crop = False
62
+ do_rescale = True
63
+ do_normalize = True
64
+ do_reduce_labels = False
65
+
66
+ def __init__(self, **kwargs: Unpack[BeitImageProcessorKwargs]):
67
+ super().__init__(**kwargs)
68
+
69
+ @auto_docstring
70
+ def preprocess(
71
+ self,
72
+ images: ImageInput,
73
+ segmentation_maps: ImageInput | None = None,
74
+ **kwargs: Unpack[BeitImageProcessorKwargs],
75
+ ) -> BatchFeature:
76
+ r"""
77
+ segmentation_maps (`ImageInput`, *optional*):
78
+ The segmentation maps to preprocess.
79
+ """
80
+ return super().preprocess(images, segmentation_maps, **kwargs)
81
+
82
+ def _preprocess_image_like_inputs(
83
+ self,
84
+ images: ImageInput,
85
+ segmentation_maps: ImageInput | None,
86
+ do_convert_rgb: bool,
87
+ input_data_format: ChannelDimension,
88
+ return_tensors: str | TensorType | None,
89
+ device: Union[str, "torch.device"] | None = None,
90
+ **kwargs,
91
+ ) -> BatchFeature:
92
+ """Handle extra inputs beyond images."""
93
+ images = self._prepare_image_like_inputs(
94
+ images=images, do_convert_rgb=do_convert_rgb, input_data_format=input_data_format, device=device
95
+ )
96
+ images_kwargs = kwargs.copy()
97
+ images_kwargs["do_reduce_labels"] = False
98
+ data = {}
99
+ data["pixel_values"] = self._preprocess(images, **images_kwargs)
100
+
101
+ # Prepare segmentation maps if provided
102
+ if segmentation_maps is not None:
103
+ processed_segmentation_maps = self._prepare_image_like_inputs(
104
+ images=segmentation_maps,
105
+ expected_ndims=2,
106
+ do_convert_rgb=False,
107
+ input_data_format=ChannelDimension.FIRST,
108
+ )
109
+
110
+ # Process segmentation maps with do_normalize=False and do_rescale=False
111
+ segmentation_maps_kwargs = kwargs.copy()
112
+ segmentation_maps_kwargs.update({"do_normalize": False, "do_rescale": False})
113
+ processed_segmentation_maps = self._preprocess(
114
+ images=processed_segmentation_maps, **segmentation_maps_kwargs
115
+ )
116
+
117
+ # Convert to int64 and squeeze channel dimension
118
+ processed_segmentation_maps = [
119
+ processed_segmentation_map.squeeze(0).to(torch.int64)
120
+ for processed_segmentation_map in processed_segmentation_maps
121
+ ]
122
+ data["labels"] = processed_segmentation_maps
123
+
124
+ return BatchFeature(data=data, tensor_type=return_tensors)
125
+
126
+ def reduce_label(self, labels: list["torch.Tensor"]) -> list["torch.Tensor"]:
127
+ """Reduce label values by 1, replacing 0 with 255."""
128
+ for idx in range(len(labels)):
129
+ label = labels[idx]
130
+ label = torch.where(label == 0, torch.tensor(255, dtype=label.dtype, device=label.device), label)
131
+ label = label - 1
132
+ label = torch.where(label == 254, torch.tensor(255, dtype=label.dtype, device=label.device), label)
133
+ labels[idx] = label
134
+ return labels
135
+
136
+ def _preprocess(
137
+ self,
138
+ images: list["torch.Tensor"],
139
+ do_resize: bool,
140
+ size: SizeDict,
141
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None",
142
+ do_center_crop: bool,
143
+ crop_size: SizeDict,
144
+ do_rescale: bool,
145
+ rescale_factor: float,
146
+ do_normalize: bool,
147
+ image_mean: float | list[float] | None,
148
+ image_std: float | list[float] | None,
149
+ disable_grouping: bool | None,
150
+ do_reduce_labels: bool = False,
151
+ **kwargs,
152
+ ) -> list["torch.Tensor"]:
153
+ """Custom preprocessing for BEiT."""
154
+ if do_reduce_labels:
155
+ images = self.reduce_label(images)
156
+
157
+ # Group images by size for batched resizing
158
+ grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
159
+ resized_images_grouped = {}
160
+ for shape, stacked_images in grouped_images.items():
161
+ if do_resize:
162
+ stacked_images = self.resize(stacked_images, size, resample)
163
+ resized_images_grouped[shape] = stacked_images
164
+ resized_images = reorder_images(resized_images_grouped, grouped_images_index)
165
+
166
+ # Group images by size for further processing
167
+ grouped_images, grouped_images_index = group_images_by_shape(resized_images, disable_grouping=disable_grouping)
168
+ processed_images_grouped = {}
169
+ for shape, stacked_images in grouped_images.items():
170
+ if do_center_crop:
171
+ stacked_images = self.center_crop(stacked_images, crop_size)
172
+ # Use fused rescale and normalize
173
+ stacked_images = self.rescale_and_normalize(
174
+ stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std
175
+ )
176
+ processed_images_grouped[shape] = stacked_images
177
+
178
+ processed_images = reorder_images(processed_images_grouped, grouped_images_index)
179
+
180
+ return processed_images
181
+
182
+ def post_process_semantic_segmentation(self, outputs, target_sizes: list[tuple] | None = None):
183
+ """
184
+ Converts the output of [`BeitForSemanticSegmentation`] into semantic segmentation maps.
185
+
186
+ Args:
187
+ outputs ([`BeitForSemanticSegmentation`]):
188
+ Raw outputs of the model.
189
+ target_sizes (`list[Tuple]` of length `batch_size`, *optional*):
190
+ List of tuples corresponding to the requested final size (height, width) of each prediction. If unset,
191
+ predictions will not be resized.
192
+
193
+ Returns:
194
+ semantic_segmentation: `list[torch.Tensor]` of length `batch_size`, where each item is a semantic
195
+ segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is
196
+ specified). Each entry of each `torch.Tensor` correspond to a semantic class id.
197
+ """
198
+ if not is_torch_available():
199
+ raise ImportError("PyTorch is required for post_process_semantic_segmentation")
200
+
201
+ logits = outputs.logits
202
+
203
+ # Resize logits and compute semantic segmentation maps
204
+ if target_sizes is not None:
205
+ if len(logits) != len(target_sizes):
206
+ raise ValueError(
207
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
208
+ )
209
+
210
+ if isinstance(target_sizes, torch.Tensor):
211
+ target_sizes = target_sizes.numpy()
212
+
213
+ semantic_segmentation = []
214
+
215
+ for idx in range(len(logits)):
216
+ resized_logits = F.interpolate(
217
+ logits[idx].unsqueeze(dim=0), size=target_sizes[idx], mode="bilinear", align_corners=False
218
+ )
219
+ semantic_map = resized_logits[0].argmax(dim=0)
220
+ semantic_segmentation.append(semantic_map)
221
+ else:
222
+ semantic_segmentation = logits.argmax(dim=1)
223
+ semantic_segmentation = [semantic_segmentation[i] for i in range(semantic_segmentation.shape[0])]
224
+
225
+ return semantic_segmentation
226
+
227
+
228
+ __all__ = ["BeitImageProcessor"]
third_party/transformers/src/transformers/models/beit/image_processing_pil_beit.py ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ """Image processor class for BEiT."""
15
+
16
+ import numpy as np
17
+
18
+ from ...image_processing_backends import PilBackend
19
+ from ...image_processing_utils import BatchFeature
20
+ from ...image_utils import (
21
+ IMAGENET_STANDARD_MEAN,
22
+ IMAGENET_STANDARD_STD,
23
+ ChannelDimension,
24
+ ImageInput,
25
+ PILImageResampling,
26
+ SizeDict,
27
+ )
28
+ from ...processing_utils import ImagesKwargs, Unpack
29
+ from ...utils import TensorType, auto_docstring
30
+ from ...utils.import_utils import requires
31
+
32
+
33
+ # Adapted from transformers.models.beit.image_processing_beit.BeitImageProcessorKwargs
34
+ class BeitImageProcessorKwargs(ImagesKwargs, total=False):
35
+ r"""
36
+ do_reduce_labels (`bool`, *optional*, defaults to `self.do_reduce_labels`):
37
+ Whether or not to reduce all label values of segmentation maps by 1. Usually used for datasets where 0
38
+ is used for background, and background itself is not included in all classes of a dataset (e.g.
39
+ ADE20k). The background label will be replaced by 255.
40
+ """
41
+
42
+ do_reduce_labels: bool
43
+
44
+
45
+ @auto_docstring
46
+ class BeitImageProcessorPil(PilBackend):
47
+ """PIL backend for BEiT with reduce_label support."""
48
+
49
+ valid_kwargs = BeitImageProcessorKwargs
50
+
51
+ resample = PILImageResampling.BICUBIC
52
+ image_mean = IMAGENET_STANDARD_MEAN
53
+ image_std = IMAGENET_STANDARD_STD
54
+ size = {"height": 224, "width": 224}
55
+ default_to_square = True
56
+ crop_size = {"height": 224, "width": 224}
57
+ do_resize = True
58
+ do_center_crop = False
59
+ do_rescale = True
60
+ do_normalize = True
61
+ do_reduce_labels = False
62
+
63
+ def __init__(self, **kwargs: Unpack[BeitImageProcessorKwargs]):
64
+ super().__init__(**kwargs)
65
+
66
+ @auto_docstring
67
+ def preprocess(
68
+ self,
69
+ images: ImageInput,
70
+ segmentation_maps: ImageInput | None = None,
71
+ **kwargs: Unpack[BeitImageProcessorKwargs],
72
+ ) -> BatchFeature:
73
+ r"""
74
+ segmentation_maps (`ImageInput`, *optional*):
75
+ The segmentation maps to preprocess.
76
+ """
77
+ return super().preprocess(images, segmentation_maps, **kwargs)
78
+
79
+ def _preprocess_image_like_inputs(
80
+ self,
81
+ images: ImageInput,
82
+ segmentation_maps: ImageInput | None,
83
+ do_convert_rgb: bool,
84
+ input_data_format: ChannelDimension,
85
+ return_tensors: str | TensorType | None,
86
+ **kwargs,
87
+ ) -> BatchFeature:
88
+ """Handle extra inputs beyond images."""
89
+ images = self._prepare_image_like_inputs(
90
+ images=images, do_convert_rgb=do_convert_rgb, input_data_format=input_data_format
91
+ )
92
+ images_kwargs = kwargs.copy()
93
+ images_kwargs["do_reduce_labels"] = False
94
+ data = {}
95
+ data["pixel_values"] = self._preprocess(images, **images_kwargs)
96
+
97
+ # Prepare segmentation maps if provided
98
+ if segmentation_maps is not None:
99
+ processed_segmentation_maps = self._prepare_image_like_inputs(
100
+ images=segmentation_maps,
101
+ expected_ndims=2,
102
+ do_convert_rgb=False,
103
+ input_data_format=ChannelDimension.FIRST,
104
+ )
105
+
106
+ # Process segmentation maps with do_normalize=False and do_rescale=False
107
+ segmentation_maps_kwargs = kwargs.copy()
108
+ segmentation_maps_kwargs.update({"do_normalize": False, "do_rescale": False})
109
+ processed_segmentation_maps = self._preprocess(
110
+ images=processed_segmentation_maps, **segmentation_maps_kwargs
111
+ )
112
+
113
+ # Convert to int64 and squeeze channel dimension
114
+ data["labels"] = [
115
+ processed_segmentation_map.squeeze(0).astype(np.int64)
116
+ for processed_segmentation_map in processed_segmentation_maps
117
+ ]
118
+
119
+ return BatchFeature(data=data, tensor_type=return_tensors)
120
+
121
+ def reduce_label(self, image: np.ndarray) -> np.ndarray:
122
+ """Reduce label values by 1, replacing 0 with 255."""
123
+ # Avoid using underflow conversion
124
+ image[image == 0] = 255
125
+ image = image - 1
126
+ image[image == 254] = 255
127
+ return image
128
+
129
+ def _preprocess(
130
+ self,
131
+ images: list[np.ndarray],
132
+ do_resize: bool,
133
+ size: SizeDict,
134
+ resample: PILImageResampling | None,
135
+ do_center_crop: bool,
136
+ crop_size: SizeDict,
137
+ do_rescale: bool,
138
+ rescale_factor: float,
139
+ do_normalize: bool,
140
+ image_mean: float | list[float] | None,
141
+ image_std: float | list[float] | None,
142
+ do_reduce_labels: bool = False,
143
+ **kwargs,
144
+ ) -> list[np.ndarray]:
145
+ """Custom preprocessing for BEiT."""
146
+ processed_images = []
147
+ for image in images:
148
+ if do_reduce_labels:
149
+ image = self.reduce_label(image)
150
+ if do_resize:
151
+ image = self.resize(image, size, resample)
152
+ if do_center_crop:
153
+ image = self.center_crop(image, crop_size)
154
+ if do_rescale:
155
+ image = self.rescale(image, rescale_factor)
156
+ if do_normalize:
157
+ image = self.normalize(image, image_mean, image_std)
158
+ processed_images.append(image)
159
+
160
+ return processed_images
161
+
162
+ @requires(backends=("torch",))
163
+ def post_process_semantic_segmentation(self, outputs, target_sizes: list[tuple] | None = None):
164
+ """
165
+ Converts the output of [`BeitForSemanticSegmentation`] into semantic segmentation maps.
166
+
167
+ Args:
168
+ outputs ([`BeitForSemanticSegmentation`]):
169
+ Raw outputs of the model.
170
+ target_sizes (`list[Tuple]` of length `batch_size`, *optional*):
171
+ List of tuples corresponding to the requested final size (height, width) of each prediction. If unset,
172
+ predictions will not be resized.
173
+
174
+ Returns:
175
+ semantic_segmentation: `list[torch.Tensor]` of length `batch_size`, where each item is a semantic
176
+ segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is
177
+ specified). Each entry of each `torch.Tensor` correspond to a semantic class id.
178
+ """
179
+ import torch
180
+ import torch.nn.functional as F
181
+
182
+ logits = outputs.logits
183
+
184
+ # Resize logits and compute semantic segmentation maps
185
+ if target_sizes is not None:
186
+ if len(logits) != len(target_sizes):
187
+ raise ValueError(
188
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
189
+ )
190
+
191
+ if isinstance(target_sizes, torch.Tensor):
192
+ target_sizes = target_sizes.numpy()
193
+
194
+ semantic_segmentation = []
195
+
196
+ for idx in range(len(logits)):
197
+ resized_logits = F.interpolate(
198
+ logits[idx].unsqueeze(dim=0), size=target_sizes[idx], mode="bilinear", align_corners=False
199
+ )
200
+ semantic_map = resized_logits[0].argmax(dim=0)
201
+ semantic_segmentation.append(semantic_map)
202
+ else:
203
+ semantic_segmentation = logits.argmax(dim=1)
204
+ semantic_segmentation = [semantic_segmentation[i] for i in range(semantic_segmentation.shape[0])]
205
+
206
+ return semantic_segmentation
207
+
208
+
209
+ __all__ = ["BeitImageProcessorPil"]
third_party/transformers/src/transformers/models/beit/modeling_beit.py ADDED
@@ -0,0 +1,1470 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 Microsoft Research 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 BEiT model."""
15
+
16
+ import collections.abc
17
+ import math
18
+ from dataclasses import dataclass
19
+
20
+ import torch
21
+ from torch import Tensor, nn
22
+ from torch.nn import CrossEntropyLoss
23
+
24
+ from ... import initialization as init
25
+ from ...activations import ACT2FN
26
+ from ...backbone_utils import BackboneMixin, filter_output_hidden_states
27
+ from ...modeling_layers import GradientCheckpointingLayer
28
+ from ...modeling_outputs import (
29
+ BackboneOutput,
30
+ BaseModelOutput,
31
+ BaseModelOutputWithPooling,
32
+ ImageClassifierOutput,
33
+ MaskedLMOutput,
34
+ SemanticSegmenterOutput,
35
+ )
36
+ from ...modeling_utils import PreTrainedModel
37
+ from ...pytorch_utils import compile_compatible_method_lru_cache
38
+ from ...utils import auto_docstring, logging, torch_int
39
+ from ...utils.generic import can_return_tuple
40
+ from .configuration_beit import BeitConfig
41
+
42
+
43
+ logger = logging.get_logger(__name__)
44
+
45
+
46
+ @dataclass
47
+ @auto_docstring(
48
+ custom_intro="""
49
+ Class for outputs of [`BeitModel`].
50
+ """
51
+ )
52
+ class BeitModelOutputWithPooling(BaseModelOutputWithPooling):
53
+ r"""
54
+ pooler_output (`torch.FloatTensor` of shape `(batch_size, hidden_size)`):
55
+ Average of the last layer hidden states of the patch tokens (excluding the *[CLS]* token) if
56
+ *config.use_mean_pooling* is set to True. If set to False, then the final hidden state of the *[CLS]* token
57
+ will be returned.
58
+ """
59
+
60
+
61
+ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = False) -> torch.Tensor:
62
+ """
63
+ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
64
+
65
+ """
66
+ if drop_prob == 0.0 or not training:
67
+ return input
68
+ keep_prob = 1 - drop_prob
69
+ shape = (input.shape[0],) + (1,) * (input.ndim - 1) # work with diff dim tensors, not just 2D ConvNets
70
+ random_tensor = keep_prob + torch.rand(shape, dtype=input.dtype, device=input.device)
71
+ random_tensor.floor_() # binarize
72
+ output = input.div(keep_prob) * random_tensor
73
+ return output
74
+
75
+
76
+ class BeitDropPath(nn.Module):
77
+ """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks)."""
78
+
79
+ def __init__(self, drop_prob: float | None = None) -> None:
80
+ super().__init__()
81
+ self.drop_prob = drop_prob
82
+
83
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
84
+ return drop_path(hidden_states, self.drop_prob, self.training)
85
+
86
+ def extra_repr(self) -> str:
87
+ return f"p={self.drop_prob}"
88
+
89
+
90
+ # Based on timm implementation, which can be found here:
91
+ # https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py
92
+ class BeitEmbeddings(nn.Module):
93
+ """
94
+ Construct the CLS token, position and patch embeddings. Optionally, also the mask token.
95
+
96
+ """
97
+
98
+ def __init__(self, config: BeitConfig) -> None:
99
+ super().__init__()
100
+
101
+ self.cls_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size))
102
+ if config.use_mask_token:
103
+ self.mask_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size))
104
+ else:
105
+ self.mask_token = None
106
+ self.patch_embeddings = BeitPatchEmbeddings(config)
107
+ self.patch_size = config.patch_size
108
+ self.image_size = (
109
+ config.image_size
110
+ if isinstance(config.image_size, collections.abc.Iterable)
111
+ else (config.image_size, config.image_size)
112
+ )
113
+ num_patches = self.patch_embeddings.num_patches
114
+ if config.use_absolute_position_embeddings:
115
+ self.position_embeddings = nn.Parameter(torch.zeros(1, num_patches + 1, config.hidden_size))
116
+ else:
117
+ self.position_embeddings = None
118
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
119
+
120
+ # Copied from transformers.models.vit.modeling_vit.ViTEmbeddings.interpolate_pos_encoding
121
+ def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor:
122
+ """
123
+ This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher resolution
124
+ images. This method is also adapted to support torch.jit tracing.
125
+
126
+ Adapted from:
127
+ - https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174-L194, and
128
+ - https://github.com/facebookresearch/dinov2/blob/e1277af2ba9496fbadf7aec6eba56e8d882d1e35/dinov2/models/vision_transformer.py#L179-L211
129
+ """
130
+
131
+ num_patches = embeddings.shape[1] - 1
132
+ num_positions = self.position_embeddings.shape[1] - 1
133
+
134
+ # always interpolate when tracing to ensure the exported model works for dynamic input shapes
135
+ if not torch.jit.is_tracing() and num_patches == num_positions and height == width:
136
+ return self.position_embeddings
137
+
138
+ class_pos_embed = self.position_embeddings[:, :1]
139
+ patch_pos_embed = self.position_embeddings[:, 1:]
140
+
141
+ dim = embeddings.shape[-1]
142
+
143
+ new_height = height // self.patch_size
144
+ new_width = width // self.patch_size
145
+
146
+ sqrt_num_positions = torch_int(num_positions**0.5)
147
+ patch_pos_embed = patch_pos_embed.reshape(1, sqrt_num_positions, sqrt_num_positions, dim)
148
+ patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2)
149
+
150
+ patch_pos_embed = nn.functional.interpolate(
151
+ patch_pos_embed,
152
+ size=(new_height, new_width),
153
+ mode="bicubic",
154
+ align_corners=False,
155
+ )
156
+
157
+ patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)
158
+
159
+ return torch.cat((class_pos_embed, patch_pos_embed), dim=1)
160
+
161
+ def forward(
162
+ self,
163
+ pixel_values: torch.Tensor,
164
+ bool_masked_pos: torch.BoolTensor | None = None,
165
+ ) -> torch.Tensor:
166
+ _, _, height, width = pixel_values.shape
167
+ embeddings, (patch_height, patch_width) = self.patch_embeddings(pixel_values)
168
+ batch_size, seq_len, _ = embeddings.size()
169
+
170
+ if bool_masked_pos is not None:
171
+ mask_tokens = self.mask_token.expand(batch_size, seq_len, -1)
172
+ # replace the masked visual tokens by mask_tokens
173
+ w = bool_masked_pos.unsqueeze(-1).type_as(mask_tokens)
174
+ embeddings = embeddings * (1 - w) + mask_tokens * w
175
+
176
+ cls_tokens = self.cls_token.expand(batch_size, -1, -1)
177
+ embeddings = torch.cat((cls_tokens, embeddings), dim=1)
178
+
179
+ if self.position_embeddings is not None:
180
+ embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width)
181
+
182
+ embeddings = self.dropout(embeddings)
183
+
184
+ return embeddings, (patch_height, patch_width)
185
+
186
+
187
+ class BeitPatchEmbeddings(nn.Module):
188
+ """
189
+ This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial
190
+ `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a
191
+ Transformer.
192
+ """
193
+
194
+ def __init__(self, config):
195
+ super().__init__()
196
+ image_size, patch_size = config.image_size, config.patch_size
197
+ num_channels, hidden_size = config.num_channels, config.hidden_size
198
+
199
+ image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size)
200
+ patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size)
201
+ num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0])
202
+ patch_shape = (image_size[0] // patch_size[0], image_size[1] // patch_size[1])
203
+ self.image_size = image_size
204
+ self.patch_size = patch_size
205
+ self.num_channels = num_channels
206
+ self.num_patches = num_patches
207
+ self.patch_shape = patch_shape
208
+
209
+ self.projection = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size)
210
+
211
+ def forward(self, pixel_values: torch.Tensor) -> torch.Tensor:
212
+ batch_size, num_channels, height, width = pixel_values.shape
213
+ if num_channels != self.num_channels:
214
+ raise ValueError(
215
+ "Make sure that the channel dimension of the pixel values match with the one set in the configuration."
216
+ )
217
+
218
+ embeddings = self.projection(pixel_values.to(self.projection.weight.dtype))
219
+ patch_height, patch_width = embeddings.shape[2], embeddings.shape[3]
220
+ embeddings = embeddings.flatten(2).transpose(1, 2)
221
+
222
+ return embeddings, (patch_height, patch_width)
223
+
224
+
225
+ class BeitSelfAttention(nn.Module):
226
+ def __init__(self, config: BeitConfig, window_size: tuple | None = None) -> None:
227
+ super().__init__()
228
+ self.config = config
229
+ if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
230
+ raise ValueError(
231
+ f"The hidden size {config.hidden_size} is not a multiple of the number of attention "
232
+ f"heads {config.num_attention_heads}."
233
+ )
234
+
235
+ self.num_attention_heads = config.num_attention_heads
236
+ self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
237
+ self.all_head_size = self.num_attention_heads * self.attention_head_size
238
+
239
+ self.query = nn.Linear(config.hidden_size, self.all_head_size)
240
+ self.key = nn.Linear(config.hidden_size, self.all_head_size, bias=False)
241
+ self.value = nn.Linear(config.hidden_size, self.all_head_size)
242
+
243
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
244
+
245
+ self.has_relative_position_bias = bool(window_size)
246
+ if self.has_relative_position_bias:
247
+ self.relative_position_bias = BeitRelativePositionBias(config, window_size=window_size)
248
+
249
+ def forward(
250
+ self,
251
+ hidden_states: torch.Tensor,
252
+ output_attentions: bool = False,
253
+ relative_position_bias: torch.Tensor | None = None,
254
+ interpolate_pos_encoding: bool = False,
255
+ resolution: tuple[int] | None = None,
256
+ ) -> tuple[torch.Tensor] | tuple[torch.Tensor, torch.Tensor]:
257
+ batch_size, seq_length, _ = hidden_states.shape
258
+ query_layer = (
259
+ self.query(hidden_states)
260
+ .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
261
+ .transpose(1, 2)
262
+ )
263
+ key_layer = (
264
+ self.key(hidden_states)
265
+ .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
266
+ .transpose(1, 2)
267
+ )
268
+ value_layer = (
269
+ self.value(hidden_states)
270
+ .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
271
+ .transpose(1, 2)
272
+ )
273
+
274
+ # Take the dot product between "query" and "key" to get the raw attention scores.
275
+ attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))
276
+
277
+ attention_scores = attention_scores / math.sqrt(self.attention_head_size)
278
+
279
+ # Add relative position bias if present.
280
+ if self.has_relative_position_bias:
281
+ height, width = resolution
282
+ window_size = (height // self.config.patch_size, width // self.config.patch_size)
283
+ attention_scores = attention_scores + self.relative_position_bias(
284
+ window_size, interpolate_pos_encoding, dim_size=hidden_states.shape[1]
285
+ )
286
+
287
+ # Add shared relative position bias if provided.
288
+ if relative_position_bias is not None:
289
+ attention_scores = attention_scores + relative_position_bias
290
+
291
+ # Normalize the attention scores to probabilities.
292
+ attention_probs = nn.functional.softmax(attention_scores, dim=-1)
293
+
294
+ # This is actually dropping out entire tokens to attend to, which might
295
+ # seem a bit unusual, but is taken from the original Transformer paper.
296
+ attention_probs = self.dropout(attention_probs)
297
+
298
+ context_layer = torch.matmul(attention_probs, value_layer)
299
+
300
+ context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
301
+ new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
302
+ context_layer = context_layer.view(*new_context_layer_shape)
303
+
304
+ outputs = (context_layer, attention_probs) if output_attentions else (context_layer,)
305
+
306
+ return outputs
307
+
308
+
309
+ class BeitSdpaSelfAttention(BeitSelfAttention):
310
+ def forward(
311
+ self,
312
+ hidden_states: torch.Tensor,
313
+ output_attentions: bool = False,
314
+ relative_position_bias: torch.Tensor | None = None,
315
+ interpolate_pos_encoding: bool = False,
316
+ resolution: tuple[int] | None = None,
317
+ ) -> tuple[torch.Tensor] | tuple[torch.Tensor, torch.Tensor]:
318
+ if output_attentions:
319
+ logger.warning_once(
320
+ f"{self.__class__.__name__} does not support `output_attentions=True`. The returned attention weights will "
321
+ "be `None`. If you want to get attention weights, please set `attn_implementation='eager'` when loading the model."
322
+ )
323
+ batch_size, seq_length, _ = hidden_states.shape
324
+ query_layer = (
325
+ self.query(hidden_states)
326
+ .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
327
+ .transpose(1, 2)
328
+ )
329
+ key_layer = (
330
+ self.key(hidden_states)
331
+ .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
332
+ .transpose(1, 2)
333
+ )
334
+ value_layer = (
335
+ self.value(hidden_states)
336
+ .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
337
+ .transpose(1, 2)
338
+ )
339
+
340
+ attn_bias = None
341
+ if self.has_relative_position_bias:
342
+ height, width = resolution
343
+ window_size = (height // self.config.patch_size, width // self.config.patch_size)
344
+ attn_bias = self.relative_position_bias(
345
+ window_size, interpolate_pos_encoding, dim_size=hidden_states.shape[1]
346
+ )
347
+
348
+ # Add shared relative position bias if provided.
349
+ if relative_position_bias is not None:
350
+ if attn_bias is None:
351
+ attn_bias = relative_position_bias
352
+ else:
353
+ attn_bias += relative_position_bias
354
+
355
+ scaling = 1 / math.sqrt(self.attention_head_size)
356
+ context_layer = torch.nn.functional.scaled_dot_product_attention(
357
+ query_layer,
358
+ key_layer,
359
+ value_layer,
360
+ attn_mask=attn_bias,
361
+ dropout_p=self.config.attention_probs_dropout_prob if self.training else 0.0,
362
+ is_causal=False,
363
+ scale=scaling,
364
+ )
365
+ context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
366
+ new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
367
+ context_layer = context_layer.view(*new_context_layer_shape)
368
+ return context_layer, None
369
+
370
+
371
+ class BeitSelfOutput(nn.Module):
372
+ """
373
+ The residual connection is defined in BeitLayer instead of here (as is the case with other models), due to the
374
+ layernorm applied before each block.
375
+ """
376
+
377
+ def __init__(self, config: BeitConfig) -> None:
378
+ super().__init__()
379
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
380
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
381
+
382
+ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor, gamma=None) -> torch.Tensor:
383
+ hidden_states = self.dense(hidden_states)
384
+ hidden_states = self.dropout(hidden_states)
385
+
386
+ return hidden_states
387
+
388
+
389
+ BEIT_SELF_ATTENTION_CLASSES = {
390
+ "eager": BeitSelfAttention,
391
+ "sdpa": BeitSdpaSelfAttention,
392
+ }
393
+
394
+
395
+ class BeitAttention(nn.Module):
396
+ def __init__(self, config: BeitConfig, window_size: tuple | None = None) -> None:
397
+ super().__init__()
398
+ self.attention = BEIT_SELF_ATTENTION_CLASSES[config._attn_implementation](config, window_size=window_size)
399
+ self.output = BeitSelfOutput(config)
400
+
401
+ def forward(
402
+ self,
403
+ hidden_states: torch.Tensor,
404
+ output_attentions: bool = False,
405
+ relative_position_bias: torch.Tensor | None = None,
406
+ interpolate_pos_encoding: bool = False,
407
+ resolution: tuple[int] | None = None,
408
+ ) -> tuple[torch.Tensor] | tuple[torch.Tensor, torch.Tensor]:
409
+ self_outputs = self.attention(
410
+ hidden_states, output_attentions, relative_position_bias, interpolate_pos_encoding, resolution
411
+ )
412
+
413
+ attention_output = self.output(self_outputs[0], hidden_states)
414
+
415
+ outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them
416
+ return outputs
417
+
418
+
419
+ class BeitIntermediate(nn.Module):
420
+ def __init__(self, config: BeitConfig) -> None:
421
+ super().__init__()
422
+ self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
423
+ if isinstance(config.hidden_act, str):
424
+ self.intermediate_act_fn = ACT2FN[config.hidden_act]
425
+ else:
426
+ self.intermediate_act_fn = config.hidden_act
427
+
428
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
429
+ hidden_states = self.dense(hidden_states)
430
+ hidden_states = self.intermediate_act_fn(hidden_states)
431
+
432
+ return hidden_states
433
+
434
+
435
+ class BeitOutput(nn.Module):
436
+ def __init__(self, config: BeitConfig) -> None:
437
+ super().__init__()
438
+ self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
439
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
440
+
441
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
442
+ hidden_states = self.dense(hidden_states)
443
+ hidden_states = self.dropout(hidden_states)
444
+
445
+ return hidden_states
446
+
447
+
448
+ class BeitLayer(GradientCheckpointingLayer):
449
+ """This corresponds to the Block class in the timm implementation."""
450
+
451
+ def __init__(self, config: BeitConfig, window_size: tuple | None = None, drop_path_rate: float = 0.0) -> None:
452
+ super().__init__()
453
+ self.chunk_size_feed_forward = config.chunk_size_feed_forward
454
+ self.seq_len_dim = 1
455
+ self.attention = BeitAttention(config, window_size=window_size)
456
+ self.intermediate = BeitIntermediate(config)
457
+ self.output = BeitOutput(config)
458
+ self.layernorm_before = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
459
+ self.drop_path = BeitDropPath(drop_path_rate) if drop_path_rate > 0.0 else nn.Identity()
460
+ self.layernorm_after = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
461
+
462
+ init_values = config.layer_scale_init_value
463
+ if init_values > 0:
464
+ self.lambda_1 = nn.Parameter(init_values * torch.ones(config.hidden_size), requires_grad=True)
465
+ self.lambda_2 = nn.Parameter(init_values * torch.ones(config.hidden_size), requires_grad=True)
466
+ else:
467
+ self.lambda_1, self.lambda_2 = None, None
468
+
469
+ def forward(
470
+ self,
471
+ hidden_states: torch.Tensor,
472
+ output_attentions: bool = False,
473
+ relative_position_bias: torch.Tensor | None = None,
474
+ interpolate_pos_encoding: bool = False,
475
+ resolution: tuple[int, int] | None = None,
476
+ ) -> tuple[torch.Tensor] | tuple[torch.Tensor, torch.Tensor]:
477
+ self_attention_outputs = self.attention(
478
+ self.layernorm_before(hidden_states), # in BEiT, layernorm is applied before self-attention
479
+ output_attentions=output_attentions,
480
+ relative_position_bias=relative_position_bias,
481
+ interpolate_pos_encoding=interpolate_pos_encoding,
482
+ resolution=resolution,
483
+ )
484
+ attention_output = self_attention_outputs[0]
485
+ outputs = self_attention_outputs[1:] # add self attentions if we output attention weights
486
+
487
+ # apply lambda_1 if present
488
+ if self.lambda_1 is not None:
489
+ attention_output = self.lambda_1 * attention_output
490
+
491
+ # first residual connection
492
+ hidden_states = self.drop_path(attention_output) + hidden_states
493
+
494
+ # in BEiT, layernorm is also applied after self-attention
495
+ layer_output = self.layernorm_after(hidden_states)
496
+
497
+ layer_output = self.intermediate(layer_output)
498
+ layer_output = self.output(layer_output)
499
+
500
+ if self.lambda_2 is not None:
501
+ layer_output = self.lambda_2 * layer_output
502
+
503
+ # second residual connection
504
+ layer_output = self.drop_path(layer_output) + hidden_states
505
+
506
+ outputs = (layer_output,) + outputs
507
+
508
+ return outputs
509
+
510
+
511
+ class BeitRelativePositionBias(nn.Module):
512
+ def __init__(self, config: BeitConfig, window_size: tuple) -> None:
513
+ super().__init__()
514
+ self.window_size = window_size
515
+ self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3
516
+ self.relative_position_bias_table = nn.Parameter(
517
+ torch.zeros(self.num_relative_distance, config.num_attention_heads)
518
+ ) # 2*Wh-1 * 2*Ww-1, nH
519
+ # cls to token & token 2 cls & cls to cls
520
+
521
+ @compile_compatible_method_lru_cache(maxsize=10)
522
+ def generate_relative_position_index(self, window_size: tuple[int, int]) -> torch.Tensor:
523
+ """
524
+ This method creates the relative position index, modified to support arbitrary window sizes,
525
+ as introduced in [MiDaS v3.1](https://huggingface.co/papers/2307.14460).
526
+ """
527
+ num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3
528
+ # cls to token & token 2 cls & cls to cls
529
+ # get pair-wise relative position index for each token inside the window
530
+ window_area = window_size[0] * window_size[1]
531
+ grid = torch.meshgrid(torch.arange(window_size[0]), torch.arange(window_size[1]), indexing="ij")
532
+ coords = torch.stack(grid) # 2, Wh, Ww
533
+ coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww
534
+ relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww
535
+ relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2
536
+ relative_coords[:, :, 0] += window_size[0] - 1 # shift to start from 0
537
+ relative_coords[:, :, 1] += window_size[1] - 1
538
+ relative_coords[:, :, 0] *= 2 * window_size[1] - 1
539
+ relative_position_index = torch.zeros(size=(window_area + 1,) * 2, dtype=relative_coords.dtype)
540
+ relative_position_index[1:, 1:] = relative_coords.sum(-1) # Wh*Ww, Wh*Ww
541
+ relative_position_index[0, 0:] = num_relative_distance - 3
542
+ relative_position_index[0:, 0] = num_relative_distance - 2
543
+ relative_position_index[0, 0] = num_relative_distance - 1
544
+ return relative_position_index
545
+
546
+ def forward(self, window_size, interpolate_pos_encoding: bool = False, dim_size=None) -> torch.Tensor:
547
+ """
548
+ Modification of timm.models.beit.py: Attention._get_rel_pos_bias to support arbitrary window sizes.
549
+ """
550
+ old_height = 2 * self.window_size[0] - 1
551
+ old_width = 2 * self.window_size[1] - 1
552
+
553
+ new_height = 2 * window_size[0] - 1
554
+ new_width = 2 * window_size[1] - 1
555
+
556
+ old_relative_position_bias_table = self.relative_position_bias_table
557
+
558
+ old_num_relative_distance = self.num_relative_distance
559
+ new_num_relative_distance = new_height * new_width + 3
560
+
561
+ old_sub_table = old_relative_position_bias_table[: old_num_relative_distance - 3]
562
+
563
+ old_sub_table = old_sub_table.reshape(1, old_width, old_height, -1).permute(0, 3, 1, 2)
564
+ new_sub_table = nn.functional.interpolate(
565
+ old_sub_table, size=(torch_int(new_height), torch_int(new_width)), mode="bilinear"
566
+ )
567
+ new_sub_table = new_sub_table.permute(0, 2, 3, 1).reshape(new_num_relative_distance - 3, -1)
568
+
569
+ new_relative_position_bias_table = torch.cat(
570
+ [new_sub_table, old_relative_position_bias_table[old_num_relative_distance - 3 :]]
571
+ )
572
+
573
+ relative_position_index = self.generate_relative_position_index(window_size)
574
+ relative_position_bias = new_relative_position_bias_table[relative_position_index.view(-1)]
575
+
576
+ # patch_size*num_patches_height, patch_size*num_patches_width, num_attention_heads
577
+ relative_position_bias = relative_position_bias.view(
578
+ window_size[0] * window_size[1] + 1, window_size[0] * window_size[1] + 1, -1
579
+ )
580
+ # num_attention_heads, patch_size*num_patches_width, patch_size*num_patches_height
581
+ relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous()
582
+
583
+ if interpolate_pos_encoding:
584
+ relative_position_bias = nn.functional.interpolate(
585
+ relative_position_bias.unsqueeze(1),
586
+ size=(dim_size, dim_size),
587
+ mode="bilinear",
588
+ align_corners=False,
589
+ ).squeeze(1)
590
+
591
+ return relative_position_bias.unsqueeze(0)
592
+
593
+
594
+ class BeitEncoder(nn.Module):
595
+ def __init__(self, config: BeitConfig, window_size: tuple | None = None) -> None:
596
+ super().__init__()
597
+ self.config = config
598
+ self.has_relative_position_bias = config.use_shared_relative_position_bias
599
+ if self.has_relative_position_bias:
600
+ self.relative_position_bias = BeitRelativePositionBias(config, window_size=window_size)
601
+
602
+ # stochastic depth decay rule
603
+ dpr = [x.item() for x in torch.linspace(0, config.drop_path_rate, config.num_hidden_layers, device="cpu")]
604
+ self.layer = nn.ModuleList(
605
+ [
606
+ BeitLayer(
607
+ config,
608
+ window_size=window_size if config.use_relative_position_bias else None,
609
+ drop_path_rate=dpr[i],
610
+ )
611
+ for i in range(config.num_hidden_layers)
612
+ ]
613
+ )
614
+ self.gradient_checkpointing = False
615
+
616
+ def forward(
617
+ self,
618
+ hidden_states: torch.Tensor,
619
+ output_attentions: bool = False,
620
+ output_hidden_states: bool = False,
621
+ interpolate_pos_encoding: bool = False,
622
+ resolution: tuple[int, int] | None = None,
623
+ return_dict: bool = True,
624
+ ) -> tuple | BaseModelOutput:
625
+ all_hidden_states = () if output_hidden_states else None
626
+ all_self_attentions = () if output_attentions else None
627
+
628
+ for i, layer_module in enumerate(self.layer):
629
+ if output_hidden_states:
630
+ all_hidden_states = all_hidden_states + (hidden_states,)
631
+
632
+ if self.has_relative_position_bias:
633
+ height, width = resolution
634
+ window_size = (height // self.config.patch_size, width // self.config.patch_size)
635
+ relative_position_bias = self.relative_position_bias(
636
+ window_size, interpolate_pos_encoding=interpolate_pos_encoding, dim_size=hidden_states.shape[1]
637
+ )
638
+ else:
639
+ relative_position_bias = None
640
+
641
+ layer_outputs = layer_module(
642
+ hidden_states,
643
+ output_attentions=output_attentions,
644
+ relative_position_bias=relative_position_bias,
645
+ interpolate_pos_encoding=interpolate_pos_encoding,
646
+ resolution=resolution,
647
+ )
648
+
649
+ hidden_states = layer_outputs[0]
650
+
651
+ if output_attentions:
652
+ all_self_attentions = all_self_attentions + (layer_outputs[1],)
653
+
654
+ if output_hidden_states:
655
+ all_hidden_states = all_hidden_states + (hidden_states,)
656
+
657
+ if not return_dict:
658
+ return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None)
659
+ return BaseModelOutput(
660
+ last_hidden_state=hidden_states,
661
+ hidden_states=all_hidden_states,
662
+ attentions=all_self_attentions,
663
+ )
664
+
665
+
666
+ @auto_docstring
667
+ class BeitPreTrainedModel(PreTrainedModel):
668
+ config: BeitConfig
669
+ base_model_prefix = "beit"
670
+ input_modalities = ("image",)
671
+ main_input_name = "pixel_values"
672
+ supports_gradient_checkpointing = True
673
+ _no_split_modules = ["BeitLayer"]
674
+ _keys_to_ignore_on_load_unexpected = [r".*relative_position_index.*"]
675
+ _supports_sdpa = True
676
+
677
+ @torch.no_grad()
678
+ def _init_weights(self, module):
679
+ """Initialize the weights"""
680
+ super()._init_weights(module)
681
+ if isinstance(module, BeitEmbeddings):
682
+ init.zeros_(module.cls_token)
683
+ if module.mask_token is not None:
684
+ init.zeros_(module.mask_token)
685
+ if module.position_embeddings is not None:
686
+ init.zeros_(module.position_embeddings)
687
+ elif isinstance(module, BeitRelativePositionBias):
688
+ init.zeros_(module.relative_position_bias_table)
689
+ elif isinstance(module, BeitLayer):
690
+ if module.lambda_1 is not None:
691
+ init.constant_(module.lambda_1, self.config.layer_scale_init_value)
692
+ init.constant_(module.lambda_2, self.config.layer_scale_init_value)
693
+
694
+
695
+ @auto_docstring
696
+ class BeitModel(BeitPreTrainedModel):
697
+ def __init__(self, config: BeitConfig, add_pooling_layer: bool = True) -> None:
698
+ r"""
699
+ add_pooling_layer (bool, *optional*, defaults to `True`):
700
+ Whether to add a pooling layer
701
+ """
702
+ super().__init__(config)
703
+ self.config = config
704
+
705
+ self.embeddings = BeitEmbeddings(config)
706
+ self.encoder = BeitEncoder(config, window_size=self.embeddings.patch_embeddings.patch_shape)
707
+
708
+ self.layernorm = (
709
+ nn.Identity() if config.use_mean_pooling else nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
710
+ )
711
+ self.pooler = BeitPooler(config) if add_pooling_layer else None
712
+
713
+ # Initialize weights and apply final processing
714
+ self.post_init()
715
+
716
+ def get_input_embeddings(self):
717
+ return self.embeddings.patch_embeddings
718
+
719
+ @auto_docstring
720
+ def forward(
721
+ self,
722
+ pixel_values: torch.Tensor,
723
+ bool_masked_pos: torch.BoolTensor | None = None,
724
+ output_attentions: bool | None = None,
725
+ output_hidden_states: bool | None = None,
726
+ interpolate_pos_encoding: bool = False,
727
+ return_dict: bool | None = None,
728
+ **kwargs,
729
+ ) -> tuple | BeitModelOutputWithPooling:
730
+ r"""
731
+ bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`, *optional*):
732
+ Boolean masked positions. Indicates which patches are masked (1) and which aren't (0).
733
+ """
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
+ embedding_output, _ = self.embeddings(pixel_values, bool_masked_pos=bool_masked_pos)
741
+ resolution = pixel_values.shape[2:]
742
+
743
+ encoder_outputs = self.encoder(
744
+ embedding_output,
745
+ output_attentions=output_attentions,
746
+ output_hidden_states=output_hidden_states,
747
+ resolution=resolution,
748
+ return_dict=return_dict,
749
+ interpolate_pos_encoding=interpolate_pos_encoding,
750
+ )
751
+ sequence_output = encoder_outputs[0]
752
+ sequence_output = self.layernorm(sequence_output)
753
+ pooled_output = self.pooler(sequence_output) if self.pooler is not None else None
754
+
755
+ if not return_dict:
756
+ head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,)
757
+ return head_outputs + encoder_outputs[1:]
758
+
759
+ return BeitModelOutputWithPooling(
760
+ last_hidden_state=sequence_output,
761
+ pooler_output=pooled_output,
762
+ hidden_states=encoder_outputs.hidden_states,
763
+ attentions=encoder_outputs.attentions,
764
+ )
765
+
766
+
767
+ class BeitPooler(nn.Module):
768
+ def __init__(self, config: BeitConfig) -> None:
769
+ super().__init__()
770
+ self.layernorm = (
771
+ nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) if config.use_mean_pooling else None
772
+ )
773
+
774
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
775
+ if self.layernorm is not None:
776
+ # Mean pool the final hidden states of the patch tokens
777
+ patch_tokens = hidden_states[:, 1:, :]
778
+ pooled_output = self.layernorm(patch_tokens.mean(1))
779
+ else:
780
+ # Pool by simply taking the final hidden state of the [CLS] token
781
+ pooled_output = hidden_states[:, 0]
782
+
783
+ return pooled_output
784
+
785
+
786
+ @auto_docstring(
787
+ custom_intro="""
788
+ Beit Model transformer with a 'language' modeling head on top. BEiT does masked image modeling by predicting
789
+ visual tokens of a Vector-Quantize Variational Autoencoder (VQ-VAE), whereas other vision models like ViT and DeiT
790
+ predict RGB pixel values. As a result, this class is incompatible with [`AutoModelForMaskedImageModeling`], so you
791
+ will need to use [`BeitForMaskedImageModeling`] directly if you wish to do masked image modeling with BEiT.
792
+ """
793
+ )
794
+ class BeitForMaskedImageModeling(BeitPreTrainedModel):
795
+ def __init__(self, config: BeitConfig) -> None:
796
+ super().__init__(config)
797
+
798
+ self.num_labels = config.num_labels
799
+ self.beit = BeitModel(config, add_pooling_layer=False)
800
+
801
+ # Classifier head
802
+ self.layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
803
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size)
804
+
805
+ # Initialize weights and apply final processing
806
+ self.post_init()
807
+
808
+ def get_output_embeddings(self):
809
+ return None
810
+
811
+ @auto_docstring
812
+ def forward(
813
+ self,
814
+ pixel_values: torch.Tensor | None = None,
815
+ bool_masked_pos: torch.BoolTensor | None = None,
816
+ labels: torch.Tensor | None = None,
817
+ output_attentions: bool | None = None,
818
+ output_hidden_states: bool | None = None,
819
+ interpolate_pos_encoding: bool = False,
820
+ return_dict: bool | None = None,
821
+ **kwargs,
822
+ ) -> tuple | MaskedLMOutput:
823
+ r"""
824
+ bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`):
825
+ Boolean masked positions. Indicates which patches are masked (1) and which aren't (0).
826
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
827
+ Labels for computing the image classification/regression loss. Indices should be in `[0, ...,
828
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
829
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
830
+
831
+ Examples:
832
+
833
+ ```python
834
+ >>> from transformers import AutoImageProcessor, BeitForMaskedImageModeling
835
+ >>> import torch
836
+ >>> from PIL import Image
837
+ >>> import httpx
838
+ >>> from io import BytesIO
839
+
840
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
841
+ >>> with httpx.stream("GET", url) as response:
842
+ ... image = Image.open(BytesIO(response.read()))
843
+
844
+ >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-patch16-224-pt22k")
845
+ >>> model = BeitForMaskedImageModeling.from_pretrained("microsoft/beit-base-patch16-224-pt22k")
846
+
847
+ >>> num_patches = (model.config.image_size // model.config.patch_size) ** 2
848
+ >>> pixel_values = image_processor(images=image, return_tensors="pt").pixel_values
849
+ >>> # create random boolean mask of shape (batch_size, num_patches)
850
+ >>> bool_masked_pos = torch.randint(low=0, high=2, size=(1, num_patches)).bool()
851
+
852
+ >>> outputs = model(pixel_values, bool_masked_pos=bool_masked_pos)
853
+ >>> loss, logits = outputs.loss, outputs.logits
854
+ >>> list(logits.shape)
855
+ [1, 196, 8192]
856
+ ```"""
857
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
858
+
859
+ outputs = self.beit(
860
+ pixel_values,
861
+ bool_masked_pos=bool_masked_pos,
862
+ output_attentions=output_attentions,
863
+ output_hidden_states=output_hidden_states,
864
+ interpolate_pos_encoding=interpolate_pos_encoding,
865
+ return_dict=return_dict,
866
+ )
867
+
868
+ sequence_output = outputs[0]
869
+ sequence_output = self.layernorm(sequence_output)
870
+ prediction_scores = self.lm_head(sequence_output[:, 1:])
871
+
872
+ masked_lm_loss = None
873
+ if labels is not None:
874
+ loss_fct = CrossEntropyLoss() # -100 index = padding token
875
+ masked_lm_loss = loss_fct(prediction_scores[bool_masked_pos], labels)
876
+
877
+ if not return_dict:
878
+ output = (prediction_scores,) + outputs[1:]
879
+ return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output
880
+
881
+ return MaskedLMOutput(
882
+ loss=masked_lm_loss,
883
+ logits=prediction_scores,
884
+ hidden_states=outputs.hidden_states,
885
+ attentions=outputs.attentions,
886
+ )
887
+
888
+
889
+ @auto_docstring(
890
+ custom_intro="""
891
+ Beit Model transformer with an image classification head on top (a linear layer on top of the average of the final
892
+ hidden states of the patch tokens) e.g. for ImageNet.
893
+ """
894
+ )
895
+ class BeitForImageClassification(BeitPreTrainedModel):
896
+ def __init__(self, config: BeitConfig) -> None:
897
+ super().__init__(config)
898
+
899
+ self.num_labels = config.num_labels
900
+ self.beit = BeitModel(config, add_pooling_layer=True)
901
+
902
+ # Classifier head
903
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity()
904
+
905
+ # Initialize weights and apply final processing
906
+ self.post_init()
907
+
908
+ @auto_docstring
909
+ def forward(
910
+ self,
911
+ pixel_values: torch.Tensor | None = None,
912
+ labels: torch.Tensor | None = None,
913
+ output_attentions: bool | None = None,
914
+ output_hidden_states: bool | None = None,
915
+ interpolate_pos_encoding: bool = False,
916
+ return_dict: bool | None = None,
917
+ **kwargs,
918
+ ) -> tuple | ImageClassifierOutput:
919
+ r"""
920
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
921
+ Labels for computing the image classification/regression loss. Indices should be in `[0, ...,
922
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
923
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
924
+ """
925
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
926
+ outputs = self.beit(
927
+ pixel_values,
928
+ output_attentions=output_attentions,
929
+ output_hidden_states=output_hidden_states,
930
+ interpolate_pos_encoding=interpolate_pos_encoding,
931
+ return_dict=return_dict,
932
+ )
933
+
934
+ pooled_output = outputs.pooler_output if return_dict else outputs[1]
935
+
936
+ logits = self.classifier(pooled_output)
937
+
938
+ loss = None
939
+ if labels is not None:
940
+ loss = self.loss_function(labels, logits, self.config)
941
+
942
+ if not return_dict:
943
+ output = (logits,) + outputs[2:]
944
+ return ((loss,) + output) if loss is not None else output
945
+
946
+ return ImageClassifierOutput(
947
+ loss=loss,
948
+ logits=logits,
949
+ hidden_states=outputs.hidden_states,
950
+ attentions=outputs.attentions,
951
+ )
952
+
953
+
954
+ class BeitConvModule(nn.Module):
955
+ """
956
+ A convolutional block that bundles conv/norm/activation layers. This block simplifies the usage of convolution
957
+ layers, which are commonly used with a norm layer (e.g., BatchNorm) and activation layer (e.g., ReLU).
958
+
959
+ Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation.
960
+ """
961
+
962
+ def __init__(
963
+ self,
964
+ in_channels: int,
965
+ out_channels: int,
966
+ kernel_size: int | tuple[int, int],
967
+ padding: int | tuple[int, int] | str = 0,
968
+ bias: bool = False,
969
+ dilation: int | tuple[int, int] = 1,
970
+ ) -> None:
971
+ super().__init__()
972
+ self.conv = nn.Conv2d(
973
+ in_channels=in_channels,
974
+ out_channels=out_channels,
975
+ kernel_size=kernel_size,
976
+ padding=padding,
977
+ bias=bias,
978
+ dilation=dilation,
979
+ )
980
+ self.bn = nn.BatchNorm2d(out_channels)
981
+ self.activation = nn.ReLU()
982
+
983
+ def forward(self, input: torch.Tensor) -> torch.Tensor:
984
+ output = self.conv(input)
985
+ output = self.bn(output)
986
+ output = self.activation(output)
987
+
988
+ return output
989
+
990
+
991
+ class BeitPyramidPoolingBlock(nn.Module):
992
+ def __init__(self, pool_scale: int, in_channels: int, channels: int) -> None:
993
+ super().__init__()
994
+ self.layers = [
995
+ nn.AdaptiveAvgPool2d(pool_scale),
996
+ BeitConvModule(in_channels, channels, kernel_size=1),
997
+ ]
998
+ for i, layer in enumerate(self.layers):
999
+ self.add_module(str(i), layer)
1000
+
1001
+ def forward(self, input: torch.Tensor) -> torch.Tensor:
1002
+ hidden_state = input
1003
+ for layer in self.layers:
1004
+ hidden_state = layer(hidden_state)
1005
+ return hidden_state
1006
+
1007
+
1008
+ class BeitPyramidPoolingModule(nn.Module):
1009
+ """
1010
+ Pyramid Pooling Module (PPM) used in PSPNet.
1011
+
1012
+ Args:
1013
+ pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid
1014
+ Module.
1015
+ in_channels (int): Input channels.
1016
+ channels (int): Channels after modules, before conv_seg.
1017
+ align_corners (bool): align_corners argument of F.interpolate.
1018
+
1019
+ Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation.
1020
+ """
1021
+
1022
+ def __init__(self, pool_scales: tuple[int, ...], in_channels: int, channels: int, align_corners: bool) -> None:
1023
+ super().__init__()
1024
+ self.pool_scales = pool_scales
1025
+ self.align_corners = align_corners
1026
+ self.in_channels = in_channels
1027
+ self.channels = channels
1028
+ self.blocks = []
1029
+ for i, pool_scale in enumerate(pool_scales):
1030
+ block = BeitPyramidPoolingBlock(pool_scale=pool_scale, in_channels=in_channels, channels=channels)
1031
+ self.blocks.append(block)
1032
+ self.add_module(str(i), block)
1033
+
1034
+ def forward(self, x: torch.Tensor) -> list[torch.Tensor]:
1035
+ ppm_outs = []
1036
+ for ppm in self.blocks:
1037
+ ppm_out = ppm(x)
1038
+ upsampled_ppm_out = nn.functional.interpolate(
1039
+ ppm_out, size=x.size()[2:], mode="bilinear", align_corners=self.align_corners
1040
+ )
1041
+ ppm_outs.append(upsampled_ppm_out)
1042
+ return ppm_outs
1043
+
1044
+
1045
+ class BeitUperHead(nn.Module):
1046
+ """
1047
+ Unified Perceptual Parsing for Scene Understanding. This head is the implementation of
1048
+ [UPerNet](https://huggingface.co/papers/1807.10221).
1049
+
1050
+ Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation.
1051
+ """
1052
+
1053
+ def __init__(self, config: BeitConfig) -> None:
1054
+ super().__init__()
1055
+
1056
+ self.pool_scales = config.pool_scales # e.g. (1, 2, 3, 6)
1057
+ self.in_channels = [config.hidden_size] * 4 # e.g. [768, 768, 768, 768]
1058
+ self.channels = config.hidden_size
1059
+ self.align_corners = False
1060
+ self.classifier = nn.Conv2d(self.channels, config.num_labels, kernel_size=1)
1061
+
1062
+ # PSP Module
1063
+ self.psp_modules = BeitPyramidPoolingModule(
1064
+ self.pool_scales,
1065
+ self.in_channels[-1],
1066
+ self.channels,
1067
+ align_corners=self.align_corners,
1068
+ )
1069
+ self.bottleneck = BeitConvModule(
1070
+ self.in_channels[-1] + len(self.pool_scales) * self.channels,
1071
+ self.channels,
1072
+ kernel_size=3,
1073
+ padding=1,
1074
+ )
1075
+ # FPN Module
1076
+ self.lateral_convs = nn.ModuleList()
1077
+ self.fpn_convs = nn.ModuleList()
1078
+ for in_channels in self.in_channels[:-1]: # skip the top layer
1079
+ l_conv = BeitConvModule(in_channels, self.channels, kernel_size=1)
1080
+ fpn_conv = BeitConvModule(self.channels, self.channels, kernel_size=3, padding=1)
1081
+ self.lateral_convs.append(l_conv)
1082
+ self.fpn_convs.append(fpn_conv)
1083
+
1084
+ self.fpn_bottleneck = BeitConvModule(
1085
+ len(self.in_channels) * self.channels,
1086
+ self.channels,
1087
+ kernel_size=3,
1088
+ padding=1,
1089
+ )
1090
+
1091
+ def psp_forward(self, inputs):
1092
+ x = inputs[-1]
1093
+ psp_outs = [x]
1094
+ psp_outs.extend(self.psp_modules(x))
1095
+ psp_outs = torch.cat(psp_outs, dim=1)
1096
+ output = self.bottleneck(psp_outs)
1097
+
1098
+ return output
1099
+
1100
+ def forward(self, encoder_hidden_states: torch.Tensor) -> torch.Tensor:
1101
+ # build laterals
1102
+ laterals = [lateral_conv(encoder_hidden_states[i]) for i, lateral_conv in enumerate(self.lateral_convs)]
1103
+
1104
+ laterals.append(self.psp_forward(encoder_hidden_states))
1105
+
1106
+ # build top-down path
1107
+ used_backbone_levels = len(laterals)
1108
+ for i in range(used_backbone_levels - 1, 0, -1):
1109
+ prev_shape = laterals[i - 1].shape[2:]
1110
+ laterals[i - 1] = laterals[i - 1] + nn.functional.interpolate(
1111
+ laterals[i], size=prev_shape, mode="bilinear", align_corners=self.align_corners
1112
+ )
1113
+
1114
+ # build outputs
1115
+ fpn_outs = [self.fpn_convs[i](laterals[i]) for i in range(used_backbone_levels - 1)]
1116
+ # append psp feature
1117
+ fpn_outs.append(laterals[-1])
1118
+
1119
+ for i in range(used_backbone_levels - 1, 0, -1):
1120
+ fpn_outs[i] = nn.functional.interpolate(
1121
+ fpn_outs[i], size=fpn_outs[0].shape[2:], mode="bilinear", align_corners=self.align_corners
1122
+ )
1123
+ fpn_outs = torch.cat(fpn_outs, dim=1)
1124
+ output = self.fpn_bottleneck(fpn_outs)
1125
+ output = self.classifier(output)
1126
+
1127
+ return output
1128
+
1129
+
1130
+ class BeitFCNHead(nn.Module):
1131
+ """
1132
+ Fully Convolution Networks for Semantic Segmentation. This head is implemented of
1133
+ [FCNNet](https://huggingface.co/papers/1411.4038>).
1134
+
1135
+ Args:
1136
+ config (BeitConfig): Configuration.
1137
+ in_channels
1138
+ kernel_size (int): The kernel size for convs in the head. Default: 3.
1139
+ dilation (int): The dilation rate for convs in the head. Default: 1.
1140
+
1141
+
1142
+ Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation.
1143
+ """
1144
+
1145
+ def __init__(
1146
+ self, config: BeitConfig, in_index: int = 2, kernel_size: int = 3, dilation: int | tuple[int, int] = 1
1147
+ ) -> None:
1148
+ super().__init__()
1149
+ self.in_channels = config.hidden_size
1150
+ self.channels = config.auxiliary_channels
1151
+ self.num_convs = config.auxiliary_num_convs
1152
+ self.concat_input = config.auxiliary_concat_input
1153
+ self.in_index = in_index
1154
+
1155
+ conv_padding = (kernel_size // 2) * dilation
1156
+ convs = []
1157
+ convs.append(
1158
+ BeitConvModule(
1159
+ self.in_channels, self.channels, kernel_size=kernel_size, padding=conv_padding, dilation=dilation
1160
+ )
1161
+ )
1162
+ for i in range(self.num_convs - 1):
1163
+ convs.append(
1164
+ BeitConvModule(
1165
+ self.channels, self.channels, kernel_size=kernel_size, padding=conv_padding, dilation=dilation
1166
+ )
1167
+ )
1168
+ if self.num_convs == 0:
1169
+ self.convs = nn.Identity()
1170
+ else:
1171
+ self.convs = nn.Sequential(*convs)
1172
+ if self.concat_input:
1173
+ self.conv_cat = BeitConvModule(
1174
+ self.in_channels + self.channels, self.channels, kernel_size=kernel_size, padding=kernel_size // 2
1175
+ )
1176
+
1177
+ self.classifier = nn.Conv2d(self.channels, config.num_labels, kernel_size=1)
1178
+
1179
+ def forward(self, encoder_hidden_states: torch.Tensor) -> torch.Tensor:
1180
+ # just take the relevant feature maps
1181
+ hidden_states = encoder_hidden_states[self.in_index]
1182
+ output = self.convs(hidden_states)
1183
+ if self.concat_input:
1184
+ output = self.conv_cat(torch.cat([hidden_states, output], dim=1))
1185
+ output = self.classifier(output)
1186
+ return output
1187
+
1188
+
1189
+ @auto_docstring
1190
+ class BeitForSemanticSegmentation(BeitPreTrainedModel):
1191
+ def __init__(self, config: BeitConfig) -> None:
1192
+ super().__init__(config)
1193
+
1194
+ self.num_labels = config.num_labels
1195
+ self.beit = BeitModel(config, add_pooling_layer=False)
1196
+
1197
+ # FPNs
1198
+ if len(self.config.out_indices) != 4:
1199
+ raise ValueError(
1200
+ "BeitForSemanticSegmentation requires config.out_indices to be a list of 4 integers, "
1201
+ "specifying which features to use from the backbone. One can use [3, 5, 7, 11] in case of "
1202
+ "a base-sized architecture."
1203
+ )
1204
+ self.fpn1 = nn.Sequential(
1205
+ nn.ConvTranspose2d(config.hidden_size, config.hidden_size, kernel_size=2, stride=2),
1206
+ nn.BatchNorm2d(config.hidden_size),
1207
+ nn.GELU(),
1208
+ nn.ConvTranspose2d(config.hidden_size, config.hidden_size, kernel_size=2, stride=2),
1209
+ )
1210
+ self.fpn2 = nn.Sequential(
1211
+ nn.ConvTranspose2d(config.hidden_size, config.hidden_size, kernel_size=2, stride=2),
1212
+ )
1213
+ self.fpn3 = nn.Identity()
1214
+ self.fpn4 = nn.MaxPool2d(kernel_size=2, stride=2)
1215
+
1216
+ # Semantic segmentation head(s)
1217
+ self.decode_head = BeitUperHead(config)
1218
+ self.auxiliary_head = BeitFCNHead(config) if config.use_auxiliary_head else None
1219
+
1220
+ # Initialize weights and apply final processing
1221
+ self.post_init()
1222
+
1223
+ def compute_loss(self, logits, auxiliary_logits, labels):
1224
+ # upsample logits to the images' original size
1225
+ upsampled_logits = nn.functional.interpolate(
1226
+ logits, size=labels.shape[-2:], mode="bilinear", align_corners=False
1227
+ )
1228
+ if auxiliary_logits is not None:
1229
+ upsampled_auxiliary_logits = nn.functional.interpolate(
1230
+ auxiliary_logits, size=labels.shape[-2:], mode="bilinear", align_corners=False
1231
+ )
1232
+ # compute weighted loss
1233
+ loss_fct = CrossEntropyLoss(ignore_index=self.config.semantic_loss_ignore_index)
1234
+ main_loss = loss_fct(upsampled_logits, labels)
1235
+ loss = main_loss
1236
+ if auxiliary_logits is not None:
1237
+ auxiliary_loss = loss_fct(upsampled_auxiliary_logits, labels)
1238
+ loss += self.config.auxiliary_loss_weight * auxiliary_loss
1239
+
1240
+ return loss
1241
+
1242
+ @auto_docstring
1243
+ def forward(
1244
+ self,
1245
+ pixel_values: torch.Tensor | None = None,
1246
+ labels: torch.Tensor | None = None,
1247
+ output_attentions: bool | None = None,
1248
+ output_hidden_states: bool | None = None,
1249
+ interpolate_pos_encoding: bool = False,
1250
+ return_dict: bool | None = None,
1251
+ **kwargs,
1252
+ ) -> tuple | SemanticSegmenterOutput:
1253
+ r"""
1254
+ labels (`torch.LongTensor` of shape `(batch_size, height, width)`, *optional*):
1255
+ Ground truth semantic segmentation maps for computing the loss. Indices should be in `[0, ...,
1256
+ config.num_labels - 1]`. If `config.num_labels > 1`, a classification loss is computed (Cross-Entropy).
1257
+
1258
+ Examples:
1259
+
1260
+ ```python
1261
+ >>> from transformers import AutoImageProcessor, BeitForSemanticSegmentation
1262
+ >>> from PIL import Image
1263
+ >>> import httpx
1264
+ >>> from io import BytesIO
1265
+
1266
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
1267
+ >>> with httpx.stream("GET", url) as response:
1268
+ ... image = Image.open(BytesIO(response.read()))
1269
+
1270
+ >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-finetuned-ade-640-640")
1271
+ >>> model = BeitForSemanticSegmentation.from_pretrained("microsoft/beit-base-finetuned-ade-640-640")
1272
+
1273
+ >>> inputs = image_processor(images=image, return_tensors="pt")
1274
+ >>> outputs = model(**inputs)
1275
+ >>> # logits are of shape (batch_size, num_labels, height, width)
1276
+ >>> logits = outputs.logits
1277
+ ```"""
1278
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1279
+ output_hidden_states = (
1280
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
1281
+ )
1282
+
1283
+ if labels is not None and self.config.num_labels == 1:
1284
+ raise ValueError("The number of labels should be greater than one")
1285
+
1286
+ outputs = self.beit(
1287
+ pixel_values,
1288
+ output_attentions=output_attentions,
1289
+ output_hidden_states=True, # we need the intermediate hidden states
1290
+ interpolate_pos_encoding=interpolate_pos_encoding,
1291
+ return_dict=return_dict,
1292
+ )
1293
+
1294
+ encoder_hidden_states = outputs.hidden_states if return_dict else outputs[1]
1295
+
1296
+ # only keep certain features, and reshape
1297
+ # note that we do +1 as the encoder_hidden_states also includes the initial embeddings
1298
+ features = [feature for idx, feature in enumerate(encoder_hidden_states) if idx + 1 in self.config.out_indices]
1299
+ batch_size = pixel_values.shape[0]
1300
+ patch_resolution = self.config.image_size // self.config.patch_size
1301
+ features = [
1302
+ x[:, 1:, :].permute(0, 2, 1).reshape(batch_size, -1, patch_resolution, patch_resolution) for x in features
1303
+ ]
1304
+
1305
+ # apply FPNs
1306
+ ops = [self.fpn1, self.fpn2, self.fpn3, self.fpn4]
1307
+ for i in range(len(features)):
1308
+ features[i] = ops[i](features[i])
1309
+
1310
+ logits = self.decode_head(features)
1311
+
1312
+ auxiliary_logits = None
1313
+ if self.auxiliary_head is not None:
1314
+ auxiliary_logits = self.auxiliary_head(features)
1315
+
1316
+ loss = None
1317
+ if labels is not None:
1318
+ loss = self.compute_loss(logits, auxiliary_logits, labels)
1319
+
1320
+ if not return_dict:
1321
+ if output_hidden_states:
1322
+ output = (logits,) + outputs[1:]
1323
+ else:
1324
+ output = (logits,) + outputs[2:]
1325
+ return ((loss,) + output) if loss is not None else output
1326
+
1327
+ return SemanticSegmenterOutput(
1328
+ loss=loss,
1329
+ logits=logits,
1330
+ hidden_states=outputs.hidden_states if output_hidden_states else None,
1331
+ attentions=outputs.attentions,
1332
+ )
1333
+
1334
+
1335
+ @auto_docstring(
1336
+ custom_intro="""
1337
+ BEiT backbone, to be used with frameworks like DETR and MaskFormer.
1338
+ """
1339
+ )
1340
+ class BeitBackbone(BackboneMixin, BeitPreTrainedModel):
1341
+ def __init__(self, config):
1342
+ super().__init__(config)
1343
+
1344
+ self.num_features = [config.hidden_size for _ in range(config.num_hidden_layers + 1)]
1345
+ self.embeddings = BeitEmbeddings(config)
1346
+ self.encoder = BeitEncoder(config, window_size=self.embeddings.patch_embeddings.patch_shape)
1347
+
1348
+ if config.add_fpn:
1349
+ if len(self.config.out_indices) != 4:
1350
+ raise ValueError(
1351
+ "BeitBackbone requires config.out_indices to be a list of 4 integers, "
1352
+ "specifying which features to use from the backbone. One can use [3, 5, 7, 11] in case of "
1353
+ "a base-sized architecture."
1354
+ )
1355
+ hidden_size = config.hidden_size
1356
+ self.fpn1 = nn.Sequential(
1357
+ nn.ConvTranspose2d(hidden_size, hidden_size, kernel_size=2, stride=2),
1358
+ nn.BatchNorm2d(hidden_size, eps=config.batch_norm_eps),
1359
+ nn.GELU(),
1360
+ nn.ConvTranspose2d(hidden_size, hidden_size, kernel_size=2, stride=2),
1361
+ )
1362
+
1363
+ self.fpn2 = nn.Sequential(nn.ConvTranspose2d(hidden_size, hidden_size, kernel_size=2, stride=2))
1364
+ self.fpn3 = nn.Identity()
1365
+ self.fpn4 = nn.MaxPool2d(kernel_size=2, stride=2)
1366
+
1367
+ # initialize weights and apply final processing
1368
+ self.post_init()
1369
+
1370
+ def get_input_embeddings(self):
1371
+ return self.embeddings.patch_embeddings
1372
+
1373
+ @can_return_tuple
1374
+ @filter_output_hidden_states
1375
+ @auto_docstring
1376
+ def forward(
1377
+ self,
1378
+ pixel_values: Tensor,
1379
+ output_hidden_states: bool | None = None,
1380
+ output_attentions: bool | None = None,
1381
+ return_dict: bool | None = None,
1382
+ **kwargs,
1383
+ ) -> BackboneOutput:
1384
+ r"""
1385
+ Examples:
1386
+
1387
+ ```python
1388
+ >>> from transformers import AutoImageProcessor, AutoBackbone
1389
+ >>> import torch
1390
+ >>> from PIL import Image
1391
+ >>> import httpx
1392
+ >>> from io import BytesIO
1393
+
1394
+ >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
1395
+ >>> with httpx.stream("GET", url) as response:
1396
+ ... image = Image.open(BytesIO(response.read()))
1397
+
1398
+ >>> processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-patch16-224")
1399
+ >>> model = AutoBackbone.from_pretrained(
1400
+ ... "microsoft/beit-base-patch16-224", out_features=["stage1", "stage2", "stage3", "stage4"]
1401
+ ... )
1402
+
1403
+ >>> inputs = processor(image, return_tensors="pt")
1404
+
1405
+ >>> outputs = model(**inputs)
1406
+ >>> feature_maps = outputs.feature_maps
1407
+ >>> list(feature_maps[-1].shape)
1408
+ [1, 768, 14, 14]
1409
+ ```"""
1410
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
1411
+ output_hidden_states = (
1412
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
1413
+ )
1414
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
1415
+
1416
+ batch_size = pixel_values.shape[0]
1417
+ embedding_output, (patch_height, patch_width) = self.embeddings(pixel_values)
1418
+ resolution = pixel_values.shape[2:]
1419
+
1420
+ outputs = self.encoder(
1421
+ embedding_output,
1422
+ output_hidden_states=True,
1423
+ output_attentions=output_attentions,
1424
+ resolution=resolution,
1425
+ return_dict=return_dict,
1426
+ )
1427
+
1428
+ hidden_states = outputs.hidden_states if return_dict else outputs[1]
1429
+
1430
+ feature_maps = ()
1431
+ for stage, hidden_state in zip(self.stage_names, hidden_states):
1432
+ if stage in self.out_features:
1433
+ if self.config.reshape_hidden_states:
1434
+ hidden_state = hidden_state[:, 1:, :]
1435
+ hidden_state = hidden_state.permute(0, 2, 1)
1436
+ hidden_state = hidden_state.reshape(batch_size, -1, patch_height, patch_width)
1437
+
1438
+ feature_maps += (hidden_state,)
1439
+
1440
+ if self.config.add_fpn:
1441
+ feature_maps = [
1442
+ self.fpn1(feature_maps[0]),
1443
+ self.fpn2(feature_maps[1]),
1444
+ self.fpn3(feature_maps[2]),
1445
+ self.fpn4(feature_maps[3]),
1446
+ ]
1447
+ feature_maps = tuple(feature_maps)
1448
+
1449
+ if not return_dict:
1450
+ if output_hidden_states:
1451
+ output = (feature_maps,) + outputs[1:]
1452
+ else:
1453
+ output = (feature_maps,) + outputs[2:]
1454
+ return output
1455
+
1456
+ return BackboneOutput(
1457
+ feature_maps=feature_maps,
1458
+ hidden_states=outputs.hidden_states if output_hidden_states else None,
1459
+ attentions=outputs.attentions,
1460
+ )
1461
+
1462
+
1463
+ __all__ = [
1464
+ "BeitForImageClassification",
1465
+ "BeitForMaskedImageModeling",
1466
+ "BeitForSemanticSegmentation",
1467
+ "BeitModel",
1468
+ "BeitPreTrainedModel",
1469
+ "BeitBackbone",
1470
+ ]
third_party/transformers/src/transformers/models/cohere2/__init__.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 Cohere 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_cohere2 import *
22
+ from .modeling_cohere2 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/cohere2/configuration_cohere2.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/cohere2/modular_cohere2.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_cohere2.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2024 Cohere Inc. HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ #
10
+ # Licensed under the Apache License, Version 2.0 (the "License");
11
+ # you may not use this file except in compliance with the License.
12
+ # You may obtain a copy of the License at
13
+ #
14
+ # http://www.apache.org/licenses/LICENSE-2.0
15
+ #
16
+ # Unless required by applicable law or agreed to in writing, software
17
+ # distributed under the License is distributed on an "AS IS" BASIS,
18
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ # See the License for the specific language governing permissions and
20
+ # limitations under the License.
21
+ from 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="CohereForAI/c4ai-command-r-v01")
29
+ @strict
30
+ class Cohere2Config(PreTrainedConfig):
31
+ r"""
32
+ logit_scale (`float`, *optional*, defaults to 0.0625):
33
+ The scaling factor for the output logits.
34
+
35
+ ```python
36
+ >>> from transformers import Cohere2Model, Cohere2Config
37
+
38
+ >>> # Initializing a Cohere Nextmodel configuration
39
+ >>> configuration = Cohere2Config()
40
+
41
+ >>> # Initializing a model from the Cohere2 configuration
42
+ >>> model = Cohere2Model(configuration) # doctest: +SKIP
43
+
44
+ >>> # Accessing the model configuration
45
+ >>> configuration = model.config # doctest: +SKIP
46
+ ```
47
+ """
48
+
49
+ model_type = "cohere2"
50
+ keys_to_ignore_at_inference = ["past_key_values"]
51
+ base_model_tp_plan = {
52
+ "layers.*.self_attn.q_proj": "colwise",
53
+ "layers.*.self_attn.k_proj": "colwise",
54
+ "layers.*.self_attn.v_proj": "colwise",
55
+ "layers.*.self_attn.o_proj": "rowwise",
56
+ "layers.*.mlp.gate_proj": "colwise",
57
+ "layers.*.mlp.up_proj": "colwise",
58
+ "layers.*.mlp.down_proj": "rowwise",
59
+ }
60
+ base_model_pp_plan = {
61
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
62
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
63
+ "norm": (["hidden_states"], ["hidden_states"]),
64
+ }
65
+
66
+ vocab_size: int = 256000
67
+ hidden_size: int = 8192
68
+ intermediate_size: int = 22528
69
+ logit_scale: float = 0.0625
70
+ num_hidden_layers: int = 40
71
+ num_attention_heads: int = 64
72
+ num_key_value_heads: int | None = None
73
+ hidden_act: str = "silu"
74
+ max_position_embeddings: int = 8192
75
+ initializer_range: float = 0.02
76
+ layer_norm_eps: float = 1e-5
77
+ use_cache: bool = True
78
+ pad_token_id: int | None = 0
79
+ bos_token_id: int | None = 5
80
+ eos_token_id: int | list[int] | None = 255001
81
+ tie_word_embeddings: bool = True
82
+ rope_parameters: RopeParameters | dict | None = None
83
+ attention_bias: bool = False
84
+ attention_dropout: float | int = 0.0
85
+ sliding_window: int | None = 4096
86
+ layer_types: list[str] | None = None
87
+
88
+ def __post_init__(self, **kwargs):
89
+ if self.num_key_value_heads is None:
90
+ self.num_key_value_heads = self.num_attention_heads
91
+
92
+ # Need to specify head_dim in the config so it can be used in the attention forward functions
93
+ self.head_dim = self.hidden_size // self.num_attention_heads
94
+
95
+ # BC -> the pattern used to be a simple int, and it's still present in configs on the Hub
96
+ if self.layer_types is None:
97
+ # BC -> the pattern used to be a simple int, and it's still present in configs on the Hub
98
+ _sliding_window_pattern = kwargs.pop("sliding_window_pattern", 4)
99
+ self.layer_types = [
100
+ "sliding_attention" if bool((i + 1) % _sliding_window_pattern) else "full_attention"
101
+ for i in range(self.num_hidden_layers)
102
+ ]
103
+
104
+ super().__post_init__(**kwargs)
105
+
106
+
107
+ __all__ = ["Cohere2Config"]
third_party/transformers/src/transformers/models/cohere_asr/__init__.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 the HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from typing import TYPE_CHECKING
16
+
17
+ from ...utils import _LazyModule
18
+ from ...utils.import_utils import define_import_structure
19
+
20
+
21
+ if TYPE_CHECKING:
22
+ from .configuration_cohere_asr import *
23
+ from .feature_extraction_cohere_asr import *
24
+ from .modeling_cohere_asr import *
25
+ from .processing_cohere_asr import *
26
+ else:
27
+ import sys
28
+
29
+ _file = globals()["__file__"]
30
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/cohere_asr/configuration_cohere_asr.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 the HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from huggingface_hub.dataclasses import strict
16
+
17
+ from ...configuration_utils import PreTrainedConfig
18
+ from ...utils import auto_docstring
19
+ from ..auto import CONFIG_MAPPING
20
+ from ..parakeet.configuration_parakeet import ParakeetEncoderConfig
21
+
22
+
23
+ @auto_docstring(checkpoint="CohereLabs/cohere-transcribe-03-2026")
24
+ @strict
25
+ class CohereAsrConfig(PreTrainedConfig):
26
+ r"""
27
+ Example:
28
+
29
+ ```python
30
+ >>> from transformers import CohereAsrForConditionalGeneration, CohereAsrConfig
31
+
32
+ >>> configuration = CohereAsrConfig()
33
+ >>> model = CohereAsrForConditionalGeneration(configuration)
34
+ >>> configuration = model.config
35
+ ```"""
36
+
37
+ model_type = "cohere_asr"
38
+ sub_configs = {"encoder_config": ParakeetEncoderConfig}
39
+
40
+ _default_encoder_config_kwargs = {
41
+ "hidden_size": 1280,
42
+ "num_hidden_layers": 48,
43
+ "num_attention_heads": 8,
44
+ "intermediate_size": 5120,
45
+ "hidden_act": "silu",
46
+ "attention_bias": True,
47
+ "convolution_bias": True,
48
+ "conv_kernel_size": 9,
49
+ "subsampling_factor": 8,
50
+ "subsampling_conv_channels": 256,
51
+ "num_mel_bins": 128,
52
+ "subsampling_conv_kernel_size": 3,
53
+ "subsampling_conv_stride": 2,
54
+ "dropout": 0.0,
55
+ "dropout_positions": 0.0,
56
+ "layerdrop": 0.0,
57
+ "activation_dropout": 0.0,
58
+ "attention_dropout": 0.0,
59
+ "max_position_embeddings": 5000,
60
+ "scale_input": False,
61
+ "initializer_range": 0.02,
62
+ }
63
+
64
+ encoder_config: dict | PreTrainedConfig | None = None
65
+ vocab_size: int = 16384
66
+ hidden_size: int = 1024
67
+ num_hidden_layers: int = 8
68
+ num_attention_heads: int = 8
69
+ num_key_value_heads: int | None = None
70
+ intermediate_size: int = 4096
71
+ hidden_act: str = "relu"
72
+ max_position_embeddings: int = 1024
73
+ pad_token_id: int | None = 2
74
+ eos_token_id: int | None = 3
75
+ bos_token_id: int | None = 4
76
+ is_encoder_decoder: bool = True
77
+ initializer_range: float = 0.02
78
+ attention_dropout: float | int = 0.0
79
+ attention_bias: bool = True
80
+ decoder_start_token_id: int | None = None
81
+ tie_word_embeddings: bool = False
82
+ head_dim: int | None = None
83
+
84
+ def __post_init__(self, **kwargs):
85
+ if self.head_dim is None:
86
+ self.head_dim = self.hidden_size // self.num_attention_heads
87
+ if self.num_key_value_heads is None:
88
+ self.num_key_value_heads = self.num_attention_heads
89
+
90
+ if isinstance(self.encoder_config, dict):
91
+ self.encoder_config["model_type"] = self.encoder_config.get("model_type", "parakeet_encoder")
92
+ self.encoder_config = CONFIG_MAPPING[self.encoder_config["model_type"]](
93
+ **{**self._default_encoder_config_kwargs, **self.encoder_config}
94
+ )
95
+ elif self.encoder_config is None:
96
+ self.encoder_config = CONFIG_MAPPING["parakeet_encoder"](**self._default_encoder_config_kwargs)
97
+
98
+ super().__post_init__(**kwargs)
99
+
100
+
101
+ __all__ = ["CohereAsrConfig"]
third_party/transformers/src/transformers/models/cohere_asr/feature_extraction_cohere_asr.py ADDED
@@ -0,0 +1,374 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
15
+ import numpy as np
16
+ import torch
17
+
18
+ from ...feature_extraction_sequence_utils import SequenceFeatureExtractor
19
+ from ...feature_extraction_utils import BatchFeature
20
+ from ...utils import TensorType, is_librosa_available, logging
21
+ from ...utils.import_utils import requires
22
+
23
+
24
+ if is_librosa_available():
25
+ import librosa
26
+
27
+
28
+ EPSILON = 1e-5
29
+ LOG_ZERO_GUARD_VALUE = 2**-24
30
+
31
+
32
+ logger = logging.get_logger(__name__)
33
+
34
+
35
+ @requires(backends=("torch", "librosa"))
36
+ class CohereAsrFeatureExtractor(SequenceFeatureExtractor):
37
+ r"""
38
+ Constructs a CohereAsr feature extractor.
39
+
40
+ This feature extractor inherits from [`~feature_extraction_sequence_utils.SequenceFeatureExtractor`] which contains
41
+ most of the main methods. Users should refer to this superclass for more information regarding those methods.
42
+
43
+ This class extracts mel-filter bank features from raw speech using a custom numpy implementation of the `Short Time
44
+ Fourier Transform` which should match pytorch's `torch.stft` equivalent.
45
+
46
+ Args:
47
+ feature_size (`int`, *optional*, defaults to 128):
48
+ The feature dimension of the extracted features.
49
+ sampling_rate (`int`, *optional*, defaults to 16000):
50
+ The sampling rate at which the audio files should be digitalized expressed in hertz (Hz).
51
+ hop_length (`int`, *optional*, defaults to 160):
52
+ Length of the overlapping windows for the STFT used to obtain the Mel Frequency coefficients.
53
+ n_fft (`int`, *optional*, defaults to 512):
54
+ Size of the Fourier transform.
55
+ win_length (`int`, *optional*, defaults to 400):
56
+ The window length for the STFT computation.
57
+ preemphasis (`float`, *optional*, defaults to 0.97):
58
+ A preemphasis filter coefficient. 0.0 means no preemphasis filter.
59
+ padding_value (`float`, *optional*, defaults to 0.0):
60
+ Padding value used to pad the audio. Should correspond to silences.
61
+ dither (`float`, *optional*, defaults to 1e-05):
62
+ Amount of deterministic dither noise to add before feature extraction. Each sample is seeded by its
63
+ valid waveform length so that dither is batch-composition invariant. Set to 0.0 to disable.
64
+ max_audio_clip_s (`float`, *optional*, defaults to 35.0):
65
+ Maximum duration in seconds for a single audio chunk. Audio longer than
66
+ `max_audio_clip_s - overlap_chunk_second` is split at energy-based boundaries.
67
+ overlap_chunk_second (`float`, *optional*, defaults to 5.0):
68
+ Size in seconds of the boundary search window used when splitting long audio. This is not actual
69
+ overlap between chunks — it defines how far back from the chunk boundary to search for a quiet
70
+ split point.
71
+ min_energy_window_samples (`int`, *optional*, defaults to 1600):
72
+ Size in samples of the sliding window used to find the quietest point when splitting audio chunks.
73
+ """
74
+
75
+ model_input_names = ["input_features", "attention_mask"]
76
+
77
+ def __init__(
78
+ self,
79
+ feature_size=128,
80
+ sampling_rate=16000,
81
+ hop_length=160,
82
+ n_fft=512,
83
+ win_length=400,
84
+ preemphasis=0.97,
85
+ padding_value=0.0,
86
+ dither=1e-5,
87
+ max_audio_clip_s=35.0,
88
+ overlap_chunk_second=5.0,
89
+ min_energy_window_samples=1600,
90
+ **kwargs,
91
+ ):
92
+ super().__init__(feature_size=feature_size, sampling_rate=sampling_rate, padding_value=padding_value, **kwargs)
93
+
94
+ self.hop_length = hop_length
95
+ self.n_fft = n_fft
96
+ self.win_length = win_length
97
+ self.preemphasis = preemphasis
98
+ self.dither = dither
99
+ self.max_audio_clip_s = max_audio_clip_s
100
+ self.overlap_chunk_second = overlap_chunk_second
101
+ self.min_energy_window_samples = min_energy_window_samples
102
+
103
+ # TODO: @eustlb, for now we use librosa to compute the mel filters
104
+ # indeed mel_filter_bank uses np.float64 (while librosa uses np.float32), giving numerical differences
105
+ mel_filters = librosa.filters.mel(
106
+ sr=sampling_rate, n_fft=n_fft, n_mels=feature_size, fmin=0.0, fmax=sampling_rate / 2, norm="slaney"
107
+ )
108
+ self.mel_filters = torch.from_numpy(mel_filters).to(torch.float32)
109
+
110
+ def _find_split_point_energy(self, waveform: torch.Tensor, start_idx: int, end_idx: int) -> int:
111
+ segment = waveform[start_idx:end_idx]
112
+ if segment.shape[0] <= self.min_energy_window_samples:
113
+ return (start_idx + end_idx) // 2
114
+
115
+ min_energy = float("inf")
116
+ quietest_idx = start_idx
117
+ upper = segment.shape[0] - self.min_energy_window_samples
118
+ for i in range(0, upper, self.min_energy_window_samples):
119
+ window = segment[i : i + self.min_energy_window_samples]
120
+ energy = torch.sqrt(torch.mean(window * window)).item()
121
+ if energy < min_energy:
122
+ min_energy = energy
123
+ quietest_idx = start_idx + i
124
+ return quietest_idx
125
+
126
+ def _split_audio_chunks_energy(self, waveform: torch.Tensor) -> list[torch.Tensor]:
127
+ chunk_size = max(1, int(round(self.max_audio_clip_s * self.sampling_rate)))
128
+ boundary_context_size = max(1, int(round(self.overlap_chunk_second * self.sampling_rate)))
129
+ total_samples = waveform.shape[0]
130
+
131
+ if total_samples <= chunk_size:
132
+ return [waveform]
133
+
134
+ chunks_meta: list[tuple[int, int]] = []
135
+ idx = 0
136
+ while idx < total_samples:
137
+ if idx + chunk_size >= total_samples:
138
+ chunks_meta.append((idx, total_samples))
139
+ break
140
+
141
+ search_start = max(idx, idx + chunk_size - boundary_context_size)
142
+ search_end = min(idx + chunk_size, total_samples)
143
+ if search_end <= search_start:
144
+ split_point = idx + chunk_size
145
+ else:
146
+ split_point = self._find_split_point_energy(waveform, search_start, search_end)
147
+
148
+ split_point = max(idx + 1, min(split_point, total_samples))
149
+ chunks_meta.append((idx, split_point))
150
+ idx = split_point
151
+
152
+ return [waveform[start:end] for start, end in chunks_meta if end > start]
153
+
154
+ def _apply_dither(self, waveform: torch.Tensor, audio_lengths: torch.Tensor) -> torch.Tensor:
155
+ if self.dither <= 0:
156
+ return waveform
157
+ generator = torch.Generator(device=waveform.device)
158
+ for i in range(waveform.shape[0]):
159
+ valid_samples = min(int(audio_lengths[i].item()), waveform.shape[1])
160
+ if valid_samples <= 0:
161
+ continue
162
+ generator.manual_seed(valid_samples)
163
+ noise = torch.randn(valid_samples, dtype=waveform.dtype, device=waveform.device, generator=generator)
164
+ waveform[i, :valid_samples] += self.dither * noise
165
+ return waveform
166
+
167
+ def _torch_extract_fbank_features(self, waveform, device="cpu"):
168
+ # spectrogram
169
+ window = torch.hann_window(self.win_length, periodic=False, device=device)
170
+ stft = torch.stft(
171
+ waveform,
172
+ self.n_fft,
173
+ hop_length=self.hop_length,
174
+ win_length=self.win_length,
175
+ window=window,
176
+ return_complex=True,
177
+ pad_mode="constant",
178
+ )
179
+ # Let's match original implementation
180
+ magnitudes = torch.view_as_real(stft)
181
+ magnitudes = torch.sqrt(magnitudes.pow(2).sum(-1))
182
+ magnitudes = magnitudes.pow(2)
183
+
184
+ # log mel spectrogram
185
+ mel_filters = self.mel_filters.to(device)
186
+ mel_spec = mel_filters @ magnitudes
187
+ mel_spec = torch.log(mel_spec + LOG_ZERO_GUARD_VALUE)
188
+
189
+ # (batch_size, num_mel_filters, num_frames) -> (batch_size, num_frames, num_mel_filters)
190
+ mel_spec = mel_spec.permute(0, 2, 1)
191
+
192
+ return mel_spec
193
+
194
+ def __call__(
195
+ self,
196
+ raw_speech: np.ndarray | list[float] | list[np.ndarray] | list[list[float]],
197
+ truncation: bool = False,
198
+ pad_to_multiple_of: int | None = None,
199
+ return_tensors: str | TensorType | None = None,
200
+ return_attention_mask: bool | None = None,
201
+ padding: str | None = "longest",
202
+ max_length: int | None = None,
203
+ sampling_rate: int | None = None,
204
+ do_normalize: bool | None = None,
205
+ device: str | None = "cpu",
206
+ return_token_timestamps: bool | None = None,
207
+ **kwargs,
208
+ ) -> BatchFeature:
209
+ """
210
+ Main method to featurize and prepare for the model one or several sequence(s). Implementation uses PyTorch for
211
+ the STFT computation if available, otherwise a slower NumPy based one.
212
+
213
+ Args:
214
+ raw_speech (`np.ndarray`, `list[float]`, `list[np.ndarray]`, `list[list[float]]`):
215
+ The sequence or batch of sequences to be padded. Each sequence can be a numpy array, a list of float
216
+ values, a list of numpy arrays or a list of list of float values. Must be mono channel audio, not
217
+ stereo, i.e. single float per timestep.
218
+ truncation (`bool`, *optional*, default to `True`):
219
+ Activates truncation to cut input sequences longer than *max_length* to *max_length*.
220
+ pad_to_multiple_of (`int`, *optional*, defaults to None):
221
+ If set will pad the sequence to a multiple of the provided value.
222
+
223
+ This is especially useful to enable the use of Tensor Cores on NVIDIA hardware with compute capability
224
+ `>= 7.5` (Volta), or on TPUs which benefit from having sequence lengths be a multiple of 128.
225
+ return_attention_mask (`bool`, *optional*):
226
+ Whether to return the attention mask. If left to the default, will return the attention mask according
227
+ to the specific feature_extractor's default.
228
+
229
+ [What are attention masks?](../glossary#attention-mask)
230
+
231
+ <Tip>
232
+
233
+ For CohereAsr models, `attention_mask` should always be passed for batched inference, to avoid subtle
234
+ bugs.
235
+
236
+ </Tip>
237
+
238
+ return_tensors (`str` or [`~utils.TensorType`], *optional*):
239
+ If set, will return tensors instead of list of python integers. Acceptable values are:
240
+
241
+ - `'tf'`: Return TensorFlow `tf.constant` objects.
242
+ - `'pt'`: Return PyTorch `torch.Tensor` objects.
243
+ - `'np'`: Return Numpy `np.ndarray` objects.
244
+ sampling_rate (`int`, *optional*):
245
+ The sampling rate at which the `raw_speech` input was sampled. It is strongly recommended to pass
246
+ `sampling_rate` at the forward call to prevent silent errors and allow automatic speech recognition
247
+ pipeline.
248
+ padding_value (`float`, *optional*, defaults to 0.0):
249
+ The value that is used to fill the padding values / vectors.
250
+ do_normalize (`bool`, *optional*, defaults to `False`):
251
+ Whether or not to zero-mean unit-variance normalize the input. Normalizing can help to significantly
252
+ improve the performance of the model.
253
+ device (`str`, *optional*, defaults to `'cpu'`):
254
+ Specifies the device for computation of the log-mel spectrogram of audio signals in the
255
+ `_torch_extract_fbank_features` method. (e.g., "cpu", "cuda")
256
+ return_token_timestamps (`bool`, *optional*, defaults to `None`):
257
+ Deprecated. Use `return_attention_mask` instead from which the number of frames can be inferred.
258
+
259
+ Whether or not to return the number of frames of the input raw_speech.
260
+ These num_frames can be used by the model to compute word level timestamps.
261
+ """
262
+ if sampling_rate is not None:
263
+ if sampling_rate != self.sampling_rate:
264
+ raise ValueError(
265
+ f"The model corresponding to this feature extractor: {self.__class__.__name__} was trained using a"
266
+ f" sampling rate of {self.sampling_rate}. Please make sure that the provided `raw_speech` input"
267
+ f" was sampled with {self.sampling_rate} and not {sampling_rate}."
268
+ )
269
+ else:
270
+ logger.warning(
271
+ f"It is strongly recommended to pass the `sampling_rate` argument to `{self.__class__.__name__}()`. "
272
+ "Failing to do so can result in silent errors that might be hard to debug."
273
+ )
274
+
275
+ # Convert to torch tensor
276
+ if isinstance(raw_speech, np.ndarray):
277
+ raw_speech = torch.tensor(raw_speech)
278
+ elif isinstance(raw_speech, (list, tuple)) and isinstance(raw_speech[0], np.ndarray):
279
+ raw_speech = [torch.tensor(speech) for speech in raw_speech]
280
+
281
+ is_batched_torch = isinstance(raw_speech, torch.Tensor) and len(raw_speech.shape) > 1
282
+ if is_batched_torch and len(raw_speech.shape) > 2:
283
+ logger.warning(
284
+ f"Only mono-channel audio is supported for input to {self.__class__.__name__}. "
285
+ "We will take the mean of the channels to convert to mono."
286
+ )
287
+ raw_speech = raw_speech.mean(-1)
288
+
289
+ is_batched_sequence = isinstance(raw_speech, (list, tuple))
290
+ if is_batched_sequence:
291
+ for speech in raw_speech:
292
+ if len(speech.shape) > 1:
293
+ logger.warning(
294
+ f"Only mono-channel audio is supported for input to {self.__class__.__name__}. "
295
+ "We will take the mean of the channels to convert to mono."
296
+ )
297
+ speech = speech.mean(-1)
298
+
299
+ if is_batched_torch or is_batched_sequence:
300
+ raw_speech = [speech.to(torch.float32) for speech in raw_speech]
301
+ else:
302
+ raw_speech = [raw_speech.to(torch.float32)]
303
+
304
+ # Chunk long audio at energy-based boundaries
305
+ fast_path_threshold_s = max(0.0, self.max_audio_clip_s - self.overlap_chunk_second)
306
+ audio_chunk_index: list[tuple[int, int | None]] = []
307
+ chunked_speech: list[torch.Tensor] = []
308
+ for sample_idx, speech in enumerate(raw_speech):
309
+ duration_s = speech.shape[0] / self.sampling_rate
310
+ if duration_s <= fast_path_threshold_s:
311
+ chunked_speech.append(speech)
312
+ audio_chunk_index.append((sample_idx, None))
313
+ else:
314
+ chunks = self._split_audio_chunks_energy(speech)
315
+ for chunk_idx, chunk in enumerate(chunks):
316
+ chunked_speech.append(chunk)
317
+ audio_chunk_index.append((sample_idx, chunk_idx))
318
+
319
+ raw_speech = [speech[:, None] for speech in chunked_speech]
320
+
321
+ audio_lengths = [len(speech) for speech in raw_speech]
322
+ batched_speech = BatchFeature({"input_features": raw_speech, "audio_lengths": audio_lengths})
323
+
324
+ padded_inputs = self.pad(
325
+ batched_speech,
326
+ padding=padding,
327
+ max_length=max_length,
328
+ truncation=truncation,
329
+ pad_to_multiple_of=pad_to_multiple_of,
330
+ return_tensors="pt",
331
+ )
332
+ input_features = padded_inputs.input_features.squeeze(-1)
333
+
334
+ # dithering
335
+ input_features = self._apply_dither(input_features, padded_inputs.audio_lengths)
336
+
337
+ # preemphasis
338
+ if self.preemphasis is not None:
339
+ timemask = torch.arange(input_features.shape[1], device=input_features.device).unsqueeze(
340
+ 0
341
+ ) < padded_inputs.audio_lengths.unsqueeze(1)
342
+ input_features = torch.cat(
343
+ [input_features[:, :1], input_features[:, 1:] - self.preemphasis * input_features[:, :-1]], dim=1
344
+ )
345
+ input_features = input_features.masked_fill(~timemask, 0.0)
346
+
347
+ input_features = self._torch_extract_fbank_features(input_features, device)
348
+ features_lengths = torch.floor_divide(
349
+ padded_inputs.audio_lengths + self.n_fft // 2 * 2 - self.n_fft, self.hop_length
350
+ )
351
+ attention_mask = torch.arange(input_features.shape[1], device=device)[None, :] < features_lengths[:, None]
352
+
353
+ # normalize mel features, ignoring padding
354
+ mask = attention_mask.unsqueeze(-1)
355
+ input_features_masked = input_features * mask
356
+ mean = input_features_masked.sum(dim=1) / features_lengths.unsqueeze(-1)
357
+ mean = mean.unsqueeze(1)
358
+ variance = ((input_features_masked - mean) ** 2 * mask).sum(dim=1) / (features_lengths - 1).unsqueeze(-1)
359
+ std = torch.sqrt(variance).unsqueeze(1)
360
+ input_features = (input_features - mean) / (std + EPSILON)
361
+ input_features *= mask
362
+
363
+ result = BatchFeature(
364
+ data={
365
+ "input_features": input_features,
366
+ "attention_mask": attention_mask,
367
+ },
368
+ tensor_type=return_tensors,
369
+ )
370
+ result["audio_chunk_index"] = audio_chunk_index
371
+ return result
372
+
373
+
374
+ __all__ = ["CohereAsrFeatureExtractor"]
third_party/transformers/src/transformers/models/cohere_asr/modeling_cohere_asr.py ADDED
@@ -0,0 +1,658 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/cohere_asr/modular_cohere_asr.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_cohere_asr.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2026 the HuggingFace Team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ from collections.abc import Callable
22
+
23
+ import torch
24
+ import torch.nn as nn
25
+
26
+ from ...activations import ACT2FN
27
+ from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
28
+ from ...generation import GenerationMixin
29
+ from ...masking_utils import create_bidirectional_mask, create_causal_mask
30
+ from ...modeling_layers import GradientCheckpointingLayer
31
+ from ...modeling_outputs import (
32
+ BaseModelOutput,
33
+ BaseModelOutputWithPastAndCrossAttentions,
34
+ Seq2SeqLMOutput,
35
+ Seq2SeqModelOutput,
36
+ )
37
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
38
+ from ...processing_utils import Unpack
39
+ from ...utils import TransformersKwargs, auto_docstring
40
+ from ...utils.generic import can_return_tuple, merge_with_config_defaults
41
+ from ...utils.output_capturing import OutputRecorder, capture_outputs
42
+ from ..auto.modeling_auto import AutoModel
43
+ from .configuration_cohere_asr import CohereAsrConfig
44
+
45
+
46
+ class CohereAsrDecoderMLP(nn.Module):
47
+ def __init__(self, config):
48
+ super().__init__()
49
+ self.config = config
50
+ self.activation_fn = ACT2FN[config.hidden_act]
51
+ self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size)
52
+ self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size)
53
+
54
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
55
+ hidden_states = self.fc1(hidden_states)
56
+ hidden_states = self.activation_fn(hidden_states)
57
+ hidden_states = self.fc2(hidden_states)
58
+ return hidden_states
59
+
60
+
61
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
62
+ """
63
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
64
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
65
+ """
66
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
67
+ if n_rep == 1:
68
+ return hidden_states
69
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
70
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
71
+
72
+
73
+ def eager_attention_forward(
74
+ module: nn.Module,
75
+ query: torch.Tensor,
76
+ key: torch.Tensor,
77
+ value: torch.Tensor,
78
+ attention_mask: torch.Tensor | None,
79
+ scaling: float,
80
+ dropout: float = 0.0,
81
+ **kwargs: Unpack[TransformersKwargs],
82
+ ):
83
+ key_states = repeat_kv(key, module.num_key_value_groups)
84
+ value_states = repeat_kv(value, module.num_key_value_groups)
85
+
86
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
87
+ if attention_mask is not None:
88
+ attn_weights = attn_weights + attention_mask
89
+
90
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
91
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
92
+ attn_output = torch.matmul(attn_weights, value_states)
93
+ attn_output = attn_output.transpose(1, 2).contiguous()
94
+
95
+ return attn_output, attn_weights
96
+
97
+
98
+ # Modular automatically inherits RoPE, hence no inheritance for now
99
+ class CohereAsrSelfAttention(nn.Module):
100
+ def __init__(self, config: CohereAsrConfig, layer_idx: int):
101
+ super().__init__()
102
+ self.config = config
103
+ self.layer_idx = layer_idx
104
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
105
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
106
+ self.scaling = self.head_dim**-0.5
107
+ self.attention_dropout = config.attention_dropout
108
+ self.is_causal = True
109
+
110
+ self.q_proj = nn.Linear(
111
+ config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
112
+ )
113
+ self.k_proj = nn.Linear(
114
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
115
+ )
116
+ self.v_proj = nn.Linear(
117
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
118
+ )
119
+ self.o_proj = nn.Linear(
120
+ config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
121
+ )
122
+
123
+ def forward(
124
+ self,
125
+ hidden_states: torch.Tensor,
126
+ attention_mask: torch.Tensor,
127
+ past_key_values: Cache | None = None,
128
+ **kwargs,
129
+ ):
130
+ input_shape = hidden_states.shape[:-1]
131
+ hidden_shape = (*input_shape, -1, self.head_dim)
132
+
133
+ query_states = self.q_proj(hidden_states)
134
+ key_states = self.k_proj(hidden_states)
135
+ value_states = self.v_proj(hidden_states)
136
+
137
+ query_states = query_states.view(hidden_shape).transpose(1, 2)
138
+ key_states = key_states.view(hidden_shape).transpose(1, 2)
139
+ value_states = value_states.view(hidden_shape).transpose(1, 2)
140
+
141
+ if past_key_values is not None:
142
+ past_key_values = past_key_values.self_attention_cache
143
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
144
+
145
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
146
+ self.config._attn_implementation, eager_attention_forward
147
+ )
148
+
149
+ attn_output, attn_weights = attention_interface(
150
+ self,
151
+ query_states,
152
+ key_states,
153
+ value_states,
154
+ attention_mask,
155
+ dropout=0.0 if not self.training else self.attention_dropout,
156
+ scaling=self.scaling,
157
+ **kwargs,
158
+ )
159
+
160
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
161
+ attn_output = self.o_proj(attn_output)
162
+ return attn_output, attn_weights
163
+
164
+
165
+ # Modular automatically inherits RoPE, hence no inheritance for now
166
+ class CohereAsrCrossAttention(nn.Module):
167
+ def __init__(self, config: CohereAsrConfig, layer_idx: int):
168
+ super().__init__()
169
+ self.config = config
170
+ self.layer_idx = layer_idx
171
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
172
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
173
+ self.scaling = self.head_dim**-0.5
174
+ self.attention_dropout = config.attention_dropout
175
+ self.is_causal = False
176
+
177
+ self.q_proj = nn.Linear(
178
+ config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
179
+ )
180
+ self.k_proj = nn.Linear(
181
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
182
+ )
183
+ self.v_proj = nn.Linear(
184
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
185
+ )
186
+ self.o_proj = nn.Linear(
187
+ config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
188
+ )
189
+
190
+ def forward(
191
+ self,
192
+ hidden_states: torch.Tensor,
193
+ encoder_hidden_states: torch.Tensor | None = None,
194
+ attention_mask: torch.Tensor | None = None,
195
+ past_key_values: Cache | None = None,
196
+ **kwargs: Unpack[TransformersKwargs],
197
+ ):
198
+ # determine input shapes
199
+ bsz, tgt_len = hidden_states.shape[:-1]
200
+ src_len = encoder_hidden_states.shape[1]
201
+
202
+ q_input_shape = (bsz, tgt_len, -1, self.head_dim)
203
+ kv_input_shape = (bsz, src_len, -1, self.head_dim)
204
+
205
+ # get query proj
206
+ query_states = self.q_proj(hidden_states).view(*q_input_shape).transpose(1, 2)
207
+
208
+ is_updated = past_key_values.is_updated.get(self.layer_idx) if past_key_values is not None else False
209
+ if past_key_values is not None and is_updated:
210
+ # reuse k,v, cross_attentions
211
+ key_states = past_key_values.cross_attention_cache.layers[self.layer_idx].keys
212
+ value_states = past_key_values.cross_attention_cache.layers[self.layer_idx].values
213
+ else:
214
+ key_states = self.k_proj(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2)
215
+ value_states = self.v_proj(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2)
216
+
217
+ if past_key_values is not None:
218
+ # save all states to the cache
219
+ key_states, value_states = past_key_values.cross_attention_cache.update(
220
+ key_states, value_states, self.layer_idx
221
+ )
222
+ # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
223
+ past_key_values.is_updated[self.layer_idx] = True
224
+
225
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
226
+ self.config._attn_implementation, eager_attention_forward
227
+ )
228
+
229
+ attn_output, attn_weights = attention_interface(
230
+ self,
231
+ query_states,
232
+ key_states,
233
+ value_states,
234
+ attention_mask,
235
+ dropout=0.0 if not self.training else self.attention_dropout,
236
+ scaling=self.scaling,
237
+ **kwargs,
238
+ )
239
+ attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous()
240
+ attn_output = self.o_proj(attn_output)
241
+ return attn_output, attn_weights
242
+
243
+
244
+ class CohereAsrDecoderLayer(GradientCheckpointingLayer):
245
+ def __init__(self, config, layer_idx=None):
246
+ super().__init__()
247
+ self.self_attn = CohereAsrSelfAttention(config=config, layer_idx=layer_idx)
248
+ self.encoder_attn = CohereAsrCrossAttention(config=config, layer_idx=layer_idx)
249
+
250
+ self.mlp = CohereAsrDecoderMLP(config)
251
+ self.input_layernorm = nn.LayerNorm(config.hidden_size)
252
+ self.post_attention_layernorm = nn.LayerNorm(config.hidden_size)
253
+ self.final_layernorm = nn.LayerNorm(config.hidden_size)
254
+
255
+ def forward(
256
+ self,
257
+ hidden_states: torch.Tensor,
258
+ attention_mask: torch.Tensor | None = None,
259
+ encoder_hidden_states: torch.Tensor | None = None,
260
+ encoder_attention_mask: torch.Tensor | None = None,
261
+ position_ids: torch.LongTensor | None = None,
262
+ encoder_position_ids: torch.LongTensor | None = None,
263
+ past_key_values: Cache | None = None,
264
+ **kwargs: Unpack[TransformersKwargs],
265
+ ) -> tuple[torch.FloatTensor, tuple[torch.FloatTensor, torch.FloatTensor] | None]:
266
+ residual = hidden_states
267
+ hidden_states = self.input_layernorm(hidden_states)
268
+
269
+ hidden_states, _ = self.self_attn(
270
+ hidden_states=hidden_states,
271
+ attention_mask=attention_mask,
272
+ position_ids=position_ids,
273
+ past_key_values=past_key_values,
274
+ **kwargs,
275
+ )
276
+ hidden_states = residual + hidden_states
277
+
278
+ if encoder_hidden_states is not None:
279
+ residual = hidden_states
280
+ hidden_states = self.post_attention_layernorm(hidden_states)
281
+ hidden_states, _ = self.encoder_attn(
282
+ hidden_states=hidden_states,
283
+ encoder_hidden_states=encoder_hidden_states,
284
+ attention_mask=encoder_attention_mask,
285
+ past_key_values=past_key_values,
286
+ )
287
+ hidden_states = residual + hidden_states
288
+
289
+ residual = hidden_states
290
+ hidden_states = self.final_layernorm(hidden_states)
291
+ hidden_states = self.mlp(hidden_states)
292
+ hidden_states = residual + hidden_states
293
+ return hidden_states
294
+
295
+
296
+ @auto_docstring
297
+ class CohereAsrPreTrainedModel(PreTrainedModel):
298
+ config: CohereAsrConfig
299
+ base_model_prefix = "model"
300
+ main_input_name = "input_features"
301
+ input_modalities = "audio"
302
+ supports_gradient_checkpointing = True
303
+ _no_split_modules = ["CohereAsrEncoderLayer", "CohereAsrDecoderLayer"]
304
+ _supports_flash_attn = True
305
+ _supports_sdpa = True
306
+
307
+ _can_compile_fullgraph = True
308
+ _keys_to_ignore_on_load_unexpected = [r"preprocessor\.featurizer\..*"]
309
+ # TODO arthur, how do we separate when it cross / self coming from different layer?
310
+
311
+ def _get_feat_extract_output_lengths(self, input_lengths: torch.LongTensor):
312
+ """
313
+ Computes the output length of the convolutional layers
314
+ """
315
+ output_conv1_length = int((input_lengths - 127) / 64 + 1)
316
+ output_conv2_length = int((output_conv1_length - 7) / 3 + 1)
317
+ output_conv3_length = int((output_conv2_length - 3) / 2 + 1)
318
+
319
+ return output_conv3_length
320
+
321
+
322
+ @auto_docstring
323
+ class CohereAsrDecoder(CohereAsrPreTrainedModel):
324
+ main_input_name = "input_ids"
325
+ _can_record_outputs = {
326
+ "attentions": OutputRecorder(CohereAsrSelfAttention, index=1, layer_name="self_attn"),
327
+ "hidden_states": CohereAsrDecoderLayer,
328
+ "cross_attentions": OutputRecorder(CohereAsrCrossAttention, index=1, layer_name="encoder_attn"),
329
+ }
330
+
331
+ def __init__(self, config):
332
+ super().__init__(config)
333
+ self.padding_idx = config.pad_token_id
334
+ self.vocab_size = config.vocab_size
335
+
336
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
337
+ self.layers = nn.ModuleList([CohereAsrDecoderLayer(config, idx) for idx in range(config.num_hidden_layers)])
338
+ self.norm = nn.LayerNorm(config.hidden_size)
339
+ self.gradient_checkpointing = False
340
+ self.pos_emb = nn.Embedding(config.max_position_embeddings, config.hidden_size)
341
+ self.embedding_layernorm = nn.LayerNorm(config.hidden_size)
342
+ self.proj = nn.Linear(config.encoder_config.hidden_size, config.hidden_size, bias=True)
343
+
344
+ # Initialize weights and apply final processing
345
+ self.post_init()
346
+
347
+ @merge_with_config_defaults
348
+ @capture_outputs
349
+ def forward(
350
+ self,
351
+ input_ids: torch.LongTensor | None = None,
352
+ attention_mask: torch.Tensor | None = None,
353
+ position_ids: torch.LongTensor | None = None,
354
+ past_key_values: Cache | None = None,
355
+ inputs_embeds: torch.FloatTensor | None = None,
356
+ use_cache: bool | None = None,
357
+ encoder_hidden_states: torch.FloatTensor | None = None,
358
+ encoder_attention_mask: torch.Tensor | None = None,
359
+ **kwargs: Unpack[TransformersKwargs],
360
+ ) -> tuple | BaseModelOutputWithPastAndCrossAttentions:
361
+ r"""
362
+ encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*):
363
+ Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention
364
+ of the decoder.
365
+ encoder_attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
366
+ Mask to avoid performing attention on padding indices in `encoder_hidden_states`. Mask values selected in `[0, 1]`:
367
+ - 1 for tokens that are **not masked**,
368
+ - 0 for tokens that are **masked**.
369
+ [What are attention masks?](../glossary#attention-mask)
370
+ """
371
+ encoder_hidden_states = self.proj(encoder_hidden_states)
372
+ if (input_ids is None) ^ (inputs_embeds is not None):
373
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
374
+
375
+ if inputs_embeds is None:
376
+ inputs_embeds = self.embed_tokens(input_ids)
377
+
378
+ if use_cache and past_key_values is None:
379
+ past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config))
380
+
381
+ if position_ids is None:
382
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
383
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
384
+ position_ids = position_ids.unsqueeze(0)
385
+
386
+ # Fixed sinusoidal position embedding added to token embeddings, then layernorm
387
+ pos_emb = self.pos_emb(position_ids.squeeze(0))
388
+ inputs_embeds = self.embedding_layernorm(inputs_embeds + pos_emb)
389
+
390
+ causal_mask = create_causal_mask(
391
+ config=self.config,
392
+ inputs_embeds=inputs_embeds,
393
+ attention_mask=attention_mask,
394
+ past_key_values=past_key_values,
395
+ position_ids=position_ids,
396
+ )
397
+ encoder_attention_mask = create_bidirectional_mask(
398
+ config=self.config,
399
+ inputs_embeds=inputs_embeds,
400
+ attention_mask=encoder_attention_mask,
401
+ encoder_hidden_states=encoder_hidden_states,
402
+ )
403
+
404
+ hidden_states = inputs_embeds
405
+ for decoder_layer in self.layers:
406
+ hidden_states = decoder_layer(
407
+ hidden_states,
408
+ causal_mask,
409
+ encoder_hidden_states, # as a positional argument for gradient checkpointing
410
+ encoder_attention_mask=encoder_attention_mask,
411
+ position_ids=position_ids,
412
+ past_key_values=past_key_values,
413
+ **kwargs,
414
+ )
415
+
416
+ hidden_states = self.norm(hidden_states)
417
+
418
+ return BaseModelOutputWithPastAndCrossAttentions(
419
+ last_hidden_state=hidden_states,
420
+ past_key_values=past_key_values if use_cache else None,
421
+ )
422
+
423
+
424
+ @auto_docstring
425
+ class CohereAsrModel(CohereAsrPreTrainedModel):
426
+ def __init__(self, config):
427
+ super().__init__(config)
428
+ self.encoder = AutoModel.from_config(config.encoder_config)
429
+ self.decoder = CohereAsrDecoder(config)
430
+ # Initialize weights and apply final processing
431
+ self.post_init()
432
+
433
+ def get_input_embeddings(self):
434
+ return self.decoder.embed_tokens
435
+
436
+ def set_input_embeddings(self, value):
437
+ self.decoder.embed_tokens = value
438
+
439
+ def freeze_encoder(self):
440
+ """
441
+ Calling this function will disable the gradient computation for the CohereAsr encoder so that its parameters will
442
+ not be updated during training.
443
+ """
444
+ self.encoder._freeze_parameters()
445
+
446
+ def _mask_input_features(self):
447
+ """
448
+ Masks extracted features along time axis and/or along feature axis according to
449
+ [SpecAugment](https://huggingface.co/papers/1904.08779).
450
+ """
451
+ raise AttributeError("Not needed for CohereAsr")
452
+
453
+ @can_return_tuple
454
+ @auto_docstring
455
+ def forward(
456
+ self,
457
+ input_features: torch.FloatTensor | None = None,
458
+ attention_mask: torch.LongTensor | None = None,
459
+ decoder_input_ids: torch.LongTensor | None = None,
460
+ decoder_attention_mask: torch.LongTensor | None = None,
461
+ encoder_outputs: tuple[tuple[torch.FloatTensor]] | None = None,
462
+ past_key_values: EncoderDecoderCache | None = None,
463
+ decoder_inputs_embeds: tuple[torch.FloatTensor] | None = None,
464
+ decoder_position_ids: tuple[torch.LongTensor] | None = None,
465
+ use_cache: bool | None = None,
466
+ **kwargs: Unpack[TransformersKwargs],
467
+ ) -> Seq2SeqModelOutput:
468
+ r"""
469
+ input_features (`torch.FloatTensor` of shape `(batch_size, audio_length)`):
470
+ Float values of the raw speech waveform. Raw speech waveform can be
471
+ obtained by loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a
472
+ `numpy.ndarray` or a `torch.Tensor`, *e.g.* via the torchcodec library (`pip install torchcodec`) or
473
+ the soundfile library (`pip install soundfile`). To prepare the array into
474
+ `input_features`, the [`AutoFeatureExtractor`] should be used for padding
475
+ and conversion into a tensor of type `torch.FloatTensor`.
476
+ decoder_position_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`):
477
+ Indices of positions of each input sequence tokens in the position embeddings.
478
+ Used to calculate the position embeddings up to `config.decoder_config.max_position_embeddings`
479
+
480
+ Example:
481
+
482
+ ```python
483
+ >>> import torch
484
+ >>> from transformers import AutoFeatureExtractor, CohereAsrModel
485
+ >>> from datasets import load_dataset
486
+
487
+ >>> model = CohereAsrModel.from_pretrained("UsefulSensors/cohere_asr-tiny")
488
+ >>> feature_extractor = AutoFeatureExtractor.from_pretrained("UsefulSensors/cohere_asr-tiny")
489
+ >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation")
490
+ >>> inputs = feature_extractor(ds[0]["audio"]["array"], return_tensors="pt")
491
+ >>> input_features = inputs.input_features
492
+ >>> decoder_input_ids = torch.tensor([[1, 1]]) * model.config.decoder_start_token_id
493
+ >>> last_hidden_state = model(input_features, decoder_input_ids=decoder_input_ids).last_hidden_state
494
+ >>> list(last_hidden_state.shape)
495
+ [1, 2, 288]
496
+ ```
497
+ """
498
+ # Main difference: uses `input_features` instead of `input_values`
499
+ if encoder_outputs is None:
500
+ encoder_outputs: BaseModelOutput = self.encoder(input_features, attention_mask=attention_mask, **kwargs)
501
+
502
+ decoder_outputs: BaseModelOutputWithPastAndCrossAttentions = self.decoder(
503
+ input_ids=decoder_input_ids,
504
+ attention_mask=decoder_attention_mask,
505
+ encoder_hidden_states=encoder_outputs.last_hidden_state,
506
+ encoder_attention_mask=encoder_outputs.attention_mask,
507
+ past_key_values=past_key_values,
508
+ inputs_embeds=decoder_inputs_embeds,
509
+ position_ids=decoder_position_ids,
510
+ use_cache=use_cache,
511
+ **kwargs,
512
+ )
513
+
514
+ return Seq2SeqModelOutput(
515
+ last_hidden_state=decoder_outputs.last_hidden_state,
516
+ past_key_values=decoder_outputs.past_key_values,
517
+ decoder_hidden_states=decoder_outputs.hidden_states,
518
+ decoder_attentions=decoder_outputs.attentions,
519
+ cross_attentions=decoder_outputs.cross_attentions,
520
+ encoder_last_hidden_state=encoder_outputs.last_hidden_state,
521
+ encoder_hidden_states=encoder_outputs.hidden_states,
522
+ encoder_attentions=encoder_outputs.attentions,
523
+ )
524
+
525
+
526
+ def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start_token_id: int):
527
+ """
528
+ Shift input ids one token to the right.
529
+ """
530
+ shifted_input_ids = input_ids.new_zeros(input_ids.shape)
531
+ shifted_input_ids[:, 1:] = input_ids[:, :-1].clone()
532
+ shifted_input_ids[:, 0] = decoder_start_token_id
533
+
534
+ if pad_token_id is None:
535
+ raise ValueError("self.model.config.pad_token_id has to be defined.")
536
+ # replace possible -100 values in labels by `pad_token_id`
537
+ shifted_input_ids.masked_fill_(shifted_input_ids == -100, pad_token_id)
538
+
539
+ return shifted_input_ids
540
+
541
+
542
+ @auto_docstring(
543
+ custom_intro="""
544
+ The CohereAsr Model with a language modeling head. Can be used for automatic speech recognition.
545
+ """
546
+ )
547
+ class CohereAsrForConditionalGeneration(CohereAsrPreTrainedModel, GenerationMixin):
548
+ _tied_weights_keys = {"proj_out.weight": "model.decoder.embed_tokens.weight"}
549
+
550
+ def __init__(self, config):
551
+ super().__init__(config)
552
+ self.model = CohereAsrModel(config)
553
+ self.proj_out = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
554
+
555
+ # Initialize weights and apply final processing
556
+ self.post_init()
557
+
558
+ def get_output_embeddings(self):
559
+ return self.proj_out
560
+
561
+ def set_output_embeddings(self, new_embeddings):
562
+ self.proj_out = new_embeddings
563
+
564
+ def get_input_embeddings(self) -> nn.Module:
565
+ return self.model.get_input_embeddings()
566
+
567
+ @can_return_tuple
568
+ @auto_docstring
569
+ def forward(
570
+ self,
571
+ input_features: torch.FloatTensor | None = None,
572
+ attention_mask: torch.LongTensor | None = None,
573
+ decoder_input_ids: torch.LongTensor | None = None,
574
+ decoder_attention_mask: torch.LongTensor | None = None,
575
+ encoder_outputs: tuple[tuple[torch.FloatTensor]] | None = None,
576
+ past_key_values: EncoderDecoderCache | None = None,
577
+ decoder_inputs_embeds: tuple[torch.FloatTensor] | None = None,
578
+ decoder_position_ids: tuple[torch.LongTensor] | None = None,
579
+ use_cache: bool | None = None,
580
+ labels: torch.LongTensor | None = None,
581
+ **kwargs: Unpack[TransformersKwargs],
582
+ ) -> Seq2SeqLMOutput:
583
+ r"""
584
+ input_features (`torch.FloatTensor` of shape `(batch_size, audio_length)`):
585
+ Float values of the raw speech waveform. Raw speech waveform can be
586
+ obtained by loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a
587
+ `numpy.ndarray` or a `torch.Tensor`, *e.g.* via the torchcodec library (`pip install torchcodec`) or
588
+ the soundfile library (`pip install soundfile`). To prepare the array into
589
+ `input_features`, the [`AutoFeatureExtractor`] should be used for padding
590
+ and conversion into a tensor of type `torch.FloatTensor`.
591
+ decoder_position_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`):
592
+ Indices of positions of each input sequence tokens in the position embeddings.
593
+ Used to calculate the position embeddings up to `config.decoder_config.max_position_embeddings`
594
+
595
+ Example:
596
+
597
+ ```python
598
+ >>> import torch
599
+ >>> from transformers import AutoProcessor, CohereAsrForConditionalGeneration
600
+ >>> from datasets import load_dataset
601
+
602
+ >>> processor = AutoProcessor.from_pretrained("UsefulSensors/cohere_asr-tiny")
603
+ >>> model = CohereAsrForConditionalGeneration.from_pretrained("UsefulSensors/cohere_asr-tiny")
604
+
605
+ >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation")
606
+
607
+ >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="pt")
608
+ >>> input_features = inputs.input_features
609
+
610
+ >>> generated_ids = model.generate(input_features, max_new_tokens=100)
611
+
612
+ >>> transcription = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
613
+ >>> transcription
614
+ 'Mr. Quilter is the apostle of the middle classes, and we are glad to welcome his gospel.'
615
+ ```"""
616
+ # Main difference: uses `input_features` instead of `input_values`
617
+ if labels is not None:
618
+ if decoder_input_ids is None and decoder_inputs_embeds is None:
619
+ decoder_input_ids = shift_tokens_right(
620
+ labels, self.config.pad_token_id, self.config.decoder_start_token_id
621
+ )
622
+
623
+ outputs: Seq2SeqModelOutput = self.model(
624
+ input_features,
625
+ attention_mask=attention_mask,
626
+ decoder_input_ids=decoder_input_ids,
627
+ encoder_outputs=encoder_outputs,
628
+ decoder_attention_mask=decoder_attention_mask,
629
+ past_key_values=past_key_values,
630
+ decoder_inputs_embeds=decoder_inputs_embeds,
631
+ decoder_position_ids=decoder_position_ids,
632
+ use_cache=use_cache,
633
+ **kwargs,
634
+ )
635
+ logits = self.proj_out(outputs.last_hidden_state)
636
+
637
+ loss = None
638
+ if labels is not None:
639
+ loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size)
640
+
641
+ return Seq2SeqLMOutput(
642
+ loss=loss,
643
+ logits=logits,
644
+ past_key_values=outputs.past_key_values,
645
+ decoder_hidden_states=outputs.decoder_hidden_states,
646
+ decoder_attentions=outputs.decoder_attentions,
647
+ cross_attentions=outputs.cross_attentions,
648
+ encoder_last_hidden_state=outputs.encoder_last_hidden_state,
649
+ encoder_hidden_states=outputs.encoder_hidden_states,
650
+ encoder_attentions=outputs.encoder_attentions,
651
+ )
652
+
653
+ def prepare_inputs_for_generation(self, *args, audio_chunk_index=None, **kwargs):
654
+ # audio_chunk_index is returned by the processor but not used by the model, absorb it here
655
+ return super().prepare_inputs_for_generation(*args, **kwargs)
656
+
657
+
658
+ __all__ = ["CohereAsrPreTrainedModel", "CohereAsrModel", "CohereAsrForConditionalGeneration"]
third_party/transformers/src/transformers/models/cohere_asr/modular_cohere_asr.py ADDED
@@ -0,0 +1,525 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 the HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from collections.abc import Callable
16
+
17
+ import torch
18
+ import torch.nn as nn
19
+
20
+ from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
21
+ from ...generation import GenerationMixin
22
+ from ...masking_utils import create_bidirectional_mask, create_causal_mask
23
+ from ...modeling_layers import GradientCheckpointingLayer
24
+ from ...modeling_outputs import (
25
+ BaseModelOutput,
26
+ BaseModelOutputWithPastAndCrossAttentions,
27
+ Seq2SeqLMOutput,
28
+ Seq2SeqModelOutput,
29
+ )
30
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS
31
+ from ...processing_utils import Unpack
32
+ from ...utils import TransformersKwargs, auto_docstring
33
+ from ...utils.generic import can_return_tuple
34
+ from ...utils.output_capturing import OutputRecorder
35
+ from ..auto.modeling_auto import AutoModel
36
+ from ..clip.modeling_clip import CLIPMLP
37
+ from ..moonshine.modeling_moonshine import (
38
+ MoonshineDecoder,
39
+ MoonshineForConditionalGeneration,
40
+ MoonshineModel,
41
+ MoonshinePreTrainedModel,
42
+ eager_attention_forward,
43
+ shift_tokens_right,
44
+ )
45
+ from .configuration_cohere_asr import CohereAsrConfig
46
+
47
+
48
+ class CohereAsrDecoderMLP(CLIPMLP):
49
+ pass
50
+
51
+
52
+ # Modular automatically inherits RoPE, hence no inheritance for now
53
+ class CohereAsrSelfAttention(nn.Module):
54
+ def __init__(self, config: CohereAsrConfig, layer_idx: int):
55
+ super().__init__()
56
+ self.config = config
57
+ self.layer_idx = layer_idx
58
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
59
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
60
+ self.scaling = self.head_dim**-0.5
61
+ self.attention_dropout = config.attention_dropout
62
+ self.is_causal = True
63
+
64
+ self.q_proj = nn.Linear(
65
+ config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
66
+ )
67
+ self.k_proj = nn.Linear(
68
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
69
+ )
70
+ self.v_proj = nn.Linear(
71
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
72
+ )
73
+ self.o_proj = nn.Linear(
74
+ config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
75
+ )
76
+
77
+ def forward(
78
+ self,
79
+ hidden_states: torch.Tensor,
80
+ attention_mask: torch.Tensor,
81
+ past_key_values: Cache | None = None,
82
+ **kwargs,
83
+ ):
84
+ input_shape = hidden_states.shape[:-1]
85
+ hidden_shape = (*input_shape, -1, self.head_dim)
86
+
87
+ query_states = self.q_proj(hidden_states)
88
+ key_states = self.k_proj(hidden_states)
89
+ value_states = self.v_proj(hidden_states)
90
+
91
+ query_states = query_states.view(hidden_shape).transpose(1, 2)
92
+ key_states = key_states.view(hidden_shape).transpose(1, 2)
93
+ value_states = value_states.view(hidden_shape).transpose(1, 2)
94
+
95
+ if past_key_values is not None:
96
+ past_key_values = past_key_values.self_attention_cache
97
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
98
+
99
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
100
+ self.config._attn_implementation, eager_attention_forward
101
+ )
102
+
103
+ attn_output, attn_weights = attention_interface(
104
+ self,
105
+ query_states,
106
+ key_states,
107
+ value_states,
108
+ attention_mask,
109
+ dropout=0.0 if not self.training else self.attention_dropout,
110
+ scaling=self.scaling,
111
+ **kwargs,
112
+ )
113
+
114
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
115
+ attn_output = self.o_proj(attn_output)
116
+ return attn_output, attn_weights
117
+
118
+
119
+ # Modular automatically inherits RoPE, hence no inheritance for now
120
+ class CohereAsrCrossAttention(nn.Module):
121
+ def __init__(self, config: CohereAsrConfig, layer_idx: int):
122
+ super().__init__()
123
+ self.config = config
124
+ self.layer_idx = layer_idx
125
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
126
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
127
+ self.scaling = self.head_dim**-0.5
128
+ self.attention_dropout = config.attention_dropout
129
+ self.is_causal = False
130
+
131
+ self.q_proj = nn.Linear(
132
+ config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
133
+ )
134
+ self.k_proj = nn.Linear(
135
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
136
+ )
137
+ self.v_proj = nn.Linear(
138
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
139
+ )
140
+ self.o_proj = nn.Linear(
141
+ config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
142
+ )
143
+
144
+ def forward(
145
+ self,
146
+ hidden_states: torch.Tensor,
147
+ encoder_hidden_states: torch.Tensor | None = None,
148
+ attention_mask: torch.Tensor | None = None,
149
+ past_key_values: Cache | None = None,
150
+ **kwargs: Unpack[TransformersKwargs],
151
+ ):
152
+ # determine input shapes
153
+ bsz, tgt_len = hidden_states.shape[:-1]
154
+ src_len = encoder_hidden_states.shape[1]
155
+
156
+ q_input_shape = (bsz, tgt_len, -1, self.head_dim)
157
+ kv_input_shape = (bsz, src_len, -1, self.head_dim)
158
+
159
+ # get query proj
160
+ query_states = self.q_proj(hidden_states).view(*q_input_shape).transpose(1, 2)
161
+
162
+ is_updated = past_key_values.is_updated.get(self.layer_idx) if past_key_values is not None else False
163
+ if past_key_values is not None and is_updated:
164
+ # reuse k,v, cross_attentions
165
+ key_states = past_key_values.cross_attention_cache.layers[self.layer_idx].keys
166
+ value_states = past_key_values.cross_attention_cache.layers[self.layer_idx].values
167
+ else:
168
+ key_states = self.k_proj(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2)
169
+ value_states = self.v_proj(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2)
170
+
171
+ if past_key_values is not None:
172
+ # save all states to the cache
173
+ key_states, value_states = past_key_values.cross_attention_cache.update(
174
+ key_states, value_states, self.layer_idx
175
+ )
176
+ # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
177
+ past_key_values.is_updated[self.layer_idx] = True
178
+
179
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
180
+ self.config._attn_implementation, eager_attention_forward
181
+ )
182
+
183
+ attn_output, attn_weights = attention_interface(
184
+ self,
185
+ query_states,
186
+ key_states,
187
+ value_states,
188
+ attention_mask,
189
+ dropout=0.0 if not self.training else self.attention_dropout,
190
+ scaling=self.scaling,
191
+ **kwargs,
192
+ )
193
+ attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous()
194
+ attn_output = self.o_proj(attn_output)
195
+ return attn_output, attn_weights
196
+
197
+
198
+ class CohereAsrDecoderLayer(GradientCheckpointingLayer):
199
+ def __init__(self, config, layer_idx=None):
200
+ super().__init__()
201
+ self.self_attn = CohereAsrSelfAttention(config=config, layer_idx=layer_idx)
202
+ self.encoder_attn = CohereAsrCrossAttention(config=config, layer_idx=layer_idx)
203
+
204
+ self.mlp = CohereAsrDecoderMLP(config)
205
+ self.input_layernorm = nn.LayerNorm(config.hidden_size)
206
+ self.post_attention_layernorm = nn.LayerNorm(config.hidden_size)
207
+ self.final_layernorm = nn.LayerNorm(config.hidden_size)
208
+
209
+ def forward(
210
+ self,
211
+ hidden_states: torch.Tensor,
212
+ attention_mask: torch.Tensor | None = None,
213
+ encoder_hidden_states: torch.Tensor | None = None,
214
+ encoder_attention_mask: torch.Tensor | None = None,
215
+ position_ids: torch.LongTensor | None = None,
216
+ encoder_position_ids: torch.LongTensor | None = None,
217
+ past_key_values: Cache | None = None,
218
+ **kwargs: Unpack[TransformersKwargs],
219
+ ) -> tuple[torch.FloatTensor, tuple[torch.FloatTensor, torch.FloatTensor] | None]:
220
+ residual = hidden_states
221
+ hidden_states = self.input_layernorm(hidden_states)
222
+
223
+ hidden_states, _ = self.self_attn(
224
+ hidden_states=hidden_states,
225
+ attention_mask=attention_mask,
226
+ position_ids=position_ids,
227
+ past_key_values=past_key_values,
228
+ **kwargs,
229
+ )
230
+ hidden_states = residual + hidden_states
231
+
232
+ if encoder_hidden_states is not None:
233
+ residual = hidden_states
234
+ hidden_states = self.post_attention_layernorm(hidden_states)
235
+ hidden_states, _ = self.encoder_attn(
236
+ hidden_states=hidden_states,
237
+ encoder_hidden_states=encoder_hidden_states,
238
+ attention_mask=encoder_attention_mask,
239
+ past_key_values=past_key_values,
240
+ )
241
+ hidden_states = residual + hidden_states
242
+
243
+ residual = hidden_states
244
+ hidden_states = self.final_layernorm(hidden_states)
245
+ hidden_states = self.mlp(hidden_states)
246
+ hidden_states = residual + hidden_states
247
+ return hidden_states
248
+
249
+
250
+ class CohereAsrPreTrainedModel(MoonshinePreTrainedModel):
251
+ main_input_name = "input_features"
252
+ _keys_to_ignore_on_load_unexpected = [r"preprocessor\.featurizer\..*"]
253
+
254
+
255
+ class CohereAsrDecoder(MoonshineDecoder):
256
+ _can_record_outputs = {
257
+ "attentions": OutputRecorder(CohereAsrSelfAttention, index=1, layer_name="self_attn"),
258
+ "hidden_states": CohereAsrDecoderLayer,
259
+ "cross_attentions": OutputRecorder(CohereAsrCrossAttention, index=1, layer_name="encoder_attn"),
260
+ }
261
+
262
+ def __init__(self, config):
263
+ super().__init__(config)
264
+ del self.rotary_emb
265
+ self.norm = nn.LayerNorm(config.hidden_size)
266
+ self.pos_emb = nn.Embedding(config.max_position_embeddings, config.hidden_size)
267
+ self.embedding_layernorm = nn.LayerNorm(config.hidden_size)
268
+ self.proj = nn.Linear(config.encoder_config.hidden_size, config.hidden_size, bias=True)
269
+ self.post_init()
270
+
271
+ def forward(
272
+ self,
273
+ input_ids: torch.LongTensor | None = None,
274
+ attention_mask: torch.Tensor | None = None,
275
+ position_ids: torch.LongTensor | None = None,
276
+ past_key_values: Cache | None = None,
277
+ inputs_embeds: torch.FloatTensor | None = None,
278
+ use_cache: bool | None = None,
279
+ encoder_hidden_states: torch.FloatTensor | None = None,
280
+ encoder_attention_mask: torch.Tensor | None = None,
281
+ **kwargs: Unpack[TransformersKwargs],
282
+ ) -> tuple | BaseModelOutputWithPastAndCrossAttentions:
283
+ r"""
284
+ encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*):
285
+ Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention
286
+ of the decoder.
287
+ encoder_attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
288
+ Mask to avoid performing attention on padding indices in `encoder_hidden_states`. Mask values selected in `[0, 1]`:
289
+ - 1 for tokens that are **not masked**,
290
+ - 0 for tokens that are **masked**.
291
+ [What are attention masks?](../glossary#attention-mask)
292
+ """
293
+ encoder_hidden_states = self.proj(encoder_hidden_states)
294
+ if (input_ids is None) ^ (inputs_embeds is not None):
295
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
296
+
297
+ if inputs_embeds is None:
298
+ inputs_embeds = self.embed_tokens(input_ids)
299
+
300
+ if use_cache and past_key_values is None:
301
+ past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config))
302
+
303
+ if position_ids is None:
304
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
305
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
306
+ position_ids = position_ids.unsqueeze(0)
307
+
308
+ # Fixed sinusoidal position embedding added to token embeddings, then layernorm
309
+ pos_emb = self.pos_emb(position_ids.squeeze(0))
310
+ inputs_embeds = self.embedding_layernorm(inputs_embeds + pos_emb)
311
+
312
+ causal_mask = create_causal_mask(
313
+ config=self.config,
314
+ inputs_embeds=inputs_embeds,
315
+ attention_mask=attention_mask,
316
+ past_key_values=past_key_values,
317
+ position_ids=position_ids,
318
+ )
319
+ encoder_attention_mask = create_bidirectional_mask(
320
+ config=self.config,
321
+ inputs_embeds=inputs_embeds,
322
+ attention_mask=encoder_attention_mask,
323
+ encoder_hidden_states=encoder_hidden_states,
324
+ )
325
+
326
+ hidden_states = inputs_embeds
327
+ for decoder_layer in self.layers:
328
+ hidden_states = decoder_layer(
329
+ hidden_states,
330
+ causal_mask,
331
+ encoder_hidden_states, # as a positional argument for gradient checkpointing
332
+ encoder_attention_mask=encoder_attention_mask,
333
+ position_ids=position_ids,
334
+ past_key_values=past_key_values,
335
+ **kwargs,
336
+ )
337
+
338
+ hidden_states = self.norm(hidden_states)
339
+
340
+ return BaseModelOutputWithPastAndCrossAttentions(
341
+ last_hidden_state=hidden_states,
342
+ past_key_values=past_key_values if use_cache else None,
343
+ )
344
+
345
+
346
+ class CohereAsrModel(MoonshineModel):
347
+ def __init__(self, config):
348
+ super().__init__(config)
349
+ self.encoder = AutoModel.from_config(config.encoder_config)
350
+
351
+ @can_return_tuple
352
+ @auto_docstring
353
+ def forward(
354
+ self,
355
+ input_features: torch.FloatTensor | None = None,
356
+ attention_mask: torch.LongTensor | None = None,
357
+ decoder_input_ids: torch.LongTensor | None = None,
358
+ decoder_attention_mask: torch.LongTensor | None = None,
359
+ encoder_outputs: tuple[tuple[torch.FloatTensor]] | None = None,
360
+ past_key_values: EncoderDecoderCache | None = None,
361
+ decoder_inputs_embeds: tuple[torch.FloatTensor] | None = None,
362
+ decoder_position_ids: tuple[torch.LongTensor] | None = None,
363
+ use_cache: bool | None = None,
364
+ **kwargs: Unpack[TransformersKwargs],
365
+ ) -> Seq2SeqModelOutput:
366
+ r"""
367
+ input_features (`torch.FloatTensor` of shape `(batch_size, audio_length)`):
368
+ Float values of the raw speech waveform. Raw speech waveform can be
369
+ obtained by loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a
370
+ `numpy.ndarray` or a `torch.Tensor`, *e.g.* via the torchcodec library (`pip install torchcodec`) or
371
+ the soundfile library (`pip install soundfile`). To prepare the array into
372
+ `input_features`, the [`AutoFeatureExtractor`] should be used for padding
373
+ and conversion into a tensor of type `torch.FloatTensor`.
374
+ decoder_position_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`):
375
+ Indices of positions of each input sequence tokens in the position embeddings.
376
+ Used to calculate the position embeddings up to `config.decoder_config.max_position_embeddings`
377
+
378
+ Example:
379
+
380
+ ```python
381
+ >>> import torch
382
+ >>> from transformers import AutoFeatureExtractor, CohereAsrModel
383
+ >>> from datasets import load_dataset
384
+
385
+ >>> model = CohereAsrModel.from_pretrained("UsefulSensors/cohere_asr-tiny")
386
+ >>> feature_extractor = AutoFeatureExtractor.from_pretrained("UsefulSensors/cohere_asr-tiny")
387
+ >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation")
388
+ >>> inputs = feature_extractor(ds[0]["audio"]["array"], return_tensors="pt")
389
+ >>> input_features = inputs.input_features
390
+ >>> decoder_input_ids = torch.tensor([[1, 1]]) * model.config.decoder_start_token_id
391
+ >>> last_hidden_state = model(input_features, decoder_input_ids=decoder_input_ids).last_hidden_state
392
+ >>> list(last_hidden_state.shape)
393
+ [1, 2, 288]
394
+ ```
395
+ """
396
+ # Main difference: uses `input_features` instead of `input_values`
397
+ if encoder_outputs is None:
398
+ encoder_outputs: BaseModelOutput = self.encoder(input_features, attention_mask=attention_mask, **kwargs)
399
+
400
+ decoder_outputs: BaseModelOutputWithPastAndCrossAttentions = self.decoder(
401
+ input_ids=decoder_input_ids,
402
+ attention_mask=decoder_attention_mask,
403
+ encoder_hidden_states=encoder_outputs.last_hidden_state,
404
+ encoder_attention_mask=encoder_outputs.attention_mask,
405
+ past_key_values=past_key_values,
406
+ inputs_embeds=decoder_inputs_embeds,
407
+ position_ids=decoder_position_ids,
408
+ use_cache=use_cache,
409
+ **kwargs,
410
+ )
411
+
412
+ return Seq2SeqModelOutput(
413
+ last_hidden_state=decoder_outputs.last_hidden_state,
414
+ past_key_values=decoder_outputs.past_key_values,
415
+ decoder_hidden_states=decoder_outputs.hidden_states,
416
+ decoder_attentions=decoder_outputs.attentions,
417
+ cross_attentions=decoder_outputs.cross_attentions,
418
+ encoder_last_hidden_state=encoder_outputs.last_hidden_state,
419
+ encoder_hidden_states=encoder_outputs.hidden_states,
420
+ encoder_attentions=encoder_outputs.attentions,
421
+ )
422
+
423
+
424
+ class CohereAsrForConditionalGeneration(MoonshineForConditionalGeneration):
425
+ def __init__(self, config):
426
+ super().__init__(config)
427
+ self.proj_out = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
428
+ self.post_init()
429
+
430
+ @can_return_tuple
431
+ @auto_docstring
432
+ def forward(
433
+ self,
434
+ input_features: torch.FloatTensor | None = None,
435
+ attention_mask: torch.LongTensor | None = None,
436
+ decoder_input_ids: torch.LongTensor | None = None,
437
+ decoder_attention_mask: torch.LongTensor | None = None,
438
+ encoder_outputs: tuple[tuple[torch.FloatTensor]] | None = None,
439
+ past_key_values: EncoderDecoderCache | None = None,
440
+ decoder_inputs_embeds: tuple[torch.FloatTensor] | None = None,
441
+ decoder_position_ids: tuple[torch.LongTensor] | None = None,
442
+ use_cache: bool | None = None,
443
+ labels: torch.LongTensor | None = None,
444
+ **kwargs: Unpack[TransformersKwargs],
445
+ ) -> Seq2SeqLMOutput:
446
+ r"""
447
+ input_features (`torch.FloatTensor` of shape `(batch_size, audio_length)`):
448
+ Float values of the raw speech waveform. Raw speech waveform can be
449
+ obtained by loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a
450
+ `numpy.ndarray` or a `torch.Tensor`, *e.g.* via the torchcodec library (`pip install torchcodec`) or
451
+ the soundfile library (`pip install soundfile`). To prepare the array into
452
+ `input_features`, the [`AutoFeatureExtractor`] should be used for padding
453
+ and conversion into a tensor of type `torch.FloatTensor`.
454
+ decoder_position_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`):
455
+ Indices of positions of each input sequence tokens in the position embeddings.
456
+ Used to calculate the position embeddings up to `config.decoder_config.max_position_embeddings`
457
+
458
+ Example:
459
+
460
+ ```python
461
+ >>> import torch
462
+ >>> from transformers import AutoProcessor, CohereAsrForConditionalGeneration
463
+ >>> from datasets import load_dataset
464
+
465
+ >>> processor = AutoProcessor.from_pretrained("UsefulSensors/cohere_asr-tiny")
466
+ >>> model = CohereAsrForConditionalGeneration.from_pretrained("UsefulSensors/cohere_asr-tiny")
467
+
468
+ >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation")
469
+
470
+ >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="pt")
471
+ >>> input_features = inputs.input_features
472
+
473
+ >>> generated_ids = model.generate(input_features, max_new_tokens=100)
474
+
475
+ >>> transcription = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
476
+ >>> transcription
477
+ 'Mr. Quilter is the apostle of the middle classes, and we are glad to welcome his gospel.'
478
+ ```"""
479
+ # Main difference: uses `input_features` instead of `input_values`
480
+ if labels is not None:
481
+ if decoder_input_ids is None and decoder_inputs_embeds is None:
482
+ decoder_input_ids = shift_tokens_right(
483
+ labels, self.config.pad_token_id, self.config.decoder_start_token_id
484
+ )
485
+
486
+ outputs: Seq2SeqModelOutput = self.model(
487
+ input_features,
488
+ attention_mask=attention_mask,
489
+ decoder_input_ids=decoder_input_ids,
490
+ encoder_outputs=encoder_outputs,
491
+ decoder_attention_mask=decoder_attention_mask,
492
+ past_key_values=past_key_values,
493
+ decoder_inputs_embeds=decoder_inputs_embeds,
494
+ decoder_position_ids=decoder_position_ids,
495
+ use_cache=use_cache,
496
+ **kwargs,
497
+ )
498
+ logits = self.proj_out(outputs.last_hidden_state)
499
+
500
+ loss = None
501
+ if labels is not None:
502
+ loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size)
503
+
504
+ return Seq2SeqLMOutput(
505
+ loss=loss,
506
+ logits=logits,
507
+ past_key_values=outputs.past_key_values,
508
+ decoder_hidden_states=outputs.decoder_hidden_states,
509
+ decoder_attentions=outputs.decoder_attentions,
510
+ cross_attentions=outputs.cross_attentions,
511
+ encoder_last_hidden_state=outputs.encoder_last_hidden_state,
512
+ encoder_hidden_states=outputs.encoder_hidden_states,
513
+ encoder_attentions=outputs.encoder_attentions,
514
+ )
515
+
516
+ def prepare_inputs_for_generation(self, *args, audio_chunk_index=None, **kwargs):
517
+ # audio_chunk_index is returned by the processor but not used by the model, absorb it here
518
+ return GenerationMixin.prepare_inputs_for_generation(self, *args, **kwargs)
519
+
520
+
521
+ __all__ = [
522
+ "CohereAsrPreTrainedModel",
523
+ "CohereAsrModel",
524
+ "CohereAsrForConditionalGeneration",
525
+ ]
third_party/transformers/src/transformers/models/cohere_asr/processing_cohere_asr.py ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 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
+ from ...audio_utils import AudioInput, make_list_of_audio
16
+ from ...processing_utils import ProcessingKwargs, ProcessorMixin, Unpack
17
+ from ...tokenization_utils_base import PreTokenizedInput, TextInput
18
+ from ...utils import auto_docstring, is_torch_available, logging
19
+ from ...utils.import_utils import requires
20
+
21
+
22
+ if is_torch_available():
23
+ import torch
24
+
25
+
26
+ LANGUAGES = {"ar", "de", "el", "en", "es", "fr", "it", "ja", "ko", "nl", "pl", "pt", "vi", "zh"}
27
+ _NO_SPACE_LANGS = {"ja", "zh"}
28
+
29
+
30
+ logger = logging.get_logger(__name__)
31
+
32
+
33
+ class CohereAsrProcessorKwargs(ProcessingKwargs, total=False):
34
+ _defaults = {
35
+ "audio_kwargs": {
36
+ "sampling_rate": 16000,
37
+ "padding": "longest",
38
+ "return_attention_mask": True,
39
+ },
40
+ "text_kwargs": {
41
+ "padding": True,
42
+ "padding_side": "right",
43
+ "add_special_tokens": False,
44
+ },
45
+ "common_kwargs": {"return_tensors": "pt"},
46
+ }
47
+
48
+
49
+ @auto_docstring
50
+ @requires(backends=("torch",))
51
+ class CohereAsrProcessor(ProcessorMixin):
52
+ def __init__(self, feature_extractor, tokenizer):
53
+ super().__init__(feature_extractor, tokenizer)
54
+
55
+ def get_decoder_prompt_ids(self, language: str, punctuation: bool = True) -> list[int]:
56
+ """Build the decoder prompt token IDs for the given language and punctuation settings."""
57
+ if language not in LANGUAGES:
58
+ raise ValueError(
59
+ f"Unsupported language: {language!r}. Supported languages: {', '.join(sorted(LANGUAGES))}."
60
+ )
61
+ pnc_token = "<|pnc|>" if punctuation else "<|nopnc|>"
62
+ tokens = [
63
+ "▁",
64
+ "<|startofcontext|>",
65
+ "<|startoftranscript|>",
66
+ "<|emo:undefined|>",
67
+ f"<|{language}|>",
68
+ f"<|{language}|>",
69
+ pnc_token,
70
+ "<|noitn|>",
71
+ "<|notimestamp|>",
72
+ "<|nodiarize|>",
73
+ ]
74
+ return self.tokenizer.convert_tokens_to_ids(tokens)
75
+
76
+ @auto_docstring
77
+ def __call__(
78
+ self,
79
+ audio: AudioInput,
80
+ language: str,
81
+ text: TextInput | PreTokenizedInput | list[TextInput] | list[PreTokenizedInput] | None = None,
82
+ punctuation: bool = True,
83
+ sampling_rate: int | None = None,
84
+ **kwargs: Unpack[CohereAsrProcessorKwargs],
85
+ ):
86
+ r"""
87
+ language (`str`):
88
+ Language code (e.g. `"en"`, `"es"`, `"fr"`) used to build the decoder prompt. The processor
89
+ constructs the full decoder prompt and returns `decoder_input_ids` alongside the audio features.
90
+ punctuation (`bool`, defaults to `True`):
91
+ Whether to enable punctuation in the decoder prompt.
92
+ sampling_rate (`int`, *optional*):
93
+ The sampling rate of the input audio in Hz. This should match the sampling rate expected by the feature
94
+ extractor (defaults to 16000 Hz). If provided, it will be validated against the processor's expected
95
+ sampling rate, and an error will be raised if they don't match. If not provided, a warning will be
96
+ issued and the default sampling rate will be assumed.
97
+ """
98
+ audio = make_list_of_audio(audio)
99
+
100
+ output_kwargs = self._merge_kwargs(
101
+ CohereAsrProcessorKwargs,
102
+ tokenizer_init_kwargs=self.tokenizer.init_kwargs,
103
+ **kwargs,
104
+ )
105
+
106
+ if sampling_rate is None:
107
+ logger.warning_once(
108
+ f"You've provided audio without specifying the sampling rate. It will be assumed to be {output_kwargs['audio_kwargs']['sampling_rate']}, which can result in silent errors."
109
+ )
110
+ elif sampling_rate != output_kwargs["audio_kwargs"]["sampling_rate"]:
111
+ raise ValueError(
112
+ f"The sampling rate of the audio ({sampling_rate}) does not match the sampling rate of the processor ({output_kwargs['audio_kwargs']['sampling_rate']}). Please provide resampled the audio to the expected sampling rate."
113
+ )
114
+
115
+ inputs = self.feature_extractor(audio, **output_kwargs["audio_kwargs"])
116
+
117
+ prompt_ids = self.get_decoder_prompt_ids(language=language, punctuation=punctuation)
118
+ batch_size = inputs["input_features"].shape[0]
119
+ inputs["decoder_input_ids"] = torch.tensor([prompt_ids] * batch_size, dtype=torch.long)
120
+
121
+ if text is not None:
122
+ encodings = self.tokenizer(text, **output_kwargs["text_kwargs"])
123
+ inputs["labels"] = encodings["input_ids"]
124
+
125
+ return inputs
126
+
127
+ def decode(self, *args, audio_chunk_index=None, language=None, **kwargs):
128
+ texts = self.tokenizer.decode(*args, **kwargs)
129
+ if audio_chunk_index is None:
130
+ return texts
131
+ if language is None:
132
+ raise ValueError("`language` must be provided when `audio_chunk_index` is given.")
133
+ separator = "" if language in _NO_SPACE_LANGS else " "
134
+ return self._reassemble_chunk_texts(texts, audio_chunk_index, separator)
135
+
136
+ @staticmethod
137
+ def _reassemble_chunk_texts(
138
+ texts: list[str],
139
+ audio_chunk_index: list[tuple[int, int | None]],
140
+ separator: str = " ",
141
+ ) -> list[str]:
142
+ """Reassemble per-chunk transcription texts back into per-sample strings.
143
+
144
+ When audio inputs are longer than the feature extractor's `max_audio_clip_s`, they are split into
145
+ overlapping chunks before being fed to the model. This means a single original audio sample can
146
+ produce multiple decoded text segments. This method reverses that chunking: it groups the decoded
147
+ texts by their original sample index using `chunk_map`, orders the chunks, and joins them
148
+ with `separator` to reconstruct one transcription string per input sample.
149
+
150
+ Args:
151
+ texts: Decoded text strings, one per model output (i.e. one per chunk).
152
+ audio_chunk_index: List of `(sample_idx, chunk_idx)` tuples that map each entry in
153
+ `texts` back to its original sample and chunk position. A `chunk_idx` of `None`
154
+ indicates the sample was not chunked.
155
+ separator: String used to join chunks belonging to the same sample. Defaults to a
156
+ space; callers pass an empty string for languages that don't use spaces between
157
+ words (e.g. Chinese, Japanese).
158
+
159
+ Returns:
160
+ A list of reassembled transcription strings, one per original input sample.
161
+ """
162
+ max_sample_idx = max(sample_idx for sample_idx, _ in audio_chunk_index)
163
+ outputs = [""] * (max_sample_idx + 1)
164
+ chunked = {}
165
+
166
+ for (sample_idx, chunk_idx), text in zip(audio_chunk_index, texts):
167
+ if chunk_idx is None:
168
+ outputs[sample_idx] = text
169
+ else:
170
+ if sample_idx not in chunked:
171
+ chunked[sample_idx] = []
172
+ chunked[sample_idx].append((chunk_idx, text))
173
+
174
+ for sample_idx, chunk_items in chunked.items():
175
+ chunk_items.sort(key=lambda item: item[0])
176
+ non_empty = [t for _, t in chunk_items if t and t.strip()]
177
+ parts = [non_empty[0].rstrip()] + [t.strip() for t in non_empty[1:]]
178
+ outputs[sample_idx] = separator.join(parts)
179
+
180
+ return outputs
181
+
182
+ @property
183
+ def model_input_names(self):
184
+ feature_extractor_input_names = self.feature_extractor.model_input_names
185
+ return feature_extractor_input_names + ["labels"]
186
+
187
+
188
+ __all__ = ["CohereAsrProcessor"]
third_party/transformers/src/transformers/models/deepseek_vl_hybrid/__init__.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Deepseek AI 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
+ 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_deepseek_vl_hybrid import *
22
+ from .image_processing_deepseek_vl_hybrid import *
23
+ from .image_processing_pil_deepseek_vl_hybrid import *
24
+ from .modeling_deepseek_vl_hybrid import *
25
+ from .processing_deepseek_vl_hybrid import *
26
+ else:
27
+ import sys
28
+
29
+ _file = globals()["__file__"]
30
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/deepseek_vl_hybrid/configuration_deepseek_vl_hybrid.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.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_deepseek_vl_hybrid.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 Deepseek AI and The HuggingFace Team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ from huggingface_hub.dataclasses import strict
22
+
23
+ from ...configuration_utils import PreTrainedConfig
24
+ from ...utils import auto_docstring, logging
25
+ from ..auto import CONFIG_MAPPING, AutoConfig
26
+
27
+
28
+ logger = logging.get_logger(__name__)
29
+
30
+
31
+ @auto_docstring(checkpoint="deepseek-community/deepseek-vl-7b-chat")
32
+ @strict
33
+ class DeepseekVLHybridConfig(PreTrainedConfig):
34
+ r"""
35
+ high_res_vision_config (`Union[AutoConfig, dict]`, *optional*, defaults to `SamVisionConfig`):
36
+ The config object or dictionary of the high resolution vision backbone.
37
+
38
+ Example:
39
+
40
+ ```python
41
+ >>> from transformers import DeepseekVLHybridConfig, DeepseekVLHybridModel
42
+
43
+ >>> # Initializing a DeepseekVLHybrid deepseek-community/deepseek-vl-7b-chat style configuration
44
+ >>> configuration = DeepseekVLHybridConfig()
45
+
46
+ >>> # Initializing a model (with random weights) from the deepseek-community/deepseek-vl-7b-chat style configuration
47
+ >>> model = DeepseekVLHybridModel(configuration)
48
+
49
+ >>> # Accessing the model configuration
50
+ >>> configuration = model.config
51
+ ```"""
52
+
53
+ model_type = "deepseek_vl_hybrid"
54
+ sub_configs = {"text_config": AutoConfig, "vision_config": AutoConfig, "high_res_vision_config": AutoConfig}
55
+
56
+ text_config: dict | PreTrainedConfig | None = None
57
+ vision_config: dict | PreTrainedConfig | None = None
58
+ image_token_id: int = 100015
59
+ tie_word_embeddings: bool = True
60
+
61
+ high_res_vision_config: dict | PreTrainedConfig | None = None
62
+
63
+ def __post_init__(self, **kwargs):
64
+ if self.high_res_vision_config is None:
65
+ self.high_res_vision_config = {}
66
+ logger.info("`high_res_vision_config` is `None`. Initializing the `SamVisionConfig` with default values.")
67
+
68
+ if isinstance(self.high_res_vision_config, dict):
69
+ self.high_res_vision_config["model_type"] = self.high_res_vision_config.get(
70
+ "model_type", "sam_vision_model"
71
+ )
72
+ self.high_res_vision_config = CONFIG_MAPPING[self.high_res_vision_config["model_type"]](
73
+ **self.high_res_vision_config
74
+ )
75
+ if self.text_config is None:
76
+ self.text_config = {}
77
+ logger.info("`text_config` is `None`. Initializing the `LlamaConfig` with default values.")
78
+ if isinstance(self.text_config, dict):
79
+ self.text_config["model_type"] = self.text_config.get("model_type", "llama")
80
+ self.text_config = CONFIG_MAPPING[self.text_config["model_type"]](**self.text_config)
81
+
82
+ if self.vision_config is None:
83
+ self.vision_config = {}
84
+ logger.info("`vision_config` is `None`. Initializing the `SiglipVisionConfig` with default values.")
85
+ if isinstance(self.vision_config, dict):
86
+ self.vision_config["model_type"] = self.vision_config.get("model_type", "siglip_vision_model")
87
+ self.vision_config = CONFIG_MAPPING[self.vision_config["model_type"]](**self.vision_config)
88
+
89
+ super().__post_init__(**kwargs)
90
+
91
+
92
+ __all__ = ["DeepseekVLHybridConfig"]
third_party/transformers/src/transformers/models/deepseek_vl_hybrid/convert_deepseek_vl_hybrid_weights_to_hf.py ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Deepseek AI 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
+ import argparse
15
+ import gc
16
+ import json
17
+ import os
18
+
19
+ import regex as re
20
+ import torch
21
+ from huggingface_hub import snapshot_download
22
+ from huggingface_hub.errors import HFValidationError
23
+ from safetensors.torch import load_file
24
+
25
+ from transformers import (
26
+ AutoTokenizer,
27
+ DeepseekVLHybridConfig,
28
+ DeepseekVLHybridForConditionalGeneration,
29
+ DeepseekVLHybridImageProcessor,
30
+ DeepseekVLHybridProcessor,
31
+ )
32
+ from transformers.image_utils import (
33
+ IMAGENET_STANDARD_MEAN,
34
+ IMAGENET_STANDARD_STD,
35
+ OPENAI_CLIP_MEAN,
36
+ OPENAI_CLIP_STD,
37
+ PILImageResampling,
38
+ )
39
+
40
+
41
+ # fmt: off
42
+ ORIGINAL_TO_CONVERTED_KEY_MAPPING = {
43
+ # # Sam (High Resolution)
44
+ r"vision_model.vision_tower_high.vision_tower.pos_embed": r"model.high_res_vision_model.vision_encoder.pos_embed",
45
+ r"vision_model.vision_tower_high.vision_tower.patch_embed.proj.(weight|bias)": r"model.high_res_vision_model.vision_encoder.patch_embed.projection.\1",
46
+ r"vision_model.vision_tower_high.vision_tower.blocks.(\d+).norm(\d+).(weight|bias)": r"model.high_res_vision_model.vision_encoder.layers.\1.layer_norm\2.\3",
47
+ r"vision_model.vision_tower_high.vision_tower.blocks.(\d+).attn.rel_pos_(h|w)": r"model.high_res_vision_model.vision_encoder.layers.\1.attn.rel_pos_\2",
48
+ r"vision_model.vision_tower_high.vision_tower.blocks.(\d+).attn.qkv.(weight|bias)": r"model.high_res_vision_model.vision_encoder.layers.\1.attn.qkv.\2",
49
+ r"vision_model.vision_tower_high.vision_tower.blocks.(\d+).attn.proj.(weight|bias)": r"model.high_res_vision_model.vision_encoder.layers.\1.attn.proj.\2",
50
+ r"vision_model.vision_tower_high.vision_tower.blocks.(\d+).mlp.lin(\d+).(weight|bias)": r"model.high_res_vision_model.vision_encoder.layers.\1.mlp.lin\2.\3",
51
+ r"vision_model.vision_tower_high.vision_tower.neck.0.weight": r"model.high_res_vision_model.vision_encoder.neck.conv1.weight",
52
+ r"vision_model.vision_tower_high.vision_tower.neck.1.(weight|bias)": r"model.high_res_vision_model.vision_encoder.neck.layer_norm1.\1",
53
+ r"vision_model.vision_tower_high.vision_tower.neck.2.weight": r"model.high_res_vision_model.vision_encoder.neck.conv2.weight",
54
+ r"vision_model.vision_tower_high.vision_tower.neck.3.(weight|bias)": r"model.high_res_vision_model.vision_encoder.neck.layer_norm2.\1",
55
+ r"vision_model.vision_tower_high.vision_tower.neck_hd.0.weight": r"model.high_res_vision_neck.conv1.weight",
56
+ r"vision_model.vision_tower_high.vision_tower.neck_hd.1.(weight|bias)": r"model.high_res_vision_neck.layer_norm1.\1",
57
+ r"vision_model.vision_tower_high.vision_tower.neck_hd.2.weight": r"model.high_res_vision_neck.conv2.weight",
58
+ r"vision_model.vision_tower_high.vision_tower.neck_hd.3.(weight|bias)": r"model.high_res_vision_neck.layer_norm2.\1",
59
+ r"vision_model.vision_tower_high.vision_tower.downsamples.0.weight": r"model.high_res_vision_proj.conv1.weight",
60
+ r"vision_model.vision_tower_high.vision_tower.downsamples.1.weight": r"model.high_res_vision_proj.conv2.weight",
61
+ r"vision_model.vision_tower_high.vision_tower.hd_alpha_downsamples": r"model.high_res_vision_alpha",
62
+
63
+ # Siglip (Low Resolution)
64
+ r"vision_model.vision_tower_low.vision_tower.pos_embed": r"model.vision_model.vision_model.embeddings.position_embedding.weight",
65
+ r"vision_model.vision_tower_low.vision_tower.patch_embed.proj.(weight|bias)": r"model.vision_model.vision_model.embeddings.patch_embedding.\1",
66
+ r"vision_model.vision_tower_low.vision_tower.blocks.(\d+).attn.qkv.(weight|bias)": r"model.vision_model.vision_model.encoder.layers.\1.self_attn.(q|k|v)_proj.\2",
67
+ r"vision_model.vision_tower_low.vision_tower.blocks.(\d+).attn.proj.(weight|bias)": r"model.vision_model.vision_model.encoder.layers.\1.self_attn.out_proj.\2",
68
+ r"vision_model.vision_tower_low.vision_tower.blocks.(\d+).norm(\d+).(weight|bias)": r"model.vision_model.vision_model.encoder.layers.\1.layer_norm\2.\3",
69
+ r"vision_model.vision_tower_low.vision_tower.blocks.(\d+).mlp.fc(\d+).(weight|bias)": r"model.vision_model.vision_model.encoder.layers.\1.mlp.fc\2.\3",
70
+ r"vision_model.vision_tower_low.vision_tower.norm.(weight|bias)": r"model.vision_model.vision_model.post_layernorm.\1",
71
+ r"vision_model.vision_tower_low.vision_tower.attn_pool.latent": r"model.vision_model.vision_model.head.probe",
72
+ r"vision_model.vision_tower_low.vision_tower.attn_pool.proj.(weight|bias)": r"model.vision_model.vision_model.head.attention.out_proj.\1",
73
+ r"vision_model.vision_tower_low.vision_tower.attn_pool.norm.(weight|bias)": r"model.vision_model.vision_model.head.layernorm.\1",
74
+ r"vision_model.vision_tower_low.vision_tower.attn_pool.mlp.fc(\d+).(weight|bias)": r"model.vision_model.vision_model.head.mlp.fc\1.\2",
75
+
76
+ # Vision Projection
77
+ r"aligner.layers.1.(weight|bias)": r"model.aligner.proj.\1",
78
+ r"aligner.low_up_proj.(weight|bias)": r"model.aligner.vision_proj.\1",
79
+ r"aligner.high_up_proj.(weight|bias)": r"model.aligner.high_res_vision_proj.\1",
80
+
81
+ # Llama (Text Model)
82
+ r"language_model.model.(\w+)": r"model.language_model.\1",
83
+ r"language_model.lm_head.(weight|bias)": r"lm_head.\1",
84
+ }
85
+ # fmt: on
86
+
87
+ # Adopted from https://github.com/deepseek-ai/DeepSeek-VL/blob/main/deepseek_vl/utils/conversation.py#L80-L91
88
+ CHAT_TEMPLATE = (
89
+ # Define separators and initialize counter
90
+ "{% set seps = ['\n\n', '<\uff5cend\u2581of\u2581sentence\uff5c>'] %}"
91
+ "{% set i = 0 %}"
92
+ # Start with default system prompt
93
+ "You are a helpful language and vision assistant. "
94
+ "You are able to understand the visual content that the user provides, "
95
+ "and assist the user with a variety of tasks using natural language.\n\n"
96
+ # Iterate through messages
97
+ "{% for message in messages %}"
98
+ # Identify user or assistant role
99
+ "{% if message['role']|lower == 'user' %}"
100
+ "User: "
101
+ "{% elif message['role']|lower == 'assistant' %}"
102
+ "Assistant:{% if not (loop.last and not add_generation_prompt and message['content'][0]['type']=='text' and message['content'][0]['text']=='') %} {% endif %}"
103
+ "{% else %}"
104
+ "{{ message['role'].capitalize() }}: "
105
+ "{% endif %}"
106
+ # Iterate through message content (text/images)
107
+ "{% for content in message['content'] %}"
108
+ # If content is an image, replace with placeholder
109
+ "{% if content['type'] == 'image' %}"
110
+ "<image_placeholder>"
111
+ # If content is text, handle formatting
112
+ "{% elif content['type'] == 'text' %}"
113
+ "{% set text = content['text'] %}"
114
+ # Strip whitespace for first and last text blocks
115
+ "{% if loop.first %}{% set text = text.lstrip() %}{% endif %}"
116
+ "{% if loop.last %}{% set text = text.rstrip() %}{% endif %}"
117
+ # If previous content was text, add space
118
+ "{% if not loop.first and message['content'][loop.index0-1]['type'] == 'text' %}"
119
+ "{{ ' ' + text }}"
120
+ "{% else %}"
121
+ "{{ text }}"
122
+ "{% endif %}"
123
+ "{% endif %}"
124
+ "{% endfor %}" # End message content loop
125
+ # Add separators between messages
126
+ "{% if not loop.last or add_generation_prompt %}"
127
+ "{% if message['role']|lower == 'user' %}"
128
+ "{{ seps[0] }}"
129
+ "{% else %}"
130
+ "{{ seps[1] }}"
131
+ "{% endif %}"
132
+ "{% endif %}"
133
+ "{% endfor %}" # End messages loop
134
+ # Add final Assistant prompt if required
135
+ "{% if add_generation_prompt %}Assistant:{% endif %}"
136
+ )
137
+
138
+
139
+ def convert_old_keys_to_new_keys(state_dict_keys: dict):
140
+ output_dict = {}
141
+
142
+ old_text = "\n".join(state_dict_keys)
143
+ new_text = old_text
144
+ for pattern, replacement in ORIGINAL_TO_CONVERTED_KEY_MAPPING.items():
145
+ if replacement is None:
146
+ new_text = re.sub(pattern, "", new_text) # an empty line
147
+ continue
148
+ new_text = re.sub(pattern, replacement, new_text)
149
+ output_dict = dict(zip(old_text.split("\n"), new_text.split("\n")))
150
+
151
+ return output_dict
152
+
153
+
154
+ def get_qkv_state_dict(key, parameter):
155
+ """
156
+ new key which looks like this
157
+ xxxx.(q|k|v).xxx (m, n)
158
+
159
+ is converted to
160
+ xxxx.q.xxxx (m//3, n)
161
+ xxxx.k.xxxx (m//3, n)
162
+ xxxx.v.xxxx (m//3, n)
163
+ """
164
+ qkv_state_dict = {}
165
+ placeholder = re.search(r"(\(.*?\))", key).group(1) # finds "(query|key|value)"
166
+ replacements_keys = placeholder[1:-1].split("|") # creates ['query', 'key', 'value']
167
+ replacements_vals = torch.split(
168
+ parameter, split_size_or_sections=parameter.size(0) // len(replacements_keys), dim=0
169
+ )
170
+ for replacement_key, replacement_val in zip(replacements_keys, replacements_vals):
171
+ qkv_state_dict[key.replace(placeholder, replacement_key)] = replacement_val
172
+ return qkv_state_dict
173
+
174
+
175
+ def update_state_dict(old_state_dict):
176
+ all_keys = list(old_state_dict.keys())
177
+ new_keys = convert_old_keys_to_new_keys(all_keys)
178
+
179
+ state_dict = {}
180
+ for key in all_keys:
181
+ new_key = new_keys[key]
182
+ current_parameter = old_state_dict.pop(key)
183
+
184
+ if "qkv" in key and "vision_tower_high" not in key:
185
+ qkv_state_dict = get_qkv_state_dict(new_key, current_parameter)
186
+ state_dict.update(qkv_state_dict)
187
+ elif "pos_embed" in key:
188
+ if "vision_tower_high" not in key:
189
+ # timm implementation of siglip creates this param of size [1, 576, 1024]
190
+ # transformers implementation of siglip creates this param of size [576, 1024]
191
+ state_dict[new_key] = current_parameter.squeeze(0)
192
+ else:
193
+ state_dict[new_key] = current_parameter
194
+ else:
195
+ state_dict[new_key] = current_parameter
196
+
197
+ return state_dict
198
+
199
+
200
+ def load_model_state_dict(input_path: str) -> dict:
201
+ """
202
+ Load model state dict, handling both single and sharded files.
203
+ """
204
+ index_path = os.path.join(input_path, "model.safetensors.index.json")
205
+ single_file_path = os.path.join(input_path, "model.safetensors")
206
+
207
+ # Check if we have a sharded model
208
+ if os.path.exists(index_path):
209
+ print("Loading sharded model...")
210
+ state_dict = {}
211
+ with open(index_path, "r") as f:
212
+ index = json.load(f)
213
+
214
+ # Get unique shard files and load each one only once
215
+ unique_shard_files = sorted(set(index["weight_map"].values()))
216
+ for shard_file in unique_shard_files:
217
+ print(f"Loading shard {shard_file}...")
218
+ shard_path = os.path.join(input_path, shard_file)
219
+ shard_dict = load_file(shard_path)
220
+ state_dict.update(shard_dict)
221
+
222
+ return state_dict
223
+
224
+ # Single file model
225
+ elif os.path.exists(single_file_path):
226
+ print("Loading single file model...")
227
+ return load_file(single_file_path, device="cpu")
228
+
229
+ else:
230
+ raise ValueError(f"No model files found in {input_path}")
231
+
232
+
233
+ def convert_model(
234
+ hf_repo_id: str,
235
+ output_dir: str | None = None,
236
+ output_hub_path: str | None = None,
237
+ ):
238
+ if output_dir:
239
+ os.makedirs(output_dir, exist_ok=True)
240
+
241
+ try:
242
+ input_path = snapshot_download(hf_repo_id)
243
+ except HFValidationError:
244
+ # If the input path is not a HF repo ID, assume it's a local path
245
+ input_path = hf_repo_id
246
+
247
+ # ------------------------------------------------------------
248
+ # Create and save config
249
+ # ------------------------------------------------------------
250
+
251
+ config = DeepseekVLHybridConfig(
252
+ text_config={
253
+ "hidden_size": 4096,
254
+ "intermediate_size": 11008,
255
+ "max_position_embeddings": 16384,
256
+ "num_attention_heads": 32,
257
+ "num_hidden_layers": 30,
258
+ "vocab_size": 102400,
259
+ },
260
+ vision_config={
261
+ "hidden_size": 1024,
262
+ "intermediate_size": 4096,
263
+ "image_size": 384,
264
+ "patch_size": 16,
265
+ "hidden_act": "gelu",
266
+ "vision_use_head": False,
267
+ "num_attention_heads": 16,
268
+ "num_hidden_layers": 24,
269
+ },
270
+ high_res_vision_config={
271
+ "hidden_size": 768,
272
+ "intermediate_size": 3072,
273
+ "image_size": 1024,
274
+ "patch_size": 16,
275
+ "num_attention_heads": 12,
276
+ "num_hidden_layers": 12,
277
+ },
278
+ )
279
+
280
+ # save config
281
+ if output_dir:
282
+ config.save_pretrained(output_dir)
283
+ print("Model config saved successfully...")
284
+
285
+ # ------------------------------------------------------------
286
+ # Convert processor
287
+ # ------------------------------------------------------------
288
+
289
+ image_processor = DeepseekVLHybridImageProcessor(
290
+ image_mean=IMAGENET_STANDARD_MEAN,
291
+ image_std=IMAGENET_STANDARD_STD,
292
+ high_res_image_mean=OPENAI_CLIP_MEAN,
293
+ high_res_image_std=OPENAI_CLIP_STD,
294
+ resample=PILImageResampling.BILINEAR,
295
+ )
296
+
297
+ tokenizer = AutoTokenizer.from_pretrained(
298
+ input_path,
299
+ extra_special_tokens={
300
+ "pad_token": "<|end▁of▁sentence|>",
301
+ "image_token": "<image_placeholder>",
302
+ },
303
+ )
304
+
305
+ processor = DeepseekVLHybridProcessor(
306
+ image_processor=image_processor,
307
+ tokenizer=tokenizer,
308
+ chat_template=CHAT_TEMPLATE,
309
+ )
310
+
311
+ if output_dir:
312
+ print(f"Saving processor to {output_dir}...")
313
+ processor.save_pretrained(output_dir)
314
+ if output_hub_path:
315
+ print(f"Pushing processor to hub at {output_hub_path}...")
316
+ processor.push_to_hub(output_hub_path)
317
+
318
+ # ------------------------------------------------------------
319
+ # Convert weights
320
+ # ------------------------------------------------------------
321
+
322
+ print("Creating empty model...")
323
+ with torch.device("meta"):
324
+ model = DeepseekVLHybridForConditionalGeneration(config)
325
+
326
+ # Load and convert state dict
327
+ print("Loading state dict...")
328
+ state_dict = load_model_state_dict(input_path)
329
+ state_dict = update_state_dict(state_dict)
330
+
331
+ # Load converted state dict
332
+ print("Loading converted weights into model...")
333
+ info = model.load_state_dict(state_dict, strict=False, assign=True)
334
+ if len(info.missing_keys) > 0:
335
+ raise ValueError(f"Missing keys: {info.missing_keys}")
336
+
337
+ # Tie weights before any device mapping
338
+ print("Tying weights...")
339
+ model.tie_weights()
340
+
341
+ # Save the model
342
+ if output_dir:
343
+ print(f"Saving model to {output_dir}...")
344
+ model.save_pretrained(output_dir)
345
+ if output_hub_path:
346
+ print(f"Pushing model to hub at {output_hub_path}...")
347
+ model.push_to_hub(output_hub_path)
348
+
349
+ del state_dict, model
350
+ gc.collect()
351
+
352
+ # Validate the saved model if saved locally
353
+ if output_dir:
354
+ print("Reloading the local model to check if it's saved correctly...")
355
+ DeepseekVLHybridForConditionalGeneration.from_pretrained(output_dir, device_map="auto")
356
+ print("Local model reloaded successfully.")
357
+
358
+
359
+ def main():
360
+ parser = argparse.ArgumentParser()
361
+ parser.add_argument(
362
+ "--hf_repo_id",
363
+ default="deepseek-ai/deepseek-vl-7b-chat",
364
+ help="Location of official weights from DeepseekAI on HF",
365
+ )
366
+ parser.add_argument(
367
+ "--output_dir",
368
+ default=None,
369
+ help="Location to write the converted model and processor",
370
+ )
371
+ parser.add_argument(
372
+ "--output_hub_path",
373
+ default=None,
374
+ help="Repository ID to push model to hub (e.g. 'username/model-name')",
375
+ )
376
+ args = parser.parse_args()
377
+
378
+ convert_model(
379
+ hf_repo_id=args.hf_repo_id,
380
+ output_dir=args.output_dir,
381
+ output_hub_path=args.output_hub_path,
382
+ )
383
+
384
+
385
+ if __name__ == "__main__":
386
+ main()
third_party/transformers/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.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_deepseek_vl_hybrid.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 Deepseek AI and The HuggingFace Team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ from collections.abc import Iterable
22
+ from typing import Union
23
+
24
+ import torch
25
+ import torchvision.transforms.v2.functional as tvF
26
+
27
+ from ...image_processing_backends import TorchvisionBackend
28
+ from ...image_processing_utils import BatchFeature, get_size_dict
29
+ from ...image_transforms import group_images_by_shape, reorder_images
30
+ from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling, SizeDict
31
+ from ...processing_utils import ImagesKwargs, Unpack
32
+ from ...utils import TensorType, auto_docstring
33
+
34
+
35
+ class DeepseekVLHybridImageProcessorKwargs(ImagesKwargs, total=False):
36
+ r"""
37
+ min_size (`int`, *optional*, defaults to 14):
38
+ The minimum allowed size for the resized image. Ensures that neither the height nor width
39
+ falls below this value after resizing.
40
+ high_res_size (`dict`, *optional*, defaults to `{"height": 1024, "width": 1024}`):
41
+ Size of the high resolution output image after resizing. Can be overridden by the `high_res_size` parameter in the `preprocess`
42
+ method.
43
+ high_res_resample (`PILImageResampling`, *optional*, defaults to `Resampling.BICUBIC`):
44
+ Resampling filter to use if resizing the image. Only has an effect if `do_resize` is set to `True`. Can be
45
+ overridden by the `high_res_resample` parameter in the `preprocess` method.
46
+ high_res_image_mean (`float` or `list[float]`, *optional*, defaults to `OPENAI_CLIP_MEAN`):
47
+ Mean to use if normalizing the high resolution image. This is a float or list of floats the length of the number of
48
+ channels in the image. Can be overridden by the `high_res_image_mean` parameter in the `preprocess` method.
49
+ high_res_image_std (`float` or `list[float]`, *optional*, defaults to `OPENAI_CLIP_STD`):
50
+ Standard deviation to use if normalizing the high resolution image. This is a float or list of floats the length of the
51
+ number of channels in the image. Can be overridden by the `high_res_image_std` parameter in the `preprocess` method.
52
+ """
53
+
54
+ min_size: int
55
+ high_res_size: dict
56
+ high_res_resample: Union["PILImageResampling", int]
57
+ high_res_image_mean: float | list[float] | tuple[float, ...]
58
+ high_res_image_std: float | list[float] | tuple[float, ...]
59
+
60
+
61
+ @auto_docstring
62
+ class DeepseekVLHybridImageProcessor(TorchvisionBackend):
63
+ resample = PILImageResampling.BICUBIC
64
+ image_mean = OPENAI_CLIP_MEAN
65
+ image_std = OPENAI_CLIP_STD
66
+ size = {"height": 384, "width": 384}
67
+ min_size = 14
68
+ do_resize = True
69
+ do_rescale = True
70
+ do_normalize = True
71
+ do_pad = True
72
+ valid_kwargs = DeepseekVLHybridImageProcessorKwargs
73
+ high_res_image_mean = OPENAI_CLIP_MEAN
74
+ high_res_image_std = OPENAI_CLIP_STD
75
+ high_res_size = {"height": 1024, "width": 1024}
76
+ high_res_resample = PILImageResampling.BICUBIC
77
+ model_input_names = ["pixel_values", "high_res_pixel_values"]
78
+
79
+ def __init__(self, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]):
80
+ if kwargs.get("image_mean") is None:
81
+ background_color = (127, 127, 127)
82
+ else:
83
+ background_color = tuple(int(x * 255) for x in kwargs.get("image_mean"))
84
+ if kwargs.get("high_res_image_mean") is None:
85
+ high_res_background_color = (127, 127, 127)
86
+ else:
87
+ high_res_background_color = tuple(int(x * 255) for x in kwargs.get("high_res_image_mean"))
88
+ super().__init__(**kwargs)
89
+ self.background_color = tuple(background_color)
90
+ self.high_res_background_color = tuple(high_res_background_color)
91
+
92
+ def resize(
93
+ self,
94
+ image: "torch.Tensor",
95
+ size: SizeDict,
96
+ min_size: int,
97
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None",
98
+ antialias: bool = True,
99
+ **kwargs,
100
+ ) -> "torch.Tensor":
101
+ if size.height is None or size.width is None or size.height != size.width:
102
+ raise ValueError(
103
+ f"Output height and width must be the same. Got height={size['height']} and width={size['width']}"
104
+ )
105
+ size = size.height
106
+
107
+ height, width = image.shape[-2:]
108
+ max_size = max(height, width)
109
+
110
+ delta = size / max_size
111
+ # Largest side becomes `size` and the other side is scaled according to the aspect ratio.
112
+ output_size_nonpadded = SizeDict(
113
+ height=max(round(height * delta), min_size),
114
+ width=max(round(width * delta), min_size),
115
+ )
116
+
117
+ return super().resize(image, size=output_size_nonpadded, resample=resample, antialias=antialias)
118
+
119
+ def pad_to_square(
120
+ self,
121
+ images: "torch.Tensor",
122
+ background_color: int | tuple[int, int, int] = 0,
123
+ ) -> "torch.Tensor":
124
+ """
125
+ Pads an image to a square based on the longest edge.
126
+
127
+ Args:
128
+ images (`torch.Tensor`):
129
+ The images to pad.
130
+ background_color (`int` or `tuple[int, int, int]`, *optional*, defaults to 0):
131
+ The color to use for the padding. Can be an integer for single channel or a
132
+ tuple of integers representing for multi-channel images. If passed as integer
133
+ in multi-channel mode, it will default to `0` in subsequent channels.
134
+
135
+ Returns:
136
+ `torch.Tensor`: The padded images.
137
+ """
138
+ height, width = images.shape[-2:]
139
+ num_channels = images.shape[1]
140
+ batch_size = images.shape[0]
141
+
142
+ if height == width:
143
+ return images
144
+
145
+ max_dim = max(height, width)
146
+
147
+ # Ensure background_color is the correct shape
148
+ if isinstance(background_color, int):
149
+ background_color = [background_color]
150
+ elif len(background_color) != num_channels:
151
+ raise ValueError(
152
+ f"background_color must have no more than {num_channels} elements to match the number of channels"
153
+ )
154
+
155
+ padded_images = torch.zeros(
156
+ (batch_size, num_channels, max_dim, max_dim), dtype=images.dtype, device=images.device
157
+ )
158
+ for i, color in enumerate(background_color):
159
+ padded_images[:, i, :, :] = color
160
+ if width > height:
161
+ start = (max_dim - height) // 2
162
+ padded_images[:, :, start : start + height, :] = images
163
+ else:
164
+ start = (max_dim - width) // 2
165
+ padded_images[:, :, :, start : start + width] = images
166
+
167
+ return padded_images
168
+
169
+ def _preprocess(
170
+ self,
171
+ images: list["torch.Tensor"],
172
+ do_resize: bool,
173
+ size: SizeDict,
174
+ high_res_size: SizeDict,
175
+ min_size: int,
176
+ resample: "PILImageResampling | None",
177
+ high_res_resample: "PILImageResampling | None",
178
+ do_rescale: bool,
179
+ rescale_factor: float,
180
+ do_normalize: bool,
181
+ image_mean: float | list[float] | None,
182
+ image_std: float | list[float] | None,
183
+ high_res_image_mean: float | list[float] | None,
184
+ high_res_image_std: float | list[float] | None,
185
+ disable_grouping: bool | None,
186
+ return_tensors: str | TensorType | None,
187
+ do_pad: bool = True,
188
+ **kwargs,
189
+ ) -> BatchFeature:
190
+ # Group images by size for batched resizing
191
+ grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
192
+ high_res_resized_images_grouped = {}
193
+ for shape, stacked_images in grouped_images.items():
194
+ if do_resize:
195
+ stacked_high_res_images = self.resize(
196
+ image=stacked_images, size=high_res_size, min_size=min_size, resample=high_res_resample
197
+ )
198
+ high_res_resized_images_grouped[shape] = stacked_high_res_images
199
+ high_res_resized_images = reorder_images(high_res_resized_images_grouped, grouped_images_index)
200
+
201
+ # Group images by size for further processing
202
+ # Needed in case do_resize is False, or resize returns images with different sizes
203
+ grouped_high_res_images, grouped_high_res_images_index = group_images_by_shape(
204
+ high_res_resized_images, disable_grouping=disable_grouping
205
+ )
206
+ high_res_padded_images = {}
207
+ high_res_processed_images_grouped = {}
208
+ for shape, stacked_high_res_images in grouped_high_res_images.items():
209
+ if do_pad:
210
+ stacked_high_res_images = self.pad_to_square(
211
+ stacked_high_res_images, background_color=self.high_res_background_color
212
+ )
213
+ high_res_padded_images[shape] = stacked_high_res_images
214
+ # Fused rescale and normalize
215
+ stacked_high_res_images = self.rescale_and_normalize(
216
+ stacked_high_res_images,
217
+ do_rescale,
218
+ rescale_factor,
219
+ do_normalize,
220
+ high_res_image_mean,
221
+ high_res_image_std,
222
+ )
223
+ high_res_processed_images_grouped[shape] = stacked_high_res_images
224
+ high_res_processed_images = reorder_images(high_res_processed_images_grouped, grouped_high_res_images_index)
225
+
226
+ resized_images_grouped = {}
227
+ for shape, stacked_high_res_padded_images in high_res_padded_images.items():
228
+ if do_resize:
229
+ stacked_images = self.resize(
230
+ image=stacked_high_res_padded_images, size=size, min_size=min_size, resample=resample
231
+ )
232
+ resized_images_grouped[shape] = stacked_images
233
+ resized_images = reorder_images(resized_images_grouped, grouped_high_res_images_index)
234
+
235
+ grouped_resized_images, grouped_resized_images_index = group_images_by_shape(
236
+ resized_images, disable_grouping=disable_grouping
237
+ )
238
+ processed_images_grouped = {}
239
+ for shape, stacked_images in grouped_resized_images.items():
240
+ if do_pad:
241
+ stacked_images = self.pad_to_square(stacked_images, background_color=self.background_color)
242
+ # Fused rescale and normalize
243
+ stacked_images = self.rescale_and_normalize(
244
+ stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std
245
+ )
246
+ processed_images_grouped[shape] = stacked_images
247
+ processed_images = reorder_images(processed_images_grouped, grouped_resized_images_index)
248
+
249
+ return BatchFeature(
250
+ data={"pixel_values": processed_images, "high_res_pixel_values": high_res_processed_images},
251
+ tensor_type=return_tensors,
252
+ )
253
+
254
+ def postprocess(self) -> "torch.Tensor":
255
+ raise AttributeError("Not needed for DeepseekVLHybrid")
256
+
257
+ def _standardize_kwargs(
258
+ self,
259
+ size: int | Iterable[int] | dict[str, int] | SizeDict | None = None,
260
+ high_res_size: int | Iterable[int] | dict[str, int] | SizeDict | None = None,
261
+ default_to_square: bool | None = None,
262
+ image_mean: float | list[float] | None = None,
263
+ image_std: float | list[float] | None = None,
264
+ high_res_image_mean: float | list[float] | None = None,
265
+ high_res_image_std: float | list[float] | None = None,
266
+ **kwargs,
267
+ ) -> dict:
268
+ """
269
+ Update kwargs that need further processing before being validated
270
+ Can be overridden by subclasses to customize the processing of kwargs.
271
+ """
272
+ if kwargs is None:
273
+ kwargs = {}
274
+ if size is not None and not isinstance(size, SizeDict):
275
+ size = SizeDict(**get_size_dict(size=size, default_to_square=default_to_square))
276
+ if high_res_size is not None and not isinstance(high_res_size, SizeDict):
277
+ high_res_size = SizeDict(**get_size_dict(size=high_res_size, default_to_square=default_to_square))
278
+ if isinstance(image_mean, list):
279
+ image_mean = tuple(image_mean)
280
+ if isinstance(image_std, list):
281
+ image_std = tuple(image_std)
282
+ if isinstance(high_res_image_mean, list):
283
+ high_res_image_mean = tuple(high_res_image_mean)
284
+ if isinstance(high_res_image_std, list):
285
+ high_res_image_std = tuple(high_res_image_std)
286
+
287
+ kwargs["size"] = size
288
+ kwargs["high_res_size"] = high_res_size
289
+ kwargs["image_mean"] = image_mean
290
+ kwargs["image_std"] = image_std
291
+ kwargs["high_res_image_mean"] = high_res_image_mean
292
+ kwargs["high_res_image_std"] = high_res_image_std
293
+
294
+ return kwargs
295
+
296
+
297
+ __all__ = ["DeepseekVLHybridImageProcessor"]
third_party/transformers/src/transformers/models/deepseek_vl_hybrid/image_processing_pil_deepseek_vl_hybrid.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.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_deepseek_vl_hybrid.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 Deepseek AI and The HuggingFace Team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ from collections.abc import Iterable
22
+ from typing import Union
23
+
24
+ import numpy as np
25
+
26
+ from ...image_processing_backends import PilBackend
27
+ from ...image_processing_utils import BatchFeature, get_size_dict
28
+ from ...image_transforms import resize as np_resize
29
+ from ...image_utils import (
30
+ OPENAI_CLIP_MEAN,
31
+ OPENAI_CLIP_STD,
32
+ ChannelDimension,
33
+ ImageInput,
34
+ PILImageResampling,
35
+ SizeDict,
36
+ )
37
+ from ...processing_utils import ImagesKwargs, Unpack
38
+ from ...utils import TensorType, auto_docstring
39
+
40
+
41
+ class DeepseekVLHybridImageProcessorKwargs(ImagesKwargs, total=False):
42
+ r"""
43
+ min_size (`int`, *optional*, defaults to 14):
44
+ The minimum allowed size for the resized image. Ensures that neither the height nor width
45
+ falls below this value after resizing.
46
+ high_res_size (`dict`, *optional*, defaults to `{"height": 1024, "width": 1024}`):
47
+ Size of the high resolution output image after resizing. Can be overridden by the `high_res_size` parameter in the `preprocess`
48
+ method.
49
+ high_res_resample (`PILImageResampling`, *optional*, defaults to `Resampling.BICUBIC`):
50
+ Resampling filter to use if resizing the image. Only has an effect if `do_resize` is set to `True`. Can be
51
+ overridden by the `high_res_resample` parameter in the `preprocess` method.
52
+ high_res_image_mean (`float` or `list[float]`, *optional*, defaults to `OPENAI_CLIP_MEAN`):
53
+ Mean to use if normalizing the high resolution image. This is a float or list of floats the length of the number of
54
+ channels in the image. Can be overridden by the `high_res_image_mean` parameter in the `preprocess` method.
55
+ high_res_image_std (`float` or `list[float]`, *optional*, defaults to `OPENAI_CLIP_STD`):
56
+ Standard deviation to use if normalizing the high resolution image. This is a float or list of floats the length of the
57
+ number of channels in the image. Can be overridden by the `high_res_image_std` parameter in the `preprocess` method.
58
+ """
59
+
60
+ min_size: int
61
+ high_res_size: dict
62
+ high_res_resample: Union["PILImageResampling", int]
63
+ high_res_image_mean: float | list[float] | tuple[float, ...]
64
+ high_res_image_std: float | list[float] | tuple[float, ...]
65
+
66
+
67
+ @auto_docstring
68
+ class DeepseekVLHybridImageProcessorPil(PilBackend):
69
+ resample = PILImageResampling.BICUBIC
70
+ image_mean = OPENAI_CLIP_MEAN
71
+ image_std = OPENAI_CLIP_STD
72
+ size = {"height": 384, "width": 384}
73
+ min_size = 14
74
+ do_resize = True
75
+ do_rescale = True
76
+ do_normalize = True
77
+ do_pad = True
78
+ valid_kwargs = DeepseekVLHybridImageProcessorKwargs
79
+ high_res_image_mean = OPENAI_CLIP_MEAN
80
+ high_res_image_std = OPENAI_CLIP_STD
81
+ high_res_size = {"height": 1024, "width": 1024}
82
+ high_res_resample = PILImageResampling.BICUBIC
83
+ model_input_names = ["pixel_values", "high_res_pixel_values"]
84
+
85
+ def __init__(self, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]):
86
+ if kwargs.get("image_mean") is None:
87
+ background_color = (127, 127, 127)
88
+ else:
89
+ background_color = tuple(int(x * 255) for x in kwargs.get("image_mean"))
90
+ if kwargs.get("high_res_image_mean") is None:
91
+ high_res_background_color = (127, 127, 127)
92
+ else:
93
+ high_res_background_color = tuple(int(x * 255) for x in kwargs.get("high_res_image_mean"))
94
+ super().__init__(**kwargs)
95
+ self.background_color = tuple(background_color)
96
+ self.high_res_background_color = tuple(high_res_background_color)
97
+
98
+ @auto_docstring
99
+ def preprocess(self, images: ImageInput, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]) -> BatchFeature:
100
+ return super().preprocess(images, **kwargs)
101
+
102
+ def resize(
103
+ self,
104
+ image: np.ndarray,
105
+ size: SizeDict,
106
+ min_size: int,
107
+ resample: PILImageResampling | None = None,
108
+ **kwargs,
109
+ ) -> np.ndarray:
110
+ """Resize so largest side becomes size, with min_size floor."""
111
+ if size.height is None or size.width is None or size.height != size.width:
112
+ raise ValueError(
113
+ f"Output height and width must be the same. Got height={size.height} and width={size.width}"
114
+ )
115
+ target_size = size.height
116
+
117
+ height, width = image.shape[-2:]
118
+ max_size = max(height, width)
119
+
120
+ delta = target_size / max_size
121
+ new_height = max(round(height * delta), min_size)
122
+ new_width = max(round(width * delta), min_size)
123
+
124
+ return np_resize(
125
+ image,
126
+ size=(new_height, new_width),
127
+ resample=resample or self.resample,
128
+ data_format=ChannelDimension.FIRST,
129
+ input_data_format=ChannelDimension.FIRST,
130
+ )
131
+
132
+ def pad_to_square(
133
+ self,
134
+ image: np.ndarray,
135
+ background_color: int | tuple[int, int, int] = 0,
136
+ ) -> np.ndarray:
137
+ """Pad an image to a square based on the longest edge."""
138
+ height, width = image.shape[-2:]
139
+ num_channels = image.shape[0]
140
+
141
+ if height == width:
142
+ return image
143
+
144
+ max_dim = max(height, width)
145
+
146
+ if isinstance(background_color, int):
147
+ background_color = [background_color]
148
+ elif len(background_color) != num_channels:
149
+ raise ValueError(
150
+ f"background_color must have no more than {num_channels} elements to match the number of channels"
151
+ )
152
+
153
+ padded_image = np.zeros((num_channels, max_dim, max_dim), dtype=image.dtype)
154
+ for i, color in enumerate(background_color):
155
+ padded_image[i, :, :] = color
156
+
157
+ if width > height:
158
+ start = (max_dim - height) // 2
159
+ padded_image[:, start : start + height, :] = image
160
+ else:
161
+ start = (max_dim - width) // 2
162
+ padded_image[:, :, start : start + width] = image
163
+
164
+ return padded_image
165
+
166
+ def _preprocess(
167
+ self,
168
+ images: list[np.ndarray],
169
+ do_resize: bool,
170
+ size: SizeDict,
171
+ high_res_size: SizeDict,
172
+ min_size: int,
173
+ resample: "PILImageResampling | None",
174
+ high_res_resample: "PILImageResampling | None",
175
+ do_rescale: bool,
176
+ rescale_factor: float,
177
+ do_normalize: bool,
178
+ image_mean: float | list[float] | None,
179
+ image_std: float | list[float] | None,
180
+ high_res_image_mean: float | list[float] | None,
181
+ high_res_image_std: float | list[float] | None,
182
+ return_tensors: str | TensorType | None,
183
+ do_pad: bool = True,
184
+ **kwargs,
185
+ ) -> BatchFeature:
186
+ high_res_processed_images = []
187
+ processed_images = []
188
+ for image in images:
189
+ # high_res_image: resize (high) -> rescale -> normalize (high)
190
+ # low_res_image: resize (high) -> rescale -> resize (low) -> normalize (low)
191
+ high_res_image = image
192
+ if do_resize:
193
+ high_res_image = self.resize(
194
+ image=high_res_image, size=high_res_size, min_size=min_size, resample=high_res_resample
195
+ )
196
+ if do_pad:
197
+ high_res_image = self.pad_to_square(
198
+ high_res_image, background_color=self.high_res_background_color
199
+ )
200
+ image = self.resize(image=high_res_image, size=size, min_size=min_size, resample=resample)
201
+ if do_pad:
202
+ image = self.pad_to_square(image, background_color=self.background_color)
203
+ if do_rescale:
204
+ high_res_image = self.rescale(high_res_image, rescale_factor)
205
+ image = self.rescale(image, rescale_factor)
206
+ if do_normalize:
207
+ high_res_image = self.normalize(high_res_image, high_res_image_mean, high_res_image_std)
208
+ image = self.normalize(image, image_mean, image_std)
209
+ processed_images.append(image)
210
+ high_res_processed_images.append(high_res_image)
211
+
212
+ return BatchFeature(
213
+ data={"pixel_values": processed_images, "high_res_pixel_values": high_res_processed_images},
214
+ tensor_type=return_tensors,
215
+ )
216
+
217
+ def postprocess(self):
218
+ """Applies post-processing to the decoded image tokens by reversing transformations applied during preprocessing."""
219
+ raise AttributeError("Not needed for DeepseekVLHybrid")
220
+
221
+ def _standardize_kwargs(
222
+ self,
223
+ size: int | Iterable[int] | dict[str, int] | SizeDict | None = None,
224
+ high_res_size: int | Iterable[int] | dict[str, int] | SizeDict | None = None,
225
+ default_to_square: bool | None = None,
226
+ image_mean: float | list[float] | None = None,
227
+ image_std: float | list[float] | None = None,
228
+ high_res_image_mean: float | list[float] | None = None,
229
+ high_res_image_std: float | list[float] | None = None,
230
+ **kwargs,
231
+ ) -> dict:
232
+ """
233
+ Update kwargs that need further processing before being validated
234
+ Can be overridden by subclasses to customize the processing of kwargs.
235
+ """
236
+ if kwargs is None:
237
+ kwargs = {}
238
+ if size is not None and not isinstance(size, SizeDict):
239
+ size = SizeDict(**get_size_dict(size=size, default_to_square=default_to_square))
240
+ if high_res_size is not None and not isinstance(high_res_size, SizeDict):
241
+ high_res_size = SizeDict(**get_size_dict(size=high_res_size, default_to_square=default_to_square))
242
+ if isinstance(image_mean, list):
243
+ image_mean = tuple(image_mean)
244
+ if isinstance(image_std, list):
245
+ image_std = tuple(image_std)
246
+ if isinstance(high_res_image_mean, list):
247
+ high_res_image_mean = tuple(high_res_image_mean)
248
+ if isinstance(high_res_image_std, list):
249
+ high_res_image_std = tuple(high_res_image_std)
250
+
251
+ kwargs["size"] = size
252
+ kwargs["high_res_size"] = high_res_size
253
+ kwargs["image_mean"] = image_mean
254
+ kwargs["image_std"] = image_std
255
+ kwargs["high_res_image_mean"] = high_res_image_mean
256
+ kwargs["high_res_image_std"] = high_res_image_std
257
+
258
+ return kwargs
259
+
260
+
261
+ __all__ = ["DeepseekVLHybridImageProcessorPil"]
third_party/transformers/src/transformers/models/deepseek_vl_hybrid/modeling_deepseek_vl_hybrid.py ADDED
@@ -0,0 +1,539 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.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_deepseek_vl_hybrid.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 Deepseek AI and The HuggingFace Team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ from dataclasses import dataclass
22
+
23
+ import torch
24
+ import torch.nn as nn
25
+
26
+ from ... import initialization as init
27
+ from ...cache_utils import Cache
28
+ from ...generation import GenerationMixin
29
+ from ...modeling_outputs import BaseModelOutputWithPooling, ModelOutput
30
+ from ...modeling_utils import PreTrainedModel
31
+ from ...processing_utils import Unpack
32
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, torch_compilable_check
33
+ from ..auto import AutoModel
34
+ from .configuration_deepseek_vl_hybrid import DeepseekVLHybridConfig
35
+
36
+
37
+ @dataclass
38
+ @auto_docstring
39
+ class BaseModelOutputWithHighResVisionEncodings(BaseModelOutputWithPooling):
40
+ r"""
41
+ high_res_vision_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
42
+ Sequence of hidden-states at the output of the last layer of the high resolution vision model.
43
+ high_res_vision_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
44
+ Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the high resolution vision model has an embedding layer, +
45
+ one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`.
46
+
47
+ Hidden-states of the high resolution vision model at the output of each layer plus the optional initial embedding outputs.
48
+ high_res_vision_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`):
49
+ Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
50
+ sequence_length)` from the high resolution vision model.
51
+
52
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
53
+ heads.
54
+ """
55
+
56
+ high_res_vision_last_hidden_state: torch.FloatTensor | None = None
57
+ high_res_vision_hidden_states: tuple[torch.FloatTensor] | None = None
58
+ high_res_vision_attentions: tuple[torch.FloatTensor] | None = None
59
+
60
+
61
+ @dataclass
62
+ @auto_docstring(
63
+ custom_intro="""
64
+ Base class for DeepseekVLHybrid model's outputs that may also contain a past key/values (to speed up sequential decoding).
65
+ """
66
+ )
67
+ class DeepseekVLHybridBaseModelOutputWithPast(ModelOutput):
68
+ r"""
69
+ last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
70
+ Sequence of hidden-states at the output of the last layer of the model.
71
+
72
+ If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1,
73
+ hidden_size)` is output.
74
+ past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
75
+ It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
76
+
77
+ Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if
78
+ `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values`
79
+ input) to speed up sequential decoding.
80
+ image_hidden_states (`tuple(torch.FloatTensor)`, *optional*):
81
+ Tuple of `torch.FloatTensor` (one for the output of the image embeddings, `(batch_size, num_images,
82
+ sequence_length, hidden_size)`.
83
+
84
+ image_hidden_states of the model produced by the vision encoder, and optionally by the perceiver
85
+ """
86
+
87
+ last_hidden_state: torch.FloatTensor | None = None
88
+ past_key_values: Cache | None = None
89
+ hidden_states: tuple[torch.FloatTensor] | None = None
90
+ attentions: tuple[torch.FloatTensor] | None = None
91
+ image_hidden_states: tuple[torch.FloatTensor] | None = None
92
+
93
+
94
+ @dataclass
95
+ @auto_docstring(
96
+ custom_intro="""
97
+ Base class for DeepseekVLHybrid causal language model (or autoregressive) outputs.
98
+ """
99
+ )
100
+ class DeepseekVLHybridCausalLMOutputWithPast(ModelOutput):
101
+ r"""
102
+ loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
103
+ Language modeling loss (for next-token prediction).
104
+ logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
105
+ Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
106
+ past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
107
+ It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
108
+
109
+ Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
110
+ `past_key_values` input) to speed up sequential decoding.
111
+ image_hidden_states (`tuple(torch.FloatTensor)`, *optional*):
112
+ Tuple of `torch.FloatTensor` (one for the output of the image embeddings, `(batch_size, num_images,
113
+ sequence_length, hidden_size)`.
114
+
115
+ image_hidden_states of the model produced by the vision encoder, and optionally by the perceiver
116
+ """
117
+
118
+ loss: torch.FloatTensor | None = None
119
+ logits: torch.FloatTensor | None = None
120
+ past_key_values: Cache | None = None
121
+ hidden_states: tuple[torch.FloatTensor] | None = None
122
+ attentions: tuple[torch.FloatTensor] | None = None
123
+ image_hidden_states: tuple[torch.FloatTensor] | None = None
124
+
125
+
126
+ class DeepseekVLHybridLayerNorm(nn.LayerNorm):
127
+ r"""LayerNorm that supports two data formats: channels_last (default) or channels_first.
128
+ The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height,
129
+ width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width).
130
+ """
131
+
132
+ def __init__(self, normalized_shape, *, eps=1e-6, data_format="channels_last", **kwargs):
133
+ super().__init__(normalized_shape, eps=eps, **kwargs)
134
+ if data_format not in ["channels_last", "channels_first"]:
135
+ raise NotImplementedError(f"Unsupported data format: {data_format}")
136
+ self.data_format = data_format
137
+
138
+ def forward(self, features: torch.Tensor) -> torch.Tensor:
139
+ """
140
+ Args:
141
+ features: Tensor of shape (batch_size, channels, height, width) OR (batch_size, height, width, channels)
142
+ """
143
+ if self.data_format == "channels_first":
144
+ features = features.permute(0, 2, 3, 1)
145
+ features = super().forward(features)
146
+ features = features.permute(0, 3, 1, 2)
147
+ else:
148
+ features = super().forward(features)
149
+ return features
150
+
151
+
152
+ class DeepseekVLSamVisionNeck(nn.Module):
153
+ def __init__(self, config):
154
+ super().__init__()
155
+ self.config = config
156
+
157
+ self.conv1 = nn.Conv2d(config.hidden_size, config.output_channels, kernel_size=1, bias=False)
158
+ self.layer_norm1 = DeepseekVLHybridLayerNorm(config.output_channels, data_format="channels_first")
159
+ self.conv2 = nn.Conv2d(config.output_channels, config.output_channels, kernel_size=3, padding=1, bias=False)
160
+ self.layer_norm2 = DeepseekVLHybridLayerNorm(config.output_channels, data_format="channels_first")
161
+
162
+ def forward(self, hidden_states):
163
+ hidden_states = hidden_states.permute(0, 3, 1, 2)
164
+ hidden_states = self.conv1(hidden_states)
165
+ hidden_states = self.layer_norm1(hidden_states)
166
+
167
+ hidden_states = self.conv2(hidden_states)
168
+ hidden_states = self.layer_norm2(hidden_states)
169
+ return hidden_states
170
+
171
+
172
+ class DeepseekVLSamVisionProj(nn.Module):
173
+ def __init__(self, config, output_size: int = 24):
174
+ super().__init__()
175
+ self.config = config
176
+ self.output_size = output_size
177
+
178
+ self.conv1 = nn.Conv2d(
179
+ config.output_channels, config.output_channels * 2, kernel_size=3, stride=2, padding=1, bias=False
180
+ )
181
+ self.conv2 = nn.Conv2d(
182
+ config.output_channels * 2, config.output_channels * 4, kernel_size=3, stride=2, padding=1, bias=False
183
+ )
184
+
185
+ def forward(self, features: torch.Tensor) -> torch.Tensor:
186
+ # interpolate Sam encodings to match Siglip encodings
187
+ features = torch.nn.functional.interpolate(
188
+ features,
189
+ size=(4 * self.output_size, 4 * self.output_size),
190
+ mode="bilinear",
191
+ align_corners=False,
192
+ )
193
+ features = self.conv1(features)
194
+ features = self.conv2(features)
195
+ return features
196
+
197
+
198
+ class DeepseekVLHybridAligner(nn.Module):
199
+ def __init__(self, config: DeepseekVLHybridConfig):
200
+ super().__init__()
201
+
202
+ in_channels = config.vision_config.hidden_size
203
+ high_res_in_channels = config.high_res_vision_config.output_channels * 4
204
+ out_channels = config.text_config.hidden_size
205
+
206
+ self.vision_proj = nn.Linear(in_channels, out_channels // 2)
207
+ self.high_res_vision_proj = nn.Linear(high_res_in_channels, out_channels // 2)
208
+
209
+ self.act = nn.GELU()
210
+ self.proj = nn.Linear(out_channels, out_channels)
211
+
212
+ def forward(
213
+ self,
214
+ vision_encodings: torch.Tensor,
215
+ high_res_vision_encodings: torch.Tensor,
216
+ ) -> torch.Tensor:
217
+ vision_encodings = self.vision_proj(vision_encodings)
218
+ high_res_vision_encodings = self.high_res_vision_proj(high_res_vision_encodings)
219
+
220
+ encodings = torch.concat([high_res_vision_encodings, vision_encodings], dim=-1)
221
+ encodings = self.act(encodings)
222
+ encodings = self.proj(encodings)
223
+
224
+ return encodings
225
+
226
+
227
+ @auto_docstring
228
+ class DeepseekVLHybridPreTrainedModel(PreTrainedModel):
229
+ config: DeepseekVLHybridConfig
230
+ base_model_prefix = "model"
231
+ input_modalities = ("image", "text")
232
+ supports_gradient_checkpointing = True
233
+ _no_split_modules = ["LlamaDecoderLayer"]
234
+ _skip_keys_device_placement = ["past_key_values", "causal_mask"]
235
+ _supports_flash_attn = True
236
+ _supports_sdpa = True
237
+
238
+ _can_compile_fullgraph = True
239
+
240
+ @torch.no_grad()
241
+ def _init_weights(self, module):
242
+ """Initialize the weights"""
243
+ if isinstance(module, nn.Linear):
244
+ init.normal_(module.weight, mean=0.0, std=self.config.text_config.initializer_range)
245
+ if module.bias is not None:
246
+ init.zeros_(module.bias)
247
+ elif isinstance(module, nn.Conv2d):
248
+ init.kaiming_normal_(module.weight, mode="fan_out", nonlinearity="relu")
249
+ if module.bias is not None:
250
+ init.zeros_(module.bias)
251
+ elif isinstance(module, DeepseekVLHybridLayerNorm):
252
+ init.ones_(module.weight)
253
+ init.zeros_(module.bias)
254
+ elif isinstance(module, DeepseekVLHybridModel):
255
+ init.zeros_(module.high_res_vision_alpha)
256
+
257
+
258
+ DEEPSEEK_VL_COMMON_CUSTOM_ARGS = r"""
259
+ high_res_pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size), *optional*):
260
+ The tensors corresponding to the input images. Pixel values can be obtained using
261
+ [`AutoImageProcessor`].
262
+ """
263
+
264
+
265
+ @auto_docstring
266
+ class DeepseekVLHybridModel(DeepseekVLHybridPreTrainedModel):
267
+ def __init__(self, config):
268
+ super().__init__(config)
269
+ self.output_size = config.vision_config.image_size // config.vision_config.patch_size
270
+ self.global_attn_index = config.high_res_vision_config.global_attn_indexes[0]
271
+
272
+ self.high_res_vision_model = AutoModel.from_config(config.high_res_vision_config)
273
+ self.high_res_vision_neck = DeepseekVLSamVisionNeck(config.high_res_vision_config)
274
+ self.high_res_vision_proj = DeepseekVLSamVisionProj(
275
+ config.high_res_vision_config, output_size=self.output_size
276
+ )
277
+ self.high_res_vision_alpha = nn.Parameter(torch.zeros(1))
278
+ self.config = config
279
+
280
+ self.vision_model = AutoModel.from_config(config.vision_config)
281
+ self.aligner = DeepseekVLHybridAligner(config)
282
+
283
+ self.language_model = AutoModel.from_config(config=config.text_config)
284
+
285
+ self.gradient_checkpointing = False
286
+ # Initialize weights and apply final processing.
287
+ self.post_init()
288
+
289
+ def get_input_embeddings(self):
290
+ return self.language_model.get_input_embeddings()
291
+
292
+ def set_input_embeddings(self, value):
293
+ self.language_model.set_input_embeddings(value)
294
+
295
+ @can_return_tuple
296
+ @auto_docstring(custom_args=DEEPSEEK_VL_COMMON_CUSTOM_ARGS)
297
+ def get_image_features(
298
+ self,
299
+ pixel_values: torch.FloatTensor,
300
+ high_res_pixel_values: torch.FloatTensor,
301
+ **kwargs: Unpack[TransformersKwargs],
302
+ ) -> tuple | BaseModelOutputWithHighResVisionEncodings:
303
+ low_res_outputs = self.get_low_res_image_features(pixel_values, **kwargs)
304
+ high_res_outputs = self.get_high_res_image_features(high_res_pixel_values, **kwargs)
305
+ image_features = self.aligner(low_res_outputs.last_hidden_state, high_res_outputs.last_hidden_state)
306
+
307
+ return BaseModelOutputWithHighResVisionEncodings(
308
+ last_hidden_state=low_res_outputs.last_hidden_state,
309
+ pooler_output=image_features,
310
+ hidden_states=low_res_outputs.hidden_states,
311
+ attentions=low_res_outputs.attentions,
312
+ high_res_vision_last_hidden_state=high_res_outputs.last_hidden_state,
313
+ high_res_vision_hidden_states=high_res_outputs.hidden_states,
314
+ high_res_vision_attentions=high_res_outputs.attentions,
315
+ )
316
+
317
+ def get_placeholder_mask(
318
+ self, input_ids: torch.LongTensor, inputs_embeds: torch.FloatTensor, image_features: torch.FloatTensor
319
+ ):
320
+ """
321
+ Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is
322
+ equal to the length of multimodal features. If the lengths are different, an error is raised.
323
+ """
324
+ if input_ids is None:
325
+ special_image_mask = inputs_embeds == self.get_input_embeddings()(
326
+ torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
327
+ )
328
+ special_image_mask = special_image_mask.all(-1)
329
+ else:
330
+ special_image_mask = input_ids == self.config.image_token_id
331
+
332
+ n_image_tokens = special_image_mask.sum()
333
+ n_image_features = image_features.shape[0] * image_features.shape[1]
334
+ special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
335
+ torch_compilable_check(
336
+ inputs_embeds[special_image_mask].numel() == image_features.numel(),
337
+ f"Image features and image tokens do not match, tokens: {n_image_tokens}, features: {n_image_features}",
338
+ )
339
+ return special_image_mask
340
+
341
+ @can_return_tuple
342
+ @auto_docstring(custom_args=DEEPSEEK_VL_COMMON_CUSTOM_ARGS)
343
+ def forward(
344
+ self,
345
+ input_ids: torch.LongTensor | None = None,
346
+ pixel_values: torch.FloatTensor | None = None,
347
+ high_res_pixel_values: torch.FloatTensor | None = None,
348
+ attention_mask: torch.Tensor | None = None,
349
+ position_ids: torch.LongTensor | None = None,
350
+ past_key_values: Cache | None = None,
351
+ inputs_embeds: torch.FloatTensor | None = None,
352
+ use_cache: bool | None = None,
353
+ logits_to_keep: int | torch.Tensor = 0,
354
+ **kwargs,
355
+ ) -> DeepseekVLHybridBaseModelOutputWithPast:
356
+ if (input_ids is None) ^ (inputs_embeds is not None):
357
+ raise ValueError(
358
+ "You cannot specify both input_ids and inputs_embeds at the same time, and must specify either one"
359
+ )
360
+
361
+ if pixel_values is not None and high_res_pixel_values is None:
362
+ raise ValueError("Both pixel_values and high_res_pixel_values should be specified at the same time")
363
+
364
+ if inputs_embeds is None:
365
+ inputs_embeds = self.get_input_embeddings()(input_ids)
366
+
367
+ if pixel_values is not None:
368
+ if input_ids is None:
369
+ image_attention_mask = inputs_embeds == self.get_input_embeddings()(
370
+ torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
371
+ )
372
+ image_attention_mask = image_attention_mask.all(-1)
373
+ else:
374
+ image_attention_mask = input_ids == self.config.image_token_id
375
+
376
+ image_attention_mask = image_attention_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
377
+ image_embeds = self.get_image_features(pixel_values, high_res_pixel_values, return_dict=True).pooler_output
378
+ image_features = image_embeds.reshape(-1, inputs_embeds.shape[-1])
379
+ image_features = image_features.to(inputs_embeds.device, inputs_embeds.dtype)
380
+ inputs_embeds = inputs_embeds.masked_scatter(image_attention_mask, image_features)
381
+
382
+ lm_output = self.language_model(
383
+ inputs_embeds=inputs_embeds,
384
+ attention_mask=attention_mask,
385
+ position_ids=position_ids,
386
+ past_key_values=past_key_values,
387
+ use_cache=use_cache,
388
+ logits_to_keep=logits_to_keep,
389
+ **kwargs,
390
+ )
391
+
392
+ return DeepseekVLHybridBaseModelOutputWithPast(
393
+ last_hidden_state=lm_output.last_hidden_state,
394
+ past_key_values=lm_output.past_key_values,
395
+ hidden_states=lm_output.hidden_states,
396
+ attentions=lm_output.attentions,
397
+ image_hidden_states=image_embeds if pixel_values is not None else None,
398
+ )
399
+
400
+ def get_low_res_image_features(self, pixel_values: torch.FloatTensor, **kwargs: Unpack[TransformersKwargs]):
401
+ return self.vision_model(pixel_values, return_dict=True, **kwargs)
402
+
403
+ def get_high_res_image_features(
404
+ self,
405
+ pixel_values: torch.FloatTensor,
406
+ output_hidden_states: bool | None = None,
407
+ **kwargs: Unpack[TransformersKwargs],
408
+ ):
409
+ high_res_outputs = self.high_res_vision_model(
410
+ pixel_values=pixel_values,
411
+ output_hidden_states=True, # Ignore arg on purpose
412
+ return_dict=True,
413
+ **kwargs,
414
+ )
415
+ last_hidden_state = high_res_outputs.last_hidden_state
416
+ last_hidden_state = self.high_res_vision_proj(last_hidden_state)
417
+
418
+ hidden_states = high_res_outputs.hidden_states
419
+ global_hidden_state = hidden_states[self.global_attn_index + 1] # +1 for embedding layer
420
+ global_hidden_state = self.high_res_vision_neck(global_hidden_state)
421
+ global_hidden_state = self.high_res_vision_proj(global_hidden_state)
422
+
423
+ output = last_hidden_state + global_hidden_state * self.high_res_vision_alpha
424
+
425
+ # batch_size, hidden_size, height, width -> batch_size, seq_len, hidden_size
426
+ output = output.permute(0, 2, 3, 1)
427
+ output = output.reshape(output.shape[0], -1, output.shape[-1])
428
+ high_res_outputs.last_hidden_state = output
429
+
430
+ return high_res_outputs
431
+
432
+
433
+ class DeepseekVLHybridForConditionalGeneration(DeepseekVLHybridPreTrainedModel, GenerationMixin):
434
+ _tied_weights_keys = {"lm_head.weight": "model.language_model.embed_tokens.weight"}
435
+ output_modalities = ("text",)
436
+ _can_compile_fullgraph = True
437
+
438
+ def __init__(self, config: DeepseekVLHybridConfig):
439
+ super().__init__(config)
440
+ self.config = config
441
+ self.model = DeepseekVLHybridModel(config)
442
+ self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False)
443
+
444
+ # Initialize weights and apply final processing.
445
+ self.post_init()
446
+
447
+ def get_input_embeddings(self):
448
+ return self.model.language_model.get_input_embeddings()
449
+
450
+ def set_input_embeddings(self, value):
451
+ self.model.language_model.set_input_embeddings(value)
452
+
453
+ @can_return_tuple
454
+ @auto_docstring(custom_args=DEEPSEEK_VL_COMMON_CUSTOM_ARGS)
455
+ def forward(
456
+ self,
457
+ input_ids: torch.LongTensor | None = None,
458
+ pixel_values: torch.FloatTensor | None = None,
459
+ high_res_pixel_values: torch.FloatTensor | None = None,
460
+ attention_mask: torch.Tensor | None = None,
461
+ position_ids: torch.LongTensor | None = None,
462
+ past_key_values: Cache | None = None,
463
+ inputs_embeds: torch.FloatTensor | None = None,
464
+ labels: torch.LongTensor | None = None,
465
+ use_cache: bool | None = None,
466
+ logits_to_keep: int | torch.Tensor = 0,
467
+ **kwargs: Unpack[TransformersKwargs],
468
+ ) -> DeepseekVLHybridCausalLMOutputWithPast:
469
+ r"""
470
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
471
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
472
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
473
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
474
+ """
475
+ outputs = self.model(
476
+ input_ids=input_ids,
477
+ pixel_values=pixel_values,
478
+ high_res_pixel_values=high_res_pixel_values,
479
+ attention_mask=attention_mask,
480
+ position_ids=position_ids,
481
+ past_key_values=past_key_values,
482
+ inputs_embeds=inputs_embeds,
483
+ use_cache=use_cache,
484
+ **kwargs,
485
+ )
486
+ hidden_states = outputs.last_hidden_state
487
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
488
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
489
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
490
+
491
+ loss = None
492
+ if labels is not None:
493
+ loss = self.loss_function(
494
+ logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size, **kwargs
495
+ )
496
+
497
+ return DeepseekVLHybridCausalLMOutputWithPast(
498
+ loss=loss,
499
+ logits=logits,
500
+ past_key_values=outputs.past_key_values,
501
+ hidden_states=outputs.hidden_states,
502
+ attentions=outputs.attentions,
503
+ image_hidden_states=outputs.image_hidden_states,
504
+ )
505
+
506
+ def prepare_inputs_for_generation(
507
+ self,
508
+ input_ids,
509
+ past_key_values=None,
510
+ inputs_embeds=None,
511
+ pixel_values=None,
512
+ high_res_pixel_values=None,
513
+ attention_mask=None,
514
+ logits_to_keep=None,
515
+ is_first_iteration=False,
516
+ **kwargs,
517
+ ):
518
+ model_inputs = super().prepare_inputs_for_generation(
519
+ input_ids,
520
+ past_key_values=past_key_values,
521
+ inputs_embeds=inputs_embeds,
522
+ attention_mask=attention_mask,
523
+ logits_to_keep=logits_to_keep,
524
+ is_first_iteration=is_first_iteration,
525
+ **kwargs,
526
+ )
527
+
528
+ if is_first_iteration or not kwargs.get("use_cache", True):
529
+ # Pixel values are used only in the first iteration if available
530
+ # In subsequent iterations, they are already merged with text and cached
531
+ # NOTE: first iteration doesn't have to be prefill, it can be the first
532
+ # iteration with a question and cached system prompt (continue generate from cache)
533
+ model_inputs["pixel_values"] = pixel_values
534
+ model_inputs["high_res_pixel_values"] = high_res_pixel_values
535
+
536
+ return model_inputs
537
+
538
+
539
+ __all__ = ["DeepseekVLHybridPreTrainedModel", "DeepseekVLHybridModel", "DeepseekVLHybridForConditionalGeneration"]
third_party/transformers/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py ADDED
@@ -0,0 +1,787 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Deepseek AI 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
+
15
+ from collections.abc import Iterable
16
+ from dataclasses import dataclass
17
+ from typing import Union
18
+
19
+ import numpy as np
20
+ import torch
21
+ import torch.nn as nn
22
+ from huggingface_hub.dataclasses import strict
23
+
24
+ from ... import initialization as init
25
+ from ...cache_utils import Cache
26
+ from ...configuration_utils import PreTrainedConfig
27
+ from ...image_processing_backends import PilBackend, TorchvisionBackend
28
+ from ...image_processing_utils import BatchFeature, get_size_dict
29
+ from ...image_transforms import group_images_by_shape, reorder_images
30
+ from ...image_utils import (
31
+ OPENAI_CLIP_MEAN,
32
+ OPENAI_CLIP_STD,
33
+ ImageInput,
34
+ PILImageResampling,
35
+ SizeDict,
36
+ )
37
+ from ...modeling_outputs import BaseModelOutputWithPooling
38
+ from ...processing_utils import ImagesKwargs, Unpack
39
+ from ...tokenization_utils_base import (
40
+ PreTokenizedInput,
41
+ TextInput,
42
+ )
43
+ from ...utils import (
44
+ TensorType,
45
+ TransformersKwargs,
46
+ auto_docstring,
47
+ can_return_tuple,
48
+ logging,
49
+ )
50
+ from ..auto import CONFIG_MAPPING, AutoConfig, AutoModel
51
+ from ..deepseek_vl.configuration_deepseek_vl import DeepseekVLConfig
52
+ from ..deepseek_vl.image_processing_deepseek_vl import DeepseekVLImageProcessor
53
+ from ..deepseek_vl.image_processing_pil_deepseek_vl import DeepseekVLImageProcessorPil
54
+ from ..deepseek_vl.modeling_deepseek_vl import (
55
+ DeepseekVLForConditionalGeneration,
56
+ DeepseekVLModel,
57
+ DeepseekVLPreTrainedModel,
58
+ )
59
+ from ..deepseek_vl.processing_deepseek_vl import DeepseekVLProcessor, DeepseekVLProcessorKwargs
60
+ from ..idefics.modeling_idefics import IdeficsBaseModelOutputWithPast, IdeficsCausalLMOutputWithPast
61
+ from ..sam.modeling_sam import SamLayerNorm, SamVisionNeck
62
+
63
+
64
+ logger = logging.get_logger(__name__)
65
+
66
+
67
+ DEEPSEEK_VL_COMMON_CUSTOM_ARGS = r"""
68
+ high_res_pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size), *optional*):
69
+ The tensors corresponding to the input images. Pixel values can be obtained using
70
+ [`AutoImageProcessor`].
71
+ """
72
+
73
+
74
+ @auto_docstring(checkpoint="deepseek-community/deepseek-vl-7b-chat")
75
+ @strict
76
+ class DeepseekVLHybridConfig(DeepseekVLConfig):
77
+ r"""
78
+ high_res_vision_config (`Union[AutoConfig, dict]`, *optional*, defaults to `SamVisionConfig`):
79
+ The config object or dictionary of the high resolution vision backbone.
80
+
81
+ Example:
82
+
83
+ ```python
84
+ >>> from transformers import DeepseekVLHybridConfig, DeepseekVLHybridModel
85
+
86
+ >>> # Initializing a DeepseekVLHybrid deepseek-community/deepseek-vl-7b-chat style configuration
87
+ >>> configuration = DeepseekVLHybridConfig()
88
+
89
+ >>> # Initializing a model (with random weights) from the deepseek-community/deepseek-vl-7b-chat style configuration
90
+ >>> model = DeepseekVLHybridModel(configuration)
91
+
92
+ >>> # Accessing the model configuration
93
+ >>> configuration = model.config
94
+ ```"""
95
+
96
+ model_type = "deepseek_vl_hybrid"
97
+ sub_configs = {"text_config": AutoConfig, "vision_config": AutoConfig, "high_res_vision_config": AutoConfig}
98
+
99
+ high_res_vision_config: dict | PreTrainedConfig | None = None
100
+
101
+ def __post_init__(self, **kwargs):
102
+ if self.high_res_vision_config is None:
103
+ self.high_res_vision_config = {}
104
+ logger.info("`high_res_vision_config` is `None`. Initializing the `SamVisionConfig` with default values.")
105
+
106
+ if isinstance(self.high_res_vision_config, dict):
107
+ self.high_res_vision_config["model_type"] = self.high_res_vision_config.get(
108
+ "model_type", "sam_vision_model"
109
+ )
110
+ self.high_res_vision_config = CONFIG_MAPPING[self.high_res_vision_config["model_type"]](
111
+ **self.high_res_vision_config
112
+ )
113
+
114
+ super().__post_init__(**kwargs)
115
+
116
+
117
+ @dataclass
118
+ @auto_docstring
119
+ class BaseModelOutputWithHighResVisionEncodings(BaseModelOutputWithPooling):
120
+ r"""
121
+ high_res_vision_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
122
+ Sequence of hidden-states at the output of the last layer of the high resolution vision model.
123
+ high_res_vision_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
124
+ Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the high resolution vision model has an embedding layer, +
125
+ one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`.
126
+
127
+ Hidden-states of the high resolution vision model at the output of each layer plus the optional initial embedding outputs.
128
+ high_res_vision_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`):
129
+ Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
130
+ sequence_length)` from the high resolution vision model.
131
+
132
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
133
+ heads.
134
+ """
135
+
136
+ high_res_vision_last_hidden_state: torch.FloatTensor | None = None
137
+ high_res_vision_hidden_states: tuple[torch.FloatTensor] | None = None
138
+ high_res_vision_attentions: tuple[torch.FloatTensor] | None = None
139
+
140
+
141
+ class DeepseekVLHybridBaseModelOutputWithPast(IdeficsBaseModelOutputWithPast):
142
+ pass
143
+
144
+
145
+ class DeepseekVLHybridCausalLMOutputWithPast(IdeficsCausalLMOutputWithPast):
146
+ pass
147
+
148
+
149
+ class DeepseekVLHybridLayerNorm(SamLayerNorm):
150
+ pass
151
+
152
+
153
+ class DeepseekVLSamVisionNeck(SamVisionNeck):
154
+ def __init__(self, config):
155
+ super().__init__(config)
156
+
157
+
158
+ class DeepseekVLSamVisionProj(nn.Module):
159
+ def __init__(self, config, output_size: int = 24):
160
+ super().__init__()
161
+ self.config = config
162
+ self.output_size = output_size
163
+
164
+ self.conv1 = nn.Conv2d(
165
+ config.output_channels, config.output_channels * 2, kernel_size=3, stride=2, padding=1, bias=False
166
+ )
167
+ self.conv2 = nn.Conv2d(
168
+ config.output_channels * 2, config.output_channels * 4, kernel_size=3, stride=2, padding=1, bias=False
169
+ )
170
+
171
+ def forward(self, features: torch.Tensor) -> torch.Tensor:
172
+ # interpolate Sam encodings to match Siglip encodings
173
+ features = torch.nn.functional.interpolate(
174
+ features,
175
+ size=(4 * self.output_size, 4 * self.output_size),
176
+ mode="bilinear",
177
+ align_corners=False,
178
+ )
179
+ features = self.conv1(features)
180
+ features = self.conv2(features)
181
+ return features
182
+
183
+
184
+ class DeepseekVLHybridAligner(nn.Module):
185
+ def __init__(self, config: DeepseekVLHybridConfig):
186
+ super().__init__()
187
+
188
+ in_channels = config.vision_config.hidden_size
189
+ high_res_in_channels = config.high_res_vision_config.output_channels * 4
190
+ out_channels = config.text_config.hidden_size
191
+
192
+ self.vision_proj = nn.Linear(in_channels, out_channels // 2)
193
+ self.high_res_vision_proj = nn.Linear(high_res_in_channels, out_channels // 2)
194
+
195
+ self.act = nn.GELU()
196
+ self.proj = nn.Linear(out_channels, out_channels)
197
+
198
+ def forward(
199
+ self,
200
+ vision_encodings: torch.Tensor,
201
+ high_res_vision_encodings: torch.Tensor,
202
+ ) -> torch.Tensor:
203
+ vision_encodings = self.vision_proj(vision_encodings)
204
+ high_res_vision_encodings = self.high_res_vision_proj(high_res_vision_encodings)
205
+
206
+ encodings = torch.concat([high_res_vision_encodings, vision_encodings], dim=-1)
207
+ encodings = self.act(encodings)
208
+ encodings = self.proj(encodings)
209
+
210
+ return encodings
211
+
212
+
213
+ class DeepseekVLHybridPreTrainedModel(DeepseekVLPreTrainedModel):
214
+ @torch.no_grad()
215
+ def _init_weights(self, module):
216
+ """Initialize the weights"""
217
+ if isinstance(module, nn.Linear):
218
+ init.normal_(module.weight, mean=0.0, std=self.config.text_config.initializer_range)
219
+ if module.bias is not None:
220
+ init.zeros_(module.bias)
221
+ elif isinstance(module, nn.Conv2d):
222
+ init.kaiming_normal_(module.weight, mode="fan_out", nonlinearity="relu")
223
+ if module.bias is not None:
224
+ init.zeros_(module.bias)
225
+ elif isinstance(module, DeepseekVLHybridLayerNorm):
226
+ init.ones_(module.weight)
227
+ init.zeros_(module.bias)
228
+ elif isinstance(module, DeepseekVLHybridModel):
229
+ init.zeros_(module.high_res_vision_alpha)
230
+
231
+
232
+ class DeepseekVLHybridModel(DeepseekVLModel):
233
+ def __init__(self, config):
234
+ self.output_size = config.vision_config.image_size // config.vision_config.patch_size
235
+ self.global_attn_index = config.high_res_vision_config.global_attn_indexes[0]
236
+
237
+ self.high_res_vision_model = AutoModel.from_config(config.high_res_vision_config)
238
+ self.high_res_vision_neck = DeepseekVLSamVisionNeck(config.high_res_vision_config)
239
+ self.high_res_vision_proj = DeepseekVLSamVisionProj(
240
+ config.high_res_vision_config, output_size=self.output_size
241
+ )
242
+ self.high_res_vision_alpha = nn.Parameter(torch.zeros(1))
243
+
244
+ super().__init__(config)
245
+
246
+ def get_low_res_image_features(self, pixel_values: torch.FloatTensor, **kwargs: Unpack[TransformersKwargs]):
247
+ return self.vision_model(pixel_values, return_dict=True, **kwargs)
248
+
249
+ def get_high_res_image_features(
250
+ self,
251
+ pixel_values: torch.FloatTensor,
252
+ output_hidden_states: bool | None = None,
253
+ **kwargs: Unpack[TransformersKwargs],
254
+ ):
255
+ high_res_outputs = self.high_res_vision_model(
256
+ pixel_values=pixel_values,
257
+ output_hidden_states=True, # Ignore arg on purpose
258
+ return_dict=True,
259
+ **kwargs,
260
+ )
261
+ last_hidden_state = high_res_outputs.last_hidden_state
262
+ last_hidden_state = self.high_res_vision_proj(last_hidden_state)
263
+
264
+ hidden_states = high_res_outputs.hidden_states
265
+ global_hidden_state = hidden_states[self.global_attn_index + 1] # +1 for embedding layer
266
+ global_hidden_state = self.high_res_vision_neck(global_hidden_state)
267
+ global_hidden_state = self.high_res_vision_proj(global_hidden_state)
268
+
269
+ output = last_hidden_state + global_hidden_state * self.high_res_vision_alpha
270
+
271
+ # batch_size, hidden_size, height, width -> batch_size, seq_len, hidden_size
272
+ output = output.permute(0, 2, 3, 1)
273
+ output = output.reshape(output.shape[0], -1, output.shape[-1])
274
+ high_res_outputs.last_hidden_state = output
275
+
276
+ return high_res_outputs
277
+
278
+ @can_return_tuple
279
+ @auto_docstring(custom_args=DEEPSEEK_VL_COMMON_CUSTOM_ARGS)
280
+ def get_image_features(
281
+ self,
282
+ pixel_values: torch.FloatTensor,
283
+ high_res_pixel_values: torch.FloatTensor,
284
+ **kwargs: Unpack[TransformersKwargs],
285
+ ) -> tuple | BaseModelOutputWithHighResVisionEncodings:
286
+ low_res_outputs = self.get_low_res_image_features(pixel_values, **kwargs)
287
+ high_res_outputs = self.get_high_res_image_features(high_res_pixel_values, **kwargs)
288
+ image_features = self.aligner(low_res_outputs.last_hidden_state, high_res_outputs.last_hidden_state)
289
+
290
+ return BaseModelOutputWithHighResVisionEncodings(
291
+ last_hidden_state=low_res_outputs.last_hidden_state,
292
+ pooler_output=image_features,
293
+ hidden_states=low_res_outputs.hidden_states,
294
+ attentions=low_res_outputs.attentions,
295
+ high_res_vision_last_hidden_state=high_res_outputs.last_hidden_state,
296
+ high_res_vision_hidden_states=high_res_outputs.hidden_states,
297
+ high_res_vision_attentions=high_res_outputs.attentions,
298
+ )
299
+
300
+ @can_return_tuple
301
+ @auto_docstring(custom_args=DEEPSEEK_VL_COMMON_CUSTOM_ARGS)
302
+ def forward(
303
+ self,
304
+ input_ids: torch.LongTensor | None = None,
305
+ pixel_values: torch.FloatTensor | None = None,
306
+ high_res_pixel_values: torch.FloatTensor | None = None,
307
+ attention_mask: torch.Tensor | None = None,
308
+ position_ids: torch.LongTensor | None = None,
309
+ past_key_values: Cache | None = None,
310
+ inputs_embeds: torch.FloatTensor | None = None,
311
+ use_cache: bool | None = None,
312
+ logits_to_keep: int | torch.Tensor = 0,
313
+ **kwargs,
314
+ ) -> DeepseekVLHybridBaseModelOutputWithPast:
315
+ if (input_ids is None) ^ (inputs_embeds is not None):
316
+ raise ValueError(
317
+ "You cannot specify both input_ids and inputs_embeds at the same time, and must specify either one"
318
+ )
319
+
320
+ if pixel_values is not None and high_res_pixel_values is None:
321
+ raise ValueError("Both pixel_values and high_res_pixel_values should be specified at the same time")
322
+
323
+ if inputs_embeds is None:
324
+ inputs_embeds = self.get_input_embeddings()(input_ids)
325
+
326
+ if pixel_values is not None:
327
+ if input_ids is None:
328
+ image_attention_mask = inputs_embeds == self.get_input_embeddings()(
329
+ torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
330
+ )
331
+ image_attention_mask = image_attention_mask.all(-1)
332
+ else:
333
+ image_attention_mask = input_ids == self.config.image_token_id
334
+
335
+ image_attention_mask = image_attention_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
336
+ image_embeds = self.get_image_features(pixel_values, high_res_pixel_values, return_dict=True).pooler_output
337
+ image_features = image_embeds.reshape(-1, inputs_embeds.shape[-1])
338
+ image_features = image_features.to(inputs_embeds.device, inputs_embeds.dtype)
339
+ inputs_embeds = inputs_embeds.masked_scatter(image_attention_mask, image_features)
340
+
341
+ lm_output = self.language_model(
342
+ inputs_embeds=inputs_embeds,
343
+ attention_mask=attention_mask,
344
+ position_ids=position_ids,
345
+ past_key_values=past_key_values,
346
+ use_cache=use_cache,
347
+ logits_to_keep=logits_to_keep,
348
+ **kwargs,
349
+ )
350
+
351
+ return DeepseekVLHybridBaseModelOutputWithPast(
352
+ last_hidden_state=lm_output.last_hidden_state,
353
+ past_key_values=lm_output.past_key_values,
354
+ hidden_states=lm_output.hidden_states,
355
+ attentions=lm_output.attentions,
356
+ image_hidden_states=image_embeds if pixel_values is not None else None,
357
+ )
358
+
359
+
360
+ class DeepseekVLHybridForConditionalGeneration(DeepseekVLForConditionalGeneration):
361
+ @can_return_tuple
362
+ @auto_docstring(custom_args=DEEPSEEK_VL_COMMON_CUSTOM_ARGS)
363
+ def forward(
364
+ self,
365
+ input_ids: torch.LongTensor | None = None,
366
+ pixel_values: torch.FloatTensor | None = None,
367
+ high_res_pixel_values: torch.FloatTensor | None = None,
368
+ attention_mask: torch.Tensor | None = None,
369
+ position_ids: torch.LongTensor | None = None,
370
+ past_key_values: Cache | None = None,
371
+ inputs_embeds: torch.FloatTensor | None = None,
372
+ labels: torch.LongTensor | None = None,
373
+ use_cache: bool | None = None,
374
+ logits_to_keep: int | torch.Tensor = 0,
375
+ **kwargs: Unpack[TransformersKwargs],
376
+ ) -> DeepseekVLHybridCausalLMOutputWithPast:
377
+ r"""
378
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
379
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
380
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
381
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
382
+ """
383
+ outputs = self.model(
384
+ input_ids=input_ids,
385
+ pixel_values=pixel_values,
386
+ high_res_pixel_values=high_res_pixel_values,
387
+ attention_mask=attention_mask,
388
+ position_ids=position_ids,
389
+ past_key_values=past_key_values,
390
+ inputs_embeds=inputs_embeds,
391
+ use_cache=use_cache,
392
+ **kwargs,
393
+ )
394
+ hidden_states = outputs.last_hidden_state
395
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
396
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
397
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
398
+
399
+ loss = None
400
+ if labels is not None:
401
+ loss = self.loss_function(
402
+ logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size, **kwargs
403
+ )
404
+
405
+ return DeepseekVLHybridCausalLMOutputWithPast(
406
+ loss=loss,
407
+ logits=logits,
408
+ past_key_values=outputs.past_key_values,
409
+ hidden_states=outputs.hidden_states,
410
+ attentions=outputs.attentions,
411
+ image_hidden_states=outputs.image_hidden_states,
412
+ )
413
+
414
+ def prepare_inputs_for_generation(
415
+ self,
416
+ input_ids,
417
+ past_key_values=None,
418
+ inputs_embeds=None,
419
+ pixel_values=None,
420
+ high_res_pixel_values=None,
421
+ attention_mask=None,
422
+ logits_to_keep=None,
423
+ is_first_iteration=False,
424
+ **kwargs,
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
+ model_inputs["high_res_pixel_values"] = high_res_pixel_values
443
+
444
+ return model_inputs
445
+
446
+
447
+ class DeepseekVLHybridImageProcessorKwargs(ImagesKwargs, total=False):
448
+ r"""
449
+ min_size (`int`, *optional*, defaults to 14):
450
+ The minimum allowed size for the resized image. Ensures that neither the height nor width
451
+ falls below this value after resizing.
452
+ high_res_size (`dict`, *optional*, defaults to `{"height": 1024, "width": 1024}`):
453
+ Size of the high resolution output image after resizing. Can be overridden by the `high_res_size` parameter in the `preprocess`
454
+ method.
455
+ high_res_resample (`PILImageResampling`, *optional*, defaults to `Resampling.BICUBIC`):
456
+ Resampling filter to use if resizing the image. Only has an effect if `do_resize` is set to `True`. Can be
457
+ overridden by the `high_res_resample` parameter in the `preprocess` method.
458
+ high_res_image_mean (`float` or `list[float]`, *optional*, defaults to `OPENAI_CLIP_MEAN`):
459
+ Mean to use if normalizing the high resolution image. This is a float or list of floats the length of the number of
460
+ channels in the image. Can be overridden by the `high_res_image_mean` parameter in the `preprocess` method.
461
+ high_res_image_std (`float` or `list[float]`, *optional*, defaults to `OPENAI_CLIP_STD`):
462
+ Standard deviation to use if normalizing the high resolution image. This is a float or list of floats the length of the
463
+ number of channels in the image. Can be overridden by the `high_res_image_std` parameter in the `preprocess` method.
464
+ """
465
+
466
+ min_size: int
467
+ high_res_size: dict
468
+ high_res_resample: Union["PILImageResampling", int]
469
+ high_res_image_mean: float | list[float] | tuple[float, ...]
470
+ high_res_image_std: float | list[float] | tuple[float, ...]
471
+
472
+
473
+ class DeepseekVLHybridImageProcessorPil(DeepseekVLImageProcessorPil):
474
+ high_res_image_mean = OPENAI_CLIP_MEAN
475
+ high_res_image_std = OPENAI_CLIP_STD
476
+ high_res_size = {"height": 1024, "width": 1024}
477
+ high_res_resample = PILImageResampling.BICUBIC
478
+ model_input_names = ["pixel_values", "high_res_pixel_values"]
479
+
480
+ def __init__(self, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]):
481
+ if kwargs.get("image_mean") is None:
482
+ background_color = (127, 127, 127)
483
+ else:
484
+ background_color = tuple(int(x * 255) for x in kwargs.get("image_mean"))
485
+ if kwargs.get("high_res_image_mean") is None:
486
+ high_res_background_color = (127, 127, 127)
487
+ else:
488
+ high_res_background_color = tuple(int(x * 255) for x in kwargs.get("high_res_image_mean"))
489
+ PilBackend.__init__(self, **kwargs)
490
+ self.background_color = tuple(background_color)
491
+ self.high_res_background_color = tuple(high_res_background_color)
492
+
493
+ def _standardize_kwargs(
494
+ self,
495
+ size: int | Iterable[int] | dict[str, int] | SizeDict | None = None,
496
+ high_res_size: int | Iterable[int] | dict[str, int] | SizeDict | None = None,
497
+ default_to_square: bool | None = None,
498
+ image_mean: float | list[float] | None = None,
499
+ image_std: float | list[float] | None = None,
500
+ high_res_image_mean: float | list[float] | None = None,
501
+ high_res_image_std: float | list[float] | None = None,
502
+ **kwargs,
503
+ ) -> dict:
504
+ """
505
+ Update kwargs that need further processing before being validated
506
+ Can be overridden by subclasses to customize the processing of kwargs.
507
+ """
508
+ if kwargs is None:
509
+ kwargs = {}
510
+ if size is not None and not isinstance(size, SizeDict):
511
+ size = SizeDict(**get_size_dict(size=size, default_to_square=default_to_square))
512
+ if high_res_size is not None and not isinstance(high_res_size, SizeDict):
513
+ high_res_size = SizeDict(**get_size_dict(size=high_res_size, default_to_square=default_to_square))
514
+ if isinstance(image_mean, list):
515
+ image_mean = tuple(image_mean)
516
+ if isinstance(image_std, list):
517
+ image_std = tuple(image_std)
518
+ if isinstance(high_res_image_mean, list):
519
+ high_res_image_mean = tuple(high_res_image_mean)
520
+ if isinstance(high_res_image_std, list):
521
+ high_res_image_std = tuple(high_res_image_std)
522
+
523
+ kwargs["size"] = size
524
+ kwargs["high_res_size"] = high_res_size
525
+ kwargs["image_mean"] = image_mean
526
+ kwargs["image_std"] = image_std
527
+ kwargs["high_res_image_mean"] = high_res_image_mean
528
+ kwargs["high_res_image_std"] = high_res_image_std
529
+
530
+ return kwargs
531
+
532
+ def _preprocess(
533
+ self,
534
+ images: list[np.ndarray],
535
+ do_resize: bool,
536
+ size: SizeDict,
537
+ high_res_size: SizeDict,
538
+ min_size: int,
539
+ resample: "PILImageResampling | None",
540
+ high_res_resample: "PILImageResampling | None",
541
+ do_rescale: bool,
542
+ rescale_factor: float,
543
+ do_normalize: bool,
544
+ image_mean: float | list[float] | None,
545
+ image_std: float | list[float] | None,
546
+ high_res_image_mean: float | list[float] | None,
547
+ high_res_image_std: float | list[float] | None,
548
+ return_tensors: str | TensorType | None,
549
+ do_pad: bool = True,
550
+ **kwargs,
551
+ ) -> BatchFeature:
552
+ high_res_processed_images = []
553
+ processed_images = []
554
+ for image in images:
555
+ # high_res_image: resize (high) -> rescale -> normalize (high)
556
+ # low_res_image: resize (high) -> rescale -> resize (low) -> normalize (low)
557
+ high_res_image = image
558
+ if do_resize:
559
+ high_res_image = self.resize(
560
+ image=high_res_image, size=high_res_size, min_size=min_size, resample=high_res_resample
561
+ )
562
+ if do_pad:
563
+ high_res_image = self.pad_to_square(
564
+ high_res_image, background_color=self.high_res_background_color
565
+ )
566
+ image = self.resize(image=high_res_image, size=size, min_size=min_size, resample=resample)
567
+ if do_pad:
568
+ image = self.pad_to_square(image, background_color=self.background_color)
569
+ if do_rescale:
570
+ high_res_image = self.rescale(high_res_image, rescale_factor)
571
+ image = self.rescale(image, rescale_factor)
572
+ if do_normalize:
573
+ high_res_image = self.normalize(high_res_image, high_res_image_mean, high_res_image_std)
574
+ image = self.normalize(image, image_mean, image_std)
575
+ processed_images.append(image)
576
+ high_res_processed_images.append(high_res_image)
577
+
578
+ return BatchFeature(
579
+ data={"pixel_values": processed_images, "high_res_pixel_values": high_res_processed_images},
580
+ tensor_type=return_tensors,
581
+ )
582
+
583
+
584
+ class DeepseekVLHybridImageProcessor(DeepseekVLImageProcessor):
585
+ high_res_image_mean = OPENAI_CLIP_MEAN
586
+ high_res_image_std = OPENAI_CLIP_STD
587
+ high_res_size = {"height": 1024, "width": 1024}
588
+ high_res_resample = PILImageResampling.BICUBIC
589
+ model_input_names = ["pixel_values", "high_res_pixel_values"]
590
+
591
+ def __init__(self, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]):
592
+ if kwargs.get("image_mean") is None:
593
+ background_color = (127, 127, 127)
594
+ else:
595
+ background_color = tuple(int(x * 255) for x in kwargs.get("image_mean"))
596
+ if kwargs.get("high_res_image_mean") is None:
597
+ high_res_background_color = (127, 127, 127)
598
+ else:
599
+ high_res_background_color = tuple(int(x * 255) for x in kwargs.get("high_res_image_mean"))
600
+ TorchvisionBackend.__init__(self, **kwargs)
601
+ self.background_color = tuple(background_color)
602
+ self.high_res_background_color = tuple(high_res_background_color)
603
+
604
+ def _standardize_kwargs(
605
+ self,
606
+ size: int | Iterable[int] | dict[str, int] | SizeDict | None = None,
607
+ high_res_size: int | Iterable[int] | dict[str, int] | SizeDict | None = None,
608
+ default_to_square: bool | None = None,
609
+ image_mean: float | list[float] | None = None,
610
+ image_std: float | list[float] | None = None,
611
+ high_res_image_mean: float | list[float] | None = None,
612
+ high_res_image_std: float | list[float] | None = None,
613
+ **kwargs,
614
+ ) -> dict:
615
+ """
616
+ Update kwargs that need further processing before being validated
617
+ Can be overridden by subclasses to customize the processing of kwargs.
618
+ """
619
+ if kwargs is None:
620
+ kwargs = {}
621
+ if size is not None and not isinstance(size, SizeDict):
622
+ size = SizeDict(**get_size_dict(size=size, default_to_square=default_to_square))
623
+ if high_res_size is not None and not isinstance(high_res_size, SizeDict):
624
+ high_res_size = SizeDict(**get_size_dict(size=high_res_size, default_to_square=default_to_square))
625
+ if isinstance(image_mean, list):
626
+ image_mean = tuple(image_mean)
627
+ if isinstance(image_std, list):
628
+ image_std = tuple(image_std)
629
+ if isinstance(high_res_image_mean, list):
630
+ high_res_image_mean = tuple(high_res_image_mean)
631
+ if isinstance(high_res_image_std, list):
632
+ high_res_image_std = tuple(high_res_image_std)
633
+
634
+ kwargs["size"] = size
635
+ kwargs["high_res_size"] = high_res_size
636
+ kwargs["image_mean"] = image_mean
637
+ kwargs["image_std"] = image_std
638
+ kwargs["high_res_image_mean"] = high_res_image_mean
639
+ kwargs["high_res_image_std"] = high_res_image_std
640
+
641
+ return kwargs
642
+
643
+ def _preprocess(
644
+ self,
645
+ images: list["torch.Tensor"],
646
+ do_resize: bool,
647
+ size: SizeDict,
648
+ high_res_size: SizeDict,
649
+ min_size: int,
650
+ resample: "PILImageResampling | None",
651
+ high_res_resample: "PILImageResampling | None",
652
+ do_rescale: bool,
653
+ rescale_factor: float,
654
+ do_normalize: bool,
655
+ image_mean: float | list[float] | None,
656
+ image_std: float | list[float] | None,
657
+ high_res_image_mean: float | list[float] | None,
658
+ high_res_image_std: float | list[float] | None,
659
+ disable_grouping: bool | None,
660
+ return_tensors: str | TensorType | None,
661
+ do_pad: bool = True,
662
+ **kwargs,
663
+ ) -> BatchFeature:
664
+ # Group images by size for batched resizing
665
+ grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
666
+ high_res_resized_images_grouped = {}
667
+ for shape, stacked_images in grouped_images.items():
668
+ if do_resize:
669
+ stacked_high_res_images = self.resize(
670
+ image=stacked_images, size=high_res_size, min_size=min_size, resample=high_res_resample
671
+ )
672
+ high_res_resized_images_grouped[shape] = stacked_high_res_images
673
+ high_res_resized_images = reorder_images(high_res_resized_images_grouped, grouped_images_index)
674
+
675
+ # Group images by size for further processing
676
+ # Needed in case do_resize is False, or resize returns images with different sizes
677
+ grouped_high_res_images, grouped_high_res_images_index = group_images_by_shape(
678
+ high_res_resized_images, disable_grouping=disable_grouping
679
+ )
680
+ high_res_padded_images = {}
681
+ high_res_processed_images_grouped = {}
682
+ for shape, stacked_high_res_images in grouped_high_res_images.items():
683
+ if do_pad:
684
+ stacked_high_res_images = self.pad_to_square(
685
+ stacked_high_res_images, background_color=self.high_res_background_color
686
+ )
687
+ high_res_padded_images[shape] = stacked_high_res_images
688
+ # Fused rescale and normalize
689
+ stacked_high_res_images = self.rescale_and_normalize(
690
+ stacked_high_res_images,
691
+ do_rescale,
692
+ rescale_factor,
693
+ do_normalize,
694
+ high_res_image_mean,
695
+ high_res_image_std,
696
+ )
697
+ high_res_processed_images_grouped[shape] = stacked_high_res_images
698
+ high_res_processed_images = reorder_images(high_res_processed_images_grouped, grouped_high_res_images_index)
699
+
700
+ resized_images_grouped = {}
701
+ for shape, stacked_high_res_padded_images in high_res_padded_images.items():
702
+ if do_resize:
703
+ stacked_images = self.resize(
704
+ image=stacked_high_res_padded_images, size=size, min_size=min_size, resample=resample
705
+ )
706
+ resized_images_grouped[shape] = stacked_images
707
+ resized_images = reorder_images(resized_images_grouped, grouped_high_res_images_index)
708
+
709
+ grouped_resized_images, grouped_resized_images_index = group_images_by_shape(
710
+ resized_images, disable_grouping=disable_grouping
711
+ )
712
+ processed_images_grouped = {}
713
+ for shape, stacked_images in grouped_resized_images.items():
714
+ if do_pad:
715
+ stacked_images = self.pad_to_square(stacked_images, background_color=self.background_color)
716
+ # Fused rescale and normalize
717
+ stacked_images = self.rescale_and_normalize(
718
+ stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std
719
+ )
720
+ processed_images_grouped[shape] = stacked_images
721
+ processed_images = reorder_images(processed_images_grouped, grouped_resized_images_index)
722
+
723
+ return BatchFeature(
724
+ data={"pixel_values": processed_images, "high_res_pixel_values": high_res_processed_images},
725
+ tensor_type=return_tensors,
726
+ )
727
+
728
+
729
+ class DeepseekVLHybridProcessorKwargs(DeepseekVLProcessorKwargs):
730
+ pass
731
+
732
+
733
+ class DeepseekVLHybridProcessor(DeepseekVLProcessor):
734
+ def __call__(
735
+ self,
736
+ text: TextInput | PreTokenizedInput | list[TextInput] | list[PreTokenizedInput] = None,
737
+ images: ImageInput | None = None,
738
+ **kwargs: Unpack[DeepseekVLHybridProcessorKwargs],
739
+ ) -> BatchFeature:
740
+ r"""
741
+ Returns:
742
+ [`BatchFeature`]: A [`BatchFeature`] with the following fields:
743
+
744
+ - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`.
745
+ - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when
746
+ `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not
747
+ `None`).
748
+ - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`.
749
+ """
750
+ output_kwargs = self._merge_kwargs(
751
+ DeepseekVLHybridProcessorKwargs, tokenizer_init_kwargs=self.tokenizer.init_kwargs, **kwargs
752
+ )
753
+ if text is None and images is None:
754
+ raise ValueError("You must specify either text or images.")
755
+
756
+ if text is not None:
757
+ if isinstance(text, str):
758
+ text = [text]
759
+ elif not (isinstance(text, (list, tuple)) and all(isinstance(t, str) for t in text)):
760
+ raise ValueError("Invalid input text. Please provide a string, or a list of strings")
761
+
762
+ prompt_strings = []
763
+ one_img_tokens = self.image_token * self.num_image_tokens
764
+ for prompt in text:
765
+ prompt = prompt.replace(self.image_token, one_img_tokens)
766
+ prompt_strings.append(prompt)
767
+
768
+ data = self.tokenizer(prompt_strings, **output_kwargs["text_kwargs"])
769
+
770
+ # process images if pixel_values are provided
771
+ if images is not None:
772
+ inputs = self.image_processor(images, **output_kwargs["images_kwargs"])
773
+ data["pixel_values"] = inputs["pixel_values"]
774
+ data["high_res_pixel_values"] = inputs["high_res_pixel_values"]
775
+
776
+ return BatchFeature(data=data)
777
+
778
+
779
+ __all__ = [
780
+ "DeepseekVLHybridConfig",
781
+ "DeepseekVLHybridPreTrainedModel",
782
+ "DeepseekVLHybridModel",
783
+ "DeepseekVLHybridForConditionalGeneration",
784
+ "DeepseekVLHybridImageProcessor",
785
+ "DeepseekVLHybridImageProcessorPil",
786
+ "DeepseekVLHybridProcessor",
787
+ ]
third_party/transformers/src/transformers/models/deepseek_vl_hybrid/processing_deepseek_vl_hybrid.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.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_deepseek_vl_hybrid.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 Deepseek AI and The HuggingFace Team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ from ...image_processing_utils import BatchFeature
22
+ from ...image_utils import ImageInput
23
+ from ...processing_utils import ProcessingKwargs, ProcessorMixin, Unpack
24
+ from ...tokenization_utils_base import PreTokenizedInput, TextInput
25
+ from ...utils import auto_docstring
26
+
27
+
28
+ class DeepseekVLHybridProcessorKwargs(ProcessingKwargs, total=False):
29
+ _defaults = {
30
+ "text_kwargs": {"padding": False},
31
+ "common_kwargs": {"return_tensors": "pt"},
32
+ }
33
+
34
+
35
+ @auto_docstring
36
+ class DeepseekVLHybridProcessor(ProcessorMixin):
37
+ def __init__(
38
+ self,
39
+ image_processor,
40
+ tokenizer,
41
+ chat_template=None,
42
+ num_image_tokens=576,
43
+ ):
44
+ r"""
45
+ num_image_tokens (`int`, *optional*, defaults to 576):
46
+ The number of special image tokens used as placeholders for visual content in text sequences.
47
+ """
48
+ self.image_token = tokenizer.image_token
49
+ self.num_image_tokens = num_image_tokens
50
+
51
+ super().__init__(image_processor, tokenizer, chat_template=chat_template)
52
+
53
+ @auto_docstring
54
+ def __call__(
55
+ self,
56
+ text: TextInput | PreTokenizedInput | list[TextInput] | list[PreTokenizedInput] = None,
57
+ images: ImageInput | None = None,
58
+ **kwargs: Unpack[DeepseekVLHybridProcessorKwargs],
59
+ ) -> BatchFeature:
60
+ r"""
61
+ Returns:
62
+ [`BatchFeature`]: A [`BatchFeature`] with the following fields:
63
+
64
+ - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`.
65
+ - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when
66
+ `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not
67
+ `None`).
68
+ - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`.
69
+ """
70
+ output_kwargs = self._merge_kwargs(
71
+ DeepseekVLHybridProcessorKwargs, tokenizer_init_kwargs=self.tokenizer.init_kwargs, **kwargs
72
+ )
73
+ if text is None and images is None:
74
+ raise ValueError("You must specify either text or images.")
75
+
76
+ if text is not None:
77
+ if isinstance(text, str):
78
+ text = [text]
79
+ elif not (isinstance(text, (list, tuple)) and all(isinstance(t, str) for t in text)):
80
+ raise ValueError("Invalid input text. Please provide a string, or a list of strings")
81
+
82
+ prompt_strings = []
83
+ one_img_tokens = self.image_token * self.num_image_tokens
84
+ for prompt in text:
85
+ prompt = prompt.replace(self.image_token, one_img_tokens)
86
+ prompt_strings.append(prompt)
87
+
88
+ data = self.tokenizer(prompt_strings, **output_kwargs["text_kwargs"])
89
+
90
+ # process images if pixel_values are provided
91
+ if images is not None:
92
+ inputs = self.image_processor(images, **output_kwargs["images_kwargs"])
93
+ data["pixel_values"] = inputs["pixel_values"]
94
+ data["high_res_pixel_values"] = inputs["high_res_pixel_values"]
95
+
96
+ return BatchFeature(data=data)
97
+
98
+ def batch_decode(self, *args, **kwargs):
99
+ """
100
+ This method forwards all its arguments to LlamaTokenizerFast's [`~PreTrainedTokenizer.batch_decode`]. Please
101
+ refer to the docstring of this method for more information.
102
+ """
103
+ return self.tokenizer.batch_decode(*args, **kwargs)
104
+
105
+ def decode(self, *args, **kwargs):
106
+ """
107
+ This method forwards all its arguments to LlamaTokenizerFast's [`~PreTrainedTokenizer.decode`]. Please refer to
108
+ the docstring of this method for more information.
109
+ """
110
+ return self.tokenizer.decode(*args, **kwargs)
111
+
112
+ @property
113
+ def model_input_names(self):
114
+ tokenizer_input_names = self.tokenizer.model_input_names
115
+ image_processor_input_names = self.image_processor.model_input_names
116
+ return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names))
117
+
118
+
119
+ __all__ = ["DeepseekVLHybridProcessor"]
third_party/transformers/src/transformers/models/diffllama/__init__.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 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_diffllama import *
22
+ from .modeling_diffllama 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/diffllama/configuration_diffllama.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 weak-kajuma and the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # This code is based on Llama implementations in this library and Microsoft's
4
+ # Differential Transformer implementations.
5
+
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ """DiffLlama model configuration"""
18
+
19
+ from huggingface_hub.dataclasses import strict
20
+
21
+ from ...configuration_utils import PreTrainedConfig
22
+ from ...modeling_rope_utils import RopeParameters
23
+ from ...utils import auto_docstring
24
+
25
+
26
+ @auto_docstring(checkpoint="kajuma/DiffLlama-0.3B-handcut")
27
+ @strict
28
+ class DiffLlamaConfig(PreTrainedConfig):
29
+ r"""
30
+ lambda_std_dev (`float`, *optional*, defaults to 0.1):
31
+ The standard deviation for initialization of parameter lambda in attention layer.
32
+
33
+ ```python
34
+ >>> from transformers import DiffLlamaModel, DiffLlamaConfig
35
+
36
+ >>> # Initializing a DiffLlama diffllama-7b style configuration
37
+ >>> configuration = DiffLlamaConfig()
38
+
39
+ >>> # Initializing a model from the diffllama-7b style configuration
40
+ >>> model = DiffLlamaModel(configuration)
41
+
42
+ >>> # Accessing the model configuration
43
+ >>> configuration = model.config
44
+ ```
45
+ """
46
+
47
+ model_type = "diffllama"
48
+ keys_to_ignore_at_inference = ["past_key_values"]
49
+
50
+ vocab_size: int = 32000
51
+ hidden_size: int = 2048
52
+ intermediate_size: int = 8192
53
+ num_hidden_layers: int = 16
54
+ num_attention_heads: int = 32
55
+ num_key_value_heads: int | None = None
56
+ hidden_act: str = "silu"
57
+ max_position_embeddings: int = 2048
58
+ initializer_range: float = 0.02
59
+ rms_norm_eps: float = 1e-5
60
+ use_cache: bool = True
61
+ pad_token_id: int | None = None
62
+ bos_token_id: int | None = 1
63
+ eos_token_id: int | list[int] | None = 2
64
+ tie_word_embeddings: bool = False
65
+ rope_parameters: RopeParameters | dict | None = None
66
+ attention_bias: bool = False
67
+ attention_dropout: float | int | None = 0.0
68
+ lambda_std_dev: float | None = 0.1
69
+ head_dim: int | None = None
70
+
71
+ def __post_init__(self, **kwargs):
72
+ # for backward compatibility
73
+ if self.num_key_value_heads is None:
74
+ self.num_key_value_heads = self.num_attention_heads
75
+
76
+ self.head_dim = self.head_dim if self.head_dim is not None else self.hidden_size // self.num_attention_heads
77
+ super().__post_init__(**kwargs)
78
+
79
+
80
+ __all__ = ["DiffLlamaConfig"]
third_party/transformers/src/transformers/models/diffllama/modeling_diffllama.py ADDED
@@ -0,0 +1,753 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/diffllama/modular_diffllama.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_diffllama.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2024 weak-kajuma and the HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # This code is based on Llama implementations in this library and Microsoft's
10
+ # Differential Transformer implementations.
11
+
12
+ # Licensed under the Apache License, Version 2.0 (the "License");
13
+ # you may not use this file except in compliance with the License.
14
+ # You may obtain a copy of the License at
15
+ #
16
+ # http://www.apache.org/licenses/LICENSE-2.0
17
+ #
18
+ # Unless required by applicable law or agreed to in writing, software
19
+ # distributed under the License is distributed on an "AS IS" BASIS,
20
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ # See the License for the specific language governing permissions and
22
+ # limitations under the License.
23
+ import math
24
+ from collections.abc import Callable
25
+ from typing import Optional
26
+
27
+ import torch
28
+ from torch import nn
29
+
30
+ from ... import initialization as init
31
+ from ...activations import ACT2FN
32
+ from ...cache_utils import Cache, DynamicCache, StaticCache
33
+ from ...generation import GenerationMixin
34
+ from ...integrations import use_kernel_forward_from_hub, use_kernel_func_from_hub
35
+ from ...masking_utils import create_causal_mask
36
+ from ...modeling_flash_attention_utils import _flash_attention_forward, flash_attn_supports_top_left_mask
37
+ from ...modeling_layers import (
38
+ GenericForQuestionAnswering,
39
+ GenericForSequenceClassification,
40
+ GenericForTokenClassification,
41
+ GradientCheckpointingLayer,
42
+ )
43
+ from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
44
+ from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
45
+ from ...modeling_utils import PreTrainedModel
46
+ from ...processing_utils import Unpack
47
+ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging
48
+ from ...utils.generic import maybe_autocast, merge_with_config_defaults
49
+ from ...utils.output_capturing import capture_outputs
50
+ from .configuration_diffllama import DiffLlamaConfig
51
+
52
+
53
+ logger = logging.get_logger(__name__)
54
+
55
+
56
+ class DiffLlamaMLP(nn.Module):
57
+ def __init__(self, config):
58
+ super().__init__()
59
+ self.config = config
60
+ self.hidden_size = config.hidden_size
61
+ self.intermediate_size = config.intermediate_size
62
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
63
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
64
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
65
+ self.act_fn = ACT2FN[config.hidden_act]
66
+
67
+ def forward(self, x):
68
+ down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
69
+ return down_proj
70
+
71
+
72
+ class DiffLlamaRotaryEmbedding(nn.Module):
73
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
74
+
75
+ def __init__(self, config: DiffLlamaConfig, device=None):
76
+ super().__init__()
77
+ self.max_seq_len_cached = config.max_position_embeddings
78
+ self.original_max_seq_len = config.max_position_embeddings
79
+
80
+ self.config = config
81
+
82
+ self.rope_type = self.config.rope_parameters["rope_type"]
83
+ rope_init_fn: Callable = self.compute_default_rope_parameters
84
+ if self.rope_type != "default":
85
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
86
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
87
+
88
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
89
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
90
+
91
+ @staticmethod
92
+ def compute_default_rope_parameters(
93
+ config: DiffLlamaConfig | None = None,
94
+ device: Optional["torch.device"] = None,
95
+ seq_len: int | None = None,
96
+ ) -> tuple["torch.Tensor", float]:
97
+ """
98
+ Computes the inverse frequencies according to the original RoPE implementation
99
+ Args:
100
+ config ([`~transformers.PreTrainedConfig`]):
101
+ The model configuration.
102
+ device (`torch.device`):
103
+ The device to use for initialization of the inverse frequencies.
104
+ seq_len (`int`, *optional*):
105
+ The current sequence length. Unused for this type of RoPE.
106
+ Returns:
107
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
108
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
109
+ """
110
+ base = config.rope_parameters["rope_theta"]
111
+ dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
112
+
113
+ attention_factor = 1.0 # Unused in this type of RoPE
114
+
115
+ # Compute the inverse frequencies
116
+ inv_freq = 1.0 / (
117
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
118
+ )
119
+ return inv_freq, attention_factor
120
+
121
+ @torch.no_grad()
122
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
123
+ def forward(self, x, position_ids):
124
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
125
+ position_ids_expanded = position_ids[:, None, :].float()
126
+
127
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
128
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
129
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
130
+ emb = torch.cat((freqs, freqs), dim=-1)
131
+ cos = emb.cos() * self.attention_scaling
132
+ sin = emb.sin() * self.attention_scaling
133
+
134
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
135
+
136
+
137
+ def rotate_half(x):
138
+ """Rotates half the hidden dims of the input."""
139
+ x1 = x[..., : x.shape[-1] // 2]
140
+ x2 = x[..., x.shape[-1] // 2 :]
141
+ return torch.cat((-x2, x1), dim=-1)
142
+
143
+
144
+ @use_kernel_func_from_hub("rotary_pos_emb")
145
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
146
+ """Applies Rotary Position Embedding to the query and key tensors.
147
+
148
+ Args:
149
+ q (`torch.Tensor`): The query tensor.
150
+ k (`torch.Tensor`): The key tensor.
151
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
152
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
153
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
154
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
155
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
156
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
157
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
158
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
159
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
160
+ Returns:
161
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
162
+ """
163
+ cos = cos.unsqueeze(unsqueeze_dim)
164
+ sin = sin.unsqueeze(unsqueeze_dim)
165
+ q_embed = (q * cos) + (rotate_half(q) * sin)
166
+ k_embed = (k * cos) + (rotate_half(k) * sin)
167
+ return q_embed, k_embed
168
+
169
+
170
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
171
+ """
172
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
173
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
174
+ """
175
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
176
+ if n_rep == 1:
177
+ return hidden_states
178
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
179
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
180
+
181
+
182
+ def lambda_init_fn(layer_idx):
183
+ return 0.8 - 0.6 * math.exp(-0.3 * layer_idx)
184
+
185
+
186
+ class DiffLlamaAttention(nn.Module):
187
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
188
+
189
+ def __init__(self, config: DiffLlamaConfig, layer_idx: int | None = None):
190
+ super().__init__()
191
+ self.config = config
192
+ self.layer_idx = layer_idx
193
+ if layer_idx is None:
194
+ logger.warning_once(
195
+ f"Instantiating {self.__class__.__name__} without passing a `layer_idx` is not recommended and will "
196
+ "lead to errors during the forward call if caching is used. Please make sure to provide a `layer_idx` "
197
+ "when creating this class."
198
+ )
199
+
200
+ self.attention_dropout = config.attention_dropout
201
+ self.hidden_size = config.hidden_size
202
+ self.num_heads = config.num_attention_heads
203
+ self.head_dim = getattr(config, "head_dim", self.hidden_size // self.num_heads)
204
+ self.num_key_value_heads = config.num_key_value_heads
205
+ self.num_key_value_groups = self.num_heads // self.num_key_value_heads
206
+ # under this are not used
207
+ self.max_position_embeddings = config.max_position_embeddings
208
+ self.is_causal = True
209
+
210
+ self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=config.attention_bias)
211
+ self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=config.attention_bias)
212
+ self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=config.attention_bias)
213
+ self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=config.attention_bias)
214
+
215
+ self.lambda_init = lambda_init_fn(layer_idx)
216
+ self.lambda_q1 = nn.Parameter(torch.normal(0, config.lambda_std_dev, size=(self.head_dim,)))
217
+ self.lambda_k1 = nn.Parameter(torch.normal(0, config.lambda_std_dev, size=(self.head_dim,)))
218
+ self.lambda_q2 = nn.Parameter(torch.normal(0, config.lambda_std_dev, size=(self.head_dim,)))
219
+ self.lambda_k2 = nn.Parameter(torch.normal(0, config.lambda_std_dev, size=(self.head_dim,)))
220
+ self.groupnorm = nn.RMSNorm(2 * self.head_dim, eps=config.rms_norm_eps, elementwise_affine=False)
221
+
222
+ def forward(
223
+ self,
224
+ hidden_states: torch.Tensor,
225
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
226
+ attention_mask: torch.Tensor | None = None,
227
+ position_ids: torch.LongTensor | None = None,
228
+ past_key_values: Cache | None = None,
229
+ use_cache: bool = False,
230
+ **kwargs,
231
+ ) -> tuple[torch.Tensor, torch.Tensor | None, tuple[torch.Tensor] | None]:
232
+ bsz, target_len, _ = hidden_states.size()
233
+ q_len = target_len
234
+
235
+ query_states = self.q_proj(hidden_states)
236
+ key_states = self.k_proj(hidden_states)
237
+ value_states = self.v_proj(hidden_states)
238
+
239
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
240
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
241
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
242
+
243
+ cos, sin = position_embeddings
244
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
245
+
246
+ if past_key_values is not None:
247
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
248
+
249
+ key_states = repeat_kv(key_states, self.num_key_value_groups)
250
+ value_states = repeat_kv(value_states, self.num_key_value_groups)
251
+ value_states = torch.cat(torch.chunk(value_states, 2, dim=1), dim=-1)
252
+ value_states = value_states.repeat(1, 2, 1, 1)
253
+
254
+ attn_weights = torch.matmul(query_states, key_states.transpose(2, 3)) / math.sqrt(self.head_dim)
255
+
256
+ if attention_mask is not None:
257
+ attn_weights = attn_weights + attention_mask
258
+
259
+ # upcast attention to fp32
260
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
261
+ attn_weights = nn.functional.dropout(attn_weights, p=self.attention_dropout, training=self.training)
262
+ lambda_1 = torch.exp(torch.sum(self.lambda_q1 * self.lambda_k1, dim=-1, dtype=torch.float32)).to(
263
+ query_states.dtype
264
+ )
265
+ lambda_2 = torch.exp(torch.sum(self.lambda_q2 * self.lambda_k2, dim=-1, dtype=torch.float32)).to(
266
+ query_states.dtype
267
+ )
268
+ lambda_full = lambda_1 - lambda_2 + self.lambda_init
269
+
270
+ attn_output = torch.matmul(attn_weights, value_states)
271
+ attn_output1, attn_output2 = torch.chunk(attn_output, 2, dim=1)
272
+
273
+ attn_output = attn_output1 - lambda_full * attn_output2
274
+ attn_output = (1 - self.lambda_init) * self.groupnorm(attn_output)
275
+ attn_output = attn_output.transpose(1, 2).contiguous()
276
+ attn_output = attn_output.reshape(bsz, q_len, -1)
277
+ attn_output = self.o_proj(attn_output)
278
+ return attn_output, attn_weights
279
+
280
+
281
+ class DiffLlamaFlashAttention2(DiffLlamaAttention):
282
+ """
283
+ DiffLlama flash attention module. This module inherits from `DiffLlamaAttention` as the weights of the module stays
284
+ untouched. The only required change would be on the forward pass where it needs to correctly call the public API of
285
+ flash attention and deal with padding tokens in case the input contains any of them.
286
+ """
287
+
288
+ def __init__(self, *args, **kwargs):
289
+ super().__init__(*args, **kwargs)
290
+
291
+ # TODO: Should be removed once Flash Attention for RoCm is bumped to 2.1.
292
+ # flash_attn<2.1 generates top-left aligned causal mask, while what is needed here is bottom-right alignment, that was made default for flash_attn>=2.1. This attribute is used to handle this difference. Reference: https://github.com/Dao-AILab/flash-attention/releases/tag/v2.1.0.
293
+ # Beware that with flash_attn<2.1, using q_seqlen != k_seqlen (except for the case q_seqlen == 1) produces a wrong mask (top-left).
294
+ self._flash_attn_uses_top_left_mask = flash_attn_supports_top_left_mask()
295
+
296
+ def forward(
297
+ self,
298
+ hidden_states: torch.Tensor,
299
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
300
+ attention_mask: torch.LongTensor | None = None,
301
+ position_ids: torch.LongTensor | None = None,
302
+ past_key_values: Cache | None = None,
303
+ use_cache: bool = False,
304
+ ) -> tuple[torch.Tensor, None]:
305
+ if isinstance(past_key_values, StaticCache):
306
+ raise ValueError(
307
+ "`static` cache implementation is not compatible with `attn_implementation==flash_attention_2` "
308
+ "make sure to use `sdpa` in the mean time, and open an issue at https://github.com/huggingface/transformers"
309
+ )
310
+
311
+ bsz, q_len, _ = hidden_states.size()
312
+
313
+ query_states = self.q_proj(hidden_states)
314
+ key_states = self.k_proj(hidden_states)
315
+ value_states = self.v_proj(hidden_states)
316
+
317
+ # Flash attention requires the input to have the shape
318
+ # batch_size x seq_length x head_dim x hidden_dim
319
+ # therefore we just need to keep the original shape
320
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
321
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
322
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
323
+
324
+ cos, sin = position_embeddings
325
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
326
+
327
+ if past_key_values is not None:
328
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
329
+
330
+ # TODO: These transpose are quite inefficient but Flash Attention requires the layout [batch_size, sequence_length, num_heads, head_dim]. We would need to refactor the KV cache
331
+ # to be able to avoid many of these transpose/reshape/view.
332
+ query_states = query_states.transpose(1, 2)
333
+ key_states = key_states.transpose(1, 2)
334
+ value_states = value_states.transpose(1, 2)
335
+
336
+ dropout_rate = self.attention_dropout if self.training else 0.0
337
+
338
+ # In PEFT, usually we cast the layer norms in float32 for training stability reasons
339
+ # therefore the input hidden states gets silently casted in float32. Hence, we need
340
+ # cast them back in the correct dtype just to be sure everything works as expected.
341
+ # This might slowdown training & inference so it is recommended to not cast the LayerNorms
342
+ # in fp32. (DiffLlamaRMSNorm handles it correctly)
343
+
344
+ input_dtype = query_states.dtype
345
+ device_type = query_states.device.type if query_states.device.type != "mps" else "cpu"
346
+ if input_dtype == torch.float32:
347
+ if torch.is_autocast_enabled(device_type):
348
+ target_dtype = torch.get_autocast_dtype(device_type)
349
+ # Handle the case where the model is quantized
350
+ elif hasattr(self.config, "_is_quantized"):
351
+ target_dtype = self.config.dtype
352
+ else:
353
+ target_dtype = self.q_proj.weight.dtype
354
+
355
+ logger.warning_once(
356
+ f"The input hidden states seems to be silently casted in float32, this might be related to"
357
+ f" the fact you have upcasted embedding or layer norm layers in float32. We will cast back the input in"
358
+ f" {target_dtype}."
359
+ )
360
+
361
+ query_states = query_states.to(target_dtype)
362
+ key_states = key_states.to(target_dtype)
363
+ value_states = value_states.to(target_dtype)
364
+
365
+ value_states1, value_states2 = torch.chunk(value_states, 2, dim=2)
366
+ value_states1 = value_states1.repeat(1, 1, 2, 1)
367
+ value_states2 = value_states2.repeat(1, 1, 2, 1)
368
+
369
+ attn_output1 = _flash_attention_forward(
370
+ query_states,
371
+ key_states,
372
+ value_states1,
373
+ attention_mask,
374
+ q_len,
375
+ position_ids=position_ids,
376
+ dropout=dropout_rate,
377
+ sliding_window=getattr(self, "sliding_window", None),
378
+ use_top_left_mask=self._flash_attn_uses_top_left_mask,
379
+ is_causal=self.is_causal,
380
+ )
381
+
382
+ attn_output2 = _flash_attention_forward(
383
+ query_states,
384
+ key_states,
385
+ value_states2,
386
+ attention_mask,
387
+ q_len,
388
+ position_ids=position_ids,
389
+ dropout=dropout_rate,
390
+ sliding_window=getattr(self, "sliding_window", None),
391
+ use_top_left_mask=self._flash_attn_uses_top_left_mask,
392
+ is_causal=self.is_causal,
393
+ )
394
+
395
+ attn_output = torch.cat([attn_output1, attn_output2], dim=-1)
396
+ attn_output1, attn_output2 = torch.chunk(attn_output, 2, dim=2)
397
+
398
+ lambda_1 = torch.exp(torch.sum(self.lambda_q1 * self.lambda_k1, dim=-1, dtype=torch.float32)).to(
399
+ query_states.dtype
400
+ )
401
+ lambda_2 = torch.exp(torch.sum(self.lambda_q2 * self.lambda_k2, dim=-1, dtype=torch.float32)).to(
402
+ query_states.dtype
403
+ )
404
+ lambda_full = lambda_1 - lambda_2 + self.lambda_init
405
+
406
+ attn_output = attn_output1 - lambda_full * attn_output2
407
+ attn_output = (1 - self.lambda_init) * self.groupnorm(attn_output)
408
+ attn_output = attn_output.reshape(bsz, q_len, -1).contiguous()
409
+ attn_output = self.o_proj(attn_output)
410
+ return attn_output, None
411
+
412
+
413
+ class DiffLlamaSdpaAttention(DiffLlamaAttention):
414
+ """
415
+ DiffLlama attention module using torch.nn.functional.scaled_dot_product_attention. This module inherits from
416
+ `DiffLlamaAttention` as the weights of the module stays untouched. The only changes are on the forward pass to adapt to
417
+ SDPA API.
418
+ """
419
+
420
+ # Adapted from DiffLlamaAttention.forward
421
+ def forward(
422
+ self,
423
+ hidden_states: torch.Tensor,
424
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
425
+ attention_mask: torch.Tensor | None = None,
426
+ position_ids: torch.LongTensor | None = None,
427
+ past_key_values: Cache | None = None,
428
+ use_cache: bool = False,
429
+ **kwargs,
430
+ ) -> tuple[torch.Tensor, torch.Tensor | None, tuple[torch.Tensor] | None]:
431
+ bsz, q_len, _ = hidden_states.size()
432
+
433
+ query_states = self.q_proj(hidden_states)
434
+ key_states = self.k_proj(hidden_states)
435
+ value_states = self.v_proj(hidden_states)
436
+
437
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
438
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
439
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
440
+
441
+ cos, sin = position_embeddings
442
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
443
+
444
+ if past_key_values is not None:
445
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
446
+
447
+ key_states = repeat_kv(key_states, self.num_key_value_groups)
448
+ value_states = repeat_kv(value_states, self.num_key_value_groups)
449
+ value_states = torch.cat(torch.chunk(value_states, 2, dim=1), dim=-1)
450
+ value_states = value_states.repeat(1, 2, 1, 1)
451
+
452
+ causal_mask = attention_mask
453
+ if attention_mask is not None:
454
+ causal_mask = causal_mask[:, :, :, : key_states.shape[-2]]
455
+
456
+ # We dispatch to SDPA's Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment
457
+ # in SDPA to support both torch.compile's dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling.
458
+ is_causal = causal_mask is None and q_len > 1
459
+
460
+ attn_output = torch.nn.functional.scaled_dot_product_attention(
461
+ query_states,
462
+ key_states,
463
+ value_states,
464
+ attn_mask=causal_mask,
465
+ dropout_p=self.attention_dropout if self.training else 0.0,
466
+ is_causal=is_causal,
467
+ )
468
+
469
+ attn_output1, attn_output2 = torch.chunk(attn_output, 2, dim=1)
470
+
471
+ lambda_1 = torch.exp(torch.sum(self.lambda_q1 * self.lambda_k1, dim=-1, dtype=torch.float32)).to(
472
+ query_states.dtype
473
+ )
474
+ lambda_2 = torch.exp(torch.sum(self.lambda_q2 * self.lambda_k2, dim=-1, dtype=torch.float32)).to(
475
+ query_states.dtype
476
+ )
477
+ lambda_full = lambda_1 - lambda_2 + self.lambda_init
478
+
479
+ attn_output = attn_output1 - lambda_full * attn_output2
480
+ attn_output = (1 - self.lambda_init) * self.groupnorm(attn_output)
481
+ attn_output = attn_output.transpose(1, 2).contiguous()
482
+ attn_output = attn_output.view(bsz, q_len, -1)
483
+ attn_output = self.o_proj(attn_output)
484
+ return attn_output, None
485
+
486
+
487
+ @use_kernel_forward_from_hub("RMSNorm")
488
+ class DiffLlamaRMSNorm(nn.Module):
489
+ def __init__(self, hidden_size, eps: float = 1e-6) -> None:
490
+ """
491
+ DiffLlamaRMSNorm is equivalent to T5LayerNorm
492
+ """
493
+ super().__init__()
494
+ self.weight = nn.Parameter(torch.ones(hidden_size))
495
+ self.variance_epsilon = eps
496
+
497
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
498
+ input_dtype = hidden_states.dtype
499
+ hidden_states = hidden_states.to(torch.float32)
500
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
501
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
502
+ return self.weight * hidden_states.to(input_dtype)
503
+
504
+ def extra_repr(self):
505
+ return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
506
+
507
+
508
+ DIFFLLAMA_ATTENTION_CLASSES = {
509
+ "eager": DiffLlamaAttention,
510
+ "flash_attention_2": DiffLlamaFlashAttention2,
511
+ "sdpa": DiffLlamaSdpaAttention,
512
+ }
513
+
514
+
515
+ class DiffLlamaDecoderLayer(GradientCheckpointingLayer):
516
+ def __init__(self, config: DiffLlamaConfig, layer_idx: int):
517
+ super().__init__()
518
+ self.hidden_size = config.hidden_size
519
+
520
+ self.self_attn = DIFFLLAMA_ATTENTION_CLASSES[config._attn_implementation](config=config, layer_idx=layer_idx)
521
+
522
+ self.mlp = DiffLlamaMLP(config)
523
+ self.input_layernorm = DiffLlamaRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
524
+ self.post_attention_layernorm = DiffLlamaRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
525
+
526
+ def forward(
527
+ self,
528
+ hidden_states: torch.Tensor,
529
+ attention_mask: torch.Tensor | None = None,
530
+ position_ids: torch.LongTensor | None = None,
531
+ past_key_values: Cache | None = None,
532
+ use_cache: bool | None = False,
533
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
534
+ **kwargs: Unpack[TransformersKwargs],
535
+ ) -> torch.Tensor:
536
+ residual = hidden_states
537
+ hidden_states = self.input_layernorm(hidden_states)
538
+ # Self Attention
539
+ hidden_states, _ = self.self_attn(
540
+ hidden_states=hidden_states,
541
+ attention_mask=attention_mask,
542
+ position_ids=position_ids,
543
+ past_key_values=past_key_values,
544
+ use_cache=use_cache,
545
+ position_embeddings=position_embeddings,
546
+ **kwargs,
547
+ )
548
+ hidden_states = residual + hidden_states
549
+
550
+ # Fully Connected
551
+ residual = hidden_states
552
+ hidden_states = self.post_attention_layernorm(hidden_states)
553
+ hidden_states = self.mlp(hidden_states)
554
+ hidden_states = residual + hidden_states
555
+ return hidden_states
556
+
557
+
558
+ @auto_docstring
559
+ class DiffLlamaPreTrainedModel(PreTrainedModel):
560
+ config: DiffLlamaConfig
561
+ base_model_prefix = "model"
562
+ supports_gradient_checkpointing = True
563
+ _no_split_modules = ["DiffLlamaDecoderLayer"]
564
+ _skip_keys_device_placement = ["past_key_values"]
565
+ _supports_flash_attn = True
566
+ _supports_sdpa = True
567
+ _supports_flex_attn = False
568
+
569
+ _can_compile_fullgraph = True
570
+ _supports_attention_backend = False
571
+ _can_record_outputs = {
572
+ "hidden_states": DiffLlamaDecoderLayer,
573
+ "attentions": DiffLlamaAttention,
574
+ }
575
+
576
+ @torch.no_grad()
577
+ def _init_weights(self, module):
578
+ super()._init_weights(module)
579
+ if isinstance(module, DiffLlamaAttention):
580
+ init.normal_(module.lambda_q1, 0, self.config.lambda_std_dev)
581
+ init.normal_(module.lambda_k1, 0, self.config.lambda_std_dev)
582
+ init.normal_(module.lambda_q2, 0, self.config.lambda_std_dev)
583
+ init.normal_(module.lambda_k2, 0, self.config.lambda_std_dev)
584
+
585
+
586
+ @auto_docstring
587
+ class DiffLlamaModel(DiffLlamaPreTrainedModel):
588
+ def __init__(self, config: DiffLlamaConfig):
589
+ super().__init__(config)
590
+ self.padding_idx = config.pad_token_id
591
+ self.vocab_size = config.vocab_size
592
+
593
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
594
+ self.layers = nn.ModuleList(
595
+ [DiffLlamaDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
596
+ )
597
+ self.norm = DiffLlamaRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
598
+ self.rotary_emb = DiffLlamaRotaryEmbedding(config=config)
599
+ self.gradient_checkpointing = False
600
+
601
+ # Initialize weights and apply final processing
602
+ self.post_init()
603
+
604
+ @merge_with_config_defaults
605
+ @capture_outputs
606
+ @auto_docstring
607
+ def forward(
608
+ self,
609
+ input_ids: torch.LongTensor | None = None,
610
+ attention_mask: torch.Tensor | None = None,
611
+ position_ids: torch.LongTensor | None = None,
612
+ past_key_values: Cache | None = None,
613
+ inputs_embeds: torch.FloatTensor | None = None,
614
+ use_cache: bool | None = None,
615
+ **kwargs: Unpack[TransformersKwargs],
616
+ ) -> BaseModelOutputWithPast:
617
+ if (input_ids is None) ^ (inputs_embeds is not None):
618
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
619
+
620
+ if inputs_embeds is None:
621
+ inputs_embeds: torch.Tensor = self.embed_tokens(input_ids)
622
+
623
+ if use_cache and past_key_values is None:
624
+ past_key_values = DynamicCache(config=self.config)
625
+
626
+ if position_ids is None:
627
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
628
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
629
+ position_ids = position_ids.unsqueeze(0)
630
+
631
+ causal_mask = create_causal_mask(
632
+ config=self.config,
633
+ inputs_embeds=inputs_embeds,
634
+ attention_mask=attention_mask,
635
+ past_key_values=past_key_values,
636
+ position_ids=position_ids,
637
+ )
638
+
639
+ hidden_states = inputs_embeds
640
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
641
+
642
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
643
+ hidden_states = decoder_layer(
644
+ hidden_states,
645
+ attention_mask=causal_mask,
646
+ position_embeddings=position_embeddings,
647
+ position_ids=position_ids,
648
+ past_key_values=past_key_values,
649
+ use_cache=use_cache,
650
+ **kwargs,
651
+ )
652
+
653
+ hidden_states = self.norm(hidden_states)
654
+ return BaseModelOutputWithPast(
655
+ last_hidden_state=hidden_states,
656
+ past_key_values=past_key_values,
657
+ )
658
+
659
+
660
+ @auto_docstring
661
+ class DiffLlamaForCausalLM(DiffLlamaPreTrainedModel, GenerationMixin):
662
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
663
+ _tp_plan = {"lm_head": "colwise_gather_output"}
664
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
665
+
666
+ def __init__(self, config):
667
+ super().__init__(config)
668
+ self.model = DiffLlamaModel(config)
669
+ self.vocab_size = config.vocab_size
670
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
671
+
672
+ # Initialize weights and apply final processing
673
+ self.post_init()
674
+
675
+ @can_return_tuple
676
+ @auto_docstring
677
+ def forward(
678
+ self,
679
+ input_ids: torch.LongTensor | None = None,
680
+ attention_mask: torch.Tensor | None = None,
681
+ position_ids: torch.LongTensor | None = None,
682
+ past_key_values: Cache | None = None,
683
+ inputs_embeds: torch.FloatTensor | None = None,
684
+ labels: torch.LongTensor | None = None,
685
+ use_cache: bool | None = None,
686
+ logits_to_keep: int | torch.Tensor = 0,
687
+ **kwargs: Unpack[TransformersKwargs],
688
+ ) -> CausalLMOutputWithPast:
689
+ r"""
690
+ Example:
691
+
692
+ ```python
693
+ >>> from transformers import AutoTokenizer, DiffLlamaForCausalLM
694
+
695
+ >>> model = DiffLlamaForCausalLM.from_pretrained("google/diffllama-7b")
696
+ >>> tokenizer = AutoTokenizer.from_pretrained("google/diffllama-7b")
697
+
698
+ >>> prompt = "What is your favorite condiment?"
699
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
700
+
701
+ >>> # Generate
702
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
703
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
704
+ "What is your favorite condiment?"
705
+ ```"""
706
+ outputs: BaseModelOutputWithPast = self.model(
707
+ input_ids=input_ids,
708
+ attention_mask=attention_mask,
709
+ position_ids=position_ids,
710
+ past_key_values=past_key_values,
711
+ inputs_embeds=inputs_embeds,
712
+ use_cache=use_cache,
713
+ **kwargs,
714
+ )
715
+
716
+ hidden_states = outputs.last_hidden_state
717
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
718
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
719
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
720
+
721
+ loss = None
722
+ if labels is not None:
723
+ loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
724
+
725
+ return CausalLMOutputWithPast(
726
+ loss=loss,
727
+ logits=logits,
728
+ past_key_values=outputs.past_key_values,
729
+ hidden_states=outputs.hidden_states,
730
+ attentions=outputs.attentions,
731
+ )
732
+
733
+
734
+ class DiffLlamaForSequenceClassification(GenericForSequenceClassification, DiffLlamaPreTrainedModel):
735
+ pass
736
+
737
+
738
+ class DiffLlamaForQuestionAnswering(GenericForQuestionAnswering, DiffLlamaPreTrainedModel):
739
+ base_model_prefix = "transformer" # For BC, where `transformer` was used instead of `model`
740
+
741
+
742
+ class DiffLlamaForTokenClassification(GenericForTokenClassification, DiffLlamaPreTrainedModel):
743
+ pass
744
+
745
+
746
+ __all__ = [
747
+ "DiffLlamaPreTrainedModel",
748
+ "DiffLlamaModel",
749
+ "DiffLlamaForCausalLM",
750
+ "DiffLlamaForSequenceClassification",
751
+ "DiffLlamaForQuestionAnswering",
752
+ "DiffLlamaForTokenClassification",
753
+ ]
third_party/transformers/src/transformers/models/diffllama/modular_diffllama.py ADDED
@@ -0,0 +1,417 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 weak-kajuma and the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # This code is based on Llama implementations in this library and Microsoft's
4
+ # Differential Transformer implementations.
5
+
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ import math
18
+
19
+ import torch
20
+ from torch import nn
21
+
22
+ from ... import initialization as init
23
+ from ...cache_utils import Cache, StaticCache
24
+ from ...modeling_flash_attention_utils import _flash_attention_forward, flash_attn_supports_top_left_mask
25
+ from ...modeling_utils import PreTrainedModel
26
+ from ...utils import logging
27
+ from ..gemma.modeling_gemma import GemmaForCausalLM
28
+ from ..llama.modeling_llama import (
29
+ LlamaDecoderLayer,
30
+ LlamaForQuestionAnswering,
31
+ LlamaForSequenceClassification,
32
+ LlamaForTokenClassification,
33
+ LlamaModel,
34
+ LlamaPreTrainedModel,
35
+ LlamaRotaryEmbedding,
36
+ apply_rotary_pos_emb,
37
+ repeat_kv,
38
+ )
39
+ from ..mistral.modeling_mistral import MistralMLP
40
+ from .configuration_diffllama import DiffLlamaConfig
41
+
42
+
43
+ logger = logging.get_logger(__name__)
44
+
45
+ _CHECKPOINT_FOR_DOC = "kajuma/DiffLlama-0.3B-handcut"
46
+ _CONFIG_FOR_DOC = "DiffLlamaConfig"
47
+
48
+
49
+ class DiffLlamaMLP(MistralMLP):
50
+ pass
51
+
52
+
53
+ def lambda_init_fn(layer_idx):
54
+ return 0.8 - 0.6 * math.exp(-0.3 * layer_idx)
55
+
56
+
57
+ class DiffLlamaRotaryEmbedding(LlamaRotaryEmbedding):
58
+ pass
59
+
60
+
61
+ class DiffLlamaAttention(nn.Module):
62
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
63
+
64
+ def __init__(self, config: DiffLlamaConfig, layer_idx: int | None = None):
65
+ super().__init__()
66
+ self.config = config
67
+ self.layer_idx = layer_idx
68
+ if layer_idx is None:
69
+ logger.warning_once(
70
+ f"Instantiating {self.__class__.__name__} without passing a `layer_idx` is not recommended and will "
71
+ "lead to errors during the forward call if caching is used. Please make sure to provide a `layer_idx` "
72
+ "when creating this class."
73
+ )
74
+
75
+ self.attention_dropout = config.attention_dropout
76
+ self.hidden_size = config.hidden_size
77
+ self.num_heads = config.num_attention_heads
78
+ self.head_dim = getattr(config, "head_dim", self.hidden_size // self.num_heads)
79
+ self.num_key_value_heads = config.num_key_value_heads
80
+ self.num_key_value_groups = self.num_heads // self.num_key_value_heads
81
+ # under this are not used
82
+ self.max_position_embeddings = config.max_position_embeddings
83
+ self.is_causal = True
84
+
85
+ self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=config.attention_bias)
86
+ self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=config.attention_bias)
87
+ self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=config.attention_bias)
88
+ self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=config.attention_bias)
89
+
90
+ self.lambda_init = lambda_init_fn(layer_idx)
91
+ self.lambda_q1 = nn.Parameter(torch.normal(0, config.lambda_std_dev, size=(self.head_dim,)))
92
+ self.lambda_k1 = nn.Parameter(torch.normal(0, config.lambda_std_dev, size=(self.head_dim,)))
93
+ self.lambda_q2 = nn.Parameter(torch.normal(0, config.lambda_std_dev, size=(self.head_dim,)))
94
+ self.lambda_k2 = nn.Parameter(torch.normal(0, config.lambda_std_dev, size=(self.head_dim,)))
95
+ self.groupnorm = nn.RMSNorm(2 * self.head_dim, eps=config.rms_norm_eps, elementwise_affine=False)
96
+
97
+ def forward(
98
+ self,
99
+ hidden_states: torch.Tensor,
100
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
101
+ attention_mask: torch.Tensor | None = None,
102
+ position_ids: torch.LongTensor | None = None,
103
+ past_key_values: Cache | None = None,
104
+ use_cache: bool = False,
105
+ **kwargs,
106
+ ) -> tuple[torch.Tensor, torch.Tensor | None, tuple[torch.Tensor] | None]:
107
+ bsz, target_len, _ = hidden_states.size()
108
+ q_len = target_len
109
+
110
+ query_states = self.q_proj(hidden_states)
111
+ key_states = self.k_proj(hidden_states)
112
+ value_states = self.v_proj(hidden_states)
113
+
114
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
115
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
116
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
117
+
118
+ cos, sin = position_embeddings
119
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
120
+
121
+ if past_key_values is not None:
122
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
123
+
124
+ key_states = repeat_kv(key_states, self.num_key_value_groups)
125
+ value_states = repeat_kv(value_states, self.num_key_value_groups)
126
+ value_states = torch.cat(torch.chunk(value_states, 2, dim=1), dim=-1)
127
+ value_states = value_states.repeat(1, 2, 1, 1)
128
+
129
+ attn_weights = torch.matmul(query_states, key_states.transpose(2, 3)) / math.sqrt(self.head_dim)
130
+
131
+ if attention_mask is not None:
132
+ attn_weights = attn_weights + attention_mask
133
+
134
+ # upcast attention to fp32
135
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
136
+ attn_weights = nn.functional.dropout(attn_weights, p=self.attention_dropout, training=self.training)
137
+ lambda_1 = torch.exp(torch.sum(self.lambda_q1 * self.lambda_k1, dim=-1, dtype=torch.float32)).to(
138
+ query_states.dtype
139
+ )
140
+ lambda_2 = torch.exp(torch.sum(self.lambda_q2 * self.lambda_k2, dim=-1, dtype=torch.float32)).to(
141
+ query_states.dtype
142
+ )
143
+ lambda_full = lambda_1 - lambda_2 + self.lambda_init
144
+
145
+ attn_output = torch.matmul(attn_weights, value_states)
146
+ attn_output1, attn_output2 = torch.chunk(attn_output, 2, dim=1)
147
+
148
+ attn_output = attn_output1 - lambda_full * attn_output2
149
+ attn_output = (1 - self.lambda_init) * self.groupnorm(attn_output)
150
+ attn_output = attn_output.transpose(1, 2).contiguous()
151
+ attn_output = attn_output.reshape(bsz, q_len, -1)
152
+ attn_output = self.o_proj(attn_output)
153
+ return attn_output, attn_weights
154
+
155
+
156
+ class DiffLlamaFlashAttention2(DiffLlamaAttention):
157
+ """
158
+ DiffLlama flash attention module. This module inherits from `DiffLlamaAttention` as the weights of the module stays
159
+ untouched. The only required change would be on the forward pass where it needs to correctly call the public API of
160
+ flash attention and deal with padding tokens in case the input contains any of them.
161
+ """
162
+
163
+ def __init__(self, *args, **kwargs):
164
+ super().__init__(*args, **kwargs)
165
+
166
+ # TODO: Should be removed once Flash Attention for RoCm is bumped to 2.1.
167
+ # flash_attn<2.1 generates top-left aligned causal mask, while what is needed here is bottom-right alignment, that was made default for flash_attn>=2.1. This attribute is used to handle this difference. Reference: https://github.com/Dao-AILab/flash-attention/releases/tag/v2.1.0.
168
+ # Beware that with flash_attn<2.1, using q_seqlen != k_seqlen (except for the case q_seqlen == 1) produces a wrong mask (top-left).
169
+ self._flash_attn_uses_top_left_mask = flash_attn_supports_top_left_mask()
170
+
171
+ def forward(
172
+ self,
173
+ hidden_states: torch.Tensor,
174
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
175
+ attention_mask: torch.LongTensor | None = None,
176
+ position_ids: torch.LongTensor | None = None,
177
+ past_key_values: Cache | None = None,
178
+ use_cache: bool = False,
179
+ ) -> tuple[torch.Tensor, None]:
180
+ if isinstance(past_key_values, StaticCache):
181
+ raise ValueError(
182
+ "`static` cache implementation is not compatible with `attn_implementation==flash_attention_2` "
183
+ "make sure to use `sdpa` in the mean time, and open an issue at https://github.com/huggingface/transformers"
184
+ )
185
+
186
+ bsz, q_len, _ = hidden_states.size()
187
+
188
+ query_states = self.q_proj(hidden_states)
189
+ key_states = self.k_proj(hidden_states)
190
+ value_states = self.v_proj(hidden_states)
191
+
192
+ # Flash attention requires the input to have the shape
193
+ # batch_size x seq_length x head_dim x hidden_dim
194
+ # therefore we just need to keep the original shape
195
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
196
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
197
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
198
+
199
+ cos, sin = position_embeddings
200
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
201
+
202
+ if past_key_values is not None:
203
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
204
+
205
+ # TODO: These transpose are quite inefficient but Flash Attention requires the layout [batch_size, sequence_length, num_heads, head_dim]. We would need to refactor the KV cache
206
+ # to be able to avoid many of these transpose/reshape/view.
207
+ query_states = query_states.transpose(1, 2)
208
+ key_states = key_states.transpose(1, 2)
209
+ value_states = value_states.transpose(1, 2)
210
+
211
+ dropout_rate = self.attention_dropout if self.training else 0.0
212
+
213
+ # In PEFT, usually we cast the layer norms in float32 for training stability reasons
214
+ # therefore the input hidden states gets silently casted in float32. Hence, we need
215
+ # cast them back in the correct dtype just to be sure everything works as expected.
216
+ # This might slowdown training & inference so it is recommended to not cast the LayerNorms
217
+ # in fp32. (DiffLlamaRMSNorm handles it correctly)
218
+
219
+ input_dtype = query_states.dtype
220
+ device_type = query_states.device.type if query_states.device.type != "mps" else "cpu"
221
+ if input_dtype == torch.float32:
222
+ if torch.is_autocast_enabled(device_type):
223
+ target_dtype = torch.get_autocast_dtype(device_type)
224
+ # Handle the case where the model is quantized
225
+ elif hasattr(self.config, "_is_quantized"):
226
+ target_dtype = self.config.dtype
227
+ else:
228
+ target_dtype = self.q_proj.weight.dtype
229
+
230
+ logger.warning_once(
231
+ f"The input hidden states seems to be silently casted in float32, this might be related to"
232
+ f" the fact you have upcasted embedding or layer norm layers in float32. We will cast back the input in"
233
+ f" {target_dtype}."
234
+ )
235
+
236
+ query_states = query_states.to(target_dtype)
237
+ key_states = key_states.to(target_dtype)
238
+ value_states = value_states.to(target_dtype)
239
+
240
+ value_states1, value_states2 = torch.chunk(value_states, 2, dim=2)
241
+ value_states1 = value_states1.repeat(1, 1, 2, 1)
242
+ value_states2 = value_states2.repeat(1, 1, 2, 1)
243
+
244
+ attn_output1 = _flash_attention_forward(
245
+ query_states,
246
+ key_states,
247
+ value_states1,
248
+ attention_mask,
249
+ q_len,
250
+ position_ids=position_ids,
251
+ dropout=dropout_rate,
252
+ sliding_window=getattr(self, "sliding_window", None),
253
+ use_top_left_mask=self._flash_attn_uses_top_left_mask,
254
+ is_causal=self.is_causal,
255
+ )
256
+
257
+ attn_output2 = _flash_attention_forward(
258
+ query_states,
259
+ key_states,
260
+ value_states2,
261
+ attention_mask,
262
+ q_len,
263
+ position_ids=position_ids,
264
+ dropout=dropout_rate,
265
+ sliding_window=getattr(self, "sliding_window", None),
266
+ use_top_left_mask=self._flash_attn_uses_top_left_mask,
267
+ is_causal=self.is_causal,
268
+ )
269
+
270
+ attn_output = torch.cat([attn_output1, attn_output2], dim=-1)
271
+ attn_output1, attn_output2 = torch.chunk(attn_output, 2, dim=2)
272
+
273
+ lambda_1 = torch.exp(torch.sum(self.lambda_q1 * self.lambda_k1, dim=-1, dtype=torch.float32)).to(
274
+ query_states.dtype
275
+ )
276
+ lambda_2 = torch.exp(torch.sum(self.lambda_q2 * self.lambda_k2, dim=-1, dtype=torch.float32)).to(
277
+ query_states.dtype
278
+ )
279
+ lambda_full = lambda_1 - lambda_2 + self.lambda_init
280
+
281
+ attn_output = attn_output1 - lambda_full * attn_output2
282
+ attn_output = (1 - self.lambda_init) * self.groupnorm(attn_output)
283
+ attn_output = attn_output.reshape(bsz, q_len, -1).contiguous()
284
+ attn_output = self.o_proj(attn_output)
285
+ return attn_output, None
286
+
287
+
288
+ class DiffLlamaSdpaAttention(DiffLlamaAttention):
289
+ """
290
+ DiffLlama attention module using torch.nn.functional.scaled_dot_product_attention. This module inherits from
291
+ `DiffLlamaAttention` as the weights of the module stays untouched. The only changes are on the forward pass to adapt to
292
+ SDPA API.
293
+ """
294
+
295
+ # Adapted from DiffLlamaAttention.forward
296
+ def forward(
297
+ self,
298
+ hidden_states: torch.Tensor,
299
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
300
+ attention_mask: torch.Tensor | None = None,
301
+ position_ids: torch.LongTensor | None = None,
302
+ past_key_values: Cache | None = None,
303
+ use_cache: bool = False,
304
+ **kwargs,
305
+ ) -> tuple[torch.Tensor, torch.Tensor | None, tuple[torch.Tensor] | None]:
306
+ bsz, q_len, _ = hidden_states.size()
307
+
308
+ query_states = self.q_proj(hidden_states)
309
+ key_states = self.k_proj(hidden_states)
310
+ value_states = self.v_proj(hidden_states)
311
+
312
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
313
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
314
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
315
+
316
+ cos, sin = position_embeddings
317
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
318
+
319
+ if past_key_values is not None:
320
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
321
+
322
+ key_states = repeat_kv(key_states, self.num_key_value_groups)
323
+ value_states = repeat_kv(value_states, self.num_key_value_groups)
324
+ value_states = torch.cat(torch.chunk(value_states, 2, dim=1), dim=-1)
325
+ value_states = value_states.repeat(1, 2, 1, 1)
326
+
327
+ causal_mask = attention_mask
328
+ if attention_mask is not None:
329
+ causal_mask = causal_mask[:, :, :, : key_states.shape[-2]]
330
+
331
+ # We dispatch to SDPA's Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment
332
+ # in SDPA to support both torch.compile's dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling.
333
+ is_causal = causal_mask is None and q_len > 1
334
+
335
+ attn_output = torch.nn.functional.scaled_dot_product_attention(
336
+ query_states,
337
+ key_states,
338
+ value_states,
339
+ attn_mask=causal_mask,
340
+ dropout_p=self.attention_dropout if self.training else 0.0,
341
+ is_causal=is_causal,
342
+ )
343
+
344
+ attn_output1, attn_output2 = torch.chunk(attn_output, 2, dim=1)
345
+
346
+ lambda_1 = torch.exp(torch.sum(self.lambda_q1 * self.lambda_k1, dim=-1, dtype=torch.float32)).to(
347
+ query_states.dtype
348
+ )
349
+ lambda_2 = torch.exp(torch.sum(self.lambda_q2 * self.lambda_k2, dim=-1, dtype=torch.float32)).to(
350
+ query_states.dtype
351
+ )
352
+ lambda_full = lambda_1 - lambda_2 + self.lambda_init
353
+
354
+ attn_output = attn_output1 - lambda_full * attn_output2
355
+ attn_output = (1 - self.lambda_init) * self.groupnorm(attn_output)
356
+ attn_output = attn_output.transpose(1, 2).contiguous()
357
+ attn_output = attn_output.view(bsz, q_len, -1)
358
+ attn_output = self.o_proj(attn_output)
359
+ return attn_output, None
360
+
361
+
362
+ DIFFLLAMA_ATTENTION_CLASSES = {
363
+ "eager": DiffLlamaAttention,
364
+ "flash_attention_2": DiffLlamaFlashAttention2,
365
+ "sdpa": DiffLlamaSdpaAttention,
366
+ }
367
+
368
+
369
+ class DiffLlamaDecoderLayer(LlamaDecoderLayer):
370
+ def __init__(self, config: DiffLlamaConfig, layer_idx: int):
371
+ super().__init__(config, layer_idx)
372
+
373
+ self.self_attn = DIFFLLAMA_ATTENTION_CLASSES[config._attn_implementation](config=config, layer_idx=layer_idx)
374
+
375
+
376
+ class DiffLlamaPreTrainedModel(LlamaPreTrainedModel):
377
+ _supports_flex_attn = False
378
+ _supports_attention_backend = False
379
+
380
+ @torch.no_grad()
381
+ def _init_weights(self, module):
382
+ PreTrainedModel._init_weights(self, module)
383
+ if isinstance(module, DiffLlamaAttention):
384
+ init.normal_(module.lambda_q1, 0, self.config.lambda_std_dev)
385
+ init.normal_(module.lambda_k1, 0, self.config.lambda_std_dev)
386
+ init.normal_(module.lambda_q2, 0, self.config.lambda_std_dev)
387
+ init.normal_(module.lambda_k2, 0, self.config.lambda_std_dev)
388
+
389
+
390
+ class DiffLlamaModel(LlamaModel):
391
+ pass
392
+
393
+
394
+ class DiffLlamaForCausalLM(GemmaForCausalLM):
395
+ pass
396
+
397
+
398
+ class DiffLlamaForSequenceClassification(LlamaForSequenceClassification):
399
+ pass
400
+
401
+
402
+ class DiffLlamaForQuestionAnswering(LlamaForQuestionAnswering):
403
+ pass
404
+
405
+
406
+ class DiffLlamaForTokenClassification(LlamaForTokenClassification):
407
+ pass
408
+
409
+
410
+ __all__ = [
411
+ "DiffLlamaPreTrainedModel",
412
+ "DiffLlamaModel",
413
+ "DiffLlamaForCausalLM",
414
+ "DiffLlamaForSequenceClassification",
415
+ "DiffLlamaForQuestionAnswering",
416
+ "DiffLlamaForTokenClassification",
417
+ ]
third_party/transformers/src/transformers/models/encodec/__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_encodec import *
22
+ from .feature_extraction_encodec import *
23
+ from .modeling_encodec 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/encodec/configuration_encodec.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 Meta Platforms, Inc. and affiliates, 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
+ """EnCodec model configuration"""
15
+
16
+ import math
17
+
18
+ import numpy as np
19
+ from huggingface_hub.dataclasses import strict
20
+
21
+ from ...configuration_utils import PreTrainedConfig
22
+ from ...utils import auto_docstring
23
+
24
+
25
+ @auto_docstring(checkpoint="facebook/encodec_24khz")
26
+ @strict
27
+ class EncodecConfig(PreTrainedConfig):
28
+ r"""
29
+ target_bandwidths (`list[float]`, *optional*, defaults to `[1.5, 3.0, 6.0, 12.0, 24.0]`):
30
+ The range of different bandwidths the model can encode audio with.
31
+ normalize (`bool`, *optional*, defaults to `False`):
32
+ Whether the audio shall be normalized when passed.
33
+ chunk_length_s (`float`, *optional*):
34
+ If defined the audio is pre-processed into chunks of lengths `chunk_length_s` and then encoded.
35
+ overlap (`float`, *optional*):
36
+ Defines the overlap between each chunk. It is used to compute the `chunk_stride` using the following
37
+ formulae : `int((1.0 - self.overlap) * self.chunk_length)`.
38
+ num_filters (`int`, *optional*, defaults to 32):
39
+ Number of convolution kernels of first `EncodecConv1d` down sampling layer.
40
+ num_residual_layers (`int`, *optional*, defaults to 1):
41
+ Number of residual layers.
42
+ upsampling_ratios (`Sequence[int]` , *optional*, defaults to `[8, 5, 4, 2]`):
43
+ Kernel size and stride ratios. The encoder uses downsampling ratios instead of upsampling ratios, hence it
44
+ will use the ratios in the reverse order to the ones specified here that must match the decoder order.
45
+ norm_type (`str`, *optional*, defaults to `"weight_norm"`):
46
+ Normalization method. Should be in `["weight_norm", "time_group_norm"]`
47
+ kernel_size (`int`, *optional*, defaults to 7):
48
+ Kernel size for the initial convolution.
49
+ last_kernel_size (`int`, *optional*, defaults to 7):
50
+ Kernel size for the last convolution layer.
51
+ residual_kernel_size (`int`, *optional*, defaults to 3):
52
+ Kernel size for the residual layers.
53
+ dilation_growth_rate (`int`, *optional*, defaults to 2):
54
+ How much to increase the dilation with each layer.
55
+ use_causal_conv (`bool`, *optional*, defaults to `True`):
56
+ Whether to use fully causal convolution.
57
+ pad_mode (`str`, *optional*, defaults to `"reflect"`):
58
+ Padding mode for the convolutions.
59
+ compress (`int`, *optional*, defaults to 2):
60
+ Reduced dimensionality in residual branches (from Demucs v3).
61
+ num_lstm_layers (`int`, *optional*, defaults to 2):
62
+ Number of LSTM layers at the end of the encoder.
63
+ trim_right_ratio (`float`, *optional*, defaults to 1.0):
64
+ Ratio for trimming at the right of the transposed convolution under the `use_causal_conv = True` setup. If
65
+ equal to 1.0, it means that all the trimming is done at the right.
66
+ use_conv_shortcut (`bool`, *optional*, defaults to `True`):
67
+ Whether to use a convolutional layer as the 'skip' connection in the `EncodecResnetBlock` block. If False,
68
+ an identity function will be used, giving a generic residual connection.
69
+
70
+ Example:
71
+
72
+ ```python
73
+ >>> from transformers import EncodecModel, EncodecConfig
74
+
75
+ >>> # Initializing a "facebook/encodec_24khz" style configuration
76
+ >>> configuration = EncodecConfig()
77
+
78
+ >>> # Initializing a model (with random weights) from the "facebook/encodec_24khz" style configuration
79
+ >>> model = EncodecModel(configuration)
80
+
81
+ >>> # Accessing the model configuration
82
+ >>> configuration = model.config
83
+ ```"""
84
+
85
+ model_type = "encodec"
86
+
87
+ target_bandwidths: list[float] | tuple[float, ...] = (1.5, 3.0, 6.0, 12.0, 24.0)
88
+ sampling_rate: int = 24_000
89
+ audio_channels: int = 1
90
+ normalize: bool = False
91
+ chunk_length_s: int | float | None = None
92
+ overlap: float | None = None
93
+ hidden_size: int = 128
94
+ num_filters: int = 32
95
+ num_residual_layers: int = 1
96
+ upsampling_ratios: list[int] | tuple[int, ...] = (8, 5, 4, 2)
97
+ norm_type: str = "weight_norm"
98
+ kernel_size: int = 7
99
+ last_kernel_size: int = 7
100
+ residual_kernel_size: int = 3
101
+ dilation_growth_rate: int = 2
102
+ use_causal_conv: bool = True
103
+ pad_mode: str = "reflect"
104
+ compress: int = 2
105
+ num_lstm_layers: int = 2
106
+ trim_right_ratio: float = 1.0
107
+ codebook_size: int = 1024
108
+ codebook_dim: int | None = None
109
+ use_conv_shortcut: bool = True
110
+
111
+ def __post_init__(self, **kwargs):
112
+ self.codebook_dim = self.codebook_dim if self.codebook_dim is not None else self.hidden_size
113
+ super().__post_init__(**kwargs)
114
+
115
+ def validate_architecture(self):
116
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
117
+ if self.norm_type not in ["weight_norm", "time_group_norm"]:
118
+ raise ValueError(
119
+ f'self.norm_type must be one of `"weight_norm"`, `"time_group_norm"`), got {self.norm_type}'
120
+ )
121
+
122
+ # This is a property because you might want to change the chunk_length_s on the fly
123
+ @property
124
+ def chunk_length(self) -> int | None:
125
+ if self.chunk_length_s is None:
126
+ return None
127
+ else:
128
+ return int(self.chunk_length_s * self.sampling_rate)
129
+
130
+ # This is a property because you might want to change the chunk_length_s on the fly
131
+ @property
132
+ def chunk_stride(self) -> int | None:
133
+ if self.chunk_length_s is None or self.overlap is None:
134
+ return None
135
+ else:
136
+ return max(1, int((1.0 - self.overlap) * self.chunk_length))
137
+
138
+ @property
139
+ def hop_length(self) -> int:
140
+ return int(np.prod(self.upsampling_ratios))
141
+
142
+ @property
143
+ def codebook_nbits(self) -> int:
144
+ return math.ceil(math.log2(self.codebook_size))
145
+
146
+ @property
147
+ def frame_rate(self) -> int:
148
+ return math.ceil(self.sampling_rate / self.hop_length)
149
+
150
+ @property
151
+ def num_quantizers(self) -> int:
152
+ return int(1000 * self.target_bandwidths[-1] // (self.frame_rate * self.codebook_nbits))
153
+
154
+
155
+ __all__ = ["EncodecConfig"]
third_party/transformers/src/transformers/models/encodec/convert_encodec_checkpoint_to_pytorch.py ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Convert EnCodec checkpoints."""
15
+
16
+ import argparse
17
+
18
+ import torch
19
+
20
+ from transformers import (
21
+ EncodecConfig,
22
+ EncodecFeatureExtractor,
23
+ EncodecModel,
24
+ logging,
25
+ )
26
+
27
+
28
+ # checkpoints downloaded from:
29
+ # https://dl.fbaipublicfiles.com/encodec/v0/encodec_24khz-d7cc33bc.th
30
+ # https://huggingface.co/facebook/musicgen-small/resolve/main/compression_state_dict.bin
31
+ # https://dl.fbaipublicfiles.com/encodec/v0/encodec_48khz-7e698e3e.th
32
+
33
+
34
+ logging.set_verbosity_info()
35
+ logger = logging.get_logger("transformers.models.encodec")
36
+
37
+ MAPPING_QUANTIZER = {
38
+ "quantizer.vq.layers.*._codebook.inited": "quantizer.layers.*.codebook.inited",
39
+ "quantizer.vq.layers.*._codebook.cluster_size": "quantizer.layers.*.codebook.cluster_size",
40
+ "quantizer.vq.layers.*._codebook.embed": "quantizer.layers.*.codebook.embed",
41
+ "quantizer.vq.layers.*._codebook.embed_avg": "quantizer.layers.*.codebook.embed_avg",
42
+ }
43
+ MAPPING_ENCODER = {
44
+ "encoder.model.0.conv.conv": "encoder.layers.0.conv",
45
+ "encoder.model.1.block.1.conv.conv": "encoder.layers.1.block.1.conv",
46
+ "encoder.model.1.block.3.conv.conv": "encoder.layers.1.block.3.conv",
47
+ "encoder.model.1.shortcut.conv.conv": "encoder.layers.1.shortcut.conv",
48
+ "encoder.model.3.conv.conv": "encoder.layers.3.conv",
49
+ "encoder.model.4.block.1.conv.conv": "encoder.layers.4.block.1.conv",
50
+ "encoder.model.4.block.3.conv.conv": "encoder.layers.4.block.3.conv",
51
+ "encoder.model.4.shortcut.conv.conv": "encoder.layers.4.shortcut.conv",
52
+ "encoder.model.6.conv.conv": "encoder.layers.6.conv",
53
+ "encoder.model.7.block.1.conv.conv": "encoder.layers.7.block.1.conv",
54
+ "encoder.model.7.block.3.conv.conv": "encoder.layers.7.block.3.conv",
55
+ "encoder.model.7.shortcut.conv.conv": "encoder.layers.7.shortcut.conv",
56
+ "encoder.model.9.conv.conv": "encoder.layers.9.conv",
57
+ "encoder.model.10.block.1.conv.conv": "encoder.layers.10.block.1.conv",
58
+ "encoder.model.10.block.3.conv.conv": "encoder.layers.10.block.3.conv",
59
+ "encoder.model.10.shortcut.conv.conv": "encoder.layers.10.shortcut.conv",
60
+ "encoder.model.12.conv.conv": "encoder.layers.12.conv",
61
+ "encoder.model.13.lstm": "encoder.layers.13.lstm",
62
+ "encoder.model.15.conv.conv": "encoder.layers.15.conv",
63
+ }
64
+ MAPPING_ENCODER_48K = {
65
+ "encoder.model.0.conv.norm": "encoder.layers.0.norm",
66
+ "encoder.model.1.block.1.conv.norm": "encoder.layers.1.block.1.norm",
67
+ "encoder.model.1.block.3.conv.norm": "encoder.layers.1.block.3.norm",
68
+ "encoder.model.1.shortcut.conv.norm": "encoder.layers.1.shortcut.norm",
69
+ "encoder.model.3.conv.norm": "encoder.layers.3.norm",
70
+ "encoder.model.4.block.1.conv.norm": "encoder.layers.4.block.1.norm",
71
+ "encoder.model.4.block.3.conv.norm": "encoder.layers.4.block.3.norm",
72
+ "encoder.model.4.shortcut.conv.norm": "encoder.layers.4.shortcut.norm",
73
+ "encoder.model.6.conv.norm": "encoder.layers.6.norm",
74
+ "encoder.model.7.block.1.conv.norm": "encoder.layers.7.block.1.norm",
75
+ "encoder.model.7.block.3.conv.norm": "encoder.layers.7.block.3.norm",
76
+ "encoder.model.7.shortcut.conv.norm": "encoder.layers.7.shortcut.norm",
77
+ "encoder.model.9.conv.norm": "encoder.layers.9.norm",
78
+ "encoder.model.10.block.1.conv.norm": "encoder.layers.10.block.1.norm",
79
+ "encoder.model.10.block.3.conv.norm": "encoder.layers.10.block.3.norm",
80
+ "encoder.model.10.shortcut.conv.norm": "encoder.layers.10.shortcut.norm",
81
+ "encoder.model.12.conv.norm": "encoder.layers.12.norm",
82
+ "encoder.model.15.conv.norm": "encoder.layers.15.norm",
83
+ }
84
+ MAPPING_DECODER = {
85
+ "decoder.model.0.conv.conv": "decoder.layers.0.conv",
86
+ "decoder.model.1.lstm": "decoder.layers.1.lstm",
87
+ "decoder.model.3.convtr.convtr": "decoder.layers.3.conv",
88
+ "decoder.model.4.block.1.conv.conv": "decoder.layers.4.block.1.conv",
89
+ "decoder.model.4.block.3.conv.conv": "decoder.layers.4.block.3.conv",
90
+ "decoder.model.4.shortcut.conv.conv": "decoder.layers.4.shortcut.conv",
91
+ "decoder.model.6.convtr.convtr": "decoder.layers.6.conv",
92
+ "decoder.model.7.block.1.conv.conv": "decoder.layers.7.block.1.conv",
93
+ "decoder.model.7.block.3.conv.conv": "decoder.layers.7.block.3.conv",
94
+ "decoder.model.7.shortcut.conv.conv": "decoder.layers.7.shortcut.conv",
95
+ "decoder.model.9.convtr.convtr": "decoder.layers.9.conv",
96
+ "decoder.model.10.block.1.conv.conv": "decoder.layers.10.block.1.conv",
97
+ "decoder.model.10.block.3.conv.conv": "decoder.layers.10.block.3.conv",
98
+ "decoder.model.10.shortcut.conv.conv": "decoder.layers.10.shortcut.conv",
99
+ "decoder.model.12.convtr.convtr": "decoder.layers.12.conv",
100
+ "decoder.model.13.block.1.conv.conv": "decoder.layers.13.block.1.conv",
101
+ "decoder.model.13.block.3.conv.conv": "decoder.layers.13.block.3.conv",
102
+ "decoder.model.13.shortcut.conv.conv": "decoder.layers.13.shortcut.conv",
103
+ "decoder.model.15.conv.conv": "decoder.layers.15.conv",
104
+ }
105
+ MAPPING_DECODER_48K = {
106
+ "decoder.model.0.conv.norm": "decoder.layers.0.norm",
107
+ "decoder.model.3.convtr.norm": "decoder.layers.3.norm",
108
+ "decoder.model.4.block.1.conv.norm": "decoder.layers.4.block.1.norm",
109
+ "decoder.model.4.block.3.conv.norm": "decoder.layers.4.block.3.norm",
110
+ "decoder.model.4.shortcut.conv.norm": "decoder.layers.4.shortcut.norm",
111
+ "decoder.model.6.convtr.norm": "decoder.layers.6.norm",
112
+ "decoder.model.7.block.1.conv.norm": "decoder.layers.7.block.1.norm",
113
+ "decoder.model.7.block.3.conv.norm": "decoder.layers.7.block.3.norm",
114
+ "decoder.model.7.shortcut.conv.norm": "decoder.layers.7.shortcut.norm",
115
+ "decoder.model.9.convtr.norm": "decoder.layers.9.norm",
116
+ "decoder.model.10.block.1.conv.norm": "decoder.layers.10.block.1.norm",
117
+ "decoder.model.10.block.3.conv.norm": "decoder.layers.10.block.3.norm",
118
+ "decoder.model.10.shortcut.conv.norm": "decoder.layers.10.shortcut.norm",
119
+ "decoder.model.12.convtr.norm": "decoder.layers.12.norm",
120
+ "decoder.model.13.block.1.conv.norm": "decoder.layers.13.block.1.norm",
121
+ "decoder.model.13.block.3.conv.norm": "decoder.layers.13.block.3.norm",
122
+ "decoder.model.13.shortcut.conv.norm": "decoder.layers.13.shortcut.norm",
123
+ "decoder.model.15.conv.norm": "decoder.layers.15.norm",
124
+ }
125
+ MAPPING_24K = {
126
+ **MAPPING_QUANTIZER,
127
+ **MAPPING_ENCODER,
128
+ **MAPPING_DECODER,
129
+ }
130
+ MAPPING_48K = {
131
+ **MAPPING_QUANTIZER,
132
+ **MAPPING_ENCODER,
133
+ **MAPPING_ENCODER_48K,
134
+ **MAPPING_DECODER,
135
+ **MAPPING_DECODER_48K,
136
+ }
137
+ TOP_LEVEL_KEYS = []
138
+ IGNORE_KEYS = []
139
+
140
+
141
+ def set_recursively(hf_pointer, key, value, full_name, weight_type):
142
+ for attribute in key.split("."):
143
+ hf_pointer = getattr(hf_pointer, attribute)
144
+
145
+ if weight_type is not None:
146
+ hf_shape = getattr(hf_pointer, weight_type).shape
147
+ else:
148
+ hf_shape = hf_pointer.shape
149
+
150
+ if hf_shape != value.shape:
151
+ raise ValueError(
152
+ f"Shape of hf {key + '.' + weight_type if weight_type is not None else ''} is {hf_shape}, but should be"
153
+ f" {value.shape} for {full_name}"
154
+ )
155
+
156
+ if weight_type == "weight":
157
+ hf_pointer.weight.data = value
158
+ elif weight_type == "weight_g":
159
+ hf_pointer.weight_g.data = value
160
+ elif weight_type == "weight_v":
161
+ hf_pointer.weight_v.data = value
162
+ elif weight_type == "bias":
163
+ hf_pointer.bias.data = value
164
+ elif weight_type == "running_mean":
165
+ hf_pointer.running_mean.data = value
166
+ elif weight_type == "running_var":
167
+ hf_pointer.running_var.data = value
168
+ elif weight_type == "num_batches_tracked":
169
+ hf_pointer.num_batches_tracked.data = value
170
+ elif weight_type == "weight_ih_l0":
171
+ hf_pointer.weight_ih_l0.data = value
172
+ elif weight_type == "weight_hh_l0":
173
+ hf_pointer.weight_hh_l0.data = value
174
+ elif weight_type == "bias_ih_l0":
175
+ hf_pointer.bias_ih_l0.data = value
176
+ elif weight_type == "bias_hh_l0":
177
+ hf_pointer.bias_hh_l0.data = value
178
+ elif weight_type == "weight_ih_l1":
179
+ hf_pointer.weight_ih_l1.data = value
180
+ elif weight_type == "weight_hh_l1":
181
+ hf_pointer.weight_hh_l1.data = value
182
+ elif weight_type == "bias_ih_l1":
183
+ hf_pointer.bias_ih_l1.data = value
184
+ elif weight_type == "bias_hh_l1":
185
+ hf_pointer.bias_hh_l1.data = value
186
+ else:
187
+ hf_pointer.data = value
188
+
189
+ logger.info(f"{key + ('.' + weight_type if weight_type is not None else '')} was initialized from {full_name}.")
190
+
191
+
192
+ def should_ignore(name, ignore_keys):
193
+ for key in ignore_keys:
194
+ if key.endswith(".*"):
195
+ if name.startswith(key[:-1]):
196
+ return True
197
+ elif ".*." in key:
198
+ prefix, suffix = key.split(".*.")
199
+ if prefix in name and suffix in name:
200
+ return True
201
+ elif key in name:
202
+ return True
203
+ return False
204
+
205
+
206
+ def recursively_load_weights(orig_dict, hf_model, model_name):
207
+ unused_weights = []
208
+
209
+ if model_name in ["encodec_24khz", "encodec_32khz"]:
210
+ MAPPING = MAPPING_24K
211
+ elif model_name == "encodec_48khz":
212
+ MAPPING = MAPPING_48K
213
+ else:
214
+ raise ValueError(f"Unsupported model: {model_name}")
215
+
216
+ for name, value in orig_dict.items():
217
+ if should_ignore(name, IGNORE_KEYS):
218
+ logger.info(f"{name} was ignored")
219
+ continue
220
+
221
+ is_used = False
222
+ for key, mapped_key in MAPPING.items():
223
+ if "*" in key:
224
+ prefix, suffix = key.split(".*.")
225
+ if prefix in name and suffix in name:
226
+ key = suffix
227
+
228
+ if key in name:
229
+ # HACK otherwise .embed gets initialized with .embed_avg too
230
+ if key.endswith("embed") and name.endswith("embed_avg"):
231
+ continue
232
+
233
+ is_used = True
234
+ if "*" in mapped_key:
235
+ layer_index = name.split(key)[0].split(".")[-2]
236
+ mapped_key = mapped_key.replace("*", layer_index)
237
+ if "weight_g" in name:
238
+ weight_type = "weight_g"
239
+ elif "weight_v" in name:
240
+ weight_type = "weight_v"
241
+ elif "weight_ih_l0" in name:
242
+ weight_type = "weight_ih_l0"
243
+ elif "weight_hh_l0" in name:
244
+ weight_type = "weight_hh_l0"
245
+ elif "bias_ih_l0" in name:
246
+ weight_type = "bias_ih_l0"
247
+ elif "bias_hh_l0" in name:
248
+ weight_type = "bias_hh_l0"
249
+ elif "weight_ih_l1" in name:
250
+ weight_type = "weight_ih_l1"
251
+ elif "weight_hh_l1" in name:
252
+ weight_type = "weight_hh_l1"
253
+ elif "bias_ih_l1" in name:
254
+ weight_type = "bias_ih_l1"
255
+ elif "bias_hh_l1" in name:
256
+ weight_type = "bias_hh_l1"
257
+ elif "bias" in name:
258
+ weight_type = "bias"
259
+ elif "weight" in name:
260
+ weight_type = "weight"
261
+ elif "running_mean" in name:
262
+ weight_type = "running_mean"
263
+ elif "running_var" in name:
264
+ weight_type = "running_var"
265
+ elif "num_batches_tracked" in name:
266
+ weight_type = "num_batches_tracked"
267
+ else:
268
+ weight_type = None
269
+ set_recursively(hf_model, mapped_key, value, name, weight_type)
270
+ continue
271
+ if not is_used:
272
+ unused_weights.append(name)
273
+
274
+ logger.warning(f"Unused weights: {unused_weights}")
275
+
276
+
277
+ @torch.no_grad()
278
+ def convert_checkpoint(
279
+ model_name,
280
+ checkpoint_path,
281
+ pytorch_dump_folder_path,
282
+ config_path=None,
283
+ repo_id=None,
284
+ ):
285
+ """
286
+ Copy/paste/tweak model's weights to transformers design.
287
+ """
288
+ if config_path is not None:
289
+ config = EncodecConfig.from_pretrained(config_path)
290
+ else:
291
+ config = EncodecConfig()
292
+
293
+ if model_name == "encodec_24khz":
294
+ pass # config is already correct
295
+ elif model_name == "encodec_32khz":
296
+ config.upsampling_ratios = [8, 5, 4, 4]
297
+ config.target_bandwidths = [2.2]
298
+ config.num_filters = 64
299
+ config.sampling_rate = 32_000
300
+ config.codebook_size = 2048
301
+ config.use_causal_conv = False
302
+ config.normalize = False
303
+ config.use_conv_shortcut = False
304
+ elif model_name == "encodec_48khz":
305
+ config.upsampling_ratios = [8, 5, 4, 2]
306
+ config.target_bandwidths = [3.0, 6.0, 12.0, 24.0]
307
+ config.sampling_rate = 48_000
308
+ config.audio_channels = 2
309
+ config.use_causal_conv = False
310
+ config.norm_type = "time_group_norm"
311
+ config.normalize = True
312
+ config.chunk_length_s = 1.0
313
+ config.overlap = 0.01
314
+ else:
315
+ raise ValueError(f"Unknown model name: {model_name}")
316
+
317
+ model = EncodecModel(config)
318
+
319
+ feature_extractor = EncodecFeatureExtractor(
320
+ feature_size=config.audio_channels,
321
+ sampling_rate=config.sampling_rate,
322
+ chunk_length_s=config.chunk_length_s,
323
+ overlap=config.overlap,
324
+ )
325
+ feature_extractor.save_pretrained(pytorch_dump_folder_path)
326
+
327
+ original_checkpoint = torch.load(checkpoint_path, weights_only=True)
328
+ if "best_state" in original_checkpoint:
329
+ # we might have a training state saved, in which case discard the yaml results and just retain the weights
330
+ original_checkpoint = original_checkpoint["best_state"]
331
+ recursively_load_weights(original_checkpoint, model, model_name)
332
+ model.save_pretrained(pytorch_dump_folder_path)
333
+
334
+ if repo_id:
335
+ print("Pushing to the hub...")
336
+ feature_extractor.push_to_hub(repo_id)
337
+ model.push_to_hub(repo_id)
338
+
339
+
340
+ if __name__ == "__main__":
341
+ parser = argparse.ArgumentParser()
342
+ parser.add_argument(
343
+ "--model",
344
+ default="encodec_24khz",
345
+ type=str,
346
+ help="The model to convert. Should be one of 'encodec_24khz', 'encodec_32khz', 'encodec_48khz'.",
347
+ )
348
+ parser.add_argument("--checkpoint_path", required=True, default=None, type=str, help="Path to original checkpoint")
349
+ parser.add_argument("--config_path", default=None, type=str, help="Path to hf config.json of model to convert")
350
+ parser.add_argument(
351
+ "--pytorch_dump_folder_path", required=True, default=None, type=str, help="Path to the output PyTorch model."
352
+ )
353
+ parser.add_argument(
354
+ "--push_to_hub", default=None, type=str, help="Where to upload the converted model on the Hugging Face hub."
355
+ )
356
+
357
+ args = parser.parse_args()
358
+ convert_checkpoint(
359
+ args.model,
360
+ args.checkpoint_path,
361
+ args.pytorch_dump_folder_path,
362
+ args.config_path,
363
+ args.push_to_hub,
364
+ )
third_party/transformers/src/transformers/models/encodec/feature_extraction_encodec.py ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Feature extractor class for EnCodec."""
15
+
16
+ import numpy as np
17
+
18
+ from ...feature_extraction_sequence_utils import SequenceFeatureExtractor
19
+ from ...feature_extraction_utils import BatchFeature
20
+ from ...utils import PaddingStrategy, TensorType, logging
21
+
22
+
23
+ logger = logging.get_logger(__name__)
24
+
25
+
26
+ class EncodecFeatureExtractor(SequenceFeatureExtractor):
27
+ r"""
28
+ Constructs an EnCodec feature extractor.
29
+
30
+ This feature extractor inherits from [`~feature_extraction_sequence_utils.SequenceFeatureExtractor`] which contains
31
+ most of the main methods. Users should refer to this superclass for more information regarding those methods.
32
+
33
+ Instantiating a feature extractor with the defaults will yield a similar configuration to that of the
34
+ [facebook/encodec_24khz](https://huggingface.co/facebook/encodec_24khz) architecture.
35
+
36
+ Args:
37
+ feature_size (`int`, *optional*, defaults to 1):
38
+ The feature dimension of the extracted features. Use 1 for mono, 2 for stereo.
39
+ sampling_rate (`int`, *optional*, defaults to 24000):
40
+ The sampling rate at which the audio waveform should be digitalized expressed in hertz (Hz).
41
+ padding_value (`float`, *optional*, defaults to 0.0):
42
+ The value that is used to fill the padding values.
43
+ chunk_length_s (`float`, *optional*):
44
+ If defined the audio is pre-processed into chunks of lengths `chunk_length_s` and then encoded.
45
+ overlap (`float`, *optional*):
46
+ Defines the overlap between each chunk. It is used to compute the `chunk_stride` using the following
47
+ formulae : `int((1.0 - self.overlap) * self.chunk_length)`.
48
+ """
49
+
50
+ model_input_names = ["input_values", "padding_mask"]
51
+
52
+ def __init__(
53
+ self,
54
+ feature_size: int = 1,
55
+ sampling_rate: int = 24000,
56
+ padding_value: float = 0.0,
57
+ chunk_length_s: float | None = None,
58
+ overlap: float | None = None,
59
+ **kwargs,
60
+ ):
61
+ super().__init__(feature_size=feature_size, sampling_rate=sampling_rate, padding_value=padding_value, **kwargs)
62
+ self.chunk_length_s = chunk_length_s
63
+ self.overlap = overlap
64
+
65
+ # This is a property because you might want to change the chunk_length_s on the fly
66
+ @property
67
+ def chunk_length(self) -> int | None:
68
+ if self.chunk_length_s is None:
69
+ return None
70
+ else:
71
+ return int(self.chunk_length_s * self.sampling_rate)
72
+
73
+ # This is a property because you might want to change the chunk_length_s on the fly
74
+ @property
75
+ def chunk_stride(self) -> int | None:
76
+ if self.chunk_length_s is None or self.overlap is None:
77
+ return None
78
+ else:
79
+ return max(1, int((1.0 - self.overlap) * self.chunk_length))
80
+
81
+ def __call__(
82
+ self,
83
+ raw_audio: np.ndarray | list[float] | list[np.ndarray] | list[list[float]],
84
+ padding: bool | str | PaddingStrategy | None = None,
85
+ truncation: bool | None = False,
86
+ max_length: int | None = None,
87
+ return_tensors: str | TensorType | None = None,
88
+ sampling_rate: int | None = None,
89
+ ) -> BatchFeature:
90
+ """
91
+ Main method to featurize and prepare for the model one or several sequence(s).
92
+
93
+ Args:
94
+ raw_audio (`np.ndarray`, `list[float]`, `list[np.ndarray]`, `list[list[float]]`):
95
+ The sequence or batch of sequences to be processed. Each sequence can be a numpy array, a list of float
96
+ values, a list of numpy arrays or a list of list of float values. The numpy array must be of shape
97
+ `(num_samples,)` for mono audio (`feature_size = 1`), or `(2, num_samples)` for stereo audio
98
+ (`feature_size = 2`).
99
+ padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `True`):
100
+ Select a strategy to pad the returned sequences (according to the model's padding side and padding
101
+ index) among:
102
+
103
+ - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single
104
+ sequence if provided).
105
+ - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum
106
+ acceptable input length for the model if that argument is not provided.
107
+ - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different
108
+ lengths).
109
+ truncation (`bool`, *optional*, defaults to `False`):
110
+ Activates truncation to cut input sequences longer than `max_length` to `max_length`.
111
+ max_length (`int`, *optional*):
112
+ Maximum length of the returned list and optionally padding length (see above).
113
+ return_tensors (`str` or [`~utils.TensorType`], *optional*):
114
+ If set, will return tensors instead of list of python integers. Acceptable values are:
115
+
116
+ - `'pt'`: Return PyTorch `torch.Tensor` objects.
117
+ - `'np'`: Return Numpy `np.ndarray` objects.
118
+ sampling_rate (`int`, *optional*):
119
+ The sampling rate at which the `audio` input was sampled. It is strongly recommended to pass
120
+ `sampling_rate` at the forward call to prevent silent errors.
121
+ """
122
+ if sampling_rate is not None:
123
+ if sampling_rate != self.sampling_rate:
124
+ raise ValueError(
125
+ f"The model corresponding to this feature extractor: {self} was trained using a sampling rate of"
126
+ f" {self.sampling_rate}. Please make sure that the provided audio input was sampled with"
127
+ f" {self.sampling_rate} and not {sampling_rate}."
128
+ )
129
+ else:
130
+ logger.warning(
131
+ f"It is strongly recommended to pass the `sampling_rate` argument to `{self.__class__.__name__}()`. "
132
+ "Failing to do so can result in silent errors that might be hard to debug."
133
+ )
134
+
135
+ if padding and truncation:
136
+ raise ValueError("Both padding and truncation were set. Make sure you only set one.")
137
+ elif padding is None:
138
+ # by default let's pad the inputs
139
+ padding = True
140
+
141
+ is_batched = bool(
142
+ isinstance(raw_audio, (list, tuple)) and (isinstance(raw_audio[0], (np.ndarray, tuple, list)))
143
+ )
144
+
145
+ if is_batched:
146
+ raw_audio = [np.asarray(audio, dtype=np.float32).T for audio in raw_audio]
147
+ elif not is_batched and not isinstance(raw_audio, np.ndarray):
148
+ raw_audio = np.asarray(raw_audio, dtype=np.float32)
149
+ elif isinstance(raw_audio, np.ndarray) and raw_audio.dtype is np.dtype(np.float64):
150
+ raw_audio = raw_audio.astype(np.float32)
151
+
152
+ # always return batch
153
+ if not is_batched:
154
+ raw_audio = [np.asarray(raw_audio).T]
155
+
156
+ # verify inputs are valid
157
+ for idx, example in enumerate(raw_audio):
158
+ if example.ndim > 2:
159
+ raise ValueError(f"Expected input shape (channels, length) but got shape {example.shape}")
160
+ if self.feature_size == 1 and example.ndim != 1:
161
+ raise ValueError(f"Expected mono audio but example has {example.shape[-1]} channels")
162
+ if self.feature_size == 2 and example.shape[-1] != 2:
163
+ raise ValueError(f"Expected stereo audio but example has {example.shape[-1]} channels")
164
+
165
+ padded_inputs = None
166
+ input_values = BatchFeature({"input_values": raw_audio})
167
+ if self.chunk_stride is not None and self.chunk_length is not None and max_length is None:
168
+ if truncation:
169
+ max_length = min(array.shape[0] for array in raw_audio)
170
+ nb_step = int(np.floor(max_length / self.chunk_stride))
171
+ max_length = (nb_step - 1) * self.chunk_stride + self.chunk_length
172
+ elif padding:
173
+ max_length = max(array.shape[0] for array in raw_audio)
174
+ nb_step = int(np.ceil(max_length / self.chunk_stride))
175
+ max_length = (nb_step - 1) * self.chunk_stride + self.chunk_length
176
+ padding = "max_length"
177
+ else:
178
+ padded_inputs = input_values
179
+
180
+ # normal padding on batch
181
+ if padded_inputs is None:
182
+ padded_inputs = self.pad(
183
+ input_values,
184
+ max_length=max_length,
185
+ truncation=truncation,
186
+ padding=padding,
187
+ return_attention_mask=padding,
188
+ )
189
+ if padding:
190
+ padded_inputs["padding_mask"] = padded_inputs.pop("attention_mask")
191
+
192
+ input_values = []
193
+ for example in padded_inputs.pop("input_values"):
194
+ if self.feature_size == 1:
195
+ example = example[..., None]
196
+ input_values.append(example.T)
197
+
198
+ padded_inputs["input_values"] = input_values
199
+ if return_tensors is not None:
200
+ padded_inputs = padded_inputs.convert_to_tensors(return_tensors)
201
+
202
+ return padded_inputs
203
+
204
+
205
+ __all__ = ["EncodecFeatureExtractor"]
third_party/transformers/src/transformers/models/encodec/modeling_encodec.py ADDED
@@ -0,0 +1,822 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 Meta Platforms, Inc. and affiliates, 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 EnCodec model."""
15
+
16
+ import math
17
+ from dataclasses import dataclass
18
+
19
+ import torch
20
+ from torch import nn
21
+
22
+ from ... import initialization as init
23
+ from ...modeling_utils import PreTrainedAudioTokenizerBase
24
+ from ...utils import (
25
+ ModelOutput,
26
+ auto_docstring,
27
+ logging,
28
+ )
29
+ from .configuration_encodec import EncodecConfig
30
+
31
+
32
+ logger = logging.get_logger(__name__)
33
+
34
+
35
+ # General docstring
36
+
37
+
38
+ @dataclass
39
+ @auto_docstring
40
+ class EncodecOutput(ModelOutput):
41
+ r"""
42
+ audio_codes (`torch.LongTensor` of shape `(nb_frames, batch_size, nb_quantizers, frame_len)`, *optional*):
43
+ Discrete code embeddings computed using `model.encode`.
44
+ audio_values (`torch.FloatTensor` of shape `(batch_size, segment_length)`, *optional*):
45
+ Decoded audio values, obtained using the decoder part of Encodec.
46
+ """
47
+
48
+ audio_codes: torch.LongTensor | None = None
49
+ audio_values: torch.FloatTensor | None = None
50
+
51
+
52
+ @dataclass
53
+ @auto_docstring
54
+ class EncodecEncoderOutput(ModelOutput):
55
+ r"""
56
+ audio_codes (`torch.LongTensor` of shape `(nb_frames, batch_size, nb_quantizers, frame_len)`, *optional*):
57
+ Discrete code embeddings computed using `model.encode`.
58
+ audio_scales (list of length `nb_frames` of `torch.Tensor` of shape `(batch_size, 1)`, *optional*):
59
+ Scaling factor for each `audio_codes` input. This is used to unscale each chunk of audio when decoding.
60
+ last_frame_pad_length (`int`, *optional*):
61
+ The length of the padding in the last frame, if any. This is used to ensure that the encoded frames can be
62
+ outputted as a tensor. This value should be passed during decoding to ensure padding is removed from the
63
+ encoded frames.
64
+ """
65
+
66
+ audio_codes: torch.LongTensor | None = None
67
+ audio_scales: torch.FloatTensor | None = None
68
+ last_frame_pad_length: int | None = None
69
+
70
+
71
+ @dataclass
72
+ @auto_docstring
73
+ class EncodecDecoderOutput(ModelOutput):
74
+ r"""
75
+ audio_values (`torch.FloatTensor` of shape `(batch_size, segment_length)`, *optional*):
76
+ Decoded audio values, obtained using the decoder part of Encodec.
77
+ """
78
+
79
+ audio_values: torch.FloatTensor | None = None
80
+
81
+
82
+ class EncodecConv1d(nn.Module):
83
+ """Conv1d with asymmetric or causal padding and normalization."""
84
+
85
+ def __init__(
86
+ self, config, in_channels: int, out_channels: int, kernel_size: int, stride: int = 1, dilation: int = 1
87
+ ):
88
+ super().__init__()
89
+ self.causal = config.use_causal_conv
90
+ self.pad_mode = config.pad_mode
91
+ self.norm_type = config.norm_type
92
+
93
+ if self.norm_type not in ["weight_norm", "time_group_norm"]:
94
+ raise ValueError(
95
+ f'self.norm_type must be one of `"weight_norm"`, `"time_group_norm"`), got {self.norm_type}'
96
+ )
97
+
98
+ # warn user on unusual setup between dilation and stride
99
+ if stride > 1 and dilation > 1:
100
+ logger.warning(
101
+ "EncodecConv1d has been initialized with stride > 1 and dilation > 1"
102
+ f" (kernel_size={kernel_size} stride={stride}, dilation={dilation})."
103
+ )
104
+
105
+ self.conv = nn.Conv1d(in_channels, out_channels, kernel_size, stride, dilation=dilation)
106
+ weight_norm = nn.utils.weight_norm
107
+ if hasattr(nn.utils.parametrizations, "weight_norm"):
108
+ weight_norm = nn.utils.parametrizations.weight_norm
109
+
110
+ if self.norm_type == "weight_norm":
111
+ self.conv = weight_norm(self.conv)
112
+ elif self.norm_type == "time_group_norm":
113
+ self.norm = nn.GroupNorm(1, out_channels)
114
+
115
+ kernel_size = self.conv.kernel_size[0]
116
+ stride = torch.tensor(self.conv.stride[0], dtype=torch.int64)
117
+ dilation = self.conv.dilation[0]
118
+
119
+ # Effective kernel size with dilations.
120
+ kernel_size = torch.tensor((kernel_size - 1) * dilation + 1, dtype=torch.int64)
121
+
122
+ self.register_buffer("stride", stride, persistent=False)
123
+ self.register_buffer("kernel_size", kernel_size, persistent=False)
124
+ self.register_buffer("padding_total", kernel_size - stride, persistent=False)
125
+
126
+ def _get_extra_padding_for_conv1d(
127
+ self,
128
+ hidden_states: torch.Tensor,
129
+ ) -> torch.Tensor:
130
+ """See `pad_for_conv1d`."""
131
+ length = hidden_states.shape[-1]
132
+ n_frames = (length - self.kernel_size + self.padding_total) / self.stride + 1
133
+ n_frames = torch.ceil(n_frames).to(torch.int64) - 1
134
+ ideal_length = n_frames * self.stride + self.kernel_size - self.padding_total
135
+
136
+ return ideal_length - length
137
+
138
+ @staticmethod
139
+ def _pad1d(hidden_states: torch.Tensor, paddings: tuple[int, int], mode: str = "zero", value: float = 0.0):
140
+ """Tiny wrapper around torch.nn.functional.pad, just to allow for reflect padding on small input.
141
+ If this is the case, we insert extra 0 padding to the right before the reflection happens.
142
+ """
143
+ length = hidden_states.shape[-1]
144
+ padding_left, padding_right = paddings
145
+ if mode != "reflect":
146
+ return nn.functional.pad(hidden_states, paddings, mode, value)
147
+
148
+ max_pad = max(padding_left, padding_right)
149
+ extra_pad = 0
150
+ if length <= max_pad:
151
+ extra_pad = max_pad - length + 1
152
+ hidden_states = nn.functional.pad(hidden_states, (0, extra_pad))
153
+ padded = nn.functional.pad(hidden_states, paddings, mode, value)
154
+ end = padded.shape[-1] - extra_pad
155
+ return padded[..., :end]
156
+
157
+ def forward(self, hidden_states):
158
+ extra_padding = self._get_extra_padding_for_conv1d(hidden_states)
159
+
160
+ if self.causal:
161
+ # Left padding for causal
162
+ hidden_states = self._pad1d(hidden_states, (self.padding_total, extra_padding), mode=self.pad_mode)
163
+ else:
164
+ # Asymmetric padding required for odd strides
165
+ padding_right = self.padding_total // 2
166
+ padding_left = self.padding_total - padding_right
167
+ hidden_states = self._pad1d(
168
+ hidden_states, (padding_left, padding_right + extra_padding), mode=self.pad_mode
169
+ )
170
+
171
+ hidden_states = self.conv(hidden_states)
172
+
173
+ if self.norm_type == "time_group_norm":
174
+ hidden_states = self.norm(hidden_states)
175
+
176
+ return hidden_states
177
+
178
+
179
+ class EncodecConvTranspose1d(nn.Module):
180
+ """ConvTranspose1d with asymmetric or causal padding and normalization."""
181
+
182
+ def __init__(self, config, in_channels: int, out_channels: int, kernel_size: int, stride: int = 1):
183
+ super().__init__()
184
+ self.causal = config.use_causal_conv
185
+ self.trim_right_ratio = config.trim_right_ratio
186
+ self.norm_type = config.norm_type
187
+ if self.norm_type not in ["weight_norm", "time_group_norm"]:
188
+ raise ValueError(
189
+ f'self.norm_type must be one of `"weight_norm"`, `"time_group_norm"`), got {self.norm_type}'
190
+ )
191
+
192
+ self.conv = nn.ConvTranspose1d(in_channels, out_channels, kernel_size, stride)
193
+
194
+ weight_norm = nn.utils.weight_norm
195
+ if hasattr(nn.utils.parametrizations, "weight_norm"):
196
+ weight_norm = nn.utils.parametrizations.weight_norm
197
+
198
+ if config.norm_type == "weight_norm":
199
+ self.conv = weight_norm(self.conv)
200
+ elif config.norm_type == "time_group_norm":
201
+ self.norm = nn.GroupNorm(1, out_channels)
202
+
203
+ if not (self.causal or self.trim_right_ratio == 1.0):
204
+ raise ValueError("`trim_right_ratio` != 1.0 only makes sense for causal convolutions")
205
+
206
+ def forward(self, hidden_states):
207
+ kernel_size = self.conv.kernel_size[0]
208
+ stride = self.conv.stride[0]
209
+ padding_total = kernel_size - stride
210
+
211
+ hidden_states = self.conv(hidden_states)
212
+
213
+ if self.norm_type == "time_group_norm":
214
+ hidden_states = self.norm(hidden_states)
215
+
216
+ # We will only trim fixed padding. Extra padding from `pad_for_conv1d` would be
217
+ # removed at the very end, when keeping only the right length for the output,
218
+ # as removing it here would require also passing the length at the matching layer
219
+ # in the encoder.
220
+ if self.causal:
221
+ # Trim the padding on the right according to the specified ratio
222
+ # if trim_right_ratio = 1.0, trim everything from right
223
+ padding_right = math.ceil(padding_total * self.trim_right_ratio)
224
+ else:
225
+ # Asymmetric padding required for odd strides
226
+ padding_right = padding_total // 2
227
+
228
+ padding_left = padding_total - padding_right
229
+
230
+ # unpad
231
+ end = hidden_states.shape[-1] - padding_right
232
+ hidden_states = hidden_states[..., padding_left:end]
233
+ return hidden_states
234
+
235
+
236
+ class EncodecLSTM(nn.Module):
237
+ """
238
+ LSTM without worrying about the hidden state, nor the layout of the data. Expects input as convolutional layout.
239
+ """
240
+
241
+ def __init__(self, config: EncodecConfig, dimension: int):
242
+ super().__init__()
243
+ self.lstm = nn.LSTM(dimension, dimension, config.num_lstm_layers)
244
+
245
+ def forward(self, hidden_states):
246
+ hidden_states = hidden_states.permute(2, 0, 1)
247
+ hidden_states = self.lstm(hidden_states)[0] + hidden_states
248
+ hidden_states = hidden_states.permute(1, 2, 0)
249
+ return hidden_states
250
+
251
+
252
+ class EncodecResnetBlock(nn.Module):
253
+ """
254
+ Residual block from SEANet model as used by EnCodec.
255
+ """
256
+
257
+ def __init__(self, config: EncodecConfig, dim: int, dilations: list[int]):
258
+ super().__init__()
259
+ kernel_sizes = (config.residual_kernel_size, 1)
260
+ if len(kernel_sizes) != len(dilations):
261
+ raise ValueError("Number of kernel sizes should match number of dilations")
262
+
263
+ hidden = dim // config.compress
264
+ block = []
265
+ for i, (kernel_size, dilation) in enumerate(zip(kernel_sizes, dilations)):
266
+ in_chs = dim if i == 0 else hidden
267
+ out_chs = dim if i == len(kernel_sizes) - 1 else hidden
268
+ block += [nn.ELU()]
269
+ block += [EncodecConv1d(config, in_chs, out_chs, kernel_size, dilation=dilation)]
270
+ self.block = nn.ModuleList(block)
271
+
272
+ if config.use_conv_shortcut:
273
+ self.shortcut = EncodecConv1d(config, dim, dim, kernel_size=1)
274
+ else:
275
+ self.shortcut = nn.Identity()
276
+
277
+ def forward(self, hidden_states):
278
+ residual = hidden_states
279
+ for layer in self.block:
280
+ hidden_states = layer(hidden_states)
281
+
282
+ return self.shortcut(residual) + hidden_states
283
+
284
+
285
+ class EncodecEncoder(nn.Module):
286
+ """SEANet encoder as used by EnCodec."""
287
+
288
+ def __init__(self, config: EncodecConfig):
289
+ super().__init__()
290
+ model = [EncodecConv1d(config, config.audio_channels, config.num_filters, config.kernel_size)]
291
+ scaling = 1
292
+
293
+ # Downsample to raw audio scale
294
+ for ratio in reversed(config.upsampling_ratios):
295
+ current_scale = scaling * config.num_filters
296
+ # Add residual layers
297
+ for j in range(config.num_residual_layers):
298
+ model += [EncodecResnetBlock(config, current_scale, [config.dilation_growth_rate**j, 1])]
299
+ # Add downsampling layers
300
+ model += [nn.ELU()]
301
+ model += [EncodecConv1d(config, current_scale, current_scale * 2, kernel_size=ratio * 2, stride=ratio)]
302
+ scaling *= 2
303
+
304
+ model += [EncodecLSTM(config, scaling * config.num_filters)]
305
+ model += [nn.ELU()]
306
+ model += [EncodecConv1d(config, scaling * config.num_filters, config.hidden_size, config.last_kernel_size)]
307
+
308
+ self.layers = nn.ModuleList(model)
309
+
310
+ def forward(self, hidden_states):
311
+ for layer in self.layers:
312
+ hidden_states = layer(hidden_states)
313
+ return hidden_states
314
+
315
+
316
+ class EncodecDecoder(nn.Module):
317
+ """SEANet decoder as used by EnCodec."""
318
+
319
+ def __init__(self, config: EncodecConfig):
320
+ super().__init__()
321
+ scaling = int(2 ** len(config.upsampling_ratios))
322
+ model = [EncodecConv1d(config, config.hidden_size, scaling * config.num_filters, config.kernel_size)]
323
+
324
+ model += [EncodecLSTM(config, scaling * config.num_filters)]
325
+
326
+ # Upsample to raw audio scale
327
+ for ratio in config.upsampling_ratios:
328
+ current_scale = scaling * config.num_filters
329
+ # Add upsampling layers
330
+ model += [nn.ELU()]
331
+ model += [
332
+ EncodecConvTranspose1d(config, current_scale, current_scale // 2, kernel_size=ratio * 2, stride=ratio)
333
+ ]
334
+ # Add residual layers
335
+ for j in range(config.num_residual_layers):
336
+ model += [EncodecResnetBlock(config, current_scale // 2, (config.dilation_growth_rate**j, 1))]
337
+ scaling //= 2
338
+
339
+ # Add final layers
340
+ model += [nn.ELU()]
341
+ model += [EncodecConv1d(config, config.num_filters, config.audio_channels, config.last_kernel_size)]
342
+ self.layers = nn.ModuleList(model)
343
+
344
+ def forward(self, hidden_states):
345
+ for layer in self.layers:
346
+ hidden_states = layer(hidden_states)
347
+ return hidden_states
348
+
349
+
350
+ class EncodecEuclideanCodebook(nn.Module):
351
+ """Codebook with Euclidean distance."""
352
+
353
+ def __init__(self, config: EncodecConfig):
354
+ super().__init__()
355
+ embed = torch.zeros(config.codebook_size, config.codebook_dim)
356
+
357
+ self.codebook_size = config.codebook_size
358
+
359
+ self.register_buffer("inited", torch.Tensor([True]))
360
+ self.register_buffer("cluster_size", torch.zeros(config.codebook_size))
361
+ self.register_buffer("embed", embed)
362
+ self.register_buffer("embed_avg", embed.clone())
363
+
364
+ def quantize(self, hidden_states):
365
+ embed = self.embed.t()
366
+ scaled_states = hidden_states.pow(2).sum(1, keepdim=True)
367
+ dist = -(scaled_states - 2 * hidden_states @ embed + embed.pow(2).sum(0, keepdim=True))
368
+ embed_ind = dist.max(dim=-1).indices
369
+ return embed_ind
370
+
371
+ def encode(self, hidden_states):
372
+ shape = hidden_states.shape
373
+ # pre-process
374
+ hidden_states = hidden_states.reshape((-1, shape[-1]))
375
+ # quantize
376
+ embed_ind = self.quantize(hidden_states)
377
+ # post-process
378
+ embed_ind = embed_ind.view(*shape[:-1])
379
+ return embed_ind
380
+
381
+ def decode(self, embed_ind):
382
+ quantize = nn.functional.embedding(embed_ind, self.embed)
383
+ return quantize
384
+
385
+
386
+ class EncodecVectorQuantization(nn.Module):
387
+ """
388
+ Vector quantization implementation. Currently supports only euclidean distance.
389
+ """
390
+
391
+ def __init__(self, config: EncodecConfig):
392
+ super().__init__()
393
+ self.codebook = EncodecEuclideanCodebook(config)
394
+
395
+ def encode(self, hidden_states):
396
+ hidden_states = hidden_states.permute(0, 2, 1)
397
+ embed_in = self.codebook.encode(hidden_states)
398
+ return embed_in
399
+
400
+ def decode(self, embed_ind):
401
+ quantize = self.codebook.decode(embed_ind)
402
+ quantize = quantize.permute(0, 2, 1)
403
+ return quantize
404
+
405
+
406
+ class EncodecResidualVectorQuantizer(nn.Module):
407
+ """Residual Vector Quantizer."""
408
+
409
+ def __init__(self, config: EncodecConfig):
410
+ super().__init__()
411
+ self.codebook_size = config.codebook_size
412
+ self.frame_rate = config.frame_rate
413
+ self.num_quantizers = config.num_quantizers
414
+ self.layers = nn.ModuleList([EncodecVectorQuantization(config) for _ in range(config.num_quantizers)])
415
+
416
+ def get_num_quantizers_for_bandwidth(self, bandwidth: float | None = None) -> int:
417
+ """Return num_quantizers based on specified target bandwidth."""
418
+ bw_per_q = math.log2(self.codebook_size) * self.frame_rate
419
+ num_quantizers = self.num_quantizers
420
+ if bandwidth is not None and bandwidth > 0.0:
421
+ num_quantizers = int(max(1, math.floor(bandwidth * 1000 / bw_per_q)))
422
+ return num_quantizers
423
+
424
+ def encode(self, embeddings: torch.Tensor, bandwidth: float | None = None) -> torch.Tensor:
425
+ """
426
+ Encode a given input tensor with the specified frame rate at the given bandwidth. The RVQ encode method sets
427
+ the appropriate number of quantizers to use and returns indices for each quantizer.
428
+ """
429
+ num_quantizers = self.get_num_quantizers_for_bandwidth(bandwidth)
430
+ residual = embeddings
431
+ all_indices = []
432
+ for layer in self.layers[:num_quantizers]:
433
+ indices = layer.encode(residual)
434
+ quantized = layer.decode(indices)
435
+ residual = residual - quantized
436
+ all_indices.append(indices)
437
+ out_indices = torch.stack(all_indices)
438
+ return out_indices
439
+
440
+ def decode(self, codes: torch.Tensor) -> torch.Tensor:
441
+ """Decode the given codes to the quantized representation."""
442
+ quantized_out = torch.tensor(0.0, device=codes.device)
443
+ for i, indices in enumerate(codes):
444
+ layer = self.layers[i]
445
+ quantized = layer.decode(indices)
446
+ quantized_out = quantized_out + quantized
447
+ return quantized_out
448
+
449
+
450
+ @auto_docstring
451
+ class EncodecPreTrainedModel(PreTrainedAudioTokenizerBase):
452
+ config: EncodecConfig
453
+ base_model_prefix = "encodec"
454
+ main_input_name = "input_values"
455
+
456
+ @torch.no_grad()
457
+ def _init_weights(self, module):
458
+ """Initialize the weights"""
459
+ if isinstance(module, nn.GroupNorm):
460
+ init.zeros_(module.bias)
461
+ init.ones_(module.weight)
462
+ elif isinstance(module, nn.Conv1d):
463
+ init.kaiming_normal_(module.weight)
464
+ if module.bias is not None:
465
+ k = math.sqrt(module.groups / (module.in_channels * module.kernel_size[0]))
466
+ init.uniform_(module.bias, a=-k, b=k)
467
+ elif isinstance(module, nn.ConvTranspose1d):
468
+ module.reset_parameters()
469
+ elif isinstance(module, nn.LSTM):
470
+ for name, param in module.named_parameters():
471
+ if "weight" in name:
472
+ init.xavier_uniform_(param)
473
+ elif "bias" in name:
474
+ init.constant_(param, 0.0)
475
+ elif isinstance(module, EncodecConv1d):
476
+ kernel_size = module.conv.kernel_size[0]
477
+ stride = torch.tensor(module.conv.stride[0], dtype=torch.int64)
478
+ dilation = module.conv.dilation[0]
479
+ # Effective kernel size with dilations.
480
+ kernel_size = torch.tensor((kernel_size - 1) * dilation + 1, dtype=torch.int64)
481
+ init.copy_(module.stride, stride)
482
+ init.copy_(module.kernel_size, kernel_size)
483
+ init.copy_(module.padding_total, kernel_size - stride)
484
+ elif isinstance(module, EncodecEuclideanCodebook):
485
+ init.copy_(module.inited, torch.Tensor([True]))
486
+ init.zeros_(module.cluster_size)
487
+ init.zeros_(module.embed)
488
+ init.zeros_(module.embed_avg)
489
+
490
+
491
+ @auto_docstring(
492
+ custom_intro="""
493
+ The EnCodec neural audio codec model.
494
+ """
495
+ )
496
+ class EncodecModel(EncodecPreTrainedModel):
497
+ def __init__(self, config: EncodecConfig):
498
+ super().__init__(config)
499
+ self.config = config
500
+
501
+ self.encoder = EncodecEncoder(config)
502
+ self.decoder = EncodecDecoder(config)
503
+
504
+ self.quantizer = EncodecResidualVectorQuantizer(config)
505
+
506
+ self.bits_per_codebook = int(math.log2(self.config.codebook_size))
507
+ if 2**self.bits_per_codebook != self.config.codebook_size:
508
+ raise ValueError("The codebook_size must be a power of 2.")
509
+
510
+ # Initialize weights and apply final processing
511
+ self.post_init()
512
+
513
+ def _encode_frame(self, input_values: torch.Tensor, bandwidth: float) -> tuple[torch.Tensor, torch.Tensor | None]:
514
+ """
515
+ Encodes the given input using the underlying VQVAE. If `config.normalize` is set to `True` the input is first
516
+ normalized. The padding mask is required to compute the correct scale.
517
+ """
518
+ length = input_values.shape[-1]
519
+ duration = length / self.config.sampling_rate
520
+
521
+ if self.config.chunk_length_s is not None and duration > 1e-5 + self.config.chunk_length_s:
522
+ raise RuntimeError(f"Duration of frame ({duration}) is longer than chunk {self.config.chunk_length_s}")
523
+
524
+ scale = None
525
+ if self.config.normalize:
526
+ mono = torch.sum(input_values, 1, keepdim=True) / input_values.shape[1]
527
+ scale = mono.pow(2).mean(dim=-1, keepdim=True).sqrt() + 1e-8
528
+ input_values = input_values / scale
529
+ scale = scale.view(-1, 1)
530
+
531
+ embeddings = self.encoder(input_values)
532
+ codes = self.quantizer.encode(embeddings, bandwidth)
533
+ codes = codes.transpose(0, 1)
534
+ return codes, scale
535
+
536
+ def encode(
537
+ self,
538
+ input_values: torch.Tensor,
539
+ padding_mask: torch.Tensor | None = None,
540
+ bandwidth: float | None = None,
541
+ return_dict: bool | None = None,
542
+ ) -> tuple[torch.Tensor, torch.Tensor | None, int] | EncodecEncoderOutput:
543
+ """
544
+ Encodes the input audio waveform into discrete codes of shape
545
+ `(nb_frames, batch_size, nb_quantizers, frame_len)`.
546
+
547
+ - `nb_frames=1` if `self.config.chunk_length=None` (as the encoder is applied on the full audio), which is the
548
+ case for the 24kHz model. Otherwise, `nb_frames=ceil(input_length/self.config.chunk_stride)`, which is the case
549
+ for the 48kHz model.
550
+ - `frame_len` is the length of each frame, which is equal to `ceil(input_length/self.config.hop_length)` if
551
+ `self.config.chunk_length=None` (e.g., for the 24kHz model). Otherwise, if `self.config.chunk_length` is
552
+ defined, `frame_len=self.config.chunk_length/self.config.hop_length`, e.g., the case for the 48kHz model with
553
+ `frame_len=150`.
554
+
555
+ Args:
556
+ input_values (`torch.Tensor` of shape `(batch_size, channels, sequence_length)`):
557
+ Float values of the input audio waveform.
558
+ padding_mask (`torch.Tensor` of shape `(batch_size, channels, sequence_length)`):
559
+ Padding mask used to pad the `input_values`.
560
+ bandwidth (`float`, *optional*):
561
+ The target bandwidth. Must be one of `config.target_bandwidths`. If `None`, uses the smallest possible
562
+ bandwidth. bandwidth is represented as a thousandth of what it is, e.g. 6kbps bandwidth is represented
563
+ as bandwidth == 6.0
564
+
565
+ Returns:
566
+ EncodecEncoderOutput dict or a tuple containing:
567
+ - audio_codes (`torch.LongTensor` of shape `(nb_frames, batch_size, nb_quantizers, frame_len)`, *optional*),
568
+ - audio_scales (list of length `nb_frames` of `torch.Tensor` of shape `(batch_size, 1)`, *optional*),
569
+ - last_frame_pad_length (`int`, *optional*).
570
+ """
571
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
572
+
573
+ if bandwidth is None:
574
+ bandwidth = self.config.target_bandwidths[0]
575
+ if bandwidth not in self.config.target_bandwidths:
576
+ raise ValueError(
577
+ f"This model doesn't support the bandwidth {bandwidth}. Select one of {self.config.target_bandwidths}."
578
+ )
579
+
580
+ _, channels, input_length = input_values.shape
581
+
582
+ if channels < 1 or channels > 2:
583
+ raise ValueError(f"Number of audio channels must be 1 or 2, but got {channels}")
584
+
585
+ chunk_length = self.config.chunk_length
586
+ if chunk_length is None:
587
+ chunk_length = input_length
588
+ stride = input_length
589
+ else:
590
+ stride = self.config.chunk_stride
591
+
592
+ if padding_mask is None:
593
+ padding_mask = torch.ones_like(input_values).bool()
594
+ else:
595
+ padding_mask = padding_mask.view(padding_mask.shape[0], -1, padding_mask.shape[-1])
596
+
597
+ encoded_frames = []
598
+ scales = []
599
+ for offset in range(0, input_length, stride):
600
+ mask = padding_mask[..., offset : offset + chunk_length].bool()
601
+ frame = mask * input_values[..., offset : offset + chunk_length]
602
+ encoded_frame, scale = self._encode_frame(frame, bandwidth)
603
+ encoded_frames.append(encoded_frame)
604
+ scales.append(scale)
605
+
606
+ # pad last frame (if necessary) to be able to apply `torch.stack`
607
+ last_frame_pad_length = encoded_frames[0].shape[-1] - encoded_frames[-1].shape[-1]
608
+ if last_frame_pad_length > 0:
609
+ last_frame = nn.functional.pad(encoded_frames[-1], (0, last_frame_pad_length), value=0)
610
+ encoded_frames[-1] = last_frame
611
+ encoded_frames = torch.stack(encoded_frames)
612
+
613
+ if not return_dict:
614
+ return (encoded_frames, scales, last_frame_pad_length)
615
+ return EncodecEncoderOutput(encoded_frames, scales, last_frame_pad_length)
616
+
617
+ @staticmethod
618
+ def _linear_overlap_add(frames: list[torch.Tensor], stride: int):
619
+ # Generic overlap add, with linear fade-in/fade-out, supporting complex scenario
620
+ # e.g., more than 2 frames per position.
621
+ # The core idea is to use a weight function that is a triangle,
622
+ # with a maximum value at the middle of the chunk.
623
+ # We use this weighting when summing the frames, and divide by the sum of weights
624
+ # for each positions at the end. Thus:
625
+ # - if a frame is the only one to cover a position, the weighting is a no-op.
626
+ # - if 2 frames cover a position:
627
+ # ... ...
628
+ # / \/ \
629
+ # / /\ \
630
+ # S T , i.e. S offset of second frame starts, T end of first frame.
631
+ # Then the weight function for each one is: (t - S), (T - t), with `t` a given offset.
632
+ # After the final normalization, the weight of the second frame at position `t` is
633
+ # (t - S) / (t - S + (T - t)) = (t - S) / (T - S), which is exactly what we want.
634
+ #
635
+ # - if more than 2 frames overlap at a given point, we hope that by induction
636
+ # something sensible happens.
637
+ if len(frames) == 0:
638
+ raise ValueError("`frames` cannot be an empty list.")
639
+
640
+ device = frames[0].device
641
+ dtype = frames[0].dtype
642
+ shape = frames[0].shape[:-1]
643
+ total_size = stride * (len(frames) - 1) + frames[-1].shape[-1]
644
+
645
+ frame_length = frames[0].shape[-1]
646
+ time_vec = torch.linspace(0, 1, frame_length + 2, device=device, dtype=dtype)[1:-1]
647
+ weight = 0.5 - (time_vec - 0.5).abs()
648
+
649
+ sum_weight = torch.zeros(total_size, device=device, dtype=dtype)
650
+ out = torch.zeros(*shape, total_size, device=device, dtype=dtype)
651
+ offset: int = 0
652
+
653
+ for frame in frames:
654
+ frame_length = frame.shape[-1]
655
+ out[..., offset : offset + frame_length] += weight[:frame_length] * frame
656
+ sum_weight[offset : offset + frame_length] += weight[:frame_length]
657
+ offset += stride
658
+
659
+ if sum_weight.min() == 0:
660
+ raise ValueError(f"`sum_weight` minimum element must be bigger than zero: {sum_weight}`")
661
+
662
+ return out / sum_weight
663
+
664
+ def _decode_frame(self, codes: torch.Tensor, scale: torch.Tensor | None = None) -> torch.Tensor:
665
+ codes = codes.transpose(0, 1)
666
+ embeddings = self.quantizer.decode(codes)
667
+ outputs = self.decoder(embeddings)
668
+ if scale is not None:
669
+ outputs = outputs * scale.view(-1, 1, 1)
670
+ return outputs
671
+
672
+ def decode(
673
+ self,
674
+ audio_codes: torch.LongTensor,
675
+ audio_scales: torch.Tensor,
676
+ padding_mask: torch.Tensor | None = None,
677
+ return_dict: bool | None = None,
678
+ last_frame_pad_length: int | None = 0,
679
+ ) -> tuple[torch.Tensor, torch.Tensor] | EncodecDecoderOutput:
680
+ """
681
+ Decodes the given frames into an output audio waveform.
682
+
683
+ Note that the output might be a bit bigger than the input. In that case, any extra steps at the end can be
684
+ trimmed.
685
+
686
+ Args:
687
+ audio_codes (`torch.LongTensor` of shape `(nb_frames, batch_size, nb_quantizers, frame_len)`, *optional*):
688
+ Discrete code embeddings computed using `model.encode`.
689
+ audio_scales (list of length `nb_frames` of `torch.Tensor` of shape `(batch_size, 1)`, *optional*):
690
+ Scaling factor for each `audio_codes` input.
691
+ padding_mask (`torch.Tensor` of shape `(channels, sequence_length)`):
692
+ Padding mask used to pad the `input_values`.
693
+ return_dict (`bool`, *optional*):
694
+ Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
695
+ last_frame_pad_length (`int`, *optional*):
696
+ Integer representing the length of the padding in the last frame, which is removed during decoding.
697
+
698
+ """
699
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
700
+
701
+ chunk_length = self.config.chunk_length
702
+ if chunk_length is None:
703
+ if len(audio_codes) != 1:
704
+ raise ValueError(f"Expected one frame, got {len(audio_codes)}")
705
+ frame = audio_codes[0]
706
+ if last_frame_pad_length > 0:
707
+ frame = frame[..., :-last_frame_pad_length]
708
+ audio_values = self._decode_frame(frame, audio_scales[0])
709
+ else:
710
+ decoded_frames = []
711
+ for i, (frame, scale) in enumerate(zip(audio_codes, audio_scales)):
712
+ if i == len(audio_codes) - 1 and last_frame_pad_length > 0:
713
+ frame = frame[..., :-last_frame_pad_length]
714
+ frames = self._decode_frame(frame, scale)
715
+ decoded_frames.append(frames)
716
+
717
+ audio_values = self._linear_overlap_add(decoded_frames, self.config.chunk_stride or 1)
718
+
719
+ # truncate based on padding mask
720
+ if padding_mask is not None and padding_mask.shape[-1] < audio_values.shape[-1]:
721
+ audio_values = audio_values[..., : padding_mask.shape[-1]]
722
+
723
+ if not return_dict:
724
+ return (audio_values,)
725
+ return EncodecDecoderOutput(audio_values)
726
+
727
+ @auto_docstring
728
+ def forward(
729
+ self,
730
+ input_values: torch.FloatTensor,
731
+ padding_mask: torch.BoolTensor | None = None,
732
+ bandwidth: float | None = None,
733
+ audio_codes: torch.LongTensor | None = None,
734
+ audio_scales: torch.Tensor | None = None,
735
+ return_dict: bool | None = None,
736
+ last_frame_pad_length: int | None = 0,
737
+ ) -> tuple[torch.Tensor, torch.Tensor] | EncodecOutput:
738
+ r"""
739
+ input_values (`torch.FloatTensor` of shape `(batch_size, channels, sequence_length)`, *optional*):
740
+ Raw audio input converted to Float and padded to the appropriate length in order to be encoded using chunks
741
+ of length self.chunk_length and a stride of `config.chunk_stride`.
742
+ padding_mask (`torch.BoolTensor` of shape `(batch_size, channels, sequence_length)`, *optional*):
743
+ Mask to avoid computing scaling factors on padding token indices (can we avoid computing conv on these+).
744
+ Mask values selected in `[0, 1]`:
745
+
746
+ - 1 for tokens that are **not masked**,
747
+ - 0 for tokens that are **masked**.
748
+
749
+ <Tip warning={true}>
750
+
751
+ `padding_mask` should always be passed, unless the input was truncated or not padded. This is because in
752
+ order to process tensors effectively, the input audio should be padded so that `input_length % stride =
753
+ step` with `step = chunk_length-stride`. This ensures that all chunks are of the same shape
754
+
755
+ </Tip>
756
+ bandwidth (`float`, *optional*):
757
+ The target bandwidth. Must be one of `config.target_bandwidths`. If `None`, uses the smallest possible
758
+ bandwidth. bandwidth is represented as a thousandth of what it is, e.g. 6kbps bandwidth is represented as
759
+ `bandwidth == 6.0`
760
+ audio_codes (`torch.LongTensor` of shape `(nb_frames, batch_size, nb_quantizers, frame_len)`, *optional*):
761
+ Discrete code embeddings computed using `model.encode`.
762
+ audio_scales (list of length `nb_frames` of `torch.Tensor` of shape `(batch_size, 1)`, *optional*):
763
+ Scaling factor for each `audio_codes` input.
764
+ return_dict (`bool`, *optional*):
765
+ Whether to return outputs as a dict.
766
+ last_frame_pad_length (`int`, *optional*):
767
+ The length of the padding in the last frame, if any. This is used to ensure that the encoded frames can be
768
+ outputted as a tensor. This value should be passed during decoding to ensure padding is removed from the
769
+ encoded frames.
770
+
771
+ Examples:
772
+
773
+ ```python
774
+ >>> from datasets import load_dataset
775
+ >>> from transformers import AutoProcessor, EncodecModel
776
+
777
+ >>> dataset = load_dataset("hf-internal-testing/ashraq-esc50-1-dog-example")
778
+ >>> audio_sample = dataset["train"]["audio"][0]["array"]
779
+
780
+ >>> model_id = "facebook/encodec_24khz"
781
+ >>> model = EncodecModel.from_pretrained(model_id)
782
+ >>> processor = AutoProcessor.from_pretrained(model_id)
783
+
784
+ >>> inputs = processor(raw_audio=audio_sample, return_tensors="pt")
785
+
786
+ >>> outputs = model(**inputs)
787
+ >>> audio_codes = outputs.audio_codes
788
+ >>> audio_values = outputs.audio_values
789
+ ```"""
790
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
791
+
792
+ if padding_mask is None:
793
+ padding_mask = torch.ones_like(input_values).bool()
794
+ else:
795
+ # ensure that channel dimension is present
796
+ padding_mask = padding_mask.view(padding_mask.shape[0], -1, padding_mask.shape[-1])
797
+
798
+ if audio_codes is not None and audio_scales is None:
799
+ raise ValueError("You specified `audio_codes` but did not specify the `audio_scales`")
800
+
801
+ if audio_scales is not None and audio_codes is None:
802
+ raise ValueError("You specified `audio_scales` but did not specify the `audio_codes`")
803
+
804
+ if audio_scales is None and audio_codes is None:
805
+ audio_codes, audio_scales, last_frame_pad_length = self.encode(
806
+ input_values, padding_mask, bandwidth, False
807
+ )
808
+
809
+ audio_values = self.decode(
810
+ audio_codes,
811
+ audio_scales,
812
+ padding_mask,
813
+ return_dict=return_dict,
814
+ last_frame_pad_length=last_frame_pad_length,
815
+ )[0]
816
+ if not return_dict:
817
+ return (audio_codes, audio_values)
818
+
819
+ return EncodecOutput(audio_codes=audio_codes, audio_values=audio_values)
820
+
821
+
822
+ __all__ = ["EncodecModel", "EncodecPreTrainedModel"]
third_party/transformers/src/transformers/models/herbert/__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_herbert 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/herbert/tokenization_herbert.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 The Google AI Language Team Authors, Allegro.pl, Facebook Inc. 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
+
15
+
16
+ from tokenizers import 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"}
26
+
27
+
28
+ class HerbertTokenizer(TokenizersBackend):
29
+ """
30
+ Construct a BPE tokenizer for HerBERT (backed by HuggingFace's tokenizers library).
31
+
32
+ Peculiarities:
33
+
34
+ - uses BERT's pre-tokenizer: BertPreTokenizer splits tokens on spaces, and also on punctuation. Each occurrence of
35
+ a punctuation character will be treated separately.
36
+
37
+ This tokenizer inherits from [`TokenizersBackend`] which contains most of the methods. Users should refer to the
38
+ superclass for more information regarding methods.
39
+
40
+ Args:
41
+ vocab_file (`str`):
42
+ Path to the vocabulary file.
43
+ merges_file (`str`):
44
+ Path to the merges file.
45
+ cls_token (`str`, *optional*, defaults to `"<s>"`):
46
+ The classifier token.
47
+ unk_token (`str`, *optional*, defaults to `"<unk>"`):
48
+ The unknown token.
49
+ pad_token (`str`, *optional*, defaults to `"<pad>"`):
50
+ The padding token.
51
+ mask_token (`str`, *optional*, defaults to `"<mask>"`):
52
+ The mask token.
53
+ sep_token (`str`, *optional*, defaults to `"</s>"`):
54
+ The separator token.
55
+ vocab (`str`, `dict` or `list`, *optional*):
56
+ Custom vocabulary dictionary.
57
+ merges (`str` or `list[str]`, *optional*):
58
+ Custom merges list.
59
+ """
60
+
61
+ vocab_files_names = VOCAB_FILES_NAMES
62
+ model_input_names = ["input_ids", "attention_mask"]
63
+ model = BPE
64
+
65
+ def __init__(
66
+ self,
67
+ vocab: str | dict[str, int] | None = None,
68
+ merges: str | list[str] | None = None,
69
+ cls_token: str = "<s>",
70
+ unk_token: str = "<unk>",
71
+ pad_token: str = "<pad>",
72
+ mask_token: str = "<mask>",
73
+ sep_token: str = "</s>",
74
+ vocab_file: str | None = None,
75
+ merges_file: str | None = None,
76
+ **kwargs,
77
+ ):
78
+ self._vocab = vocab if vocab is not None else {str(unk_token): 0}
79
+ self._merges = merges or []
80
+ self._tokenizer = Tokenizer(
81
+ BPE(
82
+ vocab=self._vocab,
83
+ merges=self._merges,
84
+ dropout=None,
85
+ unk_token=str(unk_token),
86
+ end_of_word_suffix="</w>",
87
+ )
88
+ )
89
+
90
+ self._tokenizer.normalizer = normalizers.BertNormalizer(
91
+ lowercase=False, strip_accents=False, clean_text=True, handle_chinese_chars=True
92
+ )
93
+ self._tokenizer.pre_tokenizer = pre_tokenizers.BertPreTokenizer()
94
+ self._tokenizer.decoder = decoders.BPEDecoder(suffix="</w>")
95
+
96
+ super().__init__(
97
+ cls_token=cls_token,
98
+ unk_token=unk_token,
99
+ pad_token=pad_token,
100
+ mask_token=mask_token,
101
+ sep_token=sep_token,
102
+ **kwargs,
103
+ )
104
+
105
+ self._tokenizer.post_processor = processors.BertProcessing(
106
+ sep=(self.sep_token, 2),
107
+ cls=(self.cls_token, 0),
108
+ )
109
+
110
+
111
+ __all__ = ["HerbertTokenizer"]
third_party/transformers/src/transformers/models/maskformer/__init__.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_maskformer import *
22
+ from .configuration_maskformer_swin import *
23
+ from .feature_extraction_maskformer import *
24
+ from .image_processing_maskformer import *
25
+ from .image_processing_pil_maskformer import *
26
+ from .modeling_maskformer import *
27
+ from .modeling_maskformer_swin import *
28
+ else:
29
+ import sys
30
+
31
+ _file = globals()["__file__"]
32
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
third_party/transformers/src/transformers/models/maskformer/configuration_maskformer.py ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/maskformer/modular_maskformer.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_maskformer.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2022 Meta Platforms, Inc.s 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
+ from huggingface_hub.dataclasses import strict
21
+
22
+ from ...backbone_utils import consolidate_backbone_kwargs_to_config
23
+ from ...configuration_utils import PreTrainedConfig
24
+ from ...utils import auto_docstring, logging
25
+ from ..auto import CONFIG_MAPPING, AutoConfig
26
+
27
+
28
+ logger = logging.get_logger(__name__)
29
+
30
+
31
+ @auto_docstring(checkpoint="facebook/maskformer-swin-base-ade")
32
+ @strict
33
+ class MaskFormerDetrConfig(PreTrainedConfig):
34
+ r"""
35
+ num_queries (`int`, *optional*, defaults to 100):
36
+ Number of object queries, i.e. detection slots. This is the maximal number of objects
37
+ [`ConditionalDetrModel`] can detect in a single image. For COCO, we recommend 100 queries.
38
+ position_embedding_type (`str`, *optional*, defaults to `"sine"`):
39
+ Type of position embeddings to be used on top of the image features. One of `"sine"` or `"learned"`.
40
+ dilation (`bool`, *optional*, defaults to `False`):
41
+ Whether to replace stride with dilation in the last convolutional block (DC5). Only supported when
42
+ `use_timm_backbone` = `True`.
43
+
44
+ Examples:
45
+
46
+ ```python
47
+ >>> from transformers import MaskFormerDetrConfig, MaskFormerDetrModel
48
+
49
+ >>> # Initializing a MASK_FORMER_DETR facebook/mask_former_detr-resnet-50 style configuration
50
+ >>> configuration = MaskFormerDetrConfig()
51
+
52
+ >>> # Initializing a model (with random weights) from the facebook/mask_former_detr-resnet-50 style configuration
53
+ >>> model = MaskFormerDetrModel(configuration)
54
+
55
+ >>> # Accessing the model configuration
56
+ >>> configuration = model.config
57
+ ```"""
58
+
59
+ model_type = "detr"
60
+ sub_configs = {"backbone_config": AutoConfig}
61
+ keys_to_ignore_at_inference = ["past_key_values"]
62
+ attribute_map = {
63
+ "hidden_size": "d_model",
64
+ "num_attention_heads": "encoder_attention_heads",
65
+ "num_hidden_layers": "encoder_layers",
66
+ }
67
+
68
+ backbone_config: dict | PreTrainedConfig | None = None
69
+ num_channels: int = 3
70
+ num_queries: int = 100
71
+ encoder_layers: int = 6
72
+ encoder_ffn_dim: int = 2048
73
+ encoder_attention_heads: int = 8
74
+ decoder_layers: int = 6
75
+ decoder_ffn_dim: int = 2048
76
+ decoder_attention_heads: int = 8
77
+ encoder_layerdrop: float | int = 0.0
78
+ decoder_layerdrop: float | int = 0.0
79
+ is_encoder_decoder: bool = True
80
+ activation_function: str = "relu"
81
+ d_model: int = 256
82
+ dropout: float | int = 0.1
83
+ attention_dropout: float | int = 0.0
84
+ activation_dropout: float | int = 0.0
85
+ init_std: float = 0.02
86
+ init_xavier_std: float = 1.0
87
+ auxiliary_loss: bool = False
88
+ position_embedding_type: str = "sine"
89
+ dilation: bool = False
90
+ class_cost: int = 1
91
+ bbox_cost: int = 5
92
+ giou_cost: int = 2
93
+ mask_loss_coefficient: int = 1
94
+ dice_loss_coefficient: int = 1
95
+ bbox_loss_coefficient: int = 5
96
+ giou_loss_coefficient: int = 2
97
+ eos_coefficient: float = 0.1
98
+
99
+ def __post_init__(self, **kwargs):
100
+ backbone_kwargs = kwargs.get("backbone_kwargs", {})
101
+ timm_default_kwargs = {
102
+ "num_channels": backbone_kwargs.get("num_channels", self.num_channels),
103
+ "features_only": True,
104
+ "use_pretrained_backbone": False,
105
+ "out_indices": backbone_kwargs.get("out_indices", [1, 2, 3, 4]),
106
+ }
107
+ if self.dilation:
108
+ timm_default_kwargs["output_stride"] = backbone_kwargs.get("output_stride", 16)
109
+
110
+ self.backbone_config, kwargs = consolidate_backbone_kwargs_to_config(
111
+ backbone_config=self.backbone_config,
112
+ default_backbone="resnet50",
113
+ default_config_type="resnet",
114
+ default_config_kwargs={"out_features": ["stage4"]},
115
+ timm_default_kwargs=timm_default_kwargs,
116
+ **kwargs,
117
+ )
118
+ super().__post_init__(**kwargs)
119
+
120
+
121
+ @auto_docstring(checkpoint="facebook/maskformer-swin-base-ade")
122
+ @strict
123
+ class MaskFormerConfig(PreTrainedConfig):
124
+ r"""
125
+ fpn_feature_size (`int`, *optional*, defaults to 256):
126
+ The Feature Pyramid Network's features size.
127
+ mask_feature_size (`int`, *optional*, defaults to 256):
128
+ The masks' features size, this value will also be used to specify the Feature Pyramid Network features'
129
+ size.
130
+ decoder_config (`Dict`, *optional*):
131
+ The configuration passed to the transformer decoder model, if unset the base config for `detr-resnet-50`
132
+ will be used.
133
+ cross_entropy_weight (`float`, *optional*, defaults to 1.0):
134
+ The weight for the cross entropy loss.
135
+ output_auxiliary_logits (`bool`, *optional*):
136
+ Should the model output its `auxiliary_logits` or not.
137
+
138
+ Raises:
139
+ `ValueError`:
140
+ Raised if the backbone model type selected is not in `["swin"]` or the decoder model type selected is not
141
+ in `["detr"]`
142
+
143
+ Examples:
144
+
145
+ ```python
146
+ >>> from transformers import MaskFormerConfig, MaskFormerModel
147
+
148
+ >>> # Initializing a MaskFormer facebook/maskformer-swin-base-ade configuration
149
+ >>> configuration = MaskFormerConfig()
150
+
151
+ >>> # Initializing a model (with random weights) from the facebook/maskformer-swin-base-ade style configuration
152
+ >>> model = MaskFormerModel(configuration)
153
+
154
+ >>> # Accessing the model configuration
155
+ >>> configuration = model.config
156
+ ```
157
+
158
+ """
159
+
160
+ model_type = "maskformer"
161
+ sub_configs = {"backbone_config": AutoConfig, "decoder_config": AutoConfig}
162
+ attribute_map = {"hidden_size": "mask_feature_size"}
163
+ backbones_supported = ["resnet", "swin"]
164
+ decoders_supported = ["detr"]
165
+
166
+ fpn_feature_size: int = 256
167
+ mask_feature_size: int = 256
168
+ no_object_weight: float = 0.1
169
+ use_auxiliary_loss: bool = False
170
+ backbone_config: dict | PreTrainedConfig | None = None
171
+ decoder_config: dict | PreTrainedConfig | None = None
172
+ init_std: float = 0.02
173
+ init_xavier_std: float = 1.0
174
+ dice_weight: float = 1.0
175
+ cross_entropy_weight: float = 1.0
176
+ mask_weight: float = 20.0
177
+ output_auxiliary_logits: bool | None = None
178
+
179
+ def __post_init__(self, **kwargs):
180
+ self.backbone_config, kwargs = consolidate_backbone_kwargs_to_config(
181
+ backbone_config=self.backbone_config,
182
+ default_config_type="swin",
183
+ default_config_kwargs={
184
+ "depths": [2, 2, 18, 2],
185
+ "drop_path_rate": 0.3,
186
+ "image_size": 384,
187
+ "embed_dim": 128,
188
+ "num_heads": [4, 8, 16, 32],
189
+ "window_size": 12,
190
+ "out_features": ["stage1", "stage2", "stage3", "stage4"],
191
+ },
192
+ **kwargs,
193
+ )
194
+
195
+ # verify that the backbone is supported
196
+ if self.backbone_config is not None and self.backbone_config.model_type not in self.backbones_supported:
197
+ logger.warning_once(
198
+ f"Backbone {self.backbone_config.model_type} is not a supported model and may not be compatible with MaskFormer. "
199
+ f"Supported model types: {','.join(self.backbones_supported)}"
200
+ )
201
+
202
+ if self.decoder_config is None:
203
+ # fall back to https://huggingface.co/facebook/detr-resnet-50
204
+ self.decoder_config = MaskFormerDetrConfig()
205
+ else:
206
+ # verify that the decoder is supported
207
+ decoder_type = (
208
+ self.decoder_config.pop("model_type")
209
+ if isinstance(self.decoder_config, dict)
210
+ else self.decoder_config.model_type
211
+ )
212
+ if decoder_type not in self.decoders_supported:
213
+ raise ValueError(
214
+ f"Transformer Decoder {decoder_type} not supported, please use one of"
215
+ f" {','.join(self.decoders_supported)}"
216
+ )
217
+ if isinstance(self.decoder_config, dict):
218
+ config_class = CONFIG_MAPPING[decoder_type]
219
+ self.decoder_config = config_class.from_dict(self.decoder_config)
220
+
221
+ self.num_attention_heads = self.decoder_config.encoder_attention_heads
222
+ self.num_hidden_layers = self.decoder_config.num_hidden_layers
223
+ super().__post_init__(**kwargs)
224
+
225
+
226
+ __all__ = ["MaskFormerConfig", "MaskFormerDetrConfig"]
third_party/transformers/src/transformers/models/maskformer/configuration_maskformer_swin.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ """MaskFormer Swin Transformer model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...backbone_utils import BackboneConfigMixin
19
+ from ...configuration_utils import PreTrainedConfig
20
+ from ...utils import auto_docstring
21
+
22
+
23
+ @auto_docstring(checkpoint="microsoft/swin-tiny-patch4-window7-224")
24
+ @strict
25
+ class MaskFormerSwinConfig(BackboneConfigMixin, PreTrainedConfig):
26
+ r"""
27
+ window_size (`int`, *optional*, defaults to 7):
28
+ Size of windows.
29
+
30
+ Example:
31
+
32
+ ```python
33
+ >>> from transformers import MaskFormerSwinConfig, MaskFormerSwinModel
34
+
35
+ >>> # Initializing a microsoft/swin-tiny-patch4-window7-224 style configuration
36
+ >>> configuration = MaskFormerSwinConfig()
37
+
38
+ >>> # Initializing a model (with random weights) from the microsoft/swin-tiny-patch4-window7-224 style configuration
39
+ >>> model = MaskFormerSwinModel(configuration)
40
+
41
+ >>> # Accessing the model configuration
42
+ >>> configuration = model.config
43
+ ```"""
44
+
45
+ model_type = "maskformer-swin"
46
+
47
+ attribute_map = {
48
+ "num_attention_heads": "num_heads",
49
+ "num_hidden_layers": "num_layers",
50
+ }
51
+
52
+ image_size: int | list[int] | tuple[int, int] = 224
53
+ patch_size: int | list[int] | tuple[int, int] = 4
54
+ num_channels: int = 3
55
+ embed_dim: int = 96
56
+ depths: list[int] | tuple[int, ...] = (2, 2, 6, 2)
57
+ num_heads: list[int] | tuple[int, ...] = (3, 6, 12, 24)
58
+ window_size: int = 7
59
+ mlp_ratio: float = 4.0
60
+ qkv_bias: bool = True
61
+ hidden_dropout_prob: float | int = 0.0
62
+ attention_probs_dropout_prob: float | int = 0.0
63
+ drop_path_rate: float | int = 0.1
64
+ hidden_act: str = "gelu"
65
+ use_absolute_embeddings: bool = False
66
+ initializer_range: float = 0.02
67
+ layer_norm_eps: float = 1e-5
68
+ _out_features: list[str] | None = None
69
+ _out_indices: list[int] | None = None
70
+
71
+ def __post_init__(self, **kwargs):
72
+ # we set the hidden_size attribute in order to make Swin work with VisionEncoderDecoderModel
73
+ # this indicates the channel dimension after the last stage of the model
74
+ self.hidden_size = int(self.embed_dim * 2 ** (len(self.depths) - 1))
75
+ self.stage_names = ["stem"] + [f"stage{idx}" for idx in range(1, len(self.depths) + 1)]
76
+ self.set_output_features_output_indices(
77
+ out_indices=kwargs.pop("out_indices", None), out_features=kwargs.pop("out_features", None)
78
+ )
79
+ super().__post_init__(**kwargs)
80
+
81
+
82
+ __all__ = ["MaskFormerSwinConfig"]
third_party/transformers/src/transformers/models/maskformer/convert_maskformer_original_pytorch_checkpoint_to_pytorch.py ADDED
@@ -0,0 +1,724 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 Meta Platforms, Inc. and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import sys
15
+ from argparse import ArgumentParser
16
+ from collections.abc import Iterator
17
+ from dataclasses import dataclass
18
+ from io import BytesIO
19
+ from pathlib import Path
20
+ from pprint import pformat
21
+ from typing import Any
22
+
23
+ import httpx
24
+ import torch
25
+ import torchvision.transforms as T
26
+ from detectron2.checkpoint import DetectionCheckpointer
27
+ from detectron2.config import get_cfg
28
+ from detectron2.data import MetadataCatalog
29
+ from detectron2.projects.deeplab import add_deeplab_config
30
+ from PIL import Image
31
+ from torch import Tensor, nn
32
+
33
+ from transformers.models.maskformer.feature_extraction_maskformer import MaskFormerImageProcessor
34
+ from transformers.models.maskformer.modeling_maskformer import (
35
+ MaskFormerConfig,
36
+ MaskFormerForInstanceSegmentation,
37
+ MaskFormerForInstanceSegmentationOutput,
38
+ MaskFormerModel,
39
+ MaskFormerModelOutput,
40
+ )
41
+ from transformers.utils import logging
42
+
43
+
44
+ StateDict = dict[str, Tensor]
45
+
46
+ logging.set_verbosity_info()
47
+ logger = logging.get_logger()
48
+
49
+ torch.manual_seed(0)
50
+
51
+
52
+ class TrackedStateDict:
53
+ def __init__(self, to_track: dict):
54
+ """This class "tracks" a python dictionary by keeping track of which item is accessed.
55
+
56
+ Args:
57
+ to_track (Dict): The dictionary we wish to track
58
+ """
59
+ self.to_track = to_track
60
+ self._seen: set[str] = set()
61
+
62
+ def __getitem__(self, key: str) -> Any:
63
+ return self.to_track[key]
64
+
65
+ def __setitem__(self, key: str, item: Any):
66
+ self._seen.add(key)
67
+ self.to_track[key] = item
68
+
69
+ def diff(self) -> list[str]:
70
+ """This method returns a set difference between the keys in the tracked state dict and the one we have access so far.
71
+ This is an effective method to check if we have update all the keys
72
+
73
+ Returns:
74
+ list[str]: List of keys not yet updated
75
+ """
76
+ return set(self.to_track.keys()) - self._seen
77
+
78
+ def copy(self) -> dict:
79
+ # proxy the call to the internal dictionary
80
+ return self.to_track.copy()
81
+
82
+
83
+ # We will verify our results on an image of cute cats
84
+ def prepare_img():
85
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
86
+ with httpx.stream("GET", url) as response:
87
+ image = Image.open(BytesIO(response.read()))
88
+ return image
89
+
90
+
91
+ @dataclass
92
+ class Args:
93
+ """Fake command line arguments needed by maskformer/detectron implementation"""
94
+
95
+ config_file: str
96
+
97
+
98
+ def setup_cfg(args: Args):
99
+ # load config from file and command-line arguments
100
+ cfg = get_cfg()
101
+ add_deeplab_config(cfg)
102
+ add_mask_former_config(cfg)
103
+ cfg.merge_from_file(args.config_file)
104
+ cfg.freeze()
105
+ return cfg
106
+
107
+
108
+ class OriginalMaskFormerConfigToOursConverter:
109
+ def __call__(self, original_config: object) -> MaskFormerConfig:
110
+ model = original_config.MODEL
111
+ mask_former = model.MASK_FORMER
112
+ swin = model.SWIN
113
+
114
+ dataset_catalog = MetadataCatalog.get(original_config.DATASETS.TEST[0])
115
+ id2label = dict(enumerate(dataset_catalog.stuff_classes))
116
+ label2id = {label: idx for idx, label in id2label.items()}
117
+
118
+ config: MaskFormerConfig = MaskFormerConfig(
119
+ fpn_feature_size=model.SEM_SEG_HEAD.CONVS_DIM,
120
+ mask_feature_size=model.SEM_SEG_HEAD.MASK_DIM,
121
+ num_labels=model.SEM_SEG_HEAD.NUM_CLASSES,
122
+ no_object_weight=mask_former.NO_OBJECT_WEIGHT,
123
+ num_queries=mask_former.NUM_OBJECT_QUERIES,
124
+ backbone_config={
125
+ "pretrain_img_size": swin.PRETRAIN_IMG_SIZE,
126
+ "image_size": swin.PRETRAIN_IMG_SIZE,
127
+ "in_channels": 3,
128
+ "patch_size": swin.PATCH_SIZE,
129
+ "embed_dim": swin.EMBED_DIM,
130
+ "depths": swin.DEPTHS,
131
+ "num_heads": swin.NUM_HEADS,
132
+ "window_size": swin.WINDOW_SIZE,
133
+ "drop_path_rate": swin.DROP_PATH_RATE,
134
+ "model_type": "swin",
135
+ },
136
+ dice_weight=mask_former.DICE_WEIGHT,
137
+ ce_weight=1.0,
138
+ mask_weight=mask_former.MASK_WEIGHT,
139
+ decoder_config={
140
+ "model_type": "detr",
141
+ "max_position_embeddings": 1024,
142
+ "encoder_layers": 6,
143
+ "encoder_ffn_dim": 2048,
144
+ "encoder_attention_heads": 8,
145
+ "decoder_layers": mask_former.DEC_LAYERS,
146
+ "decoder_ffn_dim": mask_former.DIM_FEEDFORWARD,
147
+ "decoder_attention_heads": mask_former.NHEADS,
148
+ "encoder_layerdrop": 0.0,
149
+ "decoder_layerdrop": 0.0,
150
+ "d_model": mask_former.HIDDEN_DIM,
151
+ "dropout": mask_former.DROPOUT,
152
+ "attention_dropout": 0.0,
153
+ "activation_dropout": 0.0,
154
+ "init_std": 0.02,
155
+ "init_xavier_std": 1.0,
156
+ "scale_embedding": False,
157
+ "auxiliary_loss": False,
158
+ "dilation": False,
159
+ # default pretrained config values
160
+ },
161
+ id2label=id2label,
162
+ label2id=label2id,
163
+ )
164
+
165
+ return config
166
+
167
+
168
+ class OriginalMaskFormerConfigToImageProcessorConverter:
169
+ def __call__(self, original_config: object) -> MaskFormerImageProcessor:
170
+ model = original_config.MODEL
171
+ model_input = original_config.INPUT
172
+ dataset_catalog = MetadataCatalog.get(original_config.DATASETS.TEST[0])
173
+
174
+ return MaskFormerImageProcessor(
175
+ image_mean=(torch.tensor(model.PIXEL_MEAN) / 255).tolist(),
176
+ image_std=(torch.tensor(model.PIXEL_STD) / 255).tolist(),
177
+ size=model_input.MIN_SIZE_TEST,
178
+ max_size=model_input.MAX_SIZE_TEST,
179
+ num_labels=model.SEM_SEG_HEAD.NUM_CLASSES,
180
+ ignore_index=dataset_catalog.ignore_label,
181
+ size_divisibility=32, # 32 is required by swin
182
+ )
183
+
184
+
185
+ class OriginalMaskFormerCheckpointToOursConverter:
186
+ def __init__(self, original_model: nn.Module, config: MaskFormerConfig):
187
+ self.original_model = original_model
188
+ self.config = config
189
+
190
+ def pop_all(self, renamed_keys: list[tuple[str, str]], dst_state_dict: StateDict, src_state_dict: StateDict):
191
+ for src_key, dst_key in renamed_keys:
192
+ dst_state_dict[dst_key] = src_state_dict.pop(src_key)
193
+
194
+ def replace_backbone(self, dst_state_dict: StateDict, src_state_dict: StateDict, config: MaskFormerConfig):
195
+ dst_prefix: str = "pixel_level_module.encoder"
196
+ src_prefix: str = "backbone"
197
+
198
+ renamed_keys = [
199
+ (
200
+ f"{src_prefix}.patch_embed.proj.weight",
201
+ f"{dst_prefix}.model.embeddings.patch_embeddings.projection.weight",
202
+ ),
203
+ (f"{src_prefix}.patch_embed.proj.bias", f"{dst_prefix}.model.embeddings.patch_embeddings.projection.bias"),
204
+ (f"{src_prefix}.patch_embed.norm.weight", f"{dst_prefix}.model.embeddings.norm.weight"),
205
+ (f"{src_prefix}.patch_embed.norm.bias", f"{dst_prefix}.model.embeddings.norm.bias"),
206
+ ]
207
+ num_layers = len(config.backbone_config.depths)
208
+ for layer_idx in range(num_layers):
209
+ for block_idx in range(config.backbone_config.depths[layer_idx]):
210
+ renamed_keys.extend(
211
+ [ # src, dst
212
+ (
213
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.norm1.weight",
214
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.layernorm_before.weight",
215
+ ),
216
+ (
217
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.norm1.bias",
218
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.layernorm_before.bias",
219
+ ),
220
+ (
221
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.attn.relative_position_bias_table",
222
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.self.relative_position_bias_table",
223
+ ),
224
+ ]
225
+ )
226
+ # now we need to handle the attentions
227
+ # read in weights + bias of input projection layer of cross-attention
228
+
229
+ src_att_weight = src_state_dict[f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.attn.qkv.weight"]
230
+ src_att_bias = src_state_dict[f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.attn.qkv.bias"]
231
+
232
+ size = src_att_weight.shape[0]
233
+ offset = size // 3
234
+ dst_state_dict[
235
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.self.query.weight"
236
+ ] = src_att_weight[:offset, :]
237
+ dst_state_dict[
238
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.self.query.bias"
239
+ ] = src_att_bias[:offset]
240
+
241
+ dst_state_dict[
242
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.self.key.weight"
243
+ ] = src_att_weight[offset : offset * 2, :]
244
+ dst_state_dict[
245
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.self.key.bias"
246
+ ] = src_att_bias[offset : offset * 2]
247
+
248
+ dst_state_dict[
249
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.self.value.weight"
250
+ ] = src_att_weight[-offset:, :]
251
+ dst_state_dict[
252
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.self.value.bias"
253
+ ] = src_att_bias[-offset:]
254
+
255
+ # let's pop them
256
+ src_state_dict.pop(f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.attn.qkv.weight")
257
+ src_state_dict.pop(f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.attn.qkv.bias")
258
+ # proj
259
+ renamed_keys.extend(
260
+ [
261
+ (
262
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.attn.proj.weight",
263
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.output.dense.weight",
264
+ ),
265
+ (
266
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.attn.proj.bias",
267
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.output.dense.bias",
268
+ ),
269
+ ]
270
+ )
271
+
272
+ # second norm
273
+ renamed_keys.extend(
274
+ [
275
+ (
276
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.norm2.weight",
277
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.layernorm_after.weight",
278
+ ),
279
+ (
280
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.norm2.bias",
281
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.layernorm_after.bias",
282
+ ),
283
+ ]
284
+ )
285
+
286
+ # mlp
287
+ renamed_keys.extend(
288
+ [
289
+ (
290
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.mlp.fc1.weight",
291
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.intermediate.dense.weight",
292
+ ),
293
+ (
294
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.mlp.fc1.bias",
295
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.intermediate.dense.bias",
296
+ ),
297
+ (
298
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.mlp.fc2.weight",
299
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.output.dense.weight",
300
+ ),
301
+ (
302
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.mlp.fc2.bias",
303
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.output.dense.bias",
304
+ ),
305
+ ]
306
+ )
307
+
308
+ renamed_keys.extend(
309
+ [
310
+ (
311
+ f"{src_prefix}.layers.{layer_idx}.blocks.{block_idx}.attn.relative_position_index",
312
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.blocks.{block_idx}.attention.self.relative_position_index",
313
+ )
314
+ ]
315
+ )
316
+
317
+ if layer_idx < num_layers - 1:
318
+ # patch merging
319
+ renamed_keys.extend(
320
+ [
321
+ (
322
+ f"{src_prefix}.layers.{layer_idx}.downsample.reduction.weight",
323
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.downsample.reduction.weight",
324
+ ),
325
+ (
326
+ f"{src_prefix}.layers.{layer_idx}.downsample.norm.weight",
327
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.downsample.norm.weight",
328
+ ),
329
+ (
330
+ f"{src_prefix}.layers.{layer_idx}.downsample.norm.bias",
331
+ f"{dst_prefix}.model.encoder.layers.{layer_idx}.downsample.norm.bias",
332
+ ),
333
+ ]
334
+ )
335
+
336
+ # hidden states norms
337
+ renamed_keys.extend(
338
+ [
339
+ (
340
+ f"{src_prefix}.norm{layer_idx}.weight",
341
+ f"{dst_prefix}.hidden_states_norms.{layer_idx}.weight",
342
+ ),
343
+ (
344
+ f"{src_prefix}.norm{layer_idx}.bias",
345
+ f"{dst_prefix}.hidden_states_norms.{layer_idx}.bias",
346
+ ),
347
+ ]
348
+ )
349
+ self.pop_all(renamed_keys, dst_state_dict, src_state_dict)
350
+
351
+ def replace_pixel_module(self, dst_state_dict: StateDict, src_state_dict: StateDict):
352
+ dst_prefix: str = "pixel_level_module.decoder"
353
+ src_prefix: str = "sem_seg_head.pixel_decoder"
354
+
355
+ self.replace_backbone(dst_state_dict, src_state_dict, self.config)
356
+
357
+ def rename_keys_for_conv(detectron_conv: str, mine_conv: str):
358
+ return [
359
+ (f"{detectron_conv}.weight", f"{mine_conv}.0.weight"),
360
+ # 2 cuz the have act in the middle -> rename it
361
+ (f"{detectron_conv}.norm.weight", f"{mine_conv}.1.weight"),
362
+ (f"{detectron_conv}.norm.bias", f"{mine_conv}.1.bias"),
363
+ ]
364
+
365
+ renamed_keys = [
366
+ (f"{src_prefix}.mask_features.weight", f"{dst_prefix}.mask_projection.weight"),
367
+ (f"{src_prefix}.mask_features.bias", f"{dst_prefix}.mask_projection.bias"),
368
+ # the layers in the original one are in reverse order, stem is the last one!
369
+ ]
370
+
371
+ renamed_keys.extend(rename_keys_for_conv(f"{src_prefix}.layer_4", f"{dst_prefix}.fpn.stem"))
372
+
373
+ # add all the fpn layers (here we need some config parameters to know the size in advance)
374
+ for src_i, dst_i in zip(range(3, 0, -1), range(0, 3)):
375
+ renamed_keys.extend(
376
+ rename_keys_for_conv(f"{src_prefix}.adapter_{src_i}", f"{dst_prefix}.fpn.layers.{dst_i}.proj")
377
+ )
378
+ renamed_keys.extend(
379
+ rename_keys_for_conv(f"{src_prefix}.layer_{src_i}", f"{dst_prefix}.fpn.layers.{dst_i}.block")
380
+ )
381
+
382
+ self.pop_all(renamed_keys, dst_state_dict, src_state_dict)
383
+
384
+ def rename_keys_in_detr_decoder(self, dst_state_dict: StateDict, src_state_dict: StateDict):
385
+ dst_prefix: str = "transformer_module.decoder"
386
+ src_prefix: str = "sem_seg_head.predictor.transformer.decoder"
387
+ # not sure why we are not popping direcetly here!
388
+ # here we list all keys to be renamed (original name on the left, our name on the right)
389
+ rename_keys = []
390
+ for i in range(self.config.decoder_config.decoder_layers):
391
+ # decoder layers: 2 times output projection, 2 feedforward neural networks and 3 layernorms
392
+ rename_keys.append(
393
+ (
394
+ f"{src_prefix}.layers.{i}.self_attn.out_proj.weight",
395
+ f"{dst_prefix}.layers.{i}.self_attn.out_proj.weight",
396
+ )
397
+ )
398
+ rename_keys.append(
399
+ (
400
+ f"{src_prefix}.layers.{i}.self_attn.out_proj.bias",
401
+ f"{dst_prefix}.layers.{i}.self_attn.out_proj.bias",
402
+ )
403
+ )
404
+ rename_keys.append(
405
+ (
406
+ f"{src_prefix}.layers.{i}.multihead_attn.out_proj.weight",
407
+ f"{dst_prefix}.layers.{i}.encoder_attn.out_proj.weight",
408
+ )
409
+ )
410
+ rename_keys.append(
411
+ (
412
+ f"{src_prefix}.layers.{i}.multihead_attn.out_proj.bias",
413
+ f"{dst_prefix}.layers.{i}.encoder_attn.out_proj.bias",
414
+ )
415
+ )
416
+ rename_keys.append((f"{src_prefix}.layers.{i}.linear1.weight", f"{dst_prefix}.layers.{i}.fc1.weight"))
417
+ rename_keys.append((f"{src_prefix}.layers.{i}.linear1.bias", f"{dst_prefix}.layers.{i}.fc1.bias"))
418
+ rename_keys.append((f"{src_prefix}.layers.{i}.linear2.weight", f"{dst_prefix}.layers.{i}.fc2.weight"))
419
+ rename_keys.append((f"{src_prefix}.layers.{i}.linear2.bias", f"{dst_prefix}.layers.{i}.fc2.bias"))
420
+ rename_keys.append(
421
+ (f"{src_prefix}.layers.{i}.norm1.weight", f"{dst_prefix}.layers.{i}.self_attn_layer_norm.weight")
422
+ )
423
+ rename_keys.append(
424
+ (f"{src_prefix}.layers.{i}.norm1.bias", f"{dst_prefix}.layers.{i}.self_attn_layer_norm.bias")
425
+ )
426
+ rename_keys.append(
427
+ (f"{src_prefix}.layers.{i}.norm2.weight", f"{dst_prefix}.layers.{i}.encoder_attn_layer_norm.weight")
428
+ )
429
+ rename_keys.append(
430
+ (f"{src_prefix}.layers.{i}.norm2.bias", f"{dst_prefix}.layers.{i}.encoder_attn_layer_norm.bias")
431
+ )
432
+ rename_keys.append(
433
+ (f"{src_prefix}.layers.{i}.norm3.weight", f"{dst_prefix}.layers.{i}.final_layer_norm.weight")
434
+ )
435
+ rename_keys.append(
436
+ (f"{src_prefix}.layers.{i}.norm3.bias", f"{dst_prefix}.layers.{i}.final_layer_norm.bias")
437
+ )
438
+
439
+ return rename_keys
440
+
441
+ def replace_q_k_v_in_detr_decoder(self, dst_state_dict: StateDict, src_state_dict: StateDict):
442
+ dst_prefix: str = "transformer_module.decoder"
443
+ src_prefix: str = "sem_seg_head.predictor.transformer.decoder"
444
+ for i in range(self.config.decoder_config.decoder_layers):
445
+ # read in weights + bias of input projection layer of self-attention
446
+ in_proj_weight = src_state_dict.pop(f"{src_prefix}.layers.{i}.self_attn.in_proj_weight")
447
+ in_proj_bias = src_state_dict.pop(f"{src_prefix}.layers.{i}.self_attn.in_proj_bias")
448
+ # next, add query, keys and values (in that order) to the state dict
449
+ dst_state_dict[f"{dst_prefix}.layers.{i}.self_attn.q_proj.weight"] = in_proj_weight[:256, :]
450
+ dst_state_dict[f"{dst_prefix}.layers.{i}.self_attn.q_proj.bias"] = in_proj_bias[:256]
451
+ dst_state_dict[f"{dst_prefix}.layers.{i}.self_attn.k_proj.weight"] = in_proj_weight[256:512, :]
452
+ dst_state_dict[f"{dst_prefix}.layers.{i}.self_attn.k_proj.bias"] = in_proj_bias[256:512]
453
+ dst_state_dict[f"{dst_prefix}.layers.{i}.self_attn.v_proj.weight"] = in_proj_weight[-256:, :]
454
+ dst_state_dict[f"{dst_prefix}.layers.{i}.self_attn.v_proj.bias"] = in_proj_bias[-256:]
455
+ # read in weights + bias of input projection layer of cross-attention
456
+ in_proj_weight_cross_attn = src_state_dict.pop(f"{src_prefix}.layers.{i}.multihead_attn.in_proj_weight")
457
+ in_proj_bias_cross_attn = src_state_dict.pop(f"{src_prefix}.layers.{i}.multihead_attn.in_proj_bias")
458
+ # next, add query, keys and values (in that order) of cross-attention to the state dict
459
+ dst_state_dict[f"{dst_prefix}.layers.{i}.encoder_attn.q_proj.weight"] = in_proj_weight_cross_attn[:256, :]
460
+ dst_state_dict[f"{dst_prefix}.layers.{i}.encoder_attn.q_proj.bias"] = in_proj_bias_cross_attn[:256]
461
+ dst_state_dict[f"{dst_prefix}.layers.{i}.encoder_attn.k_proj.weight"] = in_proj_weight_cross_attn[
462
+ 256:512, :
463
+ ]
464
+ dst_state_dict[f"{dst_prefix}.layers.{i}.encoder_attn.k_proj.bias"] = in_proj_bias_cross_attn[256:512]
465
+ dst_state_dict[f"{dst_prefix}.layers.{i}.encoder_attn.v_proj.weight"] = in_proj_weight_cross_attn[-256:, :]
466
+ dst_state_dict[f"{dst_prefix}.layers.{i}.encoder_attn.v_proj.bias"] = in_proj_bias_cross_attn[-256:]
467
+
468
+ def replace_detr_decoder(self, dst_state_dict: StateDict, src_state_dict: StateDict):
469
+ dst_prefix: str = "transformer_module.decoder"
470
+ src_prefix: str = "sem_seg_head.predictor.transformer.decoder"
471
+ renamed_keys = self.rename_keys_in_detr_decoder(dst_state_dict, src_state_dict)
472
+ # add more
473
+ renamed_keys.extend(
474
+ [
475
+ (f"{src_prefix}.norm.weight", f"{dst_prefix}.layernorm.weight"),
476
+ (f"{src_prefix}.norm.bias", f"{dst_prefix}.layernorm.bias"),
477
+ ]
478
+ )
479
+
480
+ self.pop_all(renamed_keys, dst_state_dict, src_state_dict)
481
+
482
+ self.replace_q_k_v_in_detr_decoder(dst_state_dict, src_state_dict)
483
+
484
+ def replace_transformer_module(self, dst_state_dict: StateDict, src_state_dict: StateDict):
485
+ dst_prefix: str = "transformer_module"
486
+ src_prefix: str = "sem_seg_head.predictor"
487
+
488
+ self.replace_detr_decoder(dst_state_dict, src_state_dict)
489
+
490
+ renamed_keys = [
491
+ (f"{src_prefix}.query_embed.weight", f"{dst_prefix}.queries_embedder.weight"),
492
+ (f"{src_prefix}.input_proj.weight", f"{dst_prefix}.input_projection.weight"),
493
+ (f"{src_prefix}.input_proj.bias", f"{dst_prefix}.input_projection.bias"),
494
+ ]
495
+
496
+ self.pop_all(renamed_keys, dst_state_dict, src_state_dict)
497
+
498
+ def replace_instance_segmentation_module(self, dst_state_dict: StateDict, src_state_dict: StateDict):
499
+ # NOTE in our case we don't have a prefix, thus we removed the "." from the keys later on!
500
+ dst_prefix: str = ""
501
+ src_prefix: str = "sem_seg_head.predictor"
502
+
503
+ renamed_keys = [
504
+ (f"{src_prefix}.class_embed.weight", f"{dst_prefix}class_predictor.weight"),
505
+ (f"{src_prefix}.class_embed.bias", f"{dst_prefix}class_predictor.bias"),
506
+ ]
507
+
508
+ mlp_len = 3
509
+ for i in range(mlp_len):
510
+ renamed_keys.extend(
511
+ [
512
+ (f"{src_prefix}.mask_embed.layers.{i}.weight", f"{dst_prefix}mask_embedder.{i}.0.weight"),
513
+ (f"{src_prefix}.mask_embed.layers.{i}.bias", f"{dst_prefix}mask_embedder.{i}.0.bias"),
514
+ ]
515
+ )
516
+ logger.info(f"Replacing keys {pformat(renamed_keys)}")
517
+ self.pop_all(renamed_keys, dst_state_dict, src_state_dict)
518
+
519
+ def convert(self, mask_former: MaskFormerModel) -> MaskFormerModel:
520
+ dst_state_dict = TrackedStateDict(mask_former.state_dict())
521
+ src_state_dict = self.original_model.state_dict()
522
+
523
+ self.replace_pixel_module(dst_state_dict, src_state_dict)
524
+ self.replace_transformer_module(dst_state_dict, src_state_dict)
525
+
526
+ logger.info(f"Missed keys are {pformat(dst_state_dict.diff())}")
527
+ logger.info(f"Not copied keys are {pformat(src_state_dict.keys())}")
528
+ logger.info("🙌 Done")
529
+
530
+ mask_former.load_state_dict(dst_state_dict)
531
+
532
+ return mask_former
533
+
534
+ def convert_instance_segmentation(
535
+ self, mask_former: MaskFormerForInstanceSegmentation
536
+ ) -> MaskFormerForInstanceSegmentation:
537
+ dst_state_dict = TrackedStateDict(mask_former.state_dict())
538
+ src_state_dict = self.original_model.state_dict()
539
+
540
+ self.replace_instance_segmentation_module(dst_state_dict, src_state_dict)
541
+
542
+ mask_former.load_state_dict(dst_state_dict)
543
+
544
+ return mask_former
545
+
546
+ @staticmethod
547
+ def using_dirs(checkpoints_dir: Path, config_dir: Path) -> Iterator[tuple[object, Path, Path]]:
548
+ checkpoints: list[Path] = checkpoints_dir.glob("**/*.pkl")
549
+
550
+ for checkpoint in checkpoints:
551
+ logger.info(f"Converting {checkpoint.stem}")
552
+ # find associated config file
553
+ config: Path = config_dir / checkpoint.parents[0].stem / "swin" / f"{checkpoint.stem}.yaml"
554
+
555
+ yield config, checkpoint
556
+
557
+
558
+ def test(original_model, our_model: MaskFormerForInstanceSegmentation, image_processor: MaskFormerImageProcessor):
559
+ with torch.no_grad():
560
+ original_model = original_model.eval()
561
+ our_model = our_model.eval()
562
+
563
+ im = prepare_img()
564
+
565
+ tr = T.Compose(
566
+ [
567
+ T.Resize((384, 384)),
568
+ T.ToTensor(),
569
+ T.Normalize(
570
+ mean=torch.tensor([123.675, 116.280, 103.530]) / 255.0,
571
+ std=torch.tensor([58.395, 57.120, 57.375]) / 255.0,
572
+ ),
573
+ ],
574
+ )
575
+
576
+ x = tr(im).unsqueeze(0)
577
+
578
+ original_model_backbone_features = original_model.backbone(x.clone())
579
+
580
+ our_model_output: MaskFormerModelOutput = our_model.model(x.clone(), output_hidden_states=True)
581
+
582
+ for original_model_feature, our_model_feature in zip(
583
+ original_model_backbone_features.values(), our_model_output.encoder_hidden_states
584
+ ):
585
+ assert torch.allclose(original_model_feature, our_model_feature, atol=1e-3), (
586
+ "The backbone features are not the same."
587
+ )
588
+
589
+ original_model_pixel_out = original_model.sem_seg_head.pixel_decoder.forward_features(
590
+ original_model_backbone_features
591
+ )
592
+
593
+ assert torch.allclose(
594
+ original_model_pixel_out[0], our_model_output.pixel_decoder_last_hidden_state, atol=1e-4
595
+ ), "The pixel decoder feature are not the same"
596
+
597
+ # let's test the full model
598
+ original_model_out = original_model([{"image": x.squeeze(0)}])
599
+
600
+ original_segmentation = original_model_out[0]["sem_seg"]
601
+
602
+ our_model_out: MaskFormerForInstanceSegmentationOutput = our_model(x)
603
+
604
+ our_segmentation = image_processor.post_process_segmentation(our_model_out, target_size=(384, 384))
605
+
606
+ assert torch.allclose(original_segmentation, our_segmentation, atol=1e-3), (
607
+ "The segmentation image is not the same."
608
+ )
609
+
610
+ logger.info("Test passed!")
611
+
612
+
613
+ def get_name(checkpoint_file: Path):
614
+ model_name_raw: str = checkpoint_file.stem
615
+ # model_name_raw is something like maskformer_panoptic_swin_base_IN21k_384_bs64_554k
616
+ parent_name: str = checkpoint_file.parents[0].stem
617
+ backbone = "swin"
618
+ dataset = ""
619
+ if "coco" in parent_name:
620
+ dataset = "coco"
621
+ elif "ade" in parent_name:
622
+ dataset = "ade"
623
+ else:
624
+ raise ValueError(f"{parent_name} must be wrong since we didn't find 'coco' or 'ade' in it ")
625
+
626
+ backbone_types = ["tiny", "small", "base", "large"]
627
+
628
+ backbone_type = list(filter(lambda x: x in model_name_raw, backbone_types))[0]
629
+
630
+ model_name = f"maskformer-{backbone}-{backbone_type}-{dataset}"
631
+
632
+ return model_name
633
+
634
+
635
+ if __name__ == "__main__":
636
+ parser = ArgumentParser(
637
+ description="Command line to convert the original maskformers (with swin backbone) to our implementations."
638
+ )
639
+
640
+ parser.add_argument(
641
+ "--checkpoints_dir",
642
+ type=Path,
643
+ help=(
644
+ "A directory containing the model's checkpoints. The directory has to have the following structure:"
645
+ " <DIR_NAME>/<DATASET_NAME>/<CONFIG_NAME>.pkl\n"
646
+ "Given the files are in the pickle format, please be wary of passing it files you trust."
647
+ ),
648
+ )
649
+ parser.add_argument(
650
+ "--configs_dir",
651
+ type=Path,
652
+ help=(
653
+ "A directory containing the model's configs, see detectron2 doc. The directory has to have the following"
654
+ " structure: <DIR_NAME>/<DATASET_NAME>/<CONFIG_NAME>.yaml"
655
+ ),
656
+ )
657
+ parser.add_argument(
658
+ "--pytorch_dump_folder_path",
659
+ required=True,
660
+ type=Path,
661
+ help="Path to the folder to output PyTorch models.",
662
+ )
663
+ parser.add_argument(
664
+ "--maskformer_dir",
665
+ required=True,
666
+ type=Path,
667
+ help=(
668
+ "A path to MaskFormer's original implementation directory. You can download from here:"
669
+ " https://github.com/facebookresearch/MaskFormer"
670
+ ),
671
+ )
672
+
673
+ args = parser.parse_args()
674
+
675
+ checkpoints_dir: Path = args.checkpoints_dir
676
+ config_dir: Path = args.configs_dir
677
+ save_directory: Path = args.pytorch_dump_folder_path
678
+ maskformer_dir: Path = args.maskformer_dir
679
+ # append the path to the parents to maskformer dir
680
+ sys.path.append(str(maskformer_dir.parent))
681
+ # and import what's needed
682
+ from MaskFormer.mask_former import add_mask_former_config
683
+ from MaskFormer.mask_former.mask_former_model import MaskFormer as OriginalMaskFormer
684
+
685
+ if not save_directory.exists():
686
+ save_directory.mkdir(parents=True)
687
+
688
+ for config_file, checkpoint_file in OriginalMaskFormerCheckpointToOursConverter.using_dirs(
689
+ checkpoints_dir, config_dir
690
+ ):
691
+ image_processor = OriginalMaskFormerConfigToImageProcessorConverter()(setup_cfg(Args(config_file=config_file)))
692
+
693
+ original_config = setup_cfg(Args(config_file=config_file))
694
+ mask_former_kwargs = OriginalMaskFormer.from_config(original_config)
695
+
696
+ original_model = OriginalMaskFormer(**mask_former_kwargs).eval()
697
+
698
+ DetectionCheckpointer(original_model).load(str(checkpoint_file))
699
+
700
+ config: MaskFormerConfig = OriginalMaskFormerConfigToOursConverter()(original_config)
701
+
702
+ mask_former = MaskFormerModel(config=config).eval()
703
+
704
+ converter = OriginalMaskFormerCheckpointToOursConverter(original_model, config)
705
+
706
+ maskformer = converter.convert(mask_former)
707
+
708
+ mask_former_for_instance_segmentation = MaskFormerForInstanceSegmentation(config=config).eval()
709
+
710
+ mask_former_for_instance_segmentation.model = mask_former
711
+ mask_former_for_instance_segmentation = converter.convert_instance_segmentation(
712
+ mask_former_for_instance_segmentation
713
+ )
714
+
715
+ test(original_model, mask_former_for_instance_segmentation, image_processor)
716
+
717
+ model_name = get_name(checkpoint_file)
718
+ logger.info(f"Saving {model_name}")
719
+
720
+ image_processor.save_pretrained(save_directory / model_name)
721
+ mask_former_for_instance_segmentation.save_pretrained(save_directory / model_name)
722
+
723
+ image_processor.push_to_hub(repo_id=model_name)
724
+ mask_former_for_instance_segmentation.push_to_hub(repo_id=model_name)
third_party/transformers/src/transformers/models/maskformer/convert_maskformer_resnet_to_pytorch.py ADDED
@@ -0,0 +1,403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 MaskFormer checkpoints with ResNet backbone from the original repository. URL:
15
+ https://github.com/facebookresearch/MaskFormer"""
16
+
17
+ import argparse
18
+ import json
19
+ import os
20
+ import pickle
21
+ from io import BytesIO
22
+ from pathlib import Path
23
+
24
+ import httpx
25
+ import torch
26
+ from huggingface_hub import hf_hub_download
27
+ from PIL import Image
28
+
29
+ from transformers import MaskFormerConfig, MaskFormerForInstanceSegmentation, MaskFormerImageProcessor, ResNetConfig
30
+ from transformers.utils import logging
31
+
32
+ from ...utils import strtobool
33
+
34
+
35
+ logging.set_verbosity_info()
36
+ logger = logging.get_logger(__name__)
37
+
38
+
39
+ def get_maskformer_config(model_name: str):
40
+ if "resnet101c" in model_name:
41
+ # TODO add support for ResNet-C backbone, which uses a "deeplab" stem
42
+ raise NotImplementedError("To do")
43
+ elif "resnet101" in model_name:
44
+ backbone_config = ResNetConfig.from_pretrained(
45
+ "microsoft/resnet-101", out_features=["stage1", "stage2", "stage3", "stage4"]
46
+ )
47
+ else:
48
+ backbone_config = ResNetConfig.from_pretrained(
49
+ "microsoft/resnet-50", out_features=["stage1", "stage2", "stage3", "stage4"]
50
+ )
51
+ config = MaskFormerConfig(backbone_config=backbone_config)
52
+
53
+ repo_id = "huggingface/label-files"
54
+ if "ade20k-full" in model_name:
55
+ config.num_labels = 847
56
+ filename = "maskformer-ade20k-full-id2label.json"
57
+ elif "ade" in model_name:
58
+ config.num_labels = 150
59
+ filename = "ade20k-id2label.json"
60
+ elif "coco-stuff" in model_name:
61
+ config.num_labels = 171
62
+ filename = "maskformer-coco-stuff-id2label.json"
63
+ elif "coco" in model_name:
64
+ # TODO
65
+ config.num_labels = 133
66
+ filename = "coco-panoptic-id2label.json"
67
+ elif "cityscapes" in model_name:
68
+ config.num_labels = 19
69
+ filename = "cityscapes-id2label.json"
70
+ elif "vistas" in model_name:
71
+ config.num_labels = 65
72
+ filename = "mapillary-vistas-id2label.json"
73
+
74
+ id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r"))
75
+ id2label = {int(k): v for k, v in id2label.items()}
76
+ config.id2label = id2label
77
+ config.label2id = {v: k for k, v in id2label.items()}
78
+
79
+ return config
80
+
81
+
82
+ def create_rename_keys(config):
83
+ rename_keys = []
84
+ # stem
85
+ # fmt: off
86
+ rename_keys.append(("backbone.stem.conv1.weight", "model.pixel_level_module.encoder.embedder.embedder.convolution.weight"))
87
+ rename_keys.append(("backbone.stem.conv1.norm.weight", "model.pixel_level_module.encoder.embedder.embedder.normalization.weight"))
88
+ rename_keys.append(("backbone.stem.conv1.norm.bias", "model.pixel_level_module.encoder.embedder.embedder.normalization.bias"))
89
+ rename_keys.append(("backbone.stem.conv1.norm.running_mean", "model.pixel_level_module.encoder.embedder.embedder.normalization.running_mean"))
90
+ rename_keys.append(("backbone.stem.conv1.norm.running_var", "model.pixel_level_module.encoder.embedder.embedder.normalization.running_var"))
91
+ # fmt: on
92
+ # stages
93
+ for stage_idx in range(len(config.backbone_config.depths)):
94
+ for layer_idx in range(config.backbone_config.depths[stage_idx]):
95
+ # shortcut
96
+ if layer_idx == 0:
97
+ rename_keys.append(
98
+ (
99
+ f"backbone.res{stage_idx + 2}.{layer_idx}.shortcut.weight",
100
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.convolution.weight",
101
+ )
102
+ )
103
+ rename_keys.append(
104
+ (
105
+ f"backbone.res{stage_idx + 2}.{layer_idx}.shortcut.norm.weight",
106
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.weight",
107
+ )
108
+ )
109
+ rename_keys.append(
110
+ (
111
+ f"backbone.res{stage_idx + 2}.{layer_idx}.shortcut.norm.bias",
112
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.bias",
113
+ )
114
+ )
115
+ rename_keys.append(
116
+ (
117
+ f"backbone.res{stage_idx + 2}.{layer_idx}.shortcut.norm.running_mean",
118
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_mean",
119
+ )
120
+ )
121
+ rename_keys.append(
122
+ (
123
+ f"backbone.res{stage_idx + 2}.{layer_idx}.shortcut.norm.running_var",
124
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_var",
125
+ )
126
+ )
127
+ # 3 convs
128
+ for i in range(3):
129
+ rename_keys.append(
130
+ (
131
+ f"backbone.res{stage_idx + 2}.{layer_idx}.conv{i + 1}.weight",
132
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.convolution.weight",
133
+ )
134
+ )
135
+ rename_keys.append(
136
+ (
137
+ f"backbone.res{stage_idx + 2}.{layer_idx}.conv{i + 1}.norm.weight",
138
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.weight",
139
+ )
140
+ )
141
+ rename_keys.append(
142
+ (
143
+ f"backbone.res{stage_idx + 2}.{layer_idx}.conv{i + 1}.norm.bias",
144
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.bias",
145
+ )
146
+ )
147
+ rename_keys.append(
148
+ (
149
+ f"backbone.res{stage_idx + 2}.{layer_idx}.conv{i + 1}.norm.running_mean",
150
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_mean",
151
+ )
152
+ )
153
+ rename_keys.append(
154
+ (
155
+ f"backbone.res{stage_idx + 2}.{layer_idx}.conv{i + 1}.norm.running_var",
156
+ f"model.pixel_level_module.encoder.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_var",
157
+ )
158
+ )
159
+
160
+ # FPN
161
+ # fmt: off
162
+ rename_keys.append(("sem_seg_head.layer_4.weight", "model.pixel_level_module.decoder.fpn.stem.0.weight"))
163
+ rename_keys.append(("sem_seg_head.layer_4.norm.weight", "model.pixel_level_module.decoder.fpn.stem.1.weight"))
164
+ rename_keys.append(("sem_seg_head.layer_4.norm.bias", "model.pixel_level_module.decoder.fpn.stem.1.bias"))
165
+ for source_index, target_index in zip(range(3, 0, -1), range(0, 3)):
166
+ rename_keys.append((f"sem_seg_head.adapter_{source_index}.weight", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.proj.0.weight"))
167
+ rename_keys.append((f"sem_seg_head.adapter_{source_index}.norm.weight", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.proj.1.weight"))
168
+ rename_keys.append((f"sem_seg_head.adapter_{source_index}.norm.bias", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.proj.1.bias"))
169
+ rename_keys.append((f"sem_seg_head.layer_{source_index}.weight", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.block.0.weight"))
170
+ rename_keys.append((f"sem_seg_head.layer_{source_index}.norm.weight", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.block.1.weight"))
171
+ rename_keys.append((f"sem_seg_head.layer_{source_index}.norm.bias", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.block.1.bias"))
172
+ rename_keys.append(("sem_seg_head.mask_features.weight", "model.pixel_level_module.decoder.mask_projection.weight"))
173
+ rename_keys.append(("sem_seg_head.mask_features.bias", "model.pixel_level_module.decoder.mask_projection.bias"))
174
+ # fmt: on
175
+
176
+ # Transformer decoder
177
+ # fmt: off
178
+ for idx in range(config.decoder_config.decoder_layers):
179
+ # self-attention out projection
180
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.self_attn.out_proj.weight", f"model.transformer_module.decoder.layers.{idx}.self_attn.out_proj.weight"))
181
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.self_attn.out_proj.bias", f"model.transformer_module.decoder.layers.{idx}.self_attn.out_proj.bias"))
182
+ # cross-attention out projection
183
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.multihead_attn.out_proj.weight", f"model.transformer_module.decoder.layers.{idx}.encoder_attn.out_proj.weight"))
184
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.multihead_attn.out_proj.bias", f"model.transformer_module.decoder.layers.{idx}.encoder_attn.out_proj.bias"))
185
+ # MLP 1
186
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.linear1.weight", f"model.transformer_module.decoder.layers.{idx}.fc1.weight"))
187
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.linear1.bias", f"model.transformer_module.decoder.layers.{idx}.fc1.bias"))
188
+ # MLP 2
189
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.linear2.weight", f"model.transformer_module.decoder.layers.{idx}.fc2.weight"))
190
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.linear2.bias", f"model.transformer_module.decoder.layers.{idx}.fc2.bias"))
191
+ # layernorm 1 (self-attention layernorm)
192
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm1.weight", f"model.transformer_module.decoder.layers.{idx}.self_attn_layer_norm.weight"))
193
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm1.bias", f"model.transformer_module.decoder.layers.{idx}.self_attn_layer_norm.bias"))
194
+ # layernorm 2 (cross-attention layernorm)
195
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm2.weight", f"model.transformer_module.decoder.layers.{idx}.encoder_attn_layer_norm.weight"))
196
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm2.bias", f"model.transformer_module.decoder.layers.{idx}.encoder_attn_layer_norm.bias"))
197
+ # layernorm 3 (final layernorm)
198
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm3.weight", f"model.transformer_module.decoder.layers.{idx}.final_layer_norm.weight"))
199
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm3.bias", f"model.transformer_module.decoder.layers.{idx}.final_layer_norm.bias"))
200
+
201
+ rename_keys.append(("sem_seg_head.predictor.transformer.decoder.norm.weight", "model.transformer_module.decoder.layernorm.weight"))
202
+ rename_keys.append(("sem_seg_head.predictor.transformer.decoder.norm.bias", "model.transformer_module.decoder.layernorm.bias"))
203
+ # fmt: on
204
+
205
+ # heads on top
206
+ # fmt: off
207
+ rename_keys.append(("sem_seg_head.predictor.query_embed.weight", "model.transformer_module.queries_embedder.weight"))
208
+
209
+ rename_keys.append(("sem_seg_head.predictor.input_proj.weight", "model.transformer_module.input_projection.weight"))
210
+ rename_keys.append(("sem_seg_head.predictor.input_proj.bias", "model.transformer_module.input_projection.bias"))
211
+
212
+ rename_keys.append(("sem_seg_head.predictor.class_embed.weight", "class_predictor.weight"))
213
+ rename_keys.append(("sem_seg_head.predictor.class_embed.bias", "class_predictor.bias"))
214
+
215
+ for i in range(3):
216
+ rename_keys.append((f"sem_seg_head.predictor.mask_embed.layers.{i}.weight", f"mask_embedder.{i}.0.weight"))
217
+ rename_keys.append((f"sem_seg_head.predictor.mask_embed.layers.{i}.bias", f"mask_embedder.{i}.0.bias"))
218
+ # fmt: on
219
+
220
+ return rename_keys
221
+
222
+
223
+ def rename_key(dct, old, new):
224
+ val = dct.pop(old)
225
+ dct[new] = val
226
+
227
+
228
+ # we split up the matrix of each encoder layer into queries, keys and values
229
+ def read_in_decoder_q_k_v(state_dict, config):
230
+ # fmt: off
231
+ hidden_size = config.decoder_config.hidden_size
232
+ for idx in range(config.decoder_config.decoder_layers):
233
+ # read in weights + bias of self-attention input projection layer (in the original implementation, this is a single matrix + bias)
234
+ in_proj_weight = state_dict.pop(f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.self_attn.in_proj_weight")
235
+ in_proj_bias = state_dict.pop(f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.self_attn.in_proj_bias")
236
+ # next, add query, keys and values (in that order) to the state dict
237
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.q_proj.weight"] = in_proj_weight[: hidden_size, :]
238
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.q_proj.bias"] = in_proj_bias[:config.hidden_size]
239
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.k_proj.weight"] = in_proj_weight[hidden_size : hidden_size * 2, :]
240
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.k_proj.bias"] = in_proj_bias[hidden_size : hidden_size * 2]
241
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.v_proj.weight"] = in_proj_weight[-hidden_size :, :]
242
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.v_proj.bias"] = in_proj_bias[-hidden_size :]
243
+ # read in weights + bias of cross-attention input projection layer (in the original implementation, this is a single matrix + bias)
244
+ in_proj_weight = state_dict.pop(f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.multihead_attn.in_proj_weight")
245
+ in_proj_bias = state_dict.pop(f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.multihead_attn.in_proj_bias")
246
+ # next, add query, keys and values (in that order) to the state dict
247
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.q_proj.weight"] = in_proj_weight[: hidden_size, :]
248
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.q_proj.bias"] = in_proj_bias[:config.hidden_size]
249
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.k_proj.weight"] = in_proj_weight[hidden_size : hidden_size * 2, :]
250
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.k_proj.bias"] = in_proj_bias[hidden_size : hidden_size * 2]
251
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.v_proj.weight"] = in_proj_weight[-hidden_size :, :]
252
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.v_proj.bias"] = in_proj_bias[-hidden_size :]
253
+ # fmt: on
254
+
255
+
256
+ # We will verify our results on an image of cute cats
257
+ def prepare_img() -> torch.Tensor:
258
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
259
+ with httpx.stream("GET", url) as response:
260
+ image = Image.open(BytesIO(response.read()))
261
+ return image
262
+
263
+
264
+ @torch.no_grad()
265
+ def convert_maskformer_checkpoint(
266
+ model_name: str, checkpoint_path: str, pytorch_dump_folder_path: str, push_to_hub: bool = False
267
+ ):
268
+ """
269
+ Copy/paste/tweak model's weights to our MaskFormer structure.
270
+ """
271
+ config = get_maskformer_config(model_name)
272
+
273
+ if not strtobool(os.environ.get("TRUST_REMOTE_CODE", "False")):
274
+ raise ValueError(
275
+ "This part uses `pickle.load` which is insecure and will execute arbitrary code that is potentially "
276
+ "malicious. It's recommended to never unpickle data that could have come from an untrusted source, or "
277
+ "that could have been tampered with. If you already verified the pickle data and decided to use it, "
278
+ "you can set the environment variable `TRUST_REMOTE_CODE` to `True` to allow it."
279
+ )
280
+ # load original state_dict
281
+ with open(checkpoint_path, "rb") as f:
282
+ data = pickle.load(f)
283
+ state_dict = data["model"]
284
+
285
+ # rename keys
286
+ rename_keys = create_rename_keys(config)
287
+ for src, dest in rename_keys:
288
+ rename_key(state_dict, src, dest)
289
+ read_in_decoder_q_k_v(state_dict, config)
290
+
291
+ # update to torch tensors
292
+ for key, value in state_dict.items():
293
+ state_dict[key] = torch.from_numpy(value)
294
+
295
+ # load 🤗 model
296
+ model = MaskFormerForInstanceSegmentation(config)
297
+ model.eval()
298
+
299
+ model.load_state_dict(state_dict)
300
+
301
+ # verify results
302
+ image = prepare_img()
303
+ if "vistas" in model_name:
304
+ ignore_index = 65
305
+ elif "cityscapes" in model_name:
306
+ ignore_index = 65535
307
+ else:
308
+ ignore_index = 255
309
+ do_reduce_labels = "ade" in model_name
310
+ image_processor = MaskFormerImageProcessor(ignore_index=ignore_index, do_reduce_labels=do_reduce_labels)
311
+
312
+ inputs = image_processor(image, return_tensors="pt")
313
+
314
+ outputs = model(**inputs)
315
+
316
+ if model_name == "maskformer-resnet50-ade":
317
+ expected_logits = torch.tensor(
318
+ [[6.7710, -0.1452, -3.5687], [1.9165, -1.0010, -1.8614], [3.6209, -0.2950, -1.3813]]
319
+ )
320
+ elif model_name == "maskformer-resnet101-ade":
321
+ expected_logits = torch.tensor(
322
+ [[4.0381, -1.1483, -1.9688], [2.7083, -1.9147, -2.2555], [3.4367, -1.3711, -2.1609]]
323
+ )
324
+ elif model_name == "maskformer-resnet50-coco-stuff":
325
+ expected_logits = torch.tensor(
326
+ [[3.2309, -3.0481, -2.8695], [5.4986, -5.4242, -2.4211], [6.2100, -5.2279, -2.7786]]
327
+ )
328
+ elif model_name == "maskformer-resnet101-coco-stuff":
329
+ expected_logits = torch.tensor(
330
+ [[4.7188, -3.2585, -2.8857], [6.6871, -2.9181, -1.2487], [7.2449, -2.2764, -2.1874]]
331
+ )
332
+ elif model_name == "maskformer-resnet101-cityscapes":
333
+ expected_logits = torch.tensor(
334
+ [[-1.8861, -1.5465, 0.6749], [-2.3677, -1.6707, -0.0867], [-2.2314, -1.9530, -0.9132]]
335
+ )
336
+ elif model_name == "maskformer-resnet50-vistas":
337
+ expected_logits = torch.tensor(
338
+ [[-6.3917, -1.5216, -1.1392], [-5.5335, -4.5318, -1.8339], [-4.3576, -4.0301, 0.2162]]
339
+ )
340
+ elif model_name == "maskformer-resnet50-ade20k-full":
341
+ expected_logits = torch.tensor(
342
+ [[3.6146, -1.9367, -3.2534], [4.0099, 0.2027, -2.7576], [3.3913, -2.3644, -3.9519]]
343
+ )
344
+ elif model_name == "maskformer-resnet101-ade20k-full":
345
+ expected_logits = torch.tensor(
346
+ [[3.2211, -1.6550, -2.7605], [2.8559, -2.4512, -2.9574], [2.6331, -2.6775, -2.1844]]
347
+ )
348
+
349
+ assert torch.allclose(outputs.class_queries_logits[0, :3, :3], expected_logits, atol=1e-4)
350
+ print("Looks ok!")
351
+
352
+ if pytorch_dump_folder_path is not None:
353
+ print(f"Saving model and image processor of {model_name} to {pytorch_dump_folder_path}")
354
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
355
+ model.save_pretrained(pytorch_dump_folder_path)
356
+ image_processor.save_pretrained(pytorch_dump_folder_path)
357
+
358
+ if push_to_hub:
359
+ print(f"Pushing model and image processor of {model_name} to the hub...")
360
+ model.push_to_hub(f"facebook/{model_name}")
361
+ image_processor.push_to_hub(f"facebook/{model_name}")
362
+
363
+
364
+ if __name__ == "__main__":
365
+ parser = argparse.ArgumentParser()
366
+ # Required parameters
367
+ parser.add_argument(
368
+ "--model_name",
369
+ default="maskformer-resnet50-ade",
370
+ type=str,
371
+ required=True,
372
+ choices=[
373
+ "maskformer-resnet50-ade",
374
+ "maskformer-resnet101-ade",
375
+ "maskformer-resnet50-coco-stuff",
376
+ "maskformer-resnet101-coco-stuff",
377
+ "maskformer-resnet101-cityscapes",
378
+ "maskformer-resnet50-vistas",
379
+ "maskformer-resnet50-ade20k-full",
380
+ "maskformer-resnet101-ade20k-full",
381
+ ],
382
+ help=("Name of the MaskFormer model you'd like to convert",),
383
+ )
384
+ parser.add_argument(
385
+ "--checkpoint_path",
386
+ type=str,
387
+ required=True,
388
+ help="Path to the original pickle file (.pkl) of the original checkpoint.\n"
389
+ "Given the files are in the pickle format, please be wary of passing it files you trust.",
390
+ )
391
+ parser.add_argument(
392
+ "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory."
393
+ )
394
+ parser.add_argument(
395
+ "--push_to_hub",
396
+ action="store_true",
397
+ help="Whether or not to push the converted model to the Hugging Face hub.",
398
+ )
399
+
400
+ args = parser.parse_args()
401
+ convert_maskformer_checkpoint(
402
+ args.model_name, args.checkpoint_path, args.pytorch_dump_folder_path, args.push_to_hub
403
+ )
third_party/transformers/src/transformers/models/maskformer/convert_maskformer_swin_to_pytorch.py ADDED
@@ -0,0 +1,346 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 MaskFormer checkpoints with Swin backbone from the original repository. URL:
15
+ https://github.com/facebookresearch/MaskFormer"""
16
+
17
+ import argparse
18
+ import json
19
+ import os
20
+ import pickle
21
+ from io import BytesIO
22
+ from pathlib import Path
23
+
24
+ import httpx
25
+ import torch
26
+ from huggingface_hub import hf_hub_download
27
+ from PIL import Image
28
+
29
+ from transformers import MaskFormerConfig, MaskFormerForInstanceSegmentation, MaskFormerImageProcessor, SwinConfig
30
+ from transformers.utils import logging
31
+
32
+ from ...utils import strtobool
33
+
34
+
35
+ logging.set_verbosity_info()
36
+ logger = logging.get_logger(__name__)
37
+
38
+
39
+ def get_maskformer_config(model_name: str):
40
+ backbone_config = SwinConfig.from_pretrained(
41
+ "microsoft/swin-tiny-patch4-window7-224", out_features=["stage1", "stage2", "stage3", "stage4"]
42
+ )
43
+ config = MaskFormerConfig(backbone_config=backbone_config)
44
+
45
+ repo_id = "huggingface/label-files"
46
+ if "ade20k-full" in model_name:
47
+ # this should be ok
48
+ config.num_labels = 847
49
+ filename = "maskformer-ade20k-full-id2label.json"
50
+ elif "ade" in model_name:
51
+ # this should be ok
52
+ config.num_labels = 150
53
+ filename = "ade20k-id2label.json"
54
+ elif "coco-stuff" in model_name:
55
+ # this should be ok
56
+ config.num_labels = 171
57
+ filename = "maskformer-coco-stuff-id2label.json"
58
+ elif "coco" in model_name:
59
+ # TODO
60
+ config.num_labels = 133
61
+ filename = "coco-panoptic-id2label.json"
62
+ elif "cityscapes" in model_name:
63
+ # this should be ok
64
+ config.num_labels = 19
65
+ filename = "cityscapes-id2label.json"
66
+ elif "vistas" in model_name:
67
+ # this should be ok
68
+ config.num_labels = 65
69
+ filename = "mapillary-vistas-id2label.json"
70
+
71
+ id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r"))
72
+ id2label = {int(k): v for k, v in id2label.items()}
73
+
74
+ return config
75
+
76
+
77
+ def create_rename_keys(config):
78
+ rename_keys = []
79
+ # stem
80
+ # fmt: off
81
+ rename_keys.append(("backbone.patch_embed.proj.weight", "model.pixel_level_module.encoder.model.embeddings.patch_embeddings.projection.weight"))
82
+ rename_keys.append(("backbone.patch_embed.proj.bias", "model.pixel_level_module.encoder.model.embeddings.patch_embeddings.projection.bias"))
83
+ rename_keys.append(("backbone.patch_embed.norm.weight", "model.pixel_level_module.encoder.model.embeddings.norm.weight"))
84
+ rename_keys.append(("backbone.patch_embed.norm.bias", "model.pixel_level_module.encoder.model.embeddings.norm.bias"))
85
+ # stages
86
+ for i in range(len(config.backbone_config.depths)):
87
+ for j in range(config.backbone_config.depths[i]):
88
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.norm1.weight", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.layernorm_before.weight"))
89
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.norm1.bias", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.layernorm_before.bias"))
90
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.attn.relative_position_bias_table", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.self.relative_position_bias_table"))
91
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.attn.relative_position_index", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.self.relative_position_index"))
92
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.attn.proj.weight", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.output.dense.weight"))
93
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.attn.proj.bias", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.output.dense.bias"))
94
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.norm2.weight", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.layernorm_after.weight"))
95
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.norm2.bias", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.layernorm_after.bias"))
96
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.mlp.fc1.weight", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.intermediate.dense.weight"))
97
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.mlp.fc1.bias", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.intermediate.dense.bias"))
98
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.mlp.fc2.weight", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.output.dense.weight"))
99
+ rename_keys.append((f"backbone.layers.{i}.blocks.{j}.mlp.fc2.bias", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.output.dense.bias"))
100
+
101
+ if i < 3:
102
+ rename_keys.append((f"backbone.layers.{i}.downsample.reduction.weight", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.downsample.reduction.weight"))
103
+ rename_keys.append((f"backbone.layers.{i}.downsample.norm.weight", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.downsample.norm.weight"))
104
+ rename_keys.append((f"backbone.layers.{i}.downsample.norm.bias", f"model.pixel_level_module.encoder.model.encoder.layers.{i}.downsample.norm.bias"))
105
+ rename_keys.append((f"backbone.norm{i}.weight", f"model.pixel_level_module.encoder.hidden_states_norms.{i}.weight"))
106
+ rename_keys.append((f"backbone.norm{i}.bias", f"model.pixel_level_module.encoder.hidden_states_norms.{i}.bias"))
107
+
108
+ # FPN
109
+ rename_keys.append(("sem_seg_head.layer_4.weight", "model.pixel_level_module.decoder.fpn.stem.0.weight"))
110
+ rename_keys.append(("sem_seg_head.layer_4.norm.weight", "model.pixel_level_module.decoder.fpn.stem.1.weight"))
111
+ rename_keys.append(("sem_seg_head.layer_4.norm.bias", "model.pixel_level_module.decoder.fpn.stem.1.bias"))
112
+ for source_index, target_index in zip(range(3, 0, -1), range(0, 3)):
113
+ rename_keys.append((f"sem_seg_head.adapter_{source_index}.weight", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.proj.0.weight"))
114
+ rename_keys.append((f"sem_seg_head.adapter_{source_index}.norm.weight", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.proj.1.weight"))
115
+ rename_keys.append((f"sem_seg_head.adapter_{source_index}.norm.bias", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.proj.1.bias"))
116
+ rename_keys.append((f"sem_seg_head.layer_{source_index}.weight", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.block.0.weight"))
117
+ rename_keys.append((f"sem_seg_head.layer_{source_index}.norm.weight", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.block.1.weight"))
118
+ rename_keys.append((f"sem_seg_head.layer_{source_index}.norm.bias", f"model.pixel_level_module.decoder.fpn.layers.{target_index}.block.1.bias"))
119
+ rename_keys.append(("sem_seg_head.mask_features.weight", "model.pixel_level_module.decoder.mask_projection.weight"))
120
+ rename_keys.append(("sem_seg_head.mask_features.bias", "model.pixel_level_module.decoder.mask_projection.bias"))
121
+
122
+ # Transformer decoder
123
+ for idx in range(config.decoder_config.decoder_layers):
124
+ # self-attention out projection
125
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.self_attn.out_proj.weight", f"model.transformer_module.decoder.layers.{idx}.self_attn.out_proj.weight"))
126
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.self_attn.out_proj.bias", f"model.transformer_module.decoder.layers.{idx}.self_attn.out_proj.bias"))
127
+ # cross-attention out projection
128
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.multihead_attn.out_proj.weight", f"model.transformer_module.decoder.layers.{idx}.encoder_attn.out_proj.weight"))
129
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.multihead_attn.out_proj.bias", f"model.transformer_module.decoder.layers.{idx}.encoder_attn.out_proj.bias"))
130
+ # MLP 1
131
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.linear1.weight", f"model.transformer_module.decoder.layers.{idx}.fc1.weight"))
132
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.linear1.bias", f"model.transformer_module.decoder.layers.{idx}.fc1.bias"))
133
+ # MLP 2
134
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.linear2.weight", f"model.transformer_module.decoder.layers.{idx}.fc2.weight"))
135
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.linear2.bias", f"model.transformer_module.decoder.layers.{idx}.fc2.bias"))
136
+ # layernorm 1 (self-attention layernorm)
137
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm1.weight", f"model.transformer_module.decoder.layers.{idx}.self_attn_layer_norm.weight"))
138
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm1.bias", f"model.transformer_module.decoder.layers.{idx}.self_attn_layer_norm.bias"))
139
+ # layernorm 2 (cross-attention layernorm)
140
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm2.weight", f"model.transformer_module.decoder.layers.{idx}.encoder_attn_layer_norm.weight"))
141
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm2.bias", f"model.transformer_module.decoder.layers.{idx}.encoder_attn_layer_norm.bias"))
142
+ # layernorm 3 (final layernorm)
143
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm3.weight", f"model.transformer_module.decoder.layers.{idx}.final_layer_norm.weight"))
144
+ rename_keys.append((f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.norm3.bias", f"model.transformer_module.decoder.layers.{idx}.final_layer_norm.bias"))
145
+
146
+ rename_keys.append(("sem_seg_head.predictor.transformer.decoder.norm.weight", "model.transformer_module.decoder.layernorm.weight"))
147
+ rename_keys.append(("sem_seg_head.predictor.transformer.decoder.norm.bias", "model.transformer_module.decoder.layernorm.bias"))
148
+
149
+ # heads on top
150
+ rename_keys.append(("sem_seg_head.predictor.query_embed.weight", "model.transformer_module.queries_embedder.weight"))
151
+
152
+ rename_keys.append(("sem_seg_head.predictor.input_proj.weight", "model.transformer_module.input_projection.weight"))
153
+ rename_keys.append(("sem_seg_head.predictor.input_proj.bias", "model.transformer_module.input_projection.bias"))
154
+
155
+ rename_keys.append(("sem_seg_head.predictor.class_embed.weight", "class_predictor.weight"))
156
+ rename_keys.append(("sem_seg_head.predictor.class_embed.bias", "class_predictor.bias"))
157
+
158
+ for i in range(3):
159
+ rename_keys.append((f"sem_seg_head.predictor.mask_embed.layers.{i}.weight", f"mask_embedder.{i}.0.weight"))
160
+ rename_keys.append((f"sem_seg_head.predictor.mask_embed.layers.{i}.bias", f"mask_embedder.{i}.0.bias"))
161
+ # fmt: on
162
+
163
+ return rename_keys
164
+
165
+
166
+ def rename_key(dct, old, new):
167
+ val = dct.pop(old)
168
+ dct[new] = val
169
+
170
+
171
+ # we split up the matrix of each encoder layer into queries, keys and values
172
+ def read_in_swin_q_k_v(state_dict, backbone_config):
173
+ num_features = [int(backbone_config.embed_dim * 2**i) for i in range(len(backbone_config.depths))]
174
+ for i in range(len(backbone_config.depths)):
175
+ dim = num_features[i]
176
+ for j in range(backbone_config.depths[i]):
177
+ # fmt: off
178
+ # read in weights + bias of input projection layer (in original implementation, this is a single matrix + bias)
179
+ in_proj_weight = state_dict.pop(f"backbone.layers.{i}.blocks.{j}.attn.qkv.weight")
180
+ in_proj_bias = state_dict.pop(f"backbone.layers.{i}.blocks.{j}.attn.qkv.bias")
181
+ # next, add query, keys and values (in that order) to the state dict
182
+ state_dict[f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.self.query.weight"] = in_proj_weight[:dim, :]
183
+ state_dict[f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.self.query.bias"] = in_proj_bias[: dim]
184
+ state_dict[f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.self.key.weight"] = in_proj_weight[
185
+ dim : dim * 2, :
186
+ ]
187
+ state_dict[f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.self.key.bias"] = in_proj_bias[
188
+ dim : dim * 2
189
+ ]
190
+ state_dict[f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.self.value.weight"] = in_proj_weight[
191
+ -dim :, :
192
+ ]
193
+ state_dict[f"model.pixel_level_module.encoder.model.encoder.layers.{i}.blocks.{j}.attention.self.value.bias"] = in_proj_bias[-dim :]
194
+ # fmt: on
195
+
196
+
197
+ # we split up the matrix of each encoder layer into queries, keys and values
198
+ def read_in_decoder_q_k_v(state_dict, config):
199
+ # fmt: off
200
+ hidden_size = config.decoder_config.hidden_size
201
+ for idx in range(config.decoder_config.decoder_layers):
202
+ # read in weights + bias of self-attention input projection layer (in the original implementation, this is a single matrix + bias)
203
+ in_proj_weight = state_dict.pop(f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.self_attn.in_proj_weight")
204
+ in_proj_bias = state_dict.pop(f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.self_attn.in_proj_bias")
205
+ # next, add query, keys and values (in that order) to the state dict
206
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.q_proj.weight"] = in_proj_weight[: hidden_size, :]
207
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.q_proj.bias"] = in_proj_bias[:config.hidden_size]
208
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.k_proj.weight"] = in_proj_weight[hidden_size : hidden_size * 2, :]
209
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.k_proj.bias"] = in_proj_bias[hidden_size : hidden_size * 2]
210
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.v_proj.weight"] = in_proj_weight[-hidden_size :, :]
211
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.self_attn.v_proj.bias"] = in_proj_bias[-hidden_size :]
212
+ # read in weights + bias of cross-attention input projection layer (in the original implementation, this is a single matrix + bias)
213
+ in_proj_weight = state_dict.pop(f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.multihead_attn.in_proj_weight")
214
+ in_proj_bias = state_dict.pop(f"sem_seg_head.predictor.transformer.decoder.layers.{idx}.multihead_attn.in_proj_bias")
215
+ # next, add query, keys and values (in that order) to the state dict
216
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.q_proj.weight"] = in_proj_weight[: hidden_size, :]
217
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.q_proj.bias"] = in_proj_bias[:config.hidden_size]
218
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.k_proj.weight"] = in_proj_weight[hidden_size : hidden_size * 2, :]
219
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.k_proj.bias"] = in_proj_bias[hidden_size : hidden_size * 2]
220
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.v_proj.weight"] = in_proj_weight[-hidden_size :, :]
221
+ state_dict[f"model.transformer_module.decoder.layers.{idx}.encoder_attn.v_proj.bias"] = in_proj_bias[-hidden_size :]
222
+ # fmt: on
223
+
224
+
225
+ # We will verify our results on an image of cute cats
226
+ def prepare_img() -> torch.Tensor:
227
+ url = "http://images.cocodataset.org/val2017/000000039769.jpg"
228
+ with httpx.stream("GET", url) as response:
229
+ image = Image.open(BytesIO(response.read()))
230
+ return image
231
+
232
+
233
+ @torch.no_grad()
234
+ def convert_maskformer_checkpoint(
235
+ model_name: str, checkpoint_path: str, pytorch_dump_folder_path: str, push_to_hub: bool = False
236
+ ):
237
+ """
238
+ Copy/paste/tweak model's weights to our MaskFormer structure.
239
+ """
240
+ config = get_maskformer_config(model_name)
241
+
242
+ if not strtobool(os.environ.get("TRUST_REMOTE_CODE", "False")):
243
+ raise ValueError(
244
+ "This part uses `pickle.load` which is insecure and will execute arbitrary code that is potentially "
245
+ "malicious. It's recommended to never unpickle data that could have come from an untrusted source, or "
246
+ "that could have been tampered with. If you already verified the pickle data and decided to use it, "
247
+ "you can set the environment variable `TRUST_REMOTE_CODE` to `True` to allow it."
248
+ )
249
+ # load original state_dict
250
+ with open(checkpoint_path, "rb") as f:
251
+ data = pickle.load(f)
252
+ state_dict = data["model"]
253
+
254
+ # for name, param in state_dict.items():
255
+ # print(name, param.shape)
256
+
257
+ # rename keys
258
+ rename_keys = create_rename_keys(config)
259
+ for src, dest in rename_keys:
260
+ rename_key(state_dict, src, dest)
261
+ read_in_swin_q_k_v(state_dict, config.backbone_config)
262
+ read_in_decoder_q_k_v(state_dict, config)
263
+
264
+ # update to torch tensors
265
+ for key, value in state_dict.items():
266
+ state_dict[key] = torch.from_numpy(value)
267
+
268
+ # load 🤗 model
269
+ model = MaskFormerForInstanceSegmentation(config)
270
+ model.eval()
271
+
272
+ for name, param in model.named_parameters():
273
+ print(name, param.shape)
274
+
275
+ missing_keys, unexpected_keys = model.load_state_dict(state_dict, strict=False)
276
+ assert missing_keys == [
277
+ "model.pixel_level_module.encoder.model.layernorm.weight",
278
+ "model.pixel_level_module.encoder.model.layernorm.bias",
279
+ ]
280
+ assert len(unexpected_keys) == 0, f"Unexpected keys: {unexpected_keys}"
281
+
282
+ # verify results
283
+ image = prepare_img()
284
+ if "vistas" in model_name:
285
+ ignore_index = 65
286
+ elif "cityscapes" in model_name:
287
+ ignore_index = 65535
288
+ else:
289
+ ignore_index = 255
290
+ do_reduce_labels = "ade" in model_name
291
+ image_processor = MaskFormerImageProcessor(ignore_index=ignore_index, do_reduce_labels=do_reduce_labels)
292
+
293
+ inputs = image_processor(image, return_tensors="pt")
294
+
295
+ outputs = model(**inputs)
296
+
297
+ print("Logits:", outputs.class_queries_logits[0, :3, :3])
298
+
299
+ if model_name == "maskformer-swin-tiny-ade":
300
+ expected_logits = torch.tensor(
301
+ [[3.6353, -4.4770, -2.6065], [0.5081, -4.2394, -3.5343], [2.1909, -5.0353, -1.9323]]
302
+ )
303
+ assert torch.allclose(outputs.class_queries_logits[0, :3, :3], expected_logits, atol=1e-4)
304
+ print("Looks ok!")
305
+
306
+ if pytorch_dump_folder_path is not None:
307
+ print(f"Saving model and image processor to {pytorch_dump_folder_path}")
308
+ Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
309
+ model.save_pretrained(pytorch_dump_folder_path)
310
+ image_processor.save_pretrained(pytorch_dump_folder_path)
311
+
312
+ if push_to_hub:
313
+ print("Pushing model and image processor to the hub...")
314
+ model.push_to_hub(f"nielsr/{model_name}")
315
+ image_processor.push_to_hub(f"nielsr/{model_name}")
316
+
317
+
318
+ if __name__ == "__main__":
319
+ parser = argparse.ArgumentParser()
320
+ # Required parameters
321
+ parser.add_argument(
322
+ "--model_name",
323
+ default="maskformer-swin-tiny-ade",
324
+ type=str,
325
+ help=("Name of the MaskFormer model you'd like to convert",),
326
+ )
327
+ parser.add_argument(
328
+ "--checkpoint_path",
329
+ default="/Users/nielsrogge/Documents/MaskFormer_checkpoints/MaskFormer-Swin-tiny-ADE20k/model.pkl",
330
+ type=str,
331
+ help="Path to the original state dict (.pth file).\n"
332
+ "Given the files are in the pickle format, please be wary of passing it files you trust.",
333
+ )
334
+ parser.add_argument(
335
+ "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory."
336
+ )
337
+ parser.add_argument(
338
+ "--push_to_hub",
339
+ action="store_true",
340
+ help="Whether or not to push the converted model to the Hugging Face hub.",
341
+ )
342
+
343
+ args = parser.parse_args()
344
+ convert_maskformer_checkpoint(
345
+ args.model_name, args.checkpoint_path, args.pytorch_dump_folder_path, args.push_to_hub
346
+ )
third_party/transformers/src/transformers/models/maskformer/image_processing_maskformer.py ADDED
@@ -0,0 +1,806 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ """Image processor class for MaskFormer."""
15
+
16
+ import math
17
+ from typing import Any, Optional, Union
18
+
19
+ import numpy as np
20
+ import torch
21
+ from torch import nn
22
+ from torchvision.transforms.v2 import functional as tvF
23
+
24
+ from ...image_processing_backends import TorchvisionBackend
25
+ from ...image_processing_utils import BatchFeature, get_size_dict
26
+ from ...image_transforms import get_size_with_aspect_ratio, group_images_by_shape, reorder_images
27
+ from ...image_utils import (
28
+ IMAGENET_DEFAULT_MEAN,
29
+ IMAGENET_DEFAULT_STD,
30
+ ChannelDimension,
31
+ ImageInput,
32
+ PILImageResampling,
33
+ SizeDict,
34
+ get_image_size_for_max_height_width,
35
+ )
36
+ from ...processing_utils import ImagesKwargs, Unpack
37
+ from ...utils import TensorType, auto_docstring, logging
38
+
39
+
40
+ logger = logging.get_logger(__name__)
41
+
42
+
43
+ # Helper functions for post-processing (PyTorch-based)
44
+ def binary_mask_to_rle(mask: "torch.Tensor | np.ndarray") -> list[int]:
45
+ """
46
+ Converts given binary mask of shape `(height, width)` to the run-length encoding (RLE) format.
47
+
48
+ Args:
49
+ mask (`torch.Tensor` or `np.ndarray`):
50
+ A binary mask of shape `(height, width)` where 0 denotes background and 1 denotes the target
51
+ segment_id or class_id.
52
+ Returns:
53
+ `List`: Run-length encoded list of the binary mask. Refer to COCO API for more information about the RLE
54
+ format.
55
+ """
56
+ if isinstance(mask, np.ndarray):
57
+ mask = torch.from_numpy(mask)
58
+
59
+ pixels = mask.flatten()
60
+ zero = torch.zeros(1, device=pixels.device, dtype=pixels.dtype)
61
+ pixels = torch.cat([zero, pixels, zero])
62
+ runs = torch.where(pixels[1:] != pixels[:-1])[0] + 1
63
+ runs[1::2] -= runs[::2]
64
+ return runs.tolist()
65
+
66
+
67
+ def convert_segmentation_to_rle(segmentation):
68
+ """
69
+ Converts given segmentation map of shape `(height, width)` to the run-length encoding (RLE) format.
70
+
71
+ Args:
72
+ segmentation (`torch.Tensor`):
73
+ A segmentation map of shape `(height, width)` where each value denotes a segment or class id.
74
+ Returns:
75
+ `list[List]`: A list of lists, where each list is the run-length encoding of a segment / class id.
76
+ """
77
+ segment_ids = torch.unique(segmentation)
78
+
79
+ run_length_encodings = []
80
+ for idx in segment_ids:
81
+ mask = torch.where(segmentation == idx, 1, 0)
82
+ rle = binary_mask_to_rle(mask)
83
+ run_length_encodings.append(rle)
84
+
85
+ return run_length_encodings
86
+
87
+
88
+ def remove_low_and_no_objects(masks, scores, labels, object_mask_threshold, num_labels):
89
+ """
90
+ Binarize the given masks using `object_mask_threshold`, it returns the associated values of `masks`, `scores` and
91
+ `labels`.
92
+
93
+ Args:
94
+ masks (`torch.Tensor`):
95
+ A tensor of shape `(num_queries, height, width)`.
96
+ scores (`torch.Tensor`):
97
+ A tensor of shape `(num_queries)`.
98
+ labels (`torch.Tensor`):
99
+ A tensor of shape `(num_queries)`.
100
+ object_mask_threshold (`float`):
101
+ A number between 0 and 1 used to binarize the masks.
102
+ Raises:
103
+ `ValueError`: Raised when the first dimension doesn't match in all input tensors.
104
+ Returns:
105
+ `tuple[`torch.Tensor`, `torch.Tensor`, `torch.Tensor`]`: The `masks`, `scores` and `labels` without the region
106
+ < `object_mask_threshold`.
107
+ """
108
+ if not (masks.shape[0] == scores.shape[0] == labels.shape[0]):
109
+ raise ValueError("mask, scores and labels must have the same shape!")
110
+
111
+ to_keep = labels.ne(num_labels) & (scores > object_mask_threshold)
112
+
113
+ return masks[to_keep], scores[to_keep], labels[to_keep]
114
+
115
+
116
+ def check_segment_validity(mask_labels, mask_probs, k, mask_threshold=0.5, overlap_mask_area_threshold=0.8):
117
+ # Get the mask associated with the k class
118
+ mask_k = mask_labels == k
119
+ mask_k_area = mask_k.sum()
120
+
121
+ # Compute the area of all the stuff in query k
122
+ original_area = (mask_probs[k] >= mask_threshold).sum()
123
+ mask_exists = mask_k_area > 0 and original_area > 0
124
+
125
+ # Eliminate disconnected tiny segments
126
+ if mask_exists:
127
+ area_ratio = mask_k_area / original_area
128
+ if not area_ratio.item() > overlap_mask_area_threshold:
129
+ mask_exists = False
130
+
131
+ return mask_exists, mask_k
132
+
133
+
134
+ def compute_segments(
135
+ mask_probs,
136
+ pred_scores,
137
+ pred_labels,
138
+ mask_threshold: float = 0.5,
139
+ overlap_mask_area_threshold: float = 0.8,
140
+ label_ids_to_fuse: set[int] | None = None,
141
+ target_size: tuple[int, int] | None = None,
142
+ ):
143
+ height = mask_probs.shape[1] if target_size is None else target_size[0]
144
+ width = mask_probs.shape[2] if target_size is None else target_size[1]
145
+
146
+ segmentation = torch.zeros((height, width), dtype=torch.int32, device=mask_probs.device)
147
+ segments: list[dict] = []
148
+
149
+ if target_size is not None:
150
+ mask_probs = nn.functional.interpolate(
151
+ mask_probs.unsqueeze(0), size=target_size, mode="bilinear", align_corners=False
152
+ )[0]
153
+
154
+ current_segment_id = 0
155
+
156
+ # Weigh each mask by its prediction score
157
+ mask_probs *= pred_scores.view(-1, 1, 1)
158
+ mask_labels = mask_probs.argmax(0) # [height, width]
159
+
160
+ # Keep track of instances of each class
161
+ stuff_memory_list: dict[str, int] = {}
162
+ for k in range(pred_labels.shape[0]):
163
+ pred_class = pred_labels[k].item()
164
+ should_fuse = pred_class in label_ids_to_fuse
165
+
166
+ # Check if mask exists and large enough to be a segment
167
+ mask_exists, mask_k = check_segment_validity(
168
+ mask_labels, mask_probs, k, mask_threshold, overlap_mask_area_threshold
169
+ )
170
+
171
+ if mask_exists:
172
+ if pred_class in stuff_memory_list:
173
+ current_segment_id = stuff_memory_list[pred_class]
174
+ else:
175
+ current_segment_id += 1
176
+
177
+ # Add current object segment to final segmentation map
178
+ segmentation[mask_k] = current_segment_id
179
+ segment_score = round(pred_scores[k].item(), 6)
180
+ segments.append(
181
+ {
182
+ "id": current_segment_id,
183
+ "label_id": pred_class,
184
+ "was_fused": should_fuse,
185
+ "score": segment_score,
186
+ }
187
+ )
188
+ if should_fuse:
189
+ stuff_memory_list[pred_class] = current_segment_id
190
+
191
+ return segmentation, segments
192
+
193
+
194
+ def convert_segmentation_map_to_binary_masks_fast(
195
+ segmentation_map: "torch.Tensor",
196
+ instance_id_to_semantic_id: dict[int, int] | None = None,
197
+ ignore_index: int | None = None,
198
+ do_reduce_labels: bool = False,
199
+ ):
200
+ if do_reduce_labels and ignore_index is None:
201
+ raise ValueError("If `do_reduce_labels` is True, `ignore_index` must be provided.")
202
+
203
+ if do_reduce_labels:
204
+ segmentation_map = torch.where(segmentation_map == 0, ignore_index, segmentation_map - 1)
205
+
206
+ all_labels = torch.unique(segmentation_map)
207
+
208
+ if ignore_index is not None:
209
+ all_labels = all_labels[all_labels != ignore_index] # drop background label if applicable
210
+
211
+ binary_masks = [(segmentation_map == i) for i in all_labels]
212
+ if binary_masks:
213
+ binary_masks = torch.stack(binary_masks, dim=0)
214
+ else:
215
+ binary_masks = torch.zeros((0, *segmentation_map.shape), device=segmentation_map.device)
216
+
217
+ # Convert instance ids to class ids
218
+ if instance_id_to_semantic_id is not None:
219
+ labels = torch.zeros(all_labels.shape[0], device=segmentation_map.device)
220
+
221
+ for i, label in enumerate(all_labels):
222
+ class_id = instance_id_to_semantic_id[(label.item() + 1 if do_reduce_labels else label.item())]
223
+ labels[i] = class_id - 1 if do_reduce_labels else class_id
224
+ else:
225
+ labels = all_labels
226
+ return binary_masks.float(), labels.long()
227
+
228
+
229
+ class MaskFormerImageProcessorKwargs(ImagesKwargs, total=False):
230
+ r"""
231
+ ignore_index (`int`, *optional*):
232
+ Label to be assigned to background pixels in segmentation maps. If provided, segmentation map pixels
233
+ denoted with 0 (background) will be replaced with `ignore_index`.
234
+ do_reduce_labels (`bool`, *optional*, defaults to `False`):
235
+ Whether or not to decrement all label values of segmentation maps by 1. Usually used for datasets where 0
236
+ is used for background, and background itself is not included in all classes of a dataset (e.g. ADE20k).
237
+ The background label will be replaced by `ignore_index`.
238
+ num_labels (`int`, *optional*):
239
+ The number of labels in the segmentation map.
240
+ size_divisor (`int`, *optional*, defaults to `32`):
241
+ Some backbones need images divisible by a certain number. If not passed, it defaults to the value used in
242
+ Swin Transformer.
243
+ pad_size (`SizeDict`, *optional*):
244
+ The size to pad the images to. Must be larger than any image size provided for preprocessing. If `pad_size`
245
+ is not provided, images will be padded to the largest height and width in the batch.
246
+ """
247
+
248
+ ignore_index: int | None
249
+ do_reduce_labels: bool
250
+ num_labels: int | None
251
+ size_divisor: int
252
+ pad_size: SizeDict | None
253
+
254
+
255
+ @auto_docstring
256
+ class MaskFormerImageProcessor(TorchvisionBackend):
257
+ valid_kwargs = MaskFormerImageProcessorKwargs
258
+ resample = PILImageResampling.BILINEAR
259
+ image_mean = IMAGENET_DEFAULT_MEAN
260
+ image_std = IMAGENET_DEFAULT_STD
261
+ size = {"shortest_edge": 800, "longest_edge": 1333}
262
+ default_to_square = False
263
+ do_resize = True
264
+ do_rescale = True
265
+ rescale_factor = 1 / 255
266
+ do_normalize = True
267
+ do_pad = True
268
+ model_input_names = ["pixel_values", "pixel_mask"]
269
+ size_divisor = 32
270
+ do_reduce_labels = False
271
+
272
+ def __init__(self, **kwargs: Unpack[MaskFormerImageProcessorKwargs]) -> None:
273
+ size = kwargs.pop("size", None)
274
+ max_size = kwargs.pop("max_size", None)
275
+
276
+ if size is None and max_size is not None:
277
+ size = self.size.copy()
278
+ size["longest_edge"] = max_size
279
+ elif size is None:
280
+ size = self.size
281
+
282
+ kwargs["size"] = get_size_dict(size, max_size=max_size, default_to_square=False)
283
+ super().__init__(**kwargs)
284
+
285
+ def to_dict(self) -> dict[str, Any]:
286
+ """
287
+ Serializes this instance to a Python dictionary. This method calls the superclass method and then removes the
288
+ `_max_size` attribute from the dictionary.
289
+ """
290
+ image_processor_dict = super().to_dict()
291
+ image_processor_dict.pop("_max_size", None)
292
+ return image_processor_dict
293
+
294
+ def reduce_label(self, labels: list["torch.Tensor"]):
295
+ for idx in range(len(labels)):
296
+ label = labels[idx]
297
+ label = torch.where(label == 0, torch.tensor(255, dtype=label.dtype), label)
298
+ label = label - 1
299
+ label = torch.where(label == 254, torch.tensor(255, dtype=label.dtype), label)
300
+ labels[idx] = label
301
+
302
+ def resize(
303
+ self,
304
+ image: torch.Tensor,
305
+ size: SizeDict,
306
+ size_divisor: int = 0,
307
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None" = None,
308
+ **kwargs,
309
+ ) -> torch.Tensor:
310
+ """
311
+ Resize the image to the given size. Size can be `min_size` (scalar) or `(height, width)` tuple. If size is an
312
+ int, smaller edge of the image will be matched to this number.
313
+
314
+ Args:
315
+ image (`torch.Tensor`):
316
+ Image to resize.
317
+ size (`SizeDict`):
318
+ Size of the image's `(height, width)` dimensions after resizing.
319
+ size_divisor (`int`, *optional*, defaults to 0):
320
+ If `size_divisor` is given, the output image size will be divisible by the number.
321
+ resample (`PILImageResampling | tvF.InterpolationMode | int | None`, *optional*):
322
+ Resampling filter to use if resizing the image.
323
+ """
324
+
325
+ if size.shortest_edge and size.longest_edge:
326
+ # Resize the image so that the shortest edge or the longest edge is of the given size
327
+ # while maintaining the aspect ratio of the original image.
328
+ new_size = get_size_with_aspect_ratio(
329
+ image.size()[-2:],
330
+ size.shortest_edge,
331
+ size.longest_edge,
332
+ )
333
+ elif size.max_height and size.max_width:
334
+ new_size = get_image_size_for_max_height_width(image.size()[-2:], size.max_height, size.max_width)
335
+ elif size.height and size.width:
336
+ new_size = (size.height, size.width)
337
+ else:
338
+ raise ValueError(
339
+ f"Size must contain 'height' and 'width' keys or 'shortest_edge' and 'longest_edge' keys. Got {size}."
340
+ )
341
+ if size_divisor > 0:
342
+ height, width = new_size
343
+ height = int(math.ceil(height / size_divisor) * size_divisor)
344
+ width = int(math.ceil(width / size_divisor) * size_divisor)
345
+ new_size = (height, width)
346
+
347
+ image = super().resize(
348
+ image, size=SizeDict(height=new_size[0], width=new_size[1]), resample=resample, **kwargs
349
+ )
350
+ return image
351
+
352
+ def pad(
353
+ self,
354
+ images: torch.Tensor,
355
+ padded_size: tuple[int, int],
356
+ segmentation_maps: torch.Tensor | None = None,
357
+ fill: int = 0,
358
+ ignore_index: int = 255,
359
+ ) -> tuple[torch.Tensor, torch.Tensor, list[torch.Tensor] | None]:
360
+ original_size = images.size()[-2:]
361
+ padding_bottom = padded_size[0] - original_size[0]
362
+ padding_right = padded_size[1] - original_size[1]
363
+ if padding_bottom < 0 or padding_right < 0:
364
+ raise ValueError(
365
+ f"Padding dimensions are negative. Please make sure that the padded size is larger than the "
366
+ f"original size. Got padded size: {padded_size}, original size: {original_size}."
367
+ )
368
+ if original_size != padded_size:
369
+ padding = [0, 0, padding_right, padding_bottom]
370
+ images = tvF.pad(images, padding, fill=fill)
371
+ if segmentation_maps is not None:
372
+ segmentation_maps = [tvF.pad(mask, padding, fill=ignore_index) for mask in segmentation_maps]
373
+
374
+ # Make a pixel mask for the image, where 1 indicates a valid pixel and 0 indicates padding.
375
+ pixel_mask = torch.zeros((images.shape[0], *padded_size), dtype=torch.int64, device=images.device)
376
+ pixel_mask[:, : original_size[0], : original_size[1]] = 1
377
+
378
+ return images, pixel_mask, segmentation_maps
379
+
380
+ @auto_docstring
381
+ def preprocess(
382
+ self,
383
+ images: ImageInput,
384
+ segmentation_maps: ImageInput | None = None,
385
+ instance_id_to_semantic_id: list[dict[int, int]] | dict[int, int] | None = None,
386
+ **kwargs: Unpack[MaskFormerImageProcessorKwargs],
387
+ ) -> BatchFeature:
388
+ r"""
389
+ segmentation_maps (`ImageInput`, *optional*):
390
+ The segmentation maps.
391
+ instance_id_to_semantic_id (`Union[list[dict[int, int]], dict[int, int]]`, *optional*):
392
+ A mapping from instance IDs to semantic IDs.
393
+ """
394
+ return super().preprocess(images, segmentation_maps, instance_id_to_semantic_id, **kwargs)
395
+
396
+ def _preprocess_image_like_inputs(
397
+ self,
398
+ images: ImageInput,
399
+ segmentation_maps: ImageInput,
400
+ instance_id_to_semantic_id: list[dict[int, int]] | dict[int, int] | None,
401
+ do_convert_rgb: bool,
402
+ input_data_format: ChannelDimension,
403
+ device: Union[str, "torch.device"] | None = None,
404
+ **kwargs: Unpack[MaskFormerImageProcessorKwargs],
405
+ ) -> BatchFeature:
406
+ """
407
+ Preprocess image-like inputs.
408
+ To be overridden by subclasses when image-like inputs other than images should be processed.
409
+ It can be used for segmentation maps, depth maps, etc.
410
+ """
411
+ # Prepare input images
412
+ images = self._prepare_image_like_inputs(
413
+ images=images, do_convert_rgb=do_convert_rgb, input_data_format=input_data_format, device=device
414
+ )
415
+ if segmentation_maps is not None:
416
+ segmentation_maps = self._prepare_image_like_inputs(
417
+ images=segmentation_maps,
418
+ expected_ndims=2,
419
+ do_convert_rgb=False,
420
+ input_data_format=ChannelDimension.FIRST,
421
+ )
422
+ return self._preprocess(images, segmentation_maps, instance_id_to_semantic_id, **kwargs)
423
+
424
+ def _preprocess(
425
+ self,
426
+ images: list["torch.Tensor"],
427
+ segmentation_maps: Optional["torch.Tensor"],
428
+ instance_id_to_semantic_id: dict[int, int] | None,
429
+ do_resize: bool | None,
430
+ size: SizeDict | None,
431
+ pad_size: SizeDict | None,
432
+ size_divisor: int | None,
433
+ resample: Union["PILImageResampling", "tvF.InterpolationMode"] | None,
434
+ do_rescale: bool | None,
435
+ rescale_factor: float | None,
436
+ do_normalize: bool | None,
437
+ image_mean: float | list[float] | None,
438
+ image_std: float | list[float] | None,
439
+ ignore_index: int | None,
440
+ do_reduce_labels: bool | None,
441
+ disable_grouping: bool | None,
442
+ return_tensors: str | TensorType | None,
443
+ **kwargs,
444
+ ) -> BatchFeature:
445
+ from ...image_utils import get_max_height_width
446
+
447
+ if segmentation_maps is not None and len(images) != len(segmentation_maps):
448
+ raise ValueError("Images and segmentation maps must have the same length.")
449
+
450
+ # Group images by size for batched resizing
451
+ grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
452
+ resized_images_grouped = {}
453
+ if segmentation_maps is not None:
454
+ grouped_segmentation_maps, grouped_segmentation_maps_index = group_images_by_shape(
455
+ segmentation_maps, disable_grouping=disable_grouping
456
+ )
457
+ resized_segmentation_maps_grouped = {}
458
+ for shape, stacked_images in grouped_images.items():
459
+ if do_resize:
460
+ stacked_images = self.resize(
461
+ image=stacked_images, size=size, size_divisor=size_divisor, resample=resample
462
+ )
463
+ if segmentation_maps is not None:
464
+ stacked_segmentation_maps = grouped_segmentation_maps[shape]
465
+ if do_resize:
466
+ stacked_segmentation_maps = self.resize(
467
+ image=stacked_segmentation_maps,
468
+ size=size,
469
+ size_divisor=size_divisor,
470
+ resample=tvF.InterpolationMode.NEAREST_EXACT,
471
+ )
472
+ resized_images_grouped[shape] = stacked_images
473
+ if segmentation_maps is not None:
474
+ resized_segmentation_maps_grouped[shape] = stacked_segmentation_maps
475
+ resized_images = reorder_images(resized_images_grouped, grouped_images_index)
476
+ if segmentation_maps is not None:
477
+ resized_segmentation_maps = reorder_images(
478
+ resized_segmentation_maps_grouped, grouped_segmentation_maps_index
479
+ )
480
+ if pad_size is not None:
481
+ padded_size = (pad_size.height, pad_size.width)
482
+ else:
483
+ padded_size = get_max_height_width(resized_images)
484
+
485
+ if segmentation_maps is not None:
486
+ mask_labels = []
487
+ class_labels = []
488
+ # Convert to list of binary masks and labels
489
+ for idx, segmentation_map in enumerate(resized_segmentation_maps):
490
+ if isinstance(instance_id_to_semantic_id, list):
491
+ instance_id = instance_id_to_semantic_id[idx]
492
+ else:
493
+ instance_id = instance_id_to_semantic_id
494
+ # Use instance2class_id mapping per image
495
+ masks, classes = convert_segmentation_map_to_binary_masks_fast(
496
+ segmentation_map.squeeze(0),
497
+ instance_id,
498
+ ignore_index=ignore_index,
499
+ do_reduce_labels=do_reduce_labels,
500
+ )
501
+ mask_labels.append(masks)
502
+ class_labels.append(classes)
503
+
504
+ if segmentation_maps is not None:
505
+ # group mask_labels as paired inputs and not images so as not to stack them
506
+ grouped_images, grouped_segmentation_maps, grouped_images_index = group_images_by_shape(
507
+ resized_images, mask_labels, disable_grouping=disable_grouping
508
+ )
509
+ processed_segmentation_maps_grouped = {}
510
+ else:
511
+ grouped_images, grouped_images_index = group_images_by_shape(
512
+ resized_images, disable_grouping=disable_grouping
513
+ )
514
+ processed_images_grouped = {}
515
+ processed_pixel_masks_grouped = {}
516
+ for shape, stacked_images in grouped_images.items():
517
+ # Fused rescale and normalize
518
+ stacked_images = self.rescale_and_normalize(
519
+ stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std
520
+ )
521
+ padded_images, pixel_masks, padded_segmentation_maps = self.pad(
522
+ images=stacked_images,
523
+ segmentation_maps=grouped_segmentation_maps[shape] if segmentation_maps is not None else None,
524
+ padded_size=padded_size,
525
+ ignore_index=ignore_index,
526
+ )
527
+ processed_images_grouped[shape] = padded_images
528
+ processed_pixel_masks_grouped[shape] = pixel_masks
529
+ if segmentation_maps is not None:
530
+ processed_segmentation_maps_grouped[shape] = padded_segmentation_maps
531
+
532
+ processed_images = reorder_images(processed_images_grouped, grouped_images_index)
533
+ processed_pixel_masks = reorder_images(processed_pixel_masks_grouped, grouped_images_index)
534
+ encoded_inputs = BatchFeature(
535
+ data={"pixel_values": processed_images, "pixel_mask": processed_pixel_masks},
536
+ tensor_type=return_tensors,
537
+ )
538
+ if segmentation_maps is not None:
539
+ mask_labels = reorder_images(processed_segmentation_maps_grouped, grouped_images_index)
540
+ # we cannot batch them since they don't share a common class size
541
+ encoded_inputs["mask_labels"] = mask_labels
542
+ encoded_inputs["class_labels"] = class_labels
543
+
544
+ return encoded_inputs
545
+
546
+ # Copied from transformers.models.maskformer.image_processing_maskformer.MaskFormerImageProcessor.post_process_semantic_segmentation
547
+ def post_process_semantic_segmentation(
548
+ self, outputs, target_sizes: list[tuple[int, int]] | None = None
549
+ ) -> "torch.Tensor":
550
+ """
551
+ Converts the output of [`MaskFormerForInstanceSegmentation`] into semantic segmentation maps. Only supports
552
+ PyTorch.
553
+
554
+ Args:
555
+ outputs ([`MaskFormerForInstanceSegmentation`]):
556
+ Raw outputs of the model.
557
+ target_sizes (`list[tuple[int, int]]`, *optional*):
558
+ List of length (batch_size), where each list item (`tuple[int, int]]`) corresponds to the requested
559
+ final size (height, width) of each prediction. If left to None, predictions will not be resized.
560
+ Returns:
561
+ `list[torch.Tensor]`:
562
+ A list of length `batch_size`, where each item is a semantic segmentation map of shape (height, width)
563
+ corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each
564
+ `torch.Tensor` correspond to a semantic class id.
565
+ """
566
+ class_queries_logits = outputs.class_queries_logits # [batch_size, num_queries, num_classes+1]
567
+ masks_queries_logits = outputs.masks_queries_logits # [batch_size, num_queries, height, width]
568
+
569
+ # Remove the null class `[..., :-1]`
570
+ masks_classes = class_queries_logits.softmax(dim=-1)[..., :-1]
571
+ masks_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
572
+
573
+ # Semantic segmentation logits of shape (batch_size, num_classes, height, width)
574
+ segmentation = torch.einsum("bqc, bqhw -> bchw", masks_classes, masks_probs)
575
+ batch_size = class_queries_logits.shape[0]
576
+
577
+ # Resize logits and compute semantic segmentation maps
578
+ if target_sizes is not None:
579
+ if batch_size != len(target_sizes):
580
+ raise ValueError(
581
+ "Make sure that you pass in as many target sizes as the batch dimension of the logits"
582
+ )
583
+
584
+ semantic_segmentation = []
585
+ for idx in range(batch_size):
586
+ resized_logits = torch.nn.functional.interpolate(
587
+ segmentation[idx].unsqueeze(dim=0), size=target_sizes[idx], mode="bilinear", align_corners=False
588
+ )
589
+ semantic_map = resized_logits[0].argmax(dim=0)
590
+ semantic_segmentation.append(semantic_map)
591
+ else:
592
+ semantic_segmentation = segmentation.argmax(dim=1)
593
+ semantic_segmentation = [semantic_segmentation[i] for i in range(semantic_segmentation.shape[0])]
594
+
595
+ return semantic_segmentation
596
+
597
+ # Copied from transformers.models.maskformer.image_processing_maskformer.MaskFormerImageProcessor.post_process_instance_segmentation
598
+ def post_process_instance_segmentation(
599
+ self,
600
+ outputs,
601
+ threshold: float = 0.5,
602
+ mask_threshold: float = 0.5,
603
+ overlap_mask_area_threshold: float = 0.8,
604
+ target_sizes: list[tuple[int, int]] | None = None,
605
+ return_coco_annotation: bool | None = False,
606
+ return_binary_maps: bool | None = False,
607
+ ) -> list[dict]:
608
+ """
609
+ Converts the output of [`MaskFormerForInstanceSegmentationOutput`] into instance segmentation predictions. Only
610
+ supports PyTorch. If instances could overlap, set either return_coco_annotation or return_binary_maps
611
+ to `True` to get the correct segmentation result.
612
+
613
+ Args:
614
+ outputs ([`MaskFormerForInstanceSegmentation`]):
615
+ Raw outputs of the model.
616
+ threshold (`float`, *optional*, defaults to 0.5):
617
+ The probability score threshold to keep predicted instance masks.
618
+ mask_threshold (`float`, *optional*, defaults to 0.5):
619
+ Threshold to use when turning the predicted masks into binary values.
620
+ overlap_mask_area_threshold (`float`, *optional*, defaults to 0.8):
621
+ The overlap mask area threshold to merge or discard small disconnected parts within each binary
622
+ instance mask.
623
+ target_sizes (`list[Tuple]`, *optional*):
624
+ List of length (batch_size), where each list item (`tuple[int, int]]`) corresponds to the requested
625
+ final size (height, width) of each prediction. If left to None, predictions will not be resized.
626
+ return_coco_annotation (`bool`, *optional*, defaults to `False`):
627
+ If set to `True`, segmentation maps are returned in COCO run-length encoding (RLE) format.
628
+ return_binary_maps (`bool`, *optional*, defaults to `False`):
629
+ If set to `True`, segmentation maps are returned as a concatenated tensor of binary segmentation maps
630
+ (one per detected instance).
631
+ Returns:
632
+ `list[Dict]`: A list of dictionaries, one per image, each dictionary containing two keys:
633
+ - **segmentation** -- A tensor of shape `(height, width)` where each pixel represents a `segment_id`, or
634
+ `list[List]` run-length encoding (RLE) of the segmentation map if return_coco_annotation is set to
635
+ `True`, or a tensor of shape `(num_instances, height, width)` if return_binary_maps is set to `True`.
636
+ Set to `None` if no mask if found above `threshold`.
637
+ - **segments_info** -- A dictionary that contains additional information on each segment.
638
+ - **id** -- An integer representing the `segment_id`.
639
+ - **label_id** -- An integer representing the label / semantic class id corresponding to `segment_id`.
640
+ - **score** -- Prediction score of segment with `segment_id`.
641
+ """
642
+ if return_coco_annotation and return_binary_maps:
643
+ raise ValueError("return_coco_annotation and return_binary_maps can not be both set to True.")
644
+
645
+ # [batch_size, num_queries, num_classes+1]
646
+ class_queries_logits = outputs.class_queries_logits
647
+ # [batch_size, num_queries, height, width]
648
+ masks_queries_logits = outputs.masks_queries_logits
649
+
650
+ device = masks_queries_logits.device
651
+ num_classes = class_queries_logits.shape[-1] - 1
652
+ num_queries = class_queries_logits.shape[-2]
653
+
654
+ # Loop over items in batch size
655
+ results: list[dict[str, TensorType]] = []
656
+
657
+ for i in range(class_queries_logits.shape[0]):
658
+ mask_pred = masks_queries_logits[i]
659
+ mask_cls = class_queries_logits[i]
660
+
661
+ scores = torch.nn.functional.softmax(mask_cls, dim=-1)[:, :-1]
662
+ labels = torch.arange(num_classes, device=device).unsqueeze(0).repeat(num_queries, 1).flatten(0, 1)
663
+
664
+ scores_per_image, topk_indices = scores.flatten(0, 1).topk(num_queries, sorted=False)
665
+ labels_per_image = labels[topk_indices]
666
+
667
+ topk_indices = torch.div(topk_indices, num_classes, rounding_mode="floor")
668
+ mask_pred = mask_pred[topk_indices]
669
+ pred_masks = (mask_pred > 0).float()
670
+
671
+ # Calculate average mask prob
672
+ mask_scores_per_image = (mask_pred.sigmoid().flatten(1) * pred_masks.flatten(1)).sum(1) / (
673
+ pred_masks.flatten(1).sum(1) + 1e-6
674
+ )
675
+ pred_scores = scores_per_image * mask_scores_per_image
676
+ pred_classes = labels_per_image
677
+
678
+ segmentation = torch.zeros(masks_queries_logits.shape[2:]) - 1
679
+ if target_sizes is not None:
680
+ segmentation = torch.zeros(target_sizes[i]) - 1
681
+ pred_masks = torch.nn.functional.interpolate(
682
+ pred_masks.unsqueeze(0), size=target_sizes[i], mode="nearest"
683
+ )[0]
684
+
685
+ instance_maps, segments = [], []
686
+ current_segment_id = 0
687
+ for j in range(num_queries):
688
+ score = pred_scores[j].item()
689
+
690
+ if not torch.all(pred_masks[j] == 0) and score >= threshold:
691
+ segmentation[pred_masks[j] == 1] = current_segment_id
692
+ segments.append(
693
+ {
694
+ "id": current_segment_id,
695
+ "label_id": pred_classes[j].item(),
696
+ "was_fused": False,
697
+ "score": round(score, 6),
698
+ }
699
+ )
700
+ current_segment_id += 1
701
+ instance_maps.append(pred_masks[j])
702
+
703
+ # Return segmentation map in run-length encoding (RLE) format
704
+ if return_coco_annotation:
705
+ segmentation = convert_segmentation_to_rle(segmentation)
706
+
707
+ # Return a concatenated tensor of binary instance maps
708
+ if return_binary_maps and len(instance_maps) != 0:
709
+ segmentation = torch.stack(instance_maps, dim=0)
710
+
711
+ results.append({"segmentation": segmentation, "segments_info": segments})
712
+ return results
713
+
714
+ # Copied from transformers.models.maskformer.image_processing_maskformer.MaskFormerImageProcessor.post_process_panoptic_segmentation
715
+ def post_process_panoptic_segmentation(
716
+ self,
717
+ outputs,
718
+ threshold: float = 0.5,
719
+ mask_threshold: float = 0.5,
720
+ overlap_mask_area_threshold: float = 0.8,
721
+ label_ids_to_fuse: set[int] | None = None,
722
+ target_sizes: list[tuple[int, int]] | None = None,
723
+ ) -> list[dict]:
724
+ """
725
+ Converts the output of [`MaskFormerForInstanceSegmentationOutput`] into image panoptic segmentation
726
+ predictions. Only supports PyTorch.
727
+
728
+ Args:
729
+ outputs ([`MaskFormerForInstanceSegmentationOutput`]):
730
+ The outputs from [`MaskFormerForInstanceSegmentation`].
731
+ threshold (`float`, *optional*, defaults to 0.5):
732
+ The probability score threshold to keep predicted instance masks.
733
+ mask_threshold (`float`, *optional*, defaults to 0.5):
734
+ Threshold to use when turning the predicted masks into binary values.
735
+ overlap_mask_area_threshold (`float`, *optional*, defaults to 0.8):
736
+ The overlap mask area threshold to merge or discard small disconnected parts within each binary
737
+ instance mask.
738
+ label_ids_to_fuse (`Set[int]`, *optional*):
739
+ The labels in this state will have all their instances be fused together. For instance we could say
740
+ there can only be one sky in an image, but several persons, so the label ID for sky would be in that
741
+ set, but not the one for person.
742
+ target_sizes (`list[Tuple]`, *optional*):
743
+ List of length (batch_size), where each list item (`tuple[int, int]]`) corresponds to the requested
744
+ final size (height, width) of each prediction in batch. If left to None, predictions will not be
745
+ resized.
746
+
747
+ Returns:
748
+ `list[Dict]`: A list of dictionaries, one per image, each dictionary containing two keys:
749
+ - **segmentation** -- a tensor of shape `(height, width)` where each pixel represents a `segment_id`, set
750
+ to `None` if no mask if found above `threshold`. If `target_sizes` is specified, segmentation is resized
751
+ to the corresponding `target_sizes` entry.
752
+ - **segments_info** -- A dictionary that contains additional information on each segment.
753
+ - **id** -- an integer representing the `segment_id`.
754
+ - **label_id** -- An integer representing the label / semantic class id corresponding to `segment_id`.
755
+ - **was_fused** -- a boolean, `True` if `label_id` was in `label_ids_to_fuse`, `False` otherwise.
756
+ Multiple instances of the same class / label were fused and assigned a single `segment_id`.
757
+ - **score** -- Prediction score of segment with `segment_id`.
758
+ """
759
+
760
+ if label_ids_to_fuse is None:
761
+ logger.warning("`label_ids_to_fuse` unset. No instance will be fused.")
762
+ label_ids_to_fuse = set()
763
+
764
+ class_queries_logits = outputs.class_queries_logits # [batch_size, num_queries, num_classes+1]
765
+ masks_queries_logits = outputs.masks_queries_logits # [batch_size, num_queries, height, width]
766
+
767
+ batch_size = class_queries_logits.shape[0]
768
+ num_labels = class_queries_logits.shape[-1] - 1
769
+
770
+ mask_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width]
771
+
772
+ # Predicted label and score of each query (batch_size, num_queries)
773
+ pred_scores, pred_labels = nn.functional.softmax(class_queries_logits, dim=-1).max(-1)
774
+
775
+ # Loop over items in batch size
776
+ results: list[dict[str, TensorType]] = []
777
+
778
+ for i in range(batch_size):
779
+ mask_probs_item, pred_scores_item, pred_labels_item = remove_low_and_no_objects(
780
+ mask_probs[i], pred_scores[i], pred_labels[i], threshold, num_labels
781
+ )
782
+
783
+ # No mask found
784
+ if mask_probs_item.shape[0] <= 0:
785
+ height, width = target_sizes[i] if target_sizes is not None else mask_probs_item.shape[1:]
786
+ segmentation = torch.zeros((height, width)) - 1
787
+ results.append({"segmentation": segmentation, "segments_info": []})
788
+ continue
789
+
790
+ # Get segmentation map and segment information of batch item
791
+ target_size = target_sizes[i] if target_sizes is not None else None
792
+ segmentation, segments = compute_segments(
793
+ mask_probs=mask_probs_item,
794
+ pred_scores=pred_scores_item,
795
+ pred_labels=pred_labels_item,
796
+ mask_threshold=mask_threshold,
797
+ overlap_mask_area_threshold=overlap_mask_area_threshold,
798
+ label_ids_to_fuse=label_ids_to_fuse,
799
+ target_size=target_size,
800
+ )
801
+
802
+ results.append({"segmentation": segmentation, "segments_info": segments})
803
+ return results
804
+
805
+
806
+ __all__ = ["MaskFormerImageProcessor"]