oracle-ads 2.11.10__py3-none-any.whl → 2.11.12__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 +9 -1
- ads/aqua/common/utils.py +26 -19
- ads/aqua/finetuning/finetuning.py +8 -5
- ads/aqua/model/model.py +11 -7
- ads/common/decorator/threaded.py +97 -0
- ads/config.py +10 -0
- {oracle_ads-2.11.10.dist-info → oracle_ads-2.11.12.dist-info}/METADATA +1 -1
- {oracle_ads-2.11.10.dist-info → oracle_ads-2.11.12.dist-info}/RECORD +11 -10
- {oracle_ads-2.11.10.dist-info → oracle_ads-2.11.12.dist-info}/LICENSE.txt +0 -0
- {oracle_ads-2.11.10.dist-info → oracle_ads-2.11.12.dist-info}/WHEEL +0 -0
- {oracle_ads-2.11.10.dist-info → oracle_ads-2.11.12.dist-info}/entry_points.txt +0 -0
ads/aqua/app.py
CHANGED
@@ -303,7 +303,15 @@ class AquaApp:
|
|
303
303
|
config_file_name=config_file_name,
|
304
304
|
)
|
305
305
|
except:
|
306
|
-
|
306
|
+
# todo: temp fix for issue related to config load for byom models, update logic to choose the right path
|
307
|
+
try:
|
308
|
+
config_path = f"{artifact_path.rstrip('/')}/config/"
|
309
|
+
config = load_config(
|
310
|
+
config_path,
|
311
|
+
config_file_name=config_file_name,
|
312
|
+
)
|
313
|
+
except:
|
314
|
+
pass
|
307
315
|
|
308
316
|
if not config:
|
309
317
|
logger.error(
|
ads/aqua/common/utils.py
CHANGED
@@ -28,10 +28,11 @@ from ads.aqua.common.errors import (
|
|
28
28
|
from ads.aqua.constants import *
|
29
29
|
from ads.aqua.data import AquaResourceIdentifier
|
30
30
|
from ads.common.auth import default_signer
|
31
|
+
from ads.common.decorator.threaded import threaded
|
31
32
|
from ads.common.extended_enum import ExtendedEnumMeta
|
32
33
|
from ads.common.object_storage_details import ObjectStorageDetails
|
33
34
|
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
|
34
|
-
from ads.common.utils import get_console_link, upload_to_os
|
35
|
+
from ads.common.utils import copy_file, get_console_link, upload_to_os
|
35
36
|
from ads.config import AQUA_SERVICE_MODELS_BUCKET, CONDA_BUCKET_NS, TENANCY_OCID
|
36
37
|
from ads.model import DataScienceModel, ModelVersionSet
|
37
38
|
|
@@ -195,6 +196,7 @@ def read_file(file_path: str, **kwargs) -> str:
|
|
195
196
|
return UNKNOWN
|
196
197
|
|
197
198
|
|
199
|
+
@threaded()
|
198
200
|
def load_config(file_path: str, config_file_name: str, **kwargs) -> dict:
|
199
201
|
artifact_path = f"{file_path.rstrip('/')}/{config_file_name}"
|
200
202
|
if artifact_path.startswith("oci://"):
|
@@ -540,8 +542,10 @@ def get_container_image(
|
|
540
542
|
|
541
543
|
|
542
544
|
def fetch_service_compartment() -> Union[str, None]:
|
543
|
-
"""
|
544
|
-
|
545
|
+
"""
|
546
|
+
Loads the compartment mapping json from service bucket.
|
547
|
+
This json file has a service-model-compartment key which contains a dictionary of namespaces
|
548
|
+
and the compartment OCID of the service models in that namespace.
|
545
549
|
"""
|
546
550
|
config_file_name = (
|
547
551
|
f"oci://{AQUA_SERVICE_MODELS_BUCKET}@{CONDA_BUCKET_NS}/service_models/config"
|
@@ -554,8 +558,8 @@ def fetch_service_compartment() -> Union[str, None]:
|
|
554
558
|
)
|
555
559
|
except Exception as e:
|
556
560
|
logger.debug(
|
557
|
-
f"Config file {config_file_name}/{CONTAINER_INDEX} to fetch service compartment OCID
|
558
|
-
f"\n{str(e)}."
|
561
|
+
f"Config file {config_file_name}/{CONTAINER_INDEX} to fetch service compartment OCID "
|
562
|
+
f"could not be found. \n{str(e)}."
|
559
563
|
)
|
560
564
|
return
|
561
565
|
compartment_mapping = config.get(COMPARTMENT_MAPPING_KEY)
|
@@ -664,23 +668,26 @@ def get_model_by_reference_paths(model_file_description: dict):
|
|
664
668
|
fine_tune_output_path = UNKNOWN
|
665
669
|
models = model_file_description["models"]
|
666
670
|
|
667
|
-
|
668
|
-
|
669
|
-
model
|
670
|
-
model
|
671
|
-
model["prefix"],
|
671
|
+
if not models:
|
672
|
+
raise AquaValueError(
|
673
|
+
f"Model path is not available in the model json artifact. "
|
674
|
+
f"Please check if the model created by reference has the correct artifact."
|
672
675
|
)
|
673
|
-
bucket_uri = f"oci://{bucket_name}@{namespace}/{prefix}".rstrip("/")
|
674
|
-
if bucket_name == AQUA_SERVICE_MODELS_BUCKET:
|
675
|
-
base_model_path = bucket_uri
|
676
|
-
else:
|
677
|
-
fine_tune_output_path = bucket_uri
|
678
676
|
|
679
|
-
if
|
680
|
-
|
681
|
-
|
682
|
-
|
677
|
+
if len(models) > 0:
|
678
|
+
# since the model_file_description json does not have a flag to identify the base model, we consider
|
679
|
+
# the first instance to be the base model.
|
680
|
+
base_model_artifact = models[0]
|
681
|
+
base_model_path = f"oci://{base_model_artifact['bucketName']}@{base_model_artifact['namespace']}/{base_model_artifact['prefix']}".rstrip(
|
682
|
+
"/"
|
683
|
+
)
|
684
|
+
if len(models) > 1:
|
685
|
+
# second model is considered as fine-tuned model
|
686
|
+
ft_model_artifact = models[1]
|
687
|
+
fine_tune_output_path = f"oci://{ft_model_artifact['bucketName']}@{ft_model_artifact['namespace']}/{ft_model_artifact['prefix']}".rstrip(
|
688
|
+
"/"
|
683
689
|
)
|
690
|
+
|
684
691
|
return base_model_path, fine_tune_output_path
|
685
692
|
|
686
693
|
|
@@ -109,11 +109,13 @@ class AquaFineTuningApp(AquaApp):
|
|
109
109
|
)
|
110
110
|
|
111
111
|
source = self.get_source(create_fine_tuning_details.ft_source_id)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
112
|
+
|
113
|
+
# todo: revisit validation for fine tuned models
|
114
|
+
# if source.compartment_id != ODSC_MODEL_COMPARTMENT_OCID:
|
115
|
+
# raise AquaValueError(
|
116
|
+
# f"Fine tuning is only supported for Aqua service models in {ODSC_MODEL_COMPARTMENT_OCID}. "
|
117
|
+
# "Use a valid Aqua service model id instead."
|
118
|
+
# )
|
117
119
|
|
118
120
|
target_compartment = (
|
119
121
|
create_fine_tuning_details.compartment_id or COMPARTMENT_OCID
|
@@ -364,6 +366,7 @@ class AquaFineTuningApp(AquaApp):
|
|
364
366
|
source_freeform_tags.pop(Tags.LICENSE, None)
|
365
367
|
source_freeform_tags.update({Tags.READY_TO_FINE_TUNE: "false"})
|
366
368
|
source_freeform_tags.update({Tags.AQUA_TAG: UNKNOWN})
|
369
|
+
source_freeform_tags.pop(Tags.BASE_MODEL_CUSTOM, None)
|
367
370
|
|
368
371
|
self.update_model(
|
369
372
|
model_id=ft_model.id,
|
ads/aqua/model/model.py
CHANGED
@@ -648,15 +648,19 @@ class AquaModelApp(AquaApp):
|
|
648
648
|
copy_model_config(
|
649
649
|
artifact_path=artifact_path, os_path=os_path, auth=default_signer()
|
650
650
|
)
|
651
|
-
|
652
651
|
except:
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
value=os_path,
|
657
|
-
description="artifact location",
|
658
|
-
category="Other",
|
652
|
+
logger.debug(
|
653
|
+
f"Proceeding with model registration without copying model config files at {os_path}. "
|
654
|
+
f"Default configuration will be used for deployment and fine-tuning."
|
659
655
|
)
|
656
|
+
# Set artifact location to user bucket, and replace existing key if present.
|
657
|
+
metadata.add(
|
658
|
+
key=MODEL_BY_REFERENCE_OSS_PATH_KEY,
|
659
|
+
value=os_path,
|
660
|
+
description="artifact location",
|
661
|
+
category="Other",
|
662
|
+
replace=True,
|
663
|
+
)
|
660
664
|
|
661
665
|
model = (
|
662
666
|
model.with_custom_metadata_list(metadata)
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8; -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2021, 2024 Oracle and/or its affiliates.
|
5
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
6
|
+
|
7
|
+
|
8
|
+
import concurrent.futures
|
9
|
+
import functools
|
10
|
+
import logging
|
11
|
+
from typing import Optional
|
12
|
+
|
13
|
+
from git import Optional
|
14
|
+
|
15
|
+
from ads.config import THREADED_DEFAULT_TIMEOUT
|
16
|
+
|
17
|
+
logger = logging.getLogger(__name__)
|
18
|
+
|
19
|
+
# Create a global thread pool with a maximum of 10 threads
|
20
|
+
thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10)
|
21
|
+
|
22
|
+
|
23
|
+
class TimeoutError(Exception):
|
24
|
+
"""
|
25
|
+
Custom exception to be raised when a function times out.
|
26
|
+
|
27
|
+
Attributes
|
28
|
+
----------
|
29
|
+
message : str
|
30
|
+
The error message describing what went wrong.
|
31
|
+
|
32
|
+
Parameters
|
33
|
+
----------
|
34
|
+
message : str
|
35
|
+
The error message.
|
36
|
+
"""
|
37
|
+
|
38
|
+
def __init__(
|
39
|
+
self,
|
40
|
+
func_name: str,
|
41
|
+
timeout: int,
|
42
|
+
message: Optional[str] = "The operation could not be completed in time.",
|
43
|
+
):
|
44
|
+
super().__init__(
|
45
|
+
f"{message} The function '{func_name}' exceeded the timeout of {timeout} seconds."
|
46
|
+
)
|
47
|
+
|
48
|
+
|
49
|
+
def threaded(timeout: Optional[int] = THREADED_DEFAULT_TIMEOUT):
|
50
|
+
"""
|
51
|
+
Decorator to run a function in a separate thread using a global thread pool.
|
52
|
+
|
53
|
+
Parameters
|
54
|
+
----------
|
55
|
+
timeout (int, optional)
|
56
|
+
The maximum time in seconds to wait for the function to complete.
|
57
|
+
If the function does not complete within this time, "timeout" is returned.
|
58
|
+
|
59
|
+
Returns
|
60
|
+
-------
|
61
|
+
function: The wrapped function that will run in a separate thread with the specified timeout.
|
62
|
+
"""
|
63
|
+
|
64
|
+
def decorator(func):
|
65
|
+
@functools.wraps(func)
|
66
|
+
def wrapper(*args, **kwargs):
|
67
|
+
"""
|
68
|
+
Wrapper function to submit the decorated function to the thread pool and handle timeout.
|
69
|
+
|
70
|
+
Parameters
|
71
|
+
----------
|
72
|
+
*args: Positional arguments to pass to the decorated function.
|
73
|
+
**kwargs: Keyword arguments to pass to the decorated function.
|
74
|
+
|
75
|
+
Returns
|
76
|
+
-------
|
77
|
+
Any: The result of the decorated function if it completes within the timeout.
|
78
|
+
|
79
|
+
Raise
|
80
|
+
-----
|
81
|
+
TimeoutError
|
82
|
+
In case of the function exceeded the timeout.
|
83
|
+
"""
|
84
|
+
future = thread_pool.submit(func, *args, **kwargs)
|
85
|
+
try:
|
86
|
+
return future.result(timeout=timeout)
|
87
|
+
except concurrent.futures.TimeoutError as ex:
|
88
|
+
logger.debug(
|
89
|
+
f"The function '{func.__name__}' "
|
90
|
+
f"exceeded the timeout of {timeout} seconds. "
|
91
|
+
f"{ex}"
|
92
|
+
)
|
93
|
+
raise TimeoutError(func.__name__, timeout)
|
94
|
+
|
95
|
+
return wrapper
|
96
|
+
|
97
|
+
return decorator
|
ads/config.py
CHANGED
@@ -8,6 +8,7 @@ import contextlib
|
|
8
8
|
import inspect
|
9
9
|
import os
|
10
10
|
from typing import Dict, Optional
|
11
|
+
|
11
12
|
from ads.common.config import DEFAULT_CONFIG_PATH, DEFAULT_CONFIG_PROFILE, Config, Mode
|
12
13
|
|
13
14
|
OCI_ODSC_SERVICE_ENDPOINT = os.environ.get("OCI_ODSC_SERVICE_ENDPOINT")
|
@@ -86,6 +87,15 @@ AQUA_SERVICE_NAME = "aqua"
|
|
86
87
|
DATA_SCIENCE_SERVICE_NAME = "data-science"
|
87
88
|
|
88
89
|
|
90
|
+
THREADED_DEFAULT_TIMEOUT = 5
|
91
|
+
try:
|
92
|
+
THREADED_DEFAULT_TIMEOUT = int(
|
93
|
+
os.environ.get("THREADED_DEFAULT_TIMEOUT", THREADED_DEFAULT_TIMEOUT)
|
94
|
+
)
|
95
|
+
except ValueError:
|
96
|
+
pass
|
97
|
+
|
98
|
+
|
89
99
|
def export(
|
90
100
|
uri: Optional[str] = DEFAULT_CONFIG_PATH,
|
91
101
|
auth: Dict = None,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: oracle_ads
|
3
|
-
Version: 2.11.
|
3
|
+
Version: 2.11.12
|
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
|
@@ -1,8 +1,8 @@
|
|
1
1
|
ads/__init__.py,sha256=OxHySbHbMqPgZ8sUj33Bxy-smSiNgRjtcSUV77oBL08,3787
|
2
2
|
ads/cli.py,sha256=hjRcQfXFzkh37fbyUBg95I3R0brslZLf9IQU8nSCxio,3933
|
3
|
-
ads/config.py,sha256=
|
3
|
+
ads/config.py,sha256=t_zDKftVYOLPP-t8IcnzEbtmMRX-6a8QKY9E_SnqA8M,8163
|
4
4
|
ads/aqua/__init__.py,sha256=IUKZAsxUGVicsyeSwsGwK6rAUJ1vIUW9ywduA3U22xc,1015
|
5
|
-
ads/aqua/app.py,sha256=
|
5
|
+
ads/aqua/app.py,sha256=wKnvSiD4nROcRUjGJ2FktRDeF4rWGTT_BjekMqHd9Nw,11994
|
6
6
|
ads/aqua/cli.py,sha256=W-0kswzRDEilqHyw5GSMOrARgvOyPRtkEtpy54ew0Jo,3907
|
7
7
|
ads/aqua/constants.py,sha256=X_hGws37iJML6qxjEJLKbVbBS_CrqGZw9aTqZTMG0uA,2473
|
8
8
|
ads/aqua/data.py,sha256=7T7kdHGnEH6FXL_7jv_Da0CjEWXfjQZTFkaZWQikis4,932
|
@@ -11,7 +11,7 @@ ads/aqua/common/__init__.py,sha256=rZrmh1nho40OCeabXCNWtze-mXi-PGKetcZdxZSn3_0,2
|
|
11
11
|
ads/aqua/common/decorator.py,sha256=XFS7tYGkN4dVzmB1wTYiJk1XqJ-VLhvzfZjExiQClgc,3640
|
12
12
|
ads/aqua/common/enums.py,sha256=wgpKif1SIXFRLhceZtYuTm8jUG5r3E3pVKPWvHZX_KA,2136
|
13
13
|
ads/aqua/common/errors.py,sha256=Ev2xbaqkDqeCYDx4ZgOKOoM0sXsOXP3GIV6N1lhIUxM,3085
|
14
|
-
ads/aqua/common/utils.py,sha256=
|
14
|
+
ads/aqua/common/utils.py,sha256=BzREMfq-eMc3AJ3MpowON-vgyKUuM_upxwQeybZ31JQ,26349
|
15
15
|
ads/aqua/config/config.py,sha256=i-AIqNyIvdzI60l11XBfH22wMnxj-mkiRienZwCfqHc,744
|
16
16
|
ads/aqua/config/deployment_config_defaults.json,sha256=SoGP0J3BChwhR7L0HHpgLfSxLi0DsDfuLSGwWnrh5Zk,121
|
17
17
|
ads/aqua/config/resource_limit_names.json,sha256=Nsd_Ll5X09Wzhab7alAc2Utg8Bt2BSABK-E6JefUeA0,195
|
@@ -42,12 +42,12 @@ ads/aqua/extension/models/ws_models.py,sha256=Kv1N6ua7LA2FagCRXjHA8ahDGwwetmwBu0
|
|
42
42
|
ads/aqua/finetuning/__init__.py,sha256=vwYT5PluMR0mDQwVIavn_8Icms7LmvfV_FOrJ8fJx8I,296
|
43
43
|
ads/aqua/finetuning/constants.py,sha256=7LGF-rbbp-3IS8APjM9ABVHvm0EsaoC9A7XvxTgnRz4,743
|
44
44
|
ads/aqua/finetuning/entities.py,sha256=ZGFqewDV_YIGgmJqIXjrprSZE0yFZQF_tdbmQlvhTrQ,4045
|
45
|
-
ads/aqua/finetuning/finetuning.py,sha256=
|
45
|
+
ads/aqua/finetuning/finetuning.py,sha256=5GXya26dmerhwlCxQ4TZJWZh5pr0h-TnkZ6WahJITvY,24497
|
46
46
|
ads/aqua/model/__init__.py,sha256=j2iylvERdANxgrEDp7b_mLcKMz1CF5Go0qgYCiMwdos,278
|
47
47
|
ads/aqua/model/constants.py,sha256=eUVl3FK8SRpfnDc1jNF09CkbWXyxmfTgW6Nqvus8lx0,1476
|
48
48
|
ads/aqua/model/entities.py,sha256=vJnDKF3wcASSXz121MHLr47v3mGeQlakGqfSa8df0lY,8660
|
49
49
|
ads/aqua/model/enums.py,sha256=t8GbK2nblIPm3gClR8W31RmbtTuqpoSzoN4W3JfD6AI,1004
|
50
|
-
ads/aqua/model/model.py,sha256=
|
50
|
+
ads/aqua/model/model.py,sha256=Z-GLtJoOvvx20z6_Jzv9lrS8XNC4AmJkhWlKd8F4UQo,36133
|
51
51
|
ads/aqua/modeldeployment/__init__.py,sha256=RJCfU1yazv3hVWi5rS08QVLTpTwZLnlC8wU8diwFjnM,391
|
52
52
|
ads/aqua/modeldeployment/constants.py,sha256=I8o0ih2w2PN-hj_gS6-hTKhYTvimVEphG_ShYSZSMKY,586
|
53
53
|
ads/aqua/modeldeployment/deployment.py,sha256=M58UUUBdeTIU0W5yoDOMOmsQcYKzlYYfdUIUQMr9fOg,26973
|
@@ -98,6 +98,7 @@ ads/common/decorator/argument_to_case.py,sha256=Egff-QFUmfC8BUAozhyKOXP_-I9w_gau
|
|
98
98
|
ads/common/decorator/deprecate.py,sha256=otuXKIbBgqY6Qf86UCuqOyOg0q8bbF7-83rKn8cXOBA,2063
|
99
99
|
ads/common/decorator/require_nonempty_arg.py,sha256=QGUCwhh5NO3SoKQJ3qUro9EKE9DvK3W972XXiuUCWvE,2075
|
100
100
|
ads/common/decorator/runtime_dependency.py,sha256=XH3WVTFy0tABDw50gdiyqau8lMMd7X6evXTVF_lIrf0,6391
|
101
|
+
ads/common/decorator/threaded.py,sha256=940-52749K63N9zaT2GvV8JQ63FBCIJ_bVxakAo5AHo,2813
|
101
102
|
ads/common/decorator/utils.py,sha256=B9hC0ZTPvi8AYrbLzXjNMbYFHNZFyuONRTq8HFHdm5s,1253
|
102
103
|
ads/common/function/__init__.py,sha256=xMyuwB5xsIEW9MFmvyjmF1YnRarsIjeFe2Ib-aprCG4,210
|
103
104
|
ads/common/function/fn_util.py,sha256=ziXm5oHnesVTuUKQLlXGumKxhQiDOPCWy6HSULZKvIQ,4937
|
@@ -783,8 +784,8 @@ ads/type_discovery/unknown_detector.py,sha256=yZuYQReO7PUyoWZE7onhhtYaOg6088wf1y
|
|
783
784
|
ads/type_discovery/zipcode_detector.py,sha256=3AlETg_ZF4FT0u914WXvTT3F3Z6Vf51WiIt34yQMRbw,1421
|
784
785
|
ads/vault/__init__.py,sha256=x9tMdDAOdF5iDHk9u2di_K-ze5Nq068x25EWOBoWwqY,245
|
785
786
|
ads/vault/vault.py,sha256=hFBkpYE-Hfmzu1L0sQwUfYcGxpWmgG18JPndRl0NOXI,8624
|
786
|
-
oracle_ads-2.11.
|
787
|
-
oracle_ads-2.11.
|
788
|
-
oracle_ads-2.11.
|
789
|
-
oracle_ads-2.11.
|
790
|
-
oracle_ads-2.11.
|
787
|
+
oracle_ads-2.11.12.dist-info/entry_points.txt,sha256=9VFnjpQCsMORA4rVkvN8eH6D3uHjtegb9T911t8cqV0,35
|
788
|
+
oracle_ads-2.11.12.dist-info/LICENSE.txt,sha256=zoGmbfD1IdRKx834U0IzfFFFo5KoFK71TND3K9xqYqo,1845
|
789
|
+
oracle_ads-2.11.12.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
790
|
+
oracle_ads-2.11.12.dist-info/METADATA,sha256=ag17uHeSMSvB5r17RCx4VpGf8R_zoWhfh3IfK45_j_s,15757
|
791
|
+
oracle_ads-2.11.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|