Ë
    (täiŠ_  ã                   óÌ  — d dl Z d dlmZ d dlZd dlmZ ddlmZmZ ddl	m
Z
 ddlmZ  e
j                  e«      Z G d„ d	e«      Z G d
„ dee«      Z G d„ dej$                  «      Z G d„ dej$                  «      Z G d„ dej$                  «      Z G d„ dej$                  «      Z G d„ dej$                  «      Z G d„ dej$                  «      Z G d„ dej$                  «      Zy)é    N)ÚCallableé   )ÚConfigMixinÚregister_to_config)Úloggingé   )Ú
ModelMixinc                   óú   ‡ — e Zd ZdZded   fˆ fd„Zddej                  dee   dz  deej                     fd	„Z		 	 	 	 dd
e
ej                  z  dededede
dz  f
d„Zede
ej                  z  dz  fd„«       Zˆ xZS )ÚMultiAdaptera�  
    MultiAdapter is a wrapper model that contains multiple adapter models and merges their outputs according to
    user-assigned weighting.

    This model inherits from [`ModelMixin`]. Check the superclass documentation for common methods such as downloading
    or saving.

    Args:
        adapters (`list[T2IAdapter]`, *optional*, defaults to None):
            A list of `T2IAdapter` model instances.
    ÚadaptersÚ
T2IAdapterc                 ó$  •— t         t        | �  «        t        |«      | _        t        j                  |«      | _        t        |«      dk(  rt        d«      ‚t        |«      dk(  rt        d«      ‚|d   j                  }|d   j                  }t        dt        |«      «      D ]]  }||   j                  |k7  s||   j                  |k7  sŒ(t        d|› d|› d|› d||   j                  › d|› d	||   j                  › �«      ‚ || _	        || _
        y )
Nr   zExpecting at least one adapterr   zQFor a single adapter, please use the `T2IAdapter` class instead of `MultiAdapter`zjExpecting all adapters to have the same downscaling behavior, but got:
adapters[0].total_downscale_factor=z
adapters[0].downscale_factor=z

