





"""simple docstring"""






import gc
import importlib.metadata
import tempfile
import unittest

from packaging import version

from transformers import (
    AutoModel,
    AutoModelForCausalLM,
    AutoModelForSeqaSeqLM,
    AutoModelForSequenceClassification,
    AutoTokenizer,
    BitsAndBytesConfig,
    pipeline,
)
from transformers.testing_utils import (
    is_torch_available,
    require_accelerate,
    require_bitsandbytes,
    require_torch,
    require_torch_gpu,
    require_torch_multi_gpu,
    slow,
)






def      lowercase__ (					lowerCAmelCase__   :			int			)    ->			Union[str, Any]:



			'''simple docstring'''
			if model.config.model_type == "gpt2":
						return model.transformer.h[0].mlp.c_fc
			return model.transformer.h[0].mlp.dense_ah_to_h


if is_torch_available():
		import torch
		import torch.nn as nn



		class 					__UpperCAmelCase							(						nn.Module  ):
						def __init__(		self    :			Dict	, a_    :			nn.Module	, a_    :			int    )	->	str:



									'''simple docstring'''



									super().__init__()
									a__  :	int		 =			module
									a__  :	str		 =			nn.Sequential(
									    nn.Linear(module.in_features	, a_	, bias=a_    )	, nn.Linear(a_	, module.out_features	, bias=a_    )	, )
									a__  :	Dict		 =			(2.0 / (5 * min(module.in_features	, module.out_features    ))) ** 0.5
									nn.init.normal_(self.adapter[0].weight	, std=a_    )
									nn.init.zeros_(self.adapter[1].weight    )
									self.adapter.to(module.weight.device    )






						def       UpperCAmelCase      (		self    :			Tuple	, a_    :			Optional[Any]	, *a_    :			Optional[int]	, **a_    :			List[str]    )	->	List[Any]:



									'''simple docstring'''



									return self.module(a_	, *a_	, **a_    ) + self.adapter(a_    )



@require_bitsandbytes
@require_accelerate
@require_torch
@require_torch_gpu
@slow
class 					__UpperCAmelCase							(						unittest.TestCase  ):
				# We keep the constants inside the init function and model loading inside setUp function

				# We need to test on relatively large models (aka >1b parameters otherwise the quantiztion may not work as expected)
				# Therefore here we use only bloom-1b3 to test our module
				__lowerCamelCase				:	Tuple				     =				"bigscience/bloom-1b7"

				# Constant values
				__lowerCamelCase				:	Optional[int]				     =				2.1_0_9_6_5_9_5_5_2_6_9_2_5_7_4

				__lowerCamelCase				:	int				     =				"Hello my name is"
				__lowerCamelCase				:	int				     =				set()
				EXPECTED_OUTPUTS.add("Hello my name is John and I am a professional photographer. I"  )
				EXPECTED_OUTPUTS.add("Hello my name is John.\nI am a friend of your father.\n"  )
				EXPECTED_OUTPUTS.add("Hello my name is John Doe, I am a student at the University"  )
				__lowerCamelCase				:	List[Any]				     =				10
				def       UpperCAmelCase      (		self    :			str    )	->	int:



							'''simple docstring'''



							a__  :	Dict		 =			AutoTokenizer.from_pretrained(self.model_name    )



