mlrun 1.7.0rc15__py3-none-any.whl → 1.7.0rc17__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 +10 -1
- mlrun/__main__.py +18 -4
- mlrun/alerts/__init__.py +15 -0
- mlrun/alerts/alert.py +144 -0
- mlrun/artifacts/__init__.py +7 -1
- mlrun/artifacts/base.py +28 -3
- mlrun/artifacts/dataset.py +8 -0
- mlrun/artifacts/manager.py +18 -0
- mlrun/artifacts/model.py +8 -1
- mlrun/artifacts/plots.py +13 -0
- mlrun/common/schemas/__init__.py +10 -2
- mlrun/common/schemas/alert.py +64 -5
- mlrun/common/schemas/api_gateway.py +4 -0
- mlrun/common/schemas/artifact.py +15 -0
- mlrun/common/schemas/auth.py +2 -0
- mlrun/common/schemas/model_monitoring/__init__.py +4 -1
- mlrun/common/schemas/model_monitoring/constants.py +17 -1
- mlrun/common/schemas/model_monitoring/model_endpoints.py +60 -1
- mlrun/common/schemas/project.py +5 -1
- mlrun/config.py +11 -4
- mlrun/datastore/datastore_profile.py +10 -7
- mlrun/db/base.py +24 -4
- mlrun/db/httpdb.py +97 -43
- mlrun/db/nopdb.py +25 -4
- mlrun/errors.py +5 -0
- mlrun/launcher/base.py +3 -2
- mlrun/lists.py +4 -0
- mlrun/model.py +15 -8
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/applications/_application_steps.py +1 -2
- mlrun/model_monitoring/applications/context.py +1 -1
- mlrun/model_monitoring/applications/histogram_data_drift.py +64 -38
- mlrun/model_monitoring/db/__init__.py +2 -0
- mlrun/model_monitoring/db/stores/base/store.py +9 -36
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +63 -110
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +56 -202
- mlrun/model_monitoring/db/tsdb/__init__.py +71 -0
- mlrun/model_monitoring/db/tsdb/base.py +135 -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 +442 -0
- mlrun/model_monitoring/db/v3io_tsdb_reader.py +134 -0
- mlrun/model_monitoring/stream_processing.py +46 -210
- mlrun/model_monitoring/writer.py +50 -100
- mlrun/platforms/__init__.py +10 -9
- mlrun/platforms/iguazio.py +19 -200
- mlrun/projects/operations.py +11 -7
- mlrun/projects/pipelines.py +13 -76
- mlrun/projects/project.py +62 -17
- mlrun/render.py +9 -3
- mlrun/run.py +5 -38
- mlrun/runtimes/__init__.py +1 -0
- mlrun/runtimes/base.py +3 -3
- mlrun/runtimes/kubejob.py +2 -1
- mlrun/runtimes/nuclio/api_gateway.py +163 -77
- mlrun/runtimes/nuclio/application/application.py +160 -7
- mlrun/runtimes/nuclio/function.py +25 -45
- mlrun/runtimes/pod.py +16 -36
- mlrun/runtimes/remotesparkjob.py +1 -1
- mlrun/runtimes/sparkjob/spark3job.py +1 -1
- mlrun/runtimes/utils.py +0 -38
- mlrun/track/tracker.py +2 -1
- mlrun/utils/helpers.py +51 -31
- mlrun/utils/logger.py +11 -6
- mlrun/utils/notifications/notification/base.py +1 -1
- mlrun/utils/notifications/notification/slack.py +9 -4
- mlrun/utils/notifications/notification/webhook.py +1 -1
- mlrun/utils/notifications/notification_pusher.py +21 -14
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/METADATA +4 -3
- {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/RECORD +75 -69
- mlrun/kfpops.py +0 -860
- mlrun/platforms/other.py +0 -305
- {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/WHEEL +0 -0
- {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/top_level.txt +0 -0
mlrun/db/nopdb.py
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import datetime
|
|
17
17
|
from typing import Optional, Union
|
|
18
18
|
|
|
19
|
+
import mlrun.alerts
|
|
19
20
|
import mlrun.common.schemas
|
|
20
21
|
import mlrun.errors
|
|
21
22
|
|
|
@@ -128,7 +129,18 @@ class NopDB(RunDBInterface):
|
|
|
128
129
|
):
|
|
129
130
|
pass
|
|
130
131
|
|
|
131
|
-
def del_artifact(
|
|
132
|
+
def del_artifact(
|
|
133
|
+
self,
|
|
134
|
+
key,
|
|
135
|
+
tag="",
|
|
136
|
+
project="",
|
|
137
|
+
tree=None,
|
|
138
|
+
uid=None,
|
|
139
|
+
deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
|
|
140
|
+
mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
|
|
141
|
+
),
|
|
142
|
+
secrets: dict = None,
|
|
143
|
+
):
|
|
132
144
|
pass
|
|
133
145
|
|
|
134
146
|
def del_artifacts(self, name="", project="", tag="", labels=None):
|
|
@@ -508,8 +520,11 @@ class NopDB(RunDBInterface):
|
|
|
508
520
|
|
|
509
521
|
def store_api_gateway(
|
|
510
522
|
self,
|
|
511
|
-
|
|
512
|
-
|
|
523
|
+
api_gateway: Union[
|
|
524
|
+
mlrun.common.schemas.APIGateway,
|
|
525
|
+
mlrun.runtimes.nuclio.api_gateway.APIGateway,
|
|
526
|
+
],
|
|
527
|
+
project: str = None,
|
|
513
528
|
) -> mlrun.common.schemas.APIGateway:
|
|
514
529
|
pass
|
|
515
530
|
|
|
@@ -671,7 +686,7 @@ class NopDB(RunDBInterface):
|
|
|
671
686
|
def store_alert_config(
|
|
672
687
|
self,
|
|
673
688
|
alert_name: str,
|
|
674
|
-
alert_data: Union[dict, mlrun.
|
|
689
|
+
alert_data: Union[dict, mlrun.alerts.alert.AlertConfig],
|
|
675
690
|
project="",
|
|
676
691
|
):
|
|
677
692
|
pass
|
|
@@ -687,3 +702,9 @@ class NopDB(RunDBInterface):
|
|
|
687
702
|
|
|
688
703
|
def reset_alert_config(self, alert_name: str, project=""):
|
|
689
704
|
pass
|
|
705
|
+
|
|
706
|
+
def get_alert_template(self, template_name: str):
|
|
707
|
+
pass
|
|
708
|
+
|
|
709
|
+
def list_alert_templates(self):
|
|
710
|
+
pass
|
mlrun/errors.py
CHANGED
|
@@ -183,6 +183,10 @@ class MLRunInternalServerError(MLRunHTTPStatusError):
|
|
|
183
183
|
error_status_code = HTTPStatus.INTERNAL_SERVER_ERROR.value
|
|
184
184
|
|
|
185
185
|
|
|
186
|
+
class MLRunNotImplementedServerError(MLRunHTTPStatusError):
|
|
187
|
+
error_status_code = HTTPStatus.NOT_IMPLEMENTED.value
|
|
188
|
+
|
|
189
|
+
|
|
186
190
|
class MLRunServiceUnavailableError(MLRunHTTPStatusError):
|
|
187
191
|
error_status_code = HTTPStatus.SERVICE_UNAVAILABLE.value
|
|
188
192
|
|
|
@@ -234,4 +238,5 @@ STATUS_ERRORS = {
|
|
|
234
238
|
HTTPStatus.PRECONDITION_FAILED.value: MLRunPreconditionFailedError,
|
|
235
239
|
HTTPStatus.INTERNAL_SERVER_ERROR.value: MLRunInternalServerError,
|
|
236
240
|
HTTPStatus.SERVICE_UNAVAILABLE.value: MLRunServiceUnavailableError,
|
|
241
|
+
HTTPStatus.NOT_IMPLEMENTED.value: MLRunNotImplementedServerError,
|
|
237
242
|
}
|
mlrun/launcher/base.py
CHANGED
|
@@ -18,10 +18,11 @@ import os
|
|
|
18
18
|
import uuid
|
|
19
19
|
from typing import Any, Callable, Optional, Union
|
|
20
20
|
|
|
21
|
+
import mlrun_pipelines.common.ops
|
|
22
|
+
|
|
21
23
|
import mlrun.common.schemas
|
|
22
24
|
import mlrun.config
|
|
23
25
|
import mlrun.errors
|
|
24
|
-
import mlrun.kfpops
|
|
25
26
|
import mlrun.lists
|
|
26
27
|
import mlrun.model
|
|
27
28
|
import mlrun.runtimes
|
|
@@ -390,7 +391,7 @@ class BaseLauncher(abc.ABC):
|
|
|
390
391
|
return
|
|
391
392
|
|
|
392
393
|
if result and runtime.kfp and err is None:
|
|
393
|
-
|
|
394
|
+
mlrun_pipelines.common.ops.write_kfpmeta(result)
|
|
394
395
|
|
|
395
396
|
self._log_track_results(runtime.is_child, result, run)
|
|
396
397
|
|
mlrun/lists.py
CHANGED
|
@@ -29,12 +29,14 @@ list_header = [
|
|
|
29
29
|
"iter",
|
|
30
30
|
"start",
|
|
31
31
|
"state",
|
|
32
|
+
"kind",
|
|
32
33
|
"name",
|
|
33
34
|
"labels",
|
|
34
35
|
"inputs",
|
|
35
36
|
"parameters",
|
|
36
37
|
"results",
|
|
37
38
|
"artifacts",
|
|
39
|
+
"artifact_uris",
|
|
38
40
|
"error",
|
|
39
41
|
]
|
|
40
42
|
|
|
@@ -56,12 +58,14 @@ class RunList(list):
|
|
|
56
58
|
get_in(run, "metadata.iteration", ""),
|
|
57
59
|
get_in(run, "status.start_time", ""),
|
|
58
60
|
get_in(run, "status.state", ""),
|
|
61
|
+
get_in(run, "step_kind", get_in(run, "kind", "")),
|
|
59
62
|
get_in(run, "metadata.name", ""),
|
|
60
63
|
get_in(run, "metadata.labels", ""),
|
|
61
64
|
get_in(run, "spec.inputs", ""),
|
|
62
65
|
get_in(run, "spec.parameters", ""),
|
|
63
66
|
get_in(run, "status.results", ""),
|
|
64
67
|
get_in(run, "status.artifacts", []),
|
|
68
|
+
get_in(run, "status.artifact_uris", {}),
|
|
65
69
|
get_in(run, "status.error", ""),
|
|
66
70
|
]
|
|
67
71
|
if extend_iterations and iterations:
|
mlrun/model.py
CHANGED
|
@@ -681,10 +681,14 @@ class Notification(ModelObj):
|
|
|
681
681
|
|
|
682
682
|
def __init__(
|
|
683
683
|
self,
|
|
684
|
-
kind=
|
|
684
|
+
kind: mlrun.common.schemas.notification.NotificationKind = (
|
|
685
|
+
mlrun.common.schemas.notification.NotificationKind.slack
|
|
686
|
+
),
|
|
685
687
|
name=None,
|
|
686
688
|
message=None,
|
|
687
|
-
severity=
|
|
689
|
+
severity: mlrun.common.schemas.notification.NotificationSeverity = (
|
|
690
|
+
mlrun.common.schemas.notification.NotificationSeverity.INFO
|
|
691
|
+
),
|
|
688
692
|
when=None,
|
|
689
693
|
condition=None,
|
|
690
694
|
secret_params=None,
|
|
@@ -693,12 +697,10 @@ class Notification(ModelObj):
|
|
|
693
697
|
sent_time=None,
|
|
694
698
|
reason=None,
|
|
695
699
|
):
|
|
696
|
-
self.kind = kind
|
|
700
|
+
self.kind = kind
|
|
697
701
|
self.name = name or ""
|
|
698
702
|
self.message = message or ""
|
|
699
|
-
self.severity =
|
|
700
|
-
severity or mlrun.common.schemas.notification.NotificationSeverity.INFO
|
|
701
|
-
)
|
|
703
|
+
self.severity = severity
|
|
702
704
|
self.when = when or ["completed"]
|
|
703
705
|
self.condition = condition or ""
|
|
704
706
|
self.secret_params = secret_params or {}
|
|
@@ -1207,6 +1209,7 @@ class RunStatus(ModelObj):
|
|
|
1207
1209
|
ui_url=None,
|
|
1208
1210
|
reason: str = None,
|
|
1209
1211
|
notifications: dict[str, Notification] = None,
|
|
1212
|
+
artifact_uris: dict[str, str] = None,
|
|
1210
1213
|
):
|
|
1211
1214
|
self.state = state or "created"
|
|
1212
1215
|
self.status_text = status_text
|
|
@@ -1221,6 +1224,8 @@ class RunStatus(ModelObj):
|
|
|
1221
1224
|
self.ui_url = ui_url
|
|
1222
1225
|
self.reason = reason
|
|
1223
1226
|
self.notifications = notifications or {}
|
|
1227
|
+
# Artifact key -> URI mapping, since the full artifacts are not stored in the runs DB table
|
|
1228
|
+
self.artifact_uris = artifact_uris or {}
|
|
1224
1229
|
|
|
1225
1230
|
def is_failed(self) -> Optional[bool]:
|
|
1226
1231
|
"""
|
|
@@ -1539,8 +1544,10 @@ class RunObject(RunTemplate):
|
|
|
1539
1544
|
iter=self.metadata.iteration,
|
|
1540
1545
|
)
|
|
1541
1546
|
if run:
|
|
1542
|
-
|
|
1543
|
-
|
|
1547
|
+
run_status = run.get("status", {})
|
|
1548
|
+
# Artifacts are not stored in the DB, so we need to preserve them here
|
|
1549
|
+
run_status["artifacts"] = self.status.artifacts
|
|
1550
|
+
self.status = RunStatus.from_dict(run_status)
|
|
1544
1551
|
return self
|
|
1545
1552
|
|
|
1546
1553
|
def show(self):
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
# flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
|
|
16
16
|
# for backwards compatibility
|
|
17
17
|
|
|
18
|
-
from .db import get_store_object
|
|
18
|
+
from .db import get_store_object, get_tsdb_connector
|
|
19
19
|
from .helpers import get_stream_path
|
|
20
20
|
from .model_endpoint import ModelEndpoint
|
|
21
21
|
from .tracking_policy import TrackingPolicy
|
|
@@ -11,7 +11,6 @@
|
|
|
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
|
-
import copy
|
|
15
14
|
import json
|
|
16
15
|
import typing
|
|
17
16
|
from typing import Optional
|
|
@@ -138,7 +137,7 @@ class _PrepareMonitoringEvent(StepToDict):
|
|
|
138
137
|
if not event.get("mlrun_context"):
|
|
139
138
|
application_context = MonitoringApplicationContext().from_dict(
|
|
140
139
|
event,
|
|
141
|
-
context=
|
|
140
|
+
context=self.context,
|
|
142
141
|
model_endpoint_dict=self.model_endpoints,
|
|
143
142
|
)
|
|
144
143
|
else:
|
|
@@ -113,7 +113,7 @@ class MonitoringApplicationContext(MLClientCtx):
|
|
|
113
113
|
attrs.get(mm_constants.ApplicationEvent.FEATURE_STATS, "{}")
|
|
114
114
|
)
|
|
115
115
|
self._sample_df_stats = json.loads(
|
|
116
|
-
attrs.get(mm_constants.ApplicationEvent.
|
|
116
|
+
attrs.get(mm_constants.ApplicationEvent.CURRENT_STATS, "{}")
|
|
117
117
|
)
|
|
118
118
|
|
|
119
119
|
self.endpoint_id = attrs.get(mm_constants.ApplicationEvent.ENDPOINT_ID)
|
|
@@ -11,9 +11,10 @@
|
|
|
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 json
|
|
15
16
|
from dataclasses import dataclass
|
|
16
|
-
from typing import Final, Optional, Protocol, cast
|
|
17
|
+
from typing import Final, Optional, Protocol, Union, cast
|
|
17
18
|
|
|
18
19
|
import numpy as np
|
|
19
20
|
from pandas import DataFrame, Series
|
|
@@ -90,9 +91,27 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBaseV2):
|
|
|
90
91
|
"""
|
|
91
92
|
MLRun's default data drift application for model monitoring.
|
|
92
93
|
|
|
93
|
-
The application calculates
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
The application expects tabular numerical data, and calculates three metrics over the features' histograms.
|
|
95
|
+
The three metrics are:
|
|
96
|
+
|
|
97
|
+
* Hellinger distance.
|
|
98
|
+
* Total variance distance.
|
|
99
|
+
* Kullback-Leibler divergence.
|
|
100
|
+
|
|
101
|
+
Each metric is calculated over all the features individually and the mean is taken as the metric value.
|
|
102
|
+
The average of Hellinger and total variance distance is taken as the result.
|
|
103
|
+
|
|
104
|
+
The application logs two artifacts:
|
|
105
|
+
|
|
106
|
+
* A JSON with the general drift per feature.
|
|
107
|
+
* A plotly table different metrics per feature.
|
|
108
|
+
|
|
109
|
+
This application is deployed by default when calling:
|
|
110
|
+
|
|
111
|
+
.. code-block:: python
|
|
112
|
+
|
|
113
|
+
project.enable_model_monitoring()
|
|
114
|
+
|
|
96
115
|
"""
|
|
97
116
|
|
|
98
117
|
NAME: Final[str] = HistogramDataDriftApplicationConstants.NAME
|
|
@@ -107,8 +126,6 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBaseV2):
|
|
|
107
126
|
|
|
108
127
|
def __init__(self, value_classifier: Optional[ValueClassifier] = None) -> None:
|
|
109
128
|
"""
|
|
110
|
-
Initialize the data drift application.
|
|
111
|
-
|
|
112
129
|
:param value_classifier: Classifier object that adheres to the `ValueClassifier` protocol.
|
|
113
130
|
If not provided, the default `DataDriftClassifier()` is used.
|
|
114
131
|
"""
|
|
@@ -146,35 +163,46 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBaseV2):
|
|
|
146
163
|
|
|
147
164
|
return metrics_per_feature
|
|
148
165
|
|
|
149
|
-
def
|
|
166
|
+
def _get_general_drift_result(
|
|
150
167
|
self,
|
|
151
168
|
metrics: list[mm_results.ModelMonitoringApplicationMetric],
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
169
|
+
monitoring_context: mm_context.MonitoringApplicationContext,
|
|
170
|
+
metrics_per_feature: DataFrame,
|
|
171
|
+
) -> mm_results.ModelMonitoringApplicationResult:
|
|
172
|
+
"""Get the general drift result from the metrics list"""
|
|
173
|
+
value = cast(
|
|
174
|
+
float,
|
|
175
|
+
np.mean(
|
|
176
|
+
[
|
|
177
|
+
metric.value
|
|
178
|
+
for metric in metrics
|
|
179
|
+
if metric.name
|
|
180
|
+
in [
|
|
181
|
+
f"{HellingerDistance.NAME}_mean",
|
|
182
|
+
f"{TotalVarianceDistance.NAME}_mean",
|
|
183
|
+
]
|
|
162
184
|
]
|
|
163
|
-
|
|
185
|
+
),
|
|
164
186
|
)
|
|
165
187
|
|
|
166
188
|
status = self._value_classifier.value_to_status(value)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
189
|
+
return mm_results.ModelMonitoringApplicationResult(
|
|
190
|
+
name=HistogramDataDriftApplicationConstants.GENERAL_RESULT_NAME,
|
|
191
|
+
value=value,
|
|
192
|
+
kind=ResultKindApp.data_drift,
|
|
193
|
+
status=status,
|
|
194
|
+
extra_data={
|
|
195
|
+
EventFieldType.CURRENT_STATS: json.dumps(
|
|
196
|
+
monitoring_context.feature_stats
|
|
197
|
+
),
|
|
198
|
+
EventFieldType.DRIFT_MEASURES: metrics_per_feature.T.to_json(),
|
|
199
|
+
EventFieldType.DRIFT_STATUS: status.value,
|
|
200
|
+
},
|
|
174
201
|
)
|
|
175
202
|
|
|
203
|
+
@staticmethod
|
|
176
204
|
def _get_metrics(
|
|
177
|
-
|
|
205
|
+
metrics_per_feature: DataFrame,
|
|
178
206
|
) -> list[mm_results.ModelMonitoringApplicationMetric]:
|
|
179
207
|
"""Average the metrics over the features and add the status"""
|
|
180
208
|
metrics: list[mm_results.ModelMonitoringApplicationMetric] = []
|
|
@@ -206,8 +234,8 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBaseV2):
|
|
|
206
234
|
del sample_set_statistics[EventFieldType.TIMESTAMP]
|
|
207
235
|
return sample_set_statistics
|
|
208
236
|
|
|
237
|
+
@staticmethod
|
|
209
238
|
def _log_json_artifact(
|
|
210
|
-
self,
|
|
211
239
|
drift_per_feature_values: Series,
|
|
212
240
|
monitoring_context: mm_context.MonitoringApplicationContext,
|
|
213
241
|
) -> None:
|
|
@@ -247,7 +275,7 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBaseV2):
|
|
|
247
275
|
mm_drift_table.FeaturesDriftTablePlot().produce(
|
|
248
276
|
sample_set_statistics=sample_set_statistics,
|
|
249
277
|
inputs_statistics=inputs_statistics,
|
|
250
|
-
metrics=metrics_per_feature.T.to_dict(),
|
|
278
|
+
metrics=metrics_per_feature.T.to_dict(), # pyright: ignore[reportArgumentType]
|
|
251
279
|
drift_results=drift_results,
|
|
252
280
|
)
|
|
253
281
|
)
|
|
@@ -281,7 +309,7 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBaseV2):
|
|
|
281
309
|
self,
|
|
282
310
|
monitoring_context: mm_context.MonitoringApplicationContext,
|
|
283
311
|
) -> list[
|
|
284
|
-
|
|
312
|
+
Union[
|
|
285
313
|
mm_results.ModelMonitoringApplicationResult,
|
|
286
314
|
mm_results.ModelMonitoringApplicationMetric,
|
|
287
315
|
]
|
|
@@ -308,15 +336,13 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBaseV2):
|
|
|
308
336
|
metrics_per_feature=metrics_per_feature,
|
|
309
337
|
)
|
|
310
338
|
monitoring_context.logger.debug("Computing average per metric")
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
] = self._get_metrics(metrics_per_feature)
|
|
317
|
-
self._add_general_drift_result(
|
|
318
|
-
metrics=metrics_and_result,
|
|
339
|
+
metrics = self._get_metrics(metrics_per_feature)
|
|
340
|
+
result = self._get_general_drift_result(
|
|
341
|
+
metrics=metrics,
|
|
342
|
+
monitoring_context=monitoring_context,
|
|
343
|
+
metrics_per_feature=metrics_per_feature,
|
|
319
344
|
)
|
|
345
|
+
metrics_and_result = metrics + [result]
|
|
320
346
|
monitoring_context.logger.debug(
|
|
321
347
|
"Finished running the application", results=metrics_and_result
|
|
322
348
|
)
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
import typing
|
|
16
16
|
from abc import ABC, abstractmethod
|
|
17
17
|
|
|
18
|
+
import mlrun.common.schemas.model_monitoring.constants as mm_constants
|
|
19
|
+
|
|
18
20
|
|
|
19
21
|
class StoreBase(ABC):
|
|
20
22
|
"""
|
|
@@ -62,12 +64,10 @@ class StoreBase(ABC):
|
|
|
62
64
|
pass
|
|
63
65
|
|
|
64
66
|
@abstractmethod
|
|
65
|
-
def delete_model_endpoints_resources(self
|
|
67
|
+
def delete_model_endpoints_resources(self):
|
|
66
68
|
"""
|
|
67
69
|
Delete all model endpoints resources.
|
|
68
70
|
|
|
69
|
-
:param endpoints: A list of model endpoints flattened dictionaries.
|
|
70
|
-
|
|
71
71
|
"""
|
|
72
72
|
pass
|
|
73
73
|
|
|
@@ -112,45 +112,18 @@ class StoreBase(ABC):
|
|
|
112
112
|
pass
|
|
113
113
|
|
|
114
114
|
@abstractmethod
|
|
115
|
-
def
|
|
115
|
+
def write_application_event(
|
|
116
116
|
self,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
end: str = "now",
|
|
121
|
-
access_key: str = None,
|
|
122
|
-
) -> dict[str, list[tuple[str, float]]]:
|
|
123
|
-
"""
|
|
124
|
-
Getting metrics from the time series DB. There are pre-defined metrics for model endpoints such as
|
|
125
|
-
`predictions_per_second` and `latency_avg_5m` but also custom metrics defined by the user.
|
|
126
|
-
|
|
127
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
128
|
-
:param metrics: A list of real-time metrics to return for the model endpoint.
|
|
129
|
-
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
|
|
130
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
131
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
132
|
-
earliest time.
|
|
133
|
-
:param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
|
|
134
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
135
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
136
|
-
earliest time.
|
|
137
|
-
:param access_key: V3IO access key that will be used for generating Frames client object. If not
|
|
138
|
-
provided, the access key will be retrieved from the environment variables.
|
|
139
|
-
|
|
140
|
-
:return: A dictionary of metrics in which the key is a metric name and the value is a list of tuples that
|
|
141
|
-
includes timestamps and the values.
|
|
142
|
-
"""
|
|
143
|
-
|
|
144
|
-
pass
|
|
145
|
-
|
|
146
|
-
@abstractmethod
|
|
147
|
-
def write_application_result(self, event: dict[str, typing.Any]):
|
|
117
|
+
event: dict[str, typing.Any],
|
|
118
|
+
kind: mm_constants.WriterEventKind = mm_constants.WriterEventKind.RESULT,
|
|
119
|
+
):
|
|
148
120
|
"""
|
|
149
|
-
Write a new
|
|
121
|
+
Write a new event in the target table.
|
|
150
122
|
|
|
151
123
|
:param event: An event dictionary that represents the application result, should be corresponded to the
|
|
152
124
|
schema defined in the :py:class:`~mlrun.common.schemas.model_monitoring.constants.WriterEvent`
|
|
153
125
|
object.
|
|
126
|
+
:param kind: The type of the event, can be either "result" or "metric".
|
|
154
127
|
"""
|
|
155
128
|
pass
|
|
156
129
|
|