oracle-ads 2.13.6__py3-none-any.whl → 2.13.7__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.
Files changed (37) hide show
  1. ads/aqua/__init__.py +0 -5
  2. ads/aqua/app.py +133 -20
  3. ads/aqua/cli.py +2 -15
  4. ads/aqua/common/utils.py +12 -83
  5. ads/aqua/config/container_config.py +105 -69
  6. ads/aqua/config/evaluation/evaluation_service_config.py +40 -0
  7. ads/aqua/constants.py +22 -20
  8. ads/aqua/evaluation/evaluation.py +98 -32
  9. ads/aqua/extension/common_handler.py +3 -12
  10. ads/aqua/extension/common_ws_msg_handler.py +3 -24
  11. ads/aqua/extension/model_handler.py +59 -6
  12. ads/aqua/extension/models/ws_models.py +2 -0
  13. ads/aqua/extension/models_ws_msg_handler.py +1 -0
  14. ads/aqua/extension/utils.py +11 -24
  15. ads/aqua/finetuning/entities.py +23 -1
  16. ads/aqua/finetuning/finetuning.py +26 -10
  17. ads/aqua/model/constants.py +8 -0
  18. ads/aqua/model/entities.py +8 -1
  19. ads/aqua/model/model.py +269 -105
  20. ads/aqua/modeldeployment/deployment.py +51 -47
  21. ads/aqua/modeldeployment/utils.py +23 -5
  22. ads/aqua/ui.py +3 -4
  23. ads/config.py +2 -2
  24. ads/model/datascience_model.py +29 -0
  25. ads/model/service/oci_datascience_model.py +1 -1
  26. ads/opctl/operator/lowcode/anomaly/model/anomaly_dataset.py +8 -6
  27. ads/opctl/operator/lowcode/anomaly/model/base_model.py +1 -1
  28. ads/opctl/operator/lowcode/anomaly/operator_config.py +5 -3
  29. ads/opctl/operator/lowcode/common/transformations.py +2 -0
  30. ads/opctl/operator/lowcode/forecast/model/automlx.py +29 -0
  31. ads/type_discovery/typed_feature.py +32 -34
  32. {oracle_ads-2.13.6.dist-info → oracle_ads-2.13.7.dist-info}/METADATA +1 -1
  33. {oracle_ads-2.13.6.dist-info → oracle_ads-2.13.7.dist-info}/RECORD +36 -37
  34. ads/aqua/config/config.py +0 -31
  35. {oracle_ads-2.13.6.dist-info → oracle_ads-2.13.7.dist-info}/WHEEL +0 -0
  36. {oracle_ads-2.13.6.dist-info → oracle_ads-2.13.7.dist-info}/entry_points.txt +0 -0
  37. {oracle_ads-2.13.6.dist-info → oracle_ads-2.13.7.dist-info}/licenses/LICENSE.txt +0 -0
ads/aqua/__init__.py CHANGED
@@ -14,7 +14,6 @@ from ads.aqua.client.client import (
14
14
  get_async_httpx_client,
15
15
  get_httpx_client,
16
16
  )
17
- from ads.aqua.common.utils import fetch_service_compartment
18
17
  from ads.config import OCI_RESOURCE_PRINCIPAL_VERSION
19
18
 
20
19
  ENV_VAR_LOG_LEVEL = "ADS_AQUA_LOG_LEVEL"
@@ -39,7 +38,3 @@ def set_log_level(log_level: str):
39
38
 
40
39
  if OCI_RESOURCE_PRINCIPAL_VERSION:
41
40
  set_auth("resource_principal")
42
-
43
- ODSC_MODEL_COMPARTMENT_OCID = (
44
- os.environ.get("ODSC_MODEL_COMPARTMENT_OCID") or fetch_service_compartment()
45
- )
ads/aqua/app.py CHANGED
@@ -7,11 +7,16 @@ import os
7
7
  import traceback
8
8
  from dataclasses import fields
9
9
  from datetime import datetime, timedelta
