
    bi-                        d dl mZ d dl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mZ d dlmZmZmZ dd	lmZ  G d
 de      Zy)    )annotationsN)Optional)tqdm)
PeftConfig)	BaseTunerBaseTunerLayercheck_target_module_existsonload_layer)AuxiliaryTrainingWrapper_get_input_embeddings_name_get_submodules   )TrainableTokensLayerc                  .    e Zd ZU dZded<   d fdZd Z	 	 d	 	 	 	 	 	 	 	 	 d fdZd Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ		 	 	 	 	 	 	 	 	 	 	 	 	 	 dd	Z
dd
Zed        Zd ZddZdddZddZddZddZd dZ	 d!	 	 	 	 	 	 	 d"dZ	 	 	 	 d#	 	 	 	 	 d$dZ xZS )%TrainableTokensModeltrainable_tokens_strprefixc                n    	 t         |   |      S # t        $ r t        | j                  |      cY S w xY w)z1Forward missing attributes to the wrapped module.)super__getattr__AttributeErrorgetattrmodel)selfname	__class__s     ]/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/peft/tuners/trainable_tokens/model.pyr   z TrainableTokensModel.__getattr__"   s8    	-7&t,, 	-4::t,,	-s    44c                T    |j                   t        | j                  d      |_         |S )Nembed_tokens)target_modulesr   r   )r   peft_configmodel_configs      r   _prepare_adapter_configz,TrainableTokensModel._prepare_adapter_config)   s(    %%-)CDJJP^)_K&    c           
        t        |   d	||||d| | j                  |       }|j                  dd      r1| j                  j
                  t        | j                  j                         t              r| j                  j
                  D cg c]%  }dj                  |j                  d      d d       ' }}| j                  j                  d      D ]  \  }	}
|D cg c]  }|	j                  |      s| }}|s*t        ||	      \  }}}| j                  |   j                         }| j                  j                         |d<   | j!                  ||||||d           y y y y c c}w c c}w )
N)r   adapter_nameautocast_adapter_dtypelow_cpu_mem_usagetie_word_embeddingsF.)remove_duplicatetied_adapterr    )r   inject_adapterget_model_configgetr   _tied_weights_keys
isinstanceget_input_embeddingsr   joinsplitnamed_modulesendswithr   r"   to_dict_create_and_replace_dict)r   r   r'   r(   r)   kwargsr#   nmodule_keysr   module
target_keymatched_keysparenttargettarget_namer"   r   s                    r   r0   z#TrainableTokensModel.inject_adapter0   sy    	 	
%#9/		

 	
 ,,T2 2E:

--94::::<>RS@D

@]@]^1388AGGCL"$56^K^ $

 8 8% 8 P f=HfzDMMZdLe
ff2A%2N/FFK"&"2"2<"@"H"H"JK26**2Q2Q2SK/11#$#$Q	 T : ;
 _  gs   *E,#E1:E1c                    g S Nr/   )r   argsr<   s      r   _get_tied_target_modulesz-TrainableTokensModel._get_tied_target_modulesa   s	    
 	r%   c                    |}t        |t              r |j                  |fi | y | j                  |||fi |}| j	                  ||||       y)z
        The same as `_create_and_replace` but takes a dictionary instead of a peft config so that we can add keys that
        are not present in the config, such as `tied_adapter`.
        N)r4   r   update_layer_create_new_module_replace_module)	r   r"   r'   rC   rD   rB   current_keyr<   
new_modules	            r   r;   z-TrainableTokensModel._create_and_replace_dicth   sY     f23F77000lF]V\]J  j&Ir%   c                P    |j                         }| j                  ||||||       y)zc
        A private method to create and replace the target module with the adapter module.
        N)r:   r;   )r   r"   r'   rC   rD   rB   rM   r<   s           r   _create_and_replacez(TrainableTokensModel._create_and_replace}   s,     $$&%%flFKQWYder%   c                    t        ||      S rF   )r	   )r   r"   keys      r   _check_target_module_existsz0TrainableTokensModel._check_target_module_exists   s    )+s;;r%   c           	     v    t        ||fi |}|j                  ||d   |d   |j                  dd              |S )Ninit_weightstoken_indicesr.   )rU   rV   r.   )r   rJ   r2   )r"   r'   rC   r<   rN   s        r   rK   z'TrainableTokensModel._create_new_module   sO    )&,I&I
