o
    *jj                     @   s   d dl Z d dl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mZ d dlmZ d dlmZ d dlmZ d dlmZ 		dd	d
ZG dd de	jZdS )    N)DictListOptional)searchutils)
data_utils)FairseqIncrementalDecoder)NGramRepeatBlock)TensorTc           
      C   s   |  |   d kr|d}|jtjkr|tj}| jd|d }| jddd }|d urA||}|	|d |	|d n
|
d}|
d}|rU| }| }|| dd  }d| | | ||  }	|	|fS )N   dimindexT)r   keepdim              ?)r   	unsqueezedtypetorchZint64typegathersumeqZmasked_fill_Zsqueezesize)
lprobstargetepsilonignore_indexreduceZnll_lossZsmooth_lossZpad_maskZeps_iZloss r    o/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/models/nlp/canmt/sequence_generator.pylabel_smoothed_nll_loss   s$   



r"   c                       s  e Zd Z																		d. fd	d
	Zdd Ze 		d/deeeee	f f de
e	 de
e fddZ			d0ddZe deeeee	f f deeeee	f   fddZdeeeee	f f fddZdeeeee	f f fddZ			d1deeeee	f f de
e	 de
e	 de
e fddZdedefd d!Zdefd"d#Z	d2ded$eeeee	f   d%ee ded&e
e	 d'efd(d)Zded*ed'ed+edef
d,d-Z  ZS )3SequenceGeneratorr   r      Tr   r   FNc                    sT  t    || _|| _|| _|| _| | _| | _|du r#| n|| _|dur1|	| jhn| jh| _
t|| _|| _t|| jd | _|| _|| _|| _|| _|| _|	| _|
| _|| _|| _d| _|dkrot|| _nd| _|dkszJ d|du rt|n|| _t| jdo| jj| _| j   || _!|| _"| j!dur| j!   dS dS )a{  Generates translations of a given source sentence.

        Args:
            models (List[~fairseq.models.FairseqModel]): ensemble of models,
                currently support fairseq.models.TransformerModel for scripting
            beam_size (int, optional): beam width (default: 1)
            max_len_a/b (int, optional): generate sequences of maximum length
                ax + b, where x is the source length
            max_len (int, optional): the maximum length of the generated output
                (not including end-of-sentence)
            min_len (int, optional): the minimum length of the generated output
                (not including end-of-sentence)
            normalize_scores (bool, optional): normalize scores by the length
                of the output (default: True)
            len_penalty (float, optional): length penalty, where <1.0 favors
                shorter, >1.0 favors longer sentences (default: 1.0)
            unk_penalty (float, optional): unknown word penalty, where <0
                produces more unks, >0 produces fewer (default: 0.0)
            temperature (float, optional): temperature, where values
                >1.0 produce more uniform samples and values <1.0 produce
                sharper samples (default: 1.0)
            match_source_len (bool, optional): outputs should match the source
                length (default: False)
        Nr   g?r   z$--temperature must be greater than 0needs_src_lengths)#super__init__modelrecon_force_decodingtrans_force_decodingtgt_dictpadunkeosunionsymbols_to_strip_from_outputlen
vocab_size	beam_sizemin	max_len_a	max_len_bmin_lenmax_lennormalize_scoreslen_penaltyunk_penaltytemperaturematch_source_lenepsr	   repeat_ngram_blockerr   Z
BeamSearchhasattrr%   should_set_src_lengthsevallm_model	lm_weight)selfr(   r+   r3   r5   r6   r8   r7   r9   r:   r;   r<   r=   Zno_repeat_ngram_sizeZsearch_strategyr.   r0   rC   rD   r)   r*   	__class__r    r!   r'   .   sT   
/





zSequenceGenerator.__init__c                 C   s   | j   | S N)r(   cuda)rE   r    r    r!   rI      s   
zSequenceGenerator.cudasampleprefix_tokens	bos_tokenc                 C   s   | j |||dS )a2  Generate a batch of translations.

        Args:
            sample (dict): batch
            prefix_tokens (torch.LongTensor, optional): force decoder to begin
                with these tokens
            bos_token (int, optional): beginning of sentence token
                (default: self.eos)
        )rL   )	_generate)rE   rJ   rK   rL   r    r    r!   forward   s   zSequenceGenerator.forwardc              	   c   s"   |D ]}|rt |n|}d|vrq|d }dd | D }|dur(|  t  | |}	W d   n1 s<w   Y  |durQ|tdd |	D  t	|d j
