oracle-ads 2.11.8__py3-none-any.whl → 2.11.10__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/__init__.py +1 -1
- ads/aqua/{base.py → app.py} +27 -7
- ads/aqua/cli.py +59 -17
- ads/aqua/common/__init__.py +5 -0
- ads/aqua/{decorator.py → common/decorator.py} +14 -8
- ads/aqua/common/enums.py +69 -0
- ads/aqua/{exception.py → common/errors.py} +28 -0
- ads/aqua/{utils.py → common/utils.py} +171 -79
- ads/aqua/config/config.py +18 -0
- ads/aqua/constants.py +51 -33
- ads/aqua/data.py +15 -26
- ads/aqua/evaluation/__init__.py +8 -0
- ads/aqua/evaluation/constants.py +53 -0
- ads/aqua/evaluation/entities.py +170 -0
- ads/aqua/evaluation/errors.py +71 -0
- ads/aqua/{evaluation.py → evaluation/evaluation.py} +122 -370
- ads/aqua/extension/__init__.py +2 -0
- ads/aqua/extension/aqua_ws_msg_handler.py +97 -0
- ads/aqua/extension/base_handler.py +0 -7
- ads/aqua/extension/common_handler.py +12 -6
- ads/aqua/extension/deployment_handler.py +70 -4
- ads/aqua/extension/errors.py +10 -0
- ads/aqua/extension/evaluation_handler.py +5 -3
- ads/aqua/extension/evaluation_ws_msg_handler.py +43 -0
- ads/aqua/extension/finetune_handler.py +41 -3
- ads/aqua/extension/model_handler.py +56 -4
- ads/aqua/extension/models/__init__.py +0 -0
- ads/aqua/extension/models/ws_models.py +69 -0
- ads/aqua/extension/ui_handler.py +65 -4
- ads/aqua/extension/ui_websocket_handler.py +124 -0
- ads/aqua/extension/utils.py +1 -1
- ads/aqua/finetuning/__init__.py +7 -0
- ads/aqua/finetuning/constants.py +17 -0
- ads/aqua/finetuning/entities.py +102 -0
- ads/aqua/{finetune.py → finetuning/finetuning.py} +162 -136
- ads/aqua/model/__init__.py +8 -0
- ads/aqua/model/constants.py +46 -0
- ads/aqua/model/entities.py +266 -0
- ads/aqua/model/enums.py +26 -0
- ads/aqua/{model.py → model/model.py} +401 -309
- ads/aqua/modeldeployment/__init__.py +8 -0
- ads/aqua/modeldeployment/constants.py +26 -0
- ads/aqua/{deployment.py → modeldeployment/deployment.py} +288 -227
- ads/aqua/modeldeployment/entities.py +142 -0
- ads/aqua/modeldeployment/inference.py +75 -0
- ads/aqua/ui.py +88 -8
- ads/cli.py +55 -7
- ads/common/serializer.py +2 -2
- ads/config.py +2 -1
- ads/jobs/builders/infrastructure/dsc_job.py +49 -6
- ads/model/datascience_model.py +21 -1
- ads/model/deployment/model_deployment.py +11 -0
- ads/model/model_metadata.py +17 -6
- ads/opctl/operator/lowcode/anomaly/README.md +0 -2
- ads/opctl/operator/lowcode/anomaly/__main__.py +3 -3
- ads/opctl/operator/lowcode/anomaly/environment.yaml +0 -2
- ads/opctl/operator/lowcode/anomaly/model/automlx.py +2 -2
- ads/opctl/operator/lowcode/anomaly/model/autots.py +1 -1
- ads/opctl/operator/lowcode/anomaly/model/base_model.py +13 -17
- ads/opctl/operator/lowcode/anomaly/operator_config.py +2 -0
- ads/opctl/operator/lowcode/anomaly/schema.yaml +1 -2
- ads/opctl/operator/lowcode/anomaly/utils.py +3 -2
- ads/opctl/operator/lowcode/common/transformations.py +2 -1
- ads/opctl/operator/lowcode/common/utils.py +1 -1
- ads/opctl/operator/lowcode/forecast/README.md +1 -3
- ads/opctl/operator/lowcode/forecast/__main__.py +3 -18
- ads/opctl/operator/lowcode/forecast/const.py +2 -0
- ads/opctl/operator/lowcode/forecast/environment.yaml +1 -2
- ads/opctl/operator/lowcode/forecast/model/arima.py +1 -0
- ads/opctl/operator/lowcode/forecast/model/automlx.py +7 -4
- ads/opctl/operator/lowcode/forecast/model/autots.py +1 -0
- ads/opctl/operator/lowcode/forecast/model/base_model.py +38 -22
- ads/opctl/operator/lowcode/forecast/model/factory.py +33 -4
- ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +15 -1
- ads/opctl/operator/lowcode/forecast/model/ml_forecast.py +234 -0
- ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +9 -1
- ads/opctl/operator/lowcode/forecast/model/prophet.py +1 -0
- ads/opctl/operator/lowcode/forecast/model_evaluator.py +147 -0
- ads/opctl/operator/lowcode/forecast/operator_config.py +2 -1
- ads/opctl/operator/lowcode/forecast/schema.yaml +7 -2
- ads/opctl/operator/lowcode/forecast/utils.py +18 -44
- {oracle_ads-2.11.8.dist-info → oracle_ads-2.11.10.dist-info}/METADATA +9 -12
- {oracle_ads-2.11.8.dist-info → oracle_ads-2.11.10.dist-info}/RECORD +86 -61
- ads/aqua/job.py +0 -29
- {oracle_ads-2.11.8.dist-info → oracle_ads-2.11.10.dist-info}/LICENSE.txt +0 -0
- {oracle_ads-2.11.8.dist-info → oracle_ads-2.11.10.dist-info}/WHEEL +0 -0
- {oracle_ads-2.11.8.dist-info → oracle_ads-2.11.10.dist-info}/entry_points.txt +0 -0
@@ -3,292 +3,59 @@
|
|
3
3
|
# Copyright (c) 2024 Oracle and/or its affiliates.
|
4
4
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
5
|
import os
|
6
|
-
import re
|
7
|
-
from dataclasses import InitVar, dataclass, field
|
8
6
|
from datetime import datetime, timedelta
|
9
|
-
from enum import Enum
|
10
7
|
from threading import Lock
|
11
|
-
from typing import List, Union
|
8
|
+
from typing import List, Optional, Union
|
12
9
|
|
13
|
-
import oci
|
14
10
|
from cachetools import TTLCache
|
15
11
|
from oci.data_science.models import JobRun, Model
|
16
12
|
|
17
|
-
from ads.aqua import ODSC_MODEL_COMPARTMENT_OCID
|
18
|
-
from ads.aqua.
|
19
|
-
from ads.aqua.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
13
|
+
from ads.aqua import ODSC_MODEL_COMPARTMENT_OCID
|
14
|
+
from ads.aqua.app import AquaApp
|
15
|
+
from ads.aqua.common.enums import Tags
|
16
|
+
from ads.aqua.common.errors import AquaRuntimeError
|
17
|
+
from ads.aqua.common.utils import (
|
18
|
+
create_word_icon,
|
19
|
+
get_artifact_path,
|
20
|
+
read_file,
|
21
|
+
copy_model_config,
|
22
|
+
load_config,
|
26
23
|
)
|
27
|
-
from ads.aqua.
|
28
|
-
from ads.aqua.exception import AquaRuntimeError
|
29
|
-
from ads.aqua.training.exceptions import exit_code_dict
|
30
|
-
from ads.aqua.utils import (
|
24
|
+
from ads.aqua.constants import (
|
31
25
|
LICENSE_TXT,
|
26
|
+
MODEL_BY_REFERENCE_OSS_PATH_KEY,
|
32
27
|
README,
|
33
28
|
READY_TO_DEPLOY_STATUS,
|
34
29
|
READY_TO_FINE_TUNE_STATUS,
|
30
|
+
READY_TO_IMPORT_STATUS,
|
31
|
+
TRAINING_METRICS_FINAL,
|
32
|
+
TRINING_METRICS,
|
35
33
|
UNKNOWN,
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
VALIDATION_METRICS,
|
35
|
+
VALIDATION_METRICS_FINAL,
|
36
|
+
AQUA_MODEL_ARTIFACT_CONFIG,
|
37
|
+
AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME,
|
38
|
+
AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE,
|
39
|
+
AQUA_MODEL_TYPE_CUSTOM,
|
39
40
|
)
|
41
|
+
from ads.aqua.model.constants import *
|
42
|
+
from ads.aqua.model.entities import *
|
40
43
|
from ads.common.auth import default_signer
|
41
|
-
from ads.common.object_storage_details import ObjectStorageDetails
|
42
44
|
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
|
43
|
-
from ads.common.
|
44
|
-
from ads.common.utils import get_console_link, get_log_links
|
45
|
+
from ads.common.utils import get_console_link
|
45
46
|
from ads.config import (
|
46
|
-
|
47
|
+
AQUA_DEPLOYMENT_CONTAINER_METADATA_NAME,
|
48
|
+
AQUA_EVALUATION_CONTAINER_METADATA_NAME,
|
49
|
+
AQUA_FINETUNING_CONTAINER_METADATA_NAME,
|
47
50
|
COMPARTMENT_OCID,
|
48
|
-
CONDA_BUCKET_NS,
|
49
51
|
PROJECT_OCID,
|
50
52
|
TENANCY_OCID,
|
51
53
|
)
|
52
54
|
from ads.model import DataScienceModel
|
53
|
-
from ads.model.model_metadata import
|
55
|
+
from ads.model.model_metadata import ModelCustomMetadata, ModelCustomMetadataItem
|
54
56
|
from ads.telemetry import telemetry
|
55
57
|
|
56
58
|
|
57
|
-
class FineTuningMetricCategories(Enum):
|
58
|
-
VALIDATION = "validation"
|
59
|
-
TRAINING = "training"
|
60
|
-
|
61
|
-
|
62
|
-
@dataclass(repr=False)
|
63
|
-
class FineTuningShapeInfo(DataClassSerializable):
|
64
|
-
instance_shape: str = field(default_factory=str)
|
65
|
-
replica: int = field(default_factory=int)
|
66
|
-
|
67
|
-
|
68
|
-
# TODO: give a better name
|
69
|
-
@dataclass(repr=False)
|
70
|
-
class AquaFineTuneValidation(DataClassSerializable):
|
71
|
-
type: str = "Automatic split"
|
72
|
-
value: str = ""
|
73
|
-
|
74
|
-
|
75
|
-
@dataclass(repr=False)
|
76
|
-
class AquaFineTuningMetric(DataClassSerializable):
|
77
|
-
name: str = field(default_factory=str)
|
78
|
-
category: str = field(default_factory=str)
|
79
|
-
scores: list = field(default_factory=list)
|
80
|
-
|
81
|
-
|
82
|
-
@dataclass(repr=False)
|
83
|
-
class AquaModelLicense(DataClassSerializable):
|
84
|
-
"""Represents the response of Get Model License."""
|
85
|
-
|
86
|
-
id: str = field(default_factory=str)
|
87
|
-
license: str = field(default_factory=str)
|
88
|
-
|
89
|
-
|
90
|
-
@dataclass(repr=False)
|
91
|
-
class AquaModelSummary(DataClassSerializable):
|
92
|
-
"""Represents a summary of Aqua model."""
|
93
|
-
|
94
|
-
compartment_id: str = None
|
95
|
-
icon: str = None
|
96
|
-
id: str = None
|
97
|
-
is_fine_tuned_model: bool = None
|
98
|
-
license: str = None
|
99
|
-
name: str = None
|
100
|
-
organization: str = None
|
101
|
-
project_id: str = None
|
102
|
-
tags: dict = None
|
103
|
-
task: str = None
|
104
|
-
time_created: str = None
|
105
|
-
console_link: str = None
|
106
|
-
search_text: str = None
|
107
|
-
ready_to_deploy: bool = True
|
108
|
-
ready_to_finetune: bool = False
|
109
|
-
|
110
|
-
|
111
|
-
@dataclass(repr=False)
|
112
|
-
class AquaModel(AquaModelSummary, DataClassSerializable):
|
113
|
-
"""Represents an Aqua model."""
|
114
|
-
|
115
|
-
model_card: str = None
|
116
|
-
|
117
|
-
|
118
|
-
@dataclass(repr=False)
|
119
|
-
class AquaEvalFTCommon(DataClassSerializable):
|
120
|
-
"""Represents common fields for evaluation and fine-tuning."""
|
121
|
-
|
122
|
-
lifecycle_state: str = None
|
123
|
-
lifecycle_details: str = None
|
124
|
-
job: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
|
125
|
-
source: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
|
126
|
-
experiment: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
|
127
|
-
log_group: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
|
128
|
-
log: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
|
129
|
-
|
130
|
-
model: InitVar = None
|
131
|
-
region: InitVar = None
|
132
|
-
jobrun: InitVar = None
|
133
|
-
|
134
|
-
def __post_init__(
|
135
|
-
self, model, region: str, jobrun: oci.data_science.models.JobRun = None
|
136
|
-
):
|
137
|
-
try:
|
138
|
-
log_id = jobrun.log_details.log_id
|
139
|
-
except Exception as e:
|
140
|
-
logger.debug(f"No associated log found. {str(e)}")
|
141
|
-
log_id = ""
|
142
|
-
|
143
|
-
try:
|
144
|
-
loggroup_id = jobrun.log_details.log_group_id
|
145
|
-
except Exception as e:
|
146
|
-
logger.debug(f"No associated loggroup found. {str(e)}")
|
147
|
-
loggroup_id = ""
|
148
|
-
|
149
|
-
loggroup_url = get_log_links(region=region, log_group_id=loggroup_id)
|
150
|
-
log_url = (
|
151
|
-
get_log_links(
|
152
|
-
region=region,
|
153
|
-
log_group_id=loggroup_id,
|
154
|
-
log_id=log_id,
|
155
|
-
compartment_id=jobrun.compartment_id,
|
156
|
-
source_id=jobrun.id,
|
157
|
-
)
|
158
|
-
if jobrun
|
159
|
-
else ""
|
160
|
-
)
|
161
|
-
|
162
|
-
log_name = None
|
163
|
-
loggroup_name = None
|
164
|
-
|
165
|
-
if log_id:
|
166
|
-
try:
|
167
|
-
log = utils.query_resource(log_id, return_all=False)
|
168
|
-
log_name = log.display_name if log else ""
|
169
|
-
except:
|
170
|
-
pass
|
171
|
-
|
172
|
-
if loggroup_id:
|
173
|
-
try:
|
174
|
-
loggroup = utils.query_resource(loggroup_id, return_all=False)
|
175
|
-
loggroup_name = loggroup.display_name if loggroup else ""
|
176
|
-
except:
|
177
|
-
pass
|
178
|
-
|
179
|
-
experiment_id, experiment_name = utils._get_experiment_info(model)
|
180
|
-
|
181
|
-
self.log_group = AquaResourceIdentifier(
|
182
|
-
loggroup_id, loggroup_name, loggroup_url
|
183
|
-
)
|
184
|
-
self.log = AquaResourceIdentifier(log_id, log_name, log_url)
|
185
|
-
self.experiment = utils._build_resource_identifier(
|
186
|
-
id=experiment_id, name=experiment_name, region=region
|
187
|
-
)
|
188
|
-
self.job = utils._build_job_identifier(job_run_details=jobrun, region=region)
|
189
|
-
self.lifecycle_details = (
|
190
|
-
utils.LIFECYCLE_DETAILS_MISSING_JOBRUN
|
191
|
-
if not jobrun
|
192
|
-
else jobrun.lifecycle_details
|
193
|
-
)
|
194
|
-
|
195
|
-
|
196
|
-
@dataclass(repr=False)
|
197
|
-
class AquaFineTuneModel(AquaModel, AquaEvalFTCommon, DataClassSerializable):
|
198
|
-
"""Represents an Aqua Fine Tuned Model."""
|
199
|
-
|
200
|
-
dataset: str = field(default_factory=str)
|
201
|
-
validation: AquaFineTuneValidation = field(default_factory=AquaFineTuneValidation)
|
202
|
-
shape_info: FineTuningShapeInfo = field(default_factory=FineTuningShapeInfo)
|
203
|
-
metrics: List[AquaFineTuningMetric] = field(default_factory=list)
|
204
|
-
|
205
|
-
def __post_init__(
|
206
|
-
self,
|
207
|
-
model: DataScienceModel,
|
208
|
-
region: str,
|
209
|
-
jobrun: oci.data_science.models.JobRun = None,
|
210
|
-
):
|
211
|
-
super().__post_init__(model=model, region=region, jobrun=jobrun)
|
212
|
-
|
213
|
-
if jobrun is not None:
|
214
|
-
jobrun_env_vars = (
|
215
|
-
jobrun.job_configuration_override_details.environment_variables or {}
|
216
|
-
)
|
217
|
-
self.shape_info = FineTuningShapeInfo(
|
218
|
-
instance_shape=jobrun.job_infrastructure_configuration_details.shape_name,
|
219
|
-
# TODO: use variable for `NODE_COUNT` in ads/jobs/builders/runtimes/base.py
|
220
|
-
replica=jobrun_env_vars.get("NODE_COUNT", UNKNOWN_VALUE),
|
221
|
-
)
|
222
|
-
|
223
|
-
try:
|
224
|
-
model_hyperparameters = model.defined_metadata_list.get(
|
225
|
-
MetadataTaxonomyKeys.HYPERPARAMETERS
|
226
|
-
).value
|
227
|
-
except Exception as e:
|
228
|
-
logger.debug(
|
229
|
-
f"Failed to extract model hyperparameters from {model.id}: " f"{str(e)}"
|
230
|
-
)
|
231
|
-
model_hyperparameters = {}
|
232
|
-
|
233
|
-
self.dataset = model_hyperparameters.get(
|
234
|
-
FineTuningDefinedMetadata.TRAINING_DATA.value
|
235
|
-
)
|
236
|
-
if not self.dataset:
|
237
|
-
logger.debug(
|
238
|
-
f"Key={FineTuningDefinedMetadata.TRAINING_DATA.value} not found in model hyperparameters."
|
239
|
-
)
|
240
|
-
|
241
|
-
self.validation = AquaFineTuneValidation(
|
242
|
-
value=model_hyperparameters.get(
|
243
|
-
FineTuningDefinedMetadata.VAL_SET_SIZE.value
|
244
|
-
)
|
245
|
-
)
|
246
|
-
if not self.validation:
|
247
|
-
logger.debug(
|
248
|
-
f"Key={FineTuningDefinedMetadata.VAL_SET_SIZE.value} not found in model hyperparameters."
|
249
|
-
)
|
250
|
-
|
251
|
-
if self.lifecycle_details:
|
252
|
-
self.lifecycle_details = self._extract_job_lifecycle_details(
|
253
|
-
self.lifecycle_details
|
254
|
-
)
|
255
|
-
|
256
|
-
def _extract_job_lifecycle_details(self, lifecycle_details):
|
257
|
-
message = lifecycle_details
|
258
|
-
try:
|
259
|
-
# Extract exit code
|
260
|
-
match = re.search(r"exit code (\d+)", lifecycle_details)
|
261
|
-
if match:
|
262
|
-
exit_code = int(match.group(1))
|
263
|
-
if exit_code == 1:
|
264
|
-
return message
|
265
|
-
# Match exit code to message
|
266
|
-
exception = exit_code_dict().get(
|
267
|
-
exit_code,
|
268
|
-
lifecycle_details,
|
269
|
-
)
|
270
|
-
message = f"{exception.reason} (exit code {exit_code})"
|
271
|
-
except:
|
272
|
-
pass
|
273
|
-
|
274
|
-
return message
|
275
|
-
|
276
|
-
|
277
|
-
# TODO: merge metadata key used in create FT
|
278
|
-
|
279
|
-
|
280
|
-
class FineTuningCustomMetadata(Enum):
|
281
|
-
FT_SOURCE = "fine_tune_source"
|
282
|
-
FT_SOURCE_NAME = "fine_tune_source_name"
|
283
|
-
FT_OUTPUT_PATH = "fine_tune_output_path"
|
284
|
-
FT_JOB_ID = "fine_tune_job_id"
|
285
|
-
FT_JOB_RUN_ID = "fine_tune_jobrun_id"
|
286
|
-
TRAINING_METRICS_FINAL = "train_metrics_final"
|
287
|
-
VALIDATION_METRICS_FINAL = "val_metrics_final"
|
288
|
-
TRAINING_METRICS_EPOCH = "train_metrics_epoch"
|
289
|
-
VALIDATION_METRICS_EPOCH = "val_metrics_epoch"
|
290
|
-
|
291
|
-
|
292
59
|
class AquaModelApp(AquaApp):
|
293
60
|
"""Provides a suite of APIs to interact with Aqua models within the Oracle
|
294
61
|
Cloud Infrastructure Data Science service, serving as an interface for
|
@@ -305,6 +72,7 @@ class AquaModelApp(AquaApp):
|
|
305
72
|
Lists all Aqua models within a specified compartment and/or project.
|
306
73
|
clear_model_list_cache()
|
307
74
|
Allows clear list model cache items from the service models compartment.
|
75
|
+
register(model: str, os_path: str, local_dir: str = None)
|
308
76
|
|
309
77
|
Note:
|
310
78
|
This class is designed to work within the Oracle Cloud Infrastructure
|
@@ -382,13 +150,15 @@ class AquaModelApp(AquaApp):
|
|
382
150
|
return custom_model
|
383
151
|
|
384
152
|
@telemetry(entry_point="plugin=model&action=get", name="aqua")
|
385
|
-
def get(self, model_id) -> "AquaModel":
|
153
|
+
def get(self, model_id: str, load_model_card: Optional[bool] = True) -> "AquaModel":
|
386
154
|
"""Gets the information of an Aqua model.
|
387
155
|
|
388
156
|
Parameters
|
389
157
|
----------
|
390
158
|
model_id: str
|
391
159
|
The model OCID.
|
160
|
+
load_model_card: (bool, optional). Defaults to `True`.
|
161
|
+
Whether to load model card from artifacts or not.
|
392
162
|
|
393
163
|
Returns
|
394
164
|
-------
|
@@ -407,38 +177,57 @@ class AquaModelApp(AquaApp):
|
|
407
177
|
is_fine_tuned_model = (
|
408
178
|
True
|
409
179
|
if ds_model.freeform_tags
|
410
|
-
and ds_model.freeform_tags.get(Tags.AQUA_FINE_TUNED_MODEL_TAG
|
180
|
+
and ds_model.freeform_tags.get(Tags.AQUA_FINE_TUNED_MODEL_TAG)
|
411
181
|
else False
|
412
182
|
)
|
413
183
|
|
414
184
|
# todo: consolidate this logic in utils for model and deployment use
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
if not ObjectStorageDetails.is_oci_path(artifact_path):
|
420
|
-
artifact_path = ObjectStorageDetails(
|
421
|
-
AQUA_SERVICE_MODELS_BUCKET, CONDA_BUCKET_NS, artifact_path
|
422
|
-
).path
|
423
|
-
except ValueError:
|
424
|
-
artifact_path = utils.UNKNOWN
|
185
|
+
is_verified_type = (
|
186
|
+
ds_model.freeform_tags.get(Tags.READY_TO_IMPORT, "false").upper()
|
187
|
+
== READY_TO_IMPORT_STATUS
|
188
|
+
)
|
425
189
|
|
426
|
-
|
427
|
-
|
190
|
+
model_card = ""
|
191
|
+
if load_model_card:
|
192
|
+
artifact_path = get_artifact_path(
|
193
|
+
ds_model.custom_metadata_list._to_oci_metadata()
|
194
|
+
)
|
195
|
+
if artifact_path != UNKNOWN:
|
196
|
+
model_card = str(
|
197
|
+
read_file(
|
198
|
+
file_path=(
|
199
|
+
f"{artifact_path.rstrip('/')}/config/{README}"
|
200
|
+
if is_verified_type
|
201
|
+
else f"{artifact_path.rstrip('/')}/{README}"
|
202
|
+
),
|
203
|
+
auth=default_signer(),
|
204
|
+
)
|
205
|
+
)
|
428
206
|
|
429
|
-
|
207
|
+
inference_container = ds_model.custom_metadata_list.get(
|
208
|
+
ModelCustomMetadataFields.DEPLOYMENT_CONTAINER,
|
209
|
+
ModelCustomMetadataItem(key=ModelCustomMetadataFields.DEPLOYMENT_CONTAINER),
|
210
|
+
).value
|
211
|
+
evaluation_container = ds_model.custom_metadata_list.get(
|
212
|
+
ModelCustomMetadataFields.EVALUATION_CONTAINER,
|
213
|
+
ModelCustomMetadataItem(key=ModelCustomMetadataFields.EVALUATION_CONTAINER),
|
214
|
+
).value
|
215
|
+
finetuning_container: str = ds_model.custom_metadata_list.get(
|
216
|
+
ModelCustomMetadataFields.FINETUNE_CONTAINER,
|
217
|
+
ModelCustomMetadataItem(key=ModelCustomMetadataFields.FINETUNE_CONTAINER),
|
218
|
+
).value
|
219
|
+
|
220
|
+
aqua_model_attributes = dict(
|
430
221
|
**self._process_model(ds_model, self.region),
|
431
222
|
project_id=ds_model.project_id,
|
432
|
-
model_card=
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
)
|
437
|
-
),
|
223
|
+
model_card=model_card,
|
224
|
+
inference_container=inference_container,
|
225
|
+
finetuning_container=finetuning_container,
|
226
|
+
evaluation_container=evaluation_container,
|
438
227
|
)
|
439
228
|
|
440
229
|
if not is_fine_tuned_model:
|
441
|
-
model_details = AquaModel(**
|
230
|
+
model_details = AquaModel(**aqua_model_attributes)
|
442
231
|
self._service_model_details_cache.__setitem__(
|
443
232
|
key=model_id, value=model_details
|
444
233
|
)
|
@@ -455,7 +244,7 @@ class AquaModelApp(AquaApp):
|
|
455
244
|
|
456
245
|
try:
|
457
246
|
source_id = ds_model.custom_metadata_list.get(
|
458
|
-
FineTuningCustomMetadata.FT_SOURCE
|
247
|
+
FineTuningCustomMetadata.FT_SOURCE
|
459
248
|
).value
|
460
249
|
except ValueError as e:
|
461
250
|
logger.debug(str(e))
|
@@ -463,7 +252,7 @@ class AquaModelApp(AquaApp):
|
|
463
252
|
|
464
253
|
try:
|
465
254
|
source_name = ds_model.custom_metadata_list.get(
|
466
|
-
FineTuningCustomMetadata.FT_SOURCE_NAME
|
255
|
+
FineTuningCustomMetadata.FT_SOURCE_NAME
|
467
256
|
).value
|
468
257
|
except ValueError as e:
|
469
258
|
logger.debug(str(e))
|
@@ -494,7 +283,7 @@ class AquaModelApp(AquaApp):
|
|
494
283
|
)
|
495
284
|
|
496
285
|
model_details = AquaFineTuneModel(
|
497
|
-
**
|
286
|
+
**aqua_model_attributes,
|
498
287
|
source=source_identifier,
|
499
288
|
lifecycle_state=(
|
500
289
|
Model.LIFECYCLE_STATE_ACTIVE
|
@@ -541,29 +330,29 @@ class AquaModelApp(AquaApp):
|
|
541
330
|
|
542
331
|
validation_metrics = self._fetch_metric_from_metadata(
|
543
332
|
custom_metadata_list=custom_metadata_list,
|
544
|
-
target=FineTuningCustomMetadata.VALIDATION_METRICS_EPOCH
|
545
|
-
category=FineTuningMetricCategories.VALIDATION
|
333
|
+
target=FineTuningCustomMetadata.VALIDATION_METRICS_EPOCH,
|
334
|
+
category=FineTuningMetricCategories.VALIDATION,
|
546
335
|
metric_name=VALIDATION_METRICS,
|
547
336
|
)
|
548
337
|
|
549
338
|
training_metrics = self._fetch_metric_from_metadata(
|
550
339
|
custom_metadata_list=custom_metadata_list,
|
551
|
-
target=FineTuningCustomMetadata.TRAINING_METRICS_EPOCH
|
552
|
-
category=FineTuningMetricCategories.TRAINING
|
340
|
+
target=FineTuningCustomMetadata.TRAINING_METRICS_EPOCH,
|
341
|
+
category=FineTuningMetricCategories.TRAINING,
|
553
342
|
metric_name=TRINING_METRICS,
|
554
343
|
)
|
555
344
|
|
556
345
|
validation_final = self._fetch_metric_from_metadata(
|
557
346
|
custom_metadata_list=custom_metadata_list,
|
558
|
-
target=FineTuningCustomMetadata.VALIDATION_METRICS_FINAL
|
559
|
-
category=FineTuningMetricCategories.VALIDATION
|
347
|
+
target=FineTuningCustomMetadata.VALIDATION_METRICS_FINAL,
|
348
|
+
category=FineTuningMetricCategories.VALIDATION,
|
560
349
|
metric_name=VALIDATION_METRICS_FINAL,
|
561
350
|
)
|
562
351
|
|
563
352
|
training_final = self._fetch_metric_from_metadata(
|
564
353
|
custom_metadata_list=custom_metadata_list,
|
565
|
-
target=FineTuningCustomMetadata.TRAINING_METRICS_FINAL
|
566
|
-
category=FineTuningMetricCategories.TRAINING
|
354
|
+
target=FineTuningCustomMetadata.TRAINING_METRICS_FINAL,
|
355
|
+
category=FineTuningMetricCategories.TRAINING,
|
567
356
|
metric_name=TRAINING_METRICS_FINAL,
|
568
357
|
)
|
569
358
|
|
@@ -623,23 +412,27 @@ class AquaModelApp(AquaApp):
|
|
623
412
|
)
|
624
413
|
|
625
414
|
freeform_tags = model.freeform_tags or {}
|
626
|
-
is_fine_tuned_model = Tags.AQUA_FINE_TUNED_MODEL_TAG
|
415
|
+
is_fine_tuned_model = Tags.AQUA_FINE_TUNED_MODEL_TAG in freeform_tags
|
627
416
|
ready_to_deploy = (
|
628
|
-
freeform_tags.get(Tags.AQUA_TAG
|
417
|
+
freeform_tags.get(Tags.AQUA_TAG, "").upper() == READY_TO_DEPLOY_STATUS
|
629
418
|
)
|
630
419
|
ready_to_finetune = (
|
631
|
-
freeform_tags.get(Tags.READY_TO_FINE_TUNE
|
420
|
+
freeform_tags.get(Tags.READY_TO_FINE_TUNE, "").upper()
|
632
421
|
== READY_TO_FINE_TUNE_STATUS
|
633
422
|
)
|
423
|
+
ready_to_import = (
|
424
|
+
freeform_tags.get(Tags.READY_TO_IMPORT, "").upper()
|
425
|
+
== READY_TO_IMPORT_STATUS
|
426
|
+
)
|
634
427
|
|
635
428
|
return dict(
|
636
429
|
compartment_id=model.compartment_id,
|
637
430
|
icon=icon or UNKNOWN,
|
638
431
|
id=model_id,
|
639
|
-
license=freeform_tags.get(Tags.LICENSE
|
432
|
+
license=freeform_tags.get(Tags.LICENSE, UNKNOWN),
|
640
433
|
name=model.display_name,
|
641
|
-
organization=freeform_tags.get(Tags.ORGANIZATION
|
642
|
-
task=freeform_tags.get(Tags.TASK
|
434
|
+
organization=freeform_tags.get(Tags.ORGANIZATION, UNKNOWN),
|
435
|
+
task=freeform_tags.get(Tags.TASK, UNKNOWN),
|
643
436
|
time_created=model.time_created,
|
644
437
|
is_fine_tuned_model=is_fine_tuned_model,
|
645
438
|
tags=tags,
|
@@ -647,11 +440,16 @@ class AquaModelApp(AquaApp):
|
|
647
440
|
search_text=search_text,
|
648
441
|
ready_to_deploy=ready_to_deploy,
|
649
442
|
ready_to_finetune=ready_to_finetune,
|
443
|
+
ready_to_import=ready_to_import,
|
650
444
|
)
|
651
445
|
|
652
446
|
@telemetry(entry_point="plugin=model&action=list", name="aqua")
|
653
447
|
def list(
|
654
|
-
self,
|
448
|
+
self,
|
449
|
+
compartment_id: str = None,
|
450
|
+
project_id: str = None,
|
451
|
+
model_type: str = None,
|
452
|
+
**kwargs,
|
655
453
|
) -> List["AquaModelSummary"]:
|
656
454
|
"""Lists all Aqua models within a specified compartment and/or project.
|
657
455
|
If `compartment_id` is not specified, the method defaults to returning
|
@@ -665,6 +463,8 @@ class AquaModelApp(AquaApp):
|
|
665
463
|
The compartment OCID.
|
666
464
|
project_id: (str, optional). Defaults to `None`.
|
667
465
|
The project OCID.
|
466
|
+
model_type: (str, optional). Defaults to `None`.
|
467
|
+
Model type represents the type of model in the user compartment, can be either FT or BASE.
|
668
468
|
**kwargs:
|
669
469
|
Additional keyword arguments that can be used to filter the results.
|
670
470
|
|
@@ -682,7 +482,8 @@ class AquaModelApp(AquaApp):
|
|
682
482
|
)
|
683
483
|
|
684
484
|
logger.info(f"Fetching custom models from compartment_id={compartment_id}.")
|
685
|
-
|
485
|
+
model_type = model_type.upper() if model_type else ModelType.FT
|
486
|
+
models = self._rqs(compartment_id, model_type=model_type)
|
686
487
|
else:
|
687
488
|
# tracks number of times service model listing was called
|
688
489
|
self.telemetry.record_event_async(
|
@@ -751,16 +552,275 @@ class AquaModelApp(AquaApp):
|
|
751
552
|
}
|
752
553
|
return res
|
753
554
|
|
555
|
+
def _create_model_catalog_entry(
|
556
|
+
self,
|
557
|
+
os_path: str,
|
558
|
+
model_name: str,
|
559
|
+
inference_container: str,
|
560
|
+
finetuning_container: str,
|
561
|
+
verified_model: DataScienceModel,
|
562
|
+
compartment_id: Optional[str],
|
563
|
+
project_id: Optional[str],
|
564
|
+
) -> DataScienceModel:
|
565
|
+
"""Create model by reference from the object storage path
|
566
|
+
|
567
|
+
Args:
|
568
|
+
os_path (str): OCI where the model is uploaded - oci://bucket@namespace/prefix
|
569
|
+
model_name (str): name of the model
|
570
|
+
inference_container (str): selects service defaults
|
571
|
+
finetuning_container (str): selects service defaults
|
572
|
+
verified_model (DataScienceModel): If set, then copies all the tags and custom metadata information from the service verified model
|
573
|
+
compartment_id (Optional[str]): Compartment Id of the compartment where the model has to be created
|
574
|
+
project_id (Optional[str]): Project id of the project where the model has to be created
|
575
|
+
|
576
|
+
Returns:
|
577
|
+
DataScienceModel: Returns Datascience model instance.
|
578
|
+
"""
|
579
|
+
model = DataScienceModel()
|
580
|
+
tags = (
|
581
|
+
{
|
582
|
+
**verified_model.freeform_tags,
|
583
|
+
Tags.AQUA_SERVICE_MODEL_TAG: verified_model.id,
|
584
|
+
}
|
585
|
+
if verified_model
|
586
|
+
else {Tags.AQUA_TAG: "active", Tags.BASE_MODEL_CUSTOM: "true"}
|
587
|
+
)
|
588
|
+
tags.update({Tags.BASE_MODEL_CUSTOM: "true"})
|
589
|
+
|
590
|
+
# Remove `ready_to_import` tag that might get copied from service model.
|
591
|
+
tags.pop(Tags.READY_TO_IMPORT, None)
|
592
|
+
metadata = None
|
593
|
+
if verified_model:
|
594
|
+
# Verified model is a model in the service catalog that either has no artifacts but contains all the necessary metadata for deploying and fine tuning.
|
595
|
+
# If set, then we copy all the model metadata.
|
596
|
+
metadata = verified_model.custom_metadata_list
|
597
|
+
if verified_model.model_file_description:
|
598
|
+
model = model.with_model_file_description(
|
599
|
+
json_dict=verified_model.model_file_description
|
600
|
+
)
|
601
|
+
|
602
|
+
else:
|
603
|
+
metadata = ModelCustomMetadata()
|
604
|
+
if not inference_container:
|
605
|
+
raise AquaRuntimeError(
|
606
|
+
f"Require Inference container information. Model: {model_name} does not have associated inference container defaults. Check docs for more information on how to pass inference container."
|
607
|
+
)
|
608
|
+
if finetuning_container:
|
609
|
+
tags[Tags.READY_TO_FINE_TUNE] = "true"
|
610
|
+
metadata.add(
|
611
|
+
key=AQUA_FINETUNING_CONTAINER_METADATA_NAME,
|
612
|
+
value=finetuning_container,
|
613
|
+
description=f"Fine-tuning container mapping for {model_name}",
|
614
|
+
category="Other",
|
615
|
+
)
|
616
|
+
else:
|
617
|
+
logger.warn(
|
618
|
+
f"Proceeding with model registration without the fine-tuning container information. "
|
619
|
+
f"This model will not be available for fine tuning."
|
620
|
+
)
|
621
|
+
|
622
|
+
metadata.add(
|
623
|
+
key=AQUA_DEPLOYMENT_CONTAINER_METADATA_NAME,
|
624
|
+
value=inference_container,
|
625
|
+
description=f"Inference container mapping for {model_name}",
|
626
|
+
category="Other",
|
627
|
+
)
|
628
|
+
metadata.add(
|
629
|
+
key=AQUA_EVALUATION_CONTAINER_METADATA_NAME,
|
630
|
+
value="odsc-llm-evaluate",
|
631
|
+
description="Evaluation container mapping for SMC",
|
632
|
+
category="Other",
|
633
|
+
)
|
634
|
+
# TODO: either get task and organization from user or a config file
|
635
|
+
# tags["task"] = "UNKNOWN"
|
636
|
+
# tags["organization"] = "UNKNOWN"
|
637
|
+
|
638
|
+
try:
|
639
|
+
# If verified model already has a artifact json, use that.
|
640
|
+
artifact_path = metadata.get(MODEL_BY_REFERENCE_OSS_PATH_KEY).value
|
641
|
+
logger.info(
|
642
|
+
f"Found model artifact in the service bucket. "
|
643
|
+
f"Using artifact from service bucket instead of {os_path}"
|
644
|
+
)
|
645
|
+
|
646
|
+
# todo: implement generic copy_folder method
|
647
|
+
# copy model config from artifact path to user bucket
|
648
|
+
copy_model_config(
|
649
|
+
artifact_path=artifact_path, os_path=os_path, auth=default_signer()
|
650
|
+
)
|
651
|
+
|
652
|
+
except:
|
653
|
+
# Add artifact from user bucket
|
654
|
+
metadata.add(
|
655
|
+
key=MODEL_BY_REFERENCE_OSS_PATH_KEY,
|
656
|
+
value=os_path,
|
657
|
+
description="artifact location",
|
658
|
+
category="Other",
|
659
|
+
)
|
660
|
+
|
661
|
+
model = (
|
662
|
+
model.with_custom_metadata_list(metadata)
|
663
|
+
.with_compartment_id(compartment_id or COMPARTMENT_OCID)
|
664
|
+
.with_project_id(project_id or PROJECT_OCID)
|
665
|
+
.with_artifact(os_path)
|
666
|
+
.with_display_name(model_name)
|
667
|
+
.with_freeform_tags(**tags)
|
668
|
+
).create(model_by_reference=True)
|
669
|
+
logger.debug(model)
|
670
|
+
return model
|
671
|
+
|
672
|
+
def register(
|
673
|
+
self, import_model_details: ImportModelDetails = None, **kwargs
|
674
|
+
) -> AquaModel:
|
675
|
+
"""Loads the model from object storage and registers as Model in Data Science Model catalog
|
676
|
+
The inference container and finetuning container could be of type Service Manged Container(SMC) or custom.
|
677
|
+
If it is custom, full container URI is expected. If it of type SMC, only the container family name is expected.
|
678
|
+
|
679
|
+
Args:
|
680
|
+
import_model_details (ImportModelDetails): Model details for importing the model.
|
681
|
+
kwargs:
|
682
|
+
model (str): name of the model or OCID of the service model that has inference and finetuning information
|
683
|
+
os_path (str): Object storage destination URI to store the downloaded model. Format: oci://bucket-name@namespace/prefix
|
684
|
+
inference_container (str): selects service defaults
|
685
|
+
finetuning_container (str): selects service defaults
|
686
|
+
|
687
|
+
Returns:
|
688
|
+
AquaModel:
|
689
|
+
The registered model as a AquaModel object.
|
690
|
+
"""
|
691
|
+
verified_model_details: DataScienceModel = None
|
692
|
+
|
693
|
+
if not import_model_details:
|
694
|
+
import_model_details = ImportModelDetails(**kwargs)
|
695
|
+
|
696
|
+
try:
|
697
|
+
model_config = load_config(
|
698
|
+
file_path=import_model_details.os_path,
|
699
|
+
config_file_name=AQUA_MODEL_ARTIFACT_CONFIG,
|
700
|
+
)
|
701
|
+
except Exception as ex:
|
702
|
+
logger.error(
|
703
|
+
f"Exception occurred while loading config file from {import_model_details.os_path}"
|
704
|
+
f"Exception message: {ex}"
|
705
|
+
)
|
706
|
+
raise AquaRuntimeError(
|
707
|
+
f"The model path {import_model_details.os_path} does not contain the file config.json. "
|
708
|
+
f"Please check if the path is correct or the model artifacts are available at this location."
|
709
|
+
)
|
710
|
+
|
711
|
+
model_service_id = None
|
712
|
+
# If OCID of a model is passed, we need to copy the defaults for Tags and metadata from the service model.
|
713
|
+
if (
|
714
|
+
import_model_details.model.startswith("ocid")
|
715
|
+
and "datasciencemodel" in import_model_details.model
|
716
|
+
):
|
717
|
+
model_service_id = import_model_details.model
|
718
|
+
else:
|
719
|
+
# If users passes model name, check if there is model with the same name in the service model catalog. If it is there, then use that model
|
720
|
+
model_service_id = self._find_matching_aqua_model(
|
721
|
+
import_model_details.model
|
722
|
+
)
|
723
|
+
logger.info(
|
724
|
+
f"Found service model for {import_model_details.model}: {model_service_id}"
|
725
|
+
)
|
726
|
+
if model_service_id:
|
727
|
+
verified_model_details = DataScienceModel.from_id(model_service_id)
|
728
|
+
try:
|
729
|
+
metadata_model_type = verified_model_details.custom_metadata_list.get(
|
730
|
+
AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE
|
731
|
+
).value
|
732
|
+
if metadata_model_type:
|
733
|
+
if AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE in model_config:
|
734
|
+
if (
|
735
|
+
model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE]
|
736
|
+
!= metadata_model_type
|
737
|
+
):
|
738
|
+
raise AquaRuntimeError(
|
739
|
+
f"The {AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE} attribute in {AQUA_MODEL_ARTIFACT_CONFIG}"
|
740
|
+
f" at {import_model_details.os_path} is invalid, expected {metadata_model_type} for "
|
741
|
+
f"the model {import_model_details.model}. Please check if the path is correct or "
|
742
|
+
f"the correct model artifacts are available at this location."
|
743
|
+
f""
|
744
|
+
)
|
745
|
+
else:
|
746
|
+
logger.debug(
|
747
|
+
f"Could not find {AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE} attribute in "
|
748
|
+
f"{AQUA_MODEL_ARTIFACT_CONFIG}. Proceeding with model registration."
|
749
|
+
)
|
750
|
+
except:
|
751
|
+
pass
|
752
|
+
|
753
|
+
# Copy the model name from the service model if `model` is ocid
|
754
|
+
model_name = (
|
755
|
+
verified_model_details.display_name
|
756
|
+
if verified_model_details
|
757
|
+
else import_model_details.model
|
758
|
+
)
|
759
|
+
|
760
|
+
# Create Model catalog entry with pass by reference
|
761
|
+
ds_model = self._create_model_catalog_entry(
|
762
|
+
os_path=import_model_details.os_path,
|
763
|
+
model_name=model_name,
|
764
|
+
inference_container=import_model_details.inference_container,
|
765
|
+
finetuning_container=import_model_details.finetuning_container,
|
766
|
+
verified_model=verified_model_details,
|
767
|
+
compartment_id=import_model_details.compartment_id,
|
768
|
+
project_id=import_model_details.project_id,
|
769
|
+
)
|
770
|
+
# registered model will always have inference and evaluation container, but
|
771
|
+
# fine-tuning container may be not set
|
772
|
+
inference_container = ds_model.custom_metadata_list.get(
|
773
|
+
ModelCustomMetadataFields.DEPLOYMENT_CONTAINER
|
774
|
+
).value
|
775
|
+
evaluation_container = ds_model.custom_metadata_list.get(
|
776
|
+
ModelCustomMetadataFields.EVALUATION_CONTAINER,
|
777
|
+
).value
|
778
|
+
try:
|
779
|
+
finetuning_container = ds_model.custom_metadata_list.get(
|
780
|
+
ModelCustomMetadataFields.FINETUNE_CONTAINER,
|
781
|
+
).value
|
782
|
+
except:
|
783
|
+
finetuning_container = None
|
784
|
+
|
785
|
+
aqua_model_attributes = dict(
|
786
|
+
**self._process_model(ds_model, self.region),
|
787
|
+
project_id=ds_model.project_id,
|
788
|
+
model_card=str(
|
789
|
+
read_file(
|
790
|
+
file_path=f"{import_model_details.os_path.rstrip('/')}/{README}",
|
791
|
+
auth=default_signer(),
|
792
|
+
)
|
793
|
+
),
|
794
|
+
inference_container=inference_container,
|
795
|
+
finetuning_container=finetuning_container,
|
796
|
+
evaluation_container=evaluation_container,
|
797
|
+
)
|
798
|
+
|
799
|
+
if verified_model_details:
|
800
|
+
telemetry_model_name = model_name
|
801
|
+
else:
|
802
|
+
if AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME in model_config:
|
803
|
+
telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME]}"
|
804
|
+
elif AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE in model_config:
|
805
|
+
telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE]}"
|
806
|
+
else:
|
807
|
+
telemetry_model_name = AQUA_MODEL_TYPE_CUSTOM
|
808
|
+
|
809
|
+
self.telemetry.record_event_async(
|
810
|
+
category="aqua/model",
|
811
|
+
action="register",
|
812
|
+
detail=telemetry_model_name,
|
813
|
+
)
|
814
|
+
|
815
|
+
return AquaModel(**aqua_model_attributes)
|
816
|
+
|
754
817
|
def _if_show(self, model: DataScienceModel) -> bool:
|
755
818
|
"""Determine if the given model should be return by `list`."""
|
756
819
|
if model.freeform_tags is None:
|
757
820
|
return False
|
758
821
|
|
759
822
|
TARGET_TAGS = model.freeform_tags.keys()
|
760
|
-
return (
|
761
|
-
Tags.AQUA_TAG.value in TARGET_TAGS
|
762
|
-
or Tags.AQUA_TAG.value.lower() in TARGET_TAGS
|
763
|
-
)
|
823
|
+
return Tags.AQUA_TAG in TARGET_TAGS or Tags.AQUA_TAG.lower() in TARGET_TAGS
|
764
824
|
|
765
825
|
def _load_icon(self, model_name: str) -> str:
|
766
826
|
"""Loads icon."""
|
@@ -772,10 +832,18 @@ class AquaModelApp(AquaApp):
|
|
772
832
|
logger.debug(f"Failed to load icon for the model={model_name}: {str(e)}.")
|
773
833
|
return None
|
774
834
|
|
775
|
-
def _rqs(self, compartment_id: str, **kwargs):
|
835
|
+
def _rqs(self, compartment_id: str, model_type="FT", **kwargs):
|
776
836
|
"""Use RQS to fetch models in the user tenancy."""
|
837
|
+
if model_type == ModelType.FT:
|
838
|
+
filter_tag = Tags.AQUA_FINE_TUNED_MODEL_TAG
|
839
|
+
elif model_type == ModelType.BASE:
|
840
|
+
filter_tag = Tags.BASE_MODEL_CUSTOM
|
841
|
+
else:
|
842
|
+
raise ValueError(
|
843
|
+
f"Model of type {model_type} is unknown. The values should be in {ModelType.values()}"
|
844
|
+
)
|
777
845
|
|
778
|
-
condition_tags = f"&& (freeformTags.key = '{Tags.AQUA_TAG
|
846
|
+
condition_tags = f"&& (freeformTags.key = '{Tags.AQUA_TAG}' && freeformTags.key = '{filter_tag}')"
|
779
847
|
condition_lifecycle = "&& lifecycleState = 'ACTIVE'"
|
780
848
|
query = f"query datasciencemodel resources where (compartmentId = '{compartment_id}' {condition_lifecycle} {condition_tags})"
|
781
849
|
logger.info(query)
|
@@ -820,3 +888,27 @@ class AquaModelApp(AquaApp):
|
|
820
888
|
)
|
821
889
|
|
822
890
|
return AquaModelLicense(id=model_id, license=content)
|
891
|
+
|
892
|
+
def _find_matching_aqua_model(self, model_id: str) -> Optional[str]:
|
893
|
+
"""
|
894
|
+
Finds a matching model in AQUA based on the model ID from list of verified models.
|
895
|
+
|
896
|
+
Parameters
|
897
|
+
----------
|
898
|
+
model_id (str): Verified model ID to match.
|
899
|
+
|
900
|
+
Returns
|
901
|
+
-------
|
902
|
+
Optional[str]
|
903
|
+
Returns model ocid that matches the model in the service catalog else returns None.
|
904
|
+
"""
|
905
|
+
# Convert the model ID to lowercase once
|
906
|
+
model_id_lower = model_id.lower()
|
907
|
+
|
908
|
+
aqua_model_list = self.list()
|
909
|
+
|
910
|
+
for aqua_model_summary in aqua_model_list:
|
911
|
+
if aqua_model_summary.name.lower() == model_id_lower:
|
912
|
+
return aqua_model_summary.id
|
913
|
+
|
914
|
+
return None
|