o
    ´‹
j˜K  ã                   @   sŒ   d dl Z d dlmZ d dl mZ d dlmZ d dlmZ G dd„ dej	ƒZ
G dd	„ d	ej	ƒZG d
d„ dej	ƒZG dd„ dej	ƒZdd„ ZdS )é    N)Ú	betabinom)Únn)Ú
functional)ÚLinearc                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )	ÚLocationLayera=  Layers for Location Sensitive Attention

    Args:
        attention_dim (int): number of channels in the input tensor.
        attention_n_filters (int, optional): number of filters in convolution. Defaults to 32.
        attention_kernel_size (int, optional): kernel size of convolution filter. Defaults to 31.
    é    é   c                    s@   t ƒ  ¡  tjd||d|d d dd| _t||ddd| _d S )Né   é   F)Úin_channelsÚout_channelsÚkernel_sizeÚstrideÚpaddingÚbiasÚtanh©r   Ú	init_gain)ÚsuperÚ__init__r   ÚConv1dÚlocation_conv1dr   Úlocation_dense)ÚselfÚattention_dimÚattention_n_filtersÚattention_kernel_size©Ú	__class__© úU/home/kuhnn/.local/lib/python3.10/site-packages/TTS/tts/layers/tacotron/attentions.pyr      s   

úzLocationLayer.__init__c                 C   s    |   |¡}|  | dd¡¡}|S )z>
        Shapes:
            attention_cat: [B, 2, C]
        r
   r	   )r   r   Ú	transpose)r   Úattention_catÚprocessed_attentionr   r   r    Úforward   s   
zLocationLayer.forward)r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r$   Ú__classcell__r   r   r   r    r   	   s    r   c                       sD   e Zd ZdZdZ‡ fdd„Zdd„ Zdd„ Zd	d
„ Zdd„ Z	‡  Z
S )ÚGravesAttentiona(  Graves Attention as is ref1 with updates from ref2.
    ref1: https://arxiv.org/abs/1910.10288
    ref2: https://arxiv.org/pdf/1906.01083.pdf

    Args:
        query_dim (int): number of channels in query tensor.
        K (int): number of Gaussian heads to be used for computing attention.
    g   @EˆÙ?c              	      sj   t ƒ  ¡  d| _|| _d| _d | _t tj||ddt 	¡ tj|d| dd¡| _
d | _d | _|  ¡  d S )Nç:Œ0âŽyE>gñhãˆµøä>T©r   é   )r   r   Ú_mask_valueÚKÚepsÚJr   Ú
Sequentialr   ÚReLUÚN_aÚattention_weightsÚmu_prevÚinit_layers)r   Ú	query_dimr/   r   r   r    r   4   s   
&ÿzGravesAttention.__init__c                 C   sX   t jj | jd jd| j d| j … d¡ t jj | jd j| jd| j … d¡ d S )Nr	   r-   ç      ð?é
   )Útorchr   ÚinitÚ	constant_r4   r   r/   ©r   r   r   r    r7   B   s   ,,zGravesAttention.init_layersc                 C   sŒ   | j d u s|jd d | j jd kr$t d|jd d ¡ |j¡d | _ t |jd |jd ¡ |j¡| _t |jd | j¡ |j¡| _	d S )Nr
   éÿÿÿÿr   g       @ç      à?)
r1   Úshaper;   ÚarangeÚtoÚdeviceÚzerosr5   r/   r6   ©r   Úinputsr   r   r    Úinit_statesF   s   $$""zGravesAttention.init_statesc                 C   ó   d S ©Nr   rF   r   r   r    Úpreprocess_inputsN   ó   z!GravesAttention.preprocess_inputsc              	   C   s~  |   |¡}| | d¡d| j¡}|dd…ddd…f }|dd…ddd…f }|dd…ddd…f }tjjj|d| jd}tjj 	|¡| j
 }	| jtjj 	|¡ }
tj|dd| j
 }| jd| d¡d … }| d¡ddt |
 d¡| |	 d¡ ¡   }t |d¡}|dd…dd…f |dd…dd…f  }d	||dk< |dur«|j | | j¡ t | d¡|¡ d¡}|| _|
