a
    h*Y                     @   s  d Z ddlmZ ddlmZm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mZmZmZ d
dlmZ ddlmZ eeZeeddG dd deZeeddG dd deZeeddG dd deZeG dd deZG dd deZG dd deZG dd deZG dd deZG d d! d!eZ ed"dG d#d$ d$eZ!ed%dG d&d' d'eZ"ed(dG d)d* d*e Z#g d+Z$dS ),z5PyTorch DPR model for Open Domain Question Answering.    )	dataclass)OptionalUnionN)Tensornn   )BaseModelOutputWithPooling)PreTrainedModel)ModelOutputauto_docstringlogging   )	BertModel   )	DPRConfigz6
    Class for outputs of [`DPRQuestionEncoder`].
    )Zcustom_introc                   @   sP   e Zd ZU dZejed< dZee	ejdf  ed< dZ
ee	ejdf  ed< dS )DPRContextEncoderOutputa  
    pooler_output (`torch.FloatTensor` of shape `(batch_size, embeddings_size)`):
        The DPR encoder outputs the *pooler_output* that corresponds to the context representation. Last layer
        hidden-state of the first token of the sequence (classification token) further processed by a Linear layer.
        This output is to be used to embed contexts for nearest neighbors queries with questions embeddings.
    pooler_outputN.hidden_states