/ 1ND9	 	  	
 r%   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biasstatemetac              3  <   K   | ]  }|j                   k(    y wrF   )device).0pr[   s     r   	<genexpr>z7TrainableTokensModel._replace_module.<locals>.<genexpr>   s     I188t+Is   )setattrhasattrrX   weightrY   r   rZ   tor]   torchr8   r   any
parameters)r   rB   
child_namerN   childr   r?   r[   s          @r   rL   z$TrainableTokensModel._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|_         y )NF)named_parametersr   requires_grad)r   r   r=   r_   s       r    _mark_only_adapters_as_trainablez5TrainableTokensModel._mark_only_adapters_as_trainable   s1    **, 	(DAq{{!#"'	(r%   c                    | j                   j                         D ]*  }t        |t        t        f      s|j                  |       , y rF   )r   modulesr4   r   r   enable_adapters)r   enabledr?   s      r   _set_adapter_layersz(TrainableTokensModel._set_adapter_layers   s<    jj((* 	0F&>3K"LM&&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rq   Nrr   r   s    r   enable_adapter_layersz*TrainableTokensModel.enable_adapter_layers   s    
 	   .r%   c                (    | j                  d       y)zDisable all adapters.

        When disabling all adapters, the model output corresponds to the output of the base model.
        Frt   Nru   rv   s    r   disable_adapter_layersz+TrainableTokensModel.disable_adapter_layers   s    
 	   /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   ro   r4   r   mergedwarningswarnunmergeset_adapteractive_adapter)r   r'   r?   s      r   r   z TrainableTokensModel.set_adapter   sa     jj((* 	1F&"67==MM"noNN$""<0	1 +r%   c                &    | j                  d      S )zh
        Gets back the base model by removing all the trainable tokens modules without merging.
        F)merge_unload_and_optionally_mergerv   s    r   unloadzTrainableTokensModel.unload   s     00u0==r%   c                *    | j                  |||      S )a  
        This method merges the trained tokens into the targeted embedding layer(s) of 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`.
        )progressbar
safe_mergeadapter_namesr   )r   r   r   r   s       r   merge_and_unloadz%TrainableTokensModel.merge_and_unload   s#    " 00#
- 1 
 	
r%   c                `   | 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  r   )disabledesc"unload_and_optionally_merge_module)r   r   r   rX   )r   r   )r   r8   r   r   r   r   r
   rb   r   rL   r   get_base_layer)r   r   r   r   r   rR   _key_listr   rB   rC   rD   unloaded_modules                r   r   z1TrainableTokensModel._unload_and_optionally_merge  sG    '+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 A9D$	D! D!$D-	)r   r   )TF)
r   	nn.Moduler'   r   r(   boolr)   r   returnNone)r"   dictr'   r   rC   r   rD   r   rB   r   rM   r   r   r   )r"   r   r'   r   rC   r   rD   r   rB   r   rM   r   r   r   )r"   r   rR   r   r   r   )r   r   r   r   )T)rq   r   r   r   )r   r   )r'   zstr | list[str]r   r   )r   torch.nn.Module)FFN)r   r   r   r   r   Optional[list[str]]r   r   )TFFN)r   r   r   r   r   r   )__name__
__module____qualname__r   __annotations__r   r$   r0   rH   r;   rP   rS   staticmethodrK   rL   rm   rr   rw   ry   r   r   r   r   __classcell__)r   s   @r   r   r      s   %FC%- (,"'// / !%	/
  / 
/bJJ J 	J
 J J J 
J*ff f 	f
 f f f 
f< 	 	38(
0
/0+.> im

59
Re
	
. ! -1  	
 +r%   r   )
__future__r   r|   typingr   re   torch.nnnnr   peft.configr   peft.tuners.tuners_utilsr   r   r	   r
   
peft.utilsr   r   r   layerr   r   r/   r%   r   <module>r      s9    #      " h h \ \ '|9 |r%   