| _|S )
z±
        Shapes:
            query: [B, C_attention_rnn]
            inputs: [B, T_in, C_encoder]
            processed_inputs: place_holder
            mask: [B, T_in]
        r   r?   Nr
   r	   r@   )ÚpÚtraining©Údimr+   )r4   ÚviewÚsizer/   r;   r   r   ÚdropoutrN   Úsoftplusr0   r6   Úsoftmaxr1   Ú	unsqueezeÚsigmoidÚsumÚdataÚmasked_fill_r.   ÚbmmÚsqueezer5   )r   ÚqueryrG   Úprocessed_inputsÚmaskÚgbk_tÚg_tÚb_tÚk_tÚsig_tÚmu_tÚjÚphi_tÚalpha_tÚcontextr   r   r    r$   Q   s(   
0(zGravesAttention.forward)r%   r&   r'   r(   ÚCOEFr   r7   rH   rK   r$   r)   r   r   r   r    r*   (   s    	r*   c                       sx   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )ÚOriginalAttentiona8  Bahdanau Attention with various optional modifications.
    - Location sensitive attnetion: https://arxiv.org/abs/1712.05884
    - Forward Attention: https://arxiv.org/abs/1807.06736 + state masking at inference
    - Using sigmoid instead of softmax normalization
    - Attention windowing at inference time

    Note:
        Location Sensitive Attention extends the additive attention mechanism
    to use cumulative attention weights from previous decoder time steps with the current time step features.

        Forward attention computes most probable monotonic alignment. The modified attention probabilities at each
    timestep are computed recursively by the forward algorithm.

        Transition agent in the forward attention explicitly gates the attention mechanism whether to move forward or
    stay at each decoder timestep.

        Attention windowing is a inductive prior that prevents the model from attending to previous and future timesteps
    beyond a certain window.

    Args:
        query_dim (int): number of channels in the query tensor.
        embedding_dim (int): number of channels in the vakue tensor. In general, the value tensor is the output of the encoder layer.
        attention_dim (int): number of channels of the inner attention layers.
        location_attention (bool): enable/disable location sensitive attention.
        attention_location_n_filters (int): number of location attention filters.
        attention_location_kernel_size (int): filter size of location attention convolution layer.
        windowing (int): window size for attention windowing. if it is 5, for computing the attention, it only considers the time steps [(t-5), ..., (t+5)] of the input.
        norm (str): normalization method applied to the attention weights. 'softmax' or 'sigmoid'
        forward_attn (bool): enable/disable forward attention.
        trans_agent (bool): enable/disable transition agent in the forward attention.
        forward_attn_mask (int): enable/disable an explicit masking in forward attention. It is useful to set at especially inference time.
    c                    s¤   t ƒ  ¡  t||ddd| _t||ddd| _t|ddd| _|
r,tj|| ddd| _|r5t|||ƒ| _	t
dƒ | _|| _d | _|| _|	| _|
| _|| _|| _d S )NFr   r   r
   Tr,   Úinf)r   r   r   Úquery_layerÚinputs_layerÚvr   Útar   Úlocation_layerÚfloatr.   Ú	windowingÚwin_idxÚnormÚforward_attnÚtrans_agentÚforward_attn_maskÚlocation_attention)r   r8   Úembedding_dimr   ry   Úattention_location_n_filtersÚattention_location_kernel_sizers   ru   rv   rw   rx   r   r   r    r   £   s(   
ý
zOriginalAttention.__init__c                 C   s   d| _ d| _d| _d S )Nr?   r	   é   )rt   Úwin_backÚ	win_frontr>   r   r   r    Úinit_win_idxÆ   s   
zOriginalAttention.init_win_idxc                 C   sx   |j d }|j d }tjt |dg¡t ||g¡d d …d d…f d gdd |j¡| _dt |dg¡  |j¡| _d S )Nr   r
   r?   gH¯¼šò×z>rO   r@   )	rA   r;   ÚcatÚonesrE   rC   rD   ÚalphaÚu©r   rG   ÚBÚTr   r   r    Úinit_forward_attnË   s   

D z#OriginalAttention.init_forward_attnc                 C   s.   |  d¡}|  d¡}tj||g|jd| _d S ©Nr   r
   ©rD   )rR   r;   rE   rD   Úattention_weights_cumr…   r   r   r    Úinit_location_attentionÑ   s   