attentions__name__
__module____qualname____doc__torchFloatTensor__annotations__r   r   tupler    r   r   `/var/www/html/assistant/venv/lib/python3.9/site-packages/transformers/models/dpr/modeling_dpr.pyr   *   s   

r   c                   @   sP   e Zd ZU dZejed< dZee	ejdf  ed< dZ
ee	ejdf  ed< dS )DPRQuestionEncoderOutputa  
    pooler_output (`torch.FloatTensor` of shape `(batch_size, embeddings_size)`):
        The DPR encoder outputs the *pooler_output* that corresponds to the question representation. Last layer
        hidden-state of the first token of the sequence (classification token) further processed by a Linear layer.
        This output is to be used to embed questions for nearest neighbors queries with context embeddings.
    r   N.r   r   r   r   r   r   r   r    =   s   

r    c                   @   st   e Zd ZU dZejed< dZeej ed< dZ	eej ed< dZ
eeejdf  ed< dZeeejdf  ed< dS )	DPRReaderOutputa  
    start_logits (`torch.FloatTensor` of shape `(n_passages, sequence_length)`):
        Logits of the start index of the span for each passage.
    end_logits (`torch.FloatTensor` of shape `(n_passages, sequence_length)`):
        Logits of the end index of the span for each passage.
    relevance_logits (`torch.FloatTensor` of shape `(n_passages, )`):
        Outputs of the QA classifier of the DPRReader that corresponds to the scores of each passage to answer the
        question, compared to all the other passages.
    start_logitsN
end_logitsrelevance_logits.r   r   )r   r   r   r   r   r   r   r#   r   r$   r   r   r   r   r   r   r   r!   P   s   


r!   c                   @   s   e Zd ZdZdd ZdS )DPRPreTrainedModelTc                 C   s   t |tjr:|jjjd| jjd |jdur|jj	  nft |tj
rz|jjjd| jjd |jdur|jj|j 	  n&t |tjr|jj	  |jjd dS )zInitialize the weightsg        )meanZstdNg      ?)
isinstancer   LinearweightdataZnormal_configZinitializer_rangeZbiasZzero_Z	EmbeddingZpadding_idxZ	LayerNormZfill_)selfmoduler   r   r   _init_weightsl   s    

z DPRPreTrainedModel._init_weightsN)r   r   r   Z_supports_sdpar.   r   r   r   r   r%   h   s   r%   c                       sr   e Zd ZdZed fddZdeee ee ee eeee	e
eedf f dd	d
ZeedddZ  ZS )
DPREncoder
bert_modelr+   c                    sd   t  | t|dd| _| jjjdkr0td|j| _| jdkrXt	| jjj|j| _
|   d S )NF)Zadd_pooling_layerr   z!Encoder hidden_size can't be zero)super__init__r   r0   r+   hidden_size
ValueErrorprojection_dimr   r(   encode_proj	post_initr,   r+   	__class__r   r   r3      s    
zDPREncoder.__init__NF.	input_idsattention_masktoken_type_idsinputs_embedsoutput_attentionsoutput_hidden_statesreturn_dictreturnc              	   C   sv   | j |||||||d}|d }	|	d d dd d f }
| jdkrJ| |
}
|sb|	|
f|dd   S t|	|
|j|jdS )Nr=   r>   r?   r@   rA   rB   rC   r   r   )Zlast_hidden_stater   r   r   )r0   r6   r7   r   r   r   )r,   r=   r>   r?   r@   rA   rB   rC   outputssequence_outputZpooled_outputr   r   r   forward   s*    
	

zDPREncoder.forward)rD   c                 C   s   | j dkr| jjS | jjjS )Nr   )r6   r7   Zout_featuresr0   r+   r4   )r,   r   r   r   embeddings_size   s    
zDPREncoder.embeddings_size)NNNFFF)r   r   r   base_model_prefixr   r3   r   r   boolr   r   r   rH   propertyintrI   __classcell__r   r   r:   r   r/   }   s(         #r/   c                       sV   e Zd ZdZed fddZdeeee eeee	e
eedf f dd	d
Z  ZS )DPRSpanPredictorencoderr1   c                    sF   t  | t|| _t| jjd| _t| jjd| _| 	  d S )Nr   r   )
r2   r3   r/   rP   r   r(   rI   
qa_outputsqa_classifierr8   r9   r:   r   r   r3      s
    
zDPRSpanPredictor.__init__NF.r=   r>   r@   rA   rB   rC   rD   c                 C   s   |d ur|  n|  d d \}}| j||||||d}	|	d }
| |
}|jddd\}}|d }|d }| |
d d dd d f }|||}|||}||}|s|||f|	dd   S t||||	j	|	j
dS )Nr   )r>   r@   rA   rB   rC   r   r   )dim)r"   r#   r$   r   r   )sizerP   rQ   splitZsqueeze
contiguousrR   viewr!   r   r   )r,   r=   r>   r@   rA   rB   rC   Z
n_passagesZsequence_lengthrF   rG   Zlogitsr"   r#   r$   r   r   r   rH      s6    
$

zDPRSpanPredictor.forward)NFFF)r   r   r   rJ   r   r3   r   r   rK   r   r!   r   rH   rN   r   r   r:   r   rO      s       rO   c                   @   s"   e Zd ZU dZeed< dZdZdS )DPRPretrainedContextEncoder
    An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
    models.
    r+   Nctx_encoderr   r   r   r   r   r   Zload_tf_weightsrJ   r   r   r   r   rZ      s   
rZ   c                   @   s"   e Zd ZU dZeed< dZdZdS )DPRPretrainedQuestionEncoderr[   r+   Nquestion_encoderr]   r   r   r   r   r^      s   
r^   c                   @   s"   e Zd ZU dZeed< dZdZdS )DPRPretrainedReaderr[   r+   Nspan_predictorr]   r   r   r   r   r`   	  s   
r`   zf
    The bare DPRContextEncoder transformer outputting pooler outputs as context representations.
    c                       sp   e Zd Zed fddZed	ee ee ee ee ee ee ee e	e
eedf f dddZ  ZS )
DPRContextEncoderr1   c                    s(   t  | || _t|| _|   d S N)r2   r3   r+   r/   r\   r8   r9   r:   r   r   r3     s    
zDPRContextEncoder.__init__N.r<   c              	   C   s   |dur|n| j j}|dur |n| j j}|dur4|n| j j}|durV|durVtdn4|durh| }n"|dur| dd }ntd|dur|jn|j}	|du r|du rtj||	dn
|| j j	k}|du rtj
|tj|	d}| j|||||||d}
|s|
dd S t|
j|
j|
jd	S )
aS  
        input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
            Indices of input sequence tokens in the vocabulary. To match pretraining, DPR input sequence should be
            formatted with [CLS] and [SEP] tokens as follows:

            (a) For sequence pairs (for a pair title+text for example):

            ```
            tokens:         [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP]
            token_type_ids:   0   0  0    0    0     0       0   0   1  1  1  1   1   1
            ```

            (b) For single sequences (for a question for example):

            ```
            tokens:         [CLS] the dog is hairy . [SEP]
            token_type_ids:   0   0   0   0  0     0   0
            ```

            DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right
            rather than the left.

            Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
            [`PreTrainedTokenizer.__call__`] for details.

            [What are input IDs?](../glossary#input-ids)

        Examples:

        ```python
        >>> from transformers import DPRContextEncoder, DPRContextEncoderTokenizer

        >>> tokenizer = DPRContextEncoderTokenizer.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
        >>> model = DPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
        >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="pt")["input_ids"]
        >>> embeddings = model(input_ids).pooler_output
        ```NDYou cannot specify both input_ids and inputs_embeds at the same timerT   5You have to specify either input_ids or inputs_embedsdeviceZdtyperg   rE   r   r   r   r   )r+   rA   rB   use_return_dictr5   rV   rg   r   onespad_token_idzeroslongr\   r   r   r   r   r,   r=   r>   r?   r@   rA   rB   rC   input_shaperg   rF   r   r   r   rH   &  sB    1



zDPRContextEncoder.forward)NNNNNNN)r   r   r   r   r3   r   r   r   rK   r   r   r   rH   rN   r   r   r:   r   rb     s&          rb   zh
    The bare DPRQuestionEncoder transformer outputting pooler outputs as question representations.
    c                       sp   e Zd Zed fddZed	ee ee ee ee ee ee ee e	e
eedf f dddZ  ZS )
DPRQuestionEncoderr1   c                    s(   t  | || _t|| _|   d S rc   )r2   r3   r+   r/   r_   r8   r9   r:   r   r   r3     s    
zDPRQuestionEncoder.__init__N.r<   c              	   C   s,  |dur|n| j j}|dur |n| j j}|dur4|n| j j}|durV|durVtdn@|durt| || | }n"|dur| dd }ntd|dur|jn|j}	|du r|du rtj	||	dn
|| j j
k}|du rtj|tj|	d}| j|||||||d}
|s|
dd S t|
j|
j|
jd	S )
aj  
        input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
            Indices of input sequence tokens in the vocabulary. To match pretraining, DPR input sequence should be
            formatted with [CLS] and [SEP] tokens as follows:

            (a) For sequence pairs (for a pair title+text for example):

            ```
            tokens:         [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP]
            token_type_ids:   0   0  0    0    0     0       0   0   1  1  1  1   1   1
            ```

            (b) For single sequences (for a question for example):

            ```
            tokens:         [CLS] the dog is hairy . [SEP]
            token_type_ids:   0   0   0   0  0     0   0
            ```

            DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right
            rather than the left.

            Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
            [`PreTrainedTokenizer.__call__`] for details.

            [What are input IDs?](../glossary#input-ids)

        Examples:

        ```python
        >>> from transformers import DPRQuestionEncoder, DPRQuestionEncoderTokenizer

        >>> tokenizer = DPRQuestionEncoderTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
        >>> model = DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
        >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="pt")["input_ids"]
        >>> embeddings = model(input_ids).pooler_output
        ```
        Nrd   rT   re   rf   rh   rE   r   ri   )r+   rA   rB   rj   r5   %warn_if_padding_and_no_attention_maskrV   rg   r   rk   rl   rm   rn   r_   r    r   r   r   ro   r   r   r   rH     sD    1



zDPRQuestionEncoder.forward)NNNNNNN)r   r   r   r   r3   r   r   r   rK   r   r    r   rH   rN   r   r   r:   r   rq     s&          rq   zE
    The bare DPRReader transformer outputting span predictions.
    c                       sj   e Zd Zed fddZed	ee ee ee ee ee ee e	e
eedf f dddZ  ZS )
	DPRReaderr1   c                    s(   t  | || _t|| _|   d S rc   )r2   r3   r+   rO   ra   r8   r9   r:   r   r   r3     s    
zDPRReader.__init__N.rS   c           	      C   s   |dur|n| j j}|dur |n| j j}|dur4|n| j j}|durV|durVtdn@|durt| || | }n"|dur| dd }ntd|dur|jn|j}|du rtj	||d}| j
||||||dS )a  
        input_ids (`tuple[torch.LongTensor]` of shapes `(n_passages, sequence_length)`):
            Indices of input sequence tokens in the vocabulary. It has to be a sequence triplet with 1) the question
            and 2) the passages titles and 3) the passages texts To match pretraining, DPR `input_ids` sequence should
            be formatted with [CLS] and [SEP] with the format:

            `[CLS] <question token ids> [SEP] <titles ids> [SEP] <texts ids>`

            DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right
            rather than the left.

            Indices can be obtained using [`DPRReaderTokenizer`]. See this class documentation for more details.

            [What are input IDs?](../glossary#input-ids)
        inputs_embeds (`torch.FloatTensor` of shape `(n_passages, sequence_length, hidden_size)`, *optional*):
            Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
            is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
            model's internal embedding lookup matrix.

        Examples:

        ```python
        >>> from transformers import DPRReader, DPRReaderTokenizer

        >>> tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base")
        >>> model = DPRReader.from_pretrained("facebook/dpr-reader-single-nq-base")
        >>> encoded_inputs = tokenizer(
        ...     questions=["What is love ?"],
        ...     titles=["Haddaway"],
        ...     texts=["'What Is Love' is a song recorded by the artist Haddaway"],
        ...     return_tensors="pt",
        ... )
        >>> outputs = model(**encoded_inputs)
        >>> start_logits = outputs.start_logits
        >>> end_logits = outputs.end_logits
        >>> relevance_logits = outputs.relevance_logits
        ```
        Nrd   rT   re   rf   )r@   rA   rB   rC   )r+   rA   rB   rj   r5   rr   rV   rg   r   rk   ra   )	r,   r=   r>   r@   rA   rB   rC   rp   rg   r   r   r   rH     s.    0

zDPRReader.forward)NNNNNN)r   r   r   r   r3   r   r   r   rK   r   r!   r   rH   rN   r   r   r:   r   rs     s"         rs   )rb   rZ   r%   r^   r`   rq   rs   )%r   dataclassesr   typingr   r   r   r   r   Zmodeling_outputsr   Zmodeling_utilsr	   utilsr
   r   r   Zbert.modeling_bertr   Zconfiguration_dprr   Z
get_loggerr   loggerr   r    r!   r%   r/   rO   rZ   r^   r`   rb   rq   rs   __all__r   r   r   r   <module>   sZ   
8>deW