adapter[`z`].total_downscale_factor=z`].downscale_factor=)Úsuperr   Ú__init__ÚlenÚnum_adapterÚnnÚ
ModuleListr   Ú
ValueErrorÚtotal_downscale_factorÚdownscale_factorÚrange)Úselfr   Ú$first_adapter_total_downscale_factorÚfirst_adapter_downscale_factorÚidxÚ	__class__s        €úg/Volumes/fast/ai/experiments/MLX_z-image/.venv/lib/python3.12/site-packages/diffusers/models/adapter.pyr   zMultiAdapter.__init__)   s0  ø€ ÜŒl˜DÑ*Ô,ä˜x›=ˆÔÜŸ™ hÓ/ˆŒäˆx‹=˜AÒÜÐ=Ó>Ð>äˆx‹=˜AÒÜÐpÓqÐqð 08¸©{×/QÑ/QÐ,Ø)1°!©×)EÑ)EÐ&Ü˜œC ›MÖ*ˆCà˜‘×4Ñ4Ð8\Ò\Ø˜C‘=×1Ñ1Ð5SÓSä ð:Ø:^Ð9_ð `4Ø4RÐ3Sð T Ø #˜uÐ$>¸xÈ¹}×?cÑ?cÐ>dð e Ø #˜uÐ$8¸À#¹×9WÑ9WÐ8Xð	Zóð ð +ð 'KˆÔ#Ø >ˆÕó    NÚxsÚadapter_weightsÚreturnc                 ó”  — |€1t        j                  d| j                  z  g| j                  z  «      }nt        j                  |«      }d}t        ||| j                  «      D ]c  \  }}} ||«      }|€'|}t        t        |«      «      D ]  }|||   z  ||<   Œ Œ8t        t        |«      «      D ]  }||xx   |||   z  z  cc<   Œ Œe |S )az  
        Args:
            xs (`torch.Tensor`):
                A tensor of shape (batch, channel, height, width) representing input images for multiple adapter
                models, concatenated along dimension 1(channel dimension). The `channel` dimension should be equal to
                `num_adapter` * number of channel per image.

            adapter_weights (`list[float]`, *optional*, defaults to None):
                A list of floats representing the weights which will be multiplied by each adapter's output before
                summing them together. If `None`, equal weights will be used for all adapters.
        Nr   )ÚtorchÚtensorr   Úzipr   r   r   )	r   r    r!   Úaccume_stateÚxÚwÚadapterÚfeaturesÚis	            r   ÚforwardzMultiAdapter.forwardL   sÏ   € ð Ð"Ü#Ÿl™l¨A°×0@Ñ0@Ñ,@Ð+AÀD×DTÑDTÑ+TÓU‰Oä#Ÿl™l¨?Ó;ˆOàˆÜ   _°d·m±mÖD‰MˆAˆq�'Ù˜q“zˆHØÐ#Ø'�Üœs <Ó0Ö1�AØ&'¨,°q©/Ñ&9�L ’Oñ 2ô œs 8›}Ö-�AØ  “O q¨8°A©;¡Ñ6”Oñ .ð Eð Ðr   Úsave_directoryÚis_main_processÚsave_functionÚsafe_serializationÚvariantc                 ót   — d}|}| j                   D ]%  }|j                  |||||¬«       |dz  }|d|› �z   }Œ' y)a6  
        Save a model and its configuration file to a specified directory, allowing it to be re-loaded with the
        `[`~models.adapter.MultiAdapter.from_pretrained`]` class method.

        Args:
            save_directory (`str` or `os.PathLike`):
                The directory where the model will be saved. If the directory does not exist, it will be created.
            is_main_process (`bool`, optional, defaults=True):
                Indicates whether current process is the main process or not. Useful for distributed training (e.g.,
                TPUs) and need to call this function on all processes. In this case, set `is_main_process=True` only
                for the main process to avoid race conditions.
            save_function (`Callable`):
                Function used to save the state dictionary. Useful for distributed training (e.g., TPUs) to replace
                `torch.save` with another method. Can also be configured using`DIFFUSERS_SAVE_MODE` environment
                variable.
            safe_serialization (`bool`, optional, defaults=True):
                If `True`, save the model using `safetensors`. If `False`, save the model with `pickle`.
            variant (`str`, *optional*):
                If specified, weights are saved in the format `pytorch_model.<variant>.bin`.
        r   )r/   r0   r1   r2   r   Ú_N)r   Úsave_pretrained)	r   r.   r/   r0   r1   r2   r   Úmodel_path_to_saver*   s	            r   r5   zMultiAdapter.save_pretrainedi   s[   € ð8 ˆØ+ÐØ—}”}ˆGØ×#Ñ#Ø"Ø /Ø+Ø#5Øð $ô ð �1‰HˆCØ!3¸¸#¸°iÑ!?Ññ %r   Úpretrained_model_pathc                 óÌ  — d}g }|}t         j                  j                  |«      rTt        j                  |fi |¤Ž}|j                  |«       |dz  }|d|› �z   }t         j                  j                  |«      rŒTt        j                  t        |«      › d|› d�«       t        |«      dk(  r2t        dt         j                  j                  |«      › d|dz   › d�«      ‚ | |«      S )	a—  
        Instantiate a pretrained `MultiAdapter` model from multiple pre-trained adapter models.

        The model is set in evaluation mode by default using `model.eval()` (Dropout modules are deactivated). To train
        the model, set it back to training mode using `model.train()`.

        Warnings:
            *Weights from XXX not initialized from pretrained model* means that the weights of XXX are not pretrained
            with the rest of the model. It is up to you to train those weights with a downstream fine-tuning. *Weights
            from XXX not used in YYY* means that the layer XXX is not used by YYY, so those weights are discarded.

        Args:
            pretrained_model_path (`os.PathLike`):
                A path to a *directory* containing model weights saved using
                [`~diffusers.models.adapter.MultiAdapter.save_pretrained`], e.g., `./my_model_directory/adapter`.
            torch_dtype (`torch.dtype`, *optional*):
                Override the default `torch.dtype` and load the model under this dtype.
            output_loading_info(`bool`, *optional*, defaults to `False`):
                Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages.
            device_map (`str` or `dict[str, int | str | torch.device]`, *optional*):
                A map that specifies where each submodule should go. It doesn't need to be refined to each
                parameter/buffer name, once a given module name is inside, every submodule of it will be sent to the
                same device.

                To have Accelerate compute the most optimized `device_map` automatically, set `device_map="auto"`. For
                more information about each option see [designing a device
                map](https://hf.co/docs/accelerate/main/en/usage_guides/big_modeling#designing-a-device-map).
            max_memory (`Dict`, *optional*):
                A dictionary mapping device identifiers to their maximum memory. Default to the maximum memory
                available for each GPU and the available CPU RAM if unset.
            low_cpu_mem_usage (`bool`, *optional*, defaults to `True` if torch version >= 1.9.0 else `False`):
                Speed up model loading by not initializing the weights and only loading the pre-trained weights. This
                also tries to not use more than 1x model size in CPU memory (including peak memory) while loading the
                model. This is only supported when torch version >= 1.9.0. If you are using an older version of torch,
                setting this argument to `True` will raise an error.
            variant (`str`, *optional*):
                If specified, load weights from a `variant` file (*e.g.* pytorch_model.<variant>.bin). `variant` will
                be ignored when using `from_flax`.
            use_safetensors (`bool`, *optional*, defaults to `None`):
                If `None`, the `safetensors` weights will be downloaded if available **and** if`safetensors` library is
                installed. If `True`, the model will be forcibly loaded from`safetensors` weights. If `False`,
                `safetensors` is not used.
        r   r   r4   z adapters loaded from Ú.zNo T2IAdapters found under z. Expected at least Ú_0)ÚosÚpathÚisdirr   Úfrom_pretrainedÚappendÚloggerÚinfor   r   Údirname)Úclsr7   Úkwargsr   r   Úmodel_path_to_loadr*   s          r   r>   zMultiAdapter.from_pretrained“   sý   € ðZ ˆØˆð
 3ÐÜ�g‰g�m‰mÐ.Ô/Ü ×0Ñ0Ð1CÑNÀvÑNˆGØ�O‰O˜GÔ$à�1‰HˆCØ!6¸1¸S¸E¸Ñ!BÐô �g‰g�m‰mÐ.Õ/ô 	�‰”s˜8“}�oÐ%;Ð<QÐ;RÐRSÐTÔUäˆx‹=˜AÒÜØ-¬b¯g©g¯o©oÐ>SÓ.TÐ-UÐUiÐjð  CGñ  kGð  jHð  HIð  Jóð ñ �8‹}Ðr   ©N)TNTN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úlistr   r$   ÚTensorÚfloatr-   Ústrr;   ÚPathLikeÚboolr   r5   Úclassmethodr>   Ú__classcell__©r   s   @r   r   r      sÒ   ø„ ñ