z)OriginalAttention.init_location_attentionc                 C   s`   |  d¡}|  d¡}tj||g|jd| _| jr|  |¡ | jr%|  |¡ | j	r.|  
¡  d S d S r‰   )rR   r;   rE   rD   r5   ry   rŒ   rv   rˆ   rs   r€   r…   r   r   r    rH   Ö   s   



ÿzOriginalAttention.init_statesc                 C   s
   |   |¡S rJ   )rn   rF   r   r   r    rK   á   s   
z#OriginalAttention.preprocess_inputsc                 C   s   |  j |7  _ d S rJ   )r‹   )r   Ú
alignmentsr   r   r    Úupdate_location_attentionä   s   z+OriginalAttention.update_location_attentionc                 C   sf   t j| j d¡| j d¡fdd}|  | d¡¡}|  |¡}|  t  || | ¡¡}| 	d¡}||fS )Nr
   rO   r?   )
r;   r   r5   rV   r‹   rm   rq   ro   r   r\   )r   r]   r^   r"   Úprocessed_queryÚprocessed_attention_weightsÚenergiesr   r   r    Úget_location_attentionç   s   "

z(OriginalAttention.get_location_attentionc                 C   s6   |   | d¡¡}|  t || ¡¡}| d¡}||fS )Nr
   r?   )rm   rV   ro   r;   r   r\   )r   r]   r^   r   r‘   r   r   r    Úget_attentionï   s   
zOriginalAttention.get_attentionc                 C   sž   | j | j }| j | j }|dkrtdƒ |d d …d |…f< ||jd k r1tdƒ |d d …|d …f< | j dkr@| ¡ |d d …df< t |d¡ ¡ d  	¡ | _ |S )Nr   rl   r
   r?   )
rt   r~   r   rr   rA   Úmaxr;   ÚargmaxÚlongÚitem)r   Ú	attentionrG   Úback_winÚ	front_winr   r   r    Úapply_windowingõ   s   
z!OriginalAttention.apply_windowingc                 C   sê   t  | jd d …d d…f  ¡  |j¡d¡}d| j | j | j|  d | }| jsj| jrj| 	d¡\}}| 	d¡\}}t
|jd ƒD ](}d|||| d d …f< d||d || d …f< d||  |||| d f< qA||jdd	d
 }|S )Nr?   )r
   r   r   r   r
   r+   r   r-   g{®Gáz„?r	   T©rP   Úkeepdim)ÚFÚpadrƒ   ÚclonerC   rD   r„   rN   rx   r”   ÚrangerA   rX   )r   Ú	alignmentÚfwd_shifted_alpharƒ   Ú_ÚnÚvalÚbr   r   r    Úapply_forward_attention  s   *"z)OriginalAttention.apply_forward_attentionc           
      C   s(  | j r|  ||¡\}}n|  ||¡\}}|dur!|j | | j¡ | js-| jr-|  ||¡}| j	dkr:t
j|dd}n| j	dkrOt
 |¡t
 |¡jddd }ntd	ƒ‚| j r[|  |¡ | jrf|  |¡}|| _t
 | d¡|¡}| d¡}|| _| jr’| jr’t
j|| d¡gdd}	t
 |  |	¡¡| _|S )
z¬
        shapes:
            query: [B, C_attn_rnn]
            inputs: [B, T_en, D_en]
            processed_inputs: [B, T_en, D_attn]
            mask: [B, T_en]
        NrU   r?   rO   rW   r
   Trœ   z%Unknown value for attention norm type)ry   r’   r“   rY   rZ   r.   rN   rs   r›   ru   r;   rU   rW   rX   Ú
ValueErrorrŽ   rv   r¨   rƒ   r[   rV   r\   r5   rw   r   rp   r„   )
r   r]   rG   r^   r_   r˜   r¤   r¢   ri   Úta_inputr   r   r    r$     s0   

 


zOriginalAttention.forward)r%   r&   r'   r(   r   r€   rˆ   rŒ   rH   rK   rŽ   r’   r“   r›   r¨   r$   r)   r   r   r   r    rk      s    ##rk   c                       s@   e Zd ZdZ			d‡ fdd„	Zdd„ Zd	d
„ Zdd„ Z‡  ZS )Ú$MonotonicDynamicConvolutionAttentionaà  Dynamic convolution attention from
    https://arxiv.org/pdf/1910.10288.pdf


    query -> linear -> tanh -> linear ->|
                                        |                                            mask values
                                        v                                              |    |
               atten_w(t-1) -|-> conv1d_dynamic -> linear -|-> tanh -> + -> softmax -> * -> * -> context
                             |-> conv1d_static  -> linear -|           |
                             |-> conv1d_prior   -> log ----------------|

    query: attention rnn output.

    Note:
        Dynamic convolution attention is an alternation of the location senstive attention with
    dynamically computed convolution filters from the previous attention scores and a set of
    constraints to keep the attention alignment diagonal.
        DCA is sensitive to mixed precision training and might cause instable training.

    Args:
        query_dim (int): number of channels in the query tensor.
        embedding_dim (int): number of channels in the value tensor.
        static_filter_dim (int): number of channels in the convolution layer computing the static filters.
        static_kernel_size (int): kernel size for the convolution layer computing the static filters.
        dynamic_filter_dim (int): number of channels in the convolution layer computing the dynamic filters.
        dynamic_kernel_size (int): kernel size for the convolution layer computing the dynamic filters.
        prior_filter_len (int, optional): [description]. Defaults to 11 from the paper.
        alpha (float, optional): [description]. Defaults to 0.1 from the paper.
        beta (float, optional): [description]. Defaults to 0.9 from the paper.
    é   çš™™™™™¹?çÍÌÌÌÌÌì?c                    sÐ   t ƒ  ¡  d| _|| _|| _|| _d | _t ||¡| _	tj||| dd| _
tjd|||d d dd| _tj||dd| _t ||¡| _tj|ddd| _t t|ƒ|d |	|
¡}|  dt |¡ d¡¡ d S )	Nr+   Fr,   r
   r	   )r   r   Úpriorr   )r   r   r.   Údynamic_filter_dimÚdynamic_kernel_sizeÚprior_filter_lenr5   r   r   rm   Ú	key_layerr   Ústatic_filter_convÚstatic_filter_layerÚdynamic_filter_layerro   r   Úpmfr¡   Úregister_bufferr;   ÚFloatTensorÚflip)r   r8   rz   r   Ústatic_filter_dimÚstatic_kernel_sizer°   r±   r²   rƒ   Úbetar¯   r   r   r    r   c  s(   

ûz-MonotonicDynamicConvolutionAttention.__init__c                 C   s@  t  t  | j d¡| jd df¡| j ddd¡¡}t 	| 
d¡¡ d¡}|  t |  |¡¡¡}t j| j d¡| dd| j¡| jd d | d¡d}| | d¡| jd¡ dd¡}|  | j d¡¡ dd¡}|  t |  |¡|  |¡ ¡¡ d¡| }	t j|	dd}
|dur|
j | | j¡ |
| _t |
 d¡|¡ d¡}|S )	zˆ
        query: [B, C_attn_rnn]
        inputs: [B, T_en, D_en]
        processed_inputs: place holder.
        mask: [B, T_en]
        r
   r   r?   gíµ ÷Æ°>r	   )r   ÚgroupsrO   N)rž   Úconv1drŸ   r5   rV   r²   r¯   rQ   r;   ÚlogÚ
clamp_min_r\   r³   r   rm   r±   rR   r°   r!   r´   ro   rµ   r¶   rU   rY   rZ   r.   r[   )r   r]   rG   r^   r_   Úprior_filterÚGÚdynamic_filterÚstatic_filterr¢   r5   ri   r   r   r    r$   ˆ  s4   *ÿ
üÿýÿz,MonotonicDynamicConvolutionAttention.forwardc                 C   rI   rJ   r   rF   r   r   r    rK   ¯  rL   z6MonotonicDynamicConvolutionAttention.preprocess_inputsc                 C   s@   |  d¡}|  d¡}tj||g|jd| _d| jd d …df< d S )Nr   r
   rŠ   r9   )rR   r;   rE   rD   r5   r…   r   r   r    rH   ²  s   

z0MonotonicDynamicConvolutionAttention.init_states)r¬   r­   r®   )	r%   r&   r'   r(   r   r$   rK   rH   r)   r   r   r   r    r«   C  s    (õ%'r«   c                 C   sj   | dkrt |||||||||	|
|ƒS | dkrt||ƒS | dkr-t|||dddddddd	
S td
| › dƒ‚)NÚoriginalÚgravesÚdynamic_convolutioné   é   r¬   r­   r®   )r»   r¼   r°   r±   r²   rƒ   r½   z [!] Given Attention Type 'z' is not exist.)rk   r*   r«   ÚRuntimeError)Ú	attn_typer8   rz   r   ry   r{   r|   rs   ru   rv   rw   rx   Úattn_Kr   r   r    Ú	init_attn¹  s<   õ
örÎ   )r;   Úscipy.statsr   r   Útorch.nnr   rž   Ú%TTS.tts.layers.tacotron.common_layersr   ÚModuler   r*   rk   r«   rÎ   r   r   r   r    Ú<module>   s    W Ev