
    eid                       d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZ d dlmZ d dlmZmZmZ d dlZd dlZd dlm
Z d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZm Z m!Z!m"Z"m#Z#m$Z$m%Z% d dl&m'Z' d dl(m)Z) d dl*m+Z+ d dl,m-Z-m.Z. d dl/m0Z0 d dl1m2Z2m3Z3 d dl4m5Z5m6Z6 d dl7m8Z8m9Z9m:Z:m;Z;  ejx                  e=      Z>ddZ? G d dej                  e'e0      ZAy)    )annotationsN)Callable)Queue)Path)AnyLiteraloverload)HfApi)version)nn)trange)
AutoConfig"AutoModelForSequenceClassificationAutoTokenizerPretrainedConfigPreTrainedModelPreTrainedTokenizeris_torch_npu_available)PushToHubMixin)
deprecated)__version__)load_onnx_modelload_openvino_model)FitMixin)CrossEncoderModelCardDatagenerate_model_card)!cross_encoder_init_args_decorator)cross_encoder_predict_rank_args_decorator)fullnameget_device_nameimport_from_stringload_file_pathc                     d fd}|S )Nc                t    t        j                  t        |       z  d        t        |       z  fi |S )NT)exist_ok)osmakedirsr   )save_directorykwargs_save_pretrained_fn	subfolders     z/home/obispo/Crisostomo_bridge/mision_env/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.pywrapperz)_save_pretrained_wrapper.<locals>.wrapper/   s5    
D(94tD"4#7)#CNvNN    )r(   z
str | PathreturnNone )r*   r+   r-   s   `` r,   _save_pretrained_wrapperr2   .   s    O Nr.   c            	          e Zd ZdZe	 	 	 	 	 	 	 	 	 	 	 	 	 	 d'	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d( fd       Z	 	 	 	 	 	 	 	 d)dZd*dZ	 d+	 	 	 d,dZe	d-d       Z
	 	 	 	 	 d.	 	 	 	 	 	 	 	 	 	 	 d/d
Ze		 	 	 	 	 	 	 	 	 	 d0d       Zd1d2dZd3dZd4dZed5d       Zed6d       Zed6d       Zej(                  d7d       Ze ed      d3d              Zd Ze	 	 	 	 	 	 	 	 	 d8	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d9d       Ze	 	 	 	 	 	 	 	 	 d:	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d;d       Ze	 	 	 	 	 	 	 	 	 d8	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d<d       Ze	 	 	 	 	 	 	 	 	 d8	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d=d       Z ej6                         e	 	 	 	 	 	 	 	 	 d>	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d?d              Ze	 	 	 	 	 	 	 	 	 	 	 d@	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dAd       Zd	ddBdZd	ddBdZdCdZ ddd	dddddd 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dDd!Z!edEd"       Z"edFd#       Z#e#j(                  d+dGd$       Z#edFd%       Z$d+dHd&Z% xZ&S )ICrossEncodera  
    A CrossEncoder takes exactly two sentences / texts as input and either predicts
    a score or label for this sentence pair. It can for example predict the similarity of the sentence pair
    on a scale of 0 ... 1.

    It does not yield a sentence embedding and does not work for individual sentences.

    Args:
        model_name_or_path (str): A model name from Hugging Face Hub that can be loaded with AutoModel, or a path to a local
            model. We provide several pre-trained CrossEncoder models that can be used for common tasks.
        num_labels (int, optional): Number of labels of the classifier. If 1, the CrossEncoder is a regression model that
            outputs a continuous score 0...1. If > 1, it output several scores that can be soft-maxed to get
            probability scores for the different classes. Defaults to None.
        max_length (int, optional): Max length for input sequences. Longer sequences will be truncated. If None, max
            length of the model will be used. Defaults to None.
        activation_fn (Callable, optional): Callable (like nn.Sigmoid) about the default activation function that
            should be used on-top of model.predict(). If None. nn.Sigmoid() will be used if num_labels=1,
            else nn.Identity(). 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.
        cache_folder (`str`, `Path`, optional): Path to the folder where cached files are stored.
        trust_remote_code (bool, optional): Whether or not to allow for custom models defined on the Hub in their own modeling files.
            This option should only be 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 or not to only look at local files (i.e., do not try to download the model).
        token (bool or str, optional): Hugging Face authentication token to download private models.
        model_kwargs (Dict[str, Any], optional): Additional model configuration parameters to be passed to the Hugging Face Transformers model.
            Particularly useful options are:

            - ``torch_dtype``: Override the default `torch.dtype` and load the model under a specific `dtype`.
              The different options are:

                    1. ``torch.float16``, ``torch.bfloat16`` or ``torch.float``: load in a specified
                    ``dtype``, ignoring the model's ``config.torch_dtype`` if one exists. If not specified - the model will
                    get loaded in ``torch.float`` (fp32).

                    2. ``"auto"`` - A ``torch_dtype`` entry in the ``config.json`` file of the model will be
                    attempted to be used. If this entry isn't found then next check the ``dtype`` of the first weight in
                    the checkpoint that's of a floating point type and use that as ``dtype``. This will load the model
                    using the ``dtype`` it was saved in at the end of the training. It can't be used as an indicator of how
                    the model was trained. Since it could be trained in one of half precision dtypes, but saved in fp32.
            - ``attn_implementation``: The attention implementation to use in the model (if relevant). Can be any of
              `"eager"` (manual implementation of the attention), `"sdpa"` (using `F.scaled_dot_product_attention
              <https://pytorch.org/docs/master/generated/torch.nn.functional.scaled_dot_product_attention.html>`_),
              or `"flash_attention_2"` (using `Dao-AILab/flash-attention <https://github.com/Dao-AILab/flash-attention>`_).
              By default, if available, SDPA will be used for torch>=2.1.1. The default is otherwise the manual `"eager"`
              implementation.

            See the `AutoModelForSequenceClassification.from_pretrained
            <https://huggingface.co/docs/transformers/en/model_doc/auto#transformers.AutoModelForSequenceClassification.from_pretrained>`_
            documentation for more details.
        tokenizer_kwargs (Dict[str, Any], optional): Additional tokenizer configuration parameters to be passed to the Hugging Face Transformers tokenizer.
            See the `AutoTokenizer.from_pretrained
            <https://huggingface.co/docs/transformers/en/model_doc/auto#transformers.AutoTokenizer.from_pretrained>`_
            documentation for more details.
        config_kwargs (Dict[str, Any], optional): Additional model configuration parameters to be passed to the Hugging Face Transformers config.
            See the `AutoConfig.from_pretrained
            <https://huggingface.co/docs/transformers/en/model_doc/auto#transformers.AutoConfig.from_pretrained>`_
            documentation for more details. For example, you can set ``classifier_dropout`` via this parameter.
        model_card_data (:class:`~sentence_transformers.model_card.SentenceTransformerModelCardData`, optional): A model
            card data object that contains information about the model. This is used to generate a model card when saving
            the model. If not set, a default model card data object is created.
        backend (str): The backend to use for inference. Can be one of "torch" (default), "onnx", or "openvino".
            See https://sbert.net/docs/cross_encoder/usage/efficiency.html for benchmarking information
            on the different backends.
    NFc                v   t         |           |i }|i }|i }|xs t        |	      | _        || _        d | _        || _        t        j                  |f||||	|