ð!?  lÑ!3õ !?ñF˜%Ÿ,™,ð ¸¸e¹ÀtÑ9Kð ÐW[Ð\a×\hÑ\hÑWió ð@ !%Ø"&Ø#'Ø"ñ(@à˜bŸk™kÑ)ð(@ð ð(@ð  ð	(@ð
 !ð(@ð �t‘ó(@ðT ðA°C¸"¿+¹+Ñ4EÈÑ4Lò Aó ôAr   r   c                   ó¶   ‡ — e Zd ZdZedg d¢dddfdedee   d	ed
edef
ˆ fd„«       Zde	j                  dee	j                     fd„Zed„ «       Zed„ «       Zˆ xZS )r   a\  
    A simple ResNet-like model that accepts images containing control signals such as keyposes and depth. The model
    generates multiple feature maps that are used as additional conditioning in [`UNet2DConditionModel`]. The model's
    architecture follows the original implementation of
    [Adapter](https://github.com/TencentARC/T2I-Adapter/blob/686de4681515662c0ac2ffa07bf5dda83af1038a/ldm/modules/encoders/adapter.py#L97)
     and
     [AdapterLight](https://github.com/TencentARC/T2I-Adapter/blob/686de4681515662c0ac2ffa07bf5dda83af1038a/ldm/modules/encoders/adapter.py#L235).

    This model inherits from [`ModelMixin`]. Check the superclass documentation for the common methods, such as
    downloading or saving.

    Args:
        in_channels (`int`, *optional*, defaults to `3`):
            The number of channels in the adapter's input (*control image*). Set it to 1 if you're using a gray scale
            image.
        channels (`list[int]`, *optional*, defaults to `(320, 640, 1280, 1280)`):
            The number of channels in each downsample block's output hidden state. The `len(block_out_channels)`
            determines the number of downsample blocks in the adapter.
        num_res_blocks (`int`, *optional*, defaults to `2`):
            Number of ResNet blocks in each downsample block.
        downscale_factor (`int`, *optional*, defaults to `8`):
            A factor that determines the total downscale factor of the Adapter.
        adapter_type (`str`, *optional*, defaults to `full_adapter`):
            Adapter type (`full_adapter` or `full_adapter_xl` or `light_adapter`) to use.
    é   ©é@  é€  é   rY   r   é   Úfull_adapterÚin_channelsÚchannelsÚnum_res_blocksr   Úadapter_typec                 óÔ   •— t         ‰| �  «        |dk(  rt        ||||«      | _        y |dk(  rt	        ||||«      | _        y |dk(  rt        ||||«      | _        y t        d|› d�«      ‚)Nr[   Úfull_adapter_xlÚlight_adapterzUnsupported adapter_type: 'zH'. Choose either 'full_adapter' or 'full_adapter_xl' or 'light_adapter'.)r   r   ÚFullAdapterr*   ÚFullAdapterXLÚLightAdapterr   )r   r\   r]   r^   r   r_   r   s         €r   r   zT2IAdapter.__init__ó   s€   ø€ ô 	‰ÑÔà˜>Ò)Ü& {°H¸nÐN^Ó_ˆD�LØÐ.Ò.Ü(¨°hÀÐP`ÓaˆD�LØ˜_Ò,Ü'¨°X¸~ÐO_Ó`ˆD�LäØ-¨l¨^ð <8ð 8óð r   r(   r"   c                 ó$   — | j                  |«      S )a’  
        This function processes the input tensor `x` through the adapter model and returns a list of feature tensors,
        each representing information extracted at a different scale from the input. The length of the list is
        determined by the number of downsample blocks in the Adapter, as specified by the `channels` and
        `num_res_blocks` parameters during initialization.
        )r*   ©r   r(   s     r   r-   zT2IAdapter.forward
  s   € ð �|‰|˜A‹Ðr   c                 ó.   — | j                   j                  S rF   )r*   r   ©r   s    r   r   z!T2IAdapter.total_downscale_factor  s   € à�|‰|×2Ñ2Ð2r   c                 óB   — | j                   j                  j                  S )z×The downscale factor applied in the T2I-Adapter's initial pixel unshuffle operation. If an input image's dimensions are
        not evenly divisible by the downscale_factor then an exception will be raised.
        )r*   Ú	unshuffler   ri   s    r   r   zT2IAdapter.downscale_factor  s   € ð
 �|‰|×%Ñ%×6Ñ6Ð6r   )rG   rH   rI   rJ   r   ÚintrK   rN   r   r$   rL   r-   Úpropertyr   r   rR   rS   s   @r   r   r   Ø   s©   ø„ ñð4 ð Ú4ØØ !Ø*ñàðð �s‘)ðð ð	ð
 ðð ôó ðð,˜Ÿ™ð ¨$¨u¯|©|Ñ*<ó ð ñ3ó ð3ð ñ7ó ô7r   r   c            	       ó†   ‡ — e Zd ZdZdg d¢ddfdedee   ded	efˆ fd
„Zdej                  deej                     fd„Z	ˆ xZ
S )rc   ú2
    See [`T2IAdapter`] for more information.
    rU   rV   r   rZ   r\   r]   r^   r   c                 ó®  •— t         ‰| �  «        ||dz  z  }t        j                  |«      | _        t        j
                  ||d   dd¬«      | _        t        j                  t        |d   |d   |«      gt        dt        |«      «      D �cg c]  }t        ||dz
     ||   |d¬«      ‘Œ c}¢«      | _        |dt        |«      dz
  z  z  | _        y c c}w ©Nr   r   rU   r   ©Úkernel_sizeÚpaddingT©Údown)r   r   r   ÚPixelUnshufflerk   ÚConv2dÚconv_inr   ÚAdapterBlockr   r   Úbodyr   ©r   r\   r]   r^   r   r,   r   s         €r   r   zFullAdapter.__init__'  sÞ   ø€ ô 	‰ÑÔà!Ð$4°aÑ$7Ñ7ˆä×*Ñ*Ð+;Ó<ˆŒÜ—y‘y ¨h°q©kÀqÐRSÔTˆŒä—M‘Mä˜X a™[¨(°1©+°~ÓFðô # 1¤c¨(£mÔ4óá4˜ô ! ¨!¨a©%¡°(¸1±+¸~ÐTXÖYØ4ñðó
