§
    æ˜ºh�  ã                   ór   — d dl mZ ddlZddlmZmZ ddlmZmZ ddlmc m	Z
  G d„ dej        ¦  «        ZdS )é   )Úutilé    N)ÚnnÚTensor)ÚIterableÚDictc            	       ó–   ‡ — e Zd ZdZ	 	 	 	 ddededed	efˆ fd
„Zdee	e
ef                  defd„Zdee	e
ef                  defd„Zˆ xZS )ÚMegaBatchMarginLossaæ  
    Loss function inspired from ParaNMT paper:
    https://www.aclweb.org/anthology/P18-1042/

    Given a large batch (like 500 or more examples) of (anchor_i, positive_i) pairs,
    find for each pair in the batch the hardest negative, i.e. find j != i such that cos_sim(anchor_i, positive_j)
    is maximal. Then create from this a triplet (anchor_i, positive_i, positive_j) where positive_j
    serves as the negative for this triplet.

    Train than as with the triplet loss
    çš™™™™™é?ç333333Ó?Té2   Úpositive_marginÚnegative_marginÚuse_mini_batched_versionÚmini_batch_sizec                 ó¸   •— t          t          | ¦  «                             ¦   «          || _        || _        || _        || _        |r| j        n| j        | _	        dS )aG  
        :param model: SentenceTransformerModel
        :param positive_margin: Positive margin, cos(anchor, positive) should be > positive_margin
        :param negative_margin: Negative margin, cos(anchor, negative) should be < negative_margin
        :param use_mini_batched_version: As large batch sizes require a lot of memory, we can use a mini-batched version. We break down the large batch with 500 examples to smaller batches with fewer examples.
        :param mini_batch_size: Size for the mini-batches. Should be a devisor for the batch size in your data loader.
        N)
Úsuperr
   Ú__init__Úmodelr   r   r   Úforward_mini_batchedÚforward_non_mini_batchedÚforward)Úselfr   r   r   r   r   Ú	__class__s         €úx/var/www/html/services/rag-service/venv/lib/python3.11/site-packages/sentence_transformers/losses/MegaBatchMarginLoss.pyr   zMegaBatchMarginLoss.__init__   s]   ø€ õ 	Õ! 4Ñ(Ô(×1Ò1Ñ3Ô3Ð3ØˆŒ
Ø.ˆÔØ.ˆÔØ.ˆÔØ4LÐo�tÔ0Ð0ÐRVÔRoˆŒˆˆó    Úsentence_featuresÚlabelsc                 ó,  ‡‡‡‡— |\  ŠŠt          ‰                     ¦   «         ¦  «        }t          j        ¦   «         5  | j                             ¦   «          |                      ‰¦  «        d                              ¦   «         }| j                             ¦   «          d d d ¦  «         n# 1 swxY w Y   t          j        t          |¦  «        t          |¦  «        |j
        ¬¦  «        }t          dt          |¦  «        | j        ¦  «        D �]Š‰| j        z   Š|                      ˆˆˆfd„|D ¦   «         ¦  «        d         }d„ |D ¦   «         }t          j        ¦   «         5  t          j        ||¦  «        }|d|‰‰…         z  z
  }	t          j        |	d¬¦  «        \  }
}d d d ¦  «         n# 1 swxY w Y   |D ].}|D ])}||                              ‰|         |         ¦  «         Œ*Œ/|D ]}t          j        ||         ¦  «        ||<   Œ |                      ˆˆˆfd	„|D ¦   «         ¦  «        d         }|                      |¦  «        d         }|j        |j        k    sJ ‚|j        |j        k    sJ ‚t'          j        ||¦  «        }t'          j        ||¦  «        }t'          j        | j        |z
  ¦  «        t'          j        || j        z
  ¦  «        z   }|                     ¦   «         }‰t          |¦  «        k     r|                     ¦   «          �Œ|S )