d|}t        |d      rld|j                  v r^|j                  d   }t        j                  |      t        j                  t              kD  r t        j                  d| dt         d       d}|j                   2t#        |j                   D cg c]  }|j%                  d	       c}      }||sd
}|||_         | j(                  |f||||||	|
d| d|vr|||d<   t+        j                  |f||||	|
d|| _        d|vrYt        | j.                  d      rCt1        | j,                  j2                  | j.                  j4                        | j,                  _        t7        |d|j9                  dd       |||	      }|,	 t;        |d      5 }|j=                         | _        d d d        | jA                  |       |"tC               }t        jE                  d|        | jG                  |       | j                  jI                  |        | j                  jK                  ||       y c c}w # 1 sw Y   xY w# t>        $ r Y w xY w)N)local_files_only)	cache_dirtrust_remote_coderevisionr6   tokensentence_transformersr   zRYou are trying to use a model that was created with Sentence Transformers version z%, but you're currently using version zd. This might cause unexpected behavior or errors. In that case, try to update to the latest version.FForSequenceClassification   )configbackendr7   r8   r9   r6   r:   model_max_lengthmax_position_embeddings	README.mdr:   )r:   cache_folderr9   r6   utf8encodingzUse pytorch device: )r9   )&super__init__r   model_card_datar8   _model_card_textr?   r   from_pretrainedhasattrr;   r   parser   loggerwarningarchitecturesanyendswith
num_labels_load_modelr   	tokenizerr>   minr@   rA   r"   getopenread	Exceptionset_activation_fnr    infotoregister_modelset_base_model)selfmodel_name_or_pathrS   
max_lengthactivation_fndevicerC   r8   r9   r6   r:   model_kwargstokenizer_kwargsconfig_kwargsrI   r?   r>   model_versionclassifier_trainedarchmodel_card_pathfIn	__class__s                         r,   rH   zCrossEncoder.__init__|   s   & 	#!L M.n2K]m2n!2 $#-#=#=$
"/-$
 $
 623	VEaEa8a"88CM}}]+gmmK.HHhivhw x::E GII #+!$]c]q]q%rUYdmm4O&P%r!s&8J! *F
	
"/-
	
 
	
 %55*:P3=/0.;.K.K/
