
    biJ                       d dl mZ d dlZd dl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 d dlmZmZ d dlZd dlmZ d d	lmZ d d
lmZmZ d dlmZmZmZmZmZ d dlmZm Z m!Z!m"Z"m#Z#m$Z$m%Z% d dl&m'Z'm(Z(m)Z)m*Z*m+Z+ d dl,m-Z- ddl.m/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9 ddl:m;Z; ddl<m=Z=m>Z>m?Z?m@Z@ ddlAmBZB ddlCmDZD d ZE G d de      ZFy)    )annotationsN)contextmanager)asdictreplace)Enum)partialreduce)LiteralOptional)nn)tqdm)is_bnb_4bit_availableis_bnb_available)	BaseTunerBaseTunerLayercheck_target_module_existsonload_layerreplicate_layers)2TRANSFORMERS_MODELS_TO_LORA_TARGET_MODULES_MAPPINGAuxiliaryTrainingWrapperModulesToSaveWrapper_freeze_adapter_get_submodulesget_peft_model_state_dictget_quantization_config)dare_linear	dare_tiesmagnitude_prunetask_arithmeticties)get_pattern_key   )dispatch_aqlm)dispatch_awq)
LoraConfig)dispatch_eetq)dispatch_gptq)dispatch_hqq)dispatch_inc)Conv2d	LoraLayerParamWrapperdispatch_default)dispatch_torchao)dispatch_megatronc                    ||d<   ||fS )Nadapter_names )targetargskwargsr1   s       Q/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/peft/tuners/lora/model.py_adapter_names_pre_forward_hookr7   =   s    +F?<    c                      e Zd ZU dZdZded<   d dZed        Zd!dZ	dd		 	 	 d"d
Z
d Zd#dZed        Zd$ fdZd%d&dZd'd(dZd)dZd)dZd*dZed        Z fdZed        Z	 	 	 	 d+	 	 	 	 	 d,dZ	 	 	 	 	 	 	 	 d-dZ	 	 	 	 	 	 	 d.	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d/dZ	 	 	 d0dZd Zd1dZ	 d2	 	 	 	 	 	 	 d3dZd4dZd5d6dZ  xZ!S )7	LoraModela   
    Creates Low Rank Adapter (LoRA) model from a pretrained transformers model.

    The method is described in detail in https://huggingface.co/papers/2106.09685.

    Args:
        model ([`torch.nn.Module`]): The model to be adapted.
        config ([`LoraConfig`]): The configuration of the Lora 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 Lora model.

    Example:

        ```py
        >>> from transformers import AutoModelForSeq2SeqLM
        >>> from peft import LoraModel, LoraConfig

        >>> config = LoraConfig(
        ...     task_type="SEQ_2_SEQ_LM",
        ...     r=8,
        ...     lora_alpha=32,
        ...     target_modules=["q", "v"],
        ...     lora_dropout=0.01,
        ... )

        >>> model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
        >>> lora_model = LoraModel(model, config, "default")
        ```

        ```py
        >>> import torch
        >>> import transformers
        >>> from peft import LoraConfig, PeftModel, get_peft_model, prepare_model_for_kbit_training

        >>> rank = ...
        >>> target_modules = ["q_proj", "k_proj", "v_proj", "out_proj", "fc_in", "fc_out", "wte"]
        >>> config = LoraConfig(
        ...     r=4, lora_alpha=16, target_modules=target_modules, lora_dropout=0.1, bias="none", task_type="CAUSAL_LM"
        ... )
        >>> quantization_config = transformers.BitsAndBytesConfig(load_in_8bit=True)

        >>> tokenizer = transformers.AutoTokenizer.from_pretrained(
        ...     "kakaobrain/kogpt",
        ...     revision="KoGPT6B-ryan1.5b-float16",  # or float32 version: revision=KoGPT6B-ryan1.5b
        ...     bos_token="[BOS]",
        ...     eos_token="[EOS]",
        ...     unk_token="[UNK]",
        ...     pad_token="[PAD]",
        ...     mask_token="[MASK]",
        ... )
        >>> model = transformers.GPTJForCausalLM.from_pretrained(
        ...     "kakaobrain/kogpt",
        ...     revision="KoGPT6B-ryan1.5b-float16",  # or float32 version: revision=KoGPT6B-ryan1.5b
        ...     pad_token_id=tokenizer.eos_token_id,
        ...     use_cache=False,
        ...     device_map={"": rank},
        ...     torch_dtype=torch.float16,
        ...     quantization_config=quantization_config,
        ... )
        >>> model = prepare_model_for_kbit_training(model)
        >>> lora_model = get_peft_model(model, config)
        ```

    **Attributes**:
        - **model** ([`~transformers.PreTrainedModel`]) -- The model to be adapted.
        - **peft_config** ([`LoraConfig`]): The configuration of the Lora model.
    lora_strprefixc                    t        | j                        dkD  r2|j                  dk7  r"t        | j                  j
                   d      yy)z
        A helper method to check the config when a new adapter is being added.

        Raise a ValueError if there is something wrong with the config or if it conflicts with existing adapters.

        r"   nonezf supports only 1 adapter with bias. When using multiple adapters, set bias to 'none' for all adapters.N)lenpeft_configbias
