o
    }oi6                  	   @   s  d dl Z d dlZd dlmZmZ d dlZd dlm  m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 d dlmZ zd dlmZmZ d	ZW n eefyZ   eZd
ZY nw ddgZG dd dejZG dd deeZG dd deeZG dd deeZG dd deeZdS )    N)DictOptional)nn)fused_bias_gelu)ApexGuardDefaultsinit_method_normal)
ExportableNeuralModule)	typecheck)ModelParallelConfigtensor_parallelTFPromptEncoderPromptEncoderTypec                   @   s   e Zd ZdZdZdZdZdS )r   tpmlpmlplstm	embeddingN)__name__
__module____qualname__TPMLPMLPLSTM	EMBEDDING r   r   f/home/ubuntu/.local/lib/python3.10/site-packages/nemo/collections/nlp/modules/common/prompt_encoder.pyr   +   s
    c                       s@   e Zd ZdZ fddZdd ZdejfddZd	d
 Z	  Z
S )PromptEmbeddinga|  Prompt embeddings

    Arugments:
        init_from_prompt_text: Whether to intialize prompt embeddings
                               from from certain lm embeddings
                               corresponding to a prompt string
        hidden_size: hidden size should match lm embedding size
        total_virtual_tokens: length of prompt initalized from torch init method
    c                    sh   t    || _|| _tj| j| j| _| jjj	
d d| jj_| jdttt| jdd d S )N        Findices)
persistent)super__init__hidden_sizetotal_virtual_tokenstorchr   	Embeddingprompt_embeddingsweightdatafill_requires_gradregister_buffer
LongTensorlistrange)selfr"   r#   	__class__r   r   r!   =   s   

$zPromptEmbedding.__init__c                 C   s   | j jd dS )zA
        Method sets the prompt embedding weights to 0.0
        r   N)r&   r'   r)   r/   r   r   r   clear_prompt_embedding_weightsM   s   z.PromptEmbedding.clear_prompt_embedding_weightsr'   c                 C   s   | | jjj| jj_dS )zN
        Method sets the prompt embedding weights with a new weight w
        N)type_asr&   r'   r(   )r/   r'   r   r   r   set_prompt_embedding_weightsS   s   z,PromptEmbedding.set_prompt_embedding_weightsc                 C   s   |  | jS )z$ 
        Does forward pass
        )r&   r   r2   r   r   r   forwardY   s   zPromptEmbedding.forward)r   r   r   __doc__r!   r3   r$   Tensorr5   r6   __classcell__r   r   r0   r   r   2   s    
r   c                       sB   e Zd ZdZd fdd	ZdejfddZdd	 Zd
d Z	  Z
S )InferenceTablez 
    A wrapper class that holds the output representations of the PromptEncoder Model. 
    At inference time we do not need to forward pass through the full PromptEncoder and can just use this class.
    Fc                    sn   t    || _|| _|| _tj | _t	| j| j| j| j< | j| j 
  || _| j D ]}d|_q/d S )NF)r    r!   tasknamer"   r#   r$   r   
ModuleDictprompt_tabler   r3   is_inference_ready
parametersr*   )r/   r;   r"   r#   r>   pr0   r   r   r!   f   s   
zInferenceTable.__init__prompt_representationc                 C   s   | j | j | d| _dS )zf
        Method sets the prompt embedding inside self.prompt_table[taskname] with new weights
        TN)r=   r;   r5   r>   r/   rA   r   r   r   set_prompt_tabler   s   
zInferenceTable.set_prompt_tablec                 C   s   | j | j  S )zO 
        Returns the prompt representation cached in the prompt table
        )r=   r;   r6   r2   r   r   r   get_prompt_tabley   s   zInferenceTable.get_prompt_tablec                 C   s   | j | j   d| _dS )zp
        Method "clears" the prompt embedding inside self.prompt_table[taskname] by setting it to zero.
        FN)r=   r;   r3   r>   r2   r   r   r   clear_prompt_table   s   