"/-/
 /
 %55'$++Oh:i.1$..2Q2QSWS^S^SvSv.wDNN+ )""7D1%-
 &/F; 7s,/HHJD)7
 	}->$&FKK.vh78 	++D1++,>+Ru &sX7 7 s0   ;J1J, >J J,  J)%J, ,	J87J8c                    |dk(  rt        j                  |fd|i|| _        y |dk(  rt        d	||dd|| _        y |dk(  rt	        d	||dd|| _        y t        d| d      )
Ntorchr>   onnxzsequence-classification)ra   r>   	task_nameopenvinozUnsupported backend 'z6'. `backend` should be `torch`, `onnx`, or `openvino`.r1   )r   rK   modelr   r   
ValueError)r`   ra   r>   r?   re   s        r,   rT   zCrossEncoder._load_model   s     g*L*\*\"++ +DJ
 ( #53 	DJ 
", #53 	DJ 4WI=stuur.   c                    | j                   S )zReturn the backend used for inference, which can be one of "torch", "onnx", or "openvino".

        Returns:
            str: The backend used for inference.
        )r?   r`   s    r,   get_backendzCrossEncoder.get_backend	  s     ||r.   c           
     f   |t         j                  j                         r8t        t         j                  j	                               D cg c]  }d| 	 }}n]t               r8t        t         j                  j	                               D cg c]  }d| 	 }}nt        j                  d       dgdz  }t        j                  dj                  dj                  t        t        |                         | j                  d       | j                          t        j                   d      }|j#                         }|j#                         }g }|D ]O  }|j%                  | j&                  j(                  || ||fd	
      }|j+                          |j-                  |       Q |||dS c c}w c c}w )a  
        Starts a multi-process pool to process the prediction with several independent processes
        via :meth:`CrossEncoder.predict <sentence_transformers.cross_encoder.CrossEncoder.predict>`.

        This method is recommended if you want to predict on multiple GPUs or CPUs. It is advised
        to start only one process per GPU. This method works together with predict and
        stop_multi_process_pool.

        Args:
            target_devices (List[str], optional): PyTorch target devices, e.g. ["cuda:0", "cuda:1", ...],
                ["npu:0", "npu:1", ...], or ["cpu", "cpu", "cpu", "cpu"]. If target_devices is None and CUDA/NPU
                is available, then all available CUDA/NPU devices will be used. If target_devices is None and
                CUDA/NPU is not available, then 4 CPU devices will be used.

        Returns:
            Dict[str, Any]: A dictionary with the target processes, an input queue, and an output queue.
        zcuda:znpu:z1CUDA/NPU is not available. Starting 4 CPU workerscpu   z'Start multi-process pool on devices: {}z, spawnT)targetargsdaemon)inputoutput	processes)ro   cudais_availablerangedevice_countr   npurN   r\   formatjoinmapstrr]   share_memorympget_contextr   Processrm   _multi_process_workerstartappend)	r`   target_devicesictxinput_queueoutput_queuer   	device_idps	            r,   start_multi_process_poolz%CrossEncoder.start_multi_process_pool  sg   ( !zz&&(7<UZZ=T=T=V7W!X!E!+!X!X')6;EII<R<R<T6U!VD*!V!VOP"'1=DDTYYsSVXfOgEhijnnW%iikyy{	' 	 I~~;;{LA  A
 GGIQ	  %9UU5 "Y!Vs   
F)F.c                    | d   D ]  }|j                           | d   D ]"  }|j                          |j                          $ | d   j                          | d   j                          y)z
        Stops all processes started with start_multi_process_pool.

        Args:
            pool (Dict[str, object]): A dictionary containing the input queue, output queue, and process list.

        Returns:
            None
        r   r   r   N)	terminater   close)poolr   s     r,   stop_multi_process_poolz$CrossEncoder.stop_multi_process_poolC  sk     k" 	AKKM	 k" 	AFFHGGI	 	WXr.   Tc           	        |j                  dd      }|j                  dd      }	d|d<   d}
|1t        |t              r!t        |      dkD  r| j	                  |      }d}
	 |Ft        t        j                  t        |      t        |d         z  dz        d	      }t        |d
      }|d   }|d   }d}t        t        dt        |      |            D ]!  \  }}||||z    }|j                  |||g       # t        t        |d
z   d|       D cg c]  }|j                          c}d       }|r>|r<t        |d   d
         dkD  r|d   d
   d   n|d   d
   	 |
r| j                  |       S S |D cg c]  }|d
   	 }}t        d |D              r#t!        d |D              }t#        d|d          |rt        |d   t$        j&                        rt%        j(                  |      }nt        |d   t*        j,                        rt+        j.                  |d      }nut        |d   t              rt1        |g       }nUt1        |g       }nH|r,t%        j2                  g | j4                  j6                        }n|	rt+        j8                  g       }ng }||
r| j                  |       S S c c}w c c}w # |
r| j                  |       w w xY w)Nconvert_to_tensorFconvert_to_numpyTshow_progress_barr   r   
   i  r=   r   r   Chunksdescdisablec                    | d   S )Nr   r1   xs    r,   <lambda>z-CrossEncoder._multi_process.<locals>.<lambda>~  s
    ad r.   )keyc              3  J   K   | ]  }t        |      d kD  xr |d    du  yw   Nlen.0r   s     r,   	<genexpr>z.CrossEncoder._multi_process.<locals>.<genexpr>  s)     W3v;?<vay'<<Ws   !#c              3  J   K   | ]  }t        |      d kD  s|d    s|  ywr   r   r   s     r,   r   z.CrossEncoder._multi_process.<locals>.<genexpr>  s$     #fvFVW\bcd\eF#fs   ###zError in worker process: r   )axisrd   )rW   
