o
    *jT                     @   s   d dl mZmZ d dlmZ d dlmZmZmZm	Z	 d dl
Z
dZdZG dd deZG d	d
 d
eZG dd dZG dd deZG dd deZG dd deZG dd deZdS )    )ABCabstractmethod)UserDict)IterableListOptionalTupleNag  
    Args:
        input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size * num_beams, sequence_length)`):
            Indices of input sequence tokens in the vocabulary.

            Indices can be obtained using any class inheriting from :class:`~transformers.PretrainedTokenizer`. See
            :meth:`transformers.PreTrainedTokenizer.encode` and :meth:`transformers.PreTrainedTokenizer.__call__` for
            details.

            `What are input IDs? <../glossary.html#input-ids>`__
        next_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, 2 * num_beams)`):
            Current scores of the top :obj:`2 * num_beams` non-finished beam hypotheses.
        next_tokens (:obj:`torch.LongTensor` of shape :obj:`(batch_size, 2 * num_beams)`):
            :obj:`input_ids` of the tokens corresponding to the top :obj:`2 * num_beams` non-finished beam hypotheses.
        next_indices (:obj:`torch.LongTensor` of shape :obj:`(batch_size, 2 * num_beams)`):
            Beam indices indicating to which beam hypothesis the :obj:`next_tokens` correspond.
        pad_token_id (:obj:`int`, `optional`):
            The id of the `padding` token.
        eos_token_id (:obj:`int`, `optional`):
            The id of the `end-of-sequence` token.

    Return:
        :obj:`UserDict`: A dictionary composed of the fields as defined above:

            - **next_beam_scores** (:obj:`torch.FloatTensor` of shape :obj:`(batch_size * num_beams)`) -- Updated
              scores of all non-finished beams.
            - **next_beam_tokens** (:obj:`torch.FloatTensor` of shape :obj:`(batch_size * num_beams)`) -- Next tokens
              to be added to the non-finished beam_hypotheses.
            - **next_beam_indices** (:obj:`torch.FloatTensor` of shape :obj:`(batch_size * num_beams)`) -- Beam indices
              indicating to which beam the next tokens shall be added.

a  
    Args:
        input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size * num_beams, sequence_length)`):
            Indices of input sequence tokens in the vocabulary.

            Indices can be obtained using any class inheriting from :class:`~transformers.PretrainedTokenizer`. See
            :meth:`transformers.PreTrainedTokenizer.encode` and :meth:`transformers.PreTrainedTokenizer.__call__` for
            details.

            `What are input IDs? <../glossary.html#input-ids>`__
        final_beam_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size * num_beams)`):
            The final scores of all non-finished beams.
        final_beam_tokens (:obj:`torch.FloatTensor` of shape :obj:`(batch_size * num_beams)`):
            The last tokens to be added to the non-finished beam_hypotheses.
        final_beam_indices (:obj:`torch.FloatTensor` of shape :obj:`(batch_size * num_beams)`):
            The beam indices indicating to which beam the :obj:`final_beam_tokens` shall be added.
        pad_token_id (:obj:`int`, `optional`):
            The id of the `padding` token.
        eos_token_id (:obj:`int`, `optional`):
            The id of the `end-of-sequence` token.

    Return:
        :obj:`torch.LongTensor` of shape :obj:`(batch_size * num_return_sequences, sequence_length)`: The generated
        sequences. The second dimension (sequence_length) is either equal to :obj:`max_length` or shorter if all
        batches finished early due to the :obj:`eos_token_id`.

c                   @   sl   e Zd ZdZedejdejdejdejdeej	 f
ddZ
edejdejdejdejdejf
d	d
ZdS )
BeamScorerz
    Abstract base class for all beam scorers that are used for :meth:`~transformers.PretrainedModel.beam_search` and
    :meth:`~transformers.PretrainedModel.beam_sample`.
    	input_idsnext_scoresnext_tokensnext_indicesreturnc                 K      t dNzThis is an abstract method.NotImplementedErrorselfr
   r   r   r   kwargs r   l/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/models/nlp/mglm/generation_utils.pyprocessY   s   zBeamScorer.processc                 K   r   r   r   r   r   r   r   finalize`   s   zBeamScorer.finalizeN)__name__
