




'''simple docstring'''



import argparse
import os
from functools import reduce

import fairseq
import torch
from datasets import load_dataset

from transformers import WavaVecaProcessor, logging
from transformers.models.dataavec.configuration_dataavec_audio import DataaVecAudioConfig

# Copied from https://github.com/pytorch/fairseq/blob/main/examples/data2vec/models/data2vec_audio.py
from transformers.models.dataavec.dataavec_audio import DataaVecAudioModel as Dummy  # noqa: F401
from transformers.models.dataavec.modeling_dataavec_audio import DataaVecAudioForCTC, DataaVecAudioModel


logging.set_verbosity_info()
UpperCAmelCase_				:     Optional[int]     			=						logging.get_logger(__name__)

UpperCAmelCase_				:     Dict     			=						{
    '''post_extract_proj''': '''feature_projection.projection''',
    '''models.0.layer_norm''': '''feature_projection.layer_norm''',
    '''self_attn.k_proj''': '''encoder.layers.*.attention.k_proj''',
    '''self_attn.v_proj''': '''encoder.layers.*.attention.v_proj''',
    '''self_attn.q_proj''': '''encoder.layers.*.attention.q_proj''',
    '''self_attn.out_proj''': '''encoder.layers.*.attention.out_proj''',
    '''self_attn_layer_norm''': '''encoder.layers.*.layer_norm''',
    '''fc1''': '''encoder.layers.*.feed_forward.intermediate_dense''',
    '''fc2''': '''encoder.layers.*.feed_forward.output_dense''',
    '''final_layer_norm''': '''encoder.layers.*.final_layer_norm''',
    '''encoder.layer_norm''': '''encoder.layer_norm''',
    '''w2v_model.layer_norm''': '''feature_projection.layer_norm''',
    '''w2v_encoder.proj''': '''lm_head''',
    '''mask_emb''': '''masked_spec_embed''',
}
UpperCAmelCase_				:     str     			=						[
    '''lm_head''',
]







def 	_UpperCamelCase       (_lowerCamelCase							:   int      ,		_lowerCamelCase							:   Optional[int]      ,		_lowerCamelCase							:   List[Any]      ,		_lowerCamelCase							:   Any      ,		_lowerCamelCase							:   List[Any]		)->      Optional[Any]:




     '''simple docstring'''





     for attribute in key.split('''.'''		):
          __snake_case			    =     getattr(__UpperCAmelCase      ,		__UpperCAmelCase		)

     if weight_type is not None:
          __snake_case			    =     getattr(__UpperCAmelCase      ,		__UpperCAmelCase		).shape
     else:
          __snake_case			    =     hf_pointer.shape

     if hf_shape != value.shape:
          raise ValueError(
              f'''Shape of hf {key + "." + weight_type if weight_type is not None else ""} is {hf_shape}, but should be'''
              f''' {value.shape} for {full_name}'''		)

     if weight_type == "weight":
          __snake_case			    =     value
     elif weight_type == "weight_g":
          __snake_case			    =     value
     elif weight_type == "weight_v":
          __snake_case			    =     value
     elif weight_type == "bias":
          __snake_case			    =     value
     else:
          __snake_case			    =     value

     logger.info(f'''{key + "." + weight_type if weight_type is not None else ""} was initialized from {full_name}.'''		)







def 	_UpperCamelCase       (_lowerCamelCase							:   int      ,		_lowerCamelCase							:   Union[str, Any]      ,		_lowerCamelCase							:   int		)->      int:




     '''simple docstring'''





     __snake_case			    =     []
     __snake_case			    =     fairseq_model.state_dict()

     if not is_headless:
          __snake_case			    =     hf_model.dataavec_audio.feature_extractor
          __snake_case			    =     hf_model.dataavec_audio.encoder.pos_conv_embed

     else:
          __snake_case			    =     hf_model.feature_extractor
          __snake_case			    =     hf_model.encoder.pos_conv_embed

     for name, value in fairseq_dict.items():
          __snake_case			    =     False
          if "conv_layers" in name:
               load_conv_layer(
                   __UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase      ,		)
               __snake_case			    =     True
          elif "pos_conv" in name:
               load_pos_conv_layer(
                   __UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase      ,		)
               __snake_case			    =     True
          else:
               for key, mapped_key in MAPPING.items():
                    if not is_headless:
                         __snake_case			    =     '''data2vec_audio.''' + mapped_key if mapped_key not in TOP_LEVEL_KEYS else mapped_key
                    if key in name or key.split('''w2v_model.'''		)[-1] == name.split('''.'''		)[0]:
                         __snake_case			    =     True
                         if "*" in mapped_key:
                              __snake_case			    =     name.split(__UpperCAmelCase		)[0].split('''.'''		)[-2]
                              __snake_case			    =     mapped_key.replace('''*'''      ,		__UpperCAmelCase		)
                         if "weight_g" in name:
                              __snake_case			    =     '''weight_g'''
                         elif "weight_v" in name:
                              __snake_case			    =     '''weight_v'''
                         elif "bias" in name:
                              __snake_case			    =     '''bias'''
                         elif "weight" in name:
                              # TODO: don't match quantizer.weight_proj
                              __snake_case			    =     '''weight'''
                         else:
                              __snake_case			    =     None
                         set_recursively(__UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase		)
                    continue
          if not is_used:
               unused_weights.append(__UpperCAmelCase		)

     logger.warning(f'''Unused weights: {unused_weights}'''		)







