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.
Files changed (645) hide show
  1. genesis_flow-1.0.0.dist-info/METADATA +822 -0
  2. genesis_flow-1.0.0.dist-info/RECORD +645 -0
  3. genesis_flow-1.0.0.dist-info/WHEEL +5 -0
  4. genesis_flow-1.0.0.dist-info/entry_points.txt +19 -0
  5. genesis_flow-1.0.0.dist-info/licenses/LICENSE.txt +202 -0
  6. genesis_flow-1.0.0.dist-info/top_level.txt +1 -0
  7. mlflow/__init__.py +367 -0
  8. mlflow/__main__.py +3 -0
  9. mlflow/ag2/__init__.py +56 -0
  10. mlflow/ag2/ag2_logger.py +294 -0
  11. mlflow/anthropic/__init__.py +40 -0
  12. mlflow/anthropic/autolog.py +129 -0
  13. mlflow/anthropic/chat.py +144 -0
  14. mlflow/artifacts/__init__.py +268 -0
  15. mlflow/autogen/__init__.py +144 -0
  16. mlflow/autogen/chat.py +142 -0
  17. mlflow/azure/__init__.py +26 -0
  18. mlflow/azure/auth_handler.py +257 -0
  19. mlflow/azure/client.py +319 -0
  20. mlflow/azure/config.py +120 -0
  21. mlflow/azure/connection_factory.py +340 -0
  22. mlflow/azure/exceptions.py +27 -0
  23. mlflow/azure/stores.py +327 -0
  24. mlflow/azure/utils.py +183 -0
  25. mlflow/bedrock/__init__.py +45 -0
  26. mlflow/bedrock/_autolog.py +202 -0
  27. mlflow/bedrock/chat.py +122 -0
  28. mlflow/bedrock/stream.py +160 -0
  29. mlflow/bedrock/utils.py +43 -0
  30. mlflow/cli.py +707 -0
  31. mlflow/client.py +12 -0
  32. mlflow/config/__init__.py +56 -0
  33. mlflow/crewai/__init__.py +79 -0
  34. mlflow/crewai/autolog.py +253 -0
  35. mlflow/crewai/chat.py +29 -0
  36. mlflow/data/__init__.py +75 -0
  37. mlflow/data/artifact_dataset_sources.py +170 -0
  38. mlflow/data/code_dataset_source.py +40 -0
  39. mlflow/data/dataset.py +123 -0
  40. mlflow/data/dataset_registry.py +168 -0
  41. mlflow/data/dataset_source.py +110 -0
  42. mlflow/data/dataset_source_registry.py +219 -0
  43. mlflow/data/delta_dataset_source.py +167 -0
  44. mlflow/data/digest_utils.py +108 -0
  45. mlflow/data/evaluation_dataset.py +562 -0
  46. mlflow/data/filesystem_dataset_source.py +81 -0
  47. mlflow/data/http_dataset_source.py +145 -0
  48. mlflow/data/huggingface_dataset.py +258 -0
  49. mlflow/data/huggingface_dataset_source.py +118 -0
  50. mlflow/data/meta_dataset.py +104 -0
  51. mlflow/data/numpy_dataset.py +223 -0
  52. mlflow/data/pandas_dataset.py +231 -0
  53. mlflow/data/polars_dataset.py +352 -0
  54. mlflow/data/pyfunc_dataset_mixin.py +31 -0
  55. mlflow/data/schema.py +76 -0
  56. mlflow/data/sources.py +1 -0
  57. mlflow/data/spark_dataset.py +406 -0
  58. mlflow/data/spark_dataset_source.py +74 -0
  59. mlflow/data/spark_delta_utils.py +118 -0
  60. mlflow/data/tensorflow_dataset.py +350 -0
  61. mlflow/data/uc_volume_dataset_source.py +81 -0
  62. mlflow/db.py +27 -0
  63. mlflow/dspy/__init__.py +17 -0
  64. mlflow/dspy/autolog.py +197 -0
  65. mlflow/dspy/callback.py +398 -0
  66. mlflow/dspy/constant.py +1 -0
  67. mlflow/dspy/load.py +93 -0
  68. mlflow/dspy/save.py +393 -0
  69. mlflow/dspy/util.py +109 -0
  70. mlflow/dspy/wrapper.py +226 -0
  71. mlflow/entities/__init__.py +104 -0
  72. mlflow/entities/_mlflow_object.py +52 -0
  73. mlflow/entities/assessment.py +545 -0
  74. mlflow/entities/assessment_error.py +80 -0
  75. mlflow/entities/assessment_source.py +141 -0
  76. mlflow/entities/dataset.py +92 -0
  77. mlflow/entities/dataset_input.py +51 -0
  78. mlflow/entities/dataset_summary.py +62 -0
  79. mlflow/entities/document.py +48 -0
  80. mlflow/entities/experiment.py +109 -0
  81. mlflow/entities/experiment_tag.py +35 -0
  82. mlflow/entities/file_info.py +45 -0
  83. mlflow/entities/input_tag.py +35 -0
  84. mlflow/entities/lifecycle_stage.py +35 -0
  85. mlflow/entities/logged_model.py +228 -0
  86. mlflow/entities/logged_model_input.py +26 -0
  87. mlflow/entities/logged_model_output.py +32 -0
  88. mlflow/entities/logged_model_parameter.py +46 -0
  89. mlflow/entities/logged_model_status.py +74 -0
  90. mlflow/entities/logged_model_tag.py +33 -0
  91. mlflow/entities/metric.py +200 -0
  92. mlflow/entities/model_registry/__init__.py +29 -0
  93. mlflow/entities/model_registry/_model_registry_entity.py +13 -0
  94. mlflow/entities/model_registry/model_version.py +243 -0
  95. mlflow/entities/model_registry/model_version_deployment_job_run_state.py +44 -0
  96. mlflow/entities/model_registry/model_version_deployment_job_state.py +70 -0
  97. mlflow/entities/model_registry/model_version_search.py +25 -0
  98. mlflow/entities/model_registry/model_version_stages.py +25 -0
  99. mlflow/entities/model_registry/model_version_status.py +35 -0
  100. mlflow/entities/model_registry/model_version_tag.py +35 -0
  101. mlflow/entities/model_registry/prompt.py +73 -0
  102. mlflow/entities/model_registry/prompt_version.py +244 -0
  103. mlflow/entities/model_registry/registered_model.py +175 -0
  104. mlflow/entities/model_registry/registered_model_alias.py +35 -0
  105. mlflow/entities/model_registry/registered_model_deployment_job_state.py +39 -0
  106. mlflow/entities/model_registry/registered_model_search.py +25 -0
  107. mlflow/entities/model_registry/registered_model_tag.py +35 -0
  108. mlflow/entities/multipart_upload.py +74 -0
  109. mlflow/entities/param.py +49 -0
  110. mlflow/entities/run.py +97 -0
  111. mlflow/entities/run_data.py +84 -0
  112. mlflow/entities/run_info.py +188 -0
  113. mlflow/entities/run_inputs.py +59 -0
  114. mlflow/entities/run_outputs.py +43 -0
  115. mlflow/entities/run_status.py +41 -0
  116. mlflow/entities/run_tag.py +36 -0
  117. mlflow/entities/source_type.py +31 -0
  118. mlflow/entities/span.py +774 -0
  119. mlflow/entities/span_event.py +96 -0
  120. mlflow/entities/span_status.py +102 -0
  121. mlflow/entities/trace.py +317 -0
  122. mlflow/entities/trace_data.py +71 -0
  123. mlflow/entities/trace_info.py +220 -0
  124. mlflow/entities/trace_info_v2.py +162 -0
  125. mlflow/entities/trace_location.py +173 -0
  126. mlflow/entities/trace_state.py +39 -0
  127. mlflow/entities/trace_status.py +68 -0
  128. mlflow/entities/view_type.py +51 -0
  129. mlflow/environment_variables.py +866 -0
  130. mlflow/evaluation/__init__.py +16 -0
  131. mlflow/evaluation/assessment.py +369 -0
  132. mlflow/evaluation/evaluation.py +411 -0
  133. mlflow/evaluation/evaluation_tag.py +61 -0
  134. mlflow/evaluation/fluent.py +48 -0
  135. mlflow/evaluation/utils.py +201 -0
  136. mlflow/exceptions.py +213 -0
  137. mlflow/experiments.py +140 -0
  138. mlflow/gemini/__init__.py +81 -0
  139. mlflow/gemini/autolog.py +186 -0
  140. mlflow/gemini/chat.py +261 -0
  141. mlflow/genai/__init__.py +71 -0
  142. mlflow/genai/datasets/__init__.py +67 -0
  143. mlflow/genai/datasets/evaluation_dataset.py +131 -0
  144. mlflow/genai/evaluation/__init__.py +3 -0
  145. mlflow/genai/evaluation/base.py +411 -0
  146. mlflow/genai/evaluation/constant.py +23 -0
  147. mlflow/genai/evaluation/utils.py +244 -0
  148. mlflow/genai/judges/__init__.py +21 -0
  149. mlflow/genai/judges/databricks.py +404 -0
  150. mlflow/genai/label_schemas/__init__.py +153 -0
  151. mlflow/genai/label_schemas/label_schemas.py +209 -0
  152. mlflow/genai/labeling/__init__.py +159 -0
  153. mlflow/genai/labeling/labeling.py +250 -0
  154. mlflow/genai/optimize/__init__.py +13 -0
  155. mlflow/genai/optimize/base.py +198 -0
  156. mlflow/genai/optimize/optimizers/__init__.py +4 -0
  157. mlflow/genai/optimize/optimizers/base_optimizer.py +38 -0
  158. mlflow/genai/optimize/optimizers/dspy_mipro_optimizer.py +221 -0
  159. mlflow/genai/optimize/optimizers/dspy_optimizer.py +91 -0
  160. mlflow/genai/optimize/optimizers/utils/dspy_mipro_callback.py +76 -0
  161. mlflow/genai/optimize/optimizers/utils/dspy_mipro_utils.py +18 -0
  162. mlflow/genai/optimize/types.py +75 -0
  163. mlflow/genai/optimize/util.py +30 -0
  164. mlflow/genai/prompts/__init__.py +206 -0
  165. mlflow/genai/scheduled_scorers.py +431 -0
  166. mlflow/genai/scorers/__init__.py +26 -0
  167. mlflow/genai/scorers/base.py +492 -0
  168. mlflow/genai/scorers/builtin_scorers.py +765 -0
  169. mlflow/genai/scorers/scorer_utils.py +138 -0
  170. mlflow/genai/scorers/validation.py +165 -0
  171. mlflow/genai/utils/data_validation.py +146 -0
  172. mlflow/genai/utils/enum_utils.py +23 -0
  173. mlflow/genai/utils/trace_utils.py +211 -0
  174. mlflow/groq/__init__.py +42 -0
  175. mlflow/groq/_groq_autolog.py +74 -0
  176. mlflow/johnsnowlabs/__init__.py +888 -0
  177. mlflow/langchain/__init__.py +24 -0
  178. mlflow/langchain/api_request_parallel_processor.py +330 -0
  179. mlflow/langchain/autolog.py +147 -0
  180. mlflow/langchain/chat_agent_langgraph.py +340 -0
  181. mlflow/langchain/constant.py +1 -0
  182. mlflow/langchain/constants.py +1 -0
  183. mlflow/langchain/databricks_dependencies.py +444 -0
  184. mlflow/langchain/langchain_tracer.py +597 -0
  185. mlflow/langchain/model.py +919 -0
  186. mlflow/langchain/output_parsers.py +142 -0
  187. mlflow/langchain/retriever_chain.py +153 -0
  188. mlflow/langchain/runnables.py +527 -0
  189. mlflow/langchain/utils/chat.py +402 -0
  190. mlflow/langchain/utils/logging.py +671 -0
  191. mlflow/langchain/utils/serialization.py +36 -0
  192. mlflow/legacy_databricks_cli/__init__.py +0 -0
  193. mlflow/legacy_databricks_cli/configure/__init__.py +0 -0
  194. mlflow/legacy_databricks_cli/configure/provider.py +482 -0
  195. mlflow/litellm/__init__.py +175 -0
  196. mlflow/llama_index/__init__.py +22 -0
  197. mlflow/llama_index/autolog.py +55 -0
  198. mlflow/llama_index/chat.py +43 -0
  199. mlflow/llama_index/constant.py +1 -0
  200. mlflow/llama_index/model.py +577 -0
  201. mlflow/llama_index/pyfunc_wrapper.py +332 -0
  202. mlflow/llama_index/serialize_objects.py +188 -0
  203. mlflow/llama_index/tracer.py +561 -0
  204. mlflow/metrics/__init__.py +479 -0
  205. mlflow/metrics/base.py +39 -0
  206. mlflow/metrics/genai/__init__.py +25 -0
  207. mlflow/metrics/genai/base.py +101 -0
  208. mlflow/metrics/genai/genai_metric.py +771 -0
  209. mlflow/metrics/genai/metric_definitions.py +450 -0
  210. mlflow/metrics/genai/model_utils.py +371 -0
  211. mlflow/metrics/genai/prompt_template.py +68 -0
  212. mlflow/metrics/genai/prompts/__init__.py +0 -0
  213. mlflow/metrics/genai/prompts/v1.py +422 -0
  214. mlflow/metrics/genai/utils.py +6 -0
  215. mlflow/metrics/metric_definitions.py +619 -0
  216. mlflow/mismatch.py +34 -0
  217. mlflow/mistral/__init__.py +34 -0
  218. mlflow/mistral/autolog.py +71 -0
  219. mlflow/mistral/chat.py +135 -0
  220. mlflow/ml_package_versions.py +452 -0
  221. mlflow/models/__init__.py +97 -0
  222. mlflow/models/auth_policy.py +83 -0
  223. mlflow/models/cli.py +354 -0
  224. mlflow/models/container/__init__.py +294 -0
  225. mlflow/models/container/scoring_server/__init__.py +0 -0
  226. mlflow/models/container/scoring_server/nginx.conf +39 -0
  227. mlflow/models/dependencies_schemas.py +287 -0
  228. mlflow/models/display_utils.py +158 -0
  229. mlflow/models/docker_utils.py +211 -0
  230. mlflow/models/evaluation/__init__.py +23 -0
  231. mlflow/models/evaluation/_shap_patch.py +64 -0
  232. mlflow/models/evaluation/artifacts.py +194 -0
  233. mlflow/models/evaluation/base.py +1811 -0
  234. mlflow/models/evaluation/calibration_curve.py +109 -0
  235. mlflow/models/evaluation/default_evaluator.py +996 -0
  236. mlflow/models/evaluation/deprecated.py +23 -0
  237. mlflow/models/evaluation/evaluator_registry.py +80 -0
  238. mlflow/models/evaluation/evaluators/classifier.py +704 -0
  239. mlflow/models/evaluation/evaluators/default.py +233 -0
  240. mlflow/models/evaluation/evaluators/regressor.py +96 -0
  241. mlflow/models/evaluation/evaluators/shap.py +296 -0
  242. mlflow/models/evaluation/lift_curve.py +178 -0
  243. mlflow/models/evaluation/utils/metric.py +123 -0
  244. mlflow/models/evaluation/utils/trace.py +179 -0
  245. mlflow/models/evaluation/validation.py +434 -0
  246. mlflow/models/flavor_backend.py +93 -0
  247. mlflow/models/flavor_backend_registry.py +53 -0
  248. mlflow/models/model.py +1639 -0
  249. mlflow/models/model_config.py +150 -0
  250. mlflow/models/notebook_resources/agent_evaluation_template.html +235 -0
  251. mlflow/models/notebook_resources/eval_with_dataset_example.py +22 -0
  252. mlflow/models/notebook_resources/eval_with_synthetic_example.py +22 -0
  253. mlflow/models/python_api.py +369 -0
  254. mlflow/models/rag_signatures.py +128 -0
  255. mlflow/models/resources.py +321 -0
  256. mlflow/models/signature.py +662 -0
  257. mlflow/models/utils.py +2054 -0
  258. mlflow/models/wheeled_model.py +280 -0
  259. mlflow/openai/__init__.py +57 -0
  260. mlflow/openai/_agent_tracer.py +364 -0
  261. mlflow/openai/api_request_parallel_processor.py +131 -0
  262. mlflow/openai/autolog.py +509 -0
  263. mlflow/openai/constant.py +1 -0
  264. mlflow/openai/model.py +824 -0
  265. mlflow/openai/utils/chat_schema.py +367 -0
  266. mlflow/optuna/__init__.py +3 -0
  267. mlflow/optuna/storage.py +646 -0
  268. mlflow/plugins/__init__.py +72 -0
  269. mlflow/plugins/base.py +358 -0
  270. mlflow/plugins/builtin/__init__.py +24 -0
  271. mlflow/plugins/builtin/pytorch_plugin.py +150 -0
  272. mlflow/plugins/builtin/sklearn_plugin.py +158 -0
  273. mlflow/plugins/builtin/transformers_plugin.py +187 -0
  274. mlflow/plugins/cli.py +321 -0
  275. mlflow/plugins/discovery.py +340 -0
  276. mlflow/plugins/manager.py +465 -0
  277. mlflow/plugins/registry.py +316 -0
  278. mlflow/plugins/templates/framework_plugin_template.py +329 -0
  279. mlflow/prompt/constants.py +20 -0
  280. mlflow/prompt/promptlab_model.py +197 -0
  281. mlflow/prompt/registry_utils.py +248 -0
  282. mlflow/promptflow/__init__.py +495 -0
  283. mlflow/protos/__init__.py +0 -0
  284. mlflow/protos/assessments_pb2.py +174 -0
  285. mlflow/protos/databricks_artifacts_pb2.py +489 -0
  286. mlflow/protos/databricks_filesystem_service_pb2.py +196 -0
  287. mlflow/protos/databricks_managed_catalog_messages_pb2.py +95 -0
  288. mlflow/protos/databricks_managed_catalog_service_pb2.py +86 -0
  289. mlflow/protos/databricks_pb2.py +267 -0
  290. mlflow/protos/databricks_trace_server_pb2.py +374 -0
  291. mlflow/protos/databricks_uc_registry_messages_pb2.py +1249 -0
  292. mlflow/protos/databricks_uc_registry_service_pb2.py +170 -0
  293. mlflow/protos/facet_feature_statistics_pb2.py +296 -0
  294. mlflow/protos/internal_pb2.py +77 -0
  295. mlflow/protos/mlflow_artifacts_pb2.py +336 -0
  296. mlflow/protos/model_registry_pb2.py +1073 -0
  297. mlflow/protos/scalapb/__init__.py +0 -0
  298. mlflow/protos/scalapb/scalapb_pb2.py +104 -0
  299. mlflow/protos/service_pb2.py +2600 -0
  300. mlflow/protos/unity_catalog_oss_messages_pb2.py +457 -0
  301. mlflow/protos/unity_catalog_oss_service_pb2.py +130 -0
  302. mlflow/protos/unity_catalog_prompt_messages_pb2.py +447 -0
  303. mlflow/protos/unity_catalog_prompt_messages_pb2_grpc.py +24 -0
  304. mlflow/protos/unity_catalog_prompt_service_pb2.py +164 -0
  305. mlflow/protos/unity_catalog_prompt_service_pb2_grpc.py +785 -0
  306. mlflow/py.typed +0 -0
  307. mlflow/pydantic_ai/__init__.py +57 -0
  308. mlflow/pydantic_ai/autolog.py +173 -0
  309. mlflow/pyfunc/__init__.py +3844 -0
  310. mlflow/pyfunc/_mlflow_pyfunc_backend_predict.py +61 -0
  311. mlflow/pyfunc/backend.py +523 -0
  312. mlflow/pyfunc/context.py +78 -0
  313. mlflow/pyfunc/dbconnect_artifact_cache.py +144 -0
  314. mlflow/pyfunc/loaders/__init__.py +7 -0
  315. mlflow/pyfunc/loaders/chat_agent.py +117 -0
  316. mlflow/pyfunc/loaders/chat_model.py +125 -0
  317. mlflow/pyfunc/loaders/code_model.py +31 -0
  318. mlflow/pyfunc/loaders/responses_agent.py +112 -0
  319. mlflow/pyfunc/mlserver.py +46 -0
  320. mlflow/pyfunc/model.py +1473 -0
  321. mlflow/pyfunc/scoring_server/__init__.py +604 -0
  322. mlflow/pyfunc/scoring_server/app.py +7 -0
  323. mlflow/pyfunc/scoring_server/client.py +146 -0
  324. mlflow/pyfunc/spark_model_cache.py +48 -0
  325. mlflow/pyfunc/stdin_server.py +44 -0
  326. mlflow/pyfunc/utils/__init__.py +3 -0
  327. mlflow/pyfunc/utils/data_validation.py +224 -0
  328. mlflow/pyfunc/utils/environment.py +22 -0
  329. mlflow/pyfunc/utils/input_converter.py +47 -0
  330. mlflow/pyfunc/utils/serving_data_parser.py +11 -0
  331. mlflow/pytorch/__init__.py +1171 -0
  332. mlflow/pytorch/_lightning_autolog.py +580 -0
  333. mlflow/pytorch/_pytorch_autolog.py +50 -0
  334. mlflow/pytorch/pickle_module.py +35 -0
  335. mlflow/rfunc/__init__.py +42 -0
  336. mlflow/rfunc/backend.py +134 -0
  337. mlflow/runs.py +89 -0
  338. mlflow/server/__init__.py +302 -0
  339. mlflow/server/auth/__init__.py +1224 -0
  340. mlflow/server/auth/__main__.py +4 -0
  341. mlflow/server/auth/basic_auth.ini +6 -0
  342. mlflow/server/auth/cli.py +11 -0
  343. mlflow/server/auth/client.py +537 -0
  344. mlflow/server/auth/config.py +34 -0
  345. mlflow/server/auth/db/__init__.py +0 -0
  346. mlflow/server/auth/db/cli.py +18 -0
  347. mlflow/server/auth/db/migrations/__init__.py +0 -0
  348. mlflow/server/auth/db/migrations/alembic.ini +110 -0
  349. mlflow/server/auth/db/migrations/env.py +76 -0
  350. mlflow/server/auth/db/migrations/versions/8606fa83a998_initial_migration.py +51 -0
  351. mlflow/server/auth/db/migrations/versions/__init__.py +0 -0
  352. mlflow/server/auth/db/models.py +67 -0
  353. mlflow/server/auth/db/utils.py +37 -0
  354. mlflow/server/auth/entities.py +165 -0
  355. mlflow/server/auth/logo.py +14 -0
  356. mlflow/server/auth/permissions.py +65 -0
  357. mlflow/server/auth/routes.py +18 -0
  358. mlflow/server/auth/sqlalchemy_store.py +263 -0
  359. mlflow/server/graphql/__init__.py +0 -0
  360. mlflow/server/graphql/autogenerated_graphql_schema.py +353 -0
  361. mlflow/server/graphql/graphql_custom_scalars.py +24 -0
  362. mlflow/server/graphql/graphql_errors.py +15 -0
  363. mlflow/server/graphql/graphql_no_batching.py +89 -0
  364. mlflow/server/graphql/graphql_schema_extensions.py +74 -0
  365. mlflow/server/handlers.py +3217 -0
  366. mlflow/server/prometheus_exporter.py +17 -0
  367. mlflow/server/validation.py +30 -0
  368. mlflow/shap/__init__.py +691 -0
  369. mlflow/sklearn/__init__.py +1994 -0
  370. mlflow/sklearn/utils.py +1041 -0
  371. mlflow/smolagents/__init__.py +66 -0
  372. mlflow/smolagents/autolog.py +139 -0
  373. mlflow/smolagents/chat.py +29 -0
  374. mlflow/store/__init__.py +10 -0
  375. mlflow/store/_unity_catalog/__init__.py +1 -0
  376. mlflow/store/_unity_catalog/lineage/__init__.py +1 -0
  377. mlflow/store/_unity_catalog/lineage/constants.py +2 -0
  378. mlflow/store/_unity_catalog/registry/__init__.py +6 -0
  379. mlflow/store/_unity_catalog/registry/prompt_info.py +75 -0
  380. mlflow/store/_unity_catalog/registry/rest_store.py +1740 -0
  381. mlflow/store/_unity_catalog/registry/uc_oss_rest_store.py +507 -0
  382. mlflow/store/_unity_catalog/registry/utils.py +121 -0
  383. mlflow/store/artifact/__init__.py +0 -0
  384. mlflow/store/artifact/artifact_repo.py +472 -0
  385. mlflow/store/artifact/artifact_repository_registry.py +154 -0
  386. mlflow/store/artifact/azure_blob_artifact_repo.py +275 -0
  387. mlflow/store/artifact/azure_data_lake_artifact_repo.py +295 -0
  388. mlflow/store/artifact/cli.py +141 -0
  389. mlflow/store/artifact/cloud_artifact_repo.py +332 -0
  390. mlflow/store/artifact/databricks_artifact_repo.py +729 -0
  391. mlflow/store/artifact/databricks_artifact_repo_resources.py +301 -0
  392. mlflow/store/artifact/databricks_logged_model_artifact_repo.py +93 -0
  393. mlflow/store/artifact/databricks_models_artifact_repo.py +216 -0
  394. mlflow/store/artifact/databricks_sdk_artifact_repo.py +134 -0
  395. mlflow/store/artifact/databricks_sdk_models_artifact_repo.py +97 -0
  396. mlflow/store/artifact/dbfs_artifact_repo.py +240 -0
  397. mlflow/store/artifact/ftp_artifact_repo.py +132 -0
  398. mlflow/store/artifact/gcs_artifact_repo.py +296 -0
  399. mlflow/store/artifact/hdfs_artifact_repo.py +209 -0
  400. mlflow/store/artifact/http_artifact_repo.py +218 -0
  401. mlflow/store/artifact/local_artifact_repo.py +142 -0
  402. mlflow/store/artifact/mlflow_artifacts_repo.py +94 -0
  403. mlflow/store/artifact/models_artifact_repo.py +259 -0
  404. mlflow/store/artifact/optimized_s3_artifact_repo.py +356 -0
  405. mlflow/store/artifact/presigned_url_artifact_repo.py +173 -0
  406. mlflow/store/artifact/r2_artifact_repo.py +70 -0
  407. mlflow/store/artifact/runs_artifact_repo.py +265 -0
  408. mlflow/store/artifact/s3_artifact_repo.py +330 -0
  409. mlflow/store/artifact/sftp_artifact_repo.py +141 -0
  410. mlflow/store/artifact/uc_volume_artifact_repo.py +76 -0
  411. mlflow/store/artifact/unity_catalog_models_artifact_repo.py +168 -0
  412. mlflow/store/artifact/unity_catalog_oss_models_artifact_repo.py +168 -0
  413. mlflow/store/artifact/utils/__init__.py +0 -0
  414. mlflow/store/artifact/utils/models.py +148 -0
  415. mlflow/store/db/__init__.py +0 -0
  416. mlflow/store/db/base_sql_model.py +3 -0
  417. mlflow/store/db/db_types.py +10 -0
  418. mlflow/store/db/utils.py +314 -0
  419. mlflow/store/db_migrations/__init__.py +0 -0
  420. mlflow/store/db_migrations/alembic.ini +74 -0
  421. mlflow/store/db_migrations/env.py +84 -0
  422. mlflow/store/db_migrations/versions/0584bdc529eb_add_cascading_deletion_to_datasets_from_experiments.py +88 -0
  423. mlflow/store/db_migrations/versions/0a8213491aaa_drop_duplicate_killed_constraint.py +49 -0
  424. mlflow/store/db_migrations/versions/0c779009ac13_add_deleted_time_field_to_runs_table.py +24 -0
  425. mlflow/store/db_migrations/versions/181f10493468_allow_nulls_for_metric_values.py +35 -0
  426. mlflow/store/db_migrations/versions/27a6a02d2cf1_add_model_version_tags_table.py +38 -0
  427. mlflow/store/db_migrations/versions/2b4d017a5e9b_add_model_registry_tables_to_db.py +77 -0
  428. mlflow/store/db_migrations/versions/2d6e25af4d3e_increase_max_param_val_length.py +33 -0
  429. mlflow/store/db_migrations/versions/3500859a5d39_add_model_aliases_table.py +50 -0
  430. mlflow/store/db_migrations/versions/39d1c3be5f05_add_is_nan_constraint_for_metrics_tables_if_necessary.py +41 -0
  431. mlflow/store/db_migrations/versions/400f98739977_add_logged_model_tables.py +123 -0
  432. mlflow/store/db_migrations/versions/4465047574b1_increase_max_dataset_schema_size.py +38 -0
  433. mlflow/store/db_migrations/versions/451aebb31d03_add_metric_step.py +35 -0
  434. mlflow/store/db_migrations/versions/5b0e9adcef9c_add_cascade_deletion_to_trace_tables_fk.py +40 -0
  435. mlflow/store/db_migrations/versions/6953534de441_add_step_to_inputs_table.py +25 -0
  436. mlflow/store/db_migrations/versions/728d730b5ebd_add_registered_model_tags_table.py +38 -0
  437. mlflow/store/db_migrations/versions/7ac759974ad8_update_run_tags_with_larger_limit.py +36 -0
  438. mlflow/store/db_migrations/versions/7f2a7d5fae7d_add_datasets_inputs_input_tags_tables.py +82 -0
  439. mlflow/store/db_migrations/versions/84291f40a231_add_run_link_to_model_version.py +26 -0
  440. mlflow/store/db_migrations/versions/867495a8f9d4_add_trace_tables.py +90 -0
  441. mlflow/store/db_migrations/versions/89d4b8295536_create_latest_metrics_table.py +169 -0
  442. mlflow/store/db_migrations/versions/90e64c465722_migrate_user_column_to_tags.py +64 -0
  443. mlflow/store/db_migrations/versions/97727af70f4d_creation_time_last_update_time_experiments.py +25 -0
  444. mlflow/store/db_migrations/versions/__init__.py +0 -0
  445. mlflow/store/db_migrations/versions/a8c4a736bde6_allow_nulls_for_run_id.py +27 -0
  446. mlflow/store/db_migrations/versions/acf3f17fdcc7_add_storage_location_field_to_model_.py +29 -0
  447. mlflow/store/db_migrations/versions/bd07f7e963c5_create_index_on_run_uuid.py +26 -0
  448. mlflow/store/db_migrations/versions/bda7b8c39065_increase_model_version_tag_value_limit.py +38 -0
  449. mlflow/store/db_migrations/versions/c48cb773bb87_reset_default_value_for_is_nan_in_metrics_table_for_mysql.py +41 -0
  450. mlflow/store/db_migrations/versions/cbc13b556ace_add_v3_trace_schema_columns.py +31 -0
  451. mlflow/store/db_migrations/versions/cc1f77228345_change_param_value_length_to_500.py +34 -0
  452. mlflow/store/db_migrations/versions/cfd24bdc0731_update_run_status_constraint_with_killed.py +78 -0
  453. mlflow/store/db_migrations/versions/df50e92ffc5e_add_experiment_tags_table.py +38 -0
  454. mlflow/store/db_migrations/versions/f5a4f2784254_increase_run_tag_value_limit.py +36 -0
  455. mlflow/store/entities/__init__.py +3 -0
  456. mlflow/store/entities/paged_list.py +18 -0
  457. mlflow/store/model_registry/__init__.py +10 -0
  458. mlflow/store/model_registry/abstract_store.py +1081 -0
  459. mlflow/store/model_registry/base_rest_store.py +44 -0
  460. mlflow/store/model_registry/databricks_workspace_model_registry_rest_store.py +37 -0
  461. mlflow/store/model_registry/dbmodels/__init__.py +0 -0
  462. mlflow/store/model_registry/dbmodels/models.py +206 -0
  463. mlflow/store/model_registry/file_store.py +1091 -0
  464. mlflow/store/model_registry/rest_store.py +481 -0
  465. mlflow/store/model_registry/sqlalchemy_store.py +1286 -0
  466. mlflow/store/tracking/__init__.py +23 -0
  467. mlflow/store/tracking/abstract_store.py +816 -0
  468. mlflow/store/tracking/dbmodels/__init__.py +0 -0
  469. mlflow/store/tracking/dbmodels/initial_models.py +243 -0
  470. mlflow/store/tracking/dbmodels/models.py +1073 -0
  471. mlflow/store/tracking/file_store.py +2438 -0
  472. mlflow/store/tracking/postgres_managed_identity.py +146 -0
  473. mlflow/store/tracking/rest_store.py +1131 -0
  474. mlflow/store/tracking/sqlalchemy_store.py +2785 -0
  475. mlflow/system_metrics/__init__.py +61 -0
  476. mlflow/system_metrics/metrics/__init__.py +0 -0
  477. mlflow/system_metrics/metrics/base_metrics_monitor.py +32 -0
  478. mlflow/system_metrics/metrics/cpu_monitor.py +23 -0
  479. mlflow/system_metrics/metrics/disk_monitor.py +21 -0
  480. mlflow/system_metrics/metrics/gpu_monitor.py +71 -0
  481. mlflow/system_metrics/metrics/network_monitor.py +34 -0
  482. mlflow/system_metrics/metrics/rocm_monitor.py +123 -0
  483. mlflow/system_metrics/system_metrics_monitor.py +198 -0
  484. mlflow/tracing/__init__.py +16 -0
  485. mlflow/tracing/assessment.py +356 -0
  486. mlflow/tracing/client.py +531 -0
  487. mlflow/tracing/config.py +125 -0
  488. mlflow/tracing/constant.py +105 -0
  489. mlflow/tracing/destination.py +81 -0
  490. mlflow/tracing/display/__init__.py +40 -0
  491. mlflow/tracing/display/display_handler.py +196 -0
  492. mlflow/tracing/export/async_export_queue.py +186 -0
  493. mlflow/tracing/export/inference_table.py +138 -0
  494. mlflow/tracing/export/mlflow_v3.py +137 -0
  495. mlflow/tracing/export/utils.py +70 -0
  496. mlflow/tracing/fluent.py +1417 -0
  497. mlflow/tracing/processor/base_mlflow.py +199 -0
  498. mlflow/tracing/processor/inference_table.py +175 -0
  499. mlflow/tracing/processor/mlflow_v3.py +47 -0
  500. mlflow/tracing/processor/otel.py +73 -0
  501. mlflow/tracing/provider.py +487 -0
  502. mlflow/tracing/trace_manager.py +200 -0
  503. mlflow/tracing/utils/__init__.py +616 -0
  504. mlflow/tracing/utils/artifact_utils.py +28 -0
  505. mlflow/tracing/utils/copy.py +55 -0
  506. mlflow/tracing/utils/environment.py +55 -0
  507. mlflow/tracing/utils/exception.py +21 -0
  508. mlflow/tracing/utils/once.py +35 -0
  509. mlflow/tracing/utils/otlp.py +63 -0
  510. mlflow/tracing/utils/processor.py +54 -0
  511. mlflow/tracing/utils/search.py +292 -0
  512. mlflow/tracing/utils/timeout.py +250 -0
  513. mlflow/tracing/utils/token.py +19 -0
  514. mlflow/tracing/utils/truncation.py +124 -0
  515. mlflow/tracing/utils/warning.py +76 -0
  516. mlflow/tracking/__init__.py +39 -0
  517. mlflow/tracking/_model_registry/__init__.py +1 -0
  518. mlflow/tracking/_model_registry/client.py +764 -0
  519. mlflow/tracking/_model_registry/fluent.py +853 -0
  520. mlflow/tracking/_model_registry/registry.py +67 -0
  521. mlflow/tracking/_model_registry/utils.py +251 -0
  522. mlflow/tracking/_tracking_service/__init__.py +0 -0
  523. mlflow/tracking/_tracking_service/client.py +883 -0
  524. mlflow/tracking/_tracking_service/registry.py +56 -0
  525. mlflow/tracking/_tracking_service/utils.py +275 -0
  526. mlflow/tracking/artifact_utils.py +179 -0
  527. mlflow/tracking/client.py +5900 -0
  528. mlflow/tracking/context/__init__.py +0 -0
  529. mlflow/tracking/context/abstract_context.py +35 -0
  530. mlflow/tracking/context/databricks_cluster_context.py +15 -0
  531. mlflow/tracking/context/databricks_command_context.py +15 -0
  532. mlflow/tracking/context/databricks_job_context.py +49 -0
  533. mlflow/tracking/context/databricks_notebook_context.py +41 -0
  534. mlflow/tracking/context/databricks_repo_context.py +43 -0
  535. mlflow/tracking/context/default_context.py +51 -0
  536. mlflow/tracking/context/git_context.py +32 -0
  537. mlflow/tracking/context/registry.py +98 -0
  538. mlflow/tracking/context/system_environment_context.py +15 -0
  539. mlflow/tracking/default_experiment/__init__.py +1 -0
  540. mlflow/tracking/default_experiment/abstract_context.py +43 -0
  541. mlflow/tracking/default_experiment/databricks_notebook_experiment_provider.py +44 -0
  542. mlflow/tracking/default_experiment/registry.py +75 -0
  543. mlflow/tracking/fluent.py +3595 -0
  544. mlflow/tracking/metric_value_conversion_utils.py +93 -0
  545. mlflow/tracking/multimedia.py +206 -0
  546. mlflow/tracking/registry.py +86 -0
  547. mlflow/tracking/request_auth/__init__.py +0 -0
  548. mlflow/tracking/request_auth/abstract_request_auth_provider.py +34 -0
  549. mlflow/tracking/request_auth/registry.py +60 -0
  550. mlflow/tracking/request_header/__init__.py +0 -0
  551. mlflow/tracking/request_header/abstract_request_header_provider.py +36 -0
  552. mlflow/tracking/request_header/databricks_request_header_provider.py +38 -0
  553. mlflow/tracking/request_header/default_request_header_provider.py +17 -0
  554. mlflow/tracking/request_header/registry.py +79 -0
  555. mlflow/transformers/__init__.py +2982 -0
  556. mlflow/transformers/flavor_config.py +258 -0
  557. mlflow/transformers/hub_utils.py +83 -0
  558. mlflow/transformers/llm_inference_utils.py +468 -0
  559. mlflow/transformers/model_io.py +301 -0
  560. mlflow/transformers/peft.py +51 -0
  561. mlflow/transformers/signature.py +183 -0
  562. mlflow/transformers/torch_utils.py +55 -0
  563. mlflow/types/__init__.py +21 -0
  564. mlflow/types/agent.py +270 -0
  565. mlflow/types/chat.py +240 -0
  566. mlflow/types/llm.py +935 -0
  567. mlflow/types/responses.py +139 -0
  568. mlflow/types/responses_helpers.py +416 -0
  569. mlflow/types/schema.py +1505 -0
  570. mlflow/types/type_hints.py +647 -0
  571. mlflow/types/utils.py +753 -0
  572. mlflow/utils/__init__.py +283 -0
  573. mlflow/utils/_capture_modules.py +256 -0
  574. mlflow/utils/_capture_transformers_modules.py +75 -0
  575. mlflow/utils/_spark_utils.py +201 -0
  576. mlflow/utils/_unity_catalog_oss_utils.py +97 -0
  577. mlflow/utils/_unity_catalog_utils.py +479 -0
  578. mlflow/utils/annotations.py +218 -0
  579. mlflow/utils/arguments_utils.py +16 -0
  580. mlflow/utils/async_logging/__init__.py +1 -0
  581. mlflow/utils/async_logging/async_artifacts_logging_queue.py +258 -0
  582. mlflow/utils/async_logging/async_logging_queue.py +366 -0
  583. mlflow/utils/async_logging/run_artifact.py +38 -0
  584. mlflow/utils/async_logging/run_batch.py +58 -0
  585. mlflow/utils/async_logging/run_operations.py +49 -0
  586. mlflow/utils/autologging_utils/__init__.py +737 -0
  587. mlflow/utils/autologging_utils/client.py +432 -0
  588. mlflow/utils/autologging_utils/config.py +33 -0
  589. mlflow/utils/autologging_utils/events.py +294 -0
  590. mlflow/utils/autologging_utils/logging_and_warnings.py +328 -0
  591. mlflow/utils/autologging_utils/metrics_queue.py +71 -0
  592. mlflow/utils/autologging_utils/safety.py +1104 -0
  593. mlflow/utils/autologging_utils/versioning.py +95 -0
  594. mlflow/utils/checkpoint_utils.py +206 -0
  595. mlflow/utils/class_utils.py +6 -0
  596. mlflow/utils/cli_args.py +257 -0
  597. mlflow/utils/conda.py +354 -0
  598. mlflow/utils/credentials.py +231 -0
  599. mlflow/utils/data_utils.py +17 -0
  600. mlflow/utils/databricks_utils.py +1436 -0
  601. mlflow/utils/docstring_utils.py +477 -0
  602. mlflow/utils/doctor.py +133 -0
  603. mlflow/utils/download_cloud_file_chunk.py +43 -0
  604. mlflow/utils/env_manager.py +16 -0
  605. mlflow/utils/env_pack.py +131 -0
  606. mlflow/utils/environment.py +1009 -0
  607. mlflow/utils/exception_utils.py +14 -0
  608. mlflow/utils/file_utils.py +978 -0
  609. mlflow/utils/git_utils.py +77 -0
  610. mlflow/utils/gorilla.py +797 -0
  611. mlflow/utils/import_hooks/__init__.py +363 -0
  612. mlflow/utils/lazy_load.py +51 -0
  613. mlflow/utils/logging_utils.py +168 -0
  614. mlflow/utils/mime_type_utils.py +58 -0
  615. mlflow/utils/mlflow_tags.py +103 -0
  616. mlflow/utils/model_utils.py +486 -0
  617. mlflow/utils/name_utils.py +346 -0
  618. mlflow/utils/nfs_on_spark.py +62 -0
  619. mlflow/utils/openai_utils.py +164 -0
  620. mlflow/utils/os.py +12 -0
  621. mlflow/utils/oss_registry_utils.py +29 -0
  622. mlflow/utils/plugins.py +17 -0
  623. mlflow/utils/process.py +182 -0
  624. mlflow/utils/promptlab_utils.py +146 -0
  625. mlflow/utils/proto_json_utils.py +743 -0
  626. mlflow/utils/pydantic_utils.py +54 -0
  627. mlflow/utils/request_utils.py +279 -0
  628. mlflow/utils/requirements_utils.py +704 -0
  629. mlflow/utils/rest_utils.py +673 -0
  630. mlflow/utils/search_logged_model_utils.py +127 -0
  631. mlflow/utils/search_utils.py +2111 -0
  632. mlflow/utils/secure_loading.py +221 -0
  633. mlflow/utils/security_validation.py +384 -0
  634. mlflow/utils/server_cli_utils.py +61 -0
  635. mlflow/utils/spark_utils.py +15 -0
  636. mlflow/utils/string_utils.py +138 -0
  637. mlflow/utils/thread_utils.py +63 -0
  638. mlflow/utils/time.py +54 -0
  639. mlflow/utils/timeout.py +42 -0
  640. mlflow/utils/uri.py +572 -0
  641. mlflow/utils/validation.py +662 -0
  642. mlflow/utils/virtualenv.py +458 -0
  643. mlflow/utils/warnings_utils.py +25 -0
  644. mlflow/utils/yaml_utils.py +179 -0
  645. mlflow/version.py +24 -0