__module____qualname____doc__r   torch
LongTensorFloatTensorr   Tensorr   r   r   r   r   r   r	   S   s,    r	   c                   @   s   e Zd ZdZ			ddedededejd	ee d
ee	 dee fddZ
ede	fddZ			d dejdejdejdejdee dee deej fddZ			d dejdejdejdejdee dee deejeej f fddZdS )!BeamSearchScorera  
    :class:`transformers.BeamScorer` implementing standard beam search decoding.

    Adapted in part from `Facebook's XLM beam search code
    <https://github.com/facebookresearch/XLM/blob/9e6f6814d17be4fe5b15f2e6c43eb2b2d76daeb4/src/model/transformer.py#L529>`__.

    Args:
        batch_size (:obj:`int`):
            Batch Size of :obj:`input_ids` for which beam search decoding is run in parallel.
        max_length (:obj:`int`):
            The maximum length of the sequence to be generated.
        num_beams (:obj:`int`):
            Number of beams for beam search.
        device (:obj:`torch.device`):
            Defines the device type (*e.g.*, :obj:`"cpu"` or :obj:`"cuda"`) on which this instance of
            :obj:`BeamSearchScorer` will be allocated.
        length_penalty (:obj:`float`, `optional`, defaults to 1.0):
            Exponential penalty to the length. 1.0 means no penalty. Set to values < 1.0 in order to encourage the
            model to generate shorter sequences, to a value > 1.0 in order to encourage the model to produce longer
            sequences.
        do_early_stopping (:obj:`bool`, `optional`, defaults to :obj:`False`):
            Whether to stop the beam search when at least ``num_beams`` sentences are finished per batch or not.
        num_beam_hyps_to_keep (:obj:`int`, `optional`, defaults to 1):
            The number of beam hypotheses that shall be returned upon calling
            :meth:`~transformer.BeamSearchScorer.finalize`.
          ?F   
batch_size
max_length	num_beamsdevicelength_penaltydo_early_stoppingnum_beam_hyps_to_keepc                    sj   | _ | _| _| _| _| _d _ fddt|D  _t	j
dd t|D t	j jd _d S )NFc                    s$   g | ]}t  j j j jd qS ))r'   r&   r)   early_stopping)BeamHypothesesr'   r&   r)   r*   .0_r   r   r   
<listcomp>   s    z-BeamSearchScorer.__init__.<locals>.<listcomp>c                 S   s   g | ]}d qS )Fr   r.   r   r   r   r2          dtyper(   )r&   r'   r(   r)   r*   r+   Z_is_initrange
_beam_hypsr   Ztensorbool_done)r   r%   r&   r'   r(   r)   r*   r+   r   r1   r   __init__   s   

zBeamSearchScorer.__init__r   c                 C   s
   | j  S N)r9   allr1   r   r   r   is_done   s   
zBeamSearchScorer.is_doneNr
   r   r   r   pad_token_ideos_token_idc                    sd  |j d }t| j}	|	|j d | j ksJ t|tr|g}|j}
tj|	| jf|j	|
d}tj|	| jf|j	|
d}tj|	| jf|j	|
d}t
| jD ]\}}| j| rt|| jksbJ d| j|d urj|d usnJ dd||d d f< |||d d f< d||d d f< qJd}t
t|| || || D ]W\}\}} || j   }|d ur| |v r|| jk}|rq|j||  | |ṙ fdd|D nd d n||||f< ||||f< ||||f< |d	7 }|| jkr nq|| jk rtd
| j d||  d| d||  d	| j| p|||   || j|< qJt|d|d|ddS )Nr   r4   z?Batch can only be done if at least {} beams have been generatedzMgenerated beams >= num_beams -> eos_token_id and pad_token have to be definedc                    s   g | ]	}|   g qS r   )itemr/   memZ
next_indexr   r   r2      s    z,BeamSearchScorer.process.<locals>.<listcomp>memsr$   zAt most z tokens in z  can be equal to `eos_token_id: z`. Make sure z are corrected.)next_beam_scoresnext_beam_tokensnext_beam_indices)shapelenr7   r'   
isinstanceintr(   r   Zzerosr5   	enumerater9   formatziprA   addclone
ValueErrorr=   maxr   view)r   r
   r   r   r   r>   r?   rF   cur_lenr%   r(   rG   rH   rI   	batch_idxbeam_hypZbeam_idxZbeam_token_rank
next_tokenZ
next_scorebatch_beam_idxZ&is_beam_token_worse_than_top_num_beamsr   rD   r   r      s   






&zBeamSearchScorer.processfinal_beam_scoresfinal_beam_tokensfinal_beam_indicesc                    s  t | j}t| jD ]6\}	}
| j|	 rq
t| jD ]&}|	| j |  |   }|  }|
j||r; fddD nd d qq
||| j	 }g }t| jD ]1\}}
t
|
jdd d}t| j	D ]}| dd  \}t ||| j	| | < ||f qbqPt|  | j}||| j	 |}|  |  kr|d usJ d|| g t|D ]#\}\}}|||d || f< || |k r||||| f< | qrd	 rfd
dtt d	 D nd |fS )Nc                    s   g | ]}| g qS r   r   rB   )rZ   r   r   r2     s    z-BeamSearchScorer.finalize.<locals>.<listcomp>rE   c                 S   s   | d S )Nr   r   )xr   r   r   <lambda>  s    z+BeamSearchScorer.finalize.<locals>.<lambda>)keyr$   z `pad_token_id` has to be definedr   c                    s(   g | ] t j fd dD ddqS )c                    s   g | ]}|  qS r   r   rB   ir   r   r2   6  s    z8BeamSearchScorer.finalize.<locals>.<listcomp>.<listcomp>r   )dim)r   cat)r/   rE   ra   r   r2   5  s    )rK   r7   rN   r9   r6   r'   rA   rQ   newr+   sortedbeamspopappendminrT   r&   Zfill_)r   r
   r[   r\   r]   r>   r?   rF   r%   rW   rX   Zbeam_idZfinal_scoreZfinal_tokensZsent_lengthsbestrb   Zsorted_hypsjZbest_hypZsent_max_lendecodedZhyporC   r   )rZ   rF   r   r      sh   




