Ë
    ýÿæiÅ*  ã                   óØ   — d dl Z d dlmZ d dlmZmZmZmZmZ d dl	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 d dlmZ d dlmZ d d	lmZmZ d d
lmZmZ esdgZesddgZ G d„ de«      Zy)é    N)ÚSequence)ÚAnyÚClassVarÚListÚOptionalÚUnion)ÚTensor)Ú_load_tokenizer_and_model)Ú$_ALLOWED_INFORMATION_MEASURE_LITERALÚ_get_dataloaderÚ_get_special_tokens_mapÚ_infolm_computeÚ_infolm_updateÚ_InformationMeasure)ÚMetric)Údim_zero_cat)Ú_MATPLOTLIB_AVAILABLEÚ_TRANSFORMERS_GREATER_EQUAL_4_4)Ú_AX_TYPEÚ_PLOT_OUT_TYPEzInfoLM.plotÚInfoLMc                   óÚ  ‡ — e Zd ZU dZdZee   ed<   ee   ed<   ee   ed<   ee   ed<   ddddddddddœ	Ze	ed	<   	 	 	 	 	 	 	 	 	 	 	 	 d"de
eej                  f   dedededee   dee   dee
eej&                  f      dee   dededededeeef   dd
fˆ fd„Zedefd„«       Zde
eee   f   de
eee   f   dd
fd„Zde
eeeef   f   fd„Z	 d#dee
eee   f      d ee   defd!„Z ˆ xZ!S )$r   uÆ  Calculate `InfoLM`_.

    InfoLM measures a distance/divergence between predicted and reference sentence discrete distribution using one of
    the following information measures:

        - `KL divergence`_
        - `alpha divergence`_
        - `beta divergence`_
        - `AB divergence`_
        - `RÃ©nyi divergence`_
        - L1 distance
        - L2 distance
        - L-infinity distance
        - `Fisher-Rao distance`_

    `InfoLM`_ is a family of untrained embedding-based metrics which addresses some famous flaws of standard
    string-based metrics thanks to the usage of pre-trained masked language models. This family of metrics is mainly
    designed for summarization and data-to-text tasks.

    The implementation of this metric is fully based HuggingFace ``transformers``' package.

    As input to ``forward`` and ``update`` the metric accepts the following input:

    - ``preds`` (:class:`~Sequence`): An iterable of hypothesis corpus
    - ``target`` (:class:`~Sequence`): An iterable of reference corpus

    As output of ``forward`` and ``compute`` the metric returns the following output:

    -  ``infolm`` (:class:`~torch.Tensor`): If `return_sentence_level_score=True` return a tuple with a tensor
       with the corpus-level InfoLM score and a list of sentence-level InfoLM scores, else return a corpus-level
       InfoLM score

    Args:
        model_name_or_path:
            A name or a model path used to load ``transformers`` pretrained model.
            By default the `"bert-base-uncased"` model is used.
        temperature:
            A temperature for calibrating language modelling. For more information, please reference `InfoLM`_ paper.
        information_measure:
            A name of information measure to be used. Please use one of: ['kl_divergence', 'alpha_divergence',
            'beta_divergence', 'ab_divergence', 'renyi_divergence', 'l1_distance', 'l2_distance', 'l_infinity_distance',
            'fisher_rao_distance']
        idf:
            An indication of whether normalization using inverse document frequencies should be used.
        alpha:
            Alpha parameter of the divergence used for alpha, AB and RÃ©nyi divergence measures.
        beta:
            Beta parameter of the divergence used for beta and AB divergence measures.
        device:
            A device to be used for calculation.
        max_length:
            A maximum length of input sequences. Sequences longer than ``max_length`` are to be trimmed.
        batch_size:
            A batch size used for model processing.
        num_threads:
            A number of threads to use for a dataloader.
        verbose:
            An indication of whether a progress bar to be displayed during the embeddings calculation.
        return_sentence_level_score:
            An indication whether a sentence-level InfoLM score to be returned.

    Example:
        >>> from torchmetrics.text.infolm import InfoLM
        >>> preds = ['he read the book because he was interested in world history']
        >>> target = ['he was interested in world history because he read the book']
        >>> infolm = InfoLM('google/bert_uncased_L-2_H-128_A-2', idf=False)
        >>> infolm(preds, target)
        tensor(-0.1784)

    FÚpreds_input_idsÚpreds_attention_maskÚtarget_input_idsÚtarget_attention_maskT)	Úkl_divergenceÚalpha_divergenceÚbeta_divergenceÚab_divergenceÚrenyi_divergenceÚl1_distanceÚl2_distanceÚl_infinity_distanceÚfisher_rao_distanceÚ%_information_measure_higher_is_betterNÚmodel_name_or_pathÚtemperatureÚinformation_measureÚidfÚalphaÚbetaÚdeviceÚ
