oracle-ads 2.12.2__py3-none-any.whl → 2.12.4__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.
Files changed (56) hide show
  1. ads/aqua/common/enums.py +9 -0
  2. ads/aqua/common/utils.py +83 -6
  3. ads/aqua/config/config.py +0 -16
  4. ads/aqua/constants.py +2 -0
  5. ads/aqua/evaluation/entities.py +45 -50
  6. ads/aqua/evaluation/evaluation.py +26 -61
  7. ads/aqua/extension/deployment_handler.py +35 -0
  8. ads/aqua/extension/errors.py +1 -0
  9. ads/aqua/extension/evaluation_handler.py +0 -5
  10. ads/aqua/extension/finetune_handler.py +1 -2
  11. ads/aqua/extension/model_handler.py +38 -1
  12. ads/aqua/extension/ui_handler.py +22 -3
  13. ads/aqua/finetuning/entities.py +5 -4
  14. ads/aqua/finetuning/finetuning.py +13 -8
  15. ads/aqua/model/constants.py +1 -0
  16. ads/aqua/model/entities.py +2 -0
  17. ads/aqua/model/model.py +350 -140
  18. ads/aqua/modeldeployment/deployment.py +118 -62
  19. ads/aqua/modeldeployment/entities.py +10 -2
  20. ads/aqua/ui.py +29 -16
  21. ads/config.py +3 -8
  22. ads/dataset/dataset.py +2 -2
  23. ads/dataset/factory.py +1 -1
  24. ads/llm/deploy.py +6 -0
  25. ads/llm/guardrails/base.py +0 -1
  26. ads/llm/langchain/plugins/chat_models/oci_data_science.py +118 -41
  27. ads/llm/langchain/plugins/llms/oci_data_science_model_deployment_endpoint.py +18 -14
  28. ads/llm/templates/score_chain.jinja2 +0 -1
  29. ads/model/datascience_model.py +519 -16
  30. ads/model/deployment/model_deployment.py +13 -0
  31. ads/model/deployment/model_deployment_infrastructure.py +34 -0
  32. ads/model/generic_model.py +10 -0
  33. ads/model/model_properties.py +1 -0
  34. ads/model/service/oci_datascience_model.py +28 -0
  35. ads/opctl/operator/lowcode/anomaly/const.py +66 -1
  36. ads/opctl/operator/lowcode/anomaly/model/anomaly_merlion.py +161 -0
  37. ads/opctl/operator/lowcode/anomaly/model/autots.py +30 -15
  38. ads/opctl/operator/lowcode/anomaly/model/factory.py +15 -3
  39. ads/opctl/operator/lowcode/anomaly/model/randomcutforest.py +1 -1
  40. ads/opctl/operator/lowcode/anomaly/schema.yaml +10 -0
  41. ads/opctl/operator/lowcode/anomaly/utils.py +3 -0
  42. ads/opctl/operator/lowcode/forecast/cmd.py +3 -9
  43. ads/opctl/operator/lowcode/forecast/const.py +3 -4
  44. ads/opctl/operator/lowcode/forecast/model/factory.py +13 -12
  45. ads/opctl/operator/lowcode/forecast/model/ml_forecast.py +4 -3
  46. ads/opctl/operator/lowcode/forecast/operator_config.py +17 -10
  47. ads/opctl/operator/lowcode/forecast/schema.yaml +2 -2
  48. ads/oracledb/oracle_db.py +32 -20
  49. ads/secrets/adb.py +28 -6
  50. {oracle_ads-2.12.2.dist-info → oracle_ads-2.12.4.dist-info}/METADATA +3 -2
  51. {oracle_ads-2.12.2.dist-info → oracle_ads-2.12.4.dist-info}/RECORD +54 -55
  52. {oracle_ads-2.12.2.dist-info → oracle_ads-2.12.4.dist-info}/WHEEL +1 -1
  53. ads/aqua/config/deployment_config_defaults.json +0 -38
  54. ads/aqua/config/resource_limit_names.json +0 -9
  55. {oracle_ads-2.12.2.dist-info → oracle_ads-2.12.4.dist-info}/LICENSE.txt +0 -0
  56. {oracle_ads-2.12.2.dist-info → oracle_ads-2.12.4.dist-info}/entry_points.txt +0 -0
ads/aqua/common/enums.py CHANGED
@@ -52,6 +52,7 @@ class InferenceContainerTypeFamily(str, metaclass=ExtendedEnumMeta):
52
52
  AQUA_VLLM_CONTAINER_FAMILY = "odsc-vllm-serving"
