


"""simple docstring"""


import argparse
import json
import os

import fairseq
import torch
from fairseq.data import Dictionary

from transformers import (
    UniSpeechConfig,
    UniSpeechForCTC,
    UniSpeechForPreTraining,
    WavaVecaFeatureExtractor,
    WavaVecaPhonemeCTCTokenizer,
    WavaVecaProcessor,
    logging,
)


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

A     :   Dict			    =			{
    "post_extract_proj": "feature_projection.projection",
    "encoder.pos_conv.0": "encoder.pos_conv_embed.conv",
    "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",
    "quantizer.weight_proj": "quantizer.weight_proj",
    "quantizer.vars": "quantizer.codevectors",
    "project_q": "project_q",
    "final_proj": "project_hid",
    "w2v_encoder.proj": "ctc_proj",
    "mask_emb": "masked_spec_embed",
}
A     :   int			    =			[
    "ctc_proj",
    "quantizer.weight_proj",
    "quantizer.codevectors",
    "project_q",
    "project_hid",
]


def _lowerCamelCase	(		_UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase      ):

			'''simple docstring'''




			for attribute in key.split("."      ):
						if is_finetuned:
									if attribute in ["quantizer", "project_q", "project_hid"]:
												# those layers are only relevant for pretraining and should be dropped
												return

									if attribute == "ctc_proj":
												# we should rename `ctc_proj` to `lm_head` for fine-tuned phoneme models
												__lowerCAmelCase				    =			"lm_head"

						__lowerCAmelCase				    =			getattr(_UpperCamelCase    , _UpperCamelCase      )

			if weight_type is not None:
						__lowerCAmelCase				    =			getattr(_UpperCamelCase    , _UpperCamelCase      ).shape
			else:
						__lowerCAmelCase				    =			hf_pointer.shape

			assert hf_shape == value.shape, (
			    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":
						__lowerCAmelCase				    =			value
			elif weight_type == "weight_g":
						__lowerCAmelCase				    =			value
			elif weight_type == "weight_v":
						__lowerCAmelCase				    =			value
			elif weight_type == "bias":
						__lowerCAmelCase				    =			value
			else:
						__lowerCAmelCase				    =			value

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


def _lowerCamelCase	(		_UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase      ):

			'''simple docstring'''




			__lowerCAmelCase				    =			[]
			__lowerCAmelCase				    =			fairseq_model.state_dict()

			__lowerCAmelCase				    =			hf_model.unispeech.feature_extractor

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

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


def _lowerCamelCase	(		_UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase      ):

			'''simple docstring'''




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

			if type_id == 0:
						if "bias" in name:
									assert value.shape == feature_extractor.conv_layers[layer_id].conv.bias.data.shape, (
									    f"{full_name} has size {value.shape}, but"
									    f" {feature_extractor.conv_layers[layer_id].conv.bias.data.shape} was found."
									)
									__lowerCAmelCase				    =			value
									logger.info(f"Feat extract conv layer {layer_id} was initialized from {full_name}."      )
						elif "weight" in name:
									assert value.shape == feature_extractor.conv_layers[layer_id].conv.weight.data.shape, (
									    f"{full_name} has size {value.shape}, but"
									    f" {feature_extractor.conv_layers[layer_id].conv.weight.data.shape} was found."
									)
									__lowerCAmelCase				    =			value
									logger.info(f"Feat extract conv layer {layer_id} was initialized from {full_name}."      )
			elif (type_id == 2 and not use_group_norm) or (type_id == 2 and layer_id == 0 and use_group_norm):
						if "bias" in name:
									assert value.shape == feature_extractor.conv_layers[layer_id].layer_norm.bias.data.shape, (
									    f"{full_name} has size {value.shape}, but {feature_extractor[layer_id].layer_norm.bias.data.shape} was"
									    " found."
									)
									__lowerCAmelCase				    =			value
									logger.info(f"Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}."      )
						elif "weight" in name:
									assert value.shape == feature_extractor.conv_layers[layer_id].layer_norm.weight.data.shape, (
									    f"{full_name} has size {value.shape}, but"
									    f" {feature_extractor[layer_id].layer_norm.weight.data.shape} was found."
									)
									__lowerCAmelCase				    =			value
									logger.info(f"Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}."      )
			else:
						unused_weights.append(_UpperCamelCase      )


@torch.no_grad()
def _lowerCamelCase	(		_UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase=None    , _UpperCamelCase=None    , _UpperCamelCase=True      ):

			'''simple docstring'''




			if config_path is not None:
						__lowerCAmelCase				    =			UniSpeechConfig.from_pretrained(_UpperCamelCase      )
			else:
						__lowerCAmelCase				    =			UniSpeechConfig()

			if is_finetuned:
						if dict_path:
									__lowerCAmelCase				    =			Dictionary.load_from_json(_UpperCamelCase      )

									# important change bos & pad token id since CTC symbol is <pad> and
									# not <s> as in fairseq
									__lowerCAmelCase				    =			target_dict.pad_index
									__lowerCAmelCase				    =			target_dict.bos_index
									__lowerCAmelCase				    =			target_dict.eos_index
									__lowerCAmelCase				    =			len(target_dict.symbols      )
									__lowerCAmelCase				    =			os.path.join(_UpperCamelCase    , "vocab.json"      )
									if not os.path.isdir(_UpperCamelCase      ):
												logger.error("--pytorch_dump_folder_path ({}) should be a directory".format(_UpperCamelCase      )      )
												return
									os.makedirs(_UpperCamelCase    , exist_ok=_UpperCamelCase      )
									__lowerCAmelCase				    =			target_dict.indices

									# fairseq has the <pad> and <s> switched
									__lowerCAmelCase				    =			42
									__lowerCAmelCase				    =			43
									with open(_UpperCamelCase    , "w"    , encoding="utf-8"      ) as vocab_handle:
												json.dump(_UpperCamelCase    , _UpperCamelCase      )
									__lowerCAmelCase				    =			WavaVecaPhonemeCTCTokenizer(
									    _UpperCamelCase    , unk_token=target_dict.unk_word    , pad_token=target_dict.pad_word    , bos_token=target_dict.bos_word    , eos_token=target_dict.eos_word    , word_delimiter_token="|"    , do_lower_case=_UpperCamelCase    , )
									__lowerCAmelCase				    =			True if config.feat_extract_norm == "layer" else False
									__lowerCAmelCase				    =			WavaVecaFeatureExtractor(
									    feature_size=1    , sampling_rate=1_6000    , padding_value=0    , do_normalize=_UpperCamelCase    , return_attention_mask=_UpperCamelCase    , )
									__lowerCAmelCase				    =			WavaVecaProcessor(feature_extractor=_UpperCamelCase    , tokenizer=_UpperCamelCase      )
									processor.save_pretrained(_UpperCamelCase      )

						__lowerCAmelCase				    =			UniSpeechForCTC(_UpperCamelCase      )
			else:
						__lowerCAmelCase				    =			UniSpeechForPreTraining(_UpperCamelCase      )

			if is_finetuned:
						__lowerCAmelCase    ,	__lowerCAmelCase    ,	__lowerCAmelCase				    =			fairseq.checkpoint_utils.load_model_ensemble_and_task(
						    [checkpoint_path]    , arg_overrides={"data": "/".join(dict_path.split("/"      )[:-1]      ), "w2v_path": checkpoint_path}      )
			else:
						__lowerCAmelCase    ,	__lowerCAmelCase    ,	__lowerCAmelCase				    =			fairseq.checkpoint_utils.load_model_ensemble_and_task([checkpoint_path]      )

			__lowerCAmelCase				    =			model[0].eval()

			recursively_load_weights(_UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase      )

			hf_unispeech.save_pretrained(_UpperCamelCase      )


if __name__ == "__main__":
	A     :   Dict			    =			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"
	)
	A     :   Optional[int]			    =			parser.parse_args()
	convert_unispeech_checkpoint(
	    args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path, args.dict_path, not args.not_finetuned
	)








"""simple docstring"""


def _lowerCamelCase	(		):

			'''simple docstring'''




			__lowerCAmelCase				    =			[]
			__lowerCAmelCase				    =			1

			while len(_UpperCamelCase      ) < 1e6:
						constant.append(str(_UpperCamelCase      )      )
						i += 1

			__lowerCAmelCase				    =			"".join(_UpperCamelCase      )

			return (
			    int(constant[0]      )
			    * int(constant[9]      )
			    * int(constant[99]      )
			    * int(constant[999]      )
			    * int(constant[9999]      )
			    * int(constant[9_9999]      )
			    * int(constant[99_9999]      )
			)


if __name__ == "__main__":
	print(solution())




