o
    i-F                     @   s  d dl mZmZ d dlZd dlZd dlZd dlZd dlm	Z	 d dl
m	  mZ d dlmZ dd 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G dd de	jZG dd de	jZG dd de	jZ	 eddG dd de	jZdS )    )TupleDictN)tablesc                 C   s:   t jt jt jd t| }|dd}|dd}d| S )N)	threshold	linewidth[ ]z[ %s ]
)npset_printoptionsinfnanstrreplace)np_matout_str r   R/home/ubuntu/.local/lib/python3.10/site-packages/funasr/models/fsmn_kws/encoder.pytoKaldiMatrix   s
   r   c                       4   e Zd Z fddZdd Zdd Zdd Z  ZS )	LinearTransformc                    s0   t t|   || _|| _tj||dd| _d S )NF)bias)superr   __init__	input_dim
output_dimnnLinearlinearselfr   r   	__class__r   r   r      s   zLinearTransform.__init__c                 C      |  |}|S Nr   r    inputoutputr   r   r   forward      
zLinearTransform.forwardc                 C   sH   d}|d| j | jf 7 }|d7 }|  d }|  }|t|7 }|S )Nr   z<LinearTransform> %d %d
z<LearnRateCoef> 1
linear.weightr   r   
state_dictsqueezenumpyr   )r    re_strlinear_weightsxr   r   r   to_kaldi_net"   s   zLinearTransform.to_kaldi_netc                 C   s  |  }|  }t|dksJ |d dksJ t|d | _t|d | _|  }|ddks5J | j	  | 
 d }tj| j| jftjd	}t| jD ]/}|  }| d
  }	t|	| jkskJ tjdd |	D tjd	}
|
||d d f< qQ|| jj_d S )N   r   z<LinearTransform>      LearnRateCoefr+   dtype\[\]c                 S      g | ]}t |qS r   float.0itemr   r   r   
<listcomp>C       z2LinearTransform.to_pytorch_net.<locals>.<listcomp>)readlinestripsplitlenintr   r   findr   reset_parametersr-   torchzerosfloat32rangetensorweightdata)r    freadlinear_linelinear_splitlearn_rate_liner1   new_weightsilinesplitscolsr   r   r   to_pytorch_net.   s,   
zLinearTransform.to_pytorch_net__name__
__module____qualname__r   r)   r3   r[   __classcell__r   r   r!   r   r      s
    r   c                       r   )	AffineTransformc                    s,   t t|   || _|| _t||| _d S r$   )r   ra   r   r   r   r   r   r   r   r!   r   r   r   L   s   zAffineTransform.__init__c                 C   r#   r$   r%   r&   r   r   r   r)   R   r*   zAffineTransform.forwardc                 C   sl   d}|d| j | jf 7 }|d7 }|  d }|  }|t|7 }|  d }|  }|t|7 }|S )Nr   z<AffineTransform> %d %d
z4<LearnRateCoef> 1 <BiasLearnRateCoef> 1 <MaxNorm> 0
r+   linear.biasr,   )r    r0   r1   r2   linear_biasr   r   r   r3   W   s   zAffineTransform.to_kaldi_netc                 C   sx  |  }|  }t|dksJ |d dksJ t|d | _t|d | _td| j| jf  |  }|ddks?J | j	
  tj| j| jftjd	}t| jD ]/}|  }| d
  }t|| jksoJ tjdd |D tjd	}	|	||d d f< qU|| j	j_|  d }
|  }| d
  }t|| jksJ tjdd |D tjd	}|| j	j_d S )Nr4   r   z<AffineTransform>r5   r6   z'AffineTransform output/input dim: %d %dr7   r8   r9   r;   c                 S   r<   r   r=   r?   r   r   r   rB   ~   rC   z2AffineTransform.to_pytorch_net.<locals>.<listcomp>rb   c                 S   r<   r   r=   r?   r   r   r   rB      rC   )rD   rE   rF   rG   rH   r   r   printrI   r   rJ   rK   rL   rM   rN   rO   rP   rQ   r-   r   )r    rR   affine_lineaffine_splitrU   rV   rW   rX   rY   rZ   rc   	bias_linenew_biasr   r   r   r[   g   s@   


zAffineTransform.to_pytorch_netr\   r   r   r!   r   ra   J   s
    ra   c                       r   )	RectifiedLinearc                    s.   t t|   || _t | _td| _d S )Ng?)	r   ri   r   dimr   ReLUreluDropoutdropoutr   r!   r   r   r      s   