isinstancelistr   r   rV   mathceilmax	enumerater   putsortedr   r   rQ   nextRuntimeErrorro   Tensorcatnpndarrayconcatenatesumtensorrs   rd   array)r`   sentence_pairsr   input_was_singularr   rd   
chunk_sizepredict_kwargsr   r   created_poolr   r   chunk_idchunk_startchunk_output_listr   scoreserror_outputs                        r,   _multi_processzCrossEncoder._multi_processX  s    +../BEJ)--.@$G.3*+<Jvt4Vq008DL8	3! 3~+>T+EVAW+WZ\+\!]_cd
 Q/
7;G}K8<XL H)25C<OQ[3\)] C%+&{[:5MN5. ABC
 !-3HqLx]nYn-op!!#p"K "k/2;q>!3D/E/I{1~a(+{[\~^_O``@ ,,T2 9 /::FfQi:F: W;WW##f#ff"%>|A>O#PQQfQi6"YYv.Fq	2::6^^F;Fq	40 _F _F"b1B1BC!" ,,T2 M q ;8 ,,T2 s2    B0J7 J-'4J7 1J7 5J2DJ7 -
J7 7Kc                   	 	 |j                         \  }}} |j                  |fd| i|}t        |t        j                        r*|j
                  j                  dk7  r|j                         }nt        |t        j                        rt        j                  |      }nbt        |t              rR|D cg c]G  }t        |t        j                        r)|j
                  j                  dk7  r|j                         n|I }}|j                  ||g       c c}w # t        j                  $ r Y yt        $ rS}	t         j#                  d|  d|	        	 |j                  dt%        |	      g       n# t        $ r Y nw xY wY d}	~	yd}	~	ww xY w)z_
        Internal working process to predict sentence pairs in a multi-process setup.

        rd   ry   zError in worker process on z: N)rW   predictr   ro   r   rd   typery   r   r   asarrayr   r   queueEmptyrZ   rN   errorr   )
target_devicers   r   results_queuer   r   r)   r   scorees
             r,   r   z"CrossEncoder._multi_process_worker  sb    3>??3D0.&&~VmVvV fell38J8Je8S#ZZ\F

3ZZ/F- &,! (2%'F5<<K\K\`eKe		kppF  !!8V"45  ;;  :=/A3OP!%%xs1v&>?  sU   B1D 4AD D D F1F9FE32F3	E?<F>E??FFc                    ||| _         n| j                         | _         |r&| j                  dt        | j                                y y )Nrc   )rc   get_default_activation_fnset_config_valuer   )r`   rc   set_defaults      r,   r[   zCrossEncoder.set_activation_fn  sD    $!.D!%!?!?!AD!!/8D<N<N3OP r.   c                D   d }t        | j                  d      r2d| j                  j                  v r| j                  j                  d   }nNt        | j                  d      r8| j                  j                  "| j                  j                  }| j                  `|F| j                  s|j                  d      r t        |             S t        j                  d| d       | j                  j                  dk(  rt        j                         S t        j                         S )Nr;   rc   $sbert_ce_default_activation_functionztorch.zActivation function path 'z' is not trusted, using default activation function instead. Please load the CrossEncoder with `trust_remote_code=True` to allow loading custom activation functions via the configuration.r=   )rL   r>   r;   r   r8   
startswithr!   rN   rO   rS   r   SigmoidIdentity)r`   activation_fn_paths     r,   r   z&CrossEncoder.get_default_activation_fn  s    !4;; 78_PTP[P[PqPq=q!%!B!B?!S DKK!GH@@L!%!Q!Q@)%%);)F)Fx)P=)*<=??NN,-?,@ A3 3 ;;!!Q&::<{{}r.   c           	         	 t        | j                  d      si | j                  _        || j                  j                  |<   y# t        $ r.}t        j                  d| dt        |              Y d}~yd}~ww xY w)z
        Set a value in the underlying model's config.

        Args:
            key (str): The key to set.
            value: The value to set.
        r;   zWas not able to add 'z' to the config: N)rL   r>   r;   rZ   rN   rO   r   )r`   r   valuer   s       r,   r   zCrossEncoder.set_config_value  sk    	S4;;(?@4615:DKK--c2 	SNN23%7HQQRR	Ss   A A 	A:$A55A:c                .    | j                   j                  S N)rs   r>   rv   s    r,   r>   zCrossEncoder.config      zz   r.   c                .    | j                   j                  S r   )r>   rS   rv   s    r,   rS   zCrossEncoder.num_labels  s    {{%%%r.   c                .    | j                   j                  S r   rU   r@   rv   s    r,   rb   zCrossEncoder.max_length  s    ~~...r.   c                &    || j                   _        y r   r   )r`   r   s     r,   rb   zCrossEncoder.max_length
  s    */'r.   zqThe `default_activation_function` property was renamed and is now deprecated. Please use `activation_fn` instead.c                    | j                   S r   )rc   rv   s    r,   default_activation_functionz(CrossEncoder.default_activation_function  s     !!!r.   c                &     | j                   |i |S r   rs   )r`   r}   r)   s      r,   forwardzCrossEncoder.forward  s    tzz4*6**r.   c                     y r   r1   r`   	sentences
batch_sizer   rc   apply_softmaxr   r   rd   r   r   s              r,   r   zCrossEncoder.predict       r.   c                     y r   r1   r   s              r,   r   zCrossEncoder.predict(  s     r.   c                     y r   r1   r   s              r,   r   zCrossEncoder.predict7  r   r.   c                     y r   r1   r   s              r,   r   zCrossEncoder.predictF  s     !r.   c                \   d}|r.t        |t        t        f      rt        |d   t              r|g}d}|	t        |t              r*t	        |      dkD  r| j                  ||||	||
|||||      S |Lt        j                         t        j                  k(  xs% t        j                         t        j                  k(  }|| j                  |d       || j                  j                  }| j                  |       g }| j                          t!        dt	        |      |d|       D ]  }||||z    }| j#                  |ddd	      }|j                  |        | j                  di |d
di}| j%                  |j&                        }|r:|j(                  dkD  r+t*        j,                  j.                  j1                  |d      }|j3                  |        | j4                  j6                  dk(  r|D cg c]  }|d   	 }}|r9t	        |      rt+        j8                  |      }nut+        j:                  g |      }n]|r[t=        j>                  |D cg c]<  }|jA                         jC                         jE                         jG                         > c}      }|r|d   }|S c c}w c c}w )a  
        Performs predictions with the CrossEncoder on the given sentence pairs.

        Args:
            sentences (Union[List[Tuple[str, str]], Tuple[str, str]]): A list of sentence pairs [(Sent1, Sent2), (Sent3, Sent4)]
                or one sentence pair (Sent1, Sent2).
            batch_size (int, optional): Batch size for encoding. Defaults to 32.
            show_progress_bar (bool, optional): Output progress bar. Defaults to None.
            activation_fn (callable, optional): Activation function applied on the logits output of the CrossEncoder.
                If None, the ``model.activation_fn`` will be used, which defaults to :class:`torch.nn.Sigmoid` if num_labels=1, else
                :class:`torch.nn.Identity`. Defaults to None.
            convert_to_numpy (bool, optional): Convert the output to a numpy matrix. Defaults to True.
            apply_softmax (bool, optional): If set to True and `model.num_labels > 1`, applies softmax on the logits
                output such that for each sample, the scores of each class sum to 1. Defaults to False.
            convert_to_numpy (bool, optional): Whether the output should be a list of numpy vectors. If False, output
                a list of PyTorch tensors. Defaults to True.
            convert_to_tensor (bool, optional): Whether the output should be one large tensor. Overwrites `convert_to_numpy`.
                Defaults to False.
            device (Union[str, List[str]], optional): Device(s) to use for computation. Can be a single device string
                (e.g., "cuda:0", "cpu") or a list of devices (e.g., ["cuda:0", "cuda:1"]). If a list is provided,
                multiprocessing will be used automatically. Defaults to None.
            pool (Dict[str, Any], optional): A pool of workers created with :meth:`start_multi_process_pool`. If provided,
                multiprocessing will be used. If None and ``device`` is a list, a pool will be created automatically.
                Defaults to None.
            chunk_size (int, optional): Size of chunks for multiprocessing. If None, a sensible default is calculated.
                Only used when ``pool`` is not None or ``device`` is a list. Defaults to None.

        Returns:
            Union[List[torch.Tensor], np.ndarray, torch.Tensor]: Predictions for the passed sentence pairs.
            The return type depends on the ``convert_to_numpy`` and ``convert_to_tensor`` parameters.
            If ``convert_to_tensor`` is True, the output will be a :class:`torch.Tensor`.
            If ``convert_to_numpy`` is True, the output will be a :class:`numpy.ndarray`.
            Otherwise, the output will be a list of :class:`torch.Tensor` values.

        Examples:
            ::

                from sentence_transformers import CrossEncoder

                model = CrossEncoder("cross-encoder/stsb-roberta-base")
                sentences = [["I love cats", "Cats are amazing"], ["I prefer dogs", "Dogs are loyal"]]
                model.predict(sentences)
                # => array([0.6912767, 0.4303499], dtype=float32)

                # Using multiprocessing with automatic pool
                scores = model.predict(sentences, device=["cuda:0", "cuda:1"])

                # Using multiprocessing with manual pool
                pool = model.start_multi_process_pool()
                scores = model.predict(sentences, pool=pool)
                model.stop_multi_process_pool(pool)
        Fr   T)r   r   r   r   rd   r   r   rc   r   r   r   )r   Batchesr   pt)padding
truncationreturn_tensorsreturn_dictr=   )dimr   r1   )$r   r   tupler   r   r   rN   getEffectiveLevelloggingINFODEBUGr[   rs   rd   r]   evalr   rU   rc   logitsndimro   r   
functionalsoftmaxextendr>   rS   stackr   r   r   ry   detachfloatnumpy)r`   r   r   r   rc   r   r   r   rd   r   r   r   pred_scoresstart_indexbatchfeaturesmodel_predictionsr  r   s                      r,   r   zCrossEncoder.predictU  s   H #Ie}=*YWX\[^B_"I!% 
64 8S[1_&&("3#5%%++!1"3 '  " $((*gll:if>V>V>X\c\i\i>i  $""=e"D >ZZ&&F		!!S^Zi]nYno 	'KkK*,DEE~~#	 & H KK *

 HX H4 H''(9(@(@AFq,,44V4Cv&	'  ;;!!Q&1<=58=K=;#kk+6#ll2f=**Xc%dueiik&8&8&:&@&@&B&H&H&J%deK%a.K > &es   5J$AJ)c                J   | j                   dk7  rt        d      |D cg c]  }||g }}| j                  ||||||	|
|||
      }g }t        |      D ]5  \  }}|j	                  ||d       |s|d   j                  d||   i       7 t        |d d	      }|d
