mlrun 1.10.0rc23__py3-none-any.whl → 1.10.0rc25__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/common/schemas/hub.py +14 -0
- mlrun/common/schemas/model_monitoring/constants.py +1 -0
- mlrun/common/schemas/model_monitoring/model_endpoints.py +10 -1
- mlrun/config.py +5 -1
- mlrun/datastore/azure_blob.py +66 -43
- mlrun/datastore/datastore_profile.py +8 -2
- mlrun/datastore/model_provider/huggingface_provider.py +118 -30
- mlrun/datastore/model_provider/model_provider.py +66 -8
- mlrun/datastore/model_provider/openai_provider.py +149 -47
- mlrun/db/base.py +1 -1
- mlrun/db/httpdb.py +6 -4
- mlrun/db/nopdb.py +1 -0
- mlrun/model_monitoring/api.py +2 -2
- mlrun/model_monitoring/applications/base.py +22 -10
- mlrun/model_monitoring/applications/context.py +1 -4
- mlrun/model_monitoring/controller.py +10 -2
- mlrun/model_monitoring/db/_schedules.py +2 -4
- mlrun/platforms/iguazio.py +7 -3
- mlrun/projects/project.py +28 -24
- mlrun/runtimes/nuclio/__init__.py +1 -0
- mlrun/runtimes/nuclio/application/application.py +26 -2
- mlrun/runtimes/nuclio/function.py +10 -0
- mlrun/runtimes/nuclio/serving.py +4 -0
- mlrun/runtimes/utils.py +22 -5
- mlrun/serving/server.py +25 -14
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.10.0rc23.dist-info → mlrun-1.10.0rc25.dist-info}/METADATA +23 -22
- {mlrun-1.10.0rc23.dist-info → mlrun-1.10.0rc25.dist-info}/RECORD +32 -32
- {mlrun-1.10.0rc23.dist-info → mlrun-1.10.0rc25.dist-info}/WHEEL +0 -0
- {mlrun-1.10.0rc23.dist-info → mlrun-1.10.0rc25.dist-info}/entry_points.txt +0 -0
- {mlrun-1.10.0rc23.dist-info → mlrun-1.10.0rc25.dist-info}/licenses/LICENSE +0 -0
- {mlrun-1.10.0rc23.dist-info → mlrun-1.10.0rc25.dist-info}/top_level.txt +0 -0
|
@@ -67,7 +67,6 @@ class OpenAIProvider(ModelProvider):
|
|
|
67
67
|
default_invoke_kwargs=default_invoke_kwargs,
|
|
68
68
|
)
|
|
69
69
|
self.options = self.get_client_options()
|
|
70
|
-
self.load_client()
|
|
71
70
|
|
|
72
71
|
@classmethod
|
|
73
72
|
def _import_response_class(cls) -> None:
|
|
@@ -81,8 +80,12 @@ class OpenAIProvider(ModelProvider):
|
|
|
81
80
|
@staticmethod
|
|
82
81
|
def _extract_string_output(response: "ChatCompletion") -> str:
|
|
83
82
|
"""
|
|
84
|
-
Extracts the first
|
|
85
|
-
|
|
83
|
+
Extracts the text content of the first choice from an OpenAI ChatCompletion response.
|
|
84
|
+
Only supports responses with a single choice. Raises an error if multiple choices exist.
|
|
85
|
+
|
|
86
|
+
:param response: The ChatCompletion response from OpenAI.
|
|
87
|
+
:return: The text content of the first message in the response.
|
|
88
|
+
:raises MLRunInvalidArgumentError: If the response contains more than one choice.
|
|
86
89
|
"""
|
|
87
90
|
if len(response.choices) != 1:
|
|
88
91
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
@@ -98,25 +101,58 @@ class OpenAIProvider(ModelProvider):
|
|
|
98
101
|
subpath = ""
|
|
99
102
|
return endpoint, subpath
|
|
100
103
|
|
|
101
|
-
|
|
104
|
+
@property
|
|
105
|
+
def client(self) -> Any:
|
|
102
106
|
"""
|
|
103
|
-
|
|
107
|
+
Lazily return the synchronous OpenAI client.
|
|
108
|
+
|
|
109
|
+
If the client has not been initialized yet, it will be created
|
|
110
|
+
by calling `load_client`.
|
|
111
|
+
"""
|
|
112
|
+
self.load_client()
|
|
113
|
+
return self._client
|
|
104
114
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
115
|
+
def load_client(self) -> None:
|
|
116
|
+
"""
|
|
117
|
+
Lazily initialize the synchronous OpenAI client.
|
|
108
118
|
|
|
109
|
-
|
|
110
|
-
|
|
119
|
+
The client is created only if it does not already exist.
|
|
120
|
+
Raises ImportError if the openai package is not installed.
|
|
111
121
|
"""
|
|
122
|
+
if self._client:
|
|
123
|
+
return
|
|
112
124
|
try:
|
|
113
|
-
from openai import OpenAI
|
|
125
|
+
from openai import OpenAI # noqa
|
|
114
126
|
|
|
115
127
|
self._client = OpenAI(**self.options)
|
|
116
|
-
self._async_client = AsyncOpenAI(**self.options)
|
|
117
128
|
except ImportError as exc:
|
|
118
129
|
raise ImportError("openai package is not installed") from exc
|
|
119
130
|
|
|
131
|
+
def load_async_client(self) -> None:
|
|
132
|
+
"""
|
|
133
|
+
Lazily initialize the asynchronous OpenAI client.
|
|
134
|
+
|
|
135
|
+
The client is created only if it does not already exist.
|
|
136
|
+
Raises ImportError if the openai package is not installed.
|
|
137
|
+
"""
|
|
138
|
+
if not self._async_client:
|
|
139
|
+
try:
|
|
140
|
+
from openai import AsyncOpenAI # noqa
|
|
141
|
+
|
|
142
|
+
self._async_client = AsyncOpenAI(**self.options)
|
|
143
|
+
except ImportError as exc:
|
|
144
|
+
raise ImportError("openai package is not installed") from exc
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def async_client(self) -> Any:
|
|
148
|
+
"""
|
|
149
|
+
Return the asynchronous OpenAI client, creating it on first access.
|
|
150
|
+
|
|
151
|
+
The client is lazily initialized via `load_async_client`.
|
|
152
|
+
"""
|
|
153
|
+
self.load_async_client()
|
|
154
|
+
return self._async_client
|
|
155
|
+
|
|
120
156
|
def get_client_options(self) -> dict:
|
|
121
157
|
res = dict(
|
|
122
158
|
api_key=self._get_secret_or_env("OPENAI_API_KEY"),
|
|
@@ -132,25 +168,37 @@ class OpenAIProvider(ModelProvider):
|
|
|
132
168
|
self, operation: Optional[Callable] = None, **invoke_kwargs
|
|
133
169
|
) -> Union["ChatCompletion", "BaseModel"]:
|
|
134
170
|
"""
|
|
135
|
-
OpenAI
|
|
171
|
+
Invokes a model operation from the OpenAI client with the given keyword arguments.
|
|
172
|
+
|
|
173
|
+
This method provides flexibility to either:
|
|
174
|
+
- Call a specific OpenAI client operation (e.g., `client.images.generate`).
|
|
175
|
+
- Default to `chat.completions.create` when no operation is provided.
|
|
136
176
|
|
|
137
|
-
|
|
138
|
-
`
|
|
177
|
+
The operation must be a callable that accepts keyword arguments. If the callable
|
|
178
|
+
does not accept a `model` parameter, it will be omitted from the call.
|
|
139
179
|
|
|
140
180
|
Example:
|
|
141
181
|
```python
|
|
142
|
-
result = openai_model_provider.
|
|
182
|
+
result = openai_model_provider.custom_invoke(
|
|
143
183
|
openai_model_provider.client.images.generate,
|
|
144
184
|
prompt="A futuristic cityscape at sunset",
|
|
145
185
|
n=1,
|
|
146
186
|
size="1024x1024",
|
|
147
187
|
)
|
|
148
188
|
```
|
|
149
|
-
:param operation: Same as ModelProvider.custom_invoke.
|
|
150
|
-
:param invoke_kwargs: Same as ModelProvider.custom_invoke.
|
|
151
|
-
:return: Same as ModelProvider.custom_invoke.
|
|
152
189
|
|
|
190
|
+
:param operation: A callable representing the OpenAI operation to invoke.
|
|
191
|
+
If not provided, defaults to `client.chat.completions.create`.
|
|
192
|
+
|
|
193
|
+
:param invoke_kwargs: Additional keyword arguments to pass to the operation.
|
|
194
|
+
These are merged with `default_invoke_kwargs` and may
|
|
195
|
+
include parameters such as `temperature`, `max_tokens`,
|
|
196
|
+
or `messages`.
|
|
197
|
+
|
|
198
|
+
:return: The full response returned by the operation, typically
|
|
199
|
+
an OpenAI `ChatCompletion` or other OpenAI SDK model.
|
|
153
200
|
"""
|
|
201
|
+
|
|
154
202
|
invoke_kwargs = self.get_invoke_kwargs(invoke_kwargs)
|
|
155
203
|
model_kwargs = {"model": invoke_kwargs.pop("model", None) or self.model}
|
|
156
204
|
|
|
@@ -171,24 +219,35 @@ class OpenAIProvider(ModelProvider):
|
|
|
171
219
|
**invoke_kwargs,
|
|
172
220
|
) -> Union["ChatCompletion", "BaseModel"]:
|
|
173
221
|
"""
|
|
174
|
-
OpenAI
|
|
222
|
+
Asynchronously invokes a model operation from the OpenAI client with the given keyword arguments.
|
|
175
223
|
|
|
176
|
-
|
|
177
|
-
`
|
|
224
|
+
This method provides flexibility to either:
|
|
225
|
+
- Call a specific async OpenAI client operation (e.g., `async_client.images.generate`).
|
|
226
|
+
- Default to `chat.completions.create` when no operation is provided.
|
|
227
|
+
|
|
228
|
+
The operation must be an async callable that accepts keyword arguments.
|
|
229
|
+
If the callable does not accept a `model` parameter, it will be omitted from the call.
|
|
178
230
|
|
|
179
231
|
Example:
|
|
180
|
-
|
|
181
|
-
result = openai_model_provider.
|
|
232
|
+
```python
|
|
233
|
+
result = await openai_model_provider.async_custom_invoke(
|
|
182
234
|
openai_model_provider.async_client.images.generate,
|
|
183
235
|
prompt="A futuristic cityscape at sunset",
|
|
184
236
|
n=1,
|
|
185
237
|
size="1024x1024",
|
|
186
238
|
)
|
|
187
|
-
|
|
239
|
+
```
|
|
188
240
|
|
|
189
|
-
:param operation:
|
|
190
|
-
|
|
191
|
-
|
|
241
|
+
:param operation: An async callable representing the OpenAI operation to invoke.
|
|
242
|
+
If not provided, defaults to `async_client.chat.completions.create`.
|
|
243
|
+
|
|
244
|
+
:param invoke_kwargs: Additional keyword arguments to pass to the operation.
|
|
245
|
+
These are merged with `default_invoke_kwargs` and may
|
|
246
|
+
include parameters such as `temperature`, `max_tokens`,
|
|
247
|
+
or `messages`.
|
|
248
|
+
|
|
249
|
+
:return: The full response returned by the awaited operation,
|
|
250
|
+
typically an OpenAI `ChatCompletion` or other OpenAI SDK model.
|
|
192
251
|
|
|
193
252
|
"""
|
|
194
253
|
invoke_kwargs = self.get_invoke_kwargs(invoke_kwargs)
|
|
@@ -217,10 +276,10 @@ class OpenAIProvider(ModelProvider):
|
|
|
217
276
|
if invoke_response_format == InvokeResponseFormat.STRING:
|
|
218
277
|
return str_response
|
|
219
278
|
if invoke_response_format == InvokeResponseFormat.USAGE:
|
|
220
|
-
|
|
279
|
+
usage = response.to_dict()["usage"]
|
|
221
280
|
response = {
|
|
222
281
|
UsageResponseKeys.ANSWER: str_response,
|
|
223
|
-
UsageResponseKeys.USAGE:
|
|
282
|
+
UsageResponseKeys.USAGE: usage,
|
|
224
283
|
}
|
|
225
284
|
return response
|
|
226
285
|
|
|
@@ -233,27 +292,42 @@ class OpenAIProvider(ModelProvider):
|
|
|
233
292
|
"""
|
|
234
293
|
OpenAI-specific implementation of `ModelProvider.invoke`.
|
|
235
294
|
Invokes an OpenAI model operation using the synchronous client.
|
|
236
|
-
For full details, see `ModelProvider.invoke`.
|
|
237
295
|
|
|
238
296
|
:param messages:
|
|
239
|
-
|
|
297
|
+
A list of dictionaries representing the conversation history or input messages.
|
|
298
|
+
Each dictionary should follow the format::
|
|
299
|
+
{
|
|
300
|
+
"role": "system" | "user" | "assistant",
|
|
301
|
+
"content": "Message content as a string",
|
|
302
|
+
}
|
|
240
303
|
|
|
241
|
-
|
|
304
|
+
Example:
|
|
305
|
+
|
|
306
|
+
.. code-block:: json
|
|
307
|
+
|
|
308
|
+
[
|
|
309
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
310
|
+
{"role": "user", "content": "What is the capital of France?"}
|
|
311
|
+
]
|
|
312
|
+
|
|
313
|
+
Defaults to None if no messages are provided.
|
|
314
|
+
|
|
315
|
+
:param invoke_response_format:
|
|
242
316
|
Specifies the format of the returned response. Options:
|
|
243
317
|
|
|
244
318
|
- "string": Returns only the generated text content, taken from a single response.
|
|
245
|
-
- "
|
|
319
|
+
- "usage": Combines the generated text with metadata (e.g., token usage), returning a dictionary::
|
|
246
320
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
321
|
+
.. code-block:: json
|
|
322
|
+
{
|
|
323
|
+
"answer": "<generated_text>",
|
|
324
|
+
"usage": <ChatCompletion>.to_dict()["usage"]
|
|
325
|
+
}
|
|
252
326
|
|
|
253
327
|
- "full": Returns the full OpenAI `ChatCompletion` object.
|
|
254
328
|
|
|
255
329
|
:param invoke_kwargs:
|
|
256
|
-
Additional keyword arguments passed to the OpenAI client.
|
|
330
|
+
Additional keyword arguments passed to the OpenAI client.
|
|
257
331
|
|
|
258
332
|
:return:
|
|
259
333
|
A string, dictionary, or `ChatCompletion` object, depending on `invoke_response_format`.
|
|
@@ -274,18 +348,46 @@ class OpenAIProvider(ModelProvider):
|
|
|
274
348
|
) -> Union[str, "ChatCompletion", dict]:
|
|
275
349
|
"""
|
|
276
350
|
OpenAI-specific implementation of `ModelProvider.async_invoke`.
|
|
277
|
-
Invokes an OpenAI model operation using the
|
|
278
|
-
|
|
351
|
+
Invokes an OpenAI model operation using the asynchronous client.
|
|
352
|
+
|
|
353
|
+
:param messages:
|
|
354
|
+
A list of dictionaries representing the conversation history or input messages.
|
|
355
|
+
Each dictionary should follow the format::
|
|
356
|
+
{
|
|
357
|
+
"role": "system" | "user" | "assistant",
|
|
358
|
+
"content": "Message content as a string",
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
Example:
|
|
362
|
+
|
|
363
|
+
.. code-block:: json
|
|
364
|
+
|
|
365
|
+
[
|
|
366
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
367
|
+
{"role": "user", "content": "What is the capital of France?"}
|
|
368
|
+
]
|
|
369
|
+
|
|
370
|
+
Defaults to None if no messages are provided.
|
|
371
|
+
|
|
372
|
+
:param invoke_response_format:
|
|
373
|
+
Specifies the format of the returned response. Options:
|
|
374
|
+
|
|
375
|
+
- "string": Returns only the generated text content, taken from a single response.
|
|
376
|
+
- "usage": Combines the generated text with metadata (e.g., token usage), returning a dictionary::
|
|
279
377
|
|
|
280
|
-
|
|
378
|
+
.. code-block:: json
|
|
379
|
+
{
|
|
380
|
+
"answer": "<generated_text>",
|
|
381
|
+
"usage": <ChatCompletion>.to_dict()["usage"]
|
|
382
|
+
}
|
|
281
383
|
|
|
282
|
-
|
|
283
|
-
Same as `OpenAIProvider.invoke`.
|
|
384
|
+
- "full": Returns the full OpenAI `ChatCompletion` object.
|
|
284
385
|
|
|
285
386
|
:param invoke_kwargs:
|
|
286
|
-
|
|
287
|
-
:returns Same as `ModelProvider.async_invoke`.
|
|
387
|
+
Additional keyword arguments passed to the OpenAI client.
|
|
288
388
|
|
|
389
|
+
:return:
|
|
390
|
+
A string, dictionary, or `ChatCompletion` object, depending on `invoke_response_format`.
|
|
289
391
|
"""
|
|
290
392
|
response = await self.async_custom_invoke(messages=messages, **invoke_kwargs)
|
|
291
393
|
return self._response_handler(
|
mlrun/db/base.py
CHANGED
|
@@ -722,7 +722,7 @@ class RunDBInterface(ABC):
|
|
|
722
722
|
tsdb_metrics: bool = False,
|
|
723
723
|
metric_list: Optional[list[str]] = None,
|
|
724
724
|
top_level: bool = False,
|
|
725
|
-
|
|
725
|
+
modes: Optional[list[mm_constants.EndpointMode]] = None,
|
|
726
726
|
uids: Optional[list[str]] = None,
|
|
727
727
|
latest_only: bool = False,
|
|
728
728
|
) -> mlrun.common.schemas.ModelEndpointList:
|
mlrun/db/httpdb.py
CHANGED
|
@@ -3770,7 +3770,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3770
3770
|
tsdb_metrics: bool = False,
|
|
3771
3771
|
metric_list: Optional[list[str]] = None,
|
|
3772
3772
|
top_level: bool = False,
|
|
3773
|
-
|
|
3773
|
+
modes: Optional[list[mm_constants.EndpointMode]] = None,
|
|
3774
3774
|
uids: Optional[list[str]] = None,
|
|
3775
3775
|
latest_only: bool = False,
|
|
3776
3776
|
) -> mlrun.common.schemas.ModelEndpointList:
|
|
@@ -3791,8 +3791,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3791
3791
|
If tsdb_metrics=False, this parameter will be ignored and no tsdb metrics
|
|
3792
3792
|
will be included.
|
|
3793
3793
|
:param top_level: Whether to return only top level model endpoints.
|
|
3794
|
-
:param
|
|
3795
|
-
|
|
3794
|
+
:param modes: Specifies the modes of the model endpoints. Can be "real-time" (0), "batch" (1),
|
|
3795
|
+
"batch_legacy" (2). If set to None, all are included.
|
|
3796
3796
|
:param uids: A list of unique ids to filter by.
|
|
3797
3797
|
:param latest_only: Whether to return only the latest model endpoint version.
|
|
3798
3798
|
:return: A list of model endpoints.
|
|
@@ -3801,6 +3801,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3801
3801
|
labels = self._parse_labels(labels)
|
|
3802
3802
|
if names and isinstance(names, str):
|
|
3803
3803
|
names = [names]
|
|
3804
|
+
if isinstance(modes, mm_constants.EndpointMode):
|
|
3805
|
+
modes = [modes]
|
|
3804
3806
|
response = self.api_call(
|
|
3805
3807
|
method=mlrun.common.types.HTTPMethod.GET,
|
|
3806
3808
|
path=path,
|
|
@@ -3816,7 +3818,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3816
3818
|
"tsdb-metrics": tsdb_metrics,
|
|
3817
3819
|
"metric": metric_list,
|
|
3818
3820
|
"top-level": top_level,
|
|
3819
|
-
"mode":
|
|
3821
|
+
"mode": modes,
|
|
3820
3822
|
"uid": uids,
|
|
3821
3823
|
"latest-only": latest_only,
|
|
3822
3824
|
},
|
mlrun/db/nopdb.py
CHANGED
|
@@ -626,6 +626,7 @@ class NopDB(RunDBInterface):
|
|
|
626
626
|
tsdb_metrics: bool = False,
|
|
627
627
|
metric_list: Optional[list[str]] = None,
|
|
628
628
|
top_level: bool = False,
|
|
629
|
+
modes: Optional[list[mm_constants.EndpointMode]] = None,
|
|
629
630
|
uids: Optional[list[str]] = None,
|
|
630
631
|
latest_only: bool = False,
|
|
631
632
|
) -> mlrun.common.schemas.ModelEndpointList:
|
mlrun/model_monitoring/api.py
CHANGED
|
@@ -350,8 +350,8 @@ def _generate_model_endpoint(
|
|
|
350
350
|
project=project,
|
|
351
351
|
name=model_endpoint_name,
|
|
352
352
|
endpoint_type=mlrun.common.schemas.model_monitoring.EndpointType.BATCH_EP,
|
|
353
|
-
# Due to backwards compatibility,
|
|
354
|
-
mode=mlrun.common.schemas.model_monitoring.EndpointMode.
|
|
353
|
+
# Due to backwards compatibility, this endpoint will be created as a legacy batch endpoint.
|
|
354
|
+
mode=mlrun.common.schemas.model_monitoring.EndpointMode.BATCH_LEGACY,
|
|
355
355
|
),
|
|
356
356
|
spec=mlrun.common.schemas.ModelEndpointSpec(
|
|
357
357
|
function_name=function_name or "function",
|
|
@@ -18,7 +18,7 @@ from abc import ABC, abstractmethod
|
|
|
18
18
|
from collections import defaultdict
|
|
19
19
|
from collections.abc import Iterator
|
|
20
20
|
from contextlib import contextmanager, nullcontext
|
|
21
|
-
from datetime import datetime, timedelta
|
|
21
|
+
from datetime import datetime, timedelta, timezone
|
|
22
22
|
from typing import Any, Literal, Optional, Union, cast
|
|
23
23
|
|
|
24
24
|
import pandas as pd
|
|
@@ -591,6 +591,16 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
|
|
|
591
591
|
start_dt = datetime.fromisoformat(start)
|
|
592
592
|
end_dt = datetime.fromisoformat(end)
|
|
593
593
|
|
|
594
|
+
# If `start_dt` and `end_dt` do not include time zone information - change them to UTC
|
|
595
|
+
if (start_dt.tzinfo is None) and (end_dt.tzinfo is None):
|
|
596
|
+
start_dt = start_dt.replace(tzinfo=timezone.utc)
|
|
597
|
+
end_dt = end_dt.replace(tzinfo=timezone.utc)
|
|
598
|
+
elif (start_dt.tzinfo is None) or (end_dt.tzinfo is None):
|
|
599
|
+
raise mlrun.errors.MLRunValueError(
|
|
600
|
+
"The start and end times must either both include time zone information or both be naive (no time "
|
|
601
|
+
f"zone). Asserting the above failed, aborting the evaluate request: start={start}, end={end}."
|
|
602
|
+
)
|
|
603
|
+
|
|
594
604
|
if existing_data_handling != ExistingDataHandling.delete_all:
|
|
595
605
|
start_dt = cls._validate_monotonically_increasing_data(
|
|
596
606
|
application_schedules=application_schedules,
|
|
@@ -841,7 +851,7 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
|
|
|
841
851
|
:py:meth:`~mlrun.model_monitoring.applications.ModelMonitoringApplicationBase.do_tracking`
|
|
842
852
|
model monitoring logic as a :py:class:`~mlrun.runtimes.KubejobRuntime`, which is an MLRun function.
|
|
843
853
|
|
|
844
|
-
This function has default values for all of its arguments. You should
|
|
854
|
+
This function has default values for all of its arguments. You should change them when you want to pass
|
|
845
855
|
data to the application.
|
|
846
856
|
|
|
847
857
|
:param func_path: The path to the function. If ``None``, the current notebook is used.
|
|
@@ -858,6 +868,7 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
|
|
|
858
868
|
:param reference_data: Pandas data-frame or :py:class:`~mlrun.artifacts.dataset.DatasetArtifact` URI as
|
|
859
869
|
the reference dataset.
|
|
860
870
|
When set, its statistics override the model endpoint's feature statistics.
|
|
871
|
+
You do not need to have a model endpoint to use this option.
|
|
861
872
|
:param image: Docker image to run the job on (when running remotely).
|
|
862
873
|
:param with_repo: Whether to clone the current repo to the build source.
|
|
863
874
|
:param class_handler: The relative path to the class, useful when using Git sources or code from images.
|
|
@@ -878,8 +889,9 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
|
|
|
878
889
|
:param start: The start time of the endpoint's data, not included.
|
|
879
890
|
If you want the model endpoint's data at ``start`` included, you need to subtract a
|
|
880
891
|
small ``datetime.timedelta`` from it.
|
|
881
|
-
Make sure to include the time zone when constructing
|
|
882
|
-
manually.
|
|
892
|
+
Make sure to include the time zone when constructing ``datetime.datetime`` objects
|
|
893
|
+
manually. When both ``start`` and ``end`` times do not include a time zone, they will
|
|
894
|
+
be treated as UTC.
|
|
883
895
|
:param end: The end time of the endpoint's data, included.
|
|
884
896
|
Please note: when ``start`` and ``end`` are set, they create a left-open time interval
|
|
885
897
|
("window") :math:`(\\operatorname{start}, \\operatorname{end}]` that excludes the
|
|
@@ -902,13 +914,13 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
|
|
|
902
914
|
if ``endpoints`` are passed.
|
|
903
915
|
Note: the model monitoring infrastructure must be up for the writing to work.
|
|
904
916
|
:param existing_data_handling:
|
|
905
|
-
How to handle the existing application data for the model endpoints when writing
|
|
906
|
-
new data
|
|
907
|
-
|
|
917
|
+
How to handle the existing application data for the model endpoints when writing
|
|
918
|
+
new data whose requested ``start`` time precedes the ``end`` time of a previous run
|
|
919
|
+
that also wrote to the database. Relevant only when ``write_output=True``.
|
|
920
|
+
The options are:
|
|
908
921
|
|
|
909
|
-
- ``"fail_on_overlap"``:
|
|
910
|
-
|
|
911
|
-
- ``"skip_overlap"``: when the previously described situation occurs, the relevant
|
|
922
|
+
- ``"fail_on_overlap"``: Default. An error is raised.
|
|
923
|
+
- ``"skip_overlap"``: the overlapping data is ignored and the
|
|
912
924
|
time window is cut so that it starts at the earliest possible time after ``start``.
|
|
913
925
|
- ``"delete_all"``: delete all the data that was written by the application to the
|
|
914
926
|
model endpoints, regardless of the time window, and write the new data.
|
|
@@ -24,15 +24,12 @@ import mlrun.common.schemas.model_monitoring.constants as mm_constants
|
|
|
24
24
|
import mlrun.errors
|
|
25
25
|
import mlrun.feature_store as fstore
|
|
26
26
|
import mlrun.feature_store.feature_set as fs
|
|
27
|
-
import mlrun.features
|
|
28
27
|
import mlrun.serving
|
|
29
28
|
import mlrun.utils
|
|
30
29
|
from mlrun.artifacts import Artifact, DatasetArtifact, ModelArtifact, get_model
|
|
31
30
|
from mlrun.common.model_monitoring.helpers import FeatureStats
|
|
32
31
|
from mlrun.common.schemas import ModelEndpoint
|
|
33
|
-
from mlrun.model_monitoring.helpers import
|
|
34
|
-
calculate_inputs_statistics,
|
|
35
|
-
)
|
|
32
|
+
from mlrun.model_monitoring.helpers import calculate_inputs_statistics
|
|
36
33
|
|
|
37
34
|
|
|
38
35
|
class _ArtifactsLogger(Protocol):
|
|
@@ -801,7 +801,11 @@ class MonitoringApplicationController:
|
|
|
801
801
|
logger.info("Starting monitoring controller chief")
|
|
802
802
|
applications_names = []
|
|
803
803
|
endpoints = self.project_obj.list_model_endpoints(
|
|
804
|
-
tsdb_metrics=False,
|
|
804
|
+
tsdb_metrics=False,
|
|
805
|
+
modes=[
|
|
806
|
+
mm_constants.EndpointMode.REAL_TIME,
|
|
807
|
+
mm_constants.EndpointMode.BATCH_LEGACY,
|
|
808
|
+
],
|
|
805
809
|
).endpoints
|
|
806
810
|
last_request_dict = self.tsdb_connector.get_last_request(
|
|
807
811
|
endpoint_ids=[mep.metadata.uid for mep in endpoints]
|
|
@@ -859,7 +863,11 @@ class MonitoringApplicationController:
|
|
|
859
863
|
for endpoint in endpoints:
|
|
860
864
|
last_request = last_request_dict.get(endpoint.metadata.uid, None)
|
|
861
865
|
if isinstance(last_request, float):
|
|
862
|
-
last_request =
|
|
866
|
+
last_request = datetime.datetime.fromtimestamp(
|
|
867
|
+
last_request, tz=datetime.timezone.utc
|
|
868
|
+
)
|
|
869
|
+
elif isinstance(last_request, pd.Timestamp):
|
|
870
|
+
last_request = last_request.to_pydatetime()
|
|
863
871
|
endpoint.status.last_request = (
|
|
864
872
|
last_request or endpoint.status.last_request
|
|
865
873
|
)
|
|
@@ -16,7 +16,7 @@ import json
|
|
|
16
16
|
import sys
|
|
17
17
|
from abc import ABC, abstractmethod
|
|
18
18
|
from contextlib import AbstractContextManager
|
|
19
|
-
from datetime import datetime
|
|
19
|
+
from datetime import datetime
|
|
20
20
|
from types import TracebackType
|
|
21
21
|
from typing import TYPE_CHECKING, Final, Optional
|
|
22
22
|
|
|
@@ -281,9 +281,7 @@ class ModelMonitoringSchedulesFileApplication(ModelMonitoringSchedulesFileBase):
|
|
|
281
281
|
self, endpoint_uid: str, last_analyzed: datetime
|
|
282
282
|
) -> None:
|
|
283
283
|
self._check_open_schedules()
|
|
284
|
-
self._schedules[endpoint_uid] = last_analyzed.
|
|
285
|
-
timezone.utc
|
|
286
|
-
).isoformat()
|
|
284
|
+
self._schedules[endpoint_uid] = last_analyzed.isoformat()
|
|
287
285
|
|
|
288
286
|
def delete_endpoints_last_analyzed(self, endpoint_uids: list[str]) -> None:
|
|
289
287
|
self._check_open_schedules()
|
mlrun/platforms/iguazio.py
CHANGED
|
@@ -96,7 +96,11 @@ class OutputStream:
|
|
|
96
96
|
if access_key:
|
|
97
97
|
v3io_client_kwargs["access_key"] = access_key
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
if not mock:
|
|
100
|
+
self._v3io_client = v3io.dataplane.Client(**v3io_client_kwargs)
|
|
101
|
+
else:
|
|
102
|
+
self._v3io_client = None
|
|
103
|
+
|
|
100
104
|
self._container, self._stream_path = split_path(stream_path)
|
|
101
105
|
self._shards = shards
|
|
102
106
|
self._retention_in_hours = retention_in_hours
|
|
@@ -105,7 +109,7 @@ class OutputStream:
|
|
|
105
109
|
self._mock = mock
|
|
106
110
|
self._mock_queue = []
|
|
107
111
|
|
|
108
|
-
def create_stream(self):
|
|
112
|
+
def create_stream(self) -> None:
|
|
109
113
|
# this import creates an import loop via the utils module, so putting it in execution path
|
|
110
114
|
from mlrun.utils.helpers import logger
|
|
111
115
|
|
|
@@ -210,7 +214,7 @@ class KafkaOutputStream:
|
|
|
210
214
|
self._initialized = False
|
|
211
215
|
|
|
212
216
|
def _lazy_init(self):
|
|
213
|
-
if self._initialized:
|
|
217
|
+
if self._initialized or self._mock:
|
|
214
218
|
return
|
|
215
219
|
|
|
216
220
|
import kafka
|
mlrun/projects/project.py
CHANGED
|
@@ -2749,16 +2749,18 @@ class MlrunProject(ModelObj):
|
|
|
2749
2749
|
| Creating a function with non project source is done by specifying a module ``handler`` and on the
|
|
2750
2750
|
returned function set the source with ``function.with_source_archive(<source>)``.
|
|
2751
2751
|
|
|
2752
|
-
|
|
2752
|
+
Supported URL prefixes:
|
|
2753
2753
|
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2754
|
+
- Object: s3://, v3io://, etc.
|
|
2755
|
+
- MLRun DB: e.g db://project/func:ver
|
|
2756
|
+
- Function hub/market: e.g. hub://auto-trainer:master
|
|
2757
2757
|
|
|
2758
2758
|
Examples::
|
|
2759
2759
|
|
|
2760
2760
|
proj.set_function(func_object)
|
|
2761
|
-
proj.set_function(
|
|
2761
|
+
proj.set_function(
|
|
2762
|
+
"http://.../mynb.ipynb", "train", kind="job", image="mlrun/mlrun"
|
|
2763
|
+
)
|
|
2762
2764
|
proj.set_function("./func.yaml")
|
|
2763
2765
|
proj.set_function("hub://get_toy_data", "getdata")
|
|
2764
2766
|
|
|
@@ -2785,18 +2787,6 @@ class MlrunProject(ModelObj):
|
|
|
2785
2787
|
# By providing a path to a pip requirements file
|
|
2786
2788
|
proj.set_function("my.py", requirements="requirements.txt")
|
|
2787
2789
|
|
|
2788
|
-
One of the most important parameters is 'kind', used to specify the chosen runtime. The options are:
|
|
2789
|
-
- local: execute a local python or shell script
|
|
2790
|
-
- job: insert the code into a Kubernetes pod and execute it
|
|
2791
|
-
- nuclio: insert the code into a real-time serverless nuclio function
|
|
2792
|
-
- serving: insert code into orchestrated nuclio function(s) forming a DAG
|
|
2793
|
-
- dask: run the specified python code / script as Dask Distributed job
|
|
2794
|
-
- mpijob: run distributed Horovod jobs over the MPI job operator
|
|
2795
|
-
- spark: run distributed Spark job using Spark Kubernetes Operator
|
|
2796
|
-
- remote-spark: run distributed Spark job on remote Spark service
|
|
2797
|
-
- databricks: run code on Databricks cluster (python scripts, Spark etc.)
|
|
2798
|
-
- application: run a long living application (e.g. a web server, UI, etc.)
|
|
2799
|
-
|
|
2800
2790
|
Learn more about :doc:`../../concepts/functions-overview`.
|
|
2801
2791
|
|
|
2802
2792
|
:param func: Function object or spec/code url, None refers to current Notebook
|
|
@@ -2804,8 +2794,20 @@ class MlrunProject(ModelObj):
|
|
|
2804
2794
|
Versions (e.g. myfunc:v1). If the `tag` parameter is provided, the tag in the name
|
|
2805
2795
|
must match the tag parameter.
|
|
2806
2796
|
Specifying a tag in the name will update the project's tagged function (myfunc:v1)
|
|
2807
|
-
:param kind:
|
|
2808
|
-
|
|
2797
|
+
:param kind: Default: job. One of
|
|
2798
|
+
|
|
2799
|
+
- local: execute a local python or shell script
|
|
2800
|
+
- job: insert the code into a Kubernetes pod and execute it
|
|
2801
|
+
- nuclio: insert the code into a real-time serverless nuclio function
|
|
2802
|
+
- serving: insert code into orchestrated nuclio function(s) forming a DAG
|
|
2803
|
+
- dask: run the specified python code / script as Dask Distributed job
|
|
2804
|
+
- mpijob: run distributed Horovod jobs over the MPI job operator
|
|
2805
|
+
- spark: run distributed Spark job using Spark Kubernetes Operator
|
|
2806
|
+
- remote-spark: run distributed Spark job on remote Spark service
|
|
2807
|
+
- databricks: run code on Databricks cluster (python scripts, Spark etc.)
|
|
2808
|
+
- application: run a long living application (e.g. a web server, UI, etc.)
|
|
2809
|
+
- handler: execute a python handler (used automatically in notebooks or for debug)
|
|
2810
|
+
|
|
2809
2811
|
:param image: Docker image to be used, can also be specified in the function object/yaml
|
|
2810
2812
|
:param handler: Default function handler to invoke (can only be set with .py/.ipynb files)
|
|
2811
2813
|
:param with_repo: Add (clone) the current repo to the build source - use when the function code is in
|
|
@@ -3944,7 +3946,9 @@ class MlrunProject(ModelObj):
|
|
|
3944
3946
|
start: Optional[datetime.datetime] = None,
|
|
3945
3947
|
end: Optional[datetime.datetime] = None,
|
|
3946
3948
|
top_level: bool = False,
|
|
3947
|
-
|
|
3949
|
+
modes: Optional[
|
|
3950
|
+
Union[mm_constants.EndpointMode, list[mm_constants.EndpointMode]]
|
|
3951
|
+
] = None,
|
|
3948
3952
|
uids: Optional[list[str]] = None,
|
|
3949
3953
|
latest_only: bool = False,
|
|
3950
3954
|
tsdb_metrics: bool = False,
|
|
@@ -3960,7 +3964,7 @@ class MlrunProject(ModelObj):
|
|
|
3960
3964
|
5) function_tag
|
|
3961
3965
|
6) labels
|
|
3962
3966
|
7) top level
|
|
3963
|
-
8)
|
|
3967
|
+
8) modes
|
|
3964
3968
|
9) uids
|
|
3965
3969
|
10) start and end time, corresponding to the `created` field.
|
|
3966
3970
|
By default, when no filters are applied, all available endpoints for the given project will be listed.
|
|
@@ -3982,8 +3986,8 @@ class MlrunProject(ModelObj):
|
|
|
3982
3986
|
:param start: The start time to filter by.Corresponding to the `created` field.
|
|
3983
3987
|
:param end: The end time to filter by. Corresponding to the `created` field.
|
|
3984
3988
|
:param top_level: If true will return only routers and endpoint that are NOT children of any router.
|
|
3985
|
-
:param
|
|
3986
|
-
|
|
3989
|
+
:param modes: Specifies the mode of the model endpoint. Can be "real-time" (0), "batch" (1),
|
|
3990
|
+
"batch_legacy" (2). If set to None, all are included.
|
|
3987
3991
|
:param uids: If passed will return a list `ModelEndpoint` object with uid in uids.
|
|
3988
3992
|
:param tsdb_metrics: When True, the time series metrics will be added to the output
|
|
3989
3993
|
of the resulting.
|
|
@@ -4005,7 +4009,7 @@ class MlrunProject(ModelObj):
|
|
|
4005
4009
|
start=start,
|
|
4006
4010
|
end=end,
|
|
4007
4011
|
top_level=top_level,
|
|
4008
|
-
|
|
4012
|
+
modes=modes,
|
|
4009
4013
|
uids=uids,
|
|
4010
4014
|
latest_only=latest_only,
|
|
4011
4015
|
tsdb_metrics=tsdb_metrics,
|