
    biaR                        d dl mZ d dlZd dlZd dlmZ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mZ d d	lmZ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   G d de      Z!y)    )annotationsN)asdictreplace)Enum)Optional)nn)Conv1D)is_bnb_4bit_availableis_bnb_available)	BaseTunerBaseTunerLayercheck_target_module_exists)6TRANSFORMERS_MODELS_TO_IA3_FEEDFORWARD_MODULES_MAPPING1TRANSFORMERS_MODELS_TO_IA3_TARGET_MODULES_MAPPINGModulesToSaveWrapper_freeze_adapter_get_submodules   )Conv2dConv3dIA3LayerLinearc                      e Zd ZU dZdZded<   ed        Zed        ZddZ	d Z
edd	       Zd
 Zd fdZdddZddZddZddZddZed        Z	 d 	 	 	 	 	 d!dZd"d#dZd$dZd%dZd&dZ	 	 	 	 	 	 	 	 d'dZ xZS )(IA3ModelaP  
    Creates a Infused Adapter by Inhibiting and Amplifying Inner Activations ((IA)^3) model from a pretrained
    transformers model. The method is described in detail in https://huggingface.co/papers/2205.05638

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

    Example:

        ```py
        >>> from transformers import AutoModelForSeq2SeqLM, ia3Config
        >>> from peft import IA3Model, IA3Config

        >>> config = IA3Config(
        ...     peft_type="IA3",
        ...     task_type="SEQ_2_SEQ_LM",
        ...     target_modules=["k", "v", "w0"],
        ...     feedforward_modules=["w0"],
        ... )

        >>> model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
        >>> ia3_model = IA3Model(config, model)
        ```

    **Attributes**:
        - **model** ([`~transformers.PreTrainedModel`]) -- The model to be adapted.
        - **peft_config** ([`ia3Config`]): The configuration of the (IA)^3 model.
    ia3_strprefixc                P   t               r
dd l}ddlm} t	               rddlm} |j                  dd      }|j                  dd      }|j                  dd      }	t        |t              r|j                         }
n|}
|rt        |
j                  j                        re|j                         }|j                  |
j                  j                  |
j                  j                  |
j                   d	        ||fd|	i|}|S |rt        |
j                  j
                        re|j                         }|j                  |
j"                  |
j$                  j&                  |
j$                  j(                  d
        ||fd|	i|}|S t        |t*        j                  j,                        rt-        ||fd|	i|}|S t        |t*        j                  j.                        rt/        ||fd|	i|}|S t        |
t*        j                  j0                        r7|d   r!t3        j4                  d       dx|d<   | _        t1        ||fd|	i|}|S t        |
t8              r8|d   s!t3        j4                  d       dx|d<   | _        t1        ||f|	dd|}|S t;        d| d      )Nr   r   )Linear8bitLt)
Linear4bitloaded_in_8bitFloaded_in_4bitis_feedforward)has_fp16_weights	thresholdindex)compute_dtypecompress_statistics
quant_typefan_in_fan_outzjfan_in_fan_out is set to True but the target module is `torch.nn.Linear`. Setting fan_in_fan_out to False.zafan_in_fan_out is set to False but the target module is `Conv1D`. Setting fan_in_fan_out to True.T)r#   is_target_conv_1d_layerzTarget module zd is not supported. Currently, only `torch.nn.Linear`, `torch.nn.Conv2d`, and `Conv1D` are supported.)r   bitsandbytesbnbr   r
   r    pop