ValueError	__class____name__)selfconfigs     r6   _check_new_adapter_configz#LoraModel._check_new_adapter_config   sR       !A%FKK6,A>>**+ ,7 7  -B%r8   c                    t        | |      S N)r   )lora_configkeys     r6   _check_target_module_existsz%LoraModel._check_target_module_exists   s    )+s;;r8   c                J    |j                   rt        ||j                          yy)a  
        A private method to modify the model structure before adapter is applied.

        Args:
            peft_config (`PeftConfig`):
                The prepared adapter config.
            model (`nn.Module`):
                The model that is going to be adapted.
        N)layer_replicationr   )rF   rA   models      r6   _prepare_modelzLoraModel._prepare_model   s"     ((UK$A$AB )r8   N)parameter_namec               \   |t        d      |j                  rGt        fd| j                  j	                         D              }|rt        d|j                   d      t        |j                  j                         |      }	t        |j                  j                         |      }
|j                  j                  |	|j                        }|j                  j                  |
|j                        }|||j                  |j                  |j                  |j                  |j                   |j"                  |j$                  |j&                  j(                  |j*                  t-        | j.                  dd      t-        | j.                  dd      |d}	  t1        j2                  d	      | j.                        |d
<   g d}|D ]$  }t7        | j.                  |      }|||| d<   & ddlm} t=        |t>              xr |j@                  v }t=        |tB              rZt=        ||      sN|sL|jE                  |||j                  |j                  |j                  |j                   |j*                         y t=        |t>              r||jF                  k(  rt        d      tI        | j.                  d      r| j.                  jJ                  nd } | jL                  ||fd|i|}| jN                  vr|jQ                  d       | jS                  ||||       y # t4        $ r Y lw xY w)NzCurrent Key shouldn't be `None`c              3  H   K   | ]  \  }}|k7  s|j                     y wrJ   )target_parameters).0rL   confadapter_names      r6   	<genexpr>z0LoraModel._create_and_replace.<locals>.<genexpr>   s)      2+43TW[gTg&&2s   ""z-Adding a LoRA config with `target_parameters=z` but there are already other LoRA adapters on this model that use `target_parameters`. At the moment, only one LoRA adapter per model with `target_parameters` is allowed.is_loaded_in_8bitFis_loaded_in_4bit)r
lora_alphalora_dropoutfan_in_fan_outinit_lora_weights
use_rslorause_dora
use_qaloraqalora_group_sizeephemeral_gpu_offload	lora_biasloaded_in_8bitloaded_in_4bitrR   z:hf_quantizer.quantization_config.get_apply_tensor_subclassget_apply_tensor_subclass)gptqaqlmawq)method_quantization_configr   )AdaLoraLayer)r]   r^   r`   ra   rb   rf   zTrying to target the same nn.Parameter twice, this should not happen. Please open an issue on the PEFT repo: https://github.com/huggingface/peft/issueshf_device_map
device_map)*rC   rU   anyrA   itemsr!   rank_patternkeysalpha_patterngetr\   r]   r^   r_   r`   ra   rb   rc   rd   runtime_configre   rf   getattrrP   operator
attrgetterAttributeErrorr   peft.tuners.adaloraro   
isinstancer,   lora_Ar+   update_layerrR   hasattrrp   _create_new_moduleactive_adaptersrequires_grad__replace_module)rF   rK   rX   r3   target_nameparentcurrent_keyrR   other_configs_use_target_paramsr_key	alpha_keyr\   alphar5   quant_methodsquant_methodquantization_configro   wrap_target_paramrq   
new_modules     `                  r6   _create_and_replacezLoraModel._create_and_replace   s    >??((.1 28<8H8H8N8N8P2 /+ / CKDaDaCb cV V    8 8 = = ?M#K$=$=$B$B$DkR	$$((>))--i9O9OP '44)88!,!>!>%00#,,%00!,!>!>%0%?%?%U%U$..%djj2EuM%djj2EuM,
"	3(2E2EL3jj3F./ 0) 	TL"9$**\"Z".@S,';<=	T 	5 'v|<`,RXR_R_B_fi(FL1QZk (55"-"?"?&11$--%//   	 &,/^vG\G\5\ L  6=TZZ5Y11_cJ000lFt_itmstJ4#7#77))%0  j&II  		s   (L 	L+*L+c                H   t        |||       t        |d      r|j                  }t        j                  d      |j                         D ]  \  }}| j                  |v sd|v st        |d      r|j                  }net        |d      r|j                  }nLt        |d      r|j                  }n3t        |dd       |j                  }nt        |j                               }t        fd|j                         D              r|j                  |j                          y )	N
base_layermetaranknumqweightW_qweightin_proj_weightc              3  <   K   | ]  }|j                   k(    y wrJ   )device)rV   pr   s     r6   rY   z,LoraModel._replace_module.<locals>.<genexpr>   s     I188t+I   )setattrr   r   torchr   named_modulesr=   r   r   r   ry   r   next
parametersrr   to)	rF   r   
child_namer   childnamemoduler   r   s	           @r6   r   zLoraModel._replace_module	  s    
J/
 5,'$$E||F#&446 	-LD&t#d):5),"]]FUE*"YYFUH-"\\FU$4d;G"11F!%"2"2"45FIV5F5F5HIIIIfmm,	-r8   c                   |j                         D ]  \  }}| j                  |vsd|_         | j                  D ]  }| j                  |   j
                  }|dk(  r"|dk(  r%|j                         D ]  \  }}d|v sd|_         L|dk(  rR|j                         D ]>  }t        |t              st        |d      s!|j
                  .d|j
                  _        @ t        d| d       y )	NFr?   allrB   T	lora_onlyzRequested bias: z, is not implemented.)named_parametersr=   requires_gradr   rA   rB   modulesr~   r+   r   NotImplementedError)rF   rP   nr   active_adapterrB   ms          r6    _mark_only_adapters_as_trainablez*LoraModel._mark_only_adapters_as_trainable#  s    **, 	(DAq{{!#"'	( #22 	ZN##N388Dv~u}!224 /DAq{*./ $ 4A!!Y/GAv4F166K]/3,4 *,<TFBW*XYY	Zr8   c                   g }| j                   rd }|j                  |       t               rddlm} |j                  |       t               rddlm} |j                  |       |j                  t        t        t        t        t        t        t        t        t         g	       d }|D ]  }	 |	||fd| i|}| n |t#        d| d      |S )Nc                    d }t        | t              r| j                         }n| }|j                  j	                         D ]  \  }}t        ||      s || |fi |} |S  |S rJ   )r~   r   get_base_layer_custom_modulesrs   )r3   rX   rK   r5   r   target_base_layerrL   