zRectifiedLinear.__init__c                 C   r#   r$   )rl   )r    r'   outr   r   r   r)      s   
zRectifiedLinear.forwardc                 C   s   d}|d| j | j f 7 }|S )Nr   z<RectifiedLinear> %d %d
rj   r    r0   r   r   r   r3      s   zRectifiedLinear.to_kaldi_netc                 C   sx   |  }|  }t|dksJ |d dksJ t|d t|d ks(J t|d | jks3J t|d | _d S )Nr4   r   z<RectifiedLinear>r5   r6   )rD   rE   rF   rG   rH   rj   )r    rR   rX   rY   r   r   r   r[      s   zRectifiedLinear.to_pytorch_netr\   r   r   r!   r   ri      s
    ri   c                       sX   e Zd Z				ddedef fddZddejdejfd	d
Zdd Zdd Z	  Z
S )	FSMNBlockNr5   r   r   c                    s   t t|   || _|d u rd S || _|| _|| _|| _tj	| j| j|dg|dg| jdd| _
| jdkrItj	| j| j|dg|dg| jdd| _d S d | _d S )Nr5   F)dilationgroupsr   r   )r   rr   r   rj   lorderrorderlstriderstrider   Conv2d	conv_left
conv_right)r    r   r   ru   rv   rw   rx   r!   r   r   r      s    	

zFSMNBlock.__init__r'   cachec           
      C   s   t |d}|dddd}|d ur9||j}t j||fdd}|d d d d | jd  | j d d d f }nt	|dd| jd | j dg}| 
|}|| }| jd urt	|ddd| j| j g}|d d d d | jd d d f }| |}||7 }|dddd}|d}	|	|fS )Nr5   r   r4   r6   rp   )rK   	unsqueezepermutetodevicecatru   rw   Fpadrz   r{   rv   rx   r.   )
r    r'   r|   r2   x_pery_leftro   y_rightout_perr(   r   r   r   r)      s"   0 

"

zFSMNBlock.forwardc                 C   s   d}|d| j | j f 7 }|dd| j| j| j| jf 7 }|  d }t| 	 j
}|t|7 }| jd urI|  d }| 	 j
}|t|7 }|S )Nr   z<Fsmn> %d %d
zQ<LearnRateCoef> %d <LOrder> %d <ROrder> %d <LStride> %d <RStride> %d <MaxNorm> 0
r5   zconv_left.weightzconv_right.weight)rj   ru   rv   rw   rx   r-   r
   flipudr.   r/   Tr   r{   )r    r0   lfitersr2   rfitersr   r   r   r3      s   
zFSMNBlock.to_kaldi_netc                 C   s  |  }|  }t|dksJ |d dksJ t|d | _|  }| d  }t|dks8J |d dks@J |d d	ksHJ t|d | _|d
 dksWJ t|d | _|d dksfJ t|d | _|d dksuJ t|d | _	|d dksJ t
d tj| jd| jdftjd}t| jD ]<}t
d|  |  }| d  }	t|	| jksJ tjdd |	D tjd}
|
|| jd | dd d df< qt|dd}| j  || jj_| jdkrWt
d tj| jd| jdftjd}|  }t| jD ]9}t
d|  |  }| d  }	t|	| jks+J tjdd |	D tjd}
|
||dd d df< q
t|dd}| j  || jj_d S d S )Nr4   r   z<Fsmn>r5   r;      z<LearnRateCoef>r6   z<LOrder>   z<ROrder>      z	<LStride>      z	<RStride>	   
   z	<MaxNorm>zread conv_left weightr9   zread conv_left weight -- %dc                 S   r<   r   r=   r?   r   r   r   rB     rC   z,FSMNBlock.to_pytorch_net.<locals>.<listcomp>zread conv_right weightzread conv_right weight -- %dc                 S   r<   r   r=   r?   r   r   r   rB   .  rC   )rD   rE   rF   rG   rH   rj   ru   rv   rw   rx   rd   rK   rL   rM   rN   rO   	transposerz   rJ   rP   rQ   r{   )r    rR   	fsmn_line
fsmn_splitparams_lineparams_splitnew_lfiltersrW   rX   rY   rZ   new_rfiltersr   r   r   r[      sj    


zFSMNBlock.to_pytorch_net)NNr5   r5   r$   )r]   r^   r_   rH   r   rK   Tensorr)   r3   r[   r`   r   r   r!   r   rr      s     rr   c                       sj   e Zd Zdededededededef fdd	Zddejdeeejf fddZ	dd Z
dd Z  ZS )
BasicBlock
linear_dimproj_dimru   rv   rw   rx   stack_layerc                    sh   t t|   || _|| _|| _|| _|| _t||| _	t
||||||| _t||| _t||| _d S r$   )r   r   r   ru   rv   rw   rx   r   r   r   rr   
fsmn_blockra   affineri   rl   )r    r   r   ru   rv   rw   rx   r   r!   r   r   r   9  s   
zBasicBlock.__init__Nr'   r|   c           	      C   s   |  |}|d ur6d| j}||vr)t|jd |jd | jd | j d||< | ||| \}||< n| |d \}}| 	|}| 
|}|S )Nzcache_layer_{}r   r8   r5   )r   formatr   rK   rL   shaperu   rw   r   r   rl   )	r    r'   r|   x1cache_layer_namex2_x3x4r   r   r   r)   N  s   
 

zBasicBlock.forwardc                 C   s@   d}|| j  7 }|| j 7 }|| j 7 }|| j 7 }|S Nr   )r   r3   r   r   rl   rq   r   r   r   r3   ^  s   zBasicBlock.to_kaldi_netc                 C   s4   | j | | j| | j| | j| d S r$   )r   r[   r   r   rl   )r    rR   r   r   r   r[   g  s   zBasicBlock.to_pytorch_netr$   )r]   r^   r_   rH   r   rK   r   r   r   r)   r3   r[   r`   r   r   r!   r   r   8  s&     	r   c                       s2   e Zd Z fddZdejdejfddZ  ZS )BasicBlock_exportc                    s2   t t|   |j| _|j| _|j| _|j| _d S r$   )r   r   r   r   r   r   rl   )r    modelr!   r   r   r   o  s
   zBasicBlock_export.__init__r'   in_cachec                 C   s6   |  |}| ||\}}| |}| |}||fS r$   )r   r   r   rl   )r    r'   r   r2   	out_cacher   r   r   r)   y  s
   