zBeamSearchScorer.finalize)r#   Fr$   )NNN)r   r   r   r   rM   r   r(   r   floatr8   r:   propertyr=   r   r    r   r!   r   r   r   r   r   r   r   r"   g   st    !
"
Zr"   c                   @   sZ   e Zd ZdedededefddZdd Zdd
ej	defddZ
dededefddZd	S )r-   r'   r&   r)   r,   c                 C   s,   |d | _ || _|| _|| _g | _d| _dS )z7
        Initialize n-best list of hypotheses.
        r$   g    eAN)r&   r)   r,   r'   rg   worst_score)r   r'   r&   r)   r,   r   r   r   r:   >  s   

zBeamHypotheses.__init__c                 C   s
   t | jS )z3
        Number of hypotheses in the list.
        )rK   rg   r1   r   r   r   __len__J  s   
zBeamHypotheses.__len__Nhypsum_logprobsc                 C   s   |t |jd d| j  }t| | jk s|| jkrO| j|||f t| | jkrFtdd t	| jD }| j|d d = |d d | _dS t
|| j| _dS dS )z3
        Add a new hypothesis to the list.
        r@   r$   c                 S   s   g | ]\}\}}}||fqS r   r   )r/   idxsr0   r   r   r   r2   X  s    z&BeamHypotheses.add.<locals>.<listcomp>r   N)rT   rJ   r)   rK   r'   rp   rg   ri   rf   rN   rj   )r   rr   rs   rF   ZscoreZsorted_next_scoresr   r   r   rQ   P  s   zBeamHypotheses.addbest_sum_logprobsrV   r   c                 C   s8   t | | jk r	dS | jrdS ||| j  }| j|k}|S )z
        If there are enough hypotheses and that none of the hypotheses being generated can become better than the worst
        one in the heap, then we are done with this sentence.
        FT)rK   r'   r,   r)   rp   )r   rv   rV   Z	cur_scoreretr   r   r   r=   `  s   
zBeamHypotheses.is_doner;   )r   r   r   rM   rn   r8   r:   rq   r   r   rQ   r=   r   r   r   r   r-   <  s    
r-   c                   @   ,   e Zd ZdZdejdejdejfddZdS )LogitsProcessorzSAbstract base class for all logit processors that can be applied during generation.r
   scoresr   c                 C   s   t | j d)z#Torch method for processing logits.zH is an abstract class. Only classes inheriting this class can be called.)r   	__class__)r   r
   rz   r   r   r   __call__s  s   