53
53
  AQUA_TGI_CONTAINER_FAMILY = "odsc-tgi-serving"
54
54
  AQUA_LLAMA_CPP_CONTAINER_FAMILY = "odsc-llama-cpp-serving"
55
+ AQUA_TEI_CONTAINER_FAMILY = "odsc-tei-serving"
55
56
 
56
57
 
57
58
  class InferenceContainerParamType(str, metaclass=ExtendedEnumMeta):
@@ -80,3 +81,11 @@ class RqsAdditionalDetails(str, metaclass=ExtendedEnumMeta):
80
81
  MODEL_VERSION_SET_NAME = "modelVersionSetName"
81
82
  PROJECT_ID = "projectId"
82
83
  VERSION_LABEL = "versionLabel"
84
+
85
+
86
+ class TextEmbeddingInferenceContainerParams(str, metaclass=ExtendedEnumMeta):
87
+ """Contains a subset of params that are required for enabling model deployment in OCI Data Science. More options
88
+ are available at https://huggingface.co/docs/text-embeddings-inference/en/cli_arguments"""
89
+
90
+ MODEL_ID = "model-id"
91
+ PORT = "port"
ads/aqua/common/utils.py CHANGED
@@ -35,6 +35,7 @@ from ads.aqua.common.enums import (
35
35
  InferenceContainerParamType,
36
36
  InferenceContainerType,
37
37
  RqsAdditionalDetails,
38
+ TextEmbeddingInferenceContainerParams,
38
39
  )