D ]5\}
}t |d j
|
ddf | j}|d	 durt |d	 j
|
ddf | jnd}||||	|
 fV  qXqdS )
zIterate over a batched dataset and yield individual translations.
        Args:
            cuda (bool, optional): use GPU for generation
            timer (StopwatchMeter, optional): time generations
        	net_inputc                 S   s   i | ]\}}|d kr||qS )prev_output_tokensr    ).0kvr    r    r!   
<dictcomp>   s    z:SequenceGenerator.generate_batched_itr.<locals>.<dictcomp>Nc                 s   s     | ]}t |d  d V  qdS )r   tokensN)r1   )rQ   hr    r    r!   	<genexpr>   s    z9SequenceGenerator.generate_batched_itr.<locals>.<genexpr>id
src_tokensr   )r   Zmove_to_cudaitemsstartr   no_gradgeneratestopr   	enumeratedataZ	strip_padr,   )rE   Zdata_itrr3   rI   ZtimerrJ   sinputZencoder_inputZhyposirX   srcrefr    r    r!   generate_batched_itr   s2   

  z&SequenceGenerator.generate_batched_itrreturnc                 K   s  ddl m} | j|fi |}g }g }tt|D ]}|| d }|d }	||	 |d }
||
 qtdd |D }t|}tt|D ]}|| dd||< || dd||< qG|d ||	| j
}dd	 }t|D ]\}}|||| dt|  qr|}|| j
}| jj|dd
d}|d d }t }|g|d< |g|d< |g|d< g |d< g |d< g |d< | ||}||fS )a  Generate translations. Match the api of other fairseq generators.

        Args:
            models (List[~fairseq.models.FairseqModel]): ensemble of models
            sample (dict): batch
            prefix_tokens (torch.LongTensor, optional): force decoder to begin
                with these tokens
            constraints (torch.LongTensor, optional): force decoder to include
                the list of constraints
            bos_token (int, optional): beginning of sentence token
                (default: self.eos)
        r   )tensorrU   decoder_outc                 s   s    | ]}| d V  qdS )r   N)r   )rQ   rS   r    r    r!   rW      s    z-SequenceGenerator.generate.<locals>.<genexpr>r   c                 S   s"   |  |   ks
J ||  d S rH   )numelcopy_)rd   dstr    r    r!   copy_tensor   s   z/SequenceGenerator.generate.<locals>.copy_tensorTN)encoder_outZfull_context_alignmentZ
last_layerrn   Zencoder_padding_maskrY   encoder_embeddingZencoder_statessrc_lengths)r   rh   rM   ranger1   appendmaxZrollnewfill_r,   r_   r   r(   decoderdict_forward_src)rE   rJ   kwargsrh   	finalizedZtokens_listZdecoder_listrc   sentrU   ri   r   
batch_sizeresrm   rS   Z
tgt_tokensZdecoder_padding_maskZdecoder_out_redecoder_outsscoresr    r    r!   r]      sH   



zSequenceGenerator.generatec                 C   s(  |d }|d }|d }| j |}|d d dd}|d d }d| j _| j j||d d	\}}	}
|
dd}
d
| j _|d}tjt	t	t
ttf   dd t|D }t|D ]6}t|d |  | jkd d }|| |d | d |d  |
| d |d  || || d q[|S )NrO   rY   rP   rn   r   r   ro   Fincremental_statesTc                 S   &   g | ]}t jttttf  g qS r    r   jitannotater   r   strr
   rQ   rc   r    r    r!   
<listcomp>      z.SequenceGenerator._forward.<locals>.<listcomp>r   )rU   ri   final_encoder_embeddingfinal_encoder_out)r(   forward_encoder	transposehas_incrementalforward_decoderr   r   r   r   r   r   r   r
   rq   numpywherecpur.   rr   )rE   rJ   rO   rY   rP   encoder_outsr   r   r   avg_attn_scoresr~   r|   rz   rc   Zeos_idxr    r    r!   _forward  s8   
$

zSequenceGenerator._forwardc                 C   s   |d }|d }|d }|d }d| j _| j j||d d\}}}	}
|
d }tj|dd	}|d
 d}|d|d}t||| j| j	dd\}}	|j
d }||d}tj|jddd||d |fdd}|S )NrO   rY   rp   Zprev_src_tokensFr   r   r   r   sources)r   r   r   T)axisr   r   )r   )r(   r   Zforward_decoder_srcr   Zlog_softmaxviewr   r"   r>   r,   shapeZreshaper   catr   )rE   r   rJ   rO   rY   rp   rP   r   r   _r~   Zlogitsr   r   r|   r    r    r!   rx   -  s:   


zSequenceGenerator._forward_srcconstraintsc           4         s
  t jtttttt f f t jtttttt f f i }|d }d|v r?|d }|| j|| j	@ 
 jdd}n
