o
    }oiq                     @   s   d dl mZ d dlmZmZmZ d dlmZmZm	Z	 d dl
Z
d dlmZ d dlmZmZmZ d dlmZmZ d dlmZmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZ G dd deZ G dd de Z!eG dd dZ"dS )    )abstractmethod)	dataclassfieldis_dataclass)ListOptionalUnionN)	OmegaConf)AEDBeamInferAEDBeamInferConfigTransformerAEDBeamInfer)AEDGreedyInferConfigTransformerAEDGreedyInfer)ConfidenceConfigConfidenceMixin)
HypothesisNBestHypotheses)AggregateTokenizer)TokenizerSpec)loggingc                       sZ  e Zd ZdZdejjdejjdef fddZde	dd fd	d
Z
			d%dejdejdeej dedeee  deee eee  f fddZdee deeeef  fddZdee dee fddZdedee fddZedee de	fddZedee dee	 fdd Zedee de	fd!d"Zedee dee	 fd#d$Z  ZS )&AbstractMultiTaskDecodinguo  
    Used for performing AED auto-regressive decoding of the Multi task model given the encoder state.

    Args:
        decoding_cfg: A dict-like object which contains the following key-value pairs.
            strategy: str value which represents the type of decoding that can occur.
                Possible values are :
                -   greedy, greedy_batch (for greedy decoding).
                -   beam, tsd, alsd (for beam search decoding).

            compute_langs: a bool flag, which allows to compute language id (LID) information per token,
                word, and the entire sample (most likely language id). The LIDS will be available
                in the returned Hypothesis object as a dictionary

            compute_hypothesis_token_set: A bool flag, which determines whether to compute a list of decoded
                tokens as well as the decoded string. Default is False in order to avoid double decoding
                unless required.

            preserve_alignments: Bool flag which preserves the history of logprobs generated during
                decoding (sample / batched). When set to true, the Hypothesis will contain
                the non-null value for `alignments` in it. Here, `alignments` is a List of List of
                Tuple(Tensor (of length V + 1), Tensor(scalar, label after argmax)).

                In order to obtain this hypothesis, please utilize `rnnt_decoder_predictions_tensor` function
                with the `return_hypotheses` flag set to True.

            confidence_cfg: A dict-like object which contains the following key-value pairs related to confidence scores.
                preserve_frame_confidence: Bool flag which preserves the history of per-frame confidence scores
                    generated during greedy decoding. When set to true, the Hypothesis will contain the non-null value
                    for `frame_confidence` in it. Here, `frame_confidence` is a List of tensor floats.

                preserve_token_confidence: Bool flag which preserves the history of per-token confidence scores
                    generated during greedy decoding. When set to true, the Hypothesis will contain the non-null value
                    for `token_confidence` in it. Here, `token_confidence` is a List of tensor floats.
                    The length of the list corresponds to the number of recognized tokens.

                preserve_word_confidence: Bool flag which preserves the history of per-word confidence scores
                    generated during greedy decoding. When set to true, the Hypothesis will contain the non-null value
                    for `word_confidence` in it. Here, `word_confidence` is a List of tensor floats.
                    The length of the list corresponds to the number of recognized words.

                aggregation: Which aggregation type to use for collapsing per-token confidence into per-word
                    confidence. Valid options are `mean`, `min`, `max`, `prod`.

                method_cfg: A dict-like object which contains settings to compute per-frame confidence scores.
                    name: The method name (str).
                        Supported values:
                            - 'max_prob' for using the maximum token probability as a confidence.
                            - 'entropy' for using a normalized entropy of a log-likelihood vector.
                    entropy_type: Which type of entropy to use (str). Used if confidence_method_cfg.name is set to `entropy`.
                        Supported values:
                            - 'gibbs' for the (standard) Gibbs entropy. If the alpha (α) is provided,
                                the formula is the following: H_α = -sum_i((p^α_i)*log(p^α_i)).
                                Note that for this entropy, the alpha should comply the following inequality:
                                (log(V)+2-sqrt(log^2(V)+4))/(2*log(V)) <= α <= (1+log(V-1))/log(V-1)
                                where V is the model vocabulary size.
                            - 'tsallis' for the Tsallis entropy with the Boltzmann constant one.
                                Tsallis entropy formula is the following: H_α = 1/(α-1)*(1-sum_i(p^α_i)),
                                where α is a parameter. When α == 1, it works like the Gibbs entropy.
                                More: https://en.wikipedia.org/wiki/Tsallis_entropy
                            - 'renyi' for the Rényi entropy.
                                Rényi entropy formula is the following: H_α = 1/(1-α)*log_2(sum_i(p^α_i)),
                                where α is a parameter. When α == 1, it works like the Gibbs entropy.
                                More: https://en.wikipedia.org/wiki/R%C3%A9nyi_entropy
                    alpha: Power scale for logsoftmax (α for entropies). Here we restrict it to be > 0.
                        When the alpha equals one, scaling is not applied to 'max_prob',
                        and any entropy type behaves like the Shannon entropy: H = -sum_i(p_i*log(p_i))
                    entropy_norm: A mapping of the entropy value to the interval [0,1].
                        Supported values:
                            - 'lin' for using the linear mapping.
                            - 'exp' for using exponential mapping with linear shift.

            The config may further contain the following sub-dictionaries:
            "greedy":
                temperature: None (disabled) or float, specifying this enables temperature sampling instead of greedy decoding.
                max_generation_delta: int = -1  # -1 means up to the max length of the decoder
                preserve_alignments: bool = False (unsupported)

            "beam":
                beam_size: int, defining the beam size for beam search. Must be >= 1.
                    If beam_size == 1, will perform cached greedy search. This might be slightly different
                    results compared to the greedy search above.

                length_penalty: float, length penalty for beam search decoding. Must be >= 0.0.

                max_generation_delta: int,in case of encoder-decoder generation (e.g. NMT),
                    forbids generated sequences to be longer than the length of source sequences plus max_generation_delta

                return_best_hypothesis: optional bool, whether to return just the best hypothesis or all of the
                    hypotheses after beam search has concluded. This flag is set by default.


        transformer_decoder: Transformer decoder module.
        log_softmax_module: Log Softmax projection module to the vocab size.
        tokenizer: Aggregate Tokenizer.
    transformer_decoderlog_softmax_module	tokenizerc                    s   t    t|rt|}|| _| jdd | _| jdd| _| jdd| _	|| _
