
    izh              0          d dl Z d dlZd dlZd dlmZ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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!m"Z" d dl#m$Z$m%Z% eded   fd       Z&dZ'e%rd dl(m)Z)m*Z* d?dZ+e!r e"e+      sdgZ,ndgZ,	 	 	 	 	 	 d@dede-dedeee.ej^                  f      dee-   de0de0de0dee
ee1e.ef   gef      deeef   fdZ2dede.dedefdZ3d ed!ed"ed#edeeeef   f
d$Z4dAd%ee.   dee-   de0de.fd&Z5d'e.defd(Z6d)e.defd*Z7	 	 	 	 dBd+e.d%ee.   d'ee.   d)ee.   dee   f
d,Z8	 	 dCd-ed.ed/ed0edee-   de0deeeef   fd1Z9d2ee.   d3eee.ee.   f      deee.   ee.   eeee-e-f         f   fd4Z:d-ed.ed/ed5eee-e-f      deeeef   f
d6Z;	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dDd2ee.ee.   e1e.ef   f   d3ee.ee.   eee.      e1e.ef   f   d%ee.   dee-   de0dee   d7e	dee
ee1e.ef   gef      de0de0deee.ej^                  f      d8e-d9e-d:e-d;e0d+e.d<e0d'ee.   d)ee.   d=e0de1e.eeee<   e.f   f   f*d>Z=y)E    N)IteratorSequence)contextmanager)AnyCallableListOptionalTupleUnioncast)Tensor)Module)
DataLoader)TextDatasetTokenizedDataset_check_shape_of_model_output_get_progress_bar_input_data_collator_output_data_collator*_process_attention_mask_for_special_tokens)rank_zero_warn)_SKIP_SLOW_DOCTEST_try_proceed_with_timeout)_TQDM_AVAILABLE_TRANSFORMERS_GREATER_EQUAL_4_4returnc               #      K   t        j                  d      } | j                         }	 | j                  t         j                         d | j                  |       y# | j                  |       w xY ww)z]Ignore irrelevant fine-tuning warning from transformers when loading the model for BertScore.ztransformers.modeling_utilsN)logging	getLoggergetEffectiveLevelsetLevelERROR)loggeroriginal_levels     v/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/text/bert.py_ignore_log_warningr&   (   sW      <=F--/N(&''s   &A4#A A4A11A4zroberta-large)	AutoModelAutoTokenizerc                      t               5  t        j                  t               t	        j                  t               ddd       y# 1 sw Y   yxY w)zDownload intensive operations.N)r&   r(   from_pretrained_DEFAULT_MODELr'        r%   _download_model_for_bert_scorer.   :   s0     ")).9%%n5 #""s   3AA
bert_score
dataloader
target_lenmodeldevice
num_layers
all_layersidfverboseuser_forward_fnc	           
         g }	g }
t        | |      D ]  }t        j                         5  t        ||      }|sQ|s% ||d   |d   d      }|j                  ||nd   }n |||      }t        ||d          |j                  d      }n\|rt        d       ||d   |d   d      }t        j                  |j                  D cg c]  }|j                  d       c}d	      }ddd       |j                  d	      j                  d      z  }t        ||d   |      \  }}t        |      }t        j                  d
||      }|	j                  |j                                |r|d   |z  n|j                  |j                         }||j#                  dd      z  }|
j                  |j                                 t        j                  |	      }t        j                  |
      }||fS c c}w # 1 sw Y   xY w)a<  Calculate sentence embeddings and the inverse-document-frequency scaling factor.

    Args:
        dataloader: dataloader instance.
        target_len: A length of the longest sequence in the data. Used for padding the model output.
        model: BERT model.
        device: A device to be used for calculation.
        num_layers: The layer of representation to use.
        all_layers: An indication whether representation from all model layers should be used for BERTScore.
        idf: An Indication whether normalization using inverse document frequencies should be used.
        verbose: An indication of whether a progress bar to be displayed during the embeddings' calculation.
        user_forward_fn:
            A user's own forward function used in a combination with ``user_model``. This function must
            take ``user_model`` and a python dictionary of containing ``"input_ids"`` and ``"attention_mask"``
            represented by :class:`~torch.Tensor` as an input and return the model's output represented by the single
            :class:`~torch.Tensor`.

    Return:
        A tuple of :class:`~torch.Tensor`s containing the model's embeddings and the normalized tokens IDF.
        When ``idf = False``, tokens IDF is not calculated, and a matrix of mean weights is returned instead.
        For a single sentence, ``mean_weight = 1/seq_len``, where ``seq_len`` is a sum over the corresponding
        ``attention_mask``.

    Raises:
        ValueError:
            If ``all_layers = True`` and a model, which is not from the ``transformers`` package, is used.

    	input_idsattention_maskT)output_hidden_statesN   zQThe option `all_layers=True` can be used only with default `transformers` models.dimzblsd, bs -> blsdinput_ids_idf)keepdim)r   torchno_gradr   hidden_statesr   	unsqueeze