| S c c}w )a#  
        Performs ranking with the CrossEncoder on the given query and documents. Returns a sorted list with the document indices and scores.

        Args:
            query (str): A single query.
            documents (List[str]): A list of documents.
            top_k (Optional[int], optional): Return the top-k documents. If None, all documents are returned. Defaults to None.
            return_documents (bool, optional): If True, also returns the documents. If False, only returns the indices and scores. Defaults to False.
            batch_size (int, optional): Batch size for encoding. Defaults to 32.
            show_progress_bar (bool, optional): Output progress bar. Defaults to None.
            activation_fn ([type], optional): Activation function applied on the logits output of the CrossEncoder. If None, nn.Sigmoid() will be used if num_labels=1, else nn.Identity. Defaults to None.
            convert_to_numpy (bool, optional): Convert the output to a numpy matrix. Defaults to True.
            apply_softmax (bool, optional): If there are more than 2 dimensions and apply_softmax=True, applies softmax on the logits output. Defaults to False.
            convert_to_tensor (bool, optional): Convert the output to a tensor. Defaults to False.
            device (Union[str, List[str]], optional): Device(s) to use for computation. Can be a single device string
                (e.g., "cuda:0", "cpu") or a list of devices (e.g., ["cuda:0", "cuda:1"]). If a list is provided,
                multiprocessing will be used automatically. Defaults to None.
            pool (Dict[str, Any], optional): A pool of workers created with :meth:`start_multi_process_pool`. If provided,
                multiprocessing will be used. If None and ``device`` is a list, a pool will be created automatically.
                Defaults to None.
            chunk_size (int, optional): Size of chunks for multiprocessing. If None, a sensible default is calculated.
                Only used when ``pool`` is not None or ``device`` is a list. Defaults to None.

        Returns:
            List[Dict[Literal["corpus_id", "score", "text"], Union[int, float, str]]]: A sorted list with the "corpus_id", "score", and optionally "text" of the documents.

        Example:
            ::

                from sentence_transformers import CrossEncoder
                model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L6-v2")

                query = "Who wrote 'To Kill a Mockingbird'?"
                documents = [
                    "'To Kill a Mockingbird' is a novel by Harper Lee published in 1960. It was immediately successful, winning the Pulitzer Prize, and has become a classic of modern American literature.",
                    "The novel 'Moby-Dick' was written by Herman Melville and first published in 1851. It is considered a masterpiece of American literature and deals with complex themes of obsession, revenge, and the conflict between good and evil.",
                    "Harper Lee, an American novelist widely known for her novel 'To Kill a Mockingbird', was born in 1926 in Monroeville, Alabama. She received the Pulitzer Prize for Fiction in 1961.",
                    "Jane Austen was an English novelist known primarily for her six major novels, which interpret, critique and comment upon the British landed gentry at the end of the 18th century.",
                    "The 'Harry Potter' series, which consists of seven fantasy novels written by British author J.K. Rowling, is among the most popular and critically acclaimed books of the modern era.",
                    "'The Great Gatsby', a novel written by American author F. Scott Fitzgerald, was published in 1925. The story is set in the Jazz Age and follows the life of millionaire Jay Gatsby and his pursuit of Daisy Buchanan."
                ]

                model.rank(query, documents, return_documents=True)

            ::

                [{'corpus_id': 0,
                'score': 10.67858,
                'text': "'To Kill a Mockingbird' is a novel by Harper Lee published in 1960. It was immediately successful, winning the Pulitzer Prize, and has become a classic of modern American literature."},
                {'corpus_id': 2,
                'score': 9.761677,
                'text': "Harper Lee, an American novelist widely known for her novel 'To Kill a Mockingbird', was born in 1926 in Monroeville, Alabama. She received the Pulitzer Prize for Fiction in 1961."},
                {'corpus_id': 1,
                'score': -3.3099542,
                'text': "The novel 'Moby-Dick' was written by Herman Melville and first published in 1851. It is considered a masterpiece of American literature and deals with complex themes of obsession, revenge, and the conflict between good and evil."},
                {'corpus_id': 5,
                'score': -4.8989105,
                'text': "'The Great Gatsby', a novel written by American author F. Scott Fitzgerald, was published in 1925. The story is set in the Jazz Age and follows the life of millionaire Jay Gatsby and his pursuit of Daisy Buchanan."},
                {'corpus_id': 4,
                'score': -5.082967,
                'text': "The 'Harry Potter' series, which consists of seven fantasy novels written by British author J.K. Rowling, is among the most popular and critically acclaimed books of the modern era."}]
        r=   z|CrossEncoder.rank() only works for models with num_labels=1. Consider using CrossEncoder.predict() with input pairs instead.)
