oracle-ads 2.13.8__py3-none-any.whl → 2.13.9__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/app.py +1 -0
- ads/aqua/common/entities.py +8 -0
- ads/aqua/common/enums.py +6 -0
- ads/aqua/common/utils.py +49 -39
- ads/aqua/config/container_config.py +38 -39
- ads/aqua/constants.py +2 -0
- ads/aqua/extension/ui_handler.py +19 -1
- ads/aqua/finetuning/finetuning.py +18 -0
- ads/aqua/model/entities.py +81 -2
- ads/aqua/model/enums.py +4 -2
- ads/aqua/model/model.py +73 -19
- ads/aqua/model/utils.py +52 -0
- ads/aqua/modeldeployment/deployment.py +23 -35
- ads/aqua/ui.py +20 -0
- ads/common/oci_client.py +8 -4
- ads/config.py +1 -0
- ads/opctl/operator/lowcode/forecast/model/base_model.py +14 -4
- ads/opctl/operator/lowcode/forecast/model/prophet.py +1 -1
- ads/telemetry/client.py +5 -8
- {oracle_ads-2.13.8.dist-info → oracle_ads-2.13.9.dist-info}/METADATA +7 -6
- {oracle_ads-2.13.8.dist-info → oracle_ads-2.13.9.dist-info}/RECORD +24 -23
- {oracle_ads-2.13.8.dist-info → oracle_ads-2.13.9.dist-info}/WHEEL +0 -0
- {oracle_ads-2.13.8.dist-info → oracle_ads-2.13.9.dist-info}/entry_points.txt +0 -0
- {oracle_ads-2.13.8.dist-info → oracle_ads-2.13.9.dist-info}/licenses/LICENSE.txt +0 -0
ads/aqua/app.py
CHANGED
@@ -64,6 +64,7 @@ class AquaApp:
|
|
64
64
|
set_auth("resource_principal")
|
65
65
|
self._auth = default_signer({"service_endpoint": OCI_ODSC_SERVICE_ENDPOINT})
|
66
66
|
self.ds_client = oc.OCIClientFactory(**self._auth).data_science
|
67
|
+
self.compute_client = oc.OCIClientFactory(**default_signer()).compute
|
67
68
|
self.logging_client = oc.OCIClientFactory(**default_signer()).logging_management
|
68
69
|
self.identity_client = oc.OCIClientFactory(**default_signer()).identity
|
69
70
|
self.region = extract_region(self._auth)
|
ads/aqua/common/entities.py
CHANGED
@@ -151,10 +151,14 @@ class AquaMultiModelRef(Serializable):
|
|
151
151
|
The name of the model.
|
152
152
|
gpu_count : Optional[int]
|
153
153
|
Number of GPUs required for deployment.
|
154
|
+
model_task : Optional[str]
|
155
|
+
The task that model operates on. Supported tasks are in MultiModelSupportedTaskType
|
154
156
|
env_var : Optional[Dict[str, Any]]
|
155
157
|
Optional environment variables to override during deployment.
|
156
158
|
artifact_location : Optional[str]
|
157
159
|
Artifact path of model in the multimodel group.
|
160
|
+
fine_tune_weights_location : Optional[str]
|
161
|
+
For fine tuned models, the artifact path of the modified model weights
|
158
162
|
"""
|
159
163
|
|
160
164
|
model_id: str = Field(..., description="The model OCID to deploy.")
|
@@ -162,12 +166,16 @@ class AquaMultiModelRef(Serializable):
|
|
162
166
|
gpu_count: Optional[int] = Field(
|
163
167
|
None, description="The gpu count allocation for the model."
|
164
168
|
)
|
169
|
+
model_task: Optional[str] = Field(None, description="The task that model operates on. Supported tasks are in MultiModelSupportedTaskType")
|
165
170
|
env_var: Optional[dict] = Field(
|
166
171
|
default_factory=dict, description="The environment variables of the model."
|
167
172
|
)
|
168
173
|
artifact_location: Optional[str] = Field(
|
169
174
|
None, description="Artifact path of model in the multimodel group."
|
170
175
|
)
|
176
|
+
fine_tune_weights_location: Optional[str] = Field(
|
177
|
+
None, description="For fine tuned models, the artifact path of the modified model weights"
|
178
|
+
)
|
171
179
|
|
172
180
|
class Config:
|
173
181
|
extra = "ignore"
|
ads/aqua/common/enums.py
CHANGED
@@ -49,6 +49,7 @@ class InferenceContainerType(ExtendedEnum):
|
|
49
49
|
class InferenceContainerTypeFamily(ExtendedEnum):
|
50
50
|
AQUA_VLLM_CONTAINER_FAMILY = "odsc-vllm-serving"
|
51
51
|
AQUA_VLLM_V1_CONTAINER_FAMILY = "odsc-vllm-serving-v1"
|
52
|
+
AQUA_VLLM_LLAMA4_CONTAINER_FAMILY = "odsc-vllm-serving-llama4"
|
52
53
|
AQUA_TGI_CONTAINER_FAMILY = "odsc-tgi-serving"
|
53
54
|
AQUA_LLAMA_CPP_CONTAINER_FAMILY = "odsc-llama-cpp-serving"
|
54
55
|
|
@@ -119,4 +120,9 @@ CONTAINER_FAMILY_COMPATIBILITY: Dict[str, List[str]] = {
|
|
119
120
|
InferenceContainerTypeFamily.AQUA_VLLM_V1_CONTAINER_FAMILY,
|
120
121
|
InferenceContainerTypeFamily.AQUA_VLLM_CONTAINER_FAMILY,
|
121
122
|
],
|
123
|
+
InferenceContainerTypeFamily.AQUA_VLLM_LLAMA4_CONTAINER_FAMILY: [
|
124
|
+
InferenceContainerTypeFamily.AQUA_VLLM_LLAMA4_CONTAINER_FAMILY,
|
125
|
+
InferenceContainerTypeFamily.AQUA_VLLM_V1_CONTAINER_FAMILY,
|
126
|
+
InferenceContainerTypeFamily.AQUA_VLLM_CONTAINER_FAMILY,
|
127
|
+
],
|
122
128
|
}
|
ads/aqua/common/utils.py
CHANGED
@@ -832,7 +832,9 @@ def get_params_dict(params: Union[str, List[str]]) -> dict:
|
|
832
832
|
"""
|
833
833
|
params_list = get_params_list(params) if isinstance(params, str) else params
|
834
834
|
return {
|
835
|
-
split_result[0]: split_result[1]
|
835
|
+
split_result[0]: " ".join(split_result[1:])
|
836
|
+
if len(split_result) > 1
|
837
|
+
else UNKNOWN
|
836
838
|
for split_result in (x.split() for x in params_list)
|
837
839
|
}
|
838
840
|
|
@@ -881,7 +883,9 @@ def build_params_string(params: dict) -> str:
|
|
881
883
|
A params string.
|
882
884
|
"""
|
883
885
|
return (
|
884
|
-
" ".join(
|
886
|
+
" ".join(
|
887
|
+
f"{name} {value}" if value else f"{name}" for name, value in params.items()
|
888
|
+
).strip()
|
885
889
|
if params
|
886
890
|
else UNKNOWN
|
887
891
|
)
|
@@ -1158,9 +1162,11 @@ def validate_cmd_var(cmd_var: List[str], overrides: List[str]) -> List[str]:
|
|
1158
1162
|
|
1159
1163
|
|
1160
1164
|
def build_pydantic_error_message(ex: ValidationError):
|
1161
|
-
"""
|
1165
|
+
"""
|
1166
|
+
Added to handle error messages from pydantic model validator.
|
1162
1167
|
Combine both loc and msg for errors where loc (field) is present in error details, else only build error
|
1163
|
-
message using msg field.
|
1168
|
+
message using msg field.
|
1169
|
+
"""
|
1164
1170
|
|
1165
1171
|
return {
|
1166
1172
|
".".join(map(str, e["loc"])): e["msg"]
|
@@ -1185,67 +1191,71 @@ def is_pydantic_model(obj: object) -> bool:
|
|
1185
1191
|
|
1186
1192
|
@cached(cache=TTLCache(maxsize=1, ttl=timedelta(minutes=5), timer=datetime.now))
|
1187
1193
|
def load_gpu_shapes_index(
|
1188
|
-
auth: Optional[Dict] = None,
|
1194
|
+
auth: Optional[Dict[str, Any]] = None,
|
1189
1195
|
) -> GPUShapesIndex:
|
1190
1196
|
"""
|
1191
|
-
|
1197
|
+
Load the GPU shapes index, preferring the OS bucket copy over the local one.
|
1192
1198
|
|
1193
|
-
|
1194
|
-
|
1195
|
-
loading the index from a local file.
|
1199
|
+
Attempts to read `gpu_shapes_index.json` from OCI Object Storage first;
|
1200
|
+
if that succeeds, those entries will override the local defaults.
|
1196
1201
|
|
1197
1202
|
Parameters
|
1198
1203
|
----------
|
1199
|
-
auth
|
1200
|
-
|
1201
|
-
|
1202
|
-
authentication signer and kwargs required to instantiate IdentityClient object.
|
1204
|
+
auth
|
1205
|
+
Optional auth dict (as returned by `ads.common.auth.default_signer()`)
|
1206
|
+
to pass through to `fsspec.open()`.
|
1203
1207
|
|
1204
1208
|
Returns
|
1205
1209
|
-------
|
1206
|
-
GPUShapesIndex
|
1210
|
+
GPUShapesIndex
|
1211
|
+
Merged index where any shape present remotely supersedes the local entry.
|
1207
1212
|
|
1208
1213
|
Raises
|
1209
1214
|
------
|
1210
|
-
|
1211
|
-
|
1215
|
+
json.JSONDecodeError
|
1216
|
+
If any of the JSON is malformed.
|
1212
1217
|
"""
|
1213
1218
|
file_name = "gpu_shapes_index.json"
|
1214
|
-
data: Dict[str, Any] = {}
|
1215
1219
|
|
1216
|
-
#
|
1220
|
+
# Try remote load
|
1221
|
+
remote_data: Dict[str, Any] = {}
|
1217
1222
|
if CONDA_BUCKET_NS:
|
1218
1223
|
try:
|
1219
1224
|
auth = auth or authutil.default_signer()
|
1220
|
-
# Construct the object storage path. Adjust bucket name and path as needed.
|
1221
1225
|
storage_path = (
|
1222
1226
|
f"oci://{CONDA_BUCKET_NAME}@{CONDA_BUCKET_NS}/service_pack/{file_name}"
|
1223
1227
|
)
|
1224
|
-
logger.debug("Loading GPU shapes index from Object Storage")
|
1225
|
-
with fsspec.open(storage_path, mode="r", **auth) as file_obj:
|
1226
|
-
data = json.load(file_obj)
|
1227
|
-
logger.debug("Successfully loaded GPU shapes index.")
|
1228
|
-
except Exception as ex:
|
1229
1228
|
logger.debug(
|
1230
|
-
|
1231
|
-
)
|
1232
|
-
|
1233
|
-
# If loading from Object Storage failed, load from the local resource folder.
|
1234
|
-
if not data:
|
1235
|
-
try:
|
1236
|
-
local_path = os.path.join(
|
1237
|
-
os.path.dirname(__file__), "../resources", file_name
|
1229
|
+
"Loading GPU shapes index from Object Storage: %s", storage_path
|
1238
1230
|
)
|
1239
|
-
|
1240
|
-
|
1241
|
-
data = json.load(file_obj)
|
1242
|
-
logger.debug("Successfully loaded GPU shapes index.")
|
1243
|
-
except Exception as e:
|
1231
|
+
with fsspec.open(storage_path, mode="r", **auth) as f:
|
1232
|
+
remote_data = json.load(f)
|
1244
1233
|
logger.debug(
|
1245
|
-
|
1234
|
+
"Loaded %d shapes from Object Storage",
|
1235
|
+
len(remote_data.get("shapes", {})),
|
1246
1236
|
)
|
1237
|
+
except Exception as ex:
|
1238
|
+
logger.debug("Remote load failed (%s); falling back to local", ex)
|
1239
|
+
|
1240
|
+
# Load local copy
|
1241
|
+
local_data: Dict[str, Any] = {}
|
1242
|
+
local_path = os.path.join(os.path.dirname(__file__), "../resources", file_name)
|
1243
|
+
try:
|
1244
|
+
logger.debug("Loading GPU shapes index from local file: %s", local_path)
|
1245
|
+
with open(local_path) as f:
|
1246
|
+
local_data = json.load(f)
|
1247
|
+
logger.debug(
|
1248
|
+
"Loaded %d shapes from local file", len(local_data.get("shapes", {}))
|
1249
|
+
)
|
1250
|
+
except Exception as ex:
|
1251
|
+
logger.debug("Local load GPU shapes index failed (%s)", ex)
|
1252
|
+
|
1253
|
+
# Merge: remote shapes override local
|
1254
|
+
local_shapes = local_data.get("shapes", {})
|
1255
|
+
remote_shapes = remote_data.get("shapes", {})
|
1256
|
+
merged_shapes = {**local_shapes, **remote_shapes}
|
1247
1257
|
|
1248
|
-
return GPUShapesIndex(
|
1258
|
+
return GPUShapesIndex(shapes=merged_shapes)
|
1249
1259
|
|
1250
1260
|
|
1251
1261
|
def get_preferred_compatible_family(selected_families: set[str]) -> str:
|
@@ -7,6 +7,7 @@ from typing import Dict, List, Optional
|
|
7
7
|
from oci.data_science.models import ContainerSummary
|
8
8
|
from pydantic import Field
|
9
9
|
|
10
|
+
from ads.aqua import logger
|
10
11
|
from ads.aqua.config.utils.serializer import Serializable
|
11
12
|
from ads.aqua.constants import (
|
12
13
|
SERVICE_MANAGED_CONTAINER_URI_SCHEME,
|
@@ -168,50 +169,47 @@ class AquaContainerConfig(Serializable):
|
|
168
169
|
container_type = container.family_name
|
169
170
|
usages = [x.upper() for x in container.usages]
|
170
171
|
if "INFERENCE" in usages or "MULTI_MODEL" in usages:
|
172
|
+
# Extract additional configurations
|
173
|
+
additional_configurations = {}
|
174
|
+
try:
|
175
|
+
additional_configurations = (
|
176
|
+
container.workload_configuration_details_list[
|
177
|
+
0
|
178
|
+
].additional_configurations
|
179
|
+
)
|
180
|
+
except (AttributeError, IndexError) as ex:
|
181
|
+
logger.debug(
|
182
|
+
"Failed to extract `additional_configurations` for container '%s': %s",
|
183
|
+
getattr(container, "container_name", "<unknown>"),
|
184
|
+
ex,
|
185
|
+
)
|
186
|
+
|
171
187
|
container_item.platforms.append(
|
172
|
-
|
173
|
-
0
|
174
|
-
].additional_configurations.get("platforms")
|
188
|
+
additional_configurations.get("platforms")
|
175
189
|
)
|
176
190
|
container_item.model_formats.append(
|
177
|
-
|
178
|
-
0
|
179
|
-
].additional_configurations.get("modelFormats")
|
191
|
+
additional_configurations.get("modelFormats")
|
180
192
|
)
|
193
|
+
|
194
|
+
# Parse environment variables from `additional_configurations`.
|
195
|
+
# Only keys present in the configuration will be added to the result.
|
196
|
+
config_keys = {
|
197
|
+
"MODEL_DEPLOY_PREDICT_ENDPOINT": UNKNOWN,
|
198
|
+
"MODEL_DEPLOY_HEALTH_ENDPOINT": UNKNOWN,
|
199
|
+
"MODEL_DEPLOY_ENABLE_STREAMING": UNKNOWN,
|
200
|
+
"PORT": UNKNOWN,
|
201
|
+
"HEALTH_CHECK_PORT": UNKNOWN,
|
202
|
+
"VLLM_USE_V1": UNKNOWN,
|
203
|
+
}
|
204
|
+
|
181
205
|
env_vars = [
|
182
|
-
{
|
183
|
-
|
184
|
-
|
185
|
-
].additional_configurations.get(
|
186
|
-
"MODEL_DEPLOY_PREDICT_ENDPOINT", UNKNOWN
|
187
|
-
)
|
188
|
-
},
|
189
|
-
{
|
190
|
-
"MODEL_DEPLOY_HEALTH_ENDPOINT": container.workload_configuration_details_list[
|
191
|
-
0
|
192
|
-
].additional_configurations.get(
|
193
|
-
"MODEL_DEPLOY_HEALTH_ENDPOINT", UNKNOWN
|
194
|
-
)
|
195
|
-
},
|
196
|
-
{
|
197
|
-
"MODEL_DEPLOY_ENABLE_STREAMING": container.workload_configuration_details_list[
|
198
|
-
0
|
199
|
-
].additional_configurations.get(
|
200
|
-
"MODEL_DEPLOY_ENABLE_STREAMING", UNKNOWN
|
201
|
-
)
|
202
|
-
},
|
203
|
-
{
|
204
|
-
"PORT": container.workload_configuration_details_list[
|
205
|
-
0
|
206
|
-
].additional_configurations.get("PORT", "")
|
207
|
-
},
|
208
|
-
{
|
209
|
-
"HEALTH_CHECK_PORT": container.workload_configuration_details_list[
|
210
|
-
0
|
211
|
-
].additional_configurations.get("HEALTH_CHECK_PORT", UNKNOWN),
|
212
|
-
},
|
206
|
+
{key: additional_configurations.get(key, default)}
|
207
|
+
for key, default in config_keys.items()
|
208
|
+
if key in additional_configurations
|
213
209
|
]
|
214
|
-
|
210
|
+
|
211
|
+
# Build container spec
|
212
|
+
container_item.spec = AquaContainerConfigSpec(
|
215
213
|
cli_param=container.workload_configuration_details_list[0].cmd,
|
216
214
|
server_port=str(
|
217
215
|
container.workload_configuration_details_list[0].server_port
|
@@ -236,13 +234,14 @@ class AquaContainerConfig(Serializable):
|
|
236
234
|
)
|
237
235
|
),
|
238
236
|
)
|
239
|
-
|
237
|
+
|
240
238
|
if "INFERENCE" in usages or "MULTI_MODEL" in usages:
|
241
239
|
inference_items[container_type] = container_item
|
242
240
|
if "FINE_TUNE" in usages:
|
243
241
|
finetune_items[container_type] = container_item
|
244
242
|
if "EVALUATION" in usages:
|
245
243
|
evaluate_items[container_type] = container_item
|
244
|
+
|
246
245
|
return cls(
|
247
246
|
inference=inference_items, finetune=finetune_items, evaluate=evaluate_items
|
248
247
|
)
|
ads/aqua/constants.py
CHANGED
@@ -43,6 +43,8 @@ HF_METADATA_FOLDER = ".cache/"
|
|
43
43
|
HF_LOGIN_DEFAULT_TIMEOUT = 2
|
44
44
|
MODEL_NAME_DELIMITER = ";"
|
45
45
|
AQUA_TROUBLESHOOTING_LINK = "https://github.com/oracle-samples/oci-data-science-ai-samples/blob/main/ai-quick-actions/troubleshooting-tips.md"
|
46
|
+
MODEL_FILE_DESCRIPTION_VERSION = "1.0"
|
47
|
+
MODEL_FILE_DESCRIPTION_TYPE = "modelOSSReferenceDescription"
|
46
48
|
|
47
49
|
TRAINING_METRICS_FINAL = "training_metrics_final"
|
48
50
|
VALIDATION_METRICS_FINAL = "validation_metrics_final"
|
ads/aqua/extension/ui_handler.py
CHANGED
@@ -15,7 +15,7 @@ from ads.aqua.extension.errors import Errors
|
|
15
15
|
from ads.aqua.extension.utils import validate_function_parameters
|
16
16
|
from ads.aqua.model.entities import ImportModelDetails
|
17
17
|
from ads.aqua.ui import AquaUIApp
|
18
|
-
from ads.config import COMPARTMENT_OCID
|
18
|
+
from ads.config import COMPARTMENT_OCID, IS_BYOR_ENABLED
|
19
19
|
|
20
20
|
|
21
21
|
@dataclass
|
@@ -82,6 +82,10 @@ class AquaUIHandler(AquaAPIhandler):
|
|
82
82
|
return self.is_bucket_versioned()
|
83
83
|
elif paths.startswith("aqua/containers"):
|
84
84
|
return self.list_containers()
|
85
|
+
elif paths.startswith("aqua/capacityreservations/enabled"):
|
86
|
+
return self.is_capacity_reservations_enabled()
|
87
|
+
elif paths.startswith("aqua/capacityreservations"):
|
88
|
+
return self.list_capacity_reservations()
|
85
89
|
else:
|
86
90
|
raise HTTPError(400, f"The request {self.request.path} is invalid.")
|
87
91
|
|
@@ -103,6 +107,19 @@ class AquaUIHandler(AquaAPIhandler):
|
|
103
107
|
AquaUIApp().list_log_groups(compartment_id=compartment_id, **kwargs)
|
104
108
|
)
|
105
109
|
|
110
|
+
def is_capacity_reservations_enabled(self):
|
111
|
+
"""Checks if the tenant is whitelisted for BYOR (Bring your own reservation) feature."""
|
112
|
+
return self.finish({"status": str(IS_BYOR_ENABLED).strip().lower() == "true"})
|
113
|
+
|
114
|
+
def list_capacity_reservations(self, **kwargs):
|
115
|
+
"""Lists users compute reservations in a specified compartment."""
|
116
|
+
compartment_id = self.get_argument("compartment_id", default=COMPARTMENT_OCID)
|
117
|
+
return self.finish(
|
118
|
+
AquaUIApp().list_capacity_reservations(
|
119
|
+
compartment_id=compartment_id, **kwargs
|
120
|
+
)
|
121
|
+
)
|
122
|
+
|
106
123
|
def list_logs(self, log_group_id: str, **kwargs):
|
107
124
|
"""Lists the specified log group's log objects."""
|
108
125
|
return self.finish(AquaUIApp().list_logs(log_group_id=log_group_id, **kwargs))
|
@@ -279,4 +296,5 @@ __handlers__ = [
|
|
279
296
|
("bucket/versioning/?([^/]*)", AquaUIHandler),
|
280
297
|
("containers/?([^/]*)", AquaUIHandler),
|
281
298
|
("cli/?([^/]*)", AquaCLIHandler),
|
299
|
+
("capacityreservations/?([^/]*)", AquaUIHandler),
|
282
300
|
]
|
@@ -58,6 +58,7 @@ from ads.jobs.ads_job import Job
|
|
58
58
|
from ads.jobs.builders.infrastructure.dsc_job import DataScienceJob
|
59
59
|
from ads.jobs.builders.runtimes.base import Runtime
|
60
60
|
from ads.jobs.builders.runtimes.container_runtime import ContainerRuntime
|
61
|
+
from ads.model.common.utils import MetadataArtifactPathType
|
61
62
|
from ads.model.model_metadata import (
|
62
63
|
MetadataTaxonomyKeys,
|
63
64
|
ModelCustomMetadata,
|
@@ -315,6 +316,23 @@ class AquaFineTuningApp(AquaApp):
|
|
315
316
|
model_by_reference=True,
|
316
317
|
defined_tags=create_fine_tuning_details.defined_tags,
|
317
318
|
)
|
319
|
+
defined_metadata_dict = {}
|
320
|
+
defined_metadata_list_source = source.defined_metadata_list._to_oci_metadata()
|
321
|
+
for defined_metadata in defined_metadata_list_source:
|
322
|
+
if (
|
323
|
+
defined_metadata.has_artifact
|
324
|
+
and defined_metadata.key.lower()
|
325
|
+
!= AquaModelMetadataKeys.FINE_TUNING_CONFIGURATION.lower()
|
326
|
+
):
|
327
|
+
content = self.ds_client.get_model_defined_metadatum_artifact_content(
|
328
|
+
source.id, defined_metadata.key
|
329
|
+
).data.content
|
330
|
+
defined_metadata_dict[defined_metadata.key] = content
|
331
|
+
|
332
|
+
for key, value in defined_metadata_dict.items():
|
333
|
+
ft_model.create_defined_metadata_artifact(
|
334
|
+
key, value, MetadataArtifactPathType.CONTENT
|
335
|
+
)
|
318
336
|
|
319
337
|
ft_job_freeform_tags = {
|
320
338
|
Tags.AQUA_TAG: UNKNOWN,
|
ads/aqua/model/entities.py
CHANGED
@@ -15,12 +15,19 @@ from typing import List, Optional
|
|
15
15
|
|
16
16
|
import oci
|
17
17
|
from huggingface_hub import hf_api
|
18
|
-
from pydantic import BaseModel
|
18
|
+
from pydantic import BaseModel, Field
|
19
|
+
from pydantic.alias_generators import to_camel
|
19
20
|
|
20
21
|
from ads.aqua import logger
|
21
22
|
from ads.aqua.app import CLIBuilderMixin
|
22
23
|
from ads.aqua.common import utils
|
23
|
-
from ads.aqua.
|
24
|
+
from ads.aqua.config.utils.serializer import Serializable
|
25
|
+
from ads.aqua.constants import (
|
26
|
+
LIFECYCLE_DETAILS_MISSING_JOBRUN,
|
27
|
+
MODEL_FILE_DESCRIPTION_TYPE,
|
28
|
+
MODEL_FILE_DESCRIPTION_VERSION,
|
29
|
+
UNKNOWN_VALUE,
|
30
|
+
)
|
24
31
|
from ads.aqua.data import AquaResourceIdentifier
|
25
32
|
from ads.aqua.model.enums import FineTuningDefinedMetadata
|
26
33
|
from ads.aqua.training.exceptions import exit_code_dict
|
@@ -304,3 +311,75 @@ class ImportModelDetails(CLIBuilderMixin):
|
|
304
311
|
|
305
312
|
def __post_init__(self):
|
306
313
|
self._command = "model register"
|
314
|
+
|
315
|
+
|
316
|
+
class ModelFileInfo(Serializable):
|
317
|
+
"""Describes the file information of this model.
|
318
|
+
|
319
|
+
Attributes:
|
320
|
+
name (str): The name of the model artifact file.
|
321
|
+
version (str): The version of the model artifact file.
|
322
|
+
size_in_bytes (int): The size of the model artifact file in bytes.
|
323
|
+
"""
|
324
|
+
|
325
|
+
name: str = Field(..., description="The name of model artifact file.")
|
326
|
+
version: str = Field(..., description="The version of model artifact file.")
|
327
|
+
size_in_bytes: int = Field(
|
328
|
+
..., description="The size of model artifact file in bytes."
|
329
|
+
)
|
330
|
+
|
331
|
+
class Config:
|
332
|
+
alias_generator = to_camel
|
333
|
+
extra = "allow"
|
334
|
+
|
335
|
+
|
336
|
+
class ModelArtifactInfo(Serializable):
|
337
|
+
"""Describes the artifact information of this model.
|
338
|
+
|
339
|
+
Attributes:
|
340
|
+
namespace (str): The namespace of the model artifact location.
|
341
|
+
bucket_name (str): The bucket name of model artifact location.
|
342
|
+
prefix (str): The prefix of model artifact location.
|
343
|
+
objects: (List[ModelFileInfo]): A list of model artifact objects.
|
344
|
+
"""
|
345
|
+
|
346
|
+
namespace: str = Field(
|
347
|
+
..., description="The name space of model artifact location."
|
348
|
+
)
|
349
|
+
bucket_name: str = Field(
|
350
|
+
..., description="The bucket name of model artifact location."
|
351
|
+
)
|
352
|
+
prefix: str = Field(..., description="The prefix of model artifact location.")
|
353
|
+
objects: List[ModelFileInfo] = Field(
|
354
|
+
..., description="List of model artifact objects."
|
355
|
+
)
|
356
|
+
|
357
|
+
class Config:
|
358
|
+
alias_generator = to_camel
|
359
|
+
extra = "allow"
|
360
|
+
|
361
|
+
|
362
|
+
class ModelFileDescription(Serializable):
|
363
|
+
"""Describes the model file description.
|
364
|
+
|
365
|
+
Attributes:
|
366
|
+
version (str): The version of the model file description. Defaults to `1.0`.
|
367
|
+
type (str): The type of model file description. Defaults to `modelOSSReferenceDescription`.
|
368
|
+
models List[ModelArtifactInfo]: A list of model artifact information.
|
369
|
+
"""
|
370
|
+
|
371
|
+
version: str = Field(
|
372
|
+
default=MODEL_FILE_DESCRIPTION_VERSION,
|
373
|
+
description="The version of model file description.",
|
374
|
+
)
|
375
|
+
type: str = Field(
|
376
|
+
default=MODEL_FILE_DESCRIPTION_TYPE,
|
377
|
+
description="The type of model file description.",
|
378
|
+
)
|
379
|
+
models: List[ModelArtifactInfo] = Field(
|
380
|
+
..., description="List of model artifact information."
|
381
|
+
)
|
382
|
+
|
383
|
+
class Config:
|
384
|
+
alias_generator = to_camel
|
385
|
+
extra = "allow"
|
ads/aqua/model/enums.py
CHANGED
@@ -26,5 +26,7 @@ class FineTuningCustomMetadata(ExtendedEnum):
|
|
26
26
|
|
27
27
|
|
28
28
|
class MultiModelSupportedTaskType(ExtendedEnum):
|
29
|
-
TEXT_GENERATION = "
|
30
|
-
|
29
|
+
TEXT_GENERATION = "text_generation"
|
30
|
+
IMAGE_TEXT_TO_TEXT = "image_text_to_text"
|
31
|
+
CODE_SYNTHESIS = "code_synthesis"
|
32
|
+
EMBEDDING = "text_embedding"
|
ads/aqua/model/model.py
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
import json
|
5
5
|
import os
|
6
6
|
import pathlib
|
7
|
+
import re
|
7
8
|
from datetime import datetime, timedelta
|
8
9
|
from threading import Lock
|
9
10
|
from typing import Any, Dict, List, Optional, Set, Union
|
@@ -78,9 +79,14 @@ from ads.aqua.model.entities import (
|
|
78
79
|
AquaModelReadme,
|
79
80
|
AquaModelSummary,
|
80
81
|
ImportModelDetails,
|
82
|
+
ModelFileDescription,
|
81
83
|
ModelValidationResult,
|
82
84
|
)
|
83
85
|
from ads.aqua.model.enums import MultiModelSupportedTaskType
|
86
|
+
from ads.aqua.model.utils import (
|
87
|
+
extract_base_model_from_ft,
|
88
|
+
extract_fine_tune_artifacts_path,
|
89
|
+
)
|
84
90
|
from ads.common.auth import default_signer
|
85
91
|
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
|
86
92
|
from ads.common.utils import (
|
@@ -184,8 +190,12 @@ class AquaModelApp(AquaApp):
|
|
184
190
|
target_project = project_id or PROJECT_OCID
|
185
191
|
target_compartment = compartment_id or COMPARTMENT_OCID
|
186
192
|
|
187
|
-
# Skip model copying if it is registered model
|
188
|
-
if
|
193
|
+
# Skip model copying if it is registered model or fine-tuned model
|
194
|
+
if (
|
195
|
+
service_model.freeform_tags.get(Tags.BASE_MODEL_CUSTOM, None) is not None
|
196
|
+
or service_model.freeform_tags.get(Tags.AQUA_FINE_TUNED_MODEL_TAG)
|
197
|
+
is not None
|
198
|
+
):
|
189
199
|
logger.info(
|
190
200
|
f"Aqua Model {model_id} already exists in the user's compartment."
|
191
201
|
"Skipped copying."
|
@@ -266,8 +276,8 @@ class AquaModelApp(AquaApp):
|
|
266
276
|
"Model list cannot be empty. Please provide at least one model for deployment."
|
267
277
|
)
|
268
278
|
|
269
|
-
artifact_list = []
|
270
279
|
display_name_list = []
|
280
|
+
model_file_description_list: List[ModelFileDescription] = []
|
271
281
|
model_custom_metadata = ModelCustomMetadata()
|
272
282
|
|
273
283
|
service_inference_containers = (
|
@@ -294,6 +304,7 @@ class AquaModelApp(AquaApp):
|
|
294
304
|
for model in models:
|
295
305
|
source_model = DataScienceModel.from_id(model.model_id)
|
296
306
|
display_name = source_model.display_name
|
307
|
+
model_file_description = source_model.model_file_description
|
297
308
|
# Update model name in user's input model
|
298
309
|
model.model_name = model.model_name or display_name
|
299
310
|
|
@@ -304,20 +315,27 @@ class AquaModelApp(AquaApp):
|
|
304
315
|
# "Currently only service models are supported for multi model deployment."
|
305
316
|
# )
|
306
317
|
|
307
|
-
#
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
318
|
+
# check if model is a fine-tuned model and if so, add the fine tuned weights path to the fine_tune_weights_location pydantic field
|
319
|
+
is_fine_tuned_model = (
|
320
|
+
Tags.AQUA_FINE_TUNED_MODEL_TAG in source_model.freeform_tags
|
321
|
+
)
|
322
|
+
|
323
|
+
if is_fine_tuned_model:
|
324
|
+
model.model_id, model.model_name = extract_base_model_from_ft(
|
325
|
+
source_model
|
326
|
+
)
|
327
|
+
model_artifact_path, model.fine_tune_weights_location = (
|
328
|
+
extract_fine_tune_artifacts_path(source_model)
|
329
|
+
)
|
330
|
+
|
331
|
+
else:
|
332
|
+
# Retrieve model artifact for base models
|
333
|
+
model_artifact_path = source_model.artifact
|
316
334
|
|
317
335
|
display_name_list.append(display_name)
|
318
336
|
|
319
|
-
|
320
|
-
|
337
|
+
self._extract_model_task(model, source_model)
|
338
|
+
|
321
339
|
if not model_artifact_path:
|
322
340
|
raise AquaValueError(
|
323
341
|
f"Model '{display_name}' (ID: {model.model_id}) has no artifacts. "
|
@@ -327,7 +345,15 @@ class AquaModelApp(AquaApp):
|
|
327
345
|
# Update model artifact location in user's input model
|
328
346
|
model.artifact_location = model_artifact_path
|
329
347
|
|
330
|
-
|
348
|
+
if not model_file_description:
|
349
|
+
raise AquaValueError(
|
350
|
+
f"Model '{display_name}' (ID: {model.model_id}) has no file description. "
|
351
|
+
"Please register the model first."
|
352
|
+
)
|
353
|
+
|
354
|
+
model_file_description_list.append(
|
355
|
+
ModelFileDescription(**model_file_description)
|
356
|
+
)
|
331
357
|
|
332
358
|
# Validate deployment container consistency
|
333
359
|
deployment_container = source_model.custom_metadata_list.get(
|
@@ -360,7 +386,8 @@ class AquaModelApp(AquaApp):
|
|
360
386
|
raise AquaValueError(
|
361
387
|
"The selected models are associated with different container families: "
|
362
388
|
f"{list(selected_models_deployment_containers)}."
|
363
|
-
"For multi-model deployment, all models in the group must
|
389
|
+
"For multi-model deployment, all models in the group must belong to the same container "
|
390
|
+
"family or to compatible container families."
|
364
391
|
)
|
365
392
|
else:
|
366
393
|
deployment_container = selected_models_deployment_containers.pop()
|
@@ -405,9 +432,16 @@ class AquaModelApp(AquaApp):
|
|
405
432
|
.with_custom_metadata_list(model_custom_metadata)
|
406
433
|
)
|
407
434
|
|
408
|
-
#
|
409
|
-
|
410
|
-
|
435
|
+
# Update multi model file description to attach artifacts
|
436
|
+
custom_model.with_model_file_description(
|
437
|
+
json_dict=ModelFileDescription(
|
438
|
+
models=[
|
439
|
+
models
|
440
|
+
for model_file_description in model_file_description_list
|
441
|
+
for models in model_file_description.models
|
442
|
+
]
|
443
|
+
).model_dump(by_alias=True)
|
444
|
+
)
|
411
445
|
|
412
446
|
# Finalize creation
|
413
447
|
custom_model.create(model_by_reference=True)
|
@@ -704,6 +738,26 @@ class AquaModelApp(AquaApp):
|
|
704
738
|
else:
|
705
739
|
raise AquaRuntimeError("Only registered unverified models can be edited.")
|
706
740
|
|
741
|
+
def _extract_model_task(
|
742
|
+
self,
|
743
|
+
model: AquaMultiModelRef,
|
744
|
+
source_model: DataScienceModel,
|
745
|
+
) -> None:
|
746
|
+
"""In a Multi Model Deployment, will set model_task parameter in AquaMultiModelRef from freeform tags or user"""
|
747
|
+
# user does not supply model task, we extract from model metadata
|
748
|
+
if not model.model_task:
|
749
|
+
model.model_task = source_model.freeform_tags.get(Tags.TASK, UNKNOWN)
|
750
|
+
|
751
|
+
task_tag = re.sub(r"-", "_", model.model_task).lower()
|
752
|
+
# re-visit logic when more model task types are supported
|
753
|
+
if task_tag in MultiModelSupportedTaskType:
|
754
|
+
model.model_task = task_tag
|
755
|
+
else:
|
756
|
+
raise AquaValueError(
|
757
|
+
f"Invalid or missing {task_tag} tag for selected model {source_model.display_name}. "
|
758
|
+
f"Currently only `{MultiModelSupportedTaskType.values()}` models are supported for multi model deployment."
|
759
|
+
)
|
760
|
+
|
707
761
|
def _fetch_metric_from_metadata(
|
708
762
|
self,
|
709
763
|
custom_metadata_list: ModelCustomMetadata,
|
ads/aqua/model/utils.py
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# Copyright (c) 2025 Oracle and/or its affiliates.
|
3
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
4
|
+
"""AQUA model utils"""
|
5
|
+
|
6
|
+
from typing import Dict, Optional, Tuple
|
7
|
+
|
8
|
+
from ads.aqua.common.entities import AquaMultiModelRef
|
9
|
+
from ads.aqua.common.errors import AquaValueError
|
10
|
+
from ads.aqua.common.utils import get_model_by_reference_paths
|
11
|
+
from ads.aqua.finetuning.constants import FineTuneCustomMetadata
|
12
|
+
from ads.common.object_storage_details import ObjectStorageDetails
|
13
|
+
from ads.model.datascience_model import DataScienceModel
|
14
|
+
|
15
|
+
|
16
|
+
def extract_base_model_from_ft(aqua_model: DataScienceModel) -> Tuple[str, str]:
|
17
|
+
"""Extracts the model_name and base model OCID (config_source_id) OCID for a fine-tuned model"""
|
18
|
+
|
19
|
+
config_source_id = aqua_model.custom_metadata_list.get(
|
20
|
+
FineTuneCustomMetadata.FINE_TUNE_SOURCE
|
21
|
+
).value
|
22
|
+
model_name = aqua_model.custom_metadata_list.get(
|
23
|
+
FineTuneCustomMetadata.FINE_TUNE_SOURCE_NAME
|
24
|
+
).value
|
25
|
+
|
26
|
+
if not config_source_id or not model_name:
|
27
|
+
raise AquaValueError(
|
28
|
+
f"Either {FineTuneCustomMetadata.FINE_TUNE_SOURCE} or {FineTuneCustomMetadata.FINE_TUNE_SOURCE_NAME} is missing "
|
29
|
+
f"from custom metadata for the model {config_source_id}"
|
30
|
+
)
|
31
|
+
|
32
|
+
return config_source_id, model_name
|
33
|
+
|
34
|
+
|
35
|
+
def extract_fine_tune_artifacts_path(aqua_model: DataScienceModel) -> Tuple[str, str]:
|
36
|
+
"""Extracts the fine tuning source (fine_tune_output_path) and base model path from the DataScienceModel Object"""
|
37
|
+
|
38
|
+
base_model_path, fine_tune_output_path = get_model_by_reference_paths(
|
39
|
+
aqua_model.model_file_description
|
40
|
+
)
|
41
|
+
|
42
|
+
if not fine_tune_output_path or not ObjectStorageDetails.is_oci_path(
|
43
|
+
fine_tune_output_path
|
44
|
+
):
|
45
|
+
raise AquaValueError(
|
46
|
+
"Fine tuned output path is not available in the model artifact."
|
47
|
+
)
|
48
|
+
|
49
|
+
os_path = ObjectStorageDetails.from_path(fine_tune_output_path)
|
50
|
+
fine_tune_output_path = os_path.filepath.rstrip("/")
|
51
|
+
|
52
|
+
return base_model_path, fine_tune_output_path
|
@@ -25,7 +25,6 @@ from ads.aqua.common.utils import (
|
|
25
25
|
build_pydantic_error_message,
|
26
26
|
get_combined_params,
|
27
27
|
get_container_params_type,
|
28
|
-
get_model_by_reference_paths,
|
29
28
|
get_ocid_substring,
|
30
29
|
get_params_dict,
|
31
30
|
get_params_list,
|
@@ -46,9 +45,12 @@ from ads.aqua.constants import (
|
|
46
45
|
UNKNOWN_DICT,
|
47
46
|
)
|
48
47
|
from ads.aqua.data import AquaResourceIdentifier
|
49
|
-
from ads.aqua.finetuning.finetuning import FineTuneCustomMetadata
|
50
48
|
from ads.aqua.model import AquaModelApp
|
51
49
|
from ads.aqua.model.constants import AquaModelMetadataKeys, ModelCustomMetadataFields
|
50
|
+
from ads.aqua.model.utils import (
|
51
|
+
extract_base_model_from_ft,
|
52
|
+
extract_fine_tune_artifacts_path,
|
53
|
+
)
|
52
54
|
from ads.aqua.modeldeployment.entities import (
|
53
55
|
AquaDeployment,
|
54
56
|
AquaDeploymentConfig,
|
@@ -178,9 +180,7 @@ class AquaDeploymentApp(AquaApp):
|
|
178
180
|
# validate instance shape availability in compartment
|
179
181
|
available_shapes = [
|
180
182
|
shape.name.lower()
|
181
|
-
for shape in self.list_shapes(
|
182
|
-
compartment_id=compartment_id
|
183
|
-
)
|
183
|
+
for shape in self.list_shapes(compartment_id=compartment_id)
|
184
184
|
]
|
185
185
|
|
186
186
|
if create_deployment_details.instance_shape.lower() not in available_shapes:
|
@@ -213,6 +213,7 @@ class AquaDeploymentApp(AquaApp):
|
|
213
213
|
)
|
214
214
|
else:
|
215
215
|
model_ids = [model.model_id for model in create_deployment_details.models]
|
216
|
+
|
216
217
|
try:
|
217
218
|
model_config_summary = self.get_multimodel_deployment_config(
|
218
219
|
model_ids=model_ids, compartment_id=compartment_id
|
@@ -345,22 +346,6 @@ class AquaDeploymentApp(AquaApp):
|
|
345
346
|
config_source_id = create_deployment_details.model_id
|
346
347
|
model_name = aqua_model.display_name
|
347
348
|
|
348
|
-
is_fine_tuned_model = Tags.AQUA_FINE_TUNED_MODEL_TAG in aqua_model.freeform_tags
|
349
|
-
|
350
|
-
if is_fine_tuned_model:
|
351
|
-
try:
|
352
|
-
config_source_id = aqua_model.custom_metadata_list.get(
|
353
|
-
FineTuneCustomMetadata.FINE_TUNE_SOURCE
|
354
|
-
).value
|
355
|
-
model_name = aqua_model.custom_metadata_list.get(
|
356
|
-
FineTuneCustomMetadata.FINE_TUNE_SOURCE_NAME
|
357
|
-
).value
|
358
|
-
except ValueError as err:
|
359
|
-
raise AquaValueError(
|
360
|
-
f"Either {FineTuneCustomMetadata.FINE_TUNE_SOURCE} or {FineTuneCustomMetadata.FINE_TUNE_SOURCE_NAME} is missing "
|
361
|
-
f"from custom metadata for the model {config_source_id}"
|
362
|
-
) from err
|
363
|
-
|
364
349
|
# set up env and cmd var
|
365
350
|
env_var = create_deployment_details.env_var or {}
|
366
351
|
cmd_var = create_deployment_details.cmd_var or []
|
@@ -380,19 +365,11 @@ class AquaDeploymentApp(AquaApp):
|
|
380
365
|
|
381
366
|
env_var.update({"BASE_MODEL": f"{model_path_prefix}"})
|
382
367
|
|
383
|
-
|
384
|
-
_, fine_tune_output_path = get_model_by_reference_paths(
|
385
|
-
aqua_model.model_file_description
|
386
|
-
)
|
387
|
-
|
388
|
-
if not fine_tune_output_path:
|
389
|
-
raise AquaValueError(
|
390
|
-
"Fine tuned output path is not available in the model artifact."
|
391
|
-
)
|
392
|
-
|
393
|
-
os_path = ObjectStorageDetails.from_path(fine_tune_output_path)
|
394
|
-
fine_tune_output_path = os_path.filepath.rstrip("/")
|
368
|
+
is_fine_tuned_model = Tags.AQUA_FINE_TUNED_MODEL_TAG in aqua_model.freeform_tags
|
395
369
|
|
370
|
+
if is_fine_tuned_model:
|
371
|
+
config_source_id, model_name = extract_base_model_from_ft(aqua_model)
|
372
|
+
_, fine_tune_output_path = extract_fine_tune_artifacts_path(aqua_model)
|
396
373
|
env_var.update({"FT_MODEL": f"{fine_tune_output_path}"})
|
397
374
|
|
398
375
|
container_type_key = self._get_container_type_key(
|
@@ -645,7 +622,15 @@ class AquaDeploymentApp(AquaApp):
|
|
645
622
|
os_path = ObjectStorageDetails.from_path(artifact_path_prefix)
|
646
623
|
artifact_path_prefix = os_path.filepath.rstrip("/")
|
647
624
|
|
648
|
-
|
625
|
+
# override by-default completion/ chat endpoint with other endpoint (embedding)
|
626
|
+
config_data = {"params": params, "model_path": artifact_path_prefix}
|
627
|
+
if model.model_task:
|
628
|
+
config_data["model_task"] = model.model_task
|
629
|
+
|
630
|
+
if model.fine_tune_weights_location:
|
631
|
+
config_data["fine_tune_weights_location"] = model.fine_tune_weights_location
|
632
|
+
|
633
|
+
model_config.append(config_data)
|
649
634
|
model_name_list.append(model.model_name)
|
650
635
|
|
651
636
|
env_var.update({AQUA_MULTI_MODEL_CONFIG: json.dumps({"models": model_config})})
|
@@ -803,6 +788,9 @@ class AquaDeploymentApp(AquaApp):
|
|
803
788
|
# we arbitrarily choose last 8 characters of OCID to identify MD in telemetry
|
804
789
|
telemetry_kwargs = {"ocid": get_ocid_substring(deployment_id, key_len=8)}
|
805
790
|
|
791
|
+
if Tags.BASE_MODEL_CUSTOM in tags:
|
792
|
+
telemetry_kwargs[ "custom_base_model"] = True
|
793
|
+
|
806
794
|
# tracks unique deployments that were created in the user compartment
|
807
795
|
self.telemetry.record_event_async(
|
808
796
|
category=f"aqua/{model_type}/deployment",
|
@@ -1321,4 +1309,4 @@ class AquaDeploymentApp(AquaApp):
|
|
1321
1309
|
or gpu_specs.shapes.get(oci_shape.name.upper()),
|
1322
1310
|
)
|
1323
1311
|
for oci_shape in oci_shapes
|
1324
|
-
]
|
1312
|
+
]
|
ads/aqua/ui.py
CHANGED
@@ -90,6 +90,26 @@ class AquaUIApp(AquaApp):
|
|
90
90
|
res = self.logging_client.list_logs(log_group_id=log_group_id, **kwargs).data
|
91
91
|
return sanitize_response(oci_client=self.logging_client, response=res)
|
92
92
|
|
93
|
+
@telemetry(entry_point="plugin=ui&action=list_capacity_reservations", name="aqua")
|
94
|
+
def list_capacity_reservations(self, **kwargs) -> list:
|
95
|
+
"""
|
96
|
+
Lists users compute reservations in a specified compartment
|
97
|
+
|
98
|
+
Returns
|
99
|
+
-------
|
100
|
+
json representation of `oci.core.models.ComputeCapacityReservationSummary`.
|
101
|
+
|
102
|
+
"""
|
103
|
+
compartment_id = kwargs.pop("compartment_id", COMPARTMENT_OCID)
|
104
|
+
logger.info(f"Loading Capacity reservations from compartment: {compartment_id}")
|
105
|
+
|
106
|
+
reservations = self.compute_client.list_compute_capacity_reservations(
|
107
|
+
compartment_id=compartment_id, **kwargs
|
108
|
+
)
|
109
|
+
return sanitize_response(
|
110
|
+
oci_client=self.compute_client, response=reservations.data
|
111
|
+
)
|
112
|
+
|
93
113
|
@telemetry(entry_point="plugin=ui&action=list_compartments", name="aqua")
|
94
114
|
def list_compartments(self) -> str:
|
95
115
|
"""Lists the compartments in a tenancy specified by TENANCY_OCID env variable. This is a pass through the OCI list_compartments
|
ads/common/oci_client.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8; -*-
|
3
2
|
|
4
3
|
# Copyright (c) 2021, 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/
|
@@ -9,20 +8,20 @@ import logging
|
|
9
8
|
import oci.artifacts
|
10
9
|
from oci.ai_language import AIServiceLanguageClient
|
11
10
|
from oci.artifacts import ArtifactsClient
|
11
|
+
from oci.core import ComputeClient, VirtualNetworkClient
|
12
12
|
from oci.data_catalog import DataCatalogClient
|
13
13
|
from oci.data_flow import DataFlowClient
|
14
14
|
from oci.data_labeling_service import DataLabelingManagementClient
|
15
15
|
from oci.data_labeling_service_dataplane import DataLabelingClient
|
16
16
|
from oci.data_science import DataScienceClient
|
17
17
|
from oci.identity import IdentityClient
|
18
|
+
from oci.limits import LimitsClient
|
19
|
+
from oci.logging import LoggingManagementClient
|
18
20
|
from oci.marketplace import MarketplaceClient
|
19
21
|
from oci.object_storage import ObjectStorageClient
|
20
22
|
from oci.resource_search import ResourceSearchClient
|
21
23
|
from oci.secrets import SecretsClient
|
22
24
|
from oci.vault import VaultsClient
|
23
|
-
from oci.logging import LoggingManagementClient
|
24
|
-
from oci.core import VirtualNetworkClient
|
25
|
-
from oci.limits import LimitsClient
|
26
25
|
|
27
26
|
logger = logging.getLogger(__name__)
|
28
27
|
|
@@ -69,6 +68,7 @@ class OCIClientFactory:
|
|
69
68
|
"secret": SecretsClient,
|
70
69
|
"vault": VaultsClient,
|
71
70
|
"identity": IdentityClient,
|
71
|
+
"compute": ComputeClient,
|
72
72
|
"ai_language": AIServiceLanguageClient,
|
73
73
|
"data_labeling_dp": DataLabelingClient,
|
74
74
|
"data_labeling_cp": DataLabelingManagementClient,
|
@@ -114,6 +114,10 @@ class OCIClientFactory:
|
|
114
114
|
def object_storage(self):
|
115
115
|
return self.create_client("object_storage")
|
116
116
|
|
117
|
+
@property
|
118
|
+
def compute(self):
|
119
|
+
return self.create_client("compute")
|
120
|
+
|
117
121
|
@property
|
118
122
|
def identity(self):
|
119
123
|
return self.create_client("identity")
|
ads/config.py
CHANGED
@@ -14,6 +14,7 @@ OCI_ODSC_SERVICE_ENDPOINT = os.environ.get("OCI_ODSC_SERVICE_ENDPOINT")
|
|
14
14
|
OCI_IDENTITY_SERVICE_ENDPOINT = os.environ.get("OCI_IDENTITY_SERVICE_ENDPOINT")
|
15
15
|
NB_SESSION_COMPARTMENT_OCID = os.environ.get("NB_SESSION_COMPARTMENT_OCID")
|
16
16
|
PROJECT_OCID = os.environ.get("PROJECT_OCID") or os.environ.get("PIPELINE_PROJECT_OCID")
|
17
|
+
IS_BYOR_ENABLED = os.environ.get("ALLOWLISTED_FOR_BYOR", False)
|
17
18
|
NB_SESSION_OCID = os.environ.get("NB_SESSION_OCID")
|
18
19
|
USER_OCID = os.environ.get("USER_OCID")
|
19
20
|
OCI_RESOURCE_PRINCIPAL_VERSION = os.environ.get("OCI_RESOURCE_PRINCIPAL_VERSION")
|
@@ -573,9 +573,14 @@ class ForecastOperatorBaseModel(ABC):
|
|
573
573
|
if self.spec.generate_explanations:
|
574
574
|
try:
|
575
575
|
if not self.formatted_global_explanation.empty:
|
576
|
+
# Round to 4 decimal places before writing
|
577
|
+
global_expl_rounded = self.formatted_global_explanation.copy()
|
578
|
+
global_expl_rounded = global_expl_rounded.apply(
|
579
|
+
lambda col: np.round(col, 4) if np.issubdtype(col.dtype, np.number) else col
|
580
|
+
)
|
576
581
|
if self.spec.generate_explanation_files:
|
577
582
|
write_data(
|
578
|
-
data=
|
583
|
+
data=global_expl_rounded,
|
579
584
|
filename=os.path.join(
|
580
585
|
unique_output_dir, self.spec.global_explanation_filename
|
581
586
|
),
|
@@ -583,16 +588,21 @@ class ForecastOperatorBaseModel(ABC):
|
|
583
588
|
storage_options=storage_options,
|
584
589
|
index=True,
|
585
590
|
)
|
586
|
-
results.set_global_explanations(
|
591
|
+
results.set_global_explanations(global_expl_rounded)
|
587
592
|
else:
|
588
593
|
logger.warning(
|
589
594
|
f"Attempted to generate global explanations for the {self.spec.global_explanation_filename} file, but an issue occured in formatting the explanations."
|
590
595
|
)
|
591
596
|
|
592
597
|
if not self.formatted_local_explanation.empty:
|
598
|
+
# Round to 4 decimal places before writing
|
599
|
+
local_expl_rounded = self.formatted_local_explanation.copy()
|
600
|
+
local_expl_rounded = local_expl_rounded.apply(
|
601
|
+
lambda col: np.round(col, 4) if np.issubdtype(col.dtype, np.number) else col
|
602
|
+
)
|
593
603
|
if self.spec.generate_explanation_files:
|
594
604
|
write_data(
|
595
|
-
data=
|
605
|
+
data=local_expl_rounded,
|
596
606
|
filename=os.path.join(
|
597
607
|
unique_output_dir, self.spec.local_explanation_filename
|
598
608
|
),
|
@@ -600,7 +610,7 @@ class ForecastOperatorBaseModel(ABC):
|
|
600
610
|
storage_options=storage_options,
|
601
611
|
index=True,
|
602
612
|
)
|
603
|
-
results.set_local_explanations(
|
613
|
+
results.set_local_explanations(local_expl_rounded)
|
604
614
|
else:
|
605
615
|
logger.warning(
|
606
616
|
f"Attempted to generate local explanations for the {self.spec.local_explanation_filename} file, but an issue occured in formatting the explanations."
|
@@ -304,7 +304,7 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
304
304
|
# Global Expl
|
305
305
|
g_expl = self.drop_horizon(expl_df).mean()
|
306
306
|
g_expl.name = s_id
|
307
|
-
global_expl.append(g_expl)
|
307
|
+
global_expl.append(np.abs(g_expl))
|
308
308
|
self.global_explanation = pd.concat(global_expl, axis=1)
|
309
309
|
self.formatted_global_explanation = (
|
310
310
|
self.global_explanation / self.global_explanation.sum(axis=0) * 100
|
ads/telemetry/client.py
CHANGED
@@ -8,6 +8,7 @@ import threading
|
|
8
8
|
import traceback
|
9
9
|
import urllib.parse
|
10
10
|
from typing import Optional
|
11
|
+
import concurrent.futures
|
11
12
|
|
12
13
|
import oci
|
13
14
|
|
@@ -16,7 +17,8 @@ from ads.config import DEBUG_TELEMETRY
|
|
16
17
|
from .base import TelemetryBase
|
17
18
|
|
18
19
|
logger = logging.getLogger(__name__)
|
19
|
-
|
20
|
+
THREAD_POOL_SIZE = 16
|
21
|
+
thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=THREAD_POOL_SIZE)
|
20
22
|
|
21
23
|
class TelemetryClient(TelemetryBase):
|
22
24
|
"""Represents a telemetry python client providing functions to record an event.
|
@@ -102,7 +104,7 @@ class TelemetryClient(TelemetryBase):
|
|
102
104
|
|
103
105
|
def record_event_async(
|
104
106
|
self, category: str = None, action: str = None, detail: str = None, **kwargs
|
105
|
-
):
|
107
|
+
)-> None:
|
106
108
|
"""Send a head request to generate an event record.
|
107
109
|
|
108
110
|
Parameters
|
@@ -117,9 +119,4 @@ class TelemetryClient(TelemetryBase):
|
|
117
119
|
Thread
|
118
120
|
A started thread to send a head request to generate an event record.
|
119
121
|
"""
|
120
|
-
|
121
|
-
target=self.record_event, args=(category, action, detail), kwargs=kwargs
|
122
|
-
)
|
123
|
-
thread.daemon = True
|
124
|
-
thread.start()
|
125
|
-
return thread
|
122
|
+
thread_pool.submit(self.record_event, args=(category, action, detail), kwargs=kwargs)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: oracle_ads
|
3
|
-
Version: 2.13.
|
3
|
+
Version: 2.13.9
|
4
4
|
Summary: Oracle Accelerated Data Science SDK
|
5
5
|
Keywords: Oracle Cloud Infrastructure,OCI,Machine Learning,ML,Artificial Intelligence,AI,Data Science,Cloud,Oracle
|
6
6
|
Author: Oracle Data Science
|
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.11
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
17
17
|
License-File: LICENSE.txt
|
18
|
-
Requires-Dist: PyYAML>=6
|
18
|
+
Requires-Dist: PyYAML>=6.0.1
|
19
19
|
Requires-Dist: asteval>=0.9.25
|
20
20
|
Requires-Dist: cerberus>=1.3.4
|
21
21
|
Requires-Dist: cloudpickle>=1.6.0
|
@@ -99,13 +99,14 @@ Requires-Dist: ipython>=7.23.1, <8.0 ; extra == "notebook"
|
|
99
99
|
Requires-Dist: ipywidgets~=7.6.3 ; extra == "notebook"
|
100
100
|
Requires-Dist: lightgbm ; extra == "onnx"
|
101
101
|
Requires-Dist: onnx>=1.12.0,<=1.15.0 ; extra == "onnx" and ( python_version < '3.12')
|
102
|
-
Requires-Dist: onnx
|
103
|
-
Requires-Dist: onnxmltools
|
102
|
+
Requires-Dist: onnx~=1.17.0 ; extra == "onnx" and ( python_version >= '3.12')
|
103
|
+
Requires-Dist: onnxmltools~=1.13.0 ; extra == "onnx"
|
104
104
|
Requires-Dist: onnxruntime~=1.17.0,!=1.16.0 ; extra == "onnx" and ( python_version < '3.12')
|
105
|
-
Requires-Dist: onnxruntime ; extra == "onnx" and ( python_version >= '3.12')
|
105
|
+
Requires-Dist: onnxruntime~=1.22.0 ; extra == "onnx" and ( python_version >= '3.12')
|
106
106
|
Requires-Dist: oracle_ads[viz] ; extra == "onnx"
|
107
107
|
Requires-Dist: protobuf ; extra == "onnx"
|
108
|
-
Requires-Dist: skl2onnx>=1.10.4 ; extra == "onnx"
|
108
|
+
Requires-Dist: skl2onnx>=1.10.4 ; extra == "onnx" and ( python_version < '3.12')
|
109
|
+
Requires-Dist: skl2onnx~=1.18.0 ; extra == "onnx" and ( python_version >= '3.12')
|
109
110
|
Requires-Dist: tf2onnx ; extra == "onnx"
|
110
111
|
Requires-Dist: xgboost<=1.7 ; extra == "onnx"
|
111
112
|
Requires-Dist: conda-pack ; extra == "opctl"
|
@@ -1,23 +1,23 @@
|
|
1
1
|
ads/__init__.py,sha256=OxHySbHbMqPgZ8sUj33Bxy-smSiNgRjtcSUV77oBL08,3787
|
2
2
|
ads/cli.py,sha256=WkOpZv8jWgFYN9BNkt2LJBs9KzJHgFqq3pIymsqc8Q4,4292
|
3
|
-
ads/config.py,sha256=
|
3
|
+
ads/config.py,sha256=ZFZpp0SgKgB1-7yQ6MEdVdyJ2nwzixbH91sJ4_XnG8Y,8170
|
4
4
|
ads/aqua/__init__.py,sha256=7DjwtmZaX-_atIkmZu6XQKHqJUEeemJGR2TlxzMHSXs,973
|
5
|
-
ads/aqua/app.py,sha256=
|
5
|
+
ads/aqua/app.py,sha256=PmG8-XnOfMRJ0GQgJDl6TSGF95EBTrMXGRO8p1FG43Y,18475
|
6
6
|
ads/aqua/cli.py,sha256=8S0JnhWY9IBZjMyB-5r4I-2nl-WK6yw1iirPsAXICF0,3358
|
7
|
-
ads/aqua/constants.py,sha256=
|
7
|
+
ads/aqua/constants.py,sha256=dUl02j5XTAG6sL7XJ9HS5fT0Z869WceRLFIbBwCzmtw,5081
|
8
8
|
ads/aqua/data.py,sha256=HfxLfKiNiPJecMQy0JAztUsT3IdZilHHHOrCJnjZMc4,408
|
9
|
-
ads/aqua/ui.py,sha256=
|
9
|
+
ads/aqua/ui.py,sha256=PYyr46ewx9Qygcsv6BryUF6rLHU0t5YjUgKSb1uZK2Y,20971
|
10
10
|
ads/aqua/client/__init__.py,sha256=-46EcKQjnWEXxTt85bQzXjA5xsfoBXIGm_syKFlVL1c,178
|
11
11
|
ads/aqua/client/client.py,sha256=zlscNhFZVgGnkJ-aj5iZ5v5FedOzpQc4RJDxGPl9VvQ,31388
|
12
12
|
ads/aqua/client/openai_client.py,sha256=Gi8nSrtPAUOjxRNu-6UUAqtxWyQIQ5CAvatnm7XfnaM,12501
|
13
13
|
ads/aqua/common/__init__.py,sha256=rZrmh1nho40OCeabXCNWtze-mXi-PGKetcZdxZSn3_0,204
|
14
14
|
ads/aqua/common/decorator.py,sha256=JEN6Cy4DYgQbmIR3ShCjTuBMCnilDxq7jkYMJse1rcM,4112
|
15
|
-
ads/aqua/common/entities.py,sha256=
|
16
|
-
ads/aqua/common/enums.py,sha256=
|
15
|
+
ads/aqua/common/entities.py,sha256=ZHlnW2gf6gQ-TmRCjRcobR5qWoM3Vj7RaGYpAIzFKro,9474
|
16
|
+
ads/aqua/common/enums.py,sha256=jAo2JMANIUPkAUEaJeHT6e7-TmrkqH-a2n6smAQQPpA,4088
|
17
17
|
ads/aqua/common/errors.py,sha256=QONm-2jKBg8AjgOKXm6x-arAV1KIW9pdhfNN1Ys21Wo,3044
|
18
|
-
ads/aqua/common/utils.py,sha256=
|
18
|
+
ads/aqua/common/utils.py,sha256=OBFfvtAyI-CkM0ezF8unfYH596KzNkul-o8XMFgwep0,41833
|
19
19
|
ads/aqua/config/__init__.py,sha256=2a_1LI4jWtJpbic5_v4EoOUTXCAH7cmsy9BW5prDHjU,179
|
20
|
-
ads/aqua/config/container_config.py,sha256=
|
20
|
+
ads/aqua/config/container_config.py,sha256=W6V5VZOLyEAbiY3rEbHyv4KY8yRhj8Qp6k1nWX_FwWg,9590
|
21
21
|
ads/aqua/config/evaluation/__init__.py,sha256=2a_1LI4jWtJpbic5_v4EoOUTXCAH7cmsy9BW5prDHjU,179
|
22
22
|
ads/aqua/config/evaluation/evaluation_service_config.py,sha256=NuaQoLVYPHJiWjGfq1-F6-DK0DyOAGjVS87K1SXFVvw,4497
|
23
23
|
ads/aqua/config/utils/__init__.py,sha256=2a_1LI4jWtJpbic5_v4EoOUTXCAH7cmsy9BW5prDHjU,179
|
@@ -44,7 +44,7 @@ ads/aqua/extension/evaluation_ws_msg_handler.py,sha256=dv0iwOSTxYj1kQ1rPEoDmGgFB
|
|
44
44
|
ads/aqua/extension/finetune_handler.py,sha256=97obbhITswTrBvl88g7gk4GvF2SUHBGUAq4rOylFbtQ,3079
|
45
45
|
ads/aqua/extension/model_handler.py,sha256=LlfBqGI4YVXio0gUnqi7Tpe3yfkc7-ToZCcQ3cds6rY,14094
|
46
46
|
ads/aqua/extension/models_ws_msg_handler.py,sha256=VyPbtBZrbRMIYJqOy5DR7j4M4qJK1RBqkxX6RbIvPGE,1851
|
47
|
-
ads/aqua/extension/ui_handler.py,sha256=
|
47
|
+
ads/aqua/extension/ui_handler.py,sha256=OAyRgEQ26rpNA5CwBGG6YXM9qCuPrZAUXW490a-fkxs,12136
|
48
48
|
ads/aqua/extension/ui_websocket_handler.py,sha256=oLFjaDrqkSERbhExdvxjLJX0oRcP-DVJ_aWn0qy0uvo,5084
|
49
49
|
ads/aqua/extension/utils.py,sha256=-uppIKADKl8TFzZB2QWEIei_wtVwWN63qffhuh4Q_KA,5159
|
50
50
|
ads/aqua/extension/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -52,15 +52,16 @@ ads/aqua/extension/models/ws_models.py,sha256=IgAwu324zlT0XII2nFWQUTeEzqvbFch_9K
|
|
52
52
|
ads/aqua/finetuning/__init__.py,sha256=vwYT5PluMR0mDQwVIavn_8Icms7LmvfV_FOrJ8fJx8I,296
|
53
53
|
ads/aqua/finetuning/constants.py,sha256=Fx-8LMyF9ZbV9zo5LUYgCv9VniV7djGnM2iW7js2ILE,844
|
54
54
|
ads/aqua/finetuning/entities.py,sha256=ax6tpqrzuF54YNdwJNRSpzhAnkvOeXdnJ18EA-GfIlw,6885
|
55
|
-
ads/aqua/finetuning/finetuning.py,sha256=
|
55
|
+
ads/aqua/finetuning/finetuning.py,sha256=11DJEEZPa0yu8k0wZvp9IuYEU7IdOd_ZQFUigTqvG0k,31094
|
56
56
|
ads/aqua/model/__init__.py,sha256=j2iylvERdANxgrEDp7b_mLcKMz1CF5Go0qgYCiMwdos,278
|
57
57
|
ads/aqua/model/constants.py,sha256=oOAb4ulsdWBtokCE5SPX7wg8X8SaisLPayua58zhWfY,1856
|
58
|
-
ads/aqua/model/entities.py,sha256=
|
59
|
-
ads/aqua/model/enums.py,sha256=
|
60
|
-
ads/aqua/model/model.py,sha256=
|
58
|
+
ads/aqua/model/entities.py,sha256=JiKB8SnaUxerRMlwrgpyfQLRuTOB8I14J-Rg5RFPwqw,12660
|
59
|
+
ads/aqua/model/enums.py,sha256=bN8GKmgRl40PQrTmd1r-Pqr9VXTIV8gic5-3SAGNnwg,1152
|
60
|
+
ads/aqua/model/model.py,sha256=nq9PehumfFyh_UZDhltVl7Vi_L4TMM9KCx6yqZL3oDw,89027
|
61
|
+
ads/aqua/model/utils.py,sha256=8lYaD51JpAPb7U_xQzRSzFflRefU5Yz6vA80cuZOL0w,2087
|
61
62
|
ads/aqua/modeldeployment/__init__.py,sha256=RJCfU1yazv3hVWi5rS08QVLTpTwZLnlC8wU8diwFjnM,391
|
62
63
|
ads/aqua/modeldeployment/constants.py,sha256=lJF77zwxmlECljDYjwFAMprAUR_zctZHmawiP-4alLg,296
|
63
|
-
ads/aqua/modeldeployment/deployment.py,sha256=
|
64
|
+
ads/aqua/modeldeployment/deployment.py,sha256=5dAN-Tl1C75w6zSKtKCuzfPRjS-GfZ_LP25hq8h6b5k,55549
|
64
65
|
ads/aqua/modeldeployment/entities.py,sha256=qwNH-8eHv-C2QPMITGQkb6haaJRvZ5c0i1H0Aoxeiu4,27100
|
65
66
|
ads/aqua/modeldeployment/inference.py,sha256=rjTF-AM_rHLzL5HCxdLRTrsaSMdB-SzFYUp9dIy5ejw,2109
|
66
67
|
ads/aqua/modeldeployment/utils.py,sha256=Aky4WZ5E564JVZ96X9RYJz_KlB_cAHGzV6mihtd3HV8,22009
|
@@ -98,7 +99,7 @@ ads/common/model_artifact_schema.json,sha256=aNwC9bW5HHMXJK-XAWV56RosqOqiCkzKHBi
|
|
98
99
|
ads/common/model_export_util.py,sha256=rQjL_bb0ecGV2fj0jQXS2-aRbXl4ONDwuNVqdr3DiAQ,26574
|
99
100
|
ads/common/model_metadata.py,sha256=Md1soURHww8GHMG3q_HV0RHVb6dPtg9FZ_7Wmd9L-Yc,641
|
100
101
|
ads/common/object_storage_details.py,sha256=bvqIyB-zLpr5NMnZW8YtSupVH3RpWLBgbR3wPYlQhPU,9531
|
101
|
-
ads/common/oci_client.py,sha256=
|
102
|
+
ads/common/oci_client.py,sha256=S7Idou_9tQAd-_fPjAZBkHzkPnmJ_NPRI93lQsFcUiI,6164
|
102
103
|
ads/common/oci_datascience.py,sha256=biBgm-udtSYRL46XYfBFJjpkPFcw2ew-xvp3rbbpwmI,1698
|
103
104
|
ads/common/oci_logging.py,sha256=U0HRAUkpnycGpo2kWMrT3wjQVFZaWqLL6pZ2B6_epsM,41925
|
104
105
|
ads/common/oci_mixin.py,sha256=mhja5UomrhXH43uB0jT-u2KaT37op9tM-snxvtGfc40,34548
|
@@ -723,12 +724,12 @@ ads/opctl/operator/lowcode/forecast/model/__init__.py,sha256=sAqmLhogrLXb3xI7dPO
|
|
723
724
|
ads/opctl/operator/lowcode/forecast/model/arima.py,sha256=PvHoTdDr6RIC4I-YLzed91td6Pq6uxbgluEdu_h0e3c,11766
|
724
725
|
ads/opctl/operator/lowcode/forecast/model/automlx.py,sha256=4XwS60f7Cs9-oexAn_v0hiWHmrw4jBY_o-_VLzuOd-4,22891
|
725
726
|
ads/opctl/operator/lowcode/forecast/model/autots.py,sha256=UThBBGsEiC3WLSn-BPAuNWT_ZFa3bYMu52keB0vvSt8,13137
|
726
|
-
ads/opctl/operator/lowcode/forecast/model/base_model.py,sha256=
|
727
|
+
ads/opctl/operator/lowcode/forecast/model/base_model.py,sha256=NEc8DknGQWUXdLhqbLNtpwsYowGB9GBly0m7cYBrwaM,36585
|
727
728
|
ads/opctl/operator/lowcode/forecast/model/factory.py,sha256=5a9A3ql-bU412BiTB20ob6OxQlkdk8z_tGONMwDXT1k,3900
|
728
729
|
ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py,sha256=2NsWE2WtD_O7uAXw42_3tmG3vb5lk3mdnzCZTph4hao,18903
|
729
730
|
ads/opctl/operator/lowcode/forecast/model/ml_forecast.py,sha256=t5x6EBxOd7XwfT3FGdt-n9gscxaHMm3R2A4Evvxbj38,9646
|
730
731
|
ads/opctl/operator/lowcode/forecast/model/neuralprophet.py,sha256=60nfNGxjRDsD09Sg7s1YG8G8Qxfcyw0_2rW2PcNy1-c,20021
|
731
|
-
ads/opctl/operator/lowcode/forecast/model/prophet.py,sha256=
|
732
|
+
ads/opctl/operator/lowcode/forecast/model/prophet.py,sha256=M9WpL0A5yAr10MljAz9Tnbp6Xd4Zg4kf4a_RiQ4l0Lg,17329
|
732
733
|
ads/opctl/operator/lowcode/forecast/whatifserve/__init__.py,sha256=JNDDjLrNorKXMHUuXMifqXea3eheST-lnrcwCl2bWrk,242
|
733
734
|
ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py,sha256=w42anuqAScEQ0vBG3vW4LVLNq1bPdpAWGQEmNhMwZ08,12052
|
734
735
|
ads/opctl/operator/lowcode/forecast/whatifserve/score.py,sha256=JjEDtrqUfL4x9t-vvafXMLNwY9-vgc6QPX_Ee-wmI58,8709
|
@@ -807,7 +808,7 @@ ads/secrets/oracledb.py,sha256=VAbsY206gc_Ru8FBOCKNGnIlX4VprIIQ9PmBoujRy_k,6146
|
|
807
808
|
ads/secrets/secrets.py,sha256=k_f3hwh5RI7Hv7zEKDDuxh7kGB-F29bK15jxgu4sxVw,15197
|
808
809
|
ads/telemetry/__init__.py,sha256=_pKx4hDK7DUXHjvAq4Zbeg6wl9_UkgGE7O77KWezu8g,230
|
809
810
|
ads/telemetry/base.py,sha256=6kKVSfTxx2Dr0XL7R8OfjTy3hJoJpKMvP6D7RdVddl4,2199
|
810
|
-
ads/telemetry/client.py,sha256=
|
811
|
+
ads/telemetry/client.py,sha256=71hUqn-fF24zlb84ew5A0gugdkhBmzn30JEuNHDnMyM,5000
|
811
812
|
ads/telemetry/telemetry.py,sha256=xCu64tUEzYzFaXEMxnMdtQJPme5-9sW8l3uxibN4E04,7930
|
812
813
|
ads/templates/dataflow_pyspark.jinja2,sha256=JiTuaGt5LC7z1mrDoDIbZ5UskBETLpm0lMpn5VZYNGs,254
|
813
814
|
ads/templates/dataflow_sparksql.jinja2,sha256=8MvGzj7PWgUNo-9dg6zil8WTpBL3eNcR815fz64v1yM,466
|
@@ -851,8 +852,8 @@ ads/type_discovery/unknown_detector.py,sha256=yZuYQReO7PUyoWZE7onhhtYaOg6088wf1y
|
|
851
852
|
ads/type_discovery/zipcode_detector.py,sha256=3AlETg_ZF4FT0u914WXvTT3F3Z6Vf51WiIt34yQMRbw,1421
|
852
853
|
ads/vault/__init__.py,sha256=x9tMdDAOdF5iDHk9u2di_K-ze5Nq068x25EWOBoWwqY,245
|
853
854
|
ads/vault/vault.py,sha256=hFBkpYE-Hfmzu1L0sQwUfYcGxpWmgG18JPndRl0NOXI,8624
|
854
|
-
oracle_ads-2.13.
|
855
|
-
oracle_ads-2.13.
|
856
|
-
oracle_ads-2.13.
|
857
|
-
oracle_ads-2.13.
|
858
|
-
oracle_ads-2.13.
|
855
|
+
oracle_ads-2.13.9.dist-info/entry_points.txt,sha256=9VFnjpQCsMORA4rVkvN8eH6D3uHjtegb9T911t8cqV0,35
|
856
|
+
oracle_ads-2.13.9.dist-info/licenses/LICENSE.txt,sha256=zoGmbfD1IdRKx834U0IzfFFFo5KoFK71TND3K9xqYqo,1845
|
857
|
+
oracle_ads-2.13.9.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
858
|
+
oracle_ads-2.13.9.dist-info/METADATA,sha256=TW6czNo8lhOSi7ZdTRIEKk9lEbaEWSenFfdQksFrrUE,16764
|
859
|
+
oracle_ads-2.13.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|