ValueErrorcatnormr   r   einsumappendcputypedtypesum)r0   r1   r2   r3   r4   r5   r6   r7   r8   embeddings_listidf_scale_listbatchoutor;   processed_attention_maskrA   
embeddings	idf_scales                      r%   _get_embeddings_and_idf_scalerX   F   s   N %'O#%N":w7]]_(7E&k 2E:J4KbfgC++*:PJVXYC)%7C0eK6HImmA&"$k  E+.6F0G^bcii9J9J K9JAQ9J KQRS# & 	sxxBx))"--3C?O9PR\]^#Mn#] ll-s4LMswwy) BEE/"%==JbJgJghkhqhqJr 	 	**2t*<<m//12A 8D ?+J		.)Iy  ' !L# _s   BG5G0	G50G55G?	cos_simmetricrW   c                     |dk(  rdnd}| j                  |      j                  }t        j                  d||      j	                  d      }|j                  dd      j                         S )	zOCalculate precision or recall, transpose it and scale it with idf_scale factor.	precision      r?   zbls, bs -> blsr=   r   r>   )maxvaluesrC   rJ   rO   	transposesqueeze)rY   rZ   rW   r@   ress        r%   _get_scaled_precision_or_recallrd      s^    $!!C
++#+

%
%C
,,'i
8
<
<R
@C==A&&((r-   preds_embeddingstarget_embeddingspreds_idf_scaletarget_idf_scalec                     t        j                  d| |      }t        |d|      }t        |d|      }d|z  |z  ||z   z  }|j                  t        j                  |      d      }|||fS )a  Calculate precision, recall and F1 score over candidate and reference sentences.

    Args:
        preds_embeddings: Embeddings of candidate sentences.
        target_embeddings: Embeddings of reference sentences.
        preds_idf_scale: An IDF scale factor for candidate sentences.
        target_idf_scale: An IDF scale factor for reference sentences.

    Return:
        Tensors containing precision, recall and F1 score, respectively.

    zblpd, blrd -> blprr\   recallr^           )rC   rJ   rd   masked_fillisnan)re   rf   rg   rh   rY   r\   rj   f1_scores           r%   _get_precision_recall_f1ro      sv      ll/1ACTUG/oVI,Wh@PQF9}v%V);<H##EKK$93?Hfh&&r-   model_name_or_pathc                      |  d| |rd S d S )z,Compute `BERT_score`_ (copied and adjusted)._L_idfz_no-idfr,   )rp   r4   r6   s      r%   	_get_hashrt      s&     !J<#/MNN9/MNNr-   baseline_pathc                 8   t        |       5 }t        j                  |      }t        |      D cg c]$  \  }}|dkD  s|D cg c]  }t	        |       c}& }}}}ddd       t        j                        ddddf   S c c}w c c}}}w # 1 sw Y   3xY w)zqRead baseline from csv file from the local file.

    This method implemented to avoid `pandas` dependency.

    r   Nr>   )opencsvreader	enumeratefloatrC   tensor)ru   fnamecsv_fileidxrowitembaseline_lists          r%   _read_csv_from_local_filer      s     
