





import argparse
import json
from pathlib import Path

import torch
import torchaudio
from datasets import load_dataset
from huggingface_hub import hf_hub_download

from transformers import ASTConfig, ASTFeatureExtractor, ASTForAudioClassification
from transformers.utils import logging


logging.set_verbosity_info()
_UpperCAmelCase        =				logging.get_logger(__name__)




def  lowerCAmelCase_ (							UpperCamelCase_  )     ->		Optional[Any]:
       UpperCamelCase_          =  ASTConfig()

       if "10-10" in model_name:
              pass
       elif "speech-commands" in model_name:
              UpperCamelCase_          =  128
       elif "12-12" in model_name:
              UpperCamelCase_          =  12
              UpperCamelCase_          =  12
       elif "14-14" in model_name:
              UpperCamelCase_          =  14
              UpperCamelCase_          =  14
       elif "16-16" in model_name:
              UpperCamelCase_          =  16
              UpperCamelCase_          =  16
       else:
              raise ValueError("Model not supported"  )

       UpperCamelCase_          =  "huggingface/label-files"
       if "speech-commands" in model_name:
              UpperCamelCase_          =  35
              UpperCamelCase_          =  "speech-commands-v2-id2label.json"
       else:
              UpperCamelCase_          =  527
              UpperCamelCase_          =  "audioset-id2label.json"

       UpperCamelCase_          =  json.load(open(hf_hub_download(UpperCamelCase_					,		UpperCamelCase_					,		repo_type="dataset"  )					,		"r"  )  )
       UpperCamelCase_          =  {int(UpperCamelCase_  ): v for k, v in idalabel.items()}
       UpperCamelCase_          =  idalabel
       UpperCamelCase_          =  {v: k for k, v in idalabel.items()}

       return config




def  lowerCAmelCase_ (							UpperCamelCase_  )     ->		Any:
       if "module.v" in name:
              UpperCamelCase_          =  name.replace("module.v"					,		"audio_spectrogram_transformer"  )
       if "cls_token" in name:
              UpperCamelCase_          =  name.replace("cls_token"					,		"embeddings.cls_token"  )
       if "dist_token" in name:
              UpperCamelCase_          =  name.replace("dist_token"					,		"embeddings.distillation_token"  )
       if "pos_embed" in name:
              UpperCamelCase_          =  name.replace("pos_embed"					,		"embeddings.position_embeddings"  )
       if "patch_embed.proj" in name:
              UpperCamelCase_          =  name.replace("patch_embed.proj"					,		"embeddings.patch_embeddings.projection"  )
       # transformer blocks
       if "blocks" in name:
              UpperCamelCase_          =  name.replace("blocks"					,		"encoder.layer"  )
       if "attn.proj" in name:
              UpperCamelCase_          =  name.replace("attn.proj"					,		"attention.output.dense"  )
       if "attn" in name:
              UpperCamelCase_          =  name.replace("attn"					,		"attention.self"  )
       if "norm1" in name:
              UpperCamelCase_          =  name.replace("norm1"					,		"layernorm_before"  )
       if "norm2" in name:
              UpperCamelCase_          =  name.replace("norm2"					,		"layernorm_after"  )
       if "mlp.fc1" in name:
              UpperCamelCase_          =  name.replace("mlp.fc1"					,		"intermediate.dense"  )
       if "mlp.fc2" in name:
              UpperCamelCase_          =  name.replace("mlp.fc2"					,		"output.dense"  )
       # final layernorm
       if "audio_spectrogram_transformer.norm" in name:
              UpperCamelCase_          =  name.replace("audio_spectrogram_transformer.norm"					,		"audio_spectrogram_transformer.layernorm"  )
       # classifier head
       if "module.mlp_head.0" in name:
              UpperCamelCase_          =  name.replace("module.mlp_head.0"					,		"classifier.layernorm"  )
       if "module.mlp_head.1" in name:
              UpperCamelCase_          =  name.replace("module.mlp_head.1"					,		"classifier.dense"  )

       return name




