
'''simple docstring'''
import argparse
import re

import torch
from CLAP import create_model

from transformers import AutoFeatureExtractor, ClapConfig, ClapModel


lowercase__						       =      {
    "text_branch": "text_model",
    "audio_branch": "audio_model.audio_encoder",
    "attn": "attention.self",
    "self.proj": "output.dense",
    "attention.self_mask": "attn_mask",
    "mlp.fc1": "intermediate.dense",
    "mlp.fc2": "output.dense",
    "norm1": "layernorm_before",
    "norm2": "layernorm_after",
    "bn0": "batch_norm",
}

lowercase__						       =      AutoFeatureExtractor.from_pretrained("laion/clap-htsat-unfused", truncation="rand_trunc")




def    _UpperCamelCase						(       SCREAMING_SNAKE_CASE__ ,       SCREAMING_SNAKE_CASE__=False			)  ->							Optional[Any]:


		'''simple docstring'''


		snake_case			,snake_case  :       Union[str, Any]     			=						create_model(
		    '''HTSAT-tiny''' ,       '''roberta''' ,       SCREAMING_SNAKE_CASE__ ,       precision='''fp32''' ,       device='''cuda:0''' if torch.cuda.is_available() else '''cpu''' ,       enable_fusion=SCREAMING_SNAKE_CASE__ ,       fusion_type='''aff_2d''' if enable_fusion else None ,       )
		return model, model_cfg




def    _UpperCamelCase						(       SCREAMING_SNAKE_CASE__			)  ->							List[str]:


		'''simple docstring'''


		snake_case  :       Tuple     			=						{}

		snake_case  :       Optional[int]     			=						R'''.*sequential.(\d+).*'''
		snake_case  :       Tuple     			=						R'''.*_projection.(\d+).*'''

		for key, value in state_dict.items():
				# check if any key needs to be modified
				for key_to_modify, new_key in KEYS_TO_MODIFY_MAPPING.items():
						if key_to_modify in key:
								snake_case  :       Optional[Any]     			=						key.replace(SCREAMING_SNAKE_CASE__ ,       SCREAMING_SNAKE_CASE__			)

				if re.match(SCREAMING_SNAKE_CASE__ ,       SCREAMING_SNAKE_CASE__			):
						# replace sequential layers with list
						snake_case  :       str     			=						re.match(SCREAMING_SNAKE_CASE__ ,       SCREAMING_SNAKE_CASE__			).group(1			)

						snake_case  :       List[Any]     			=						key.replace(F'sequential.{sequential_layer}.' ,       F'layers.{int(SCREAMING_SNAKE_CASE__			)//3}.linear.'			)
				elif re.match(SCREAMING_SNAKE_CASE__ ,       SCREAMING_SNAKE_CASE__			):
						snake_case  :       int     			=						int(re.match(SCREAMING_SNAKE_CASE__ ,       SCREAMING_SNAKE_CASE__			).group(1			)			)

						# Because in CLAP they use `nn.Sequential`...
						snake_case  :       Union[str, Any]     			=						1 if projecton_layer == 0 else 2

						snake_case  :       Dict     			=						key.replace(F'_projection.{projecton_layer}.' ,       F'_projection.linear{transformers_projection_layer}.'			)

				if "audio" and "qkv" in key:
						# split qkv into query key and value
						snake_case  :       str     			=						value
						snake_case  :       List[str]     			=						mixed_qkv.size(0			) // 3

						snake_case  :       Tuple     			=						mixed_qkv[:qkv_dim]
						snake_case  :       Optional[int]     			=						mixed_qkv[qkv_dim : qkv_dim * 2]
						snake_case  :       Union[str, Any]     			=						mixed_qkv[qkv_dim * 2 :]

						snake_case  :       int     			=						query_layer
						snake_case  :       Optional[Any]     			=						key_layer
						snake_case  :       Optional[int]     			=						value_layer
				else:
						snake_case  :       int     			=						value

		return model_state_dict