m	::e$GPQYGZfGZ83^ade^e#6#$%+#6GZf 
 <<&q!"u-- 7f 
	s3   %BB	
B	
BB	
BB	
	BBbaseline_urlc                    t         j                  j                  |       5 }t        |      D cg c]O  \  }}|dkD  rE|j	                         j                  d      j                  d      D cg c]  }t        |       c}Q }}}}t        j                  |      ddddf   cddd       S c c}w c c}}}w # 1 sw Y   yxY w)ziRead baseline from csv file from URL.

    This method is implemented to avoid `pandas` dependency.

    r   zutf-8,Nr>   )
urllibrequesturlopenrz   stripdecodesplitr{   rC   r|   )r   http_requestr   r   r   r   s         r%   _read_csv_from_urlr      s     
			- &l3
3SQw &)YY[%7%7%@%F%Fs%KL%KTU4[%KL3 	 

 ||M*1ab51 
.	-L
 
.	-s.   B;=B4
-B/?B4
!B;/B4
4B;;Clangc                     |rt        |      }|S |rt        |      }|S | r|rd}| d|  d| d}t        |      }|S t        d       y)z<Load a CSV file with the baseline values used for rescaling.zWhttps://raw.githubusercontent.com/Tiiiger/bert_score/master/bert_score/rescale_baseline/z.tsvzFBaseline was not successfully loaded. No baseline is going to be used.N)r   r   r   )r   rp   ru   r   baselineurl_bases         r%   _load_baseliner      st     %>}%M O 
%l3 O 
$l"1TF!,>+?tD%l3
 O 	_`r-   r\   rj   rn   r   c                     ||du rd}t        j                  | ||gd      }|r|j                  d      n||   }||z
  d|z
  z  }|d   |d   |d   fS )z<Rescale the computed metrics with the pre-computed baseline.Fr=   r?   r>   ).r   ).r>   ).r^   )rC   stackrF   )r\   rj   rn   r   r4   r5   all_metricsbaseline_scales           r%   _rescale_metrics_with_baseliner      sv     jE1
++y&(;DK.8X''*hz>RN/A4FGKvF 3[5HHHr-   predstargetc                    t        d | D              st        d      t        d |D              }|rg }g }g }d}t        | |      D ]  \  }}t	        |t
        t        f      rr|j                  |gt        |      z         |j                  t        t        t           |             |j                  ||t        |      z   f       |t        |      z  }|j                  |       |j                  t        t        |             |j                  ||dz   f       |dz  } |||fS | t        t        t           |      dfS )a  Preprocesses predictions and targets when dealing with multiple references.

    This function handles the case where a single prediction might have multiple
    reference targets (represented as a list/tuple of strings).

    Args:
        preds: A list of predictions
        target: A list of targets, where each item could be a string or a list/tuple of strings

    Returns:
        Tuple: (preds, target, ref_group_boundaries)
            - preds: Flattened list of `str`
            - target: Flattened list of `str`
            - ref_group_boundaries: List of tuples (start, end) indicating the boundaries
              of reference groups in the flattened lists or `None`

    c              3   <   K   | ]  }t        |t                y wN)
isinstancestr.0r   s     r%   	<genexpr>z2_preprocess_multiple_references.<locals>.<genexpr>  s     7z$$s   Invalid input provided.c              3   H   K   | ]  }t        |t        t        f        y wr   )r   listtupler   s     r%   r   z2_preprocess_multiple_references.<locals>.<genexpr>  s     R64z$u>6s    "r   r>   N)allrG   anyzipr   r   r   extendlenr   r   r   rK   )	r   r   has_nested_sequencesref_group_boundaries	new_preds
new_targetcountpred	ref_groups	            r%   _preprocess_multiple_referencesr     s1   ( 777233R6RR68!	 "
"5&1OD))dE]3  $#i.!89!!$tCy)"<=$++UEC	N4J,KLY'  &!!$sI"67$++UEAI,>?
  2 *&:::$tCy&)4//r-   r   c                 b   g g g }}}|D ]  \  }}| j                         dkD  r|j                  | dd||f   j                  d      d          |j                  |dd||f   j                  d      d          |j                  |dd||f   j                  d      d          |j                  | || j                                |j                  ||| j                                |j                  ||| j                                
 | j                         dkD  rFt        j                  |d      } t        j                  |d      }t        j                  |d      }n?t        j                  |      } t        j                  |      }t        j                  |      }| ||fS )a)  Postprocesses metrics when dealing with multiple references.

    For each group of references that correspond to a single prediction,
    this function takes the maximum score among all references.

    Args:
        precision: Tensor of precision scores
        recall: Tensor of recall scores
        f1_score: Tensor of F1 scores
        ref_group_boundaries: List of tuples (start, end) indicating the boundaries
                              of reference groups

    Returns:
        tuple: (precision, recall, f1_score) with updated metrics

    r>   Nr?   r   )r@   rK   r_   rC   r   )	r\   rj   rn   r   max_precision
max_recallmax_f1startends	            r%    _postprocess_multiple_referencesr   2  s   & )+Bv:M*
s==?Q  1eCi<!8!<!<!<!CA!FGfQc	\26616=a@AMM(1eCi<0444;A>?  5!5!9!9!;<fU3/3356MM(5-1134 + }}KK15	ZQ/;;v1-KK.	Z(;;v&fh&&r-   user_tokenizer
max_length
batch_sizenum_threadsreturn_hashrescale_with_baseline
truncationc                    d}t        | t              r| g} t        |t              r|g}t        | t        t        f      st        |       } t        |t        t        f      st        |      }t	        |       t	        |      k7  r#t        dt	        |        dt	        |             t        | t              r<t	        |       dkD  r.t        |t              rt	        |      dkD  rt        | |      \  } }}t        |	t              st        d|	 d      |rt        st        d      |tt        st        d      |t        d	t         d       t               5  t        j                  |xs t              }t!        j                  |xs t              }ddd       n|}|j#                          |j%                  |
       	 t'        |j(                  d
      rgt        |j(                  j*                  t,              rC|rL||j(                  j*                  kD  r3t        d| d| d|j(                  j*                         t        d       t1        d | |fD              }t1        d | |fD              }t1        d | |fD              }|r6t        d       dgdgdgd}|r|j3                  dt5        |||	      i       |S |rt7        ||||      nd}|r,t9        |||	|      }t9        | |||	|j:                  |      }n7|r*t=        di |d|	i}t=        di | |	|j:                  d}nt        d      t?        |||      }t?        |||      }tA        ||jB                  ||
|||	||	      \  }} tA        ||jB                  ||
|||	||	      \  }!}"|!|jD                  jF                     }!||jD                  jF                     }|"|jD                  jF                     }"| |jD                  jF                     } tI        |!||"|       \  }#}$}%|tK        |#|$|%|||      \  }#}$}%|tM        |#|$|%|      \  }#}$}%|#|$|%d}|r|j3                  dt5        |||	      i       |S # 1 sw Y   xY w# t.        $ r t        d       Y 3w xY w)a2  `Bert_score Evaluating Text Generation`_ for text similirity matching.

    This metric leverages the pre-trained contextual embeddings from BERT and matches words in candidate and reference
    sentences by cosine similarity. It has been shown to correlate with human judgment on sentence-level and
    system-level evaluation. Moreover, BERTScore computes precision, recall, and F1 measure, which can be useful for
    evaluating different language generation tasks.

    This implementation follows the original implementation from `BERT_score`_.

    Args:
        preds (Union[str, Sequence[str]]): A single predicted sentence or a sequence of predicted sentences.
        target (Union[str, Sequence[str], Sequence[Sequence[str]]]): A single target sentence, a sequence of target
            sentences, or a sequence of sequences of target sentences for multiple references per prediction.
        model_name_or_path: A name or a model path used to load ``transformers`` pretrained model.
        num_layers: A layer of representation to use.
        all_layers:
            An indication of whether the representation from all model's layers should be used.
            If ``all_layers = True``, the argument ``num_layers`` is ignored.
        model: A user's own model.
        user_tokenizer:
            A user's own tokenizer used with the own model. This must be an instance with the ``__call__`` method.
            This method must take an iterable of sentences (``List[str]``) and must return a python dictionary
            containing ``"input_ids"`` and ``"attention_mask"`` represented by :class:`~torch.Tensor`.
            It is up to the user's model of whether ``"input_ids"`` is a :class:`~torch.Tensor` of input ids
            or embedding vectors. his tokenizer must prepend an equivalent of ``[CLS]`` token and append an equivalent
            of ``[SEP]`` token as `transformers` tokenizer does.
        user_forward_fn:
            A user's own forward function used in a combination with ``user_model``.
            This function must take ``user_model`` and a python dictionary of containing ``"input_ids"``
            and ``"attention_mask"`` represented by :class:`~torch.Tensor` as an input and return the model's output
            represented by the single :class:`~torch.Tensor`.
        verbose: An indication of whether a progress bar to be displayed during the embeddings' calculation.
        idf: An indication of whether normalization using inverse document frequencies should be used.
        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.
        return_hash: An indication of whether the correspodning ``hash_code`` should be returned.
        lang: A language of input sentences. It is used when the scores are rescaled with a baseline.
        rescale_with_baseline:
            An indication of whether bertscore should be rescaled with a pre-computed baseline.
            When a pretrained model from ``transformers`` model is used, the corresponding baseline is downloaded
            from the original ``bert-score`` package from `BERT_score`_ if available.
            In other cases, please specify a path to the baseline csv/tsv file, which must follow the formatting
            of the files from `BERT_score`_
        baseline_path: A path to the user's own local csv/tsv file with the baseline scale.
        baseline_url: A url path to the user's own  csv/tsv file with the baseline scale.
        truncation: An indication of whether the input sequences should be truncated to the maximum length.

    Returns:
        Python dictionary containing the keys ``precision``, ``recall`` and ``f1`` with corresponding values.

    Raises:
        ValueError:
            If ``len(preds) != len(target)``.
        ModuleNotFoundError:
            If `tqdm` package is required and not installed.
        ModuleNotFoundError:
            If ``transformers`` package is required and not installed.
        ValueError:
            If ``num_layer`` is larger than the number of the model layers.
        ValueError:
            If invalid input is provided.

    Example:
        >>> from pprint import pprint
        >>> from torchmetrics.functional.text.bert import bert_score
        >>> preds = ["hello there", "general kenobi"]
        >>> target = ["hello there", "master kenobi"]
        >>> pprint(bert_score(preds, target))
        {'f1': tensor([1.0000, 0.9961]), 'precision': tensor([1.0000, 0.9961]), 'recall': tensor([1.0000, 0.9961])}

    Example:
        >>> from pprint import pprint
        >>> from torchmetrics.functional.text.bert import bert_score
        >>> preds = ["hello there", "general kenobi"]
        >>> target = [["hello there", "master kenobi"], ["hello there", "master kenobi"]]
        >>> pprint(bert_score(preds, target))
        {'f1': tensor([1.0000, 0.9961]), 'precision': tensor([1.0000, 0.9961]), 'recall': tensor([1.0000, 0.9961])}

    NzLExpected number of predicted and reference sentences to be the same, but gotz and r   z1Expected argument `idf` to be a boolean, but got .zcAn argument `verbose = True` requires `tqdm` package be installed. Install with `pip install tqdm`.z`bert_score` metric with default models requires `transformers` package be installed. Either install with `pip install transformers>=4.4` or `pip install torchmetrics[text]`.zThe argument `model_name_or_path` was not specified while it is required when default `transformers` model are used.It is, therefore, used the default recommended model - num_hidden_layersznum_layers=z is forbidden for z. Please use num_layers <= zhModel config does not have `num_hidden_layers` as an integer attribute. Unable to validate `num_layers`.zXIt was not possible to retrieve the parameter `num_layers` from the model specification.c              3   \   K   | ]$  }t        |t              xr t        |      d k(   & ywr   N)r   r   r   r   texts     r%   r   zbert_score.<locals>.<genexpr>  s*     aQ`:dD1Dc$i1nDQ`s   *,c              3      K   | ]9  }t        |t              xr# t        |      d kD  xr t        |d    t               ; ywr   )r   r   r   r   r   s     r%   r   zbert_score.<locals>.<genexpr>  s=      ZiRV
4M3t9q=MZQ5MMZis   ?Ac              3   f   K   | ])  }t        |t              xr t        |d    t               + yw)r:   N)r   dictr   r   s     r%   r   zbert_score.<locals>.<genexpr>  s0      UdT
4H:d;.?#HHUds   /1z%Predictions and references are empty.rk   )r\   rj   f1hash)r6   r   )r6   
tokens_idfr   r6   )r6   r   r   )r   num_workersr,   )'r   r   r   r   r   rG   r   boolr   ModuleNotFoundErrorr   r   r+   r&   r(   r*   r'   evaltohasattrconfigr   intAttributeErrorr   updatert   r   r   r   r   r   rX   r   datasetsorting_indicesro   r   r   )&r   r   rp   r4   r5   r2   r   r8   r7   r6   r3   r   r   r   r   r   r   ru   r   r   r   	tokenizer_are_empty_lists_are_valid_lists_are_valid_tensorsoutput_dictr   target_datasetpreds_datasettarget_loaderpreds_loaderrf   rh   re   rg   r\   rj   rn   s&                                         r%   r/   r/   ]  s   N =A%&#edD\*UftTl+f
5zS[ Z5zl%F}.
 	

 %3u:>j6NSVW]S^abSb.MeU[.\+v+c4 LSEQRSTT!q
 	
 }.%l  %JJXIYYZ\
 !"%556H6ZN[I--.@.RNSE #" #		JJL	HHVs5<<!45*U\\EcEceh:ij5<<+I+II !*-?@R?S T1161O1O0PR 
 3 aRWY_Q`aa [`bhZi   V[]cUd  >?e%C

 	2DjRU(VWX Yn~d$6|TswH $VY
Xbc#%00!
 
)<F<<(`5`cnF_F_`233~*R]^Mm
P[\L*G~00%ZY\^egv+'' )Fm..vz:WZ\cet)%o ((<(<(L(LM)-*?*?*O*OP%l&:&:&J&JKO'(=(=(M(MN":+_>N#Ivx &Dvx:z'
#	68 '&Fvx)='
#	68
 K
 FI.@*c$RSTE #"(  sqrss   ;Q=BQ! Q!Q98Q9)r   N)NNFFFN)NNF)enNNN)NF)NNFNNNFFNi   @   r   Fr   FNNF)>rx   r   r   collections.abcr   r   
contextlibr   typingr   r   r   r	   r
   r   r   rC   r   torch.nnr   torch.utils.datar   4torchmetrics.functional.text.helper_embedding_metricr   r   r   r   r   r   r   torchmetrics.utilitiesr   torchmetrics.utilities.checksr   r   torchmetrics.utilities.importsr   r   r&   r+   transformersr'   r(   r.   __doctest_skip__r   r   r3   r   r   rX   rd   ro   rt   r   r   r   r   r   r   r{   r/   r,   r-   r%   <module>r      s$      . % D D D    '   2 W [ (Xd^ ( ( !"56 ";<Z"[(>$~ 26 $OSN!N!N! N! U3,-.	N!
 N! N! 
N! N! hS&[0A'BF'JKLN! 66>N!b)V )S )V )X^ )''17'JP'dj'
666!"'6O(3- OHSM O_c Ops O
	.S 	.V 	.2S 2V 2  (,#'"&	
  C= 3-	
 f8 !%III I 	I
 I I 666!"I$+09+0"5hsm);#<=+0
49d3i$uS#X*?!@@A+0\('('%('17('OSTYZ]_bZbTcOd('
666!"('\ )- $"OS15"'#'"&)qhsmT#v+%667q#x}hx}&=tCK?PPQq !q 	q
 q Fq q hS&[0A'BF'JKLq q 
q U3,-.q q q q q  !q"  #q$ C=%q& 3-'q( )q* 
#uVT%[#-.
./+qr-   