o
    wiV                     @   s   d dl Z d dlmZmZmZ d dlmZ d dlZd dl	m
Z
 d dlmZ d dlmZ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
gZG dd
 d
ejejejejZ dS )    N)DictListOptional)model_summary)
DictConfig	OmegaConf	open_dict)fn)io)$MaskedTokenLossReductionWithLossMask)logging)AppStateSpeechLanguageModelc                       s  e Zd Z fddZedefddZejdefddZd6d	ede	j
fd
dZdejfddZdejfddZd7dee fddZdd Zdd Zdd Zdd Zedd Zejdd Zed d! Zejd"d! Zdeeeeeejf f  fd#d$Zdeeeeeejf f  fd%d&Z	'd8d(eeeejf  d)edeeeeeejf f  fd*d+Z	'd8d(eeeejf  d)edeeeeeejf f  fd,d-Z d8d)edefd.d/Z!d8d)edefd0d1Z"ede#fd2d3Z$ede#fd4d5Z%  Z&S )9r   c                    sp   t    t }|   ti | _tj	 r$tj
 d ur$tj
 |_d | _d | _d | _d | _d | _d | _d S N)super__init__r   _set_model_guidr   create_cfgtorchcudais_availablecurrent_device	device_id_validation_step_outputs_validation_names_num_validation_dl_test_step_outputs_test_names_num_test_dl)self	app_state	__class__ b/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/nemo/collections/speechlm/models/base.pyr   #   s   

zSpeechLanguageModel.__init__returnc                 C   s   | j S r   r   r    r$   r$   r%   cfg8   s   zSpeechLanguageModel.cfgr)   c                 C   
   || _ d S r   r'   )r    r)   r$   r$   r%   r)   <      
   	max_depthc                 C   s   t j| |dS )a
  Summarize this LightningModule.
        Args:
            max_depth: The maximum depth of layer nesting that the summary will include. A value of 0 turns the
                layer summary off. Default: 1.
        Return:
            The model summary object
        )r-   )r   	summarize)r    r-   r$   r$   r%   r.   @   s   zSpeechLanguageModel.summarizemodulec                 C      |  D ]}d|_qd S )NF
parametersrequires_gradr    r/   paramr$   r$   r%   freeze_moduleJ      z!SpeechLanguageModel.freeze_modulec                 C   r0   )NTr1   r4   r$   r$   r%   unfreeze_moduleN   r7   z#SpeechLanguageModel.unfreeze_moduleNstagec                 C   sl   |    |   |   t| j | jdur| jjj| j_W d   n1 s(w   Y  t	
|   dS )zCalled at the beginning of fit, validate, test, or predict.
        This is called on every process when using DDP.

        Args:
            stage: fit, validate, test or predict
        N)propagate_model_guidsetup_multi_validation_datasetup_multi_test_datar   r   trainer
datamoduler)   datar   infor.   )r    r9   r$   r$   r%   setupR   s   
zSpeechLanguageModel.setupc                 C   s2   t | dst }tt | _|| j d S d S )N
model_guid)hasattrr   struuiduuid4rB   register_model_guid)r    appstater$   r$   r%   r   e   s
   
z#SpeechLanguageModel._set_model_guidc                    s<   dt jf fdd  D ]\}}j|_ | qdS )zK
        Propagates the model GUID to all submodules, recursively.
        r/   c                    s"   j | _ |  D ]} | qd S r   )rB   children)r/   childrecursively_propagate_guidr    r$   r%   rL   s   s   
zLSpeechLanguageModel.propagate_model_guid.<locals>.recursively_propagate_guidN)plLightningModulenamed_modulesrB   )r    _r/   r$   rK   r%   r:   n   s
   
z(SpeechLanguageModel.propagate_model_guidc                 C      | j d u rtd d S | j j}t|dd d u rtd d S t|dd | _t|dd | _| jd u r8t| j| _| jd u ra| jsKt	dt|dd  dd t
| jD | _td	| j  d S t| j| jkrxt	d
t| j d| j dd S )N<Trainer is not set. Cannot setup multi validation/test data._validation_dszENo validation dataset found. Skipping setup of multi validation data.r   r   z5`_num_validation_dl` not found/valid in data module: c                 S      g | ]}d | qS )val_r$   .0idxr$   r$   r%   
<listcomp>       zCSpeechLanguageModel.setup_multi_validation_data.<locals>.<listcomp>zE`_validation_names` not found in data module. Setting default names: z%Number of validation names provided (z0) does not match number of validation datasets ().)r=   r   warningr>   getattrr@   r   r   len
ValueErrorranger    data_moduler$   r$   r%   r;   |   s2   





