

import os
import sys
import tempfile

import torch

from .state import AcceleratorState
from .utils import PrecisionType, PrepareForLaunch, is_mps_available, patch_environment

def      snake_case__      (   SCREAMING_SNAKE_CASE_		:   Tuple     ,					SCREAMING_SNAKE_CASE_		:   int=()     ,					SCREAMING_SNAKE_CASE_		:   int=None     ,					SCREAMING_SNAKE_CASE_		:   Dict="no"     ,					SCREAMING_SNAKE_CASE_		:   Dict="29500"      ):



     '''simple docstring'''





     lowercase__   :       Optional[int]				=	False
     lowercase__   :       Optional[Any]				=	False
     if any(key.startswith('KAGGLE'      ) for key in os.environ.keys()      ):
          lowercase__   :       Optional[Any]				=	True
     elif "IPython" in sys.modules:
          lowercase__   :       Dict				=	'google.colab' in str(sys.modules['IPython'].get_ipython()      )

     try:
          lowercase__   :       Union[str, Any]				=	PrecisionType(mixed_precision.lower()      )
     except ValueError:
          raise ValueError(
              f"""Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}."""      )

     if (in_colab or in_kaggle) and (os.environ.get('TPU_NAME'     ,					SCREAMING_SNAKE_CASE_      ) is not None):
          # TPU launch
          import torch_xla.distributed.xla_multiprocessing as xmp

          if len(AcceleratorState._shared_state      ) > 0:
               raise ValueError(
                   'To train on TPU in Colab or Kaggle Kernel, the `Accelerator` should only be initialized inside '
                   'your training function. Restart your notebook and make sure no cells initializes an '
                   '`Accelerator`.'      )
          if num_processes is None:
               lowercase__   :       Tuple				=	8

          lowercase__   :       str				=	PrepareForLaunch(SCREAMING_SNAKE_CASE_     ,					distributed_type='TPU'      )
          print(f"""Launching a training on {num_processes} TPU cores."""      )
          xmp.spawn(SCREAMING_SNAKE_CASE_     ,					args=SCREAMING_SNAKE_CASE_     ,					nprocs=SCREAMING_SNAKE_CASE_     ,					start_method='fork'      )
     elif in_colab:
          # No need for a distributed launch otherwise as it's either CPU or one GPU.
          if torch.cuda.is_available():
               print('Launching training on one GPU.'      )
          else:
               print('Launching training on one CPU.'      )
          function(*SCREAMING_SNAKE_CASE_      )
     else:
          if num_processes is None:
               raise ValueError(
                   'You have to specify the number of GPUs you would like to use, add `num_processes=...` to your call.'      )

          if num_processes > 1:
               # Multi-GPU launch
               from torch.multiprocessing import start_processes
               from torch.multiprocessing.spawn import ProcessRaisedException

               if len(AcceleratorState._shared_state      ) > 0:
                    raise ValueError(
                        'To launch a multi-GPU training from your notebook, the `Accelerator` should only be initialized '
                        'inside your training function. Restart your notebook and make sure no cells initializes an '
                        '`Accelerator`.'      )

               if torch.cuda.is_initialized():
                    raise ValueError(
                        'To launch a multi-GPU training from your notebook, you need to avoid running any instruction '
                        'using `torch.cuda` in any cell. Restart your notebook and make sure no cells use any CUDA '
                        'function.'      )

               # torch.distributed will expect a few environment variable to be here. We set the ones common to each
               # process here (the other ones will be set be the launcher).
               with patch_environment(
                   world_size=SCREAMING_SNAKE_CASE_     ,					master_addr='127.0.01'     ,					master_port=SCREAMING_SNAKE_CASE_     ,					mixed_precision=SCREAMING_SNAKE_CASE_      ):
                    lowercase__   :       Dict				=	PrepareForLaunch(SCREAMING_SNAKE_CASE_     ,					distributed_type='MULTI_GPU'      )
                    print(f"""Launching training on {num_processes} GPUs."""      )
                    try:
                         start_processes(SCREAMING_SNAKE_CASE_     ,					args=SCREAMING_SNAKE_CASE_     ,					nprocs=SCREAMING_SNAKE_CASE_     ,					start_method='fork'      )
                    except ProcessRaisedException as e:
                         if "Cannot re-initialize CUDA in forked subprocess" in e.args[0]:
                              raise RuntimeError(
                                  'CUDA has been initialized before the `notebook_launcher` could create a forked subprocess. '
                                  'This likely stems from an outside import causing issues once the `notebook_launcher()` is called. '
                                  'Please review your imports and test them when running the `notebook_launcher()` to identify '
                                  'which one is problematic.'      ) from e

          else:
               # No need for a distributed launch otherwise as it's either CPU, GPU or MPS.
               if is_mps_available():
                    lowercase__   :       List[Any]				=	'1'
                    print('Launching training on MPS.'      )
               elif torch.cuda.is_available():
                    print('Launching training on one GPU.'      )
               else:
                    print('Launching training on CPU.'      )
               function(*SCREAMING_SNAKE_CASE_      )

