
    biH                        d dl mZ d dlZd dlmZ d dlmZ d dlmZ d dl	Z	d dl
mZ d dlmZ d dlmZ d dlmZmZmZ d d	lmZmZmZ d
dlmZ d
dlmZmZ  G d de      Zy)    )annotationsN)asdict)Enum)Optional)tqdm)Conv1D)	BaseTunerBaseTunerLayercheck_target_module_exists)4TRANSFORMERS_MODELS_TO_VBLORA_TARGET_MODULES_MAPPINGModulesToSaveWrapper_get_submodules   )VBLoRAConfig)LinearVBLoRALayerc                      e Zd ZU dZdZded<   ddZddZddZe	d        Z
d	 Ze	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	 	 	 	 d%	 	 	 	 	 d&dZd'dZ	 d(	 	 	 	 	 	 	 d)dZd Zd*d+dZd#dZ xZS ),VBLoRAModela  
    Creates VBLoRA model from a pretrained transformers model.

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

    Args:
        model ([`~transformers.PreTrainedModel`]): The model to be adapted.
        config ([`VBLoRAConfig`]): The configuration of the VBLoRA 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 VBLoRA model.

    Example:

        ```py
        >>> from transformers import AutoModelForCausalLM
        >>> from peft import VBLoRAConfig, get_peft_model

        >>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
        >>> config = VBLoRAConfig(
        ...     task_type="SEQ_CLS",
        ...     r=4,
        ...     target_modules=["fc1", "fc2", "k_proj", "out_proj", "q_proj", "v_proj"],
        ...     num_vectors=60,
        ...     vector_length=256,
        ...     save_only_topk_weights=True,
        ... )
        >>> model = get_peft_model(base_model, config)
        ```

    **Attributes**:
        - **model** ([`~transformers.PreTrainedModel`]) -- The model to be adapted.
        - **peft_config** ([`VBLoRAConfig`]): The configuration of the VBLoRAConfig model.
    vblora_strprefixc                    t        j                  |j                  |j                        }t         j                  j
                  j                  ||j                   |j                         || j                  |<   y N)	torchzerosnum_vectorsvector_lengthnninituniform_init_vector_bank_boundvblora_vector_bank)selfconfigadapter_namer"   s       S/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/peft/tuners/vblora/model.py_init_vblora_vector_bankz$VBLoRAModel._init_vblora_vector_bankJ   sZ    "[[););V=Q=QR1F4Q4Q3QSYSpSpq0B-    c                8    t        j                  i       | _        y r   )r   ParameterDictr"   )r#   modelr$   r%   s       r&   _pre_injection_hookzVBLoRAModel._pre_injection_hookO   s    "$"2"22"6r(   c                    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__)r#   r$   s     r&   _check_new_adapter_configz%VBLoRAModel._check_new_adapter_configR   sR       !A%FKK6,A>>**+ ,7 7  -B%r(   c                    t        | |      S r   )r   )vblora_configkeys     r&   _check_target_module_existsz'VBLoRAModel._check_target_module_existsb   s    )-==r(   c           
         |t        d      t        |d      xr |j                  d u}|j                  |d}| j	                  ||       t        |t              r`|j                  || j                  |j                  |j                  |j                  |j                  |j                  |j                         y  | j                  d|| j                  ||d|}	|| j                   vr|	j#                  d       | j%                  |||	|       y )NzCurrent Key shouldn't be `None`r1   )fan_in_fan_outr1   )r%   r"   rtopkr   r   vblora_dropoutinit_logits_std)r7   r"   r%   targetF )r2   hasattrr1   r;   r'   
isinstancer   update_layerr"   r<   r=   r   r   r>   r?   _create_new_moduleactive_adapterrequires_grad__replace_module)
r#   r7   r%   r@   target_nameparentcurrent_keyr1   kwargs
new_modules
             r&   _create_and_replacezVBLoRAModel._create_and_replacef   s    >??vv&B6;;d+B+::
 	%%m\B ff%)#'#:#://"'')55+99,;; - = =   	 100 +#'#:#:)	
 J 4#6#66))%0  j&Ir(   c                   t        | ||       t        |d      r|j                  }t        |d      s.|j                  |_        t        |d      r|j                  |_        t        |dd       ^t        |d      r|j                  |j                  _        n|j                  |_        |j                  |j                  j                         t        j                  d      |j                         D ]R  \  }}d|v st        fd|j                         D              r.|j                  |j                  j                         T y )N
base_layerr1   statemetar   c              3  <   K   | ]  }|j                   k(    y wr   )device).0prR   s     r&   	<genexpr>z.VBLoRAModel._replace_module.<locals>.<genexpr>   s     I188t+Is   )setattrrB   rP   weightr1   getattrrQ   torT   r   named_modulesany
parameters)rJ   
child_namerM   childnamemodulerR   s         @r&   rH   zVBLoRAModel._replace_module   s    
J/
 5,'$$Ez<0 %Juf%"'**
5'4(4z<0.3kk
%%+#(;;
 MM%,,--.||F#&446 	3LD&D IV5F5F5HIIIIell112	3r(   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.   allr1   Tvblora_onlyzRequested bias: z, is not implemented.)named_parametersr   requires_gradactive_adaptersr0   r1   modulesrC   r   rB   NotImplementedError)r#   r+   nrV   rF   r1   ms          r&    _mark_only_adapters_as_trainablez,VBLoRAModel._mark_only_adapters_as_trainable   s    **, 	(DAq{{!#"'	( #22 	ZN##N388Dv~u}!224 /DAq{*./ & 4A!![1ga6HQVVM_/3,4 *,<TFBW*XYY	Zr(   c                   t        |t              r|j                         }n|}t        |t        j                  j
                        r'|d   rmt        j                  d       dx|d<   | _        nKt        |t              r,d|d<   |d   s1t        j                  d       dx|d<   | _        nt        d| d      t        d
|||| j                  | j                  | j                  | j                  | j                  | j                   d		|}|S )Nr;   zjfan_in_fan_out is set to True but the target module is `torch.nn.Linear`. Setting fan_in_fan_out to False.FTis_target_conv_1d_layerzafan_in_fan_out is set to False but the target module is `Conv1D`. Setting fan_in_fan_out to True.zTarget module z is not supported. Currently, only the following modules are supported: `torch.nn.Linear`, `transformers.pytorch_utils.Conv1D`.)	rP   r"   r%   r<   r   r   r=   r>   r?   rA   )rC   r
   get_base_layerr   r   r   warningswarnr;   r   r2   r<   r   r   r=   r>   r?   )r7   r"   r%   r@   rL   target_base_layerrM   s          r&   rE   zVBLoRAModel._create_new_module   s*   fn- & 5 5 7 &'9&'7 KPO'(=+G)6204F,-*+w KON'(=+G  )J J   
1%oo%11'55##(77)99
 

 r(   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.r+   )super__getattr__AttributeErrorrZ   r+   )r#   ra   r3   s     r&   rv   zVBLoRAModel.__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)r0   itemsr   rC   r   value)r#   	inferenceconfig_dictr8   r{   kvr$   s           r&   get_peft_config_as_dictz#VBLoRAModel.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 r   )r+   ri   rC   r
   r   enable_adapters)r#   enabledrb   s      r&   _set_adapter_layerszVBLoRAModel._set_adapter_layers   s<    jj((* 	0F&>3G"HI&&w/	0r(   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   r#   s    r&   enable_adapter_layersz!VBLoRAModel.enable_adapter_layers  s    
 	   .r(   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)rh   r0   r1   rq   rr   r   )r#   rF   valmsgs       r&   disable_adapter_layersz"VBLoRAModel.disable_adapter_layers
  sr    
 #22 	#N"">277Cf}TUXTY ZG G  c"	# 	   /r(   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)
r+   ri   rC   r   mergedrq   rr   unmergeset_adapterrF   )r#   r%   rb   s      r&   r   zVBLoRAModel.set_adapter  s`     jj((* 	1F&+.==MM"noNN$""<0	1 +r(   c                ~    | j                   0|d   t        vrt        d      t        t        |d            | _         | S )N
model_typez0Please specify `target_modules` in `peft_config`)target_modulesr   r2   set)r0   model_configs     r&   _prepare_adapter_configz#VBLoRAModel._prepare_adapter_config0  sK    %%-L)1ee !STT),D\R^E_`*K& r(   c                "   | j                   j                         D cg c]  \  }}| j                  |vs| }}}d|rdndz   dz   }t        || |      D ]  }	 t	        | j                   |      \  }	}
}t        |
d      r8|r|
j                  ||       | j                  |	||
j                         |
       bt        |
