o
    zi[:                     @   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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r~ddl)m*Z* e+e,Z-dZ.eddZ/eddZ0G dd de"Z1defddZ2dS )z
MLflow Logger
-------------
    N)	Namespace)Path)time)	TYPE_CHECKINGAnyCallableDictListLiteralMappingOptionalUnion)RequirementCache)Tensor)override)_add_prefix_convert_params_flatten_dict)ModelCheckpoint)Loggerrank_zero_experiment)_scan_checkpoints)rank_zero_onlyrank_zero_warnMlflowClientzfile:zmlflow>=1.0.0mlflowzmlflow>=2.8.0c                       s  e Zd ZdZdZddeddddddddf
d	ed
ee dee dee	ee
f  dee ded dedee dee dee f fddZeed4ddZedee fddZedee fddZeedee	ee
f ef ddfdd Zeed5d!eeef d"ee ddfd#d$Zeed6d&eddfd'd(Zeedee fd)d*Zeedee fd+d,Zeedee fd-d.Zed/e ddfd0d1Z!d/e ddfd2d3Z"  Z#S )7MLFlowLoggera
  Log using `MLflow <https://mlflow.org>`_.

    Install it with pip:

    .. code-block:: bash

        pip install mlflow  # or mlflow-skinny

    .. 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.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 `./mlruns` 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.
        synchronous: Hints mlflow whether to block the execution for every logging call until complete where
            applicable. Requires mlflow >= 2.8.0

    Raises:
        ModuleNotFoundError:
            If required MLFlow package is not installed on the device.

    -lightning_logsNMLFLOW_TRACKING_URIz./mlrunsF experiment_namerun_nametracking_uritagssave_dir	log_model)TFallprefixartifact_locationrun_idsynchronousc                    s   t sttt |
d urtstdt   |st | }|| _d | _|| _	|| _
|	| _|| _|| _i | _d | _|| _|| _|
d u rFi nd|
i| _d| _ddlm} ||| _d S )Nz$`synchronous` requires mlflow>=2.8.0r,   Fr   r   )_MLFLOW_AVAILABLEModuleNotFoundErrorstr_MLFLOW_SYNCHRONOUS_AVAILABLE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_log_batch_kwargs_initializedmlflow.trackingr   _mlflow_client)selfr"   r#   r$   r%   r&   r'   r)   r*   r+   r,   r   	__class__ T/home/ubuntu/.local/lib/python3.10/site-packages/pytorch_lightning/loggers/mlflow.pyr2   s   s,   
zMLFlowLogger.__init__returnr   c                 C   s2  ddl }| jr
| jS || j | jdur'| j| j}|jj| _	d| _| jS | j	du rQ| j
| j}|dur<|j| _	ntd| j d | jj| j| jd| _	| jdu r| jdur| jp_i | _ddlm} || jv rytd| d	| j d
 | j| j|< t }| jj| j	|| jd}|jj| _d| _| jS )zActual MLflow object. To use MLflow features in your :class:`~pytorch_lightning.core.LightningModule` do the
        following.

        Example::

            self.logger.experiment.some_mlflow_function()

        r   NTzExperiment with name z not found. Creating it.)namer*   )MLFLOW_RUN_NAMEzThe tag z3 is found in tags. The value will be overridden by .)experiment_idr%   )r   r?   rA   set_tracking_urir6   r8   get_runinforK   r5   get_experiment_by_namer4   logwarningcreate_experimentr=   r7   r%   mlflow.utils.mlflow_tagsrI   _get_resolve_tags
create_runr+   )rB   r   runexptrI   resolve_tagsrE   rE   rF   
experiment   s>   







zMLFlowLogger.experimentc                 C      | j }| jS )zqCreate the experiment if it does not exist to get the run id.

        Returns:
            The run id.

        )rY   r8   rB   _rE   rE   rF   r+         zMLFlowLogger.run_idc                 C   rZ   )zCreate the experiment if it does not exist to get the experiment id.

        Returns:
            The experiment id.

        )rY   r5   r[   rE   rE   rF   rK      r]   zMLFlowLogger.experiment_idparamsc                    st   t |}t|}ddlm   fdd| D }tdt|dD ]}| jjd| j	|||d  d| j
 q!d S )Nr   Paramc                    s(   g | ]\}} |t |d d dqS )N   )keyvalue)r/   ).0kvr_   rE   rF   
