
import argparse
import hashlib
import os
import urllib
import warnings

import torch
from torch import nn
from tqdm import tqdm

from transformers import WhisperConfig, WhisperForConditionalGeneration


SCREAMING_SNAKE_CASE							:Optional[int] 			=    {
    '''tiny.en''': '''https://openaipublic.azureedge.net/main/whisper/models/d3dd57d32accea0b295c96e26691aa14d8822fac7d9d27d5dc00b4ca2826dd03/tiny.en.pt''',
    '''tiny''': '''https://openaipublic.azureedge.net/main/whisper/models/65147644a518d12f04e32d6f3b26facc3f8dd46e5390956a9424a650c0ce22b9/tiny.pt''',
    '''base.en''': '''https://openaipublic.azureedge.net/main/whisper/models/25a8566e1d0c1e2231d1c762132cd20e0f96a85d16145c3a00adf5d1ac670ead/base.en.pt''',
    '''base''': '''https://openaipublic.azureedge.net/main/whisper/models/ed3a0b6b1c0edf879ad9b11b1af5a0e6ab5db9205f891f668f8b0e6c6326e34e/base.pt''',
    '''small.en''': '''https://openaipublic.azureedge.net/main/whisper/models/f953ad0fd29cacd07d5a9eda5624af0f6bcf2258be67c92b79389873d91e0872/small.en.pt''',
    '''small''': '''https://openaipublic.azureedge.net/main/whisper/models/9ecf779972d90ba49c06d968637d720dd632c55bbf19d441fb42bf17a411e794/small.pt''',
    '''medium.en''': '''https://openaipublic.azureedge.net/main/whisper/models/d7440d1dc186f76616474e0ff0b3b6b879abc9d1a4926b7adfa41db2d497ab4f/medium.en.pt''',
    '''medium''': '''https://openaipublic.azureedge.net/main/whisper/models/345ae4da62f9b3d59415adc60127b97c714f32e89e936602e85993674d08dcb1/medium.pt''',
    '''large''': '''https://openaipublic.azureedge.net/main/whisper/models/e4b87e7e0bf463eb8e6956e646f1e277e901512310def2c24bf0e11bd3c28e9a/large.pt''',
    '''large-v2''': '''https://openaipublic.azureedge.net/main/whisper/models/81f7c96c852ee8fc832187b0132e569d6c3065a3252ed18e56effd0b6a73e524/large-v2.pt''',
}


def 						UpperCAmelCase      (     a_						)		->     List[Any]:







				"""simple docstring"""



				__A             =			["layers", "blocks"]
				for k in ignore_keys:
								state_dict.pop(_lowercase		,       _lowercase						)


SCREAMING_SNAKE_CASE							:Union[str, Any] 			=    {
    '''blocks''': '''layers''',
    '''mlp.0''': '''fc1''',
    '''mlp.2''': '''fc2''',
    '''mlp_ln''': '''final_layer_norm''',
    '''.attn.query''': '''.self_attn.q_proj''',
    '''.attn.key''': '''.self_attn.k_proj''',
    '''.attn.value''': '''.self_attn.v_proj''',
    '''.attn_ln''': '''.self_attn_layer_norm''',
    '''.attn.out''': '''.self_attn.out_proj''',
    '''.cross_attn.query''': '''.encoder_attn.q_proj''',
    '''.cross_attn.key''': '''.encoder_attn.k_proj''',
    '''.cross_attn.value''': '''.encoder_attn.v_proj''',
    '''.cross_attn_ln''': '''.encoder_attn_layer_norm''',
    '''.cross_attn.out''': '''.encoder_attn.out_proj''',
    '''decoder.ln.''': '''decoder.layer_norm.''',
    '''encoder.ln.''': '''encoder.layer_norm.''',
    '''token_embedding''': '''embed_tokens''',
    '''encoder.positional_embedding''': '''encoder.embed_positions.weight''',
    '''decoder.positional_embedding''': '''decoder.embed_positions.weight''',
    '''ln_post''': '''layer_norm''',
}


def 						UpperCAmelCase      (     a_						)		->     Union[str, Any]:







				"""simple docstring"""



				__A             =			list(s_dict.keys()						)
				for key in keys:
								__A             =			key
								for k, v in WHISPER_MAPPING.items():
												if k in key:
																__A             =			new_key.replace(_lowercase		,       _lowercase						)

								print(F'''{key} -> {new_key}'''						)

								__A             =			s_dict.pop(_lowercase						)
				return s_dict


def 						UpperCAmelCase      (     a_						)		->     Optional[Any]:







				"""simple docstring"""



				__A             =			emb.weight.shape
				__A             =			nn.Linear(_lowercase		,       _lowercase		,       bias=_lowercase						)
				__A             =			emb.weight.data
				return lin_layer


