

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

a		=logging.get_logger(__name__)






def        SCREAMING_SNAKE_CASE__	(  lowerCamelCase__     ,			lowerCamelCase__     ,			lowerCamelCase__     ,			lowerCamelCase__=None     ,			lowerCamelCase__=None      )  ->					Any:
	# Recurse if needed
	if "." in tensor_name:
		__lowerCamelCase    :    Dict 	=			tensor_name.split('.'      )
		for split in splits[:-1]:
			__lowerCamelCase    :    List[str] 	=			getattr(lowerCamelCase__     ,			lowerCamelCase__      )
			if new_module is None:
				raise ValueError(F"{module} has no attribute {split}."      )
			__lowerCamelCase    :    Any 	=			new_module
		__lowerCamelCase    :    Optional[Any] 	=			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}."      )
	__lowerCamelCase    :    List[str] 	=			tensor_name in module._buffers
	__lowerCamelCase    :    List[str] 	=			getattr(lowerCamelCase__     ,			lowerCamelCase__      )

	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}."      )

	__lowerCamelCase    :    int 	=			False
	__lowerCamelCase    :    str 	=			False
	if is_buffer or not is_bitsandbytes_available():
		__lowerCamelCase    :    List[Any] 	=			False
		__lowerCamelCase    :    str 	=			False
	else:
		__lowerCamelCase    :    Union[str, Any] 	=			hasattr(bnb.nn     ,			'Params4bit'      ) and isinstance(module._parameters[tensor_name]     ,			bnb.nn.Paramsabit      )
		__lowerCamelCase    :    int 	=			isinstance(module._parameters[tensor_name]     ,			bnb.nn.IntaParams      )

	if is_abit or is_abit:
		__lowerCamelCase    :    int 	=			module._parameters[tensor_name]
		if param.device.type != "cuda":
			if value is None:
				__lowerCamelCase    :    Dict 	=			old_value.to(lowerCamelCase__      )
			elif isinstance(lowerCamelCase__     ,			torch.Tensor      ):
				__lowerCamelCase    :    Union[str, Any] 	=			value.to('cpu'      )
				if value.dtype == torch.inta:
					__lowerCamelCase    :    List[Any] 	=			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:
				__lowerCamelCase    :    Tuple 	=			torch.tensor(lowerCamelCase__     ,			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     ,			lowerCamelCase__      ) and fpaa_statistics is None:
				__lowerCamelCase    :    Optional[int] 	=			new_value.T

			__lowerCamelCase    :    str 	=			old_value.__dict__
			if is_abit:
				__lowerCamelCase    :    List[Any] 	=			bnb.nn.IntaParams(lowerCamelCase__     ,			requires_grad=lowerCamelCase__     ,			**lowerCamelCase__      ).to(lowerCamelCase__      )
			elif is_abit:
				__lowerCamelCase    :    Tuple 	=			bnb.nn.Paramsabit(lowerCamelCase__     ,			requires_grad=lowerCamelCase__     ,			**lowerCamelCase__      ).to(lowerCamelCase__      )

			__lowerCamelCase    :    int 	=			new_value
			if fpaa_statistics is not None:
				setattr(module.weight     ,			'SCB'     ,			fpaa_statistics.to(lowerCamelCase__      )      )

	else:
		if value is None:
			__lowerCamelCase    :    List[Any] 	=			old_value.to(lowerCamelCase__      )
		elif isinstance(lowerCamelCase__     ,			torch.Tensor      ):
			__lowerCamelCase    :    Union[str, Any] 	=			value.to(lowerCamelCase__      )
		else:
			__lowerCamelCase    :    Optional[int] 	=			torch.tensor(lowerCamelCase__     ,			device=lowerCamelCase__      )

		if is_buffer:
			__lowerCamelCase    :    Optional[int] 	=			new_value
		else:
			__lowerCamelCase    :    int 	=			nn.Parameter(lowerCamelCase__     ,			requires_grad=old_value.requires_grad      )
			__lowerCamelCase    :    int 	=			new_value






