ó
    >:j„ñ  ã                  óv  • S SK Jr  S SKrS SKrS SKrS SKrS SKJr  S SKJ	r	  S SK
JrJrJr  S SKrS SKJ
r  S SKrS SKJrJr  S SKJr  S SKJrJr  S S	KJr  S S
KJr  S SKJr  S SK J!r!  S SK"J#r#  S SK$J%r%  S SK&J'r'  S SK(J)r)  S SK*J+r+J,r,  S SK-J.r.J/r/  S SK0J1r1  S SK2J3r3  \Rh                  " \55      r6 " S S\!5      r7g)é    )ÚannotationsN)ÚCallable)ÚQueue)ÚAnyÚLiteralÚoverload)ÚTensorÚnn)Útrange)Ú
AutoConfigÚPretrainedConfig)ÚPreTrainedModel)Úlogging)Ú
deprecated)Ú	BaseModel)Ú	TextInput)ÚTransformer)ÚPooling)ÚSparseEncoderModelCardData)ÚSparseAutoEncoderÚSpladePooling)Úbatch_to_deviceÚselect_max_active_dims)Údeprecated_kwargs)ÚSimilarityFunctionc                  ó  ^ • \ rS rSr% Sr\rSrS\S'   SSS.r	S\S	'   S
r
\" SS9 S4SSSSSSSSSSSSSSSSS.                                   S5U 4S jjjj5       r\" SS9           S6                           S7S jj5       r\" SS9           S6                           S7S jj5       r\" SS9           S6                           S7S jj5       rS8U 4S jjrS9U 4S jjr\S:S j5       r\R(                      S;S j5       rS<S jr\S=S j5       r\S>S j5       r\S?S j5       r\S=S j5       r\      S>S j5       r\  S?S  j5       r    S@           SAS! jjr\          SBS" j5       rSCS# jr\" S$\S%9SCS& j5       r      SD                   SES' jjr        SF                     SGS( jjr!\SHS) j5       r"\SIU 4S* jj5       r#\#R(                  SJS+ j5       r#\SKU 4S, jj5       r$SLS- jr%\SCS. j5       r&\&R(                  SMS/ j5       r&\      SNS0 j5       r' S4     SOS1 jjr(SPS2 jr)S3r*U =r+$ )QÚSparseEncoderé#   a^  
Loads or creates a SparseEncoder model that can be used to map text to sparse embeddings.

Args:
    model_name_or_path (str, optional): If a filepath on disk, loads the model from that path. Otherwise, tries
        to download a pre-trained SparseEncoder model. If that fails, tries to construct a model from the
        Hugging Face Hub with that name. Defaults to None.
    modules (list[nn.Module], optional): A list of torch modules that are called sequentially. Can be used to
        create custom SparseEncoder models from scratch. Defaults to None.
    device (str, optional): Device (like ``"cuda"``, ``"cpu"``, ``"mps"``, ``"npu"``) that should be used for
        computation. If None, checks if a GPU can be used. Defaults to None.
    prompts (dict[str, str], optional): A dictionary with prompts for the model. The key is the prompt name,
        the value is the prompt text. The prompt text will be prepended before any text to encode. For example:
        ``{"query": "query: ", "passage": "passage: "}``. If a model has saved prompts, you can override
        them by passing your own, or pass ``{"query": "", "document": ""}`` to disable them.
        Defaults to None.
    default_prompt_name (str, optional): The name of the prompt that should be used by default. If not set,
        no prompt will be applied. Defaults to None.
    cache_folder (str, optional): Path to store models. Can also be set by the ``SENTENCE_TRANSFORMERS_HOME``
        environment variable. Defaults to None.
    trust_remote_code (bool, optional): Whether to allow for custom models defined on the Hub in their own
        modeling files. Only set to ``True`` for repositories you trust and in which you have read the code,
        as it will execute code present on the Hub on your local machine. Defaults to False.
    revision (str, optional): The specific model version to use. It can be a branch name, a tag name, or a
        commit id, for a stored model on Hugging Face. Defaults to None.
    local_files_only (bool, optional): Whether to only look at local files (i.e., do not try to download
        the model). Defaults to False.
    token (bool or str, optional): Hugging Face authentication token to download private models.
        Defaults to None.
    model_kwargs (dict[str, Any], optional): Keyword arguments passed to the underlying Hugging Face
        Transformers model via ``AutoModel.from_pretrained``. Particularly useful options include:

        - ``torch_dtype``: Override the default ``torch.dtype`` and load the model under a specific
          dtype. Can be ``torch.float16``, ``torch.bfloat16``, ``torch.float32``, or ``"auto"`` to
          use the dtype from the model's ``config.json``.
        - ``attn_implementation``: The attention implementation to use. For example ``"eager"``,
          ``"sdpa"``, or ``"flash_attention_2"``. If you ``pip install kernels``, then
          ``"flash_attention_2"`` should work without having to install ``flash_attn``. It is
          frequently the fastest option. Defaults to ``"sdpa"`` when available (torch>=2.1.1).
        - ``device_map``: Device map for model parallelism, e.g. ``"auto"``.
        - ``provider``: For ``backend="onnx"``, the ONNX execution provider
          (e.g. ``"CUDAExecutionProvider"``).
        - ``file_name``: For ``backend="onnx"`` or ``"openvino"``, the filename to load
          (e.g. for optimized or quantized models).
        - ``export``: For ``backend="onnx"`` or ``"openvino"``, whether to export the model to the
          backend format. Also set automatically if the exported file doesn't exist.

        See the `PreTrainedModel.from_pretrained
        <https://huggingface.co/docs/transformers/en/main_classes/model#transformers.PreTrainedModel.from_pretrained>`_
        documentation for more details. Defaults to None.
    processor_kwargs (dict[str, Any], optional): Keyword arguments passed to the Hugging Face Transformers
        processor/tokenizer via ``AutoProcessor.from_pretrained``. See the `AutoTokenizer.from_pretrained
        <https://huggingface.co/docs/transformers/en/model_doc/auto#transformers.AutoTokenizer.from_pretrained>`_
        documentation for more details. Defaults to None.
    config_kwargs (dict[str, Any], optional): Keyword arguments passed to the Hugging Face Transformers
        config via ``AutoConfig.from_pretrained``. See the `AutoConfig.from_pretrained
        <https://huggingface.co/docs/transformers/en/model_doc/auto#transformers.AutoConfig.from_pretrained>`_
        documentation for more details. Defaults to None.
    model_card_data (:class:`~sentence_transformers.sparse_encoder.model_card.SparseEncoderModelCardData`, optional):
        A model card data object that contains information about the model. Used to generate a model card
        when saving the model. If not set, a default model card data object is created. Defaults to None.
    backend (str, optional): The backend to use for inference. Can be ``"torch"`` (default), ``"onnx"``,
        or ``"openvino"``. Defaults to ``"torch"``.
    similarity_fn_name (str or SimilarityFunction, optional): The name of the similarity function to use.
        Valid options are ``"cosine"``, ``"dot"``, ``"euclidean"``, and ``"manhattan"``. If not set, it is
        automatically set to ``"cosine"`` when :attr:`similarity` or :attr:`similarity_pairwise` are first
        accessed. Defaults to None.
    max_active_dims (int, optional): The maximum number of active (non-zero) dimensions in the output of the
        model. ``None`` means no limit, which can be slow or memory-intensive if your model wasn't (yet)
        finetuned to high sparsity. Defaults to None.

Example:
    ::

        from sentence_transformers import SparseEncoder

        # Load a pre-trained SparseEncoder model
        model = SparseEncoder('naver/splade-cocondenser-ensembledistil')

        # Encode some texts
        sentences = [
            "The weather is lovely today.",
            "It's so sunny outside!",
            "He drove to the stadium.",
        ]
        embeddings = model.encode(sentences)
        print(embeddings.shape)
        # (3, 30522)

        # Get the similarity scores between all sentences
        similarities = model.similarity(embeddings, embeddings)
        print(similarities)
        # tensor([[   35.629,     9.154,     0.098],
        #         [    9.154,    27.478,     0.019],
        #         [    0.098,     0.019,    29.553]])