def 						UpperCAmelCase      (     a_		,       a_						)		->     bytes:







				"""simple docstring"""



				os.makedirs(_lowercase		,       exist_ok=_lowercase						)
				__A             =			os.path.basename(_lowercase						)

				__A             =			url.split("/"						)[-2]
				__A             =			os.path.join(_lowercase		,       _lowercase						)

				if os.path.exists(_lowercase						) and not os.path.isfile(_lowercase						):
								raise RuntimeError(F'''{download_target} exists and is not a regular file'''						)

				if os.path.isfile(_lowercase						):
								__A             =			open(_lowercase		,       "rb"						).read()
								if hashlib.shaaaa(_lowercase						).hexdigest() == expected_shaaaa:
												return model_bytes
								else:
												warnings.warn(F'''{download_target} exists, but the SHA256 checksum does not match; re-downloading the file'''						)

				with urllib.request.urlopen(_lowercase						) as source, open(_lowercase		,       "wb"						) as output:
								with tqdm(
								    total=int(source.info().get("Content-Length"						)						)		,       ncols=8_0		,       unit="iB"		,       unit_scale=_lowercase		,       unit_divisor=1_0_2_4						) as loop:
												while True:
																__A             =			source.read(8_1_9_2						)
																if not buffer:
																				break

																output.write(_lowercase						)
																loop.update(len(_lowercase						)						)

				__A             =			open(_lowercase		,       "rb"						).read()
				if hashlib.shaaaa(_lowercase						).hexdigest() != expected_shaaaa:
								raise RuntimeError(
								    "Model has been downloaded but the SHA256 checksum does not not match. Please retry loading the model."						)

				return model_bytes


def 						UpperCAmelCase      (     a_		,       a_						)		->     List[str]:







				"""simple docstring"""



				if ".pt" not in checkpoint_path:
								__A             =			_download(_MODELS[checkpoint_path]						)
				else:
								__A             =			torch.load(_lowercase		,       map_location="cpu"						)
				__A             =			original_checkpoint["dims"]
				__A             =			original_checkpoint["model_state_dict"]
				__A             =			state_dict["decoder.token_embedding.weight"]
				remove_ignore_keys_(_lowercase						)
				rename_keys(_lowercase						)
				__A             =			True
				__A             =			state_dict["decoder.layers.0.fc1.weight"].shape[0]

				__A             =			WhisperConfig(
				    vocab_size=dimensions["n_vocab"]		,       encoder_ffn_dim=_lowercase		,       decoder_ffn_dim=_lowercase		,       num_mel_bins=dimensions["n_mels"]		,       d_model=dimensions["n_audio_state"]		,       max_target_positions=dimensions["n_text_ctx"]		,       encoder_layers=dimensions["n_audio_layer"]		,       encoder_attention_heads=dimensions["n_audio_head"]		,       decoder_layers=dimensions["n_text_layer"]		,       decoder_attention_heads=dimensions["n_text_state"]		,       max_source_positions=dimensions["n_audio_ctx"]		,       )

				__A             =			WhisperForConditionalGeneration(_lowercase						)
				__A             =			model.model.load_state_dict(_lowercase		,       strict=_lowercase						)
				if len(_lowercase						) > 0 and not set(_lowercase						) <= {
				    "encoder.embed_positions.weights",
				    "decoder.embed_positions.weights",
				}:
								raise ValueError(
								    "Only `encoder.embed_positions.weights` and `decoder.embed_positions.weights`  are allowed to be missing,"
								    F''' but all the following weights are missing {missing}'''						)

				if tie_embeds:
								__A             =			make_linear_from_emb(model.model.decoder.embed_tokens						)
				else:
								__A             =			proj_out_weights

				model.save_pretrained(_lowercase						)


if __name__ == "__main__":
					SCREAMING_SNAKE_CASE							:Union[str, Any] 			=    argparse.ArgumentParser()
					# # Required parameters
					parser.add_argument('--checkpoint_path', type=str, help='Patht to the downloaded checkpoints')
					parser.add_argument('--pytorch_dump_folder_path', default=None, type=str, help='Path to the output PyTorch model.')
					SCREAMING_SNAKE_CASE							:Union[str, Any] 			=    parser.parse_args()

					convert_openai_whisper_to_tfms(args.checkpoint_path, args.pytorch_dump_folder_path)


from collections import OrderedDict
from typing import TYPE_CHECKING, Any, List, Mapping, Optional

from packaging import version


if TYPE_CHECKING:
					from ... import PreTrainedTokenizer, TensorType

from ...configuration_utils import PretrainedConfig
from ...onnx import OnnxConfigWithPast, PatchingSpec
from ...utils import is_torch_available, logging


SCREAMING_SNAKE_CASE							:Optional[Any]										=    logging.get_logger(__name__)

