a
    d	8                     @   s  d 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Z ddl	m	Z	 ddl
mZmZmZmZ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mZmZ ddlmZ ddlmZm Z  ddl!m"Z" ddl#m$Z$m%Z% e&e'Z(dZ)edZ*e*r*ddl+m,Z,m-Z- ddl.m/Z/m0Z0 ddl1m2Z2 nd\Z0Z/d\Z,Z-dZ2e3e/drXddl4m5Z5 n4e3e/drrddl6m5Z5 ndee ee dddZ5G dd deZ7dS )z
MLflow Logger
-------------
    N)	Namespace)Path)time)AnyDictListMappingOptionalUnion)RequirementCache)Tensor)Literal)_add_prefix_convert_params_flatten_dict)ModelCheckpoint)Loggerrank_zero_experiment)_scan_checkpoints)rank_zero_onlyrank_zero_warnzfile:zmlflow>=1.0.0)MetricParam)contextMlflowClient)MLFLOW_RUN_NAME)NNzmlflow.runNameresolve_tags)r   registry)tagsreturnc                 C   s   | S )a=  
        Args:
            tags: A dictionary of tags to override. If specified, tags passed in this argument will
                 override those inferred from the context.

        Returns: A dictionary of resolved tags.

        Note:
            See ``mlflow.tracking.context.registry`` for more details.
         )r   r    r    i/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/pytorch_lightning/loggers/mlflow.pyr   <   s    c                       sz  e Zd ZdZdZddedddddddf	eee ee ee	ee
f  ee ed	 eee ee d
	 fddZeeedddZeee dddZeee dddZeee	ee
f ef ddddZed)eeef ee ddddZed*eddddZeee dddZeee dd d!Zeee dd"d#Zedd$d%d&Z edd$d'd(Z!  Z"S )+MLFlowLoggeraR
  Log using `MLflow <https://mlflow.org>`_.

    Install it with pip:

    .. code-block:: bash

        pip install mlflow

    .. code-block:: python

        from pytorch_lightning import Trainer
        from pytorch_lightning.loggers import MLFlowLogger

        mlf_logger = MLFlowLogger(experiment_name="lightning_logs", tracking_uri="file:./ml-runs")
        trainer = Trainer(logger=mlf_logger)

    Use the logger anywhere in your :class:`~pytorch_lightning.core.module.LightningModule` as follows:

    .. code-block:: python

        from pytorch_lightning import LightningModule


        class LitModel(LightningModule):
            def training_step(self, batch, batch_idx):
                # example
                self.logger.experiment.whatever_ml_flow_supports(...)

            def any_lightning_module_function_or_hook(self):
                self.logger.experiment.whatever_ml_flow_supports(...)

    Args:
        experiment_name: The name of the experiment.
        run_name: Name of the new run. The `run_name` is internally stored as a ``mlflow.runName`` tag.
            If the ``mlflow.runName`` tag has already been set in `tags`, the value is overridden by the `run_name`.
        tracking_uri: Address of local or remote tracking server.
            If not provided, defaults to `MLFLOW_TRACKING_URI` environment variable if set, otherwise it falls
            back to `file:<save_dir>`.
        tags: A dictionary tags for the experiment.
        save_dir: A path to a local directory where the MLflow runs get saved.
            Defaults to `./mlflow` if `tracking_uri` is not provided.
            Has no effect if `tracking_uri` is provided.
        log_model: Log checkpoints created by :class:`~pytorch_lightning.callbacks.model_checkpoint.ModelCheckpoint`
            as MLFlow artifacts.

            * if ``log_model == 'all'``, checkpoints are logged during training.
            * if ``log_model == True``, checkpoints are logged at the end of training, except when
              :paramref:`~pytorch_lightning.callbacks.Checkpoint.save_top_k` ``== -1``
              which also logs every checkpoint during training.
            * if ``log_model == False`` (default), no checkpoint is logged.

        prefix: A string to put at the beginning of metric keys.
        artifact_location: The location to store run artifacts. If not provided, the server picks an appropriate
            default.
        run_id: The run identifier of the experiment. If not provided, a new run is started.

    Raises:
        ModuleNotFoundError:
            If required MLFlow package is not installed on the device.
    -Zlightning_logsNZMLFLOW_TRACKING_URIz./mlrunsF )TFall)	experiment_namerun_nametracking_urir   save_dir	log_modelprefixartifact_locationrun_idc
           
         s   t sttt t   |s*t | }|| _d | _|| _|| _	|	| _
