§
    æ˜ºh¾  ã                   óh   — d dl mZmZ d dlmZmZ ddlmZmZ d dlm	Z	  G d„ dej
        ¦  «        ZdS )	é    )ÚnnÚTensor)ÚIterableÚDicté   )ÚBatchHardTripletLossÚ$BatchHardTripletLossDistanceFunction)ÚSentenceTransformerc                   ón   ‡ — e Zd ZdZej        dfdedefˆ fd„Zde	e
eef                  defd„Zd	„ Zˆ xZS )
ÚBatchAllTripletLossa­  
    BatchAllTripletLoss takes a batch with (label, sentence) pairs and computes the loss for all possible, valid
    triplets, i.e., anchor and positive must have the same label, anchor and negative a different label. The labels
    must be integers, with same label indicating sentences from the same class. You train dataset
    must contain at least 2 examples per label class.

    | Source: https://github.com/NegatioN/OnlineMiningTripletLoss/blob/master/online_triplet_loss/losses.py
    | Paper: In Defense of the Triplet Loss for Person Re-Identification, https://arxiv.org/abs/1703.07737
    | Blog post: https://omoindrot.github.io/triplet-loss

    :param model: SentenceTransformer model
    :param distance_metric: Function that returns a distance between two emeddings. The class SiameseDistanceMetric contains pre-defined metrices that can be used
    :param margin: Negative samples should be at least margin further apart from the anchor than the positive.

    Example::

        from sentence_transformers import SentenceTransformer, SentencesDataset, losses
        from sentence_transformers.readers import InputExample

        model = SentenceTransformer('distilbert-base-nli-mean-tokens')
        train_examples = [InputExample(texts=['Sentence from class 0'], label=0), InputExample(texts=['Another sentence from class 0'], label=0),
            InputExample(texts=['Sentence from class 1'], label=1), InputExample(texts=['Sentence from class 2'], label=2)]
        train_dataset = SentencesDataset(train_examples, model)
        train_dataloader = DataLoader(train_dataset, shuffle=True, batch_size=train_batch_size)
        train_loss = losses.BatchAllTripletLoss(model=model)
    é   ÚmodelÚmarginc                 ó€   •— t          t          | ¦  «                             ¦   «          || _        || _        || _        d S )N)Úsuperr   Ú__init__Úsentence_embedderÚtriplet_marginÚdistance_metric)Úselfr   r   r   Ú	__class__s       €úx/var/www/html/services/rag-service/venv/lib/python3.11/site-packages/sentence_transformers/losses/BatchAllTripletLoss.pyr   zBatchAllTripletLoss.__init__#   s@   ø€ õ 	Õ! 4Ñ(Ô(×1Ò1Ñ3Ô3Ð3Ø!&ˆÔØ$ˆÔØ.ˆÔÐÐó    Úsentence_featuresÚlabelsc                 óp   — |                       |d         ¦  «        d         }|                      ||¦  «        S )Nr   Úsentence_embedding)r   Úbatch_all_triplet_loss)r   r   r   Úreps       r   ÚforwardzBatchAllTripletLoss.forward.   s7   € Ø×$Ò$Ð%6°qÔ%9Ñ:Ô:Ð;OÔPˆØ×*Ò*¨6°3Ñ7Ô7Ð7r   c                 ó|  — |                       |¦  «        }|                     d¦  «        }|                     d¦  «        }||z
  | j        z   }t          j        |¦  «        }|                     ¦   «         |z  }d||dk     <   ||dk             }|                     d¦  «        }	|                     ¦   «         |	dz   z  }|S )a]  Build the triplet loss over a batch of embeddings.
        We generate all the valid triplets and average the loss over the positive ones.
        Args:
            labels: labels of the batch, of size (batch_size,)
            embeddings: tensor of shape (batch_size, embed_dim)
            margin: margin for triplet loss
            squared: Boolean. If true, output is the pairwise squared euclidean distance matrix.
                     If false, output is the pairwise euclidean distance matrix.
        Returns:
            Label_Sentence_Triplet: scalar tensor containing the triplet loss
        é   r   r   g¼‰Ø—²Òœ<)r   Ú	unsqueezer   r   Úget_triplet_maskÚfloatÚsizeÚsum)
r   r   Ú
embeddingsÚpairwise_distÚanchor_positive_distÚanchor_negative_distÚtriplet_lossÚmaskÚvalid_tripletsÚnum_positive_tripletss
             r   r   z*BatchAllTripletLoss.batch_all_triplet_loss2   sÒ   € ð ×,Ò,¨ZÑ8Ô8ˆà,×6Ò6°qÑ9Ô9ÐØ,×6Ò6°qÑ9Ô9Ðð ,Ð.BÑBÀTÔEXÑXˆõ $Ô4°VÑ<Ô<ˆØ—z’z‘|”| lÑ2ˆð *+ˆ�\ AÒ%Ñ&ð & l°UÒ&:Ô;ˆØ .× 3Ò 3°AÑ 6Ô 6Ðð
 $×'Ò'Ñ)Ô)Ð-BÀUÑ-JÑKˆàÐr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   Úeucledian_distancer
   r%   r   r   r   Ústrr   r    r   Ú__classcell__)r   s   @r   r   r      s¨   ø€ € € € € ðð ð< =ÔOØð		/ð 	/à"ð	/ð ð		/ð 	/ð 	/ð 	/ð 	/ð 	/ð8¨°$°s¸F°{Ô2CÔ)Dð 8Èfð 8ð 8ð 8ð 8ð)ð )ð )ð )ð )ð )ð )r   r   N)Útorchr   r   Útypingr   r   r   r	   Ú)sentence_transformers.SentenceTransformerr
   ÚModuler   © r   r   ú<module>r<      sŸ   ðØ Ð Ð Ð Ð Ð Ð Ð Ø !Ð !Ð !Ð !Ð !Ð !Ð !Ð !Ø \Ð \Ð \Ð \Ð \Ð \Ð \Ð \Ø IÐ IÐ IÐ IÐ IÐ IðTð Tð Tð Tð T˜"œ)ñ Tô Tð Tð Tð Tr   