
"""simple docstring"""


import inspect
import os
from argparse import ArgumentParser, Namespace
from importlib import import_module

import huggingface_hub
import numpy as np
from packaging import version

from .. import (
    FEATURE_EXTRACTOR_MAPPING,
    IMAGE_PROCESSOR_MAPPING,
    PROCESSOR_MAPPING,
    TOKENIZER_MAPPING,
    AutoConfig,
    AutoFeatureExtractor,
    AutoImageProcessor,
    AutoProcessor,
    AutoTokenizer,
    is_datasets_available,
    is_tf_available,
    is_torch_available,
)
from ..utils import TF2_WEIGHTS_INDEX_NAME, TF2_WEIGHTS_NAME, logging
from . import BaseTransformersCLICommand


if is_tf_available():
							import tensorflow as tf

							tf.config.experimental.enable_tensor_float_aa_execution(False)

if is_torch_available():
							import torch

if is_datasets_available():
							from datasets import load_dataset


lowerCAmelCase								=						5E-5  # larger error tolerance than in our internal tests, to avoid flaky user-facing errors






def        lowerCAmelCase_       (		snake_case_		:      List[Any]      )       ->Union[str, Any]:
			return PTtoTFCommand(
			    args.model_name							,   args.local_dir							,   args.max_error							,   args.new_weights							,   args.no_pr							,   args.push							,   args.extra_commit_description							,   args.override_model_class							,   )

