


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()
A				:       Union[str, Any]      =  logging.get_logger(__name__)





def 						_lowerCAmelCase							(     _lowerCAmelCase			)    ->						Tuple:


						'''simple docstring'''






						__snake_case				=		ASTConfig()

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

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

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

						return config





def 						_lowerCAmelCase							(     _lowerCAmelCase			)    ->						Optional[int]:


						'''simple docstring'''






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

						return name





def 						_lowerCAmelCase							(     _lowerCAmelCase   ,						_lowerCAmelCase			)    ->						Tuple:


						'''simple docstring'''






						for key in orig_state_dict.copy().keys():
												__snake_case				=		orig_state_dict.pop(_lowerCAmelCase			)

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

						return orig_state_dict





def 						_lowerCAmelCase							(     _lowerCAmelCase			)    ->						List[str]:


						'''simple docstring'''






						__snake_case				=		[
						    "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(_lowerCAmelCase   ,						_lowerCAmelCase			)





@torch.no_grad()
def 						_lowerCAmelCase							(     _lowerCAmelCase   ,						_lowerCAmelCase   ,						_lowerCAmelCase=False			)    ->						str:


						'''simple docstring'''






						__snake_case				=		get_audio_spectrogram_transformer_config(_lowerCAmelCase			)

						__snake_case				=		{
						    "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
						__snake_case				=		model_name_to_url[model_name]
						__snake_case				=		torch.hub.load_state_dict_from_url(_lowerCAmelCase   ,						map_location="cpu"			)
						# remove some keys
						remove_keys(_lowerCAmelCase			)
						# rename some keys
						__snake_case				=		convert_state_dict(_lowerCAmelCase   ,						_lowerCAmelCase			)

						# load 🤗 model
						__snake_case				=		ASTForAudioClassification(_lowerCAmelCase			)
						model.eval()

						model.load_state_dict(_lowerCAmelCase			)

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

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

												__snake_case		,       __snake_case				=		torchaudio.load(_lowerCAmelCase			)
												__snake_case				=		waveform.squeeze().numpy()

						__snake_case				=		feature_extractor(_lowerCAmelCase   ,						sampling_rate=1_6000   ,						return_tensors="pt"			)

						# forward pass
						__snake_case				=		model(**_lowerCAmelCase			)
						__snake_case				=		outputs.logits

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

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

						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__":
	A				:       Optional[Any]      =  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.'
	)

	A				:       str      =  parser.parse_args()
	convert_audio_spectrogram_transformer_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)









import unittest

import numpy as np

from transformers.testing_utils import require_torch, require_vision
from transformers.utils import is_torch_available, is_vision_available

from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs


if is_torch_available():
	import torch

if is_vision_available():
	from PIL import Image

	from transformers import PoolFormerImageProcessor






class      UpperCamelCase(	unittest.TestCase ):


					def __init__(    self						:		Tuple  ,     SCREAMING_SNAKE_CASE						:		List[Any]  ,     SCREAMING_SNAKE_CASE						:		Optional[Any]=7  ,     SCREAMING_SNAKE_CASE						:		Dict=3  ,     SCREAMING_SNAKE_CASE						:		Any=3_0  ,     SCREAMING_SNAKE_CASE						:		List[str]=4_0_0  ,     SCREAMING_SNAKE_CASE						:		Any=True  ,     SCREAMING_SNAKE_CASE						:		List[Any]=None  ,     SCREAMING_SNAKE_CASE						:		int=0.9  ,     SCREAMING_SNAKE_CASE						:		Tuple=None  ,     SCREAMING_SNAKE_CASE						:		int=True  ,     SCREAMING_SNAKE_CASE						:		Union[str, Any]=[0.5, 0.5, 0.5]  ,     SCREAMING_SNAKE_CASE						:		Optional[Any]=[0.5, 0.5, 0.5]  ,     )      ->						Union[str, Any]:




											'''simple docstring'''

											__snake_case				=		size if size is not None else {"shortest_edge": 3_0}
											__snake_case				=		crop_size if crop_size is not None else {"height": 3_0, "width": 3_0}
											__snake_case				=		parent
											__snake_case				=		batch_size
											__snake_case				=		num_channels
											__snake_case				=		min_resolution
											__snake_case				=		max_resolution
											__snake_case				=		do_resize_and_center_crop
											__snake_case				=		size
											__snake_case				=		crop_pct
											__snake_case				=		crop_size
											__snake_case				=		do_normalize
											__snake_case				=		image_mean
											__snake_case				=		image_std






					def 				SCREAMING_SNAKE_CASE_	(    self						:		str    )      ->						Any:




											'''simple docstring'''

											return {
											    "size": self.size,
											    "do_resize_and_center_crop": self.do_resize_and_center_crop,
											    "crop_pct": self.crop_pct,
											    "crop_size": self.crop_size,
											    "do_normalize": self.do_normalize,
											    "image_mean": self.image_mean,
											    "image_std": self.image_std,
											}






