


import importlib.metadata
import warnings
from copy import deepcopy

from packaging import version

from ..utils import logging
from .import_utils import is_accelerate_available, is_bitsandbytes_available


if is_bitsandbytes_available():
	import bitsandbytes as bnb
	import torch
	import torch.nn as nn

	from ..pytorch_utils import ConvaD

if is_accelerate_available():
	from accelerate import init_empty_weights
	from accelerate.utils import find_tied_parameters

lowerCAmelCase           =		logging.get_logger(__name__)







def        _lowerCamelCase(	lowercase__   , lowercase__   , lowercase__   , lowercase__=None   , lowercase__=None	)						->	List[Any]:

		'''simple docstring'''







		if "." in tensor_name:
				__lowercase=			tensor_name.split('.'	)
				for split in splits[:-1]:
						__lowercase=			getattr(lowercase__   , lowercase__	)
						if new_module is None:
								raise ValueError(F'{module} has no attribute {split}.'	)
						__lowercase=			new_module
				__lowercase=			splits[-1]

		if tensor_name not in module._parameters and tensor_name not in module._buffers:
				raise ValueError(F'{module} does not have a parameter or a buffer named {tensor_name}.'	)
		__lowercase=			tensor_name in module._buffers
		__lowercase=			getattr(lowercase__   , lowercase__	)

		if old_value.device == torch.device('meta'	) and device not in ["meta", torch.device('meta'	)] and value is None:
				raise ValueError(F'{tensor_name} is on the meta device, we need a `value` to put in on {device}.'	)

		__lowercase=			False
		__lowercase=			False
		if is_buffer or not is_bitsandbytes_available():
				__lowercase=			False
				__lowercase=			False
		else:
				__lowercase=			hasattr(bnb.nn   , 'Params4bit'	) and isinstance(module._parameters[tensor_name]   , bnb.nn.Paramsabit	)
				__lowercase=			isinstance(module._parameters[tensor_name]   , bnb.nn.IntaParams	)

		if is_abit or is_abit:
				__lowercase=			module._parameters[tensor_name]
				if param.device.type != "cuda":
						if value is None:
								__lowercase=			old_value.to(lowercase__	)
						elif isinstance(lowercase__   , torch.Tensor	):
								__lowercase=			value.to('cpu'	)
								if value.dtype == torch.inta:
										__lowercase=			version.parse(importlib.metadata.version('bitsandbytes'	)	) > version.parse(
										    '0.37.2'	)
										if not is_abit_serializable:
												raise ValueError(
												    'Detected int8 weights but the version of bitsandbytes is not compatible with int8 serialization. '
												    'Make sure to download the latest `bitsandbytes` version. `pip install --upgrade bitsandbytes`.'	)
						else:
								__lowercase=			torch.tensor(lowercase__   , device='cpu'	)

						# Support models using `Conv1D` in place of `nn.Linear` (e.g. gpt2) by transposing the weight matrix prior to quantization.
						# Since weights are saved in the correct "orientation", we skip transposing when loading.
						if issubclass(module.source_cls   , lowercase__	) and fpaa_statistics is None:
								__lowercase=			new_value.T

						__lowercase=			old_value.__dict__
						if is_abit:
								__lowercase=			bnb.nn.IntaParams(lowercase__   , requires_grad=lowercase__   , **lowercase__	).to(lowercase__	)
						elif is_abit:
								__lowercase=			bnb.nn.Paramsabit(lowercase__   , requires_grad=lowercase__   , **lowercase__	).to(lowercase__	)

						__lowercase=			new_value
						if fpaa_statistics is not None:
								setattr(module.weight   , 'SCB'   , fpaa_statistics.to(lowercase__	)	)

		else:
				if value is None:
						__lowercase=			old_value.to(lowercase__	)
				elif isinstance(lowercase__   , torch.Tensor	):
						__lowercase=			value.to(lowercase__	)
				else:
						__lowercase=			torch.tensor(lowercase__   , device=lowercase__	)

				if is_buffer:
						__lowercase=			new_value
				else:
						__lowercase=			nn.Parameter(lowercase__   , requires_grad=old_value.requires_grad	)
						__lowercase=			new_value







