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,138 @@
|
|
1
|
+
# This file contains utility functions for scorer functionality.
|
2
|
+
|
3
|
+
import ast
|
4
|
+
import inspect
|
5
|
+
import logging
|
6
|
+
import re
|
7
|
+
from textwrap import dedent
|
8
|
+
from typing import Any, Callable, Optional
|
9
|
+
|
10
|
+
_logger = logging.getLogger(__name__)
|
11
|
+
|
12
|
+
|
13
|
+
# FunctionBodyExtractor class is forked from https://github.com/unitycatalog/unitycatalog/blob/20dd3820be332ac04deec4e063099fb863eb3392/ai/core/src/unitycatalog/ai/core/utils/callable_utils.py
|
14
|
+
class FunctionBodyExtractor(ast.NodeVisitor):
|
15
|
+
"""
|
16
|
+
AST NodeVisitor class to extract the body of a function.
|
17
|
+
"""
|
18
|
+
|
19
|
+
def __init__(self, func_name: str, source_code: str):
|
20
|
+
self.func_name = func_name
|
21
|
+
self.source_code = source_code
|
22
|
+
self.function_body = ""
|
23
|
+
self.indent_unit = 4
|
24
|
+
self.found = False
|
25
|
+
|
26
|
+
def visit_FunctionDef(self, node: ast.FunctionDef):
|
27
|
+
if not self.found and node.name == self.func_name:
|
28
|
+
self.found = True
|
29
|
+
self.extract_body(node)
|
30
|
+
|
31
|
+
def extract_body(self, node: ast.FunctionDef):
|
32
|
+
body = node.body
|
33
|
+
# Skip the docstring
|
34
|
+
if (
|
35
|
+
body
|
36
|
+
and isinstance(body[0], ast.Expr)
|
37
|
+
and isinstance(body[0].value, ast.Constant)
|
38
|
+
and isinstance(body[0].value.value, str)
|
39
|
+
):
|
40
|
+
body = body[1:]
|
41
|
+
|
42
|
+
if not body:
|
43
|
+
return
|
44
|
+
|
45
|
+
start_lineno = body[0].lineno
|
46
|
+
end_lineno = body[-1].end_lineno
|
47
|
+
|
48
|
+
source_lines = self.source_code.splitlines(keepends=True)
|
49
|
+
function_body_lines = source_lines[start_lineno - 1 : end_lineno]
|
50
|
+
|
51
|
+
self.function_body = dedent("".join(function_body_lines)).rstrip("\n")
|
52
|
+
|
53
|
+
indents = [stmt.col_offset for stmt in body if stmt.col_offset is not None]
|
54
|
+
if indents:
|
55
|
+
self.indent_unit = min(indents)
|
56
|
+
|
57
|
+
|
58
|
+
# extract_function_body function is forked from https://github.com/unitycatalog/unitycatalog/blob/20dd3820be332ac04deec4e063099fb863eb3392/ai/core/src/unitycatalog/ai/core/utils/callable_utils.py
|
59
|
+
def extract_function_body(func: Callable[..., Any]) -> tuple[str, int]:
|
60
|
+
"""
|
61
|
+
Extracts the body of a function as a string without the signature or docstring,
|
62
|
+
dedents the code, and returns the indentation unit used in the function (e.g., 2 or 4 spaces).
|
63
|
+
"""
|
64
|
+
source_lines, _ = inspect.getsourcelines(func)
|
65
|
+
dedented_source = dedent("".join(source_lines))
|
66
|
+
func_name = func.__name__
|
67
|
+
|
68
|
+
extractor = FunctionBodyExtractor(func_name, dedented_source)
|
69
|
+
parsed_source = ast.parse(dedented_source)
|
70
|
+
extractor.visit(parsed_source)
|
71
|
+
|
72
|
+
return extractor.function_body, extractor.indent_unit
|
73
|
+
|
74
|
+
|
75
|
+
def recreate_function(source: str, signature: str, func_name: str) -> Optional[Callable[..., Any]]:
|
76
|
+
"""
|
77
|
+
Recreate a function from its source code, signature, and name.
|
78
|
+
|
79
|
+
Args:
|
80
|
+
source: The function body source code.
|
81
|
+
signature: The function signature string (e.g., "(inputs, outputs)").
|
82
|
+
func_name: The name of the function.
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
The recreated function or None if recreation failed.
|
86
|
+
"""
|
87
|
+
try:
|
88
|
+
# Parse the signature to build the function definition
|
89
|
+
sig_match = re.match(r"\((.*?)\)", signature)
|
90
|
+
if not sig_match:
|
91
|
+
return None
|
92
|
+
|
93
|
+
params_str = sig_match.group(1).strip()
|
94
|
+
|
95
|
+
# Build the function definition
|
96
|
+
func_def = f"def {func_name}({params_str}):\n"
|
97
|
+
# Indent the source code
|
98
|
+
indented_source = "\n".join(f" {line}" for line in source.split("\n"))
|
99
|
+
func_def += indented_source
|
100
|
+
|
101
|
+
# Create a namespace with common MLflow imports that scorer functions might use
|
102
|
+
import_namespace = {}
|
103
|
+
|
104
|
+
# Import commonly used MLflow classes
|
105
|
+
try:
|
106
|
+
from mlflow.entities import (
|
107
|
+
Assessment,
|
108
|
+
AssessmentError,
|
109
|
+
AssessmentSource,
|
110
|
+
AssessmentSourceType,
|
111
|
+
Feedback,
|
112
|
+
)
|
113
|
+
from mlflow.genai.judges import CategoricalRating
|
114
|
+
|
115
|
+
import_namespace.update(
|
116
|
+
{
|
117
|
+
"Feedback": Feedback,
|
118
|
+
"Assessment": Assessment,
|
119
|
+
"AssessmentSource": AssessmentSource,
|
120
|
+
"AssessmentError": AssessmentError,
|
121
|
+
"AssessmentSourceType": AssessmentSourceType,
|
122
|
+
"CategoricalRating": CategoricalRating,
|
123
|
+
}
|
124
|
+
)
|
125
|
+
except ImportError:
|
126
|
+
pass # Some imports might not be available in all contexts
|
127
|
+
|
128
|
+
local_namespace = {}
|
129
|
+
|
130
|
+
# Execute the function definition with MLflow imports available
|
131
|
+
exec(func_def, import_namespace, local_namespace)
|
132
|
+
|
133
|
+
# Return the recreated function
|
134
|
+
return local_namespace[func_name]
|
135
|
+
|
136
|
+
except Exception:
|
137
|
+
_logger.warning(f"Failed to recreate function '{func_name}' from serialized source code")
|
138
|
+
return None
|
@@ -0,0 +1,165 @@
|
|
1
|
+
import logging
|
2
|
+
from collections import defaultdict
|
3
|
+
from typing import Any, Callable, Optional
|
4
|
+
|
5
|
+
from mlflow.exceptions import MlflowException
|
6
|
+
from mlflow.genai.scorers.base import Scorer
|
7
|
+
from mlflow.genai.scorers.builtin_scorers import (
|
8
|
+
BuiltInScorer,
|
9
|
+
MissingColumnsException,
|
10
|
+
get_all_scorers,
|
11
|
+
)
|
12
|
+
|
13
|
+
try:
|
14
|
+
# `pandas` is not required for `mlflow-skinny`.
|
15
|
+
import pandas as pd
|
16
|
+
except ImportError:
|
17
|
+
pass
|
18
|
+
|
19
|
+
_logger = logging.getLogger(__name__)
|
20
|
+
|
21
|
+
|
22
|
+
def validate_scorers(scorers: list[Any]) -> list[Scorer]:
|
23
|
+
"""
|
24
|
+
Validate a list of specified scorers.
|
25
|
+
|
26
|
+
Args:
|
27
|
+
scorers: A list of scorers to validate.
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
A list of valid scorers.
|
31
|
+
"""
|
32
|
+
from databricks.rag_eval.evaluation.metrics import Metric
|
33
|
+
|
34
|
+
if not isinstance(scorers, list) or len(scorers) == 0:
|
35
|
+
raise MlflowException.invalid_parameter_value(
|
36
|
+
"The `scorers` argument must be a list of scorers with at least one scorer. "
|
37
|
+
"If you are unsure about which scorer to use, you can specify "
|
38
|
+
"`scorers=mlflow.genai.scorers.get_all_scorers()` to jump start with all "
|
39
|
+
"available built-in scorers."
|
40
|
+
)
|
41
|
+
|
42
|
+
valid_scorers = []
|
43
|
+
legacy_metrics = []
|
44
|
+
|
45
|
+
for scorer in scorers:
|
46
|
+
if isinstance(scorer, Scorer):
|
47
|
+
valid_scorers.append(scorer)
|
48
|
+
elif isinstance(scorer, Metric):
|
49
|
+
legacy_metrics.append(scorer)
|
50
|
+
valid_scorers.append(scorer)
|
51
|
+
else:
|
52
|
+
# Show helpful error message for common mistakes
|
53
|
+
if isinstance(scorer, list) and (scorer == get_all_scorers()):
|
54
|
+
# Common mistake 1: scorers=[get_all_scorers()]
|
55
|
+
if len(scorers) == 1:
|
56
|
+
hint = (
|
57
|
+
"\nHint: Use `scorers=get_all_scorers()` to pass all "
|
58
|
+
"builtin scorers at once."
|
59
|
+
)
|
60
|
+
# Common mistake 2: scorers=[get_all_scorers(), scorer1, scorer2]
|
61
|
+
elif len(scorer) > 1:
|
62
|
+
hint = (
|
63
|
+
"\nHint: Use `scorers=[*get_all_scorers(), scorer1, scorer2]` to pass "
|
64
|
+
"all builtin scorers at once along with your custom scorers."
|
65
|
+
)
|
66
|
+
# Common mistake 3: scorers=[RetrievalRelevance, Correctness]
|
67
|
+
elif isinstance(scorer, type) and issubclass(scorer, BuiltInScorer):
|
68
|
+
hint = (
|
69
|
+
"\nHint: It looks like you passed a scorer class instead of an instance. "
|
70
|
+
f"Correct way to pass scorers is `scorers=[{scorer.__name__}()]`."
|
71
|
+
)
|
72
|
+
else:
|
73
|
+
hint = ""
|
74
|
+
|
75
|
+
raise MlflowException.invalid_parameter_value(
|
76
|
+
f"The `scorers` argument must be a list of scorers. The specified "
|
77
|
+
f"list contains an invalid item with type: {type(scorer).__name__}."
|
78
|
+
f"{hint}"
|
79
|
+
)
|
80
|
+
|
81
|
+
if legacy_metrics:
|
82
|
+
legacy_metric_names = [metric.name for metric in legacy_metrics]
|
83
|
+
_logger.warning(
|
84
|
+
f"Scorers {legacy_metric_names} are legacy metrics and will soon be deprecated "
|
85
|
+
"in future releases. Please use the builtin scorers defined in `mlflow.genai.scorers` "
|
86
|
+
"or custom scorers defined with the @scorer decorator instead."
|
87
|
+
)
|
88
|
+
|
89
|
+
return valid_scorers
|
90
|
+
|
91
|
+
|
92
|
+
def valid_data_for_builtin_scorers(
|
93
|
+
data: "pd.DataFrame",
|
94
|
+
builtin_scorers: list[BuiltInScorer],
|
95
|
+
predict_fn: Optional[Callable[..., Any]] = None,
|
96
|
+
) -> None:
|
97
|
+
"""
|
98
|
+
Validate that the required columns are present in the data for running the builtin scorers.
|
99
|
+
|
100
|
+
Args:
|
101
|
+
data: The data to validate. This must be a pandas DataFrame converted to
|
102
|
+
the legacy evaluation set schema via `_convert_to_legacy_eval_set`.
|
103
|
+
builtin_scorers: The list of builtin scorers to validate the data for.
|
104
|
+
predict_fn: The predict function to validate the data for.
|
105
|
+
"""
|
106
|
+
input_columns = set(data.columns.tolist())
|
107
|
+
|
108
|
+
# Revert the replacement of "inputs"->"request" and "outputs"->"response"
|
109
|
+
# in the upstream processing.
|
110
|
+
if "request" in input_columns:
|
111
|
+
input_columns.remove("request")
|
112
|
+
input_columns.add("inputs")
|
113
|
+
if "response" in input_columns:
|
114
|
+
input_columns.remove("response")
|
115
|
+
input_columns.add("outputs")
|
116
|
+
|
117
|
+
if predict_fn is not None:
|
118
|
+
# If the predict function is provided, the data doesn't need to
|
119
|
+
# contain the "outputs" column.
|
120
|
+
input_columns.add("outputs")
|
121
|
+
|
122
|
+
if "trace" in input_columns:
|
123
|
+
# Inputs and outputs are inferred from the trace.
|
124
|
+
input_columns |= {"inputs", "outputs"}
|
125
|
+
|
126
|
+
if predict_fn is not None:
|
127
|
+
input_columns |= {"trace"}
|
128
|
+
|
129
|
+
# Explode keys in the "expectations" column for easier processing.
|
130
|
+
if "expectations" in input_columns:
|
131
|
+
for value in data["expectations"].values:
|
132
|
+
if pd.isna(value):
|
133
|
+
continue
|
134
|
+
if not isinstance(value, dict):
|
135
|
+
raise MlflowException.invalid_parameter_value(
|
136
|
+
"The 'expectations' column must be a dictionary of each expectation name "
|
137
|
+
"to its value. For example, `{'expected_response': 'answer to the question'}`."
|
138
|
+
)
|
139
|
+
for k in value:
|
140
|
+
input_columns.add(f"expectations/{k}")
|
141
|
+
|
142
|
+
# Missing column -> list of scorers that require the column.
|
143
|
+
missing_col_to_scorers = defaultdict(list)
|
144
|
+
for scorer in builtin_scorers:
|
145
|
+
try:
|
146
|
+
scorer.validate_columns(input_columns)
|
147
|
+
except MissingColumnsException as e:
|
148
|
+
for col in e.missing_columns:
|
149
|
+
missing_col_to_scorers[col].append(scorer.name)
|
150
|
+
|
151
|
+
if missing_col_to_scorers:
|
152
|
+
msg = (
|
153
|
+
"The input data is missing following columns that are required by the specified "
|
154
|
+
"scorers. The results will be null for those scorers."
|
155
|
+
)
|
156
|
+
for col, scorers in missing_col_to_scorers.items():
|
157
|
+
if col.startswith("expectations/"):
|
158
|
+
col = col.replace("expectations/", "")
|
159
|
+
msg += (
|
160
|
+
f"\n - `{col}` field in `expectations` column "
|
161
|
+
f"is required by [{', '.join(scorers)}]."
|
162
|
+
)
|
163
|
+
else:
|
164
|
+
msg += f"\n - `{col}` column is required by [{', '.join(scorers)}]."
|
165
|
+
_logger.info(msg)
|
@@ -0,0 +1,146 @@
|
|
1
|
+
import inspect
|
2
|
+
import logging
|
3
|
+
from typing import Any, Callable
|
4
|
+
|
5
|
+
from mlflow.exceptions import MlflowException
|
6
|
+
from mlflow.tracing.provider import trace_disabled
|
7
|
+
|
8
|
+
_logger = logging.getLogger(__name__)
|
9
|
+
|
10
|
+
|
11
|
+
def check_model_prediction(predict_fn: Callable[..., Any], sample_input: Any):
|
12
|
+
"""
|
13
|
+
Validate if the predict function executes properly with the provided input.
|
14
|
+
|
15
|
+
Args:
|
16
|
+
predict_fn: The predict function to be evaluated.
|
17
|
+
sample_input: A sample input to the model.
|
18
|
+
"""
|
19
|
+
_logger.info("Testing model prediction with the first sample in the dataset.")
|
20
|
+
|
21
|
+
# Wrap the function to add a decorator for disabling tracing
|
22
|
+
@trace_disabled
|
23
|
+
def _check():
|
24
|
+
predict_fn(**sample_input)
|
25
|
+
|
26
|
+
try:
|
27
|
+
_check()
|
28
|
+
except Exception as e:
|
29
|
+
# Check input format and raise friendly message for typical error patterns
|
30
|
+
_validate_function_and_input_compatibility(predict_fn, sample_input, e)
|
31
|
+
_logger.debug(f"Failed to run predict_fn with input: {sample_input}", exc_info=True)
|
32
|
+
|
33
|
+
|
34
|
+
def _validate_function_and_input_compatibility(
|
35
|
+
predict_fn: Callable[..., Any], sample_input: dict[str, Any], e: Exception
|
36
|
+
) -> Callable[..., Any]:
|
37
|
+
"""
|
38
|
+
Validate the data format in the input column against the predict_fn.
|
39
|
+
|
40
|
+
The input column must contain a dictionary of field names and values. When the
|
41
|
+
predict_fn is provided, the field names must match the arguments of the predict_fn.
|
42
|
+
"""
|
43
|
+
params = inspect.signature(predict_fn).parameters
|
44
|
+
if not params:
|
45
|
+
raise MlflowException.invalid_parameter_value(
|
46
|
+
"`predict_fn` must accept at least one argument."
|
47
|
+
) from e
|
48
|
+
|
49
|
+
# Check for *args-style parameters which aren't supported
|
50
|
+
_validate_no_var_args(params, e)
|
51
|
+
|
52
|
+
# Check if input keys match function parameters
|
53
|
+
_validate_input_keys_match_function_params(params, sample_input.keys(), e)
|
54
|
+
|
55
|
+
# For other errors, show a generic error message
|
56
|
+
raise MlflowException.invalid_parameter_value(
|
57
|
+
"Failed to run the prediction function specified in the `predict_fn` "
|
58
|
+
f"parameter. Input: {sample_input}. Error: {e}\n\n"
|
59
|
+
) from e
|
60
|
+
|
61
|
+
|
62
|
+
def _has_variable_positional_arguments(params: inspect.Signature) -> bool:
|
63
|
+
"""Check if the function has variable positional arguments."""
|
64
|
+
return any(p.kind == inspect.Parameter.VAR_POSITIONAL for p in params.values())
|
65
|
+
|
66
|
+
|
67
|
+
def _validate_no_var_args(params: inspect.Signature, e: Exception):
|
68
|
+
if not any(p.kind == inspect.Parameter.VAR_POSITIONAL for p in params.values()):
|
69
|
+
return
|
70
|
+
|
71
|
+
"""Raise an error for functions using *args which aren't supported."""
|
72
|
+
code_sample = """```python
|
73
|
+
def predict_fn(param1, param2):
|
74
|
+
# Invoke the original predict function with positional arguments
|
75
|
+
return fn(param1, param2)
|
76
|
+
|
77
|
+
data = [
|
78
|
+
{
|
79
|
+
"inputs": {
|
80
|
+
"param1": "value1",
|
81
|
+
"param2": "value2",
|
82
|
+
}
|
83
|
+
}
|
84
|
+
]
|
85
|
+
|
86
|
+
mlflow.genai.evaluate(predict_fn=predict_fn, data=data, ...)
|
87
|
+
```
|
88
|
+
"""
|
89
|
+
|
90
|
+
raise MlflowException.invalid_parameter_value(
|
91
|
+
"The `predict_fn` has dynamic positional arguments (e.g. `*args`), "
|
92
|
+
"so it cannot be used as a `predict_fn`. Please wrap it into another "
|
93
|
+
"function that accepts explicit keyword arguments.\n"
|
94
|
+
f"Example:\n\n{code_sample}\n"
|
95
|
+
) from e
|
96
|
+
|
97
|
+
|
98
|
+
def _validate_input_keys_match_function_params(
|
99
|
+
params: inspect.Signature,
|
100
|
+
input_keys: list[str],
|
101
|
+
e: Exception,
|
102
|
+
):
|
103
|
+
if _has_required_keyword_arguments(params, input_keys):
|
104
|
+
return
|
105
|
+
|
106
|
+
"""Raise an error when input keys don't match function parameters."""
|
107
|
+
param_names = list(params.keys())
|
108
|
+
input_example = {arg: f"value{i + 1}" for i, arg in enumerate(param_names[:3])}
|
109
|
+
|
110
|
+
if len(param_names) > 3:
|
111
|
+
input_example["..."] = "..."
|
112
|
+
|
113
|
+
code_sample = "\n".join(
|
114
|
+
[
|
115
|
+
"```python",
|
116
|
+
"data = [",
|
117
|
+
" {",
|
118
|
+
' "inputs": {',
|
119
|
+
*(f' "{k}": "{v}",' for k, v in input_example.items()),
|
120
|
+
" }",
|
121
|
+
" }",
|
122
|
+
"]",
|
123
|
+
"```",
|
124
|
+
]
|
125
|
+
)
|
126
|
+
|
127
|
+
raise MlflowException.invalid_parameter_value(
|
128
|
+
"The `inputs` column must be a dictionary with the parameter names of "
|
129
|
+
f"the `predict_fn` as keys. It seems the specified keys do not match "
|
130
|
+
f"with the `predict_fn`'s arguments. Correct example:\n\n{code_sample}"
|
131
|
+
) from e
|
132
|
+
|
133
|
+
|
134
|
+
def _has_required_keyword_arguments(params: inspect.Signature, required_args: list[str]) -> bool:
|
135
|
+
"""Check if the function accepts the specified keyword arguments."""
|
136
|
+
func_args = []
|
137
|
+
|
138
|
+
for name, param in params.items():
|
139
|
+
# If the function has **kwargs, it accepts all keyword arguments
|
140
|
+
if param.kind == inspect.Parameter.VAR_KEYWORD:
|
141
|
+
return True
|
142
|
+
|
143
|
+
func_args.append(name)
|
144
|
+
|
145
|
+
# Required argument must be a subset of the function's arguments
|
146
|
+
return set(required_args) <= set(func_args)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from enum import Enum, EnumMeta
|
2
|
+
|
3
|
+
|
4
|
+
class MetaEnum(EnumMeta):
|
5
|
+
"""Metaclass for Enum classes that allows to check if a value is a valid member of the Enum."""
|
6
|
+
|
7
|
+
def __contains__(cls, item):
|
8
|
+
try:
|
9
|
+
cls(item)
|
10
|
+
except ValueError:
|
11
|
+
return False
|
12
|
+
return True
|
13
|
+
|
14
|
+
|
15
|
+
class StrEnum(str, Enum, metaclass=MetaEnum):
|
16
|
+
def __str__(self):
|
17
|
+
"""Return the string representation of the enum using its value."""
|
18
|
+
return self.value
|
19
|
+
|
20
|
+
@classmethod
|
21
|
+
def values(cls) -> list[str]:
|
22
|
+
"""Return a list of all string values of the Enum."""
|
23
|
+
return [str(member) for member in cls]
|
@@ -0,0 +1,211 @@
|
|
1
|
+
import logging
|
2
|
+
from typing import Any, Callable, Optional
|
3
|
+
|
4
|
+
from opentelemetry.trace import NoOpTracer
|
5
|
+
|
6
|
+
import mlflow
|
7
|
+
from mlflow.entities.span import Span, SpanType
|
8
|
+
from mlflow.entities.trace import Trace
|
9
|
+
from mlflow.genai.utils.data_validation import check_model_prediction
|
10
|
+
from mlflow.tracing.constant import TraceTagKey
|
11
|
+
from mlflow.tracing.display.display_handler import IPythonTraceDisplayHandler
|
12
|
+
from mlflow.tracking.client import MlflowClient
|
13
|
+
|
14
|
+
_logger = logging.getLogger(__name__)
|
15
|
+
|
16
|
+
|
17
|
+
def convert_predict_fn(predict_fn: Callable[..., Any], sample_input: Any) -> Callable[..., Any]:
|
18
|
+
"""
|
19
|
+
Check the predict_fn is callable and add trace decorator if it is not already traced.
|
20
|
+
"""
|
21
|
+
with NoOpTracerPatcher() as counter:
|
22
|
+
check_model_prediction(predict_fn, sample_input)
|
23
|
+
|
24
|
+
if counter.count == 0:
|
25
|
+
predict_fn = mlflow.trace(predict_fn)
|
26
|
+
|
27
|
+
# Wrap the prediction function to unwrap the inputs dictionary into keyword arguments.
|
28
|
+
return lambda request: predict_fn(**request)
|
29
|
+
|
30
|
+
|
31
|
+
class NoOpTracerPatcher:
|
32
|
+
"""
|
33
|
+
A context manager to count the number of times NoOpTracer's start_span is called.
|
34
|
+
|
35
|
+
The check is done in the following steps so it doesn't have any side effects:
|
36
|
+
1. Disable tracing.
|
37
|
+
2. Patch the NoOpTracer.start_span method to count the number of times it is called.
|
38
|
+
NoOpTracer is used when tracing is disabled.
|
39
|
+
3. Call the predict function with the sample input.
|
40
|
+
4. Restore the original NoOpTracer.start_span method and re-enable tracing.
|
41
|
+
|
42
|
+
|
43
|
+
WARNING: This function is not thread-safe. We do not provide support for running
|
44
|
+
`mlflow.genai.evaluate` in multi-threaded environments.`
|
45
|
+
"""
|
46
|
+
|
47
|
+
def __init__(self):
|
48
|
+
self.count = 0
|
49
|
+
|
50
|
+
def __enter__(self):
|
51
|
+
self.original = NoOpTracer.start_span
|
52
|
+
|
53
|
+
def _patched_start_span(_self, *args, **kwargs):
|
54
|
+
self.count += 1
|
55
|
+
return self.original(_self, *args, **kwargs)
|
56
|
+
|
57
|
+
NoOpTracer.start_span = _patched_start_span
|
58
|
+
return self
|
59
|
+
|
60
|
+
def __exit__(self, exc_type, exc_value, traceback):
|
61
|
+
NoOpTracer.start_span = self.original
|
62
|
+
|
63
|
+
|
64
|
+
def parse_inputs_to_str(inputs: Any) -> str:
|
65
|
+
"""Parse the inputs to a request string compatible with the judges API"""
|
66
|
+
from databricks.rag_eval.utils import input_output_utils
|
67
|
+
|
68
|
+
return input_output_utils.request_to_string(inputs)
|
69
|
+
|
70
|
+
|
71
|
+
def parse_output_to_str(output: Any) -> str:
|
72
|
+
"""Parse the output to a string compatible with the judges API"""
|
73
|
+
from databricks.rag_eval.utils import input_output_utils
|
74
|
+
|
75
|
+
return input_output_utils.response_to_string(output)
|
76
|
+
|
77
|
+
|
78
|
+
def extract_retrieval_context_from_trace(trace: Optional[Trace]) -> dict[str, list[Any]]:
|
79
|
+
"""
|
80
|
+
Extract the retrieval context from the trace.
|
81
|
+
Only consider the last retrieval span in the trace if there are multiple retrieval spans.
|
82
|
+
If the trace does not have a retrieval span, return None.
|
83
|
+
⚠️ Warning: Please make sure to not throw exception. If fails, return None.
|
84
|
+
"""
|
85
|
+
if trace is None or trace.data is None:
|
86
|
+
return {}
|
87
|
+
|
88
|
+
# Only consider the top-level retrieval spans
|
89
|
+
top_level_retrieval_spans = _get_top_level_retrieval_spans(trace)
|
90
|
+
if len(top_level_retrieval_spans) == 0:
|
91
|
+
return {}
|
92
|
+
|
93
|
+
retrieved = {} # span_id -> list of documents
|
94
|
+
|
95
|
+
for retrieval_span in top_level_retrieval_spans:
|
96
|
+
try:
|
97
|
+
contexts = [_parse_chunk(chunk) for chunk in retrieval_span.outputs or []]
|
98
|
+
retrieved[retrieval_span.span_id] = [c for c in contexts if c is not None]
|
99
|
+
except Exception as e:
|
100
|
+
_logger.debug(
|
101
|
+
f"Fail to get retrieval context from span: {retrieval_span}. Error: {e!r}"
|
102
|
+
)
|
103
|
+
|
104
|
+
return retrieved
|
105
|
+
|
106
|
+
|
107
|
+
def _get_top_level_retrieval_spans(trace: Trace) -> list[Span]:
|
108
|
+
"""
|
109
|
+
Get the top-level retrieval spans in the trace.
|
110
|
+
Top-level retrieval spans are retrieval spans that are not children of other retrieval spans.
|
111
|
+
For example, given the following spans:
|
112
|
+
- Span A (Chain)
|
113
|
+
- Span B (Retriever)
|
114
|
+
- Span C (Retriever)
|
115
|
+
- Span D (Retriever)
|
116
|
+
- Span E (LLM)
|
117
|
+
- Span F (Retriever)
|
118
|
+
Span B and Span D are top-level retrieval spans.
|
119
|
+
Span C and Span F are NOT top-level because they are children of other retrieval spans.
|
120
|
+
"""
|
121
|
+
top_level_retrieval_spans = []
|
122
|
+
# Cache span_id -> span mapping for fast lookup
|
123
|
+
all_spans = {span.span_id: span for span in trace.data.spans}
|
124
|
+
for span in trace.search_spans(span_type=SpanType.RETRIEVER):
|
125
|
+
# Check if this span is a child of another retrieval span
|
126
|
+
parent_id = span.parent_id
|
127
|
+
while parent_id:
|
128
|
+
parent_span = all_spans.get(parent_id)
|
129
|
+
if not parent_span:
|
130
|
+
# Malformed trace
|
131
|
+
_logger.debug(
|
132
|
+
f"Malformed trace: span {span} has parent span ID {parent_id}, "
|
133
|
+
"but the parent span is not found in the trace."
|
134
|
+
)
|
135
|
+
break
|
136
|
+
|
137
|
+
if parent_span.span_type == SpanType.RETRIEVER:
|
138
|
+
# This span is a child of another retrieval span
|
139
|
+
break
|
140
|
+
|
141
|
+
parent_id = parent_span.parent_id
|
142
|
+
else:
|
143
|
+
# If the loop completes without breaking, this is a top-level span
|
144
|
+
top_level_retrieval_spans.append(span)
|
145
|
+
|
146
|
+
return top_level_retrieval_spans
|
147
|
+
|
148
|
+
|
149
|
+
def _parse_chunk(chunk: Any) -> Optional[dict[str, Any]]:
|
150
|
+
if not isinstance(chunk, dict):
|
151
|
+
return None
|
152
|
+
|
153
|
+
doc = {"content": chunk.get("page_content")}
|
154
|
+
if doc_uri := chunk.get("metadata", {}).get("doc_uri"):
|
155
|
+
doc["doc_uri"] = doc_uri
|
156
|
+
return doc
|
157
|
+
|
158
|
+
|
159
|
+
def clean_up_extra_traces(run_id: str, start_time_ms: int):
|
160
|
+
"""
|
161
|
+
Clean up noisy traces generated outside predict function.
|
162
|
+
|
163
|
+
Evaluation run should only contain traces that is being evaluated or generated by the predict
|
164
|
+
function. If not, the result will not show the correct list of traces.
|
165
|
+
Sometimes, there are extra traces generated during the evaluation, for example, custom scorer
|
166
|
+
code might generate traces. This function cleans up those noisy traces.
|
167
|
+
|
168
|
+
TODO: This is not a fundamental solution. Ideally, evaluation result should be able to render
|
169
|
+
correct result even if there are extra traces in the run.
|
170
|
+
|
171
|
+
Args:
|
172
|
+
run_id: The ID of the run to clean up.
|
173
|
+
start_time_ms: The start time of the evaluation in milliseconds.
|
174
|
+
"""
|
175
|
+
from mlflow.tracking.fluent import _get_experiment_id
|
176
|
+
|
177
|
+
try:
|
178
|
+
# Search for all traces generated during evaluation
|
179
|
+
traces = mlflow.search_traces(
|
180
|
+
run_id=run_id,
|
181
|
+
# Not download spans for efficiency
|
182
|
+
include_spans=False,
|
183
|
+
# Limit to traces generated after evaluation time to ensure we will not
|
184
|
+
# delete traces generated before evaluation.
|
185
|
+
filter_string=f"trace.timestamp >= {start_time_ms}",
|
186
|
+
return_type="list",
|
187
|
+
)
|
188
|
+
extra_trace_ids = [
|
189
|
+
# Traces from predict function should always have the EVAL_REQUEST_ID tag
|
190
|
+
trace.info.trace_id
|
191
|
+
for trace in traces
|
192
|
+
if TraceTagKey.EVAL_REQUEST_ID not in trace.info.tags
|
193
|
+
]
|
194
|
+
if extra_trace_ids:
|
195
|
+
_logger.debug(
|
196
|
+
f"Found {len(extra_trace_ids)} extra traces generated during evaluation run. "
|
197
|
+
"Deleting them."
|
198
|
+
)
|
199
|
+
MlflowClient().delete_traces(
|
200
|
+
experiment_id=_get_experiment_id(), trace_ids=extra_trace_ids
|
201
|
+
)
|
202
|
+
# Avoid displaying the deleted trace in notebook cell output
|
203
|
+
for trace_id in extra_trace_ids:
|
204
|
+
IPythonTraceDisplayHandler.get_instance().traces_to_display.pop(trace_id, None)
|
205
|
+
else:
|
206
|
+
_logger.debug("No extra traces found during evaluation run.")
|
207
|
+
except Exception as e:
|
208
|
+
_logger.warning(
|
209
|
+
f"Failed to clean up extra traces generated during evaluation. The "
|
210
|
+
f"result page might not show the correct list of traces. Error: {e}"
|
211
|
+
)
|