





'''simple docstring'''






import warnings

from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding




class  _A (					__lowercase		):
		lowercase__:   Any				     =   ['''image_processor''', '''tokenizer''']
		lowercase__:   Any				     =   '''CLIPImageProcessor'''
		lowercase__:   Optional[Any]				     =   ('''CLIPTokenizer''', '''CLIPTokenizerFast''')

		def __init__(   self					:   int  ,      __magic_name__					:   Dict=None  ,      __magic_name__					:   Dict=None  ,      **__magic_name__					:   Union[str, Any]			)					->    Any:


					"""simple docstring"""

					__snake_case					:      Optional[Any]							      =     None
					if "feature_extractor" in kwargs:
								warnings.warn(
								    """The `feature_extractor` argument is deprecated and will be removed in v5, use `image_processor`"""
								    """ instead."""  ,      __magic_name__  ,      )
								__snake_case					:      List[Any]							      =     kwargs.pop("""feature_extractor"""			)

					__snake_case					:      List[str]							      =     image_processor if image_processor is not None else feature_extractor
					if image_processor is None:
								raise ValueError("""You need to specify an `image_processor`."""			)
					if tokenizer is None:
								raise ValueError("""You need to specify a `tokenizer`."""			)

					super().__init__(__magic_name__  ,      __magic_name__			)

		def __call__(   self					:   int  ,      __magic_name__					:   List[str]=None  ,      __magic_name__					:   Tuple=None  ,      __magic_name__					:   Any=None  ,      **__magic_name__					:   Union[str, Any]			)					->    Optional[int]:


					"""simple docstring"""

					if text is None and images is None:
								raise ValueError("""You have to specify either text or images. Both cannot be none."""			)

					if text is not None:
								__snake_case					:      int							      =     self.tokenizer(__magic_name__  ,      return_tensors=__magic_name__  ,      **__magic_name__			)

					if images is not None:
								__snake_case					:      str							      =     self.image_processor(__magic_name__  ,      return_tensors=__magic_name__  ,      **__magic_name__			)

					if text is not None and images is not None:
								__snake_case					:      Union[str, Any]							      =     image_features.pixel_values
								return encoding
					elif text is not None:
								return encoding
					else:
								return BatchEncoding(data=dict(**__magic_name__			)  ,      tensor_type=__magic_name__			)

		def 	lowercase__     (   self					:   Optional[int]  ,      *__magic_name__					:   List[Any]  ,      **__magic_name__					:   Any			)					->    Optional[Any]:


					"""simple docstring"""

					return self.tokenizer.batch_decode(*__magic_name__  ,      **__magic_name__			)

		def 	lowercase__     (   self					:   List[str]  ,      *__magic_name__					:   Tuple  ,      **__magic_name__					:   List[Any]			)					->    int:


					"""simple docstring"""

					return self.tokenizer.decode(*__magic_name__  ,      **__magic_name__			)

		@property
		def 	lowercase__     (   self					:   List[Any]			)					->    Optional[Any]:


					"""simple docstring"""

					__snake_case					:      Dict							      =     self.tokenizer.model_input_names
					__snake_case					:      str							      =     self.image_processor.model_input_names
					return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names			)			)

		@property
		def 	lowercase__     (   self					:   int			)					->    List[str]:


					"""simple docstring"""

					warnings.warn(
					    """`feature_extractor_class` is deprecated and will be removed in v5. Use `image_processor_class` instead."""  ,      __magic_name__  ,      )
					return self.image_processor_class

		@property
		def 	lowercase__     (   self					:   Union[str, Any]			)					->    Dict:


					"""simple docstring"""

					warnings.warn(
					    """`feature_extractor` is deprecated and will be removed in v5. Use `image_processor` instead."""  ,      __magic_name__  ,      )
					return self.image_processor









'''simple docstring'''






import inspect
import unittest

import torch
import torch.nn as nn