|| _|| _| | jdd  | | jj d S )Npreserve_alignmentscompute_langsFcompute_hypothesis_token_setconfidence_cfg)super__init__r   r	   
structuredcfggetr   r   r   r   r   r   _init_confidencechange_strategystrategyselfdecoding_cfgr   r   r   	__class__ l/home/ubuntu/.local/lib/python3.10/site-packages/nemo/collections/asr/parts/submodules/multitask_decoding.pyr      s   

z"AbstractMultiTaskDecoding.__init__r%   returnc                 C   sf  g d}||vrt d| d| | jd u r2|dv r%| jjdd| _n|dv r2| jjdd| _|dv rh| jjdd urCt d	t| j| j| j	| jjd
d| j| j
pX| j| j| jjj| jjjd	| _d S |dkrt| j| j| j	| jjdd| jjj| jjdd| jjd
d| jjdd| j| jjdd | jjddd| _d S t d| d| )N)greedygreedy_batchbeamz!Decoding strategy must be one of zbut was provided )r.   r/   r   F)r0   ngram_lm_modelzZGreedy strategy cannot be used with ngram_lm_model. Use beam strategy with beam=1 instead.max_generation_delta)	r   r   r   r2   r   preserve_token_confidenceconfidence_method_cfgtemperature	n_samplesr0   search_typedefaultlength_penaltyg        return_best_hypothesisTngram_lm_alpha)r   r   r   r8   	beam_sizer:   r2   r;   r   r1   r<   z5Incorrect decoding strategy provided. Must be one of z
but was provided )
ValueErrorr   r!   r.   r"   r0   r   r   r   r   r4   preserve_frame_confidencer5   r6   r7   decodingr   r=   )r'   r%   possible_strategiesr+   r+   r,   r$      sV   

z)AbstractMultiTaskDecoding.change_strategyNFencoder_hidden_statesencoder_input_maskdecoder_input_idsreturn_hypothesespartial_hypothesesc                 C   s   t   | j||||d}|d }W d   n1 sw   Y  |}t|d trTg }g }	|D ]}
|
j}| |}||d  |	| q0|rK|	S dd |	D }|S | |}|rk| jri| j	sd| j
ri| |}|S dd |D S )a  
        Decode an encoder output by autoregressive decoding of the Decoder+Joint networks.

        Args:
            encoder_output: torch.Tensor of shape [B, D, T].
            encoded_lengths: torch.Tensor containing lengths of the padded encoder outputs. Shape [B].
            return_hypotheses: bool. If set to True it will return list of Hypothesis or NBestHypotheses

        Returns:
            If `return_all_hypothesis` is set:
                A list[list[Hypothesis]].
                    Look at rnnt_utils.Hypothesis for more information.

            If `return_all_hypothesis` is not set:
                A list[Hypothesis].
                List of best hypotheses
                    Look at rnnt_utils.Hypothesis for more information.
        )rB   rC   rD   rF   r   Nc                 S   s   g | ]	}d d |D qS )c                 S      g | ]}t |j|j|jqS r+   r   score