class    A_     (					_lowerCamelCase       ):



							"""simple docstring"""






							@staticmethod
							def 				UpperCAmelCase__							(  lowerCamelCase_  :Optional[Any]	):





										"""simple docstring"""

										lowerCamelCase__     :					List[Any]     	=parser.add_parser(
										    'pt-to-tf'					,							help=(
										        'CLI tool to run convert a transformers model from a PyTorch checkpoint to a TensorFlow checkpoint.'
										        ' Can also be used to validate existing weights without opening PRs, with --no-pr.'
										    )					,							)
										train_parser.add_argument(
										    '--model-name'					,							type=__UpperCamelCase					,							required=__UpperCamelCase					,							help='The model name, including owner/organization, as seen on the hub.'					,							)
										train_parser.add_argument(
										    '--local-dir'					,							type=__UpperCamelCase					,							default=''					,							help='Optional local directory of the model repository. Defaults to /tmp/{model_name}'					,							)
										train_parser.add_argument(
										    '--max-error'					,							type=__UpperCamelCase					,							default=__UpperCamelCase					,							help=(
										        f"""Maximum error tolerance. Defaults to {MAX_ERROR}. This flag should be avoided, use at your own risk."""
										    )					,							)
										train_parser.add_argument(
										    '--new-weights'					,							action='store_true'					,							help='Optional flag to create new TensorFlow weights, even if they already exist.'					,							)
										train_parser.add_argument(
										    '--no-pr'					,							action='store_true'					,							help='Optional flag to NOT open a PR with converted weights.'	)
										train_parser.add_argument(
										    '--push'					,							action='store_true'					,							help='Optional flag to push the weights directly to `main` (requires permissions)'					,							)
										train_parser.add_argument(
										    '--extra-commit-description'					,							type=__UpperCamelCase					,							default=''					,							help='Optional additional commit description to use when opening a PR (e.g. to tag the owner).'					,							)
										train_parser.add_argument(
										    '--override-model-class'					,							type=__UpperCamelCase					,							default=__UpperCamelCase					,							help='If you think you know better than the auto-detector, you can specify the model class here. '
										    'Can be either an AutoModel class or a specific model class like BertForSequenceClassification.'					,							)
										train_parser.set_defaults(func=__UpperCamelCase	)





							@staticmethod
							def 				UpperCAmelCase__							(  lowerCamelCase_  :str					,							lowerCamelCase_  :Dict	):





										"""simple docstring"""

										lowerCamelCase__     :					Optional[Any]     	=set(pt_outputs.keys()	)
										lowerCamelCase__     :					int     	=set(tf_outputs.keys()	)
										if pt_out_attrs != tf_out_attrs:
													raise ValueError(
													    f"""The model outputs have different attributes, aborting. (Pytorch: {pt_out_attrs}, TensorFlow:"""
													    f""" {tf_out_attrs})"""	)

										# 2. For each output attribute, computes the difference
										def _find_pt_tf_differences(lowerCamelCase_  :int					,							lowerCamelCase_  :Dict					,							lowerCamelCase_  :List[str]					,							lowerCamelCase_  :List[Any]=""	):
													# If the current attribute is a tensor, it is a leaf and we make the comparison. Otherwise, we will dig in
													# recursivelly, keeping the name of the attribute.
													if isinstance(__UpperCamelCase					,							torch.Tensor	):
																lowerCamelCase__     :					Any     	=np.max(np.abs(pt_out.numpy() - tf_out.numpy()	)	)
																lowerCamelCase__     :					Optional[Any]     	=tensor_difference
													else:
																lowerCamelCase__     :					Union[str, Any]     	=attr_name
																for i, pt_item in enumerate(__UpperCamelCase	):
																			# If it is a named attribute, we keep the name. Otherwise, just its index.
																			if isinstance(__UpperCamelCase					,							__UpperCamelCase	):
																						lowerCamelCase__     :					List[Any]     	=root_name + pt_item
																						lowerCamelCase__     :					Union[str, Any]     	=tf_out[pt_item]
																						lowerCamelCase__     :					Union[str, Any]     	=pt_out[pt_item]
																			else:
																						lowerCamelCase__     :					Optional[int]     	=root_name + f"""[{i}]"""
																						lowerCamelCase__     :					int     	=tf_out[i]
																			lowerCamelCase__     :					Any     	=_find_pt_tf_differences(__UpperCamelCase					,							__UpperCamelCase					,							__UpperCamelCase					,							__UpperCamelCase	)

													return differences

										return _find_pt_tf_differences(__UpperCamelCase					,							__UpperCamelCase					,							{}	)





							def __init__(  self  :Union[str, Any]					,							lowerCamelCase_  :Any					,							lowerCamelCase_  :Optional[Any]					,							lowerCamelCase_  :List[Any]					,							lowerCamelCase_  :Optional[Any]					,							lowerCamelCase_  :Dict					,							lowerCamelCase_  :List[Any]					,							lowerCamelCase_  :List[Any]					,							lowerCamelCase_  :Any					,							*lowerCamelCase_  :Dict					,							):





										"""simple docstring"""

										lowerCamelCase__     :					Dict     	=logging.get_logger('transformers-cli/pt_to_tf'	)
										lowerCamelCase__     :					Any     	=model_name
										lowerCamelCase__     :					Tuple     	=local_dir if local_dir else os.path.join('/tmp'					,							__UpperCamelCase	)
										lowerCamelCase__     :					Any     	=max_error
										lowerCamelCase__     :					Tuple     	=new_weights
										lowerCamelCase__     :					int     	=no_pr
										lowerCamelCase__     :					Tuple     	=push
										lowerCamelCase__     :					List[Any]     	=extra_commit_description
										lowerCamelCase__     :					Tuple     	=override_model_class





							def 				UpperCAmelCase__							(  self  :Optional[int]					,							lowerCamelCase_  :Union[str, Any]					,							lowerCamelCase_  :Optional[Any]					,							lowerCamelCase_  :Dict	):





										"""simple docstring"""

										def _get_audio_input():
													lowerCamelCase__     :					Optional[Any]     	=load_dataset('hf-internal-testing/librispeech_asr_dummy'					,							'clean'					,							split='validation'	)
													lowerCamelCase__     :					str     	=ds.sort('id'	).select(range(2	)	)[:2]['audio']
													lowerCamelCase__     :					Union[str, Any]     	=[x['array'] for x in speech_samples]
													return raw_samples

										lowerCamelCase__     :					Optional[Any]     	=type(pt_model.config	)
										if model_config_class in PROCESSOR_MAPPING:
													lowerCamelCase__     :					Optional[int]     	=AutoProcessor.from_pretrained(self._local_dir	)
													if model_config_class in TOKENIZER_MAPPING and processor.tokenizer.pad_token is None:
																lowerCamelCase__     :					Optional[Any]     	=processor.tokenizer.eos_token
										elif model_config_class in IMAGE_PROCESSOR_MAPPING:
													lowerCamelCase__     :					Any     	=AutoImageProcessor.from_pretrained(self._local_dir	)
										elif model_config_class in FEATURE_EXTRACTOR_MAPPING:
													lowerCamelCase__     :					List[str]     	=AutoFeatureExtractor.from_pretrained(self._local_dir	)
										elif model_config_class in TOKENIZER_MAPPING:
													lowerCamelCase__     :					Optional[Any]     	=AutoTokenizer.from_pretrained(self._local_dir	)
													if processor.pad_token is None:
																lowerCamelCase__     :					Optional[int]     	=processor.eos_token
										else:
													raise ValueError(f"""Unknown data processing type (model config type: {model_config_class})"""	)

										lowerCamelCase__     :					Dict     	=set(inspect.signature(pt_model.forward	).parameters.keys()	)
										lowerCamelCase__     :					Tuple     	={}
										if "input_ids" in model_forward_signature:
													processor_inputs.update(
													    {
													        'text': ['Hi there!', 'I am a batch with more than one row and different input lengths.'],
													        'padding': True,
													        'truncation': True,
													    }	)
										if "pixel_values" in model_forward_signature:
													lowerCamelCase__     :					Dict     	=load_dataset('cifar10'					,							'plain_text'					,							split='test'	)[:2]['img']
													processor_inputs.update({'images': sample_images}	)
										if "input_features" in model_forward_signature:
													lowerCamelCase__     :					List[str]     	=inspect.signature(processor.feature_extractor	).parameters
													# Pad to the largest input length by default but take feature extractor default
													# padding value if it exists e.g. "max_length" and is not False or None
													if "padding" in feature_extractor_signature:
																lowerCamelCase__     :					Union[str, Any]     	=feature_extractor_signature['padding'].default
																if default_strategy is not False and default_strategy is not None:
																			lowerCamelCase__     :					Any     	=default_strategy
																else:
																			lowerCamelCase__     :					int     	=True
													else:
																lowerCamelCase__     :					Union[str, Any]     	=True
													processor_inputs.update({'audio': _get_audio_input(), 'padding': padding_strategy}	)
										if "input_values" in model_forward_signature:  # Wav2Vec2 audio input
													processor_inputs.update({'audio': _get_audio_input(), 'padding': True}	)
										lowerCamelCase__     :					List[Any]     	=processor(**__UpperCamelCase					,							return_tensors='pt'	)
										lowerCamelCase__     :					Optional[int]     	=processor(**__UpperCamelCase					,							return_tensors='tf'	)

										# Extra input requirements, in addition to the input modality
										if (
										    config.is_encoder_decoder
										    or (hasattr(__UpperCamelCase					,							'encoder'	) and hasattr(__UpperCamelCase					,							'decoder'	))
										    or "decoder_input_ids" in tf_dummy_inputs
										):
													lowerCamelCase__     :					Tuple     	=np.asarray([[1], [1]]					,							dtype=__UpperCamelCase	) * (pt_model.config.decoder_start_token_id or 0)
													pt_input.update({'decoder_input_ids': torch.tensor(__UpperCamelCase	)}	)
													tf_input.update({'decoder_input_ids': tf.convert_to_tensor(__UpperCamelCase	)}	)

										return pt_input, tf_input





							def 				UpperCAmelCase__							(  self  :str	):





										"""simple docstring"""

										if version.parse(huggingface_hub.__version__	) < version.parse('0.9.0'	):
													raise ImportError(
													    'The huggingface_hub version must be >= 0.9.0 to use this command. Please update your huggingface_hub'
													    ' installation.'	)
										else:
													from huggingface_hub import Repository, create_commit
													from huggingface_hub._commit_api import CommitOperationAdd

										# Fetch remote data
										lowerCamelCase__     :					Tuple     	=Repository(local_dir=self._local_dir					,							clone_from=self._model_name	)

										# Load config and get the appropriate architecture -- the latter is needed to convert the head's weights
										lowerCamelCase__     :					Optional[Any]     	=AutoConfig.from_pretrained(self._local_dir	)
										lowerCamelCase__     :					Optional[Any]     	=config.architectures
										if self._override_model_class is not None:
													if self._override_model_class.startswith('TF'	):
																lowerCamelCase__     :					str     	=[self._override_model_class[2:]]
													else:
																lowerCamelCase__     :					Union[str, Any]     	=[self._override_model_class]
													try:
																lowerCamelCase__     :					List[str]     	=getattr(import_module('transformers'	)					,							architectures[0]	)
													except AttributeError:
																raise ValueError(f"""Model class {self._override_model_class} not found in transformers."""	)
													try:
																lowerCamelCase__     :					int     	=getattr(import_module('transformers'	)					,							'TF' + architectures[0]	)
													except AttributeError:
																raise ValueError(f"""TF model class TF{self._override_model_class} not found in transformers."""	)
										elif architectures is None:  # No architecture defined -- use auto classes
													lowerCamelCase__     :					List[str]     	=getattr(import_module('transformers'	)					,							'AutoModel'	)
													lowerCamelCase__     :					List[str]     	=getattr(import_module('transformers'	)					,							'TFAutoModel'	)
													self._logger.warning('No detected architecture, using AutoModel/TFAutoModel'	)
										else:  # Architecture defined -- use it
													if len(__UpperCamelCase	) > 1:
																raise ValueError(f"""More than one architecture was found, aborting. (architectures = {architectures})"""	)
													self._logger.warning(f"""Detected architecture: {architectures[0]}"""	)
													lowerCamelCase__     :					Dict     	=getattr(import_module('transformers'	)					,							architectures[0]	)
													try:
																lowerCamelCase__     :					Union[str, Any]     	=getattr(import_module('transformers'	)					,							'TF' + architectures[0]	)
													except AttributeError:
																raise AttributeError(f"""The TensorFlow equivalent of {architectures[0]} doesn't exist in transformers."""	)

        # Check the TF dummy inputs to see what keys we need in the forward pass
										lowerCamelCase__     :					Dict     	=tf_class.from_config(__UpperCamelCase	)
										lowerCamelCase__     :					Any     	=tf_from_pt_model.dummy_inputs

										del tf_from_pt_model  # Try to keep only one model in memory at a time

										# Load the model and get some basic inputs
										lowerCamelCase__     :					int     	=pt_class.from_pretrained(self._local_dir	)
										pt_model.eval()

										lowerCamelCase__     :					List[str]     	=self.get_inputs(__UpperCamelCase					,							__UpperCamelCase					,							__UpperCamelCase	)

										with torch.no_grad():
													lowerCamelCase__     :					str     	=pt_model(**__UpperCamelCase					,							output_hidden_states=__UpperCamelCase	)
										del pt_model  # will no longer be used, and may have a large memory footprint

										lowerCamelCase__     :					Dict     	=tf_class.from_pretrained(self._local_dir					,							from_pt=__UpperCamelCase	)
										lowerCamelCase__     :					Tuple     	=tf_from_pt_model(**__UpperCamelCase					,							output_hidden_states=__UpperCamelCase					,							training=__UpperCamelCase	)

										# Confirms that cross loading PT weights into TF worked.
										lowerCamelCase__     :					int     	=self.find_pt_tf_differences(__UpperCamelCase					,							__UpperCamelCase	)
										lowerCamelCase__     :					Union[str, Any]     	={k: v for k, v in crossload_differences.items() if 'hidden' not in k}
										lowerCamelCase__     :					Dict     	={k: v for k, v in crossload_differences.items() if 'hidden' in k}
										if len(__UpperCamelCase	) == 0 and architectures is not None:
													raise ValueError(
													    f"""Something went wrong -- the config file has architectures ({architectures}), but no model head"""
													    ' output was found. All outputs start with \'hidden\''	)
										lowerCamelCase__     :					Optional[int]     	=max(output_differences.values()	) if output_differences else 0.0
										lowerCamelCase__     :					int     	=max(hidden_differences.values()	)
										if max_crossload_output_diff > self._max_error or max_crossload_hidden_diff > self._max_error:
													raise ValueError(
													    'The cross-loaded TensorFlow model has different outputs, something went wrong!\n'
													    + f"""\nList of maximum output differences above the threshold ({self._max_error}):\n"""
													    + '\n'.join([f"""{k}: {v:.3e}""" for k, v in output_differences.items() if v > self._max_error]	)
													    + f"""\n\nList of maximum hidden layer differences above the threshold ({self._max_error}):\n"""
													    + '\n'.join([f"""{k}: {v:.3e}""" for k, v in hidden_differences.items() if v > self._max_error]	)	)

										# Save the weights in a TF format (if needed) and confirms that the results are still good
										lowerCamelCase__     :					Any     	=os.path.join(self._local_dir					,							__UpperCamelCase	)
										lowerCamelCase__     :					Optional[Any]     	=os.path.join(self._local_dir					,							__UpperCamelCase	)
										if (not os.path.exists(__UpperCamelCase	) and not os.path.exists(__UpperCamelCase	)) or self._new_weights:
													tf_from_pt_model.save_pretrained(self._local_dir	)
										del tf_from_pt_model  # will no longer be used, and may have a large memory footprint

										lowerCamelCase__     :					List[str]     	=tf_class.from_pretrained(self._local_dir	)
										lowerCamelCase__     :					Union[str, Any]     	=tf_model(**__UpperCamelCase					,							output_hidden_states=__UpperCamelCase	)

										lowerCamelCase__     :					Optional[Any]     	=self.find_pt_tf_differences(__UpperCamelCase					,							__UpperCamelCase	)
										lowerCamelCase__     :					Any     	={k: v for k, v in conversion_differences.items() if 'hidden' not in k}
										lowerCamelCase__     :					Any     	={k: v for k, v in conversion_differences.items() if 'hidden' in k}
										if len(__UpperCamelCase	) == 0 and architectures is not None:
													raise ValueError(
													    f"""Something went wrong -- the config file has architectures ({architectures}), but no model head"""
													    ' output was found. All outputs start with \'hidden\''	)
										lowerCamelCase__     :					int     	=max(output_differences.values()	) if output_differences else 0.0
										lowerCamelCase__     :					Any     	=max(hidden_differences.values()	)
										if max_conversion_output_diff > self._max_error or max_conversion_hidden_diff > self._max_error:
													raise ValueError(
													    'The converted TensorFlow model has different outputs, something went wrong!\n'
													    + f"""\nList of maximum output differences above the threshold ({self._max_error}):\n"""
													    + '\n'.join([f"""{k}: {v:.3e}""" for k, v in output_differences.items() if v > self._max_error]	)
													    + f"""\n\nList of maximum hidden layer differences above the threshold ({self._max_error}):\n"""
													    + '\n'.join([f"""{k}: {v:.3e}""" for k, v in hidden_differences.items() if v > self._max_error]	)	)

										lowerCamelCase__     :					Any     	='Update TF weights' if self._new_weights else 'Add TF weights'
										if self._push:
													repo.git_add(auto_lfs_track=__UpperCamelCase	)
													repo.git_commit(__UpperCamelCase	)
													repo.git_push(blocking=__UpperCamelCase	)  # this prints a progress bar with the upload
													self._logger.warning(f"""TF weights pushed into {self._model_name}"""	)
										elif not self._no_pr:
													self._logger.warning('Uploading the weights into a new PR...'	)
													lowerCamelCase__     :					Optional[int]     	=(
													    'Model converted by the [`transformers`\' `pt_to_tf`'
													    ' CLI](https://github.com/huggingface/transformers/blob/main/src/transformers/commands/pt_to_tf.py). '
													    'All converted model outputs and hidden layers were validated against its PyTorch counterpart.\n\n'
													    f"""Maximum crossload output difference={max_crossload_output_diff:.3e}; """
													    f"""Maximum crossload hidden layer difference={max_crossload_hidden_diff:.3e};\n"""
													    f"""Maximum conversion output difference={max_conversion_output_diff:.3e}; """
													    f"""Maximum conversion hidden layer difference={max_conversion_hidden_diff:.3e};\n"""
													)
													if self._max_error > MAX_ERROR:
																commit_descrition += (
																    f"""\n\nCAUTION: The maximum admissible error was manually increased to {self._max_error}!"""
																)
													if self._extra_commit_description:
																commit_descrition += "\n\n" + self._extra_commit_description

													# sharded model -> adds all related files (index and .h5 shards)
													if os.path.exists(__UpperCamelCase	):
																lowerCamelCase__     :					str     	=[
																    CommitOperationAdd(path_in_repo=__UpperCamelCase					,							path_or_fileobj=__UpperCamelCase	)
																]
																for shard_path in tf.io.gfile.glob(self._local_dir + '/tf_model-*.h5'	):
																			operations += [
																			    CommitOperationAdd(path_in_repo=os.path.basename(__UpperCamelCase	)					,							path_or_fileobj=__UpperCamelCase	)
																			]
													else:
																lowerCamelCase__     :					List[Any]     	=[CommitOperationAdd(path_in_repo=__UpperCamelCase					,							path_or_fileobj=__UpperCamelCase	)]

													lowerCamelCase__     :					Tuple     	=create_commit(
													    repo_id=self._model_name					,							operations=__UpperCamelCase					,							commit_message=__UpperCamelCase					,							commit_description=__UpperCamelCase					,							repo_type='model'					,							create_pr=__UpperCamelCase					,							).pr_url
													self._logger.warning(f"""PR open in {hub_pr_url}"""	)

