o
    i)                     @   s   d Z ddlZddlZddlZddlmZ ddl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	lmZ d
d Zdd Zdd Zdd Zdd Zdd ZdddZdd ZefddZdS )zFinetuning methods.    N)OrderedDict)get_model_conf
torch_load)ASRInterface)MTInterface)custom_torch_load)TTSInterface)dynamic_importc                    sZ   |   D ]\ }t fdd|D rtd  d d|_qtdd |  }| |fS )a$  Freeze model parameters according to modules list.

    Args:
        model (torch.nn.Module): Main model.
        modules (List): Specified module(s) to freeze.

    Return:
        model (torch.nn.Module) : Updated main model.
        model_params (filter): Filtered model parameters.

    c                 3       | ]}  |V  qd S N
startswith.0mmod W/home/ubuntu/.local/lib/python3.10/site-packages/espnet/asr/pytorch_backend/asr_init.py	<genexpr>       z!freeze_modules.<locals>.<genexpr>z	Freezing z). It will not be updated during training.Fc                 S   s   | j S r   )requires_gradxr   r   r   <lambda>#   s    z freeze_modules.<locals>.<lambda>)named_parametersanyloggingwarningr   filter
parameters)modelmodulesparammodel_paramsr   r   r   freeze_modules   s   r%   c                    s   g }g }|   D ]\ }t fdd|D r| |jfg7 }qt|dd d}|  D ]\}tfdd|D rC||jfg7 }q,t|dd d}||k}|swtd td	t|t|   td
t|t|   td |S )aR  Verify tuples (key, shape) for input model modules match specified modules.

    Args:
        model_state_dict (Dict) : Main model state dict.
        partial_state_dict (Dict): Pre-trained model state dict.
        modules (List): Specified module(s) to transfer.

    Return:
        (bool): Whether transfer learning is allowed.

    c                 3   r
   r   r   r   )key_mr   r   r   8   r   z(transfer_verification.<locals>.<genexpr>c                 S      | d | d fS Nr      r   r   r   r   r   r   :       z'transfer_verification.<locals>.<lambda>keyc                 3   r
   r   r   r   )key_pr   r   r   =   r   c                 S   r'   r(   r   r   r   r   r   r   ?   r*   zYSome specified modules from the pre-trained model don't match with the new model modules:zPre-trained: zNew model: r)   )itemsr   shapesortedr   errorsetexit)model_state_dictpartial_state_dictr"   model_modulespartial_modulesvalue_mvalue_pmodule_matchr   )r&   r-   r   transfer_verification(   s*   r;   c                    s:   t  }|  D ]\ }t fdd|D r|| < q|S )a&  Create state dict with specified modules matching input model modules.

    Args:
        model_state_dict (Dict): Pre-trained model state dict.
        modules (Dict): Specified module(s) to transfer.

    Return:
        new_state_dict (Dict): State dict with specified modules weights.

    c                 3   r
   r   r   r   r+   r   r   r   ]   r   z)get_partial_state_dict.<locals>.<genexpr>)r   r.   r   )r4   r"   new_state_dictvaluer   r+   r   get_partial_state_dictO   s   r>   c                 C   sj   t  }t|  D ])\}}|dkr||d< q	|dr2|d}d|d  d |d  d }|||< q	|S )	zCreate compatible ASR decoder state dict from LM state dict.

    Args:
        lm_state_dict (Dict): Pre-trained LM state dict.

    Return:
        new_state_dict (Dict): State dict with compatible key names.

    zpredictor.embed.weightzdec.embed.weightzpredictor.rnn..zdec.decoder.      _l0)r   listr.   r   split)lm_state_dictr<   r,   r=   _splitnew_keyr   r   r   get_lm_state_dictc   s   



