o
    8wi\:                     @   s   d Z ddlZddlZddlmZmZ ddlmZ eeZ	G dd dZ
G dd de
ZG d	d
 d
e
ZG dd de
Zdd ZG dd dZdddZdd ZdS )zXLoggers for experiment monitoring.

Authors
 * Peter Plantinga 2020
 * Jarod Duret 2023
    N)if_main_processmain_process_only)
get_loggerc                   @   s"   e Zd ZdZ				dddZdS )TrainLoggerz:Abstract class defining an interface for training loggers.NFc                 C   s   t )a'  Log the stats for one epoch.

        Arguments
        ---------
        stats_meta : dict of str:scalar pairs
            Meta information about the stats (e.g., epoch, learning-rate, etc.).
        train_stats : dict of str:list pairs
            Each loss type is represented with a str : list pair including
            all the values for the training pass.
        valid_stats : dict of str:list pairs
            Each loss type is represented with a str : list pair including
            all the values for the validation pass.
        test_stats : dict of str:list pairs
            Each loss type is represented with a str : list pair including
            all the values for the test pass.
        verbose : bool
            Whether to also put logging information to the standard logger.
        )NotImplementedError)self
stats_metatrain_statsvalid_stats
test_statsverbose r   [/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/speechbrain/utils/train_logger.py	log_stats   s   zTrainLogger.log_statsNNNF)__name__
__module____qualname____doc__r   r   r   r   r   r      s    r   c                   @   sD   e Zd ZdZdddZdddZddd	Ze				
dddZdS )FileTrainLoggerzText logger of training information.

    Arguments
    ---------
    save_file : str
        The file to use for logging train information.
    precision : int
        Number of decimal places to display. Default 2, example: 1.35e-5.
       c                 C   s   || _ || _d S N)	save_file	precision)r   r   r   r   r   r   __init__=   s   
zFileTrainLogger.__init__Nc                 C   sv   t |trd|  k rdk rn n
|d| j d}nt |tr)|d| j d}|dur4| d| }| d| S )	z+Convert one item to string, handling floatsg      ?g      Y@.feN z: )
isinstancefloatr   )r   keyvaluedatasetr   r   r   _item_to_stringA   s   "
zFileTrainLogger._item_to_stringc                    s   d  fdd| D S )z,Convert all stats to a single string summaryz, c                    s   g | ]\}} || qS r   )r$   ).0kvr#   r   r   r   
<listcomp>N   s    z4FileTrainLogger._stats_to_string.<locals>.<listcomp>)joinitems)r   statsr#   r   r(   r   _stats_to_stringK   s   z FileTrainLogger._stats_to_stringTc           
      C   s   |  |}d|fd|fd|ffD ]\}}|dur"|d|  || 7 }qt| jddd}	t||	d	 W d   n1 s<w   Y  |rJt| dS dS )
See TrainLogger.log_stats()trainvalidtestNz - azutf-8)encoding)file)r-   openr   printloggerinfo)
r   r   r	   r
   r   r   string_summaryr#   r,   foutr   r   r   r   Q   s   

zFileTrainLogger.log_stats)r   r   )NNNT)	r   r   r   r   r   r$   r-   r   r   r   r   r   r   r   2   s    




r   c                   @   sF   e Zd ZdZdd Ze				dddZedd	 Zed
d ZdS )TensorboardLoggerzLogs training information in the format required by Tensorboard.

    Arguments
    ---------
    save_dir : str
        A directory for storing all the relevant logs.

    Raises
    ------
    ImportError if Tensorboard is not installed.
    c                 C   s>   || _ ddlm} d | _t r|| j | _i i i dd| _d S )Nr   )SummaryWriter)r/   r0   r1   meta)save_dirtorch.utils.tensorboardr<   writerr   global_step)r   r>   r<   r   r   r   r   w   s   zTensorboardLogger.__init__NFc                 C   s  | j d  d7  < | D ]\}}| j||| j d  qd|fd|fd|ffD ]d\}}	|	du r1q(|	 D ]V\}
}|
| j | vrGd| j | |
< |
 d| }t|trq|D ]}| j | |
 d }| j||| || j | |
< qUq5|}| j | |
 d }| j||| || j | |
< q5q(dS )	r.   r=      r/   r0   r1   Nr   /)rA   r+   r@   
add_scalarr   list)r   r   r	   r
   r   r   namer"   r#   r,   stat
value_listtagnew_global_stepr   r   r   r      s2   

