
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()
lowercase_ 				=			logging.get_logger(__name__)


def 							a__					(							snake_case							):





  """simple docstring"""
  __SCREAMING_SNAKE_CASE      :	List[Any]					=		ASTConfig()

  if "10-10" in model_name:
    pass
  elif "speech-commands" in model_name:
    __SCREAMING_SNAKE_CASE      :	Tuple					=		128
  elif "12-12" in model_name:
    __SCREAMING_SNAKE_CASE      :	List[str]					=		12
    __SCREAMING_SNAKE_CASE      :	str					=		12
  elif "14-14" in model_name:
    __SCREAMING_SNAKE_CASE      :	Tuple					=		14
    __SCREAMING_SNAKE_CASE      :	int					=		14
  elif "16-16" in model_name:
    __SCREAMING_SNAKE_CASE      :	List[str]					=		16
    __SCREAMING_SNAKE_CASE      :	Tuple					=		16
  else:
    raise ValueError('''Model not supported'''							)

  __SCREAMING_SNAKE_CASE      :	Union[str, Any]					=		'''huggingface/label-files'''
  if "speech-commands" in model_name:
    __SCREAMING_SNAKE_CASE      :	int					=		35
    __SCREAMING_SNAKE_CASE      :	Tuple					=		'''speech-commands-v2-id2label.json'''
  else:
    __SCREAMING_SNAKE_CASE      :	Union[str, Any]					=		527
    __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		'''audioset-id2label.json'''

  __SCREAMING_SNAKE_CASE      :	Dict					=		json.load(open(hf_hub_download(snake_case       ,			snake_case       ,			repo_type='''dataset'''							)       ,			'''r'''							)							)
  __SCREAMING_SNAKE_CASE      :	int					=		{int(snake_case							): v for k, v in idalabel.items()}
  __SCREAMING_SNAKE_CASE      :	Dict					=		idalabel
  __SCREAMING_SNAKE_CASE      :	List[str]					=		{v: k for k, v in idalabel.items()}

  return config


def 							a__					(							snake_case							):





  """simple docstring"""
  if "module.v" in name:
    __SCREAMING_SNAKE_CASE      :	Any					=		name.replace('''module.v'''       ,			'''audio_spectrogram_transformer'''							)
  if "cls_token" in name:
    __SCREAMING_SNAKE_CASE      :	Optional[int]					=		name.replace('''cls_token'''       ,			'''embeddings.cls_token'''							)
  if "dist_token" in name:
    __SCREAMING_SNAKE_CASE      :	Dict					=		name.replace('''dist_token'''       ,			'''embeddings.distillation_token'''							)
  if "pos_embed" in name:
    __SCREAMING_SNAKE_CASE      :	Dict					=		name.replace('''pos_embed'''       ,			'''embeddings.position_embeddings'''							)
  if "patch_embed.proj" in name:
    __SCREAMING_SNAKE_CASE      :	List[str]					=		name.replace('''patch_embed.proj'''       ,			'''embeddings.patch_embeddings.projection'''							)
  # transformer blocks
  if "blocks" in name:
    __SCREAMING_SNAKE_CASE      :	Any					=		name.replace('''blocks'''       ,			'''encoder.layer'''							)
  if "attn.proj" in name:
    __SCREAMING_SNAKE_CASE      :	Any					=		name.replace('''attn.proj'''       ,			'''attention.output.dense'''							)
  if "attn" in name:
    __SCREAMING_SNAKE_CASE      :	Tuple					=		name.replace('''attn'''       ,			'''attention.self'''							)
  if "norm1" in name:
    __SCREAMING_SNAKE_CASE      :	str					=		name.replace('''norm1'''       ,			'''layernorm_before'''							)
  if "norm2" in name:
    __SCREAMING_SNAKE_CASE      :	Dict					=		name.replace('''norm2'''       ,			'''layernorm_after'''							)
  if "mlp.fc1" in name:
    __SCREAMING_SNAKE_CASE      :	List[str]					=		name.replace('''mlp.fc1'''       ,			'''intermediate.dense'''							)
  if "mlp.fc2" in name:
    __SCREAMING_SNAKE_CASE      :	Dict					=		name.replace('''mlp.fc2'''       ,			'''output.dense'''							)
  # final layernorm
  if "audio_spectrogram_transformer.norm" in name:
    __SCREAMING_SNAKE_CASE      :	Any					=		name.replace('''audio_spectrogram_transformer.norm'''       ,			'''audio_spectrogram_transformer.layernorm'''							)
  # classifier head
  if "module.mlp_head.0" in name:
    __SCREAMING_SNAKE_CASE      :	List[str]					=		name.replace('''module.mlp_head.0'''       ,			'''classifier.layernorm'''							)
  if "module.mlp_head.1" in name:
    __SCREAMING_SNAKE_CASE      :	int					=		name.replace('''module.mlp_head.1'''       ,			'''classifier.dense'''							)

  return name


