oracle-ads 2.13.1rc0__py3-none-any.whl → 2.13.2rc1__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 +7 -1
- ads/aqua/app.py +24 -23
- ads/aqua/client/client.py +48 -11
- ads/aqua/common/entities.py +28 -1
- ads/aqua/common/enums.py +13 -7
- ads/aqua/common/utils.py +8 -13
- ads/aqua/config/container_config.py +203 -0
- ads/aqua/config/evaluation/evaluation_service_config.py +5 -181
- ads/aqua/constants.py +0 -1
- ads/aqua/evaluation/evaluation.py +4 -4
- ads/aqua/extension/base_handler.py +4 -0
- ads/aqua/extension/model_handler.py +19 -28
- ads/aqua/finetuning/finetuning.py +2 -3
- ads/aqua/model/entities.py +2 -3
- ads/aqua/model/model.py +25 -30
- ads/aqua/modeldeployment/deployment.py +6 -14
- ads/aqua/modeldeployment/entities.py +2 -2
- ads/aqua/server/__init__.py +4 -0
- ads/aqua/server/__main__.py +24 -0
- ads/aqua/server/app.py +47 -0
- ads/aqua/server/aqua_spec.yml +1291 -0
- ads/aqua/ui.py +5 -199
- ads/common/auth.py +20 -11
- ads/common/utils.py +91 -11
- ads/config.py +3 -0
- ads/llm/__init__.py +1 -0
- ads/llm/langchain/plugins/llms/oci_data_science_model_deployment_endpoint.py +32 -23
- ads/model/artifact_downloader.py +4 -1
- ads/model/common/utils.py +15 -3
- ads/model/datascience_model.py +339 -8
- ads/model/model_metadata.py +54 -14
- ads/model/model_version_set.py +5 -3
- ads/model/service/oci_datascience_model.py +477 -5
- ads/opctl/operator/common/utils.py +16 -0
- ads/opctl/operator/lowcode/anomaly/model/base_model.py +3 -3
- ads/opctl/operator/lowcode/anomaly/model/randomcutforest.py +1 -1
- ads/opctl/operator/lowcode/anomaly/utils.py +1 -1
- ads/opctl/operator/lowcode/common/data.py +5 -2
- ads/opctl/operator/lowcode/common/transformations.py +7 -13
- ads/opctl/operator/lowcode/common/utils.py +7 -2
- ads/opctl/operator/lowcode/forecast/model/arima.py +15 -10
- ads/opctl/operator/lowcode/forecast/model/automlx.py +39 -9
- ads/opctl/operator/lowcode/forecast/model/autots.py +7 -5
- ads/opctl/operator/lowcode/forecast/model/base_model.py +135 -110
- ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +30 -14
- ads/opctl/operator/lowcode/forecast/model/ml_forecast.py +2 -2
- ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +46 -32
- ads/opctl/operator/lowcode/forecast/model/prophet.py +82 -29
- ads/opctl/operator/lowcode/forecast/model_evaluator.py +142 -62
- ads/opctl/operator/lowcode/forecast/operator_config.py +29 -3
- ads/opctl/operator/lowcode/forecast/schema.yaml +1 -1
- ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py +108 -56
- {oracle_ads-2.13.1rc0.dist-info → oracle_ads-2.13.2rc1.dist-info}/METADATA +15 -12
- {oracle_ads-2.13.1rc0.dist-info → oracle_ads-2.13.2rc1.dist-info}/RECORD +57 -53
- {oracle_ads-2.13.1rc0.dist-info → oracle_ads-2.13.2rc1.dist-info}/WHEEL +1 -1
- ads/aqua/config/evaluation/evaluation_service_model_config.py +0 -8
- {oracle_ads-2.13.1rc0.dist-info → oracle_ads-2.13.2rc1.dist-info}/entry_points.txt +0 -0
- {oracle_ads-2.13.1rc0.dist-info → oracle_ads-2.13.2rc1.dist-info/licenses}/LICENSE.txt +0 -0
ads/aqua/ui.py
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# Copyright (c) 2024 Oracle and/or its affiliates.
|
2
|
+
# Copyright (c) 2024, 2025 Oracle and/or its affiliates.
|
3
3
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
4
4
|
import concurrent.futures
|
5
|
-
from dataclasses import dataclass, field, fields
|
6
5
|
from datetime import datetime, timedelta
|
7
|
-
from enum import Enum
|
8
6
|
from threading import Lock
|
9
|
-
from typing import Dict, List, Optional
|
10
7
|
|
11
8
|
from cachetools import TTLCache
|
12
9
|
from oci.exceptions import ServiceError
|
@@ -14,210 +11,18 @@ from oci.identity.models import Compartment
|
|
14
11
|
|
15
12
|
from ads.aqua import logger
|
16
13
|
from ads.aqua.app import AquaApp
|
17
|
-
from ads.aqua.common.entities import ContainerSpec
|
18
14
|
from ads.aqua.common.enums import Tags
|
19
15
|
from ads.aqua.common.errors import AquaResourceAccessError, AquaValueError
|
20
16
|
from ads.aqua.common.utils import get_container_config, sanitize_response
|
17
|
+
from ads.aqua.config.container_config import AquaContainerConfig
|
21
18
|
from ads.aqua.constants import PRIVATE_ENDPOINT_TYPE
|
22
19
|
from ads.common import oci_client as oc
|
23
20
|
from ads.common.auth import default_signer
|
24
21
|
from ads.common.object_storage_details import ObjectStorageDetails
|
25
|
-
from ads.
|
26
|
-
from ads.config import (
|
27
|
-
COMPARTMENT_OCID,
|
28
|
-
DATA_SCIENCE_SERVICE_NAME,
|
29
|
-
TENANCY_OCID,
|
30
|
-
)
|
22
|
+
from ads.config import COMPARTMENT_OCID, DATA_SCIENCE_SERVICE_NAME, TENANCY_OCID
|
31
23
|
from ads.telemetry import telemetry
|
32
24
|
|
33
25
|
|
34
|
-
class ModelFormat(Enum):
|
35
|
-
GGUF = "GGUF"
|
36
|
-
SAFETENSORS = "SAFETENSORS"
|
37
|
-
UNKNOWN = "UNKNOWN"
|
38
|
-
|
39
|
-
def to_dict(self):
|
40
|
-
return self.value
|
41
|
-
|
42
|
-
|
43
|
-
# todo: the container config spec information is shared across ui and deployment modules, move them
|
44
|
-
# within ads.aqua.common.entities. In that case, check for circular imports due to usage of get_container_config.
|
45
|
-
|
46
|
-
|
47
|
-
@dataclass(repr=False)
|
48
|
-
class AquaContainerEvaluationConfig(DataClassSerializable):
|
49
|
-
"""
|
50
|
-
Represents the evaluation configuration for the container.
|
51
|
-
"""
|
52
|
-
|
53
|
-
inference_max_threads: Optional[int] = None
|
54
|
-
inference_rps: Optional[int] = None
|
55
|
-
inference_timeout: Optional[int] = None
|
56
|
-
inference_retries: Optional[int] = None
|
57
|
-
inference_backoff_factor: Optional[int] = None
|
58
|
-
inference_delay: Optional[int] = None
|
59
|
-
|
60
|
-
@classmethod
|
61
|
-
def from_config(cls, config: dict) -> "AquaContainerEvaluationConfig":
|
62
|
-
return cls(
|
63
|
-
inference_max_threads=config.get("inference_max_threads"),
|
64
|
-
inference_rps=config.get("inference_rps"),
|
65
|
-
inference_timeout=config.get("inference_timeout"),
|
66
|
-
inference_retries=config.get("inference_retries"),
|
67
|
-
inference_backoff_factor=config.get("inference_backoff_factor"),
|
68
|
-
inference_delay=config.get("inference_delay"),
|
69
|
-
)
|
70
|
-
|
71
|
-
def to_filtered_dict(self):
|
72
|
-
return {
|
73
|
-
field.name: getattr(self, field.name)
|
74
|
-
for field in fields(self)
|
75
|
-
if getattr(self, field.name) is not None
|
76
|
-
}
|
77
|
-
|
78
|
-
|
79
|
-
@dataclass(repr=False)
|
80
|
-
class AquaContainerConfigSpec(DataClassSerializable):
|
81
|
-
cli_param: str = None
|
82
|
-
server_port: str = None
|
83
|
-
health_check_port: str = None
|
84
|
-
env_vars: List[dict] = None
|
85
|
-
restricted_params: List[str] = None
|
86
|
-
|
87
|
-
|
88
|
-
@dataclass(repr=False)
|
89
|
-
class AquaContainerConfigItem(DataClassSerializable):
|
90
|
-
"""Represents an item of the AQUA container configuration."""
|
91
|
-
|
92
|
-
class Platform(Enum):
|
93
|
-
ARM_CPU = "ARM_CPU"
|
94
|
-
NVIDIA_GPU = "NVIDIA_GPU"
|
95
|
-
|
96
|
-
def to_dict(self):
|
97
|
-
return self.value
|
98
|
-
|
99
|
-
def __repr__(self):
|
100
|
-
return repr(self.value)
|
101
|
-
|
102
|
-
name: str = None
|
103
|
-
version: str = None
|
104
|
-
display_name: str = None
|
105
|
-
family: str = None
|
106
|
-
platforms: List[Platform] = None
|
107
|
-
model_formats: List[ModelFormat] = None
|
108
|
-
spec: AquaContainerConfigSpec = field(default_factory=AquaContainerConfigSpec)
|
109
|
-
|
110
|
-
|
111
|
-
@dataclass(repr=False)
|
112
|
-
class AquaContainerConfig(DataClassSerializable):
|
113
|
-
"""
|
114
|
-
Represents a configuration with AQUA containers to be returned to the client.
|
115
|
-
"""
|
116
|
-
|
117
|
-
inference: Dict[str, AquaContainerConfigItem] = field(default_factory=dict)
|
118
|
-
finetune: Dict[str, AquaContainerConfigItem] = field(default_factory=dict)
|
119
|
-
evaluate: Dict[str, AquaContainerConfigItem] = field(default_factory=dict)
|
120
|
-
|
121
|
-
def to_dict(self):
|
122
|
-
return {
|
123
|
-
"inference": list(self.inference.values()),
|
124
|
-
"finetune": list(self.finetune.values()),
|
125
|
-
"evaluate": list(self.evaluate.values()),
|
126
|
-
}
|
127
|
-
|
128
|
-
@classmethod
|
129
|
-
def from_container_index_json(
|
130
|
-
cls,
|
131
|
-
config: Optional[Dict] = None,
|
132
|
-
enable_spec: Optional[bool] = False,
|
133
|
-
) -> "AquaContainerConfig":
|
134
|
-
"""
|
135
|
-
Create an AquaContainerConfig instance from a container index JSON.
|
136
|
-
|
137
|
-
Parameters
|
138
|
-
----------
|
139
|
-
config : Dict
|
140
|
-
The container index JSON.
|
141
|
-
enable_spec: bool
|
142
|
-
flag to check if container specification details should be fetched.
|
143
|
-
|
144
|
-
Returns
|
145
|
-
-------
|
146
|
-
AquaContainerConfig
|
147
|
-
The container configuration instance.
|
148
|
-
"""
|
149
|
-
if not config:
|
150
|
-
config = get_container_config()
|
151
|
-
inference_items = {}
|
152
|
-
finetune_items = {}
|
153
|
-
evaluate_items = {}
|
154
|
-
|
155
|
-
# extract inference containers
|
156
|
-
for container_type, containers in config.items():
|
157
|
-
if isinstance(containers, list):
|
158
|
-
for container in containers:
|
159
|
-
platforms = [
|
160
|
-
AquaContainerConfigItem.Platform[platform]
|
161
|
-
for platform in container.get("platforms", [])
|
162
|
-
]
|
163
|
-
model_formats = [
|
164
|
-
ModelFormat[model_format]
|
165
|
-
for model_format in container.get("modelFormats", [])
|
166
|
-
]
|
167
|
-
container_spec = (
|
168
|
-
config.get(ContainerSpec.CONTAINER_SPEC, {}).get(
|
169
|
-
container_type, {}
|
170
|
-
)
|
171
|
-
if enable_spec
|
172
|
-
else None
|
173
|
-
)
|
174
|
-
container_item = AquaContainerConfigItem(
|
175
|
-
name=container.get("name", ""),
|
176
|
-
version=container.get("version", ""),
|
177
|
-
display_name=container.get(
|
178
|
-
"displayName", container.get("version", "")
|
179
|
-
),
|
180
|
-
family=container_type,
|
181
|
-
platforms=platforms,
|
182
|
-
model_formats=model_formats,
|
183
|
-
spec=(
|
184
|
-
AquaContainerConfigSpec(
|
185
|
-
cli_param=container_spec.get(
|
186
|
-
ContainerSpec.CLI_PARM, ""
|
187
|
-
),
|
188
|
-
server_port=container_spec.get(
|
189
|
-
ContainerSpec.SERVER_PORT, ""
|
190
|
-
),
|
191
|
-
health_check_port=container_spec.get(
|
192
|
-
ContainerSpec.HEALTH_CHECK_PORT, ""
|
193
|
-
),
|
194
|
-
env_vars=container_spec.get(ContainerSpec.ENV_VARS, []),
|
195
|
-
restricted_params=container_spec.get(
|
196
|
-
ContainerSpec.RESTRICTED_PARAMS, []
|
197
|
-
),
|
198
|
-
)
|
199
|
-
if container_spec
|
200
|
-
else None
|
201
|
-
),
|
202
|
-
)
|
203
|
-
if container.get("type") == "inference":
|
204
|
-
inference_items[container_type] = container_item
|
205
|
-
elif (
|
206
|
-
container.get("type") == "fine-tune"
|
207
|
-
or container_type == "odsc-llm-fine-tuning"
|
208
|
-
):
|
209
|
-
finetune_items[container_type] = container_item
|
210
|
-
elif (
|
211
|
-
container.get("type") == "evaluate"
|
212
|
-
or container_type == "odsc-llm-evaluate"
|
213
|
-
):
|
214
|
-
evaluate_items[container_type] = container_item
|
215
|
-
|
216
|
-
return AquaContainerConfig(
|
217
|
-
inference=inference_items, finetune=finetune_items, evaluate=evaluate_items
|
218
|
-
)
|
219
|
-
|
220
|
-
|
221
26
|
class AquaUIApp(AquaApp):
|
222
27
|
"""Contains APIs for supporting Aqua UI.
|
223
28
|
|
@@ -512,7 +317,8 @@ class AquaUIApp(AquaApp):
|
|
512
317
|
|
513
318
|
Returns
|
514
319
|
-------
|
515
|
-
|
320
|
+
str has json representation of `oci.data_science.models.ModelDeploymentShapeSummary`.
|
321
|
+
"""
|
516
322
|
compartment_id = kwargs.pop("compartment_id", COMPARTMENT_OCID)
|
517
323
|
logger.info(
|
518
324
|
f"Loading model deployment shape summary from compartment: {compartment_id}"
|
ads/common/auth.py
CHANGED
@@ -88,13 +88,15 @@ def set_auth(
|
|
88
88
|
auth: Optional[str] = AuthType.API_KEY,
|
89
89
|
oci_config_location: Optional[str] = DEFAULT_LOCATION,
|
90
90
|
profile: Optional[str] = DEFAULT_PROFILE,
|
91
|
-
config: Optional[Dict] =
|
92
|
-
|
93
|
-
|
91
|
+
config: Optional[Dict] = (
|
92
|
+
{"region": os.environ["OCI_RESOURCE_REGION"]}
|
93
|
+
if os.environ.get("OCI_RESOURCE_REGION")
|
94
|
+
else {}
|
95
|
+
),
|
94
96
|
signer: Optional[Any] = None,
|
95
97
|
signer_callable: Optional[Callable] = None,
|
96
|
-
signer_kwargs: Optional[Dict] =
|
97
|
-
client_kwargs: Optional[Dict] =
|
98
|
+
signer_kwargs: Optional[Dict] = None,
|
99
|
+
client_kwargs: Optional[Dict] = None,
|
98
100
|
) -> None:
|
99
101
|
"""
|
100
102
|
Sets the default authentication type.
|
@@ -195,6 +197,9 @@ def set_auth(
|
|
195
197
|
>>> # instance principals authentication dictionary created based on callable with kwargs parameters:
|
196
198
|
>>> ads.set_auth(signer_callable=signer_callable, signer_kwargs=signer_kwargs)
|
197
199
|
"""
|
200
|
+
signer_kwargs = signer_kwargs or {}
|
201
|
+
client_kwargs = client_kwargs or {}
|
202
|
+
|
198
203
|
auth_state = AuthState()
|
199
204
|
|
200
205
|
valid_auth_keys = AuthFactory.classes.keys()
|
@@ -258,9 +263,11 @@ def api_keys(
|
|
258
263
|
"""
|
259
264
|
signer_args = dict(
|
260
265
|
oci_config=oci_config if isinstance(oci_config, Dict) else {},
|
261
|
-
oci_config_location=
|
262
|
-
|
263
|
-
|
266
|
+
oci_config_location=(
|
267
|
+
oci_config
|
268
|
+
if isinstance(oci_config, str)
|
269
|
+
else os.path.expanduser(DEFAULT_LOCATION)
|
270
|
+
),
|
264
271
|
oci_key_profile=profile,
|
265
272
|
client_kwargs=client_kwargs,
|
266
273
|
)
|
@@ -334,9 +341,11 @@ def security_token(
|
|
334
341
|
"""
|
335
342
|
signer_args = dict(
|
336
343
|
oci_config=oci_config if isinstance(oci_config, Dict) else {},
|
337
|
-
oci_config_location=
|
338
|
-
|
339
|
-
|
344
|
+
oci_config_location=(
|
345
|
+
oci_config
|
346
|
+
if isinstance(oci_config, str)
|
347
|
+
else os.path.expanduser(DEFAULT_LOCATION)
|
348
|
+
),
|
340
349
|
oci_key_profile=profile,
|
341
350
|
client_kwargs=client_kwargs,
|
342
351
|
)
|
ads/common/utils.py
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8; -*-
|
3
2
|
|
4
3
|
# Copyright (c) 2020, 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/
|
6
5
|
|
7
|
-
from __future__ import absolute_import, print_function
|
8
6
|
|
9
7
|
import collections
|
10
8
|
import contextlib
|
@@ -23,9 +21,8 @@ import tempfile
|
|
23
21
|
from datetime import datetime
|
24
22
|
from enum import Enum
|
25
23
|
from io import DEFAULT_BUFFER_SIZE
|
26
|
-
from pathlib import Path
|
27
24
|
from textwrap import fill
|
28
|
-
from typing import Dict, Optional, Union
|
25
|
+
from typing import Any, Dict, Optional, Tuple, Union
|
29
26
|
from urllib import request
|
30
27
|
from urllib.parse import urlparse
|
31
28
|
|
@@ -66,6 +63,8 @@ MIN_RATIO_FOR_DOWN_SAMPLING = 1 / 20
|
|
66
63
|
# Maximum distinct values by cardinality will be used for plotting
|
67
64
|
MAX_DISPLAY_VALUES = 10
|
68
65
|
|
66
|
+
UNKNOWN = ""
|
67
|
+
|
69
68
|
# par link of the index json file.
|
70
69
|
PAR_LINK = "https://objectstorage.us-ashburn-1.oraclecloud.com/p/WyjtfVIG0uda-P3-2FmAfwaLlXYQZbvPZmfX1qg0-sbkwEQO6jpwabGr2hMDBmBp/n/ociodscdev/b/service-conda-packs/o/service_pack/index.json"
|
71
70
|
|
@@ -85,6 +84,7 @@ mpl.rcParams["axes.prop_cycle"] = cycler(
|
|
85
84
|
color=["teal", "blueviolet", "forestgreen", "peru", "y", "dodgerblue", "r"]
|
86
85
|
)
|
87
86
|
|
87
|
+
|
88
88
|
# sqlalchemy engines
|
89
89
|
_engines = {}
|
90
90
|
|
@@ -152,6 +152,22 @@ def oci_key_location():
|
|
152
152
|
)
|
153
153
|
|
154
154
|
|
155
|
+
def text_sanitizer(content):
|
156
|
+
if isinstance(content, str):
|
157
|
+
return (
|
158
|
+
content.replace("“", '"')
|
159
|
+
.replace("”", '"')
|
160
|
+
.replace("’", "'")
|
161
|
+
.replace("‘", "'")
|
162
|
+
.replace("—", "-")
|
163
|
+
.encode("utf-8", "ignore")
|
164
|
+
.decode("utf-8", "ignore")
|
165
|
+
)
|
166
|
+
if isinstance(content, dict):
|
167
|
+
return json.dumps(content)
|
168
|
+
return str(content)
|
169
|
+
|
170
|
+
|
155
171
|
@deprecated(
|
156
172
|
"2.5.10",
|
157
173
|
details="Deprecated, use: from ads.common.auth import AuthState; AuthState().oci_config_path",
|
@@ -215,6 +231,37 @@ def random_valid_ocid(prefix="ocid1.dataflowapplication.oc1.iad"):
|
|
215
231
|
return f"{left}.{fake}"
|
216
232
|
|
217
233
|
|
234
|
+
def parse_bool(value: Any) -> bool:
|
235
|
+
"""
|
236
|
+
Converts a value to boolean. For strings, it interprets 'true', '1', or 'yes'
|
237
|
+
(case insensitive) as True; everything else as False.
|
238
|
+
|
239
|
+
Parameters
|
240
|
+
----------
|
241
|
+
value : Any
|
242
|
+
The value to convert to boolean.
|
243
|
+
|
244
|
+
Returns
|
245
|
+
-------
|
246
|
+
bool
|
247
|
+
The boolean interpretation of the value.
|
248
|
+
"""
|
249
|
+
if isinstance(value, bool):
|
250
|
+
return value
|
251
|
+
if isinstance(value, str):
|
252
|
+
return value.strip().lower() in ("true", "1", "yes")
|
253
|
+
return bool(value)
|
254
|
+
|
255
|
+
|
256
|
+
def read_file(file_path: str, **kwargs) -> str:
|
257
|
+
try:
|
258
|
+
with fsspec.open(file_path, "r", **kwargs.get("auth", {})) as f:
|
259
|
+
return f.read()
|
260
|
+
except Exception as e:
|
261
|
+
logger.debug(f"Failed to read file {file_path}. {e}")
|
262
|
+
return UNKNOWN
|
263
|
+
|
264
|
+
|
218
265
|
def get_dataframe_styles(max_width=75):
|
219
266
|
"""Styles used for dataframe, example usage:
|
220
267
|
|
@@ -501,13 +548,13 @@ def print_user_message(
|
|
501
548
|
if is_documentation_mode() and is_notebook():
|
502
549
|
if display_type.lower() == "tip":
|
503
550
|
if "\n" in msg:
|
504
|
-
t = "<b>{
|
551
|
+
t = f"<b>{title.upper().strip()}:</b>" if title else ""
|
505
552
|
|
506
553
|
user_message = "{}{}".format(
|
507
554
|
t,
|
508
555
|
"".join(
|
509
556
|
[
|
510
|
-
"<br> + {
|
557
|
+
f"<br> + {x.strip()}"
|
511
558
|
for x in msg.strip().split("\n")
|
512
559
|
]
|
513
560
|
),
|
@@ -646,7 +693,7 @@ def ellipsis_strings(raw, n=24):
|
|
646
693
|
else:
|
647
694
|
n2 = int(n) // 2 - 3
|
648
695
|
n1 = n - n2 - 3
|
649
|
-
result.append("{
|
696
|
+
result.append(f"{s[:n1]}...{s[-n2:]}")
|
650
697
|
|
651
698
|
return result
|
652
699
|
|
@@ -942,9 +989,9 @@ def generate_requirement_file(
|
|
942
989
|
with open(os.path.join(file_path, file_name), "w") as req_file:
|
943
990
|
for lib in requirements:
|
944
991
|
if requirements[lib]:
|
945
|
-
req_file.write("{}=={}\n"
|
992
|
+
req_file.write(f"{lib}=={requirements[lib]}\n")
|
946
993
|
else:
|
947
|
-
req_file.write("{}\n"
|
994
|
+
req_file.write(f"{lib}\n")
|
948
995
|
|
949
996
|
|
950
997
|
def _get_feature_type_and_dtype(column):
|
@@ -966,7 +1013,7 @@ def to_dataframe(
|
|
966
1013
|
pd.Series,
|
967
1014
|
np.ndarray,
|
968
1015
|
pd.DataFrame,
|
969
|
-
]
|
1016
|
+
],
|
970
1017
|
):
|
971
1018
|
"""
|
972
1019
|
Convert to pandas DataFrame.
|
@@ -1391,7 +1438,7 @@ def remove_file(file_path: str, auth: Optional[Dict] = None) -> None:
|
|
1391
1438
|
fs = fsspec.filesystem(scheme, **auth)
|
1392
1439
|
try:
|
1393
1440
|
fs.rm(file_path)
|
1394
|
-
except FileNotFoundError
|
1441
|
+
except FileNotFoundError:
|
1395
1442
|
raise FileNotFoundError(f"`{file_path}` not found.")
|
1396
1443
|
except Exception as e:
|
1397
1444
|
raise e
|
@@ -1786,3 +1833,36 @@ def get_log_links(
|
|
1786
1833
|
console_link_url = f"https://cloud.oracle.com/logging/log-groups/{log_group_id}?region={region}"
|
1787
1834
|
|
1788
1835
|
return console_link_url
|
1836
|
+
|
1837
|
+
|
1838
|
+
def parse_content_disposition(header: str) -> Tuple[str, Dict[str, str]]:
|
1839
|
+
"""
|
1840
|
+
Parses a Content-Disposition header into its main disposition and a dictionary of parameters.
|
1841
|
+
|
1842
|
+
For example:
|
1843
|
+
'attachment; filename="example.txt"'
|
1844
|
+
will be parsed into:
|
1845
|
+
('attachment', {'filename': 'example.txt'})
|
1846
|
+
|
1847
|
+
Parameters
|
1848
|
+
----------
|
1849
|
+
header (str): The Content-Disposition header string.
|
1850
|
+
|
1851
|
+
Returns
|
1852
|
+
-------
|
1853
|
+
Tuple[str, Dict[str, str]]: A tuple containing the disposition and a dictionary of parameters.
|
1854
|
+
"""
|
1855
|
+
if not header:
|
1856
|
+
return "", {}
|
1857
|
+
|
1858
|
+
parts = header.split(";")
|
1859
|
+
# The first part is the main disposition (e.g., "attachment").
|
1860
|
+
disposition = parts[0].strip().lower()
|
1861
|
+
params: Dict[str, str] = {}
|
1862
|
+
|
1863
|
+
# Process each subsequent part to extract key-value pairs.
|
1864
|
+
for part in parts[1:]:
|
1865
|
+
if "=" in part:
|
1866
|
+
key, value = part.split("=", 1)
|
1867
|
+
params[key.strip().lower()] = value.strip().strip('"')
|
1868
|
+
return disposition, params
|
ads/config.py
CHANGED
@@ -80,6 +80,9 @@ AQUA_TELEMETRY_BUCKET_NS = os.environ.get("AQUA_TELEMETRY_BUCKET_NS", CONDA_BUCK
|
|
80
80
|
DEBUG_TELEMETRY = os.environ.get("DEBUG_TELEMETRY", None)
|
81
81
|
AQUA_SERVICE_NAME = "aqua"
|
82
82
|
DATA_SCIENCE_SERVICE_NAME = "data-science"
|
83
|
+
USER = "USER"
|
84
|
+
SERVICE = "SERVICE"
|
85
|
+
|
83
86
|
|
84
87
|
|
85
88
|
THREADED_DEFAULT_TIMEOUT = 5
|
ads/llm/__init__.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
|
3
|
-
# Copyright (c) 2024 Oracle and/or its affiliates.
|
3
|
+
# Copyright (c) 2024, 2025 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
|
|
6
6
|
|
@@ -433,23 +433,6 @@ class OCIModelDeploymentLLM(BaseLLM, BaseOCIModelDeployment):
|
|
433
433
|
model: str = DEFAULT_MODEL_NAME
|
434
434
|
"""The name of the model."""
|
435
435
|
|
436
|
-
max_tokens: int = 256
|
437
|
-
"""Denotes the number of tokens to predict per generation."""
|
438
|
-
|
439
|
-
temperature: float = 0.2
|
440
|
-
"""A non-negative float that tunes the degree of randomness in generation."""
|
441
|
-
|
442
|
-
k: int = -1
|
443
|
-
"""Number of most likely tokens to consider at each step."""
|
444
|
-
|
445
|
-
p: float = 0.75
|
446
|
-
"""Total probability mass of tokens to consider at each step."""
|
447
|
-
|
448
|
-
best_of: int = 1
|
449
|
-
"""Generates best_of completions server-side and returns the "best"
|
450
|
-
(the one with the highest log probability per token).
|
451
|
-
"""
|
452
|
-
|
453
436
|
stop: Optional[List[str]] = None
|
454
437
|
"""Stop words to use when generating. Model output is cut off
|
455
438
|
at the first occurrence of any of these substrings."""
|
@@ -466,14 +449,9 @@ class OCIModelDeploymentLLM(BaseLLM, BaseOCIModelDeployment):
|
|
466
449
|
def _default_params(self) -> Dict[str, Any]:
|
467
450
|
"""Get the default parameters."""
|
468
451
|
return {
|
469
|
-
"best_of": self.best_of,
|
470
|
-
"max_tokens": self.max_tokens,
|
471
452
|
"model": self.model,
|
472
453
|
"stop": self.stop,
|
473
454
|
"stream": self.streaming,
|
474
|
-
"temperature": self.temperature,
|
475
|
-
"top_k": self.k,
|
476
|
-
"top_p": self.p,
|
477
455
|
}
|
478
456
|
|
479
457
|
@property
|
@@ -788,6 +766,23 @@ class OCIModelDeploymentTGI(OCIModelDeploymentLLM):
|
|
788
766
|
|
789
767
|
"""
|
790
768
|
|
769
|
+
max_tokens: int = 256
|
770
|
+
"""Denotes the number of tokens to predict per generation."""
|
771
|
+
|
772
|
+
temperature: float = 0.2
|
773
|
+
"""A non-negative float that tunes the degree of randomness in generation."""
|
774
|
+
|
775
|
+
k: int = -1
|
776
|
+
"""Number of most likely tokens to consider at each step."""
|
777
|
+
|
778
|
+
p: float = 0.75
|
779
|
+
"""Total probability mass of tokens to consider at each step."""
|
780
|
+
|
781
|
+
best_of: int = 1
|
782
|
+
"""Generates best_of completions server-side and returns the "best"
|
783
|
+
(the one with the highest log probability per token).
|
784
|
+
"""
|
785
|
+
|
791
786
|
api: Literal["/generate", "/v1/completions"] = "/v1/completions"
|
792
787
|
"""Api spec."""
|
793
788
|
|
@@ -922,6 +917,20 @@ class OCIModelDeploymentVLLM(OCIModelDeploymentLLM):
|
|
922
917
|
|
923
918
|
"""
|
924
919
|
|
920
|
+
max_tokens: int = 256
|
921
|
+
"""Denotes the number of tokens to predict per generation."""
|
922
|
+
|
923
|
+
temperature: float = 0.2
|
924
|
+
"""A non-negative float that tunes the degree of randomness in generation."""
|
925
|
+
|
926
|
+
p: float = 0.75
|
927
|
+
"""Total probability mass of tokens to consider at each step."""
|
928
|
+
|
929
|
+
best_of: int = 1
|
930
|
+
"""Generates best_of completions server-side and returns the "best"
|
931
|
+
(the one with the highest log probability per token).
|
932
|
+
"""
|
933
|
+
|
925
934
|
n: int = 1
|
926
935
|
"""Number of output sequences to return for the given prompt."""
|
927
936
|
|
ads/model/artifact_downloader.py
CHANGED
@@ -170,7 +170,10 @@ class LargeArtifactDownloader(ArtifactDownloader):
|
|
170
170
|
"""Downloads model artifacts."""
|
171
171
|
self.progress.update("Importing model artifacts from catalog")
|
172
172
|
|
173
|
-
if
|
173
|
+
if (
|
174
|
+
self.dsc_model.is_model_created_by_reference()
|
175
|
+
and self.model_file_description
|
176
|
+
):
|
174
177
|
self.download_from_model_file_description()
|
175
178
|
self.progress.update()
|
176
179
|
return
|
ads/model/common/utils.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*--
|
3
2
|
|
4
3
|
# Copyright (c) 2022, 2023 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/
|
@@ -7,16 +6,29 @@
|
|
7
6
|
import json
|
8
7
|
import os
|
9
8
|
import tempfile
|
10
|
-
import yaml
|
11
9
|
from typing import Any, Dict, Optional
|
12
10
|
from zipfile import ZipFile
|
13
|
-
from ads.common import utils
|
14
11
|
|
12
|
+
import yaml
|
13
|
+
|
14
|
+
from ads.common import utils
|
15
|
+
from ads.common.extended_enum import ExtendedEnum
|
15
16
|
|
16
17
|
DEPRECATE_AS_ONNX_WARNING = "This attribute `as_onnx` will be deprecated in the future. You can choose specific format by setting `model_save_serializer`."
|
17
18
|
DEPRECATE_USE_TORCH_SCRIPT_WARNING = "This attribute `use_torch_script` will be deprecated in the future. You can choose specific format by setting `model_save_serializer`."
|
18
19
|
|
19
20
|
|
21
|
+
class MetadataArtifactPathType(ExtendedEnum):
|
22
|
+
"""
|
23
|
+
Enum for defining metadata artifact path type.
|
24
|
+
Can be either local path or OSS path. It can also be the content itself.
|
25
|
+
"""
|
26
|
+
|
27
|
+
LOCAL = "local"
|
28
|
+
OSS = "oss"
|
29
|
+
CONTENT = "content"
|
30
|
+
|
31
|
+
|
20
32
|
def _extract_locals(
|
21
33
|
locals: Dict[str, Any], filter_out_nulls: Optional[bool] = True
|
22
34
|
) -> Dict[str, Any]:
|