rH   c                    s   g }g }t |  }|D ] t fdd|D r| g7 }q| g7 }q|r?td| d td t|  td |S )zFilter non-matched modules in model state dict.

    Args:
        model_state_dict (Dict): Pre-trained model state dict.
        modules (List): Specified module(s) to transfer.

    Return:
        new_mods (List): Filtered module list.

    c                 3   s    | ]}|  V  qd S r   r   )r   r,   r   r   r   r      r   z!filter_modules.<locals>.<genexpr>z`Specified module(s) don't match or (partially match) available modules in model. You specified: r?   z"The existing modules in model are:r)   )rC   keysr   r   r1   r3   )r4   r"   new_modsincorrect_mods
mods_modelr   r   r   filter_modules{   s"   
rM   c              	      s   | ds
| ds| S t }d|v rdnd}t|  D ]J\ }t fdddD rcd	 v rF|td
 d }td
d 	d	| |d |
dkrc|ddd|f |dd|df  }|| < q|S )a'  Create a compatible transducer model state dict for transfer learning.

    If RNN encoder modules from a non-Transducer model are found in
    the pre-trained model state dict, the corresponding modules keys are
    renamed for compatibility.

    Args:
        model_state_dict (Dict): Pre-trained model state dict
        encoder_type (str): Type of pre-trained encoder.
        encoder_units (int): Number of encoder units in pre-trained model.

    Returns:
        new_state_dict (Dict): Transducer compatible pre-trained model state dict.

    p)lstmgrubbirnnrnnc                 3   s    | ]}| v V  qd S r   r   )r   kr+   r   r   r      s    z:create_transducer_compatible_state_dict.<locals>.<genexpr>)l_lastnbrnnrV   z
_l([0-9]+)r)   rB   r@   N)endswithr   rC   r.   r   researchgroupsubreplacesize)r4   encoder_typeencoder_unitsr<   rnn_key_namer=   
layer_namer   r+   r   'create_transducer_compatible_state_dict   s"   
(
rc   Tc                 C   s   t | tjtj| d\}}}td|   t|dr"|j}nd}t|dr,d|_	t
|}d|v rG|||||d}t| ||d ||fS ||||}t| | ||fS )	a+  Load the trained model for recognition.

    Args:
        model_path (str): Path to model.***.best
        training (bool): Training mode specification for transducer model.

    Returns:
        model (torch.nn.Module): Trained model.
        train_args (Namespace): Trained model arguments.

    
model.jsonReading model parameters from model_module'espnet.nets.pytorch_backend.e2e_asr:E2Ectc_typebuiltin
transducer)training)r   ospathjoindirnamer   infohasattrrf   rh   r	   r   r   )
model_pathrk   idimodim
train_argsrf   model_classr!   r   r   r   load_trained_model   s"   



rw   c           	      C   s   t d|   tjtj| d}d| v rtt| S t	| |\}}}t
|dr/|j}nd}t|}||||}t| | t|tsQt|tsQt|tsQJ |rbd|jvrbt| |j|jS | S )a  Extract the trained model state dict for pre-initialization.

    Args:
        model_path (str): Path to trained model.
        new_is_transducer (bool): Whether the new model is Transducer-based.

    Return:
        (Dict): Trained model state dict.

    re   rd   rnnlmrf   rg   rj   )r   rp   rl   rm   rn   ro   rH   torchloadr   rq   rf   r	   r   
isinstancer   r   r   rc   
state_dictetypeeunits)	rr   new_is_transducer	conf_pathrs   rt   argsrf   rv   r!   r   r   r   get_trained_model_state_dict   s0   

r   c                 C   s   dd }|j }|j}|j}|j}t|j}	|	| ||}
t|
|s"J |
 }t	d ||f||ffD ]@\}}|durst
j|rgt|d|jv }t||}t||}|rft|||rf|||| || q3td|  td q3|
| |
S )am  Load ASR/MT/TTS model with pre-trained weights for specified modules.

    Args:
        idim (int): Input dimension.
        odim (int): Output dimension.
        args Namespace: Model arguments.
        interface (ASRInterface|MTInterface|TTSInterface): Model interface.

    Return:
        main_model (torch.nn.Module): Model with pre-initialized weights.

    c                 S   s8   t d| d|  |  D ]
}t d|  qd S )NzLoading z from model: zOverriding module )r   rp   rI   r   )r|   r"   rr   rT   r   r   r   print_new_keys)  s   z,load_trained_modules.<locals>.print_new_keysz&Model(s) found for pre-initialization.Nrj   zSpecified model was not found: r)   )enc_initdec_initenc_init_modsdec_init_modsr	   rf   r{   r|   r   r   rl   rm   isfiler   rM   r>   r;   updater1   r3   load_state_dict)rs   rt   r   	interfacer   enc_model_pathdec_model_pathenc_modulesdec_modulesrv   
main_modelmain_state_dictrr   r"   r4   r5   r   r   r   load_trained_modules  s@   






r   )T)__doc__r   rl   rY   collectionsr   ry   espnet.asr.asr_utilsr   r   espnet.nets.asr_interfacer   espnet.nets.mt_interfacer   ,espnet.nets.pytorch_backend.transducer.utilsr   espnet.nets.tts_interfacer   espnet.utils.dynamic_importr	   r%   r;   r>   rH   rM   rc   rw   r   r   r   r   r   r   <module>   s*    '!
+'-