o
    8wiT.                     @  s   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 deZdS )    )annotationsN)Optional)tqdm)
PeftConfig)	BaseTunerBaseTunerLayercheck_target_module_existsonload_layer)AuxiliaryTrainingWrapper_get_input_embeddings_name_get_submodules   )TrainableTokensLayerc                      s   e Zd ZU dZded< dCdD fddZdE fd
dZdd Z	dFdG fddZdd Z	dHdd Z
dId"d#ZdJd%d&Zed'd( Zd)d* ZdKd+d,ZdLdMd.d/ZdNd0d1ZdNd2d3ZdOd5d6ZdPd8d9Z	:dQdRd?d@Z				:dSdTdAdBZ  ZS )UTrainableTokensModeltrainable_tokens_strprefixFlow_cpu_mem_usageboolc                   s   t  j||||d d S )N)r   )super__init__)selfmodelconfigadapter_namer   	__class__ _/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/peft/tuners/trainable_tokens/model.pyr   "   s   zTrainableTokensModel.__init__namec                   s.   zt  |W S  ty   t| j| Y S w )z1Forward missing attributes to the wrapped module.)r   __getattr__AttributeErrorgetattrr   )r   r   r   r   r   r    %   s
   z TrainableTokensModel.__getattr__c                 C  s   |j d u rt| jd|_ |S )Nembed_tokens)target_modulesr   r   )r   peft_configmodel_configr   r   r   _prepare_adapter_config,   s   
z,TrainableTokensModel._prepare_adapter_configTr   	nn.Moduler   autocast_adapter_dtypereturnNonec              
     s   t  j||||d | | }|ddre| jjd urgt| j tridd | jjD }| jj	ddD ]7\ } fdd|D }|rdt
| \}	}
}| j|  }| j |d< | |||
||	|d	  q3d S d S d S d S )
N)r   r   r)   r   tie_word_embeddingsFc                 S  s$   g | ]}d  |d dd qS ).N)joinsplit).0nr   r   r   
<listcomp>K   s   $ z7TrainableTokensModel.inject_adapter.<locals>.<listcomp>)remove_duplicatec                   s   g | ]	}  |r|qS r   )endswith)r1   
target_keyr   r   r   r3   N   s    tied_adapterr   )r   inject_adapterget_model_configgetr   _tied_weights_keys
isinstanceget_input_embeddingsr   named_modulesr   r%   to_dict_create_and_replace_dict)r   r   r   r)   r   r&   module_keysmodulematched_keysparenttargettarget_namer%   r   r7   r   r9   3   s>   

	z#TrainableTokensModel.inject_adapterc                 O  s   g S Nr   )r   argskwargsr   r   r   _get_tied_target_modules^   s   z-TrainableTokensModel._get_tied_target_modulesr%   dictrF   rG   rE   current_keyc           	      C  sN   |}t |tr|j|fi | dS | j|||fi |}| |||| dS )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)r=   r   update_layer_create_new_module_replace_module)	r   r%   r   rF   rG   rE   rM   rJ   
new_moduler   r   r   rA   e   s
   
z-TrainableTokensModel._create_and_replace_dictr   c                 C  s    |  }| |||||| dS )zc
        A private method to create and replace the target module with the adapter module.
        N)r@   rA   )r   r%   r   rF   rG   rE   rM   rJ   r   r   r   _create_and_replacez   s   z(TrainableTokensModel._create_and_replacekeyc                 C  s
   t ||S rH   )r   )r   r%   rS   r   r   r   _check_target_module_exists   s   
z0TrainableTokensModel._check_target_module_existsc                 K  s8   t ||fi |}|j||d |d |dd d |S )Ninit_weightstoken_indicesr8   )rU   rV   r8   )r   rN   r;   )r%   r   rF   rJ   rQ   r   r   r   rO      s   
z'TrainableTokensModel._create_new_modulec                   s   t ||| t|dr|j}t|ds |j|_t|dr |j|_t|dd d ur>t|dr3|j|j_n|j|_||jj t	d |
 D ]\}}| j|v rdt fdd| D sd||jj qGd S )N