def        _lowerCamelCase(	lowercase__   , lowercase__=None   , lowercase__=None   , lowercase__=None   , lowercase__=False	)						->	Union[str, Any]:

		'''simple docstring'''







		for name, module in model.named_children():
				if current_key_name is None:
						__lowercase=			[]
				current_key_name.append(lowercase__	)

				if (isinstance(lowercase__   , nn.Linear	) or isinstance(lowercase__   , lowercase__	)) and name not in modules_to_not_convert:
						# Check if the current key is not in the `modules_to_not_convert`
						if not any(key in '.'.join(lowercase__	) for key in modules_to_not_convert	):
								with init_empty_weights():
										if isinstance(lowercase__   , lowercase__	):
												__lowercase,							__lowercase=			module.weight.shape
										else:
												__lowercase=			module.in_features
												__lowercase=			module.out_features

										if quantization_config.quantization_method() == "llm_int8":
												__lowercase=			bnb.nn.LinearabitLt(
												    lowercase__   , lowercase__   , module.bias is not None   , has_fpaa_weights=quantization_config.llm_inta_has_fpaa_weight   , threshold=quantization_config.llm_inta_threshold   , )
												__lowercase=			True
										else:
												if (
												    quantization_config.llm_inta_skip_modules is not None
												    and name in quantization_config.llm_inta_skip_modules
												):
														pass
												else:
														__lowercase=			bnb.nn.Linearabit(
														    lowercase__   , lowercase__   , module.bias is not None   , quantization_config.bnb_abit_compute_dtype   , compress_statistics=quantization_config.bnb_abit_use_double_quant   , quant_type=quantization_config.bnb_abit_quant_type   , )
														__lowercase=			True
                    # Store the module class in case we need to transpose the weight later
										__lowercase=			type(lowercase__	)
										# Force requires grad to False to avoid unexpected errors
										model._modules[name].requires_grad_(lowercase__	)
				if len(list(module.children()	)	) > 0:
						__lowercase,							__lowercase=			_replace_with_bnb_linear(
						    lowercase__   , lowercase__   , lowercase__   , lowercase__   , has_been_replaced=lowercase__   , )
				# Remove the last key for recursion
				current_key_name.pop(-1	)
		return model, has_been_replaced







def        _lowerCamelCase(	lowercase__   , lowercase__=None   , lowercase__=None   , lowercase__=None	)						->	List[str]:

		'''simple docstring'''







		__lowercase=			['lm_head'] if modules_to_not_convert is None else modules_to_not_convert
		__lowercase,							__lowercase=			_replace_with_bnb_linear(
		    lowercase__   , lowercase__   , lowercase__   , lowercase__	)

		if not has_been_replaced:
				logger.warning(
				    'You are loading your model in 8bit or 4bit but no linear modules were found in your model.'
				    ' Please double check your model architecture, or submit an issue on github if you think this is'
				    ' a bug.'	)

		return model







def        _lowerCamelCase(	*lowercase__   , **lowercase__	)						->	Optional[Any]:

		'''simple docstring'''







		warnings.warn(
		    '`replace_8bit_linear` will be deprecated in a future version, please use `replace_with_bnb_linear` instead'   , lowercase__   , )
		return replace_with_bnb_linear(*lowercase__   , **lowercase__	)







def        _lowerCamelCase(	*lowercase__   , **lowercase__	)						->	List[str]:

		'''simple docstring'''







		warnings.warn(
		    '`set_module_8bit_tensor_to_device` will be deprecated in a future version, please use `set_module_quantized_tensor_to_device` instead'   , lowercase__   , )
		return set_module_quantized_tensor_to_device(*lowercase__   , **lowercase__	)