z!InferenceTable.clear_prompt_table)F)r   r   r   r7   r!   r$   r8   rC   rD   rE   r9   r   r   r0   r   r:   `   s    r:   c                
       sF   e Zd ZdZdededededef
 fddZd	ej	fd
dZ
  ZS )r   z
    The Tensor Parallel MLP prompt encoder network that is used to generate the virtual 
    token embeddings for p-tuning. It only have two layers.
    configr#   r"   output_sizeinit_stdc              	      s   t    || _|| _|| _d| _t|}d|_d|_	t
j| j| j|dt|ddd| _t
j| j| j|dt|ddd| _dS )ar  
        Initializes the Tensor Model parallel MLP PromptEncoderMLP module.
        Args:
            config: the model parallel config used my megatron core
            total_virtual_tokens: the total number of vitural tokens
            hidden_size: hidden dimension
            output_size:  the output dimension
            init_std: the MLP init std value 
        geluFT)rF   gather_outputinit_methodskip_bias_addbias)rF   input_is_parallelrK   rL   rM   N)r    r!   r"   rG   r#   
activationcopydeepcopysequence_parallelgradient_accumulation_fusionr   ColumnParallelLinearr   firstRowParallelLinearsecond)r/   rF   r#   r"   rG   rH   r0   r   r   r!      s4   

	zTPMLP.__init__returnc                 C   s2   |  |\}}t||}| |\}}|| }|S N)rU   r   rW   )r/   input_embedsintermediate_parallelbias_paralleloutput_embedsr   r   r   r6      s
   
zTPMLP.forward)r   r   r   r7   r   intfloatr!   r$   r8   r6   r9   r   r   r0   r   r      s    .r   c                       s   e Zd ZdZ	d!dedededededed	edef fd
dZ	de
jfddZdd Zdd Zd"ddZd#ddZdd Ze dedede
jfdd Z  ZS )$r   zm
    The prompt encoder network that is used to generate the virtual 
    token embeddings for p-tuning.
    r;   rF   encoder_typer#   	token_dimlstm_dropout
num_layersrH   c
                    s  t    || _|| _|| _|| _|| _|| _d| _|| _	|	| _
| dttt| j tj| j| j| _t|	| j| j| _| jtjkrPt| jj d	S | jtjkrtjj| j| j||ddd| _tt| jd | jd t t| jd | j| _d	S | jtj kr|dkrt!dt| j| jt g}
t|d D ]}|
"t| j| jt g q|
#t| j| j tj|
 | _d	S | jtj$krt$|| j| j| j| j	| _%d	S t!d)
a  
        Initializes the PromptEncoder module.
        Args:
            config: the model parallel config used my megatron core
            total_virtual_tokens: the total number of vitural tokens
            hidden_size: hidden dimension
            lstm_dropout: the dropout used for the LSTM
            num_layers: number of layers used in the LSTM
            init_std: used for TPMLP encoder type to initialize the mlp weights
        rI   r   T)
input_sizer"   rc   dropoutbidirectionalbatch_first      zXThe MLP prompt encoder must have at least 2 layers, and exactly 2 layers is recommended.zPPrompt encoder type not recognized. Please use one of MLP (recommended) or LSTM.N)&r    r!   ra   rd   rG   r"   r#   r`   rO   rH   r;   r+   r$   r,   r-   r.   r   r%   r   r:   inference_tabler   r   initxavier_normal_r'   r   	lstm_head
SequentialLinearReLUmlp_headr   
ValueErrorextendappendr   r   )r/   rF   r`   r#   ra   r"   rb   rc   rH   r;   layers_r0   r   r   r!      sT   
	
 zPromptEncoder.__init__rA   c                 C   s   |   }| j| dS )z{
        This method caches the output representation from the Encoder and saves it inside `self.inference_table`.
        N)detachclonerj   rC   rB   r   r   r   set_inference_table  s   z!PromptEncoder.set_inference_tablec                 C   s   | j   d S rY   )rj   rE   r2   r   r   r   clear_inference_table  s   z#PromptEncoder.clear_inference_tablec                 C   s
   | j  S rY   )rj   rD   r2   r   r   r   get_inference_table   s   
z!PromptEncoder.get_inference_tableNFc                 C   s   i }| j  |d< | j |d< | jtjkr	 |S | jtjkr/| j |d< | j |d< |S | jtj	kr>| j |d< |S | jtj
krM| j |d< |S tdNr=   
embeddingsrq   rm   r   'Prompt encoder type not recognized. Pl.)rj   
state_dictr   r`   r   r   r   rq   rm   r   r   r   rr   )r/   
desinationprefix	keep_vars_state_dictr   r   r   r   #  s(   
zPromptEncoder.state_dictTc                 C   s   | j |d  | j|d  | jtjkr	 d S | jtjkr1| j|d  | j	|d  d S | jtj
krA| j|d  d S | jtjkrQ| j|d  d S tdr|   )rj   load_state_dictr   r`   r   r   r   rq   rm   r   r   r   r   rr   )r/   r   strictr   r   r   r   8  s    
zPromptEncoder.load_state_dictc                 C   s   |  | jd}| jtjkr|}|S | jtjkr%| | |d }|S | jtj	kr2| |}|S | jtj
kr?| |}|S td)Nr   r~   )r   r   	unsqueezer`   r   r   r   rq   rm   r   r   r   rr   )r/   rZ   r]   r   r   r   _forwardH  s   	

zPromptEncoder._forward
batch_sizeuse_cached_repsrX   c                 C   sx   |r
|   d}n'| jr| jjr|   |  }n| jjs*|  }| |d |   d}|	|| j
| j}|S )zZ 
        Forward pass through the encoder with caching of prompt representations
        r   )r{   r   trainingrj   r>   rz   r   ry   squeezeexpandr#   ra   )r/   r   r   r]   r   r   r   r6   V  s   
zPromptEncoder.forward)r;   )NNF)T)r   r   r   r7   r   enumr^   r_   strr!   r$   r8   ry   rz   r{   r   r   r   r
   boolr6   r9   r   r   r0   r   r      s8    	
M

") rP   r   typingr   r   r$   torch.nn.initr   rk   <nemo.collections.nlp.modules.common.megatron.fused_bias_gelur   2nemo.collections.nlp.modules.common.megatron.utilsr   r   nemo.core.classesr   r	   nemo.core.classes.commonr
   megatron.corer   r   HAVE_MEGATRON_COREImportErrorModuleNotFoundError__all__Enumr   r   r:   r   r   r   r   r   r   <module>   s.   .'<