|| _|| _i | _d | _|| _|| _d| _t|| _d S )NF)_MLFLOW_AVAILABLEModuleNotFoundErrorstrsuper__init__LOCAL_FILE_URI_PREFIX_experiment_name_experiment_id_tracking_uri	_run_name_run_idr   
_log_model_logged_model_time_checkpoint_callback_prefix_artifact_location_initializedr   _mlflow_client)
selfr&   r'   r(   r   r)   r*   r+   r,   r-   	__class__r    r!   r2      s$    
zMLFlowLogger.__init__)r   c                 C   s  | j r| jS | jdur:| j| j}|jj| _d| _ | jS | jdu r| j| j}|durd|j| _n*t	
d| j d | jj| j| jd| _| jdu r| jdur| jpi | _t| jv rt	
dt d| j d | j| jt< | jj| jt| jd	}|jj| _d| _ | jS )
z
        Actual MLflow object. To use MLflow features in your
        :class:`~pytorch_lightning.core.module.LightningModule` do the following.

        Example::

            self.logger.experiment.some_mlflow_function()

        NTzExperiment with name z not found. Creating it.)namer,   zThe tag z3 is found in tags. The value will be overridden by .)experiment_idr   )r>   r?   r8   get_runinforE   r5   Zget_experiment_by_namer4   logwarningZcreate_experimentr=   r7   r   r   Z
create_runr   r-   )r@   runZexptr    r    r!   
experiment   s6    






zMLFlowLogger.experimentc                 C   s   | j }| jS )zpCreate the experiment if it does not exist to get the run id.

        Returns:
            The run id.
        )rK   r8   r@   _r    r    r!   r-      s    zMLFlowLogger.run_idc                 C   s   | j }| jS )z~Create the experiment if it does not exist to get the experiment id.

        Returns:
            The experiment id.
        )rK   r5   rL   r    r    r!   rE      s    zMLFlowLogger.experiment_id)paramsr   c                 C   sZ   t |}t|}dd | D }tdt|dD ]"}| jj| j|||d  d q2d S )Nc                 S   s(   g | ] \}}t |t|d d dqS )N   )keyvalue)r   r0   ).0kvr    r    r!   
<listcomp>       z0MLFlowLogger.log_hyperparams.<locals>.<listcomp>r   d   )r-   rN   )r   r   itemsrangelenrK   	log_batchr-   )r@   rN   Zparams_listidxr    r    r!   log_hyperparams   s
    zMLFlowLogger.log_hyperparams)metricsstepr   c              	   C   s   t jdksJ dt|| j| j}g }tt d }| D ]z\}}t|t	rht
d| d| d q<tdd|}||krtd	| d
| dtd |}|t||||pdd q<| jj| j|d d S )Nr   z-experiment tried to log from global_rank != 0i  z$Discarding metric with string value =rD   z[^a-zA-Z0-9_/. -]+r$   zVMLFlow only allows '_', '/', '.' and ' ' special characters in metric name. Replacing z with )category)rP   rQ   	timestampr_   )r-   r^   )r   Zrankr   r<   LOGGER_JOIN_CHARintr   rX   
isinstancer0   rH   rI   resubr   RuntimeWarningappendr   rK   r[   r-   )r@   r^   r_   Zmetrics_listZtimestamp_msrS   rT   Znew_kr    r    r!   log_metrics   s*    
zMLFlowLogger.log_metricssuccess)statusr   c                 C   sf   | j s
d S |dkrd}n|dkr&d}n|dkr2d}| jrD| | j | j| jrb| j| j| d S )Nrk   FINISHEDfailedZFAILEDfinished)r>   r;   _scan_and_log_checkpointsrK   rF   r-   Zset_terminated)r@   rl   r    r    r!   finalize  s    zMLFlowLogger.finalizec                 C   s   | j tr| j tS dS )zThe root file directory in which MLflow experiments are saved.

        Return:
            Local path to the root experiment directory if the tracking uri is local.
            Otherwise returns `None`.
        N)r6   
