oracle-ads 2.11.10__py3-none-any.whl → 2.11.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ads/aqua/common/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, copy_file
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
- """Loads the compartment mapping json from service bucket. This json file has a service-model-compartment key which
544
- contains a dictionary of namespaces and the compartment OCID of the service models in that namespace.
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 could not be found. "
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
- for model in models:
668
- namespace, bucket_name, prefix = (
669
- model["namespace"],
670
- model["bucketName"],
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 not base_model_path:
680
- raise AquaValueError(
681
- f"Base Model should come from the bucket {AQUA_SERVICE_MODELS_BUCKET}. "
682
- f"Other paths are not supported by Aqua."
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
- if source.compartment_id != ODSC_MODEL_COMPARTMENT_OCID:
113
- raise AquaValueError(
114
- f"Fine tuning is only supported for Aqua service models in {ODSC_MODEL_COMPARTMENT_OCID}. "
115
- "Use a valid Aqua service model id instead."
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
- # 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",
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")
@@ -85,6 +86,8 @@ DEBUG_TELEMETRY = os.environ.get("DEBUG_TELEMETRY", None)
85
86
  AQUA_SERVICE_NAME = "aqua"
86
87
  DATA_SCIENCE_SERVICE_NAME = "data-science"
87
88
 
89
+ THREADED_DEFAULT_TIMEOUT = os.environ.get("THREADED_DEFAULT_TIMEOUT", 5)
90
+
88
91
 
89
92
  def export(
90
93
  uri: Optional[str] = DEFAULT_CONFIG_PATH,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oracle_ads
3
- Version: 2.11.10
3
+ Version: 2.11.11
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,6 +1,6 @@
1
1
  ads/__init__.py,sha256=OxHySbHbMqPgZ8sUj33Bxy-smSiNgRjtcSUV77oBL08,3787
2
2
  ads/cli.py,sha256=hjRcQfXFzkh37fbyUBg95I3R0brslZLf9IQU8nSCxio,3933
3
- ads/config.py,sha256=bnDj2umPk4Jx9dy3Kh1JicUjm_XkHartgnHUaLehbXQ,7979
3
+ ads/config.py,sha256=ySDPxRi1Ms0rbiFE_VOASgfTVcL_iZu0uLhkCpkEEdc,8054
4
4
  ads/aqua/__init__.py,sha256=IUKZAsxUGVicsyeSwsGwK6rAUJ1vIUW9ywduA3U22xc,1015
5
5
  ads/aqua/app.py,sha256=8C6zvuB-w0W9U6PyDxOdHXCfuENaCuAhSsfzJmHBWq0,11623
6
6
  ads/aqua/cli.py,sha256=W-0kswzRDEilqHyw5GSMOrARgvOyPRtkEtpy54ew0Jo,3907
@@ -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=nn0l2ZOGOfbLfHkcaFLHLut7UJTAg9lBqDBiUvhuP7M,25982
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=a-83VKslwSKw2yWG-_0GSrD3G1J3ypkK7qDLqckflHs,24366
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=A5ch4JxD0u75L2Zzw07gPQ_ynyuq4ixq9oqKIWDJplE,35861
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.10.dist-info/entry_points.txt,sha256=9VFnjpQCsMORA4rVkvN8eH6D3uHjtegb9T911t8cqV0,35
787
- oracle_ads-2.11.10.dist-info/LICENSE.txt,sha256=zoGmbfD1IdRKx834U0IzfFFFo5KoFK71TND3K9xqYqo,1845
788
- oracle_ads-2.11.10.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
789
- oracle_ads-2.11.10.dist-info/METADATA,sha256=YYmO-ooQDVDzZlLoy1DHfhgQcdQ5EY9YGls_wxcTSTE,15757
790
- oracle_ads-2.11.10.dist-info/RECORD,,
787
+ oracle_ads-2.11.11.dist-info/entry_points.txt,sha256=9VFnjpQCsMORA4rVkvN8eH6D3uHjtegb9T911t8cqV0,35
788
+ oracle_ads-2.11.11.dist-info/LICENSE.txt,sha256=zoGmbfD1IdRKx834U0IzfFFFo5KoFK71TND3K9xqYqo,1845
789
+ oracle_ads-2.11.11.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
790
+ oracle_ads-2.11.11.dist-info/METADATA,sha256=DmKOw1ACxyqtjbH59VFZTfdiWw1_qDjUOXhcULrBRrE,15757
791
+ oracle_ads-2.11.11.dist-info/RECORD,,