r   r   r   rc   r   r   r   rd   r   r   )	corpus_idr   r   textc                    | d   S )Nr   r1   r   s    r,   r   z#CrossEncoder.rank.<locals>.<lambda>I  s
    '
 r.   T)r   reverseN)rS   rt   r   r   r   updater   )r`   query	documentstop_kreturn_documentsr   r   rc   r   r   r   rd   r   r   docquery_doc_pairsr   resultsr   r   s                       r,   rankzCrossEncoder.rank  s    ^ ??aR  4==CE3<==%!/''-/!  
 !&) 	;HAuNNU;<""FIaL#9:	;
 &:DIv+ >s   B safe_serializationc                   |yt         j                  d|        | j                  dt                | j                  j
                  |fd|i|  | j                  j
                  |fi | | j                  |       y)zW
        Saves the model and tokenizer to path; identical to `save_pretrained`
        NzSave model to r   r/  )rN   r\   r   r   rs   save_pretrainedrU   _create_model_cardr`   pathr/  r)   s       r,   savezCrossEncoder.saveL  sv     <nTF+,i5"

""4Y<NYRXY&&&t6v6%r.   c               ,     | j                   |fd|i|S )a  
        Save the model and tokenizer to the specified path.

        Args:
            path (str): Directory where the model should be saved
            safe_serialization (bool, optional): Whether to save using `safetensors` or the traditional
                PyTorch way. Defaults to True.
            **kwargs: Additional arguments passed to the underlying save methods of the model and tokenizer.

        Returns:
            None
        r/  )r5  r3  s       r,   r1  zCrossEncoder.save_pretrainedY  s      tyyO2DOOOr.   c                   | j                   red| j                  j                  vrM| j                   }| j                  j                  r7|j	                  dd| j                  j                   d      }n	 t        |       }t        t        j                  j                  |d      d	d
      5 }|j                  |       ddd       y# t        $ r. t        j                  dt        j                          d       Y yw xY w# 1 sw Y   yxY w)a>  
        Create an automatic model and stores it in the specified path. If no training was done and the loaded model
        was a CrossEncoder model already, then its model card is reused.

        Args:
            path (str): The path where the model card will be stored.

        Returns:
            None
        generated_from_trainerz-model = CrossEncoder("cross_encoder_model_id"zmodel = CrossEncoder(""z#Error while generating model card:
zConsider opening an issue on https://github.com/huggingface/sentence-transformers/issues with this traceback.
Skipping model card creation.NrB   wrD   rE   )rJ   rI   tagsmodel_idreplacer   rZ   rN   r   	traceback
format_excrX   r&   r4  r   write)r`   r4  
model_cardfOuts       r,   r2  zCrossEncoder._create_model_cardh  s       %=TEYEYE^E^%^..J##,,'//C,T-A-A-J-J,K1M

06
 "'',,t[13H 	#DJJz"	# 	#  :9;O;O;Q:R44
 	# 	#s   3C *C?4C<;C<?D)r:   privater/  commit_messager%   r9   	create_prr;  c          	        t        |      }
|
j                  ||d|xs |      }|j                  }| j                  j	                  |       |	| j                  j                  |	       ||
j                  ||d       |d}d}t        j                         5 }| j                  ||       |
j                  ||||||	      }ddd       |rj                  S j                  S # 1 sw Y   #xY w)
a  
        Upload the CrossEncoder model to the Hugging Face Hub.

        Example:
            ::

                from sentence_transformers import CrossEncoder

                model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L6-v2")
                model.push_to_hub("username/my-crossencoder-model")
                # => "https://huggingface.co/username/my-crossencoder-model"

        Args:
            repo_id (str): The name of the repository on the Hugging Face Hub, e.g. "username/repo_name",
                "organization/repo_name" or just "repo_name".
            token (str, optional): The authentication token to use for the Hugging Face Hub API.
                If not provided, will use the token stored via the Hugging Face CLI.
            private (bool, optional): Whether to create a private repository. If not specified,
                the repository will be public.
            safe_serialization (bool, optional): Whether or not to convert the model weights in safetensors
                format for safer serialization. Defaults to True.
            commit_message (str, optional): The commit message to use for the push. Defaults to "Add new CrossEncoder model".
            exist_ok (bool, optional): If True, do not raise an error if the repository already exists.
                Ignored if ``create_pr=True``. Defaults to False.
            revision (str, optional): The git branch to commit to. Defaults to the head of the 'main' branch.
            create_pr (bool, optional): Whether to create a Pull Request with the upload or directly commit. Defaults to False.
            tags (list[str], optional): A list of tags to add to the model card. Defaults to None.

        Returns:
            str: URL of the commit or pull request (if create_pr=True)
        )r:   N)repo_idrC  	repo_typer%   T)rG  branchr%   zAdd new CrossEncoder model r.  )rG  folder_pathrD  commit_descriptionr9   rE  )r
   create_reporG  rI   set_model_idadd_tagscreate_branchtempfileTemporaryDirectoryr1  upload_folderpr_url
commit_url)r`   rG  r:   rC  r/  rD  r%   r9   rE  r;  apirepo_urlrL  tmp_dir
folder_urls                  r,   push_to_hubzCrossEncoder.push_to_hub  s   X % ??*	 # 
 ""))'2  ))$/ghN!9N((* 	g  #5 !  **#-#5!# + J	 $$$$$$!	 	s   +C''C0c                    | j                   S )a  
        Property to get the underlying transformers PreTrainedModel instance.

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

        Example:
            ::

                from sentence_transformers import CrossEncoder

                model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L6-v2")

                # You can now access the underlying transformers model
                transformers_model = model.transformers_model
                print(type(transformers_model))
                # => <class 'transformers.models.bert.modeling_bert.BertForSequenceClassification'>
        r   rv   s    r,   transformers_modelzCrossEncoder.transformers_model  s    , zzr.   c                D    t         j                  d       | j                  S )NzY`CrossEncoder._target_device` has been removed, please use `CrossEncoder.device` instead.)rN   rO   rd   rv   s    r,   _target_devicezCrossEncoder._target_device  s    g	
 {{r.   c                &    | j                  |       y r   )r]   )r`   rd   s     r,   r^  zCrossEncoder._target_device  s    r.   c                .    | j                   j                  S r   )rs   rd   rv   s    r,   rd   zCrossEncoder.device  r   r.   c                8    | j                   j                  |      S r   )rs   gradient_checkpointing_enable)r`   gradient_checkpointing_kwargss     r,   rb  z*CrossEncoder.gradient_checkpointing_enable  s    zz778UVVr.   )NNNNNFNFNNNNNro   ) ra   r   rS   
