mlrun 1.5.0rc12__py3-none-any.whl → 1.5.0rc13__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/__main__.py +31 -2
- mlrun/api/api/endpoints/functions.py +110 -52
- mlrun/api/crud/model_monitoring/deployment.py +208 -38
- mlrun/api/crud/model_monitoring/helpers.py +19 -6
- mlrun/api/crud/model_monitoring/model_endpoints.py +14 -1
- mlrun/api/db/sqldb/db.py +3 -1
- mlrun/api/utils/builder.py +2 -4
- mlrun/common/model_monitoring/helpers.py +19 -5
- mlrun/common/schemas/model_monitoring/constants.py +69 -0
- mlrun/common/schemas/model_monitoring/model_endpoints.py +10 -0
- mlrun/config.py +30 -12
- mlrun/datastore/__init__.py +1 -0
- mlrun/datastore/sources.py +4 -30
- mlrun/datastore/targets.py +68 -31
- mlrun/db/httpdb.py +20 -6
- mlrun/feature_store/api.py +3 -31
- mlrun/feature_store/feature_vector.py +1 -1
- mlrun/feature_store/retrieval/base.py +8 -3
- mlrun/launcher/remote.py +3 -3
- mlrun/lists.py +11 -0
- mlrun/model_monitoring/__init__.py +0 -1
- mlrun/model_monitoring/api.py +1 -1
- mlrun/model_monitoring/application.py +313 -0
- mlrun/model_monitoring/batch_application.py +526 -0
- mlrun/model_monitoring/batch_application_handler.py +32 -0
- mlrun/model_monitoring/evidently_application.py +89 -0
- mlrun/model_monitoring/helpers.py +39 -3
- mlrun/model_monitoring/stores/kv_model_endpoint_store.py +37 -0
- mlrun/model_monitoring/tracking_policy.py +4 -4
- mlrun/model_monitoring/writer.py +37 -0
- mlrun/projects/pipelines.py +38 -4
- mlrun/projects/project.py +257 -43
- mlrun/run.py +5 -2
- mlrun/runtimes/__init__.py +2 -0
- mlrun/runtimes/function.py +2 -1
- mlrun/utils/helpers.py +12 -0
- mlrun/utils/http.py +3 -0
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.5.0rc12.dist-info → mlrun-1.5.0rc13.dist-info}/METADATA +5 -5
- {mlrun-1.5.0rc12.dist-info → mlrun-1.5.0rc13.dist-info}/RECORD +45 -40
- /mlrun/model_monitoring/{model_monitoring_batch.py → batch.py} +0 -0
- {mlrun-1.5.0rc12.dist-info → mlrun-1.5.0rc13.dist-info}/LICENSE +0 -0
- {mlrun-1.5.0rc12.dist-info → mlrun-1.5.0rc13.dist-info}/WHEEL +0 -0
- {mlrun-1.5.0rc12.dist-info → mlrun-1.5.0rc13.dist-info}/entry_points.txt +0 -0
- {mlrun-1.5.0rc12.dist-info → mlrun-1.5.0rc13.dist-info}/top_level.txt +0 -0
mlrun/__main__.py
CHANGED
|
@@ -17,6 +17,7 @@ import json
|
|
|
17
17
|
import pathlib
|
|
18
18
|
import socket
|
|
19
19
|
import traceback
|
|
20
|
+
import warnings
|
|
20
21
|
from ast import literal_eval
|
|
21
22
|
from base64 import b64decode, b64encode
|
|
22
23
|
from os import environ, path, remove
|
|
@@ -445,7 +446,7 @@ def run(
|
|
|
445
446
|
@click.option("--archive", "-a", default="", help="destination archive for code (tar)")
|
|
446
447
|
@click.option("--silent", is_flag=True, help="do not show build logs")
|
|
447
448
|
@click.option("--with-mlrun", is_flag=True, help="add MLRun package")
|
|
448
|
-
@click.option("--db", default="", help="save run results to
|
|
449
|
+
@click.option("--db", default="", help="save run results to DB url")
|
|
449
450
|
@click.option(
|
|
450
451
|
"--runtime", "-r", default="", help="function spec dict, for pipeline usage"
|
|
451
452
|
)
|
|
@@ -591,6 +592,13 @@ def build(
|
|
|
591
592
|
default="",
|
|
592
593
|
help="path/url of function yaml or function " "yaml or db://<project>/<name>[:tag]",
|
|
593
594
|
)
|
|
595
|
+
# TODO: Remove in 1.6.0
|
|
596
|
+
@click.option(
|
|
597
|
+
"--dashboard",
|
|
598
|
+
"-d",
|
|
599
|
+
default="",
|
|
600
|
+
help="Deprecated. Keep empty to allow auto-detect by MLRun API",
|
|
601
|
+
)
|
|
594
602
|
@click.option("--project", "-p", default="", help="project name")
|
|
595
603
|
@click.option("--model", "-m", multiple=True, help="model name and path (name=path)")
|
|
596
604
|
@click.option("--kind", "-k", default=None, help="runtime sub kind")
|
|
@@ -609,6 +617,7 @@ def deploy(
|
|
|
609
617
|
spec,
|
|
610
618
|
source,
|
|
611
619
|
func_url,
|
|
620
|
+
dashboard,
|
|
612
621
|
project,
|
|
613
622
|
model,
|
|
614
623
|
tag,
|
|
@@ -669,6 +678,14 @@ def deploy(
|
|
|
669
678
|
function.set_env(k, v)
|
|
670
679
|
function.verbose = verbose
|
|
671
680
|
|
|
681
|
+
if dashboard:
|
|
682
|
+
warnings.warn(
|
|
683
|
+
"'--dashboard' is deprecated in 1.3.0, and will be removed in 1.6.0, "
|
|
684
|
+
"Keep '--dashboard' value empty to allow auto-detection by MLRun API.",
|
|
685
|
+
# TODO: Remove in 1.6.0
|
|
686
|
+
FutureWarning,
|
|
687
|
+
)
|
|
688
|
+
|
|
672
689
|
try:
|
|
673
690
|
addr = function.deploy(project=project, tag=tag)
|
|
674
691
|
except Exception as err:
|
|
@@ -917,7 +934,9 @@ def version():
|
|
|
917
934
|
|
|
918
935
|
@main.command()
|
|
919
936
|
@click.argument("uid", type=str)
|
|
920
|
-
@click.option(
|
|
937
|
+
@click.option(
|
|
938
|
+
"--project", "-p", help="project name (defaults to mlrun.mlconf.default_project)"
|
|
939
|
+
)
|
|
921
940
|
@click.option("--offset", type=int, default=0, help="byte offset")
|
|
922
941
|
@click.option("--db", help="api and db service path/url")
|
|
923
942
|
@click.option("--watch", "-w", is_flag=True, help="watch/follow log")
|
|
@@ -1004,6 +1023,14 @@ def logs(uid, project, offset, db, watch):
|
|
|
1004
1023
|
"https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html#module-apscheduler.triggers.cron."
|
|
1005
1024
|
"For using the pre-defined workflow's schedule, set --schedule 'true'",
|
|
1006
1025
|
)
|
|
1026
|
+
# TODO: Remove in 1.6.0
|
|
1027
|
+
@click.option(
|
|
1028
|
+
"--overwrite-schedule",
|
|
1029
|
+
"-os",
|
|
1030
|
+
is_flag=True,
|
|
1031
|
+
help="Deprecated (Saving schedules is now an upsert opertaion)."
|
|
1032
|
+
" Overwrite a schedule when submitting a new one with the same name.",
|
|
1033
|
+
)
|
|
1007
1034
|
@click.option(
|
|
1008
1035
|
"--save-secrets",
|
|
1009
1036
|
is_flag=True,
|
|
@@ -1043,6 +1070,7 @@ def project(
|
|
|
1043
1070
|
timeout,
|
|
1044
1071
|
schedule,
|
|
1045
1072
|
notifications,
|
|
1073
|
+
overwrite_schedule,
|
|
1046
1074
|
save_secrets,
|
|
1047
1075
|
save,
|
|
1048
1076
|
):
|
|
@@ -1132,6 +1160,7 @@ def project(
|
|
|
1132
1160
|
local=local,
|
|
1133
1161
|
schedule=schedule,
|
|
1134
1162
|
timeout=timeout,
|
|
1163
|
+
overwrite=overwrite_schedule,
|
|
1135
1164
|
)
|
|
1136
1165
|
except Exception as err:
|
|
1137
1166
|
print(traceback.format_exc())
|
|
@@ -47,6 +47,7 @@ import mlrun.api.utils.singletons.project_member
|
|
|
47
47
|
import mlrun.common.model_monitoring
|
|
48
48
|
import mlrun.common.model_monitoring.helpers
|
|
49
49
|
import mlrun.common.schemas
|
|
50
|
+
import mlrun.common.schemas.model_monitoring.constants as mm_constants
|
|
50
51
|
from mlrun.api.api import deps
|
|
51
52
|
from mlrun.api.crud.secrets import Secrets, SecretsClientType
|
|
52
53
|
from mlrun.api.utils.builder import build_runtime
|
|
@@ -729,35 +730,31 @@ def _build_function(
|
|
|
729
730
|
launcher.enrich_runtime(runtime=fn, full=is_nuclio_runtime)
|
|
730
731
|
|
|
731
732
|
fn.save(versioned=False)
|
|
732
|
-
if
|
|
733
|
-
|
|
734
|
-
|
|
733
|
+
if fn.kind in RuntimeKinds.nuclio_runtimes():
|
|
734
|
+
mlrun.api.api.utils.apply_enrichment_and_validation_on_function(
|
|
735
|
+
fn,
|
|
736
|
+
auth_info,
|
|
737
|
+
)
|
|
738
|
+
monitoring_application = (
|
|
739
|
+
fn.metadata.labels.get(mm_constants.ModelMonitoringAppTag.KEY)
|
|
740
|
+
== mm_constants.ModelMonitoringAppTag.VAL
|
|
741
|
+
)
|
|
742
|
+
serving_to_monitor = (
|
|
743
|
+
fn.kind == RuntimeKinds.serving and fn.spec.track_models
|
|
744
|
+
)
|
|
745
|
+
if serving_to_monitor or monitoring_application:
|
|
735
746
|
try:
|
|
736
|
-
if
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
747
|
+
if not mlrun.mlconf.is_ce_mode():
|
|
748
|
+
model_monitoring_access_key = process_model_monitoring_secret(
|
|
749
|
+
db_session,
|
|
750
|
+
fn.metadata.project,
|
|
751
|
+
mlrun.common.schemas.model_monitoring.ProjectSecretKeys.ACCESS_KEY,
|
|
752
|
+
)
|
|
753
|
+
else:
|
|
740
754
|
model_monitoring_access_key = None
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
fn.metadata.project,
|
|
745
|
-
mlrun.common.schemas.model_monitoring.ProjectSecretKeys.ACCESS_KEY,
|
|
746
|
-
)
|
|
747
|
-
|
|
748
|
-
stream_path = (
|
|
749
|
-
mlrun.api.crud.model_monitoring.get_stream_path(
|
|
750
|
-
project=fn.metadata.project
|
|
751
|
-
)
|
|
752
|
-
)
|
|
753
|
-
|
|
754
|
-
if stream_path.startswith("v3io://"):
|
|
755
|
-
# Initialize model monitoring V3IO stream
|
|
756
|
-
_create_model_monitoring_stream(
|
|
757
|
-
project=fn.metadata.project,
|
|
758
|
-
function=fn,
|
|
759
|
-
stream_path=stream_path,
|
|
760
|
-
)
|
|
755
|
+
if serving_to_monitor:
|
|
756
|
+
# Handle model monitoring
|
|
757
|
+
logger.info("Tracking enabled, initializing model monitoring")
|
|
761
758
|
|
|
762
759
|
if fn.spec.tracking_policy:
|
|
763
760
|
# Convert to `TrackingPolicy` object as `fn.spec.tracking_policy` is provided as a dict
|
|
@@ -768,7 +765,32 @@ def _build_function(
|
|
|
768
765
|
# Initialize tracking policy with default values
|
|
769
766
|
fn.spec.tracking_policy = TrackingPolicy()
|
|
770
767
|
|
|
771
|
-
|
|
768
|
+
if not mlrun.mlconf.is_ce_mode():
|
|
769
|
+
# create v3io stream for model_monitoring_stream
|
|
770
|
+
_create_model_monitoring_stream(
|
|
771
|
+
project=fn.metadata.project,
|
|
772
|
+
function=fn,
|
|
773
|
+
monitoring_application=monitoring_application,
|
|
774
|
+
stream_path=mlrun.api.crud.model_monitoring.get_stream_path(
|
|
775
|
+
project=fn.metadata.project,
|
|
776
|
+
application_name=mm_constants.MonitoringFunctionNames.STREAM,
|
|
777
|
+
),
|
|
778
|
+
)
|
|
779
|
+
if fn.spec.tracking_policy.application_batch:
|
|
780
|
+
# create v3io stream for model_monitoring_writer | model monitoring application
|
|
781
|
+
_create_model_monitoring_stream(
|
|
782
|
+
project=fn.metadata.project,
|
|
783
|
+
function=fn,
|
|
784
|
+
monitoring_application=monitoring_application,
|
|
785
|
+
stream_path=mlrun.api.crud.model_monitoring.get_stream_path(
|
|
786
|
+
project=fn.metadata.project,
|
|
787
|
+
application_name=mm_constants.MonitoringFunctionNames.WRITER,
|
|
788
|
+
),
|
|
789
|
+
access_key=model_monitoring_access_key,
|
|
790
|
+
)
|
|
791
|
+
|
|
792
|
+
# deploy model monitoring stream, model monitoring batch job,
|
|
793
|
+
# model monitoring batch application job and model monitoring writer
|
|
772
794
|
mlrun.api.crud.model_monitoring.deployment.MonitoringDeployment().deploy_monitoring_functions(
|
|
773
795
|
project=fn.metadata.project,
|
|
774
796
|
db_session=db_session,
|
|
@@ -776,9 +798,32 @@ def _build_function(
|
|
|
776
798
|
tracking_policy=fn.spec.tracking_policy,
|
|
777
799
|
model_monitoring_access_key=model_monitoring_access_key,
|
|
778
800
|
)
|
|
801
|
+
|
|
802
|
+
if monitoring_application:
|
|
803
|
+
if not mlrun.mlconf.is_ce_mode():
|
|
804
|
+
# create v3io stream for model monitoring application
|
|
805
|
+
_create_model_monitoring_stream(
|
|
806
|
+
project=fn.metadata.project,
|
|
807
|
+
function=fn,
|
|
808
|
+
monitoring_application=monitoring_application,
|
|
809
|
+
stream_path=mlrun.api.crud.model_monitoring.get_stream_path(
|
|
810
|
+
project=fn.metadata.project,
|
|
811
|
+
application_name=fn.metadata.name,
|
|
812
|
+
),
|
|
813
|
+
access_key=model_monitoring_access_key,
|
|
814
|
+
)
|
|
815
|
+
# apply stream trigger to monitoring application
|
|
816
|
+
fn = mlrun.api.crud.model_monitoring.deployment.MonitoringDeployment()._apply_stream_trigger(
|
|
817
|
+
project=fn.metadata.project,
|
|
818
|
+
function=fn,
|
|
819
|
+
model_monitoring_access_key=model_monitoring_access_key,
|
|
820
|
+
function_name=fn.metadata.name,
|
|
821
|
+
auth_info=auth_info,
|
|
822
|
+
)
|
|
779
823
|
except Exception as exc:
|
|
780
824
|
logger.warning(
|
|
781
|
-
"Failed deploying model monitoring infrastructure for the
|
|
825
|
+
f"Failed deploying model monitoring infrastructure for the "
|
|
826
|
+
f"{'project' if serving_to_monitor else f'{fn.metadata.name} application'}",
|
|
782
827
|
project=fn.metadata.project,
|
|
783
828
|
exc=exc,
|
|
784
829
|
traceback=traceback.format_exc(),
|
|
@@ -915,33 +960,46 @@ async def _get_function_status(data, auth_info: mlrun.common.schemas.AuthInfo):
|
|
|
915
960
|
)
|
|
916
961
|
|
|
917
962
|
|
|
918
|
-
def _create_model_monitoring_stream(
|
|
919
|
-
|
|
963
|
+
def _create_model_monitoring_stream(
|
|
964
|
+
project: str,
|
|
965
|
+
function,
|
|
966
|
+
monitoring_application: bool,
|
|
967
|
+
stream_path: str,
|
|
968
|
+
access_key: str = None,
|
|
969
|
+
):
|
|
970
|
+
if stream_path.startswith("v3io://"):
|
|
971
|
+
_init_serving_function_stream_args(fn=function)
|
|
920
972
|
|
|
921
|
-
|
|
973
|
+
_, container, stream_path = parse_model_endpoint_store_prefix(stream_path)
|
|
922
974
|
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
975
|
+
# TODO: How should we configure sharding here?
|
|
976
|
+
logger.info(
|
|
977
|
+
"Creating model endpoint stream for project",
|
|
978
|
+
project=project,
|
|
979
|
+
stream_path=stream_path,
|
|
980
|
+
container=container,
|
|
981
|
+
endpoint=config.v3io_api,
|
|
982
|
+
)
|
|
931
983
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
984
|
+
v3io_client = v3io.dataplane.Client(
|
|
985
|
+
endpoint=config.v3io_api, access_key=os.environ.get("V3IO_ACCESS_KEY")
|
|
986
|
+
)
|
|
987
|
+
stream_args = (
|
|
988
|
+
config.model_endpoint_monitoring.application_stream_args
|
|
989
|
+
if monitoring_application
|
|
990
|
+
else config.model_endpoint_monitoring.serving_stream_args
|
|
991
|
+
)
|
|
992
|
+
response = v3io_client.create_stream(
|
|
993
|
+
container=container,
|
|
994
|
+
path=stream_path,
|
|
995
|
+
shard_count=stream_args.shard_count,
|
|
996
|
+
retention_period_hours=stream_args.retention_period_hours,
|
|
997
|
+
raise_for_status=v3io.dataplane.RaiseForStatus.never,
|
|
998
|
+
access_key=access_key,
|
|
999
|
+
)
|
|
942
1000
|
|
|
943
|
-
|
|
944
|
-
|
|
1001
|
+
if not (response.status_code == 400 and "ResourceInUse" in str(response.body)):
|
|
1002
|
+
response.raise_for_status([409, 204])
|
|
945
1003
|
|
|
946
1004
|
|
|
947
1005
|
def _init_serving_function_stream_args(fn: ServingRuntime):
|