def  lowerCAmelCase_ (							UpperCamelCase_					,		UpperCamelCase_  )     ->		int:
       for key in orig_state_dict.copy().keys():
              UpperCamelCase_          =  orig_state_dict.pop(UpperCamelCase_  )

              if "qkv" in key:
                     UpperCamelCase_          =  key.split("."  )
                     UpperCamelCase_          =  int(key_split[3]  )
                     UpperCamelCase_          =  config.hidden_size
                     if "weight" in key:
                            UpperCamelCase_          =  val[:dim, :]
                            UpperCamelCase_          =  val[dim : dim * 2, :]
                            UpperCamelCase_          =  val[-dim:, :]
                     else:
                            UpperCamelCase_          =  val[:dim]
                            UpperCamelCase_          =  val[dim : dim * 2]
                            UpperCamelCase_          =  val[-dim:]
              else:
                     UpperCamelCase_          =  val

       return orig_state_dict




def  lowerCAmelCase_ (							UpperCamelCase_  )     ->		Union[str, Any]:
       UpperCamelCase_          =  [
           "module.v.head.weight",
           "module.v.head.bias",
           "module.v.head_dist.weight",
           "module.v.head_dist.bias",
       ]
       for k in ignore_keys:
              state_dict.pop(UpperCamelCase_					,		UpperCamelCase_  )




@torch.no_grad()
def  lowerCAmelCase_ (							UpperCamelCase_					,		UpperCamelCase_					,		UpperCamelCase_=False  )     ->		Optional[Any]:
       UpperCamelCase_          =  get_audio_spectrogram_transformer_config(UpperCamelCase_  )

       UpperCamelCase_          =  {
           "ast-finetuned-audioset-10-10-0.4593": (
               "https://www.dropbox.com/s/ca0b1v2nlxzyeb4/audioset_10_10_0.4593.pth?dl=1"
           ),
           "ast-finetuned-audioset-10-10-0.450": (
               "https://www.dropbox.com/s/1tv0hovue1bxupk/audioset_10_10_0.4495.pth?dl=1"
           ),
           "ast-finetuned-audioset-10-10-0.448": (
               "https://www.dropbox.com/s/6u5sikl4b9wo4u5/audioset_10_10_0.4483.pth?dl=1"
           ),
           "ast-finetuned-audioset-10-10-0.448-v2": (
               "https://www.dropbox.com/s/kt6i0v9fvfm1mbq/audioset_10_10_0.4475.pth?dl=1"
           ),
           "ast-finetuned-audioset-12-12-0.447": (
               "https://www.dropbox.com/s/snfhx3tizr4nuc8/audioset_12_12_0.4467.pth?dl=1"
           ),
           "ast-finetuned-audioset-14-14-0.443": (
               "https://www.dropbox.com/s/z18s6pemtnxm4k7/audioset_14_14_0.4431.pth?dl=1"
           ),
           "ast-finetuned-audioset-16-16-0.442": (
               "https://www.dropbox.com/s/mdsa4t1xmcimia6/audioset_16_16_0.4422.pth?dl=1"
           ),
           "ast-finetuned-speech-commands-v2": (
               "https://www.dropbox.com/s/q0tbqpwv44pquwy/speechcommands_10_10_0.9812.pth?dl=1"
           ),
       }

       # load original state_dict
       UpperCamelCase_          =  model_name_to_url[model_name]
       UpperCamelCase_          =  torch.hub.load_state_dict_from_url(UpperCamelCase_					,		map_location="cpu"  )
       # remove some keys
       remove_keys(UpperCamelCase_  )
       # rename some keys
       UpperCamelCase_          =  convert_state_dict(UpperCamelCase_					,		UpperCamelCase_  )

       # load 🤗 model
       UpperCamelCase_          =  ASTForAudioClassification(UpperCamelCase_  )
       model.eval()

       model.load_state_dict(UpperCamelCase_  )

       # verify outputs on dummy input
       # source: https://github.com/YuanGongND/ast/blob/79e873b8a54d0a3b330dd522584ff2b9926cd581/src/run.py#L62
       UpperCamelCase_          =  -4.2_67_73_93 if "speech-commands" not in model_name else -6.84_59_78
       UpperCamelCase_          =  4.5_68_99_74 if "speech-commands" not in model_name else 5.5_65_45_26
       UpperCamelCase_          =  1024 if "speech-commands" not in model_name else 128
       UpperCamelCase_          =  ASTFeatureExtractor(mean=UpperCamelCase_					,		std=UpperCamelCase_					,		max_length=UpperCamelCase_  )

       if "speech-commands" in model_name:
              UpperCamelCase_          =  load_dataset("speech_commands"					,		"v0.02"					,		split="validation"  )
              UpperCamelCase_          =  dataset[0]["audio"]["array"]
       else:
              UpperCamelCase_          =  hf_hub_download(
                  repo_id="nielsr/audio-spectogram-transformer-checkpoint"					,		filename="sample_audio.flac"					,		repo_type="dataset"					,		)

              UpperCamelCase_       , UpperCamelCase_          =  torchaudio.load(UpperCamelCase_  )
              UpperCamelCase_          =  waveform.squeeze().numpy()

       UpperCamelCase_          =  feature_extractor(UpperCamelCase_					,		sampling_rate=16000					,		return_tensors="pt"  )

       # forward pass
       UpperCamelCase_          =  model(**UpperCamelCase_  )
       UpperCamelCase_          =  outputs.logits

       if model_name == "ast-finetuned-audioset-10-10-0.4593":
              UpperCamelCase_          =  torch.tensor([-0.87_60, -7.00_42, -8.66_02]  )
       elif model_name == "ast-finetuned-audioset-10-10-0.450":
              UpperCamelCase_          =  torch.tensor([-1.19_86, -7.09_03, -8.27_18]  )
       elif model_name == "ast-finetuned-audioset-10-10-0.448":
              UpperCamelCase_          =  torch.tensor([-2.61_28, -8.00_80, -9.43_44]  )
       elif model_name == "ast-finetuned-audioset-10-10-0.448-v2":
              UpperCamelCase_          =  torch.tensor([-1.50_80, -7.45_34, -8.89_17]  )
       elif model_name == "ast-finetuned-audioset-12-12-0.447":
              UpperCamelCase_          =  torch.tensor([-0.50_50, -6.58_33, -8.08_43]  )
       elif model_name == "ast-finetuned-audioset-14-14-0.443":
              UpperCamelCase_          =  torch.tensor([-0.38_26, -7.03_36, -8.24_13]  )
       elif model_name == "ast-finetuned-audioset-16-16-0.442":
              UpperCamelCase_          =  torch.tensor([-1.21_13, -6.91_01, -8.34_70]  )
       elif model_name == "ast-finetuned-speech-commands-v2":
              UpperCamelCase_          =  torch.tensor([6.15_89, -8.05_66, -8.79_84]  )
       else:
              raise ValueError("Unknown model name"  )
       if not torch.allclose(logits[0, :3]					,		UpperCamelCase_					,		atol=1e-4  ):
              raise ValueError("Logits don't match"  )
       print("Looks ok!"  )

       if pytorch_dump_folder_path is not None:
              Path(UpperCamelCase_  ).mkdir(exist_ok=UpperCamelCase_  )
              print(F'''Saving model {model_name} to {pytorch_dump_folder_path}'''  )
              model.save_pretrained(UpperCamelCase_  )
              print(F'''Saving feature extractor to {pytorch_dump_folder_path}'''  )
              feature_extractor.save_pretrained(UpperCamelCase_  )

       if push_to_hub:
              print("Pushing model and feature extractor to the hub..."  )
              model.push_to_hub(F'''MIT/{model_name}'''  )
              feature_extractor.push_to_hub(F'''MIT/{model_name}'''  )