def    _UpperCamelCase						(       SCREAMING_SNAKE_CASE__ ,       SCREAMING_SNAKE_CASE__ ,       SCREAMING_SNAKE_CASE__ ,       SCREAMING_SNAKE_CASE__=False			)  ->							Optional[Any]:


		'''simple docstring'''


		snake_case			,snake_case  :       Union[str, Any]     			=						init_clap(SCREAMING_SNAKE_CASE__ ,       enable_fusion=SCREAMING_SNAKE_CASE__			)

		clap_model.eval()
		snake_case  :       List[str]     			=						clap_model.state_dict()
		snake_case  :       List[str]     			=						rename_state_dict(SCREAMING_SNAKE_CASE__			)

		snake_case  :       Any     			=						ClapConfig()
		snake_case  :       str     			=						enable_fusion
		snake_case  :       Optional[Any]     			=						ClapModel(SCREAMING_SNAKE_CASE__			)

		# ignore the spectrogram embedding layer
		model.load_state_dict(SCREAMING_SNAKE_CASE__ ,       strict=SCREAMING_SNAKE_CASE__			)

		model.save_pretrained(SCREAMING_SNAKE_CASE__			)
		transformers_config.save_pretrained(SCREAMING_SNAKE_CASE__			)


if __name__ == "__main__":
						lowercase__						       =      argparse.ArgumentParser()
						parser.add_argument("--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.")
						parser.add_argument("--checkpoint_path", default=None, type=str, help="Path to fairseq checkpoint")
						parser.add_argument("--config_path", default=None, type=str, help="Path to hf config.json of model to convert")
						parser.add_argument("--enable_fusion", action="store_true", help="Whether to enable fusion or not")
						lowercase__						       =      parser.parse_args()

						convert_clap_checkpoint(args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path, args.enable_fusion)




'''simple docstring'''
from collections import OrderedDict
from typing import Any, Mapping, Optional

from ... import PreTrainedTokenizer
from ...configuration_utils import PretrainedConfig
from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeqaSeqConfigWithPast
from ...onnx.utils import compute_effective_axis_dimension
from ...utils import TensorType, is_torch_available, logging


lowercase__						       =      logging.get_logger(__name__)

lowercase__						       =      {
    "Helsinki-NLP/opus-mt-en-de": "https://huggingface.co/Helsinki-NLP/opus-mt-en-de/resolve/main/config.json",
    # See all Marian models at https://huggingface.co/models?filter=marian
}






class 	snake_case__       (      __SCREAMING_SNAKE_CASE					):







		"""simple docstring"""

		lowerCamelCase     							=						"""marian"""
		lowerCamelCase     							=						["""past_key_values"""]
		lowerCamelCase     							=						{"""num_attention_heads""": """encoder_attention_heads""", """hidden_size""": """d_model"""}



		def __init__(      self				:			Any  ,	UpperCamelCase__				:			Dict=5_8101  ,	UpperCamelCase__				:			int=None  ,	UpperCamelCase__				:			Union[str, Any]=1024  ,	UpperCamelCase__				:			List[Any]=12  ,	UpperCamelCase__				:			str=4096  ,	UpperCamelCase__				:			Optional[Any]=16  ,	UpperCamelCase__				:			str=12  ,	UpperCamelCase__				:			Tuple=4096  ,	UpperCamelCase__				:			Any=16  ,	UpperCamelCase__				:			Tuple=0.0  ,	UpperCamelCase__				:			Dict=0.0  ,	UpperCamelCase__				:			Dict=True  ,	UpperCamelCase__				:			Any=True  ,	UpperCamelCase__				:			List[Any]="gelu"  ,	UpperCamelCase__				:			Tuple=1024  ,	UpperCamelCase__				:			Optional[Any]=0.1  ,	UpperCamelCase__				:			str=0.0  ,	UpperCamelCase__				:			Optional[int]=0.0  ,	UpperCamelCase__				:			Optional[Any]=0.02  ,	UpperCamelCase__				:			Tuple=5_8100  ,	UpperCamelCase__				:			Union[str, Any]=False  ,	UpperCamelCase__				:			str=5_8100  ,	UpperCamelCase__				:			List[str]=0  ,	UpperCamelCase__				:			int=0  ,	UpperCamelCase__				:			Dict=True  ,	**UpperCamelCase__				:			int  ,	)						->			int:






				"""simple docstring"""







				snake_case  :       List[Any]     			=						vocab_size
				snake_case  :       Optional[int]     			=						decoder_vocab_size or vocab_size
				snake_case  :       int     			=						max_position_embeddings
				snake_case  :       Tuple     			=						d_model
				snake_case  :       int     			=						encoder_ffn_dim
				snake_case  :       Optional[int]     			=						encoder_layers
				snake_case  :       Union[str, Any]     			=						encoder_attention_heads
				snake_case  :       List[str]     			=						decoder_ffn_dim
				snake_case  :       List[str]     			=						decoder_layers
				snake_case  :       List[str]     			=						decoder_attention_heads
				snake_case  :       Any     			=						dropout
				snake_case  :       Optional[Any]     			=						attention_dropout
				snake_case  :       Tuple     			=						activation_dropout
				snake_case  :       Union[str, Any]     			=						activation_function
				snake_case  :       int     			=						init_std
				snake_case  :       Dict     			=						encoder_layerdrop
				snake_case  :       Dict     			=						decoder_layerdrop
				snake_case  :       List[Any]     			=						use_cache
				snake_case  :       int     			=						encoder_layers
				snake_case  :       List[str]     			=						scale_embedding  # scale factor will be sqrt(d_model) if True
				snake_case  :       str     			=						share_encoder_decoder_embeddings
				super().__init__(
				    pad_token_id=UpperCamelCase__  ,	eos_token_id=UpperCamelCase__  ,	is_encoder_decoder=UpperCamelCase__  ,	decoder_start_token_id=UpperCamelCase__  ,	forced_eos_token_id=UpperCamelCase__  ,	**UpperCamelCase__  ,	)