custom_clss           r6   dynamic_dispatch_funcz;LoraModel._create_new_module.<locals>.dynamic_dispatch_funcA  su    !
fn5(.(=(=(?%(.%'2'B'B'H'H'J OC!"3S9%/%O%O
!!
 "!r8   r"   )dispatch_bnb_8bit)dispatch_bnb_4bitrK   zTarget module z is not supported. Currently, only the following modules are supported: `torch.nn.Linear`, `torch.nn.Embedding`, `torch.nn.Conv1d`, `torch.nn.Conv2d`, `torch.nn.Conv3d`, `transformers.pytorch_utils.Conv1D`, `torch.nn.MultiheadAttention.`.)r   appendr   bnbr   r   r   extendr&   r#   r$   r'   r(   r)   r.   r/   r-   rC   )
rK   rX   r3   r5   dispatchersr   r   r   r   
dispatchers
             r6   r   zLoraModel._create_new_module8  s     &&" 45 .01 ".01 ! 
	
 
% 	J#FL\k\U[\J%	
   )W W  r8   c                z    	 t         |   |      S # t        $ r |dk(  r t        | j                  |      cY S w xY w)z1Forward missing attributes to the wrapped module.rP   )super__getattr__r|   ry   rP   )rF   r   rD   s     r6   r   zLoraModel.__getattr__{  sB    	-7&t,, 	-w4::t,,	-s    %::c           
        i }| j                   j                         D ]U  \  }}t        |      j                         D ci c]$  \  }}|t        |t              r|j
                  n|& }}}|sQd|d<   W |<   |S c c}}w )NTinference_mode)rA   rs   r   r~   r   value)rF   	inferenceconfig_dictrL   r   kvrG   s           r6   get_peft_config_as_dictz!LoraModel.get_peft_config_as_dict  s    **002 	0JCKQRW=K^K^K`a41aaJq$$7Q>aFa+/'(	0 "C	 bs   )A<c                    | j                   j                         D ]*  }t        |t        t        f      s|j                  |       , y rJ   )rP   r   r~   r   r   enable_adapters)rF   enabledr   s      r6   _set_adapter_layerszLoraModel._set_adapter_layers  s<    jj((* 	0F&>3K"LM&&w/	0r8   c                (    | j                  d       y)zyEnable all adapters.

        Call this if you have previously disabled all adapters and want to re-enable them.
        Tr   N)r   rF   s    r6   enable_adapter_layerszLoraModel.enable_adapter_layers  s    
 	   .r8   c                    | j                   D ]<  }| j                  |   j                  }|dk7  s"d| d}t        j                  |       > | j                  d       y)zDisable all adapters.

        When disabling all adapters, the model output corresponds to the output of the base model.
        r?   z>Careful, disabling adapter layers with bias configured to be 'zL' does not produce the same output as the base model would without adaption.Fr   N)r   rA   rB   warningswarnr   )rF   r   valmsgs       r6   disable_adapter_layersz LoraModel.disable_adapter_layers  sr    
 #22 	#N"">277Cf}TUXTY ZG G  c"	# 	   /r8   c                    | j                   j                         D ]U  }t        |t              s|j                  r%t        j                  d       |j                          |j                  |       W || _	        y)a   Set the active adapter(s).

        Additionally, this function will set the specified adapters to trainable (i.e., requires_grad=True). If this is
        not desired, use the following code.

        ```py
        >>> for name, param in model_peft.named_parameters():
        ...     if ...:  # some check on name (ex. if 'lora' in name)
        ...         param.requires_grad = False
        ```

        Args:
            adapter_name (`str` or `list[str]`): Name of the adapter(s) to be activated.
        zJAdapter cannot be set when the model is merged. Unmerging the model first.N)
rP   r   r~   r+   mergedr   r   unmergeset_adapterr   )rF   rX   r   s      r6   r   zLoraModel.set_adapter  s`     jj((* 	1F&),==MM"noNN$""<0	1 +r8   c              /    K   j                  dd       }|d  y | j                  rt        d      t               }| j	                         D ]M  }t        |t              s||j                  j                         z  }||j                  j                         z  }O |D ch c]
  }|dk7  s	| }}||z
  }|r&t        ddj                  t        |                   j                  dd       }	t        |	t              xr |	dkD  }