SCREAMING_SNAKE_CASE							:Union[str, Any]										=    {
    'bigscience/bloom': 'https://huggingface.co/bigscience/bloom/resolve/main/config.json',
    'bigscience/bloom-560m': 'https://huggingface.co/bigscience/bloom-560m/blob/main/config.json',
    'bigscience/bloom-1b1': 'https://huggingface.co/bigscience/bloom-1b1/blob/main/config.json',
    'bigscience/bloom-1b7': 'https://huggingface.co/bigscience/bloom-1b7/blob/main/config.json',
    'bigscience/bloom-3b': 'https://huggingface.co/bigscience/bloom-3b/blob/main/config.json',
    'bigscience/bloom-7b1': 'https://huggingface.co/bigscience/bloom-7b1/blob/main/config.json',
}





class 							UpperCAmelCase				(  __SCREAMING_SNAKE_CASE  ):




	'''simple docstring'''





	snake_case_    =					"bloom"
	snake_case_    =					["past_key_values"]
	snake_case_    =					{
	    "num_hidden_layers": "n_layer",
	    "num_attention_heads": "n_head",
	}






	def __init__(	self :			Optional[Any]							,A :			List[Any]=25_08_80							,A :			Optional[int]=64							,A :			List[Any]=2							,A :			Optional[int]=8							,A :			str=1E-5							,A :			str=0.02							,A :			int=True							,A :			Optional[Any]=1							,A :			int=2							,A :			str=False							,A :			Dict=0.0							,A :			List[Any]=0.0							,A :			str=1							,A :			List[Any]=False							,**A :			List[Any]							,):
					__A             =			vocab_size
					# Backward compatibility with n_embed kwarg
					__A             =			kwargs.pop("n_embed"							,A			)
					__A             =			hidden_size if n_embed is None else n_embed
					__A             =			n_layer
					__A             =			n_head
					__A             =			layer_norm_epsilon
					__A             =			initializer_range
					__A             =			use_cache
					__A             =			pretraining_tp
					__A             =			apply_residual_connection_post_layernorm
					__A             =			hidden_dropout
					__A             =			attention_dropout

					__A             =			bos_token_id
					__A             =			eos_token_id
					__A             =			slow_but_exact

					super().__init__(bos_token_id=A							,eos_token_id=A							,**A			)





class 							UpperCAmelCase				(  __SCREAMING_SNAKE_CASE  ):




	'''simple docstring'''





	snake_case_    =					version.parse("1.12"  )






	def __init__(	self :			str							,A :			PretrainedConfig							,A :			str = "default"							,A :			List[PatchingSpec] = None							,A :			bool = False							,):
					super().__init__(A							,task=A							,patching_specs=A							,use_past=A			)
					if not getattr(self._config							,"pad_token_id"							,A			):
									# TODO: how to do that better?
									__A             =			0






	@property
	def     UpperCamelCase_  (	self :			Union[str, Any]			):
					__A             =			OrderedDict({"input_ids": {0: "batch", 1: "sequence"}}			)
					if self.use_past:
									# BLOOM stores values on dynamic axis 2. For more details see: https://github.com/huggingface/transformers/pull/18344
									self.fill_with_past_key_values_(A							,direction="inputs"							,inverted_values_shape=A			)
									__A             =			{0: "batch", 1: "past_sequence + sequence"}
					else:
									__A             =			{0: "batch", 1: "sequence"}

					return common_inputs






	@property
	def     UpperCamelCase_  (	self :			Optional[Any]			):
					return self._config.n_layer






	@property
	def     UpperCamelCase_  (	self :			List[Any]			):
					return self._config.n_head






	@property
	def     UpperCamelCase_  (	self :			Optional[int]			):
					return 1E-3






	def     UpperCamelCase_  (	self :			Any							,A :			"PreTrainedTokenizer"							,A :			int = -1							,A :			int = -1							,A :			bool = False							,A :			Optional["TensorType"] = None							,):
					__A             =			super(A							,self			).generate_dummy_inputs(
					    A							,batch_size=A							,seq_length=A							,is_pair=A							,framework=A			)

					# We need to order the input in the way they appears in the forward()
					__A             =			OrderedDict({"input_ids": common_inputs["input_ids"]}			)

					# Need to add the past_keys
					if self.use_past:
									if not is_torch_available():
													raise ValueError("Cannot generate dummy past_keys inputs without PyTorch installed."			)
									else:
													import torch

													__A      ,							__A             =			common_inputs["input_ids"].shape
													# Not using the same length for past_key_values
													__A             =			seqlen + 2
													__A             =			self._config.hidden_size // self.num_attention_heads
													__A             =			(
													    batch * self.num_attention_heads,
													    head_dim,
													    past_key_values_length,
													)
													__A             =			(
													    batch * self.num_attention_heads,
													    past_key_values_length,
													    head_dim,
													)
													__A             =			[
													    (torch.zeros(A			), torch.zeros(A			)) for _ in range(self.num_layers			)
													]

					__A             =			common_inputs["attention_mask"]
					if self.use_past:
									__A             =			ordered_inputs["attention_mask"].dtype
									__A             =			torch.cat(
									    [ordered_inputs["attention_mask"], torch.ones(A							,A							,dtype=A			)]							,dim=1			)

					return ordered_inputs







	@property
	def     UpperCamelCase_  (	self :			int			):
					return 13
