o
    8wi+;                     @   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 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r~ddl(m)Z) e*e+Z,dZ-eddZ.eddZ/G dd de!Z0defddZ1dS )z
MLflow Logger
-------------
    N)	Namespace)Mapping)Path)time)TYPE_CHECKINGAnyCallableLiteral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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dee dee dee f fddZeed5d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d6d"eeef d#ee ddfd$d%Zeed7d'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d0e ddfd1d2Z!d0e ddfd3d4Z"  Z#S )8MLFlowLoggeraP  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.
        checkpoint_path_prefix: A string to prefix the checkpoint artifact's path.
        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checkpoint_path_prefix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_checkpoint_path_prefixmlflow.trackingr   _mlflow_client)selfr    r!   r"   r#   r$   r%   r'   r(   r)   r*   r+   r   	__class__ ]/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/pytorch_lightning/loggers/mlflow.pyr1   t   s.   
zMLFlowLogger.__init__returnr   c                 C   s<  ddl }| jr
| jS || j | jdur'| j| j}|jj| _	d| _| jS | j	du rV| j
| j}|durA|jdkrA|j| _	ntd| j d | jj| j| jd| _	| jdu r| jdur| jpdi | _ddlm} || jv r~t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   NTdeletedz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_urir5   r7   get_runinforL   r4   get_experiment_by_namer3   lifecycle_stagelogwarningcreate_experimentr<   r6   r#   mlflow.utils.mlflow_tagsrJ   _get_resolve_tags
create_runr*   )rB   r   runexptrJ   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.

        )r[   r7   rB   _rE   rE   rF   r*         zMLFlowLogger.run_idc                 C   r\   )zCreate the experiment if it does not exist to get the experiment id.

        Returns:
            The experiment id.

        )r[   r4   r]   rE   rE   rF   rL      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vra   rE   rF   
<listcomp>   s   ( z0MLFlowLogger.log_hyperparams.<locals>.<listcomp>d   )r*   r`   rE   )r   r   mlflow.entitiesrb   itemsrangelenr[   	log_batchr*   r=   )rB   r`   params_listidxrE   ra   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 =rK   z[^a-zA-Z0-9_/. -]+r   zVMLFlow only allows '_', '/', '.' and ' ' special characters in metric name. Replacing z with )category)rd   re   	timestamprt   )r*   rs   rE   )r   rankrk   ru   r   r;   LOGGER_JOIN_CHARintr   rl   
isinstancer.   rR   rS   resubr   RuntimeWarningappendr[   ro   r*   r=   )	rB   rs   rt   ru   metrics_listtimestamp_msrg   rh   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_checkpointsr[   rN   r*   set_terminated)rB   r   rE   rE   rF   finalize  s   zMLFlowLogger.finalizec                 C   s"   | j tr| j ttd 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)r5   
startswithr2   rn   rB   rE   rE   rF   r$   &  s   
zMLFlowLogger.save_dirc                 C      | j S )zQGet the experiment id.

        Returns:
            The experiment id.

        )rL   r   rE   rE   rF   rI   4     	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)r8   
save_top_kr   r:   )rB   r   rE   rE   rF   after_save_checkpointJ  s
   

z"MLFlowLogger.after_save_checkpointc              
      sT  t  | j}|D ]\}}}}t|tr| n|t|j fdddD d}| jkr0ddgndg}t| jt|j	 }	| j
| j||	 t P}
t|
 dd}tj||d	d
 W d    n1 sfw   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)rf   rg   r   rE   rF   
<dictcomp>\  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/metadata.yamlwF)default_flow_stylez/aliases.txt)r   r9   r|   r   itemr   rI   best_model_pathr?   stemr[   log_artifactr7   tempfileTemporaryDirectory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   R  s,   

z&MLFlowLogger._scan_and_log_checkpoints)rG   r   N)r   )$__name__
__module____qualname____doc__rz   osgetenvr.   r
   dictr   r	   boolr1   propertyr   r[   r*   rL   r   r   r   r   rr   r   floatr{   r   r   r$   rI   r   r   r   r   __classcell__rE   rE   rC   rF   r   1   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   )contextrZ   )rZ   registryc                 S   s   | S r   rE   )r#   rE   rE   rF   <lambda>  s    z#_get_resolve_tags.<locals>.<lambda>)r@   r   r   mlflow.tracking.contextrZ    mlflow.tracking.context.registry)r   rZ   rE   rE   rF   rV     s   

rV   )2r   loggingr   r}   r   argparser   collections.abcr   pathlibr   r   typingr   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   rR   r2   r,   r/   r   rV   rE   rE   rE   rF   <module>   s:    


  U