o
    }oi7                     @   s   d dl Z d dlmZ d dlmZmZ d dl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	lmZmZmZmZ d d
lmZ d dlm Z mZ d dlmZ dgZG dd de
eZG dd deZdS )    N)ABC)ListOptional)WithOptionalCudaGraphs)ModelPT)PretrainedModelInfo)
Exportable)AccessMixin)AudioSignal
LabelsTypeLengthsType
NeuralType)get_io_names)loggingmodel_utils)cast_allASRModelc                       s   e Zd Zd#defddZd#defddZed$d	d
Zd%dej	de
dej	fddZdd Z fddZd&ddZd&ddZd&ddZdeeeeeej	f f  f fddZd&ddZd&dd Zedefd!d"Z  ZS )'r   r   dataloader_idxc                 C   s4  i }i }d|d v rt dd |D  }d|i}|| d|d v rHt dd |D  }t dd |D  }d|| i}|| d	|d v rt d
d |D  }	t dd |D  }
t dd |D jdd}t dd |D jdd}d| j|	|
||i}|| i |d|iS )Nval_lossr   c                 S      g | ]}|d  qS )r    .0xr   r   Y/home/ubuntu/.local/lib/python3.10/site-packages/nemo/collections/asr/models/asr_model.py
<listcomp>'       z7ASRModel.multi_validation_epoch_end.<locals>.<listcomp>val_wer_numc                 S   r   )r   r   r   r   r   r   r   -   r   c                 S   r   )val_wer_denomr   r   r   r   r   r   .   r   val_werval_bleu_numc                 S   r   )val_bleu_pred_lenr   r   r   r   r   r   4   r   c                 S   r   )val_bleu_target_lenr   r   r   r   r   r   5   r   c                 S   r   )r    r   r   r   r   r   r   6   r   )dimc                 S   r   )val_bleu_denomr   r   r   r   r   r   7   r   val_bleulog)torchstackmeanupdatesumbleu_compute_bleuselfoutputsr   r   tensorboard_logsval_loss_meanwer_num	wer_denomr   bleu_pred_lenbleu_target_lenbleu_num
bleu_denomr%   r   r   r   multi_validation_epoch_end"   s&   


z#ASRModel.multi_validation_epoch_endc                 C   s,  i }i }d|d v rt dd |D  }d|i}|| d|d v rHt dd |D  }t dd |D  }d|| i}|| d	|d v rt d
d |D  }	t dd |D  }
t dd |D  }t dd |D  }d| j|	|
||i}|| i |d|iS )N	test_lossr   c                 S   r   )r:   r   r   r   r   r   r   C   r   z1ASRModel.multi_test_epoch_end.<locals>.<listcomp>test_wer_numc                 S   r   )r;   r   r   r   r   r   r   I   r   c                 S   r   )test_wer_denomr   r   r   r   r   r   J   r   test_wertest_bleu_numc                 S   r   )test_bleu_pred_lenr   r   r   r   r   r   P   r   c                 S   r   )test_bleu_target_lenr   r   r   r   r   r   Q   r   c                 S   r   )r>   r   r   r   r   r   r   R   r   c                 S   r   )test_bleu_denomr   r   r   r   r   r   S   r   	test_bleur&   )r'   r(   r)   r*   r+   werr-   r.   r   r   r   multi_test_epoch_end>   s&   


zASRModel.multi_test_epoch_endreturnList[PretrainedModelInfo]c                 C   s   t | }|S )z
        This method returns a list of pre-trained model which can be instantiated directly from NVIDIA's NGC cloud.
        Returns:
            List of available pre-trained models.
        )r   &resolve_subclass_pretrained_model_info)clslist_of_modelsr   r   r   list_available_modelsZ   s   
zASRModel.list_available_modelsFlossreset_registryc                 C   s   t | jrEt | }i }| D ](\}}d|v r9|d }t|}||7 }|d}	d|	}
d|
 }