if __name__ == "__main__":
     _UpperCAmelCase        =				argparse.ArgumentParser()
     # Required parameters
     parser.add_argument(
         '--model_name',
         default='ast-finetuned-audioset-10-10-0.4593',
         type=str,
         help='Name of the Audio Spectrogram Transformer model you\'d like to convert.',
     )
     parser.add_argument(
         '--pytorch_dump_folder_path', default=None, type=str, help='Path to the output PyTorch model directory.'
     )
     parser.add_argument(
         '--push_to_hub', action='store_true', help='Whether or not to push the converted model to the 🤗 hub.'
     )

     _UpperCAmelCase        =				parser.parse_args()
     convert_audio_spectrogram_transformer_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)








import json
import os
import subprocess
import unittest
from ast import literal_eval

import pytest
from parameterized import parameterized, parameterized_class

from . import is_sagemaker_available


if is_sagemaker_available():
     from sagemaker import Session, TrainingJobAnalytics
     from sagemaker.huggingface import HuggingFace



@pytest.mark.skipif(
    literal_eval(os.getenv('''TEST_SAGEMAKER'''  ,						'''False'''     )     ) is not True  ,						reason='''Skipping test because should only be run when releasing minor transformers version'''  ,						)
@pytest.mark.usefixtures('''sm_env'''     )
@parameterized_class(
    [
        {
            '''framework''': '''pytorch''',
            '''script''': '''run_glue.py''',
            '''model_name_or_path''': '''distilbert-base-cased''',
            '''instance_type''': '''ml.p3.16xlarge''',
            '''results''': {'''train_runtime''': 6_5_0, '''eval_accuracy''': 0.7, '''eval_loss''': 0.6},
        },
        {
            '''framework''': '''pytorch''',
            '''script''': '''run_ddp.py''',
            '''model_name_or_path''': '''distilbert-base-cased''',
            '''instance_type''': '''ml.p3.16xlarge''',
            '''results''': {'''train_runtime''': 6_0_0, '''eval_accuracy''': 0.7, '''eval_loss''': 0.6},
        },
        {
            '''framework''': '''tensorflow''',
            '''script''': '''run_tf_dist.py''',
            '''model_name_or_path''': '''distilbert-base-cased''',
            '''instance_type''': '''ml.p3.16xlarge''',
            '''results''': {'''train_runtime''': 6_0_0, '''eval_accuracy''': 0.6, '''eval_loss''': 0.7},
        },
    ]     )