39
40
  from ads.aqua.common.errors import (
40
41
  AquaFileNotFoundError,
@@ -51,6 +52,7 @@ from ads.aqua.constants import (
51
52
  MODEL_BY_REFERENCE_OSS_PATH_KEY,
52
53
  SERVICE_MANAGED_CONTAINER_URI_SCHEME,
53
54
  SUPPORTED_FILE_FORMATS,
55
+ TEI_CONTAINER_DEFAULT_HOST,
54
56
  TGI_INFERENCE_RESTRICTED_PARAMS,
55
57
  UNKNOWN,
56
58
  UNKNOWN_JSON_STR,
@@ -63,7 +65,12 @@ from ads.common.extended_enum import ExtendedEnumMeta
63
65
  from ads.common.object_storage_details import ObjectStorageDetails
64
66
  from ads.common.oci_resource import SEARCH_TYPE, OCIResource
65
67
  from ads.common.utils import copy_file, get_console_link, upload_to_os
66
- from ads.config import AQUA_SERVICE_MODELS_BUCKET, CONDA_BUCKET_NS, TENANCY_OCID
68
+ from ads.config import (
69
+ AQUA_MODEL_DEPLOYMENT_FOLDER,
70
+ AQUA_SERVICE_MODELS_BUCKET,
71
+ CONDA_BUCKET_NS,
72
+ TENANCY_OCID,
73
+ )
67
74
  from ads.model import DataScienceModel, ModelVersionSet
68
75
 
69
76
  logger = logging.getLogger("ads.aqua")
@@ -569,15 +576,13 @@ def get_container_image(
569
576
  A dict of allowed configs.
570
577
  """
571
578
 
579
+ container_image = UNKNOWN
572
580
  config = config_file_name or get_container_config()
573
581
  config_file_name = service_config_path()
574
582
 
575
583
  if container_type not in config:
576
- raise AquaValueError(
577
- f"{config_file_name} does not have config details for model: {container_type}"
578
- )
584
+ return UNKNOWN
579
585
 
580
- container_image = None
581
586
  mapping = config[container_type]
582
587
  versions = [obj["version"] for obj in mapping]
583
588
  # assumes numbered versions, update if `latest` is used
@@ -1071,7 +1076,6 @@ def list_hf_models(query: str) -> List[str]:
1071
1076
  try:
1072
1077
  models = HfApi().list_models(
1073
1078
  model_name=query,
1074
- task="text-generation",
1075
1079
  sort="downloads",
1076
1080
  direction=-1,
1077
1081
  limit=20,
@@ -1079,3 +1083,76 @@ def list_hf_models(query: str) -> List[str]:
1079
1083
  return [model.id for model in models if model.disabled is None]
1080
1084
  except HfHubHTTPError as err:
1081
1085
  raise format_hf_custom_error_message(err) from err
1086
+
1087
+
1088
+ def generate_tei_cmd_var(os_path: str) -> List[str]:
1089
+ """This utility functions generates CMD params for Text Embedding Inference container. Only the
1090
+ essential parameters for OCI model deployment are added, defaults are used for the rest.
1091
+ Parameters
1092
+ ----------
1093
+ os_path: str
1094
+ OCI bucket path where the model artifacts are uploaded - oci://bucket@namespace/prefix
1095
+
1096
+ Returns
1097
+ -------
1098
+ cmd_var:
1099
+ List of command line arguments
1100
+ """
1101
+
1102
+ cmd_prefix = "--"
1103
+ cmd_var = [
1104
+ f"{cmd_prefix}{TextEmbeddingInferenceContainerParams.MODEL_ID}",
1105
+ f"{AQUA_MODEL_DEPLOYMENT_FOLDER}{ObjectStorageDetails.from_path(os_path.rstrip('/')).filepath}/",
1106
+ f"{cmd_prefix}{TextEmbeddingInferenceContainerParams.PORT}",
1107
+ TEI_CONTAINER_DEFAULT_HOST,
1108
+ ]
1109
+
1110
+ return cmd_var
1111
+
1112
+
1113
+ def parse_cmd_var(cmd_list: List[str]) -> dict:
1114
+ """Helper functions that parses a list into a key-value dictionary. The list contains keys separated by the prefix
1115
+ '--' and the value of the key is the subsequent element.
1116
+ """
1117
+ parsed_cmd = {}
1118
+
1119
+ for i, cmd in enumerate(cmd_list):
1120
+ if cmd.startswith("--"):
1121
+ if i + 1 < len(cmd_list) and not cmd_list[i + 1].startswith("--"):
1122
+ parsed_cmd[cmd] = cmd_list[i + 1]
1123
+ i += 1
1124
+ else:
1125
+ parsed_cmd[cmd] = None
1126
+ return parsed_cmd
1127
+
1128
+
1129
+ def validate_cmd_var(cmd_var: List[str], overrides: List[str]) -> List[str]:
1130
+ """This function accepts two lists of parameters and combines them. If the second list shares the common parameter
1131
+ names/keys, then it raises an error.
1132
+ Parameters
1133
+ ----------
1134
+ cmd_var: List[str]
1135
+ Default list of parameters
1136
+ overrides: List[str]
1137
+ List of parameters to override
1138
+ Returns
1139
+ -------
1140
+ List[str] of combined parameters
1141
+ """
1142
+ cmd_var = [str(x) for x in cmd_var]
1143
+ if not overrides:
1144
+ return cmd_var
1145
+ overrides = [str(x) for x in overrides]
1146
+
1147
+ cmd_dict = parse_cmd_var(cmd_var)
1148
+ overrides_dict = parse_cmd_var(overrides)
1149
+
1150
+ # check for conflicts
1151
+ common_keys = set(cmd_dict.keys()) & set(overrides_dict.keys())
1152
+ if common_keys:
1153
+ raise AquaValueError(
1154
+ f"The following CMD input cannot be overridden for model deployment: {', '.join(common_keys)}"
1155
+ )
1156
+
1157
+ combined_cmd_var = cmd_var + overrides
1158
+ return combined_cmd_var
ads/aqua/config/config.py CHANGED
@@ -29,19 +29,3 @@ def get_evaluation_service_config(
29
29
  .get(ContainerSpec.CONTAINER_SPEC, {})
30
30
  .get(container, {})
31
31
  )
32
-
33
-
34
- # TODO: move this to global config.json in object storage
35
- def get_finetuning_config_defaults():
36
- """Generate and return the fine-tuning default configuration dictionary."""
37
- return {
38
- "shape": {
39
- "VM.GPU.A10.1": {"batch_size": 1, "replica": "1-10"},
40
- "VM.GPU.A10.2": {"batch_size": 1, "replica": "1-10"},
41
- "BM.GPU.A10.4": {"batch_size": 1, "replica": 1},
42
- "BM.GPU4.8": {"batch_size": 4, "replica": 1},
43
- "BM.GPU.L40S-NC.4": {"batch_size": 4, "replica": 1},
44
- "BM.GPU.A100-v2.8": {"batch_size": 6, "replica": 1},
45
- "BM.GPU.H100.8": {"batch_size": 6, "replica": 1},
46
- }
47
- }
ads/aqua/constants.py CHANGED
@@ -27,6 +27,7 @@ NB_SESSION_IDENTIFIER = "NB_SESSION_OCID"
27
27
  LIFECYCLE_DETAILS_MISSING_JOBRUN = "The associated JobRun resource has been deleted."
28
28
  READY_TO_DEPLOY_STATUS = "ACTIVE"
29
29
  READY_TO_FINE_TUNE_STATUS = "TRUE"
30
+ PRIVATE_ENDPOINT_TYPE = "MODEL_DEPLOYMENT"
30
31
  AQUA_GA_LIST = ["id19sfcrra6z"]
31
32
  AQUA_MODEL_TYPE_SERVICE = "service"
32
33
  AQUA_MODEL_TYPE_CUSTOM = "custom"
@@ -79,3 +80,4 @@ LLAMA_CPP_INFERENCE_RESTRICTED_PARAMS = {
79
80
  "--port",
80
81
  "--host",
81
82
  }
83
+ TEI_CONTAINER_DEFAULT_HOST = "8080"
@@ -9,19 +9,18 @@ aqua.evaluation.entities
9
9
  This module contains dataclasses for aqua evaluation.
10
10
  """
11
11
 
12
- from dataclasses import dataclass, field
13
- from typing import List, Optional, Union
12
+ from pydantic import Field
13
+ from typing import Any, Dict, List, Optional, Union
14
14
 
15
15
  from ads.aqua.data import AquaResourceIdentifier
16
- from ads.common.serializer import DataClassSerializable
16
+ from ads.aqua.config.utils.serializer import Serializable
17
17
 
18
18
 
19
- @dataclass(repr=False)
20
- class CreateAquaEvaluationDetails(DataClassSerializable):
21
- """Dataclass to create aqua model evaluation.
19
+ class CreateAquaEvaluationDetails(Serializable):
20
+ """Class for creating aqua model evaluation.
22
21
 
23
- Fields
24
- ------
22
+ Properties
23
+ ----------
25
24
  evaluation_source_id: str
26
25
  The evaluation source id. Must be either model or model deployment ocid.
27
26
  evaluation_name: str
@@ -83,69 +82,64 @@ class CreateAquaEvaluationDetails(DataClassSerializable):
83
82
  ocpus: Optional[float] = None
84
83
  log_group_id: Optional[str] = None
85
84
  log_id: Optional[str] = None
86
- metrics: Optional[List] = None
85
+ metrics: Optional[List[str]] = None
87
86
  force_overwrite: Optional[bool] = False
88
87
 
88
+ class Config:
89
+ extra = "ignore"
89
90
 
90
- @dataclass(repr=False)
91
- class AquaEvalReport(DataClassSerializable):
91
+ class AquaEvalReport(Serializable):
92
92
  evaluation_id: str = ""
93
93
  content: str = ""
94
94
 
95
+ class Config:
96
+ extra = "ignore"
95
97
 
96
- @dataclass(repr=False)
97
- class ModelParams(DataClassSerializable):
98
- max_tokens: str = ""
99
- top_p: str = ""
100
- top_k: str = ""
101
- temperature: str = ""
102
- presence_penalty: Optional[float] = 0.0
103
- frequency_penalty: Optional[float] = 0.0
104
- stop: Optional[Union[str, List[str]]] = field(default_factory=list)
105
- model: Optional[str] = "odsc-llm"
106
-
107
-
108
- @dataclass(repr=False)
109
- class AquaEvalParams(ModelParams, DataClassSerializable):
98
+ class AquaEvalParams(Serializable):
110
99
  shape: str = ""
111
100
  dataset_path: str = ""
112
101
  report_path: str = ""
113
102
 
103
+ class Config:
104
+ extra = "allow"
114
105
 
115
- @dataclass(repr=False)
116
- class AquaEvalMetric(DataClassSerializable):
106
+ class AquaEvalMetric(Serializable):
117
107
  key: str
118
108
  name: str
119
109
  description: str = ""
120
110
 
111
+ class Config:
112
+ extra = "ignore"
121
113
 
122
- @dataclass(repr=False)
123
- class AquaEvalMetricSummary(DataClassSerializable):
114
+ class AquaEvalMetricSummary(Serializable):
124
115
  metric: str = ""
125
116
  score: str = ""
126
117
  grade: str = ""
127
118
 
119
+ class Config:
120
+ extra = "ignore"
128
121
 
129
- @dataclass(repr=False)
130
- class AquaEvalMetrics(DataClassSerializable):
122
+ class AquaEvalMetrics(Serializable):
131
123
  id: str
132
124
  report: str
133
- metric_results: List[AquaEvalMetric] = field(default_factory=list)
134
- metric_summary_result: List[AquaEvalMetricSummary] = field(default_factory=list)
125
+ metric_results: List[AquaEvalMetric] = Field(default_factory=list)
126
+ metric_summary_result: List[AquaEvalMetricSummary] = Field(default_factory=list)
135
127
 
128
+ class Config:
129
+ extra = "ignore"
136
130
 
137
- @dataclass(repr=False)
138
- class AquaEvaluationCommands(DataClassSerializable):
131
+ class AquaEvaluationCommands(Serializable):
139
132
  evaluation_id: str
140
133
  evaluation_target_id: str
141
- input_data: dict
142
- metrics: list
134
+ input_data: Dict[str, Any]
135
+ metrics: List[str]
143
136
  output_dir: str
144
- params: dict
137
+ params: Dict[str, Any]
145
138
 
139
+ class Config:
140
+ extra = "ignore"
146
141
 
147
- @dataclass(repr=False)
148
- class AquaEvaluationSummary(DataClassSerializable):
142
+ class AquaEvaluationSummary(Serializable):
149
143
  """Represents a summary of Aqua evalution."""
150
144
 
151
145
  id: str
@@ -154,17 +148,18 @@ class AquaEvaluationSummary(DataClassSerializable):
154
148
  lifecycle_state: str
155
149
  lifecycle_details: str
156
150
  time_created: str
157
- tags: dict
158
- experiment: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
159
- source: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
160
- job: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
161
- parameters: AquaEvalParams = field(default_factory=AquaEvalParams)
151
+ tags: Dict[str, Any]
152
+ experiment: AquaResourceIdentifier = Field(default_factory=AquaResourceIdentifier)
153
+ source: AquaResourceIdentifier = Field(default_factory=AquaResourceIdentifier)
154
+ job: AquaResourceIdentifier = Field(default_factory=AquaResourceIdentifier)
155
+ parameters: AquaEvalParams = Field(default_factory=AquaEvalParams)
162
156
 
157
+ class Config:
158
+ extra = "ignore"
163
159
 
164
- @dataclass(repr=False)
165
- class AquaEvaluationDetail(AquaEvaluationSummary, DataClassSerializable):
160
+ class AquaEvaluationDetail(AquaEvaluationSummary):
166
161
  """Represents a details of Aqua evalution."""
167
162
 
168
- log_group: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
169
- log: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
170
- introspection: dict = field(default_factory=dict)
163
+ log_group: AquaResourceIdentifier = Field(default_factory=AquaResourceIdentifier)
164
+ log: AquaResourceIdentifier = Field(default_factory=AquaResourceIdentifier)
165
+ introspection: dict = Field(default_factory=dict)
@@ -7,7 +7,6 @@ import os
7
7
  import re
8
8
  import tempfile
9
9
  from concurrent.futures import ThreadPoolExecutor, as_completed
10
- from dataclasses import asdict, fields
11
10
  from datetime import datetime, timedelta
12
11
  from pathlib import Path
13
12
  from threading import Lock
@@ -46,7 +45,6 @@ from ads.aqua.common.utils import (
46
45
  upload_local_to_os,
47
46
  )
48
47
  from ads.aqua.config.config import get_evaluation_service_config
49
- from ads.aqua.config.evaluation.evaluation_service_config import EvaluationServiceConfig
50
48
  from ads.aqua.constants import (
51
49
  CONSOLE_LINK_RESOURCE_TYPE_MAPPING,
52
50
  EVALUATION_REPORT,
@@ -75,7 +73,6 @@ from ads.aqua.evaluation.entities import (
75
73
  AquaEvaluationSummary,
76
74
  AquaResourceIdentifier,
77
75
  CreateAquaEvaluationDetails,
78
- ModelParams,
79
76
  )
80
77
  from ads.aqua.evaluation.errors import EVALUATION_JOB_EXIT_CODE_MESSAGE
81
78
  from ads.aqua.ui import AquaContainerConfig
@@ -161,10 +158,11 @@ class AquaEvaluationApp(AquaApp):
161
158
  try:
162
159
  create_aqua_evaluation_details = CreateAquaEvaluationDetails(**kwargs)
163
160
  except Exception as ex:
161
+ custom_errors = {
162
+ ".".join(map(str, e["loc"])): e["msg"] for e in json.loads(ex.json())
163
+ }
164
164
  raise AquaValueError(
165
- "Invalid create evaluation parameters. "
166
- "Allowable parameters are: "
167
- f"{', '.join([field.name for field in fields(CreateAquaEvaluationDetails)])}."
165
+ f"Invalid create evaluation parameters. Error details: {custom_errors}."
168
166
  ) from ex
169
167
 
170
168
  if not is_valid_ocid(create_aqua_evaluation_details.evaluation_source_id):
@@ -175,15 +173,7 @@ class AquaEvaluationApp(AquaApp):
175
173
 
176
174
  # The model to evaluate
177
175
  evaluation_source = None
178
- # The evaluation service config
179
- evaluation_config: EvaluationServiceConfig = get_evaluation_service_config()
180
- # The evaluation inference configuration. The inference configuration will be extracted
181
- # based on the inferencing container family.
182
176
  eval_inference_configuration: Dict = {}
183
- # The evaluation inference model sampling params. The system parameters that will not be
184
- # visible for user, but will be applied implicitly for evaluation. The service model params
185
- # will be extracted based on the container family and version.
186
- eval_inference_service_model_params: Dict = {}
187
177
 
188
178
  if (
189
179
  DataScienceResource.MODEL_DEPLOYMENT
@@ -200,29 +190,14 @@ class AquaEvaluationApp(AquaApp):
200
190
  runtime = ModelDeploymentContainerRuntime.from_dict(
201
191
  evaluation_source.runtime.to_dict()
202
192
  )
203
- container_config = AquaContainerConfig.from_container_index_json(
193
+ inference_config = AquaContainerConfig.from_container_index_json(
204
194
  enable_spec=True
205
- )
206
- for (
207
- inference_container_family,
208
- inference_container_info,
209
- ) in container_config.inference.items():
210
- if (
211
- inference_container_info.name
212
- == runtime.image[: runtime.image.rfind(":")]
213
- ):
195
+ ).inference
196
+ for container in inference_config.values():
197
+ if container.name == runtime.image[: runtime.image.rfind(":")]:
214
198
  eval_inference_configuration = (
215
- evaluation_config.get_merged_inference_params(
216
- inference_container_family
217
- ).to_dict()
218
- )
219
- eval_inference_service_model_params = (
220
- evaluation_config.get_merged_inference_model_params(
221
- inference_container_family,
222
- inference_container_info.version,
223
- )
199
+ container.spec.evaluation_configuration
224
200
  )
225
-
226
201
  except Exception:
227
202
  logger.debug(
228
203
  f"Could not load inference config details for the evaluation source id: "
@@ -277,19 +252,12 @@ class AquaEvaluationApp(AquaApp):
277
252
  )
278
253
  evaluation_dataset_path = dst_uri
279
254
 
280
- evaluation_model_parameters = None
281
- try:
282
- evaluation_model_parameters = AquaEvalParams(
283
- shape=create_aqua_evaluation_details.shape_name,
284
- dataset_path=evaluation_dataset_path,
285
- report_path=create_aqua_evaluation_details.report_path,
286
- **create_aqua_evaluation_details.model_parameters,
287
- )
288
- except Exception as ex:
289
- raise AquaValueError(
290
- "Invalid model parameters. Model parameters should "
291
- f"be a dictionary with keys: {', '.join(list(ModelParams.__annotations__.keys()))}."
292
- ) from ex
255
+ evaluation_model_parameters = AquaEvalParams(
256
+ shape=create_aqua_evaluation_details.shape_name,
257
+ dataset_path=evaluation_dataset_path,
258
+ report_path=create_aqua_evaluation_details.report_path,
259
+ **create_aqua_evaluation_details.model_parameters,
260
+ )
293
261
 
294
262
  target_compartment = (
295
263
  create_aqua_evaluation_details.compartment_id or COMPARTMENT_OCID
@@ -370,7 +338,7 @@ class AquaEvaluationApp(AquaApp):
370
338
  evaluation_model_taxonomy_metadata = ModelTaxonomyMetadata()
371
339
  evaluation_model_taxonomy_metadata[
372
340
  MetadataTaxonomyKeys.HYPERPARAMETERS
373
- ].value = {"model_params": dict(asdict(evaluation_model_parameters))}
341
+ ].value = {"model_params": evaluation_model_parameters.to_dict()}
374
342
 
375
343
  evaluation_model = (
376
344
  DataScienceModel()
@@ -443,7 +411,6 @@ class AquaEvaluationApp(AquaApp):
443
411
  dataset_path=evaluation_dataset_path,
444
412
  report_path=create_aqua_evaluation_details.report_path,
445
413
  model_parameters={
446
- **eval_inference_service_model_params,
447
414
  **create_aqua_evaluation_details.model_parameters,
448
415
  },
449
416
  metrics=create_aqua_evaluation_details.metrics,
@@ -580,16 +547,14 @@ class AquaEvaluationApp(AquaApp):
580
547
  **{
581
548
  "AIP_SMC_EVALUATION_ARGUMENTS": json.dumps(
582
549
  {
583
- **asdict(
584
- self._build_launch_cmd(
585
- evaluation_id=evaluation_id,
586
- evaluation_source_id=evaluation_source_id,
587
- dataset_path=dataset_path,
588
- report_path=report_path,
589
- model_parameters=model_parameters,
590
- metrics=metrics,
591
- ),
592
- ),
550
+ **self._build_launch_cmd(
551
+ evaluation_id=evaluation_id,
552
+ evaluation_source_id=evaluation_source_id,
553
+ dataset_path=dataset_path,
554
+ report_path=report_path,
555
+ model_parameters=model_parameters,
556
+ metrics=metrics,
557
+ ).to_dict(),
593
558
  **(inference_configuration or {}),
594
559
  },
595
560
  ),
@@ -662,9 +627,9 @@ class AquaEvaluationApp(AquaApp):
662
627
  "format": Path(dataset_path).suffix,
663
628
  "url": dataset_path,
664
629
  },
665
- metrics=metrics,
630
+ metrics=metrics or [],
666
631
  output_dir=report_path,
667
- params=model_parameters,
632
+ params=model_parameters or {},
668
633
  )
669
634
 
670
635
  @telemetry(entry_point="plugin=evaluation&action=get", name="aqua")
@@ -54,6 +54,33 @@ class AquaDeploymentHandler(AquaAPIhandler):
54
54
  else:
55
55
  raise HTTPError(400, f"The request {self.request.path} is invalid.")
56
56
 
57
+ @handle_exceptions
58
+ def delete(self, model_deployment_id):
59
+ return self.finish(AquaDeploymentApp().delete(model_deployment_id))
60
+
61
+ @handle_exceptions
62
+ def put(self, *args, **kwargs):
63
+ """
64
+ Handles put request for the activating and deactivating OCI datascience model deployments
65
+ Raises
66
+ ------
67
+ HTTPError
68
+ Raises HTTPError if inputs are missing or are invalid
69
+ """
70
+ url_parse = urlparse(self.request.path)
71
+ paths = url_parse.path.strip("/").split("/")
72
+ if len(paths) != 4 or paths[0] != "aqua" or paths[1] != "deployments":
73
+ raise HTTPError(400, f"The request {self.request.path} is invalid.")
74
+
75
+ model_deployment_id = paths[2]
76
+ action = paths[3]
77
+ if action == "activate":
78
+ return self.finish(AquaDeploymentApp().activate(model_deployment_id))
79
+ elif action == "deactivate":
80
+ return self.finish(AquaDeploymentApp().deactivate(model_deployment_id))
81
+ else:
82
+ raise HTTPError(400, f"The request {self.request.path} is invalid.")
83
+
57
84
  @handle_exceptions
58
85
  def post(self, *args, **kwargs):
59
86
  """
@@ -102,6 +129,9 @@ class AquaDeploymentHandler(AquaAPIhandler):
102
129
  ocpus = input_data.get("ocpus")
103
130
  memory_in_gbs = input_data.get("memory_in_gbs")
104
131
  model_file = input_data.get("model_file")
132
+ private_endpoint_id = input_data.get("private_endpoint_id")
133
+ container_image_uri = input_data.get("container_image_uri")
134
+ cmd_var = input_data.get("cmd_var")
105
135
 
106
136
  self.finish(
107
137
  AquaDeploymentApp().create(
@@ -124,6 +154,9 @@ class AquaDeploymentHandler(AquaAPIhandler):
124
154
  ocpus=ocpus,
125
155
  memory_in_gbs=memory_in_gbs,
126
156
  model_file=model_file,
157
+ private_endpoint_id=private_endpoint_id,
158
+ container_image_uri=container_image_uri,
159
+ cmd_var=cmd_var,
127
160
  )
128
161
  )
129
162
 
@@ -264,5 +297,7 @@ __handlers__ = [
264
297
  ("deployments/?([^/]*)/params", AquaDeploymentParamsHandler),
265
298
  ("deployments/config/?([^/]*)", AquaDeploymentHandler),
266
299
  ("deployments/?([^/]*)", AquaDeploymentHandler),
300
+ ("deployments/?([^/]*)/activate", AquaDeploymentHandler),
301
+ ("deployments/?([^/]*)/deactivate", AquaDeploymentHandler),
267
302
  ("inference", AquaDeploymentInferenceHandler),
268
303
  ]
@@ -8,3 +8,4 @@ class Errors(str):
8
8
  NO_INPUT_DATA = "No input data provided."
9
9
  MISSING_REQUIRED_PARAMETER = "Missing required parameter: '{}'"
10
10
  MISSING_ONEOF_REQUIRED_PARAMETER = "Either '{}' or '{}' is required."
11
+ INVALID_VALUE_OF_PARAMETER = "Invalid value of parameter: '{}'"
@@ -12,7 +12,6 @@ from ads.aqua.evaluation import AquaEvaluationApp
12
12
  from ads.aqua.evaluation.entities import CreateAquaEvaluationDetails
13
13
  from ads.aqua.extension.base_handler import AquaAPIhandler
14
14
  from ads.aqua.extension.errors import Errors
15
- from ads.aqua.extension.utils import validate_function_parameters
16
15
  from ads.config import COMPARTMENT_OCID
17
16
 
18
17
 
@@ -47,10 +46,6 @@ class AquaEvaluationHandler(AquaAPIhandler):
47
46
  if not input_data:
48
47
  raise HTTPError(400, Errors.NO_INPUT_DATA)
49
48
 
50
- validate_function_parameters(
51
- data_class=CreateAquaEvaluationDetails, input_data=input_data
52
- )
53
-
54
49
  self.finish(
55
50
  # TODO: decide what other kwargs will be needed for create aqua evaluation.
56
51
  AquaEvaluationApp().create(
@@ -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,8 +8,8 @@ from urllib.parse import urlparse
9
8
  from tornado.web import HTTPError
10
9
 
11
10
  from ads.aqua.common.decorator import handle_exceptions
12
- from ads.aqua.extension.errors import Errors
13
11
  from ads.aqua.extension.base_handler import AquaAPIhandler
12
+ from ads.aqua.extension.errors import Errors
14
13
  from ads.aqua.extension.utils import validate_function_parameters
15
14
  from ads.aqua.finetuning import AquaFineTuningApp
16
15
  from ads.aqua.finetuning.entities import CreateFineTuningDetails
@@ -9,7 +9,10 @@ from tornado.web import HTTPError
9
9
 
10
10
  from ads.aqua.common.decorator import handle_exceptions
11
11
  from ads.aqua.common.errors import AquaRuntimeError, AquaValueError
12
- from ads.aqua.common.utils import get_hf_model_info, list_hf_models
12
+ from ads.aqua.common.utils import (
13
+ get_hf_model_info,
14
+ list_hf_models,
15
+ )
13
16
  from ads.aqua.extension.base_handler import AquaAPIhandler
14
17
  from ads.aqua.extension.errors import Errors
15
18
  from ads.aqua.model import AquaModelApp
@@ -73,6 +76,8 @@ class AquaModelHandler(AquaAPIhandler):
73
76
  paths = url_parse.path.strip("/")
74
77
  if paths.startswith("aqua/model/cache"):
75
78
  return self.finish(AquaModelApp().clear_model_list_cache())
79
+ elif id:
80
+ return self.finish(AquaModelApp().delete_model(id))
76
81
  else:
77
82
  raise HTTPError(400, f"The request {self.request.path} is invalid.")
78
83
 
@@ -123,6 +128,7 @@ class AquaModelHandler(AquaAPIhandler):
123
128
  download_from_hf = (
124
129
  str(input_data.get("download_from_hf", "false")).lower() == "true"
125
130
  )
131
+ inference_container_uri = input_data.get("inference_container_uri")
126
132
 
127
133
  return self.finish(
128
134
  AquaModelApp().register(
@@ -134,9 +140,40 @@ class AquaModelHandler(AquaAPIhandler):
134
140
  compartment_id=compartment_id,
135
141
  project_id=project_id,
136
142
  model_file=model_file,
143
+ inference_container_uri=inference_container_uri,
137
144
  )
138
145
  )
139
146
 
147
+ @handle_exceptions
148
+ def put(self, id):
149
+ try:
150
+ input_data = self.get_json_body()
151
+ except Exception as ex:
152
+ raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
153
+
154
+ if not input_data:
155
+ raise HTTPError(400, Errors.NO_INPUT_DATA)
156
+
157
+ inference_container = input_data.get("inference_container")
158
+ inference_containers = AquaModelApp.list_valid_inference_containers()
159
+ if (
160
+ inference_container is not None
161
+ and inference_container not in inference_containers
162
+ ):
163
+ raise HTTPError(
164
+ 400, Errors.INVALID_VALUE_OF_PARAMETER.format("inference_container")
165
+ )
166
+
167
+ enable_finetuning = input_data.get("enable_finetuning")
168
+ task = input_data.get("task")
169
+ app=AquaModelApp()
170
+ self.finish(
171
+ app.edit_registered_model(
172
+ id, inference_container, enable_finetuning, task
173
+ )
174
+ )
175
+ app.clear_model_details_cache(model_id=id)
176
+
140
177
 
141
178
  class AquaModelLicenseHandler(AquaAPIhandler):
142
179
  """Handler for Aqua Model license REST APIs."""