def        _lowerCamelCase(	lowercase__	)						->	str:

		'''simple docstring'''







		__lowercase=			deepcopy(lowercase__	)  # this has 0 cost since it is done inside `init_empty_weights` context manager`
		tied_model.tie_weights()

		__lowercase=			find_tied_parameters(lowercase__	)
		# For compatibility with Accelerate < 0.18
		if isinstance(lowercase__   , lowercase__	):
				__lowercase=			sum(list(tied_params.values()	)   , []	) + list(tied_params.keys()	)
		else:
				__lowercase=			sum(lowercase__   , []	)
		__lowercase=			len(lowercase__	) > 0

		# Check if it is a base model
		__lowercase=			not hasattr(lowercase__   , model.base_model_prefix	)

		# Ignore this for base models (BertModel, GPT2Model, etc.)
		if (not has_tied_params) and is_base_model:
				return []

		# otherwise they have an attached head
		__lowercase=			list(model.named_children()	)
		__lowercase=			[list_modules[-1][0]]

		# add last module together with tied weights
		__lowercase=			set(lowercase__	) - set(lowercase__	)
		__lowercase=			list(set(lowercase__	)	) + list(lowercase__	)

		# remove ".weight" from the keys
		__lowercase=			['.weight', '.bias']
		__lowercase=			[]
		for name in list_untouched:
				for name_to_remove in names_to_remove:
						if name_to_remove in name:
								__lowercase=			name.replace(lowercase__   , ''	)
				filtered_module_names.append(lowercase__	)

		return filtered_module_names










import os
import re
import warnings
from shutil import copyfile
from typing import List, Optional, Tuple

from ...tokenization_utils_fast import PreTrainedTokenizerFast
from ...utils import is_sentencepiece_available, logging


if is_sentencepiece_available():
	from .tokenization_ta import TaTokenizer
else:
	lowerCAmelCase           =		None


lowerCAmelCase           =		logging.get_logger(__name__)

lowerCAmelCase           =		{'''vocab_file''': '''spiece.model''', '''tokenizer_file''': '''tokenizer.json'''}

lowerCAmelCase           =		{
    '''vocab_file''': {
        '''t5-small''': '''https://huggingface.co/t5-small/resolve/main/spiece.model''',
        '''t5-base''': '''https://huggingface.co/t5-base/resolve/main/spiece.model''',
        '''t5-large''': '''https://huggingface.co/t5-large/resolve/main/spiece.model''',
        '''t5-3b''': '''https://huggingface.co/t5-3b/resolve/main/spiece.model''',
        '''t5-11b''': '''https://huggingface.co/t5-11b/resolve/main/spiece.model''',
    },
    '''tokenizer_file''': {
        '''t5-small''': '''https://huggingface.co/t5-small/resolve/main/tokenizer.json''',
        '''t5-base''': '''https://huggingface.co/t5-base/resolve/main/tokenizer.json''',
        '''t5-large''': '''https://huggingface.co/t5-large/resolve/main/tokenizer.json''',
        '''t5-3b''': '''https://huggingface.co/t5-3b/resolve/main/tokenizer.json''',
        '''t5-11b''': '''https://huggingface.co/t5-11b/resolve/main/tokenizer.json''',
    },
}


# TODO(PVP) - this should be removed in Transformers v5
lowerCAmelCase           =		{
    '''t5-small''': 5_1_2,
    '''t5-base''': 5_1_2,
    '''t5-large''': 5_1_2,
    '''t5-3b''': 5_1_2,
    '''t5-11b''': 5_1_2,
}