z/SpeechLanguageModel.setup_multi_validation_datac                 C   rQ   )NrR   _test_dsz9No test dataset found. Skipping setup of multi test data.r   r   z/`_num_test_dl` not found/valid in data module: c                 S   rT   )test_r$   rV   r$   r$   r%   rY      rZ   z=SpeechLanguageModel.setup_multi_test_data.<locals>.<listcomp>z?`_test_names` not found in data module. Setting default names: zNumber of test names provided (z*) does not match number of test datasets (r[   )r=   r   r\   r>   r]   r@   r   r   r^   r_   r`   ra   r$   r$   r%   r<      s.   




z)SpeechLanguageModel.setup_multi_test_datac                 C   B   | j dur| j S g | _ | jdkrt| jD ]}| j g  q| j S )z
        Cached outputs of validation_step. It can be a list of items (for single data loader) or a list of lists
        (for multiple data loaders).

        Returns:
            List of outputs of validation_step.
        Nr,   )r   r   r`   appendr    rP   r$   r$   r%   validation_step_outputs   s   
	
z+SpeechLanguageModel.validation_step_outputsc                 C   r*   r   )r   r    valuer$   r$   r%   rh      r+   c                 C   re   )z
        Cached outputs of test_step. It can be a list of items (for single data loader) or a list of lists (for multiple data loaders).

        Returns:
            List of outputs of test_step.
        Nr,   )r   r   r`   rf   rg   r$   r$   r%   test_step_outputs   s   

z%SpeechLanguageModel.test_step_outputsc                 C   r*   r   )r   ri   r$   r$   r%   rk      r+   c                 C   s  | j durt| j dkri S t| j d tr7| j| j dd}|dur0d|v r0| j|ddd | j   |S di i}t| j D ]\}}| 	|}| j||d}|pSi }d|v rgd|vrg|| j
krg|d |d< | D ]N\}}|dkri }| D ]&\}	}
|	|d vr|| j
kr|	}|
|| d|	 < n| d|	 }|
||< qy|d }|| ||d< qk| d| }|||< qk| j |   q@d|v r| j|ddd |S )	a  
        Default DataLoader for Validation set which automatically supports multiple data loaders
        via `multi_validation_epoch_end`.

        If multi dataset support is not required, override this method entirely in base class.
        In such a case, there is no need to implement `multi_validation_epoch_end` either.

        .. note::
            If more than one data loader exists, and they all provide `val_loss`,
            only the `val_loss` of the first data loader will be used by default.
            This default can be changed by passing the special key `val_dl_idx: int`
            inside the `validation_ds` config.

        Args:
            outputs: Single or nested list of tensor outputs from one or more data loaders.

        Returns:
            A dictionary containing the union of all items from individual data_loaders,
            along with merged logs from all data loaders.
        Nr   dataloader_idxlogTon_epochval_lossrP   )rh   r^   
isinstancedictmulti_validation_epoch_endlog_dictpopclear	enumerate get_validation_dataloader_prefix_val_dl_idxitemsupdate)r    output_dictrm   val_outputsdataloader_prefixdataloader_logskvru   k_logv_log	new_k_logoutput_logsnew_kr$   r$   r%   on_validation_epoch_end   sD   





z+SpeechLanguageModel.on_validation_epoch_endc                 C   s  | j durt| j dkri S t| j d tr7| j| j dd}|dur0d|v r0| j|ddd | j   |S di i}t| j D ]\}}| 	|}| j||d}|pSi }d|v rgd|vrg|| j
krg|d |d< | D ]P\}}|dkri }| D ]&\}	}
|	|d vr|| j
kr|	}|
|| d|	 < n| d|	 }|
||< qy|di }|| ||d< qk| d| }|||< qk| j |   q@d|v r| j|ddd |S )	a  
        Default DataLoader for Test set which automatically supports multiple data loaders
        via `multi_test_epoch_end`.

        If multi dataset support is not required, override this method entirely in base class.
        In such a case, there is no need to implement `multi_test_epoch_end` either.

        .. note::
            If more than one data loader exists, and they all provide `test_loss`,
            only the `test_loss` of the first data loader will be used by default.
            This default can be changed by passing the special key `test_dl_idx: int`
            inside the `test_ds` config.

        Args:
            outputs: Single or nested list of tensor outputs from one or more data loaders.

        Returns:
            A dictionary containing the union of all items from individual data_loaders,
            along with merged logs from all data loaders.
        Nr   rl   rn   Tro   	test_lossrP   )rk   r^   rr   rs   multi_test_epoch_endru   rv   rw   rx   get_test_dataloader_prefix_test_dl_idxr{   getr|   )r    r}   rm   test_outputsr   r   r   r   ru   r   r   r   r   r   r$   r$   r%   on_test_epoch_endJ  sD   





z%SpeechLanguageModel.on_test_epoch_endr   outputsrm   c                 C      t d dS )a8  
        Adds support for multiple validation datasets. Should be overriden by subclass,
        so as to obtain appropriate logs for each of the dataloaders.

        Args:
            outputs: Same as that provided by LightningModule.on_validation_epoch_end()
                for a single dataloader.
            dataloader_idx: int representing the index of the dataloader.

        Returns:
            A dictionary of values, optionally containing a sub-dict `log`,
            such that the values in the log will be pre-pended by the dataloader prefix.
        aE  Multi data loader support has been enabled, but `multi_validation_epoch_end(outputs, dataloader_idx) has not been implemented.