y_sequencetext.0hr+   r+   r,   
<listcomp>      zRAbstractMultiTaskDecoding.decode_predictions_tensor.<locals>.<listcomp>.<listcomp>r+   )rM   hhr+   r+   r,   rO     s    zGAbstractMultiTaskDecoding.decode_predictions_tensor.<locals>.<listcomp>c                 S   rG   r+   rH   rL   r+   r+   r,   rO     rP   )torchinference_moder@   
isinstancer   n_best_hypothesesdecode_hypothesisappendr?   preserve_word_confidencer4   compute_confidence)r'   rB   rC   rD   rE   rF   hypotheses_listprediction_list
hypothesesall_hypotheses	nbest_hypn_hypsdecoded_hypsall_hypr+   r+   r,   decode_predictions_tensor   s@   




z3AbstractMultiTaskDecoding.decode_predictions_tensorrZ   c                 C   s^   t t|D ]&}|| j}t|tkr| }| |}| jr'| ||| _	||| _
q|S )z
        Decode a list of hypotheses into a list of strings.

        Args:
            hypotheses_list: List of Hypothesis.

        Returns:
            A list of strings.
        )rangelenrJ   typelisttolistdecode_tokens_to_strr   decode_ids_to_tokenstokensrK   )r'   rZ   ind
prediction
hypothesisr+   r+   r,   rV     s   


z+AbstractMultiTaskDecoding.decode_hypothesisc                 C   s    | j r|D ]}| ||_q|S )aH  
        Compute high-level (per-token and/or per-word) confidence scores for a list of hypotheses.
        Assumes that `token_confidence` is present in the hypotheses.

        Args:
            hypotheses_list: List of Hypothesis.

        Returns:
            A list of hypotheses with high-level confidence scores.
        )rX   _aggregate_token_confidenceword_confidence)r'   rZ   hypr+   r+   r,   rY   9  s   z,AbstractMultiTaskDecoding.compute_confidencerm   c                 C   s   |  |j|j|jS )a"  
        Implemented by subclass in order to reduce token confidence to a word-level confidence.

        **Note**: Only supports Sentencepiece based tokenizers!

        Args:
            hypothesis: Hypothesis

        Returns:
            A list of word-level confidence scores.
        )2_aggregate_token_confidence_subwords_sentencepiecewordstoken_confidencerJ   )r'   rm   r+   r+   r,   rn   I  s   z5AbstractMultiTaskDecoding._aggregate_token_confidencerj   c                 C      t  )z
        Implemented by subclass in order to decoder a token id list into a string.

        Args:
            tokens: List of int representing the token ids.

        Returns:
            A decoded string.
        NotImplementedErrorr'   rj   r+   r+   r,   rh   Y  s   z.AbstractMultiTaskDecoding.decode_tokens_to_strc                 C   rt   a&  
        Implemented by subclass in order to decode a token id list into a token list.
        A token list is the string representation of each token id.

        Args:
            tokens: List of int representing the token ids.

        Returns:
            A list of decoded tokens.
        ru   rw   r+   r+   r,   ri   f     z.AbstractMultiTaskDecoding.decode_ids_to_tokensc                 C   rt   )z
        Implemented by subclass in order to
        compute the most likely language ID (LID) string given the tokens.

        Args:
            tokens: List of int representing the token ids.

        Returns:
            A decoded LID string.
        ru   rw   r+   r+   r,   decode_tokens_to_langt  ry   z/AbstractMultiTaskDecoding.decode_tokens_to_langc                 C   rt   )z
        Implemented by subclass in order to
        decode a token id list into language ID (LID) list.

        Args:
            tokens: List of int representing the token ids.

        Returns:
            A list of decoded LIDS.
        ru   rw   r+   r+   r,   decode_ids_to_langs  ry   z-AbstractMultiTaskDecoding.decode_ids_to_langs)NFN)__name__
__module____qualname____doc__rR   nnModuler   r   strr$   Tensorr   boolr   r   r   rb   r   rV   rY   floatrn   r   intrh   ri   rz   r{   __classcell__r+   r+   r)   r,   r   &   sJ    a9