base_layerbiasstatemetac                 3  s    | ]}|j  kV  qd S rH   )device)r1   prZ   r   r   	<genexpr>   s    z7TrainableTokensModel._replace_module.<locals>.<genexpr>)setattrhasattrrW   weightrX   r"   rY   tor[   torchr?   r   any
parameters)r   rE   
child_namerQ   childr   rC   r   r]   r   rP      s&   





z$TrainableTokensModel._replace_modulec                 C  s&   |  D ]\}}| j|vrd|_qd S )NF)named_parametersr   requires_grad)r   r   r2   r\   r   r   r    _mark_only_adapters_as_trainable   s
   
z5TrainableTokensModel._mark_only_adapters_as_trainableenabledc                 C  s,   | j  D ]}t|ttfr|| qd S rH   )r   modulesr=   r   r
   enable_adapters)r   rk   rC   r   r   r   _set_adapter_layers   s
   
z(TrainableTokensModel._set_adapter_layersc                 C     | j dd dS )zyEnable all adapters.

        Call this if you have previously disabled all adapters and want to re-enable them.
        Trk   Nrn   r   r   r   r   enable_adapter_layers      z*TrainableTokensModel.enable_adapter_layersc                 C  ro   )zDisable all adapters.

        When disabling all adapters, the model output corresponds to the output of the base model.
        Frp   Nrq   rr   r   r   r   disable_adapter_layers   rt   z+TrainableTokensModel.disable_adapter_layersstr | list[str]c                 C  sF   | j  D ]}t|tr|jrtd |  || q|| _	dS )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   rl   r=   r   mergedwarningswarnunmergeset_adapteractive_adapter)r   r   rC   r   r   r   r{      s   



z TrainableTokensModel.set_adaptertorch.nn.Modulec                 C  s   | j ddS )zh
        Gets back the base model by removing all the trainable tokens modules without merging.
        F)merge_unload_and_optionally_mergerr   r   r   r   unload   s   zTrainableTokensModel.unloadNprogressbar
safe_mergeadapter_namesOptional[list[str]]c                 C  s   | j |||d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`.
        )r   r   r   r   )r   r   r   r   r   r   r   merge_and_unload   s   z%TrainableTokensModel.merge_and_unloadc              	     s    fdd j  D }d|rdnd d }t|| |dD ]Y}zt j |\}}	}
W n	 ty4   Y qw t|	6 t|	drP|	j|||d	} ||
||	 nt|	d
rh|r^|	j	||d  ||
|	
 |	 W d    n1 srw   Y  q j S )Nc                   s   g | ]\}} j |vr|qS r   )r   )r1   rS   _rr   r   r   r3     s    zETrainableTokensModel._unload_and_optionally_merge.<locals>.<listcomp>z
Unloading zand merging  r   )disabledesc"unload_and_optionally_merge_module)r~   r   r   rW   )r   r   )r   r?   r   r   r!   r	   r`   r   rP   r~   get_base_layer)r   r~   r   r   r   key_listr   rS   rE   rF   rG   unloaded_moduler   rr   r   r      s,   


z1TrainableTokensModel._unload_and_optionally_merge)F)r   r   )r   r   )TF)
r   r(   r   r   r)   r   r   r   r*   r+   )r%   rL   r   r   rF   r(   rG   r   rE   r(   rM   r   r*   r+   )r%   r   r   r   rF   r(   rG   r   rE   r(   rM   r   r*   r+   )r%   r   rS   r   r*   r   )r   r(   r*   r+   )T)rk   r   r*   r+   )r*   r+   )r   rv   r*   r+   )r*   r}   )FFN)r   r   r   r   r   r   r*   r}   )TFFN)r   r   r   r   r   r   )__name__
__module____qualname__r   __annotations__r   r    r'   r9   rK   rA   rR   rT   staticmethodrO   rP   rj   rn   rs   ru   r{   r   r   r   __classcell__r   r   r   r   r      s6   
 +








r   )
__future__r   rx   typingr   rc   torch.nnnnr   peft.configr   peft.tuners.tuners_utilsr   r   r   r	   
peft.utilsr
   r   r   layerr   r   r   r   r   r   <module>   s   