Ë
    l^(hð  ã                  ó‚   — d dl mZ d dlmZ d dlmZ d dl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)ÚIterable)ÚAnyN)ÚTensorÚnn)Úutil)ÚSentenceTransformerc                  óJ   ‡ — e Zd Zdej                  fdˆ fd„Zdd„Zdd„Zˆ xZS )Ú%MultipleNegativesSymmetricRankingLossg      4@c                ó~   •— t         ‰| �  «        || _        || _        || _        t        j                  «       | _        y)až  
        Given a list of (anchor, positive) pairs, this loss sums the following two losses:

        1. Forward loss: Given an anchor, find the sample with the highest similarity out of all positives in the batch.
           This is equivalent to :class:`MultipleNegativesRankingLoss`.
        2. Backward loss: Given a positive, find the sample with the highest similarity out of all anchors in the batch.

        For example with question-answer pairs, :class:`MultipleNegativesRankingLoss` just computes the loss to find
        the answer given a question, but :class:`MultipleNegativesSymmetricRankingLoss` additionally computes the
        loss to find the question given an answer.

        Note: If you pass triplets, the negative entry will be ignored. A anchor is just searched for the positive.

        Args:
            model: SentenceTransformer model
            scale: Output of similarity function is multiplied by scale
                value
            similarity_fct: similarity function between sentence
                embeddings. By default, cos_sim. Can also be set to dot
                product (and then set scale to 1)

        Requirements:
            1. (anchor, positive) pairs

        Inputs:
            +---------------------------------------+--------+
            | Texts                                 | Labels |
            +=======================================+========+
            | (anchor, positive) pairs              | none   |
            +---------------------------------------+--------+

        Recommendations:
            - Use ``BatchSamplers.NO_DUPLICATES`` (:class:`docs <sentence_transformers.training_args.BatchSamplers>`) to
              ensure that no in-batch negatives are duplicates of the anchor or positive samples.

        Relations:
            - Like :class:`MultipleNegativesRankingLoss`, but with an additional loss term.
            - :class:`CachedMultipleNegativesSymmetricRankingLoss` is equivalent to this loss, but it uses caching that
              allows for much higher batch sizes (and thus better performance) without extra memory usage. However, it
              is slightly slower.

        Example:
            ::

                from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses
                from datasets import Dataset

                model = SentenceTransformer("microsoft/mpnet-base")
                train_dataset = Dataset.from_dict({
                    "anchor": ["It's nice weather outside today.", "He drove to work."],
                    "positive": ["It's so sunny.", "He took the car to the office."],
                })
                loss = losses.MultipleNegativesSymmetricRankingLoss(model)

                trainer = SentenceTransformerTrainer(
                    model=model,
                    train_dataset=train_dataset,
                    loss=loss,
                )
                trainer.train()
        N)ÚsuperÚ__init__ÚmodelÚscaleÚsimilarity_fctr   ÚCrossEntropyLossÚcross_entropy_loss)Úselfr   r   r   Ú	__class__s       €ú€/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/sentence_transformers/losses/MultipleNegativesSymmetricRankingLoss.pyr   z.MultipleNegativesSymmetricRankingLoss.__init__   s8   ø€ ô| 	‰ÑÔØˆŒ
ØˆŒ
Ø,ˆÔÜ"$×"5Ñ"5Ó"7ˆÕó    c                óð  — |D �cg c]  }| j                  |«      d   ‘Œ }}|d   }t        j                  |dd  «      }| j                  ||«      | j                  z  }t        j
                  t        t        |«      «      t        j                  |j                  ¬«      }|d d …dt        |d   «      …f   }| j                  ||«      }	| j                  |j                  dd«      |«      }
|	|
z   dz  S c c}w )NÚsentence_embeddingr   é   )ÚdtypeÚdeviceé   )r   ÚtorchÚcatr   r   ÚtensorÚrangeÚlenÚlongr   r   Ú	transpose)r   Úsentence_featuresÚlabelsÚsentence_featureÚrepsÚanchorÚ
candidatesÚscoresÚanchor_positive_scoresÚforward_lossÚbackward_losss              r   Úforwardz-MultipleNegativesSymmetricRankingLoss.forwardR   sî   € Ø[lÖmÐGW�—
‘
Ð+Ó,Ð-AÓBÐmˆÐmØ�a‘ˆÜ—Y‘Y˜t A B˜xÓ(ˆ
à×$Ñ$ V¨ZÓ8¸4¿:¹:ÑEˆÜ—‘Ü”#�f“+Ó¤e§j¡j¸¿¹ô
ˆð "(ª¨1¬s°4¸±7«|Ð+;Ð(;Ñ!<ÐØ×.Ñ.¨v°vÓ>ˆØ×/Ñ/Ð0F×0PÑ0PÐQRÐTUÓ0VÐX^Ó_ˆØ˜}Ñ,°Ñ1Ð1ùò ns   …C3c                óH   — | j                   | j                  j                  dœS )N)r   r   )r   r   Ú__name__)r   s    r   Úget_config_dictz5MultipleNegativesSymmetricRankingLoss.get_config_dicta   s   € ØŸ™°t×7JÑ7J×7SÑ7SÑTÐTr   )r   r	   r   ÚfloatÚreturnÚNone)r%   zIterable[dict[str, Tensor]]r&   r   r4   r   )r4   zdict[str, Any])	r1   Ú
__module__Ú__qualname__r   Úcos_simr   r/   r2   Ú__classcell__)r   s   @r   r   r      s!   ø„ ØBFÐW[×WcÑWcö B8óH2÷Ur   r   )Ú
__future__r   Úcollections.abcr   Útypingr   r   r   r   Úsentence_transformersr   Ú)sentence_transformers.SentenceTransformerr	   ÚModuler   © r   r   ú<module>rA      s.   ðÝ "å $Ý ã ß å &Ý IôUU¨B¯I©Iõ UUr   