t              sst        |	||
j                  |
j                             | j                   S c c}}w # t
        $ r Y w xY w)Nz
Unloading zand merging  r+   )disabledescrP   )
safe_mergeadapter_names)r+   r\   r   r   r   rw   rB   mergerH   rp   rC   r   rX   modules_to_saverF   )r#   r   progressbarr   r   r8   _key_listr   rJ   r@   rI   s               r&   _unload_and_optionally_mergez(VBLoRAModel._unload_and_optionally_merge:  s
    '+jj&>&>&@[FCDKKWZDZC[[~B?'Ik/E 	\C.=djj#.N+ v|,LLJmLT$$V[&:O:O:QSYZF$89V-C-CFDYDY-Z[	\ zz# \
 " s   C<C<D	DD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.
        zAdapter z does not existN)new_active_adapters)listr0   keysr2   r+   r\   r   r   rC   r   delete_adapterrF   _delete_auxiliary_adapter)r#   r%   r8   r   r   new_adapterr@   s          r&   r   zVBLoRAModel.delete_adapterT  s     tD$4$4$9$9$;<<x~_EFF\*&*jj&>&>&@[FCDKKWZDZC[[ 	;C*4::s;LAvq&+.%%l3&"("7"7":K	; */R&&|&U \s   C36C3c                *    | j                  |||      S )aJ  
        This method merges the VBLoRA 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   r   r   )r#   r   r   r   s       r&   merge_and_unloadzVBLoRAModel.merge_and_unloadk  s#    : 00#