ˆŒ	ð '7¸¼sÀ8»}ÈqÑ?PÑ9QÑ&QˆÕ#ùòs   ÂC
r(   r"   c                 ó¢   — | j                  |«      }| j                  |«      }g }| j                  D ]  } ||«      }|j                  |«       Œ |S )aÐ  
        This method processes the input tensor `x` through the FullAdapter model and performs operations including
        pixel unshuffling, convolution, and a stack of AdapterBlocks. It returns a list of feature tensors, each
        capturing information at a different stage of processing within the FullAdapter model. The number of feature
        tensors in the list is determined by the number of downsample blocks specified during initialization.
        ©rk   ry   r{   r?   ©r   r(   r+   Úblocks       r   r-   zFullAdapter.forwardA  sN   € ð �N‰N˜1ÓˆØ�L‰L˜‹Oˆàˆà—Y”YˆEÙ�a“ˆAØ�O‰O˜AÕð ð ˆr   ©rG   rH   rI   rJ   rl   rK   r   r$   rL   r-   rR   rS   s   @r   rc   rc   "  sj   ø„ ñð Ú4ØØ !ñRàðRð �s‘)ðRð ð	Rð
 õRð4˜Ÿ™ð ¨$¨u¯|©|Ñ*<÷ r   rc   c            	       ó†   ‡ — e Zd ZdZdg d¢ddfdedee   ded	efˆ fd
„Zdej                  deej                     fd„Z	ˆ xZ
S )rd   ro   rU   rV   r   é   r\   r]   r^   r   c           	      ót  •— t         ‰| �  «        ||dz  z  }t        j                  |«      | _        t        j
                  ||d   dd¬«      | _        g | _        t        t        |«      «      D ]š  }|dk(  r0| j                  j                  t        ||dz
     ||   |«      «       Œ8|dk(  r2| j                  j                  t        ||dz
     ||   |d¬«      «       Œo| j                  j                  t        ||   ||   |«      «       Œœ t        j                  | j                  «      | _        |dz  | _        y rq   )r   r   r   rw   rk   rx   ry   r{   r   r   r?   rz   r   r   r|   s         €r   r   zFullAdapterXL.__init__Y  s  ø€ ô 	‰ÑÔà!Ð$4°aÑ$7Ñ7ˆä×*Ñ*Ð+;Ó<ˆŒÜ—y‘y ¨h°q©kÀqÐRSÔTˆŒàˆŒ	ä”s˜8“}Ö%ˆAØ�AŠvØ—	‘	× Ñ ¤¨h°q¸1±u©o¸xÈ¹{ÈNÓ![Õ\Ø�a’Ø—	‘	× Ñ ¤¨h°q¸1±u©o¸xÈ¹{ÈNÐaeÔ!fÕgà—	‘	× Ñ ¤¨h°q©k¸8ÀA¹;ÈÓ!WÕXð &ô —M‘M $§)¡)Ó,ˆŒ	à&6¸Ñ&:ˆÕ#r   r(   r"   c                 ó¢   — | j                  |«      }| j                  |«      }g }| j                  D ]  } ||«      }|j                  |«       Œ |S )zù
        This method takes the tensor x as input and processes it through FullAdapterXL model. It consists of operations
        including unshuffling pixels, applying convolution layer and appending each block into list of feature tensors.
        r~   r   s       r   r-   zFullAdapterXL.forwardu  sN   € ð
 �N‰N˜1ÓˆØ�L‰L˜‹Oˆàˆà—Y”YˆEÙ�a“ˆAØ�O‰O˜AÕð ð ˆr   r�   rS   s   @r   rd   rd   T  se   ø„ ñð Ú4ØØ "ñ;àð;ð �s‘)ð;ð ð	;ð
 õ;ð8˜Ÿ™ð ¨$¨u¯|©|Ñ*<÷ r   rd   c            	       ón   ‡ — e Zd ZdZd
dedededefˆ fd„Zdej                  dej                  fd	„Z	ˆ xZ
S )rz   a#  
    An AdapterBlock is a helper model that contains multiple ResNet-like blocks. It is used in the `FullAdapter` and
    `FullAdapterXL` models.

    Args:
        in_channels (`int`):
            Number of channels of AdapterBlock's input.
        out_channels (`int`):
            Number of channels of AdapterBlock's output.
        num_res_blocks (`int`):
            Number of ResNet blocks in the AdapterBlock.
        down (`bool`, *optional*, defaults to `False`):
            If `True`, perform downsampling on AdapterBlock's input.
    r\   Úout_channelsr^   rv   c                 ó8  •— t         ‰| �  «        d | _        |rt        j                  ddd¬«      | _        d | _        ||k7  rt        j                  ||d¬«      | _        t        j                  t        |«      D �cg c]  }t        |«      ‘Œ c}Ž | _
        y c c}w )Nr   T©rs   ÚstrideÚ	ceil_moder   ©rs   )r   r   Ú