isinstancer   get_base_layerr   copyupdatestater$   r%   r&   r'   weightr(   r)   torchr   r   r   warningswarnr*   r	   
ValueError)
ia3_configadapter_nametargetkwargsr-   r   r    r!   r"   r#   target_base_layereightbit_kwargs
new_modulefourbit_kwargss                 P/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/peft/tuners/ia3/model.py_create_new_modulezIA3Model._create_new_moduleN   s    &) "'$4e<$4e<$4e<fn- & 5 5 7 &j):CFF<O<OP$kkmO""(9(?(?(P(P!2!8!8!B!B.44 &flm>m]lmJJ I 
+<cff>O>O P#[[]N!!%6%D%D+<+C+C+W+W"3":":"E"E $FLjj[ijJ6 5 0^^^W]^J2 1 0^^^W]^J. - )588??;&'7 HML'(:+D^^^W]^J  )62*+w HLK'(:+D5C]aekJ 	   )d e     c                    t        | |      S N)r   )r9   keys     rA   _check_target_module_existsz$IA3Model._check_target_module_exists   s    )*c::rC   c                `    |j                         D ]  \  }}| j                  |vsd|_         y )NF)named_parametersr   requires_grad)selfmodelnps       rA    _mark_only_adapters_as_trainablez)IA3Model._mark_only_adapters_as_trainable   s1    **, 	(DAq{{!#"'	(rC   c           	        | j                  ||      }|j                  |j                  |t        | j                  dd      t        | j                  dd      d}t        |t              r|j                  ||j                         y  | j                  |||fi |}	|| j                  vr|	j                  d       | j                  |||	|       y )Nis_loaded_in_8bitFis_loaded_in_4bit)r*   init_ia3_weightsr#   r!   r"   ) _check_target_module_feedforwardr*   rS   getattrrL   r/   r   update_layerrB   active_adaptersrequires_grad__replace_module)
rK   r9   r:   r;   target_nameparentcurrent_keyr#   r<   r?   s
             rA   _create_and_replacezIA3Model._create_and_replace   s     >>z;W )77 * ; ;,%djj2EuM%djj2EuM
 fh'++
 100\6\U[\J4#7#77))%0  j&IrC   c                    t        | j                  t              r+t        t	        j
                  | j                              }|S t        fd| j                  D              }|S )z
        A helper private method that checks if the target module `key` matches with a feedforward module specified in
        `ia3_config`
        c              3  @   K   | ]  }j                  |        y wrE   )endswith).0
target_keyrF   s     rA   	<genexpr>z<IA3Model._check_target_module_feedforward.<locals>.<genexpr>   s      kjj!9 ks   )r/   feedforward_modulesr   boolre	fullmatchany)r9   rF   r#   s    ` rA   rT   z)IA3Model._check_target_module_feedforward   sV     j44c:!",,z/M/Ms"STN  ! kJLjLj kkNrC   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 ]\  \  }}| j                  |v st        fd|j                         D              r8|j                  |j                  j                         ^ y )N
base_layerbiasr3   metac              3  <   K   | ]  }|j                   k(    y wrE   )device)ra   rN   rl   s     rA   rc   z+IA3Model._replace_module.<locals>.<genexpr>   s     I188t+Is   )setattrhasattrrj   r4   rk   rU   r3   torn   r5   named_modulesr   rh   
parameters)rK   r[   
child_namer?   childnamemodulerl   s          @rA   rY   zIA3Model._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	3rC   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.rL   )super__getattr__AttributeErrorrU   rL   )rK   rv   	__class__s     rA   rz   zIA3Model.__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)peft_configitemsr   r/   r   value)rK   	inferenceconfig_dictrF   r   kvconfigs           rA   get_peft_config_as_dictz IA3Model.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 rE   )rL   modulesr/   r   r   enable_adapters)rK   enabledrw   s      rA   _set_adapter_layerszIA3Model._set_adapter_layers   s<    jj((* 	0F&8-A"BC&&w/	0rC   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   rK   s    rA   enable_adapter_layerszIA3Model.enable_adapter_layers   s    
 	   .rC   c                (    | j                  d       y)zDisable all adapters.

        When disabling all adapters, the model output corresponds to the output of the base model.
        Fr   Nr   r   s    rA   disable_adapter_layerszIA3Model.disable_adapter_layers   s    
 	   /rC   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)
rL   r   r/   r   mergedr6   r7   unmergeset_adapteractive_adapter)rK   r:   rw   s      rA   r   zIA3Model.set_adapter  s`     jj((* 	1F&(+==MM"noNN$""<0	1 +rC   c                    | j                   0|d   t        vrt        d      t        t        |d            | _         | j                  0|d   t
        vrt        d      t        t
        |d            | _        | S )N
model_typez0Please specify `target_modules` in `peft_config`z5Please specify `feedforward_modules` in `peft_config`)target_modulesr   r8   setrd   r   )r   model_configs     rA   _prepare_adapter_configz IA3Model._prepare_adapter_config  s    %%-L)1bb !STT),A,|B\]*K& **2L)1gg !XYY.1F|T`Gab/K+ rC   c                    t        | j                  dd      rt        d      t        | j                  dd      rt        d      | j                  |       | j                  j	                         D cg c]  \  }}| j
                  |vs| }}}|D ]  }	 t        | j                  |      \  }}}	t        |d      r8|r|j                  ||       | j                  ||	|j                         |       bt        |t              ss|j                  |j                     }