max_lengthÚ
batch_sizeÚnum_threadsÚverboseÚreturn_sentence_level_scoreÚkwargsÚreturnc                 óh  •— t        ‰| �  di |¤Ž || _        || _        || _        || _        || _        || _        t        j                  |xs d«      | _
        |	| _        |
| _        || _        || _        t        ||«      \  | _        | _        t%        |||«      | _        |xs  | j"                  j(                  j*                  | _        t-        | j                   «      | _        | j1                  dg d¬«       | j1                  dg d¬«       | j1                  dg d¬«       | j1                  dg d¬«       y )	NÚcpur   Úcat)Údist_reduce_fxr   r   r   © )ÚsuperÚ__init__r'   r(   r)   r*   r+   r,   Útorchr-   Ú_devicer/   r0   r1   r2   r
   Ú	tokenizerÚmodelr   Úinformation_measure_clsÚconfigr.   r   Úspecial_tokens_mapÚ	add_state)Úselfr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   Ú	__class__s                 €úm/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/text/infolm.pyr;   zInfoLM.__init__†   s  ø€ ô  	‰ÑÑ"˜6Ò"Ø"4ˆÔØ&ˆÔØ#6ˆÔ ØˆŒØˆŒ
ØˆŒ	Ü—|‘| F¢O¨eÓ4ˆŒØ$ˆŒØ&ˆÔØˆŒØ+FˆÔ(ä%>Ð?QÐSYÓ%ZÑ"ˆŒ˜œ
Ü':Ð;NÐPUÐW[Ó'\ˆÔ$Ø$ÒD¨¯
©
×(9Ñ(9×(DÑ(DˆŒÜ"9¸$¿.¹.Ó"IˆÔà�‰Ð(¨"¸UˆÔCØ�‰Ð-¨rÀ%ˆÔHØ�‰Ð)¨2¸eˆÔDØ�‰Ð.°À5ˆÕIó    c                 ó4   — | j                   | j                     S )z¹Returns a bool indicating whether a higher value of the information measure is better.

        Done this way as depends on if the information measure is positive or negative.

        )r&   r)   )rD   s    rF   Úhigher_is_betterzInfoLM.higher_is_better­   s   € ð ×9Ñ9¸$×:RÑ:RÑSÐSrG   ÚpredsÚtargetc                 ó*  — t        ||| j                  | j                  «      \  }}}}| j                  j	                  |«       | j
                  j	                  |«       | j                  j	                  |«       | j                  j	                  |«       y)z*Update state with predictions and targets.N)r   r>   r.   r   Úappendr   r   r   )rD   rJ   rK   r   r   r   r   s          rF   ÚupdatezInfoLM.update¶   s   € äYgØ�6˜4Ÿ>™>¨4¯?©?óZ
ÑVˆÐ-Ð/?ÐAVð 	×Ñ×#Ñ# OÔ4Ø×!Ñ!×(Ñ(Ð)=Ô>Ø×Ñ×$Ñ$Ð%5Ô6Ø×"Ñ"×)Ñ)Ð*?Õ@rG   c           
      óJ  — t        t        | j                  «      t        | j                  «      | j                  | j
                  | j                  ¬«      }t        t        | j                  «      t        | j                  «      | j                  | j
                  | j                  ¬«      }t        | j                  ||| j                  | j                  | j                  | j                  | j                  «      }| j                  r|j!                  «       |fS |j!                  «       S )zLCalculate selected information measure using the pre-trained language model.)Ú	input_idsÚattention_maskr*   r/   Únum_workers)r   r   r   r   r*   r/   r0   r   r   r   r?   r(   r@   rB   r1   r2   Úmean)rD   Úpreds_dataloaderÚtarget_dataloaderÚinfo_lm_scores       rF   ÚcomputezInfoLM.computeÀ   sð   € ä*Ü" 4×#7Ñ#7Ó8Ü'¨×(AÑ(AÓBØ—‘Ø—‘Ø×(Ñ(ô