zBasicBlock_export.forward)r]   r^   r_   r   rK   r   r)   r`   r   r   r!   r   r   n  s    
r   c                       sJ   e Zd Z fddZdejdeeejf fddZdd Z	d	d
 Z
  ZS )	FsmnStackc                    s   t t| j|  d S r$   )r   r   r   )r    argsr!   r   r   r     s   zFsmnStack.__init__r'   r|   c                 C   s"   |}| j  D ]}|||}q|S r$   )_modulesvalues)r    r'   r|   r2   moduler   r   r   r)     s   zFsmnStack.forwardc                 C   s$   d}| j  D ]}|| 7 }q|S r   )r   r   r3   )r    r0   r   r   r   r   r3     s   zFsmnStack.to_kaldi_netc                 C   s   | j  D ]}|| qd S r$   )r   r   r[   )r    rR   r   r   r   r   r[     s   zFsmnStack.to_pytorch_net)r]   r^   r_   r   rK   r   r   r   r)   r3   r[   r`   r   r   r!   r   r     s
    r   encoder_classesFSMNConvertc                       s   e Zd Z	ddededededededed	ed
edededef fddZdefddZ	ddejde	e
ejf deeje	e
ejf f fddZdd Zdd Z  ZS )r   Tr   input_affine_dimfsmn_layersr   r   ru   rv   rw   rx   output_affine_dimr   use_softmaxc                    s   t    || _|| _|| _ | _| _|
| _|| _t	||| _
t	| | _t  | _t fddt|D  | _t	 |
| _t	|
|| _|| _| jrZtjdd| _d S d S )Nc              
      s    g | ]}t  |qS r   )r   )r@   rW   r   ru   rw   r   rv   rx   r   r   rB     s    z(FSMNConvert.__init__.<locals>.<listcomp>r8   rp   )r   r   r   r   r   r   r   r   r   ra   
in_linear1
in_linear2ri   rl   r   rN   fsmnout_linear1out_linear2r   r   Softmaxsoftmax)r    r   r   r   r   r   ru   rv   rw   rx   r   r   r   r!   r   r   r     s,   
zFSMNConvert.__init__returnc                 C   s   | j S r$   )r   )r    r   r   r   output_size  s   zFSMNConvert.output_sizeNr'   r|   c           
      C   sV   |  |}| |}| |}| ||}| |}| |}| jr)| |}	|	S |S )a(  
        Args:
            input (torch.Tensor): Input tensor (B, T, D)
            cache: when cache is not None, the forward is in streaming. The type of cache is a dict, egs,
            {'cache_layer_1': torch.Tensor(B, T1, D)}, T1 is equal to self.lorder. It is {} for the 1st frame
        )r   r   rl   r   r   r   r   r   )
r    r'   r|   r   r   r   r   x5x6x7r   r   r   r)     s   





zFSMNConvert.forwardc                 C   s   d}|d7 }|| j  7 }|| j 7 }|| j 7 }| jD ]}|| 7 }q|| j 7 }|| j 7 }|d| j| jf 7 }|d7 }|S )Nr   z<Nnet>
z<Softmax> %d %d
z</Nnet>
)r   r3   r   rl   r   r   r   r   )r    r0   r   r   r   r   r3     s   
zFSMNConvert.to_kaldi_netc                 C   s  t |dddx}t |d}| }| dksJ | j| | j| | j| | jD ]}|| q.| j| | j	| | }| 
 }|d  dksVJ t|d | jksaJ t|d | jkslJ | }| d	ksxJ W d    n1 sw   Y  |  d S )
Nrutf8)encodingz<Nnet>r   z	<Softmax>r5   r6   z</Nnet>)openrD   rE   r   r[   r   rl   r   r   r   rF   rH   r   close)r    
kaldi_filerR   nnet_start_liner   softmax_linesoftmax_splitnnet_end_liner   r   r   r[     s(   

zFSMNConvert.to_pytorch_net)Tr$   )r]   r^   r_   rH   boolr   r   rK   r   r   r   r   r)   r3   r[   r`   r   r   r!   r   r     sL    	
)
)typingr   r   copyosr/   r
   rK   torch.nnr   torch.nn.functional
functionalr   funasr.registerr   r   Moduler   ra   ri   rr   r   r   
Sequentialr   registerr   r   r   r   r   <module>   s(    5E 6