def      snake_case__      (   SCREAMING_SNAKE_CASE_		:   List[Any]     ,					SCREAMING_SNAKE_CASE_		:   Optional[Any]=()     ,					SCREAMING_SNAKE_CASE_		:   Dict=2      ):



     '''simple docstring'''





     from torch.multiprocessing import start_processes

     with tempfile.NamedTemporaryFile() as tmp_file:
          # torch.distributed will expect a few environment variable to be here. We set the ones common to each
          # process here (the other ones will be set be the launcher).
          with patch_environment(
              world_size=SCREAMING_SNAKE_CASE_     ,					master_addr='127.0.01'     ,					master_port='29500'     ,					accelerate_mixed_precision='no'     ,					accelerate_debug_rdv_file=tmp_file.name     ,					accelerate_use_cpu='yes'     ,					):
               lowercase__   :       Union[str, Any]				=	PrepareForLaunch(SCREAMING_SNAKE_CASE_     ,					debug=SCREAMING_SNAKE_CASE_      )
               start_processes(SCREAMING_SNAKE_CASE_     ,					args=SCREAMING_SNAKE_CASE_     ,					nprocs=SCREAMING_SNAKE_CASE_     ,					start_method='fork'      )




import argparse

import fairseq
import torch

from transformers import UniSpeechSatConfig, UniSpeechSatForCTC, UniSpeechSatForPreTraining, logging


logging.set_verbosity_info()
snake_case_        =			logging.get_logger(__name__)

snake_case_        =			{
    '''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''',
    '''encoder.layer_norm_for_extract''': '''layer_norm_for_extract''',
    '''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''': '''lm_head''',
    '''label_embs_concat''': '''label_embeddings_concat''',
    '''mask_emb''': '''masked_spec_embed''',
    '''spk_proj''': '''speaker_proj''',
}
snake_case_        =			[
    '''lm_head''',
    '''quantizer.weight_proj''',
    '''quantizer.codevectors''',
    '''project_q''',
    '''project_hid''',
    '''label_embeddings_concat''',
    '''speaker_proj''',
    '''layer_norm_for_extract''',
]

def      snake_case__      (   SCREAMING_SNAKE_CASE_		:   Tuple     ,					SCREAMING_SNAKE_CASE_		:   Tuple     ,					SCREAMING_SNAKE_CASE_		:   Any     ,					SCREAMING_SNAKE_CASE_		:   Optional[Any]     ,					SCREAMING_SNAKE_CASE_		:   Dict      ):



     '''simple docstring'''





     for attribute in key.split('.'      ):
          lowercase__   :       Optional[Any]				=	getattr(SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_      )

     if weight_type is not None:
          lowercase__   :       Union[str, Any]				=	getattr(SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_      ).shape
     else:
          lowercase__   :       Optional[int]				=	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":
          lowercase__   :       Optional[int]				=	value
     elif weight_type == "weight_g":
          lowercase__   :       Union[str, Any]				=	value
     elif weight_type == "weight_v":
          lowercase__   :       Tuple				=	value
     elif weight_type == "bias":
          lowercase__   :       Any				=	value
     else:
          lowercase__   :       Union[str, Any]				=	value

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

def      snake_case__      (   SCREAMING_SNAKE_CASE_		:   Optional[int]     ,					SCREAMING_SNAKE_CASE_		:   Any      ):



     '''simple docstring'''





     lowercase__   :       Optional[int]				=	[]
     lowercase__   :       Union[str, Any]				=	fairseq_model.state_dict()

     lowercase__   :       Optional[int]				=	hf_model.unispeech_sat.feature_extractor

     for name, value in fairseq_dict.items():
          lowercase__   :       Tuple				=	False
          if "conv_layers" in name:
               load_conv_layer(
                   SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_     ,					hf_model.config.feat_extract_norm == 'group'     ,					)
               lowercase__   :       Optional[int]				=	True
          else:
               for key, mapped_key in MAPPING.items():
                    lowercase__   :       List[str]				=	'unispeech_sat.' + 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]:
                         if "layer_norm_for_extract" in name and (".".join(name.split('.'      )[:-1]      ) != key):
                              # special case since naming is very similar
                              continue
                         lowercase__   :       Tuple				=	True
                         if "*" in mapped_key:
                              lowercase__   :       Any				=	name.split(SCREAMING_SNAKE_CASE_      )[0].split('.'      )[-2]
                              lowercase__   :       Optional[Any]				=	mapped_key.replace('*'     ,					SCREAMING_SNAKE_CASE_      )
                         if "weight_g" in name:
                              lowercase__   :       int				=	'weight_g'
                         elif "weight_v" in name:
                              lowercase__   :       Any				=	'weight_v'
                         elif "bias" in name:
                              lowercase__   :       str				=	'bias'
                         elif "weight" in name:
                              # TODO: don't match quantizer.weight_proj
                              lowercase__   :       Union[str, Any]				=	'weight'
                         else:
                              lowercase__   :       Union[str, Any]				=	None
                         set_recursively(SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_      )
                    continue
          if not is_used:
               unused_weights.append(SCREAMING_SNAKE_CASE_      )

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

