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,16 @@
|
|
1
|
+
import inspect
|
2
|
+
|
3
|
+
|
4
|
+
def _get_arg_names(f):
|
5
|
+
"""Get the argument names of a function.
|
6
|
+
|
7
|
+
Args:
|
8
|
+
f: A function.
|
9
|
+
|
10
|
+
Returns:
|
11
|
+
A list of argument names.
|
12
|
+
|
13
|
+
"""
|
14
|
+
# `inspect.getargspec` or `inspect.getfullargspec` doesn't work properly for a wrapped function.
|
15
|
+
# See https://hynek.me/articles/decorators#mangled-signatures for details.
|
16
|
+
return list(inspect.signature(f).parameters.keys())
|
@@ -0,0 +1 @@
|
|
1
|
+
from mlflow.utils.async_logging import run_operations # noqa: F401
|
@@ -0,0 +1,258 @@
|
|
1
|
+
"""
|
2
|
+
Defines an AsyncArtifactsLoggingQueue that provides async fashion artifact writes using
|
3
|
+
queue based approach.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import atexit
|
7
|
+
import logging
|
8
|
+
import threading
|
9
|
+
from concurrent.futures import ThreadPoolExecutor
|
10
|
+
from queue import Empty, Queue
|
11
|
+
from typing import TYPE_CHECKING, Callable, Union
|
12
|
+
|
13
|
+
from mlflow.utils.async_logging.run_artifact import RunArtifact
|
14
|
+
from mlflow.utils.async_logging.run_operations import RunOperations
|
15
|
+
|
16
|
+
if TYPE_CHECKING:
|
17
|
+
import PIL.Image
|
18
|
+
|
19
|
+
_logger = logging.getLogger(__name__)
|
20
|
+
|
21
|
+
|
22
|
+
class AsyncArtifactsLoggingQueue:
|
23
|
+
"""
|
24
|
+
This is a queue based run data processor that queue incoming data and process it using a single
|
25
|
+
worker thread. This class is used to process artifacts saving in async fashion.
|
26
|
+
|
27
|
+
Args:
|
28
|
+
logging_func: A callable function that takes in three arguments:
|
29
|
+
- filename: The name of the artifact file.
|
30
|
+
- artifact_path: The path to the artifact.
|
31
|
+
- artifact: The artifact to be logged.
|
32
|
+
"""
|
33
|
+
|
34
|
+
def __init__(
|
35
|
+
self, artifact_logging_func: Callable[[str, str, Union["PIL.Image.Image"]], None]
|
36
|
+
) -> None:
|
37
|
+
self._queue: Queue[RunArtifact] = Queue()
|
38
|
+
self._lock = threading.RLock()
|
39
|
+
self._artifact_logging_func = artifact_logging_func
|
40
|
+
|
41
|
+
self._stop_data_logging_thread_event = threading.Event()
|
42
|
+
self._is_activated = False
|
43
|
+
|
44
|
+
def _at_exit_callback(self) -> None:
|
45
|
+
"""Callback function to be executed when the program is exiting.
|
46
|
+
|
47
|
+
Stops the data processing thread and waits for the queue to be drained. Finally, shuts down
|
48
|
+
the thread pools used for data logging and artifact processing status check.
|
49
|
+
"""
|
50
|
+
try:
|
51
|
+
# Stop the data processing thread
|
52
|
+
self._stop_data_logging_thread_event.set()
|
53
|
+
# Waits till logging queue is drained.
|
54
|
+
self._artifact_logging_thread.join()
|
55
|
+
self._artifact_logging_worker_threadpool.shutdown(wait=True)
|
56
|
+
self._artifact_status_check_threadpool.shutdown(wait=True)
|
57
|
+
except Exception as e:
|
58
|
+
_logger.error(f"Encountered error while trying to finish logging: {e}")
|
59
|
+
|
60
|
+
def flush(self) -> None:
|
61
|
+
"""Flush the async logging queue.
|
62
|
+
|
63
|
+
Calling this method will flush the queue to ensure all the data are logged.
|
64
|
+
"""
|
65
|
+
# Stop the data processing thread.
|
66
|
+
self._stop_data_logging_thread_event.set()
|
67
|
+
# Waits till logging queue is drained.
|
68
|
+
self._artifact_logging_thread.join()
|
69
|
+
self._artifact_logging_worker_threadpool.shutdown(wait=True)
|
70
|
+
self._artifact_status_check_threadpool.shutdown(wait=True)
|
71
|
+
|
72
|
+
# Restart the thread to listen to incoming data after flushing.
|
73
|
+
self._stop_data_logging_thread_event.clear()
|
74
|
+
self._set_up_logging_thread()
|
75
|
+
|
76
|
+
def _logging_loop(self) -> None:
|
77
|
+
"""
|
78
|
+
Continuously logs run data until `self._continue_to_process_data` is set to False.
|
79
|
+
If an exception occurs during logging, a `MlflowException` is raised.
|
80
|
+
"""
|
81
|
+
try:
|
82
|
+
while not self._stop_data_logging_thread_event.is_set():
|
83
|
+
self._log_artifact()
|
84
|
+
# Drain the queue after the stop event is set.
|
85
|
+
while not self._queue.empty():
|
86
|
+
self._log_artifact()
|
87
|
+
except Exception as e:
|
88
|
+
from mlflow.exceptions import MlflowException
|
89
|
+
|
90
|
+
raise MlflowException(f"Exception inside the run data logging thread: {e}")
|
91
|
+
|
92
|
+
def _log_artifact(self) -> None:
|
93
|
+
"""Process the run's artifacts in the running runs queues.
|
94
|
+
|
95
|
+
For each run in the running runs queues, this method retrieves the next artifact of run
|
96
|
+
from the queue and processes it by calling the `_artifact_logging_func` method with the run
|
97
|
+
ID and artifact. If the artifact is empty, it is skipped. After processing the artifact,
|
98
|
+
the processed watermark is updated and the artifact event is set.
|
99
|
+
If an exception occurs during processing, the exception is logged and the artifact event
|
100
|
+
is set with the exception. If the queue is empty, it is ignored.
|
101
|
+
"""
|
102
|
+
try:
|
103
|
+
run_artifact = self._queue.get(timeout=1)
|
104
|
+
except Empty:
|
105
|
+
# Ignore empty queue exception
|
106
|
+
return
|
107
|
+
|
108
|
+
def logging_func(run_artifact):
|
109
|
+
try:
|
110
|
+
self._artifact_logging_func(
|
111
|
+
filename=run_artifact.filename,
|
112
|
+
artifact_path=run_artifact.artifact_path,
|
113
|
+
artifact=run_artifact.artifact,
|
114
|
+
)
|
115
|
+
|
116
|
+
# Signal the artifact processing is done.
|
117
|
+
run_artifact.completion_event.set()
|
118
|
+
|
119
|
+
except Exception as e:
|
120
|
+
_logger.error(f"Failed to log artifact {run_artifact.filename}. Exception: {e}")
|
121
|
+
run_artifact.exception = e
|
122
|
+
run_artifact.completion_event.set()
|
123
|
+
|
124
|
+
self._artifact_logging_worker_threadpool.submit(logging_func, run_artifact)
|
125
|
+
|
126
|
+
def _wait_for_artifact(self, artifact: RunArtifact) -> None:
|
127
|
+
"""Wait for given artifacts to be processed by the logging thread.
|
128
|
+
|
129
|
+
Args:
|
130
|
+
artifact: The artifact to wait for.
|
131
|
+
|
132
|
+
Raises:
|
133
|
+
Exception: If an exception occurred while processing the artifact.
|
134
|
+
"""
|
135
|
+
artifact.completion_event.wait()
|
136
|
+
if artifact.exception:
|
137
|
+
raise artifact.exception
|
138
|
+
|
139
|
+
def __getstate__(self):
|
140
|
+
"""Return the state of the object for pickling.
|
141
|
+
|
142
|
+
This method is called by the `pickle` module when the object is being pickled. It returns a
|
143
|
+
dictionary containing the object's state, with non-picklable attributes removed.
|
144
|
+
|
145
|
+
Returns:
|
146
|
+
dict: A dictionary containing the object's state.
|
147
|
+
"""
|
148
|
+
state = self.__dict__.copy()
|
149
|
+
del state["_queue"]
|
150
|
+
del state["_lock"]
|
151
|
+
del state["_is_activated"]
|
152
|
+
|
153
|
+
if "_stop_data_logging_thread_event" in state:
|
154
|
+
del state["_stop_data_logging_thread_event"]
|
155
|
+
if "_artifact_logging_thread" in state:
|
156
|
+
del state["_artifact_logging_thread"]
|
157
|
+
if "_artifact_logging_worker_threadpool" in state:
|
158
|
+
del state["_artifact_logging_worker_threadpool"]
|
159
|
+
if "_artifact_status_check_threadpool" in state:
|
160
|
+
del state["_artifact_status_check_threadpool"]
|
161
|
+
|
162
|
+
return state
|
163
|
+
|
164
|
+
def __setstate__(self, state):
|
165
|
+
"""Set the state of the object from a given state dictionary.
|
166
|
+
|
167
|
+
It pops back the removed non-picklable attributes from `self.__getstate__()`.
|
168
|
+
|
169
|
+
Args:
|
170
|
+
state (dict): A dictionary containing the state of the object.
|
171
|
+
|
172
|
+
Returns:
|
173
|
+
None
|
174
|
+
"""
|
175
|
+
self.__dict__.update(state)
|
176
|
+
self._queue = Queue()
|
177
|
+
self._lock = threading.RLock()
|
178
|
+
self._is_activated = False
|
179
|
+
self._artifact_logging_thread = None
|
180
|
+
self._artifact_logging_worker_threadpool = None
|
181
|
+
self._artifact_status_check_threadpool = None
|
182
|
+
self._stop_data_logging_thread_event = threading.Event()
|
183
|
+
|
184
|
+
def log_artifacts_async(self, filename, artifact_path, artifact) -> RunOperations:
|
185
|
+
"""Asynchronously logs runs artifacts.
|
186
|
+
|
187
|
+
Args:
|
188
|
+
filename: Filename of the artifact to be logged.
|
189
|
+
artifact_path: Directory within the run's artifact directory in which to log the
|
190
|
+
artifact.
|
191
|
+
artifact: The artifact to be logged.
|
192
|
+
|
193
|
+
Returns:
|
194
|
+
mlflow.utils.async_utils.RunOperations: An object that encapsulates the
|
195
|
+
asynchronous operation of logging the artifact of run data.
|
196
|
+
The object contains a list of `concurrent.futures.Future` objects that can be used
|
197
|
+
to check the status of the operation and retrieve any exceptions
|
198
|
+
that occurred during the operation.
|
199
|
+
"""
|
200
|
+
from mlflow import MlflowException
|
201
|
+
|
202
|
+
if not self._is_activated:
|
203
|
+
raise MlflowException("AsyncArtifactsLoggingQueue is not activated.")
|
204
|
+
artifact = RunArtifact(
|
205
|
+
filename=filename,
|
206
|
+
artifact_path=artifact_path,
|
207
|
+
artifact=artifact,
|
208
|
+
completion_event=threading.Event(),
|
209
|
+
)
|
210
|
+
self._queue.put(artifact)
|
211
|
+
operation_future = self._artifact_status_check_threadpool.submit(
|
212
|
+
self._wait_for_artifact, artifact
|
213
|
+
)
|
214
|
+
return RunOperations(operation_futures=[operation_future])
|
215
|
+
|
216
|
+
def is_active(self) -> bool:
|
217
|
+
return self._is_activated
|
218
|
+
|
219
|
+
def _set_up_logging_thread(self) -> None:
|
220
|
+
"""Sets up the logging thread.
|
221
|
+
|
222
|
+
If the logging thread is already set up, this method does nothing.
|
223
|
+
"""
|
224
|
+
with self._lock:
|
225
|
+
self._artifact_logging_thread = threading.Thread(
|
226
|
+
target=self._logging_loop,
|
227
|
+
name="MLflowAsyncArtifactsLoggingLoop",
|
228
|
+
daemon=True,
|
229
|
+
)
|
230
|
+
self._artifact_logging_worker_threadpool = ThreadPoolExecutor(
|
231
|
+
max_workers=5,
|
232
|
+
thread_name_prefix="MLflowArtifactsLoggingWorkerPool",
|
233
|
+
)
|
234
|
+
|
235
|
+
self._artifact_status_check_threadpool = ThreadPoolExecutor(
|
236
|
+
max_workers=5,
|
237
|
+
thread_name_prefix="MLflowAsyncArtifactsLoggingStatusCheck",
|
238
|
+
)
|
239
|
+
self._artifact_logging_thread.start()
|
240
|
+
|
241
|
+
def activate(self) -> None:
|
242
|
+
"""Activates the async logging queue
|
243
|
+
|
244
|
+
1. Initializes queue draining thread.
|
245
|
+
2. Initializes threads for checking the status of logged artifact.
|
246
|
+
3. Registering an atexit callback to ensure that any remaining log data
|
247
|
+
is flushed before the program exits.
|
248
|
+
|
249
|
+
If the queue is already activated, this method does nothing.
|
250
|
+
"""
|
251
|
+
with self._lock:
|
252
|
+
if self._is_activated:
|
253
|
+
return
|
254
|
+
|
255
|
+
self._set_up_logging_thread()
|
256
|
+
atexit.register(self._at_exit_callback)
|
257
|
+
|
258
|
+
self._is_activated = True
|
@@ -0,0 +1,366 @@
|
|
1
|
+
"""
|
2
|
+
Defines an AsyncLoggingQueue that provides async fashion logging of metrics/tags/params using
|
3
|
+
queue based approach.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import atexit
|
7
|
+
import enum
|
8
|
+
import logging
|
9
|
+
import threading
|
10
|
+
from concurrent.futures import ThreadPoolExecutor
|
11
|
+
from queue import Empty, Queue
|
12
|
+
from typing import Callable
|
13
|
+
|
14
|
+
from mlflow.entities.metric import Metric
|
15
|
+
from mlflow.entities.param import Param
|
16
|
+
from mlflow.entities.run_tag import RunTag
|
17
|
+
from mlflow.environment_variables import (
|
18
|
+
MLFLOW_ASYNC_LOGGING_BUFFERING_SECONDS,
|
19
|
+
MLFLOW_ASYNC_LOGGING_THREADPOOL_SIZE,
|
20
|
+
)
|
21
|
+
from mlflow.utils.async_logging.run_batch import RunBatch
|
22
|
+
from mlflow.utils.async_logging.run_operations import RunOperations
|
23
|
+
|
24
|
+
_logger = logging.getLogger(__name__)
|
25
|
+
|
26
|
+
|
27
|
+
ASYNC_LOGGING_WORKER_THREAD_PREFIX = "MLflowBatchLoggingWorkerPool"
|
28
|
+
ASYNC_LOGGING_STATUS_CHECK_THREAD_PREFIX = "MLflowAsyncLoggingStatusCheck"
|
29
|
+
|
30
|
+
|
31
|
+
class QueueStatus(enum.Enum):
|
32
|
+
"""Status of the async queue"""
|
33
|
+
|
34
|
+
# The queue is listening to new data and logging enqueued data to MLflow.
|
35
|
+
ACTIVE = 1
|
36
|
+
# The queue is not listening to new data, but still logging enqueued data to MLflow.
|
37
|
+
TEAR_DOWN = 2
|
38
|
+
# The queue is neither listening to new data or logging enqueued data to MLflow.
|
39
|
+
IDLE = 3
|
40
|
+
|
41
|
+
|
42
|
+
_MAX_ITEMS_PER_BATCH = 1000
|
43
|
+
_MAX_PARAMS_PER_BATCH = 100
|
44
|
+
_MAX_TAGS_PER_BATCH = 100
|
45
|
+
|
46
|
+
|
47
|
+
class AsyncLoggingQueue:
|
48
|
+
"""
|
49
|
+
This is a queue based run data processor that queues incoming batches and processes them using
|
50
|
+
single worker thread.
|
51
|
+
"""
|
52
|
+
|
53
|
+
def __init__(
|
54
|
+
self, logging_func: Callable[[str, list[Metric], list[Param], list[RunTag]], None]
|
55
|
+
) -> None:
|
56
|
+
"""Initializes an AsyncLoggingQueue object.
|
57
|
+
|
58
|
+
Args:
|
59
|
+
logging_func: A callable function that takes in four arguments: a string
|
60
|
+
representing the run_id, a list of Metric objects,
|
61
|
+
a list of Param objects, and a list of RunTag objects.
|
62
|
+
"""
|
63
|
+
self._queue = Queue()
|
64
|
+
self._lock = threading.RLock()
|
65
|
+
self._logging_func = logging_func
|
66
|
+
|
67
|
+
self._stop_data_logging_thread_event = threading.Event()
|
68
|
+
self._status = QueueStatus.IDLE
|
69
|
+
|
70
|
+
def _at_exit_callback(self) -> None:
|
71
|
+
"""Callback function to be executed when the program is exiting.
|
72
|
+
|
73
|
+
Stops the data processing thread and waits for the queue to be drained. Finally, shuts down
|
74
|
+
the thread pools used for data logging and batch processing status check.
|
75
|
+
"""
|
76
|
+
try:
|
77
|
+
# Stop the data processing thread
|
78
|
+
self._stop_data_logging_thread_event.set()
|
79
|
+
# Waits till logging queue is drained.
|
80
|
+
self._batch_logging_thread.join()
|
81
|
+
self._batch_logging_worker_threadpool.shutdown(wait=True)
|
82
|
+
self._batch_status_check_threadpool.shutdown(wait=True)
|
83
|
+
except Exception as e:
|
84
|
+
_logger.error(f"Encountered error while trying to finish logging: {e}")
|
85
|
+
|
86
|
+
def end_async_logging(self) -> None:
|
87
|
+
with self._lock:
|
88
|
+
# Stop the data processing thread.
|
89
|
+
self._stop_data_logging_thread_event.set()
|
90
|
+
# Waits till logging queue is drained.
|
91
|
+
self._batch_logging_thread.join()
|
92
|
+
# Set the status to tear down. The worker threads will still process
|
93
|
+
# the remaining data.
|
94
|
+
self._status = QueueStatus.TEAR_DOWN
|
95
|
+
# Clear the status to avoid blocking next logging.
|
96
|
+
self._stop_data_logging_thread_event.clear()
|
97
|
+
|
98
|
+
def shut_down_async_logging(self) -> None:
|
99
|
+
"""
|
100
|
+
Shut down the async logging queue and wait for the queue to be drained.
|
101
|
+
Use this method if the async logging should be terminated.
|
102
|
+
"""
|
103
|
+
self.end_async_logging()
|
104
|
+
self._batch_logging_worker_threadpool.shutdown(wait=True)
|
105
|
+
self._batch_status_check_threadpool.shutdown(wait=True)
|
106
|
+
self._status = QueueStatus.IDLE
|
107
|
+
|
108
|
+
def flush(self) -> None:
|
109
|
+
"""
|
110
|
+
Flush the async logging queue and restart thread to listen
|
111
|
+
to incoming data after flushing.
|
112
|
+
|
113
|
+
Calling this method will flush the queue to ensure all the data are logged.
|
114
|
+
"""
|
115
|
+
self.shut_down_async_logging()
|
116
|
+
# Reinitialize the logging thread and set the status to active.
|
117
|
+
self.activate()
|
118
|
+
|
119
|
+
def _logging_loop(self) -> None:
|
120
|
+
"""
|
121
|
+
Continuously logs run data until `self._continue_to_process_data` is set to False.
|
122
|
+
If an exception occurs during logging, a `MlflowException` is raised.
|
123
|
+
"""
|
124
|
+
try:
|
125
|
+
while not self._stop_data_logging_thread_event.is_set():
|
126
|
+
self._log_run_data()
|
127
|
+
# Drain the queue after the stop event is set.
|
128
|
+
while not self._queue.empty():
|
129
|
+
self._log_run_data()
|
130
|
+
except Exception as e:
|
131
|
+
from mlflow.exceptions import MlflowException
|
132
|
+
|
133
|
+
raise MlflowException(f"Exception inside the run data logging thread: {e}")
|
134
|
+
|
135
|
+
def _fetch_batch_from_queue(self) -> list[RunBatch]:
|
136
|
+
"""Fetches a batch of run data from the queue.
|
137
|
+
|
138
|
+
Returns:
|
139
|
+
RunBatch: A batch of run data.
|
140
|
+
"""
|
141
|
+
batches = []
|
142
|
+
if self._queue.empty():
|
143
|
+
return batches
|
144
|
+
queue_size = self._queue.qsize() # Estimate the queue's size.
|
145
|
+
merged_batch = self._queue.get()
|
146
|
+
for i in range(queue_size - 1):
|
147
|
+
if self._queue.empty():
|
148
|
+
# `queue_size` is an estimate, so we need to check if the queue is empty.
|
149
|
+
break
|
150
|
+
batch = self._queue.get()
|
151
|
+
|
152
|
+
if (
|
153
|
+
merged_batch.run_id != batch.run_id
|
154
|
+
or (
|
155
|
+
len(merged_batch.metrics + merged_batch.params + merged_batch.tags)
|
156
|
+
+ len(batch.metrics + batch.params + batch.tags)
|
157
|
+
)
|
158
|
+
>= _MAX_ITEMS_PER_BATCH
|
159
|
+
or len(merged_batch.params) + len(batch.params) >= _MAX_PARAMS_PER_BATCH
|
160
|
+
or len(merged_batch.tags) + len(batch.tags) >= _MAX_TAGS_PER_BATCH
|
161
|
+
):
|
162
|
+
# Make a new batch if the run_id is different or the batch is full.
|
163
|
+
batches.append(merged_batch)
|
164
|
+
merged_batch = batch
|
165
|
+
else:
|
166
|
+
merged_batch.add_child_batch(batch)
|
167
|
+
merged_batch.params.extend(batch.params)
|
168
|
+
merged_batch.tags.extend(batch.tags)
|
169
|
+
merged_batch.metrics.extend(batch.metrics)
|
170
|
+
|
171
|
+
batches.append(merged_batch)
|
172
|
+
return batches
|
173
|
+
|
174
|
+
def _log_run_data(self) -> None:
|
175
|
+
"""Process the run data in the running runs queues.
|
176
|
+
|
177
|
+
For each run in the running runs queues, this method retrieves the next batch of run data
|
178
|
+
from the queue and processes it by calling the `_processing_func` method with the run ID,
|
179
|
+
metrics, parameters, and tags in the batch. If the batch is empty, it is skipped. After
|
180
|
+
processing the batch, the processed watermark is updated and the batch event is set.
|
181
|
+
If an exception occurs during processing, the exception is logged and the batch event is set
|
182
|
+
with the exception. If the queue is empty, it is ignored.
|
183
|
+
|
184
|
+
Returns: None
|
185
|
+
"""
|
186
|
+
async_logging_buffer_seconds = MLFLOW_ASYNC_LOGGING_BUFFERING_SECONDS.get()
|
187
|
+
try:
|
188
|
+
if async_logging_buffer_seconds:
|
189
|
+
self._stop_data_logging_thread_event.wait(async_logging_buffer_seconds)
|
190
|
+
run_batches = self._fetch_batch_from_queue()
|
191
|
+
else:
|
192
|
+
run_batches = [self._queue.get(timeout=1)]
|
193
|
+
except Empty:
|
194
|
+
# Ignore empty queue exception
|
195
|
+
return
|
196
|
+
|
197
|
+
def logging_func(run_batch):
|
198
|
+
try:
|
199
|
+
self._logging_func(
|
200
|
+
run_id=run_batch.run_id,
|
201
|
+
metrics=run_batch.metrics,
|
202
|
+
params=run_batch.params,
|
203
|
+
tags=run_batch.tags,
|
204
|
+
)
|
205
|
+
except Exception as e:
|
206
|
+
_logger.error(f"Run Id {run_batch.run_id}: Failed to log run data: Exception: {e}")
|
207
|
+
run_batch.exception = e
|
208
|
+
finally:
|
209
|
+
run_batch.complete()
|
210
|
+
|
211
|
+
for run_batch in run_batches:
|
212
|
+
try:
|
213
|
+
self._batch_logging_worker_threadpool.submit(logging_func, run_batch)
|
214
|
+
except Exception as e:
|
215
|
+
_logger.error(
|
216
|
+
f"Failed to submit batch for logging: {e}. Usually this means you are not "
|
217
|
+
"shutting down MLflow properly before exiting. Please make sure you are using "
|
218
|
+
"context manager, e.g., `with mlflow.start_run():` or call `mlflow.end_run()`"
|
219
|
+
"explicitly to terminate MLflow logging before exiting."
|
220
|
+
)
|
221
|
+
run_batch.exception = e
|
222
|
+
run_batch.complete()
|
223
|
+
|
224
|
+
def _wait_for_batch(self, batch: RunBatch) -> None:
|
225
|
+
"""Wait for the given batch to be processed by the logging thread.
|
226
|
+
|
227
|
+
Args:
|
228
|
+
batch: The batch to wait for.
|
229
|
+
|
230
|
+
Raises:
|
231
|
+
Exception: If an exception occurred while processing the batch.
|
232
|
+
"""
|
233
|
+
batch.completion_event.wait()
|
234
|
+
if batch.exception:
|
235
|
+
raise batch.exception
|
236
|
+
|
237
|
+
def __getstate__(self):
|
238
|
+
"""Return the state of the object for pickling.
|
239
|
+
|
240
|
+
This method is called by the `pickle` module when the object is being pickled. It returns a
|
241
|
+
dictionary containing the object's state, with non-picklable attributes removed.
|
242
|
+
|
243
|
+
Returns:
|
244
|
+
dict: A dictionary containing the object's state.
|
245
|
+
"""
|
246
|
+
state = self.__dict__.copy()
|
247
|
+
del state["_queue"]
|
248
|
+
del state["_lock"]
|
249
|
+
del state["_status"]
|
250
|
+
|
251
|
+
if "_run_data_logging_thread" in state:
|
252
|
+
del state["_run_data_logging_thread"]
|
253
|
+
if "_stop_data_logging_thread_event" in state:
|
254
|
+
del state["_stop_data_logging_thread_event"]
|
255
|
+
if "_batch_logging_thread" in state:
|
256
|
+
del state["_batch_logging_thread"]
|
257
|
+
if "_batch_logging_worker_threadpool" in state:
|
258
|
+
del state["_batch_logging_worker_threadpool"]
|
259
|
+
if "_batch_status_check_threadpool" in state:
|
260
|
+
del state["_batch_status_check_threadpool"]
|
261
|
+
|
262
|
+
return state
|
263
|
+
|
264
|
+
def __setstate__(self, state):
|
265
|
+
"""Set the state of the object from a given state dictionary.
|
266
|
+
|
267
|
+
It pops back the removed non-picklable attributes from `self.__getstate__()`.
|
268
|
+
|
269
|
+
Args:
|
270
|
+
state (dict): A dictionary containing the state of the object.
|
271
|
+
|
272
|
+
Returns:
|
273
|
+
None
|
274
|
+
"""
|
275
|
+
self.__dict__.update(state)
|
276
|
+
self._queue = Queue()
|
277
|
+
self._lock = threading.RLock()
|
278
|
+
self._status = QueueStatus.IDLE
|
279
|
+
self._batch_logging_thread = None
|
280
|
+
self._batch_logging_worker_threadpool = None
|
281
|
+
self._batch_status_check_threadpool = None
|
282
|
+
self._stop_data_logging_thread_event = threading.Event()
|
283
|
+
|
284
|
+
def log_batch_async(
|
285
|
+
self, run_id: str, params: list[Param], tags: list[RunTag], metrics: list[Metric]
|
286
|
+
) -> RunOperations:
|
287
|
+
"""Asynchronously logs a batch of run data (parameters, tags, and metrics).
|
288
|
+
|
289
|
+
Args:
|
290
|
+
run_id (str): The ID of the run to log data for.
|
291
|
+
params (list[mlflow.entities.Param]): A list of parameters to log for the run.
|
292
|
+
tags (list[mlflow.entities.RunTag]): A list of tags to log for the run.
|
293
|
+
metrics (list[mlflow.entities.Metric]): A list of metrics to log for the run.
|
294
|
+
|
295
|
+
Returns:
|
296
|
+
mlflow.utils.async_utils.RunOperations: An object that encapsulates the
|
297
|
+
asynchronous operation of logging the batch of run data.
|
298
|
+
The object contains a list of `concurrent.futures.Future` objects that can be used
|
299
|
+
to check the status of the operation and retrieve any exceptions
|
300
|
+
that occurred during the operation.
|
301
|
+
"""
|
302
|
+
from mlflow import MlflowException
|
303
|
+
|
304
|
+
if not self.is_active():
|
305
|
+
raise MlflowException("AsyncLoggingQueue is not activated.")
|
306
|
+
batch = RunBatch(
|
307
|
+
run_id=run_id,
|
308
|
+
params=params,
|
309
|
+
tags=tags,
|
310
|
+
metrics=metrics,
|
311
|
+
completion_event=threading.Event(),
|
312
|
+
)
|
313
|
+
self._queue.put(batch)
|
314
|
+
operation_future = self._batch_status_check_threadpool.submit(self._wait_for_batch, batch)
|
315
|
+
return RunOperations(operation_futures=[operation_future])
|
316
|
+
|
317
|
+
def is_active(self) -> bool:
|
318
|
+
return self._status == QueueStatus.ACTIVE
|
319
|
+
|
320
|
+
def is_idle(self) -> bool:
|
321
|
+
return self._status == QueueStatus.IDLE
|
322
|
+
|
323
|
+
def _set_up_logging_thread(self) -> None:
|
324
|
+
"""
|
325
|
+
Sets up the logging thread.
|
326
|
+
|
327
|
+
This method shouldn't be called directly without shutting down the async
|
328
|
+
logging first if an existing async logging exists, otherwise it might
|
329
|
+
hang the program.
|
330
|
+
"""
|
331
|
+
with self._lock:
|
332
|
+
self._batch_logging_thread = threading.Thread(
|
333
|
+
target=self._logging_loop,
|
334
|
+
name="MLflowAsyncLoggingLoop",
|
335
|
+
daemon=True,
|
336
|
+
)
|
337
|
+
self._batch_logging_worker_threadpool = ThreadPoolExecutor(
|
338
|
+
max_workers=MLFLOW_ASYNC_LOGGING_THREADPOOL_SIZE.get() or 10,
|
339
|
+
thread_name_prefix=ASYNC_LOGGING_WORKER_THREAD_PREFIX,
|
340
|
+
)
|
341
|
+
|
342
|
+
self._batch_status_check_threadpool = ThreadPoolExecutor(
|
343
|
+
max_workers=MLFLOW_ASYNC_LOGGING_THREADPOOL_SIZE.get() or 10,
|
344
|
+
thread_name_prefix=ASYNC_LOGGING_STATUS_CHECK_THREAD_PREFIX,
|
345
|
+
)
|
346
|
+
|
347
|
+
self._batch_logging_thread.start()
|
348
|
+
|
349
|
+
def activate(self) -> None:
|
350
|
+
"""Activates the async logging queue
|
351
|
+
|
352
|
+
1. Initializes queue draining thread.
|
353
|
+
2. Initializes threads for checking the status of logged batch.
|
354
|
+
3. Registering an atexit callback to ensure that any remaining log data
|
355
|
+
is flushed before the program exits.
|
356
|
+
|
357
|
+
If the queue is already activated, this method does nothing.
|
358
|
+
"""
|
359
|
+
with self._lock:
|
360
|
+
if self.is_active():
|
361
|
+
return
|
362
|
+
|
363
|
+
self._set_up_logging_thread()
|
364
|
+
atexit.register(self._at_exit_callback)
|
365
|
+
|
366
|
+
self._status = QueueStatus.ACTIVE
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import threading
|
2
|
+
from typing import TYPE_CHECKING, Union
|
3
|
+
|
4
|
+
if TYPE_CHECKING:
|
5
|
+
import PIL
|
6
|
+
|
7
|
+
|
8
|
+
class RunArtifact:
|
9
|
+
def __init__(
|
10
|
+
self,
|
11
|
+
filename: str,
|
12
|
+
artifact_path: str,
|
13
|
+
artifact: Union["PIL.Image.Image"],
|
14
|
+
completion_event: threading.Event,
|
15
|
+
) -> None:
|
16
|
+
"""Initializes an instance of `RunArtifacts`.
|
17
|
+
|
18
|
+
Args:
|
19
|
+
filename: Filename of the artifact to be logged
|
20
|
+
artifact_path: Directory within the run's artifact directory in which to log the
|
21
|
+
artifact.
|
22
|
+
artifact: The artifact to be logged.
|
23
|
+
completion_event: A threading.Event object.
|
24
|
+
"""
|
25
|
+
self.filename = filename
|
26
|
+
self.artifact_path = artifact_path
|
27
|
+
self.artifact = artifact
|
28
|
+
self.completion_event = completion_event
|
29
|
+
self._exception = None
|
30
|
+
|
31
|
+
@property
|
32
|
+
def exception(self):
|
33
|
+
"""Exception raised during logging the batch."""
|
34
|
+
return self._exception
|
35
|
+
|
36
|
+
@exception.setter
|
37
|
+
def exception(self, exception):
|
38
|
+
self._exception = exception
|