int | Nonerb   rd  rc   Callable | Nonerd   
str | NonerC   rf  r8   boolr9   rf  r6   rg  r:   zbool | str | Nonere   dict | Nonerf   rh  rg   rh  rI   z CrossEncoderModelCardData | Noner?   $Literal['torch', 'onnx', 'openvino']r/   r0   )ra   r   r>   r   r?   r   r/   r0   )r/   ri  r   )r   list[str] | Noner/   2dict[Literal['input', 'output', 'processes'], Any])r   rk  r/   r0   )TFNNN)r   'list[tuple[str, str]] | list[list[str]]r   bool | Noner   rg  r   9dict[Literal['input', 'output', 'processes'], Any] | Nonerd   %str | list[str | torch.device] | Noner   rd  )
r   r   rs   r4   r   r   r   r   r/   r0   )T)rc   re  r   rg  r/   r0   )r/   r   )r   r   r/   r0   )r/   r   )r/   int)r   rp  r/   r0   )	......NNN)r   ztuple[str, str] | list[str]r   rp  r   rm  rc   re  r   rm  r   Literal[False]r   rq  rd   ro  r   rn  r   rd  r/   torch.Tensor)	....TFNNN)r   Elist[tuple[str, str]] | list[list[str]] | tuple[str, str] | list[str]r   rp  r   rm  rc   re  r   rm  r   Literal[True]r   rq  rd   ro  r   rn  r   rd  r/   z
np.ndarray)r   rs  r   rp  r   rm  rc   re  r   rm  r   rg  r   rt  rd   ro  r   rn  r   rd  r/   rr  )r   rl  r   rp  r   rm  rc   re  r   rm  r   rq  r   rq  rd   ro  r   rn  r   rd  r/   zlist[torch.Tensor])	    NNFTFNNN)r   rs  r   rp  r   rm  rc   re  r   rm  r   rg  r   rg  rd   ro  r   rn  r   rd  r/   z.list[torch.Tensor] | np.ndarray | torch.Tensor)NFru  NNFTFNNN)r&  r   r'  z	list[str]r(  rd  r)  rg  r   rp  r   rm  rc   re  r   rg  r   rg  rd   ro  r   rn  r   rd  r/   zDlist[dict[Literal['corpus_id', 'score', 'text'], int | float | str]])r4  r   r/  rg  r/   r0   )r4  r   r/   r0   )rG  r   r:   rf  rC  rm  r/  rg  rD  rf  r%   rg  r9   rf  rE  rg  r;  rj  r/   r   )r/   zPreTrainedModel | None)r/   ztorch.device)rd   zint | str | torch.device | Noner/   r0   )r/   r0   )'__name__
__module____qualname____doc__r   rH   rT   rw   r   staticmethodr   r   r   r[   r   r   propertyr>   rS   rb   setterr   r   r   r	   r   ro   inference_moder   r-  r5  r1  r2  rZ  r\  r^  rd   rb  __classcell__)rm   s   @r,   r4   r4   6   s   CJ ' "&!%)-!#'"'#!&#'$((,%)<@8?!lSlS lS 	lS
 'lS lS !lS  lS lS lS !lS "lS &lS #lS :lS  6!lS" 