|d d  }|
rCt        |t        t        f      st!        dt#        |       d	      t%        fd
|D        g       }g }| j	                         D ]X  }t        |t              st        |t&              s$t)        t*        |      }|j-                  |d      }|j/                  |       Z |
rt1        | j2                  d      r| j2                  j5                         j	                         D ]X  }t        |t              st        |t&              s$t)        t*        |      }|j-                  |d      }|j/                  |       Z d  |D ]  }|j7                           y c c}w w)Nr1   z?Cannot pass `adapter_names` when the model is in training mode.__base__z.Trying to infer with non-existing adapter(s): z, 	num_beamsr"   zGot adapter names of type z, expected a list of str.c              3  0   K   | ]  }|gd    z    yw)r   Nr2   )rV   r   r5   s     r6   rY   z7LoraModel._enable_peft_forward_hooks.<locals>.<genexpr>  s      Rq!vk':!: Rs   )r1   T)with_kwargsget_encoder)poptrainingrC   setr   r~   r+   r   ru   lora_embedding_Ajoinsortedrw   intlisttuple	TypeErrortypesumr   r   r7   register_forward_pre_hookr   r   rP   r   remove)rF   r4   r5   r1   expected_adapterslayerr   unique_adaptersunexpected_adaptersr   uses_beam_searchoriginal_adapter_nameshook_handlesr   pre_forwardhandles     `             r6   _enable_peft_forward_hooksz$LoraModel._enable_peft_forward_hooks  s^     

?D9 ==^__
  E\\^ 	CE%+!U\\%6%6%88!!U%;%;%@%@%BB!	C -:PDTZ=O4PP-0AAMdiiX^_rXsNtMuvww JJ{D1	%i5I9q=!.q!1mdE];"<T-=P<QQj kll   RM RTVWMlln 	,F&),
6C[0\%&EUbc99+SW9X##F+		, 

M B **002::< 0fi0JvG_4` #**IYo"pK#==kW[=\F ''/0 	" 	FMMO	K Qs.   AI<"A I<"
I7-I71CI<	BI<$AI<c                    t         |           t        | j                  dd      dk(  rt	        d      | j
                  j                  d      rt	        d      y)zVerify that the configuration supports merging.

        Currently gptq quantization and replicated layers do not support merging.
        quantization_methodNrj   z9Cannot merge LORA layers when the model is gptq quantizedrO   z>Cannot merge LORA layers when base model layers are replicated)r   _check_merge_allowedry   rP   rC   rA   rw   )rF   rD   s    r6   r   zLoraModel._check_merge_allowed  sX    
 	$&4::4d;vEXYY 34]^^ 5r8   c                    | j                   >|d   t        v rt        t        |d            | _         | S | j                  st	        d      | S )N
model_typezFPlease specify `target_modules` or `target_parameters`in `peft_config`)target_modulesr   r   rU   rC   )rA   model_configs     r6   _prepare_adapter_configz!LoraModel._prepare_adapter_config  s\    %%-L)-__-0F|T`Gab.*
  !22 !ijjr8   c                   |r| j                          | j                  j                         D cg c]  \  }}| j                  |vs| }}}d|rdndz   dz   }t	        || |      D ]  }	 t        | j                  |      \  }	}
}t        |
      5  t        |
d      r)|
j                  |||      }| j                  |	|||
       nCt        |
d      r7|r|
j                  ||	       | j                  |	||
j                         |
       d d d         | j                  S c c}}w # t        $ r Y w xY w# 1 sw Y   xY w)