zsparse-encoderú
str | NoneÚ default_huggingface_organizationN)ÚqueryÚdocumentzdict[str, str | None]Ú_default_promptsÚsparse_encoder_model_idÚprocessor_kwargs)Útokenizer_kwargsFÚtorch)ÚmodulesÚdeviceÚpromptsÚdefault_prompt_nameÚcache_folderÚtrust_remote_codeÚrevisionÚlocal_files_onlyÚtokenÚmodel_kwargsr%   Úconfig_kwargsÚmodel_card_dataÚbackendÚsimilarity_fn_nameÚmax_active_dimsc               ó&  >• UU l         [        TU ]	  UUUUUUU	U
UUUUUUUS9  U   Ub  US::  a  [        SU S35      eUU l        UcJ  U R
                  R                  5        H+  n[        U[        5      (       d  M  UR                  U l          g    g g )N)Úmodel_name_or_pathr(   r)   r,   r-   r.   r/   r0   r1   r%   r2   r3   r4   r*   r+   r   z0max_active_dims must be a positive integer, got Ú.)
r5   ÚsuperÚ__init__Ú
ValueErrorr6   Ú_modulesÚvaluesÚ
isinstancer   Úk)Úselfr8   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r%   r2   r3   r4   r5   r6   ÚmoduleÚ	__class__s                      €Úg/home/mande/repo/quber/.venv/lib/python3.13/site-packages/sentence_transformers/sparse_encoder/model.pyr;   ÚSparseEncoder.__init__Š   s½   ø€ ð0 #5ˆÔä‰ÑØ1ØØØ%Ø/ØØ-ØØ%Ø-Ø'Ø+ØØØ 3ð 	ñ 	
ñ$ 	àÑ&¨?¸aÓ+?ÜÐOÐP_ÐO`Ð`aÐbÓcÐcØ.ˆÔØÑ"ØŸ-™-×.Ñ.Ö0�Ü˜fÔ&7×8Ó8Ø+1¯8©8�DÔ(Ùò 1ð #ó    Úinputs)Ú	sentencesc                ór   • Uc  Uc  SU R                   ;   a  SnU R                  " SUUUUUUUUU	U
UUSS.UD6$ )aw  
Computes embeddings specifically optimized for query representation.

This method is a specialized version of :meth:`encode` that differs in exactly two ways:

1. If no ``prompt_name`` or ``prompt`` is provided, it uses a predefined "query" prompt,
   if available in the model's ``prompts`` dictionary.
2. It sets the ``task`` to "query". If the model has a :class:`~sentence_transformers.base.modules.Router`
   module, it will use the "query" task type to route the input through the appropriate submodules.

.. tip::

    Adjusting ``batch_size`` can significantly improve processing speed. The optimal value depends on your
    hardware, model size, precision, and input length. Benchmark a few batch sizes on a small subset of your
    data to find the best value.

All other parameters are identical to :meth:`encode`. See :meth:`encode` for the full parameter documentation.

Example:
    ::

        from sentence_transformers import SparseEncoder

        # Load a pre-trained SparseEncoder model
        model = SparseEncoder("naver/splade-cocondenser-ensembledistil")

        # Encode some texts
        queries = [
            "What are the effects of climate change?",
            "History of artificial intelligence",
            "Technical specifications product XYZ",
        ]
        embeddings = model.encode_query(queries)
        print(embeddings.shape)
        # (3, 30522)