downsampler   Ú	AvgPool2dÚin_convrx   Ú
Sequentialr   ÚAdapterResnetBlockÚresnets)r   r\   r‡   r^   rv   r4   r   s         €r   r   zAdapterBlock.__init__–  s�   ø€ Ü‰ÑÔàˆŒÙÜ Ÿl™l°qÀÈdÔSˆDŒOàˆŒØ˜,Ò&ÜŸ9™9 [°,ÈAÔNˆDŒLä—}‘}Ü8=¸nÔ8MÓNÑ8M°1Ô  Õ.Ð8MÑNð
ˆ�ùÚNs   Á;Br(   r"   c                 óœ   — | j                   �| j                  |«      }| j                  �| j                  |«      }| j                  |«      }|S )a  
        This method takes tensor x as input and performs operations downsampling and convolutional layers if the
        self.downsample and self.in_conv properties of AdapterBlock model are specified. Then it applies a series of
        residual blocks to the input tensor.
        )r�   r�   r’   rg   s     r   r-   zAdapterBlock.forward¥  sE   € ð �?‰?Ð&Ø—‘ Ó"ˆAà�<‰<Ð#Ø—‘˜Q“ˆAà�L‰L˜‹Oˆàˆr   ©F©rG   rH   rI   rJ   rl   rP   r   r$   rL   r-   rR   rS   s   @r   rz   rz   †  sE   ø„ ññ
 Cð 