Nz
Unloading zand merging  rP   )disabledesc"unload_and_optionally_merge_module)merge
safe_merger1   r   )r  r1   )r   rP   r   r=   r   r   r|   r   r   r	  r   r
  r   )rF   r
  progressbarr  r1   rL   _key_listr  r   r3   r   unloaded_modules                r6   _unload_and_optionally_mergez&LoraModel._unload_and_optionally_merge  sV    %%'&*jj&>&>&@[FCDKKWZDZC[[~B?'Ik/E 	_C.=djj#.N+ f% 
_6#GH&,&O&O#
- 'P 'O ((ovVV\2
-X((f>S>S>UW]^
_ 
_	_" zz' \
 " 
_ 
_s*   D!D!-D'A9D6'	D32D36D?	c                .    |D ]6  }|t         j                  j                               vs)t        d| d       |D ]*  } j                  |   j                  st        d| d        j                         D cg c]  }t        |t              s| }}|D cg c]  t        fd|D              dkD  r }}|rt        dt        |       d      t        |      dk(  rd	n|} fd
|D        D 	cg c]H  }	|	j                  s|	j                  n-t        |	j                  g|	j                  j                          J }
}	|dv r(t        t        |
            dk7  rt        d      |
d   }n@|dk(  rt        |
      }n/|j                  d      r|xs t        |
      }nt        d|       |D cg c]$  }t!         j                  |   j"                        & }}|st        d|       t        t        |            dkD  rt        d      |d   t$        u rdj'                   fd|D              }nA|d   t        u r$t)        t*        j,                   fd|D              }nt/        d|d    d      |||fS c c}w c c}w c c}	w c c}w )z
        Helper function to check if the arguments to add_weighted_adapter are valid and compatible with the underlying
        model.
        Adapter  does not existzSadd_weighted_adapter does not support targeting nn.Parameter (problematic adapter 'z')c              3  :   K   | ]  }|j                   v   y wrJ   )modules_to_save)rV   adapterwrappers     r6   rY   z8LoraModel._check_add_weighted_adapter.<locals>.<genexpr>H  s     N'7g555N   r"   z\Cannot add weighted adapters if they target the same module with modules_to_save, but found z such instance(s).linearc              3  <   K   | ]  }j                   |     y wrJ   )rA   rV   r  rF   s     r6   rY   z8LoraModel._check_add_weighted_adapter.<locals>.<genexpr>V  s     M4++G4Mr   )r  r    r   r   r   zkAll adapters must have the same r value when using combination_type linear, ties, dare_ties or dare_linear.r   catsvdzInvalid combination_type: z'Found no adapter matching the names in zall adapter configs should follow the same target modules type. Combining adapters with `target_modules` type being a mix of list/set and string is not supported.|c              3  X   K   | ]!  }d j                   |   j                   d # yw)()NrA   r  r  s     r6   rY   z8LoraModel._check_add_weighted_adapter.<locals>.<genexpr>u  s.     )r^eAd.>.>w.G.V.V-WWX*Y)rs   '*c              3  P   K   | ]  }j                   |   j                    y wrJ   r"  r  s     r6   rY   z8LoraModel._check_add_weighted_adapter.<locals>.<genexpr>x  s"     `Gt//8GG`s   #&zInvalid type z found in target_modules)r   rA   ru   rC   rU   r   r~   r   r   r@   rt   r\   maxvaluesr   endswithr   r  r<   r   r	   rz   or_r   )rF   adapterscombination_typesvd_rankr  r   modules_to_save_wrappersr  problematic_wrappersrG   adapters_ranksnew_ranktarget_module_typesnew_target_moduless   `      `      r6   _check_add_weighted_adapterz%LoraModel._check_add_weighted_adapter0  s      	FGd4#3#3#8#8#:;; 8G9O!DEE	F   	G(:: ijqirrtu 	 :>#tv:V\^rKsF#t #t 4 
NXNNQRR  
  

  n+,--?A  (+8}'98?O
 NHM%
  #//FHHS5aFDWDWD^D^D`5aa%
 %
 ``3~&'1, #  &a(H& >*H&&u-63~#6H9:J9KLMM]efRYtD$4$4W$=$L$LMff"FxjQRRs&'(1,u 
 q!S(!$)riq)r!r #s*!'`W_`" m,?,B+CC[\]]+===s $u 
