Ë
    l^(hß  ã                  ób   — d dl mZ d dlmZmZ d dlmZ d dlmZ  G d„ dej                  «      Z
y)é    )Úannotations)ÚTensorÚnn)ÚCrossEncoder)Úfullnamec                  ób   ‡ — e Zd Z ej                  «       fdˆ fd„Zdd„Zd„ Zedd„«       Z	ˆ xZ
S )ÚMarginMSELossc                óº  •— t         ‰| �  «        || _        || _        t	        j
                  di |¤Ž| _        t        | j                  t        «      s8t        | j                  j                  › dt        | j                  «      › d�«      ‚| j                  j                  dk7  r9t        | j                  j                  › d| j                  j                  › d�«      ‚y)aÜ  
        Computes the MSE loss between ``|sim(Query, Pos) - sim(Query, Neg)|`` and ``|gold_sim(Query, Pos) - gold_sim(Query, Neg)|``.
        This loss is often used to distill a cross-encoder model from a teacher cross-encoder model or gold labels.

        In contrast to :class:`~sentence_transformers.cross_encoder.losses.MultipleNegativesRankingLoss`, the two passages do not
        have to be strictly positive and negative, both can be relevant or not relevant for a given query. This can be
        an advantage of MarginMSELoss over MultipleNegativesRankingLoss.

        .. note::

            Be mindful of the magnitude of both the labels and what the model produces. If the teacher model produces
            logits with Sigmoid to bound them to [0, 1], then you may wish to use a Sigmoid activation function in the loss.

        Args:
            model (:class:`~sentence_transformers.cross_encoder.CrossEncoder`): A CrossEncoder model to be trained.
            activation_fn (:class:`~torch.nn.Module`): Activation function applied to the logits before computing the loss.
            **kwargs: Additional keyword arguments passed to the underlying :class:`torch.nn.MSELoss`.

        References:
            - Improving Efficient Neural Ranking Models with Cross-Architecture Knowledge Distillation: https://arxiv.org/abs/2010.02666
            - `Cross Encoder > Training Examples > Distillation <../../../examples/cross_encoder/training/distillation/README.html>`_

        Requirements:
            1. Your model must be initialized with `num_labels = 1` (a.k.a. the default) to predict one class.
            2. Usually uses a finetuned CrossEncoder teacher M in a knowledge distillation setup.

        Inputs:
            +--------------------------------------------+-------------------------------------------------------------+-------------------------------+
            | Texts                                      | Labels                                                      | Number of Model Output Labels |
            +============================================+=============================================================+===============================+
            | (query, passage_one, passage_two) triplets | gold_sim(query, passage_one) - gold_sim(query, passage_two) | 1                             |
            +--------------------------------------------+-------------------------------------------------------------+-------------------------------+

        Relations:
            - :class:`MSELoss` is similar to this loss, but without a margin through the negative pair.

        Example:
            ::

                from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses
                from datasets import Dataset

                student_model = CrossEncoder("microsoft/mpnet-base")
                teacher_model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L12-v2")
                train_dataset = Dataset.from_dict({
                    "query": ["What are pandas?", "What is the capital of France?"],
                    "positive": ["Pandas are a kind of bear.", "The capital of France is Paris."],
                    "negative": ["Pandas are a kind of fish.", "The capital of France is Berlin."],
                })

                def compute_labels(batch):
                    positive_scores = teacher_model.predict(list(zip(batch["query"], batch["positive"])))
                    negative_scores = teacher_model.predict(list(zip(batch["query"], batch["negative"])))
                    return {
                        "label": positive_scores - negative_scores
                    }

                train_dataset = train_dataset.map(compute_labels, batched=True)
                loss = losses.MarginMSELoss(student_model)

                trainer = CrossEncoderTrainer(
                    model=student_model,
                    train_dataset=train_dataset,
                    loss=loss,
                )
                trainer.train()
        z? expects a model of type CrossEncoder, but got a model of type ú.é   z; expects a model with 1 output label, but got a model with z output labels.N© )ÚsuperÚ__init__ÚmodelÚactivation_fnr   ÚMSELossÚloss_fctÚ
