

from copy import deepcopy
from pathlib import Path
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union

import torch
from torch import nn
from torch.utils.data import Dataset

from .deepspeed import is_deepspeed_zeroa_enabled
from .generation.configuration_utils import GenerationConfig
from .trainer import Trainer
from .utils import logging


if TYPE_CHECKING:
						from .data.data_collator import DataCollator
						from .modeling_utils import PreTrainedModel
						from .tokenization_utils_base import PreTrainedTokenizerBase
						from .trainer_callback import TrainerCallback
						from .trainer_utils import EvalPrediction, PredictionOutput
						from .training_args import TrainingArguments


A__							=				logging.get_logger(__name__)

class 					__UpperCamelCase					(       SCREAMING_SNAKE_CASE      ):







	def __init__( self:			Dict	,			__UpperCamelCase:			Union["PreTrainedModel", nn.Module] = None	,			__UpperCamelCase:			"TrainingArguments" = None	,			__UpperCamelCase:			Optional["DataCollator"] = None	,			__UpperCamelCase:			Optional[Dataset] = None	,			__UpperCamelCase:			Optional[Union[Dataset, Dict[str, Dataset]]] = None	,			__UpperCamelCase:			Optional["PreTrainedTokenizerBase"] = None	,			__UpperCamelCase:			Optional[Callable[[], "PreTrainedModel"]] = None	,			__UpperCamelCase:			Optional[Callable[["EvalPrediction"], Dict]] = None	,			__UpperCamelCase:			Optional[List["TrainerCallback"]] = None	,			__UpperCamelCase:			Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR] = (None, None)	,			__UpperCamelCase:			Optional[Callable[[torch.Tensor, torch.Tensor], torch.Tensor]] = None	,			):

						'''simple docstring'''





						super().__init__(
						    model=__UpperCamelCase	,			args=__UpperCamelCase	,			data_collator=__UpperCamelCase	,			train_dataset=__UpperCamelCase	,			eval_dataset=__UpperCamelCase	,			tokenizer=__UpperCamelCase	,			model_init=__UpperCamelCase	,			compute_metrics=__UpperCamelCase	,			callbacks=__UpperCamelCase	,			optimizers=__UpperCamelCase	,			preprocess_logits_for_metrics=__UpperCamelCase	,			)

						# Override self.model.generation_config if a GenerationConfig is specified in args.
						# Priority: args.generation_config > model.generation_config > default GenerationConfig.
						if self.args.generation_config is not None:
											__magic_name__				=     self.load_generation_config(self.args.generation_config   )
											__magic_name__				=     gen_config







	@staticmethod
	def 						_SCREAMING_SNAKE_CASE				( __UpperCamelCase:			Union[str, GenerationConfig]   ):

						'''simple docstring'''





						if isinstance(__UpperCamelCase	,			__UpperCamelCase   ):
											return deepcopy(__UpperCamelCase   )

						# str or Path
						__magic_name__				=     Path(__UpperCamelCase   ) if isinstance(__UpperCamelCase	,			__UpperCamelCase   ) else gen_config_arg
						__magic_name__				=     None

						# Figuring if it is path pointing to a file, pointing to a directory or else a model id or URL
						# This step is required in order to determine config_file_name
						if pretrained_model_name.is_file():
											__magic_name__				=     pretrained_model_name.name
											__magic_name__				=     pretrained_model_name.parent
						# dir path
						elif pretrained_model_name.is_dir():
											pass
						# model id or URL
						else:
											__magic_name__				=     gen_config_arg

						__magic_name__				=     GenerationConfig.from_pretrained(__UpperCamelCase	,			__UpperCamelCase   )
						return gen_config







	def 						_SCREAMING_SNAKE_CASE				( self:			Dict	,			__UpperCamelCase:			Optional[Dataset] = None	,			__UpperCamelCase:			Optional[List[str]] = None	,			__UpperCamelCase:			str = "eval"	,			**__UpperCamelCase:			Any	,			):

						'''simple docstring'''





						__magic_name__				=     gen_kwargs.copy()
						if gen_kwargs.get('max_length'   ) is None and gen_kwargs.get('max_new_tokens'   ) is None:
											__magic_name__				=     self.args.generation_max_length
						__magic_name__				=     (
						    gen_kwargs['num_beams'] if gen_kwargs.get('num_beams'   ) is not None else self.args.generation_num_beams
						)
						__magic_name__				=     gen_kwargs

						return super().evaluate(__UpperCamelCase	,			ignore_keys=__UpperCamelCase	,			metric_key_prefix=__UpperCamelCase   )







	def 						_SCREAMING_SNAKE_CASE				( self:			Union[str, Any]	,			__UpperCamelCase:			Dataset	,			__UpperCamelCase:			Optional[List[str]] = None	,			__UpperCamelCase:			str = "test"	,			**__UpperCamelCase:			Optional[int]	,			):

						'''simple docstring'''





						__magic_name__				=     gen_kwargs.copy()
						if gen_kwargs.get('max_length'   ) is None and gen_kwargs.get('max_new_tokens'   ) is None:
											__magic_name__				=     self.args.generation_max_length
						__magic_name__				=     (
						    gen_kwargs['num_beams'] if gen_kwargs.get('num_beams'   ) is not None else self.args.generation_num_beams
						)
						__magic_name__				=     gen_kwargs

						return super().predict(__UpperCamelCase	,			ignore_keys=__UpperCamelCase	,			metric_key_prefix=__UpperCamelCase   )







	def 						_SCREAMING_SNAKE_CASE				( self:			Dict	,			__UpperCamelCase:			nn.Module	,			__UpperCamelCase:			Dict[str, Union[torch.Tensor, Any]]	,			__UpperCamelCase:			bool	,			__UpperCamelCase:			Optional[List[str]] = None	,			**__UpperCamelCase:			Any	,			):

						'''simple docstring'''





						if not self.args.predict_with_generate or prediction_loss_only:
											return super().prediction_step(
											    __UpperCamelCase	,			__UpperCamelCase	,			prediction_loss_only=__UpperCamelCase	,			ignore_keys=__UpperCamelCase   )

						__magic_name__				=     'labels' in inputs
						__magic_name__				=     self._prepare_inputs(__UpperCamelCase   )

						# XXX: adapt synced_gpus for fairscale as well
						# Priority (handled in generate):
						# gen_kwargs > model.generation_config > default GenerationConfig()

						if len(__UpperCamelCase   ) == 0 and hasattr(self	,			'_gen_kwargs'   ):
											__magic_name__				=     self._gen_kwargs.copy()

						if gen_kwargs.get('max_length'   ) is None and gen_kwargs.get('max_new_tokens'   ) is None:
											__magic_name__				=     self.model.config.max_length
						__magic_name__				=     (
						    gen_kwargs['num_beams'] if gen_kwargs.get('num_beams'   ) is not None else self.model.config.num_beams
						)
						__magic_name__				=     True if is_deepspeed_zeroa_enabled() else False
						__magic_name__				=     (
						    gen_kwargs['synced_gpus'] if gen_kwargs.get('synced_gpus'   ) is not None else default_synced_gpus
						)

						# If the `decoder_input_ids` was created from `labels`, evict the former, so that the model can freely generate
						# (otherwise, it would continue generating from the padded `decoder_input_ids`)
						if (
						    "labels" in inputs
						    and "decoder_input_ids" in inputs
						    and inputs["labels"].shape == inputs["decoder_input_ids"].shape
						):
											__magic_name__				=     {k: v for k, v in inputs.items() if k != 'decoder_input_ids'}
						__magic_name__				=     self.model.generate(**__UpperCamelCase	,			**__UpperCamelCase   )

						# Temporary hack to ensure the generation config is not initialized for each iteration of the evaluation loop
						# TODO: remove this hack when the legacy code that initializes generation_config from a model config is
						# removed in https://github.com/huggingface/transformers/blob/98d88b23f54e5a23e741833f1e973fdf600cc2c5/src/transformers/generation/utils.py#L1183
						if self.model.generation_config._from_model_config:
											__magic_name__				=     False

						# Retrieves GenerationConfig from model.generation_config
						__magic_name__				=     self.model.generation_config
						# in case the batch is shorter than max length, the output should be padded
						if generated_tokens.shape[-1] < gen_config.max_length:
											__magic_name__				=     self._pad_tensors_to_max_len(__UpperCamelCase	,			gen_config.max_length   )
						elif gen_config.max_new_tokens is not None and generated_tokens.shape[-1] < gen_config.max_new_tokens + 1:
											__magic_name__				=     self._pad_tensors_to_max_len(__UpperCamelCase	,			gen_config.max_new_tokens + 1   )

						with torch.no_grad():
											if has_labels:
																with self.compute_loss_context_manager():
																					__magic_name__				=     model(**__UpperCamelCase   )
																if self.label_smoother is not None:
																					__magic_name__				=     self.label_smoother(__UpperCamelCase	,			inputs['labels']   ).mean().detach()
																else:
																					__magic_name__				=     (outputs['loss'] if isinstance(__UpperCamelCase	,			__UpperCamelCase   ) else outputs[0]).mean().detach()
											else:
																__magic_name__				=     None

						if self.args.prediction_loss_only:
											return loss, None, None

						if has_labels:
											__magic_name__				=     inputs['labels']
											if labels.shape[-1] < gen_config.max_length:
																__magic_name__				=     self._pad_tensors_to_max_len(__UpperCamelCase	,			gen_config.max_length   )
											elif gen_config.max_new_tokens is not None and labels.shape[-1] < gen_config.max_new_tokens + 1:
																__magic_name__				=     self._pad_tensors_to_max_len(__UpperCamelCase	,			gen_config.max_new_tokens + 1   )
						else:
											__magic_name__				=     None

						return loss, generated_tokens, labels







	def 						_SCREAMING_SNAKE_CASE				( self:			int	,			__UpperCamelCase:			str	,			__UpperCamelCase:			int   ):

						'''simple docstring'''





						if self.tokenizer is not None and hasattr(self.tokenizer	,			'pad_token_id'   ):
											# If PAD token is not defined at least EOS token has to be defined
											__magic_name__				=     (
											    self.tokenizer.pad_token_id if self.tokenizer.pad_token_id is not None else self.tokenizer.eos_token_id
											)
						else:
											if self.model.config.pad_token_id is not None:
																__magic_name__				=     self.model.config.pad_token_id
											else:
																raise ValueError('Pad_token_id must be set in the configuration of the model, in order to pad tensors'   )

						__magic_name__				=     pad_token_id * torch.ones(
						    (tensor.shape[0], max_length)	,			dtype=tensor.dtype	,			device=tensor.device   )
						__magic_name__				=     tensor
						return padded_tensor







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