def 							a__					(							snake_case       ,			snake_case							):





  """simple docstring"""
  for key in orig_state_dict.copy().keys():
    __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		orig_state_dict.pop(snake_case							)

    if "qkv" in key:
      __SCREAMING_SNAKE_CASE      :	List[str]					=		key.split('''.'''							)
      __SCREAMING_SNAKE_CASE      :	Any					=		int(key_split[3]							)
      __SCREAMING_SNAKE_CASE      :	Tuple					=		config.hidden_size
      if "weight" in key:
        __SCREAMING_SNAKE_CASE      :	List[Any]					=		val[:dim, :]
        __SCREAMING_SNAKE_CASE      :	Union[str, Any]					=		val[dim : dim * 2, :]
        __SCREAMING_SNAKE_CASE      :	Dict					=		val[-dim:, :]
      else:
        __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		val[:dim]
        __SCREAMING_SNAKE_CASE      :	List[str]					=		val[dim : dim * 2]
        __SCREAMING_SNAKE_CASE      :	int					=		val[-dim:]
    else:
      __SCREAMING_SNAKE_CASE      :	List[Any]					=		val

  return orig_state_dict


def 							a__					(							snake_case							):





  """simple docstring"""
  __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		[
      '''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(snake_case       ,			snake_case							)


@torch.no_grad()
def 							a__					(							snake_case       ,			snake_case       ,			snake_case=False							):





  """simple docstring"""
  __SCREAMING_SNAKE_CASE      :	List[str]					=		get_audio_spectrogram_transformer_config(snake_case							)

  __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		{
      '''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
  __SCREAMING_SNAKE_CASE      :	int					=		model_name_to_url[model_name]
  __SCREAMING_SNAKE_CASE      :	Optional[int]					=		torch.hub.load_state_dict_from_url(snake_case       ,			map_location='''cpu'''							)
  # remove some keys
  remove_keys(snake_case							)
  # rename some keys
  __SCREAMING_SNAKE_CASE      :	Dict					=		convert_state_dict(snake_case       ,			snake_case							)

  # load 🤗 model
  __SCREAMING_SNAKE_CASE      :	Any					=		ASTForAudioClassification(snake_case							)
  model.eval()

  model.load_state_dict(snake_case							)

  # verify outputs on dummy input
  # source: https://github.com/YuanGongND/ast/blob/79e873b8a54d0a3b330dd522584ff2b9926cd581/src/run.py#L62
  __SCREAMING_SNAKE_CASE      :	Tuple					=		-4.267_7393 if '''speech-commands''' not in model_name else -6.84_5978
  __SCREAMING_SNAKE_CASE      :	Tuple					=		4.568_9974 if '''speech-commands''' not in model_name else 5.565_4526
  __SCREAMING_SNAKE_CASE      :	Dict					=		1_024 if '''speech-commands''' not in model_name else 128
  __SCREAMING_SNAKE_CASE      :	List[Any]					=		ASTFeatureExtractor(mean=snake_case       ,			std=snake_case       ,			max_length=snake_case							)

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

    __SCREAMING_SNAKE_CASE,		__SCREAMING_SNAKE_CASE      :	List[Any]					=		torchaudio.load(snake_case							)
    __SCREAMING_SNAKE_CASE      :	str					=		waveform.squeeze().numpy()

  __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		feature_extractor(snake_case       ,			sampling_rate=16_000       ,			return_tensors='''pt'''							)

  # forward pass
  __SCREAMING_SNAKE_CASE      :	str					=		model(**snake_case							)
  __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		outputs.logits

  if model_name == "ast-finetuned-audioset-10-10-0.4593":
    __SCREAMING_SNAKE_CASE      :	List[Any]					=		torch.tensor([-0.8760, -7.0042, -8.6602]							)
  elif model_name == "ast-finetuned-audioset-10-10-0.450":
    __SCREAMING_SNAKE_CASE      :	Tuple					=		torch.tensor([-1.1986, -7.0903, -8.2718]							)
  elif model_name == "ast-finetuned-audioset-10-10-0.448":
    __SCREAMING_SNAKE_CASE      :	Optional[int]					=		torch.tensor([-2.6128, -8.0080, -9.4344]							)
  elif model_name == "ast-finetuned-audioset-10-10-0.448-v2":
    __SCREAMING_SNAKE_CASE      :	Tuple					=		torch.tensor([-1.5080, -7.4534, -8.8917]							)
  elif model_name == "ast-finetuned-audioset-12-12-0.447":
    __SCREAMING_SNAKE_CASE      :	Union[str, Any]					=		torch.tensor([-0.5050, -6.5833, -8.0843]							)
  elif model_name == "ast-finetuned-audioset-14-14-0.443":
    __SCREAMING_SNAKE_CASE      :	Optional[int]					=		torch.tensor([-0.3826, -7.0336, -8.2413]							)
  elif model_name == "ast-finetuned-audioset-16-16-0.442":
    __SCREAMING_SNAKE_CASE      :	str					=		torch.tensor([-1.2113, -6.9101, -8.3470]							)
  elif model_name == "ast-finetuned-speech-commands-v2":
    __SCREAMING_SNAKE_CASE      :	Any					=		torch.tensor([6.1589, -8.0566, -8.7984]							)
  else:
    raise ValueError('''Unknown model name'''							)
  if not torch.allclose(logits[0, :3]       ,			snake_case       ,			atol=1E-4							):
    raise ValueError('''Logits don\'t match'''							)
  print('''Looks ok!'''							)

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

  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__":
   lowercase_ 				=			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."""
   )

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







_lowercase		:  Any			       ={"""a""": ["""c""", """b"""], """b""": ["""d""", """e"""], """c""": [], """d""": [], """e""": []}
_lowercase		:  Union[str, Any]			       =["""a""", """b""", """c""", """d""", """e"""]


def 		_SCREAMING_SNAKE_CASE     ( lowerCAmelCase__							,lowerCAmelCase__							,lowerCAmelCase__						):
		lowerCamelCase_	:     int 						=      start
		# add current to visited
		visited.append(lowerCAmelCase__						)
		lowerCamelCase_	:     Optional[int] 						=      edges[current]
		for neighbor in neighbors:
				# if neighbor not in visited, visit
				if neighbor not in visited:
						lowerCamelCase_	:     Dict 						=      topological_sort(lowerCAmelCase__							,lowerCAmelCase__							,lowerCAmelCase__						)
    # if all neighbors visited add current to sort
		sort.append(lowerCAmelCase__						)
		# if all vertices haven't been visited select a new one to visit
		if len(lowerCAmelCase__						) != len(lowerCAmelCase__						):
				for vertice in vertices:
						if vertice not in visited:
								lowerCamelCase_	:     Any 						=      topological_sort(lowerCAmelCase__							,lowerCAmelCase__							,lowerCAmelCase__						)
    # return sort
		return sort


if __name__ == "__main__":
		_lowercase		:  str			       =topological_sort("""a""", [], [])
		print(sort)