"F$r   c                       s   e Zd ZdZdejjdejjdef fddZde	e
 defd	d
Zde	e
 de	e fddZde	e
 defddZde	e
 de	e fddZde	e de	eeef  f fddZ  ZS )MultiTaskDecodingu  
    Used for performing AED auto-regressive decoding of the Multi task model given the encoder state.

    Args:
        decoding_cfg: A dict-like object which contains the following key-value pairs.
            strategy: str value which represents the type of decoding that can occur.
                Possible values are :
                -   greedy, greedy_batch (for greedy decoding).
                -   beam, tsd, alsd (for beam search decoding).

            compute_langs: a bool flag, which allows to compute language id (LID) information per token,
                word, and the entire sample (most likely language id). The LIDS will be available
                in the returned Hypothesis object as a dictionary

            compute_hypothesis_token_set: A bool flag, which determines whether to compute a list of decoded
                tokens as well as the decoded string. Default is False in order to avoid double decoding
                unless required.

            preserve_alignments: Bool flag which preserves the history of logprobs generated during
                decoding (sample / batched). When set to true, the Hypothesis will contain
                the non-null value for `alignments` in it. Here, `alignments` is a List of List of
                Tuple(Tensor (of length V + 1), Tensor(scalar, label after argmax)).

                In order to obtain this hypothesis, please utilize `rnnt_decoder_predictions_tensor` function
                with the `return_hypotheses` flag set to True.

            confidence_cfg: A dict-like object which contains the following key-value pairs related to confidence scores.
                preserve_frame_confidence: Bool flag which preserves the history of per-frame confidence scores
                    generated during greedy decoding. When set to true, the Hypothesis will contain the non-null value
                    for `frame_confidence` in it. Here, `frame_confidence` is a List of tensor floats.

                preserve_token_confidence: Bool flag which preserves the history of per-token confidence scores
                    generated during greedy decoding. When set to true, the Hypothesis will contain the non-null value
                    for `token_confidence` in it. Here, `token_confidence` is a List of tensor floats.
                    The length of the list corresponds to the number of recognized tokens.

                preserve_word_confidence: Bool flag which preserves the history of per-word confidence scores
                    generated during greedy decoding. When set to true, the Hypothesis will contain the non-null value
                    for `word_confidence` in it. Here, `word_confidence` is a List of tensor floats.
                    The length of the list corresponds to the number of recognized words.

                aggregation: Which aggregation type to use for collapsing per-token confidence into per-word
                    confidence. Valid options are `mean`, `min`, `max`, `prod`.

                method_cfg: A dict-like object which contains settings to compute per-frame confidence scores.
                    name: The method name (str).
                        Supported values:
                            - 'max_prob' for using the maximum token probability as a confidence.
                            - 'entropy' for using a normalized entropy of a log-likelihood vector.
                    entropy_type: Which type of entropy to use (str). Used if confidence_method_cfg.name is set to `entropy`.
                        Supported values:
                            - 'gibbs' for the (standard) Gibbs entropy. If the alpha (α) is provided,
                                the formula is the following: H_α = -sum_i((p^α_i)*log(p^α_i)).
                                Note that for this entropy, the alpha should comply the following inequality:
                                (log(V)+2-sqrt(log^2(V)+4))/(2*log(V)) <= α <= (1+log(V-1))/log(V-1)
                                where V is the model vocabulary size.
                            - 'tsallis' for the Tsallis entropy with the Boltzmann constant one.
                                Tsallis entropy formula is the following: H_α = 1/(α-1)*(1-sum_i(p^α_i)),
                                where α is a parameter. When α == 1, it works like the Gibbs entropy.
                                More: https://en.wikipedia.org/wiki/Tsallis_entropy
                            - 'renyi' for the Rényi entropy.
                                Rényi entropy formula is the following: H_α = 1/(1-α)*log_2(sum_i(p^α_i)),
                                where α is a parameter. When α == 1, it works like the Gibbs entropy.
                                More: https://en.wikipedia.org/wiki/R%C3%A9nyi_entropy
                    alpha: Power scale for logsoftmax (α for entropies). Here we restrict it to be > 0.
                        When the alpha equals one, scaling is not applied to 'max_prob',
                        and any entropy type behaves like the Shannon entropy: H = -sum_i(p_i*log(p_i))
                    entropy_norm: A mapping of the entropy value to the interval [0,1].
                        Supported values:
                            - 'lin' for using the linear mapping.
                            - 'exp' for using exponential mapping with linear shift.

            The config may further contain the following sub-dictionaries:
            "greedy":
                temperature: None (disabled) or float, specifying this enables temperature sampling instead of greedy decoding.

                max_generation_delta: int = -1  # -1 means up to the max length of the decoder

                preserve_alignments: bool = False (unsupported)

            "beam":
                beam_size: int, defining the beam size for beam search. Must be >= 1.
                    If beam_size == 1, will perform cached greedy search. This might be slightly different
                    results compared to the greedy search above.

                length_penalty: float, length penalty for beam search decoding. Must be >= 0.0.

                max_generation_delta: int, maximum number of additional target tokens to generate

                return_best_hypothesis: optional bool, whether to return just the best hypothesis or all of the
                    hypotheses after beam search has concluded. This flag is set by default.


        transformer_decoder: Transformer decoder module.
        log_softmax_module: Log Softmax projection module to the vocab size.
        tokenizer: TokenizerSpec.
    r   r   r   c                    s:   || _ t j||||d t| jtr| jd d S d S )N)r(   r   r   r   subword)r   r   r   rT   r@   r
   set_decoding_typer&   r)   r+   r,   r     s   zMultiTaskDecoding.__init__rj   r-   c                 C      | j |}|S )z
        Implemented by subclass in order to decoder a token list into a string.

        Args:
            tokens: List of int representing the token ids.

        Returns:
            A decoded string.
        )r   ids_to_text)r'   rj   rm   r+   r+   r,   rh        