zTensorboardLogger.log_statsc                 C   s   | j j||| jd |d dS )zAdd audio signal in the logs.r=   )sample_rateN)r@   	add_audiorA   )r   rF   r"   rK   r   r   r   	log_audio   s   
zTensorboardLogger.log_audioc                 C   s.   t |}|dur| j||| jd  dS dS )zAdd a figure in the logs.Nr=   )plot_spectrogramr@   
add_figurerA   )r   rF   r"   figr   r   r   
log_figure   s   zTensorboardLogger.log_figurer   )	r   r   r   r   r   r   r   rM   rQ   r   r   r   r   r;   j   s    %
r;   c                   @   s.   e Zd ZdZdd Ze				dddZdS )	WandBLoggera  
    Logger for WandB (Weights & Biases). This logger is designed to be used in the same way as TrainLogger
    and supports handling nested dictionaries as well.

    Arguments
    ---------
    initializer: callable
        A callable function that initializes the WandB run.
        For more information on the parameters that can be passed to the initializer, refer to
        the documentation: https://docs.wandb.ai/ref/python/init
    *args: tuple
        Positional arguments to be passed to the initializer function.
    **kwargs: dict
        Keyword arguments to be passed to the initializer function.

    Example
    -------
    To initialize the logger, use the following pattern in hparams.yaml:

    ```
    train_logger: !new:speechbrain.utils.train_logger.WandBLogger
        initializer: !name:wandb.init
            entity: speechbrain
            project: sb_project
            name: sb_run
            reinit: True
            resume: False
            dir: !ref <output_folder>/wandb
            id: sb_run
            resume: allow
    ```

    NOTE
    ----
    If there is an issue with the WandB Logger initialization, it raises an exception.
    c              
   O   sJ   zd | _ t r||i || _ W d S W d S  ty$ } z|dd }~ww )Nz7There was an issue with the WandB Logger initialization)runr   	Exception)r   initializerargskwargsr   r   r   r   r      s   zWandBLogger.__init__NFc           
      C   s~   i }d|fd|fd|ffD ]\}}|du rq|||< q| dd}	|	dur3| jji |||	d dS | ji || dS )r.   r/   r0   r1   Nepoch)step)getrS   log)
r   r   r	   r
   r   r   logsr#   r,   rY   r   r   r   r      s   

zWandBLogger.log_statsr   )r   r   r   r   r   r   r   r   r   r   r   rR      s    %rR   c                  C   s2   z	ddl } | jjW S  ty   td Y dS w )zeReturns the TorchVision image saver, if available
    or None if it is not - optional dependency
    r   Nz2torchvision is not available - cannot save figures)torchvisionutils
save_imageImportErrorr7   warning)r]   r   r   r   _get_image_saver  s   

rb   c                   @   sj   e Zd ZdZdeji dde i ddZdZ	dd	d
Z	dd Z
dd Zdd Zdd Zedd ZdS )ProgressSampleLoggera  A logger that outputs samples during training progress, used primarily in speech synthesis but customizable, reusable and applicable to any other generative task

    Natively, this logger supports images and raw PyTorch output.
    Other custom formats can be added as needed.

    Example:

    In hparams.yaml
    progress_sample_logger: !new:speechbrain.utils.progress_samples.ProgressSampleLogger
        output_path: output/samples
        progress_batch_sample_size: 3
        format_defs:
            foo:
                extension: bar
                saver: !speechbrain.dataio.mystuff.save_my_format
                kwargs:
                    baz: qux
        formats:
            foobar: foo



    In the brain:

    Run the following to "remember" a sample (e.g. from compute_objectives)

    self.hparams.progress_sample_logger.remember(
        target=spectrogram_target,
        output=spectrogram_output,
        alignments=alignments_output,
        my_output=
        raw_batch={
            "inputs": inputs,
            "spectrogram_target": spectrogram_target,
            "spectrogram_output": spectrogram_output,
            "alignments": alignments_output
        }
    )

    Run the following at the end of the epoch (e.g. from on_stage_end)
    self.progress_sample_logger.save(epoch)



    Arguments
    ---------
    output_path: str
        the filesystem path to which samples will be saved.
    formats: dict
        A mapping from keys to formats.
    format_defs: dict
        a dictionary with format identifiers as keys and dictionaries with
        handler callables and extensions as values. The signature of the handler
        should be similar to torch.save

        Example:
        {
            "myformat": {
                "extension": "myf",
                "saver": somemodule.save_my_format
            }
        }
    batch_sample_size: int
        The number of items to retrieve when extracting a batch sample
    pth)	extensionsaverrW   png)rawimageri   NrB   c                 C   s@   i | _ |pi | _t| j| _|d ur| j| || _|| _d S r   )progress_samplesformatsdict_DEFAULT_FORMAT_DEFSformat_defsupdatebatch_sample_sizeoutput_path)r   rq   rk   rn   rp   r   r   r   r   [  s   

zProgressSampleLogger.__init__c                 C   s
   i | _ dS )z.Initializes the collection of progress samplesN)rj   r   r   r   r   resetf  s   
