o
    ip3                     @   sp   d Z ddl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mZ G dd deZG dd	 d	eZdS )
zParallel beam search module.    N)AnyDictList
NamedTupleTuple)pad_sequence)
BeamSearch
Hypothesisc                   @   s   e Zd ZU dZeg Zejed< eg Z	ejed< eg Z
ejed< e Zeeejf ed< e Zeeef ed< defdd	Zd
S )BatchHypothesisz*Batchfied/Vectorized hypothesis data type.yseqscorelengthscoresstatesreturnc                 C   s
   t | jS )zReturn a batch size.)lenr   self r   Q/home/ubuntu/.local/lib/python3.10/site-packages/espnet/nets/batch_beam_search.py__len__   s   
zBatchHypothesis.__len__N)__name__
__module____qualname____doc__torchtensorr   Tensor__annotations__r   r   dictr   r   strr   intr   r   r   r   r   r
      s   
 r
   c                   @   sp  e Zd ZdZdee defddZdedee defddZ	ded	edefd
dZ
dedee fddZdejdejdeejejejejf fddZdejdefddZdedejdeeeejf eeef f fddZdedejdejdeeeejf eeef f fddZdedededefddZdedejdefd d!Zd	ed"ed#eded$ee defd%d&Zd'S )(BatchBeamSearchz!Batch beam search implementation.hypsr   c                    s   t  dkr	t S ttdd  D d| jdtjdd  D tjdtdd  D  fd	d
| jD  fdd
| jD dS )zConvert list to batch.r   c                 S      g | ]}|j qS r   )r   .0hr   r   r   
<listcomp>#       z+BatchBeamSearch.batchfy.<locals>.<listcomp>T)batch_firstpadding_valuec                 S   s   g | ]}t |jqS r   )r   r   r%   r   r   r   r(   %       )dtypec                 S   r$   r   )r   r%   r   r   r   r(   &   r)   c                    s&   i | ]  t  fd dD qS )c                       g | ]}|j   qS r   r   r%   kr   r   r(   '   r,   6BatchBeamSearch.batchfy.<locals>.<dictcomp>.<listcomp>)r   r   r&   r#   r0   r   
<dictcomp>'   s   & z+BatchBeamSearch.batchfy.<locals>.<dictcomp>c                    s    i | ]   fd dD qS )c                    r.   r   )r   r%   r0   r   r   r(   (   r,   r2   r   r3   r4   r0   r   r5   (   s     )r   r   r   r   r   )r   r
   r   eosr   r   int64scorers)r   r#   r   r4   r   batchfy   s   zBatchBeamSearch.batchfyidsc                    sN   t |j  |j  |j   fdd|j D  fdd|j D dS )Nc                       i | ]	\}}||  qS r   r   r&   r1   v)r:   r   r   r5   0       z1BatchBeamSearch._batch_select.<locals>.<dictcomp>c                    s(   i | ]\   fd dD qS )c                    s   g | ]}j   |qS r   r8   select_state)r&   i)r1   r   r=   r   r   r(   2   s    z<BatchBeamSearch._batch_select.<locals>.<dictcomp>.<listcomp>r   r3   r:   r   )r1   r=   r   r5   1   s    )r   r   r   r   r   )r
   r   r   r   r   itemsr   )r   r#   r:   r   rB   r   _batch_select+   s   zBatchBeamSearch._batch_selectrA   c                    sT   t |j d |j  f |j   fdd|j D  fdd|j D dS )Nc                    r;   r   r   r<   rA   r   r   r5   ;   r>   z+BatchBeamSearch._select.<locals>.<dictcomp>c                    $   i | ]\}}|j | | qS r   r?   r<   rA   r   r   r   r5   <   s    r   r   r   r   )r	   r   r   r   r   rC   r   )r   r#   rA   r   rG   r   _select7   s   zBatchBeamSearch._select