If you require multi data loader support for validation sets, please override this method.
If you do not require multi data loader support, please instead override `on_validation_epoch_end(outputs).Nr   r\   r    r   rm   r$   r$   r%   rt        z.SpeechLanguageModel.multi_validation_epoch_endc                 C   r   )a2  
        Adds support for multiple test datasets. Should be overriden by subclass,
        so as to obtain appropriate logs for each of the dataloaders.

        Args:
            outputs: Same as that provided by LightningModule.on_validation_epoch_end()
                for a single dataloader.
            dataloader_idx: int representing the index of the dataloader.

        Returns:
            A dictionary of values, optionally containing a sub-dict `log`,
            such that the values in the log will be pre-pended by the dataloader prefix.
        a9  Multi data loader support has been enabled, but `multi_test_epoch_end(outputs, dataloader_idx) has not been implemented.
If you require multi data loader support for validation sets, please override this method.
If you do not require multi data loader support, please instead override `on_test_epoch_end(outputs).Nr   r   r$   r$   r%   r     r   z(SpeechLanguageModel.multi_test_epoch_endc                 C   
   | j | S z
        Get the name of one or more data loaders, which will be prepended to all logs.

        Args:
            dataloader_idx: Index of the data loader.

        Returns:
            str name of the data loader at index provided.
        )r   r    rm   r$   r$   r%   ry        

z4SpeechLanguageModel.get_validation_dataloader_prefixc                 C   r   r   )r   r   r$   r$   r%   r     r   z.SpeechLanguageModel.get_test_dataloader_prefixc                 C   s   | j st | _ | j S r   )_training_loss_reductionr   r(   r$   r$   r%   training_loss_reduction  s   z+SpeechLanguageModel.training_loss_reductionc                 C   s   | j s	tdd| _ | j S )NT)validation_step)_validation_loss_reductionr   r(   r$   r$   r%   validation_loss_reduction  s   z-SpeechLanguageModel.validation_loss_reduction)r,   r   )r   )'__name__
__module____qualname__r   propertyr   r)   setterintr   ModelSummaryr.   nnModuler6   r8   r   rD   rA   r   r:   r;   r<   rh   rk   r   r   Tensorr   r   r   rt   r   ry   r   r   r   r   __classcell__r$   r$   r"   r%   r   "   s\    
	



$$_^

)!rE   typingr   r   r   lightning.pytorchpytorchrM   r   torch.nnr   lightning.pytorch.utilitiesr   	omegaconfr   r   r   nemo.collections.llmr	   nemo.lightningr
    nemo.lightning.megatron_parallelr   
nemo.utilsr   nemo.utils.app_stater   __all__rN   IOMixinConnectorMixinFNMixinr   r$   r$   r$   r%   <module>   s   "