oracle-ads 2.13.9rc1__py3-none-any.whl → 2.13.10rc0__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 +5 -0
- ads/aqua/common/enums.py +12 -0
- ads/aqua/common/utils.py +49 -39
- ads/aqua/config/container_config.py +38 -39
- ads/aqua/extension/deployment_handler.py +122 -39
- ads/aqua/extension/ui_handler.py +19 -1
- ads/aqua/model/model.py +23 -3
- ads/aqua/model/utils.py +52 -0
- ads/aqua/modeldeployment/__init__.py +2 -4
- ads/aqua/modeldeployment/deployment.py +23 -34
- ads/aqua/ui.py +20 -0
- ads/common/oci_client.py +9 -5
- ads/config.py +1 -0
- ads/opctl/operator/lowcode/forecast/model/prophet.py +13 -8
- ads/telemetry/client.py +5 -8
- {oracle_ads-2.13.9rc1.dist-info → oracle_ads-2.13.10rc0.dist-info}/METADATA +7 -6
- {oracle_ads-2.13.9rc1.dist-info → oracle_ads-2.13.10rc0.dist-info}/RECORD +21 -21
- ads/aqua/modeldeployment/inference.py +0 -74
- {oracle_ads-2.13.9rc1.dist-info → oracle_ads-2.13.10rc0.dist-info}/WHEEL +0 -0
- {oracle_ads-2.13.9rc1.dist-info → oracle_ads-2.13.10rc0.dist-info}/entry_points.txt +0 -0
- {oracle_ads-2.13.9rc1.dist-info → oracle_ads-2.13.10rc0.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
@@ -157,6 +157,8 @@ class AquaMultiModelRef(Serializable):
|
|
157
157
|
Optional environment variables to override during deployment.
|
158
158
|
artifact_location : Optional[str]
|
159
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
|
160
162
|
"""
|
161
163
|
|
162
164
|
model_id: str = Field(..., description="The model OCID to deploy.")
|
@@ -171,6 +173,9 @@ class AquaMultiModelRef(Serializable):
|
|
171
173
|
artifact_location: Optional[str] = Field(
|
172
174
|
None, description="Artifact path of model in the multimodel group."
|
173
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
|
+
)
|
174
179
|
|
175
180
|
class Config:
|
176
181
|
extra = "ignore"
|
ads/aqua/common/enums.py
CHANGED
@@ -20,6 +20,12 @@ class Resource(ExtendedEnum):
|
|
20
20
|
MODEL_VERSION_SET = "model-version-sets"
|
21
21
|
|
22
22
|
|
23
|
+
class PredictEndpoints(ExtendedEnum):
|
24
|
+
CHAT_COMPLETIONS_ENDPOINT = "/v1/chat/completions"
|
25
|
+
TEXT_COMPLETIONS_ENDPOINT = "/v1/completions"
|
26
|
+
EMBEDDING_ENDPOINT = "/v1/embedding"
|
27
|
+
|
28
|
+
|
23
29
|
class Tags(ExtendedEnum):
|
24
30
|
TASK = "task"
|
25
31
|
LICENSE = "license"
|
@@ -49,6 +55,7 @@ class InferenceContainerType(ExtendedEnum):
|
|
49
55
|
class InferenceContainerTypeFamily(ExtendedEnum):
|
50
56
|
AQUA_VLLM_CONTAINER_FAMILY = "odsc-vllm-serving"
|
51
57
|
AQUA_VLLM_V1_CONTAINER_FAMILY = "odsc-vllm-serving-v1"
|
58
|
+
AQUA_VLLM_LLAMA4_CONTAINER_FAMILY = "odsc-vllm-serving-llama4"
|
52
59
|
AQUA_TGI_CONTAINER_FAMILY = "odsc-tgi-serving"
|
53
60
|
AQUA_LLAMA_CPP_CONTAINER_FAMILY = "odsc-llama-cpp-serving"
|
54
61
|
|
@@ -119,4 +126,9 @@ CONTAINER_FAMILY_COMPATIBILITY: Dict[str, List[str]] = {
|
|
119
126
|
InferenceContainerTypeFamily.AQUA_VLLM_V1_CONTAINER_FAMILY,
|
120
127
|
InferenceContainerTypeFamily.AQUA_VLLM_CONTAINER_FAMILY,
|
121
128
|
],
|
129
|
+
InferenceContainerTypeFamily.AQUA_VLLM_LLAMA4_CONTAINER_FAMILY: [
|
130
|
+
InferenceContainerTypeFamily.AQUA_VLLM_LLAMA4_CONTAINER_FAMILY,
|
131
|
+
InferenceContainerTypeFamily.AQUA_VLLM_V1_CONTAINER_FAMILY,
|
132
|
+
InferenceContainerTypeFamily.AQUA_VLLM_CONTAINER_FAMILY,
|
133
|
+
],
|
122
134
|
}
|
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
|
)
|
@@ -2,16 +2,18 @@
|
|
2
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
|
|
5
|
-
from typing import List, Union
|
5
|
+
from typing import List, Optional, Union
|
6
6
|
from urllib.parse import urlparse
|
7
7
|
|
8
8
|
from tornado.web import HTTPError
|
9
9
|
|
10
|
+
from ads.aqua.app import logger
|
11
|
+
from ads.aqua.client.client import Client, ExtendedRequestError
|
10
12
|
from ads.aqua.common.decorator import handle_exceptions
|
13
|
+
from ads.aqua.common.enums import PredictEndpoints
|
11
14
|
from ads.aqua.extension.base_handler import AquaAPIhandler
|
12
15
|
from ads.aqua.extension.errors import Errors
|
13
|
-
from ads.aqua.modeldeployment import AquaDeploymentApp
|
14
|
-
from ads.aqua.modeldeployment.entities import ModelParams
|
16
|
+
from ads.aqua.modeldeployment import AquaDeploymentApp
|
15
17
|
from ads.config import COMPARTMENT_OCID
|
16
18
|
|
17
19
|
|
@@ -175,23 +177,107 @@ class AquaDeploymentHandler(AquaAPIhandler):
|
|
175
177
|
)
|
176
178
|
|
177
179
|
|
178
|
-
class
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
180
|
+
class AquaDeploymentStreamingInferenceHandler(AquaAPIhandler):
|
181
|
+
def _get_model_deployment_response(
|
182
|
+
self,
|
183
|
+
model_deployment_id: str,
|
184
|
+
payload: dict,
|
185
|
+
route_override_header: Optional[str],
|
186
|
+
):
|
187
|
+
"""
|
188
|
+
Returns the model deployment inference response in a streaming fashion.
|
189
|
+
|
190
|
+
This method connects to the specified model deployment endpoint and
|
191
|
+
streams the inference output back to the caller, handling both text
|
192
|
+
and chat completion endpoints depending on the route override.
|
193
|
+
|
194
|
+
Parameters
|
195
|
+
----------
|
196
|
+
model_deployment_id : str
|
197
|
+
The OCID of the model deployment to invoke.
|
198
|
+
Example: 'ocid1.datasciencemodeldeployment.iad.oc1.xxxyz'
|
199
|
+
|
200
|
+
payload : dict
|
201
|
+
Dictionary containing the model inference parameters.
|
202
|
+
Same example for text completions:
|
203
|
+
{
|
204
|
+
"max_tokens": 1024,
|
205
|
+
"temperature": 0.5,
|
206
|
+
"prompt": "what are some good skills deep learning expert. Give us some tips on how to structure interview with some coding example?",
|
207
|
+
"top_p": 0.4,
|
208
|
+
"top_k": 100,
|
209
|
+
"model": "odsc-llm",
|
210
|
+
"frequency_penalty": 1,
|
211
|
+
"presence_penalty": 1,
|
212
|
+
"stream": true
|
213
|
+
}
|
214
|
+
|
215
|
+
route_override_header : Optional[str]
|
216
|
+
Optional override for the inference route, used for routing between
|
217
|
+
different endpoint types (e.g., chat vs. text completions).
|
218
|
+
Example: '/v1/chat/completions'
|
219
|
+
|
220
|
+
Returns
|
221
|
+
-------
|
222
|
+
Generator[str]
|
223
|
+
A generator that yields strings of the model's output as they are received.
|
224
|
+
|
225
|
+
Raises
|
226
|
+
------
|
227
|
+
HTTPError
|
228
|
+
If the request to the model deployment fails or if streaming cannot be established.
|
229
|
+
"""
|
230
|
+
|
231
|
+
model_deployment = AquaDeploymentApp().get(model_deployment_id)
|
232
|
+
endpoint = model_deployment.endpoint + "/predictWithResponseStream"
|
233
|
+
endpoint_type = model_deployment.environment_variables.get(
|
234
|
+
"MODEL_DEPLOY_PREDICT_ENDPOINT", PredictEndpoints.TEXT_COMPLETIONS_ENDPOINT
|
235
|
+
)
|
236
|
+
aqua_client = Client(endpoint=endpoint)
|
237
|
+
|
238
|
+
if PredictEndpoints.CHAT_COMPLETIONS_ENDPOINT in (
|
239
|
+
endpoint_type,
|
240
|
+
route_override_header,
|
241
|
+
):
|
242
|
+
try:
|
243
|
+
for chunk in aqua_client.chat(
|
244
|
+
messages=payload.pop("messages"),
|
245
|
+
payload=payload,
|
246
|
+
stream=True,
|
247
|
+
):
|
248
|
+
try:
|
249
|
+
yield chunk["choices"][0]["delta"]["content"]
|
250
|
+
except Exception as e:
|
251
|
+
logger.debug(
|
252
|
+
f"Exception occurred while parsing streaming response: {e}"
|
253
|
+
)
|
254
|
+
except ExtendedRequestError as ex:
|
255
|
+
raise HTTPError(400, str(ex))
|
256
|
+
except Exception as ex:
|
257
|
+
raise HTTPError(500, str(ex))
|
258
|
+
|
259
|
+
elif endpoint_type == PredictEndpoints.TEXT_COMPLETIONS_ENDPOINT:
|
260
|
+
try:
|
261
|
+
for chunk in aqua_client.generate(
|
262
|
+
prompt=payload.pop("prompt"),
|
263
|
+
payload=payload,
|
264
|
+
stream=True,
|
265
|
+
):
|
266
|
+
try:
|
267
|
+
yield chunk["choices"][0]["text"]
|
268
|
+
except Exception as e:
|
269
|
+
logger.debug(
|
270
|
+
f"Exception occurred while parsing streaming response: {e}"
|
271
|
+
)
|
272
|
+
except ExtendedRequestError as ex:
|
273
|
+
raise HTTPError(400, str(ex))
|
274
|
+
except Exception as ex:
|
275
|
+
raise HTTPError(500, str(ex))
|
190
276
|
|
191
277
|
@handle_exceptions
|
192
|
-
def post(self,
|
278
|
+
def post(self, model_deployment_id):
|
193
279
|
"""
|
194
|
-
Handles inference request for the Active Model Deployments
|
280
|
+
Handles streaming inference request for the Active Model Deployments
|
195
281
|
Raises
|
196
282
|
------
|
197
283
|
HTTPError
|
@@ -205,32 +291,29 @@ class AquaDeploymentInferenceHandler(AquaAPIhandler):
|
|
205
291
|
if not input_data:
|
206
292
|
raise HTTPError(400, Errors.NO_INPUT_DATA)
|
207
293
|
|
208
|
-
endpoint = input_data.get("endpoint")
|
209
|
-
if not endpoint:
|
210
|
-
raise HTTPError(400, Errors.MISSING_REQUIRED_PARAMETER.format("endpoint"))
|
211
|
-
|
212
|
-
if not self.validate_predict_url(endpoint):
|
213
|
-
raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT.format("endpoint"))
|
214
|
-
|
215
294
|
prompt = input_data.get("prompt")
|
216
|
-
|
217
|
-
raise HTTPError(400, Errors.MISSING_REQUIRED_PARAMETER.format("prompt"))
|
295
|
+
messages = input_data.get("messages")
|
218
296
|
|
219
|
-
|
220
|
-
input_data.get("model_params") if input_data.get("model_params") else {}
|
221
|
-
)
|
222
|
-
try:
|
223
|
-
model_params_obj = ModelParams(**model_params)
|
224
|
-
except Exception as ex:
|
297
|
+
if not prompt and not messages:
|
225
298
|
raise HTTPError(
|
226
|
-
400, Errors.
|
227
|
-
) from ex
|
228
|
-
|
229
|
-
return self.finish(
|
230
|
-
MDInferenceResponse(prompt, model_params_obj).get_model_deployment_response(
|
231
|
-
endpoint
|
299
|
+
400, Errors.MISSING_REQUIRED_PARAMETER.format("prompt/messages")
|
232
300
|
)
|
301
|
+
if not input_data.get("model"):
|
302
|
+
raise HTTPError(400, Errors.MISSING_REQUIRED_PARAMETER.format("model"))
|
303
|
+
route_override_header = self.request.headers.get("route", None)
|
304
|
+
self.set_header("Content-Type", "text/event-stream")
|
305
|
+
response_gen = self._get_model_deployment_response(
|
306
|
+
model_deployment_id, input_data, route_override_header
|
233
307
|
)
|
308
|
+
try:
|
309
|
+
for chunk in response_gen:
|
310
|
+
self.write(chunk)
|
311
|
+
self.flush()
|
312
|
+
self.finish()
|
313
|
+
except Exception as ex:
|
314
|
+
self.set_status(ex.status_code)
|
315
|
+
self.write({"message": "Error occurred", "reason": str(ex)})
|
316
|
+
self.finish()
|
234
317
|
|
235
318
|
|
236
319
|
class AquaDeploymentParamsHandler(AquaAPIhandler):
|
@@ -294,5 +377,5 @@ __handlers__ = [
|
|
294
377
|
("deployments/?([^/]*)", AquaDeploymentHandler),
|
295
378
|
("deployments/?([^/]*)/activate", AquaDeploymentHandler),
|
296
379
|
("deployments/?([^/]*)/deactivate", AquaDeploymentHandler),
|
297
|
-
("inference",
|
380
|
+
("inference/stream/?([^/]*)", AquaDeploymentStreamingInferenceHandler),
|
298
381
|
]
|
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
|
]
|
ads/aqua/model/model.py
CHANGED
@@ -83,6 +83,10 @@ from ads.aqua.model.entities import (
|
|
83
83
|
ModelValidationResult,
|
84
84
|
)
|
85
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
|
+
)
|
86
90
|
from ads.common.auth import default_signer
|
87
91
|
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
|
88
92
|
from ads.common.utils import (
|
@@ -311,12 +315,27 @@ class AquaModelApp(AquaApp):
|
|
311
315
|
# "Currently only service models are supported for multi model deployment."
|
312
316
|
# )
|
313
317
|
|
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
|
334
|
+
|
314
335
|
display_name_list.append(display_name)
|
315
336
|
|
316
337
|
self._extract_model_task(model, source_model)
|
317
338
|
|
318
|
-
# Retrieve model artifact
|
319
|
-
model_artifact_path = source_model.artifact
|
320
339
|
if not model_artifact_path:
|
321
340
|
raise AquaValueError(
|
322
341
|
f"Model '{display_name}' (ID: {model.model_id}) has no artifacts. "
|
@@ -367,7 +386,8 @@ class AquaModelApp(AquaApp):
|
|
367
386
|
raise AquaValueError(
|
368
387
|
"The selected models are associated with different container families: "
|
369
388
|
f"{list(selected_models_deployment_containers)}."
|
370
|
-
"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."
|
371
391
|
)
|
372
392
|
else:
|
373
393
|
deployment_container = selected_models_deployment_containers.pop()
|
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
|
@@ -1,8 +1,6 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
#
|
3
|
-
# Copyright (c) 2024 Oracle and/or its affiliates.
|
2
|
+
# Copyright (c) 2025 Oracle and/or its affiliates.
|
4
3
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
4
|
from ads.aqua.modeldeployment.deployment import AquaDeploymentApp
|
6
|
-
from ads.aqua.modeldeployment.inference import MDInferenceResponse
|
7
5
|
|
8
|
-
__all__ = ["AquaDeploymentApp"
|
6
|
+
__all__ = ["AquaDeploymentApp"]
|
@@ -17,7 +17,11 @@ from ads.aqua.common.entities import (
|
|
17
17
|
ComputeShapeSummary,
|
18
18
|
ContainerPath,
|
19
19
|
)
|
20
|
-
from ads.aqua.common.enums import
|
20
|
+
from ads.aqua.common.enums import (
|
21
|
+
InferenceContainerTypeFamily,
|
22
|
+
ModelFormat,
|
23
|
+
Tags,
|
24
|
+
)
|
21
25
|
from ads.aqua.common.errors import AquaRuntimeError, AquaValueError
|
22
26
|
from ads.aqua.common.utils import (
|
23
27
|
DEFINED_METADATA_TO_FILE_MAP,
|
@@ -25,7 +29,6 @@ from ads.aqua.common.utils import (
|
|
25
29
|
build_pydantic_error_message,
|
26
30
|
get_combined_params,
|
27
31
|
get_container_params_type,
|
28
|
-
get_model_by_reference_paths,
|
29
32
|
get_ocid_substring,
|
30
33
|
get_params_dict,
|
31
34
|
get_params_list,
|
@@ -46,9 +49,12 @@ from ads.aqua.constants import (
|
|
46
49
|
UNKNOWN_DICT,
|
47
50
|
)
|
48
51
|
from ads.aqua.data import AquaResourceIdentifier
|
49
|
-
from ads.aqua.finetuning.finetuning import FineTuneCustomMetadata
|
50
52
|
from ads.aqua.model import AquaModelApp
|
51
53
|
from ads.aqua.model.constants import AquaModelMetadataKeys, ModelCustomMetadataFields
|
54
|
+
from ads.aqua.model.utils import (
|
55
|
+
extract_base_model_from_ft,
|
56
|
+
extract_fine_tune_artifacts_path,
|
57
|
+
)
|
52
58
|
from ads.aqua.modeldeployment.entities import (
|
53
59
|
AquaDeployment,
|
54
60
|
AquaDeploymentConfig,
|
@@ -211,6 +217,7 @@ class AquaDeploymentApp(AquaApp):
|
|
211
217
|
)
|
212
218
|
else:
|
213
219
|
model_ids = [model.model_id for model in create_deployment_details.models]
|
220
|
+
|
214
221
|
try:
|
215
222
|
model_config_summary = self.get_multimodel_deployment_config(
|
216
223
|
model_ids=model_ids, compartment_id=compartment_id
|
@@ -343,22 +350,6 @@ class AquaDeploymentApp(AquaApp):
|
|
343
350
|
config_source_id = create_deployment_details.model_id
|
344
351
|
model_name = aqua_model.display_name
|
345
352
|
|
346
|
-
is_fine_tuned_model = Tags.AQUA_FINE_TUNED_MODEL_TAG in aqua_model.freeform_tags
|
347
|
-
|
348
|
-
if is_fine_tuned_model:
|
349
|
-
try:
|
350
|
-
config_source_id = aqua_model.custom_metadata_list.get(
|
351
|
-
FineTuneCustomMetadata.FINE_TUNE_SOURCE
|
352
|
-
).value
|
353
|
-
model_name = aqua_model.custom_metadata_list.get(
|
354
|
-
FineTuneCustomMetadata.FINE_TUNE_SOURCE_NAME
|
355
|
-
).value
|
356
|
-
except ValueError as err:
|
357
|
-
raise AquaValueError(
|
358
|
-
f"Either {FineTuneCustomMetadata.FINE_TUNE_SOURCE} or {FineTuneCustomMetadata.FINE_TUNE_SOURCE_NAME} is missing "
|
359
|
-
f"from custom metadata for the model {config_source_id}"
|
360
|
-
) from err
|
361
|
-
|
362
353
|
# set up env and cmd var
|
363
354
|
env_var = create_deployment_details.env_var or {}
|
364
355
|
cmd_var = create_deployment_details.cmd_var or []
|
@@ -378,19 +369,11 @@ class AquaDeploymentApp(AquaApp):
|
|
378
369
|
|
379
370
|
env_var.update({"BASE_MODEL": f"{model_path_prefix}"})
|
380
371
|
|
381
|
-
|
382
|
-
_, fine_tune_output_path = get_model_by_reference_paths(
|
383
|
-
aqua_model.model_file_description
|
384
|
-
)
|
385
|
-
|
386
|
-
if not fine_tune_output_path:
|
387
|
-
raise AquaValueError(
|
388
|
-
"Fine tuned output path is not available in the model artifact."
|
389
|
-
)
|
390
|
-
|
391
|
-
os_path = ObjectStorageDetails.from_path(fine_tune_output_path)
|
392
|
-
fine_tune_output_path = os_path.filepath.rstrip("/")
|
372
|
+
is_fine_tuned_model = Tags.AQUA_FINE_TUNED_MODEL_TAG in aqua_model.freeform_tags
|
393
373
|
|
374
|
+
if is_fine_tuned_model:
|
375
|
+
config_source_id, model_name = extract_base_model_from_ft(aqua_model)
|
376
|
+
_, fine_tune_output_path = extract_fine_tune_artifacts_path(aqua_model)
|
394
377
|
env_var.update({"FT_MODEL": f"{fine_tune_output_path}"})
|
395
378
|
|
396
379
|
container_type_key = self._get_container_type_key(
|
@@ -647,6 +630,12 @@ class AquaDeploymentApp(AquaApp):
|
|
647
630
|
config_data = {"params": params, "model_path": artifact_path_prefix}
|
648
631
|
if model.model_task:
|
649
632
|
config_data["model_task"] = model.model_task
|
633
|
+
|
634
|
+
if model.fine_tune_weights_location:
|
635
|
+
config_data["fine_tune_weights_location"] = (
|
636
|
+
model.fine_tune_weights_location
|
637
|
+
)
|
638
|
+
|
650
639
|
model_config.append(config_data)
|
651
640
|
model_name_list.append(model.model_name)
|
652
641
|
|
@@ -805,6 +794,9 @@ class AquaDeploymentApp(AquaApp):
|
|
805
794
|
# we arbitrarily choose last 8 characters of OCID to identify MD in telemetry
|
806
795
|
telemetry_kwargs = {"ocid": get_ocid_substring(deployment_id, key_len=8)}
|
807
796
|
|
797
|
+
if Tags.BASE_MODEL_CUSTOM in tags:
|
798
|
+
telemetry_kwargs["custom_base_model"] = True
|
799
|
+
|
808
800
|
# tracks unique deployments that were created in the user compartment
|
809
801
|
self.telemetry.record_event_async(
|
810
802
|
category=f"aqua/{model_type}/deployment",
|
@@ -948,7 +940,6 @@ class AquaDeploymentApp(AquaApp):
|
|
948
940
|
model_deployment = self.ds_client.get_model_deployment(
|
949
941
|
model_deployment_id=model_deployment_id, **kwargs
|
950
942
|
).data
|
951
|
-
|
952
943
|
oci_aqua = (
|
953
944
|
(
|
954
945
|
Tags.AQUA_TAG in model_deployment.freeform_tags
|
@@ -993,7 +984,6 @@ class AquaDeploymentApp(AquaApp):
|
|
993
984
|
aqua_deployment = AquaDeployment.from_oci_model_deployment(
|
994
985
|
model_deployment, self.region
|
995
986
|
)
|
996
|
-
|
997
987
|
if Tags.MULTIMODEL_TYPE_TAG in model_deployment.freeform_tags:
|
998
988
|
aqua_model_id = model_deployment.freeform_tags.get(
|
999
989
|
Tags.AQUA_MODEL_ID_TAG, UNKNOWN
|
@@ -1024,7 +1014,6 @@ class AquaDeploymentApp(AquaApp):
|
|
1024
1014
|
aqua_deployment.models = [
|
1025
1015
|
AquaMultiModelRef(**metadata) for metadata in multi_model_metadata
|
1026
1016
|
]
|
1027
|
-
|
1028
1017
|
return AquaDeploymentDetail(
|
1029
1018
|
**vars(aqua_deployment),
|
1030
1019
|
log_group=AquaResourceIdentifier(
|
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,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8; -*-
|
3
2
|
|
4
|
-
# Copyright (c) 2021,
|
3
|
+
# Copyright (c) 2021, 2025 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
6
|
import logging
|
@@ -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")
|
@@ -43,22 +43,27 @@ def _fit_model(data, params, additional_regressors):
|
|
43
43
|
from prophet import Prophet
|
44
44
|
|
45
45
|
monthly_seasonality = params.pop("monthly_seasonality", False)
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
|
47
|
+
has_min = "min" in params
|
48
|
+
has_max = "max" in params
|
49
|
+
if has_min or has_max:
|
49
50
|
params["growth"] = "logistic"
|
51
|
+
data_floor = params.pop("min", None)
|
52
|
+
data_cap = params.pop("max", None)
|
53
|
+
|
50
54
|
model = Prophet(**params)
|
51
55
|
if monthly_seasonality:
|
52
56
|
model.add_seasonality(name="monthly", period=30.5, fourier_order=5)
|
53
57
|
params["monthly_seasonality"] = monthly_seasonality
|
54
58
|
for add_reg in additional_regressors:
|
55
59
|
model.add_regressor(add_reg)
|
56
|
-
|
60
|
+
|
61
|
+
if has_min:
|
57
62
|
data["floor"] = float(data_floor)
|
58
|
-
params["
|
59
|
-
if
|
63
|
+
params["min"] = data_floor
|
64
|
+
if has_max:
|
60
65
|
data["cap"] = float(data_cap)
|
61
|
-
params["
|
66
|
+
params["max"] = data_cap
|
62
67
|
|
63
68
|
model.fit(data)
|
64
69
|
return model
|
@@ -304,7 +309,7 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
304
309
|
# Global Expl
|
305
310
|
g_expl = self.drop_horizon(expl_df).mean()
|
306
311
|
g_expl.name = s_id
|
307
|
-
global_expl.append(g_expl)
|
312
|
+
global_expl.append(np.abs(g_expl))
|
308
313
|
self.global_explanation = pd.concat(global_expl, axis=1)
|
309
314
|
self.formatted_global_explanation = (
|
310
315
|
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.10rc0
|
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,GenAI,Generative AI,Forecast,Anomaly,Document Understanding
|
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
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=fBJczGd4Trv9Lf0O4_TAEDWYkp5ou9oGeKhxdSW2-84,4274
|
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
|
@@ -36,7 +36,7 @@ ads/aqua/extension/aqua_ws_msg_handler.py,sha256=VDa9vQOsYKX6flsUkDEx6nl-5MFCH5R
|
|
36
36
|
ads/aqua/extension/base_handler.py,sha256=W-eBXn9XYypCZuY84e9cSKRuY0CDyuou_znV6Yn9YzU,3047
|
37
37
|
ads/aqua/extension/common_handler.py,sha256=okjFJlJv0FLXsMM1td6upqqA6tJEJIj1IIfTiughC5Q,3809
|
38
38
|
ads/aqua/extension/common_ws_msg_handler.py,sha256=PAy98ZsM8VAXcy11ahsuam3QUDdmE-Hz4F5pISVkNHY,1242
|
39
|
-
ads/aqua/extension/deployment_handler.py,sha256=
|
39
|
+
ads/aqua/extension/deployment_handler.py,sha256=9ncV1H1pWnyoZuF4iva7n4xpSpGZauZJs2455Vxg2YE,13929
|
40
40
|
ads/aqua/extension/deployment_ws_msg_handler.py,sha256=JX3ZHRtscrflSxT7ZTEEI_p_owtk3m5FZq3QXE96AGY,2013
|
41
41
|
ads/aqua/extension/errors.py,sha256=4LbzZdCoDEtOcrVI-1dgiza4oAYGof6w5LbN6HqroYk,1396
|
42
42
|
ads/aqua/extension/evaluation_handler.py,sha256=fJH73fa0xmkEiP8SxKL4A4dJgj-NoL3z_G-w_WW2zJs,4353
|
@@ -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
|
@@ -57,12 +57,12 @@ ads/aqua/model/__init__.py,sha256=j2iylvERdANxgrEDp7b_mLcKMz1CF5Go0qgYCiMwdos,27
|
|
57
57
|
ads/aqua/model/constants.py,sha256=oOAb4ulsdWBtokCE5SPX7wg8X8SaisLPayua58zhWfY,1856
|
58
58
|
ads/aqua/model/entities.py,sha256=JiKB8SnaUxerRMlwrgpyfQLRuTOB8I14J-Rg5RFPwqw,12660
|
59
59
|
ads/aqua/model/enums.py,sha256=bN8GKmgRl40PQrTmd1r-Pqr9VXTIV8gic5-3SAGNnwg,1152
|
60
|
-
ads/aqua/model/model.py,sha256=
|
61
|
-
ads/aqua/
|
60
|
+
ads/aqua/model/model.py,sha256=nq9PehumfFyh_UZDhltVl7Vi_L4TMM9KCx6yqZL3oDw,89027
|
61
|
+
ads/aqua/model/utils.py,sha256=8lYaD51JpAPb7U_xQzRSzFflRefU5Yz6vA80cuZOL0w,2087
|
62
|
+
ads/aqua/modeldeployment/__init__.py,sha256=k5fGG2b6mae-uiQyuTAHqPjlzcUyJ4NFaF-uoMnK5Uc,277
|
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=V0ZJY63NXE2uqv_Lm5zdT6wSiqXR7QydZh-IL0ObGEo,55603
|
64
65
|
ads/aqua/modeldeployment/entities.py,sha256=qwNH-8eHv-C2QPMITGQkb6haaJRvZ5c0i1H0Aoxeiu4,27100
|
65
|
-
ads/aqua/modeldeployment/inference.py,sha256=rjTF-AM_rHLzL5HCxdLRTrsaSMdB-SzFYUp9dIy5ejw,2109
|
66
66
|
ads/aqua/modeldeployment/utils.py,sha256=Aky4WZ5E564JVZ96X9RYJz_KlB_cAHGzV6mihtd3HV8,22009
|
67
67
|
ads/aqua/resources/gpu_shapes_index.json,sha256=-6rSkyQ04T1z_Yfr3cxGPI7NAtgTwG7beIEjLYuMMIc,1948
|
68
68
|
ads/aqua/server/__init__.py,sha256=fswoO0kX0hrp2b1owF4f-bv_OodntvvUY3FvhL6FCMk,179
|
@@ -98,7 +98,7 @@ ads/common/model_artifact_schema.json,sha256=aNwC9bW5HHMXJK-XAWV56RosqOqiCkzKHBi
|
|
98
98
|
ads/common/model_export_util.py,sha256=rQjL_bb0ecGV2fj0jQXS2-aRbXl4ONDwuNVqdr3DiAQ,26574
|
99
99
|
ads/common/model_metadata.py,sha256=Md1soURHww8GHMG3q_HV0RHVb6dPtg9FZ_7Wmd9L-Yc,641
|
100
100
|
ads/common/object_storage_details.py,sha256=bvqIyB-zLpr5NMnZW8YtSupVH3RpWLBgbR3wPYlQhPU,9531
|
101
|
-
ads/common/oci_client.py,sha256=
|
101
|
+
ads/common/oci_client.py,sha256=HcGUWdc0GQLksJmn6GIrcBJvuhcanwhMlJhdt85_JIA,6164
|
102
102
|
ads/common/oci_datascience.py,sha256=biBgm-udtSYRL46XYfBFJjpkPFcw2ew-xvp3rbbpwmI,1698
|
103
103
|
ads/common/oci_logging.py,sha256=U0HRAUkpnycGpo2kWMrT3wjQVFZaWqLL6pZ2B6_epsM,41925
|
104
104
|
ads/common/oci_mixin.py,sha256=mhja5UomrhXH43uB0jT-u2KaT37op9tM-snxvtGfc40,34548
|
@@ -728,7 +728,7 @@ ads/opctl/operator/lowcode/forecast/model/factory.py,sha256=5a9A3ql-bU412BiTB20o
|
|
728
728
|
ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py,sha256=2NsWE2WtD_O7uAXw42_3tmG3vb5lk3mdnzCZTph4hao,18903
|
729
729
|
ads/opctl/operator/lowcode/forecast/model/ml_forecast.py,sha256=t5x6EBxOd7XwfT3FGdt-n9gscxaHMm3R2A4Evvxbj38,9646
|
730
730
|
ads/opctl/operator/lowcode/forecast/model/neuralprophet.py,sha256=-AS3PPd8Fqn1uaMybJwTnFbmIfUxNPDlgYjGtjy9-E8,19944
|
731
|
-
ads/opctl/operator/lowcode/forecast/model/prophet.py,sha256=
|
731
|
+
ads/opctl/operator/lowcode/forecast/model/prophet.py,sha256=U0M3M7yzy7ea-mEG1c-dELL6t1Pf_LnnnbrZB08CG_Y,17402
|
732
732
|
ads/opctl/operator/lowcode/forecast/whatifserve/__init__.py,sha256=JNDDjLrNorKXMHUuXMifqXea3eheST-lnrcwCl2bWrk,242
|
733
733
|
ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py,sha256=w42anuqAScEQ0vBG3vW4LVLNq1bPdpAWGQEmNhMwZ08,12052
|
734
734
|
ads/opctl/operator/lowcode/forecast/whatifserve/score.py,sha256=JjEDtrqUfL4x9t-vvafXMLNwY9-vgc6QPX_Ee-wmI58,8709
|
@@ -807,7 +807,7 @@ ads/secrets/oracledb.py,sha256=VAbsY206gc_Ru8FBOCKNGnIlX4VprIIQ9PmBoujRy_k,6146
|
|
807
807
|
ads/secrets/secrets.py,sha256=k_f3hwh5RI7Hv7zEKDDuxh7kGB-F29bK15jxgu4sxVw,15197
|
808
808
|
ads/telemetry/__init__.py,sha256=_pKx4hDK7DUXHjvAq4Zbeg6wl9_UkgGE7O77KWezu8g,230
|
809
809
|
ads/telemetry/base.py,sha256=6kKVSfTxx2Dr0XL7R8OfjTy3hJoJpKMvP6D7RdVddl4,2199
|
810
|
-
ads/telemetry/client.py,sha256=
|
810
|
+
ads/telemetry/client.py,sha256=71hUqn-fF24zlb84ew5A0gugdkhBmzn30JEuNHDnMyM,5000
|
811
811
|
ads/telemetry/telemetry.py,sha256=xCu64tUEzYzFaXEMxnMdtQJPme5-9sW8l3uxibN4E04,7930
|
812
812
|
ads/templates/dataflow_pyspark.jinja2,sha256=JiTuaGt5LC7z1mrDoDIbZ5UskBETLpm0lMpn5VZYNGs,254
|
813
813
|
ads/templates/dataflow_sparksql.jinja2,sha256=8MvGzj7PWgUNo-9dg6zil8WTpBL3eNcR815fz64v1yM,466
|
@@ -851,8 +851,8 @@ ads/type_discovery/unknown_detector.py,sha256=yZuYQReO7PUyoWZE7onhhtYaOg6088wf1y
|
|
851
851
|
ads/type_discovery/zipcode_detector.py,sha256=3AlETg_ZF4FT0u914WXvTT3F3Z6Vf51WiIt34yQMRbw,1421
|
852
852
|
ads/vault/__init__.py,sha256=x9tMdDAOdF5iDHk9u2di_K-ze5Nq068x25EWOBoWwqY,245
|
853
853
|
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.
|
854
|
+
oracle_ads-2.13.10rc0.dist-info/entry_points.txt,sha256=9VFnjpQCsMORA4rVkvN8eH6D3uHjtegb9T911t8cqV0,35
|
855
|
+
oracle_ads-2.13.10rc0.dist-info/licenses/LICENSE.txt,sha256=zoGmbfD1IdRKx834U0IzfFFFo5KoFK71TND3K9xqYqo,1845
|
856
|
+
oracle_ads-2.13.10rc0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
857
|
+
oracle_ads-2.13.10rc0.dist-info/METADATA,sha256=MZ4kGFRBnDsst32Mrvla6SR2ufMpOvR9p48bBBuQkKs,16782
|
858
|
+
oracle_ads-2.13.10rc0.dist-info/RECORD,,
|
@@ -1,74 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
|
3
|
-
# Copyright (c) 2024, 2025 Oracle and/or its affiliates.
|
4
|
-
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
|
-
|
6
|
-
import json
|
7
|
-
from dataclasses import dataclass, field
|
8
|
-
|
9
|
-
import requests
|
10
|
-
|
11
|
-
from ads.aqua.app import AquaApp
|
12
|
-
from ads.aqua.modeldeployment.entities import ModelParams
|
13
|
-
from ads.common.auth import default_signer
|
14
|
-
from ads.telemetry import telemetry
|
15
|
-
|
16
|
-
|
17
|
-
@dataclass
|
18
|
-
class MDInferenceResponse(AquaApp):
|
19
|
-
"""Contains APIs for Aqua Model deployments Inference.
|
20
|
-
|
21
|
-
Attributes
|
22
|
-
----------
|
23
|
-
|
24
|
-
model_params: Dict
|
25
|
-
prompt: string
|
26
|
-
|
27
|
-
Methods
|
28
|
-
-------
|
29
|
-
get_model_deployment_response(self, **kwargs) -> "String"
|
30
|
-
Creates an instance of model deployment via Aqua
|
31
|
-
"""
|
32
|
-
|
33
|
-
prompt: str = None
|
34
|
-
model_params: field(default_factory=ModelParams) = None
|
35
|
-
|
36
|
-
@telemetry(entry_point="plugin=inference&action=get_response", name="aqua")
|
37
|
-
def get_model_deployment_response(self, endpoint):
|
38
|
-
"""
|
39
|
-
Returns MD inference response
|
40
|
-
|
41
|
-
Parameters
|
42
|
-
----------
|
43
|
-
endpoint: str
|
44
|
-
MD predict url
|
45
|
-
prompt: str
|
46
|
-
User prompt.
|
47
|
-
|
48
|
-
model_params: (Dict, optional)
|
49
|
-
Model parameters to be associated with the message.
|
50
|
-
Currently supported VLLM+OpenAI parameters.
|
51
|
-
|
52
|
-
--model-params '{
|
53
|
-
"max_tokens":500,
|
54
|
-
"temperature": 0.5,
|
55
|
-
"top_k": 10,
|
56
|
-
"top_p": 0.5,
|
57
|
-
"model": "/opt/ds/model/deployed_model",
|
58
|
-
...}'
|
59
|
-
|
60
|
-
Returns
|
61
|
-
-------
|
62
|
-
model_response_content
|
63
|
-
"""
|
64
|
-
|
65
|
-
params_dict = self.model_params.to_dict()
|
66
|
-
params_dict = {
|
67
|
-
key: value for key, value in params_dict.items() if value is not None
|
68
|
-
}
|
69
|
-
body = {"prompt": self.prompt, **params_dict}
|
70
|
-
request_kwargs = {"json": body, "headers": {"Content-Type": "application/json"}}
|
71
|
-
response = requests.post(
|
72
|
-
endpoint, auth=default_signer()["signer"], **request_kwargs
|
73
|
-
)
|
74
|
-
return json.loads(response.content)
|
File without changes
|
File without changes
|
File without changes
|