



'''simple docstring'''

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				:    int     						=logging.get_logger(__name__)







def 						__UpperCamelCase				(							_lowercase,				_lowercase,				_lowercase,				_lowercase=None,				_lowercase=None					) ->			int:
	# Recurse if needed
	if "." in tensor_name:
		_lowercase					:       List[str]       =		tensor_name.split('.'					)
		for split in splits[:-1]:
			_lowercase					:       Optional[int]       =		getattr(_lowercase,				_lowercase					)
			if new_module is None:
				raise ValueError(f'''{module} has no attribute {split}.'''					)
			_lowercase					:       int       =		new_module
		_lowercase					:       List[str]       =		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					:       Union[str, Any]       =		tensor_name in module._buffers
	_lowercase					:       str       =		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					:       Optional[Any]       =		False
	_lowercase					:       Union[str, Any]       =		False
	if is_buffer or not is_bitsandbytes_available():
		_lowercase					:       Optional[Any]       =		False
		_lowercase					:       List[Any]       =		False
	else:
		_lowercase					:       Optional[Any]       =		hasattr(bnb.nn,				'Params4bit'					) and isinstance(module._parameters[tensor_name],				bnb.nn.Paramsabit					)
		_lowercase					:       Union[str, Any]       =		isinstance(module._parameters[tensor_name],				bnb.nn.IntaParams					)

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

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

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

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

		if is_buffer:
			_lowercase					:       int       =		new_value
		else:
			_lowercase					:       int       =		nn.Parameter(_lowercase,				requires_grad=old_value.requires_grad					)
			_lowercase					:       Tuple       =		new_value







def 						__UpperCamelCase				(							_lowercase,				_lowercase=None,				_lowercase=None,				_lowercase=None,				_lowercase=False					) ->			Union[str, Any]:
	for name, module in model.named_children():
		if current_key_name is None:
			_lowercase					:       Dict       =		[]
		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					:       Optional[int]       =		module.weight.shape
					else:
						_lowercase					:       Any       =		module.in_features
						_lowercase					:       str       =		module.out_features

					if quantization_config.quantization_method() == "llm_int8":
						_lowercase					:       int       =		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					:       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:
							_lowercase					:       int       =		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					:       Dict       =		True
                    # Store the module class in case we need to transpose the weight later
					_lowercase					:       str       =		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					:       str       =		_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 						__UpperCamelCase				(							_lowercase,				_lowercase=None,				_lowercase=None,				_lowercase=None					) ->			Optional[int]:
	_lowercase					:       Optional[Any]       =		['lm_head'] if modules_to_not_convert is None else modules_to_not_convert
	_lowercase  ,    _lowercase					:       List[Any]       =		_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 						__UpperCamelCase				(							*_lowercase,				**_lowercase					) ->			List[str]:
	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 						__UpperCamelCase				(							*_lowercase,				**_lowercase					) ->			Dict:
	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 						__UpperCamelCase				(							_lowercase					) ->			int:
	_lowercase					:       List[Any]       =		deepcopy(_lowercase					)  # this has 0 cost since it is done inside `init_empty_weights` context manager`
	tied_model.tie_weights()

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

	# Check if it is a base model
	_lowercase					:       str       =		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					:       int       =		list(model.named_children()					)
	_lowercase					:       List[str]       =		[list_modules[-1][0]]

	# add last module together with tied weights
	_lowercase					:       Optional[Any]       =		set(_lowercase					) - set(_lowercase					)
	_lowercase					:       Optional[Any]       =		list(set(_lowercase					)					) + list(_lowercase					)

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

	return filtered_module_names





'''simple docstring'''

import os
from collections.abc import Iterator







def 						__UpperCamelCase				(							_lowercase = "."					) ->			Iterator[str]:
	for dir_path, dir_names, filenames in os.walk(_lowercase					):
		_lowercase					:       Optional[int]       =		[d for d in dir_names if d != 'scripts' and d[0] not in '._']
		for filename in filenames:
			if filename == "__init__.py":
				continue
			if os.path.splitext(_lowercase					)[1] in (".py", ".ipynb"):
				yield os.path.join(_lowercase,				_lowercase					).lstrip('./'					)







def 						__UpperCamelCase				(							_lowercase					) ->			List[str]:
	return f'''{i * "  "}*''' if i else "\n##"







def 						__UpperCamelCase				(							_lowercase,				_lowercase					) ->			str:
	_lowercase					:       Optional[Any]       =		old_path.split(os.sep					)
	for i, new_part in enumerate(new_path.split(os.sep					)					):
		if (i + 1 > len(_lowercase					) or old_parts[i] != new_part) and new_part:
			print(f'''{md_prefix(_lowercase					)} {new_part.replace("_",				" "					).title()}'''					)
	return new_path







def 						__UpperCamelCase				(							_lowercase = "."					) ->			None:
	_lowercase					:       Dict       =		''
	for filepath in sorted(good_file_paths(_lowercase					)					):
		_lowercase  ,    _lowercase					:       Optional[Any]       =		os.path.split(_lowercase					)
		if filepath != old_path:
			_lowercase					:       Dict       =		print_path(_lowercase,				_lowercase					)
		_lowercase					:       Optional[int]       =		(filepath.count(os.sep					) + 1) if filepath else 0
		_lowercase					:       Dict       =		f'''{filepath}/{filename}'''.replace(' ',				'%20'					)
		_lowercase					:       Optional[int]       =		os.path.splitext(filename.replace('_',				' '					).title()					)[0]
		print(f'''{md_prefix(_lowercase					)} [{filename}]({url})'''					)


if __name__ == "__main__":
		print_directory_md('''.''')
