genesis-flow 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- genesis_flow-1.0.0.dist-info/METADATA +822 -0
- genesis_flow-1.0.0.dist-info/RECORD +645 -0
- genesis_flow-1.0.0.dist-info/WHEEL +5 -0
- genesis_flow-1.0.0.dist-info/entry_points.txt +19 -0
- genesis_flow-1.0.0.dist-info/licenses/LICENSE.txt +202 -0
- genesis_flow-1.0.0.dist-info/top_level.txt +1 -0
- mlflow/__init__.py +367 -0
- mlflow/__main__.py +3 -0
- mlflow/ag2/__init__.py +56 -0
- mlflow/ag2/ag2_logger.py +294 -0
- mlflow/anthropic/__init__.py +40 -0
- mlflow/anthropic/autolog.py +129 -0
- mlflow/anthropic/chat.py +144 -0
- mlflow/artifacts/__init__.py +268 -0
- mlflow/autogen/__init__.py +144 -0
- mlflow/autogen/chat.py +142 -0
- mlflow/azure/__init__.py +26 -0
- mlflow/azure/auth_handler.py +257 -0
- mlflow/azure/client.py +319 -0
- mlflow/azure/config.py +120 -0
- mlflow/azure/connection_factory.py +340 -0
- mlflow/azure/exceptions.py +27 -0
- mlflow/azure/stores.py +327 -0
- mlflow/azure/utils.py +183 -0
- mlflow/bedrock/__init__.py +45 -0
- mlflow/bedrock/_autolog.py +202 -0
- mlflow/bedrock/chat.py +122 -0
- mlflow/bedrock/stream.py +160 -0
- mlflow/bedrock/utils.py +43 -0
- mlflow/cli.py +707 -0
- mlflow/client.py +12 -0
- mlflow/config/__init__.py +56 -0
- mlflow/crewai/__init__.py +79 -0
- mlflow/crewai/autolog.py +253 -0
- mlflow/crewai/chat.py +29 -0
- mlflow/data/__init__.py +75 -0
- mlflow/data/artifact_dataset_sources.py +170 -0
- mlflow/data/code_dataset_source.py +40 -0
- mlflow/data/dataset.py +123 -0
- mlflow/data/dataset_registry.py +168 -0
- mlflow/data/dataset_source.py +110 -0
- mlflow/data/dataset_source_registry.py +219 -0
- mlflow/data/delta_dataset_source.py +167 -0
- mlflow/data/digest_utils.py +108 -0
- mlflow/data/evaluation_dataset.py +562 -0
- mlflow/data/filesystem_dataset_source.py +81 -0
- mlflow/data/http_dataset_source.py +145 -0
- mlflow/data/huggingface_dataset.py +258 -0
- mlflow/data/huggingface_dataset_source.py +118 -0
- mlflow/data/meta_dataset.py +104 -0
- mlflow/data/numpy_dataset.py +223 -0
- mlflow/data/pandas_dataset.py +231 -0
- mlflow/data/polars_dataset.py +352 -0
- mlflow/data/pyfunc_dataset_mixin.py +31 -0
- mlflow/data/schema.py +76 -0
- mlflow/data/sources.py +1 -0
- mlflow/data/spark_dataset.py +406 -0
- mlflow/data/spark_dataset_source.py +74 -0
- mlflow/data/spark_delta_utils.py +118 -0
- mlflow/data/tensorflow_dataset.py +350 -0
- mlflow/data/uc_volume_dataset_source.py +81 -0
- mlflow/db.py +27 -0
- mlflow/dspy/__init__.py +17 -0
- mlflow/dspy/autolog.py +197 -0
- mlflow/dspy/callback.py +398 -0
- mlflow/dspy/constant.py +1 -0
- mlflow/dspy/load.py +93 -0
- mlflow/dspy/save.py +393 -0
- mlflow/dspy/util.py +109 -0
- mlflow/dspy/wrapper.py +226 -0
- mlflow/entities/__init__.py +104 -0
- mlflow/entities/_mlflow_object.py +52 -0
- mlflow/entities/assessment.py +545 -0
- mlflow/entities/assessment_error.py +80 -0
- mlflow/entities/assessment_source.py +141 -0
- mlflow/entities/dataset.py +92 -0
- mlflow/entities/dataset_input.py +51 -0
- mlflow/entities/dataset_summary.py +62 -0
- mlflow/entities/document.py +48 -0
- mlflow/entities/experiment.py +109 -0
- mlflow/entities/experiment_tag.py +35 -0
- mlflow/entities/file_info.py +45 -0
- mlflow/entities/input_tag.py +35 -0
- mlflow/entities/lifecycle_stage.py +35 -0
- mlflow/entities/logged_model.py +228 -0
- mlflow/entities/logged_model_input.py +26 -0
- mlflow/entities/logged_model_output.py +32 -0
- mlflow/entities/logged_model_parameter.py +46 -0
- mlflow/entities/logged_model_status.py +74 -0
- mlflow/entities/logged_model_tag.py +33 -0
- mlflow/entities/metric.py +200 -0
- mlflow/entities/model_registry/__init__.py +29 -0
- mlflow/entities/model_registry/_model_registry_entity.py +13 -0
- mlflow/entities/model_registry/model_version.py +243 -0
- mlflow/entities/model_registry/model_version_deployment_job_run_state.py +44 -0
- mlflow/entities/model_registry/model_version_deployment_job_state.py +70 -0
- mlflow/entities/model_registry/model_version_search.py +25 -0
- mlflow/entities/model_registry/model_version_stages.py +25 -0
- mlflow/entities/model_registry/model_version_status.py +35 -0
- mlflow/entities/model_registry/model_version_tag.py +35 -0
- mlflow/entities/model_registry/prompt.py +73 -0
- mlflow/entities/model_registry/prompt_version.py +244 -0
- mlflow/entities/model_registry/registered_model.py +175 -0
- mlflow/entities/model_registry/registered_model_alias.py +35 -0
- mlflow/entities/model_registry/registered_model_deployment_job_state.py +39 -0
- mlflow/entities/model_registry/registered_model_search.py +25 -0
- mlflow/entities/model_registry/registered_model_tag.py +35 -0
- mlflow/entities/multipart_upload.py +74 -0
- mlflow/entities/param.py +49 -0
- mlflow/entities/run.py +97 -0
- mlflow/entities/run_data.py +84 -0
- mlflow/entities/run_info.py +188 -0
- mlflow/entities/run_inputs.py +59 -0
- mlflow/entities/run_outputs.py +43 -0
- mlflow/entities/run_status.py +41 -0
- mlflow/entities/run_tag.py +36 -0
- mlflow/entities/source_type.py +31 -0
- mlflow/entities/span.py +774 -0
- mlflow/entities/span_event.py +96 -0
- mlflow/entities/span_status.py +102 -0
- mlflow/entities/trace.py +317 -0
- mlflow/entities/trace_data.py +71 -0
- mlflow/entities/trace_info.py +220 -0
- mlflow/entities/trace_info_v2.py +162 -0
- mlflow/entities/trace_location.py +173 -0
- mlflow/entities/trace_state.py +39 -0
- mlflow/entities/trace_status.py +68 -0
- mlflow/entities/view_type.py +51 -0
- mlflow/environment_variables.py +866 -0
- mlflow/evaluation/__init__.py +16 -0
- mlflow/evaluation/assessment.py +369 -0
- mlflow/evaluation/evaluation.py +411 -0
- mlflow/evaluation/evaluation_tag.py +61 -0
- mlflow/evaluation/fluent.py +48 -0
- mlflow/evaluation/utils.py +201 -0
- mlflow/exceptions.py +213 -0
- mlflow/experiments.py +140 -0
- mlflow/gemini/__init__.py +81 -0
- mlflow/gemini/autolog.py +186 -0
- mlflow/gemini/chat.py +261 -0
- mlflow/genai/__init__.py +71 -0
- mlflow/genai/datasets/__init__.py +67 -0
- mlflow/genai/datasets/evaluation_dataset.py +131 -0
- mlflow/genai/evaluation/__init__.py +3 -0
- mlflow/genai/evaluation/base.py +411 -0
- mlflow/genai/evaluation/constant.py +23 -0
- mlflow/genai/evaluation/utils.py +244 -0
- mlflow/genai/judges/__init__.py +21 -0
- mlflow/genai/judges/databricks.py +404 -0
- mlflow/genai/label_schemas/__init__.py +153 -0
- mlflow/genai/label_schemas/label_schemas.py +209 -0
- mlflow/genai/labeling/__init__.py +159 -0
- mlflow/genai/labeling/labeling.py +250 -0
- mlflow/genai/optimize/__init__.py +13 -0
- mlflow/genai/optimize/base.py +198 -0
- mlflow/genai/optimize/optimizers/__init__.py +4 -0
- mlflow/genai/optimize/optimizers/base_optimizer.py +38 -0
- mlflow/genai/optimize/optimizers/dspy_mipro_optimizer.py +221 -0
- mlflow/genai/optimize/optimizers/dspy_optimizer.py +91 -0
- mlflow/genai/optimize/optimizers/utils/dspy_mipro_callback.py +76 -0
- mlflow/genai/optimize/optimizers/utils/dspy_mipro_utils.py +18 -0
- mlflow/genai/optimize/types.py +75 -0
- mlflow/genai/optimize/util.py +30 -0
- mlflow/genai/prompts/__init__.py +206 -0
- mlflow/genai/scheduled_scorers.py +431 -0
- mlflow/genai/scorers/__init__.py +26 -0
- mlflow/genai/scorers/base.py +492 -0
- mlflow/genai/scorers/builtin_scorers.py +765 -0
- mlflow/genai/scorers/scorer_utils.py +138 -0
- mlflow/genai/scorers/validation.py +165 -0
- mlflow/genai/utils/data_validation.py +146 -0
- mlflow/genai/utils/enum_utils.py +23 -0
- mlflow/genai/utils/trace_utils.py +211 -0
- mlflow/groq/__init__.py +42 -0
- mlflow/groq/_groq_autolog.py +74 -0
- mlflow/johnsnowlabs/__init__.py +888 -0
- mlflow/langchain/__init__.py +24 -0
- mlflow/langchain/api_request_parallel_processor.py +330 -0
- mlflow/langchain/autolog.py +147 -0
- mlflow/langchain/chat_agent_langgraph.py +340 -0
- mlflow/langchain/constant.py +1 -0
- mlflow/langchain/constants.py +1 -0
- mlflow/langchain/databricks_dependencies.py +444 -0
- mlflow/langchain/langchain_tracer.py +597 -0
- mlflow/langchain/model.py +919 -0
- mlflow/langchain/output_parsers.py +142 -0
- mlflow/langchain/retriever_chain.py +153 -0
- mlflow/langchain/runnables.py +527 -0
- mlflow/langchain/utils/chat.py +402 -0
- mlflow/langchain/utils/logging.py +671 -0
- mlflow/langchain/utils/serialization.py +36 -0
- mlflow/legacy_databricks_cli/__init__.py +0 -0
- mlflow/legacy_databricks_cli/configure/__init__.py +0 -0
- mlflow/legacy_databricks_cli/configure/provider.py +482 -0
- mlflow/litellm/__init__.py +175 -0
- mlflow/llama_index/__init__.py +22 -0
- mlflow/llama_index/autolog.py +55 -0
- mlflow/llama_index/chat.py +43 -0
- mlflow/llama_index/constant.py +1 -0
- mlflow/llama_index/model.py +577 -0
- mlflow/llama_index/pyfunc_wrapper.py +332 -0
- mlflow/llama_index/serialize_objects.py +188 -0
- mlflow/llama_index/tracer.py +561 -0
- mlflow/metrics/__init__.py +479 -0
- mlflow/metrics/base.py +39 -0
- mlflow/metrics/genai/__init__.py +25 -0
- mlflow/metrics/genai/base.py +101 -0
- mlflow/metrics/genai/genai_metric.py +771 -0
- mlflow/metrics/genai/metric_definitions.py +450 -0
- mlflow/metrics/genai/model_utils.py +371 -0
- mlflow/metrics/genai/prompt_template.py +68 -0
- mlflow/metrics/genai/prompts/__init__.py +0 -0
- mlflow/metrics/genai/prompts/v1.py +422 -0
- mlflow/metrics/genai/utils.py +6 -0
- mlflow/metrics/metric_definitions.py +619 -0
- mlflow/mismatch.py +34 -0
- mlflow/mistral/__init__.py +34 -0
- mlflow/mistral/autolog.py +71 -0
- mlflow/mistral/chat.py +135 -0
- mlflow/ml_package_versions.py +452 -0
- mlflow/models/__init__.py +97 -0
- mlflow/models/auth_policy.py +83 -0
- mlflow/models/cli.py +354 -0
- mlflow/models/container/__init__.py +294 -0
- mlflow/models/container/scoring_server/__init__.py +0 -0
- mlflow/models/container/scoring_server/nginx.conf +39 -0
- mlflow/models/dependencies_schemas.py +287 -0
- mlflow/models/display_utils.py +158 -0
- mlflow/models/docker_utils.py +211 -0
- mlflow/models/evaluation/__init__.py +23 -0
- mlflow/models/evaluation/_shap_patch.py +64 -0
- mlflow/models/evaluation/artifacts.py +194 -0
- mlflow/models/evaluation/base.py +1811 -0
- mlflow/models/evaluation/calibration_curve.py +109 -0
- mlflow/models/evaluation/default_evaluator.py +996 -0
- mlflow/models/evaluation/deprecated.py +23 -0
- mlflow/models/evaluation/evaluator_registry.py +80 -0
- mlflow/models/evaluation/evaluators/classifier.py +704 -0
- mlflow/models/evaluation/evaluators/default.py +233 -0
- mlflow/models/evaluation/evaluators/regressor.py +96 -0
- mlflow/models/evaluation/evaluators/shap.py +296 -0
- mlflow/models/evaluation/lift_curve.py +178 -0
- mlflow/models/evaluation/utils/metric.py +123 -0
- mlflow/models/evaluation/utils/trace.py +179 -0
- mlflow/models/evaluation/validation.py +434 -0
- mlflow/models/flavor_backend.py +93 -0
- mlflow/models/flavor_backend_registry.py +53 -0
- mlflow/models/model.py +1639 -0
- mlflow/models/model_config.py +150 -0
- mlflow/models/notebook_resources/agent_evaluation_template.html +235 -0
- mlflow/models/notebook_resources/eval_with_dataset_example.py +22 -0
- mlflow/models/notebook_resources/eval_with_synthetic_example.py +22 -0
- mlflow/models/python_api.py +369 -0
- mlflow/models/rag_signatures.py +128 -0
- mlflow/models/resources.py +321 -0
- mlflow/models/signature.py +662 -0
- mlflow/models/utils.py +2054 -0
- mlflow/models/wheeled_model.py +280 -0
- mlflow/openai/__init__.py +57 -0
- mlflow/openai/_agent_tracer.py +364 -0
- mlflow/openai/api_request_parallel_processor.py +131 -0
- mlflow/openai/autolog.py +509 -0
- mlflow/openai/constant.py +1 -0
- mlflow/openai/model.py +824 -0
- mlflow/openai/utils/chat_schema.py +367 -0
- mlflow/optuna/__init__.py +3 -0
- mlflow/optuna/storage.py +646 -0
- mlflow/plugins/__init__.py +72 -0
- mlflow/plugins/base.py +358 -0
- mlflow/plugins/builtin/__init__.py +24 -0
- mlflow/plugins/builtin/pytorch_plugin.py +150 -0
- mlflow/plugins/builtin/sklearn_plugin.py +158 -0
- mlflow/plugins/builtin/transformers_plugin.py +187 -0
- mlflow/plugins/cli.py +321 -0
- mlflow/plugins/discovery.py +340 -0
- mlflow/plugins/manager.py +465 -0
- mlflow/plugins/registry.py +316 -0
- mlflow/plugins/templates/framework_plugin_template.py +329 -0
- mlflow/prompt/constants.py +20 -0
- mlflow/prompt/promptlab_model.py +197 -0
- mlflow/prompt/registry_utils.py +248 -0
- mlflow/promptflow/__init__.py +495 -0
- mlflow/protos/__init__.py +0 -0
- mlflow/protos/assessments_pb2.py +174 -0
- mlflow/protos/databricks_artifacts_pb2.py +489 -0
- mlflow/protos/databricks_filesystem_service_pb2.py +196 -0
- mlflow/protos/databricks_managed_catalog_messages_pb2.py +95 -0
- mlflow/protos/databricks_managed_catalog_service_pb2.py +86 -0
- mlflow/protos/databricks_pb2.py +267 -0
- mlflow/protos/databricks_trace_server_pb2.py +374 -0
- mlflow/protos/databricks_uc_registry_messages_pb2.py +1249 -0
- mlflow/protos/databricks_uc_registry_service_pb2.py +170 -0
- mlflow/protos/facet_feature_statistics_pb2.py +296 -0
- mlflow/protos/internal_pb2.py +77 -0
- mlflow/protos/mlflow_artifacts_pb2.py +336 -0
- mlflow/protos/model_registry_pb2.py +1073 -0
- mlflow/protos/scalapb/__init__.py +0 -0
- mlflow/protos/scalapb/scalapb_pb2.py +104 -0
- mlflow/protos/service_pb2.py +2600 -0
- mlflow/protos/unity_catalog_oss_messages_pb2.py +457 -0
- mlflow/protos/unity_catalog_oss_service_pb2.py +130 -0
- mlflow/protos/unity_catalog_prompt_messages_pb2.py +447 -0
- mlflow/protos/unity_catalog_prompt_messages_pb2_grpc.py +24 -0
- mlflow/protos/unity_catalog_prompt_service_pb2.py +164 -0
- mlflow/protos/unity_catalog_prompt_service_pb2_grpc.py +785 -0
- mlflow/py.typed +0 -0
- mlflow/pydantic_ai/__init__.py +57 -0
- mlflow/pydantic_ai/autolog.py +173 -0
- mlflow/pyfunc/__init__.py +3844 -0
- mlflow/pyfunc/_mlflow_pyfunc_backend_predict.py +61 -0
- mlflow/pyfunc/backend.py +523 -0
- mlflow/pyfunc/context.py +78 -0
- mlflow/pyfunc/dbconnect_artifact_cache.py +144 -0
- mlflow/pyfunc/loaders/__init__.py +7 -0
- mlflow/pyfunc/loaders/chat_agent.py +117 -0
- mlflow/pyfunc/loaders/chat_model.py +125 -0
- mlflow/pyfunc/loaders/code_model.py +31 -0
- mlflow/pyfunc/loaders/responses_agent.py +112 -0
- mlflow/pyfunc/mlserver.py +46 -0
- mlflow/pyfunc/model.py +1473 -0
- mlflow/pyfunc/scoring_server/__init__.py +604 -0
- mlflow/pyfunc/scoring_server/app.py +7 -0
- mlflow/pyfunc/scoring_server/client.py +146 -0
- mlflow/pyfunc/spark_model_cache.py +48 -0
- mlflow/pyfunc/stdin_server.py +44 -0
- mlflow/pyfunc/utils/__init__.py +3 -0
- mlflow/pyfunc/utils/data_validation.py +224 -0
- mlflow/pyfunc/utils/environment.py +22 -0
- mlflow/pyfunc/utils/input_converter.py +47 -0
- mlflow/pyfunc/utils/serving_data_parser.py +11 -0
- mlflow/pytorch/__init__.py +1171 -0
- mlflow/pytorch/_lightning_autolog.py +580 -0
- mlflow/pytorch/_pytorch_autolog.py +50 -0
- mlflow/pytorch/pickle_module.py +35 -0
- mlflow/rfunc/__init__.py +42 -0
- mlflow/rfunc/backend.py +134 -0
- mlflow/runs.py +89 -0
- mlflow/server/__init__.py +302 -0
- mlflow/server/auth/__init__.py +1224 -0
- mlflow/server/auth/__main__.py +4 -0
- mlflow/server/auth/basic_auth.ini +6 -0
- mlflow/server/auth/cli.py +11 -0
- mlflow/server/auth/client.py +537 -0
- mlflow/server/auth/config.py +34 -0
- mlflow/server/auth/db/__init__.py +0 -0
- mlflow/server/auth/db/cli.py +18 -0
- mlflow/server/auth/db/migrations/__init__.py +0 -0
- mlflow/server/auth/db/migrations/alembic.ini +110 -0
- mlflow/server/auth/db/migrations/env.py +76 -0
- mlflow/server/auth/db/migrations/versions/8606fa83a998_initial_migration.py +51 -0
- mlflow/server/auth/db/migrations/versions/__init__.py +0 -0
- mlflow/server/auth/db/models.py +67 -0
- mlflow/server/auth/db/utils.py +37 -0
- mlflow/server/auth/entities.py +165 -0
- mlflow/server/auth/logo.py +14 -0
- mlflow/server/auth/permissions.py +65 -0
- mlflow/server/auth/routes.py +18 -0
- mlflow/server/auth/sqlalchemy_store.py +263 -0
- mlflow/server/graphql/__init__.py +0 -0
- mlflow/server/graphql/autogenerated_graphql_schema.py +353 -0
- mlflow/server/graphql/graphql_custom_scalars.py +24 -0
- mlflow/server/graphql/graphql_errors.py +15 -0
- mlflow/server/graphql/graphql_no_batching.py +89 -0
- mlflow/server/graphql/graphql_schema_extensions.py +74 -0
- mlflow/server/handlers.py +3217 -0
- mlflow/server/prometheus_exporter.py +17 -0
- mlflow/server/validation.py +30 -0
- mlflow/shap/__init__.py +691 -0
- mlflow/sklearn/__init__.py +1994 -0
- mlflow/sklearn/utils.py +1041 -0
- mlflow/smolagents/__init__.py +66 -0
- mlflow/smolagents/autolog.py +139 -0
- mlflow/smolagents/chat.py +29 -0
- mlflow/store/__init__.py +10 -0
- mlflow/store/_unity_catalog/__init__.py +1 -0
- mlflow/store/_unity_catalog/lineage/__init__.py +1 -0
- mlflow/store/_unity_catalog/lineage/constants.py +2 -0
- mlflow/store/_unity_catalog/registry/__init__.py +6 -0
- mlflow/store/_unity_catalog/registry/prompt_info.py +75 -0
- mlflow/store/_unity_catalog/registry/rest_store.py +1740 -0
- mlflow/store/_unity_catalog/registry/uc_oss_rest_store.py +507 -0
- mlflow/store/_unity_catalog/registry/utils.py +121 -0
- mlflow/store/artifact/__init__.py +0 -0
- mlflow/store/artifact/artifact_repo.py +472 -0
- mlflow/store/artifact/artifact_repository_registry.py +154 -0
- mlflow/store/artifact/azure_blob_artifact_repo.py +275 -0
- mlflow/store/artifact/azure_data_lake_artifact_repo.py +295 -0
- mlflow/store/artifact/cli.py +141 -0
- mlflow/store/artifact/cloud_artifact_repo.py +332 -0
- mlflow/store/artifact/databricks_artifact_repo.py +729 -0
- mlflow/store/artifact/databricks_artifact_repo_resources.py +301 -0
- mlflow/store/artifact/databricks_logged_model_artifact_repo.py +93 -0
- mlflow/store/artifact/databricks_models_artifact_repo.py +216 -0
- mlflow/store/artifact/databricks_sdk_artifact_repo.py +134 -0
- mlflow/store/artifact/databricks_sdk_models_artifact_repo.py +97 -0
- mlflow/store/artifact/dbfs_artifact_repo.py +240 -0
- mlflow/store/artifact/ftp_artifact_repo.py +132 -0
- mlflow/store/artifact/gcs_artifact_repo.py +296 -0
- mlflow/store/artifact/hdfs_artifact_repo.py +209 -0
- mlflow/store/artifact/http_artifact_repo.py +218 -0
- mlflow/store/artifact/local_artifact_repo.py +142 -0
- mlflow/store/artifact/mlflow_artifacts_repo.py +94 -0
- mlflow/store/artifact/models_artifact_repo.py +259 -0
- mlflow/store/artifact/optimized_s3_artifact_repo.py +356 -0
- mlflow/store/artifact/presigned_url_artifact_repo.py +173 -0
- mlflow/store/artifact/r2_artifact_repo.py +70 -0
- mlflow/store/artifact/runs_artifact_repo.py +265 -0
- mlflow/store/artifact/s3_artifact_repo.py +330 -0
- mlflow/store/artifact/sftp_artifact_repo.py +141 -0
- mlflow/store/artifact/uc_volume_artifact_repo.py +76 -0
- mlflow/store/artifact/unity_catalog_models_artifact_repo.py +168 -0
- mlflow/store/artifact/unity_catalog_oss_models_artifact_repo.py +168 -0
- mlflow/store/artifact/utils/__init__.py +0 -0
- mlflow/store/artifact/utils/models.py +148 -0
- mlflow/store/db/__init__.py +0 -0
- mlflow/store/db/base_sql_model.py +3 -0
- mlflow/store/db/db_types.py +10 -0
- mlflow/store/db/utils.py +314 -0
- mlflow/store/db_migrations/__init__.py +0 -0
- mlflow/store/db_migrations/alembic.ini +74 -0
- mlflow/store/db_migrations/env.py +84 -0
- mlflow/store/db_migrations/versions/0584bdc529eb_add_cascading_deletion_to_datasets_from_experiments.py +88 -0
- mlflow/store/db_migrations/versions/0a8213491aaa_drop_duplicate_killed_constraint.py +49 -0
- mlflow/store/db_migrations/versions/0c779009ac13_add_deleted_time_field_to_runs_table.py +24 -0
- mlflow/store/db_migrations/versions/181f10493468_allow_nulls_for_metric_values.py +35 -0
- mlflow/store/db_migrations/versions/27a6a02d2cf1_add_model_version_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/2b4d017a5e9b_add_model_registry_tables_to_db.py +77 -0
- mlflow/store/db_migrations/versions/2d6e25af4d3e_increase_max_param_val_length.py +33 -0
- mlflow/store/db_migrations/versions/3500859a5d39_add_model_aliases_table.py +50 -0
- mlflow/store/db_migrations/versions/39d1c3be5f05_add_is_nan_constraint_for_metrics_tables_if_necessary.py +41 -0
- mlflow/store/db_migrations/versions/400f98739977_add_logged_model_tables.py +123 -0
- mlflow/store/db_migrations/versions/4465047574b1_increase_max_dataset_schema_size.py +38 -0
- mlflow/store/db_migrations/versions/451aebb31d03_add_metric_step.py +35 -0
- mlflow/store/db_migrations/versions/5b0e9adcef9c_add_cascade_deletion_to_trace_tables_fk.py +40 -0
- mlflow/store/db_migrations/versions/6953534de441_add_step_to_inputs_table.py +25 -0
- mlflow/store/db_migrations/versions/728d730b5ebd_add_registered_model_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/7ac759974ad8_update_run_tags_with_larger_limit.py +36 -0
- mlflow/store/db_migrations/versions/7f2a7d5fae7d_add_datasets_inputs_input_tags_tables.py +82 -0
- mlflow/store/db_migrations/versions/84291f40a231_add_run_link_to_model_version.py +26 -0
- mlflow/store/db_migrations/versions/867495a8f9d4_add_trace_tables.py +90 -0
- mlflow/store/db_migrations/versions/89d4b8295536_create_latest_metrics_table.py +169 -0
- mlflow/store/db_migrations/versions/90e64c465722_migrate_user_column_to_tags.py +64 -0
- mlflow/store/db_migrations/versions/97727af70f4d_creation_time_last_update_time_experiments.py +25 -0
- mlflow/store/db_migrations/versions/__init__.py +0 -0
- mlflow/store/db_migrations/versions/a8c4a736bde6_allow_nulls_for_run_id.py +27 -0
- mlflow/store/db_migrations/versions/acf3f17fdcc7_add_storage_location_field_to_model_.py +29 -0
- mlflow/store/db_migrations/versions/bd07f7e963c5_create_index_on_run_uuid.py +26 -0
- mlflow/store/db_migrations/versions/bda7b8c39065_increase_model_version_tag_value_limit.py +38 -0
- mlflow/store/db_migrations/versions/c48cb773bb87_reset_default_value_for_is_nan_in_metrics_table_for_mysql.py +41 -0
- mlflow/store/db_migrations/versions/cbc13b556ace_add_v3_trace_schema_columns.py +31 -0
- mlflow/store/db_migrations/versions/cc1f77228345_change_param_value_length_to_500.py +34 -0
- mlflow/store/db_migrations/versions/cfd24bdc0731_update_run_status_constraint_with_killed.py +78 -0
- mlflow/store/db_migrations/versions/df50e92ffc5e_add_experiment_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/f5a4f2784254_increase_run_tag_value_limit.py +36 -0
- mlflow/store/entities/__init__.py +3 -0
- mlflow/store/entities/paged_list.py +18 -0
- mlflow/store/model_registry/__init__.py +10 -0
- mlflow/store/model_registry/abstract_store.py +1081 -0
- mlflow/store/model_registry/base_rest_store.py +44 -0
- mlflow/store/model_registry/databricks_workspace_model_registry_rest_store.py +37 -0
- mlflow/store/model_registry/dbmodels/__init__.py +0 -0
- mlflow/store/model_registry/dbmodels/models.py +206 -0
- mlflow/store/model_registry/file_store.py +1091 -0
- mlflow/store/model_registry/rest_store.py +481 -0
- mlflow/store/model_registry/sqlalchemy_store.py +1286 -0
- mlflow/store/tracking/__init__.py +23 -0
- mlflow/store/tracking/abstract_store.py +816 -0
- mlflow/store/tracking/dbmodels/__init__.py +0 -0
- mlflow/store/tracking/dbmodels/initial_models.py +243 -0
- mlflow/store/tracking/dbmodels/models.py +1073 -0
- mlflow/store/tracking/file_store.py +2438 -0
- mlflow/store/tracking/postgres_managed_identity.py +146 -0
- mlflow/store/tracking/rest_store.py +1131 -0
- mlflow/store/tracking/sqlalchemy_store.py +2785 -0
- mlflow/system_metrics/__init__.py +61 -0
- mlflow/system_metrics/metrics/__init__.py +0 -0
- mlflow/system_metrics/metrics/base_metrics_monitor.py +32 -0
- mlflow/system_metrics/metrics/cpu_monitor.py +23 -0
- mlflow/system_metrics/metrics/disk_monitor.py +21 -0
- mlflow/system_metrics/metrics/gpu_monitor.py +71 -0
- mlflow/system_metrics/metrics/network_monitor.py +34 -0
- mlflow/system_metrics/metrics/rocm_monitor.py +123 -0
- mlflow/system_metrics/system_metrics_monitor.py +198 -0
- mlflow/tracing/__init__.py +16 -0
- mlflow/tracing/assessment.py +356 -0
- mlflow/tracing/client.py +531 -0
- mlflow/tracing/config.py +125 -0
- mlflow/tracing/constant.py +105 -0
- mlflow/tracing/destination.py +81 -0
- mlflow/tracing/display/__init__.py +40 -0
- mlflow/tracing/display/display_handler.py +196 -0
- mlflow/tracing/export/async_export_queue.py +186 -0
- mlflow/tracing/export/inference_table.py +138 -0
- mlflow/tracing/export/mlflow_v3.py +137 -0
- mlflow/tracing/export/utils.py +70 -0
- mlflow/tracing/fluent.py +1417 -0
- mlflow/tracing/processor/base_mlflow.py +199 -0
- mlflow/tracing/processor/inference_table.py +175 -0
- mlflow/tracing/processor/mlflow_v3.py +47 -0
- mlflow/tracing/processor/otel.py +73 -0
- mlflow/tracing/provider.py +487 -0
- mlflow/tracing/trace_manager.py +200 -0
- mlflow/tracing/utils/__init__.py +616 -0
- mlflow/tracing/utils/artifact_utils.py +28 -0
- mlflow/tracing/utils/copy.py +55 -0
- mlflow/tracing/utils/environment.py +55 -0
- mlflow/tracing/utils/exception.py +21 -0
- mlflow/tracing/utils/once.py +35 -0
- mlflow/tracing/utils/otlp.py +63 -0
- mlflow/tracing/utils/processor.py +54 -0
- mlflow/tracing/utils/search.py +292 -0
- mlflow/tracing/utils/timeout.py +250 -0
- mlflow/tracing/utils/token.py +19 -0
- mlflow/tracing/utils/truncation.py +124 -0
- mlflow/tracing/utils/warning.py +76 -0
- mlflow/tracking/__init__.py +39 -0
- mlflow/tracking/_model_registry/__init__.py +1 -0
- mlflow/tracking/_model_registry/client.py +764 -0
- mlflow/tracking/_model_registry/fluent.py +853 -0
- mlflow/tracking/_model_registry/registry.py +67 -0
- mlflow/tracking/_model_registry/utils.py +251 -0
- mlflow/tracking/_tracking_service/__init__.py +0 -0
- mlflow/tracking/_tracking_service/client.py +883 -0
- mlflow/tracking/_tracking_service/registry.py +56 -0
- mlflow/tracking/_tracking_service/utils.py +275 -0
- mlflow/tracking/artifact_utils.py +179 -0
- mlflow/tracking/client.py +5900 -0
- mlflow/tracking/context/__init__.py +0 -0
- mlflow/tracking/context/abstract_context.py +35 -0
- mlflow/tracking/context/databricks_cluster_context.py +15 -0
- mlflow/tracking/context/databricks_command_context.py +15 -0
- mlflow/tracking/context/databricks_job_context.py +49 -0
- mlflow/tracking/context/databricks_notebook_context.py +41 -0
- mlflow/tracking/context/databricks_repo_context.py +43 -0
- mlflow/tracking/context/default_context.py +51 -0
- mlflow/tracking/context/git_context.py +32 -0
- mlflow/tracking/context/registry.py +98 -0
- mlflow/tracking/context/system_environment_context.py +15 -0
- mlflow/tracking/default_experiment/__init__.py +1 -0
- mlflow/tracking/default_experiment/abstract_context.py +43 -0
- mlflow/tracking/default_experiment/databricks_notebook_experiment_provider.py +44 -0
- mlflow/tracking/default_experiment/registry.py +75 -0
- mlflow/tracking/fluent.py +3595 -0
- mlflow/tracking/metric_value_conversion_utils.py +93 -0
- mlflow/tracking/multimedia.py +206 -0
- mlflow/tracking/registry.py +86 -0
- mlflow/tracking/request_auth/__init__.py +0 -0
- mlflow/tracking/request_auth/abstract_request_auth_provider.py +34 -0
- mlflow/tracking/request_auth/registry.py +60 -0
- mlflow/tracking/request_header/__init__.py +0 -0
- mlflow/tracking/request_header/abstract_request_header_provider.py +36 -0
- mlflow/tracking/request_header/databricks_request_header_provider.py +38 -0
- mlflow/tracking/request_header/default_request_header_provider.py +17 -0
- mlflow/tracking/request_header/registry.py +79 -0
- mlflow/transformers/__init__.py +2982 -0
- mlflow/transformers/flavor_config.py +258 -0
- mlflow/transformers/hub_utils.py +83 -0
- mlflow/transformers/llm_inference_utils.py +468 -0
- mlflow/transformers/model_io.py +301 -0
- mlflow/transformers/peft.py +51 -0
- mlflow/transformers/signature.py +183 -0
- mlflow/transformers/torch_utils.py +55 -0
- mlflow/types/__init__.py +21 -0
- mlflow/types/agent.py +270 -0
- mlflow/types/chat.py +240 -0
- mlflow/types/llm.py +935 -0
- mlflow/types/responses.py +139 -0
- mlflow/types/responses_helpers.py +416 -0
- mlflow/types/schema.py +1505 -0
- mlflow/types/type_hints.py +647 -0
- mlflow/types/utils.py +753 -0
- mlflow/utils/__init__.py +283 -0
- mlflow/utils/_capture_modules.py +256 -0
- mlflow/utils/_capture_transformers_modules.py +75 -0
- mlflow/utils/_spark_utils.py +201 -0
- mlflow/utils/_unity_catalog_oss_utils.py +97 -0
- mlflow/utils/_unity_catalog_utils.py +479 -0
- mlflow/utils/annotations.py +218 -0
- mlflow/utils/arguments_utils.py +16 -0
- mlflow/utils/async_logging/__init__.py +1 -0
- mlflow/utils/async_logging/async_artifacts_logging_queue.py +258 -0
- mlflow/utils/async_logging/async_logging_queue.py +366 -0
- mlflow/utils/async_logging/run_artifact.py +38 -0
- mlflow/utils/async_logging/run_batch.py +58 -0
- mlflow/utils/async_logging/run_operations.py +49 -0
- mlflow/utils/autologging_utils/__init__.py +737 -0
- mlflow/utils/autologging_utils/client.py +432 -0
- mlflow/utils/autologging_utils/config.py +33 -0
- mlflow/utils/autologging_utils/events.py +294 -0
- mlflow/utils/autologging_utils/logging_and_warnings.py +328 -0
- mlflow/utils/autologging_utils/metrics_queue.py +71 -0
- mlflow/utils/autologging_utils/safety.py +1104 -0
- mlflow/utils/autologging_utils/versioning.py +95 -0
- mlflow/utils/checkpoint_utils.py +206 -0
- mlflow/utils/class_utils.py +6 -0
- mlflow/utils/cli_args.py +257 -0
- mlflow/utils/conda.py +354 -0
- mlflow/utils/credentials.py +231 -0
- mlflow/utils/data_utils.py +17 -0
- mlflow/utils/databricks_utils.py +1436 -0
- mlflow/utils/docstring_utils.py +477 -0
- mlflow/utils/doctor.py +133 -0
- mlflow/utils/download_cloud_file_chunk.py +43 -0
- mlflow/utils/env_manager.py +16 -0
- mlflow/utils/env_pack.py +131 -0
- mlflow/utils/environment.py +1009 -0
- mlflow/utils/exception_utils.py +14 -0
- mlflow/utils/file_utils.py +978 -0
- mlflow/utils/git_utils.py +77 -0
- mlflow/utils/gorilla.py +797 -0
- mlflow/utils/import_hooks/__init__.py +363 -0
- mlflow/utils/lazy_load.py +51 -0
- mlflow/utils/logging_utils.py +168 -0
- mlflow/utils/mime_type_utils.py +58 -0
- mlflow/utils/mlflow_tags.py +103 -0
- mlflow/utils/model_utils.py +486 -0
- mlflow/utils/name_utils.py +346 -0
- mlflow/utils/nfs_on_spark.py +62 -0
- mlflow/utils/openai_utils.py +164 -0
- mlflow/utils/os.py +12 -0
- mlflow/utils/oss_registry_utils.py +29 -0
- mlflow/utils/plugins.py +17 -0
- mlflow/utils/process.py +182 -0
- mlflow/utils/promptlab_utils.py +146 -0
- mlflow/utils/proto_json_utils.py +743 -0
- mlflow/utils/pydantic_utils.py +54 -0
- mlflow/utils/request_utils.py +279 -0
- mlflow/utils/requirements_utils.py +704 -0
- mlflow/utils/rest_utils.py +673 -0
- mlflow/utils/search_logged_model_utils.py +127 -0
- mlflow/utils/search_utils.py +2111 -0
- mlflow/utils/secure_loading.py +221 -0
- mlflow/utils/security_validation.py +384 -0
- mlflow/utils/server_cli_utils.py +61 -0
- mlflow/utils/spark_utils.py +15 -0
- mlflow/utils/string_utils.py +138 -0
- mlflow/utils/thread_utils.py +63 -0
- mlflow/utils/time.py +54 -0
- mlflow/utils/timeout.py +42 -0
- mlflow/utils/uri.py +572 -0
- mlflow/utils/validation.py +662 -0
- mlflow/utils/virtualenv.py +458 -0
- mlflow/utils/warnings_utils.py +25 -0
- mlflow/utils/yaml_utils.py +179 -0
- mlflow/version.py +24 -0
@@ -0,0 +1,294 @@
|
|
1
|
+
import warnings
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
from mlflow.utils.autologging_utils import _logger
|
5
|
+
|
6
|
+
|
7
|
+
def _catch_exception(fn):
|
8
|
+
"""A decorator that catches exceptions thrown by the wrapped function and logs them."""
|
9
|
+
|
10
|
+
def wrapper(*args):
|
11
|
+
try:
|
12
|
+
fn(*args)
|
13
|
+
except Exception as e:
|
14
|
+
_logger.debug(f"Failed to log autologging event via '{fn}'. Exception: {e}")
|
15
|
+
|
16
|
+
return wrapper
|
17
|
+
|
18
|
+
|
19
|
+
class AutologgingEventLoggerWrapper:
|
20
|
+
"""
|
21
|
+
A wrapper around AutologgingEventLogger for DRY:
|
22
|
+
- Store common arguments to avoid passing them to each logger method
|
23
|
+
- Catches exceptions thrown by the logger and logs them
|
24
|
+
|
25
|
+
NB: We could not modify the AutologgingEventLogger class directly because
|
26
|
+
it is used in Databricks code base as well.
|
27
|
+
"""
|
28
|
+
|
29
|
+
def __init__(self, session, destination: Any, function_name: str):
|
30
|
+
self._session = session
|
31
|
+
self._destination = destination
|
32
|
+
self._function_name = function_name
|
33
|
+
self._logger = AutologgingEventLogger.get_logger()
|
34
|
+
|
35
|
+
@_catch_exception
|
36
|
+
def log_patch_function_start(self, args, kwargs):
|
37
|
+
self._logger.log_patch_function_start(
|
38
|
+
self._session, self._destination, self._function_name, args, kwargs
|
39
|
+
)
|
40
|
+
|
41
|
+
@_catch_exception
|
42
|
+
def log_patch_function_success(self, args, kwargs):
|
43
|
+
self._logger.log_patch_function_success(
|
44
|
+
self._session, self._destination, self._function_name, args, kwargs
|
45
|
+
)
|
46
|
+
|
47
|
+
@_catch_exception
|
48
|
+
def log_patch_function_error(self, args, kwargs, exception):
|
49
|
+
self._logger.log_patch_function_error(
|
50
|
+
self._session, self._destination, self._function_name, args, kwargs, exception
|
51
|
+
)
|
52
|
+
|
53
|
+
@_catch_exception
|
54
|
+
def log_original_function_start(self, args, kwargs):
|
55
|
+
self._logger.log_original_function_start(
|
56
|
+
self._session, self._destination, self._function_name, args, kwargs
|
57
|
+
)
|
58
|
+
|
59
|
+
@_catch_exception
|
60
|
+
def log_original_function_success(self, args, kwargs):
|
61
|
+
self._logger.log_original_function_success(
|
62
|
+
self._session, self._destination, self._function_name, args, kwargs
|
63
|
+
)
|
64
|
+
|
65
|
+
@_catch_exception
|
66
|
+
def log_original_function_error(self, args, kwargs, exception):
|
67
|
+
self._logger.log_original_function_error(
|
68
|
+
self._session, self._destination, self._function_name, args, kwargs, exception
|
69
|
+
)
|
70
|
+
|
71
|
+
|
72
|
+
class AutologgingEventLogger:
|
73
|
+
"""
|
74
|
+
Provides instrumentation hooks for important autologging lifecycle events, including:
|
75
|
+
|
76
|
+
- Calls to `mlflow.autolog()` APIs
|
77
|
+
- Calls to patched APIs with associated termination states
|
78
|
+
("success" and "failure due to error")
|
79
|
+
- Calls to original / underlying APIs made by patched function code with
|
80
|
+
associated termination states ("success" and "failure due to error")
|
81
|
+
|
82
|
+
Default implementations are included for each of these hooks, which emit corresponding
|
83
|
+
DEBUG-level logging statements. Developers can provide their own hook implementations
|
84
|
+
by subclassing `AutologgingEventLogger` and calling the static
|
85
|
+
`AutologgingEventLogger.set_logger()` method to supply a new event logger instance.
|
86
|
+
|
87
|
+
Callers fetch the configured logger via `AutologgingEventLogger.get_logger()`
|
88
|
+
and invoke one or more hooks (e.g., `AutologgingEventLogger.get_logger().log_autolog_called()`).
|
89
|
+
"""
|
90
|
+
|
91
|
+
_event_logger = None
|
92
|
+
|
93
|
+
@staticmethod
|
94
|
+
def get_logger():
|
95
|
+
"""Fetches the configured `AutologgingEventLogger` instance for logging.
|
96
|
+
|
97
|
+
Returns:
|
98
|
+
The instance of `AutologgingEventLogger` specified via `set_logger`
|
99
|
+
(if configured) or the default implementation of `AutologgingEventLogger`
|
100
|
+
(if a logger was not configured via `set_logger`).
|
101
|
+
|
102
|
+
"""
|
103
|
+
return AutologgingEventLogger._event_logger or AutologgingEventLogger()
|
104
|
+
|
105
|
+
@staticmethod
|
106
|
+
def set_logger(logger):
|
107
|
+
"""Configures the `AutologgingEventLogger` instance for logging. This instance
|
108
|
+
is exposed via `AutologgingEventLogger.get_logger()` and callers use it to invoke
|
109
|
+
logging hooks (e.g., AutologgingEventLogger.get_logger().log_autolog_called()).
|
110
|
+
|
111
|
+
Args:
|
112
|
+
logger: The instance of `AutologgingEventLogger` to use when invoking logging hooks.
|
113
|
+
|
114
|
+
"""
|
115
|
+
AutologgingEventLogger._event_logger = logger
|
116
|
+
|
117
|
+
def log_autolog_called(self, integration, call_args, call_kwargs):
|
118
|
+
"""Called when the `autolog()` method for an autologging integration
|
119
|
+
is invoked (e.g., when a user invokes `mlflow.sklearn.autolog()`)
|
120
|
+
|
121
|
+
Args:
|
122
|
+
integration: The autologging integration for which `autolog()` was called.
|
123
|
+
call_args: **DEPRECATED** The positional arguments passed to the `autolog()` call.
|
124
|
+
This field is empty in MLflow > 1.13.1; all arguments are passed in
|
125
|
+
keyword form via `call_kwargs`.
|
126
|
+
call_kwargs: The arguments passed to the `autolog()` call in keyword form.
|
127
|
+
Any positional arguments should also be converted to keyword form
|
128
|
+
and passed via `call_kwargs`.
|
129
|
+
"""
|
130
|
+
if len(call_args) > 0:
|
131
|
+
warnings.warn(
|
132
|
+
f"Received {len(call_args)} positional arguments via `call_args`. `call_args` is"
|
133
|
+
" deprecated in MLflow > 1.13.1, and all arguments should be passed"
|
134
|
+
" in keyword form via `call_kwargs`.",
|
135
|
+
category=DeprecationWarning,
|
136
|
+
stacklevel=2,
|
137
|
+
)
|
138
|
+
_logger.debug(
|
139
|
+
"Called autolog() method for %s autologging with args '%s' and kwargs '%s'",
|
140
|
+
integration,
|
141
|
+
call_args,
|
142
|
+
call_kwargs,
|
143
|
+
)
|
144
|
+
|
145
|
+
def log_patch_function_start(self, session, patch_obj, function_name, call_args, call_kwargs):
|
146
|
+
"""Called upon invocation of a patched API associated with an autologging integration
|
147
|
+
(e.g., `sklearn.linear_model.LogisticRegression.fit()`).
|
148
|
+
|
149
|
+
Args:
|
150
|
+
session: The `AutologgingSession` associated with the patched API call.
|
151
|
+
patch_obj: The object (class, module, etc) on which the patched API was called.
|
152
|
+
function_name: The name of the patched API that was called.
|
153
|
+
call_args: The positional arguments passed to the patched API call.
|
154
|
+
call_kwargs: The keyword arguments passed to the patched API call.
|
155
|
+
|
156
|
+
"""
|
157
|
+
_logger.debug(
|
158
|
+
"Invoked patched API '%s.%s' for %s autologging with args '%s' and kwargs '%s'",
|
159
|
+
patch_obj,
|
160
|
+
function_name,
|
161
|
+
session.integration,
|
162
|
+
call_args,
|
163
|
+
call_kwargs,
|
164
|
+
)
|
165
|
+
|
166
|
+
def log_patch_function_success(self, session, patch_obj, function_name, call_args, call_kwargs):
|
167
|
+
"""
|
168
|
+
Called upon successful termination of a patched API associated with an autologging
|
169
|
+
integration (e.g., `sklearn.linear_model.LogisticRegression.fit()`).
|
170
|
+
|
171
|
+
Args:
|
172
|
+
session: The `AutologgingSession` associated with the patched API call.
|
173
|
+
patch_obj: The object (class, module, etc) on which the patched API was called.
|
174
|
+
function_name: The name of the patched API that was called.
|
175
|
+
call_args: The positional arguments passed to the patched API call.
|
176
|
+
call_kwargs: The keyword arguments passed to the patched API call.
|
177
|
+
"""
|
178
|
+
_logger.debug(
|
179
|
+
"Patched API call '%s.%s' for %s autologging completed successfully. Patched ML"
|
180
|
+
" API was called with args '%s' and kwargs '%s'",
|
181
|
+
patch_obj,
|
182
|
+
function_name,
|
183
|
+
session.integration,
|
184
|
+
call_args,
|
185
|
+
call_kwargs,
|
186
|
+
)
|
187
|
+
|
188
|
+
def log_patch_function_error(
|
189
|
+
self, session, patch_obj, function_name, call_args, call_kwargs, exception
|
190
|
+
):
|
191
|
+
"""Called when execution of a patched API associated with an autologging integration
|
192
|
+
(e.g., `sklearn.linear_model.LogisticRegression.fit()`) terminates with an exception.
|
193
|
+
|
194
|
+
Args:
|
195
|
+
session: The `AutologgingSession` associated with the patched API call.
|
196
|
+
patch_obj: The object (class, module, etc) on which the patched API was called.
|
197
|
+
function_name: The name of the patched API that was called.
|
198
|
+
call_args: The positional arguments passed to the patched API call.
|
199
|
+
call_kwargs: The keyword arguments passed to the patched API call.
|
200
|
+
exception: The exception that caused the patched API call to terminate.
|
201
|
+
"""
|
202
|
+
_logger.debug(
|
203
|
+
"Patched API call '%s.%s' for %s autologging threw exception. Patched API was"
|
204
|
+
" called with args '%s' and kwargs '%s'. Exception: %s",
|
205
|
+
patch_obj,
|
206
|
+
function_name,
|
207
|
+
session.integration,
|
208
|
+
call_args,
|
209
|
+
call_kwargs,
|
210
|
+
exception,
|
211
|
+
)
|
212
|
+
|
213
|
+
def log_original_function_start(
|
214
|
+
self, session, patch_obj, function_name, call_args, call_kwargs
|
215
|
+
):
|
216
|
+
"""
|
217
|
+
Called during the execution of a patched API associated with an autologging integration
|
218
|
+
when the original / underlying API is invoked. For example, this is called when
|
219
|
+
a patched implementation of `sklearn.linear_model.LogisticRegression.fit()` invokes
|
220
|
+
the original implementation of `sklearn.linear_model.LogisticRegression.fit()`.
|
221
|
+
|
222
|
+
Args:
|
223
|
+
session: The `AutologgingSession` associated with the patched API call.
|
224
|
+
patch_obj: The object (class, module, etc) on which the original API was called.
|
225
|
+
function_name: The name of the original API that was called.
|
226
|
+
call_args: The positional arguments passed to the original API call.
|
227
|
+
call_kwargs: The keyword arguments passed to the original API call.
|
228
|
+
"""
|
229
|
+
_logger.debug(
|
230
|
+
"Original function invoked during execution of patched API '%s.%s' for %s"
|
231
|
+
" autologging. Original function was invoked with args '%s' and kwargs '%s'",
|
232
|
+
patch_obj,
|
233
|
+
function_name,
|
234
|
+
session.integration,
|
235
|
+
call_args,
|
236
|
+
call_kwargs,
|
237
|
+
)
|
238
|
+
|
239
|
+
def log_original_function_success(
|
240
|
+
self, session, patch_obj, function_name, call_args, call_kwargs
|
241
|
+
):
|
242
|
+
"""Called during the execution of a patched API associated with an autologging integration
|
243
|
+
when the original / underlying API invocation terminates successfully. For example,
|
244
|
+
when a patched implementation of `sklearn.linear_model.LogisticRegression.fit()` invokes the
|
245
|
+
original / underlying implementation of `LogisticRegression.fit()`, then this function is
|
246
|
+
called if the original / underlying implementation successfully completes.
|
247
|
+
|
248
|
+
Args:
|
249
|
+
session: The `AutologgingSession` associated with the patched API call.
|
250
|
+
patch_obj: The object (class, module, etc) on which the original API was called.
|
251
|
+
function_name: The name of the original API that was called.
|
252
|
+
call_args: The positional arguments passed to the original API call.
|
253
|
+
call_kwargs: The keyword arguments passed to the original API call.
|
254
|
+
|
255
|
+
"""
|
256
|
+
_logger.debug(
|
257
|
+
"Original function invocation completed successfully during execution of patched API"
|
258
|
+
" call '%s.%s' for %s autologging. Original function was invoked with with"
|
259
|
+
" args '%s' and kwargs '%s'",
|
260
|
+
patch_obj,
|
261
|
+
function_name,
|
262
|
+
session.integration,
|
263
|
+
call_args,
|
264
|
+
call_kwargs,
|
265
|
+
)
|
266
|
+
|
267
|
+
def log_original_function_error(
|
268
|
+
self, session, patch_obj, function_name, call_args, call_kwargs, exception
|
269
|
+
):
|
270
|
+
"""Called during the execution of a patched API associated with an autologging integration
|
271
|
+
when the original / underlying API invocation terminates with an error. For example,
|
272
|
+
when a patched implementation of `sklearn.linear_model.LogisticRegression.fit()` invokes the
|
273
|
+
original / underlying implementation of `LogisticRegression.fit()`, then this function is
|
274
|
+
called if the original / underlying implementation terminates with an exception.
|
275
|
+
|
276
|
+
Args:
|
277
|
+
session: The `AutologgingSession` associated with the patched API call.
|
278
|
+
patch_obj: The object (class, module, etc) on which the original API was called.
|
279
|
+
function_name: The name of the original API that was called.
|
280
|
+
call_args: The positional arguments passed to the original API call.
|
281
|
+
call_kwargs: The keyword arguments passed to the original API call.
|
282
|
+
exception: The exception that caused the original API call to terminate.
|
283
|
+
"""
|
284
|
+
_logger.debug(
|
285
|
+
"Original function invocation threw exception during execution of patched"
|
286
|
+
" API call '%s.%s' for %s autologging. Original function was invoked with"
|
287
|
+
" args '%s' and kwargs '%s'. Exception: %s",
|
288
|
+
patch_obj,
|
289
|
+
function_name,
|
290
|
+
session.integration,
|
291
|
+
call_args,
|
292
|
+
call_kwargs,
|
293
|
+
exception,
|
294
|
+
)
|
@@ -0,0 +1,328 @@
|
|
1
|
+
import os
|
2
|
+
import warnings
|
3
|
+
from pathlib import Path
|
4
|
+
from threading import RLock
|
5
|
+
from threading import get_ident as get_current_thread_id
|
6
|
+
|
7
|
+
import mlflow
|
8
|
+
from mlflow.utils import logging_utils
|
9
|
+
|
10
|
+
ORIGINAL_SHOWWARNING = warnings.showwarning
|
11
|
+
|
12
|
+
|
13
|
+
class _WarningsController:
|
14
|
+
"""
|
15
|
+
Provides threadsafe utilities to modify warning behavior for MLflow autologging, including:
|
16
|
+
|
17
|
+
- Global disablement of MLflow warnings across all threads
|
18
|
+
- Global rerouting of MLflow warnings to an MLflow event logger (i.e. `logger.warning()`)
|
19
|
+
across all threads
|
20
|
+
- Disablement of non-MLflow warnings for the current thread
|
21
|
+
- Rerouting of non-MLflow warnings to an MLflow event logger for the current thread
|
22
|
+
"""
|
23
|
+
|
24
|
+
def __init__(self):
|
25
|
+
self._mlflow_root_path = Path(os.path.dirname(mlflow.__file__)).resolve()
|
26
|
+
self._state_lock = RLock()
|
27
|
+
|
28
|
+
self._did_patch_showwarning = False
|
29
|
+
|
30
|
+
self._disabled_threads = set()
|
31
|
+
self._rerouted_threads = set()
|
32
|
+
self._mlflow_warnings_disabled_globally = False
|
33
|
+
self._mlflow_warnings_rerouted_to_event_logs = False
|
34
|
+
|
35
|
+
def _patched_showwarning(self, message, category, filename, lineno, *args, **kwargs):
|
36
|
+
"""
|
37
|
+
A patched implementation of `warnings.showwarning` that enforces the warning configuration
|
38
|
+
options configured on the controller (e.g. rerouting or disablement of MLflow warnings,
|
39
|
+
disablement of all warnings for the current thread).
|
40
|
+
|
41
|
+
Note that reassigning `warnings.showwarning` is the standard / recommended approach for
|
42
|
+
modifying warning message display behaviors. For reference, see
|
43
|
+
https://docs.python.org/3/library/warnings.html#warnings.showwarning
|
44
|
+
"""
|
45
|
+
# NB: We explicitly avoid blocking on the `self._state_lock` lock during `showwarning`
|
46
|
+
# to so that threads don't have to execute serially whenever they emit warnings with
|
47
|
+
# `warnings.warn()`. We only lock during configuration changes to ensure that
|
48
|
+
# `warnings.showwarning` is patched or unpatched at the correct times.
|
49
|
+
|
50
|
+
from mlflow.utils.autologging_utils import _logger
|
51
|
+
|
52
|
+
# If the warning's source file is contained within the MLflow package's base
|
53
|
+
# directory, it is an MLflow warning and should be emitted via `logger.warning`
|
54
|
+
warning_source_path = Path(filename).resolve()
|
55
|
+
is_mlflow_warning = self._mlflow_root_path in warning_source_path.parents
|
56
|
+
curr_thread = get_current_thread_id()
|
57
|
+
|
58
|
+
if (curr_thread in self._disabled_threads) or (
|
59
|
+
is_mlflow_warning and self._mlflow_warnings_disabled_globally
|
60
|
+
):
|
61
|
+
return
|
62
|
+
elif (curr_thread in self._rerouted_threads and not is_mlflow_warning) or (
|
63
|
+
is_mlflow_warning and self._mlflow_warnings_rerouted_to_event_logs
|
64
|
+
):
|
65
|
+
_logger.warning(
|
66
|
+
'MLflow autologging encountered a warning: "%s:%d: %s: %s"',
|
67
|
+
filename,
|
68
|
+
lineno,
|
69
|
+
category.__name__,
|
70
|
+
message,
|
71
|
+
)
|
72
|
+
else:
|
73
|
+
ORIGINAL_SHOWWARNING(message, category, filename, lineno, *args, **kwargs)
|
74
|
+
|
75
|
+
def _should_patch_showwarning(self):
|
76
|
+
return (
|
77
|
+
(len(self._disabled_threads) > 0)
|
78
|
+
or (len(self._rerouted_threads) > 0)
|
79
|
+
or self._mlflow_warnings_disabled_globally
|
80
|
+
or self._mlflow_warnings_rerouted_to_event_logs
|
81
|
+
)
|
82
|
+
|
83
|
+
def _modify_patch_state_if_necessary(self):
|
84
|
+
"""
|
85
|
+
Patches or unpatches `warnings.showwarning` if necessary, as determined by:
|
86
|
+
- Whether or not `warnings.showwarning` is already patched
|
87
|
+
- Whether or not any custom warning state has been configured on the warnings
|
88
|
+
controller (i.e. disablement or rerouting of certain warnings globally or for a
|
89
|
+
particular thread)
|
90
|
+
|
91
|
+
Note that reassigning `warnings.showwarning` is the standard / recommended approach for
|
92
|
+
modifying warning message display behaviors. For reference, see
|
93
|
+
https://docs.python.org/3/library/warnings.html#warnings.showwarning
|
94
|
+
"""
|
95
|
+
with self._state_lock:
|
96
|
+
if self._should_patch_showwarning() and not self._did_patch_showwarning:
|
97
|
+
# NB: guard to prevent patching an instance of a patch
|
98
|
+
if warnings.showwarning != self._patched_showwarning:
|
99
|
+
warnings.showwarning = self._patched_showwarning
|
100
|
+
self._did_patch_showwarning = True
|
101
|
+
elif not self._should_patch_showwarning() and self._did_patch_showwarning:
|
102
|
+
# NB: only unpatch iff the patched function is active
|
103
|
+
if warnings.showwarning == self._patched_showwarning:
|
104
|
+
warnings.showwarning = ORIGINAL_SHOWWARNING
|
105
|
+
self._did_patch_showwarning = False
|
106
|
+
|
107
|
+
def set_mlflow_warnings_disablement_state_globally(self, disabled=True):
|
108
|
+
"""Disables (or re-enables) MLflow warnings globally across all threads.
|
109
|
+
|
110
|
+
Args:
|
111
|
+
disabled: If `True`, disables MLflow warnings globally across all threads.
|
112
|
+
If `False`, enables MLflow warnings globally across all threads.
|
113
|
+
|
114
|
+
"""
|
115
|
+
with self._state_lock:
|
116
|
+
self._mlflow_warnings_disabled_globally = disabled
|
117
|
+
self._modify_patch_state_if_necessary()
|
118
|
+
|
119
|
+
def set_mlflow_warnings_rerouting_state_globally(self, rerouted=True):
|
120
|
+
"""
|
121
|
+
Enables (or disables) rerouting of MLflow warnings to an MLflow event logger with level
|
122
|
+
WARNING (e.g. `logger.warning()`) globally across all threads.
|
123
|
+
|
124
|
+
Args:
|
125
|
+
rerouted: If `True`, enables MLflow warning rerouting globally across all threads.
|
126
|
+
If `False`, disables MLflow warning rerouting globally across all threads.
|
127
|
+
"""
|
128
|
+
with self._state_lock:
|
129
|
+
self._mlflow_warnings_rerouted_to_event_logs = rerouted
|
130
|
+
self._modify_patch_state_if_necessary()
|
131
|
+
|
132
|
+
def set_non_mlflow_warnings_disablement_state_for_current_thread(self, disabled=True):
|
133
|
+
"""Disables (or re-enables) non-MLflow warnings for the current thread.
|
134
|
+
|
135
|
+
Args:
|
136
|
+
disabled: If `True`, disables non-MLflow warnings for the current thread. If `False`,
|
137
|
+
enables non-MLflow warnings for the current thread. non-MLflow warning
|
138
|
+
behavior in other threads is unaffected.
|
139
|
+
|
140
|
+
"""
|
141
|
+
with self._state_lock:
|
142
|
+
if disabled:
|
143
|
+
self._disabled_threads.add(get_current_thread_id())
|
144
|
+
else:
|
145
|
+
self._disabled_threads.discard(get_current_thread_id())
|
146
|
+
self._modify_patch_state_if_necessary()
|
147
|
+
|
148
|
+
def set_non_mlflow_warnings_rerouting_state_for_current_thread(self, rerouted=True):
|
149
|
+
"""Enables (or disables) rerouting of non-MLflow warnings to an MLflow event logger with
|
150
|
+
level WARNING (e.g. `logger.warning()`) for the current thread.
|
151
|
+
|
152
|
+
Args:
|
153
|
+
rerouted: If `True`, enables non-MLflow warning rerouting for the current thread.
|
154
|
+
If `False`, disables non-MLflow warning rerouting for the current thread.
|
155
|
+
non-MLflow warning behavior in other threads is unaffected.
|
156
|
+
|
157
|
+
"""
|
158
|
+
with self._state_lock:
|
159
|
+
if rerouted:
|
160
|
+
self._rerouted_threads.add(get_current_thread_id())
|
161
|
+
else:
|
162
|
+
self._rerouted_threads.discard(get_current_thread_id())
|
163
|
+
self._modify_patch_state_if_necessary()
|
164
|
+
|
165
|
+
def get_warnings_disablement_state_for_current_thread(self):
|
166
|
+
"""
|
167
|
+
Returns:
|
168
|
+
True if non-MLflow warnings are disabled for the current thread. False otherwise.
|
169
|
+
"""
|
170
|
+
return get_current_thread_id() in self._disabled_threads
|
171
|
+
|
172
|
+
def get_warnings_rerouting_state_for_current_thread(self):
|
173
|
+
"""
|
174
|
+
Returns:
|
175
|
+
True if non-MLflow warnings are rerouted to an MLflow event logger with level
|
176
|
+
WARNING for the current thread. False otherwise.
|
177
|
+
"""
|
178
|
+
return get_current_thread_id() in self._rerouted_threads
|
179
|
+
|
180
|
+
|
181
|
+
_WARNINGS_CONTROLLER = _WarningsController()
|
182
|
+
|
183
|
+
|
184
|
+
class NonMlflowWarningsBehaviorForCurrentThread:
|
185
|
+
"""
|
186
|
+
Context manager that modifies the behavior of non-MLflow warnings upon entry, according to the
|
187
|
+
specified parameters.
|
188
|
+
|
189
|
+
Args:
|
190
|
+
disable_warnings: If `True`, disable (mutate & discard) non-MLflow warnings. If `False`,
|
191
|
+
do not disable non-MLflow warnings.
|
192
|
+
reroute_warnings: If `True`, reroute non-MLflow warnings to an MLflow event logger with
|
193
|
+
level WARNING. If `False`, do not reroute non-MLflow warnings.
|
194
|
+
"""
|
195
|
+
|
196
|
+
def __init__(self, disable_warnings, reroute_warnings):
|
197
|
+
self._disable_warnings = disable_warnings
|
198
|
+
self._reroute_warnings = reroute_warnings
|
199
|
+
self._prev_disablement_state = None
|
200
|
+
self._prev_rerouting_state = None
|
201
|
+
|
202
|
+
def __enter__(self):
|
203
|
+
self._enter_impl()
|
204
|
+
return self
|
205
|
+
|
206
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
207
|
+
self._exit_impl(exc_type, exc_val, exc_tb)
|
208
|
+
|
209
|
+
async def __aenter__(self):
|
210
|
+
self._enter_impl()
|
211
|
+
return self
|
212
|
+
|
213
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
214
|
+
self._exit_impl(exc_type, exc_val, exc_tb)
|
215
|
+
|
216
|
+
def _enter_impl(self):
|
217
|
+
self._prev_disablement_state = (
|
218
|
+
_WARNINGS_CONTROLLER.get_warnings_disablement_state_for_current_thread()
|
219
|
+
)
|
220
|
+
self._prev_rerouting_state = (
|
221
|
+
_WARNINGS_CONTROLLER.get_warnings_rerouting_state_for_current_thread()
|
222
|
+
)
|
223
|
+
try:
|
224
|
+
_WARNINGS_CONTROLLER.set_non_mlflow_warnings_disablement_state_for_current_thread(
|
225
|
+
disabled=self._disable_warnings
|
226
|
+
)
|
227
|
+
_WARNINGS_CONTROLLER.set_non_mlflow_warnings_rerouting_state_for_current_thread(
|
228
|
+
rerouted=self._reroute_warnings
|
229
|
+
)
|
230
|
+
except Exception:
|
231
|
+
pass
|
232
|
+
|
233
|
+
def _exit_impl(self, *args, **kwargs):
|
234
|
+
_WARNINGS_CONTROLLER.set_non_mlflow_warnings_disablement_state_for_current_thread(
|
235
|
+
disabled=self._prev_disablement_state
|
236
|
+
)
|
237
|
+
_WARNINGS_CONTROLLER.set_non_mlflow_warnings_rerouting_state_for_current_thread(
|
238
|
+
rerouted=self._prev_rerouting_state
|
239
|
+
)
|
240
|
+
|
241
|
+
|
242
|
+
class MlflowEventsAndWarningsBehaviorGlobally:
|
243
|
+
"""
|
244
|
+
Threadsafe context manager that modifies the behavior of MLflow event logging statements
|
245
|
+
and MLflow warnings upon entry, according to the specified parameters. Modifications are
|
246
|
+
applied globally across all threads and are not reverted until all threads that have made
|
247
|
+
a particular modification have exited the context.
|
248
|
+
|
249
|
+
Args:
|
250
|
+
disable_event_logs: If `True`, disable (mute & discard) MLflow event logging statements.
|
251
|
+
If `False`, do not disable MLflow event logging statements.
|
252
|
+
disable_warnings: If `True`, disable (mutate & discard) MLflow warnings. If `False`,
|
253
|
+
do not disable MLflow warnings.
|
254
|
+
reroute_warnings: If `True`, reroute MLflow warnings to an MLflow event logger with
|
255
|
+
level WARNING. If `False`, do not reroute MLflow warnings.
|
256
|
+
|
257
|
+
"""
|
258
|
+
|
259
|
+
_lock = RLock()
|
260
|
+
_disable_event_logs_count = 0
|
261
|
+
_disable_warnings_count = 0
|
262
|
+
_reroute_warnings_count = 0
|
263
|
+
|
264
|
+
def __init__(self, disable_event_logs, disable_warnings, reroute_warnings):
|
265
|
+
self._disable_event_logs = disable_event_logs
|
266
|
+
self._disable_warnings = disable_warnings
|
267
|
+
self._reroute_warnings = reroute_warnings
|
268
|
+
|
269
|
+
def __enter__(self):
|
270
|
+
self._enter_impl()
|
271
|
+
return self
|
272
|
+
|
273
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
274
|
+
self._exit_impl(exc_type, exc_val, exc_tb)
|
275
|
+
|
276
|
+
async def __aenter__(self):
|
277
|
+
self._enter_impl()
|
278
|
+
return self
|
279
|
+
|
280
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
281
|
+
self._exit_impl(exc_type, exc_val, exc_tb)
|
282
|
+
|
283
|
+
def _enter_impl(self):
|
284
|
+
try:
|
285
|
+
with MlflowEventsAndWarningsBehaviorGlobally._lock:
|
286
|
+
if self._disable_event_logs:
|
287
|
+
if MlflowEventsAndWarningsBehaviorGlobally._disable_event_logs_count <= 0:
|
288
|
+
logging_utils.disable_logging()
|
289
|
+
MlflowEventsAndWarningsBehaviorGlobally._disable_event_logs_count += 1
|
290
|
+
|
291
|
+
if self._disable_warnings:
|
292
|
+
if MlflowEventsAndWarningsBehaviorGlobally._disable_warnings_count <= 0:
|
293
|
+
_WARNINGS_CONTROLLER.set_mlflow_warnings_disablement_state_globally(
|
294
|
+
disabled=True
|
295
|
+
)
|
296
|
+
MlflowEventsAndWarningsBehaviorGlobally._disable_warnings_count += 1
|
297
|
+
|
298
|
+
if self._reroute_warnings:
|
299
|
+
if MlflowEventsAndWarningsBehaviorGlobally._reroute_warnings_count <= 0:
|
300
|
+
_WARNINGS_CONTROLLER.set_mlflow_warnings_rerouting_state_globally(
|
301
|
+
rerouted=True
|
302
|
+
)
|
303
|
+
MlflowEventsAndWarningsBehaviorGlobally._reroute_warnings_count += 1
|
304
|
+
except Exception:
|
305
|
+
pass
|
306
|
+
|
307
|
+
def _exit_impl(self, *args, **kwargs):
|
308
|
+
try:
|
309
|
+
with MlflowEventsAndWarningsBehaviorGlobally._lock:
|
310
|
+
if self._disable_event_logs:
|
311
|
+
MlflowEventsAndWarningsBehaviorGlobally._disable_event_logs_count -= 1
|
312
|
+
if self._disable_warnings:
|
313
|
+
MlflowEventsAndWarningsBehaviorGlobally._disable_warnings_count -= 1
|
314
|
+
if self._reroute_warnings:
|
315
|
+
MlflowEventsAndWarningsBehaviorGlobally._reroute_warnings_count -= 1
|
316
|
+
|
317
|
+
if MlflowEventsAndWarningsBehaviorGlobally._disable_event_logs_count <= 0:
|
318
|
+
logging_utils.enable_logging()
|
319
|
+
if MlflowEventsAndWarningsBehaviorGlobally._disable_warnings_count <= 0:
|
320
|
+
_WARNINGS_CONTROLLER.set_mlflow_warnings_disablement_state_globally(
|
321
|
+
disabled=False
|
322
|
+
)
|
323
|
+
if MlflowEventsAndWarningsBehaviorGlobally._reroute_warnings_count <= 0:
|
324
|
+
_WARNINGS_CONTROLLER.set_mlflow_warnings_rerouting_state_globally(
|
325
|
+
rerouted=False
|
326
|
+
)
|
327
|
+
except Exception:
|
328
|
+
pass
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import concurrent.futures
|
2
|
+
from threading import RLock
|
3
|
+
|
4
|
+
from mlflow.entities import Metric
|
5
|
+
from mlflow.tracking.client import MlflowClient
|
6
|
+
|
7
|
+
_metrics_queue_lock = RLock()
|
8
|
+
_metrics_queue = []
|
9
|
+
_thread_pool = concurrent.futures.ThreadPoolExecutor(
|
10
|
+
max_workers=1, thread_name_prefix="MlflowMetricsQueue"
|
11
|
+
)
|
12
|
+
|
13
|
+
_MAX_METRIC_QUEUE_SIZE = 500
|
14
|
+
|
15
|
+
|
16
|
+
def _assoc_list_to_map(lst):
|
17
|
+
"""
|
18
|
+
Convert an association list to a dictionary.
|
19
|
+
"""
|
20
|
+
d = {}
|
21
|
+
for run_id, metric in lst:
|
22
|
+
d[run_id] = d[run_id] + [metric] if run_id in d else [metric]
|
23
|
+
return d
|
24
|
+
|
25
|
+
|
26
|
+
def flush_metrics_queue():
|
27
|
+
"""Flush the metric queue and log contents in batches to MLflow.
|
28
|
+
|
29
|
+
Queue is divided into batches according to run id.
|
30
|
+
"""
|
31
|
+
try:
|
32
|
+
# Multiple queue flushes may be scheduled simultaneously on different threads
|
33
|
+
# (e.g., if the queue is at its flush threshold and several more items
|
34
|
+
# are added before a flush occurs). For correctness and efficiency, only one such
|
35
|
+
# flush operation should proceed; all others are redundant and should be dropped
|
36
|
+
acquired_lock = _metrics_queue_lock.acquire(blocking=False)
|
37
|
+
if acquired_lock:
|
38
|
+
client = MlflowClient()
|
39
|
+
# For thread safety and to avoid modifying a list while iterating over it, we record a
|
40
|
+
# separate list of the items being flushed and remove each one from the metric queue,
|
41
|
+
# rather than clearing the metric queue or reassigning it (clearing / reassigning is
|
42
|
+
# dangerous because we don't block threads from adding to the queue while a flush is
|
43
|
+
# in progress)
|
44
|
+
snapshot = _metrics_queue[:]
|
45
|
+
for item in snapshot:
|
46
|
+
_metrics_queue.remove(item)
|
47
|
+
|
48
|
+
metrics_by_run = _assoc_list_to_map(snapshot)
|
49
|
+
for run_id, metrics in metrics_by_run.items():
|
50
|
+
client.log_batch(run_id, metrics=metrics, params=[], tags=[])
|
51
|
+
finally:
|
52
|
+
if acquired_lock:
|
53
|
+
_metrics_queue_lock.release()
|
54
|
+
|
55
|
+
|
56
|
+
def add_to_metrics_queue(key, value, step, time, run_id):
|
57
|
+
"""Add a metric to the metric queue.
|
58
|
+
|
59
|
+
Flush the queue if it exceeds max size.
|
60
|
+
|
61
|
+
Args:
|
62
|
+
key: string, the metrics key,
|
63
|
+
value: float, the metrics value.
|
64
|
+
step: int, the step of current metric.
|
65
|
+
time: int, the timestamp of current metric.
|
66
|
+
run_id: string, the run id of the associated mlflow run.
|
67
|
+
"""
|
68
|
+
met = Metric(key=key, value=value, timestamp=time, step=step)
|
69
|
+
_metrics_queue.append((run_id, met))
|
70
|
+
if len(_metrics_queue) > _MAX_METRIC_QUEUE_SIZE:
|
71
|
+
_thread_pool.submit(flush_metrics_queue)
|