@require_torch
@require_vision
class      UpperCamelCase(	_a  ,				unittest.TestCase ):
					snake_case_		:					List[str]    					=						PoolFormerImageProcessor if is_vision_available() else None


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




											'''simple docstring'''

											__snake_case				=		PoolFormerImageProcessingTester(self    )


					@property
					def 				SCREAMING_SNAKE_CASE_	(    self						:		int    )      ->						Dict:




											'''simple docstring'''

											return self.image_processor_tester.prepare_image_processor_dict()


					def 				SCREAMING_SNAKE_CASE_	(    self						:		Dict    )      ->						List[str]:




											'''simple docstring'''

											__snake_case				=		self.image_processing_class(**self.image_processor_dict    )
											self.assertTrue(hasattr(SCREAMING_SNAKE_CASE  ,     "do_resize_and_center_crop"    )    )
											self.assertTrue(hasattr(SCREAMING_SNAKE_CASE  ,     "size"    )    )
											self.assertTrue(hasattr(SCREAMING_SNAKE_CASE  ,     "crop_pct"    )    )
											self.assertTrue(hasattr(SCREAMING_SNAKE_CASE  ,     "do_normalize"    )    )
											self.assertTrue(hasattr(SCREAMING_SNAKE_CASE  ,     "image_mean"    )    )
											self.assertTrue(hasattr(SCREAMING_SNAKE_CASE  ,     "image_std"    )    )


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




											'''simple docstring'''

											__snake_case				=		self.image_processing_class.from_dict(self.image_processor_dict    )
											self.assertEqual(image_processor.size  ,     {"shortest_edge": 3_0}    )
											self.assertEqual(image_processor.crop_size  ,     {"height": 3_0, "width": 3_0}    )

											__snake_case				=		self.image_processing_class.from_dict(self.image_processor_dict  ,     size=4_2  ,     crop_size=8_4    )
											self.assertEqual(image_processor.size  ,     {"shortest_edge": 4_2}    )
											self.assertEqual(image_processor.crop_size  ,     {"height": 8_4, "width": 8_4}    )


					def 				SCREAMING_SNAKE_CASE_	(    self						:		Optional[int]    )      ->						List[Any]:




											'''simple docstring'''

											pass


					def 				SCREAMING_SNAKE_CASE_	(    self						:		Optional[Any]    )      ->						Dict:




											'''simple docstring'''

											__snake_case				=		self.image_processing_class(**self.image_processor_dict    )
											# create random PIL images
											__snake_case				=		prepare_image_inputs(self.image_processor_tester  ,     equal_resolution=SCREAMING_SNAKE_CASE    )
											for image in image_inputs:
																	self.assertIsInstance(SCREAMING_SNAKE_CASE  ,     Image.Image    )

											# Test not batched input
											__snake_case				=		image_processing(image_inputs[0]  ,     return_tensors="pt"    ).pixel_values

											self.assertEqual(
											    encoded_images.shape  ,     (
											        1,
											        self.image_processor_tester.num_channels,
											        self.image_processor_tester.crop_size["height"],
											        self.image_processor_tester.crop_size["width"],
											    )  ,     )

											# Test batched
											__snake_case				=		image_processing(SCREAMING_SNAKE_CASE  ,     return_tensors="pt"    ).pixel_values
											self.assertEqual(
											    encoded_images.shape  ,     (
											        self.image_processor_tester.batch_size,
											        self.image_processor_tester.num_channels,
											        self.image_processor_tester.crop_size["height"],
											        self.image_processor_tester.crop_size["width"],
											    )  ,     )


					def 				SCREAMING_SNAKE_CASE_	(    self						:		Optional[Any]    )      ->						Optional[int]:




											'''simple docstring'''

											__snake_case				=		self.image_processing_class(**self.image_processor_dict    )
											# create random numpy tensors
											__snake_case				=		prepare_image_inputs(self.image_processor_tester  ,     equal_resolution=SCREAMING_SNAKE_CASE  ,     numpify=SCREAMING_SNAKE_CASE    )
											for image in image_inputs:
																	self.assertIsInstance(SCREAMING_SNAKE_CASE  ,     np.ndarray    )

											# Test not batched input
											__snake_case				=		image_processing(image_inputs[0]  ,     return_tensors="pt"    ).pixel_values
											self.assertEqual(
											    encoded_images.shape  ,     (
											        1,
											        self.image_processor_tester.num_channels,
											        self.image_processor_tester.crop_size["height"],
											        self.image_processor_tester.crop_size["width"],
											    )  ,     )

											# Test batched
											__snake_case				=		image_processing(SCREAMING_SNAKE_CASE  ,     return_tensors="pt"    ).pixel_values
											self.assertEqual(
											    encoded_images.shape  ,     (
											        self.image_processor_tester.batch_size,
											        self.image_processor_tester.num_channels,
											        self.image_processor_tester.crop_size["height"],
											        self.image_processor_tester.crop_size["width"],
											    )  ,     )






					def 				SCREAMING_SNAKE_CASE_	(    self						:		Optional[int]    )      ->						Union[str, Any]:




											'''simple docstring'''

											__snake_case				=		self.image_processing_class(**self.image_processor_dict    )
											# create random PyTorch tensors
											__snake_case				=		prepare_image_inputs(self.image_processor_tester  ,     equal_resolution=SCREAMING_SNAKE_CASE  ,     torchify=SCREAMING_SNAKE_CASE    )
											for image in image_inputs:
																	self.assertIsInstance(SCREAMING_SNAKE_CASE  ,     torch.Tensor    )

											# Test not batched input
											__snake_case				=		image_processing(image_inputs[0]  ,     return_tensors="pt"    ).pixel_values
											self.assertEqual(
											    encoded_images.shape  ,     (
											        1,
											        self.image_processor_tester.num_channels,
											        self.image_processor_tester.crop_size["height"],
											        self.image_processor_tester.crop_size["width"],
											    )  ,     )

											# Test batched
											__snake_case				=		image_processing(SCREAMING_SNAKE_CASE  ,     return_tensors="pt"    ).pixel_values
											self.assertEqual(
											    encoded_images.shape  ,     (
											        self.image_processor_tester.batch_size,
											        self.image_processor_tester.num_channels,
											        self.image_processor_tester.crop_size["height"],
											        self.image_processor_tester.crop_size["width"],
											    )  ,     )