from accelerate.hooks import (
    AlignDevicesHook,
    ModelHook,
    SequentialHook,
    add_hook_to_module,
    attach_align_device_hook,
    remove_hook_from_module,
    remove_hook_from_submodules,
)
from accelerate.test_utils import require_multi_gpu




class  _A (					nn.Module		):

		def __init__(   self					:   List[str]			)					->    Optional[Any]:


					"""simple docstring"""

					super().__init__()
					__snake_case					:      List[Any]							      =     nn.Linear(3  ,      4			)
					__snake_case					:      str							      =     nn.BatchNormad(4			)
					__snake_case					:      Optional[Any]							      =     nn.Linear(4  ,      5			)

		def 	lowercase__     (   self					:   str  ,      __magic_name__					:   Dict			)					->    List[str]:


					"""simple docstring"""

					return self.lineara(self.batchnorm(self.lineara(__magic_name__			)			)			)





class  _A (					__lowercase		):

		def 	lowercase__     (   self					:   List[str]  ,      __magic_name__					:   Tuple  ,      *__magic_name__					:   Dict  ,      **__magic_name__					:   Optional[Any]			)					->    Tuple:


					"""simple docstring"""

					return (args[0] + 1,) + args[1:], kwargs





class  _A (					__lowercase		):

		def 	lowercase__     (   self					:   str  ,      __magic_name__					:   Union[str, Any]  ,      __magic_name__					:   Tuple			)					->    Union[str, Any]:


					"""simple docstring"""

					return output + 1