%
0 gs   ?JJ  J;AJ:)Jc                   |t        | j                  j                               v ry| j                  |||      \  }}}t	        | j                  |d      |||i i       | j                  |<   | j                  | j                  |       t        | j                  |       | j                  j                         D cg c]  \  }}| j                  |vs| }}}|D ]  }t        | j                  |      \  }}}t        |t              s/||j                  v r3|j                  |   j                  }|j                  |   j                  }n.||j                   v r|j                   |   }|j"                  |   }n|j$                  dz  |_        |j$                  dz  |_        |dk(  r]g g }}t'        ||      D ]  \  }}||j                  v r3|j                  |   j                  }|j                  |   j                  }n.||j                   v r|j                   |   }|j"                  |   }nu|j)                  |j$                  |z  |j*                  |   z         |j)                  |j$                          t-        |      dk(  rt/        d      t1        j2                  |d      }t1        j2                  |d	      }||j$                  d|j4                  d   ddf<   ||j$                  ddd|j4                  d	   f<   )|d
v r,| j7                  ||||||||	|
|||      \  |_        |_        Y|dv s_| j9                  |||||	|
      \  |_        |_         yc c}}w )a	  
        This method adds a new adapter by merging the given adapters with the given weights.

        When using the `cat` combination_type you should be aware that rank of the resulting adapter will be equal to
        the sum of all adapters ranks. So it's possible that the mixed adapter may become too big and result in OOM
        errors.

        Args:
            adapters (`list`):
                List of adapter names to be merged.
            weights (`list`):
                List of weights for each adapter.
            adapter_name (`str`):
                Name of the new adapter.
            combination_type (`str`):
                The merging type can be one of [`svd`, `linear`, `cat`, `ties`, `ties_svd`, `dare_ties`, `dare_linear`,
                `dare_ties_svd`, `dare_linear_svd`, `magnitude_prune`, `magnitude_prune_svd`]. When using the `cat`
                combination_type, the rank of the resulting adapter is equal to the sum of all adapters ranks (the
                mixed adapter may be too big and result in OOM errors).
            svd_rank (`int`, *optional*):
                Rank of output adapter for svd. If None provided, will use max rank of merging adapters.
            svd_clamp (`float`, *optional*):
                A quantile threshold for clamping SVD decomposition output. If None is provided, do not perform
                clamping. Defaults to None.
            svd_full_matrices (`bool`, *optional*):
                Controls whether to compute the full or reduced SVD, and consequently, the shape of the returned
                tensors U and Vh. Defaults to True.
            svd_driver (`str`, *optional*):
                Name of the cuSOLVER method to be used. This keyword argument only works when merging on CUDA. Can be
                one of [None, `gesvd`, `gesvdj`, `gesvda`]. For more info please refer to `torch.linalg.svd`
                documentation. Defaults to None.
            density (`float`, *optional*):
                Value between 0 and 1. 0 means all values are pruned and 1 means no values are pruned. Should be used
                with [`ties`, `ties_svd`, `dare_ties`, `dare_linear`, `dare_ties_svd`, `dare_linear_svd`,
                `magnintude_prune`, `magnitude_prune_svd`]
            majority_sign_method (`str`):
                The method, should be one of ["total", "frequency"], to use to get the magnitude of the sign values.
                Should be used with [`ties`, `ties_svd`, `dare_ties`, `dare_ties_svd`]
        N)r(  r)  r*  r   )r\   r]   r  rv   rt   g        r  z9No matching LoRAs found. Please raise an issue on GitHub.dimr"   )r  ties_svddare_linear_svddare_ties_svdmagnitude_prune_svdfull_matricesdriver)r  r    r   r   r   )r   rA   ru   r1  r   inject_adapterrP   r   r   r=   r   r~   r+   r   r   lora_Br   lora_embedding_Bdatazipr   scalingr@   rC   r   r  shape1_svd_generalized_task_arithmetic_weighted_adapter-_generalized_task_arithmetic_weighted_adapter)rF   r(  weightsrX   r)  r*  	svd_clampsvd_full_matrices
svd_driverdensitymajority_sign_methodr.  r0  rL   r  r  r3   target_lora_Atarget_lora_Bloras_Aloras_Br  r   current_adapter_lora_Acurrent_adapter_lora_Bs                            r6   add_weighted_adapterzLoraModel.add_weighted_adapter  sv   j 4 0 0 5 5 7889=9Y9Y- :Z :
6($6 *1Xa[)-*
& 	DJJ5 	

L1&*jj&>&>&@[FCDKKWZDZC[[ :	C*4::s;LAvq&),6==0$*MM,$?$F$FM$*MM,$?$F$FM!V%<%<<$*$;$;L$IM$*$;$;L$IM%2%7%7#%="%2%7%7#%="#u,')2WG+.x+A 
D"fmm35;]]75K5R5R25;]]75K5R5R2$(?(??5;5L5LW5U25;5L5LW5U2$'='B'BV'Kfnn]dNe'ef'='B'BC
D 7|q(()dee#iiQ7G#iiQ7G@GM&&'9q)9'91'<=@GM&&q*<GMM!,<*<'<=% *  >B=s=s(  %%,!&7) >t >:M&(: &)jj=A=o=o((GVWNb>:M&(:q:	 \s   <M"M"c                   g }g }t        fd|D              }t        ||      D ]T  \  }}|j                  v s|j                  v s#|j	                  |       |j	                  |j
                  |   z         V t        |      dk(  rt        d      |D cg c]  }j                  |       }}t        j                  |      j                  |d   j                        }|dk(  rt        ||      }n\|dk(  rt        ||||	      }nH|dk(  rt        |||      }n5|dk(  rt!        ||||	      }n!|dk(  rt#        |||      }nt        d	|       t%        t&              }|rEj(                  j+                         d
d dk(  }|s|j-                  d      }n|j/                         }t1        d      rj2                  s|r|j4                  }t        j6                  j9                  |||      \  }}}|d d d |f   }|d | }|t        j:                  |      z  }|d |d d f   }|
pt        j<                  |j-                         |j-                         g      }t        j>                  ||
      }| }|jA                  ||      }|jA                  ||      }|rJ|jC                  |jD                  jF                        }|jC                  |jD                  jF                        }||fS c c}w )Nc              3  :   K   | ]  }|j                   v   y wrJ   )r   )rV   r  r3   s     r6   rY   zNLoraModel._svd_generalized_task_arithmetic_weighted_adapter.<locals>.<genexpr>  s     V'7f&=&==Vr  r   z9No matching LoRAs found. Please raise an issue on Github.r  r5  r6  r7  r8  z*Invalid value passed to combination type:       )r"   r"   r"   )	start_dimr_   r9  )$rr   r@  r   r   r   rA  r@   rC   get_delta_weightr   tensorr   r   r   r    r   r   r   r~   r*   r   sizeflattensqueezer   r_   Tlinalgr  diagr  quantileclampreshaper?  rB  )rF   r)  r(  rE  r.  r3   rK  rL  rI  rJ  r`  r:  r;  valid_adaptersvalid_weightsis_embeddingr  r   delta_weightconv2d
