




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()
__lowerCAmelCase						:							List[Any]			     =						logging.get_logger(__name__)

__lowerCAmelCase						:							Optional[int]			     =						{
    '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',
}
__lowerCAmelCase						:							int			     =						[
    'lm_head',
]




def      __magic_name__							(					A						:   str,    A						:   Optional[int],    A						:   str,    A						:   Optional[int],    A						:   Union[str, Any]  ):






			'''simple docstring'''







			for attribute in key.split("."  ):
						a       =     getattr(A,    A  )

			if weight_type is not None:
						a       =     getattr(A,    A  ).shape
			else:
						a       =     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":
						a       =     value
			elif weight_type == "weight_g":
						a       =     value
			elif weight_type == "weight_v":
						a       =     value
			elif weight_type == "bias":
						a       =     value
			else:
						a       =     value

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




def      __magic_name__							(					A						:   str,    A						:   Optional[Any],    A						:   Union[str, Any]  ):






			'''simple docstring'''







			a       =     []
			a       =     fairseq_model.state_dict()

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

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

			for name, value in fairseq_dict.items():
						a       =     False
						if "conv_layers" in name:
									load_conv_layer(
									    A,    A,    A,    A,    )
									a       =     True
						elif "pos_conv" in name:
									load_pos_conv_layer(
									    A,    A,    A,    A,    )
									a       =     True
						else:
									for key, mapped_key in MAPPING.items():
												if not is_headless:
															a       =     "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]:
															a       =     True
															if "*" in mapped_key:
																		a       =     name.split(A  )[0].split("."  )[-2]
																		a       =     mapped_key.replace("*",    A  )
															if "weight_g" in name:
																		a       =     "weight_g"
															elif "weight_v" in name:
																		a       =     "weight_v"
															elif "bias" in name:
																		a       =     "bias"
															elif "weight" in name:
																		# TODO: don't match quantizer.weight_proj
																		a       =     "weight"
															else:
																		a       =     None
															set_recursively(A,    A,    A,    A,    A  )
												continue
						if not is_used:
									unused_weights.append(A  )

			logger.warning(F"""Unused weights: {unused_weights}"""  )




def      __magic_name__							(					A						:   List[Any],    A						:   Any  ):






			'''simple docstring'''







			a       =     path.split("."  )
			return reduce(A,    A,    A  )




