
    rh                    j    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  G d dej                        Z
y)    )annotations)IterableN)Tensornn)SparseEncoderc                  D     e Zd Zdd fdZddZddZed	d       Z xZS )
	FlopsLossc                >    t         |           || _        || _        y)a  
        FlopsLoss implements a regularization technique to promote sparsity in sparse encoder models.
        It calculates the squared L2 norm of the mean embedding vector, which helps reduce the number of floating-point
        operations (FLOPs) required during inference by encouraging more zero values in the embeddings.
        It can use a threshold to ignore embeddings with too few non-zero (active) elements.

        This loss is used as a regularization component within other losses like :class:`SpladeLoss` rather than
        being used as a standalone loss function.

        Args:
            model: SparseEncoder model to be regularized
            threshold: Optional threshold for the number of non-zero (active) elements in the embeddings.
                If specified, only embeddings with more than this number of non-zero (active) elements will be considered.
                This can help to ignore embeddings that are too sparse and may not contribute meaningfully to the loss.

        References:
            - For further details, see: https://arxiv.org/pdf/2004.05665 for the general FLOPS loss and https://arxiv.org/pdf/2504.14839 for FLOPS with thresholds, a.k.a. FLOPS with l0 masking.

        Relations:
            - Used as a component within :class:`SpladeLoss` to regularize both query and document embeddings

        Example:
            - This loss is typically used within the :class:`SpladeLoss` class, which combines it with other loss components.

        N)super__init__model	threshold)selfr   r   	__class__s      /var/www/html/ai-insurance-compliance-backend/venv/lib/python3.12/site-packages/sentence_transformers/sparse_encoder/losses/FlopsLoss.pyr   zFlopsLoss.__init__   s    4 	
"    c                    t        d      )NzaFlopsLoss is not intended to be used directly. Use it as a regulizer within the SpladeLoss class.)NotImplementedError)r   sentence_featureslabelss      r   forwardzFlopsLoss.forward*   s    !o
 	
r   c                    | j                   F|dk7  j                  d      }|| j                   kD  j                         }||j                  d      z  }t	        j                  t	        j
                  |d      dz        S )Nr      )dim   )r   sumfloat	unsqueezetorchmean)r   
embeddingsl0_normmasks       r   compute_loss_from_embeddingsz&FlopsLoss.compute_loss_from_embeddings/   sl    >>%!Q+++2Gdnn,335D#dnnQ&77JyyJA6!;<<r   c                     y)Na(  
@article{paria2020minimizing,
    title={Minimizing flops to learn efficient sparse representations},
    author={Paria, Biswajit and Yeh, Chih-Kuan and Yen, Ian EH and Xu, Ning and Ravikumar, Pradeep and P{'o}czos, Barnab{'a}s},
    journal={arXiv preprint arXiv:2004.05665},
    year={2020}
}
 )r   s    r   citationzFlopsLoss.citation7   s    r   )N)r   r   r   zfloat | NonereturnNone)r   zIterable[dict[str, Tensor]]r   r   r(   r   )r!   zlist[torch.Tensor]r(   ztorch.Tensor)r(   str)	__name__
__module____qualname__r   r   r$   propertyr'   __classcell__)r   s   @r   r	   r	      s&    #<

=  r   r	   )
__future__r   collections.abcr   r   r   r   2sentence_transformers.sparse_encoder.SparseEncoderr   Moduler	   r&   r   r   <module>r4      s$    " $   L5		 5r   