- 1 
 	
r(   c                &    | j                  d      S )z
        Gets back the base model by removing all the VBLoRA modules without merging. This gives back the original base
        model.
        F)r   r   r   s    r&   unloadzVBLoRAModel.unload  s    
 00u0==r(   c                   d}d}d}| j                         D ]U  \  }}d|v r||j                         z  }d|v r||j                         z  }6|j                  sC||j                         z  }W | j                  |   j                  r| j                  |   j
                  }d}|dk  rd}n|dk  rd}n
|d	k  rd}nd
}|| j                  |   j
                  z  | j                  |   j                  dz
  z  }	|| j                  |   j
                  z  | j                  |   j                  z  |z  }
t        ||	z   |
z         }||fS ||z   }||fS )z`
        Returns the number of savable VB-LoRA parameters and other savable parameters.
        r   vblora_logitsr"   r      g      ?i   g      ?l           )rf   numelrg   r0   save_only_topk_weightsr   r=   int)r#   adapterlogits_paramsvector_bank_paramsother_paramsra   paramr   factortopk_weight_paramstopk_indices_paramsvblora_paramss               r&   get_nb_savable_parametersz%VBLoRAModel.get_nb_savable_parameters  s    002 	.KD%$&.%-"ekkm3"$$-	. G$;;**73??KFT!u$u$ 0 0 9 E EEIYIYZaIbIgIgjkIkl   0 0 9 E EEHXHXY`HaHfHffioo     25G GJ] ]^M l** />Ml**r(   c                V    | j                         \  }}t        d|dd||z   d       y)z_
        Prints the number of savable VB-LoRA parameters and total savable parameters.
        z1VB-LoRA params to-be-saved (float32-equivalent): z,dz || total params to-be-saved: N)r   print)r#   r   r   s      r&   print_savable_parametersz$VBLoRAModel.print_savable_parameters  sB     '+&D&D&F#|?b?Q R,-:\-I2+NP	
r(   )r$   r   r%   r   returnNone)r+   	nn.Moduler$   r   r%   r   r   r   )r$   r   r   r   )r+   r   r   r   )ra   r   )F)r|   bool)T)r   r   r   r   )r   r   )r%   zstr | list[str]r   r   )TFFN)r   r   r   r   r   Optional[list[str]])r%   r   r   r   )FFN)r   r   r   r   r   r   r   ztorch.nn.Module)default)r   ztuple[int, int])r4   
__module____qualname____doc__r   __annotations__r'   r,   r5   staticmethodr9   rN   rH   rm   rE   rv   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__)r3   s   @r&   r   r   !   s   $L FCC
7  > >*JX 3 38Z( & &P-0
/0+.   ! -1  	
 +4V0 im

59
Re
	
B>"+H
r(   r   )
__future__r   rq   dataclassesr   enumr   typingr   r   torch.nnr   r   transformers.pytorch_utilsr   peft.tuners.tuners_utilsr	   r
   r   
peft.utilsr   r   r   r$   r   layerr   r   r   rA   r(   r&   <module>r      sB    #        - Z Z r r   &^
) ^
r(   