"""simple docstring"""


from ...configuration_utils import PretrainedConfig
from ...utils import logging


lowerCAmelCase								=						logging.get_logger(__name__)

lowerCAmelCase								=						{
    """uw-madison/nystromformer-512""": """https://huggingface.co/uw-madison/nystromformer-512/resolve/main/config.json""",
    # See all Nystromformer models at https://huggingface.co/models?filter=nystromformer
}

class    A_     (					A__       ):



							"""simple docstring"""






							SCREAMING_SNAKE_CASE_     				=       """nystromformer"""





							def __init__(  self  :Optional[Any]					,							lowerCamelCase_  :Optional[Any]=30_000					,							lowerCamelCase_  :str=768					,							lowerCamelCase_  :str=12					,							lowerCamelCase_  :str=12					,							lowerCamelCase_  :Any=3_072					,							lowerCamelCase_  :Optional[int]="gelu_new"					,							lowerCamelCase_  :List[Any]=0.1					,							lowerCamelCase_  :List[str]=0.1					,							lowerCamelCase_  :Any=510					,							lowerCamelCase_  :Optional[int]=2					,							lowerCamelCase_  :List[Any]=64					,							lowerCamelCase_  :Union[str, Any]=64					,							lowerCamelCase_  :str=65					,							lowerCamelCase_  :Union[str, Any]=False					,							lowerCamelCase_  :str=0.02					,							lowerCamelCase_  :Any=1e-5					,							lowerCamelCase_  :int=1					,							lowerCamelCase_  :Optional[int]=0					,							lowerCamelCase_  :str=2					,							**lowerCamelCase_  :int					,							):





										"""simple docstring"""

										lowerCamelCase__     :					int		=vocab_size
										lowerCamelCase__     :					Optional[int]		=max_position_embeddings
										lowerCamelCase__     :					List[Any]		=hidden_size
										lowerCamelCase__     :					Tuple		=num_hidden_layers
										lowerCamelCase__     :					Optional[Any]		=num_attention_heads
										lowerCamelCase__     :					List[str]		=intermediate_size
										lowerCamelCase__     :					Union[str, Any]		=hidden_act
										lowerCamelCase__     :					int		=hidden_dropout_prob
										lowerCamelCase__     :					Tuple		=attention_probs_dropout_prob
										lowerCamelCase__     :					Dict		=initializer_range
										lowerCamelCase__     :					Tuple		=type_vocab_size
										lowerCamelCase__     :					Any		=segment_means_seq_len
										lowerCamelCase__     :					int		=num_landmarks
										lowerCamelCase__     :					Tuple		=conv_kernel_size
										lowerCamelCase__     :					Optional[int]		=inv_coeff_init_option
										lowerCamelCase__     :					List[str]		=layer_norm_eps
										super().__init__(pad_token_id=lowerCamelCase_					,							bos_token_id=lowerCamelCase_					,							eos_token_id=lowerCamelCase_					,							**lowerCamelCase_	)