A__							=				logging.get_logger(__name__)

A__							=				{
    "tau/splinter-base": "https://huggingface.co/tau/splinter-base/resolve/main/config.json",
    "tau/splinter-base-qass": "https://huggingface.co/tau/splinter-base-qass/resolve/main/config.json",
    "tau/splinter-large": "https://huggingface.co/tau/splinter-large/resolve/main/config.json",
    "tau/splinter-large-qass": "https://huggingface.co/tau/splinter-large-qass/resolve/main/config.json",
    # See all Splinter models at https://huggingface.co/models?filter=splinter
}

class 					__UpperCamelCase					(       SCREAMING_SNAKE_CASE      ):
	_lowercase	: int												=	"splinter"







	def __init__( self:			str	,			__UpperCamelCase:			Any=3_05_22	,			__UpperCamelCase:			List[Any]=7_68	,			__UpperCamelCase:			str=12	,			__UpperCamelCase:			Optional[Any]=12	,			__UpperCamelCase:			Optional[int]=30_72	,			__UpperCamelCase:			List[str]="gelu"	,			__UpperCamelCase:			Union[str, Any]=0.1	,			__UpperCamelCase:			Dict=0.1	,			__UpperCamelCase:			str=5_12	,			__UpperCamelCase:			Dict=2	,			__UpperCamelCase:			str=0.02	,			__UpperCamelCase:			Tuple=1E-12	,			__UpperCamelCase:			Optional[int]=True	,			__UpperCamelCase:			Union[str, Any]=0	,			__UpperCamelCase:			Optional[int]=1_04	,			**__UpperCamelCase:			Tuple	,			):

						'''simple docstring'''





						super().__init__(pad_token_id=__UpperCamelCase	,			**__UpperCamelCase   )

						__magic_name__				=     vocab_size
						__magic_name__				=     max_position_embeddings
						__magic_name__				=     hidden_size
						__magic_name__				=     num_hidden_layers
						__magic_name__				=     num_attention_heads
						__magic_name__				=     intermediate_size
						__magic_name__				=     hidden_act
						__magic_name__				=     hidden_dropout_prob
						__magic_name__				=     attention_probs_dropout_prob
						__magic_name__				=     initializer_range
						__magic_name__				=     type_vocab_size
						__magic_name__				=     layer_norm_eps
						__magic_name__				=     use_cache
						__magic_name__				=     question_token_id