10
- from typing import Any, Dict, Optional, Union
10
+ from itertools import chain
11
+ from typing import Any, Dict, List, Optional, Union
11
12
 
12
13
  import oci
13
14
  from cachetools import TTLCache, cached
14
- from oci.data_science.models import UpdateModelDetails, UpdateModelProvenanceDetails
15
+ from oci.data_science.models import (
16
+ ContainerSummary,
17
+ UpdateModelDetails,
18
+ UpdateModelProvenanceDetails,
19
+ )
15
20
 
16
21
  from ads import set_auth
17
22
  from ads.aqua import logger
@@ -24,6 +29,11 @@ from ads.aqua.common.utils import (
24
29
  is_valid_ocid,
25
30
  load_config,
26
31
  )
32
+ from ads.aqua.config.container_config import (
33
+ AquaContainerConfig,
34
+ AquaContainerConfigItem,
35
+ )
36
+ from ads.aqua.constants import SERVICE_MANAGED_CONTAINER_URI_SCHEME
27
37
  from ads.common import oci_client as oc
28
38
  from ads.common.auth import default_signer
29
39
  from ads.common.utils import UNKNOWN, extract_region, is_path_exists
@@ -240,7 +250,9 @@ class AquaApp:
240
250
  .with_custom_metadata_list(model_custom_metadata)
241
251
  .with_defined_metadata_list(model_taxonomy_metadata)
242
252
  .with_provenance_metadata(ModelProvenanceMetadata(training_id=UNKNOWN))
243
- .with_defined_tags(**(defined_tags or {})) # Create defined tags when a model is created.
253
+ .with_defined_tags(
254
+ **(defined_tags or {})
255
+ ) # Create defined tags when a model is created.
244
256
  .create(
245
257
  **kwargs,
246
258
  )
@@ -271,6 +283,43 @@ class AquaApp:
271
283
  logger.info(f"Artifact not found in model {model_id}.")
272
284
  return False
273
285
 
286
+ def get_config_from_metadata(
287
+ self, model_id: str, metadata_key: str
288
+ ) -> ModelConfigResult:
289
+ """Gets the config for the given Aqua model from model catalog metadata content.
290
+
291
+ Parameters
292
+ ----------
293
+ model_id: str
294
+ The OCID of the Aqua model.
295
+ metadata_key: str
296
+ The metadata key name where artifact content is stored
297
+ Returns
298
+ -------
299
+ ModelConfigResult
300
+ A Pydantic model containing the model_details (extracted from OCI) and the config dictionary.
301
+ """
302
+ config = {}
303
+ oci_model = self.ds_client.get_model(model_id).data
304
+ try:
305
+ config = self.ds_client.get_model_defined_metadatum_artifact_content(
306
+ model_id, metadata_key
307
+ ).data.content.decode("utf-8")
308
+ return ModelConfigResult(config=json.loads(config), model_details=oci_model)
309
+ except UnicodeDecodeError as ex:
310
+ logger.error(
311
+ f"Failed to decode content for '{metadata_key}' in defined metadata for model '{model_id}' : {ex}"
312
+ )
313
+ except json.JSONDecodeError as ex:
314
+ logger.error(
315
+ f"Invalid JSON format for '{metadata_key}' in defined metadata for model '{model_id}' : {ex}"
316
+ )
317
+ except Exception as ex:
318
+ logger.error(
319
+ f"Failed to retrieve defined metadata key '{metadata_key}' for model '{model_id}': {ex}"
320
+ )
321
+ return ModelConfigResult(config=config, model_details=oci_model)
322
+
274
323
  @cached(cache=TTLCache(maxsize=1, ttl=timedelta(minutes=1), timer=datetime.now))