class 							_UpperCamelCase					(	unittest.TestCase     ):

       def lowercase (		self: Union[str, Any]		)       -> List[str]:




              """simple docstring"""


              if self.framework == "pytorch":
                     subprocess.run(
                         f'''cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py'''.split()					,   encoding="utf-8"					,   check=_SCREAMING_SNAKE_CASE					,   )
              assert hasattr(self					,   "env"		)

       def lowercase (		self: List[str]					,   _SCREAMING_SNAKE_CASE: Dict		)       -> str:




              """simple docstring"""


              UpperCamelCase_          =  f'''{self.env.base_job_name}-{instance_count}-{"ddp" if "ddp" in self.script else "smd"}'''
              # distributed data settings
              UpperCamelCase_          =  {"smdistributed": {"dataparallel": {"enabled": True}}} if self.script != "run_ddp.py" else None

              # creates estimator
              return HuggingFace(
                  entry_point=self.script					,   source_dir=self.env.test_path					,   role=self.env.role					,   image_uri=self.env.image_uri					,   base_job_name=_SCREAMING_SNAKE_CASE					,   instance_count=_SCREAMING_SNAKE_CASE					,   instance_type=self.instance_type					,   debugger_hook_config=_SCREAMING_SNAKE_CASE					,   hyperparameters={**self.env.distributed_hyperparameters, "model_name_or_path": self.model_name_or_path}					,   metric_definitions=self.env.metric_definitions					,   distribution=_SCREAMING_SNAKE_CASE					,   py_version="py36"					,   )

       def lowercase (		self: List[str]					,   _SCREAMING_SNAKE_CASE: Any		)       -> List[Any]:




              """simple docstring"""


              TrainingJobAnalytics(_SCREAMING_SNAKE_CASE		).export_csv(f'''{self.env.test_path}/{job_name}_metrics.csv'''		)



       @parameterized.expand([(2,)]		)
       def lowercase (		self: str					,   _SCREAMING_SNAKE_CASE: Tuple		)       -> Optional[Any]:




              """simple docstring"""


              UpperCamelCase_          =  self.create_estimator(_SCREAMING_SNAKE_CASE		)

              # run training
              estimator.fit()

              # result dataframe
              UpperCamelCase_          =  TrainingJobAnalytics(estimator.latest_training_job.name		).dataframe()

              # extract kpis
              UpperCamelCase_          =  list(result_metrics_df[result_metrics_df.metric_name == "eval_accuracy"]["value"]		)
              UpperCamelCase_          =  list(result_metrics_df[result_metrics_df.metric_name == "eval_loss"]["value"]		)
              # get train time from SageMaker job, this includes starting, preprocessing, stopping
              UpperCamelCase_          =  (
                  Session().describe_training_job(estimator.latest_training_job.name		).get("TrainingTimeInSeconds"					,   999999		)
              )

              # assert kpis
              assert train_runtime <= self.results["train_runtime"]
              assert all(t >= self.results["eval_accuracy"] for t in eval_accuracy		)
              assert all(t <= self.results["eval_loss"] for t in eval_loss		)

              # dump tests result into json file to share in PR
              with open(f'''{estimator.latest_training_job.name}.json'''					,   "w"		) as outfile:
                     json.dump({"train_time": train_runtime, "eval_accuracy": eval_accuracy, "eval_loss": eval_loss}					,   _SCREAMING_SNAKE_CASE		)