@@ -0,0 +1,434 @@
1
+ import logging
2
+ import operator
3
+ import os
4
+ from decimal import Decimal
5
+ from typing import Optional
6
+
7
+ from mlflow.exceptions import MlflowException
8
+ from mlflow.models.evaluation import EvaluationResult
9
+ from mlflow.protos.databricks_pb2 import BAD_REQUEST, INVALID_PARAMETER_VALUE
10
+
11
+ _logger = logging.getLogger(__name__)
12
+
13
+
14
+ class MetricThreshold:
15
+ """
16
+ This class allows you to define metric thresholds for model validation.
17
+ Allowed thresholds are: threshold, min_absolute_change, min_relative_change.
18
+
19
+ Args:
20
+ threshold: (Optional) A number representing the value threshold for the metric.
21
+
22
+ - If greater is better for the metric, the metric value has to be
23
+ >= threshold to pass validation.
24
+ - Otherwise, the metric value has to be <= threshold to pass the validation.
25
+
26
+ min_absolute_change: (Optional) A positive number representing the minimum absolute
27
+ change required for candidate model to pass validation with
28
+ the baseline model.
29
+
30
+ - If greater is better for the metric, metric value has to be
31
+ >= baseline model metric value + min_absolute_change to pass the validation.
32
+ - Otherwise, metric value has to be <= baseline model metric value - min_absolute_change
33
+ to pass the validation.
34
+
35
+ min_relative_change: (Optional) A floating point number between 0 and 1 representing
36
+ the minimum relative change (in percentage of
37
+ baseline model metric value) for candidate model
38
+ to pass the comparison with the baseline model.
39
+
40
+ - If greater is better for the metric, metric value has to be
41
+ >= baseline model metric value * (1 + min_relative_change)
42
+ - Otherwise, metric value has to be
43
+ <= baseline model metric value * (1 - min_relative_change)
44
+ - Note that if the baseline model metric value is equal to 0, the
45
+ threshold falls back performing a simple verification that the
46
+ candidate metric value is better than the baseline metric value,
47
+ i.e. metric value >= baseline model metric value + 1e-10 if greater
48
+ is better; metric value <= baseline model metric value - 1e-10 if
49
+ lower is better.
50
+
51
+ greater_is_better: A required boolean representing whether greater value is
52
+ better for the metric.
53
+ """
54
+
55
+ def __init__(
56
+ self,
57
+ threshold=None,
58
+ min_absolute_change=None,
59
+ min_relative_change=None,
60
+ greater_is_better=None,
61
+ ):
62
+ if threshold is not None and type(threshold) not in {int, float}:
63
+ raise MetricThresholdClassException("`threshold` parameter must be a number.")
64
+ if min_absolute_change is not None and (
65
+ type(min_absolute_change) not in {int, float} or min_absolute_change <= 0
66
+ ):
67
+ raise MetricThresholdClassException(
68
+ "`min_absolute_change` parameter must be a positive number."
69
+ )
70
+ if min_relative_change is not None:
71
+ if not isinstance(min_relative_change, float):
72
+ raise MetricThresholdClassException(
73
+ "`min_relative_change` parameter must be a floating point number."
74
+ )
75
+ if min_relative_change < 0 or min_relative_change > 1:
76
+ raise MetricThresholdClassException(
77
+ "`min_relative_change` parameter must be between 0 and 1."
78
+ )
79
+ if greater_is_better is None:
80
+ raise MetricThresholdClassException("`greater_is_better` parameter must be defined.")
81
+ if not isinstance(greater_is_better, bool):
82
+ raise MetricThresholdClassException("`greater_is_better` parameter must be a boolean.")
83
+ if threshold is None and min_absolute_change is None and min_relative_change is None:
84
+ raise MetricThresholdClassException("no threshold was specified.")
85
+ self._threshold = threshold
86
+ self._min_absolute_change = min_absolute_change
87
+ self._min_relative_change = min_relative_change
88
+ self._greater_is_better = greater_is_better
89
+
90
+ @property
91
+ def threshold(self):
92
+ """
93
+ Value of the threshold.
94
+ """
95
+ return self._threshold
96
+
97
+ @property
98
+ def min_absolute_change(self):
99
+ """
100
+ Value of the minimum absolute change required to pass model comparison with baseline model.
101
+ """
102
+ return self._min_absolute_change
103
+
104
+ @property
105
+ def min_relative_change(self):
106
+ """
107
+ Float value of the minimum relative change required to pass model comparison with
108
+ baseline model.
109
+ """
110
+ return self._min_relative_change
111
+
112
+ @property
113
+ def greater_is_better(self):
114
+ """
115
+ Boolean value representing whether greater value is better for the metric.
116
+ """
117
+ return self._greater_is_better
118
+
119
+ def __str__(self):
120
+ """
121
+ Returns a human-readable string consisting of all specified thresholds.
122
+ """
123
+ threshold_strs = []
124
+ if self._threshold is not None:
125
+ threshold_strs.append(f"Threshold: {self._threshold}.")
126
+ if self._min_absolute_change is not None:
127
+ threshold_strs.append(f"Minimum Absolute Change: {self._min_absolute_change}.")
128
+ if self._min_relative_change is not None:
129
+ threshold_strs.append(f"Minimum Relative Change: {self._min_relative_change}.")
130
+ if self._greater_is_better is not None:
131
+ if self._greater_is_better:
132
+ threshold_strs.append("Greater value is better.")
133
+ else:
134
+ threshold_strs.append("Lower value is better.")
135
+ return " ".join(threshold_strs)
136
+
137
+
138
+ class MetricThresholdClassException(MlflowException):
139
+ def __init__(self, _message, **kwargs):
140
+ message = "Could not instantiate MetricThreshold class: " + _message
141
+ super().__init__(message, error_code=INVALID_PARAMETER_VALUE, **kwargs)
142
+
143
+
144
+ class _MetricValidationResult:
145
+ """
146
+ Internal class for representing validation result per metric.
147
+ Not user facing, used for organizing metric failures and generating failure message
148
+ more conveniently.
149
+
150
+ Args:
151
+ metric_name: String representing the metric name
152
+ candidate_metric_value: value of metric for candidate model
153
+ metric_threshold: :py:class: `MetricThreshold<mlflow.models.validation.MetricThreshold>`
154
+ The MetricThreshold for the metric.
155
+ baseline_metric_value: value of metric for baseline model
156
+ """
157
+
158
+ missing_candidate = False
159
+ missing_baseline = False
160
+ threshold_failed = False
161
+ min_absolute_change_failed = False
162
+ min_relative_change_failed = False
163
+
164
+ def __init__(
165
+ self,
166
+ metric_name,
167
+ candidate_metric_value,
168
+ metric_threshold,
169
+ baseline_metric_value=None,
170
+ ):
171
+ self.metric_name = metric_name
172
+ self.candidate_metric_value = candidate_metric_value
173
+ self.baseline_metric_value = baseline_metric_value
174
+ self.metric_threshold = metric_threshold
175
+
176
+ def __str__(self):
177
+ """
178
+ Returns a human-readable string representing the validation result for the metric.
179
+ """
180
+ if self.is_success():
181
+ return f"Metric {self.metric_name} passed the validation."
182
+
183
+ if self.missing_candidate:
184
+ return (
185
+ f"Metric validation failed: metric {self.metric_name} was missing from the "
186
+ f"evaluation result of the candidate model."
187
+ )
188
+
189
+ result_strs = []
190
+ if self.threshold_failed:
191
+ result_strs.append(
192
+ f"Metric {self.metric_name} value threshold check failed: "
193
+ f"candidate model {self.metric_name} = {self.candidate_metric_value}, "
194
+ f"{self.metric_name} threshold = {self.metric_threshold.threshold}."
195
+ )
196
+ if self.missing_baseline:
197
+ result_strs.append(
198
+ f"Model comparison failed: metric {self.metric_name} was missing from "
199
+ f"the evaluation result of the baseline model."
200
+ )
201
+ else:
202
+ if self.min_absolute_change_failed:
203
+ result_strs.append(
204
+ f"Metric {self.metric_name} minimum absolute change check failed: "
205
+ f"candidate model {self.metric_name} = {self.candidate_metric_value}, "
206
+ f"baseline model {self.metric_name} = {self.baseline_metric_value}, "
207
+ f"{self.metric_name} minimum absolute change threshold = "
208
+ f"{self.metric_threshold.min_absolute_change}."
209
+ )
210
+ if self.min_relative_change_failed:
211
+ result_strs.append(
212
+ f"Metric {self.metric_name} minimum relative change check failed: "
213
+ f"candidate model {self.metric_name} = {self.candidate_metric_value}, "
214
+ f"baseline model {self.metric_name} = {self.baseline_metric_value}, "
215
+ f"{self.metric_name} minimum relative change threshold = "
216
+ f"{self.metric_threshold.min_relative_change}."
217
+ )
218
+ return " ".join(result_strs)
219
+
220
+ def is_success(self):
221
+ return (
222
+ not self.missing_candidate
223
+ and not self.missing_baseline
224
+ and not self.threshold_failed
225
+ and not self.min_absolute_change_failed
226
+ and not self.min_relative_change_failed
227
+ )
228
+
229
+
230
+ class ModelValidationFailedException(MlflowException):
231
+ def __init__(self, message, **kwargs):
232
+ super().__init__(message, error_code=BAD_REQUEST, **kwargs)
233
+
234
+
235
+ def validate_evaluation_results(
236
+ validation_thresholds: dict[str, MetricThreshold],
237
+ candidate_result: EvaluationResult,
238
+ baseline_result: Optional[EvaluationResult] = None,
239
+ ):
240
+ """
241
+ Validate the evaluation result from one model (candidate) against another
242
+ model (baseline). If the candidate results do not meet the validation
243
+ thresholds, an ModelValidationFailedException will be raised.
244
+
245
+ .. note::
246
+
247
+ This API is a replacement for the deprecated model validation
248
+ functionality in the :py:func:`mlflow.evaluate` API.
249
+
250
+ Args:
251
+ validation_thresholds: A dictionary of metric name to
252
+ :py:class:`mlflow.models.MetricThreshold` used for model validation.
253
+ Each metric name must either be the name of a builtin metric or the
254
+ name of a metric defined in the ``extra_metrics`` parameter.
255
+ candidate_result: The evaluation result of the candidate model.
256
+ Returned by the :py:func:`mlflow.evaluate` API.
257
+ baseline_result: The evaluation result of the baseline model.
258
+ Returned by the :py:func:`mlflow.evaluate` API.
259
+ If set to None, the candidate model result will be
260
+ compared against the threshold values directly.
261
+
262
+ Code Example:
263
+
264
+ .. code-block:: python
265
+ :caption: Example of Model Validation
266
+
267
+ import mlflow
268
+ from mlflow.models import MetricThreshold
269
+
270
+ thresholds = {
271
+ "accuracy_score": MetricThreshold(
272
+ # accuracy should be >=0.8
273
+ threshold=0.8,
274
+ # accuracy should be at least 5 percent greater than baseline model accuracy
275
+ min_absolute_change=0.05,
276
+ # accuracy should be at least 0.05 greater than baseline model accuracy
277
+ min_relative_change=0.05,
278
+ greater_is_better=True,
279
+ ),
280
+ }
281
+
282
+ # Get evaluation results for the candidate model
283
+ candidate_result = mlflow.evaluate(
284
+ model="<YOUR_CANDIDATE_MODEL_URI>",
285
+ data=eval_dataset,
286
+ targets="ground_truth",
287
+ model_type="classifier",
288
+ )
289
+
290
+ # Get evaluation results for the baseline model
291
+ baseline_result = mlflow.evaluate(
292
+ model="<YOUR_BASELINE_MODEL_URI>",
293
+ data=eval_dataset,
294
+ targets="ground_truth",
295
+ model_type="classifier",
296
+ )
297
+
298
+ # Validate the results
299
+ mlflow.validate_evaluation_results(
300
+ thresholds,
301
+ candidate_result,
302
+ baseline_result,
303
+ )
304
+
305
+ See `the Model Validation documentation
306
+ <../../models/index.html#performing-model-validation>`_ for more details.
307
+ """
308
+ try:
309
+ assert type(validation_thresholds) is dict
310
+ for key in validation_thresholds.keys():
311
+ assert type(key) is str
312
+ for threshold in validation_thresholds.values():
313
+ assert isinstance(threshold, MetricThreshold)
314
+ except AssertionError:
315
+ raise MlflowException(
316
+ message="The validation thresholds argument must be a dictionary that maps strings "
317
+ "to MetricThreshold objects.",
318
+ error_code=INVALID_PARAMETER_VALUE,
319
+ )
320
+
321
+ _logger.info("Validating candidate model metrics against baseline")
322
+ _validate(
323
+ validation_thresholds,
324
+ candidate_result.metrics,
325
+ baseline_result.metrics if baseline_result else {},
326
+ )
327
+ _logger.info("Model validation passed!")
328
+
329
+
330
+ def _validate(
331
+ validation_thresholds: dict[str, MetricThreshold],
332
+ candidate_metrics: dict[str, float],
333
+ baseline_metrics: dict[str, float],
334
+ ):
335
+ """
336
+ Validate the model based on validation_thresholds by metrics value and
337
+ metrics comparison between candidate model's metrics (candidate_metrics) and
338
+ baseline model's metrics (baseline_metrics).
339
+
340
+ Args:
341
+ validation_thresholds: A dictionary from metric_name to MetricThreshold.
342
+ candidate_metrics: The metric evaluation result of the candidate model.
343
+ baseline_metrics: The metric evaluation result of the baseline model.
344
+
345
+ Raises:
346
+ If the validation does not pass, raise an MlflowException with detail failure message.
347
+ """
348
+ validation_results = {
349
+ metric_name: _MetricValidationResult(
350
+ metric_name,
351
+ candidate_metrics.get(metric_name),
352
+ threshold,
353
+ baseline_metrics.get(metric_name),
354
+ )
355
+ for (metric_name, threshold) in validation_thresholds.items()
356
+ }
357
+
358
+ for metric_name, metric_threshold in validation_thresholds.items():
359
+ validation_result = validation_results[metric_name]
360
+
361
+ if metric_name not in candidate_metrics:
362
+ validation_result.missing_candidate = True
363
+ continue
364
+
365
+ candidate_metric_value = candidate_metrics[metric_name]
366
+ baseline_metric_value = baseline_metrics[metric_name] if baseline_metrics else None
367
+
368
+ # If metric is greater is better, >= is used, otherwise <= is used
369
+ # for thresholding metric value and model comparison
370
+ comparator_fn = operator.__ge__ if metric_threshold.greater_is_better else operator.__le__
371
+ operator_fn = operator.add if metric_threshold.greater_is_better else operator.sub
372
+
373
+ if metric_threshold.threshold is not None:
374
+ # metric threshold fails
375
+ # - if not (metric_value >= threshold) for greater is better
376
+ # - if not (metric_value <= threshold) for lower is better
377
+ validation_result.threshold_failed = not comparator_fn(
378
+ candidate_metric_value, metric_threshold.threshold
379
+ )
380
+
381
+ if (
382
+ metric_threshold.min_relative_change or metric_threshold.min_absolute_change
383
+ ) and metric_name not in baseline_metrics:
384
+ validation_result.missing_baseline = True
385
+ continue
386
+
387
+ if metric_threshold.min_absolute_change is not None:
388
+ # metric comparison absolute change fails
389
+ # - if not (metric_value >= baseline + min_absolute_change) for greater is better
390
+ # - if not (metric_value <= baseline - min_absolute_change) for lower is better
391
+ validation_result.min_absolute_change_failed = not comparator_fn(
392
+ Decimal(candidate_metric_value),
393
+ Decimal(operator_fn(baseline_metric_value, metric_threshold.min_absolute_change)),
394
+ )
395
+
396
+ if metric_threshold.min_relative_change is not None:
397
+ # If baseline metric value equals 0, fallback to simple comparison check
398
+ if baseline_metric_value == 0:
399
+ _logger.warning(
400
+ f"Cannot perform relative model comparison for metric {metric_name} as "
401
+ "baseline metric value is 0. Falling back to simple comparison: verifying "
402
+ "that candidate metric value is better than the baseline metric value."
403
+ )
404
+ validation_result.min_relative_change_failed = not comparator_fn(
405
+ Decimal(candidate_metric_value),
406
+ Decimal(operator_fn(baseline_metric_value, 1e-10)),
407
+ )
408
+ continue
409
+ # metric comparison relative change fails
410
+ # - if (metric_value - baseline) / baseline < min_relative_change for greater is better
411
+ # - if (baseline - metric_value) / baseline < min_relative_change for lower is better
412
+ if metric_threshold.greater_is_better:
413
+ relative_change = (
414
+ candidate_metric_value - baseline_metric_value
415
+ ) / baseline_metric_value
416
+ else:
417
+ relative_change = (
418
+ baseline_metric_value - candidate_metric_value
419
+ ) / baseline_metric_value
420
+ validation_result.min_relative_change_failed = (
421
+ relative_change < metric_threshold.min_relative_change
422
+ )
423
+
424
+ failure_messages = []
425
+
426
+ for metric_validation_result in validation_results.values():
427
+ if metric_validation_result.is_success():
428
+ continue
429
+ failure_messages.append(str(metric_validation_result))
430
+
431
+ if not failure_messages:
432
+ return
433
+
434
+ raise ModelValidationFailedException(message=os.linesep.join(failure_messages))
@@ -0,0 +1,93 @@
1
+ from abc import ABCMeta, abstractmethod
2
+
3
+ from mlflow.utils.annotations import developer_stable
4
+
5
+
6
+ @developer_stable
7
+ class FlavorBackend:
8
+ """
9
+ Abstract class for Flavor Backend.
10
+ This class defines the API interface for local model deployment of MLflow model flavors.
11
+ """
12
+
13
+ __metaclass__ = ABCMeta
14
+
15
+ def __init__(self, config, **kwargs):
16
+ self._config = config
17
+
18
+ @abstractmethod
19
+ def predict(self, model_uri, input_path, output_path, content_type):
20
+ """
21
+ Generate predictions using a saved MLflow model referenced by the given URI.
22
+ Input and output are read from and written to a file or stdin / stdout.
23
+
24
+ Args:
25
+ model_uri: URI pointing to the MLflow model to be used for scoring.
26
+ input_path: Path to the file with input data. If not specified, data is read from
27
+ stdin.
28
+ output_path: Path to the file with output predictions. If not specified, data is
29
+ written to stdout.
30
+ content_type: Specifies the input format. Can be one of {``json``, ``csv``}
31
+ """
32
+
33
+ @abstractmethod
34
+ def serve(
35
+ self,
36
+ model_uri,
37
+ port,
38
+ host,
39
+ timeout,
40
+ enable_mlserver,
41
+ synchronous=True,
42
+ stdout=None,
43
+ stderr=None,
44
+ ):
45
+ """
46
+ Serve the specified MLflow model locally.
47
+
48
+ Args:
49
+ model_uri: URI pointing to the MLflow model to be used for scoring.
50
+ port: Port to use for the model deployment.
51
+ host: Host to use for the model deployment. Defaults to ``localhost``.
52
+ timeout: Timeout in seconds to serve a request. Defaults to 60.
53
+ enable_mlserver: Whether to use MLServer or the local scoring server.
54
+ synchronous: If True, wait until server process exit and return 0, if process exit
55
+ with non-zero return code, raise exception.
56
+ If False, return the server process `Popen` instance immediately.
57
+ stdout: Redirect server stdout
58
+ stderr: Redirect server stderr
59
+ """
60
+
61
+ def prepare_env(self, model_uri, capture_output=False):
62
+ """
63
+ Performs any preparation necessary to predict or serve the model, for example
64
+ downloading dependencies or initializing a conda environment. After preparation,
65
+ calling predict or serve should be fast.
66
+ """
67
+
68
+ @abstractmethod
69
+ def build_image(
70
+ self, model_uri, image_name, install_mlflow, mlflow_home, enable_mlserver, base_image=None
71
+ ): ...
72
+
73
+ @abstractmethod
74
+ def generate_dockerfile(
75
+ self, model_uri, output_path, install_mlflow, mlflow_home, enable_mlserver, base_image=None
76
+ ): ...
77
+
78
+ @abstractmethod
79
+ def can_score_model(self):
80
+ """
81
+ Check whether this flavor backend can be deployed in the current environment.
82
+
83
+ Returns:
84
+ True if this flavor backend can be applied in the current environment.
85
+ """
86
+
87
+ def can_build_image(self):
88
+ """
89
+ Returns:
90
+ True if this flavor has a `build_image` method defined for building a docker
91
+ container capable of serving the model, False otherwise.
92
+ """
93
+ return callable(getattr(self.__class__, "build_image", None))
@@ -0,0 +1,53 @@
1
+ """
2
+ Registry of supported flavor backends. Contains a mapping of flavors to flavor backends. This
3
+ mapping is used to select suitable flavor when deploying generic MLflow models.
4
+
5
+ Flavor backend can deploy particular flavor locally to generate predictions, deploy as a local
6
+ REST api endpoint, or build a docker image for serving the model locally or remotely.
7
+ Not all flavors have a flavor backend.
8
+ """
9
+
10
+ import logging
11
+
12
+ from mlflow.models.model import Model
13
+ from mlflow.store.artifact.artifact_repository_registry import get_artifact_repository
14
+ from mlflow.tracking.artifact_utils import (
15
+ _get_root_uri_and_artifact_path,
16
+ )
17
+ from mlflow.utils.file_utils import TempDir
18
+
19
+ _logger = logging.getLogger(__name__)
20
+
21
+
22
+ def _get_flavor_backend_for_local_model(model=None, build_docker=True, **kwargs):
23
+ from mlflow import pyfunc, rfunc
24
+ from mlflow.pyfunc.backend import PyFuncBackend
25
+ from mlflow.rfunc.backend import RFuncBackend
26
+
27
+ if not model:
28
+ return pyfunc.FLAVOR_NAME, PyFuncBackend({}, **kwargs)
29
+
30
+ backends = {pyfunc.FLAVOR_NAME: PyFuncBackend, rfunc.FLAVOR_NAME: RFuncBackend}
31
+ for flavor, Backend in backends.items():
32
+ if flavor in model.flavors:
33
+ backend = Backend(model.flavors[flavor], **kwargs)
34
+ if (build_docker and backend.can_build_image()) or backend.can_score_model():
35
+ return flavor, backend
36
+
37
+ return None, None
38
+
39
+
40
+ def get_flavor_backend(model_uri, **kwargs):
41
+ if model_uri:
42
+ with TempDir() as tmp:
43
+ root_uri, artifact_path = _get_root_uri_and_artifact_path(model_uri)
44
+ artifact_repo = get_artifact_repository(root_uri)
45
+ local_path = artifact_repo.download_artifacts(artifact_path, dst_path=tmp.path())
46
+ model = Model.load(local_path)
47
+ else:
48
+ model = None
49
+ flavor_name, flavor_backend = _get_flavor_backend_for_local_model(model, **kwargs)
50
+ if flavor_backend is None:
51
+ raise Exception("No suitable flavor backend was found for the model.")
52
+ _logger.info("Selected backend for flavor '%s'", flavor_name)
53
+ return flavor_backend