°sð 
ÈCð 
ÐW[õ 
ð˜Ÿ™ð ¨%¯,©,÷ r   rz   c                   ó`   ‡ — e Zd ZdZdefˆ fd„Zdej                  dej                  fd„Zˆ xZ	S )r‘   zÆ
    An `AdapterResnetBlock` is a helper model that implements a ResNet-like block.

    Args:
        channels (`int`):
            Number of channels of AdapterResnetBlock's input and output.
    r]   c                 óÊ   •— t         ‰| �  «        t        j                  ||dd¬«      | _        t        j
                  «       | _        t        j                  ||d¬«      | _        y )NrU   r   rr   rŒ   ©r   r   r   rx   Úblock1ÚReLUÚactÚblock2©r   r]   r   s     €r   r   zAdapterResnetBlock.__init__¿  sE   ø€ Ü‰ÑÔÜ—i‘i ¨(ÀÈ1ÔMˆŒÜ—7‘7“9ˆŒÜ—i‘i ¨(ÀÔBˆ�r   r(   r"   c                 ón   — | j                  | j                  |«      «      }| j                  |«      }||z   S )zÎ
        This method takes input tensor x and applies a convolutional layer, ReLU activation, and another convolutional
        layer on the input tensor. It returns addition with the input tensor.
        ©r›   r™   rœ   ©r   r(   Úhs      r   r-   zAdapterResnetBlock.forwardÅ  ó0   € ð �H‰H�T—[‘[ “^Ó$ˆØ�K‰K˜‹Nˆà�1‰uˆr   ©
rG   rH   rI   rJ   rl   r   r$   rL   r-   rR   rS   s   @r   r‘   r‘   ¶  s1   ø„ ñðC õ Cð	˜Ÿ™ð 	¨%¯,©,÷ 	r   r‘   c            	       ó†   ‡ — e Zd ZdZdg d¢ddfdedee   ded	efˆ fd
„Zdej                  deej                     fd„Z	ˆ xZ
S )re   ro   rU   )rW   rX   rY   é   rZ   r\   r]   r^   r   c                 óŽ  •— t         ‰| �  «        ||dz  z  }t        j                  |«      | _        t        j
                  t        ||d   |«      gt        t        |«      dz
  «      D �cg c]  }t        ||   ||dz      |d¬«      ‘Œ c}¢t        |d   |d   |d¬«      ‘«      | _	        |dt        |«      z  z  | _
        y c c}w )Nr   r   r   Tru   éÿÿÿÿ)r   r   r   rw   rk   r   ÚLightAdapterBlockr   r   r{   r   r|   s         €r   r   zLightAdapter.__init__Ù  sÛ   ø€ ô 	‰ÑÔà!Ð$4°aÑ$7Ñ7ˆä×*Ñ*Ð+;Ó<ˆŒä—M‘Mä! +¨x¸©{¸NÓKðô #¤3 x£=°1Ñ#4Ô5óá5˜ô & h¨q¡k°8¸AÀ¹E±?ÀNÐY]Ö^Ø5ñðô " (¨2¡,°¸±¸nÐSWÔXðó	
ˆŒ	ð '7¸!¼sÀ8»}Ñ:LÑ&MˆÕ#ùòs   Á*C
r(   r"   c                 ó€   — | j                  |«      }g }| j                  D ]  } ||«      }|j                  |«       Œ |S )zÞ
        This method takes the input tensor x and performs downscaling and appends it in list of feature tensors. Each
        feature tensor corresponds to a different level of processing within the LightAdapter.
        )rk   r{   r?   r   s       r   r-   zLightAdapter.forwardó  sA   € ð
 �N‰N˜1Óˆàˆà—Y”YˆEÙ�a“ˆAØ�O‰O˜AÕð ð ˆr   r�   rS   s   @r   re   re   Ô  sj   ø„ ñð Ú.ØØ !ñNàðNð �s‘)ðNð ð	Nð
 õNð4˜Ÿ™ð ¨$¨u¯|©|Ñ*<÷ r   re   c            	       ón   ‡ — e Zd ZdZd
dedededefˆ fd„Zdej                  dej                  fd	„Z	ˆ xZ
S )r¨   a<  
    A `LightAdapterBlock` is a helper model that contains multiple `LightAdapterResnetBlocks`. It is used in the
    `LightAdapter` model.

    Args:
        in_channels (`int`):
            Number of channels of LightAdapterBlock's input.
        out_channels (`int`):
            Number of channels of LightAdapterBlock's output.
        num_res_blocks (`int`):
            Number of LightAdapterResnetBlocks in the LightAdapterBlock.
        down (`bool`, *optional*, defaults to `False`):
            If `True`, perform downsampling on LightAdapterBlock's input.
    r\   r‡   r^   rv   c                 ód  •— t         ‰| �  «        |dz  }d | _        |rt        j                  ddd¬«      | _        t        j
                  ||d¬«      | _        t        j                  t        |«      D �cg c]  }t        |«      ‘Œ c}Ž | _
        t        j
                  ||d¬«      | _        y c c}w )Nr¥   r   Tr‰   r   rŒ   )r   r   r�   r   rŽ   rx   r�   r�   r   ÚLightAdapterResnetBlockr’   Úout_conv)r   r\   r‡   r^   rv   Úmid_channelsr4   r   s          €r   r   zLightAdapterBlock.__init__  s“   ø€ Ü‰ÑÔØ# qÑ(ˆàˆŒÙÜ Ÿl™l°qÀÈdÔSˆDŒOä—y‘y ¨lÈÔJˆŒÜ—}‘}ÔV[Ð\jÔVkÓ&lÑVkÐQRÔ'>¸|Õ'LÐVkÑ&lÐmˆŒÜŸ	™	 ,°È!ÔLˆ�ùò 'ms   Á4B-r(   r"   c                 ó¦   — | j                   �| j                  |«      }| j                  |«      }| j                  |«      }| j                  |«      }|S )zÆ
        This method takes tensor x as input and performs downsampling if required. Then it applies in convolution
        layer, a sequence of residual blocks, and out convolutional layer.
        )r�   r�   r’   r­   rg   s     r   r-   zLightAdapterBlock.forward  sI   € ð
 �?‰?Ð&Ø—‘ Ó"ˆAà�L‰L˜‹OˆØ�L‰L˜‹OˆØ�M‰M˜!Óˆàˆr   r”   r•   rS   s   @r   r¨   r¨     sJ   ø„ ññ
M Cð 
M°sð 
MÈCð 
MÐW[õ 
Mð˜Ÿ™ð ¨%¯,©,÷ r   r¨   c                   ó`   ‡ — e Zd ZdZdefˆ fd„Zdej                  dej                  fd„Zˆ xZ	S )r¬   a  
    A `LightAdapterResnetBlock` is a helper model that implements a ResNet-like block with a slightly different
    architecture than `AdapterResnetBlock`.

    Args:
        channels (`int`):
            Number of channels of LightAdapterResnetBlock's input and output.
    r]   c                 óÌ   •— t         ‰| �  «        t        j                  ||dd¬«      | _        t        j
                  «       | _        t        j                  ||dd¬«      | _        y )NrU   r   rr   r˜   r�   s     €r   r   z LightAdapterResnetBlock.__init__8  sG   ø€ Ü‰ÑÔÜ—i‘i ¨(ÀÈ1ÔMˆŒÜ—7‘7“9ˆŒÜ—i‘i ¨(ÀÈ1ÔMˆ�r   r(   r"   c                 ón   — | j                  | j                  |«      «      }| j                  |«      }||z   S )z¼
        This function takes input tensor x and processes it through one convolutional layer, ReLU activation, and
        another convolutional layer and adds it to input tensor.
        rŸ   r    s      r   r-   zLightAdapterResnetBlock.forward>  r¢   r   r£   rS   s   @r   r¬   r¬   .  s1   ø„ ñðN õ Nð	˜Ÿ™ð 	¨%¯,©,÷ 	r   r¬   )r;   Útypingr   r$   Útorch.nnr   Úconfiguration_utilsr   r   Úutilsr   Úmodeling_utilsr	   Ú
get_loggerrG   r@   r   r   ÚModulerc   rd   rz   r‘   re   r¨   r¬   © r   r   Ú<module>r»      sÅ   ðó 
Ý ã Ý ç AÝ Ý &ð 
ˆ×	Ñ	˜HÓ	%€ôy�:ô yôxD7�˜[ô D7ôT/�"—)‘)ô /ôd/�B—I‘Iô /ôd-�2—9‘9ô -ô`˜Ÿ™ô ô<,�2—9‘9ô ,ô^(˜Ÿ	™	ô (ôV˜bŸi™iõ r   