t        |
d      r%|r|
j                  ||       |
j                         }
t!        ||	|
        | j                  S c c}}w # t        $ r Y w xY w)a  
        This method merges the (IA)^3 layers into the base model. This is needed if someone wants to use the base model
        as a standalone model.

        Args:
            safe_merge (`bool`, `optional`, defaults to `False`):
                If True, the merge operation will be performed in a copy of the original weights and check for NaNs
                before merging the weights. This is useful if you want to check if the merge operation will produce
                NaNs. Defaults to `False`.
            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`.
        rQ   Fz>Cannot merge ia3 layers when the model is loaded in 8-bit moderR   z>Cannot merge ia3 layers when the model is loaded in 4-bit moderj   
safe_mergeadapter_names)rU   rL   r8   _unloading_checksrr   r   r   r{   rp   mergerY   r0   r/   r   modules_to_saver   ro   )rK   r   r   r   rF   _key_listr[   r;   rZ   r?   s              rA   _unload_and_optionally_mergez%IA3Model._unload_and_optionally_merge.  se     4::2E:]^^4::2E:]^^}-&*jj&>&>&@[FCDKKWZDZC[[ 	9C.=djj#.N+ v|,LLJmLT$$V[&:O:O:QSYZF$89#33F4I4IJ
:|4"((Jm(\!+!:!:!<JZ8%	9( zz+ \ " s   3E+
E+E11	E=<E=c                (    | j                  ||      S )u  
        This method merges the IA³ layers into the base model. This is needed if someone wants to use the base model as
        a standalone model.

        Args:
            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   )rK   r   r   s      rA   merge_and_unloadzIA3Model.merge_and_unload\  s    2 00JVc0ddrC   c                &    | j                  d      S )u   
        Gets back the base model by removing all the IA³ modules without merging. This gives back the original base
        model.
        F)r   r   r   s    rA   unloadzIA3Model.unloadw  s    
 00u0==rC   c                   || 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.
        Adapter  does not existN)new_active_adapters)r   r8   rL   rr   r   r   r/   r   delete_adapterrW   r   _delete_auxiliary_adapter)rK   r:   rF   r   r   new_adapterr;   s          rA   r   zIA3Model.delete_adapter~  s     t///x~_EFF\*&*jj&>&>&@[FCDKKWZDZC[[ 	<C*4::s;LAvq&(+%%l3&"("8"8";K	< */R&&|&U \s   CCc                    D ]  }| j                   vst        d| d        j                         D cg c]  }t        |t              s| }}t        fd|D              rt        d      D ch c]$  }t         j                   |   j                        & }}D ch c]$  }t         j                   |   j                        & }}t        |      dkD  st        |      dkD  rt        d      t        |v rdj                   fdD              }nt        j                   fd	D         }t        |v rdj                   fd
D              }||fS t        j                   fdD         }||fS 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.
        r   r   c              3  N   K   | ]  t        fd D              dkD    yw)c              3  :   K   | ]  }|j                   v   y wrE   )r   )ra   adapterwrappers     rA   rc   zAIA3Model._check_add_weighted_adapter.<locals>.<genexpr>.<genexpr>  s     Kw7222Ks   r   N)sum)ra   r   adapterss    @rA   rc   z7IA3Model._check_add_weighted_adapter.<locals>.<genexpr>  s&      
T[CK(KKaO
s   !%zLCannot add weighted adapters targeting the same module with modules_to_save.r   zQAll adapter configs should have the same type for target and feedforward modules.|c              3  X   K   | ]!  }d j                   |   j                   d # yw()Nr   r   ra   r   rK   s     rA   rc   z7IA3Model._check_add_weighted_adapter.<locals>.<genexpr>  s.     )r^eAd.>.>w.G.V.V-WWX*Y)r   '*c              3  P   K   | ]  }j                   |   j                    y wrE   r   r   s     rA   rc   z7IA3Model._check_add_weighted_adapter.<locals>.<genexpr>  s#     ,nZaT-=-=g-F-U-U,n   #&c              3  X   K   | ]!  }d j                   |   j                   d # ywr   r   rd   r   s     rA   rc   z7IA3Model._check_add_weighted_adapter.<locals>.<genexpr>  s1      /IP!D$$W-AAB!D/r   c              3  P   K   | ]  }j                   |   j                    y wrE   r   r   s     rA   rc   z7IA3Model._check_add_weighted_adapter.<locals>.<genexpr>  s"     XG$""7+??Xr   )r   r8   r   r/   r   rh   typer   rd   lenr   joinr   union)	rK   r   r   rw   modules_to_save_wrapperstarget_module_typesfeedforward_module_typesnew_target_modulesnew_feedforward_moduless	   ``       rA   _check_add_weighted_adapterz$IA3Model._check_add_weighted_adapter  s      	FGd... 8G9O!DEE	F
 :>#tv:V\^rKsF#t #t 
_w
 
 kll ^ffRYtD$4$4W$=$L$LMffgo#p\cD)9)9')B)V)V$W#p #p"#a'3/G+H1+Lpqq %%!$)riq)r!r!$,nem,n!o**&)hh /T\/ '# "#:::	 '*iiXxX'# "#:::7 $u g#ps   E<E<8)F')Fc                @   |t        | j                  j                               v ry| j                  |      \  }}t	        | j                  |d      ||      | j                  |<   | j                  | j                  |       t        | j                  |       | j                  j                         D cg c]  \  }}| j                  |vs| }}}|D ]  }t        | j                  |      \  }}	}t        |	t              s.||	j                  v r|	j                  |   }
nM|
j                  j                         |
_        t!        ||      D ]F  \  }}||	j                  v r|	j                  |   }n%|
xj                  |j                  |z  z  c_        H  yc c}}w )ac  
        This method adds a new adapter by merging the given adapters with the given weights.

        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.
        N)r   r   )r   rd   )listr   keysr   r   inject_adapterrL   r   rr   r   r   r/   r   ia3_ldatazero_zip)rK   r   weightsr:   r   r   rF   r   r   r;   target_ia3_lr   r4   current_adapter_ia3_ls                 rA   add_weighted_adapterzIA3Model.add_weighted_adapter  s   " 4 0 0 5 5 7886:6V6V 7W 7
33 *1Xa[)- 7*
&
 	DJJ5 	

L1&*jj&>&>&@[FCDKKWZDZC[[ 	MC*4::s;LAvq&(+6<</#)<<#=L$0$5$5$;$;$=!'*8W'= MOGV&,,.06W0E-  %%)>)C)Cf)LL%M	M \s   6FF)rL   z	nn.ModulereturnNone)r   re   )rv   r   )F)r   re   )T)r   r   )r:   zstr | list[str]r   r   )TFN)r   re   r   re   r   Optional[list[str]])FN)r   re   r   r   r   torch.nn.Module)r   r   )r:   r   r   r   )r   	list[str]r   ztuple[str, str])r   r   r   zlist[float]r:   r   r   r   )__name__
__module____qualname____doc__r   __annotations__staticmethodrB   rG   rO   r]   rT   rY   rz   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__)r|   s   @rA   r   r   '   s   "H FCA AF ; ;(
J@ 	 	36-0
/0+.    bf,,.2,K^,\e6>V.&;P1M1M 1M 	1M
 
1MrC   r   )"
__future__r   rf   r6   dataclassesr   r   enumr   typingr   r5   r   transformers.pytorch_utilsr	   peft.import_utilsr
   r   peft.tuners.tuners_utilsr   r   r   
peft.utilsr   r   r   r   r   layerr   r   r   r   r    rC   rA   <module>r      sM    # 	  '     - E Z Z  4 3GMy GMrC   