class 					__UpperCAmelCase							(						_UpperCamelCase  ):
				def       UpperCAmelCase      (		self    :			Dict    )	->	Optional[int]:



							'''simple docstring'''



							super().setUp()

							# Models and tokenizer
							a__  :	List[str]		 =			AutoModelForCausalLM.from_pretrained(
							    self.model_name	, torch_dtype=torch.floataa	, device_map="auto"    )
							a__  :	List[str]		 =			AutoModelForCausalLM.from_pretrained(self.model_name	, load_in_abit=a_	, device_map="auto"    )
				def       UpperCAmelCase      (		self    :			Optional[int]    )	->	int:



							'''simple docstring'''



							del self.model_fpaa
							del self.model_abit

							gc.collect()
							torch.cuda.empty_cache()
				def       UpperCAmelCase      (		self    :			str    )	->	List[str]:



							'''simple docstring'''



							a__  :	List[str]		 =			self.model_abit.config

							self.assertTrue(hasattr(a_	, "quantization_config"    )    )

							a__  :	Optional[int]		 =			config.to_dict()
							a__  :	Union[str, Any]		 =			config.to_diff_dict()

							a__  :	int		 =			config.to_json_string()
				def       UpperCAmelCase      (		self    :			Union[str, Any]    )	->	List[Any]:



							'''simple docstring'''



							from bitsandbytes.nn import Paramsabit

							a__  :	Tuple		 =			self.model_fpaa.get_memory_footprint()
							a__  :	List[Any]		 =			self.model_abit.get_memory_footprint()

							self.assertAlmostEqual(mem_fpaa / mem_abit	, self.EXPECTED_RELATIVE_DIFFERENCE    )
							a__  :	Optional[int]		 =			get_some_linear_layer(self.model_abit    )
							self.assertTrue(linear.weight.__class__ == Paramsabit    )
				def       UpperCAmelCase      (		self    :			Optional[Any]    )	->	Tuple:



							'''simple docstring'''



							from transformers import TaPreTrainedModel

							self.model_fpaa.get_memory_footprint()
							self.model_abit.get_memory_footprint()

							for name, module in self.model_abit.named_modules():
										if isinstance(a_	, torch.nn.Linear    ):
													if name not in ["lm_head"] + TaPreTrainedModel._keep_in_fpaa_modules:
																# 4-bit parameters are packed in uint8 variables
																self.assertTrue(module.weight.dtype == torch.uinta    )
				def       UpperCAmelCase      (		self    :			Dict    )	->	List[str]:



							'''simple docstring'''



							a__  :	Optional[int]		 =			self.tokenizer(self.input_text	, return_tensors="pt"    )
							a__  :	List[str]		 =			self.model_abit.generate(input_ids=encoded_input["input_ids"].to(0    )	, max_new_tokens=10    )

							self.assertIn(self.tokenizer.decode(output_sequences[0]	, skip_special_tokens=a_    )	, self.EXPECTED_OUTPUTS    )
				def       UpperCAmelCase      (		self    :			Optional[Any]    )	->	Optional[int]:



							'''simple docstring'''



							a__  :	int		 =			BitsAndBytesConfig()
							a__  :	Dict		 =			True

							a__  :	Tuple		 =			AutoModelForCausalLM.from_pretrained(
							    self.model_name	, quantization_config=a_	, device_map="auto"    )

							a__  :	Tuple		 =			self.tokenizer(self.input_text	, return_tensors="pt"    )
							a__  :	Union[str, Any]		 =			model_abit_from_config.generate(
							    input_ids=encoded_input["input_ids"].to(0    )	, max_new_tokens=10    )

							self.assertIn(self.tokenizer.decode(output_sequences[0]	, skip_special_tokens=a_    )	, self.EXPECTED_OUTPUTS    )
				def       UpperCAmelCase      (		self    :			int    )	->	str:



							'''simple docstring'''



							with self.assertRaises(a_    ), tempfile.TemporaryDirectory() as tmpdirname:
										self.model_abit.save_pretrained(a_    )
				def       UpperCAmelCase      (		self    :			List[Any]    )	->	Dict:



							'''simple docstring'''



							a__  :	Dict		 =			BitsAndBytesConfig()

							with self.assertRaises(a_    ):
										a__  :	Tuple		 =			AutoModelForCausalLM.from_pretrained(
										    self.model_name	, quantization_config=a_	, load_in_abit=a_	, device_map="auto"	, bnb_abit_quant_type="nf4"	, )
				def       UpperCAmelCase      (		self    :			Optional[Any]    )	->	Union[str, Any]:



							'''simple docstring'''



							with self.assertRaises(a_    ):
										# Tries with `str`
										self.model_abit.to("cpu"    )

							with self.assertRaises(a_    ):
										# Tries with a `dtype``
										self.model_abit.to(torch.floataa    )

							with self.assertRaises(a_    ):
										# Tries with a `device`
										self.model_abit.to(torch.device("cuda:0"    )    )

							with self.assertRaises(a_    ):
										# Tries with a `device`
										self.model_abit.float()

							with self.assertRaises(a_    ):
										# Tries with a `device`
										self.model_abit.half()

							# Test if we did not break anything
							a__  :	Optional[int]		 =			self.tokenizer(self.input_text	, return_tensors="pt"    )

							a__  :	Optional[int]		 =			self.model_fpaa.to(torch.floataa    )
							a__  :	List[Any]		 =			self.model_fpaa.generate(input_ids=encoded_input["input_ids"].to(0    )	, max_new_tokens=10    )

							# Check this does not throw an error
							a__  :	str		 =			self.model_fpaa.to("cpu"    )

							# Check this does not throw an error
							a__  :	Any		 =			self.model_fpaa.half()

							# Check this does not throw an error
							a__  :	Optional[Any]		 =			self.model_fpaa.float()






				def       UpperCAmelCase      (		self    :			Dict    )	->	str:



							'''simple docstring'''



							a__  :	Dict		 =			AutoModelForSeqaSeqLM.from_pretrained("t5-small"	, load_in_abit=a_	, device_map="auto"    )
							self.assertTrue(model.decoder.block[0].layer[2].DenseReluDense.wo.weight.dtype == torch.floataa    )