class  _A (					unittest.TestCase		):

		def 	lowercase__     (   self					:   Dict			)					->    Any:


					"""simple docstring"""

					__snake_case					:      int							      =     ModelForTest()
					__snake_case					:      Tuple							      =     ModelHook()

					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					self.assertEqual(test_model._hf_hook  ,      __magic_name__			)
					self.assertTrue(hasattr(__magic_name__  ,      """_old_forward"""			)			)

					# Check adding the hook did not change the name or the signature
					self.assertEqual(test_model.forward.__name__  ,      """forward"""			)
					self.assertListEqual(list(inspect.signature(test_model.forward			).parameters			)  ,      ["""x"""]			)

					remove_hook_from_module(__magic_name__			)
					self.assertFalse(hasattr(__magic_name__  ,      """_hf_hook"""			)			)
					self.assertFalse(hasattr(__magic_name__  ,      """_old_forward"""			)			)

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


					"""simple docstring"""

					__snake_case					:      List[Any]							      =     ModelForTest()
					__snake_case					:      Optional[int]							      =     ModelHook()

					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					add_hook_to_module(__magic_name__  ,      __magic_name__  ,      append=__magic_name__			)

					self.assertEqual(isinstance(test_model._hf_hook  ,      __magic_name__			)  ,      __magic_name__			)
					self.assertEqual(len(test_model._hf_hook.hooks			)  ,      2			)
					self.assertTrue(hasattr(__magic_name__  ,      """_old_forward"""			)			)

					# Check adding the hook did not change the name or the signature
					self.assertEqual(test_model.forward.__name__  ,      """forward"""			)
					self.assertListEqual(list(inspect.signature(test_model.forward			).parameters			)  ,      ["""x"""]			)

					remove_hook_from_module(__magic_name__			)
					self.assertFalse(hasattr(__magic_name__  ,      """_hf_hook"""			)			)
					self.assertFalse(hasattr(__magic_name__  ,      """_old_forward"""			)			)

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


					"""simple docstring"""

					__snake_case					:      List[Any]							      =     ModelForTest()
					__snake_case					:      Any							      =     torch.randn(2  ,      3			)
					__snake_case					:      str							      =     test_model(x + 1			)
					__snake_case					:      int							      =     test_model(x + 2			)

					__snake_case					:      Union[str, Any]							      =     PreForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      int							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      __magic_name__  ,      atol=1E-5			)			)

					# Attaching a hook to a model when it already has one replaces, does not chain
					__snake_case					:      Optional[int]							      =     PreForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      List[Any]							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      __magic_name__  ,      atol=1E-5			)			)

					# You need to use the sequential hook to chain two or more hooks
					__snake_case					:      Optional[int]							      =     SequentialHook(PreForwardHook()  ,      PreForwardHook()			)
					add_hook_to_module(__magic_name__  ,      __magic_name__			)

					__snake_case					:      List[str]							      =     test_model(__magic_name__			)
					assert torch.allclose(__magic_name__  ,      __magic_name__  ,      atol=1E-5			)

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


					"""simple docstring"""

					__snake_case					:      Union[str, Any]							      =     ModelForTest()
					__snake_case					:      str							      =     torch.randn(2  ,      3			)
					__snake_case					:      Any							      =     test_model(__magic_name__			)

					__snake_case					:      Any							      =     PostForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      Any							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      output + 1  ,      atol=1E-5			)			)

					# Attaching a hook to a model when it already has one replaces, does not chain
					__snake_case					:      Any							      =     PostForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      Dict							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      output + 1  ,      atol=1E-5			)			)

					# You need to use the sequential hook to chain two or more hooks
					__snake_case					:      str							      =     SequentialHook(PostForwardHook()  ,      PostForwardHook()			)
					add_hook_to_module(__magic_name__  ,      __magic_name__			)

					__snake_case					:      int							      =     test_model(__magic_name__			)
					assert torch.allclose(__magic_name__  ,      output + 2  ,      atol=1E-5			)

		def 	lowercase__     (   self					:   str			)					->    int:


					"""simple docstring"""

					__snake_case					:      Union[str, Any]							      =     ModelForTest()
					__snake_case					:      int							      =     torch.randn(2  ,      3			)
					__snake_case					:      Any							      =     test_model(__magic_name__			)

					__snake_case					:      Dict							      =     PostForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      List[Any]							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      output + 1			)			)
					self.assertTrue(outputa.requires_grad			)

					__snake_case					:      Dict							      =     True
					__snake_case					:      int							      =     test_model(__magic_name__			)
					self.assertFalse(outputa.requires_grad			)

		@require_multi_gpu
		def 	lowercase__     (   self					:   Tuple			)					->    List[Any]:


					"""simple docstring"""

					__snake_case					:      Tuple							      =     ModelForTest()
					# Everything is on CPU
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# This will move each submodule on different devices
					add_hook_to_module(model.lineara  ,      AlignDevicesHook(execution_device=0			)			)
					add_hook_to_module(model.batchnorm  ,      AlignDevicesHook(execution_device=0			)			)
					add_hook_to_module(model.lineara  ,      AlignDevicesHook(execution_device=1			)			)

					self.assertEqual(model.lineara.weight.device  ,      torch.device(0			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device(0			)			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      torch.device(0			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device(1			)			)

					# We can still make a forward pass. The input does not need to be on any particular device
					__snake_case					:      Tuple							      =     torch.randn(2  ,      3			)
					__snake_case					:      Union[str, Any]							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      torch.device(1			)			)

					# We can add a general hook to put back output on same device as input.
					add_hook_to_module(__magic_name__  ,      AlignDevicesHook(io_same_device=__magic_name__			)			)
					__snake_case					:      Tuple							      =     torch.randn(2  ,      3			).to(0			)
					__snake_case					:      Any							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      torch.device(0			)			)

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


					"""simple docstring"""

					__snake_case					:      int							      =     ModelForTest()

					# Everything is on CPU
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# This will move each submodule on different devices
					__snake_case					:      List[str]							      =     {"""execution_device""": 0 if torch.cuda.is_available() else """cpu""", """offload""": True}

					add_hook_to_module(model.lineara  ,      AlignDevicesHook(**__magic_name__			)			)
					add_hook_to_module(model.batchnorm  ,      AlignDevicesHook(**__magic_name__			)			)
					add_hook_to_module(model.lineara  ,      AlignDevicesHook(**__magic_name__			)			)

					# Parameters have been offloaded, so on the meta device
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					# Buffers are not included in the offload by default, so are on the execution device
					__snake_case					:      Any							      =     torch.device(hook_kwargs["""execution_device"""]			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      __magic_name__			)

					__snake_case					:      Dict							      =     torch.randn(2  ,      3			)
					__snake_case					:      Any							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_module(model.lineara			)
					remove_hook_from_module(model.batchnorm			)
					remove_hook_from_module(model.lineara			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# Now test with buffers included in the offload
					__snake_case					:      int							      =     {
					    """execution_device""": 0 if torch.cuda.is_available() else """cpu""",
					    """offload""": True,
					    """offload_buffers""": True,
					}

					add_hook_to_module(model.lineara  ,      AlignDevicesHook(**__magic_name__			)			)
					add_hook_to_module(model.batchnorm  ,      AlignDevicesHook(**__magic_name__			)			)
					add_hook_to_module(model.lineara  ,      AlignDevicesHook(**__magic_name__			)			)

					# Parameters have been offloaded, so on the meta device, buffers included
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      torch.device("""meta"""			)			)

					__snake_case					:      str							      =     torch.randn(2  ,      3			)
					__snake_case					:      str							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_module(model.lineara			)
					remove_hook_from_module(model.batchnorm			)
					remove_hook_from_module(model.lineara			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

		def 	lowercase__     (   self					:   Dict			)					->    str:


					"""simple docstring"""

					__snake_case					:      Tuple							      =     ModelForTest()

					# Everything is on CPU
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# This will move each submodule on different devices
					__snake_case					:      Union[str, Any]							      =     0 if torch.cuda.is_available() else """cpu"""
					attach_align_device_hook(__magic_name__  ,      execution_device=__magic_name__  ,      offload=__magic_name__			)

					# Parameters have been offloaded, so on the meta device
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					# Buffers are not included in the offload by default, so are on the execution device
					__snake_case					:      Union[str, Any]							      =     torch.device(__magic_name__			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      __magic_name__			)

					__snake_case					:      Optional[int]							      =     torch.randn(2  ,      3			)
					__snake_case					:      Dict							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_submodules(__magic_name__			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# Now test with buffers included in the offload
					attach_align_device_hook(__magic_name__  ,      execution_device=__magic_name__  ,      offload=__magic_name__  ,      offload_buffers=__magic_name__			)

					# Parameters have been offloaded, so on the meta device, buffers included
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      torch.device("""meta"""			)			)

					__snake_case					:      Dict							      =     torch.randn(2  ,      3			)
					__snake_case					:      Optional[int]							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_submodules(__magic_name__			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

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


					"""simple docstring"""

					__snake_case					:      Any							      =     ModelForTest()

					# Everything is on CPU
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# This will move each submodule on different devices
					__snake_case					:      str							      =     0 if torch.cuda.is_available() else """cpu"""
					attach_align_device_hook(
					    __magic_name__  ,      execution_device=__magic_name__  ,      offload=__magic_name__  ,      weights_map=model.state_dict()			)

					# Parameters have been offloaded, so on the meta device
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					# Buffers are not included in the offload by default, so are on the execution device
					__snake_case					:      List[str]							      =     torch.device(__magic_name__			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      __magic_name__			)

					__snake_case					:      Tuple							      =     torch.randn(2  ,      3			)
					__snake_case					:      Optional[Any]							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_submodules(__magic_name__			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# Now test with buffers included in the offload
					attach_align_device_hook(
					    __magic_name__  ,      execution_device=__magic_name__  ,      offload=__magic_name__  ,      weights_map=model.state_dict()  ,      offload_buffers=__magic_name__  ,      )

					# Parameters have been offloaded, so on the meta device, buffers included
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      torch.device("""meta"""			)			)

					__snake_case					:      List[str]							      =     torch.randn(2  ,      3			)
					__snake_case					:      Dict							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_submodules(__magic_name__			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)