NÚsentence_embedding)Údevicer   c                 ó2   •— i | ]}|‰|         ‰‰…         “ŒS © r#   )Ú.0ÚkeyÚanchorÚend_idxÚ	start_idxs     €€€r   ú
<dictcomp>z<MegaBatchMarginLoss.forward_mini_batched.<locals>.<dictcomp>9   s)   ø€ Ð$bÐ$bÐ$bÈS S¨&°¬+°iÀÐ6GÔ*HÐ$bÐ$bÐ$br   c                 ó   — i | ]}|g “ŒS r#   r#   )r$   r%   s     r   r)   z<MegaBatchMarginLoss.forward_mini_batched.<locals>.<dictcomp>?   s   € Ð%GÐ%GÐ%G°# c¨2Ð%GÐ%GÐ%Gr   r   é   ©Údimc                 ó2   •— i | ]}|‰|         ‰‰…         “ŒS r#   r#   )r$   r%   r'   Úpositiver(   s     €€€r   r)   z<MegaBatchMarginLoss.forward_mini_batched.<locals>.<dictcomp>O   s*   ø€ Ð&fÐ&fÐ&fÐQT s¨H°S¬M¸)ÀGÐ:KÔ,LÐ&fÐ&fÐ&fr   )ÚlistÚkeysÚtorchÚno_gradr   ÚevalÚdetachÚtrainÚeyeÚlenr!   Úranger   r   Úpytorch_cos_simÚmaxÚappendÚstackÚshapeÚFÚcosine_similarityÚrelur   r   ÚmeanÚbackward)r   r   r   Úfeature_namesÚall_positive_embÚdiagonal_matrixÚ
anchor_embÚhard_negative_featuresÚ
cos_scoresÚnegative_scoresÚnegatives_maxÚnegatives_idsÚhard_negative_idr%   Úpositive_embÚnegative_embÚ
pos_cosineÚ
neg_cosineÚlossesr&   r'   r/   r(   s                      @@@@r   r   z(MegaBatchMarginLoss.forward_mini_batched+   sÉ  øøøø€ Ø,Ñˆ�Ý˜VŸ[š[™]œ]Ñ+Ô+ˆåŒ]‰_Œ_ð 	ð 	ØŒJ�OŠOÑÔÐØ#Ÿzšz¨(Ñ3Ô3Ð4HÔI×PÒPÑRÔRÐØŒJ×ÒÑÔÐð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	õ
  œ)¥CÐ(8Ñ$9Ô$9½3Ð?OÑ;PÔ;PÐYiÔYpÐqÑqÔqˆõ ˜q¥#Ð&6Ñ"7Ô"7¸Ô9MÑNÔNð (	"ñ (	"ˆIØ $Ô"6Ñ6ˆGØŸšÐ$bÐ$bÐ$bÐ$bÐ$bÐ$bÐTaÐ$bÑ$bÔ$bÑcÔcØ$ôˆJð &HÐ%G¸Ð%GÑ%GÔ%GÐ"Ý”‘”ð Qð QÝ!Ô1°*Ð>NÑOÔO�
à  _°Y¸wÐ5FÔ%GÑ!GÑGð  õ 05¬y¸ÈaÐ/PÑ/PÔ/PÑ,�˜}ðQð Qð Qñ Qô Qð Qð Qð Qð Qð Qð Qøøøð Qð Qð Qð Qð %2ð Xð XÐ Ø(ð Xð X�CØ*¨3Ô/×6Ò6°xÀ´}ÐEUÔ7VÑWÔWÐWÐWðXð %ð Wð W�Ý.3¬kÐ:PÐQTÔ:UÑ.VÔ.VÐ& sÑ+Ð+ð  Ÿ:š:Ð&fÐ&fÐ&fÐ&fÐ&fÐ&fÐXeÐ&fÑ&fÔ&fÑgÔgØ$ôˆLð  Ÿ:š:Ð&<Ñ=Ô=Ð>RÔSˆLàÔ# |Ô'9Ò9Ð9Ð9Ð9ØÔ# |Ô'9Ò9Ð9Ð9Ð9õ Ô,¨Z¸ÑFÔFˆJÝÔ,¨Z¸ÑFÔFˆJÝ”V˜DÔ0°:Ñ=Ñ>Ô>ÅÄÈ
ÐUYÔUiÑHiÑAjÔAjÑjˆFØ—[’[‘]”]ˆFð �˜Z™œÒ(Ð(Ø—’Ñ!Ô!Ð!ùàˆs$   ¾A B*Â*B.Â1B.Å#?F.Æ.F2	Æ5F2	c                 óŠ  ‡ — ˆ fd„|D ¦   «         }|\  }}t          j        ||¦  «        }t          j        |¦  «        }|dt          j        |j        d|j        iŽz  z
  }t          j        |d¬¦  «        \  }	}
t          j	        ‰ j
        |z
  ¦  «        t          j	        |	‰ j        z
  ¦  «        z   }|                     ¦   «         S )Nc                 óF   •— g | ]}‰                      |¦  «        d          ‘ŒS )r    )r   )r$   Úsentence_featurer   s     €r   ú
<listcomp>z@MegaBatchMarginLoss.forward_non_mini_batched.<locals>.<listcomp>e   s-   ø€ ÐmÐmÐmÐGW�—
’
Ð+Ñ,Ô,Ð-AÔBÐmÐmÐmr   r   r!   r+   r,   )r   r:   r2   Údiagonalr7   r>   r!   r;   r?   rA   r   r   rB   )r   r   r   ÚrepsÚembeddings_aÚembeddings_brI   Úpositive_scoresrJ   rK   Ú_rR   s   `           r   r   z,MegaBatchMarginLoss.forward_non_mini_batchedd   sÇ   ø€ ØmÐmÐmÐmÐ[lÐmÑmÔmˆØ%)Ñ"ˆ�låÔ)¨,¸ÑEÔEˆ
Ýœ.¨Ñ4Ô4ˆØ$Ø•”	˜:Ô+ÐF°JÔ4EÐFÐFÑFñ
ˆõ !œ9 _¸!Ð<Ñ<Ô<Ñˆ�qÝ”˜Ô,¨Ñ>Ñ?Ô?Å!Ä&ÈÐY]ÔYmÑImÑBnÔBnÑnˆØ�{Š{‰}Œ}Ðr   )r   r   Tr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚfloatÚboolÚintr   r   r   Ústrr   r   r   Ú__classcell__)r   s   @r   r
   r
      sð   ø€ € € € € ð
ð 
ð "%Ø!$Ø)-Ø!ðpð pð ðpð ð	pð
 #'ðpð ðpð pð pð pð pð pð,6°h¸tÀCÈÀKÔ?PÔ6Qð 6Ð[að 6ð 6ð 6ð 6ðr¸(À4ÈÈVÈÔCTÔ:Uð Ð_eð ð ð ð ð ð ð ð r   r
   )Ú r   r2   r   r   Útypingr   r   Útorch.nn.functionalÚ
functionalr?   ÚModuler
   r#   r   r   ú<module>rk      s«   ðØ Ð Ð Ð Ð Ð Ø €€€Ø Ð Ð Ð Ð Ð Ð Ð Ø !Ð !Ð !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð Ð Ð Ð ðgð gð gð gð g˜"œ)ñ gô gð gð gð gr   