@require_bitsandbytes
@require_accelerate
@require_torch
@require_torch_gpu
@slow
class 					__UpperCAmelCase							(						unittest.TestCase  ):
				@classmethod
				def       UpperCAmelCase      (		cls    :			Optional[int]    )	->	Any:



							'''simple docstring'''



							a__  :	Optional[Any]		 =			"t5-small"
							a__  :	Any		 =			"google/flan-t5-small"  # flan-t5 uses dense-act instead of dense-relu-dense
							a__  :	Any		 =			AutoTokenizer.from_pretrained(cls.model_name    )
							a__  :	Tuple		 =			"Translate in German: Hello, my dog is cute"
				def       UpperCAmelCase      (		self    :			int    )	->	Optional[int]:



							'''simple docstring'''



							gc.collect()
							torch.cuda.empty_cache()
				def       UpperCAmelCase      (		self    :			str    )	->	int:



							'''simple docstring'''



							from transformers import TaForConditionalGeneration

							a__  :	Any		 =			TaForConditionalGeneration._keep_in_fpaa_modules
							a__  :	int		 =			None

							# test with `t5-small`
							a__  :	List[str]		 =			TaForConditionalGeneration.from_pretrained(self.model_name	, load_in_abit=a_	, device_map="auto"    )
							a__  :	Tuple		 =			self.tokenizer(self.input_text	, return_tensors="pt"    ).to(0    )
							a__  :	str		 =			model.generate(**a_    )

							# test with `flan-t5-small`
							a__  :	str		 =			TaForConditionalGeneration.from_pretrained(
							    self.dense_act_model_name	, load_in_abit=a_	, device_map="auto"    )
							a__  :	Optional[Any]		 =			self.tokenizer(self.input_text	, return_tensors="pt"    ).to(0    )
							a__  :	List[str]		 =			model.generate(**a_    )
							a__  :	Dict		 =			modules






				def       UpperCAmelCase      (		self    :			Union[str, Any]    )	->	List[Any]:



							'''simple docstring'''



							import bitsandbytes as bnb

							from transformers import TaForConditionalGeneration

							# test with `t5-small`
							a__  :	List[str]		 =			TaForConditionalGeneration.from_pretrained(self.model_name	, load_in_abit=a_	, device_map="auto"    )

							# there was a bug with decoders - this test checks that it is fixed
							self.assertTrue(isinstance(model.decoder.block[0].layer[0].SelfAttention.q	, bnb.nn.Linearabit    )    )

							a__  :	List[str]		 =			self.tokenizer(self.input_text	, return_tensors="pt"    ).to(0    )
							a__  :	int		 =			model.generate(**a_    )

							# test with `flan-t5-small`
							a__  :	Tuple		 =			TaForConditionalGeneration.from_pretrained(
							    self.dense_act_model_name	, load_in_abit=a_	, device_map="auto"    )
							a__  :	Optional[Any]		 =			self.tokenizer(self.input_text	, return_tensors="pt"    ).to(0    )
							a__  :	str		 =			model.generate(**a_    )