<listcomp>   s   ( z0MLFlowLogger.log_hyperparams.<locals>.<listcomp>d   )r+   r^   rE   )r   r   mlflow.entitiesr`   itemsrangelenrY   	log_batchr+   r>   )rB   r^   params_listidxrE   r_   rF   log_hyperparams   s   *zMLFlowLogger.log_hyperparamsmetricsstepc           	   	   C   s   t jdks	J dddlm} t|| j| j}g }tt d }|	 D ]=\}}t
|tr:td| d| d q$tdd	|}||krTtd
| d| dtd |}||||||p]dd q$| jjd| j|d| j d S )Nr   z-experiment tried to log from global_rank != 0)Metrici  z$Discarding metric with string value =rJ   z[^a-zA-Z0-9_/. -]+r!   zVMLFlow only allows '_', '/', '.' and ' ' special characters in metric name. Replacing z with )category)rb   rc   	timestamprr   )r+   rq   rE   )r   rankri   rs   r   r<   LOGGER_JOIN_CHARintr   rj   
isinstancer/   rP   rQ   resubr   RuntimeWarningappendrY   rm   r+   r>   )	rB   rq   rr   rs   metrics_listtimestamp_msre   rf   new_krE   rE   rF   log_metrics   s,   
 zMLFlowLogger.log_metricssuccessstatusc                 C   sj   | j sd S |dkrd}n|dkrd}n|dkrd}| jr"| | j | j| jr3| j| j| d S d S )Nr   FINISHEDfailedFAILEDfinished)r?   r;   _scan_and_log_checkpointsrY   rM   r+   set_terminated)rB   r   rE   rE   rF   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rB   rE   rE   rF   r&   #  s   
zMLFlowLogger.save_dirc                 C      | j S )zQGet the experiment id.

        Returns:
            The experiment id.

        )rK   r   rE   rE   rF   rH   1     	zMLFlowLogger.namec                 C   r   )zCGet the run id.

        Returns:
            The run id.

        )r+   r   rE   rE   rF   version<  r   zMLFlowLogger.versioncheckpoint_callbackc                 C   sD   | j dks| j du r|jdkr| | d S | j du r || _d S d S )Nr(   T)r9   
save_top_kr   r;   )rB   r   rE   rE   rF   after_save_checkpointG  s
   

z"MLFlowLogger.after_save_checkpointc              
      s\  t  | j}|D ]\}}}}t|tr| n|t|j fdddD d}| jkr0ddgndg}dt|j }	| j	
| j||	 tjddt d	P}
t|
 d
d}tj||dd W d    n1 sjw   Y  t|
 dd}|t| W d    n1 sw   Y  | j	| j|
|	 W d    n1 sw   Y  || j|< qd S )Nc                    s"   i | ]}t  |r|t |qS rE   )hasattrgetattr)rd   re   r   rE   rF   
<dictcomp>Y  s    

z:MLFlowLogger._scan_and_log_checkpoints.<locals>.<dictcomp>)monitormode	save_lastr   save_weights_only_every_n_train_steps_every_n_val_epochs)scoreoriginal_filename
Checkpointlatestbestzmodel/checkpoints/test)r)   suffixdirz/metadata.yamlwF)default_flow_stylez/aliases.txt)r   r:   rz   r   itemr   rH   best_model_pathstemrY   log_artifactr8   tempfileTemporaryDirectoryosgetcwdopenyamldumpwriter/   log_artifacts)rB   r   checkpointstpstagmetadataaliasesartifact_pathtmp_dirtmp_file_metadatatmp_file_aliasesrE   r   rF   r   O  s,   
z&MLFlowLogger._scan_and_log_checkpoints)rG   r   N)r   )$__name__
__module____qualname____doc__rx   r   getenvr/   r   r   r   r
   boolr2   propertyr   rY   r+   rK   r   r   r   r   rp   r   floatry   r   r   r&   rH   r   r   r   r   __classcell__rE   rE   rC   rF   r   0   s|    @	
'2

&(		r   rG   c                  C   sL   ddl m}  t| drddlm} |S t| dr ddlm} |S dd }|S )Nr   )contextrX   )rX   registryc                 S   s   | S r   rE   )r%   rE   rE   rF   <lambda>  s    z#_get_resolve_tags.<locals>.<lambda>)r@   r   r   mlflow.tracking.contextrX    mlflow.tracking.context.registry)r   rX   rE   rE   rF   rT     s   

rT   )3r   loggingr   r{   r   argparser   pathlibr   r   typingr   r   r   r   r	   r
   r   r   r   r    lightning_utilities.core.importsr   torchr   typing_extensionsr   !lightning_fabric.utilities.loggerr   r   r   ,pytorch_lightning.callbacks.model_checkpointr    pytorch_lightning.loggers.loggerr   r   #pytorch_lightning.loggers.utilitiesr   %pytorch_lightning.utilities.rank_zeror   r   r@   r   	getLoggerr   rP   r3   r-   r0   r   rT   rE   rE   rE   rF   <module>   s8   ,


  S