def        SCREAMING_SNAKE_CASE__	(  lowerCamelCase__     ,			lowerCamelCase__=None     ,			lowerCamelCase__=None     ,			lowerCamelCase__=None     ,			lowerCamelCase__=False      )  ->					Dict:
	for name, module in model.named_children():
		if current_key_name is None:
			__lowerCamelCase    :    Optional[int] 	=			[]
		current_key_name.append(lowerCamelCase__      )

		if (isinstance(lowerCamelCase__     ,			nn.Linear      ) or isinstance(lowerCamelCase__     ,			lowerCamelCase__      )) 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(lowerCamelCase__      ) for key in modules_to_not_convert      ):
				with init_empty_weights():
					if isinstance(lowerCamelCase__     ,			lowerCamelCase__      ):
						__lowerCamelCase	,			__lowerCamelCase    :    int 	=			module.weight.shape
					else:
						__lowerCamelCase    :    List[Any] 	=			module.in_features
						__lowerCamelCase    :    List[Any] 	=			module.out_features

					if quantization_config.quantization_method() == "llm_int8":
						__lowerCamelCase    :    Union[str, Any] 	=			bnb.nn.LinearabitLt(
						    lowerCamelCase__     ,			lowerCamelCase__     ,			module.bias is not None     ,			has_fpaa_weights=quantization_config.llm_inta_has_fpaa_weight     ,			threshold=quantization_config.llm_inta_threshold     ,			)
						__lowerCamelCase    :    List[str] 	=			True
					else:
						if (
						    quantization_config.llm_inta_skip_modules is not None
						    and name in quantization_config.llm_inta_skip_modules
						):
							pass
						else:
							__lowerCamelCase    :    Optional[int] 	=			bnb.nn.Linearabit(
							    lowerCamelCase__     ,			lowerCamelCase__     ,			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     ,			)
							__lowerCamelCase    :    str 	=			True
                    # Store the module class in case we need to transpose the weight later
					__lowerCamelCase    :    List[str] 	=			type(lowerCamelCase__      )
					# Force requires grad to False to avoid unexpected errors
					model._modules[name].requires_grad_(lowerCamelCase__      )
		if len(list(module.children()      )      ) > 0:
			__lowerCamelCase	,			__lowerCamelCase    :    Dict 	=			_replace_with_bnb_linear(
			    lowerCamelCase__     ,			lowerCamelCase__     ,			lowerCamelCase__     ,			lowerCamelCase__     ,			has_been_replaced=lowerCamelCase__     ,			)
		# Remove the last key for recursion
		current_key_name.pop(-1      )
	return model, has_been_replaced






def        SCREAMING_SNAKE_CASE__	(  lowerCamelCase__     ,			lowerCamelCase__=None     ,			lowerCamelCase__=None     ,			lowerCamelCase__=None      )  ->					Tuple:
	__lowerCamelCase    :    Any 	=			['lm_head'] if modules_to_not_convert is None else modules_to_not_convert
	__lowerCamelCase	,			__lowerCamelCase    :    Tuple 	=			_replace_with_bnb_linear(
	    lowerCamelCase__     ,			lowerCamelCase__     ,			lowerCamelCase__     ,			lowerCamelCase__      )

	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        SCREAMING_SNAKE_CASE__	(  *lowerCamelCase__     ,			**lowerCamelCase__      )  ->					Optional[Any]:
	warnings.warn(
	    '`replace_8bit_linear` will be deprecated in a future version, please use `replace_with_bnb_linear` instead'     ,			lowerCamelCase__     ,			)
	return replace_with_bnb_linear(*lowerCamelCase__     ,			**lowerCamelCase__      )






def        SCREAMING_SNAKE_CASE__	(  *lowerCamelCase__     ,			**lowerCamelCase__      )  ->					Any:
	warnings.warn(
	    '`set_module_8bit_tensor_to_device` will be deprecated in a future version, please use `set_module_quantized_tensor_to_device` instead'     ,			lowerCamelCase__     ,			)
	return set_module_quantized_tensor_to_device(*lowerCamelCase__     ,			**lowerCamelCase__      )