batch_hypsc                    s    fddt t jD S )zRevert batch to list.c              	      s^   g | ]+ t j  d j   j   fddjD  fddj D dqS )Nc                    s   i | ]
}| j |  qS r   r/   )r&   r1   rJ   rA   r   r   r5   G   s    z8BatchBeamSearch.unbatchfy.<locals>.<listcomp>.<dictcomp>c                    s$   i | ]\}}||  j| qS r   )r@   r   r<   rK   r   r   r5   H       rH   )r	   r   r   r   r8   rC   r3   rJ   r   rE   r   r(   C   s    
z-BatchBeamSearch.unbatchfy.<locals>.<listcomp>)ranger   r   )r   rJ   r   rM   r   	unbatchfyA   s   
zBatchBeamSearch.unbatchfyweighted_scoresc                 C   s6   | d| jd }|| j }|| j }||||fS )ai  Batch-compute topk full token ids and partial token ids.

        Args:
            weighted_scores (torch.Tensor): The weighted sum scores for each tokens.
                Its shape is `(n_beam, self.vocab_size)`.
            ids (torch.Tensor): The partial token ids to compute topk.
                Its shape is `(n_beam, self.pre_beam_size)`.

        Returns:
            Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
                The topk full (prev_hyp, new_token) ids
                and partial (prev_hyp, new_token) ids.
                Their shapes are all `(self.beam_size,)`

           )viewtopk	beam_sizen_vocab)r   rP   r:   top_idsprev_hyp_idsnew_token_idsr   r   r   
batch_beamP   s   

zBatchBeamSearch.batch_beamxc              
   C   s^   t  }t  }| j D ]\}}||||< d||< q| td||tj| jg|j	ddgS )zGet an initial hypothesis data.

        Args:
            x (torch.Tensor): The encoder output feature

        Returns:
            Hypothesis: The initial hypothesis.

        g        )device)r   r   r   r   )
r   r8   rC   batch_init_stater9   r	   r   r   sosr\   )r   r[   init_statesinit_scoresr1   dr   r   r   init_hypj   s   

zBatchBeamSearch.init_hyphypc                 C   sJ   t  }t  }| j D ]\}}||j|j| |\||< ||< q||fS )a  Score new hypothesis by `self.full_scorers`.

        Args:
            hyp (Hypothesis): Hypothesis with prefix tokens to score
            x (torch.Tensor): Corresponding input feature

        Returns:
            Tuple[Dict[str, torch.Tensor], Dict[str, Any]]: Tuple of
                score dict of `hyp` that has string keys of `self.full_scorers`
                and tensor score values of shape: `(self.n_vocab,)`,
                and state dict that has string keys
                and state values of `self.full_scorers`

        )r   full_scorersrC   batch_scorer   r   )r   rc   r[   r   r   r1   ra   r   r   r   
score_full   s
   $zBatchBeamSearch.score_fullc                 C   sL   t  }t  }| j D ]\}}||j||j| |\||< ||< q||fS )ae  Score new hypothesis by `self.full_scorers`.

        Args:
            hyp (Hypothesis): Hypothesis with prefix tokens to score
            ids (torch.Tensor): 2D tensor of new partial tokens to score
            x (torch.Tensor): Corresponding input feature

        Returns:
            Tuple[Dict[str, torch.Tensor], Dict[str, Any]]: Tuple of
                score dict of `hyp` that has string keys of `self.full_scorers`
                and tensor score values of shape: `(self.n_vocab,)`,
                and state dict that has string keys
                and state values of `self.full_scorers`

        )r   part_scorersrC   batch_score_partialr   r   )r   rc   r:   r[   r   r   r1   ra   r   r   r   score_partial   s   zBatchBeamSearch.score_partialr   part_statespart_idxc                 C   s>   t  }| D ]\}}|||< q| D ]\}}|||< q|S )a  Merge states for new hypothesis.

        Args:
            states: states of `self.full_scorers`
            part_states: states of `self.part_scorers`
            part_idx (int): The new token id for `part_scores`

        Returns:
            Dict[str, torch.Tensor]: The new score dict.
                Its keys are names of `self.full_scorers` and `self.part_scorers`.
                Its values are states of the scorers.

        )r   rC   )r   r   rj   rk   