#lS 'lS\vv !v 	v 
v< 260V.0V	;0Vd  . *.#(JN8<!%L3?L3 'L3 !	L3
 HL3 6L3 L3\ ### # 	#
 
# #JQ4S ! ! & & / / 0 0 	."	 
"+  ),),%(+.,/8<JN!%.  '	
 ' # ) * 6 H  
   ),),%(*.,18<JN!%X  '	
 ' # ( * 6 H  
   ),),%(!$+.8<JN!%X  '	
 ' #  ) 6 H  
   ),),%(+.,/8<JN!%!:! ! '	!
 '! #! )! *! 6! H! ! 
! ! U. )-)-%*!%"'8<JN!%HXH H '	H
 'H #H H  H 6H HH H 
8H / HT /
 !!&)-)-!%"'8<JN!%hh h 	h
 h h 'h 'h h  h 6h Hh h 
Nh /hT =A & HL P!#N !##'%)#!%N%N% 	N%
 N% !N% #N% N% N% N% N% 
N%`  .     ! !W Wr.   r4   )r*   r   r+   r   r/   zCallable[..., None])B
__future__r   r  r   r&   r   rQ  r>  collections.abcr   multiprocessingr   pathlibr   typingr   r   r	   r  r   ro   torch.multiprocessingr   huggingface_hubr
   	packagingr   r   tqdm.autonotebookr   transformersr   r   r   r   r   r   r   transformers.utilsr   typing_extensionsr   r;   r   sentence_transformers.backendr   r   -sentence_transformers.cross_encoder.fit_mixinr   .sentence_transformers.cross_encoder.model_cardr   r   (sentence_transformers.cross_encoder.utilr   r   sentence_transformers.utilr   r    r!   r"   	getLoggerrv  rN   r2   Moduler4   r1   r.   r,   <module>r     s    "   	    $ !  ) )   " !   $   . ( - N B i e d			8	$NW299nh NWr.   