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,332 @@
|
|
1
|
+
import asyncio
|
2
|
+
import threading
|
3
|
+
import uuid
|
4
|
+
from typing import TYPE_CHECKING, Any, Optional, Union
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from llama_index.core import QueryBundle
|
8
|
+
|
9
|
+
from mlflow.models.utils import _convert_llm_input_data
|
10
|
+
|
11
|
+
CHAT_ENGINE_NAME = "chat"
|
12
|
+
QUERY_ENGINE_NAME = "query"
|
13
|
+
RETRIEVER_ENGINE_NAME = "retriever"
|
14
|
+
SUPPORTED_ENGINES = {CHAT_ENGINE_NAME, QUERY_ENGINE_NAME, RETRIEVER_ENGINE_NAME}
|
15
|
+
|
16
|
+
_CHAT_MESSAGE_HISTORY_PARAMETER_NAME = "chat_history"
|
17
|
+
|
18
|
+
|
19
|
+
def _convert_llm_input_data_with_unwrapping(data):
|
20
|
+
"""
|
21
|
+
Transforms the input data to the format expected by the LlamaIndex engine.
|
22
|
+
|
23
|
+
TODO: Migrate the unwrapping logic to mlflow.evaluate() function or _convert_llm_input_data,
|
24
|
+
# because it is not specific to LlamaIndex.
|
25
|
+
"""
|
26
|
+
data = _convert_llm_input_data(data)
|
27
|
+
|
28
|
+
# For mlflow.evaluate() call, the input dataset will be a pandas DataFrame. The DF should have
|
29
|
+
# a column named "inputs" which contains the actual query data. After the preprocessing, the
|
30
|
+
# each row will be passed here as a dictionary with the key "inputs". Therefore, we need to
|
31
|
+
# extract the actual query data from the dictionary.
|
32
|
+
if isinstance(data, dict) and ("inputs" in data):
|
33
|
+
data = data["inputs"]
|
34
|
+
|
35
|
+
return data
|
36
|
+
|
37
|
+
|
38
|
+
def _format_predict_input_query_engine_and_retriever(data) -> "QueryBundle":
|
39
|
+
"""Convert pyfunc input to a QueryBundle."""
|
40
|
+
from llama_index.core import QueryBundle
|
41
|
+
|
42
|
+
data = _convert_llm_input_data_with_unwrapping(data)
|
43
|
+
|
44
|
+
if isinstance(data, str):
|
45
|
+
return QueryBundle(query_str=data)
|
46
|
+
elif isinstance(data, dict):
|
47
|
+
return QueryBundle(**data)
|
48
|
+
elif isinstance(data, list):
|
49
|
+
# NB: handle pandas returning lists when there is a single row
|
50
|
+
prediction_input = [_format_predict_input_query_engine_and_retriever(d) for d in data]
|
51
|
+
return prediction_input if len(prediction_input) > 1 else prediction_input[0]
|
52
|
+
else:
|
53
|
+
raise ValueError(
|
54
|
+
f"Unsupported input type: {type(data)}. It must be one of "
|
55
|
+
"[str, dict, list, numpy.ndarray, pandas.DataFrame]"
|
56
|
+
)
|
57
|
+
|
58
|
+
|
59
|
+
class _LlamaIndexModelWrapperBase:
|
60
|
+
def __init__(
|
61
|
+
self,
|
62
|
+
llama_model, # Engine or Workflow
|
63
|
+
model_config: Optional[dict[str, Any]] = None,
|
64
|
+
):
|
65
|
+
self._llama_model = llama_model
|
66
|
+
self.model_config = model_config or {}
|
67
|
+
|
68
|
+
@property
|
69
|
+
def index(self):
|
70
|
+
return self._llama_model.index
|
71
|
+
|
72
|
+
def get_raw_model(self):
|
73
|
+
return self._llama_model
|
74
|
+
|
75
|
+
def _predict_single(self, *args, **kwargs) -> Any:
|
76
|
+
raise NotImplementedError
|
77
|
+
|
78
|
+
def _format_predict_input(self, data):
|
79
|
+
raise NotImplementedError
|
80
|
+
|
81
|
+
def _do_inference(self, input, params: Optional[dict[str, Any]]) -> dict[str, Any]:
|
82
|
+
"""
|
83
|
+
Perform engine inference on a single engine input e.g. not an iterable of
|
84
|
+
engine inputs. The engine inputs must already be preprocessed/cleaned.
|
85
|
+
"""
|
86
|
+
|
87
|
+
if isinstance(input, dict):
|
88
|
+
return self._predict_single(**input, **(params or {}))
|
89
|
+
else:
|
90
|
+
return self._predict_single(input, **(params or {}))
|
91
|
+
|
92
|
+
def predict(self, data, params: Optional[dict[str, Any]] = None) -> Union[list[str], str]:
|
93
|
+
data = self._format_predict_input(data)
|
94
|
+
|
95
|
+
if isinstance(data, list):
|
96
|
+
return [self._do_inference(x, params) for x in data]
|
97
|
+
else:
|
98
|
+
return self._do_inference(data, params)
|
99
|
+
|
100
|
+
|
101
|
+
class ChatEngineWrapper(_LlamaIndexModelWrapperBase):
|
102
|
+
@property
|
103
|
+
def engine_type(self):
|
104
|
+
return CHAT_ENGINE_NAME
|
105
|
+
|
106
|
+
def _predict_single(self, *args, **kwargs) -> str:
|
107
|
+
return self._llama_model.chat(*args, **kwargs).response
|
108
|
+
|
109
|
+
@staticmethod
|
110
|
+
def _convert_chat_message_history_to_chat_message_objects(
|
111
|
+
data: dict[str, Any],
|
112
|
+
) -> dict[str, Any]:
|
113
|
+
from llama_index.core.llms import ChatMessage
|
114
|
+
|
115
|
+
if chat_message_history := data.get(_CHAT_MESSAGE_HISTORY_PARAMETER_NAME):
|
116
|
+
if isinstance(chat_message_history, list):
|
117
|
+
if all(isinstance(message, dict) for message in chat_message_history):
|
118
|
+
data[_CHAT_MESSAGE_HISTORY_PARAMETER_NAME] = [
|
119
|
+
ChatMessage(**message) for message in chat_message_history
|
120
|
+
]
|
121
|
+
else:
|
122
|
+
raise ValueError(
|
123
|
+
f"Unsupported input type: {type(chat_message_history)}. "
|
124
|
+
"It must be a list of dicts."
|
125
|
+
)
|
126
|
+
|
127
|
+
return data
|
128
|
+
|
129
|
+
def _format_predict_input(self, data) -> Union[str, dict[str, Any], list[Any]]:
|
130
|
+
data = _convert_llm_input_data_with_unwrapping(data)
|
131
|
+
|
132
|
+
if isinstance(data, str):
|
133
|
+
return data
|
134
|
+
elif isinstance(data, dict):
|
135
|
+
return self._convert_chat_message_history_to_chat_message_objects(data)
|
136
|
+
elif isinstance(data, list):
|
137
|
+
# NB: handle pandas returning lists when there is a single row
|
138
|
+
prediction_input = [self._format_predict_input(d) for d in data]
|
139
|
+
return prediction_input if len(prediction_input) > 1 else prediction_input[0]
|
140
|
+
else:
|
141
|
+
raise ValueError(
|
142
|
+
f"Unsupported input type: {type(data)}. It must be one of "
|
143
|
+
"[str, dict, list, numpy.ndarray, pandas.DataFrame]"
|
144
|
+
)
|
145
|
+
|
146
|
+
|
147
|
+
class QueryEngineWrapper(_LlamaIndexModelWrapperBase):
|
148
|
+
@property
|
149
|
+
def engine_type(self):
|
150
|
+
return QUERY_ENGINE_NAME
|
151
|
+
|
152
|
+
def _predict_single(self, *args, **kwargs) -> str:
|
153
|
+
return self._llama_model.query(*args, **kwargs).response
|
154
|
+
|
155
|
+
def _format_predict_input(self, data) -> "QueryBundle":
|
156
|
+
return _format_predict_input_query_engine_and_retriever(data)
|
157
|
+
|
158
|
+
|
159
|
+
class RetrieverEngineWrapper(_LlamaIndexModelWrapperBase):
|
160
|
+
@property
|
161
|
+
def engine_type(self):
|
162
|
+
return RETRIEVER_ENGINE_NAME
|
163
|
+
|
164
|
+
def _predict_single(self, *args, **kwargs) -> list[dict[str, Any]]:
|
165
|
+
response = self._llama_model.retrieve(*args, **kwargs)
|
166
|
+
return [node.dict() for node in response]
|
167
|
+
|
168
|
+
def _format_predict_input(self, data) -> "QueryBundle":
|
169
|
+
return _format_predict_input_query_engine_and_retriever(data)
|
170
|
+
|
171
|
+
|
172
|
+
class WorkflowWrapper(_LlamaIndexModelWrapperBase):
|
173
|
+
@property
|
174
|
+
def index(self):
|
175
|
+
raise NotImplementedError("LlamaIndex Workflow does not have an index")
|
176
|
+
|
177
|
+
@property
|
178
|
+
def engine_type(self):
|
179
|
+
raise NotImplementedError("LlamaIndex Workflow is not an engine")
|
180
|
+
|
181
|
+
def predict(self, data, params: Optional[dict[str, Any]] = None) -> Union[list[str], str]:
|
182
|
+
inputs = self._format_predict_input(data, params)
|
183
|
+
|
184
|
+
# LlamaIndex Workflow runs async but MLflow pyfunc doesn't support async inference yet.
|
185
|
+
predictions = self._wait_async_task(self._run_predictions(inputs))
|
186
|
+
|
187
|
+
# Even if the input is single instance, the signature enforcement convert it to a Pandas
|
188
|
+
# DataFrame with a single row. In this case, we should unwrap the result (list) so it
|
189
|
+
# won't be inconsistent with the output without signature enforcement.
|
190
|
+
should_unwrap = len(data) == 1 and isinstance(predictions, list)
|
191
|
+
return predictions[0] if should_unwrap else predictions
|
192
|
+
|
193
|
+
def _format_predict_input(
|
194
|
+
self, data, params: Optional[dict[str, Any]] = None
|
195
|
+
) -> list[dict[str, Any]]:
|
196
|
+
inputs = _convert_llm_input_data_with_unwrapping(data)
|
197
|
+
params = params or {}
|
198
|
+
if isinstance(inputs, dict):
|
199
|
+
return [{**inputs, **params}]
|
200
|
+
return [{**x, **params} for x in inputs]
|
201
|
+
|
202
|
+
async def _run_predictions(self, inputs: list[dict[str, Any]]) -> asyncio.Future:
|
203
|
+
tasks = [self._predict_single(x) for x in inputs]
|
204
|
+
return await asyncio.gather(*tasks)
|
205
|
+
|
206
|
+
async def _predict_single(self, x: dict[str, Any]) -> Any:
|
207
|
+
if not isinstance(x, dict):
|
208
|
+
raise ValueError(f"Unsupported input type: {type(x)}. It must be a dictionary.")
|
209
|
+
return await self._llama_model.run(**x)
|
210
|
+
|
211
|
+
def _wait_async_task(self, task: asyncio.Future) -> Any:
|
212
|
+
"""
|
213
|
+
A utility function to run async tasks in a blocking manner.
|
214
|
+
|
215
|
+
If there is no event loop running already, for example, in a model serving endpoint,
|
216
|
+
we can simply create a new event loop and run the task there. However, in a notebook
|
217
|
+
environment (or pytest with asyncio decoration), there is already an event loop running
|
218
|
+
at the root level and we cannot start a new one.
|
219
|
+
"""
|
220
|
+
if not self._is_event_loop_running():
|
221
|
+
return asyncio.new_event_loop().run_until_complete(task)
|
222
|
+
else:
|
223
|
+
# NB: The popular way to run async task where an event loop is already running is to
|
224
|
+
# use nest_asyncio. However, nest_asyncio.apply() breaks the async OpenAI client
|
225
|
+
# somehow, which is used for the most of LLM calls in LlamaIndex including Databricks
|
226
|
+
# LLMs. Therefore, we use a hacky workaround that creates a new thread and run the
|
227
|
+
# new event loop there. This may degrade the performance compared to the native
|
228
|
+
# asyncio, but it should be fine because this is only used in the notebook env.
|
229
|
+
results = None
|
230
|
+
exception = None
|
231
|
+
|
232
|
+
def _run():
|
233
|
+
nonlocal results, exception
|
234
|
+
|
235
|
+
try:
|
236
|
+
loop = asyncio.new_event_loop()
|
237
|
+
asyncio.set_event_loop(loop)
|
238
|
+
results = loop.run_until_complete(task)
|
239
|
+
except Exception as e:
|
240
|
+
exception = e
|
241
|
+
finally:
|
242
|
+
loop.close()
|
243
|
+
|
244
|
+
thread = threading.Thread(
|
245
|
+
target=_run, name=f"mlflow_llamaindex_async_task_runner_{uuid.uuid4().hex[:8]}"
|
246
|
+
)
|
247
|
+
thread.start()
|
248
|
+
thread.join()
|
249
|
+
|
250
|
+
if exception:
|
251
|
+
raise exception
|
252
|
+
|
253
|
+
return results
|
254
|
+
|
255
|
+
def _is_event_loop_running(self) -> bool:
|
256
|
+
try:
|
257
|
+
loop = asyncio.get_running_loop()
|
258
|
+
return loop is not None
|
259
|
+
except Exception:
|
260
|
+
return False
|
261
|
+
|
262
|
+
|
263
|
+
def create_pyfunc_wrapper(
|
264
|
+
model: Any,
|
265
|
+
engine_type: Optional[str] = None,
|
266
|
+
model_config: Optional[dict[str, Any]] = None,
|
267
|
+
):
|
268
|
+
"""
|
269
|
+
A factory function that creates a Pyfunc wrapper around a LlamaIndex index/engine/workflow.
|
270
|
+
|
271
|
+
Args:
|
272
|
+
model: A LlamaIndex index/engine/workflow.
|
273
|
+
engine_type: The type of the engine. Only required if `model` is an index
|
274
|
+
and must be one of [chat, query, retriever].
|
275
|
+
model_config: A dictionary of model configuration parameters.
|
276
|
+
"""
|
277
|
+
try:
|
278
|
+
from llama_index.core.workflow import Workflow
|
279
|
+
|
280
|
+
if isinstance(model, Workflow):
|
281
|
+
return _create_wrapper_from_workflow(model, model_config)
|
282
|
+
except ImportError:
|
283
|
+
pass
|
284
|
+
|
285
|
+
from llama_index.core.indices.base import BaseIndex
|
286
|
+
|
287
|
+
if isinstance(model, BaseIndex):
|
288
|
+
return _create_wrapper_from_index(model, engine_type, model_config)
|
289
|
+
else:
|
290
|
+
# Engine does not have a common base class so we assume
|
291
|
+
# everything else is an engine
|
292
|
+
return _create_wrapper_from_engine(model, model_config)
|
293
|
+
|
294
|
+
|
295
|
+
def _create_wrapper_from_index(
|
296
|
+
index, engine_type: str, model_config: Optional[dict[str, Any]] = None
|
297
|
+
):
|
298
|
+
model_config = model_config or {}
|
299
|
+
if engine_type == QUERY_ENGINE_NAME:
|
300
|
+
engine = index.as_query_engine(**model_config)
|
301
|
+
return QueryEngineWrapper(engine, model_config)
|
302
|
+
elif engine_type == CHAT_ENGINE_NAME:
|
303
|
+
engine = index.as_chat_engine(**model_config)
|
304
|
+
return ChatEngineWrapper(engine, model_config)
|
305
|
+
elif engine_type == RETRIEVER_ENGINE_NAME:
|
306
|
+
engine = index.as_retriever(**model_config)
|
307
|
+
return RetrieverEngineWrapper(engine, model_config)
|
308
|
+
else:
|
309
|
+
raise ValueError(
|
310
|
+
f"Unsupported engine type: {engine_type}. It must be one of {SUPPORTED_ENGINES}"
|
311
|
+
)
|
312
|
+
|
313
|
+
|
314
|
+
def _create_wrapper_from_engine(engine: Any, model_config: Optional[dict[str, Any]] = None):
|
315
|
+
from llama_index.core.base.base_query_engine import BaseQueryEngine
|
316
|
+
from llama_index.core.chat_engine.types import BaseChatEngine
|
317
|
+
from llama_index.core.retrievers import BaseRetriever
|
318
|
+
|
319
|
+
if isinstance(engine, BaseChatEngine):
|
320
|
+
return ChatEngineWrapper(engine, model_config)
|
321
|
+
elif isinstance(engine, BaseQueryEngine):
|
322
|
+
return QueryEngineWrapper(engine, model_config)
|
323
|
+
elif isinstance(engine, BaseRetriever):
|
324
|
+
return RetrieverEngineWrapper(engine, model_config)
|
325
|
+
else:
|
326
|
+
raise ValueError(
|
327
|
+
f"Unsupported engine type: {type(engine)}. It must be one of {SUPPORTED_ENGINES}"
|
328
|
+
)
|
329
|
+
|
330
|
+
|
331
|
+
def _create_wrapper_from_workflow(workflow: Any, model_config: Optional[dict[str, Any]] = None):
|
332
|
+
return WorkflowWrapper(workflow, model_config)
|
@@ -0,0 +1,188 @@
|
|
1
|
+
import importlib
|
2
|
+
import inspect
|
3
|
+
import json
|
4
|
+
import logging
|
5
|
+
from typing import Any, Callable
|
6
|
+
|
7
|
+
from llama_index.core import PromptTemplate
|
8
|
+
from llama_index.core.base.embeddings.base import BaseEmbedding
|
9
|
+
from llama_index.core.callbacks.base import CallbackManager
|
10
|
+
from llama_index.core.schema import BaseComponent
|
11
|
+
|
12
|
+
_logger = logging.getLogger(__name__)
|
13
|
+
|
14
|
+
|
15
|
+
def _get_object_import_path(o: object) -> str:
|
16
|
+
if not inspect.isclass(o):
|
17
|
+
o = o.__class__
|
18
|
+
|
19
|
+
module_name = inspect.getmodule(o).__name__
|
20
|
+
class_name = o.__qualname__
|
21
|
+
|
22
|
+
# Validate the import
|
23
|
+
module = importlib.import_module(module_name)
|
24
|
+
if not hasattr(module, class_name):
|
25
|
+
raise ValueError(f"Module {module} does not have {class_name}")
|
26
|
+
|
27
|
+
return f"{module_name}.{class_name}"
|
28
|
+
|
29
|
+
|
30
|
+
def _sanitize_api_key(object_as_dict: dict[str, str]) -> dict[str, str]:
|
31
|
+
return {k: v for k, v in object_as_dict.items() if "api_key" not in k.lower()}
|
32
|
+
|
33
|
+
|
34
|
+
def object_to_dict(o: object):
|
35
|
+
if isinstance(o, (list, tuple)):
|
36
|
+
return [object_to_dict(v) for v in o]
|
37
|
+
|
38
|
+
if isinstance(o, BaseComponent):
|
39
|
+
# we can't serialize callables in the model fields
|
40
|
+
callable_fields = set()
|
41
|
+
fields = o.model_fields if hasattr(o, "model_fields") else o.__fields__
|
42
|
+
for k, v in fields.items():
|
43
|
+
field_val = getattr(o, k, None)
|
44
|
+
if field_val != v.default and callable(field_val):
|
45
|
+
callable_fields.add(k)
|
46
|
+
# exclude default values from serialization to avoid
|
47
|
+
# unnecessary clutter in the serialized object
|
48
|
+
o_state_as_dict = o.to_dict(exclude=callable_fields)
|
49
|
+
|
50
|
+
if o_state_as_dict != {}:
|
51
|
+
o_state_as_dict = _sanitize_api_key(o_state_as_dict)
|
52
|
+
o_state_as_dict.pop("class_name")
|
53
|
+
else:
|
54
|
+
return o_state_as_dict
|
55
|
+
|
56
|
+
return {
|
57
|
+
"object_constructor": _get_object_import_path(o),
|
58
|
+
"object_kwargs": o_state_as_dict,
|
59
|
+
}
|
60
|
+
else:
|
61
|
+
return None
|
62
|
+
|
63
|
+
|
64
|
+
def _construct_prompt_template_object(
|
65
|
+
constructor: Callable[..., PromptTemplate], kwargs: dict[str, Any]
|
66
|
+
) -> PromptTemplate:
|
67
|
+
"""Construct a PromptTemplate object based on the constructor and kwargs.
|
68
|
+
|
69
|
+
This method is necessary because the `template_vars` cannot be passed directly to the
|
70
|
+
constructor and needs to be set on an instantiated object.
|
71
|
+
"""
|
72
|
+
if template := kwargs.pop("template", None):
|
73
|
+
prompt_template = constructor(template)
|
74
|
+
for k, v in kwargs.items():
|
75
|
+
setattr(prompt_template, k, v)
|
76
|
+
|
77
|
+
return prompt_template
|
78
|
+
else:
|
79
|
+
raise ValueError(
|
80
|
+
"'template' is a required kwargs and is not present in the prompt template kwargs."
|
81
|
+
)
|
82
|
+
|
83
|
+
|
84
|
+
def dict_to_object(object_representation: dict[str, Any]) -> object:
|
85
|
+
if "object_constructor" not in object_representation:
|
86
|
+
raise ValueError("'object_constructor' key not found in dict.")
|
87
|
+
if "object_kwargs" not in object_representation:
|
88
|
+
raise ValueError("'object_kwargs' key not found in dict.")
|
89
|
+
|
90
|
+
constructor_str = object_representation["object_constructor"]
|
91
|
+
kwargs = object_representation["object_kwargs"]
|
92
|
+
|
93
|
+
import_path, class_name = constructor_str.rsplit(".", 1)
|
94
|
+
module = importlib.import_module(import_path)
|
95
|
+
|
96
|
+
if isinstance(module, PromptTemplate):
|
97
|
+
return _construct_prompt_template_object(module, kwargs)
|
98
|
+
else:
|
99
|
+
object_class = getattr(module, class_name)
|
100
|
+
|
101
|
+
# Many embeddings model accepts parameter `model`, while BaseEmbedding accepts `model_name`.
|
102
|
+
# Both parameters will be serialized as kwargs, but passing both to the constructor will
|
103
|
+
# raise duplicate argument error. Some class like OpenAIEmbedding handles this in its
|
104
|
+
# constructor, but not all integrations do. Therefore, we have to handle it here.
|
105
|
+
# E.g. https://github.com/run-llama/llama_index/blob/2b18eb4654b14c68d63f6239cddb10740668fbc8/llama-index-integrations/embeddings/llama-index-embeddings-openai/llama_index/embeddings/openai/base.py#L316-L320
|
106
|
+
if (
|
107
|
+
issubclass(object_class, BaseEmbedding)
|
108
|
+
and (model := kwargs.get("model"))
|
109
|
+
and (model_name := kwargs.get("model_name"))
|
110
|
+
and model == model_name
|
111
|
+
):
|
112
|
+
kwargs.pop("model_name")
|
113
|
+
|
114
|
+
return object_class.from_dict(kwargs)
|
115
|
+
|
116
|
+
|
117
|
+
def _deserialize_dict_of_objects(path: str) -> dict[str, Any]:
|
118
|
+
with open(path) as f:
|
119
|
+
to_deserialize = json.load(f)
|
120
|
+
|
121
|
+
output = {}
|
122
|
+
for k, v in to_deserialize.items():
|
123
|
+
if isinstance(v, list):
|
124
|
+
output.update({k: [dict_to_object(vv) for vv in v]})
|
125
|
+
else:
|
126
|
+
output.update({k: dict_to_object(v)})
|
127
|
+
|
128
|
+
return output
|
129
|
+
|
130
|
+
|
131
|
+
def serialize_settings(path: str) -> None:
|
132
|
+
"""Serialize the global LlamaIndex Settings object to a JSON file at the given path."""
|
133
|
+
from llama_index.core import Settings
|
134
|
+
|
135
|
+
_logger.info(
|
136
|
+
"API key(s) will be removed from the global Settings object during serialization "
|
137
|
+
"to protect against key leakage. At inference time, the key(s) must be passed as "
|
138
|
+
"environment variables."
|
139
|
+
)
|
140
|
+
|
141
|
+
to_serialize = {}
|
142
|
+
unsupported_objects = []
|
143
|
+
|
144
|
+
for k, v in Settings.__dict__.items():
|
145
|
+
if v is None:
|
146
|
+
continue
|
147
|
+
|
148
|
+
# Setting.callback_manager is default to an empty CallbackManager instance.
|
149
|
+
if (k == "_callback_manager") and isinstance(v, CallbackManager) and v.handlers == []:
|
150
|
+
continue
|
151
|
+
|
152
|
+
def _convert(obj):
|
153
|
+
object_json = object_to_dict(obj)
|
154
|
+
if object_json is None:
|
155
|
+
prop_name = k[1:] if k.startswith("_") else k
|
156
|
+
unsupported_objects.append((prop_name, v))
|
157
|
+
return object_json
|
158
|
+
|
159
|
+
if isinstance(v, list):
|
160
|
+
to_serialize[k] = [_convert(obj) for obj in v if v is not None]
|
161
|
+
else:
|
162
|
+
if (object_json := _convert(v)) and (object_json is not None):
|
163
|
+
to_serialize[k] = object_json
|
164
|
+
|
165
|
+
if unsupported_objects:
|
166
|
+
msg = (
|
167
|
+
"The following objects in Settings are not supported for serialization and will not "
|
168
|
+
"be logged with your model. MLflow only supports serialization of objects that inherit "
|
169
|
+
"from llama_index.core.schema.BaseComponent.\n"
|
170
|
+
)
|
171
|
+
msg += "\n".join(f" - {type(v).__name__} for Settings.{k}" for k, v in unsupported_objects)
|
172
|
+
_logger.info(msg)
|
173
|
+
|
174
|
+
with open(path, "w") as f:
|
175
|
+
json.dump(to_serialize, f, indent=2)
|
176
|
+
|
177
|
+
|
178
|
+
def deserialize_settings(path: str):
|
179
|
+
"""Deserialize the global LlamaIndex Settings object from a JSON file at the given path."""
|
180
|
+
settings_dict = _deserialize_dict_of_objects(path)
|
181
|
+
|
182
|
+
from llama_index.core import Settings
|
183
|
+
|
184
|
+
for k, v in settings_dict.items():
|
185
|
+
# To use the property setter rather than directly setting the private attribute e.g. _llm
|
186
|
+
if k.startswith("_"):
|
187
|
+
k = k[1:]
|
188
|
+
setattr(Settings, k, v)
|