startswithr3   lstripr@   r    r    r!   r)   %  s    zMLFlowLogger.save_dirc                 C   s   | j S )zPGet the experiment id.

        Returns:
            The experiment id.
        )rE   rt   r    r    r!   rC   0  s    zMLFlowLogger.namec                 C   s   | j S )zBGet the run id.

        Returns:
            The run id.
        )r-   rt   r    r    r!   version9  s    zMLFlowLogger.version)checkpoint_callbackr   c                 C   s>   | j dks| j du r*|jdkr*| | n| j du r:|| _d S )Nr%   T)r9   
save_top_krp   r;   )r@   rv   r    r    r!   after_save_checkpointB  s    
z"MLFlowLogger.after_save_checkpointc              
      sb  t  | j}|D ]J\}}}}t|tr0| n|t|j fdddD d}| jkrbddgndg}dt|j }	| j	
| j||	 tjddt d	}
t|
 d
d }tj||dd W d    n1 s0    Y  t|
 dd}|t| W d    n1 s0    Y  | j	| j|
|	 W d    n1 sH0    Y  || j|< qd S )Nc                    s"   i | ]}t  |r|t |qS r    )hasattrgetattr)rR   rS   rv   r    r!   
<dictcomp>S  s   

z:MLFlowLogger._scan_and_log_checkpoints.<locals>.<dictcomp>)ZmonitormodeZ	save_lastrx   Zsave_weights_onlyZ_every_n_train_stepsZ_every_n_val_epochs)ZscoreZoriginal_filenameZ
CheckpointZlatestbestzmodel/checkpoints/test)r+   suffixdirz/metadata.yamlwF)Zdefault_flow_stylez/aliases.txt)r   r:   re   r   itemr   rC   Zbest_model_pathstemrK   Zlog_artifactr8   tempfileTemporaryDirectoryosgetcwdopenyamldumpwriter0   Zlog_artifacts)r@   rv   ZcheckpointstpstagmetadataaliasesZartifact_pathZtmp_dirZtmp_file_metadataZtmp_file_aliasesr    r|   r!   rp   I  s$    
..2z&MLFlowLogger._scan_and_log_checkpoints)N)rk   )#__name__
__module____qualname____doc__rc   r   getenvr0   r	   r   r   r   r2   propertyr   r   rK   r-   rE   r   r
   r   r]   r   floatrd   rj   rq   r)   rC   ru   r   ry   rp   __classcell__r    r    rA   r!   r"   J   sV   ="+		""
r"   )N)8r   loggingr   rf   r   argparser   pathlibr   r   typingr   r   r   r   r	   r
   r   Z lightning_utilities.core.importsr   Ztorchr   Ztyping_extensionsr   Z!lightning_fabric.utilities.loggerr   r   r   Z,pytorch_lightning.callbacks.model_checkpointr   Z pytorch_lightning.loggers.loggerr   r   Z"pytorch_lightning.utilities.loggerr   Z%pytorch_lightning.utilities.rank_zeror   r   	getLoggerr   rH   r3   r.   Zmlflow.entitiesr   r   Zmlflow.trackingr   r   Zmlflow.utils.mlflow_tagsr   rz   Zmlflow.tracking.contextr   Z mlflow.tracking.context.registryr"   r    r    r    r!   <module>   sB    