tdt|  | d d \}	}
| j}d}| jrb|  }ntt| j|
 | j | jd }| j|ks{J d| j|}|d	 d
 d
d}|d d
 }t |	ddd|d}||j 
 }| j!||}|d usJ t "|	| |d |# }t "|	| |d |
 $| j	}|d u r| jn||d d d
f< d }t "|	||%d}t jt&t&tttf   dd t'|	D  dd t'|	D }|	}d| }t d
|	| (d)||j }t d
|)||j }d }d }d }d|v rQt*|d trQ|d }n	t d
|	)|}t'|d D ]}|d ur|d ur|t |+ )| }|d|,|(d|  || }| j-|| | j!||}| j.|d d d |d f ||| j/\}} }!|!d
d}!|d
kr|!}"n	t j0|"|!gdd}"t 1t2j3 ||||k< t2j3 |d d | j	f< |d d | j4f  | j58  < ||krt2j3 |d d d | jf< t2j3 |d d | jd d f< |d ur/||dk r/||k r/| 6||||||\}}}n|| jk r@t2j3 |d d | jf< | d urk|d u r[t 7|	| | d|d |}|d d d d |d f 8|  |)|}t 7d
|}#t 7d
|}$| j9r| j:;| | j<d ur| <|||	||}| j:=|||	d| j>||	|dd d d d d |f |d d d |d f |\}%}&}'|'?|}(|&%| j|%t2j3 @ })t 1d
|)|)d d d |f |< t j@|(d d d |f |)d d d |f d}#g }*|#+ d
kr7t j@|%d d d |f |)d d d |f d}$| A||#|$|| ||||||"}*|tB|*8 }|d
ks>J |d
krF n| j:jCrS||krS n||k saJ | d| tB|*d
kr|	tB|* }+t jD|	t jE|&j d},d|,|*< t j|	|&j d@|,}| j:F| |)| })|'| }'|G|+d |'?|}(|%| }%|&| }&|d ur|| }|| }|| }||	d| |+| d}||	d| |+| d}|"H |	d| |+| |"dd}"|d ur ||	d| |+| |dd}|+}	nd }| |)d d d |f  @  |)d d d |f< t ?|))|| |d |)d }-t jI|-|ddd\}.}/|.J|d d d |f }| jKddL sRJ t jM|(d|/d}0t jM|%d|/d}1|0d}0|1d}1t jN|d d d |d f d
|0d|d d d |d f< t jM|&d|/d||	|dd d d d |d f< |d
krt jN|d d d |f d
|0d|d d d |f< t jM|%d|/d||	|dd d d d |f< | j:O|/ |d ur t jN|d d d d d |d f d
|0d|d d d d d |d f< |0}q`t'tB D ]It 1dd   D }t jP|dd\}2}3 fdd|3D  < t jt&tttf     < |   d
 d< |   d
 d< q
 S )NrO   rY   r   r   z8expected src_tokens or source in net input. input keys:    r   z;min_len cannot be larger than max_len, please adjust these!rn   r   ro   c                 S   r   r    r   r   r    r    r!   r     r   z/SequenceGenerator._generate.<locals>.<listcomp>c                 S   s   g | ]}d qS )Fr    r   r    r    r!   r     s    rX   )maskz < )r   deviceF)r   )rR   r   Zlargestr   c                 S   s   g | ]
}t |d   qS )score)floatitem)rQ   elemr    r    r!   r     s    T)Z
descendingc                    s   g | ]}  | qS r    r    )rQ   Zssirz   r{   r    r!   r     s    r   r   )Qr   r   r   r   r   r   r
   ner.   r,   longr   	Exceptionkeysr   r3   r=   rs   r   r4   intr5   r6   r8   r7   r(   r   r   Zaranger   repeattor   Zreorder_encoder_outZzerosr   ru   r   r   rq   r   Ztype_as
isinstancerj   Zadd_Zreorder_incremental_stater   r<   r   rh   mathinfr-   r;   _prefix_tokensemptyrk   rA   r   Zset_src_lengthsr?   stepr2   addZmasked_selectfinalize_hyposr1   Zstop_on_max_lenZonesboolZprune_sentencesZresize_
contiguousZtopkgeanyallr   index_selectZupdate_constraintssort)4rE   rJ   rK   r   rL   r   rO   rY   rp   ZbszZsrc_lenr3   r8   r   r   r   Z	new_orderr   rU   attnZcands_to_ignorefinishedZnum_remaining_sentZ	cand_sizeZbbsz_offsetsZcand_offsetsZreorder_stateZ
batch_idxsZoriginal_batch_idxsr   Zcorrr   r   Zdecoder_out_wordZdecoder_out_tensorZeos_bbsz_idx
eos_scoresZcand_scoresZcand_indicesZ
cand_beamsZcand_bbsz_idxeos_maskZfinalized_sentsZnew_bszZ
batch_maskZactive_maskZnew_cands_to_ignoreZactive_hyposZactive_bbsz_idxZactive_scoresr   Zsorted_scores_indicesr    r   r!   rM   K  s2   


 


	










 



"


$$









&
"
  

zSequenceGenerator._generater   r3   c                 C   s4  |dd|f  dd|d}|d| d}|| j}	ttj	 
|||	< ||	 d||	  d||	 ||	< || j}
|
 r||
 d||ddddd|d f }|
d|dddf }|| ddd|f }||k sJ | |||}| |||}| |||}|||fS )zHandle prefix tokensNr   r   r   )r   r   r   r   r   r,   r   rh   r   r   r   Zscatterr   r.   r   r   r   replicate_first_beam)rE   r   r   r   rU   rK   r3   Zprefix_toksZprefix_lprobsZprefix_maskr   Z
first_beamZeos_mask_batch_dimZtarget_prefixr    r    r!   r     sD   

z SequenceGenerator._prefix_tokensc                 C   sH   | d||d}|| d d d dd d f ||< | d|dS )Nr   r   )r   r   )rE   rh   r   r3   r    r    r!   r     s   "z&SequenceGenerator.replicate_first_beamrz   r   r   r8   c              
   C   s  |  |  ks
J |dur|d|}|d|ddd|d f }| j|dd|f< |	durD|	d|ddddd|d f nd}|d|ddd|d f }||dd|f< |ddddf |ddddf  |ddddf< | jr||d | j  }g }d}|D ]}|r|d7 }q|| qi }t| d D ]r}|| }|| }|| }|||  }t|	 d t|	  }||vrd||< | j
r||
| krttj |}t|| |k r|dur|| }ntd}|| || ||td|| |dur|| ng d qg }| D ]5}tt|dd }tt|dd }|| sR| |||t|| |rRd||< || q|S )	a  Finalize hypothesis, store finalized information in `finalized`, and change `finished` accordingly.
        A sentence is finalized when {beam_size} finished items have been collected for it.

        Returns number of sentences (not beam items) being finalized.
        These will be removed from the batch and not processed further.
        Args:
            bbsz_idx (Tensor):
        Nr   r   r   r   r   )rU   r   Z	attention	alignmentZpositional_scoresri   T)rj   r   r.   r9   r:   rr   rq   r   r   r   r=   r   rh   r   r   r   r1   r   r   r   r   splitis_finished)rE   r   Zbbsz_idxr   rU   r   rz   r   r3   r   rp   r8   ri   Zdecoder_out_cloneZtokens_cloneZ
attn_cloneZ
pos_scoresZ	cum_unfinprevfZ
sents_seenrc   idxr   	unfin_idxr{   seenZ	hypo_attnZnewly_finishedr    r    r!   r     sr    
 8



z SequenceGenerator.finalize_hyposr   finalized_sent_lenc                 C   s$   ||ksJ ||ks||krdS dS )z
        Check whether decoding for a sentence is finished, which
        occurs when the list of finalized sentences has reached the
        beam size, or when we reach the maximum length.
        TFr    )rE   r   r   r8   r   r3   r    r    r!   r   B  s   zSequenceGenerator.is_finished)r   r   r$   r$   r   Tr   r   r   Fr   NNNNr   TF)NN)NFN)NNNrH   )__name__
__module____qualname__r'   rI   r   r\   r   r   r
   r   r   rN   rf   r   r]   r   rx   rM   r   r   r   r   r   __classcell__r    r    rF   r!   r#   ,   s    b
#<
&
!
  Y
 	

{r#   )NT)r   systypingr   r   r   r   r   Ztorch.nnnnZfairseqr   r   Zfairseq.datar   Zfairseq.modelsr   Zfairseq.ngram_repeat_blockr	   r
   r"   Moduler#   r    r    r    r!   <module>   s   