def      __magic_name__							(					A						:   Dict,    A						:   Dict,    A						:   List[Any],    A						:   Optional[int]  ):






			'''simple docstring'''







			a       =     access_by_string(A,    A  )
			a       =     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."""  )
			a       =     fsq_value
			logger.info(F"""{full_name} was correctly initialized from {hf_weight_path}."""  )




def      __magic_name__							(					A						:   List[Any],    A						:   List[str],    A						:   Optional[int],    A						:   List[str]  ):






			'''simple docstring'''







			a       =     full_name.split("conv_layers."  )[-1]
			a       =     name.split("."  )
			a       =     int(items[0]  )
			a       =     int(items[1]  )

			a       =     name.split("."  )[-1]
			if type_id == 0:
						a       =     "conv"
			elif type_id == 2:
						a       =     "layer_norm"
			else:
						unused_weights.append(A  )
						return

			set_weights(A,    A,    A,    F"""conv_layers.{layer_id}.{layer_type}.{weight_type}"""  )




def      __magic_name__							(					A						:   Any,    A						:   Union[str, Any],    A						:   int,    A						:   Union[str, Any]  ):






			'''simple docstring'''







			a       =     full_name.split("pos_conv."  )[-1]
			a       =     name.split("."  )
			a       =     int(items[0]  )
			a       =     int(items[1]  )

			a       =     name.split("."  )[-1]
			if type_id != 0:
						unused_weights.append(A  )
						return
			else:
						a       =     "conv"

			set_weights(A,    A,    A,    F"""layers.{layer_id}.{layer_type}.{weight_type}"""  )




@torch.no_grad()
def      __magic_name__							(					A						:   List[str],    A						:   str,    A						:   Dict=None,    A						:   Optional[Any]=None,    A						:   Tuple=True  ):






			'''simple docstring'''







			if config_path is not None:
						a       =     DataaVecAudioConfig.from_pretrained(A  )
			else:
						a       =     DataaVecAudioConfig()

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

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

			def load_dataavec(A						:   List[Any]  ):
						a       ,						a       ,						a       =     fairseq.checkpoint_utils.load_model_ensemble_and_task([path]  )
						return model[0].eval()

			a       =     load_dataavec(A  )

			recursively_load_weights(A,    A,    not is_finetuned  )

			a       =     WavaVecaProcessor.from_pretrained("facebook/wav2vec2-large-lv60"  )

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

			a       =     processor(A,    return_tensors="pt",    padding=A  )

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

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

						a       =     torch.argmax(A,    dim=-1  )
						a       =     processor.batch_decode(A  )

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

			print(our_output.shape,    their_output.shape  )
			a       =     torch.max(torch.abs(our_output - their_output  )  ).item()
			print(F"""max_absolute_diff = {max_absolute_diff}"""  )  # ~ 1e-7
			a       =     torch.allclose(A,    A,    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(A  )

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


if __name__ == "__main__":
		__lowerCAmelCase						:							Any			     =						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'
		)
		__lowerCAmelCase						:							List[str]			     =						parser.parse_args()
		convert_wavaveca_checkpoint(
		    args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path, args.dict_path, not args.not_finetuned
		)












import datasets

from .evaluate import (
    apply_no_ans_threshold,
    find_all_best_thresh,
    get_raw_scores,
    make_eval_dict,
    make_qid_to_has_ans,
    merge_eval,
)


__lowerCAmelCase						:							Optional[int]			     =						'\\n@inproceedings{Rajpurkar2016SQuAD10,\n  title={SQuAD: 100, 000+ Questions for Machine Comprehension of Text},\n  author={Pranav Rajpurkar and Jian Zhang and Konstantin Lopyrev and Percy Liang},\n  booktitle={EMNLP},\n  year={2016}\n}\n'

__lowerCAmelCase						:							str			     =						'\nThis metric wrap the official scoring script for version 2 of the Stanford Question\nAnswering Dataset (SQuAD).\n\nStanford Question Answering Dataset (SQuAD) is a reading comprehension dataset, consisting of questions posed by\ncrowdworkers on a set of Wikipedia articles, where the answer to every question is a segment of text, or span,\nfrom the corresponding reading passage, or the question might be unanswerable.\n\nSQuAD2.0 combines the 100,000 questions in SQuAD1.1 with over 50,000 unanswerable questions\nwritten adversarially by crowdworkers to look similar to answerable ones.\nTo do well on SQuAD2.0, systems must not only answer questions when possible, but also\ndetermine when no answer is supported by the paragraph and abstain from answering.\n'

__lowerCAmelCase						:							Optional[Any]			     =						'\nComputes SQuAD v2 scores (F1 and EM).\nArgs:\n    predictions: List of triple for question-answers to score with the following elements:\n        - the question-answer \'id\' field as given in the references (see below)\n        - the text of the answer\n        - the probability that the question has no answer\n    references: List of question-answers dictionaries with the following key-values:\n            - \'id\': id of the question-answer pair (see above),\n            - \'answers\': a list of Dict {\'text\': text of the answer as a string}\n    no_answer_threshold: float\n        Probability threshold to decide that a question has no answer.\nReturns:\n    \'exact\': Exact match (the normalized answer exactly match the gold answer)\n    \'f1\': The F-score of predicted tokens versus the gold answer\n    \'total\': Number of score considered\n    \'HasAns_exact\': Exact match (the normalized answer exactly match the gold answer)\n    \'HasAns_f1\': The F-score of predicted tokens versus the gold answer\n    \'HasAns_total\': Number of score considered\n    \'NoAns_exact\': Exact match (the normalized answer exactly match the gold answer)\n    \'NoAns_f1\': The F-score of predicted tokens versus the gold answer\n    \'NoAns_total\': Number of score considered\n    \'best_exact\': Best exact match (with varying threshold)\n    \'best_exact_thresh\': No-answer probability threshold associated to the best exact match\n    \'best_f1\': Best F1 (with varying threshold)\n    \'best_f1_thresh\': No-answer probability threshold associated to the best F1\nExamples:\n\n    >>> predictions = [{\'prediction_text\': \'1976\', \'id\': \'56e10a3be3433e1400422b22\', \'no_answer_probability\': 0.}]\n    >>> references = [{\'answers\': {\'answer_start\': [97], \'text\': [\'1976\']}, \'id\': \'56e10a3be3433e1400422b22\'}]\n    >>> squad_v2_metric = datasets.load_metric("squad_v2")\n    >>> results = squad_v2_metric.compute(predictions=predictions, references=references)\n    >>> print(results)\n    {\'exact\': 100.0, \'f1\': 100.0, \'total\': 1, \'HasAns_exact\': 100.0, \'HasAns_f1\': 100.0, \'HasAns_total\': 1, \'best_exact\': 100.0, \'best_exact_thresh\': 0.0, \'best_f1\': 100.0, \'best_f1_thresh\': 0.0}\n'




@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION       ,			_KWARGS_DESCRIPTION  )
class        snake_case__				(datasets.Metric  ):
				"""simple docstring"""



				def 				__UpperCAmelCase				( self							:	List[str]				)   ->	Union[str, Any]:
							return datasets.MetricInfo(
							    description=_DESCRIPTION   , citation=_CITATION   , inputs_description=_KWARGS_DESCRIPTION   , features=datasets.Features(
							        {
							            "predictions": {
							                "id": datasets.Value("string"				),
							                "prediction_text": datasets.Value("string"				),
							                "no_answer_probability": datasets.Value("float32"				),
							            },
							            "references": {
							                "id": datasets.Value("string"				),
							                "answers": datasets.features.Sequence(
							                    {"text": datasets.Value("string"				), "answer_start": datasets.Value("int32"				)}				),
							            },
							        }				)   , codebase_urls=["https://rajpurkar.github.io/SQuAD-explorer/"]   , reference_urls=["https://rajpurkar.github.io/SQuAD-explorer/"]   , )





				def 				__UpperCAmelCase				( self							:	List[str]   , __lowerCamelCase							:	Tuple   , __lowerCamelCase							:	Optional[Any]   , __lowerCamelCase							:	Dict=1.0				)   ->	List[str]:
							a       =     {p["id"]: p["no_answer_probability"] for p in predictions}
							a       =     [{"paragraphs": [{"qas": references}]}]
							a       =     {p["id"]: p["prediction_text"] for p in predictions}

							a       =     make_qid_to_has_ans(__lowerCamelCase				)  # maps qid to True/False
							a       =     [k for k, v in qid_to_has_ans.items() if v]
							a       =     [k for k, v in qid_to_has_ans.items() if not v]

							a       ,						a       =     get_raw_scores(__lowerCamelCase   , __lowerCamelCase				)
							a       =     apply_no_ans_threshold(__lowerCamelCase   , __lowerCamelCase   , __lowerCamelCase   , __lowerCamelCase				)
							a       =     apply_no_ans_threshold(__lowerCamelCase   , __lowerCamelCase   , __lowerCamelCase   , __lowerCamelCase				)
							a       =     make_eval_dict(__lowerCamelCase   , __lowerCamelCase				)

							if has_ans_qids:
										a       =     make_eval_dict(__lowerCamelCase   , __lowerCamelCase   , qid_list=__lowerCamelCase				)
										merge_eval(__lowerCamelCase   , __lowerCamelCase   , "HasAns"				)
							if no_ans_qids:
										a       =     make_eval_dict(__lowerCamelCase   , __lowerCamelCase   , qid_list=__lowerCamelCase				)
										merge_eval(__lowerCamelCase   , __lowerCamelCase   , "NoAns"				)
							find_all_best_thresh(__lowerCamelCase   , __lowerCamelCase   , __lowerCamelCase   , __lowerCamelCase   , __lowerCamelCase   , __lowerCamelCase				)
							return dict(__lowerCamelCase				)