def      snake_case__      (   SCREAMING_SNAKE_CASE_		:   Tuple     ,					SCREAMING_SNAKE_CASE_		:   Tuple     ,					SCREAMING_SNAKE_CASE_		:   int     ,					SCREAMING_SNAKE_CASE_		:   Union[str, Any]     ,					SCREAMING_SNAKE_CASE_		:   Optional[Any]      ):



     '''simple docstring'''





     lowercase__   :       List[Any]				=	full_name.split('conv_layers.'      )[-1]
     lowercase__   :       Dict				=	name.split('.'      )
     lowercase__   :       List[str]				=	int(items[0]      )
     lowercase__   :       Any				=	int(items[1]      )

     if type_id == 0:
          if "bias" in name:
               if value.shape != feature_extractor.conv_layers[layer_id].conv.bias.data.shape:
                    raise ValueError(
                        f"""{full_name} has size {value.shape}, but"""
                        f""" {feature_extractor.conv_layers[layer_id].conv.bias.data.shape} was found."""      )
               lowercase__   :       List[Any]				=	value
               logger.info(f"""Feat extract conv layer {layer_id} was initialized from {full_name}."""      )
          elif "weight" in name:
               if value.shape != feature_extractor.conv_layers[layer_id].conv.weight.data.shape:
                    raise ValueError(
                        f"""{full_name} has size {value.shape}, but"""
                        f""" {feature_extractor.conv_layers[layer_id].conv.weight.data.shape} was found."""      )
               lowercase__   :       Any				=	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:
               if value.shape != feature_extractor.conv_layers[layer_id].layer_norm.bias.data.shape:
                    raise ValueError(
                        f"""{full_name} has size {value.shape}, but"""
                        f""" {feature_extractor[layer_id].layer_norm.bias.data.shape} was found."""      )
               lowercase__   :       str				=	value
               logger.info(f"""Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}."""      )
          elif "weight" in name:
               if value.shape != feature_extractor.conv_layers[layer_id].layer_norm.weight.data.shape:
                    raise ValueError(
                        f"""{full_name} has size {value.shape}, but"""
                        f""" {feature_extractor[layer_id].layer_norm.weight.data.shape} was found."""      )
               lowercase__   :       int				=	value
               logger.info(f"""Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}."""      )
     else:
          unused_weights.append(SCREAMING_SNAKE_CASE_      )

@torch.no_grad()
def      snake_case__      (   SCREAMING_SNAKE_CASE_		:   Any     ,					SCREAMING_SNAKE_CASE_		:   List[Any]     ,					SCREAMING_SNAKE_CASE_		:   List[str]=None     ,					SCREAMING_SNAKE_CASE_		:   List[Any]=None     ,					SCREAMING_SNAKE_CASE_		:   int=True      ):



     '''simple docstring'''





     if config_path is not None:
          lowercase__   :       Any				=	UniSpeechSatConfig.from_pretrained(SCREAMING_SNAKE_CASE_      )
     else:
          lowercase__   :       Dict				=	UniSpeechSatConfig()

     lowercase__   :       str				=	''

     if is_finetuned:
          lowercase__   :       Any				=	UniSpeechSatForCTC(SCREAMING_SNAKE_CASE_      )
     else:
          lowercase__   :       Optional[Any]				=	UniSpeechSatForPreTraining(SCREAMING_SNAKE_CASE_      )

     lowercase__				,			lowercase__				,			lowercase__   :       List[Any]				=	fairseq.checkpoint_utils.load_model_ensemble_and_task(
         [checkpoint_path]     ,					arg_overrides={'data': '/'.join(dict_path.split('/'      )[:-1]      )}      )
     lowercase__   :       List[str]				=	model[0].eval()

     recursively_load_weights(SCREAMING_SNAKE_CASE_     ,					SCREAMING_SNAKE_CASE_      )

     hf_wavavec.save_pretrained(SCREAMING_SNAKE_CASE_      )


if __name__ == "__main__":
       snake_case_        =			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'''
       )
       snake_case_        =			parser.parse_args()
       convert_unispeech_sat_checkpoint(
           args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path, args.dict_path, not args.not_finetuned
       )