def        SCREAMING_SNAKE_CASE__	(  lowerCamelCase__      )  ->					Union[str, Any]:
	__lowerCamelCase    :    Dict 	=			deepcopy(lowerCamelCase__      )  # this has 0 cost since it is done inside `init_empty_weights` context manager`
	tied_model.tie_weights()

	__lowerCamelCase    :    Tuple 	=			find_tied_parameters(lowerCamelCase__      )
	# For compatibility with Accelerate < 0.18
	if isinstance(lowerCamelCase__     ,			lowerCamelCase__      ):
		__lowerCamelCase    :    Union[str, Any] 	=			sum(list(tied_params.values()      )     ,			[]      ) + list(tied_params.keys()      )
	else:
		__lowerCamelCase    :    List[Any] 	=			sum(lowerCamelCase__     ,			[]      )
	__lowerCamelCase    :    Optional[int] 	=			len(lowerCamelCase__      ) > 0

	# Check if it is a base model
	__lowerCamelCase    :    Tuple 	=			not hasattr(lowerCamelCase__     ,			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
	__lowerCamelCase    :    int 	=			list(model.named_children()      )
	__lowerCamelCase    :    List[Any] 	=			[list_modules[-1][0]]

	# add last module together with tied weights
	__lowerCamelCase    :    Tuple 	=			set(lowerCamelCase__      ) - set(lowerCamelCase__      )
	__lowerCamelCase    :    Optional[int] 	=			list(set(lowerCamelCase__      )      ) + list(lowerCamelCase__      )

	# remove ".weight" from the keys
	__lowerCamelCase    :    Optional[int] 	=			['.weight', '.bias']
	__lowerCamelCase    :    Tuple 	=			[]
	for name in list_untouched:
		for name_to_remove in names_to_remove:
			if name_to_remove in name:
				__lowerCamelCase    :    str 	=			name.replace(lowerCamelCase__     ,			''      )
		filtered_module_names.append(lowerCamelCase__      )

	return filtered_module_names







from __future__ import annotations

import unittest

from transformers import is_tf_available
from transformers.testing_utils import require_sentencepiece, require_tf, require_tokenizers, slow


if is_tf_available():
					import numpy as np
					import tensorflow as tf

					from transformers import TFCamembertModel






@require_tf
@require_sentencepiece
@require_tokenizers
class 	A_		(	unittest.TestCase    ):
							@slow
							def    lowerCAmelCase					(		self		:      Optional[int]):
								__lowerCamelCase    :    Tuple 	=			TFCamembertModel.from_pretrained('jplu/tf-camembert-base')

								__lowerCamelCase    :    str 	=			tf.convert_to_tensor(
								    [[5, 1_2_1, 1_1, 6_6_0, 1_6, 7_3_0, 2_5_5_4_3, 1_1_0, 8_3, 6]]       ,dtype=tf.intaa       ,)  # J'aime le camembert !"

								__lowerCamelCase    :    int 	=			model(SCREAMING_SNAKE_CASE__)['last_hidden_state']
								__lowerCamelCase    :    Dict 	=			tf.TensorShape((1, 1_0, 7_6_8))
								self.assertEqual(output.shape       ,SCREAMING_SNAKE_CASE__)
								# compare the actual values for a slice.
								__lowerCamelCase    :    Any 	=			tf.convert_to_tensor(
								    [[[-0.0254, 0.0235, 0.1027], [0.0606, -0.1811, -0.0418], [-0.1561, -0.1127, 0.2687]]]       ,dtype=tf.floataa       ,)
								# camembert = torch.hub.load('pytorch/fairseq', 'camembert.v0')
								# camembert.eval()
								# expected_slice = roberta.model.forward(input_ids)[0][:, :3, :3].detach()

								self.assertTrue(np.allclose(output[:, :3, :3].numpy()       ,expected_slice.numpy()       ,atol=1E-4))