isinstancer   Ú
ValueErrorÚ	__class__Ú__name__ÚtypeÚ
num_labels)Úselfr   r   Úkwargsr   s       €úv/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/sentence_transformers/cross_encoder/losses/MarginMSELoss.pyr   zMarginMSELoss.__init__
   sÌ   ø€ ôH 	‰ÑÔØˆŒ
Ø*ˆÔÜŸ
™
Ñ, VÑ,ˆŒä˜$Ÿ*™*¤lÔ3ÜØ—>‘>×*Ñ*Ð+ð ,+Ü+/°·
±
Ó+;Ð*<¸Að?óð ð
 �:‰:× Ñ  AÒ%ÜØ—>‘>×*Ñ*Ð+ð ,(Ø(,¯
©
×(=Ñ(=Ð'>¸oðOóð ð &ó    c                óì  — t        |«      dk7  rt        dt        |«      › d�«      ‚t        t        |d   |d   «      «      }| j                  j                  |ddd¬«      }|j                  | j                  j                  «        | j                  di |¤Žd   j                  d	«      }| j                  |«      }t        t        |d   |d
   «      «      }| j                  j                  |ddd¬«      }|j                  | j                  j                  «        | j                  di |¤Žd   j                  d	«      }| j                  |«      }||z
  }| j                  ||j                  «       «      }	|	S )Né   zOMSELoss expects a dataset with three non-label columns, but got a dataset with z	 columns.r   r   TÚpt)ÚpaddingÚ
truncationÚreturn_tensorséÿÿÿÿé   r   )Úlenr   ÚlistÚzipr   Ú	tokenizerÚtoÚdeviceÚviewr   r   Úfloat)
r   ÚinputsÚlabelsÚpositive_pairsÚtokensÚpositive_logitsÚnegative_pairsÚnegative_logitsÚmargin_logitsÚlosss
             r   ÚforwardzMarginMSELoss.forward_   si  € Üˆv‹;˜!ÒÜØaÔbeÐflÓbmÐanÐnwÐxóð ô œc &¨¡)¨V°A©YÓ7Ó8ˆØ—‘×%Ñ%ØØØØð	 &ó 
ˆð 	�	‰	�$—*‘*×#Ñ#Ô$Ø$˜$Ÿ*™*Ñ. vÑ.¨qÑ1×6Ñ6°rÓ:ˆØ×,Ñ,¨_Ó=ˆäœc &¨¡)¨V°A©YÓ7Ó8ˆØ—‘×%Ñ%ØØØØð	 &ó 
ˆð 	�	‰	�$—*‘*×#Ñ#Ô$Ø$˜$Ÿ*™*Ñ. vÑ.¨qÑ1×6Ñ6°rÓ:ˆØ×,Ñ,¨_Ó=ˆà'¨/Ñ9ˆØ�}‰}˜]¨F¯L©L«NÓ;ˆØˆr   c                ó0   — dt        | j                  «      iS )Nr   )r   r   ©r   s    r   Úget_config_dictzMarginMSELoss.get_config_dict   s   € àœX d×&8Ñ&8Ó9ð
ð 	
r   c                 ó   — y)NuY  
@misc{hofstÃ¤tter2021improving,
    title={Improving Efficient Neural Ranking Models with Cross-Architecture Knowledge Distillation},
    author={Sebastian HofstÃ¤tter and Sophia Althammer and Michael SchrÃ¶der and Mete Sertkan and Allan Hanbury},
    year={2021},
    eprint={2010.02666},
    archivePrefix={arXiv},
    primaryClass={cs.IR}
}
r   r9   s    r   ÚcitationzMarginMSELoss.citation„   s   € ð	r   )r   r   r   z	nn.ModuleÚreturnÚNone)r.   zlist[list[str]]r/   r   r=   r   )r=   Ústr)r   Ú
__module__Ú__qualname__r   ÚIdentityr   r7   r:   Úpropertyr<   Ú__classcell__)r   s   @r   r	   r	   	   s4   ø„ ØGRÀrÇ{Á{Ã}ö Sójò@
ð
 ò
ó ô
r   r	   N)Ú
__future__r   Útorchr   r   Ú0sentence_transformers.cross_encoder.CrossEncoderr   Úsentence_transformers.utilr   ÚModuler	   r   r   r   ú<module>rJ      s#   ðÝ "ç å IÝ /ôF�B—I‘Iõ Fr   