


from . import (
    albert,
    align,
    altclip,
    audio_spectrogram_transformer,
    auto,
    autoformer,
    bark,
    bart,
    barthez,
    bartpho,
    beit,
    bert,
    bert_generation,
    bert_japanese,
    bertweet,
    big_bird,
    bigbird_pegasus,
    biogpt,
    bit,
    blenderbot,
    blenderbot_small,
    blip,
    blip_a,
    bloom,
    bridgetower,
    byta,
    camembert,
    canine,
    chinese_clip,
    clap,
    clip,
    clipseg,
    codegen,
    conditional_detr,
    convbert,
    convnext,
    convnextva,
    cpm,
    cpmant,
    ctrl,
    cvt,
    dataavec,
    deberta,
    deberta_va,
    decision_transformer,
    deformable_detr,
    deit,
    deprecated,
    deta,
    detr,
    dialogpt,
    dinat,
    distilbert,
    dit,
    donut,
    dpr,
    dpt,
    efficientformer,
    efficientnet,
    electra,
    encodec,
    encoder_decoder,
    ernie,
    ernie_m,
    esm,
    falcon,
    flaubert,
    flava,
    fnet,
    focalnet,
    fsmt,
    funnel,
    git,
    glpn,
    gpta,
    gpt_bigcode,
    gpt_neo,
    gpt_neox,
    gpt_neox_japanese,
    gpt_swa,
    gptj,
    gptsan_japanese,
    graphormer,
    groupvit,
    herbert,
    hubert,
    ibert,
    imagegpt,
    informer,
    instructblip,
    jukebox,
    layoutlm,
    layoutlmva,
    layoutlmva,
    layoutxlm,
    led,
    levit,
    lilt,
    llama,
    longformer,
    longta,
    luke,
    lxmert,
    mam_aaa,
    marian,
    markuplm,
    maskaformer,
    maskformer,
    mbart,
    mbartaa,
    mega,
    megatron_bert,
    megatron_gpta,
    mgp_str,
    mluke,
    mobilebert,
    mobilenet_va,
    mobilenet_va,
    mobilevit,
    mobilevitva,
    mpnet,
    mra,
    mta,
    musicgen,
    mvp,
    nat,
    nezha,
    nllb,
    nllb_moe,
    nystromformer,
    oneformer,
    open_llama,
    openai,
    opt,
    owlvit,
    pegasus,
    pegasus_x,
    perceiver,
    phobert,
    pixastruct,
    plbart,
    poolformer,
    prophetnet,
    qdqbert,
    rag,
    realm,
    reformer,
    regnet,
    rembert,
    resnet,
    roberta,
    roberta_prelayernorm,
    roc_bert,
    roformer,
    rwkv,
    sam,
    segformer,
    sew,
    sew_d,
    speech_encoder_decoder,
    speech_to_text,
    speech_to_text_a,
    speechta,
    splinter,
    squeezebert,
    swiftformer,
    swin,
    swinasr,
    swinva,
    switch_transformers,
    ta,
    table_transformer,
    tapas,
    time_series_transformer,
    timesformer,
    timm_backbone,
    transfo_xl,
    trocr,
    tvlt,
    umta,
    unispeech,
    unispeech_sat,
    upernet,
    videomae,
    vilt,
    vision_encoder_decoder,
    vision_text_dual_encoder,
    visual_bert,
    vit,
    vit_hybrid,
    vit_mae,
    vit_msn,
    vivit,
    wavaveca,
    wavaveca_conformer,
    wavaveca_phoneme,
    wavaveca_with_lm,
    wavlm,
    whisper,
    x_clip,
    xglm,
    xlm,
    xlm_prophetnet,
    xlm_roberta,
    xlm_roberta_xl,
    xlnet,
    xmod,
    yolos,
    yoso,
)









'''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"""			)			)