Ðô ,Ü" 4×#8Ñ#8Ó9Ü'¨×(BÑ(BÓCØ—‘Ø—‘Ø×(Ñ(ô
Ðô (Ø�J‰JØØØ×ÑØ�H‰HØ×(Ñ(Ø×#Ñ#Ø�L‰Ló	
ˆð ×+Ò+Ø ×%Ñ%Ó'¨Ð6Ð6à×!Ñ!Ó#Ð#rG   ÚvalÚaxc                 ó&   — | j                  ||«      S )a1  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> from torchmetrics.text.infolm import InfoLM
            >>> metric = InfoLM('google/bert_uncased_L-2_H-128_A-2', idf=False)
            >>> preds = ['he read the book because he was interested in world history']
            >>> target = ['he was interested in world history because he read the book']
            >>> metric.update(preds, target)
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> from torchmetrics.text.infolm import InfoLM
            >>> metric = InfoLM('google/bert_uncased_L-2_H-128_A-2', idf=False)
            >>> preds = ["this is the prediction", "there is an other sample"]
            >>> target = ["this is the reference", "there is another one"]
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(preds, target))
            >>> fig_, ax_ = metric.plot(values)

        )Ú_plot)rD   rX   rY   s      rF   ÚplotzInfoLM.plotá   s   € ðT �z‰z˜#˜rÓ"Ð"rG   )zbert-base-uncasedg      Ð?r   TNNNNé@   r   TF)NN)"Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úis_differentiabler   r	   Ú__annotations__r&   r   r   ÚstrÚosÚPathLikeÚfloatr   Úboolr   r<   r-   ÚintÚdictr   r;   ÚpropertyrI   r   rN   ÚtuplerW   r   r   r\   Ú__classcell__)rE   s   @rF   r   r   *   s  ø… ñEðN ÐØ˜&‘\Ó!Ø˜v™,Ó&Ø˜6‘lÓ"Ø ™<Ó'ð Ø à ØØ!ØØØ$Ø$ñ7Ð)¨8ó ð  7JØ!ØDSØØ!%Ø $Ø59Ø$(ØØØØ,1ñ%Jà! # r§{¡{Ð"2Ñ3ð%Jð ð%Jð Bð	%Jð
 ð%Jð ˜‰ð%Jð �u‰oð%Jð ˜˜s E§L¡LÐ0Ñ1Ñ2ð%Jð ˜S‘Mð%Jð ð%Jð ð%Jð ð%Jð &*ð%Jð �s˜C�x‘.ð%Jð 
õ%JðN ðT $ò Tó ðTðA˜E # x°¡}Ð"4Ñ5ð A¸uÀSÈ(ÐSVÉ-ÐEWÑ?Xð AÐ]aó Að$˜˜v u¨V°V¨^Ñ'<Ð<Ñ=ó $ðD _cñ*#Ø˜E &¨(°6Ñ*:Ð":Ñ;Ñ<ð*#ØIQÐRZÑI[ð*#à	÷*#rG   ) re   Úcollections.abcr   Útypingr   r   r   r   r   r<   r	   Ú4torchmetrics.functional.text.helper_embedding_metricr
   Ú#torchmetrics.functional.text.infolmr   r   r   r   r   r   Útorchmetrics.metricr   Útorchmetrics.utilities.datar   Útorchmetrics.utilities.importsr   r   Útorchmetrics.utilities.plotr   r   Ú__doctest_skip__r   r9   rG   rF   Ú<module>rw      s[   ðó 
Ý $ß 7Õ 7ã Ý å Z÷÷ õ 'Ý 4ß aß @áØ%�Ðá&Ø  -Ð0Ðôa#ˆVõ a#rG   