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,146 @@
|
|
1
|
+
import json
|
2
|
+
import logging
|
3
|
+
import tempfile
|
4
|
+
import time
|
5
|
+
import uuid
|
6
|
+
from abc import ABC, abstractmethod
|
7
|
+
from pathlib import Path
|
8
|
+
from typing import Any, Optional
|
9
|
+
|
10
|
+
import requests
|
11
|
+
|
12
|
+
from mlflow.deployments import PredictionsResponse
|
13
|
+
from mlflow.environment_variables import MLFLOW_SCORING_SERVER_REQUEST_TIMEOUT
|
14
|
+
from mlflow.exceptions import MlflowException
|
15
|
+
from mlflow.pyfunc import scoring_server
|
16
|
+
from mlflow.utils.proto_json_utils import dump_input_data
|
17
|
+
|
18
|
+
_logger = logging.getLogger(__name__)
|
19
|
+
|
20
|
+
|
21
|
+
class BaseScoringServerClient(ABC):
|
22
|
+
@abstractmethod
|
23
|
+
def wait_server_ready(self, timeout=30, scoring_server_proc=None):
|
24
|
+
"""
|
25
|
+
Wait until the scoring server is ready to accept requests.
|
26
|
+
"""
|
27
|
+
|
28
|
+
@abstractmethod
|
29
|
+
def invoke(self, data, params: Optional[dict[str, Any]] = None):
|
30
|
+
"""
|
31
|
+
Invoke inference on input data. The input data must be pandas dataframe or numpy array or
|
32
|
+
a dict of numpy arrays.
|
33
|
+
|
34
|
+
Args:
|
35
|
+
data: Model input data.
|
36
|
+
params: Additional parameters to pass to the model for inference.
|
37
|
+
|
38
|
+
Returns:
|
39
|
+
Prediction result.
|
40
|
+
"""
|
41
|
+
|
42
|
+
|
43
|
+
class ScoringServerClient(BaseScoringServerClient):
|
44
|
+
def __init__(self, host, port):
|
45
|
+
self.url_prefix = f"http://{host}:{port}"
|
46
|
+
|
47
|
+
def ping(self):
|
48
|
+
ping_status = requests.get(url=self.url_prefix + "/ping")
|
49
|
+
if ping_status.status_code != 200:
|
50
|
+
raise Exception(f"ping failed (error code {ping_status.status_code})")
|
51
|
+
|
52
|
+
def get_version(self):
|
53
|
+
resp_status = requests.get(url=self.url_prefix + "/version")
|
54
|
+
if resp_status.status_code != 200:
|
55
|
+
raise Exception(f"version failed (error code {resp_status.status_code})")
|
56
|
+
return resp_status.text
|
57
|
+
|
58
|
+
def wait_server_ready(self, timeout=30, scoring_server_proc=None):
|
59
|
+
begin_time = time.time()
|
60
|
+
|
61
|
+
while True:
|
62
|
+
time.sleep(0.3)
|
63
|
+
try:
|
64
|
+
self.ping()
|
65
|
+
return
|
66
|
+
except Exception:
|
67
|
+
pass
|
68
|
+
if time.time() - begin_time > timeout:
|
69
|
+
break
|
70
|
+
if scoring_server_proc is not None:
|
71
|
+
return_code = scoring_server_proc.poll()
|
72
|
+
if return_code is not None:
|
73
|
+
raise RuntimeError(f"Server process already exit with returncode {return_code}")
|
74
|
+
raise RuntimeError("Wait scoring server ready timeout.")
|
75
|
+
|
76
|
+
def invoke(self, data, params: Optional[dict[str, Any]] = None):
|
77
|
+
"""
|
78
|
+
Args:
|
79
|
+
data: Model input data.
|
80
|
+
params: Additional parameters to pass to the model for inference.
|
81
|
+
|
82
|
+
Returns:
|
83
|
+
:py:class:`PredictionsResponse <mlflow.deployments.PredictionsResponse>` result.
|
84
|
+
"""
|
85
|
+
response = requests.post(
|
86
|
+
url=self.url_prefix + "/invocations",
|
87
|
+
data=dump_input_data(data, params=params),
|
88
|
+
headers={"Content-Type": scoring_server.CONTENT_TYPE_JSON},
|
89
|
+
)
|
90
|
+
if response.status_code != 200:
|
91
|
+
raise Exception(
|
92
|
+
f"Invocation failed (error code {response.status_code}, response: {response.text})"
|
93
|
+
)
|
94
|
+
return PredictionsResponse.from_json(response.text)
|
95
|
+
|
96
|
+
|
97
|
+
class StdinScoringServerClient(BaseScoringServerClient):
|
98
|
+
def __init__(self, process):
|
99
|
+
super().__init__()
|
100
|
+
self.process = process
|
101
|
+
self.tmpdir = Path(tempfile.mkdtemp())
|
102
|
+
self.output_json = self.tmpdir.joinpath("output.json")
|
103
|
+
|
104
|
+
def wait_server_ready(self, timeout=30, scoring_server_proc=None):
|
105
|
+
return_code = self.process.poll()
|
106
|
+
if return_code is not None:
|
107
|
+
raise RuntimeError(f"Server process already exit with returncode {return_code}")
|
108
|
+
|
109
|
+
def invoke(self, data, params: Optional[dict[str, Any]] = None):
|
110
|
+
"""
|
111
|
+
Invoke inference on input data. The input data must be pandas dataframe or numpy array or
|
112
|
+
a dict of numpy arrays.
|
113
|
+
|
114
|
+
Args:
|
115
|
+
data: Model input data.
|
116
|
+
params: Additional parameters to pass to the model for inference.
|
117
|
+
|
118
|
+
Returns:
|
119
|
+
:py:class:`PredictionsResponse <mlflow.deployments.PredictionsResponse>` result.
|
120
|
+
"""
|
121
|
+
if not self.output_json.exists():
|
122
|
+
self.output_json.touch()
|
123
|
+
|
124
|
+
request_id = str(uuid.uuid4())
|
125
|
+
request = {
|
126
|
+
"id": request_id,
|
127
|
+
"data": dump_input_data(data, params=params),
|
128
|
+
"output_file": str(self.output_json),
|
129
|
+
}
|
130
|
+
self.process.stdin.write(json.dumps(request) + "\n")
|
131
|
+
self.process.stdin.flush()
|
132
|
+
|
133
|
+
begin_time = time.time()
|
134
|
+
while True:
|
135
|
+
_logger.info("Waiting for scoring to complete...")
|
136
|
+
try:
|
137
|
+
with self.output_json.open(mode="r+") as f:
|
138
|
+
resp = PredictionsResponse.from_json(f.read())
|
139
|
+
if resp.get("id") == request_id:
|
140
|
+
f.truncate(0)
|
141
|
+
return resp
|
142
|
+
except Exception as e:
|
143
|
+
_logger.debug("Exception while waiting for scoring to complete: %s", e)
|
144
|
+
if time.time() - begin_time > MLFLOW_SCORING_SERVER_REQUEST_TIMEOUT.get():
|
145
|
+
raise MlflowException("Scoring timeout")
|
146
|
+
time.sleep(1)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
from mlflow.utils._spark_utils import _SparkDirectoryDistributor
|
2
|
+
|
3
|
+
|
4
|
+
class SparkModelCache:
|
5
|
+
"""Caches models in memory on Spark Executors, to avoid continually reloading from disk.
|
6
|
+
|
7
|
+
This class has to be part of a different module than the one that _uses_ it. This is
|
8
|
+
because Spark will pickle classes that are defined in the local scope, but relies on
|
9
|
+
Python's module loading behavior for classes in different modules. In this case, we
|
10
|
+
are relying on the fact that Python will load a module at-most-once, and can therefore
|
11
|
+
store per-process state in a static map.
|
12
|
+
"""
|
13
|
+
|
14
|
+
# Map from unique name --> (loaded model, local_model_path).
|
15
|
+
_models = {}
|
16
|
+
|
17
|
+
# Number of cache hits we've had, for testing purposes.
|
18
|
+
_cache_hits = 0
|
19
|
+
|
20
|
+
def __init__(self):
|
21
|
+
pass
|
22
|
+
|
23
|
+
@staticmethod
|
24
|
+
def add_local_model(spark, model_path):
|
25
|
+
"""Given a SparkSession and a model_path which refers to a pyfunc directory locally,
|
26
|
+
we will zip the directory up, enable it to be distributed to executors, and return
|
27
|
+
the "archive_path", which should be used as the path in get_or_load().
|
28
|
+
"""
|
29
|
+
return _SparkDirectoryDistributor.add_dir(spark, model_path)
|
30
|
+
|
31
|
+
@staticmethod
|
32
|
+
def get_or_load(archive_path):
|
33
|
+
"""Given a path returned by add_local_model(), this method will return a tuple of
|
34
|
+
(loaded_model, local_model_path).
|
35
|
+
If this Python process ever loaded the model before, we will reuse that copy.
|
36
|
+
"""
|
37
|
+
if archive_path in SparkModelCache._models:
|
38
|
+
SparkModelCache._cache_hits += 1
|
39
|
+
return SparkModelCache._models[archive_path]
|
40
|
+
|
41
|
+
local_model_dir = _SparkDirectoryDistributor.get_or_extract(archive_path)
|
42
|
+
|
43
|
+
# We must rely on a supposed cyclic import here because we want this behavior
|
44
|
+
# on the Spark Executors (i.e., don't try to pickle the load_model function).
|
45
|
+
from mlflow.pyfunc import load_model
|
46
|
+
|
47
|
+
SparkModelCache._models[archive_path] = (load_model(local_model_dir), local_model_dir)
|
48
|
+
return SparkModelCache._models[archive_path]
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import argparse
|
2
|
+
import inspect
|
3
|
+
import json
|
4
|
+
import logging
|
5
|
+
import sys
|
6
|
+
|
7
|
+
from mlflow.pyfunc import scoring_server
|
8
|
+
from mlflow.pyfunc.model import _log_warning_if_params_not_in_predict_signature
|
9
|
+
|
10
|
+
_logger = logging.getLogger(__name__)
|
11
|
+
logging.basicConfig(level=logging.INFO)
|
12
|
+
|
13
|
+
parser = argparse.ArgumentParser()
|
14
|
+
parser.add_argument("--model-uri")
|
15
|
+
args = parser.parse_args()
|
16
|
+
|
17
|
+
_logger.info("Loading model from %s", args.model_uri)
|
18
|
+
|
19
|
+
model = scoring_server.load_model_with_mlflow_config(args.model_uri)
|
20
|
+
input_schema = model.metadata.get_input_schema()
|
21
|
+
_logger.info("Loaded model")
|
22
|
+
|
23
|
+
_logger.info("Waiting for request")
|
24
|
+
for line in sys.stdin:
|
25
|
+
_logger.info("Received request")
|
26
|
+
request = json.loads(line)
|
27
|
+
|
28
|
+
_logger.info("Parsing input data")
|
29
|
+
data = request["data"]
|
30
|
+
data, params = scoring_server._split_data_and_params(data)
|
31
|
+
data = scoring_server.infer_and_parse_data(data, input_schema)
|
32
|
+
|
33
|
+
_logger.info("Making predictions")
|
34
|
+
if "params" in inspect.signature(model.predict).parameters:
|
35
|
+
preds = model.predict(data, params=params)
|
36
|
+
else:
|
37
|
+
_log_warning_if_params_not_in_predict_signature(_logger, params)
|
38
|
+
preds = model.predict(data)
|
39
|
+
|
40
|
+
_logger.info("Writing predictions")
|
41
|
+
with open(request["output_file"], "a") as f:
|
42
|
+
scoring_server.predictions_to_json(preds, f, {"id": request["id"]})
|
43
|
+
|
44
|
+
_logger.info("Done")
|
@@ -0,0 +1,224 @@
|
|
1
|
+
import inspect
|
2
|
+
import warnings
|
3
|
+
from functools import lru_cache, wraps
|
4
|
+
from typing import Any, NamedTuple, Optional
|
5
|
+
|
6
|
+
import pydantic
|
7
|
+
|
8
|
+
from mlflow.exceptions import MlflowException
|
9
|
+
from mlflow.models.signature import (
|
10
|
+
_extract_type_hints,
|
11
|
+
_is_context_in_predict_function_signature,
|
12
|
+
)
|
13
|
+
from mlflow.types.type_hints import (
|
14
|
+
InvalidTypeHintException,
|
15
|
+
_convert_data_to_type_hint,
|
16
|
+
_infer_schema_from_list_type_hint,
|
17
|
+
_is_type_hint_from_example,
|
18
|
+
_signature_cannot_be_inferred_from_type_hint,
|
19
|
+
_validate_data_against_type_hint,
|
20
|
+
model_validate,
|
21
|
+
)
|
22
|
+
from mlflow.utils.annotations import filter_user_warnings_once
|
23
|
+
from mlflow.utils.warnings_utils import color_warning
|
24
|
+
|
25
|
+
_INVALID_SIGNATURE_ERROR_MSG = (
|
26
|
+
"Model's `{func_name}` method contains invalid parameters: {invalid_params}. "
|
27
|
+
"Only the following parameter names are allowed: context, model_input, and params. "
|
28
|
+
"Note that invalid parameters will no longer be permitted in future versions."
|
29
|
+
)
|
30
|
+
|
31
|
+
|
32
|
+
class FuncInfo(NamedTuple):
|
33
|
+
input_type_hint: Optional[type[Any]]
|
34
|
+
input_param_name: str
|
35
|
+
|
36
|
+
|
37
|
+
def pyfunc(func):
|
38
|
+
"""
|
39
|
+
A decorator that forces data validation against type hint of the input data
|
40
|
+
in the wrapped method. It is no-op if the type hint is not supported by MLflow.
|
41
|
+
|
42
|
+
.. note::
|
43
|
+
The function that applies this decorator must be a valid `predict` function
|
44
|
+
of `mlflow.pyfunc.PythonModel`, or a callable that takes a single input.
|
45
|
+
"""
|
46
|
+
|
47
|
+
func_info = _get_func_info_if_type_hint_supported(func)
|
48
|
+
return _wrap_predict_with_pyfunc(func, func_info)
|
49
|
+
|
50
|
+
|
51
|
+
def _wrap_predict_with_pyfunc(func, func_info: Optional[FuncInfo]):
|
52
|
+
if func_info is not None:
|
53
|
+
model_input_index = _model_input_index_in_function_signature(func)
|
54
|
+
|
55
|
+
@wraps(func)
|
56
|
+
def wrapper(*args, **kwargs):
|
57
|
+
try:
|
58
|
+
args, kwargs = _validate_model_input(
|
59
|
+
args,
|
60
|
+
kwargs,
|
61
|
+
model_input_index,
|
62
|
+
func_info.input_type_hint,
|
63
|
+
func_info.input_param_name,
|
64
|
+
)
|
65
|
+
except Exception as e:
|
66
|
+
if isinstance(e, MlflowException):
|
67
|
+
raise e
|
68
|
+
raise MlflowException(
|
69
|
+
"Failed to validate the input data against the type hint "
|
70
|
+
f"`{func_info.input_type_hint}`. Error: {e}"
|
71
|
+
)
|
72
|
+
return func(*args, **kwargs)
|
73
|
+
else:
|
74
|
+
|
75
|
+
@wraps(func)
|
76
|
+
def wrapper(*args, **kwargs):
|
77
|
+
return func(*args, **kwargs)
|
78
|
+
|
79
|
+
wrapper._is_pyfunc = True
|
80
|
+
return wrapper
|
81
|
+
|
82
|
+
|
83
|
+
def wrap_non_list_predict_pydantic(func, input_pydantic_model, validation_error_msg, unpack=False):
|
84
|
+
"""
|
85
|
+
Used by MLflow defined subclasses of PythonModel that have non-list a pydantic model as input.
|
86
|
+
Takes in a dict input, validates it against `input_pydantic_model`, and then creates
|
87
|
+
the pydantic model.
|
88
|
+
|
89
|
+
If `unpack` is True, the validated dict is parsed into the function arguments.
|
90
|
+
Otherwise, the whole pydantic object is passed to the function.
|
91
|
+
|
92
|
+
Args:
|
93
|
+
func: The predict/predict_stream method of the PythonModel subclass.
|
94
|
+
input_pydantic_model: The pydantic model that the input should be validated against.
|
95
|
+
validation_error_msg: The error message to raise if the dict input fails to validate.
|
96
|
+
unpack: Whether to unpack the validated dict into the function arguments. Defaults to False.
|
97
|
+
|
98
|
+
Raises:
|
99
|
+
MlflowException: If the input fails to validate against the pydantic model.
|
100
|
+
|
101
|
+
Returns:
|
102
|
+
A function that can take either a dict input or a pydantic object as input.
|
103
|
+
"""
|
104
|
+
|
105
|
+
@wraps(func)
|
106
|
+
def wrapper(self, *args, **kwargs):
|
107
|
+
if len(args) == 1 and isinstance(args[0], dict):
|
108
|
+
try:
|
109
|
+
model_validate(input_pydantic_model, args[0])
|
110
|
+
pydantic_obj = input_pydantic_model(**args[0])
|
111
|
+
except pydantic.ValidationError as e:
|
112
|
+
raise MlflowException(
|
113
|
+
f"{validation_error_msg} Pydantic validation error: {e}"
|
114
|
+
) from e
|
115
|
+
else:
|
116
|
+
if unpack:
|
117
|
+
param_names = inspect.signature(func).parameters.keys() - {"self"}
|
118
|
+
kwargs = {k: getattr(pydantic_obj, k) for k in param_names}
|
119
|
+
return func(self, **kwargs)
|
120
|
+
else:
|
121
|
+
return func(self, pydantic_obj)
|
122
|
+
else:
|
123
|
+
# Before logging, this is equivalent to the behavior from the raw predict method
|
124
|
+
# After logging, signature enforcement happens in the _convert_input method
|
125
|
+
# of the wrapper class
|
126
|
+
return func(self, *args, **kwargs)
|
127
|
+
|
128
|
+
wrapper._is_pyfunc = True
|
129
|
+
return wrapper
|
130
|
+
|
131
|
+
|
132
|
+
def _check_func_signature(func, func_name) -> list[str]:
|
133
|
+
parameters = inspect.signature(func).parameters
|
134
|
+
param_names = [name for name in parameters.keys() if name != "self"]
|
135
|
+
if invalid_params := set(param_names) - {"self", "context", "model_input", "params"}:
|
136
|
+
warnings.warn(
|
137
|
+
_INVALID_SIGNATURE_ERROR_MSG.format(func_name=func_name, invalid_params=invalid_params),
|
138
|
+
FutureWarning,
|
139
|
+
stacklevel=2,
|
140
|
+
)
|
141
|
+
return param_names
|
142
|
+
|
143
|
+
|
144
|
+
@lru_cache
|
145
|
+
@filter_user_warnings_once
|
146
|
+
def _get_func_info_if_type_hint_supported(func) -> Optional[FuncInfo]:
|
147
|
+
"""
|
148
|
+
Internal method to check if the predict function has type hints and if they are supported
|
149
|
+
by MLflow.
|
150
|
+
For PythonModel, the signature must be one of below:
|
151
|
+
- predict(self, context, model_input, params=None)
|
152
|
+
- predict(self, model_input, params=None)
|
153
|
+
For callables, the function must contain only one input argument.
|
154
|
+
"""
|
155
|
+
param_names = _check_func_signature(func, "predict")
|
156
|
+
input_arg_index = 1 if _is_context_in_predict_function_signature(func=func) else 0
|
157
|
+
type_hint = _extract_type_hints(func, input_arg_index=input_arg_index).input
|
158
|
+
input_param_name = param_names[input_arg_index]
|
159
|
+
if type_hint is not None:
|
160
|
+
if _signature_cannot_be_inferred_from_type_hint(type_hint) or _is_type_hint_from_example(
|
161
|
+
type_hint
|
162
|
+
):
|
163
|
+
return
|
164
|
+
try:
|
165
|
+
_infer_schema_from_list_type_hint(type_hint)
|
166
|
+
except InvalidTypeHintException as e:
|
167
|
+
raise MlflowException(
|
168
|
+
f"{e.message} To disable data validation, remove the type hint from the "
|
169
|
+
"predict function. Otherwise, fix the type hint."
|
170
|
+
)
|
171
|
+
# catch other exceptions to avoid breaking model usage
|
172
|
+
except Exception as e:
|
173
|
+
color_warning(
|
174
|
+
message="Type hint used in the model's predict function is not supported "
|
175
|
+
f"for MLflow's schema validation. {e} "
|
176
|
+
"Remove the type hint to disable this warning. "
|
177
|
+
"To enable validation for the input data, specify input example "
|
178
|
+
"or model signature when logging the model. ",
|
179
|
+
category=UserWarning,
|
180
|
+
stacklevel=3,
|
181
|
+
color="red",
|
182
|
+
)
|
183
|
+
else:
|
184
|
+
return FuncInfo(input_type_hint=type_hint, input_param_name=input_param_name)
|
185
|
+
else:
|
186
|
+
color_warning(
|
187
|
+
"Add type hints to the `predict` method to enable data validation "
|
188
|
+
"and automatic signature inference during model logging. "
|
189
|
+
"Check https://mlflow.org/docs/latest/model/python_model.html#type-hint-usage-in-pythonmodel"
|
190
|
+
" for more details.",
|
191
|
+
stacklevel=1,
|
192
|
+
color="yellow",
|
193
|
+
category=UserWarning,
|
194
|
+
)
|
195
|
+
|
196
|
+
|
197
|
+
def _model_input_index_in_function_signature(func):
|
198
|
+
parameters = inspect.signature(func).parameters
|
199
|
+
# we need to exclude the first argument if "self" is in the parameters
|
200
|
+
index = 1 if "self" in parameters else 0
|
201
|
+
if _is_context_in_predict_function_signature(parameters=parameters):
|
202
|
+
index += 1
|
203
|
+
return index
|
204
|
+
|
205
|
+
|
206
|
+
def _validate_model_input(
|
207
|
+
args, kwargs, model_input_index_in_sig, type_hint, model_input_param_name
|
208
|
+
):
|
209
|
+
model_input = None
|
210
|
+
input_pos = None
|
211
|
+
if model_input_param_name in kwargs:
|
212
|
+
model_input = kwargs[model_input_param_name]
|
213
|
+
input_pos = "kwargs"
|
214
|
+
elif len(args) >= model_input_index_in_sig + 1:
|
215
|
+
model_input = args[model_input_index_in_sig]
|
216
|
+
input_pos = model_input_index_in_sig
|
217
|
+
if input_pos is not None:
|
218
|
+
data = _convert_data_to_type_hint(model_input, type_hint)
|
219
|
+
data = _validate_data_against_type_hint(data, type_hint)
|
220
|
+
if input_pos == "kwargs":
|
221
|
+
kwargs[model_input_param_name] = data
|
222
|
+
else:
|
223
|
+
args = args[:input_pos] + (data,) + args[input_pos + 1 :]
|
224
|
+
return args, kwargs
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import os
|
2
|
+
from contextlib import contextmanager
|
3
|
+
|
4
|
+
from mlflow.environment_variables import _MLFLOW_IS_IN_SERVING_ENVIRONMENT
|
5
|
+
|
6
|
+
|
7
|
+
@contextmanager
|
8
|
+
def _simulate_serving_environment():
|
9
|
+
"""
|
10
|
+
Some functions (e.g. validate_serving_input) replicate the data transformation logic
|
11
|
+
that happens in the model serving environment to validate data before model deployment.
|
12
|
+
This context manager can be used to simulate the serving environment for such functions.
|
13
|
+
"""
|
14
|
+
original_value = _MLFLOW_IS_IN_SERVING_ENVIRONMENT.get_raw()
|
15
|
+
try:
|
16
|
+
_MLFLOW_IS_IN_SERVING_ENVIRONMENT.set("true")
|
17
|
+
yield
|
18
|
+
finally:
|
19
|
+
if original_value is not None:
|
20
|
+
os.environ[_MLFLOW_IS_IN_SERVING_ENVIRONMENT.name] = original_value
|
21
|
+
else:
|
22
|
+
del os.environ[_MLFLOW_IS_IN_SERVING_ENVIRONMENT.name]
|
@@ -0,0 +1,47 @@
|
|
1
|
+
from dataclasses import fields, is_dataclass
|
2
|
+
from typing import Union, get_args, get_origin
|
3
|
+
|
4
|
+
from mlflow.utils.annotations import experimental
|
5
|
+
|
6
|
+
|
7
|
+
def _is_optional_dataclass(field_type) -> bool:
|
8
|
+
"""
|
9
|
+
Check if the field type is an Optional containing a dataclass.
|
10
|
+
Currently, ... | None (in Python 3.10) is not supported.
|
11
|
+
"""
|
12
|
+
if get_origin(field_type) is Union:
|
13
|
+
inner_types = get_args(field_type)
|
14
|
+
# Check if it's a Union[Dataclass, NoneType] (i.e., Optional[Dataclass])
|
15
|
+
if len(inner_types) == 2 and any(t is type(None) for t in inner_types):
|
16
|
+
effective_type = next(t for t in get_args(field_type) if t is not type(None))
|
17
|
+
return is_dataclass(effective_type)
|
18
|
+
return False
|
19
|
+
|
20
|
+
|
21
|
+
@experimental(version="2.18.0")
|
22
|
+
def _hydrate_dataclass(dataclass_type, data):
|
23
|
+
"""Recursively create an instance of the dataclass_type from data."""
|
24
|
+
if not (is_dataclass(dataclass_type) or _is_optional_dataclass(dataclass_type)):
|
25
|
+
raise ValueError(f"{dataclass_type.__name__} is not a dataclass")
|
26
|
+
if data is None:
|
27
|
+
return None
|
28
|
+
|
29
|
+
field_names = {f.name: f.type for f in fields(dataclass_type)}
|
30
|
+
kwargs = {}
|
31
|
+
for key, field_type in field_names.items():
|
32
|
+
if key in data:
|
33
|
+
value = data[key]
|
34
|
+
if is_dataclass(field_type):
|
35
|
+
kwargs[key] = _hydrate_dataclass(field_type, value)
|
36
|
+
elif _is_optional_dataclass(field_type):
|
37
|
+
effective_type = next(t for t in get_args(field_type) if t is not type(None))
|
38
|
+
kwargs[key] = _hydrate_dataclass(effective_type, value)
|
39
|
+
elif get_origin(field_type) == list:
|
40
|
+
item_type = get_args(field_type)[0]
|
41
|
+
if is_dataclass(item_type):
|
42
|
+
kwargs[key] = [_hydrate_dataclass(item_type, item) for item in value]
|
43
|
+
else:
|
44
|
+
kwargs[key] = value
|
45
|
+
else:
|
46
|
+
kwargs[key] = value
|
47
|
+
return dataclass_type(**kwargs)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
# Support unwrapped JSON with these keys for LLM use cases of Chat, Completions, Embeddings tasks
|
4
|
+
LLM_CHAT_KEY = "messages"
|
5
|
+
LLM_COMPLETIONS_KEY = "prompt"
|
6
|
+
LLM_EMBEDDINGS_KEY = "input"
|
7
|
+
SUPPORTED_LLM_FORMATS = {LLM_CHAT_KEY, LLM_COMPLETIONS_KEY, LLM_EMBEDDINGS_KEY}
|
8
|
+
|
9
|
+
|
10
|
+
def is_unified_llm_input(json_input: dict[str, Any]):
|
11
|
+
return any(x in json_input for x in SUPPORTED_LLM_FORMATS)
|