conv2d_1x1USVhdisthi_vallow_vals        `                     r6   rC  z;LoraModel._svd_generalized_task_arithmetic_weighted_adapter  s    VXVV"8W5 	GOGV&--'7f6M6M+M%%g.$$VfnnW.E%EF	G ~!#XYYHVWW//8WW]366|A7M7MNu$*<GL+mWFZ[L!22&|]GLL0$\='K_`L!66*<PLIJZI[\]]FF+++-a2f<J+33a3@+335F,-&2G2GL'>>L <<##LV\#]1ba(lOixL

1		199aiik2::<89D^^D%0FgG(A'6*B		-,,223AM..445B1uQ Xs   K+c                   g }g }g }	t        ||      D ]  \  }
}|
|j                  v r3|j                  |
   j                  }|j                  |
   j                  }n.|
|j                  v r|j                  |
   }|j
                  |
   }nu|j                  t        j                  ||j                  |
   z               |j                  |j                         |	j                  |j                          t        j                  |      j                  |d   j                        }||	g}|d   j                  }t!        |      D ]~  \  }}|dk(  rt#        ||      ||<   |dk(  rt%        ||||      ||<   2|dk(  rt'        |||      ||<   H|dk(  rt)        ||||      ||<   _|dk(  rt+        |||      ||<   ut-        d       |D cg c]  }|j                  |       }}|S c c}w )Nr   r  r    r   r   r   zInvalid combination type)r@  r   r   r=  r   r>  r   mathsqrtrA  r?  r   rX  r   r   dtype	enumerater   r    r   r   r   rC   )rF   r)  r(  rE  r3   rI  rJ  rc  lora_A_deltaslora_B_deltasr  r   rO  rP  lora_deltasrq  itask_tensorsdeltas                      r6   rD  z7LoraModel._generalized_task_arithmetic_weighted_adapterK  s    "8W5 	>OGV&--')/w)?)F)F&)/w)?)F)F&F333)/)@)@)I&)/)@)@)I&  6FNN74K+K!LM  !7!<!<=  !7!<!<=	> ]366}Q7G7N7NO$m4a &&(5 	=OA|8+!0}!MA!V+!%lM7L`!aA!]2!,\='!RA![0!*<Qe!fA!%66!0}g!VA !;<<	= 5@@5uxx@@ As   G$c                   |t        | j                  j                               vrt        d| d      | j                  |= | j                  j                         D cg c]  \  }}| j                  |vs| }}}d}|D ]P  }t        | j                  |      \  }}}t        |t              s.|j                  |       |B|j                  dd }R |xs g | _        | j                  ||       yc c}}w )z
        Deletes an existing adapter.

        Args:
            adapter_name (str): Name of the adapter to be deleted.
        r  r  N)new_active_adapters)r   rA   ru   rC   rP   r   r=   r   r~   r+   delete_adapterr   r   _delete_auxiliary_adapter)rF   rX   rL   r  r  new_adapterr3   s          r6   r{  zLoraModel.delete_adapterw  s     tD$4$4$9$9$;<<x~_EFF\*&*jj&>&>&@[FCDKKWZDZC[[ 	<C*4::s;LAvq&),%%l3&"("8"8";K	< */R&&|&U \s   C36C3c                *    | j                  |||      S )aG  
        This method merges the LoRa layers into the base model. This is needed if someone wants to use the base model
        as a standalone model.

        Args:
            progressbar (`bool`):
                whether to show a progressbar indicating the unload and merge process
            safe_merge (`bool`):
                whether to activate the safe merging check to check if there is any potential Nan in the adapter
                weights
            adapter_names (`List[str]`, *optional*):
                The list of adapter names that should be merged. If None, all active adapters will be merged. Defaults
                to `None`.
        Example:

        ```py
        >>> from transformers import AutoModelForCausalLM
        >>> from peft import PeftModel

        >>> base_model = AutoModelForCausalLM.from_pretrained("tiiuae/falcon-40b")
        >>> peft_model_id = "smangrul/falcon-40B-int4-peft-lora-sfttrainer-sample"
        >>> model = PeftModel.from_pretrained(base_model, peft_model_id)
        >>> merged_model = model.merge_and_unload()
        ```
        )r  r  r1   r  )rF   r  r  r1   s       r6   merge_and_unloadzLoraModel.merge_and_unload  s#    8 00#