| ||
< qt	|dkrE| 
| |rLt |  |S )al  
        Utility method to enable calculation of auxiliary losses for ASR training.

        Args:
            loss: The output loss value prior to addition with auxiliary losses.
            reset_registry: Bool, whether to reset the AccessMixin registry after adding auxiliary losses.

        Returns:
            Loss tensor used for back propagation.
        adapter_loss./zadapter_loss/r   )r	   is_access_enabled
model_guidget_module_registryitemsr+   splitjoindetachlenlog_dictrL   )r/   rK   rL   registryrX   loss_keyloss_registry	loss_list
loss_valuekeyskeyr   r   r   add_auxiliary_lossese   s$   




zASRModel.add_auxiliary_lossesc                 C   s2   d| _ d| jv r| jd r| jd | _ dS dS dS )aT  
        Utility method that must be explicitly called by the subclass in order to support optional optimization flags.
        This method is the only valid place to access self.cfg prior to DDP training occurs.

        The subclass may chose not to support this method, therefore all variables here must be checked via hasattr()
        Fskip_nan_gradN)_skip_nan_grad_cfgr/   r   r   r   setup_optimization_flags   s   z!ASRModel.setup_optimization_flagsc                    s   t    t| drd| jrft|  j}tjdg|tj	d}| 
 D ]"\}}|jdurDt|j p:t|j  }|sD|d } nq"tj rUtjj|tjjjd |dk rhtd |   dS dS dS dS )zH
        zero-out the gradients which any of them is NAN or INF
        rb      )devicedtypeNr   )opzCdetected inf or nan values in gradients! Setting gradients to zero.)superon_after_backwardhasattrrb   next
parametersrg   r'   tensorfloat32named_parametersgradisnananyisinfdistributedis_initialized
all_reduceReduceOpMINr   warning	zero_grad)r/   rg   valid_gradients
param_nameparamis_not_nan_or_inf	__class__r   r   rk      s$   

"

zASRModel.on_after_backwardNc                 C      t j| dd dS )z
        Decoder with CUDA graphs does not release memory, thus we disable it for training epoch.
        EncDecRNNTModel.decoding.decoding is the inference class with CUDA graphs
        decoding.decodingattribute_pathN)r   disable_cuda_graphs_recursiverd   r   r   r   on_train_epoch_start      zASRModel.on_train_epoch_startc                 C   r   )z
        After training, we can enable the decoder with CUDA graphs.
        EncDecRNNTModel.decoding.decoding is the inference class with CUDA graphs
        r   r   Nr   enable_cuda_graphs_recursiverd   r   r   r   on_train_epoch_end   r   zASRModel.on_train_epoch_endc                 C   r   )z
        For validation, we enable CUDA graphs to speedup validation.
        EncDecRNNTModel.decoding.decoding is the inference class with CUDA graphs.
        r   r   Nr   rd   r   r   r   on_validation_epoch_start   r   z"ASRModel.on_validation_epoch_startc                    s   t j| dd t jddS )z
        After validation, we disable CUDA graphs, since `validation` can be called in training loop, and
        training will continue after validation
        EncDecRNNTModel.decoding.decoding is the inference class with CUDA graphs.
        r   r   T)sync_metrics)r   r   rj   on_validation_epoch_endrd   r   r   r   r      s   z ASRModel.on_validation_epoch_endc                 C   r   )a  
        For testing, we enable CUDA graphs to speedup validation.
        We do not need to disable CUDA graphs after testing, since `test` cannot be called in training loop.
        EncDecRNNTModel.decoding.decoding is the inference class with CUDA graphs.
        r   r   Nr   rd   r   r   r   on_test_epoch_start      zASRModel.on_test_epoch_startc                 C   r   )a  
        For predicting, we enable CUDA graphs to speedup validation.
        We do not need to disable CUDA graphs after predicting, since `predict` cannot be called in training loop.
        EncDecRNNTModel.decoding.decoding is the inference class with CUDA graphs
        r   r   Nr   rd   r   r   r   on_predict_epoch_start   r   zASRModel.on_predict_epoch_startc                 C   sP   t tdt ddtdt ddtdt d| jjdtdt ddgdS )z
        Return a typing schema for optimal batch size calibration for various
        sequence lengths using OOMptimizer.
        )BTinput)type