r!   ©rG   Úprompt_nameÚpromptÚ
batch_sizeÚshow_progress_barÚconvert_to_tensorÚconvert_to_sparse_tensorÚsave_to_cpur)   r6   ÚpoolÚ
chunk_sizeÚtask© ©r*   Úencode)rA   rG   rK   rL   rM   rN   rO   rP   rQ   r)   r6   rR   rS   Úkwargss                 rD   Úencode_queryÚSparseEncoder.encode_queryÁ   sf   € ðj Ñ 6¡>°gÀÇÁÓ6MØ!ˆKà�{Š{ð 
ØØ#ØØ!Ø/Ø/Ø%=Ø#ØØ+ØØ!Øñ
ð ñ
ð 	
rF   c                ó†   • Uc  Uc  S H  nXàR                   ;   d  M  Un  O   U R                  " SUUUUUUUUU	U
UUSS.UD6$ )a,  
Computes embeddings specifically optimized for document/passage representation.

This method is a specialized version of :meth:`encode` that differs in exactly two ways:

1. If no ``prompt_name`` or ``prompt`` is provided, it uses the first available prompt from the following
   candidates: ``"document"``, ``"passage"``, ``"corpus"`` (checked in that order).
2. It sets the ``task`` to "document". If the model has a :class:`~sentence_transformers.base.modules.Router`
   module, it will use the "document" task type to route the input through the appropriate submodules.

.. tip::

    Adjusting ``batch_size`` can significantly improve processing speed. The optimal value depends on your
    hardware, model size, precision, and input length. Benchmark a few batch sizes on a small subset of your
    data to find the best value.

All other parameters are identical to :meth:`encode`. See :meth:`encode` for the full parameter documentation.

Example:
    ::

        from sentence_transformers import SparseEncoder

        # Load a pre-trained SparseEncoder model
        model = SparseEncoder("naver/splade-cocondenser-ensembledistil")

        # Encode some texts
        sentences = [
            "This research paper discusses the effects of climate change on marine life.",
            "The article explores the history of artificial intelligence development.",
            "This document contains technical specifications for the new product line.",
        ]
        embeddings = model.encode_document(sentences)
        print(embeddings.shape)
        # (3, 30522)
)r"   ÚpassageÚcorpusr"   rJ   rU   rV   )rA   rG   rK   rL   rM   rN   rO   rP   rQ   r)   r6   rR   rS   rX   Úcandidate_prompt_names                  rD   Úencode_documentÚSparseEncoder.encode_document
  sv   € ðj Ñ 6¡>Û)JÐ%Ø(¯L©LÕ8Ø"7�KÙñ *Kð
 �{Š{ð 
ØØ#ØØ!Ø/Ø/Ø%=Ø#ØØ+ØØ!Øñ
ð ñ
ð 	
rF   c                óP  • Uc5  [         R                  5       [        R                  [        R                  4;   nUS::  a  [        SU S35      eU R                  U5      nU(       a  U/nOO[        U[        5      (       d:  [        U[        R                  5      (       a  UR                  5       O
[        U5      nU R                  5       n[        U5      [        U5      -
  S1-
  =n(       as  [        U R                  R                   S[        U5       S3U(       a#  SU R                  R                   S	U S3-   5      eSU R                  R                   S
3-   5      eUc$  [        U	[        5      (       a<  [!        U	5      S:”  a-  U R"                  " SUUUU	UUUUUUSU
S.UD6nU(       a  US   nU$ U R%                  X25      nU	c  U R&                  n	U R)                  U	5        U R+                  5         U
b  U
OU R,                  n
[/        U5      nU
b  U
US'   / n[        R0                  " U Vs/ s H  nU R3                  U5      * PM     sn5      nU R5                  5       (       a  U R7                  U5      nU Vs/ s H  nUU   PM
     nn[9        S[!        U5      USU(       + S9 H¬  nUUUU-    nU R:                  " U4SU0UD6n[=        UU	5      n[>        R@                  " 5          U RB                  " U40 UD6S   nU
b
  [E        UU
S9nSSS5        U(       a  WRG                  5       nU(       a  WRI                  5       nURK                  W5        M®     [        R0                  " U5       Vs/ s H  nUU   PM
     nnU(       as  [!        U5      S:X  aN  [>        RL                  " / U R&                  S9nU(       a  URG                  5       nU(       a  URI                  5       nO[>        RN                  " U5      nU(       a  US   nU$ s  snf s  snf ! , (       d  f       GN= fs  snf )ak  
Computes sparse sentence embeddings.

.. tip::

    If you are unsure whether you should use :meth:`encode`, :meth:`encode_query`, or :meth:`encode_document`,
    your best bet is to use :meth:`encode_query` and :meth:`encode_document` for Information Retrieval tasks
    with clear query and document/passage distinction, and use :meth:`encode` for all other tasks.

    Note that :meth:`encode` is the most general method and can be used for any task, including Information
    Retrieval, and that if the model was not trained with predefined prompts and/or task types, then all three
    methods will return identical embeddings.

.. tip::

    Adjusting ``batch_size`` can significantly improve processing speed. The optimal value depends on your
    hardware, model size, precision, and input length. Benchmark a few batch sizes on a small subset of your
    data to find the best value.

Args:
    inputs (Union[str, List[str]]): The texts to embed.
    prompt_name (str, optional): The name of the prompt to use for encoding. Must be a key in the ``prompts``
        dictionary, which is either set in the constructor or loaded from the model configuration. For example if
        ``prompt_name`` is "query" and the ``prompts`` is {"query": "query: ", ...}, then the sentence "What
        is the capital of France?" will be encoded as "query: What is the capital of France?" because the sentence
        is appended to the prompt. If ``prompt`` is also set, this argument is ignored. Defaults to None.
    prompt (str, optional): The prompt to use for encoding. For example, if the prompt is "query: ", then the
        sentence "What is the capital of France?" will be encoded as "query: What is the capital of France?"
        because the sentence is appended to the prompt. If ``prompt`` is set, ``prompt_name`` is ignored.
        Defaults to None.
    batch_size (int, optional): The batch size used for the computation. Defaults to 32.
    show_progress_bar (bool, optional): Whether to output a progress bar when encoding. Defaults to None,
        in which case the progress bar will be shown if the logger's effective level is INFO or DEBUG.
    convert_to_tensor (bool, optional): Whether the output should be a single stacked tensor (True) or a list
        of individual tensors (False). Sparse tensors may be challenging to slice, so this allows you to
        output lists of tensors instead. Defaults to True.
    convert_to_sparse_tensor (bool, optional): Whether the output should be in the format of a sparse (COO) tensor.
        Defaults to True.
    save_to_cpu (bool, optional): Whether the output should be moved to cpu or stay on the device it has been
        computed on. Defaults to False.
    device (str, torch.device, list, or None, optional): Device(s) to use for computation. Can be:

        - A single device string (e.g., "cuda:0", "cpu") for single-process encoding
        - A list of device strings (e.g., ["cuda:0", "cuda:1"], ["cpu", "cpu", "cpu", "cpu"]) to distribute
          encoding across multiple processes
        - None to auto-detect available device for single-process encoding

        If a list is provided, multi-process encoding will be used. Defaults to None.
    max_active_dims (int, optional): The maximum number of active (non-zero) dimensions in the output of the
        model. ``None`` means the value from the model's config will be used. Defaults to None. If also None in
        the model's config, there will be no limit on the number of active dimensions, which can be slow or
        memory-intensive if your model wasn't (yet) finetuned to high sparsity.
    pool (dict, optional): A pool created by :meth:`start_multi_process_pool` for multi-process encoding.
        If provided, the encoding will be distributed across multiple processes. This is recommended for large
        datasets and when multiple GPUs are available. Defaults to None.
    chunk_size (int, optional): Size of chunks for multi-process encoding. Only used with multiprocessing, i.e.
        when ``pool`` is not None or ``device`` is a list. If None, a sensible default is calculated.
        Defaults to None.

Returns:
    Union[list[Tensor], Tensor]: By default, a 2d torch sparse tensor with shape [num_inputs, output_dimension]
    is returned. If only one string input is provided, then the output is a 1d tensor with shape
    [output_dimension]. If ``convert_to_tensor`` is False, a list of individual tensors is returned instead.

Example:
    ::

        from sentence_transformers import SparseEncoder

        # Load a pre-trained SparseEncoder model
        model = SparseEncoder("naver/splade-cocondenser-ensembledistil")

        # Encode some texts
        sentences = [
            "The weather is lovely today.",
            "It's so sunny outside!",
            "He drove to the stadium.",
        ]
        embeddings = model.encode(sentences)
        print(embeddings.shape)
        # (3, 30522)
Nr   z+batch_size must be a positive integer, got r9   rT   zZ.encode() has been called with additional keyword arguments that this model does not use: z. zAs per zA.get_model_kwargs(), the valid additional keyword arguments are: zQ.get_model_kwargs(), this model does not accept any additional keyword arguments.T)rG   rN   rR   r)   rS   rK   rL   rM   rO   rP   rQ   r6   r6   ÚBatches©ÚdescÚdisablerL   Úsentence_embedding)r6   )r)   rU   )(ÚloggerÚgetEffectiveLevelr   ÚINFOÚDEBUGr<   Úis_singular_inputr?   ÚlistÚnpÚndarrayÚtolistÚget_model_kwargsÚsetrC   Ú__name__ÚlenÚ_multi_processÚ_resolve_promptr)   ÚtoÚevalr6   ÚdictÚargsortÚ_input_lengthÚ_can_flatten_inputsÚ_interleave_sorted_indicesr   Ú
preprocessr   r'   Úinference_modeÚforwardr   Ú	to_sparseÚcpuÚextendÚtensorÚstack)rA   rG   rK   rL   rM   rN   rO   rP   rQ   r)   r6   rR   rS   rX   rk   r1   Úunused_kwargsÚ
embeddingsÚforward_kwargsÚall_embeddingsÚsenÚlength_sorted_idxÚidxÚinputs_sortedÚstart_indexÚinputs_batchÚfeaturess                              rD   rW   ÚSparseEncoder.encodeV  s/  € ðF Ñ$Ü &× 8Ñ 8Ó :Ü—‘Ü—‘ð?ñ !Ðð
 ˜‹?ÜÐJÈ:È,ÐVWÐXÓYÐYð !×2Ñ2°6Ó:ÐÞØ�X‰FÜ˜F¤D×)Ñ)ä(2°6¼2¿:¹:×(FÑ(F�V—]‘]”_ÌDÐQWËLˆFð ×,Ñ,Ó.ˆÜ ›K¬#¨lÓ*;Ñ;¸v¸hÑFÐFˆ=ÕFÜØ—>‘>×*Ñ*Ð+ð  ,Fô  GKð  LYó  GZð  F[ð  []ð  ^ö $ð ˜dŸn™n×5Ñ5Ð6Ð6wð  yEð  xFð  FGð  Hñóð ð
 # 4§>¡>×#:Ñ#:Ð";ð  <Mð  Nñ	óð ð Ñ¤
¨6´4× 8Ñ 8¼SÀ»[È1»_Ø×,Ò,ð Øà"3àØØ%à'ØØ%Ø"3Ø)AØ Ø /ñð  ñ!ˆJö$ !Ø'¨™]�
ØÐà×%Ñ% fÓ:ˆà‰>Ø—[‘[ˆFà�‰�ŒØ�	‰	Œà-<Ñ-H™/Èd×NbÑNbˆä˜f›ˆØÑ&Ø0?ˆNÐ,Ñ-àˆÜŸJšJÉFÓ'SÊFÀS¨×);Ñ);¸CÓ)@Ó(@ÉFÑ'SÓTÐØ×#Ñ#×%Ñ%Ø $× ?Ñ ?Ð@QÓ RÐÙ0AÓBÒ0A¨˜ œÑ0AˆÐBä! !¤S¨£[°*À9ÐZkÔVkÔlˆKØ(¨°{ÀZÑ7OÐPˆLØ—’ |ÑM¸FÐMÀfÑMˆHÜ& x°Ó8ˆHä×%Ò%Õ'Ø!Ÿ\š\¨(ÑE°nÑEÐFZÑ[�
à"Ñ.Ü!7¸
ÐTcÑ!d�J÷	 (ö (Ø'×1Ñ1Ó3�
ÞØ'Ÿ^™^Ó-�
à×!Ñ! *Ö-ñ! mô$ :<¿ºÐDUÔ9VÓWÒ9V°#˜.¨Ô-Ñ9VˆÐWæÜ�>Ó" aÓ'Ü!&§¢¨b¸¿¹Ñ!E�Þ+Ø%3×%=Ñ%=Ó%?�NÞØ%3×%7Ñ%7Ó%9�Nøä!&§¢¨^Ó!<�æØ+¨AÑ.ˆNàÐùòM (Tùò C÷ (Ö'üò Xs   È-PÉ:PË'$PÍ.P#Ð
P 	c                ó>   >• [         TU ]  5       SU R                  0-  $ ©Nr5   )r:   Ú_get_model_configÚ_similarity_fn_name©rA   rC   s    €rD   r“   ÚSparseEncoder._get_model_config&  s(   ø€ Ü‰wÑ(Ó*Ø  $×":Ñ":ð.
ñ 
ð 	
rF   c                ón   >• [         TU ]  U5        U R                  c  UR                  SS 5      U l        g g r’   )r:   Ú_parse_model_configr”   Úgetr5   )rA   Úmodel_configrC   s     €rD   r˜   Ú!SparseEncoder._parse_model_config+  s7   ø€ Ü‰Ñ# LÔ1Ø×#Ñ#Ñ+Ø&2×&6Ñ&6Ð7KÈTÓ&RˆDÕ#ð ,rF   c                ó^   • U R                   c  [        R                  U l        U R                   $ )a­  Return the name of the similarity function used by :meth:`SparseEncoder.similarity` and :meth:`SparseEncoder.similarity_pairwise`.

Returns:
    Literal["cosine", "dot", "euclidean", "manhattan"]: The name of the similarity function.
        Defaults to "dot" when first accessed if not explicitly set.

Example:
    >>> model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
    >>> model.similarity_fn_name
    'dot'
)r”   r   ÚDOTr5   ©rA   s    rD   r5   Ú SparseEncoder.similarity_fn_name0  s*   € ð ×#Ñ#Ñ+Ü&8×&<Ñ&<ˆDÔ#Ø×'Ñ'Ð'rF   c                óÆ   • [        U[        5      (       a  UR                  nXl        Ub7  [        R                  " U5      U l        [        R                  " U5      U l        g g ©N)r?   r   Úvaluer”   Úto_similarity_fnÚ_similarityÚto_similarity_pairwise_fnÚ_similarity_pairwise©rA   r¢   s     rD   r5   rŸ   A  sS   € ô
 �eÔ/×0Ñ0Ø—K‘KˆEØ#(Ô àÑÜ1×BÒBÀ5ÓIˆDÔÜ(:×(TÒ(TÐUZÓ([ˆDÕ%ð rF   c                óP   • U  H   n[        U[        5      (       d  M  Xl          g   g)a  
Sets the ``include_prompt`` attribute in the pooling layer in the model, if there is one.

This is useful for models where the prompt should be excluded from the pooling strategy,
e.g. CSR models with a :class:`~sentence_transformers.sentence_transformer.modules.Pooling` layer.
N)r?   r   Úinclude_prompt)rA   r©   rB   s      rD   Úset_pooling_include_promptÚ(SparseEncoder.set_pooling_include_promptN  s$   € ó ˆFÜ˜&¤'×*Ó*Ø(6Ô%Ùò rF   c                ó   • g r¡   rU   ©rA   Úembeddings1Úembeddings2s      rD   Ú
similarityÚSparseEncoder.similarityZ  s   € ØNQrF   c                ó   • g r¡   rU   r­   s      rD   r°   r±   ]  s   € ØpsrF   c                ó2   • U R                     U R                  $ )aI  
Compute the similarity between two collections of embeddings. The output will be a matrix with the similarity
scores between all embeddings from the first parameter and all embeddings from the second parameter. This
differs from `similarity_pairwise` which computes the similarity between each pair of embeddings.
This method supports only embeddings with fp32 precision and does not accommodate quantized embeddings.

Args:
    embeddings1 (Union[Tensor, ndarray]): [num_embeddings_1, embedding_dim] or [embedding_dim]-shaped numpy array or torch tensor.
    embeddings2 (Union[Tensor, ndarray]): [num_embeddings_2, embedding_dim] or [embedding_dim]-shaped numpy array or torch tensor.

Returns:
    Tensor: A [num_embeddings_1, num_embeddings_2]-shaped torch tensor with similarity scores.

Example:
    ::

        >>> model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
        >>> sentences = [
        ...     "The weather is so nice!",
        ...     "It's so sunny outside.",
        ...     "He's driving to the movie theater.",
        ...     "She's going to the cinema.",
        ... ]
        >>> embeddings = model.encode(sentences)
        >>> model.similarity(embeddings, embeddings)
        tensor([[   30.953,    12.871,     0.000,     0.011],
                [   12.871,    27.505,     0.580,     0.578],
                [    0.000,     0.580,    36.068,    15.301],
                [    0.011,     0.578,    15.301,    39.466]])
        >>> model.similarity_fn_name
        "dot"
        >>> model.similarity_fn_name = "cosine"
        >>> model.similarity(embeddings, embeddings)
        tensor([[    1.000,     0.441,     0.000,     0.000],
                [    0.441,     1.000,     0.018,     0.018],
                [    0.000,     0.018,     1.000,     0.406],
                [    0.000,     0.018,     0.406,     1.000]])
)r5   r¤   rž   s    rD   r°   r±   `  s   € ðR 	×ÒØ×ÑÐrF   c                ó   • g r¡   rU   r­   s      rD   Úsimilarity_pairwiseÚ!SparseEncoder.similarity_pairwiseŒ  s   € ØWZrF   c                ó   • g r¡   rU   r­   s      rD   rµ   r¶   �  s   € ð rF   c                ó2   • U R                     U R                  $ )a,  
Compute the similarity between two collections of embeddings. The output will be a vector with the similarity
scores between each pair of embeddings.
This method supports only embeddings with fp32 precision and does not accommodate quantized embeddings.

Args:
    embeddings1 (Union[Tensor, ndarray]): [num_embeddings, embedding_dim] or [embedding_dim]-shaped numpy array or torch tensor.
    embeddings2 (Union[Tensor, ndarray]): [num_embeddings, embedding_dim] or [embedding_dim]-shaped numpy array or torch tensor.

Returns:
    Tensor: A [num_embeddings]-shaped torch tensor with pairwise similarity scores.

Example:
    ::

        >>> model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
        >>> sentences = [
        ...     "The weather is so nice!",
        ...     "It's so sunny outside.",
        ...     "He's driving to the movie theater.",
        ...     "She's going to the cinema.",
        ... ]
        >>> embeddings = model.encode(sentences, convert_to_sparse_tensor=False)
        >>> model.similarity_pairwise(embeddings[::2], embeddings[1::2])
        tensor([12.871, 15.301])
        >>> model.similarity_fn_name
        "dot"
        >>> model.similarity_fn_name = "cosine"
        >>> model.similarity_pairwise(embeddings[::2], embeddings[1::2])
        tensor([0.441, 0.406])
)r5   r¦   rž   s    rD   rµ   r¶   ”  s   € ðH 	×ÒØ×(Ñ(Ð(rF   c           	     óü  • UR                  SS5      nSUS'   SnUc(  [        U[        5      (       a  U R                  U5      nSn UcG  [	        [
        R                  " [        U5      [        US   5      -  S-  5      S5      n[        US5      nUS	   n	US
   n
U(       a"  [
        R                  " [        U5      U-  5      OSn[        U5       H   nXÅ-  nXXÕ-    nU	R                  XÎU/5        M"     [        [        USU(       + S9 Vs/ s H  oúR                  5       PM     snS S9nU H   n[        US   [        5      (       d  M  US   e   U Vs/ s H  nUS   PM
     nnU(       a²  [        US   [        5      (       a)  [        [        R                  R!                  U5      5      nO�[        US   ["        R$                  5      (       a  ["        R&                  " U5      nOT[        US   [(        R*                  5      (       a  [(        R,                  " USS9nOU(       a  ["        R$                  " 5       nUU(       a  U R/                  U5        $ $ s  snf s  snf ! U(       a  U R/                  U5        f f = f)zìInternal method for multi-process encoding.

Distributes encoding across multiple processes using the provided pool or list of devices.
If a pool is not provided but ``device`` is a list, a pool is created and cleaned up automatically.
rO   FrN   TÚ	processesé
   iˆ  é   ÚinputÚoutputr   ÚChunksrc   c                ó   • U S   $ )Nr   rU   )Úxs    rD   Ú<lambda>Ú.SparseEncoder._multi_process.<locals>.<lambda>â  s   € ˜a šdrF   )Úkey)Úaxis)r™   r?   rl   Ústart_multi_process_poolÚminÚmathÚceilrs   ÚmaxÚrangeÚputÚsortedr   Ú	ExceptionÚ	itertoolsÚchainÚfrom_iterabler'   r	   Úcatrm   rn   ÚconcatenateÚstop_multi_process_pool)rA   rG   rN   rR   r)   rS   Úencode_kwargsrO   Úcreated_poolÚinput_queueÚoutput_queueÚ
num_chunksÚchunk_idÚchunk_startÚchunkÚ_Úoutput_listr¾   r†   s                      rD   rt   ÚSparseEncoder._multi_process»  s3  € ð *×-Ñ-Ð.AÀ5ÓIÐØ-2ˆÐ)Ñ*ð ˆØ‰<œJ v¬t×4Ñ4Ø×0Ñ0°Ó8ˆDØˆLð'	3ØÑ!Ü ¤§¢¬3¨v«;¼¸TÀ+Ñ=NÓ9OÑ+OÐRTÑ+TÓ!UÐW[Ó\�
Ü  ¨QÓ/�
à7;¸G±}ˆKØ8<¸X¹ˆLæ@FœŸš¤3 v£;°Ñ#;Ô<ÈAˆJÜ! *Ö-�Ø&Ñ3�Ø¨[Ñ-EÐF�Ø—‘ °-Ð @ÖAñ .ô
 !Ü-3°JÀXÐ[lÔWlÒ-mÓnÒ-m¨×!Ñ!Ö#Ñ-mÑnÙ"ñˆKó &�Ü˜f Q™i¬×3Ó3Ø  ™)�Oñ &ñ
 3>Ó>²+¨˜& œ)±+ˆJÐ>ÞÜ˜j¨™m¬T×2Ñ2Ü!%¤i§o¡o×&CÑ&CÀJÓ&OÓ!P‘JÜ 
¨1¡¬u¯|©|×<Ñ<Ü!&§¢¨:Ó!6‘JÜ 
¨1¡¬r¯z©z×:Ñ:Ü!#§¢°
ÀÑ!C�JøÞ"Ü"Ÿ\š\›^�
Øö Ø×,Ñ,¨TÕ2ð ùò/ oùò ?øö Ø×,Ñ,¨TÕ2ð ús2   ÁCI  ÄIÄ$"I  Å
I  ÅIÅ$CI  É
I  É I;c                óè  •   UR                  5       u  pEnUR                  " U4SU 0UD6n[        U[        R                  5      (       a*  UR
                  R                  S:w  a  UR                  5       nUR                  XG/5        M†  ! [        R                   a     g[         aJ  n[        R                  SU  SU 35         UR                  WU/5        O! [         a     Of = f SnAgSnAff = f)z‰Internal working process to encode sentences in multi-process setup.

Workers are terminated externally via ``stop_multi_process_pool``.
r)   r�   zError in worker process on z: N)r™   rW   r?   r'   r	   r)   Útyper�   rÌ   ÚqueueÚEmptyrÎ   rg   Úerror)	Útarget_deviceÚmodelr×   Úresults_queuerÚ   rG   rX   r†   Úes	            rD   Ú_multi_process_workerÚ#SparseEncoder._multi_process_workerû  sã   € ð ðØ+6¯?©?Ó+<Ñ(� &Ø"Ÿ\š\¨&ÑQ¸ÐQÈ&ÑQ�
Ü˜j¬%¯,©,×7Ñ7¸J×<MÑ<M×<RÑ<RÐV[Ó<[Ø!+§¡Ó!1�JØ×!Ñ! 8Ð"8Ô9ñ øô —;‘;ó ÙÜó Ü—‘Ð:¸=¸/ÈÈAÈ3ÐOÔPðØ!×%Ñ% x° mÕ4øÜ ó ÙðúäûðúsB   ƒBB ÂC1Â	C1Â'C,ÃCÃC,Ã
C$Ã!C,Ã#C$Ã$C,Ã,C1c                óÆ   • Sn[        U R                  R                  5       5       H7  nS H(  n[        X#S5      n[	        U5      (       d  M!  U" 5       n  O   Uc  M6    U$    U$ )aœ  
Returns the number of dimensions in the output of :meth:`SparseEncoder.encode`.

Unlike :class:`~sentence_transformers.sentence_transformer.model.SentenceTransformer`, sparse encoders do not support ``truncate_dim``,
so this returns the raw output dimension from the last module in the pipeline.

Returns:
    int or None: The number of dimensions in the output of ``encode``. If it's not known, it's ``None``.
N)Úget_embedding_dimensionÚ get_sentence_embedding_dimensionÚget_word_embedding_dimension)Úreversedr=   r>   ÚgetattrÚcallable)rA   Ú
output_dimrB   ÚnameÚmethods        rD   rì   Ú%SparseEncoder.get_embedding_dimension  sm   € ð ˆ
Ü˜tŸ}™}×3Ñ3Ó5Ö6ˆFó�ô
 ! ¨tÓ4�Ü˜F×#Ó#Ù!'£�JÙñð Ó%ØØÐñ 7ð ÐrF   z\The `get_sentence_embedding_dimension` method has been renamed to `get_embedding_dimension`.)Úcategoryc                ó"   • U R                  5       $ r¡   )rì   rž   s    rD   rí   Ú.SparseEncoder.get_sentence_embedding_dimension.  s   € ð
 ×+Ñ+Ó-Ð-rF   c
           
     ó   • UUUUS.n
0 U
EU=(       d    0 En0 U
EU=(       d    0 En0 U
EU	=(       d    0 En	[         R                  " U4SU0U	D6n[        S [        USS5      =(       d    /  5       5      nU(       a;  [	        USUUUU	U R
                  S9n[        R                  S5        [        S	S
9nXÞ/nOv[        R                  S5        [	        USUUUU	U R
                  S9n[        UR                  5       SS9n[        UR                  5       SUR                  5       -  SSS9nUUU/nU(       d  U R                  R                  XS9  U0 4$ )aÿ  
Creates a simple transformer-based model and returns the modules.
For models with a ForMaskedLM architecture, uses SpladePooling with 'max' strategy.
For regular Transformers, uses a CSR implementation (Pooling + SparseAutoEncoder) by default.

Args:
    model_name_or_path (str): The name or path of the pre-trained model.
    token (Optional[Union[bool, str]]): The token to use for the model.
    cache_folder (Optional[str]): The folder to cache the model.
    revision (Optional[str], optional): The revision of the model. Defaults to None.
    trust_remote_code (bool, optional): Whether to trust remote code. Defaults to False.
    local_files_only (bool, optional): Whether to use only local files. Defaults to False.
    model_kwargs (Optional[Dict[str, Any]], optional): Additional keyword arguments for the model. Defaults to None.
    processor_kwargs (Optional[Dict[str, Any]], optional): Additional keyword arguments for the processor/tokenizer. Defaults to None.
    config_kwargs (Optional[Dict[str, Any]], optional): Additional keyword arguments for the config. Defaults to None.
    has_modules (bool, optional): Whether the model has modules.json. Defaults to False.

Returns:
    tuple[list[nn.Module], dict[str, Any]]: The modules and an empty kwargs dict.
©r0   r-   r.   r/   Ú	cache_dirc              3  óB   #   • U  H  oR                  S 5      v •  M     g7f)ÚForMaskedLMN)Úendswith)Ú.0Úarchs     rD   Ú	<genexpr>Ú6SparseEncoder._load_default_modules.<locals>.<genexpr>c  s   é € ÐqÒDp¸DŸ=™=¨×7Ð7ÒDpùs   ‚ÚarchitecturesNz	fill-mask)Útransformer_taskrû   r1   r%   r2   r4   z.Detected MLM architecture, using SpladePoolingrÊ   )Úpooling_strategyz`No MLM architecture detected, using default Transformer + mean Pooling + SparseAutoEncoder (CSR)zfeature-extractionÚmean)Úpooling_modeé   é   i   ©Ú	input_dimÚ
hidden_dimr@   Úk_aux)r.   )r   Úfrom_pretrainedÚanyrð   r   r4   rg   Úinfor   r   rì   r   r3   Úset_base_model)rA   r8   r0   r,   r.   r-   r/   r1   r%   r2   Úshared_kwargsÚconfigÚis_mlm_modelÚtransformer_modelÚpooling_modelr(   ÚpoolingÚsaes                     rD   Ú_load_default_modulesÚ#SparseEncoder._load_default_modules5  sš  € ðB Ø!2Ø Ø 0ñ	
ˆð A˜-Ð@¨L×,>¸BÐ@ˆØH˜mÐHÐ0@×0FÀBÐHÐØB˜=ÐB¨]×-@¸bÐBˆä#-×#=Ò#=Øñ$
Ø*6ð$
Ø:Gñ$
ˆô ÑqÄGÈFÐTcÐeiÓDj×DpÐnpÐDpÓqÓqˆæä +Ø"Ø!,Ø&Ø)Ø!1Ø+ØŸ™ñ!Ðô �K‰KÐHÔIÜ)¸5ÑAˆMØ(Ð8‰Gô �K‰KØrôô !,Ø"Ø!5Ø&Ø)Ø!1Ø+ØŸ™ñ!Ðô Ð/×GÑGÓIÐX^Ñ_ˆGÜ#Ø!×9Ñ9Ó;Ø˜w×>Ñ>Ó@Ñ@ØØñ	ˆCð )¨'°3Ð7ˆGæØ× Ñ ×/Ñ/Ð0BÐ/ÑVØ˜ˆ{ÐrF   c                ó:  • U
S:w  a  U R                  UUUUUUUUU	S9	$ UUUUS.n0 UEU=(       d    0 En0 UEU=(       d    0 En0 UEU	=(       d    0 En	[        R                  S5        U R                  UUUUUUUUU	S9	u  oÀl        [        UR                  5       5      nSn[        U5       H&  n[        US5      (       d  M  UR                  5       n  O   Uc  [        S5      e[        USU-  US-  US	-  S
9nUR                  U5        SU l        XÀR                  4$ )a  Converts a non-SparseEncoder model into a SparseEncoder by appending a SparseAutoEncoder.

If ``model_type`` is ``"SentenceTransformer"``, loads the SentenceTransformer modules and appends a
SparseAutoEncoder on top. Otherwise, falls back to :meth:`_load_default_modules`.
ÚSentenceTransformer)r0   r,   r.   r-   r/   r1   r%   r2   rú   zWSentenceTransformer model found, appending SparseAutoEncoder on top to form a CSR modelNrì   zƒCannot determine the embedding dimension from the loaded modules. At least one module must have a `get_embedding_dimension` method.r  é   r
  )r  rg   r  Ú_load_config_modulesÚmodule_kwargsrl   r>   rï   Úhasattrrì   r<   r   ÚappendÚ_model_card_text)rA   r8   r0   r,   r.   r-   r/   r1   r%   r2   Ú
model_typer  r(   rò   rB   r  s                   rD   Ú_load_converted_modulesÚ%SparseEncoder._load_converted_modulesŽ  s„  € ð$ Ð.Ó.Ø×-Ñ-Ø"ØØ)Ø!Ø"3Ø!1Ø)Ø!1Ø+ð .ð 
ð 
ð Ø!2Ø Ø 0ñ	
ˆð A˜-Ð@¨L×,>¸BÐ@ˆØH˜mÐHÐ0@×0FÀBÐHÐØB˜=ÐB¨]×-@¸bÐBˆä�‰ÐmÔnØ&*×&?Ñ&?ØØØ%ØØ/Ø-Ø%Ø-Ø'ð '@ð 
'
Ñ#ˆÔ#ô �w—~‘~Ó'Ó(ˆàˆ
Ü˜wÖ'ˆFÜ�vÐ8×9Ó9Ø#×;Ñ;Ó=�
Ùñ (ð ÑÜðTóð ô  Ø Ø˜:‘~Ø˜A‰oØ ‘/ñ	
ˆð 	�‰�sÔà $ˆÔØ×*Ñ*Ð*Ð*rF   c                óú  • [        U [        R                  5      (       d  [        S5      eU R                  S;  a  [        SU R                   S35      eU R                  S:X  a  U R                  S5      n U R                  u  pUS:X  d  US:X  a  SSS	.$ U R                  5       n U R                  5       nUSS
 US
S -
  n[        R                  " UR                  5       5      R                  5       nSXR-  -
  nUUS	.$ )aƒ  
Calculate sparsity statistics for the given embeddings, including the mean number of active
(non-zero) dimensions and the mean sparsity ratio.

For a single embedding (1D), the values are for that embedding directly. For a batch of embeddings
(2D), they are averaged across the batch.

Args:
    embeddings (torch.Tensor): The embeddings to analyze. Must be a 1D or 2D tensor.

Returns:
    dict[str, float]: Dictionary with ``"active_dims"`` (mean active dimensions) and
        ``"sparsity_ratio"`` (mean sparsity ratio).

Example:
    ::

        from sentence_transformers import SparseEncoder

        model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
        embeddings = model.encode(["The weather is so nice!", "It's so sunny outside."])
        stats = model.sparsity(embeddings)
        print(stats)
        # => {'active_dims': 44.0, 'sparsity_ratio': 0.9985584020614624}
z!Embeddings must be a torch.Tensor)r¼   r  z Expected a 1D or 2D tensor, got úD.r¼   r   g        g      ð?)Úactive_dimsÚsparsity_ratioNéÿÿÿÿ)r?   r'   r	   Ú	TypeErrorÚndimr<   Ú	unsqueezeÚshapeÚto_sparse_csrÚcrow_indicesr  ÚfloatÚitem)r†   Únum_rowsÚnum_colsr0  Únon_zero_per_rowÚmean_active_dimsÚmean_sparsity_ratios          rD   ÚsparsityÚSparseEncoder.sparsityÚ  s  € ô6 ˜*¤e§l¡l×3Ñ3ÜÐ?Ó@Ð@à�?‰? &Ó(ÜÐ?À
ÇÁÐ?PÐPRÐSÓTÐTð �?‰?˜aÓØ#×-Ñ-¨aÓ0ˆJà'×-Ñ-Ñˆà�q‹=˜H¨›Mà"Ø"%ñð ð  ×-Ñ-Ó/ˆ
Ø!×.Ñ.Ó0ˆØ'¨¨Ð+¨l¸3¸BÐ.?Ñ?Ðä Ÿ:š:Ð&6×&<Ñ&<Ó&>Ó?×DÑDÓFÐØ!Ð%5Ñ%@ÑAÐð ,Ø1ñ
ð 	
rF   c                ó   >• [         TU ]  $ )aZ  
Returns the maximal input sequence length for the model. Longer inputs will be truncated.

Returns:
    int: The maximal input sequence length.

Example:
    ::

        from sentence_transformers import SparseEncoder

        model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
        print(model.max_seq_length)
        # => 512
)r:   Úmax_seq_lengthr•   s    €rD   r;  ÚSparseEncoder.max_seq_length  s   ø€ ô" ‰wÑ%Ð%rF   c                ó   • XS   l         g)zc
Property to set the maximal input sequence length for the model. Longer inputs will be truncated.
r   N)r;  r§   s     rD   r;  r<  '  s   € ð "'ˆQ‰ÕrF   c                ó   >• [         TU ]  $ )a¿  
Property to get the underlying transformers PreTrainedModel instance, if it exists.
Note that it's possible for a model to have multiple underlying transformers models, but this property
will return the first one it finds in the module hierarchy.

Returns:
    PreTrainedModel or None: The underlying transformers model or None if not found.

Example:
    ::

        from sentence_transformers import SparseEncoder

        model = SparseEncoder("naver/splade-v3")

        # You can now access the underlying transformers model
        transformers_model = model.transformers_model
        print(type(transformers_model))
        # => <class 'transformers.models.bert.modeling_bert.BertForMaskedLM'>
)r:   Útransformers_modelr•   s    €rD   r?  Ú SparseEncoder.transformers_model/  s   ø€ ô, ‰wÑ)Ð)rF   c                óx   • U R                   R                  5        H  n[        U[        5      (       d  M  Us  $    g)zVReturns the SpladePooling module if present, or None. Only searches top-level modules.N)r=   r>   r?   r   )rA   rB   s     rD   Ú_get_splade_poolingÚ!SparseEncoder._get_splade_poolingG  s0   € à—m‘m×*Ñ*Ö,ˆFÜ˜&¤-×0Ó0Ø’ñ -ð rF   c                ól   • U R                  5       nUb  UR                  $ [        R                  S5        g)a;  
Returns the chunk size of the SpladePooling module, if present.

This chunk size is along the sequence length dimension (i.e., number of tokens per chunk).
If None, processes the entire sequence at once. Using smaller chunks reduces memory usage but may
lower training and inference speed. Default is None.

This property is only meaningful for SPLADE-architecture models. For CSR-architecture models
(Transformer + Pooling + SparseAutoEncoder), it returns None.

Returns:
    int or None: The chunk size, or None if SpladePooling is not found or chunk_size is not set.
Nz6SpladePooling module not found. Cannot get chunk_size.©rB  rS   rg   Úwarning)rA   Úsplade_poolings     rD   Úsplade_pooling_chunk_sizeÚ'SparseEncoder.splade_pooling_chunk_sizeN  s4   € ð ×1Ñ1Ó3ˆØÑ%Ø!×,Ñ,Ð,Ü�‰ÐOÔPØrF   c                ób   • U R                  5       nUb  Xl        g[        R                  S5        g)z>
Sets the chunk size of the SpladePooling module, if present.
Nz6SpladePooling module not found. Cannot set chunk_size.rE  )rA   r¢   rG  s      rD   rH  rI  c  s+   € ð
 ×1Ñ1Ó3ˆØÑ%Ø(-Õ%ä�N‰NÐSÕTrF   c                ó>  • U R                   (       d  U R                  5       n UR                   (       d  UR                  5       nU R                  S:w  a  [        SU R                   S35      eU R                  S   UR                  S   :w  a,  [        SU R                  S    SUR                  S    S35      eUR                  S:X  a  X-  nOSUR                  S:X  a*  [
        R                  " U Vs/ s H  o0U-  PM	     sn5      nO[        S	UR                   S35      eUR                  5       nUR                  5       S
:„  n[
        R                  " UR                  5       SS2U4   UR                  5       U   UR                  5       UR                  S9nU$ s  snf )a/  
Compute the intersection of two sparse embeddings via element-wise multiplication.

For each dimension, the result retains the minimum contribution from both embeddings, keeping only
dimensions where both inputs are positive (i.e., shared active dimensions). This is useful for
token-level matching and interpretability when combined with :meth:`decode`.

Args:
    embeddings_1 (torch.Tensor): First embedding tensor of shape ``(vocab_size,)``.
    embeddings_2 (torch.Tensor): Second embedding tensor of shape ``(vocab_size,)`` or
        ``(batch_size, vocab_size)``.

Returns:
    torch.Tensor: Sparse intersection tensor with the same shape as ``embeddings_2``.

Example:
    ::

        from sentence_transformers import SparseEncoder

        model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
        query_emb = model.encode_query("What is AI?")
        doc_emb = model.encode_document("Artificial intelligence is a branch of computer science.")
        shared = model.intersection(query_emb, doc_emb)
        print(model.decode(shared, top_k=5))
r¼   z-Expected 1D tensor for embeddings_1, but got z shape.r*  z+Vocab dimension mismatch: embeddings_1 has z, embeddings_2 has r9   r  z3Expected 1D or 2D tensor for embeddings_2, but got r   N)Úsizer)   )Ú	is_sparser€   r,  r<   r.  r'   r„   Úcoalescer>   Úsparse_coo_tensorÚindicesrL  r)   )Úembeddings_1Úembeddings_2ÚintersectionÚ	embeddingr(  s        rD   rS  ÚSparseEncoder.intersectionn  s�  € ð> ×%×%Ø'×1Ñ1Ó3ˆLØ×%×%Ø'×1Ñ1Ó3ˆLà×Ñ Ó!ÜÐLÈ\×M_ÑM_ÐL`Ð`gÐhÓiÐià×Ñ˜bÑ! \×%7Ñ%7¸Ñ%;Ó;ÜØ=¸l×>PÑ>PÐQSÑ>TÐ=Uð V$Ø$0×$6Ñ$6°rÑ$:Ð#;¸1ð>óð ð
 ×Ñ Ó!Ø'Ñ6‰LØ×Ñ !Ó#ä Ÿ;š;ÑR^Ó'_ÒR^ÀY°yÔ(@ÑR^Ñ'_Ó`‰LäÐRÐS_×SeÑSeÐRfÐfmÐnÓoÐoð $×,Ñ,Ó.ˆØ"×)Ñ)Ó+¨aÑ/ˆÜ×.Ò.Ø× Ñ Ó"¢1 k >Ñ2Ø×ÑÓ! +Ñ.Ø×"Ñ"Ó$Ø×&Ñ&ñ	
ˆð Ðùò (`s   Ã1Fc           
     óà  • Ub  US::  a  [        SU S35      e[        U[        R                  5      (       d  [	        S[        U5       35      eUR                  S:H  nU(       a  UR                  S5      nO)UR                  S:w  a  [        SUR                   S35      eUR                  (       d  UR                  5       nUR                  5       nUR                  5       nUR                  5       nUR                  5       S:X  a8  [        UR                  S5      5       Vs/ s H  n/ PM     nnU(       a  US   $ U$ US   US   p˜[        R                   " X�R                  S5      S	9R#                  5       n
/ nSnU
 HÜ  nUS:X  a  UR%                  / 5        M  X[X¼-    nX›X¼-    nUb  ['        X,5      OUnXü:  a!  [        R(                  " Xß5      u  nnUU   nUnO[        R*                  " US
S9nUU   nUU   nU R,                  R/                  UR#                  5       5      nUR%                  [1        [3        UUR#                  5       5      5      5        X¼-  nMÞ     U(       a  US   $ U$ s  snf )aŽ  
Decode a sparse embedding into (token, weight) pairs sorted by descending weight.

Args:
    embeddings (torch.Tensor): Sparse embedding tensor of shape ``(vocab_size,)``
        for a single embedding or ``(batch_size, vocab_size)`` for a batch.
    top_k (int, optional): Maximum number of top-weighted tokens to return per sample.
        If ``None``, all non-zero tokens are returned. Must be positive. Defaults to ``None``.

Returns:
    list[tuple[str, float]]: If the input is 1D, a list of ``(token, weight)`` tuples.
    list[list[tuple[str, float]]]: If the input is 2D, a list (one per sample)
        of lists of ``(token, weight)`` tuples.
r   z&top_k must be a positive integer, got r9   zExpected torch.Tensor, got r¼   r  z#Input tensor must be 1D or 2D, got r'  )Ú	minlengthT)Ú
descending)r<   r?   r'   r	   r+  rá   r,  r-  rM  r€   rN  rP  r>   ÚnumelrË   rL  Úbincountro   r!  rÇ   Útopkry   Ú	tokenizerÚconvert_ids_to_tokensrl   Úzip)rA   r†   Útop_kÚwas_1drP  r>   rÝ   ÚresultsÚsample_indicesÚtoken_indicesÚsample_countsÚ	start_idxÚcountÚsample_valuesÚsample_tokensÚeffective_kÚ
top_valuesÚtop_idxÚ
sorted_idxÚ
token_strss                       rD   ÚdecodeÚSparseEncoder.decode¯  sP  € ð" Ñ ¨!£ÜÐEÀeÀWÈAÐNÓOÐOä˜*¤e§l¡l×3Ñ3ÜÐ9¼$¸zÓ:JÐ9KÐLÓMÐMð —‘ AÑ%ˆÞØ#×-Ñ-¨aÓ0‰JØ�_‰_ Ó!ÜÐBÀ:Ç?Á?ÐBSÐSUÐVÓWÐWð ×#×#Ø#×-Ñ-Ó/ˆJà×(Ñ(Ó*ˆ
Ø×$Ñ$Ó&ˆØ×"Ñ"Ó$ˆà�<‰<‹>˜QÓÜBGÈ
ÏÉÐXYÓHZÔB[Ó5\ÒB[¸Q³bÑB[ˆGÐ5\Þ!'�7˜1‘:Ð4¨WÐ4à(/°©
°G¸A±J˜ÜŸš ~ÇÁÐQRÓASÑT×[Ñ[Ó]ˆàˆØˆ	Û"ˆEØ˜‹zØ—‘˜rÔ"Ùà"¨yÑ/@ÐAˆMØ)°iÑ6GÐHˆMà/4Ñ/@œ#˜eÔ+ÀeˆKØÓ"Ü&+§j¢j°Ó&LÑ#�
˜GØ -¨gÑ 6�Ø *‘ä"Ÿ]š]¨=ÀTÑJ�
Ø -¨jÑ 9�Ø -¨jÑ 9�àŸ™×=Ñ=¸m×>RÑ>RÓ>TÓUˆJØ�N‰Nœ4¤ J°×0DÑ0DÓ0FÓ GÓHÔIàÑŠIñ+ #ö. $ˆw�q‰zÐ0¨Ð0ùò? 6]s   Ä!I+c           	     ól   • U R                   R                  nU R                  5       nSU SU SU SU S3	$ )Nz·## Testing this pull request
You can test this pull request before merging by loading the model from this PR with the `revision` argument:
```python
from sentence_transformers import zO

# NOTE: Update this to the number of your pull request
pr_number = 2
model = z(
    "z5",
    revision=f"refs/pr/{pr_number}",
    backend="aÏ  ",
)

# Verify that everything works as expected
embeddings = model.encode(["The weather is lovely today.", "It's so sunny outside!", "He drove to the stadium."])
print(embeddings.shape)

similarities = model.similarity(embeddings, embeddings)
print(similarities)
```

---
*This PR was auto-generated with [`push_to_hub`](https://sbert.net/docs/package_reference/sparse_encoder/SparseEncoder.html#sentence_transformers.sparse_encoder.SparseEncoder.push_to_hub).*
)rC   rr   Úget_backend)rA   Úrepo_idÚ
class_namer4   s       rD   Ú_push_to_hub_usage_tipÚ$SparseEncoder._push_to_hub_usage_tip÷  sZ   € Ø—^‘^×,Ñ,ˆ
Ø×"Ñ"Ó$ˆð#ð $. ,ð /	ð 
ˆð Ø€Yð àˆYð ðð 	rF   )r"  r¤   r”   r¦   r6   r  r5   r¡   )$r8   r   r(   zlist[nn.Module] | Noner)   r   r*   zdict[str, str] | Noner+   r   r,   r   r-   Úboolr.   r   r/   rv  r0   úbool | str | Noner1   údict[str, Any] | Noner%   rx  r2   rx  r3   z!SparseEncoderModelCardData | Noner4   z$Literal['torch', 'onnx', 'openvino']r5   zstr | SimilarityFunction | Noner6   ú
int | NoneÚreturnÚNone)NNé    NTTFNNNN)rG   zlist[TextInput] | TextInputrK   r   rL   r   rM   ÚintrN   úbool | NonerO   rv  rP   rv  rQ   rv  r)   ú4str | torch.device | list[str | torch.device] | Noner6   ry  rR   ú9dict[Literal['input', 'output', 'processes'], Any] | NonerS   ry  rX   r   rz  úlist[Tensor] | Tensor)rz  údict[str, Any])rš   r‚  rz  r{  )rz  z2Literal['cosine', 'dot', 'euclidean', 'manhattan'])r¢   zNLiteral['cosine', 'dot', 'euclidean', 'manhattan'] | SimilarityFunction | Nonerz  r{  )r©   rv  rz  r{  )r®   r	   r¯   r	   rz  r	   )r®   únpt.NDArray[np.float32]r¯   rƒ  rz  r	   )rz  zVCallable[[Tensor | npt.NDArray[np.float32], Tensor | npt.NDArray[np.float32]], Tensor])TNNN)rG   zlist[TextInput]rN   r~  rR   r€  r)   r  rS   ry  rz  r�  )
rå   Ústrræ   r   r×   r   rç   r   rz  r{  )rz  ry  )NFFNNN)r8   r„  r0   rw  r,   r   r.   r   r-   rv  r/   rv  r1   rx  r%   rx  r2   rx  rz  ú&tuple[list[nn.Module], dict[str, Any]])NFFNNNN)r8   r„  r0   rw  r,   r   r.   r   r-   rv  r/   rv  r1   rx  r%   rx  r2   rx  r#  r   rz  r…  )r†   útorch.Tensorrz  zdict[str, float])rz  r}  )r¢   r}  rz  r{  )rz  zPreTrainedModel | None)rz  zSpladePooling | None)r¢   ry  rz  r{  )rQ  r†  rR  r†  rz  r	   )r†   r†  r_  ry  rz  z7list[tuple[str, float]] | list[list[tuple[str, float]]])rr  r„  rz  r„  ),rr   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   Úmodel_card_data_classr    Ú__annotations__r#   Ú _model_card_model_id_placeholderr   r;   rY   r_   rW   r“   r˜   Úpropertyr5   Úsetterrª   r   r°   rµ   rt   Ústaticmethodré   rì   r   ÚFutureWarningrí   r  r$  r8  r;  r?  rB  rH  rS  rn  rt  Ú__static_attributes__Ú__classcell__)rC   s   @rD   r   r   #   s`  ø‡ ñ_ðB 7ÐØ3CÐ$ jÓCØ8<È$Ñ.OÐÐ+ÓOØ'@Ð$áÐ(:Ñ;ð *.ð4ð +/Ø!Ø)-Ø*.Ø#'Ø"'Ø#Ø!&Ø#'Ø.2Ø26Ø/3Ø=AØ8?à>BØ&*ñ)4à&ð4ð (ð	4ð
 ð4ð 'ð4ð (ð4ð !ð4ð  ð4ð ð4ð ð4ð !ð4ð ,ð4ð 0ð4ð -ð4ð  ;ð!4ð" 6ð#4ð& <ð'4ð( $ð)4ð* 
÷+4ð 4ó <ð4ñl  Ñ*ð #'Ø!ØØ)-Ø"&Ø)-Ø!ØGKØ&*ØJNØ!%ðF
à+ðF
ð  ðF
ð ð	F
ð
 ðF
ð 'ðF
ð  ðF
ð #'ðF
ð ðF
ð EðF
ð $ðF
ð HðF
ð ðF
ð ðF
ð 
ôF
ó +ðF
ñP  Ñ*ð #'Ø!ØØ)-Ø"&Ø)-Ø!ØGKØ&*ØJNØ!%ðI
à+ðI
ð  ðI
ð ð	I
ð
 ðI
ð 'ðI
ð  ðI
ð #'ðI
ð ðI
ð EðI
ð $ðI
ð HðI
ð ðI
ð ðI
ð 
ôI
ó +ðI
ñV  Ñ*ð #'Ø!ØØ)-Ø"&Ø)-Ø!ØGKØ&*ØJNØ!%ðMà+ðMð  ðMð ð	Mð
 ðMð 'ðMð  ðMð #'ðMð ðMð EðMð $ðMð HðMð ðMð ðMð 
ôMó +ðM÷^
÷
Sð
 ó(ó ð(ð  ×Ñð
\à]ð
\ð 
ó
\ó ð
\ô
ð ÛQó ØQàÛsó Øsàó) ó ð) ðV ÛZó ØZàðØ2ðØAXðà	óó ðð ð$)à	_ó$)ó ð$)ðR *.ØJNØGKØ!%ð>3àð>3ð 'ð>3ð Hð	>3ð
 Eð>3ð ð>3ð 
õ>3ð@ ðØðØ#0ðØ?DðØUZðà	óó ðô2ñ2 ØfØñó.ó	ð.ð  $Ø"'Ø!&Ø.2Ø26Ø/3ðWàðWð !ðWð !ð	Wð
 ðWð  ðWð ðWð ,ðWð 0ðWð -ðWð 
0õWð|  $Ø"'Ø!&Ø.2Ø26Ø/3Ø!%ðJ+àðJ+ð !ðJ+ð !ð	J+ð
 ðJ+ð  ðJ+ð ðJ+ð ,ðJ+ð 0ðJ+ð -ðJ+ð ðJ+ð 
0õJ+ðX ó7
ó ð7
ðr ö&ó ð&ð$ ×Ñó'ó ð'ð ö*ó ð*ô.ð óó ðð( ×%Ñ%óUó &ðUð ð>Ø"ð>à"ð>ð 
ó>ó ð>ðB =AðF1Ø&ðF1Ø/9ðF1à	@õF1÷Pò rF   r   )8Ú
__future__r   rÏ   r   rÈ   râ   Úcollections.abcr   Úmultiprocessingr   Útypingr   r   r   Únumpyrm   Únumpy.typingÚnptr'   r	   r
   Útqdmr   Útransformersr   r   Útransformers.modeling_utilsr   Útransformers.utilsÚtransformers_loggingÚtyping_extensionsr   Úsentence_transformers.baser   Ú)sentence_transformers.base.modality_typesr   Ú"sentence_transformers.base.modulesr   Ú2sentence_transformers.sentence_transformer.modulesr   Ú/sentence_transformers.sparse_encoder.model_cardr   Ú,sentence_transformers.sparse_encoder.modulesr   r   Úsentence_transformers.utilr   r   Ú%sentence_transformers.util.decoratorsr   Ú%sentence_transformers.util.similarityr   Ú
get_loggerrr   rg   r   rU   rF   rD   Ú<module>r«     sv   ðÝ "ã Û Û Û Ý $Ý !ß )Ñ )ã Ý Û ß Ý ß 5Ý 7Ý >Ý (å 0Ý ?Ý :Ý FÝ Vß Yß NÝ CÝ Dð 
×	(Ò	(¨Ó	2€ôp�Iõ prF   