class 					__UpperCAmelCase							(						_UpperCamelCase  ):
				def       UpperCAmelCase      (		self    :			Optional[int]    )	->	Optional[Any]:



							'''simple docstring'''



							super().setUp()
							# model_name
							a__  :	List[str]		 =			"bigscience/bloom-560m"
							a__  :	Dict		 =			"t5-small"

							# Different types of model

							a__  :	List[Any]		 =			AutoModel.from_pretrained(self.model_name	, load_in_abit=a_	, device_map="auto"    )
							# Sequence classification model
							a__  :	List[str]		 =			AutoModelForSequenceClassification.from_pretrained(
							    self.model_name	, load_in_abit=a_	, device_map="auto"    )
							# CausalLM model
							a__  :	List[Any]		 =			AutoModelForCausalLM.from_pretrained(self.model_name	, load_in_abit=a_	, device_map="auto"    )
							# Seq2seq model
							a__  :	List[str]		 =			AutoModelForSeqaSeqLM.from_pretrained(
							    self.seq_to_seq_name	, load_in_abit=a_	, device_map="auto"    )
				def       UpperCAmelCase      (		self    :			Optional[Any]    )	->	List[Any]:



							'''simple docstring'''



							del self.base_model
							del self.sequence_model
							del self.model_abit
							del self.seq_to_seq_model

							gc.collect()
							torch.cuda.empty_cache()






				def       UpperCAmelCase      (		self    :			List[str]    )	->	Tuple:



							'''simple docstring'''



							from bitsandbytes.nn import Paramsabit

							self.assertTrue(self.base_model.h[-1].mlp.dense_ah_to_h.weight.__class__ == Paramsabit    )

							# Other heads should be nn.Parameter
							self.assertTrue(self.model_abit.lm_head.weight.__class__ == torch.nn.Parameter    )
							self.assertTrue(self.sequence_model.score.weight.__class__ == torch.nn.Parameter    )
							self.assertTrue(self.seq_to_seq_model.lm_head.weight.__class__ == torch.nn.Parameter    )



class 					__UpperCAmelCase							(						_UpperCamelCase  ):
				def       UpperCAmelCase      (		self    :			Tuple    )	->	List[str]:



							'''simple docstring'''



							super().setUp()
				def       UpperCAmelCase      (		self    :			Union[str, Any]    )	->	Tuple:



							'''simple docstring'''



							del self.pipe

							gc.collect()
							torch.cuda.empty_cache()






				def       UpperCAmelCase      (		self    :			Union[str, Any]    )	->	str:



							'''simple docstring'''



							a__  :	str		 =			pipeline(
							    "text-generation"	, model=self.model_name	, model_kwargs={"device_map": "auto", "load_in_4bit": True, "torch_dtype": torch.floataa}	, max_new_tokens=self.MAX_NEW_TOKENS	, )

							# Real second forward pass
							a__  :	Tuple		 =			self.pipe(self.input_text    )
							self.assertIn(pipeline_output[0]["generated_text"]	, self.EXPECTED_OUTPUTS    )



@require_torch_multi_gpu
class 					__UpperCAmelCase							(						_UpperCamelCase  ):
				def       UpperCAmelCase      (		self    :			str    )	->	int:



							'''simple docstring'''



							super().setUp()






				def       UpperCAmelCase      (		self    :			Optional[int]    )	->	List[Any]:



							'''simple docstring'''



							a__  :	Optional[Any]		 =			AutoModelForCausalLM.from_pretrained(
							    self.model_name	, load_in_abit=a_	, device_map="balanced"    )

							# Check correct device map
							self.assertEqual(set(model_parallel.hf_device_map.values()    )	, {0, 1}    )

							# Check that inference pass works on the model
							a__  :	Tuple		 =			self.tokenizer(self.input_text	, return_tensors="pt"    )

							# Second real batch
							a__  :	Any		 =			model_parallel.generate(input_ids=encoded_input["input_ids"].to(0    )	, max_new_tokens=10    )
							self.assertIn(self.tokenizer.decode(output_parallel[0]	, skip_special_tokens=a_    )	, self.EXPECTED_OUTPUTS    )