zLogitsProcessor.__call__Nr   r   r   r   r   r   r    r|   r   r   r   r   ry   p  s    ry   c                   @   rx   )LogitsProcessorListav  
    This class can be used to create a list of :class:`~transformers.LogitsProcessor` or
    :class:`~transformers.LogitsWarper` to subsequently process a :obj:`scores` input tensor. This class inherits from
    list and adds a specific `__call__` method to apply each :class:`~transformers.LogitsProcessor` or
    :class:`~transformers.LogitsProcessor` to the inputs.
    r
   rz   r   c                 C   s   | D ]}|||}q|S r;   r   )r   r
   rz   	processorr   r   r   r|     s   zLogitsProcessorList.__call__Nr}   r   r   r   r   r~   {  s    r~   c                   @   s>   e Zd ZdZdedefddZdejdejdejfd	d
Z	dS )MinLengthLogitsProcessoraU  
    :class:`transformers.LogitsProcessor` enforcing a min-length by setting EOS probability to 0.

    Args:
        min_length (:obj:`int`):
            The minimum length below which the score of :obj:`eos_token_id` is set to :obj:`-float("Inf")`.
        eos_token_id (:obj:`int`):
            The id of the `end-of-sequence` token.
    
min_lengthr?   c                 C   sP   t |tr	|dk rtd| t |tr|dk r td| || _|| _d S )Nr   z2`min_length` has to be a positive integer, but is z4`eos_token_id` has to be a positive integer, but is )rL   rM   rS   r   r?   )r   r   r?   r   r   r   r:     s   
z!MinLengthLogitsProcessor.__init__r
   rz   r   c                 C   s0   |j d }|| jk rtd |d d | jf< |S )Nr@   inf)rJ   r   rn   r?   )r   r
   rz   rV   r   r   r   r|     s   

z!MinLengthLogitsProcessor.__call__N)
r   r   r   r   rM   r:   r   r   r    r|   r   r   r   r   r     s    
r   c                
   @   s^   e Zd ZdZdefddZdejdejdejfdd	Z	d
ej
dededeee  fddZdS )NoRepeatNGramLogitsProcessoraT  
    :class:`transformers.LogitsProcessor` that enforces no repetition of n-grams. See `Fairseq
    <https://github.com/pytorch/fairseq/blob/a07cb6f40480928c9e0548b737aadd36ee66ac76/fairseq/sequence_generator.py#L345>`__.

    Args:
        ngram_size (:obj:`int`):
            All ngrams of size :obj:`ngram_size` can only occur once.
    
ngram_sizec                 C   s*   t |tr	|dkrtd| || _d S )Nr   z;`ngram_size` has to be a strictly positive integer, but is )rL   rM   rS   r   )r   r   r   r   r   r:     s
   
z%NoRepeatNGramLogitsProcessor.__init__r
   rz   r   c                 C   sJ   |j d }|j d }| |||}t|D ]\}}td |||f< q|S )Nr   r@   r   )rJ   _calc_banned_ngram_tokensrN   rn   )r   r
   rz   Znum_batch_hypothesesrV   Zbanned_batch_tokensrb   banned_tokensr   r   r   r|     s   

z%NoRepeatNGramLogitsProcessor.__call__prev_input_ids	num_hyposrV   c           	         s   d j k rdd t|D S dd t|D t|D ]2}|  | }tfddtj D  D ]}t|dd }||g |d g ||< q7qfdd	  fd
dt|D }|S )z6Copied from fairseq for no_repeat_ngram in beam_searchr$   c                 S   s   g | ]}g qS r   r   r.   r   r   r   r2     r3   zJNoRepeatNGramLogitsProcessor._calc_banned_ngram_tokens.<locals>.<listcomp>c                 S   s   g | ]}i qS r   r   r.   r   r   r   r2     r3   c                    s   g | ]} |d  qS r;   r   )r/   rb   )
gen_tokensr   r   r2     s    Nr@   c                    s6    d j  }t| | f  }|  |g S )Nr$   )r   tupletolistget)hypo_idxZ	start_idxZ	ngram_idx)rV   generated_ngramsr   r   r   r   _get_generated_ngrams  s   zUNoRepeatNGramLogitsProcessor._calc_banned_ngram_tokens.<locals>._get_generated_ngramsc                    s   g | ]} |qS r   r   )r/   r   )r   r   r   r2     s    )r   r6   r   rP   r   r   )	r   r   r   rV   rt   Zgenerated_ngramZngramZprev_ngram_tupler   r   )r   rV   r   r   r   r   r   r     s*   

z6NoRepeatNGramLogitsProcessor._calc_banned_ngram_tokensN)r   r   r   r   rM   r:   r   r   r    r|   r!   r   r   r   r   r   r   r   r     s    	

r   )abcr   r   collectionsr   typingr   r   r   r   r   ZPROCESS_INPUTS_DOCSTRINGZFINALIZE_INPUTS_DOCSTRINGr	   r"   r-   ry   listr~   r   r   r   r   r   r   <module>   s   ! V4!