class       A    (   A_ ):
							UpperCamelCase_   :							Dict       =VOCAB_FILES_NAMES
							UpperCamelCase_   :							Dict       =PRETRAINED_VOCAB_FILES_MAP
							UpperCamelCase_   :							List[Any]       =PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
							UpperCamelCase_   :							str       =['''input_ids''', '''attention_mask''']
							UpperCamelCase_   :							List[str]       =TaTokenizer

							UpperCamelCase_   :							List[int]       =[]


							def __init__(self      ,				lowerCAmelCase=None      ,				lowerCAmelCase=None      ,				lowerCAmelCase="</s>"      ,				lowerCAmelCase="<unk>"      ,				lowerCAmelCase="<pad>"      ,				lowerCAmelCase=1_0_0      ,				lowerCAmelCase=None      ,				**lowerCAmelCase      ,				):
									# Add extra_ids to the special token list
									if extra_ids > 0 and additional_special_tokens is None:
											__lowercase=			[f'<extra_id_{i}>' for i in range(lowerCAmelCase					)]
									elif extra_ids > 0 and additional_special_tokens is not None:
											# Check that we have the right number of extra special tokens
											__lowercase=			len(set(filter(lambda lowerCAmelCase					: bool('extra_id_' in str(lowerCAmelCase					)					)      ,				lowerCAmelCase					)					)					)
											if extra_tokens != extra_ids:
													raise ValueError(
													    f'Both extra_ids ({extra_ids}) and additional_special_tokens ({additional_special_tokens}) are'
													    ' provided to T5Tokenizer. In this case the additional_special_tokens must include the extra_ids'
													    ' tokens'					)

									super().__init__(
									    lowerCAmelCase      ,				tokenizer_file=lowerCAmelCase      ,				eos_token=lowerCAmelCase      ,				unk_token=lowerCAmelCase      ,				pad_token=lowerCAmelCase      ,				extra_ids=lowerCAmelCase      ,				additional_special_tokens=lowerCAmelCase      ,				**lowerCAmelCase      ,				)

									__lowercase=			vocab_file
									__lowercase=			False if not self.vocab_file else True
									__lowercase=			extra_ids


							@staticmethod
							def 			_A       (lowerCAmelCase      ,				lowerCAmelCase      ,				lowerCAmelCase					):
									if pretrained_model_name_or_path in TaTokenizerFast.max_model_input_sizes:
											__lowercase=			TaTokenizerFast.max_model_input_sizes[pretrained_model_name_or_path]
											if init_max_model_length is not None and init_max_model_length != max_model_length:
													return init_max_model_length
											elif init_max_model_length is None:
													warnings.warn(
													    'This tokenizer was incorrectly instantiated with a model max length of'
													    f' {deprecated_max_model_length} which will be corrected in Transformers v5.\nFor now, this'
													    ' behavior is kept to avoid breaking backwards compatibility when padding/encoding with'
													    ' `truncation is True`.\n- Be aware that you SHOULD NOT rely on'
													    f' {pretrained_model_name_or_path} automatically truncating your input to'
													    f' {deprecated_max_model_length} when padding/encoding.\n- If you want to encode/pad to sequences'
													    f' longer than {deprecated_max_model_length} you can either instantiate this tokenizer with'
													    ' `model_max_length` or pass `max_length` when encoding/padding.\n- To avoid this warning, please'
													    ' instantiate this tokenizer with `model_max_length` set to your preferred value.'      ,				lowerCAmelCase      ,				)

									return max_model_length


							def 			_A       (self      ,				lowerCAmelCase      ,				lowerCAmelCase = None					):
									if not self.can_save_slow_tokenizer:
											raise ValueError(
											    'Your fast tokenizer does not have the necessary information to save the vocabulary for a slow '
											    'tokenizer.'					)

									if not os.path.isdir(lowerCAmelCase					):
											logger.error(f'Vocabulary path ({save_directory}) should be a directory'					)
											return
									__lowercase=			os.path.join(
									    lowerCAmelCase      ,				(filename_prefix + '-' if filename_prefix else '') + VOCAB_FILES_NAMES['vocab_file']					)

									if os.path.abspath(self.vocab_file					) != os.path.abspath(lowerCAmelCase					):
											copyfile(self.vocab_file      ,				lowerCAmelCase					)
											logger.info(f'Copy vocab file to {out_vocab_file}'					)

									return (out_vocab_file,)


							def 			_A       (self      ,				lowerCAmelCase      ,				lowerCAmelCase = None					):
									__lowercase=			token_ids_a + [self.eos_token_id]
									if token_ids_a is None:
											return self.prefix_tokens + token_ids_a
									else:
											__lowercase=			token_ids_a + [self.eos_token_id]
											return self.prefix_tokens + token_ids_a + token_ids_a


							def 			_A       (self      ,				lowerCAmelCase      ,				lowerCAmelCase = None					):
									__lowercase=			[self.eos_token_id]

									if token_ids_a is None:
											return len(token_ids_a + eos					) * [0]
									return len(token_ids_a + eos + token_ids_a + eos					) * [0]


							def 			_A       (self					):
									return list(
									    set(filter(lambda lowerCAmelCase					: bool(re.search(r'<extra_id_\d+>'      ,				lowerCAmelCase					)					) is not None      ,				self.additional_special_tokens					)					)					)







							def 			_A       (self					):
									return [self.convert_tokens_to_ids(lowerCAmelCase					) for token in self.get_sentinel_tokens()]