z&MultiTaskDecoding.decode_tokens_to_strc                 C   r   rx   )r   ids_to_tokens)r'   rj   
token_listr+   r+   r,   ri     s   z&MultiTaskDecoding.decode_ids_to_tokensc                 C   r   )z
        Compute the most likely language ID (LID) string given the tokens.

        Args:
            tokens: List of int representing the token ids.

        Returns:
            A decoded LID string.
        )r   ids_to_lang)r'   rj   langr+   r+   r,   rz   "  r   z'MultiTaskDecoding.decode_tokens_to_langc                 C   r   )z
        Decode a token id list into language ID (LID) list.

        Args:
            tokens: List of int representing the token ids.

        Returns:
            A list of decoded LIDS.
        )r   ids_to_text_and_langs)r'   rj   	lang_listr+   r+   r,   r{   /  r   z%MultiTaskDecoding.decode_ids_to_langsrZ   c                    s   t  |}| jr>t| jtr9tt|D ]!}|| j}t	|t
kr&| }| ||| _| ||| _q|S td |S )z
        Decode a list of hypotheses into a list of strings.
        Overrides the super() method optionally adding lang information

        Args:
            hypotheses_list: List of Hypothesis.

        Returns:
            A list of strings.
        zbIgnoring request for lang output in hypotheses since the model does not use an aggregate tokenizer)r   rV   r   rT   r   r   rc   rd   rJ   re   rf   rg   rz   langsr{   langs_charsr   warning)r'   rZ   r\   rk   rl   r)   r+   r,   rV   <  s   
z#MultiTaskDecoding.decode_hypothesis)r|   r}   r~   r   rR   r   r   r   r   r   r   r   rh   ri   rz   r{   r   r   r   rV   r   r+   r+   r)   r,   r     s    b.r   c                   @   s   e Zd ZU dZeed< dZeed< dZe	e ed< e
dd d	Zeed
< dZeed< e
ed	Zeed< e
dd d	Zeed< dZeed< dS )MultiTaskDecodingConfigr0   r%   Fr   Nr   c                   C   s   t  S )N)r   r+   r+   r+   r,   <lambda>e  s    z MultiTaskDecodingConfig.<lambda>)default_factoryr   r   r.   c                   C   s
   t ddS )N   )r=   )r   r+   r+   r+   r,   r   n  s   
 g      ?r6   )r|   r}   r~   r%   r   __annotations__r   r   r   r   r   r   r   r   r   r.   r0   r   r6   r   r+   r+   r+   r,   r   [  s   
 r   )#abcr   dataclassesr   r   r   typingr   r   r   rR   	omegaconfr	   =nemo.collections.asr.parts.submodules.multitask_beam_decodingr
   r   r   ?nemo.collections.asr.parts.submodules.multitask_greedy_decodingr   r   5nemo.collections.asr.parts.utils.asr_confidence_utilsr   r   +nemo.collections.asr.parts.utils.rnnt_utilsr   r   6nemo.collections.common.tokenizers.aggregate_tokenizerr   1nemo.collections.common.tokenizers.tokenizer_specr   
nemo.utilsr   r   r   r   r+   r+   r+   r,   <module>   s&     m K