
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


__lowerCamelCase				=			{
    """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   (       __lowerCamelCase	:					List[Any]       ):
       snake_case			:  List[str]     							= ["layers", "blocks"]
       for k in ignore_keys:
              state_dict.pop(__lowerCamelCase							,   __lowerCamelCase       )


__lowerCamelCase				=			{
    """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   (       __lowerCamelCase	:					Dict       ):
       snake_case			:  List[str]     							= list(s_dict.keys()       )
       for key in keys:
              snake_case			:  Dict     							= key
              for k, v in WHISPER_MAPPING.items():
                     if k in key:
                            snake_case			:  int     							= new_key.replace(__lowerCamelCase							,   __lowerCamelCase       )

              print(f"""{key} -> {new_key}"""       )

              snake_case			:  Union[str, Any]     							= s_dict.pop(__lowerCamelCase       )
       return s_dict


def      UpperCamelCase   (       __lowerCamelCase	:					List[str]       ):
       snake_case							,   snake_case			:  Optional[int]     							= emb.weight.shape
       snake_case			:  Union[str, Any]     							= nn.Linear(__lowerCamelCase							,   __lowerCamelCase							,   bias=__lowerCamelCase       )
       snake_case			:  Optional[int]     							= emb.weight.data
       return lin_layer


def      UpperCamelCase   (       __lowerCamelCase	:					str							,   __lowerCamelCase	:					str       ):
       os.makedirs(__lowerCamelCase							,   exist_ok=__lowerCamelCase       )
       snake_case			:  str     							= os.path.basename(__lowerCamelCase       )

       snake_case			:  Tuple     							= url.split("/"       )[-2]
       snake_case			:  List[Any]     							= os.path.join(__lowerCamelCase							,   __lowerCamelCase       )

       if os.path.exists(__lowerCamelCase       ) and not os.path.isfile(__lowerCamelCase       ):
              raise RuntimeError(f"""{download_target} exists and is not a regular file"""       )

       if os.path.isfile(__lowerCamelCase       ):
              snake_case			:  int     							= open(__lowerCamelCase							,   "rb"       ).read()
              if hashlib.shaaaa(__lowerCamelCase       ).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(__lowerCamelCase       ) as source, open(__lowerCamelCase							,   "wb"       ) as output:
              with tqdm(
                  total=int(source.info().get("Content-Length"       )       )							,   ncols=80							,   unit="iB"							,   unit_scale=__lowerCamelCase							,   unit_divisor=1024       ) as loop:
                     while True:
                            snake_case			:  Union[str, Any]     							= source.read(8192       )
                            if not buffer:
                                   break

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

       snake_case			:  List[Any]     							= open(__lowerCamelCase							,   "rb"       ).read()
       if hashlib.shaaaa(__lowerCamelCase       ).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   (       __lowerCamelCase	:					int							,   __lowerCamelCase	:					Optional[Any]       ):
       if ".pt" not in checkpoint_path:
              snake_case			:  Optional[int]     							= _download(_MODELS[checkpoint_path]       )
       else:
              snake_case			:  List[Any]     							= torch.load(__lowerCamelCase							,   map_location="cpu"       )
       snake_case			:  int     							= original_checkpoint["dims"]
       snake_case			:  Union[str, Any]     							= original_checkpoint["model_state_dict"]
       snake_case			:  Optional[Any]     							= state_dict["decoder.token_embedding.weight"]
       remove_ignore_keys_(__lowerCamelCase       )
       rename_keys(__lowerCamelCase       )
       snake_case			:  int     							= True
       snake_case			:  Optional[int]     							= state_dict["decoder.layers.0.fc1.weight"].shape[0]

       snake_case			:  Any     							= WhisperConfig(
           vocab_size=dimensions["n_vocab"]							,   encoder_ffn_dim=__lowerCamelCase							,   decoder_ffn_dim=__lowerCamelCase							,   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"]							,   )

       snake_case			:  int     							= WhisperForConditionalGeneration(__lowerCamelCase       )
       snake_case							,   snake_case			:  Tuple     							= model.model.load_state_dict(__lowerCamelCase							,   strict=__lowerCamelCase       )
       if len(__lowerCamelCase       ) > 0 and not set(__lowerCamelCase       ) <= {
           "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:
              snake_case			:  List[Any]     							= make_linear_from_emb(model.model.decoder.embed_tokens       )
       else:
              snake_case			:  Tuple     							= proj_out_weights

       model.save_pretrained(__lowerCamelCase       )


if __name__ == "__main__":
   __lowerCamelCase				=			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.""")
   __lowerCamelCase				=			parser.parse_args()

   convert_openai_whisper_to_tfms(args.checkpoint_path, args.pytorch_dump_folder_path)







from __future__ import annotations

from collections.abc import Callable
from typing import Any, Generic, TypeVar

__lowerCamelCase				=			TypeVar("""T""")






class     UpperCAmelCase						(		Generic[T]					):



   def __init__(self						:   int       ,		snake_case__						:   list[T]       ,		snake_case__						:   Callable[[T, T], T]					)						->      None:


          '''simple docstring'''


          snake_case			:  Any | T     							= None

          snake_case			:  int     							= len(snake_case__					)
          snake_case			:  list[T]     							= [any_type for _ in range(self.N					)] + arr
          snake_case			:  str     							= fnc
          self.build()



   def 							_SCREAMING_SNAKE_CASE  (self						:   Union[str, Any]					)						->      None:


          '''simple docstring'''


          for p in range(self.N - 1       ,		0       ,		-1					):
                 snake_case			:  int     							= self.fn(self.st[p * 2]       ,		self.st[p * 2 + 1]					)



   def 							_SCREAMING_SNAKE_CASE  (self						:   Dict       ,		snake_case__						:   int       ,		snake_case__						:   T					)						->      None:


          '''simple docstring'''


          p += self.N
          snake_case			:  int     							= v
          while p > 1:
                 snake_case			:  List[str]     							= p // 2
                 snake_case			:  Tuple     							= self.fn(self.st[p * 2]       ,		self.st[p * 2 + 1]					)



   def 							_SCREAMING_SNAKE_CASE  (self						:   Optional[Any]       ,		snake_case__						:   int       ,		snake_case__						:   int					)						->      T | None:  # noqa: E741


          '''simple docstring'''


          snake_case							,   snake_case			:  Optional[int]     							= l + self.N, r + self.N

          snake_case			:  T | None     							= None
          while l <= r:
                 if l % 2 == 1:
                        snake_case			:  List[str]     							= self.st[l] if res is None else self.fn(snake_case__       ,		self.st[l]					)
                 if r % 2 == 0:
                        snake_case			:  int     							= self.st[r] if res is None else self.fn(snake_case__       ,		self.st[r]					)
                 snake_case							,   snake_case			:  str     							= (l + 1) // 2, (r - 1) // 2
          return res


if __name__ == "__main__":
   from functools import reduce

   __lowerCamelCase				=			[1, 10, -2, 9, -3, 8, 4, -7, 5, 6, 11, -12]

   __lowerCamelCase				=			{
       0: 7,
       1: 2,
       2: 6,
       3: -14,
       4: 5,
       5: 4,
       6: 7,
       7: -10,
       8: 9,
       9: 10,
       10: 12,
       11: 1,
   }

   __lowerCamelCase				=			SegmentTree(test_array, min)
   __lowerCamelCase				=			SegmentTree(test_array, max)
   __lowerCamelCase				=			SegmentTree(test_array, lambda a, b: a + b)


   def      UpperCamelCase   (       ):
          for i in range(len(__lowerCamelCase       )       ):
                 for j in range(__lowerCamelCase							,   len(__lowerCamelCase       )       ):
                        snake_case			:  int     							= reduce(__lowerCamelCase							,   test_array[i : j + 1]       )
                        snake_case			:  Tuple     							= reduce(__lowerCamelCase							,   test_array[i : j + 1]       )
                        snake_case			:  Union[str, Any]     							= reduce(lambda __lowerCamelCase							,   __lowerCamelCase       : a + b							,   test_array[i : j + 1]       )
                        assert min_range == min_segment_tree.query(__lowerCamelCase							,   __lowerCamelCase       )
                        assert max_range == max_segment_tree.query(__lowerCamelCase							,   __lowerCamelCase       )
                        assert sum_range == sum_segment_tree.query(__lowerCamelCase							,   __lowerCamelCase       )

   test_all_segments()

   for index, value in test_updates.items():
      __lowerCamelCase				=			value
      min_segment_tree.update(index, value)
      max_segment_tree.update(index, value)
      sum_segment_tree.update(index, value)
      test_all_segments()





