o
    8wÖiê  ã                   @   sd   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
mZmZ G dd	„ d	eƒZdS )
é    )ÚUnionN)Únn)ÚLycorisConfigÚLycorisTuner)Úget_pattern_keyé   )ÚConv2dÚLinearÚ	LoKrLayerc                   @   s€   e Zd ZU dZdZeed< ejj	e	ejj
e
iZeeejj ee f ed< dededeeejf ded	ejd
eddfdd„ZdS )Ú	LoKrModelaé  
    Creates Low-Rank Kronecker Product model from a pretrained model. The original method is partially described in
    https://huggingface.co/papers/2108.06098 and in https://huggingface.co/papers/2309.14859 Current implementation
    heavily borrows from
    https://github.com/KohakuBlueleaf/LyCORIS/blob/eb460098187f752a5d66406d3affade6f0a07ece/lycoris/modules/lokr.py

    Args:
        model (`torch.nn.Module`): The model to which the adapter tuner layers will be attached.
        config ([`LoKrConfig`]): The configuration of the LoKr model.
        adapter_name (`str`): The name of the adapter, defaults to `"default"`.
        low_cpu_mem_usage (`bool`, `optional`, defaults to `False`):
            Create empty adapter weights on meta device. Useful to speed up the loading process.

    Returns:
        `torch.nn.Module`: The LoKr model.

    Example:
        ```py
        >>> from diffusers import StableDiffusionPipeline
        >>> from peft import LoKrModel, LoKrConfig

        >>> config_te = LoKrConfig(
        ...     r=8,
        ...     lora_alpha=32,
        ...     target_modules=["k_proj", "q_proj", "v_proj", "out_proj", "fc1", "fc2"],
        ...     rank_dropout=0.0,
        ...     module_dropout=0.0,
        ...     init_weights=True,
        ... )
        >>> config_unet = LoKrConfig(
        ...     r=8,
        ...     lora_alpha=32,
        ...     target_modules=[
        ...         "proj_in",
        ...         "proj_out",
        ...         "to_k",
        ...         "to_q",
        ...         "to_v",
        ...         "to_out.0",
        ...         "ff.net.0.proj",
        ...         "ff.net.2",
        ...     ],
        ...     rank_dropout=0.0,
        ...     module_dropout=0.0,
        ...     init_weights=True,
        ...     use_effective_conv2d=True,
        ... )

        >>> model = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
        >>> model.text_encoder = LoKrModel(model.text_encoder, config_te, "default")
        >>> model.unet = LoKrModel(model.unet, config_unet, "default")
        ```

    **Attributes**:
        - **model** ([`~torch.nn.Module`]) -- The model to be adapted.
        - **peft_config** ([`LoKrConfig`]): The configuration of the LoKr model.
    Úlokr_ÚprefixÚlayers_mappingÚconfigÚadapter_nameÚtargetÚtarget_nameÚparentÚcurrent_keyÚreturnNc                 C   s¤   t |j ¡ |ƒ}t |j ¡ |ƒ}| ¡ }	|j ||j¡|	d< |j ||j¡|	d< |j|	d< t	|t
ƒr=|j|fi |	¤Ž dS | j|||fi |	¤Ž}
|  |||
|¡ dS )zc
        A private method to create and replace the target module with the adapter module.
        ÚrÚalphaÚrank_dropout_scaleN)r   Úrank_patternÚkeysÚalpha_patternÚto_dictÚgetr   r   r   Ú
isinstancer
   Úupdate_layerÚ_create_new_moduleÚ_replace_module)Úselfr   r   r   r   r   r   Úr_keyÚ	alpha_keyÚkwargsÚ
new_module© r'   úS/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/peft/tuners/lokr/model.pyÚ_create_and_replace[   s   

zLoKrModel._create_and_replace)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚstrÚ__annotations__Útorchr   r   r	   r   ÚdictÚtypeÚModuler
   r   r   r)   r'   r'   r'   r(   r      s*   
 : þþýüûúùør   )Útypingr   r0   r   Úpeft.tuners.lycoris_utilsr   r   Úpeft.utils.otherr   Úlayerr   r	   r
   r   r'   r'   r'   r(   Ú<module>   s   