def 	_UpperCamelCase       (_lowerCamelCase							:   Any      ,		_lowerCamelCase							:   str		)->      Dict:




     '''simple docstring'''





     __snake_case			    =     path.split('''.'''		)
     return reduce(__UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase		)







def 	_UpperCamelCase       (_lowerCamelCase							:   List[str]      ,		_lowerCamelCase							:   Any      ,		_lowerCamelCase							:   int      ,		_lowerCamelCase							:   str		)->      str:




     '''simple docstring'''





     __snake_case			    =     access_by_string(__UpperCAmelCase      ,		__UpperCAmelCase		)
     __snake_case			    =     hf_weight.data

     if fsq_value.shape != hf_value.shape:
          raise ValueError(f'''{full_name} has size {fsq_value.shape}, but {hf_value.shape} was found.'''		)
     __snake_case			    =     fsq_value
     logger.info(f'''{full_name} was correctly initialized from {hf_weight_path}.'''		)







def 	_UpperCamelCase       (_lowerCamelCase							:   Optional[int]      ,		_lowerCamelCase							:   Optional[int]      ,		_lowerCamelCase							:   int      ,		_lowerCamelCase							:   str		)->      Any:




     '''simple docstring'''





     __snake_case			    =     full_name.split('''conv_layers.'''		)[-1]
     __snake_case			    =     name.split('''.'''		)
     __snake_case			    =     int(items[0]		)
     __snake_case			    =     int(items[1]		)

     __snake_case			    =     name.split('''.'''		)[-1]
     if type_id == 0:
          __snake_case			    =     '''conv'''
     elif type_id == 2:
          __snake_case			    =     '''layer_norm'''
     else:
          unused_weights.append(__UpperCAmelCase		)
          return

     set_weights(__UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase      ,		f'''conv_layers.{layer_id}.{layer_type}.{weight_type}'''		)







def 	_UpperCamelCase       (_lowerCamelCase							:   List[str]      ,		_lowerCamelCase							:   Tuple      ,		_lowerCamelCase							:   List[Any]      ,		_lowerCamelCase							:   Union[str, Any]		)->      List[str]:




     '''simple docstring'''





     __snake_case			    =     full_name.split('''pos_conv.'''		)[-1]
     __snake_case			    =     name.split('''.'''		)
     __snake_case			    =     int(items[0]		)
     __snake_case			    =     int(items[1]		)

     __snake_case			    =     name.split('''.'''		)[-1]
     if type_id != 0:
          unused_weights.append(__UpperCAmelCase		)
          return
     else:
          __snake_case			    =     '''conv'''

     set_weights(__UpperCAmelCase      ,		__UpperCAmelCase      ,		__UpperCAmelCase      ,		f'''layers.{layer_id}.{layer_type}.{weight_type}'''		)







