U
    <Af                     @   sv   d dl Z d dlZd dlZd dlmZ d dlmZmZmZm	Z	 d dl
mZ erXd dlmZ eeZG dd deZdS )    N)nullcontext)TYPE_CHECKINGDictListOptional)SentenceEvaluator)SentenceTransformerc                	       sn   e Zd ZdZdee ee eeeeee d fdd	Z	ddee
eef dddZeedddZ  ZS )MSEEvaluatora
  
    Computes the mean squared error (x100) between the computed sentence embedding
    and some target sentence embedding.

    The MSE is computed between ||teacher.encode(source_sentences) - student.encode(target_sentences)||.

    For multilingual knowledge distillation (https://arxiv.org/abs/2004.09813), source_sentences are in English
    and target_sentences are in a different language like German, Chinese, Spanish...

    Args:
        source_sentences (List[str]): Source sentences to embed with the teacher model.
        target_sentences (List[str]): Target sentences to embed with the student model.
        teacher_model (SentenceTransformer, optional): The teacher model to compute the source sentence embeddings.
        show_progress_bar (bool, optional): Show progress bar when computing embeddings. Defaults to False.
        batch_size (int, optional): Batch size to compute sentence embeddings. Defaults to 32.
        name (str, optional): Name of the evaluator. Defaults to "".
        write_csv (bool, optional): Write results to CSV file. Defaults to True.
        truncate_dim (int, optional): The dimension to truncate sentence embeddings to. `None` uses the model's current truncation
            dimension. Defaults to None.

    Example:
        ::

            from sentence_transformers import SentenceTransformer
            from sentence_transformers.evaluation import MSEEvaluator
            from datasets import load_dataset

            # Load a model
            student_model = SentenceTransformer('paraphrase-multilingual-mpnet-base-v2')
            teacher_model = SentenceTransformer('all-mpnet-base-v2')

            # Load any dataset with some texts
            dataset = load_dataset("sentence-transformers/stsb", split="validation")
            sentences = dataset["sentence1"] + dataset["sentence2"]

            # Given queries, a corpus and a mapping with relevant documents, the InformationRetrievalEvaluator computes different IR metrics.
            mse_evaluator = MSEEvaluator(
                source_sentences=sentences,
                target_sentences=sentences,
                teacher_model=teacher_model,
                name="stsb-dev",
            )
            results = mse_evaluator(student_model)
            '''
            MSE evaluation (lower = better) on the stsb-dev dataset:
            MSE (*100):  0.805045
            '''
            print(mse_evaluator.primary_metric)
            # => "stsb-dev_negative_mse"
            print(results[mse_evaluator.primary_metric])
            # => -0.8050452917814255
    NF     T)source_sentencestarget_sentencesshow_progress_bar
batch_sizename	write_csvtruncate_dimc	           	   	      s   t    || _| jd kr t n
|| j |j|||dd| _W 5 Q R X || _|| _|| _	|| _
d| d | _dddg| _|| _d| _d S )	NTr   r   Zconvert_to_numpyZmse_evaluation_z_results.csvepochstepsZMSEnegative_mse)super__init__r   r   truncate_sentence_embeddingsencodesource_embeddingsr   r   r   r   csv_filecsv_headersr   Zprimary_metric)	selfr   r   Zteacher_modelr   r   r   r   r   	__class__ Q/tmp/pip-unpacked-wheel-i7fohqg6/sentence_transformers/evaluation/MSEEvaluator.pyr   E   s&    
   zMSEEvaluator.__init__r   )modeloutput_pathreturnc              	   C   s|  |dkr0|dkrd| }q4d| d| d}nd}| j d k	rP|d| j  d7 }| j d kr`t n
|| j  |j| j| j| jd	d
}W 5 Q R X | j| d  }|d9 }t	
d| j d| d t	
d| |d k	rT| jrTtj|| j}tj|}	t|d|	rdnddd2}
t|
}|	s:|| j ||||g W 5 Q R X d| i}| || j}| || |S )Nr#   z after epoch z
 in epoch z after z stepsr   z (truncated to )Tr      d   z'MSE evaluation (lower = better) on the z dataset:zMSE (*100):	{:4f}awzutf-8)newlinemodeencodingr   )r   r   r   r   r   r   r   r   Zmeanloggerinfor   formatr   ospathjoinr   isfileopencsvwriterwriterowr   Zprefix_name_to_metricsZ store_metrics_in_model_card_data)r   r$   r%   r   r   Zout_txtZtarget_embeddingsZmseZcsv_pathZoutput_file_existsfr9   Zmetricsr!   r!   r"   __call__c   s<    


zMSEEvaluator.__call__)r&   c                 C   s   dS )NzKnowledge Distillationr!   )r   r!   r!   r"   description   s    zMSEEvaluator.description)NFr
   r   TN)Nr#   r#   )__name__
__module____qualname____doc__r   strboolintr   r   r   floatr<   propertyr=   __classcell__r!   r!   r   r"   r	      s&   9      )r	   )r8   loggingr3   
contextlibr   typingr   r   r   r   Z2sentence_transformers.evaluation.SentenceEvaluatorr   Z)sentence_transformers.SentenceTransformerr   	getLoggerr>   r0   r	   r!   r!   r!   r"   <module>   s   