zProgressSampleLogger.resetc                 K   s   | j dd | D  dS )zUpdates the internal dictionary of snapshots with the provided
        values

        Arguments
        ---------
        **kwargs: dict
            the parameters to be saved with
        c                 S      i | ]	\}}|t |qS r   detach)r%   r!   r"   r   r   r   
<dictcomp>t      z1ProgressSampleLogger.remember.<locals>.<dictcomp>N)rj   ro   r+   )r   rW   r   r   r   rememberj  s   	zProgressSampleLogger.rememberc                    sN   t |tr fdd| D }|S t |tjtfr#|d j }|S |}|S )a  Obtains a sample of a batch for saving. This can be useful to
        monitor raw data (both samples and predictions) over the course
        of training

        Arguments
        ---------
        value: dict|torch.Tensor|list
            the raw values from the batch

        Returns
        -------
        result: object
            the same type of object as the provided value
        c                    s   i | ]
\}}|  |qS r   )get_batch_sampler%   r!   
item_valuerr   r   r   rw     s    
z9ProgressSampleLogger.get_batch_sample.<locals>.<dictcomp>N)r   rl   r+   torchTensorrE   rp   )r   r"   resultr   rr   r   rz   w  s   

z%ProgressSampleLogger.get_batch_samplec                 C   s&   | j  D ]\}}| ||| qdS )zSaves all items previously saved with remember() calls

        Arguments
        ---------
        epoch: int
            The epoch number
        N)rj   r+   	save_item)r   rX   r!   datar   r   r   save  s   zProgressSampleLogger.savec           
      C   s   t j| jt|}t j|st | | j|| j	}| j
|}|du r+td| d|d  }t j||}|d}	|	durQ|	||fi |d  dS dS )a  Saves a single sample item

        Arguments
        ---------
        key: str
            the key/identifier of the item
        data: torch.Tensor
            the  data to save
        epoch: int
            the epoch number (used in file path calculations)
        NzUnsupported format {format}r   re   rf   rW   )ospathr*   rq   strexistsmakedirsrk   rZ   DEFAULT_FORMATrn   
ValueError)
r   r!   r   rX   target_pathformat
format_def	file_nameeffective_file_namerf   r   r   r   r     s   

zProgressSampleLogger.save_item)NNrB   )r   r   r   r   r}   r   rb   rm   r   r   rs   ry   rz   r   r   r   r   r   r   rc     s"    C
rc      
   Fc                 C   s   zddl }|d ddlm} W n ty    td Y dS w |   	 
 } |j|d}|j| ddd |  |  |sG|  |S )	zcReturns the matplotlib spectrogram if available
    or None if it is not - optional dependency
    r   NAggz0matplotlib is not available - cannot log figures)figsizeautolower)aspectorigin)
matplotlibusematplotlib.pyplotpyplotr`   r7   ra   rv   cpunumpysqueezefigureimshowcolorbartight_layoutclose)spectrogramapfig_size
output_figr   pltrP   r   r   r   rN     s    

rN   c                 C   sD   t | tjr|   }|S t | trdd |  D }|S | }|S )al  Detaches the specified object from the graph, which can be a
    single tensor or a dictionary of tensors. Dictionaries of tensors are
    converted recursively

    Arguments
    ---------
    value: torch.Tensor|dict
        a tensor or a dictionary of tensors

    Returns
    -------
    result: torch.Tensor|dict
        a tensor of dictionary of tensors
    c                 S   rt   r   ru   r{   r   r   r   rw     rx   zdetach.<locals>.<dictcomp>)r   r}   r~   rv   r   rl   r+   )r"   r   r   r   r   rv     s   
rv   )Nr   F)r   r   r}   speechbrain.utils.distributedr   r   speechbrain.utils.loggerr   r   r7   r   r   r;   rR   rb   rc   rN   rv   r   r   r   r   <module>   s     8NI 
*