mlrun 1.6.4rc2__py3-none-any.whl → 1.7.0rc20__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.
Potentially problematic release.
This version of mlrun might be problematic. Click here for more details.
- mlrun/__init__.py +11 -1
- mlrun/__main__.py +26 -112
- mlrun/alerts/__init__.py +15 -0
- mlrun/alerts/alert.py +144 -0
- mlrun/api/schemas/__init__.py +5 -4
- mlrun/artifacts/__init__.py +8 -3
- mlrun/artifacts/base.py +46 -257
- mlrun/artifacts/dataset.py +11 -192
- mlrun/artifacts/manager.py +47 -48
- mlrun/artifacts/model.py +31 -159
- mlrun/artifacts/plots.py +23 -380
- mlrun/common/constants.py +69 -0
- mlrun/common/db/sql_session.py +2 -3
- mlrun/common/formatters/__init__.py +19 -0
- mlrun/common/formatters/artifact.py +21 -0
- mlrun/common/formatters/base.py +78 -0
- mlrun/common/formatters/function.py +41 -0
- mlrun/common/formatters/pipeline.py +53 -0
- mlrun/common/formatters/project.py +51 -0
- mlrun/common/helpers.py +1 -2
- mlrun/common/model_monitoring/helpers.py +9 -5
- mlrun/{runtimes → common/runtimes}/constants.py +37 -9
- mlrun/common/schemas/__init__.py +24 -4
- mlrun/common/schemas/alert.py +203 -0
- mlrun/common/schemas/api_gateway.py +148 -0
- mlrun/common/schemas/artifact.py +18 -8
- mlrun/common/schemas/auth.py +11 -5
- mlrun/common/schemas/background_task.py +1 -1
- mlrun/common/schemas/client_spec.py +4 -1
- mlrun/common/schemas/feature_store.py +16 -16
- mlrun/common/schemas/frontend_spec.py +8 -7
- mlrun/common/schemas/function.py +5 -1
- mlrun/common/schemas/hub.py +11 -18
- mlrun/common/schemas/memory_reports.py +2 -2
- mlrun/common/schemas/model_monitoring/__init__.py +18 -3
- mlrun/common/schemas/model_monitoring/constants.py +83 -26
- mlrun/common/schemas/model_monitoring/grafana.py +13 -9
- mlrun/common/schemas/model_monitoring/model_endpoints.py +99 -16
- mlrun/common/schemas/notification.py +4 -4
- mlrun/common/schemas/object.py +2 -2
- mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
- mlrun/common/schemas/pipeline.py +1 -10
- mlrun/common/schemas/project.py +24 -23
- mlrun/common/schemas/runtime_resource.py +8 -12
- mlrun/common/schemas/schedule.py +3 -3
- mlrun/common/schemas/tag.py +1 -2
- mlrun/common/schemas/workflow.py +2 -2
- mlrun/common/types.py +7 -1
- mlrun/config.py +54 -17
- mlrun/data_types/to_pandas.py +10 -12
- mlrun/datastore/__init__.py +5 -8
- mlrun/datastore/alibaba_oss.py +130 -0
- mlrun/datastore/azure_blob.py +17 -5
- mlrun/datastore/base.py +62 -39
- mlrun/datastore/datastore.py +28 -9
- mlrun/datastore/datastore_profile.py +146 -20
- mlrun/datastore/filestore.py +0 -1
- mlrun/datastore/google_cloud_storage.py +6 -2
- mlrun/datastore/hdfs.py +56 -0
- mlrun/datastore/inmem.py +2 -2
- mlrun/datastore/redis.py +6 -2
- mlrun/datastore/s3.py +9 -0
- mlrun/datastore/snowflake_utils.py +43 -0
- mlrun/datastore/sources.py +201 -96
- mlrun/datastore/spark_utils.py +1 -2
- mlrun/datastore/store_resources.py +7 -7
- mlrun/datastore/targets.py +358 -104
- mlrun/datastore/utils.py +72 -58
- mlrun/datastore/v3io.py +5 -1
- mlrun/db/base.py +185 -35
- mlrun/db/factory.py +1 -1
- mlrun/db/httpdb.py +614 -179
- mlrun/db/nopdb.py +210 -26
- mlrun/errors.py +12 -1
- mlrun/execution.py +41 -24
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +40 -72
- mlrun/feature_store/common.py +1 -1
- mlrun/feature_store/feature_set.py +76 -55
- mlrun/feature_store/feature_vector.py +28 -30
- mlrun/feature_store/ingestion.py +7 -6
- mlrun/feature_store/retrieval/base.py +16 -11
- mlrun/feature_store/retrieval/conversion.py +11 -13
- mlrun/feature_store/retrieval/dask_merger.py +2 -0
- mlrun/feature_store/retrieval/job.py +9 -3
- mlrun/feature_store/retrieval/local_merger.py +2 -0
- mlrun/feature_store/retrieval/spark_merger.py +34 -24
- mlrun/feature_store/steps.py +37 -34
- mlrun/features.py +9 -20
- mlrun/frameworks/_common/artifacts_library.py +9 -9
- mlrun/frameworks/_common/mlrun_interface.py +5 -5
- mlrun/frameworks/_common/model_handler.py +48 -48
- mlrun/frameworks/_common/plan.py +2 -3
- mlrun/frameworks/_common/producer.py +3 -4
- mlrun/frameworks/_common/utils.py +5 -5
- mlrun/frameworks/_dl_common/loggers/logger.py +6 -7
- mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +9 -9
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +23 -47
- mlrun/frameworks/_ml_common/artifacts_library.py +1 -2
- mlrun/frameworks/_ml_common/loggers/logger.py +3 -4
- mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +4 -5
- mlrun/frameworks/_ml_common/model_handler.py +24 -24
- mlrun/frameworks/_ml_common/pkl_model_server.py +2 -2
- mlrun/frameworks/_ml_common/plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +2 -3
- mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +2 -3
- mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
- mlrun/frameworks/_ml_common/utils.py +4 -4
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +9 -9
- mlrun/frameworks/huggingface/model_server.py +4 -4
- mlrun/frameworks/lgbm/__init__.py +33 -33
- mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
- mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -5
- mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -5
- mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -3
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +6 -6
- mlrun/frameworks/lgbm/model_handler.py +10 -10
- mlrun/frameworks/lgbm/model_server.py +6 -6
- mlrun/frameworks/lgbm/utils.py +5 -5
- mlrun/frameworks/onnx/dataset.py +8 -8
- mlrun/frameworks/onnx/mlrun_interface.py +3 -3
- mlrun/frameworks/onnx/model_handler.py +6 -6
- mlrun/frameworks/onnx/model_server.py +7 -7
- mlrun/frameworks/parallel_coordinates.py +4 -3
- mlrun/frameworks/pytorch/__init__.py +18 -18
- mlrun/frameworks/pytorch/callbacks/callback.py +4 -5
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +17 -17
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +11 -11
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +23 -29
- mlrun/frameworks/pytorch/callbacks_handler.py +38 -38
- mlrun/frameworks/pytorch/mlrun_interface.py +20 -20
- mlrun/frameworks/pytorch/model_handler.py +17 -17
- mlrun/frameworks/pytorch/model_server.py +7 -7
- mlrun/frameworks/sklearn/__init__.py +13 -13
- mlrun/frameworks/sklearn/estimator.py +4 -4
- mlrun/frameworks/sklearn/metrics_library.py +14 -14
- mlrun/frameworks/sklearn/mlrun_interface.py +3 -6
- mlrun/frameworks/sklearn/model_handler.py +2 -2
- mlrun/frameworks/tf_keras/__init__.py +10 -7
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +15 -15
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +11 -11
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +19 -23
- mlrun/frameworks/tf_keras/mlrun_interface.py +9 -11
- mlrun/frameworks/tf_keras/model_handler.py +14 -14
- mlrun/frameworks/tf_keras/model_server.py +6 -6
- mlrun/frameworks/xgboost/__init__.py +13 -13
- mlrun/frameworks/xgboost/model_handler.py +6 -6
- mlrun/k8s_utils.py +14 -16
- mlrun/launcher/__init__.py +1 -1
- mlrun/launcher/base.py +16 -15
- mlrun/launcher/client.py +8 -6
- mlrun/launcher/factory.py +1 -1
- mlrun/launcher/local.py +17 -11
- mlrun/launcher/remote.py +16 -10
- mlrun/lists.py +7 -6
- mlrun/model.py +238 -73
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/api.py +138 -315
- mlrun/model_monitoring/application.py +5 -296
- mlrun/model_monitoring/applications/__init__.py +24 -0
- mlrun/model_monitoring/applications/_application_steps.py +157 -0
- mlrun/model_monitoring/applications/base.py +282 -0
- mlrun/model_monitoring/applications/context.py +214 -0
- mlrun/model_monitoring/applications/evidently_base.py +211 -0
- mlrun/model_monitoring/applications/histogram_data_drift.py +349 -0
- mlrun/model_monitoring/applications/results.py +99 -0
- mlrun/model_monitoring/controller.py +104 -84
- mlrun/model_monitoring/controller_handler.py +13 -5
- mlrun/model_monitoring/db/__init__.py +18 -0
- mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
- mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
- mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +64 -40
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
- mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -0
- mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +684 -0
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
- mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +310 -165
- mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
- mlrun/model_monitoring/db/tsdb/base.py +329 -0
- mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
- mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
- mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
- mlrun/model_monitoring/evidently_application.py +6 -118
- mlrun/model_monitoring/features_drift_table.py +134 -106
- mlrun/model_monitoring/helpers.py +127 -28
- mlrun/model_monitoring/metrics/__init__.py +13 -0
- mlrun/model_monitoring/metrics/histogram_distance.py +127 -0
- mlrun/model_monitoring/model_endpoint.py +3 -2
- mlrun/model_monitoring/prometheus.py +1 -4
- mlrun/model_monitoring/stream_processing.py +62 -231
- mlrun/model_monitoring/tracking_policy.py +9 -2
- mlrun/model_monitoring/writer.py +152 -124
- mlrun/package/__init__.py +6 -6
- mlrun/package/context_handler.py +5 -5
- mlrun/package/packager.py +7 -7
- mlrun/package/packagers/default_packager.py +6 -6
- mlrun/package/packagers/numpy_packagers.py +15 -15
- mlrun/package/packagers/pandas_packagers.py +5 -5
- mlrun/package/packagers/python_standard_library_packagers.py +10 -10
- mlrun/package/packagers_manager.py +19 -23
- mlrun/package/utils/_formatter.py +6 -6
- mlrun/package/utils/_pickler.py +2 -2
- mlrun/package/utils/_supported_format.py +4 -4
- mlrun/package/utils/log_hint_utils.py +2 -2
- mlrun/package/utils/type_hint_utils.py +4 -9
- mlrun/platforms/__init__.py +11 -10
- mlrun/platforms/iguazio.py +24 -203
- mlrun/projects/operations.py +35 -21
- mlrun/projects/pipelines.py +68 -99
- mlrun/projects/project.py +830 -266
- mlrun/render.py +3 -11
- mlrun/run.py +162 -166
- mlrun/runtimes/__init__.py +62 -7
- mlrun/runtimes/base.py +39 -32
- mlrun/runtimes/daskjob.py +8 -8
- mlrun/runtimes/databricks_job/databricks_cancel_task.py +1 -1
- mlrun/runtimes/databricks_job/databricks_runtime.py +7 -7
- mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
- mlrun/runtimes/funcdoc.py +0 -28
- mlrun/runtimes/function_reference.py +1 -1
- mlrun/runtimes/kubejob.py +28 -122
- mlrun/runtimes/local.py +6 -3
- mlrun/runtimes/mpijob/__init__.py +0 -20
- mlrun/runtimes/mpijob/abstract.py +9 -10
- mlrun/runtimes/mpijob/v1.py +1 -1
- mlrun/{model_monitoring/stores/models/sqlite.py → runtimes/nuclio/__init__.py} +7 -9
- mlrun/runtimes/nuclio/api_gateway.py +709 -0
- mlrun/runtimes/nuclio/application/__init__.py +15 -0
- mlrun/runtimes/nuclio/application/application.py +523 -0
- mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
- mlrun/runtimes/{function.py → nuclio/function.py} +112 -73
- mlrun/runtimes/{nuclio.py → nuclio/nuclio.py} +6 -6
- mlrun/runtimes/{serving.py → nuclio/serving.py} +45 -51
- mlrun/runtimes/pod.py +286 -88
- mlrun/runtimes/remotesparkjob.py +2 -2
- mlrun/runtimes/sparkjob/spark3job.py +51 -34
- mlrun/runtimes/utils.py +7 -75
- mlrun/secrets.py +9 -5
- mlrun/serving/remote.py +2 -7
- mlrun/serving/routers.py +13 -10
- mlrun/serving/server.py +22 -26
- mlrun/serving/states.py +99 -25
- mlrun/serving/utils.py +3 -3
- mlrun/serving/v1_serving.py +6 -7
- mlrun/serving/v2_serving.py +59 -20
- mlrun/track/tracker.py +2 -1
- mlrun/track/tracker_manager.py +3 -3
- mlrun/track/trackers/mlflow_tracker.py +1 -2
- mlrun/utils/async_http.py +5 -7
- mlrun/utils/azure_vault.py +1 -1
- mlrun/utils/clones.py +1 -2
- mlrun/utils/condition_evaluator.py +3 -3
- mlrun/utils/db.py +3 -3
- mlrun/utils/helpers.py +183 -197
- mlrun/utils/http.py +2 -5
- mlrun/utils/logger.py +76 -14
- mlrun/utils/notifications/notification/__init__.py +17 -12
- mlrun/utils/notifications/notification/base.py +14 -2
- mlrun/utils/notifications/notification/console.py +2 -0
- mlrun/utils/notifications/notification/git.py +3 -1
- mlrun/utils/notifications/notification/ipython.py +3 -1
- mlrun/utils/notifications/notification/slack.py +101 -21
- mlrun/utils/notifications/notification/webhook.py +11 -1
- mlrun/utils/notifications/notification_pusher.py +155 -30
- mlrun/utils/retryer.py +208 -0
- mlrun/utils/singleton.py +1 -1
- mlrun/utils/v3io_clients.py +2 -4
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +2 -6
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +31 -19
- mlrun-1.7.0rc20.dist-info/RECORD +353 -0
- mlrun/kfpops.py +0 -868
- mlrun/model_monitoring/batch.py +0 -1095
- mlrun/model_monitoring/stores/models/__init__.py +0 -27
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -384
- mlrun/platforms/other.py +0 -306
- mlrun-1.6.4rc2.dist-info/RECORD +0 -314
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +0 -0
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
mlrun/artifacts/manager.py
CHANGED
|
@@ -16,11 +16,15 @@ import typing
|
|
|
16
16
|
from os.path import exists, isdir
|
|
17
17
|
from urllib.parse import urlparse
|
|
18
18
|
|
|
19
|
+
import mlrun.common.schemas.artifact
|
|
19
20
|
import mlrun.config
|
|
20
|
-
from mlrun.utils.helpers import
|
|
21
|
+
from mlrun.utils.helpers import (
|
|
22
|
+
get_local_file_schema,
|
|
23
|
+
template_artifact_path,
|
|
24
|
+
validate_inline_artifact_body_size,
|
|
25
|
+
)
|
|
21
26
|
|
|
22
27
|
from ..utils import (
|
|
23
|
-
is_legacy_artifact,
|
|
24
28
|
is_relative_path,
|
|
25
29
|
logger,
|
|
26
30
|
validate_artifact_key_name,
|
|
@@ -29,56 +33,28 @@ from ..utils import (
|
|
|
29
33
|
from .base import (
|
|
30
34
|
Artifact,
|
|
31
35
|
DirArtifact,
|
|
32
|
-
LegacyArtifact,
|
|
33
|
-
LegacyDirArtifact,
|
|
34
|
-
LegacyLinkArtifact,
|
|
35
36
|
LinkArtifact,
|
|
36
37
|
)
|
|
37
38
|
from .dataset import (
|
|
38
39
|
DatasetArtifact,
|
|
39
|
-
LegacyDatasetArtifact,
|
|
40
|
-
LegacyTableArtifact,
|
|
41
40
|
TableArtifact,
|
|
42
41
|
)
|
|
43
|
-
from .model import
|
|
42
|
+
from .model import ModelArtifact
|
|
44
43
|
from .plots import (
|
|
45
|
-
BokehArtifact,
|
|
46
|
-
ChartArtifact,
|
|
47
|
-
LegacyBokehArtifact,
|
|
48
|
-
LegacyChartArtifact,
|
|
49
|
-
LegacyPlotArtifact,
|
|
50
|
-
LegacyPlotlyArtifact,
|
|
51
44
|
PlotArtifact,
|
|
52
45
|
PlotlyArtifact,
|
|
53
46
|
)
|
|
54
47
|
|
|
55
|
-
# TODO - Remove deprecated types when deleted in 1.7.0
|
|
56
48
|
artifact_types = {
|
|
57
49
|
"": Artifact,
|
|
58
50
|
"artifact": Artifact,
|
|
59
51
|
"dir": DirArtifact,
|
|
60
52
|
"link": LinkArtifact,
|
|
61
53
|
"plot": PlotArtifact,
|
|
62
|
-
"chart": ChartArtifact,
|
|
63
54
|
"table": TableArtifact,
|
|
64
55
|
"model": ModelArtifact,
|
|
65
56
|
"dataset": DatasetArtifact,
|
|
66
57
|
"plotly": PlotlyArtifact,
|
|
67
|
-
"bokeh": BokehArtifact,
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
# TODO - Remove this when legacy types are deleted in 1.7.0
|
|
71
|
-
legacy_artifact_types = {
|
|
72
|
-
"": LegacyArtifact,
|
|
73
|
-
"dir": LegacyDirArtifact,
|
|
74
|
-
"link": LegacyLinkArtifact,
|
|
75
|
-
"plot": LegacyPlotArtifact,
|
|
76
|
-
"chart": LegacyChartArtifact,
|
|
77
|
-
"table": LegacyTableArtifact,
|
|
78
|
-
"model": LegacyModelArtifact,
|
|
79
|
-
"dataset": LegacyDatasetArtifact,
|
|
80
|
-
"plotly": LegacyPlotlyArtifact,
|
|
81
|
-
"bokeh": LegacyBokehArtifact,
|
|
82
58
|
}
|
|
83
59
|
|
|
84
60
|
|
|
@@ -96,17 +72,14 @@ class ArtifactProducer:
|
|
|
96
72
|
def get_meta(self) -> dict:
|
|
97
73
|
return {"kind": self.kind, "name": self.name, "tag": self.tag}
|
|
98
74
|
|
|
75
|
+
@property
|
|
76
|
+
def uid(self):
|
|
77
|
+
return None
|
|
78
|
+
|
|
99
79
|
|
|
100
80
|
def dict_to_artifact(struct: dict) -> Artifact:
|
|
101
|
-
# Need to distinguish between LegacyArtifact classes and Artifact classes. Use existence of the "metadata"
|
|
102
|
-
# property to make this distinction
|
|
103
81
|
kind = struct.get("kind", "")
|
|
104
|
-
|
|
105
|
-
if is_legacy_artifact(struct):
|
|
106
|
-
return mlrun.artifacts.base.convert_legacy_artifact_to_new_format(struct)
|
|
107
|
-
|
|
108
82
|
artifact_class = artifact_types[kind]
|
|
109
|
-
|
|
110
83
|
return artifact_class.from_dict(struct)
|
|
111
84
|
|
|
112
85
|
|
|
@@ -176,11 +149,13 @@ class ArtifactManager:
|
|
|
176
149
|
upload=None,
|
|
177
150
|
labels=None,
|
|
178
151
|
db_key=None,
|
|
152
|
+
project=None,
|
|
153
|
+
is_retained_producer=None,
|
|
179
154
|
**kwargs,
|
|
180
155
|
) -> Artifact:
|
|
181
156
|
"""
|
|
182
157
|
Log an artifact to the DB and upload it to the artifact store.
|
|
183
|
-
:param producer: The producer of the artifact, the producer depends
|
|
158
|
+
:param producer: The producer of the artifact, the producer depends on where the artifact is being logged.
|
|
184
159
|
:param item: The artifact to log.
|
|
185
160
|
:param body: The body of the artifact.
|
|
186
161
|
:param target_path: The target path of the artifact. (cannot be a relative path)
|
|
@@ -198,6 +173,9 @@ class ArtifactManager:
|
|
|
198
173
|
:param labels: Labels to add to the artifact.
|
|
199
174
|
:param db_key: The key to use when logging the artifact to the DB.
|
|
200
175
|
If not provided, will generate a key based on the producer name and the artifact key.
|
|
176
|
+
:param project: The project to log the artifact to. If not provided, will use the producer's project.
|
|
177
|
+
:param is_retained_producer: Whether the producer is retained or not. Relevant to register artifacts flow
|
|
178
|
+
where a project may log artifacts which were produced by another producer.
|
|
201
179
|
:param kwargs: Arguments to pass to the artifact class.
|
|
202
180
|
:return: The logged artifact.
|
|
203
181
|
"""
|
|
@@ -212,6 +190,7 @@ class ArtifactManager:
|
|
|
212
190
|
target_path = target_path or item.target_path
|
|
213
191
|
|
|
214
192
|
validate_artifact_key_name(key, "artifact.key")
|
|
193
|
+
validate_inline_artifact_body_size(item.spec.inline)
|
|
215
194
|
src_path = local_path or item.src_path # TODO: remove src_path
|
|
216
195
|
self.ensure_artifact_source_file_exists(item=item, path=src_path, body=body)
|
|
217
196
|
if format == "html" or (src_path and pathlib.Path(src_path).suffix == "html"):
|
|
@@ -221,7 +200,7 @@ class ArtifactManager:
|
|
|
221
200
|
|
|
222
201
|
if db_key is None:
|
|
223
202
|
# set the default artifact db key
|
|
224
|
-
if producer.kind == "run":
|
|
203
|
+
if producer.kind == "run" and not is_retained_producer:
|
|
225
204
|
# When the producer's type is "run,"
|
|
226
205
|
# we generate a different db_key than the one we obtained in the request.
|
|
227
206
|
# As a result, a new artifact for the requested key will be created,
|
|
@@ -246,8 +225,11 @@ class ArtifactManager:
|
|
|
246
225
|
item.labels.update({"workflow-id": item.producer.get("workflow")})
|
|
247
226
|
|
|
248
227
|
item.iter = producer.iteration
|
|
249
|
-
project = producer.project
|
|
228
|
+
project = project or producer.project
|
|
250
229
|
item.project = project
|
|
230
|
+
if is_retained_producer:
|
|
231
|
+
# if the producer is retained, we want to use the original target path
|
|
232
|
+
target_path = target_path or item.target_path
|
|
251
233
|
|
|
252
234
|
# if target_path is provided and not relative, then no need to upload the artifact as it already exists
|
|
253
235
|
if target_path:
|
|
@@ -255,7 +237,8 @@ class ArtifactManager:
|
|
|
255
237
|
raise ValueError(
|
|
256
238
|
f"target_path ({target_path}) param cannot be relative"
|
|
257
239
|
)
|
|
258
|
-
upload
|
|
240
|
+
if upload is None:
|
|
241
|
+
upload = False
|
|
259
242
|
|
|
260
243
|
# if target_path wasn't provided, but src_path is not relative, then no need to upload the artifact as it
|
|
261
244
|
# already exists. In this case set the target_path to the src_path and set upload to False
|
|
@@ -282,7 +265,9 @@ class ArtifactManager:
|
|
|
282
265
|
|
|
283
266
|
if target_path and item.is_dir and not target_path.endswith("/"):
|
|
284
267
|
target_path += "/"
|
|
285
|
-
target_path = template_artifact_path(
|
|
268
|
+
target_path = template_artifact_path(
|
|
269
|
+
artifact_path=target_path, project=producer.project, run_uid=producer.uid
|
|
270
|
+
)
|
|
286
271
|
item.target_path = target_path
|
|
287
272
|
|
|
288
273
|
item.before_log()
|
|
@@ -292,13 +277,10 @@ class ArtifactManager:
|
|
|
292
277
|
# before uploading the item, we want to ensure that its tags are valid,
|
|
293
278
|
# so that we don't upload something that won't be stored later
|
|
294
279
|
validate_tag_name(item.metadata.tag, "artifact.metadata.tag")
|
|
295
|
-
|
|
296
|
-
item.upload()
|
|
297
|
-
else:
|
|
298
|
-
item.upload(artifact_path=artifact_path)
|
|
280
|
+
item.upload(artifact_path=artifact_path)
|
|
299
281
|
|
|
300
282
|
if db_key:
|
|
301
|
-
self._log_to_db(db_key,
|
|
283
|
+
self._log_to_db(db_key, project, producer.inputs, item)
|
|
302
284
|
size = str(item.size) or "?"
|
|
303
285
|
db_str = "Y" if (self.artifact_db and db_key) else "N"
|
|
304
286
|
logger.debug(
|
|
@@ -366,6 +348,23 @@ class ArtifactManager:
|
|
|
366
348
|
project=project,
|
|
367
349
|
)
|
|
368
350
|
|
|
351
|
+
def delete_artifact(
|
|
352
|
+
self,
|
|
353
|
+
item: Artifact,
|
|
354
|
+
deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
|
|
355
|
+
mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
|
|
356
|
+
),
|
|
357
|
+
secrets: dict = None,
|
|
358
|
+
):
|
|
359
|
+
self.artifact_db.del_artifact(
|
|
360
|
+
key=item.db_key,
|
|
361
|
+
project=item.project,
|
|
362
|
+
tag=item.tag,
|
|
363
|
+
tree=item.tree,
|
|
364
|
+
deletion_strategy=deletion_strategy,
|
|
365
|
+
secrets=secrets,
|
|
366
|
+
)
|
|
367
|
+
|
|
369
368
|
|
|
370
369
|
def extend_artifact_path(artifact_path: str, default_artifact_path: str):
|
|
371
370
|
artifact_path = str(artifact_path or "")
|
mlrun/artifacts/model.py
CHANGED
|
@@ -11,13 +11,14 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
import tempfile
|
|
16
|
+
import warnings
|
|
15
17
|
from os import path
|
|
16
|
-
from typing import Any
|
|
18
|
+
from typing import Any, Optional
|
|
17
19
|
|
|
18
20
|
import pandas as pd
|
|
19
21
|
import yaml
|
|
20
|
-
from deprecated import deprecated
|
|
21
22
|
|
|
22
23
|
import mlrun
|
|
23
24
|
import mlrun.datastore
|
|
@@ -26,7 +27,7 @@ from ..data_types import InferOptions, get_infer_interface
|
|
|
26
27
|
from ..features import Feature
|
|
27
28
|
from ..model import ObjectList
|
|
28
29
|
from ..utils import StorePrefix, is_relative_path
|
|
29
|
-
from .base import Artifact, ArtifactSpec,
|
|
30
|
+
from .base import Artifact, ArtifactSpec, upload_extra_data
|
|
30
31
|
|
|
31
32
|
model_spec_filename = "model_spec.yaml"
|
|
32
33
|
|
|
@@ -69,8 +70,8 @@ class ModelArtifactSpec(ArtifactSpec):
|
|
|
69
70
|
model_file=None,
|
|
70
71
|
metrics=None,
|
|
71
72
|
paraemeters=None,
|
|
72
|
-
inputs: list[Feature] = None,
|
|
73
|
-
outputs: list[Feature] = None,
|
|
73
|
+
inputs: Optional[list[Feature]] = None,
|
|
74
|
+
outputs: Optional[list[Feature]] = None,
|
|
74
75
|
framework=None,
|
|
75
76
|
algorithm=None,
|
|
76
77
|
feature_vector=None,
|
|
@@ -92,8 +93,8 @@ class ModelArtifactSpec(ArtifactSpec):
|
|
|
92
93
|
self.model_file = model_file
|
|
93
94
|
self.metrics = metrics or {}
|
|
94
95
|
self.parameters = paraemeters or {}
|
|
95
|
-
self.inputs
|
|
96
|
-
self.outputs
|
|
96
|
+
self.inputs = inputs or []
|
|
97
|
+
self.outputs = outputs or []
|
|
97
98
|
self.framework = framework
|
|
98
99
|
self.algorithm = algorithm
|
|
99
100
|
self.feature_vector = feature_vector
|
|
@@ -102,21 +103,21 @@ class ModelArtifactSpec(ArtifactSpec):
|
|
|
102
103
|
self.model_target_file = model_target_file
|
|
103
104
|
|
|
104
105
|
@property
|
|
105
|
-
def inputs(self) ->
|
|
106
|
+
def inputs(self) -> ObjectList:
|
|
106
107
|
"""input feature list"""
|
|
107
108
|
return self._inputs
|
|
108
109
|
|
|
109
110
|
@inputs.setter
|
|
110
|
-
def inputs(self, inputs: list[Feature]):
|
|
111
|
+
def inputs(self, inputs: list[Feature]) -> None:
|
|
111
112
|
self._inputs = ObjectList.from_list(Feature, inputs)
|
|
112
113
|
|
|
113
114
|
@property
|
|
114
|
-
def outputs(self) ->
|
|
115
|
+
def outputs(self) -> ObjectList:
|
|
115
116
|
"""output feature list"""
|
|
116
117
|
return self._outputs
|
|
117
118
|
|
|
118
119
|
@outputs.setter
|
|
119
|
-
def outputs(self, outputs: list[Feature]):
|
|
120
|
+
def outputs(self, outputs: list[Feature]) -> None:
|
|
120
121
|
self._outputs = ObjectList.from_list(Feature, outputs)
|
|
121
122
|
|
|
122
123
|
|
|
@@ -148,6 +149,12 @@ class ModelArtifact(Artifact):
|
|
|
148
149
|
model_dir=None,
|
|
149
150
|
**kwargs,
|
|
150
151
|
):
|
|
152
|
+
if key or body or format or target_path:
|
|
153
|
+
warnings.warn(
|
|
154
|
+
"Artifact constructor parameters are deprecated and will be removed in 1.9.0. "
|
|
155
|
+
"Use the metadata and spec parameters instead.",
|
|
156
|
+
DeprecationWarning,
|
|
157
|
+
)
|
|
151
158
|
super().__init__(key, body, format=format, target_path=target_path, **kwargs)
|
|
152
159
|
model_file = str(model_file or "")
|
|
153
160
|
if model_file and "/" in model_file:
|
|
@@ -176,22 +183,22 @@ class ModelArtifact(Artifact):
|
|
|
176
183
|
self._spec = self._verify_dict(spec, "spec", ModelArtifactSpec)
|
|
177
184
|
|
|
178
185
|
@property
|
|
179
|
-
def inputs(self) ->
|
|
186
|
+
def inputs(self) -> ObjectList:
|
|
180
187
|
"""input feature list"""
|
|
181
188
|
return self.spec.inputs
|
|
182
189
|
|
|
183
190
|
@inputs.setter
|
|
184
|
-
def inputs(self, inputs: list[Feature]):
|
|
191
|
+
def inputs(self, inputs: list[Feature]) -> None:
|
|
185
192
|
"""input feature list"""
|
|
186
193
|
self.spec.inputs = inputs
|
|
187
194
|
|
|
188
195
|
@property
|
|
189
|
-
def outputs(self) ->
|
|
196
|
+
def outputs(self) -> ObjectList:
|
|
190
197
|
"""input feature list"""
|
|
191
198
|
return self.spec.outputs
|
|
192
199
|
|
|
193
200
|
@outputs.setter
|
|
194
|
-
def outputs(self, outputs: list[Feature]):
|
|
201
|
+
def outputs(self, outputs: list[Feature]) -> None:
|
|
195
202
|
"""input feature list"""
|
|
196
203
|
self.spec.outputs = outputs
|
|
197
204
|
|
|
@@ -290,7 +297,7 @@ class ModelArtifact(Artifact):
|
|
|
290
297
|
if not self.spec.model_file:
|
|
291
298
|
raise ValueError("model_file attr must be specified")
|
|
292
299
|
|
|
293
|
-
super(
|
|
300
|
+
super().before_log()
|
|
294
301
|
|
|
295
302
|
if self.spec.framework:
|
|
296
303
|
self.metadata.labels = self.metadata.labels or {}
|
|
@@ -396,144 +403,6 @@ class ModelArtifact(Artifact):
|
|
|
396
403
|
return mlrun.get_dataitem(target_model_path).get()
|
|
397
404
|
|
|
398
405
|
|
|
399
|
-
# TODO: remove in 1.7.0
|
|
400
|
-
@deprecated(
|
|
401
|
-
version="1.3.0",
|
|
402
|
-
reason="'LegacyModelArtifact' will be removed in 1.7.0, use 'ModelArtifact' instead",
|
|
403
|
-
category=FutureWarning,
|
|
404
|
-
)
|
|
405
|
-
class LegacyModelArtifact(LegacyArtifact):
|
|
406
|
-
"""ML Model artifact
|
|
407
|
-
|
|
408
|
-
Store link to ML model file(s) along with the model metrics, parameters, schema, and stats
|
|
409
|
-
"""
|
|
410
|
-
|
|
411
|
-
_dict_fields = LegacyArtifact._dict_fields + [
|
|
412
|
-
"model_file",
|
|
413
|
-
"metrics",
|
|
414
|
-
"parameters",
|
|
415
|
-
"inputs",
|
|
416
|
-
"outputs",
|
|
417
|
-
"framework",
|
|
418
|
-
"algorithm",
|
|
419
|
-
"extra_data",
|
|
420
|
-
"feature_vector",
|
|
421
|
-
"feature_weights",
|
|
422
|
-
"feature_stats",
|
|
423
|
-
"model_target_file",
|
|
424
|
-
]
|
|
425
|
-
kind = "model"
|
|
426
|
-
_store_prefix = StorePrefix.Model
|
|
427
|
-
|
|
428
|
-
def __init__(
|
|
429
|
-
self,
|
|
430
|
-
key=None,
|
|
431
|
-
body=None,
|
|
432
|
-
format=None,
|
|
433
|
-
model_file=None,
|
|
434
|
-
metrics=None,
|
|
435
|
-
target_path=None,
|
|
436
|
-
parameters=None,
|
|
437
|
-
inputs=None,
|
|
438
|
-
outputs=None,
|
|
439
|
-
framework=None,
|
|
440
|
-
algorithm=None,
|
|
441
|
-
feature_vector=None,
|
|
442
|
-
feature_weights=None,
|
|
443
|
-
extra_data=None,
|
|
444
|
-
model_target_file=None,
|
|
445
|
-
**kwargs,
|
|
446
|
-
):
|
|
447
|
-
super().__init__(key, body, format=format, target_path=target_path, **kwargs)
|
|
448
|
-
self._inputs: ObjectList = None
|
|
449
|
-
self._outputs: ObjectList = None
|
|
450
|
-
|
|
451
|
-
self.model_file = model_file
|
|
452
|
-
self.parameters = parameters or {}
|
|
453
|
-
self.metrics = metrics or {}
|
|
454
|
-
self.inputs: list[Feature] = inputs or []
|
|
455
|
-
self.outputs: list[Feature] = outputs or []
|
|
456
|
-
self.extra_data = extra_data or {}
|
|
457
|
-
self.framework = framework
|
|
458
|
-
self.algorithm = algorithm
|
|
459
|
-
self.feature_vector = feature_vector
|
|
460
|
-
self.feature_weights = feature_weights
|
|
461
|
-
self.feature_stats = None
|
|
462
|
-
self.model_target_file = model_target_file
|
|
463
|
-
|
|
464
|
-
@property
|
|
465
|
-
def inputs(self) -> list[Feature]:
|
|
466
|
-
"""input feature list"""
|
|
467
|
-
return self._inputs
|
|
468
|
-
|
|
469
|
-
@inputs.setter
|
|
470
|
-
def inputs(self, inputs: list[Feature]):
|
|
471
|
-
self._inputs = ObjectList.from_list(Feature, inputs)
|
|
472
|
-
|
|
473
|
-
@property
|
|
474
|
-
def outputs(self) -> list[Feature]:
|
|
475
|
-
"""output feature list"""
|
|
476
|
-
return self._outputs
|
|
477
|
-
|
|
478
|
-
@outputs.setter
|
|
479
|
-
def outputs(self, outputs: list[Feature]):
|
|
480
|
-
self._outputs = ObjectList.from_list(Feature, outputs)
|
|
481
|
-
|
|
482
|
-
def infer_from_df(self, df, label_columns=None, with_stats=True, num_bins=None):
|
|
483
|
-
"""infer inputs, outputs, and stats from provided df (training set)
|
|
484
|
-
|
|
485
|
-
:param df: dataframe to infer from
|
|
486
|
-
:param label_columns: name of the label (target) column
|
|
487
|
-
:param with_stats: infer statistics (min, max, .. histogram)
|
|
488
|
-
:param num_bins: number of bins for histogram
|
|
489
|
-
"""
|
|
490
|
-
subset = df
|
|
491
|
-
inferer = get_infer_interface(subset)
|
|
492
|
-
if label_columns:
|
|
493
|
-
if not isinstance(label_columns, list):
|
|
494
|
-
label_columns = [label_columns]
|
|
495
|
-
subset = df.drop(columns=label_columns)
|
|
496
|
-
inferer.infer_schema(subset, self.inputs, {}, options=InferOptions.Features)
|
|
497
|
-
if label_columns:
|
|
498
|
-
inferer.infer_schema(
|
|
499
|
-
df[label_columns], self.outputs, {}, options=InferOptions.Features
|
|
500
|
-
)
|
|
501
|
-
if with_stats:
|
|
502
|
-
self.feature_stats = inferer.get_stats(
|
|
503
|
-
df, options=InferOptions.Histogram, num_bins=num_bins
|
|
504
|
-
)
|
|
505
|
-
|
|
506
|
-
@property
|
|
507
|
-
def is_dir(self):
|
|
508
|
-
return True
|
|
509
|
-
|
|
510
|
-
def before_log(self):
|
|
511
|
-
if not self.model_file:
|
|
512
|
-
raise ValueError("model_file attr must be specified")
|
|
513
|
-
|
|
514
|
-
super(LegacyModelArtifact, self).before_log()
|
|
515
|
-
|
|
516
|
-
if self.framework:
|
|
517
|
-
self.labels = self.labels or {}
|
|
518
|
-
self.labels["framework"] = self.framework
|
|
519
|
-
|
|
520
|
-
def upload(self):
|
|
521
|
-
target_model_path = path.join(self.target_path, self.model_file)
|
|
522
|
-
body = self.get_body()
|
|
523
|
-
if body:
|
|
524
|
-
self._upload_body(body, target=target_model_path)
|
|
525
|
-
else:
|
|
526
|
-
src_model_path = _get_src_path(self, self.model_file)
|
|
527
|
-
if not path.isfile(src_model_path):
|
|
528
|
-
raise ValueError(f"model file {src_model_path} not found")
|
|
529
|
-
self._upload_file(src_model_path, target=target_model_path)
|
|
530
|
-
|
|
531
|
-
upload_extra_data(self, self.extra_data)
|
|
532
|
-
|
|
533
|
-
spec_path = path.join(self.target_path, model_spec_filename)
|
|
534
|
-
mlrun.datastore.store_manager.object(url=spec_path).put(self.to_yaml())
|
|
535
|
-
|
|
536
|
-
|
|
537
406
|
def _get_src_path(model_spec: ModelArtifact, filename):
|
|
538
407
|
if model_spec.src_path:
|
|
539
408
|
return path.join(model_spec.src_path, filename)
|
|
@@ -552,9 +421,9 @@ def get_model(model_dir, suffix=""):
|
|
|
552
421
|
|
|
553
422
|
example::
|
|
554
423
|
|
|
555
|
-
model_file, model_artifact, extra_data = get_model(models_path, suffix=
|
|
424
|
+
model_file, model_artifact, extra_data = get_model(models_path, suffix=".pkl")
|
|
556
425
|
model = load(open(model_file, "rb"))
|
|
557
|
-
categories = extra_data[
|
|
426
|
+
categories = extra_data["categories"].as_df()
|
|
558
427
|
|
|
559
428
|
:param model_dir: model dir or artifact path (store://..) or DataItem
|
|
560
429
|
:param suffix: model filename suffix (when using a dir)
|
|
@@ -640,7 +509,7 @@ def _get_extra(target, extra_data, is_dir=False):
|
|
|
640
509
|
def _remove_tag_from_spec_yaml(model_spec):
|
|
641
510
|
spec_dict = model_spec.to_dict()
|
|
642
511
|
spec_dict["metadata"].pop("tag", None)
|
|
643
|
-
return yaml.
|
|
512
|
+
return yaml.safe_dump(spec_dict)
|
|
644
513
|
|
|
645
514
|
|
|
646
515
|
def update_model(
|
|
@@ -663,8 +532,11 @@ def update_model(
|
|
|
663
532
|
|
|
664
533
|
example::
|
|
665
534
|
|
|
666
|
-
update_model(
|
|
667
|
-
|
|
535
|
+
update_model(
|
|
536
|
+
model_path,
|
|
537
|
+
metrics={"speed": 100},
|
|
538
|
+
extra_data={"my_data": b"some text", "file": "s3://mybucket/.."},
|
|
539
|
+
)
|
|
668
540
|
|
|
669
541
|
:param model_artifact: model artifact object or path (store://..) or DataItem
|
|
670
542
|
:param parameters: parameters dict
|