275
324
  def get_config(
276
325
  self,
@@ -310,22 +359,7 @@ class AquaApp:
310
359
  raise AquaRuntimeError(f"Target model {oci_model.id} is not an Aqua model.")
311
360
 
312
361
  config: Dict[str, Any] = {}
313
-
314
- # if the current model has a service model tag, then
315
- if Tags.AQUA_SERVICE_MODEL_TAG in oci_model.freeform_tags:
316
- base_model_ocid = oci_model.freeform_tags[Tags.AQUA_SERVICE_MODEL_TAG]
317
- logger.info(
318
- f"Base model found for the model: {oci_model.id}. "
319
- f"Loading {config_file_name} for base model {base_model_ocid}."
320
- )
321
- if config_folder == ConfigFolder.ARTIFACT:
322
- artifact_path = get_artifact_path(oci_model.custom_metadata_list)
323
- else:
324
- base_model = self.ds_client.get_model(base_model_ocid).data
325
- artifact_path = get_artifact_path(base_model.custom_metadata_list)
326
- else:
327
- logger.info(f"Loading {config_file_name} for model {oci_model.id}...")
328
- artifact_path = get_artifact_path(oci_model.custom_metadata_list)
362
+ artifact_path = get_artifact_path(oci_model.custom_metadata_list)
329
363
  if not artifact_path:
330
364
  logger.debug(
331
365
  f"Failed to get artifact path from custom metadata for the model: {model_id}"
@@ -340,7 +374,7 @@ class AquaApp:
340
374
  config_file_path = os.path.join(config_path, config_file_name)
341
375
  if is_path_exists(config_file_path):
342
376
  try:
343
- logger.debug(
377
+ logger.info(
344
378
  f"Loading config: `{config_file_name}` from `{config_path}`"
345
379
  )
346
380
  config = load_config(
@@ -361,6 +395,85 @@ class AquaApp:
361
395
 
362
396
  return ModelConfigResult(config=config, model_details=oci_model)
363
397
 
398
+ def get_container_image(self, container_type: str = None) -> str:
399
+ """
400
+ Gets the latest smc container complete image name from the given container type.
401
+
402
+ Parameters
403
+ ----------
404
+ container_type: str
405
+ type of container, can be either odsc-vllm-serving, odsc-llm-fine-tuning, odsc-llm-evaluate
406
+
407
+ Returns
408
+ -------
409
+ str:
410
+ A complete container name along with version. ex: dsmc://odsc-vllm-serving:0.7.4.1
411
+ """
412
+
413
+ containers = self.list_service_containers()
414
+ container = next(
415
+ (c for c in containers if c.is_latest and c.family_name == container_type),
416
+ None,
417
+ )
418
+ if not container:
419
+ raise AquaValueError(f"Invalid container type : {container_type}")
420
+ container_image = (
421
+ SERVICE_MANAGED_CONTAINER_URI_SCHEME
422
+ + container.container_name
423
+ + ":"
424
+ + container.tag
425
+ )
426
+ return container_image
427
+
428
+ @cached(cache=TTLCache(maxsize=20, ttl=timedelta(minutes=30), timer=datetime.now))
429
+ def list_service_containers(self) -> List[ContainerSummary]:
430
+ """
431
+ List containers from containers.conf in OCI Datascience control plane
432
+ """
433
+ containers = self.ds_client.list_containers().data
434
+ return containers
435
+
436
+ def get_container_config(self) -> AquaContainerConfig:
437
+ """
438
+ Fetches latest containers from containers.conf in OCI Datascience control plane
439
+
440
+ Returns
441
+ -------
442
+ AquaContainerConfig
443
+ An Object that contains latest container info for the given container family
444
+
445
+ """
446
+ return AquaContainerConfig.from_service_config(
447
+ service_containers=self.list_service_containers()
448
+ )
449
+
450
+ def get_container_config_item(
451
+ self, container_family: str
452
+ ) -> AquaContainerConfigItem:
453
+ """
454
+ Fetches latest container for given container_family_name from containers.conf in OCI Datascience control plane
455
+
456
+ Returns
457
+ -------
458
+ AquaContainerConfigItem
459
+ An Object that contains latest container info for the given container family
460
+
461
+ """
462
+
463
+ aqua_container_config = self.get_container_config()
464
+ inference_config = aqua_container_config.inference.values()
465
+ ft_config = aqua_container_config.finetune.values()
466
+ eval_config = aqua_container_config.evaluate.values()
467
+ container = next(
468
+ (
469
+ container
470
+ for container in chain(inference_config, ft_config, eval_config)
471
+ if container.family.lower() == container_family.lower()
472
+ ),
473
+ None,
474
+ )
475
+ return container
476
+
364
477
  @property
365
478
  def telemetry(self):
366
479
  if not self._telemetry:
ads/aqua/cli.py CHANGED
@@ -1,23 +1,20 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8 -*--
3
2
 
4
- # Copyright (c) 2024 Oracle and/or its affiliates.
3
+ # Copyright (c) 2024, 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
  import os
7
6
 
8
7
  from ads.aqua import (
9
8
  ENV_VAR_LOG_LEVEL,
10
- ODSC_MODEL_COMPARTMENT_OCID,
11
9
  logger,
12
10
  set_log_level,
13
11
  )
14
- from ads.aqua.common.errors import AquaCLIError, AquaConfigError
12
+ from ads.aqua.common.errors import AquaCLIError
15
13
  from ads.aqua.evaluation import AquaEvaluationApp
16
14
  from ads.aqua.finetuning import AquaFineTuningApp
17
15
  from ads.aqua.model import AquaModelApp
18
16
  from ads.aqua.modeldeployment import AquaDeploymentApp
19
17
  from ads.common.utils import LOG_LEVELS
20
- from ads.config import NB_SESSION_OCID
21
18
 
22
19
 
23
20
  class AquaCommand:
@@ -82,16 +79,6 @@ class AquaCommand:
82
79
 
83
80
  set_log_level(aqua_log_level)
84
81
 
85
- if not ODSC_MODEL_COMPARTMENT_OCID:
86
- if NB_SESSION_OCID:
87
- raise AquaConfigError(
88
- f"Aqua is not available for the notebook session {NB_SESSION_OCID}. For more information, "
89
- f"please refer to the documentation."
90
- )
91
- raise AquaConfigError(
92
- "ODSC_MODEL_COMPARTMENT_OCID environment variable is not set for Aqua."
93
- )
94
-
95
82
  @staticmethod
96
83
  def _validate_value(flag, value):
97
84
  """Check if the given value for bool flag is valid.
ads/aqua/common/utils.py CHANGED
@@ -50,12 +50,14 @@ from ads.aqua.common.errors import (
50
50
  )
51
51
  from ads.aqua.constants import (
52
52
  AQUA_GA_LIST,
53
- COMPARTMENT_MAPPING_KEY,
54
53
  CONSOLE_LINK_RESOURCE_TYPE_MAPPING,
55
- CONTAINER_INDEX,
54
+ DEPLOYMENT_CONFIG,
55
+ FINE_TUNING_CONFIG,
56
56
  HF_LOGIN_DEFAULT_TIMEOUT,
57
+ LICENSE,
57
58
  MAXIMUM_ALLOWED_DATASET_IN_BYTE,
58
59
  MODEL_BY_REFERENCE_OSS_PATH_KEY,
60
+ README,
59
61
  SERVICE_MANAGED_CONTAINER_URI_SCHEME,
60
62
  SUPPORTED_FILE_FORMATS,
61
63
  TEI_CONTAINER_DEFAULT_HOST,
@@ -89,6 +91,14 @@ from ads.model import DataScienceModel, ModelVersionSet
89
91
  logger = logging.getLogger("ads.aqua")
90
92
 
91
93
 
94
+ DEFINED_METADATA_TO_FILE_MAP = {
95
+ "readme": README,
96
+ "license": LICENSE,
97
+ "finetuneconfiguration": FINE_TUNING_CONFIG,
98
+ "deploymentconfiguration": DEPLOYMENT_CONFIG,
99
+ }
100
+
101
+
92
102
  class LifecycleStatus(ExtendedEnum):
93
103
  UNKNOWN = ""
94
104
 
@@ -549,87 +559,6 @@ def _build_job_identifier(
549
559
  return AquaResourceIdentifier()
550
560
 
551
561
 
552
- def service_config_path():
553
- return f"oci://{AQUA_SERVICE_MODELS_BUCKET}@{CONDA_BUCKET_NS}/service_models/config"
554
-
555
-
556
- @cached(cache=TTLCache(maxsize=1, ttl=timedelta(minutes=10), timer=datetime.now))
557
- def get_container_config():
558
- config = load_config(
559
- file_path=service_config_path(),
560
- config_file_name=CONTAINER_INDEX,
561
- )
562
-
563
- return config
564
-
565
-
566
- def get_container_image(
567
- config_file_name: str = None, container_type: str = None
568
- ) -> str:
569
- """Gets the image name from the given model and container type.
570
- Parameters
571
- ----------
572
- config_file_name: str
573
- name of the config file
574
- container_type: str
575
- type of container, can be either deployment-container, finetune-container, evaluation-container
576
-
577
- Returns
578
- -------
579
- Dict:
580
- A dict of allowed configs.
581
- """
582
-
583
- container_image = UNKNOWN
584
- config = config_file_name or get_container_config()
585
- config_file_name = service_config_path()
586
-
587
- if container_type not in config:
588
- return UNKNOWN
589
-
590
- mapping = config[container_type]
591
- versions = [obj["version"] for obj in mapping]
592
- # assumes numbered versions, update if `latest` is used
593
- latest = get_max_version(versions)
594
- for obj in mapping:
595
- if obj["version"] == str(latest):
596
- container_image = f"{obj['name']}:{obj['version']}"
597
- break
598
-
599
- if not container_image:
600
- raise AquaValueError(
601
- f"{config_file_name} is missing name and/or version details."
602
- )
603
-
604
- return container_image
605
-
606
-
607
- def fetch_service_compartment() -> Union[str, None]:
608
- """
609
- Loads the compartment mapping json from service bucket.
610
- This json file has a service-model-compartment key which contains a dictionary of namespaces
611
- and the compartment OCID of the service models in that namespace.
612
- """
613
- config_file_name = (
614
- f"oci://{AQUA_SERVICE_MODELS_BUCKET}@{CONDA_BUCKET_NS}/service_models/config"
615
- )
616
-
617
- try:
618
- config = load_config(
619
- file_path=config_file_name,
620
- config_file_name=CONTAINER_INDEX,
621
- )
622
- except Exception as e:
623
- logger.debug(
624
- f"Config file {config_file_name}/{CONTAINER_INDEX} to fetch service compartment OCID "
625
- f"could not be found. \n{str(e)}."
626
- )
627
- return
628
- compartment_mapping = config.get(COMPARTMENT_MAPPING_KEY)
629
- if compartment_mapping:
630
- return compartment_mapping.get(CONDA_BUCKET_NS)
631
-
632
-
633
562
  def get_max_version(versions):
634
563
  """Takes in a list of versions and returns the higher version."""
635
564
  if not versions:
@@ -1,14 +1,20 @@
1
1
  #!/usr/bin/env python
2
2
  # Copyright (c) 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 json
5
5
  from typing import Dict, List, Optional
6
6
 
7
+ from oci.data_science.models import ContainerSummary
7
8
  from pydantic import Field
8
9
 
9
- from ads.aqua.common.entities import ContainerSpec
10
10
  from ads.aqua.config.utils.serializer import Serializable
11
+ from ads.aqua.constants import (
12
+ SERVICE_MANAGED_CONTAINER_URI_SCHEME,
13
+ UNKNOWN_JSON_LIST,
14
+ UNKNOWN_JSON_STR,
15
+ )
11
16
  from ads.common.extended_enum import ExtendedEnum
17
+ from ads.common.utils import UNKNOWN
12
18
 
13
19
 
14
20
  class Usage(ExtendedEnum):
@@ -46,6 +52,9 @@ class AquaContainerConfigSpec(Serializable):
46
52
  restricted_params: Optional[List[str]] = Field(
47
53
  default_factory=list, description="List of restricted parameters."
48
54
  )
55
+ evaluation_configuration: Optional[Dict] = Field(
56
+ default_factory=dict, description="Dict of evaluation configuration."
57
+ )
49
58
 
50
59
  class Config:
51
60
  extra = "allow"
@@ -126,87 +135,114 @@ class AquaContainerConfig(Serializable):
126
135
  }
127
136
 
128
137
  @classmethod
129
- def from_container_index_json(
130
- cls,
131
- config: Dict,
132
- enable_spec: Optional[bool] = False,
138
+ def from_service_config(
139
+ cls, service_containers: List[ContainerSummary]
133
140
  ) -> "AquaContainerConfig":
134
141
  """
135
- Creates an AquaContainerConfig instance from a container index JSON.
142
+ Creates an AquaContainerConfig instance from a service containers.conf.
136
143
 
137
144
  Parameters
138
145
  ----------
139
- config (Optional[Dict]): The container index JSON.
140
- enable_spec (Optional[bool]): If True, fetch container specification details.
141
-
146
+ service_containers (List[Any]): List of containers specified in containers.conf
142
147
  Returns
143
148
  -------
144
149
  AquaContainerConfig: The constructed container configuration.
145
150
  """
146
- # TODO: Return this logic back if necessary in the next iteraion.
147
- # if not config:
148
- # config = get_container_config()
149
151
 
150
152
  inference_items: Dict[str, AquaContainerConfigItem] = {}
151
153
  finetune_items: Dict[str, AquaContainerConfigItem] = {}
152
154
  evaluate_items: Dict[str, AquaContainerConfigItem] = {}
153
-
154
- for container_type, containers in config.items():
155
- if isinstance(containers, list):
156
- for container in containers:
157
- platforms = container.get("platforms", [])
158
- model_formats = container.get("modelFormats", [])
159
- usages = container.get("usages", [])
160
- container_spec = (
161
- config.get(ContainerSpec.CONTAINER_SPEC, {}).get(
162
- container_type, {}
155
+ for container in service_containers:
156
+ if not container.is_latest:
157
+ continue
158
+ container_item = AquaContainerConfigItem(
159
+ name=SERVICE_MANAGED_CONTAINER_URI_SCHEME + container.container_name,
160
+ version=container.tag,
161
+ display_name=container.display_name,
162
+ family=container.family_name,
163
+ usages=container.usages,
164
+ platforms=[],
165
+ model_formats=[],
166
+ spec=None,
167
+ )
168
+ container_type = container.family_name
169
+ usages = [x.upper() for x in container.usages]
170
+ if "INFERENCE" in usages or "MULTI_MODEL" in usages:
171
+ container_item.platforms.append(
172
+ container.workload_configuration_details_list[
173
+ 0
174
+ ].additional_configurations.get("platforms")
175
+ )
176
+ container_item.model_formats.append(
177
+ container.workload_configuration_details_list[
178
+ 0
179
+ ].additional_configurations.get("modelFormats")
180
+ )
181
+ env_vars = [
182
+ {
183
+ "MODEL_DEPLOY_PREDICT_ENDPOINT": container.workload_configuration_details_list[
184
+ 0
185
+ ].additional_configurations.get(
186
+ "MODEL_DEPLOY_PREDICT_ENDPOINT", UNKNOWN
163
187
  )
164
- if enable_spec
165
- else None
166
- )
167
- container_item = AquaContainerConfigItem(
168
- name=container.get("name", ""),
169
- version=container.get("version", ""),
170
- display_name=container.get(
171
- "displayName", container.get("version", "")
172
- ),
173
- family=container_type,
174
- platforms=platforms,
175
- model_formats=model_formats,
176
- usages=usages,
177
- spec=(
178
- AquaContainerConfigSpec(
179
- cli_param=container_spec.get(
180
- ContainerSpec.CLI_PARM, ""
181
- ),
182
- server_port=container_spec.get(
183
- ContainerSpec.SERVER_PORT, ""
184
- ),
185
- health_check_port=container_spec.get(
186
- ContainerSpec.HEALTH_CHECK_PORT, ""
187
- ),
188
- env_vars=container_spec.get(ContainerSpec.ENV_VARS, []),
189
- restricted_params=container_spec.get(
190
- ContainerSpec.RESTRICTED_PARAMS, []
191
- ),
192
- )
193
- if container_spec
194
- else None
195
- ),
196
- )
197
- if container.get("type") == "inference":
198
- inference_items[container_type] = container_item
199
- elif (
200
- container.get("type") == "fine-tune"
201
- or container_type == "odsc-llm-fine-tuning"
202
- ):
203
- finetune_items[container_type] = container_item
204
- elif (
205
- container.get("type") == "evaluate"
206
- or container_type == "odsc-llm-evaluate"
207
- ):
208
- evaluate_items[container_type] = container_item
209
-
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
+ },
213
+ ]
214
+ container_spec = AquaContainerConfigSpec(
215
+ cli_param=container.workload_configuration_details_list[0].cmd,
216
+ server_port=str(
217
+ container.workload_configuration_details_list[0].server_port
218
+ ),
219
+ health_check_port=str(
220
+ container.workload_configuration_details_list[
221
+ 0
222
+ ].health_check_port
223
+ ),
224
+ env_vars=env_vars,
225
+ restricted_params=json.loads(
226
+ container.workload_configuration_details_list[
227
+ 0
228
+ ].additional_configurations.get("restrictedParams")
229
+ or UNKNOWN_JSON_LIST
230
+ ),
231
+ evaluation_configuration=json.loads(
232
+ container.workload_configuration_details_list[
233
+ 0
234
+ ].additional_configurations.get(
235
+ "evaluationConfiguration", UNKNOWN_JSON_STR
236
+ )
237
+ ),
238
+ )
239
+ container_item.spec = container_spec
240
+ if "INFERENCE" in usages or "MULTI_MODEL" in usages:
241
+ inference_items[container_type] = container_item
242
+ if "FINE_TUNE" in usages:
243
+ finetune_items[container_type] = container_item
244
+ if "EVALUATION" in usages:
245
+ evaluate_items[container_type] = container_item
210
246
  return cls(
211
247
  inference=inference_items, finetune=finetune_items, evaluate=evaluate_items
212
248
  )
@@ -3,12 +3,16 @@
3
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
+ import json
6
7
  from typing import Any, Dict, List, Optional
7
8
 
9
+ from oci.data_science.models import ContainerSummary
8
10
  from pydantic import Field
9
11
 
10
12
  from ads.aqua.config.utils.serializer import Serializable
11
13
 
14
+ DEFAULT_EVALUATION_CONTAINER = "odsc-llm-evaluate"
15
+
12
16
 
13
17
  class ShapeFilterConfig(Serializable):
14
18
  """Represents the filtering options for a specific shape."""
@@ -105,3 +109,39 @@ class EvaluationServiceConfig(Serializable):
105
109
 
106
110
  class Config:
107
111
  extra = "allow"
112
+
113
+ @staticmethod
114
+ def from_oci_container_config(
115
+ oci_container_config: ContainerSummary,
116
+ ) -> "EvaluationServiceConfig":
117
+ """
118
+ Returns EvaluationServiceConfig for given oci_container_config
119
+ """
120
+
121
+ shapes = json.loads(
122
+ oci_container_config.workload_configuration_details_list[
123
+ 0
124
+ ].use_case_configuration.additional_configurations.get("shapes")
125
+ )
126
+ metrics = json.loads(
127
+ oci_container_config.workload_configuration_details_list[
128
+ 0
129
+ ].use_case_configuration.additional_configurations.get("metrics")
130
+ )
131
+ model_params = ModelParamsConfig(
132
+ default={
133
+ "model": "odsc-llm",
134
+ "max_tokens": 500,
135
+ "temperature": 0.7,
136
+ "top_p": 0.9,
137
+ "top_k": 50,
138
+ "presence_penalty": 0.0,
139
+ "frequency_penalty": 0.0,
140
+ "stop": [],
141
+ }
142
+ )
143
+ return EvaluationServiceConfig(
144
+ ui_config=UIConfig(
145
+ model_params=model_params, shapes=shapes, metrics=metrics
146
+ )
147
+ )