class 	snake_case__       (      __SCREAMING_SNAKE_CASE					):







		"""simple docstring"""

		@property
		# Copied from transformers.models.bart.configuration_bart.BartOnnxConfig.inputs
		def       lowerCAmelCase				(      self				:			Optional[int]      )						->			Mapping[str, Mapping[int, str]]:






				"""simple docstring"""







				if self.task in ["default", "seq2seq-lm"]:
						snake_case  :       Any     			=						OrderedDict(
						    [
						        ('''input_ids''', {0: '''batch''', 1: '''encoder_sequence'''}),
						        ('''attention_mask''', {0: '''batch''', 1: '''encoder_sequence'''}),
						    ]      )

						if self.use_past:
								snake_case  :       List[Any]     			=						{0: '''batch'''}
								snake_case  :       Optional[Any]     			=						{0: '''batch''', 1: '''past_decoder_sequence + sequence'''}
						else:
								snake_case  :       List[Any]     			=						{0: '''batch''', 1: '''decoder_sequence'''}
								snake_case  :       Any     			=						{0: '''batch''', 1: '''decoder_sequence'''}

						if self.use_past:
								self.fill_with_past_key_values_(UpperCamelCase__  ,	direction='''inputs'''      )
				elif self.task == "causal-lm":
						# TODO: figure this case out.
						snake_case  :       Any     			=						OrderedDict(
						    [
						        ('''input_ids''', {0: '''batch''', 1: '''encoder_sequence'''}),
						        ('''attention_mask''', {0: '''batch''', 1: '''encoder_sequence'''}),
						    ]      )
						if self.use_past:
								snake_case			,snake_case  :       Union[str, Any]     			=						self.num_layers
								for i in range(UpperCamelCase__      ):
										snake_case  :       Optional[Any]     			=						{0: '''batch''', 2: '''past_sequence + sequence'''}
										snake_case  :       List[str]     			=						{0: '''batch''', 2: '''past_sequence + sequence'''}
				else:
						snake_case  :       Dict     			=						OrderedDict(
						    [
						        ('''input_ids''', {0: '''batch''', 1: '''encoder_sequence'''}),
						        ('''attention_mask''', {0: '''batch''', 1: '''encoder_sequence'''}),
						        ('''decoder_input_ids''', {0: '''batch''', 1: '''decoder_sequence'''}),
						        ('''decoder_attention_mask''', {0: '''batch''', 1: '''decoder_sequence'''}),
						    ]      )

				return common_inputs



		@property
		# Copied from transformers.models.bart.configuration_bart.BartOnnxConfig.outputs
		def       lowerCAmelCase				(      self				:			Any      )						->			Mapping[str, Mapping[int, str]]:






				"""simple docstring"""







				if self.task in ["default", "seq2seq-lm"]:
						snake_case  :       Any     			=						super().outputs
				else:
						snake_case  :       int     			=						super(UpperCamelCase__  ,	self      ).outputs
						if self.use_past:
								snake_case			,snake_case  :       Optional[Any]     			=						self.num_layers
								for i in range(UpperCamelCase__      ):
										snake_case  :       Optional[Any]     			=						{0: '''batch''', 2: '''past_sequence + sequence'''}
										snake_case  :       Optional[Any]     			=						{0: '''batch''', 2: '''past_sequence + sequence'''}
				return common_outputs



		def       lowerCAmelCase				(      self				:			Union[str, Any]  ,	UpperCamelCase__				:			PreTrainedTokenizer  ,	UpperCamelCase__				:			int = -1  ,	UpperCamelCase__				:			int = -1  ,	UpperCamelCase__				:			bool = False  ,	UpperCamelCase__				:			Optional[TensorType] = None  ,	)						->			Mapping[str, Any]:






				"""simple docstring"""







				snake_case  :       Optional[Any]     			=						self._generate_dummy_inputs_for_encoder_and_decoder(
				    UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__      )

				# Generate decoder inputs
				snake_case  :       Optional[int]     			=						seq_length if not self.use_past else 1
				snake_case  :       Optional[int]     			=						self._generate_dummy_inputs_for_encoder_and_decoder(
				    UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__      )
				snake_case  :       Dict     			=						{f'decoder_{name}': tensor for name, tensor in decoder_inputs.items()}
				snake_case  :       Any     			=						dict(**UpperCamelCase__  ,	**UpperCamelCase__      )

				if self.use_past:
						if not is_torch_available():
								raise ValueError('''Cannot generate dummy past_keys inputs without PyTorch installed.'''      )
						else:
								import torch
						snake_case			,snake_case  :       Dict     			=						common_inputs['''input_ids'''].shape
						snake_case  :       Any     			=						common_inputs['''decoder_input_ids'''].shape[1]
						snake_case			,snake_case  :       Tuple     			=						self.num_attention_heads
						snake_case  :       str     			=						(
						    batch,
						    num_encoder_attention_heads,
						    encoder_seq_length,
						    self._config.hidden_size // num_encoder_attention_heads,
						)
						snake_case  :       Union[str, Any]     			=						decoder_seq_length + 3
						snake_case  :       Union[str, Any]     			=						(
						    batch,
						    num_decoder_attention_heads,
						    decoder_past_length,
						    self._config.hidden_size // num_decoder_attention_heads,
						)

						snake_case  :       Optional[int]     			=						torch.cat(
						    [common_inputs['''decoder_attention_mask'''], torch.ones(UpperCamelCase__  ,	UpperCamelCase__      )]  ,	dim=1      )

						snake_case  :       Dict     			=						[]
						# If the number of encoder and decoder layers are present in the model configuration, both are considered
						snake_case			,snake_case  :       str     			=						self.num_layers
						snake_case  :       Union[str, Any]     			=						min(UpperCamelCase__  ,	UpperCamelCase__      )
						snake_case  :       Union[str, Any]     			=						max(UpperCamelCase__  ,	UpperCamelCase__      ) - min_num_layers
						snake_case  :       str     			=						'''encoder''' if num_encoder_layers > num_decoder_layers else '''decoder'''

						for _ in range(UpperCamelCase__      ):
								common_inputs["past_key_values"].append(
								    (
								        torch.zeros(UpperCamelCase__      ),
								        torch.zeros(UpperCamelCase__      ),
								        torch.zeros(UpperCamelCase__      ),
								        torch.zeros(UpperCamelCase__      ),
								    )      )
						# TODO: test this.
						snake_case  :       Optional[int]     			=						encoder_shape if remaining_side_name == '''encoder''' else decoder_shape
						for _ in range(UpperCamelCase__  ,	UpperCamelCase__      ):
								common_inputs["past_key_values"].append((torch.zeros(UpperCamelCase__      ), torch.zeros(UpperCamelCase__      ))      )
				return common_inputs



		def       lowerCAmelCase				(      self				:			Optional[Any]  ,	UpperCamelCase__				:			PreTrainedTokenizer  ,	UpperCamelCase__				:			int = -1  ,	UpperCamelCase__				:			int = -1  ,	UpperCamelCase__				:			bool = False  ,	UpperCamelCase__				:			Optional[TensorType] = None  ,	)						->			Mapping[str, Any]:






				"""simple docstring"""







				snake_case  :       str     			=						self._generate_dummy_inputs_for_encoder_and_decoder(
				    UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__      )

				if self.use_past:
						if not is_torch_available():
								raise ValueError('''Cannot generate dummy past_keys inputs without PyTorch installed.'''      )
						else:
								import torch
						snake_case			,snake_case  :       Optional[Any]     			=						common_inputs['''input_ids'''].shape
						# Not using the same length for past_key_values
						snake_case  :       int     			=						seqlen + 2
						snake_case			,snake_case  :       int     			=						self.num_layers
						snake_case			,snake_case  :       List[Any]     			=						self.num_attention_heads
						snake_case  :       Optional[int]     			=						(
						    batch,
						    num_encoder_attention_heads,
						    past_key_values_length,
						    self._config.hidden_size // num_encoder_attention_heads,
						)

						snake_case  :       Tuple     			=						common_inputs['''attention_mask'''].dtype
						snake_case  :       Optional[int]     			=						torch.cat(
						    [common_inputs['''attention_mask'''], torch.ones(UpperCamelCase__  ,	UpperCamelCase__  ,	dtype=UpperCamelCase__      )]  ,	dim=1      )
						snake_case  :       str     			=						[
						    (torch.zeros(UpperCamelCase__      ), torch.zeros(UpperCamelCase__      )) for _ in range(UpperCamelCase__      )
						]
				return common_inputs



		def       lowerCAmelCase				(      self				:			List[Any]  ,	UpperCamelCase__				:			PreTrainedTokenizer  ,	UpperCamelCase__				:			int = -1  ,	UpperCamelCase__				:			int = -1  ,	UpperCamelCase__				:			bool = False  ,	UpperCamelCase__				:			Optional[TensorType] = None  ,	)						->			Mapping[str, Any]:






				"""simple docstring"""







				snake_case  :       Tuple     			=						compute_effective_axis_dimension(
				    UpperCamelCase__  ,	fixed_dimension=OnnxConfig.default_fixed_batch  ,	num_token_to_add=0      )

				# If dynamic axis (-1) we forward with a fixed dimension of 8 tokens to avoid optimizations made by ONNX
				snake_case  :       List[str]     			=						tokenizer.num_special_tokens_to_add(UpperCamelCase__      )
				snake_case  :       str     			=						compute_effective_axis_dimension(
				    UpperCamelCase__  ,	fixed_dimension=OnnxConfig.default_fixed_sequence  ,	num_token_to_add=UpperCamelCase__      )

				# Generate dummy inputs according to compute batch and sequence
				snake_case  :       str     			=						[''' '''.join([tokenizer.unk_token]      ) * seq_length] * batch_size
				snake_case  :       Union[str, Any]     			=						dict(tokenizer(UpperCamelCase__  ,	return_tensors=UpperCamelCase__      )      )
				return common_inputs



		def       lowerCAmelCase				(      self				:			List[Any]  ,	UpperCamelCase__				:			PreTrainedTokenizer  ,	UpperCamelCase__				:			int = -1  ,	UpperCamelCase__				:			int = -1  ,	UpperCamelCase__				:			bool = False  ,	UpperCamelCase__				:			Optional[TensorType] = None  ,	)						->			Mapping[str, Any]:






				"""simple docstring"""







				if self.task in ["default", "seq2seq-lm"]:
						snake_case  :       Dict     			=						self._generate_dummy_inputs_for_default_and_seqaseq_lm(
						    UpperCamelCase__  ,	batch_size=UpperCamelCase__  ,	seq_length=UpperCamelCase__  ,	is_pair=UpperCamelCase__  ,	framework=UpperCamelCase__      )

				else:
						snake_case  :       Tuple     			=						self._generate_dummy_inputs_for_causal_lm(
						    UpperCamelCase__  ,	batch_size=UpperCamelCase__  ,	seq_length=UpperCamelCase__  ,	is_pair=UpperCamelCase__  ,	framework=UpperCamelCase__      )

				return common_inputs



		def       lowerCAmelCase				(      self				:			Optional[int]  ,	UpperCamelCase__				:			Optional[Any]  ,	UpperCamelCase__				:			List[str]  ,	UpperCamelCase__				:			int  ,	UpperCamelCase__				:			Union[str, Any]      )						->			Union[str, Any]:






				"""simple docstring"""







				if self.task in ["default", "seq2seq-lm"]:
						snake_case  :       List[Any]     			=						super()._flatten_past_key_values_(UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__      )
				else:
						snake_case  :       Optional[int]     			=						super(UpperCamelCase__  ,	self      )._flatten_past_key_values_(
						    UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__  ,	UpperCamelCase__      )



		@property
		def       lowerCAmelCase				(      self				:			Optional[Any]      )						->			float:






				"""simple docstring"""







				return 1e-4