- 1 
 	
r8   c                &    | j                  d      S )z
        Gets back the base model by removing all the lora modules without merging. This gives back the original base
        model.
        F)r
  r  r   s    r6   unloadzLoraModel.unload  s    
 00u0==r8   c           
        | j                   j                         D ]  \  }}|j                  j                  t        j
                  k7  s.|j                  j                  t        j                  k7  sV|j                  j                  t        j                  k7  s~|j                  d      st        j                  d        t        | |j                  dd      |      }i }|j                         D ]  }d|v rDt	        j                  ||   |dj                  |j!                  d      dd          gd	
      ||<   Kd|v sPt	        j                  ||   |dj                  |j!                  d      dd           gd
      ||<    |S )a!  
        This function can calculate the updates of the PiSSA/CorDA/OLoRA by comparing the parameters of the
        PiSSA/CorDA/OLoRA adapter in `output_state_dict` with the initial values of PiSSA/CorDA/OLoRA in
        `adapter_name`, thus converting PiSSA/CorDA/OLoRA to LoRA.
        pissaa   Note that Quant(W_res) + AB != Quant(W) + \Delta(AB); the converted LoRA, when combined with W or Quant(W), may introduce a certain gap in the fine-tuned model. Therefore, we recommend directly using the Quant(W_res) in conjunction with the PiSSA adapter. 
state_dictN)r  rX   r   .r"   r   r3  r=  )rP   r   r?  rq  r   float32float16bfloat16
startswithr   r   r   rw   ru   r  r   split)rF   output_state_dictrX   r5   r   parammutated_init_state_dicttensors_loras           r6   subtract_mutated_initzLoraModel.subtract_mutated_init  sq     ::668 
	KD%

  EMM1JJ$$5JJ$$6))'2v
	 #<zz,5%#

 %**, 	D 4%*YY&t,.EchhtzzZ]_`_aObFc.dekl&T" T!%*YY&t,/FsxxPTPZPZ[^P_`a`bPcGd/e.eflm&T"	 r8   )rG   r%   returnNone)rA   r%   rP   	nn.Module)rR   zOptional[str]r  r  )rP   r  r  r  )r   r<   )F)r   bool)T)r   r  r  r  )r  r  )rX   zstr | list[str]r  r  )TFFN)r  r  r  r  r1   Optional[list[str]])r(  	list[str]r)  r<   r*  
int | Noner  ztuple[str, int, str])r  NNTNNtotal)r(  r  rE  zlist[float]rX   r<   r)  r<   r*  r  rF  r  rG  r  rH  z
str | NonerI  zfloat | NonerJ  zLiteral['total', 'frequency']r  r  )NTN)rX   r<   r  r  )FFN)r  r  r  r  r1   r  r  torch.nn.Module)r  r  rJ   )r  zdict[str, torch.Tensor]rX   r<   )"rE   
__module____qualname____doc__r=   __annotations__rH   staticmethodrM   rQ   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r1  rQ  rC  rD  r{  r  r  r  __classcell__)rD   s   @r6   r:   r:   C   s   FP FC < <C, )-YJ &YJ 
YJv-4Z* @ @D-0
/0+. 9 9v	_   ! -1  	
 +>M>!M>58M>DNM>	M>h !&# $"&!% $>EFF F 	F
 F F F  F F F <F 
Ff BH*XV0 im

59
Re
	
@>$ $r8   r:   )G
__future__r   ro  rz   r   
contextlibr   dataclassesr   r   enumr   	functoolsr   r	   typingr
   r   r   r   r   peft.import_utilsr   r   peft.tuners.tuners_utilsr   r   r   r   r   
peft.utilsr   r   r   r   r   r   r   peft.utils.merge_utilsr   r   r   r   r    peft.utils.otherr!   rk   r#   rl   r$   rG   r%   eetqr&   rj   r'   hqqr(   incr)   r   r*   r+   r,   r-   torchaor.   tp_layerr/   r7   r:   r2   r8   r6   <module>r     s    #    % '  % $    E    b a ,        D D % 'V	 Vr8   