@torch.no_grad()
def 	_UpperCamelCase       (_lowerCamelCase							:   List[Any]      ,		_lowerCamelCase							:   str      ,		_lowerCamelCase							:   str=None      ,		_lowerCamelCase							:   Optional[Any]=None      ,		_lowerCamelCase							:   Tuple=True		)->      Tuple:




     '''simple docstring'''





     if config_path is not None:
          __snake_case			    =     DataaVecAudioConfig.from_pretrained(__UpperCAmelCase		)
     else:
          __snake_case			    =     DataaVecAudioConfig()

     if not is_finetuned:
          # Modify final_proj layer name
          __snake_case			    =     DataaVecAudioModel(__UpperCAmelCase		)
          __snake_case			    =     os.path.dirname(__UpperCAmelCase		)

          __snake_case			    =     torch.load(__UpperCAmelCase		)
          __snake_case			    =     state_dict['''model'''].pop('''final_proj.0.weight'''		)
          __snake_case			    =     state_dict['''model'''].pop('''final_proj.0.bias'''		)
          __snake_case			    =     os.path.join(__UpperCAmelCase      ,		'''converted.pt'''		)
          torch.save(__UpperCAmelCase      ,		__UpperCAmelCase		)
     else:
          __snake_case			    =     DataaVecAudioForCTC(__UpperCAmelCase		)
          __snake_case			    =     checkpoint_path

     def load_dataavec(_lowerCamelCase							:   List[str]		):
          __snake_case    ,			__snake_case    ,			__snake_case			    =     fairseq.checkpoint_utils.load_model_ensemble_and_task([path]		)
          return model[0].eval()

     __snake_case			    =     load_dataavec(__UpperCAmelCase		)

     recursively_load_weights(__UpperCAmelCase      ,		__UpperCAmelCase      ,		not is_finetuned		)

     __snake_case			    =     WavaVecaProcessor.from_pretrained('''facebook/wav2vec2-large-lv60'''		)

     __snake_case			    =     load_dataset('''patrickvonplaten/librispeech_asr_dummy'''      ,		'''clean'''      ,		split='''validation'''		)
     __snake_case			    =     [x['''array'''] for x in ds[:4]['''audio''']]

     __snake_case			    =     processor(__UpperCAmelCase      ,		return_tensors='''pt'''      ,		padding=__UpperCAmelCase		)

     __snake_case			    =     inputs.input_values
     __snake_case			    =     inputs.attention_mask
     #    input_values = inputs.input_values[:, :-1]
     #    attention_mask = inputs.attention_mask[:, :-1]

     hf_wavavec.eval()
     model.eval()
     if is_finetuned:
          __snake_case			    =     model(source=__UpperCAmelCase      ,		padding_mask=(1 - attention_mask)      ,		mask=__UpperCAmelCase      ,		features_only=__UpperCAmelCase		)[
              '''encoder_out'''
          ].transpose(0      ,		1		)
          __snake_case			    =     hf_wavavec(__UpperCAmelCase      ,		attention_mask=__UpperCAmelCase		)['''logits''']

          __snake_case			    =     torch.argmax(__UpperCAmelCase      ,		dim=-1		)
          __snake_case			    =     processor.batch_decode(__UpperCAmelCase		)

          print(f'''Expected Output: {ds[:4]["text"]}, Pred: {output_string}'''		)
     else:
          __snake_case			    =     model(source=__UpperCAmelCase      ,		padding_mask=(1 - attention_mask)      ,		mask=__UpperCAmelCase      ,		features_only=__UpperCAmelCase		)[
              '''layer_results'''
          ][-1][0].transpose(0      ,		1		)
          __snake_case			    =     hf_wavavec(__UpperCAmelCase      ,		attention_mask=__UpperCAmelCase		)['''last_hidden_state''']

     print(our_output.shape      ,		their_output.shape		)
     __snake_case			    =     torch.max(torch.abs(our_output - their_output		)		).item()
     print(f'''max_absolute_diff = {max_absolute_diff}'''		)  # ~ 1e-7
     __snake_case			    =     torch.allclose(__UpperCAmelCase      ,		__UpperCAmelCase      ,		atol=1E-3		)
     print('''Do both models output the same tensors?'''      ,		'''🔥''' if success else '''💩'''		)
     if not success:
          raise Exception('''Something went wRoNg'''		)

     hf_wavavec.save_pretrained(__UpperCAmelCase		)

     if is_finetuned:
          processor.save_pretrained(__UpperCAmelCase		)
     else:
          processor.feature_extractor.save_pretrained(__UpperCAmelCase		)


if __name__ == "__main__":
     UpperCAmelCase_				:     Optional[int]     			=						argparse.ArgumentParser()
     parser.add_argument('''--pytorch_dump_folder_path''', default=None, type=str, help='''Path to the output PyTorch model.''')
     parser.add_argument('''--checkpoint_path''', default=None, type=str, help='''Path to fairseq checkpoint''')
     parser.add_argument('''--dict_path''', default=None, type=str, help='''Path to dict of fine-tuned model''')
     parser.add_argument('''--config_path''', default=None, type=str, help='''Path to hf config.json of model to convert''')
     parser.add_argument(
         '''--not_finetuned''', action='''store_true''', help='''Whether the model to convert is a fine-tuned model or not'''
     )
     UpperCAmelCase_				:     Union[str, Any]     			=						parser.parse_args()
     convert_wavaveca_checkpoint(
         args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path, args.dict_path, not args.not_finetuned
     )











def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) * 9 / 5) + 32							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round(float(__UpperCAmelCase	) + 273.15							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) * 9 / 5) + 491.67							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) - 32) * 5 / 9							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round(((float(__UpperCAmelCase	) - 32) * 5 / 9) + 273.15							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round(float(__UpperCAmelCase	) + 459.67							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round(float(__UpperCAmelCase	) - 273.15							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round(((float(__UpperCAmelCase	) - 273.15) * 9 / 5) + 32							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) * 9 / 5)							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) - 491.67) * 5 / 9							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round(float(__UpperCAmelCase	) - 459.67							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) * 5 / 9)							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) * 1.25 + 273.15)							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) * 2.25 + 32)							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) * 1.25)							,					__UpperCAmelCase	)







def 				A			(		__UpperCAmelCase							,					__UpperCAmelCase = 2	)       ->       float:



						'''simple docstring'''






						return round((float(__UpperCAmelCase	) * 2.25 + 32 + 459.67)							,					__UpperCAmelCase	)


if __name__ == "__main__":
							import doctest

							doctest.testmod()