seq_length)r   output)r   r   
vocab_size)rH   inputs)tupler   r
   r   r   	tokenizerr   rd   r   r   r   oomptimizer_schema   s   
zASRModel.oomptimizer_schema)r   )rE   rF   )F)rE   N)__name__
__module____qualname__intr9   rD   classmethodrJ   r'   Tensorboolr`   re   rk   r   r   r   r   dictstrr   r   r   propertyr   __classcell__r   r   r   r   r   !   s     
&


(
	
c                       sh   e Zd ZdZedd Zedd Zedd Z	dd	d
Zedd Z	edd Z
 fddZ  ZS )ExportableEncDecModelz
    Simple utiliy mix-in to export models that consist of encoder/decoder pair
    plus pre/post processor, but have to be exported as encoder/decoder pair only
    (covers most ASR classes)
    c                 C      | j S N)encoderrd   r   r   r   input_module      z"ExportableEncDecModel.input_modulec                 C   r   r   )decoderrd   r   r   r   output_module   r   z#ExportableEncDecModel.output_modulec                 C   sn   | j j}t| jddr1| jj}dd t| d d D }t| dd  D ]\}}|||< q(t|| jS )Nexport_cache_supportFc                 S   s   i | ]\}}||qS r   r   )r   ntr   r   r   
<dictcomp>  s    z6ExportableEncDecModel.output_names.<locals>.<dictcomp>rf   )r   output_typesgetattrr   listrS   r    disabled_deployment_output_names)r/   otypesin_typesr   r   r   r   r   output_names  s   
z"ExportableEncDecModel.output_namesNc           
      C   s   t | jd| jj}|du r|||d}t|tr|d }n||||||d\}}}}}t | jd| jj}||d}	t|	trB|	d }	|durM|	||||f}	t|	tjtj	dS )ad  
        This forward is used when we need to export the model to ONNX format.
        Inputs cache_last_channel and cache_last_time are needed to be passed for exporting streaming models.

        Args:
            input: Tensor that represents a batch of raw audio signals of shape [B, T]. T here represents timesteps.
            length: Vector of length B, that contains the individual lengths of the audio sequences.
            cache_last_channel: Tensor of shape [N, B, T, H] which contains the cache for last channel layers
            cache_last_time: Tensor of shape [N, B, H, T] which contains the cache for last time layers
                N is the number of such layers which need caching, B is batch size, H is the hidden size of activations,
                and T is the length of the cache

        Returns:
            the output of the model
        forward_for_exportN)audio_signallengthr   )r   r   cache_last_channelcache_last_timecache_last_channel_len)encoder_output)
from_dtypeto_dtype)
r   r   forward
isinstancer   r   r   r'   float16rp   )
r/   r   r   r   r   r   enc_funr   dec_funretr   r   r   r     s(   


z(ExportableEncDecModel.forward_for_exportc                 C      | j jS r   )r   disabled_deployment_input_namesrd   r   r   r   r   4     z5ExportableEncDecModel.disabled_deployment_input_namesc                 C   r   r   )r   r   rd   r   r   r   r   8  r   z6ExportableEncDecModel.disabled_deployment_output_namesc                    sF   d|v rt |d }|| j_td|  | j  t | d S )Ncache_supportzCaching support enabled: )r   r   r   r   infosetup_streaming_paramsrj   set_export_config)r/   argsenabler   r   r   r   <  s   
z'ExportableEncDecModel.set_export_config)NNNN)r   r   r   __doc__r   r   r   r   r   r   r   r   r   r   r   r   r   r      s    




(

r   )r   abcr   typingr   r   r'   2nemo.collections.common.parts.optional_cuda_graphsr   nemo.core.classesr   nemo.core.classes.commonr   nemo.core.classes.exportabler   nemo.core.classes.mixinsr	   nemo.core.neural_typesr
   r   r   r   !nemo.core.utils.neural_type_utilsr   
nemo.utilsr   nemo.utils.cast_utilsr   __all__r   r   r   r   r   r   <module>   s"    S