new_statesr1   r=   r   r   r   merge_states   s   

zBatchBeamSearch.merge_statesrunning_hypsc                    s  t |}d}tj|j|j|jd}||j|g|jR  \}}j	D ]}|j
| ||  7 }q%jrMjdkr=|n|j }	tj|	jddd }|||\}
}jD ]}|j
| |
|  7 }qY||jj|j|jdd7 }g }|}t|| D ]R\ }|  }|t| |f |j||j fdd| D |fd	d|
 D  fd
d| D fdd| D d q|S )a   Search new tokens for running hypotheses and encoded speech x.

        Args:
            running_hyps (BatchHypothesis): Running hypotheses on beam
            x (torch.Tensor): Encoded speech feature (T, D)

        Returns:
            BatchHypothesis: Best sorted hypotheses

        N)r-   r\   fullrQ   )dimrR   c                    r;   r   r   r<   )full_prev_hyp_idr   r   r5     r>   z*BatchBeamSearch.search.<locals>.<dictcomp>c                    r;   r   r   r<   )part_prev_hyp_idr   r   r5     r>   c                    rF   r   )rd   r@   r<   )rq   r   r   r   r5   	  rL   c                    s&   i | ]\}}|j | | qS r   )rg   r@   r<   )part_new_token_idrr   r   r   r   r5     s    )r   r   r   r   ) r   r   zerosrV   r-   r\   rf   expandshaperd   weightsdo_pre_beampre_beam_score_keyrT   pre_beam_sizeri   rg   r   to	unsqueezerO   ziprZ   appendr	   append_tokenr   merge_scoresr   rC   rm   r9   )r   rn   r[   n_batchpart_idsrP   r   r   r1   pre_beam_scorespart_scoresrj   	best_hyps	prev_hypsfull_new_token_idprev_hypr   )rq   rs   rr   r   r   search   sl    





zBatchBeamSearch.searchmaxlenmaxlenratio
ended_hypsc                    s@  |j jd }td|   jdur.tdd fdd|j dd|jd f D   ||d krftd	 t	|j tj
|df j|j jtjd
fd}|j | ||j dd< |jd |jdd< |j t||jd f  jk}tj|dddD ]}	 ||	}
||
 qtj|dkddd} ||S )a  Perform post-processing of beam search iterations.

        Args:
            i (int): The length of hypothesis tokens.
            maxlen (int): The maximum length of tokens in beam search.
            maxlenratio (int): The maximum length ratio in beam search.
            running_hyps (BatchHypothesis): The running hypotheses in beam search.
            ended_hyps (List[Hypothesis]): The ended hypotheses in beam search.

        Returns:
            BatchHypothesis: The new running hypotheses.

        r   z the number of running hypothes: Nzbest hypo:  c                    s   g | ]} j | qS r   )
token_list)r&   r[   r   r   r   r(   4  s    z0BatchBeamSearch.post_process.<locals>.<listcomp>rR   z-adding <eos> in the last position in the loop)r\   r-   F)as_tuplerQ   )r   rv   loggingdebugr   joinr   infor   catro   r6   r\   r7   
resize_as_arangenonzerorS   rI   r~   rD   )r   rA   r   r   rn   r   r   yseq_eosis_eosbrc   remained_idsr   r   r   post_process  sJ   



	zBatchBeamSearch.post_processN)r   r   r   r   r   r	   r
   r9   r!   rD   rI   rO   r   r   r   rZ   rb   r   r    r   rf   ri   rm   r   floatr   r   r   r   r   r"      sZ    



Or"   )r   r   typingr   r   r   r   r   r   torch.nn.utils.rnnr   espnet.nets.beam_searchr   r	   r
   r"   r   r   r   r   <module>   s    