oracle-ads 2.11.14__py3-none-any.whl → 2.11.16__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.
- ads/aqua/common/entities.py +17 -0
- ads/aqua/common/enums.py +5 -1
- ads/aqua/common/utils.py +109 -22
- ads/aqua/config/config.py +1 -1
- ads/aqua/config/deployment_config_defaults.json +29 -1
- ads/aqua/config/resource_limit_names.json +1 -0
- ads/aqua/constants.py +35 -18
- ads/aqua/evaluation/entities.py +0 -1
- ads/aqua/evaluation/evaluation.py +165 -121
- ads/aqua/extension/common_ws_msg_handler.py +57 -0
- ads/aqua/extension/deployment_handler.py +14 -13
- ads/aqua/extension/deployment_ws_msg_handler.py +54 -0
- ads/aqua/extension/errors.py +1 -1
- ads/aqua/extension/evaluation_handler.py +4 -7
- ads/aqua/extension/evaluation_ws_msg_handler.py +28 -10
- ads/aqua/extension/model_handler.py +31 -6
- ads/aqua/extension/models/ws_models.py +78 -3
- ads/aqua/extension/models_ws_msg_handler.py +49 -0
- ads/aqua/extension/ui_websocket_handler.py +7 -1
- ads/aqua/model/entities.py +17 -9
- ads/aqua/model/model.py +260 -90
- ads/aqua/modeldeployment/constants.py +0 -16
- ads/aqua/modeldeployment/deployment.py +97 -74
- ads/aqua/modeldeployment/entities.py +9 -20
- ads/aqua/ui.py +152 -28
- ads/common/object_storage_details.py +2 -5
- ads/common/serializer.py +2 -3
- ads/jobs/builders/infrastructure/dsc_job.py +29 -3
- ads/jobs/builders/infrastructure/dsc_job_runtime.py +74 -27
- ads/jobs/builders/runtimes/container_runtime.py +83 -4
- ads/opctl/operator/common/operator_config.py +1 -0
- ads/opctl/operator/lowcode/anomaly/README.md +3 -3
- ads/opctl/operator/lowcode/anomaly/__main__.py +5 -6
- ads/opctl/operator/lowcode/anomaly/const.py +9 -0
- ads/opctl/operator/lowcode/anomaly/model/anomaly_dataset.py +6 -2
- ads/opctl/operator/lowcode/anomaly/model/base_model.py +51 -26
- ads/opctl/operator/lowcode/anomaly/model/factory.py +41 -13
- ads/opctl/operator/lowcode/anomaly/model/isolationforest.py +79 -0
- ads/opctl/operator/lowcode/anomaly/model/oneclasssvm.py +79 -0
- ads/opctl/operator/lowcode/anomaly/operator_config.py +1 -0
- ads/opctl/operator/lowcode/anomaly/schema.yaml +16 -2
- ads/opctl/operator/lowcode/anomaly/utils.py +16 -13
- ads/opctl/operator/lowcode/common/data.py +2 -1
- ads/opctl/operator/lowcode/common/errors.py +6 -0
- ads/opctl/operator/lowcode/common/transformations.py +37 -9
- ads/opctl/operator/lowcode/common/utils.py +32 -10
- ads/opctl/operator/lowcode/forecast/model/base_model.py +21 -13
- ads/opctl/operator/lowcode/forecast/model/ml_forecast.py +14 -18
- ads/opctl/operator/lowcode/forecast/model_evaluator.py +15 -4
- ads/opctl/operator/lowcode/forecast/schema.yaml +9 -0
- ads/opctl/operator/lowcode/recommender/MLoperator +16 -0
- ads/opctl/operator/lowcode/recommender/README.md +206 -0
- ads/opctl/operator/lowcode/recommender/__init__.py +5 -0
- ads/opctl/operator/lowcode/recommender/__main__.py +82 -0
- ads/opctl/operator/lowcode/recommender/cmd.py +33 -0
- ads/opctl/operator/lowcode/recommender/constant.py +25 -0
- ads/opctl/operator/lowcode/recommender/environment.yaml +11 -0
- ads/opctl/operator/lowcode/recommender/model/base_model.py +198 -0
- ads/opctl/operator/lowcode/recommender/model/factory.py +58 -0
- ads/opctl/operator/lowcode/recommender/model/recommender_dataset.py +25 -0
- ads/opctl/operator/lowcode/recommender/model/svd.py +88 -0
- ads/opctl/operator/lowcode/recommender/operator_config.py +81 -0
- ads/opctl/operator/lowcode/recommender/schema.yaml +265 -0
- ads/opctl/operator/lowcode/recommender/utils.py +13 -0
- ads/pipeline/ads_pipeline_run.py +13 -2
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/METADATA +6 -1
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/RECORD +70 -50
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/LICENSE.txt +0 -0
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/WHEEL +0 -0
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
# Copyright (c) 2024 Oracle and/or its affiliates.
|
4
3
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
4
|
|
@@ -8,8 +7,8 @@ from urllib.parse import urlparse
|
|
8
7
|
from tornado.web import HTTPError
|
9
8
|
|
10
9
|
from ads.aqua.common.decorator import handle_exceptions
|
11
|
-
from ads.aqua.extension.errors import Errors
|
12
10
|
from ads.aqua.extension.base_handler import AquaAPIhandler
|
11
|
+
from ads.aqua.extension.errors import Errors
|
13
12
|
from ads.aqua.modeldeployment import AquaDeploymentApp, MDInferenceResponse
|
14
13
|
from ads.aqua.modeldeployment.entities import ModelParams
|
15
14
|
from ads.config import COMPARTMENT_OCID, PROJECT_OCID
|
@@ -66,8 +65,8 @@ class AquaDeploymentHandler(AquaAPIhandler):
|
|
66
65
|
"""
|
67
66
|
try:
|
68
67
|
input_data = self.get_json_body()
|
69
|
-
except Exception:
|
70
|
-
raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
|
68
|
+
except Exception as ex:
|
69
|
+
raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
|
71
70
|
|
72
71
|
if not input_data:
|
73
72
|
raise HTTPError(400, Errors.NO_INPUT_DATA)
|
@@ -100,6 +99,8 @@ class AquaDeploymentHandler(AquaAPIhandler):
|
|
100
99
|
health_check_port = input_data.get("health_check_port")
|
101
100
|
env_var = input_data.get("env_var")
|
102
101
|
container_family = input_data.get("container_family")
|
102
|
+
ocpus = input_data.get("ocpus")
|
103
|
+
memory_in_gbs = input_data.get("memory_in_gbs")
|
103
104
|
|
104
105
|
self.finish(
|
105
106
|
AquaDeploymentApp().create(
|
@@ -119,6 +120,8 @@ class AquaDeploymentHandler(AquaAPIhandler):
|
|
119
120
|
health_check_port=health_check_port,
|
120
121
|
env_var=env_var,
|
121
122
|
container_family=container_family,
|
123
|
+
ocpus=ocpus,
|
124
|
+
memory_in_gbs=memory_in_gbs,
|
122
125
|
)
|
123
126
|
)
|
124
127
|
|
@@ -153,9 +156,7 @@ class AquaDeploymentInferenceHandler(AquaAPIhandler):
|
|
153
156
|
return False
|
154
157
|
if not url.netloc:
|
155
158
|
return False
|
156
|
-
|
157
|
-
return False
|
158
|
-
return True
|
159
|
+
return url.path.endswith("/predict")
|
159
160
|
except Exception:
|
160
161
|
return False
|
161
162
|
|
@@ -170,8 +171,8 @@ class AquaDeploymentInferenceHandler(AquaAPIhandler):
|
|
170
171
|
"""
|
171
172
|
try:
|
172
173
|
input_data = self.get_json_body()
|
173
|
-
except Exception:
|
174
|
-
raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
|
174
|
+
except Exception as ex:
|
175
|
+
raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
|
175
176
|
|
176
177
|
if not input_data:
|
177
178
|
raise HTTPError(400, Errors.NO_INPUT_DATA)
|
@@ -192,10 +193,10 @@ class AquaDeploymentInferenceHandler(AquaAPIhandler):
|
|
192
193
|
)
|
193
194
|
try:
|
194
195
|
model_params_obj = ModelParams(**model_params)
|
195
|
-
except:
|
196
|
+
except Exception as ex:
|
196
197
|
raise HTTPError(
|
197
198
|
400, Errors.INVALID_INPUT_DATA_FORMAT.format("model_params")
|
198
|
-
)
|
199
|
+
) from ex
|
199
200
|
|
200
201
|
return self.finish(
|
201
202
|
MDInferenceResponse(prompt, model_params_obj).get_model_deployment_response(
|
@@ -236,8 +237,8 @@ class AquaDeploymentParamsHandler(AquaAPIhandler):
|
|
236
237
|
"""
|
237
238
|
try:
|
238
239
|
input_data = self.get_json_body()
|
239
|
-
except Exception:
|
240
|
-
raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
|
240
|
+
except Exception as ex:
|
241
|
+
raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
|
241
242
|
|
242
243
|
if not input_data:
|
243
244
|
raise HTTPError(400, Errors.NO_INPUT_DATA)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
# Copyright (c) 2024 Oracle and/or its affiliates.
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
|
+
|
6
|
+
import json
|
7
|
+
from typing import List, Union
|
8
|
+
|
9
|
+
from ads.aqua.common.decorator import handle_exceptions
|
10
|
+
from ads.aqua.extension.aqua_ws_msg_handler import AquaWSMsgHandler
|
11
|
+
from ads.aqua.extension.models.ws_models import (
|
12
|
+
ListDeploymentResponse,
|
13
|
+
ModelDeploymentDetailsResponse,
|
14
|
+
RequestResponseType,
|
15
|
+
)
|
16
|
+
from ads.aqua.modeldeployment import AquaDeploymentApp
|
17
|
+
from ads.config import COMPARTMENT_OCID
|
18
|
+
|
19
|
+
|
20
|
+
class AquaDeploymentWSMsgHandler(AquaWSMsgHandler):
|
21
|
+
def __init__(self, message: Union[str, bytes]):
|
22
|
+
super().__init__(message)
|
23
|
+
|
24
|
+
@staticmethod
|
25
|
+
def get_message_types() -> List[RequestResponseType]:
|
26
|
+
return [
|
27
|
+
RequestResponseType.ListDeployments,
|
28
|
+
RequestResponseType.DeploymentDetails,
|
29
|
+
]
|
30
|
+
|
31
|
+
@handle_exceptions
|
32
|
+
def process(self) -> Union[ListDeploymentResponse, ModelDeploymentDetailsResponse]:
|
33
|
+
request = json.loads(self.message)
|
34
|
+
if request.get("kind") == "ListDeployments":
|
35
|
+
deployment_list = AquaDeploymentApp().list(
|
36
|
+
compartment_id=request.get("compartment_id") or COMPARTMENT_OCID,
|
37
|
+
project_id=request.get("project_id"),
|
38
|
+
)
|
39
|
+
response = ListDeploymentResponse(
|
40
|
+
message_id=request.get("message_id"),
|
41
|
+
kind=RequestResponseType.ListDeployments,
|
42
|
+
data=deployment_list,
|
43
|
+
)
|
44
|
+
return response
|
45
|
+
elif request.get("kind") == "DeploymentDetails":
|
46
|
+
deployment_details = AquaDeploymentApp().get(
|
47
|
+
request.get("model_deployment_id")
|
48
|
+
)
|
49
|
+
response = ModelDeploymentDetailsResponse(
|
50
|
+
message_id=request.get("message_id"),
|
51
|
+
kind=RequestResponseType.DeploymentDetails,
|
52
|
+
data=deployment_details,
|
53
|
+
)
|
54
|
+
return response
|
ads/aqua/extension/errors.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
# Copyright (c) 2024 Oracle and/or its affiliates.
|
4
3
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
4
|
|
@@ -8,3 +7,4 @@ class Errors(str):
|
|
8
7
|
INVALID_INPUT_DATA_FORMAT = "Invalid format of input data."
|
9
8
|
NO_INPUT_DATA = "No input data provided."
|
10
9
|
MISSING_REQUIRED_PARAMETER = "Missing required parameter: '{}'"
|
10
|
+
MISSING_ONEOF_REQUIRED_PARAMETER = "Either '{}' or '{}' is required."
|
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
# Copyright (c) 2024 Oracle and/or its affiliates.
|
4
3
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
4
|
|
@@ -10,8 +9,8 @@ from tornado.web import HTTPError
|
|
10
9
|
from ads.aqua.common.decorator import handle_exceptions
|
11
10
|
from ads.aqua.evaluation import AquaEvaluationApp
|
12
11
|
from ads.aqua.evaluation.entities import CreateAquaEvaluationDetails
|
13
|
-
from ads.aqua.extension.errors import Errors
|
14
12
|
from ads.aqua.extension.base_handler import AquaAPIhandler
|
13
|
+
from ads.aqua.extension.errors import Errors
|
15
14
|
from ads.aqua.extension.utils import validate_function_parameters
|
16
15
|
from ads.config import COMPARTMENT_OCID
|
17
16
|
|
@@ -41,8 +40,8 @@ class AquaEvaluationHandler(AquaAPIhandler):
|
|
41
40
|
"""
|
42
41
|
try:
|
43
42
|
input_data = self.get_json_body()
|
44
|
-
except Exception:
|
45
|
-
raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
|
43
|
+
except Exception as ex:
|
44
|
+
raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
|
46
45
|
|
47
46
|
if not input_data:
|
48
47
|
raise HTTPError(400, Errors.NO_INPUT_DATA)
|
@@ -77,9 +76,7 @@ class AquaEvaluationHandler(AquaAPIhandler):
|
|
77
76
|
def list(self):
|
78
77
|
"""List Aqua models."""
|
79
78
|
compartment_id = self.get_argument("compartment_id", default=COMPARTMENT_OCID)
|
80
|
-
|
81
|
-
project_id = self.get_argument("project_id", default=None)
|
82
|
-
return self.finish(AquaEvaluationApp().list(compartment_id, project_id))
|
79
|
+
return self.finish(AquaEvaluationApp().list(compartment_id))
|
83
80
|
|
84
81
|
def get_default_metrics(self):
|
85
82
|
"""Lists supported metrics for evaluation."""
|
@@ -1,18 +1,16 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*--
|
3
2
|
|
4
3
|
# Copyright (c) 2024 Oracle and/or its affiliates.
|
5
4
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
6
5
|
|
6
|
+
import json
|
7
7
|
from typing import List, Union
|
8
8
|
|
9
|
-
from tornado.web import HTTPError
|
10
|
-
|
11
9
|
from ads.aqua.common.decorator import handle_exceptions
|
12
10
|
from ads.aqua.evaluation import AquaEvaluationApp
|
13
11
|
from ads.aqua.extension.aqua_ws_msg_handler import AquaWSMsgHandler
|
14
12
|
from ads.aqua.extension.models.ws_models import (
|
15
|
-
|
13
|
+
EvaluationDetailsResponse,
|
16
14
|
ListEvaluationsResponse,
|
17
15
|
RequestResponseType,
|
18
16
|
)
|
@@ -22,22 +20,42 @@ from ads.config import COMPARTMENT_OCID
|
|
22
20
|
class AquaEvaluationWSMsgHandler(AquaWSMsgHandler):
|
23
21
|
@staticmethod
|
24
22
|
def get_message_types() -> List[RequestResponseType]:
|
25
|
-
return [
|
23
|
+
return [
|
24
|
+
RequestResponseType.ListEvaluations,
|
25
|
+
RequestResponseType.EvaluationDetails,
|
26
|
+
]
|
26
27
|
|
27
28
|
def __init__(self, message: Union[str, bytes]):
|
28
29
|
super().__init__(message)
|
29
30
|
|
30
31
|
@handle_exceptions
|
31
|
-
def process(self) -> ListEvaluationsResponse:
|
32
|
-
|
32
|
+
def process(self) -> Union[ListEvaluationsResponse, EvaluationDetailsResponse]:
|
33
|
+
request = json.loads(self.message)
|
34
|
+
if request["kind"] == "ListEvaluations":
|
35
|
+
return self.list_evaluations(request)
|
36
|
+
if request["kind"] == "EvaluationDetails":
|
37
|
+
return self.evaluation_details(request)
|
33
38
|
|
39
|
+
@staticmethod
|
40
|
+
def list_evaluations(request) -> ListEvaluationsResponse:
|
34
41
|
eval_list = AquaEvaluationApp().list(
|
35
|
-
|
36
|
-
list_eval_request.project_id,
|
42
|
+
request.get("compartment_id") or COMPARTMENT_OCID
|
37
43
|
)
|
38
44
|
response = ListEvaluationsResponse(
|
39
|
-
message_id=
|
45
|
+
message_id=request["message_id"],
|
40
46
|
kind=RequestResponseType.ListEvaluations,
|
41
47
|
data=eval_list,
|
42
48
|
)
|
43
49
|
return response
|
50
|
+
|
51
|
+
@staticmethod
|
52
|
+
def evaluation_details(request) -> EvaluationDetailsResponse:
|
53
|
+
evaluation_details = AquaEvaluationApp().get(
|
54
|
+
eval_id=request.get("evaluation_id")
|
55
|
+
)
|
56
|
+
response = EvaluationDetailsResponse(
|
57
|
+
message_id=request.get("message_id"),
|
58
|
+
kind=RequestResponseType.EvaluationDetails,
|
59
|
+
data=evaluation_details,
|
60
|
+
)
|
61
|
+
return response
|
@@ -1,27 +1,50 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
# Copyright (c) 2024 Oracle and/or its affiliates.
|
4
3
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
4
|
|
6
|
-
import re
|
7
|
-
from typing import Optional
|
8
5
|
from urllib.parse import urlparse
|
9
6
|
|
10
7
|
from tornado.web import HTTPError
|
11
|
-
|
8
|
+
|
12
9
|
from ads.aqua.common.decorator import handle_exceptions
|
10
|
+
from ads.aqua.common.errors import AquaValueError
|
13
11
|
from ads.aqua.extension.base_handler import AquaAPIhandler
|
12
|
+
from ads.aqua.extension.errors import Errors
|
14
13
|
from ads.aqua.model import AquaModelApp
|
14
|
+
from ads.aqua.ui import ModelFormat
|
15
15
|
|
16
16
|
|
17
17
|
class AquaModelHandler(AquaAPIhandler):
|
18
18
|
"""Handler for Aqua Model REST APIs."""
|
19
19
|
|
20
20
|
@handle_exceptions
|
21
|
-
def get(
|
21
|
+
def get(
|
22
|
+
self,
|
23
|
+
model_id="",
|
24
|
+
):
|
22
25
|
"""Handle GET request."""
|
23
|
-
|
26
|
+
url_parse = urlparse(self.request.path)
|
27
|
+
paths = url_parse.path.strip("/")
|
28
|
+
if paths.startswith("aqua/model/files"):
|
29
|
+
os_path = self.get_argument("os_path")
|
30
|
+
if not os_path:
|
31
|
+
raise HTTPError(
|
32
|
+
400, Errors.MISSING_REQUIRED_PARAMETER.format("os_path")
|
33
|
+
)
|
34
|
+
model_format = self.get_argument("model_format")
|
35
|
+
if not model_format:
|
36
|
+
raise HTTPError(
|
37
|
+
400, Errors.MISSING_REQUIRED_PARAMETER.format("model_format")
|
38
|
+
)
|
39
|
+
try:
|
40
|
+
model_format = ModelFormat(model_format.upper())
|
41
|
+
except ValueError:
|
42
|
+
raise AquaValueError(f"Invalid model format: {model_format}")
|
43
|
+
else:
|
44
|
+
return self.finish(AquaModelApp.get_model_files(os_path, model_format))
|
45
|
+
elif not model_id:
|
24
46
|
return self.list()
|
47
|
+
|
25
48
|
return self.read(model_id)
|
26
49
|
|
27
50
|
def read(self, model_id):
|
@@ -81,6 +104,7 @@ class AquaModelHandler(AquaAPIhandler):
|
|
81
104
|
finetuning_container = input_data.get("finetuning_container")
|
82
105
|
compartment_id = input_data.get("compartment_id")
|
83
106
|
project_id = input_data.get("project_id")
|
107
|
+
model_file = input_data.get("model_file")
|
84
108
|
|
85
109
|
return self.finish(
|
86
110
|
AquaModelApp().register(
|
@@ -90,6 +114,7 @@ class AquaModelHandler(AquaAPIhandler):
|
|
90
114
|
finetuning_container=finetuning_container,
|
91
115
|
compartment_id=compartment_id,
|
92
116
|
project_id=project_id,
|
117
|
+
model_file=model_file,
|
93
118
|
)
|
94
119
|
)
|
95
120
|
|
@@ -7,15 +7,22 @@
|
|
7
7
|
from dataclasses import dataclass
|
8
8
|
from typing import List, Optional
|
9
9
|
|
10
|
-
from ads.aqua.evaluation.entities import AquaEvaluationSummary
|
11
|
-
from ads.aqua.model.entities import AquaModelSummary
|
10
|
+
from ads.aqua.evaluation.entities import AquaEvaluationSummary, AquaEvaluationDetail
|
11
|
+
from ads.aqua.model.entities import AquaModelSummary, AquaModel
|
12
|
+
from ads.aqua.modeldeployment.entities import AquaDeployment, AquaDeploymentDetail
|
12
13
|
from ads.common.extended_enum import ExtendedEnumMeta
|
13
14
|
from ads.common.serializer import DataClassSerializable
|
14
15
|
|
15
16
|
|
16
17
|
class RequestResponseType(str, metaclass=ExtendedEnumMeta):
|
17
18
|
ListEvaluations = "ListEvaluations"
|
19
|
+
EvaluationDetails = "EvaluationDetails"
|
20
|
+
ListDeployments = "ListDeployments"
|
21
|
+
DeploymentDetails = "DeploymentDetails"
|
18
22
|
ListModels = "ListModels"
|
23
|
+
ModelDetails = "ModelDetails"
|
24
|
+
AdsVersion = "AdsVersion"
|
25
|
+
CompatibilityCheck = "CompatibilityCheck"
|
19
26
|
Error = "Error"
|
20
27
|
|
21
28
|
|
@@ -23,7 +30,7 @@ class RequestResponseType(str, metaclass=ExtendedEnumMeta):
|
|
23
30
|
class BaseResponse(DataClassSerializable):
|
24
31
|
message_id: str
|
25
32
|
kind: RequestResponseType
|
26
|
-
data: object
|
33
|
+
data: Optional[object]
|
27
34
|
|
28
35
|
|
29
36
|
@dataclass
|
@@ -40,9 +47,37 @@ class ListEvaluationsRequest(BaseRequest):
|
|
40
47
|
kind = RequestResponseType.ListEvaluations
|
41
48
|
|
42
49
|
|
50
|
+
@dataclass
|
51
|
+
class EvaluationDetailsRequest(BaseRequest):
|
52
|
+
kind = RequestResponseType.EvaluationDetails
|
53
|
+
evaluation_id: str
|
54
|
+
|
55
|
+
|
43
56
|
@dataclass
|
44
57
|
class ListModelsRequest(BaseRequest):
|
45
58
|
compartment_id: Optional[str] = None
|
59
|
+
project_id: Optional[str] = None
|
60
|
+
model_type: Optional[str] = None
|
61
|
+
kind = RequestResponseType.ListDeployments
|
62
|
+
|
63
|
+
|
64
|
+
@dataclass
|
65
|
+
class ModelDetailsRequest(BaseRequest):
|
66
|
+
kind = RequestResponseType.ModelDetails
|
67
|
+
model_id: str
|
68
|
+
|
69
|
+
|
70
|
+
@dataclass
|
71
|
+
class ListDeploymentRequest(BaseRequest):
|
72
|
+
compartment_id: str
|
73
|
+
project_id: Optional[str] = None
|
74
|
+
kind = RequestResponseType.ListDeployments
|
75
|
+
|
76
|
+
|
77
|
+
@dataclass
|
78
|
+
class DeploymentDetailsRequest(BaseRequest):
|
79
|
+
model_deployment_id: str
|
80
|
+
kind = RequestResponseType.DeploymentDetails
|
46
81
|
|
47
82
|
|
48
83
|
@dataclass
|
@@ -50,11 +85,51 @@ class ListEvaluationsResponse(BaseResponse):
|
|
50
85
|
data: List[AquaEvaluationSummary]
|
51
86
|
|
52
87
|
|
88
|
+
@dataclass
|
89
|
+
class EvaluationDetailsResponse(BaseResponse):
|
90
|
+
data: AquaEvaluationDetail
|
91
|
+
|
92
|
+
|
93
|
+
@dataclass
|
94
|
+
class ListDeploymentResponse(BaseResponse):
|
95
|
+
data: List[AquaDeployment]
|
96
|
+
|
97
|
+
|
98
|
+
@dataclass
|
99
|
+
class ModelDeploymentDetailsResponse(BaseResponse):
|
100
|
+
data: AquaDeploymentDetail
|
101
|
+
|
102
|
+
|
53
103
|
@dataclass
|
54
104
|
class ListModelsResponse(BaseResponse):
|
55
105
|
data: List[AquaModelSummary]
|
56
106
|
|
57
107
|
|
108
|
+
@dataclass
|
109
|
+
class ModelDetailsResponse(BaseResponse):
|
110
|
+
data: AquaModel
|
111
|
+
|
112
|
+
|
113
|
+
@dataclass
|
114
|
+
class AdsVersionRequest(BaseRequest):
|
115
|
+
kind: RequestResponseType.AdsVersion
|
116
|
+
|
117
|
+
|
118
|
+
@dataclass
|
119
|
+
class AdsVersionResponse(BaseResponse):
|
120
|
+
data: str
|
121
|
+
|
122
|
+
|
123
|
+
@dataclass
|
124
|
+
class CompatibilityCheckRequest(BaseRequest):
|
125
|
+
kind: RequestResponseType.CompatibilityCheck
|
126
|
+
|
127
|
+
|
128
|
+
@dataclass
|
129
|
+
class CompatibilityCheckResponse(BaseResponse):
|
130
|
+
data: object
|
131
|
+
|
132
|
+
|
58
133
|
@dataclass
|
59
134
|
class AquaWsError(DataClassSerializable):
|
60
135
|
status: str
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
# Copyright (c) 2024 Oracle and/or its affiliates.
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
|
+
|
6
|
+
import json
|
7
|
+
from typing import List, Union
|
8
|
+
|
9
|
+
from ads.aqua.common.decorator import handle_exceptions
|
10
|
+
from ads.aqua.extension.aqua_ws_msg_handler import AquaWSMsgHandler
|
11
|
+
from ads.aqua.extension.models.ws_models import (
|
12
|
+
ListModelsResponse,
|
13
|
+
ModelDetailsResponse,
|
14
|
+
RequestResponseType,
|
15
|
+
)
|
16
|
+
from ads.aqua.model import AquaModelApp
|
17
|
+
|
18
|
+
|
19
|
+
class AquaModelWSMsgHandler(AquaWSMsgHandler):
|
20
|
+
def __init__(self, message: Union[str, bytes]):
|
21
|
+
super().__init__(message)
|
22
|
+
|
23
|
+
@staticmethod
|
24
|
+
def get_message_types() -> List[RequestResponseType]:
|
25
|
+
return [RequestResponseType.ListModels, RequestResponseType.ModelDetails]
|
26
|
+
|
27
|
+
@handle_exceptions
|
28
|
+
def process(self) -> Union[ListModelsResponse, ModelDetailsResponse]:
|
29
|
+
request = json.loads(self.message)
|
30
|
+
if request.get("kind") == "ListModels":
|
31
|
+
models_list = AquaModelApp().list(
|
32
|
+
compartment_id=request.get("compartment_id"),
|
33
|
+
project_id=request.get("project_id"),
|
34
|
+
model_type=request.get("model_type"),
|
35
|
+
)
|
36
|
+
response = ListModelsResponse(
|
37
|
+
message_id=request.get("message_id"),
|
38
|
+
kind=RequestResponseType.ListModels,
|
39
|
+
data=models_list,
|
40
|
+
)
|
41
|
+
return response
|
42
|
+
elif request.get("kind") == "ModelDetails":
|
43
|
+
model_id = request.get("model_id")
|
44
|
+
response = AquaModelApp().get(model_id)
|
45
|
+
return ModelDetailsResponse(
|
46
|
+
message_id=request.get("message_id"),
|
47
|
+
kind=RequestResponseType.ModelDetails,
|
48
|
+
data=response,
|
49
|
+
)
|
@@ -14,6 +14,8 @@ from tornado.websocket import WebSocketHandler
|
|
14
14
|
|
15
15
|
from ads.aqua import logger
|
16
16
|
from ads.aqua.extension.aqua_ws_msg_handler import AquaWSMsgHandler
|
17
|
+
from ads.aqua.extension.common_ws_msg_handler import AquaCommonWsMsgHandler
|
18
|
+
from ads.aqua.extension.deployment_ws_msg_handler import AquaDeploymentWSMsgHandler
|
17
19
|
from ads.aqua.extension.evaluation_ws_msg_handler import AquaEvaluationWSMsgHandler
|
18
20
|
from ads.aqua.extension.models.ws_models import (
|
19
21
|
AquaWsError,
|
@@ -22,6 +24,7 @@ from ads.aqua.extension.models.ws_models import (
|
|
22
24
|
ErrorResponse,
|
23
25
|
RequestResponseType,
|
24
26
|
)
|
27
|
+
from ads.aqua.extension.models_ws_msg_handler import AquaModelWSMsgHandler
|
25
28
|
|
26
29
|
MAX_WORKERS = 20
|
27
30
|
|
@@ -43,7 +46,10 @@ def get_aqua_internal_error_response(message_id: str) -> ErrorResponse:
|
|
43
46
|
class AquaUIWebSocketHandler(WebSocketHandler):
|
44
47
|
"""Handler for Aqua Websocket."""
|
45
48
|
|
46
|
-
_handlers_: List[Type[AquaWSMsgHandler]] = [AquaEvaluationWSMsgHandler
|
49
|
+
_handlers_: List[Type[AquaWSMsgHandler]] = [AquaEvaluationWSMsgHandler,
|
50
|
+
AquaDeploymentWSMsgHandler,
|
51
|
+
AquaModelWSMsgHandler,
|
52
|
+
AquaCommonWsMsgHandler]
|
47
53
|
|
48
54
|
thread_pool: ThreadPoolExecutor
|
49
55
|
|
ads/aqua/model/entities.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
# Copyright (c) 2024 Oracle and/or its affiliates.
|
4
3
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
4
|
|
@@ -9,19 +8,20 @@ aqua.model.entities
|
|
9
8
|
|
10
9
|
This module contains dataclasses for Aqua Model.
|
11
10
|
"""
|
11
|
+
|
12
12
|
import re
|
13
13
|
from dataclasses import InitVar, dataclass, field
|
14
14
|
from typing import List, Optional
|
15
15
|
|
16
16
|
import oci
|
17
|
-
|
18
17
|
from ads.aqua import logger
|
19
18
|
from ads.aqua.app import CLIBuilderMixin
|
20
19
|
from ads.aqua.common import utils
|
21
|
-
from ads.aqua.constants import UNKNOWN_VALUE
|
20
|
+
from ads.aqua.constants import LIFECYCLE_DETAILS_MISSING_JOBRUN, UNKNOWN_VALUE
|
22
21
|
from ads.aqua.data import AquaResourceIdentifier
|
23
22
|
from ads.aqua.model.enums import FineTuningDefinedMetadata
|
24
23
|
from ads.aqua.training.exceptions import exit_code_dict
|
24
|
+
from ads.aqua.ui import ModelFormat
|
25
25
|
from ads.common.serializer import DataClassSerializable
|
26
26
|
from ads.common.utils import get_log_links
|
27
27
|
from ads.model.datascience_model import DataScienceModel
|
@@ -41,6 +41,12 @@ class AquaFineTuneValidation(DataClassSerializable):
|
|
41
41
|
value: str = ""
|
42
42
|
|
43
43
|
|
44
|
+
class ModelValidationResult:
|
45
|
+
model_file: Optional[str] = None
|
46
|
+
model_format: ModelFormat = None
|
47
|
+
telemetry_model_name: str = None
|
48
|
+
|
49
|
+
|
44
50
|
@dataclass(repr=False)
|
45
51
|
class AquaFineTuningMetric(DataClassSerializable):
|
46
52
|
name: str = field(default_factory=str)
|
@@ -76,6 +82,9 @@ class AquaModelSummary(DataClassSerializable):
|
|
76
82
|
ready_to_deploy: bool = True
|
77
83
|
ready_to_finetune: bool = False
|
78
84
|
ready_to_import: bool = False
|
85
|
+
nvidia_gpu_supported: bool = False
|
86
|
+
arm_cpu_supported: bool = False
|
87
|
+
model_format: ModelFormat = ModelFormat.UNKNOWN
|
79
88
|
|
80
89
|
|
81
90
|
@dataclass(repr=False)
|
@@ -147,14 +156,14 @@ class AquaEvalFTCommon(DataClassSerializable):
|
|
147
156
|
try:
|
148
157
|
log = utils.query_resource(log_id, return_all=False)
|
149
158
|
log_name = log.display_name if log else ""
|
150
|
-
except:
|
159
|
+
except Exception:
|
151
160
|
pass
|
152
161
|
|
153
162
|
if loggroup_id:
|
154
163
|
try:
|
155
164
|
loggroup = utils.query_resource(loggroup_id, return_all=False)
|
156
165
|
loggroup_name = loggroup.display_name if loggroup else ""
|
157
|
-
except:
|
166
|
+
except Exception:
|
158
167
|
pass
|
159
168
|
|
160
169
|
experiment_id, experiment_name = utils._get_experiment_info(model)
|
@@ -168,9 +177,7 @@ class AquaEvalFTCommon(DataClassSerializable):
|
|
168
177
|
)
|
169
178
|
self.job = utils._build_job_identifier(job_run_details=jobrun, region=region)
|
170
179
|
self.lifecycle_details = (
|
171
|
-
|
172
|
-
if not jobrun
|
173
|
-
else jobrun.lifecycle_details
|
180
|
+
LIFECYCLE_DETAILS_MISSING_JOBRUN if not jobrun else jobrun.lifecycle_details
|
174
181
|
)
|
175
182
|
|
176
183
|
|
@@ -247,7 +254,7 @@ class AquaFineTuneModel(AquaModel, AquaEvalFTCommon, DataClassSerializable):
|
|
247
254
|
lifecycle_details,
|
248
255
|
)
|
249
256
|
message = f"{exception.reason} (exit code {exit_code})"
|
250
|
-
except:
|
257
|
+
except Exception:
|
251
258
|
pass
|
252
259
|
|
253
260
|
return message
|
@@ -261,6 +268,7 @@ class ImportModelDetails(CLIBuilderMixin):
|
|
261
268
|
finetuning_container: Optional[str] = None
|
262
269
|
compartment_id: Optional[str] = None
|
263
270
|
project_id: Optional[str] = None
|
271
|
+
model_file: Optional[str] = None
|
264
272
|
|
265
273
|
def __post_init__(self):
|
266
274
|
self._command = "model register"
|