
    rh                    r    d dl mZ d dlZd dlmZ d dlZd dlmZ  ej                  e	      Z
 G d de      Zy)    )annotationsN)Literal)Modulec                       e Zd ZU dZdZddgZg dZded<   	 	 	 	 d	 	 	 	 	 	 	 	 	 d fdZ	 	 	 	 dd	Z	d
dddZ
ddZddZ xZS )SpladePoolingaL  
    SPLADE Pooling module for creating the sparse embeddings.

    This module implements the SPLADE pooling mechanism that:

    1. Takes token logits from a masked language model (MLM).
    2. Applies a sparse transformation using an activation function followed by log1p (i.e., log(1 + activation(MLM_logits))).
    3. Applies a pooling strategy `max` or `sum` to produce sparse embeddings.

    The resulting embeddings are highly sparse and capture lexical information,
    making them suitable for efficient information retrieval.

    Args:
        pooling_strategy (str): Pooling method across token dimensions.
            Choices:
                - `sum`: Sum pooling (used in original SPLADE see https://arxiv.org/pdf/2107.05720).
                - `max`: Max pooling (used in SPLADEv2 and later models see https://arxiv.org/pdf/2109.10086 or https://arxiv.org/pdf/2205.04733).
        activation_function (str): Activation function applied before log1p transformation.
            Choices:
                - `relu`: ReLU activation (standard in all Splade models).
                - `log1p_relu`: log(1 + ReLU(x)) variant used in Opensearch Splade models, see https://arxiv.org/pdf/2504.14839.
        word_embedding_dimension (int, optional): Dimensionality of the output embeddings (if needed).
        chunk_size (int, optional): Chunk size along the sequence length dimension (i.e., number of tokens per chunk).
            If None, processes entire sequence at once. Using smaller chunks the reduces memory usage but may
            lower the training and inference speed. Default is None.
    )summaxrelu
log1p_relu)pooling_strategyactivation_functionword_embedding_dimensionz	list[str]config_keysc                    t         |           || _        || j                  vrt	        d      || _        || j                  vrt	        d      || _        || _        y )Nz.pooling_strategy must be either 'max' or 'sum'z9activation_function must be either 'relu' or 'log1p_relu')	super__init__r   SPLADE_POOLING_MODES
ValueErrorr   SPLADE_ACTIVATIONr   
chunk_size)selfr   r   r   r   	__class__s        /var/www/html/ai-insurance-compliance-backend/venv/lib/python3.12/site-packages/sentence_transformers/sparse_encoder/models/SpladePooling.pyr   zSpladePooling.__init__-   sc     	 04#<#<<MNN#6 d&<&<<XYY(@%$    c                   |d   }|d   }|j                  d      j                  |j                        }|j                  \  }}}|j                  }| j
                  dk(  r/t        j                  ||ft        d      |j                  |      }	nL| j
                  dk(  r%t        j                  ||f|j                  |      }	nt        d| j
                         | j                  | j                  d
k  r|n| j                  }
t        d
||
      D ]   }	 |d	d	|||
z   d	d	f   }|d	d	|||
z   d	d	f   }||z  }|j                         }| j                  s|j                         }n|j!                         }| j"                  dk(  r-| j                  s|j                         }n|j!                         }| j
                  dk(  r1t        j$                  |d      d
   }t        j&                  |	|      }	nt        j(                  |d      }|	|z  }	 | j4                  |	j                  d   | _        |	|d<   |S # t*        $ r7}dt-        |      j/                         v rt0        j3                  d       |d	}~ww xY w)a}  
        Forward pass of the model.
        Args:
            features: Dictionary containing input features. Expects:
                - 'token_embeddings': MLM logits (shape: batch_size, seq_length, vocab_size).
                - 'attention_mask': Attention mask (shape: batch_size, seq_length).
        Returns:
            Dictionary containing SPLADE pooled embeddings
        token_embeddingsattention_maskr	   z-inf)dtypedevicer   zUnsupported pooling_strategy: Nr   r      )dimzout of memoryzRan out of memory during SpladePooling. Consider setting or decreasing the 'chunk_size' parameter. Smaller chunk_size reduces memory usage at the cost of slower processing, but will allow for larger batch sizes.sentence_embedding)	unsqueezetor   shaper    r   torchfullfloatzerosr   r   rangerelu_traininglog1p_log1pr   r	   maximumr   RuntimeErrorstrlowerloggerwarningr   )r   features
mlm_logitsr   attention_mask_expanded
batch_sizeseq_lenvocab_sr    pooled_scoresr   icurrent_chunk_logitscurrent_chunk_maskmasked_current_chunk_logitscurrent_chunk_transformedchunk_pooledes                     r   forwardzSpladePooling.forward>   s    01
!"23 #1":":2">"A"A*BRBR"S'1'7'7$
GW""   E)!JJ
G'<eFmS]ScSclrsM""e+!KKW(=ZEUEU^deM=d>S>S=TUVV "&!8DOOq<PWW[WfWf
q':. !	A '1!QZ5G2J'K$%<QA
N@RTU=U%V".BEW.W+,G,M,M,O)}}0I0P0P0R-0I0O0O0Q-++|;==4M4T4T4V14M4S4S4U1((E1#(99-FA#Nq#QL$)MM-$NM#(99-FA#NL!\1M1!	F ((0,9,?,?,BD))6%&   "c!flln4NNA s   C<H<<	I<2I77I<T)safe_serializationc               &    | j                  |       y )N)save_config)r   output_pathrE   argskwargss        r   savezSpladePooling.save   s    %r   c                *    d| j                          dS )NzSpladePooling())get_config_dictr   s    r   __repr__zSpladePooling.__repr__   s     4 4 67q99r   c                    | j                   S )z|Get the dimension of the sentence embedding.

        Returns:
            int: Dimension of the sentence embedding
        )r   rO   s    r    get_sentence_embedding_dimensionz.SpladePooling.get_sentence_embedding_dimension   s     ,,,r   )r	   r
   NN)
r   zLiteral['max', 'sum']r   zLiteral['relu', 'log1p_relu']r   
int | Noner   rS   returnNone)r6   dict[str, torch.Tensor]rT   rV   )rH   r2   rE   boolrT   rU   )rT   r2   )rT   int)__name__
__module____qualname____doc__r   r   r   __annotations__r   rD   rK   rP   rR   __classcell__)r   s   @r   r   r      s    6 *.dKd 38=C/3!%%/% ;% #-	%
 % 
%"G)G 
!GR HL &:-r   r   )
__future__r   loggingtypingr   r'   #sentence_transformers.models.Moduler   	getLoggerrY   r4   r    r   r   <module>re      s4    "    6			8	$F-F F-r   