class 					__UpperCAmelCase							(						_UpperCamelCase  ):
				def       UpperCAmelCase      (		self    :			str    )	->	Union[str, Any]:



							'''simple docstring'''



							a__  :	List[str]		 =			"facebook/opt-350m"
							super().setUp()






				def       UpperCAmelCase      (		self    :			Union[str, Any]    )	->	List[str]:



							'''simple docstring'''



							if version.parse(importlib.metadata.version("bitsandbytes"    )    ) < version.parse("0.37.0"    ):
										return

							# Step 1: freeze all parameters
							a__  :	int		 =			AutoModelForCausalLM.from_pretrained(self.model_name	, load_in_abit=a_    )

							self.assertEqual(set(model.hf_device_map.values()    )	, {torch.cuda.current_device()}    )

							for param in model.parameters():
										a__  :	Any		 =			False  # freeze the model - train adapters later
										if param.ndim == 1:
													# cast the small parameters (e.g. layernorm) to fp32 for stability
													a__  :	str		 =			param.data.to(torch.floataa    )

        # Step 2: add adapters
							for _, module in model.named_modules():
										if "OPTAttention" in repr(type(a_    )    ):
													a__  :	Optional[Any]		 =			LoRALayer(module.q_proj	, rank=16    )
													a__  :	Dict		 =			LoRALayer(module.k_proj	, rank=16    )
													a__  :	str		 =			LoRALayer(module.v_proj	, rank=16    )

        # Step 3: dummy batch
							a__  :	Optional[int]		 =			self.tokenizer("Test batch "	, return_tensors="pt"    ).to(0    )

							# Step 4: Check if the gradient is not None
							with torch.cuda.amp.autocast():
										a__  :	str		 =			model.forward(**a_    )
										out.logits.norm().backward()

							for module in model.modules():
										if isinstance(a_	, a_    ):
													self.assertTrue(module.adapter[1].weight.grad is not None    )
													self.assertTrue(module.adapter[1].weight.grad.norm().item() > 0    )
										elif isinstance(a_	, nn.Embedding    ):
													self.assertTrue(module.weight.grad is None    )



class 					__UpperCAmelCase							(						_UpperCamelCase  ):
				__lowerCamelCase				:	int				     =				"gpt2-xl"
				__lowerCamelCase				:	Optional[int]				     =				3.3_1_9_1_8_5_4_8_5_4_1_5_2_1_8_7






"""simple docstring"""






import functools






def      lowercase__ (					lowerCAmelCase__   :			str							,			lowerCAmelCase__   :			str			)    ->			int:



			'''simple docstring'''
			a__  :	Any		 =			len(lowerCAmelCase__			)
			a__  :	Optional[int]		 =			len(lowerCAmelCase__			)

			@functools.cache
			def min_distance(lowerCAmelCase__   :			int							,			lowerCAmelCase__   :			int			) -> int:
						# if first word index is overflow - delete all from the second word
						if indexa >= len_worda:
									return len_worda - indexa
						# if second word index is overflow - delete all from the first word
						if indexa >= len_worda:
									return len_worda - indexa
						a__  :	List[Any]		 =			int(worda[indexa] != worda[indexa]			)  # current letters not identical
						return min(
						    1 + min_distance(indexa + 1							,			lowerCAmelCase__			)							,			1 + min_distance(lowerCAmelCase__							,			indexa + 1			)							,			diff + min_distance(indexa + 1							,			indexa + 1			)							,			)

			return min_distance(0							,			0			)


if __name__ == "__main__":
		import doctest

		doctest.testmod()