oracle-ads 2.11.14__py3-none-any.whl → 2.11.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ads/aqua/common/entities.py +17 -0
- ads/aqua/common/enums.py +5 -1
- ads/aqua/common/utils.py +109 -22
- ads/aqua/config/config.py +1 -1
- ads/aqua/config/deployment_config_defaults.json +29 -1
- ads/aqua/config/resource_limit_names.json +1 -0
- ads/aqua/constants.py +35 -18
- ads/aqua/evaluation/entities.py +0 -1
- ads/aqua/evaluation/evaluation.py +165 -121
- ads/aqua/extension/common_ws_msg_handler.py +57 -0
- ads/aqua/extension/deployment_handler.py +14 -13
- ads/aqua/extension/deployment_ws_msg_handler.py +54 -0
- ads/aqua/extension/errors.py +1 -1
- ads/aqua/extension/evaluation_handler.py +4 -7
- ads/aqua/extension/evaluation_ws_msg_handler.py +28 -10
- ads/aqua/extension/model_handler.py +31 -6
- ads/aqua/extension/models/ws_models.py +78 -3
- ads/aqua/extension/models_ws_msg_handler.py +49 -0
- ads/aqua/extension/ui_websocket_handler.py +7 -1
- ads/aqua/model/entities.py +17 -9
- ads/aqua/model/model.py +260 -90
- ads/aqua/modeldeployment/constants.py +0 -16
- ads/aqua/modeldeployment/deployment.py +97 -74
- ads/aqua/modeldeployment/entities.py +9 -20
- ads/aqua/ui.py +152 -28
- ads/common/object_storage_details.py +2 -5
- ads/common/serializer.py +2 -3
- ads/jobs/builders/infrastructure/dsc_job.py +29 -3
- ads/jobs/builders/infrastructure/dsc_job_runtime.py +74 -27
- ads/jobs/builders/runtimes/container_runtime.py +83 -4
- ads/opctl/operator/common/operator_config.py +1 -0
- ads/opctl/operator/lowcode/anomaly/README.md +3 -3
- ads/opctl/operator/lowcode/anomaly/__main__.py +5 -6
- ads/opctl/operator/lowcode/anomaly/const.py +9 -0
- ads/opctl/operator/lowcode/anomaly/model/anomaly_dataset.py +6 -2
- ads/opctl/operator/lowcode/anomaly/model/base_model.py +51 -26
- ads/opctl/operator/lowcode/anomaly/model/factory.py +41 -13
- ads/opctl/operator/lowcode/anomaly/model/isolationforest.py +79 -0
- ads/opctl/operator/lowcode/anomaly/model/oneclasssvm.py +79 -0
- ads/opctl/operator/lowcode/anomaly/operator_config.py +1 -0
- ads/opctl/operator/lowcode/anomaly/schema.yaml +16 -2
- ads/opctl/operator/lowcode/anomaly/utils.py +16 -13
- ads/opctl/operator/lowcode/common/data.py +2 -1
- ads/opctl/operator/lowcode/common/errors.py +6 -0
- ads/opctl/operator/lowcode/common/transformations.py +37 -9
- ads/opctl/operator/lowcode/common/utils.py +32 -10
- ads/opctl/operator/lowcode/forecast/model/base_model.py +21 -13
- ads/opctl/operator/lowcode/forecast/model/ml_forecast.py +14 -18
- ads/opctl/operator/lowcode/forecast/model_evaluator.py +15 -4
- ads/opctl/operator/lowcode/forecast/schema.yaml +9 -0
- ads/opctl/operator/lowcode/recommender/MLoperator +16 -0
- ads/opctl/operator/lowcode/recommender/README.md +206 -0
- ads/opctl/operator/lowcode/recommender/__init__.py +5 -0
- ads/opctl/operator/lowcode/recommender/__main__.py +82 -0
- ads/opctl/operator/lowcode/recommender/cmd.py +33 -0
- ads/opctl/operator/lowcode/recommender/constant.py +25 -0
- ads/opctl/operator/lowcode/recommender/environment.yaml +11 -0
- ads/opctl/operator/lowcode/recommender/model/base_model.py +198 -0
- ads/opctl/operator/lowcode/recommender/model/factory.py +58 -0
- ads/opctl/operator/lowcode/recommender/model/recommender_dataset.py +25 -0
- ads/opctl/operator/lowcode/recommender/model/svd.py +88 -0
- ads/opctl/operator/lowcode/recommender/operator_config.py +81 -0
- ads/opctl/operator/lowcode/recommender/schema.yaml +265 -0
- ads/opctl/operator/lowcode/recommender/utils.py +13 -0
- ads/pipeline/ads_pipeline_run.py +13 -2
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/METADATA +6 -1
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/RECORD +70 -50
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/LICENSE.txt +0 -0
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/WHEEL +0 -0
- {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/entry_points.txt +0 -0
ads/aqua/model/model.py
CHANGED
@@ -1,27 +1,31 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
# Copyright (c) 2024 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
|
import os
|
6
5
|
from datetime import datetime, timedelta
|
7
6
|
from threading import Lock
|
8
|
-
from typing import
|
7
|
+
from typing import Dict, Optional, Set, Union
|
9
8
|
|
10
9
|
from cachetools import TTLCache
|
11
|
-
from oci.data_science.models import JobRun, Model
|
12
10
|
|
13
11
|
from ads.aqua import ODSC_MODEL_COMPARTMENT_OCID
|
14
12
|
from ads.aqua.app import AquaApp
|
15
13
|
from ads.aqua.common.enums import Tags
|
16
|
-
from ads.aqua.common.errors import AquaRuntimeError
|
14
|
+
from ads.aqua.common.errors import AquaRuntimeError, AquaValueError
|
17
15
|
from ads.aqua.common.utils import (
|
16
|
+
copy_model_config,
|
18
17
|
create_word_icon,
|
19
18
|
get_artifact_path,
|
20
|
-
|
21
|
-
copy_model_config,
|
19
|
+
list_os_files_with_extension,
|
22
20
|
load_config,
|
21
|
+
read_file,
|
23
22
|
)
|
24
23
|
from ads.aqua.constants import (
|
24
|
+
AQUA_MODEL_ARTIFACT_CONFIG,
|
25
|
+
AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME,
|
26
|
+
AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE,
|
27
|
+
AQUA_MODEL_ARTIFACT_FILE,
|
28
|
+
AQUA_MODEL_TYPE_CUSTOM,
|
25
29
|
LICENSE_TXT,
|
26
30
|
MODEL_BY_REFERENCE_OSS_PATH_KEY,
|
27
31
|
README,
|
@@ -33,13 +37,10 @@ from ads.aqua.constants import (
|
|
33
37
|
UNKNOWN,
|
34
38
|
VALIDATION_METRICS,
|
35
39
|
VALIDATION_METRICS_FINAL,
|
36
|
-
AQUA_MODEL_ARTIFACT_CONFIG,
|
37
|
-
AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME,
|
38
|
-
AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE,
|
39
|
-
AQUA_MODEL_TYPE_CUSTOM,
|
40
40
|
)
|
41
41
|
from ads.aqua.model.constants import *
|
42
42
|
from ads.aqua.model.entities import *
|
43
|
+
from ads.aqua.ui import AquaContainerConfig, AquaContainerConfigItem
|
43
44
|
from ads.common.auth import default_signer
|
44
45
|
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
|
45
46
|
from ads.common.utils import get_console_link
|
@@ -54,6 +55,7 @@ from ads.config import (
|
|
54
55
|
from ads.model import DataScienceModel
|
55
56
|
from ads.model.model_metadata import ModelCustomMetadata, ModelCustomMetadataItem
|
56
57
|
from ads.telemetry import telemetry
|
58
|
+
from oci.data_science.models import JobRun, Model
|
57
59
|
|
58
60
|
|
59
61
|
class AquaModelApp(AquaApp):
|
@@ -236,7 +238,7 @@ class AquaModelApp(AquaApp):
|
|
236
238
|
try:
|
237
239
|
jobrun_ocid = ds_model.provenance_metadata.training_id
|
238
240
|
jobrun = self.ds_client.get_job_run(jobrun_ocid).data
|
239
|
-
except Exception
|
241
|
+
except Exception:
|
240
242
|
logger.debug(
|
241
243
|
f"Missing jobrun information in the provenance metadata of the given model {model_id}."
|
242
244
|
)
|
@@ -268,8 +270,7 @@ class AquaModelApp(AquaApp):
|
|
268
270
|
|
269
271
|
job_run_status = (
|
270
272
|
jobrun.lifecycle_state
|
271
|
-
if jobrun
|
272
|
-
and not jobrun.lifecycle_state == JobRun.LIFECYCLE_STATE_DELETED
|
273
|
+
if jobrun and jobrun.lifecycle_state != JobRun.LIFECYCLE_STATE_DELETED
|
273
274
|
else (
|
274
275
|
JobRun.LIFECYCLE_STATE_SUCCEEDED
|
275
276
|
if self.if_artifact_exist(ds_model.id)
|
@@ -363,8 +364,21 @@ class AquaModelApp(AquaApp):
|
|
363
364
|
training_final,
|
364
365
|
]
|
365
366
|
|
367
|
+
@staticmethod
|
368
|
+
def to_aqua_model(
|
369
|
+
model: Union[
|
370
|
+
DataScienceModel,
|
371
|
+
oci.data_science.models.model.Model,
|
372
|
+
oci.data_science.models.ModelSummary,
|
373
|
+
oci.resource_search.models.ResourceSummary,
|
374
|
+
],
|
375
|
+
region: str,
|
376
|
+
) -> AquaModel:
|
377
|
+
"""Converts a model to an Aqua model."""
|
378
|
+
return AquaModel(**AquaModelApp._process_model(model, region))
|
379
|
+
|
380
|
+
@staticmethod
|
366
381
|
def _process_model(
|
367
|
-
self,
|
368
382
|
model: Union[
|
369
383
|
DataScienceModel,
|
370
384
|
oci.data_science.models.model.Model,
|
@@ -389,12 +403,10 @@ class AquaModelApp(AquaApp):
|
|
389
403
|
else model.id
|
390
404
|
)
|
391
405
|
|
392
|
-
console_link = (
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
region=region,
|
397
|
-
),
|
406
|
+
console_link = get_console_link(
|
407
|
+
resource="models",
|
408
|
+
ocid=model_id,
|
409
|
+
region=region,
|
398
410
|
)
|
399
411
|
|
400
412
|
description = ""
|
@@ -406,7 +418,7 @@ class AquaModelApp(AquaApp):
|
|
406
418
|
description = model.additional_details.get("description")
|
407
419
|
|
408
420
|
search_text = (
|
409
|
-
|
421
|
+
AquaModelApp._build_search_text(tags=tags, description=description)
|
410
422
|
if tags
|
411
423
|
else UNKNOWN
|
412
424
|
)
|
@@ -416,6 +428,7 @@ class AquaModelApp(AquaApp):
|
|
416
428
|
ready_to_deploy = (
|
417
429
|
freeform_tags.get(Tags.AQUA_TAG, "").upper() == READY_TO_DEPLOY_STATUS
|
418
430
|
)
|
431
|
+
|
419
432
|
ready_to_finetune = (
|
420
433
|
freeform_tags.get(Tags.READY_TO_FINE_TUNE, "").upper()
|
421
434
|
== READY_TO_FINE_TUNE_STATUS
|
@@ -425,6 +438,24 @@ class AquaModelApp(AquaApp):
|
|
425
438
|
== READY_TO_IMPORT_STATUS
|
426
439
|
)
|
427
440
|
|
441
|
+
inference_containers = AquaContainerConfig.from_container_index_json().inference
|
442
|
+
|
443
|
+
model_format = ModelFormat[
|
444
|
+
freeform_tags.get(Tags.MODEL_FORMAT, ModelFormat.SAFETENSORS.value).upper()
|
445
|
+
]
|
446
|
+
supported_platform: Set[AquaContainerConfigItem.Platform] = set()
|
447
|
+
|
448
|
+
for container in inference_containers.values():
|
449
|
+
if model_format in container.model_formats:
|
450
|
+
supported_platform.update(container.platforms)
|
451
|
+
|
452
|
+
nvidia_gpu_supported = (
|
453
|
+
AquaContainerConfigItem.Platform.NVIDIA_GPU in supported_platform
|
454
|
+
)
|
455
|
+
arm_cpu_supported = (
|
456
|
+
AquaContainerConfigItem.Platform.ARM_CPU in supported_platform
|
457
|
+
)
|
458
|
+
|
428
459
|
return dict(
|
429
460
|
compartment_id=model.compartment_id,
|
430
461
|
icon=icon or UNKNOWN,
|
@@ -433,7 +464,7 @@ class AquaModelApp(AquaApp):
|
|
433
464
|
name=model.display_name,
|
434
465
|
organization=freeform_tags.get(Tags.ORGANIZATION, UNKNOWN),
|
435
466
|
task=freeform_tags.get(Tags.TASK, UNKNOWN),
|
436
|
-
time_created=model.time_created,
|
467
|
+
time_created=str(model.time_created),
|
437
468
|
is_fine_tuned_model=is_fine_tuned_model,
|
438
469
|
tags=tags,
|
439
470
|
console_link=console_link,
|
@@ -441,6 +472,9 @@ class AquaModelApp(AquaApp):
|
|
441
472
|
ready_to_deploy=ready_to_deploy,
|
442
473
|
ready_to_finetune=ready_to_finetune,
|
443
474
|
ready_to_import=ready_to_import,
|
475
|
+
nvidia_gpu_supported=nvidia_gpu_supported,
|
476
|
+
arm_cpu_supported=arm_cpu_supported,
|
477
|
+
model_format=model_format,
|
444
478
|
)
|
445
479
|
|
446
480
|
@telemetry(entry_point="plugin=model&action=list", name="aqua")
|
@@ -540,7 +574,7 @@ class AquaModelApp(AquaApp):
|
|
540
574
|
dict with the key used, and True if cache has the key that needs to be deleted.
|
541
575
|
"""
|
542
576
|
res = {}
|
543
|
-
logger.info(
|
577
|
+
logger.info("Clearing _service_models_cache")
|
544
578
|
with self._cache_lock:
|
545
579
|
if ODSC_MODEL_COMPARTMENT_OCID in self._service_models_cache.keys():
|
546
580
|
self._service_models_cache.pop(key=ODSC_MODEL_COMPARTMENT_OCID)
|
@@ -559,8 +593,10 @@ class AquaModelApp(AquaApp):
|
|
559
593
|
inference_container: str,
|
560
594
|
finetuning_container: str,
|
561
595
|
verified_model: DataScienceModel,
|
596
|
+
model_format: ModelFormat,
|
562
597
|
compartment_id: Optional[str],
|
563
598
|
project_id: Optional[str],
|
599
|
+
model_file: Optional[str],
|
564
600
|
) -> DataScienceModel:
|
565
601
|
"""Create model by reference from the object storage path
|
566
602
|
|
@@ -577,15 +613,19 @@ class AquaModelApp(AquaApp):
|
|
577
613
|
DataScienceModel: Returns Datascience model instance.
|
578
614
|
"""
|
579
615
|
model = DataScienceModel()
|
580
|
-
tags = (
|
616
|
+
tags: Dict[str, str] = (
|
581
617
|
{
|
582
618
|
**verified_model.freeform_tags,
|
583
619
|
Tags.AQUA_SERVICE_MODEL_TAG: verified_model.id,
|
584
620
|
}
|
585
621
|
if verified_model
|
586
|
-
else {
|
622
|
+
else {
|
623
|
+
Tags.AQUA_TAG: "active",
|
624
|
+
Tags.BASE_MODEL_CUSTOM: "true",
|
625
|
+
}
|
587
626
|
)
|
588
627
|
tags.update({Tags.BASE_MODEL_CUSTOM: "true"})
|
628
|
+
tags.update({Tags.MODEL_FORMAT: model_format.value})
|
589
629
|
|
590
630
|
# Remove `ready_to_import` tag that might get copied from service model.
|
591
631
|
tags.pop(Tags.READY_TO_IMPORT, None)
|
@@ -615,8 +655,15 @@ class AquaModelApp(AquaApp):
|
|
615
655
|
)
|
616
656
|
else:
|
617
657
|
logger.warn(
|
618
|
-
|
619
|
-
|
658
|
+
"Proceeding with model registration without the fine-tuning container information. "
|
659
|
+
"This model will not be available for fine tuning."
|
660
|
+
)
|
661
|
+
if model_file:
|
662
|
+
metadata.add(
|
663
|
+
key=AQUA_MODEL_ARTIFACT_FILE,
|
664
|
+
value=model_file,
|
665
|
+
description=f"The model file for {model_name}",
|
666
|
+
category="Other",
|
620
667
|
)
|
621
668
|
|
622
669
|
metadata.add(
|
@@ -673,6 +720,174 @@ class AquaModelApp(AquaApp):
|
|
673
720
|
logger.debug(model)
|
674
721
|
return model
|
675
722
|
|
723
|
+
@staticmethod
|
724
|
+
def get_model_files(os_path: str, model_format: ModelFormat) -> [str]:
|
725
|
+
"""
|
726
|
+
Get a list of model files based on the given OS path and model format.
|
727
|
+
|
728
|
+
Args:
|
729
|
+
os_path (str): The OS path where the model files are located.
|
730
|
+
model_format (ModelFormat): The format of the model files.
|
731
|
+
|
732
|
+
Returns:
|
733
|
+
List[str]: A list of model file names.
|
734
|
+
|
735
|
+
"""
|
736
|
+
model_files: List[str] = []
|
737
|
+
if model_format == ModelFormat.SAFETENSORS:
|
738
|
+
try:
|
739
|
+
load_config(
|
740
|
+
file_path=os_path,
|
741
|
+
config_file_name=AQUA_MODEL_ARTIFACT_CONFIG,
|
742
|
+
)
|
743
|
+
except AquaValueError:
|
744
|
+
pass
|
745
|
+
else:
|
746
|
+
model_files.append(AQUA_MODEL_ARTIFACT_CONFIG)
|
747
|
+
|
748
|
+
if model_format == ModelFormat.GGUF:
|
749
|
+
model_files.extend(
|
750
|
+
list_os_files_with_extension(oss_path=os_path, extension=".gguf")
|
751
|
+
)
|
752
|
+
return model_files
|
753
|
+
|
754
|
+
def validate_model_config(
|
755
|
+
self,
|
756
|
+
import_model_details: ImportModelDetails,
|
757
|
+
verified_model: Optional[DataScienceModel],
|
758
|
+
) -> ModelValidationResult:
|
759
|
+
"""
|
760
|
+
Validates the model configuration and returns the model format telemetry model name.
|
761
|
+
|
762
|
+
Args:
|
763
|
+
import_model_details (ImportModelDetails): The details of the imported model.
|
764
|
+
verified_model (Optional[DataScienceModel]): The verified model.
|
765
|
+
|
766
|
+
Returns:
|
767
|
+
ModelValidationResult: The result of the model validation.
|
768
|
+
|
769
|
+
Raises:
|
770
|
+
AquaRuntimeError: If there is an error while loading the config file or if the model path is incorrect.
|
771
|
+
AquaValueError: If the model format is not supported by AQUA."""
|
772
|
+
inference_containers_config = (
|
773
|
+
AquaContainerConfig.from_container_index_json().inference
|
774
|
+
)
|
775
|
+
inference_container = import_model_details.inference_container
|
776
|
+
model_format: ModelFormat
|
777
|
+
validation_result: ModelValidationResult = ModelValidationResult()
|
778
|
+
if verified_model:
|
779
|
+
aqua_model = self.to_aqua_model(verified_model, self.region)
|
780
|
+
model_format = aqua_model.model_format
|
781
|
+
else:
|
782
|
+
# Todo: Revisit this logic once a container supports multiple formats
|
783
|
+
try:
|
784
|
+
model_format = inference_containers_config[
|
785
|
+
inference_container
|
786
|
+
].model_formats[0]
|
787
|
+
except (KeyError, IndexError):
|
788
|
+
logger.warn(
|
789
|
+
"Unable to fetch model format for the model automatically defaulting to safetensors"
|
790
|
+
)
|
791
|
+
model_format = ModelFormat.SAFETENSORS
|
792
|
+
pass
|
793
|
+
validation_result.model_format = model_format
|
794
|
+
if model_format == ModelFormat.SAFETENSORS:
|
795
|
+
try:
|
796
|
+
model_config = load_config(
|
797
|
+
file_path=import_model_details.os_path,
|
798
|
+
config_file_name=AQUA_MODEL_ARTIFACT_CONFIG,
|
799
|
+
)
|
800
|
+
except Exception as ex:
|
801
|
+
logger.error(
|
802
|
+
f"Exception occurred while loading config file from {import_model_details.os_path}"
|
803
|
+
f"Exception message: {ex}"
|
804
|
+
)
|
805
|
+
raise AquaRuntimeError(
|
806
|
+
f"The model path {import_model_details.os_path} does not contain the file config.json. "
|
807
|
+
f"Please check if the path is correct or the model artifacts are available at this location."
|
808
|
+
)
|
809
|
+
else:
|
810
|
+
try:
|
811
|
+
metadata_model_type = verified_model.custom_metadata_list.get(
|
812
|
+
AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE
|
813
|
+
).value
|
814
|
+
if metadata_model_type:
|
815
|
+
if AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE in model_config:
|
816
|
+
if (
|
817
|
+
model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE]
|
818
|
+
!= metadata_model_type
|
819
|
+
):
|
820
|
+
raise AquaRuntimeError(
|
821
|
+
f"The {AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE} attribute in {AQUA_MODEL_ARTIFACT_CONFIG}"
|
822
|
+
f" at {import_model_details.os_path} is invalid, expected {metadata_model_type} for "
|
823
|
+
f"the model {import_model_details.model}. Please check if the path is correct or "
|
824
|
+
f"the correct model artifacts are available at this location."
|
825
|
+
f""
|
826
|
+
)
|
827
|
+
else:
|
828
|
+
logger.debug(
|
829
|
+
f"Could not find {AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE} attribute in "
|
830
|
+
f"{AQUA_MODEL_ARTIFACT_CONFIG}. Proceeding with model registration."
|
831
|
+
)
|
832
|
+
except:
|
833
|
+
pass
|
834
|
+
if verified_model:
|
835
|
+
validation_result.telemetry_model_name = verified_model.display_name
|
836
|
+
elif (
|
837
|
+
model_config is not None
|
838
|
+
and AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME in model_config
|
839
|
+
):
|
840
|
+
validation_result.telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME]}"
|
841
|
+
elif (
|
842
|
+
model_config is not None
|
843
|
+
and AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE in model_config
|
844
|
+
):
|
845
|
+
validation_result.telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE]}"
|
846
|
+
else:
|
847
|
+
validation_result.telemetry_model_name = AQUA_MODEL_TYPE_CUSTOM
|
848
|
+
|
849
|
+
elif model_format == ModelFormat.GGUF:
|
850
|
+
if import_model_details.finetuning_container:
|
851
|
+
raise AquaValueError(
|
852
|
+
"Finetuning is currently not supported with GGUF model format"
|
853
|
+
)
|
854
|
+
if verified_model:
|
855
|
+
model_file = verified_model.custom_metadata_list.get(
|
856
|
+
AQUA_MODEL_ARTIFACT_FILE, None
|
857
|
+
)
|
858
|
+
else:
|
859
|
+
model_file = import_model_details.model_file
|
860
|
+
model_files = self.get_model_files(
|
861
|
+
import_model_details.os_path, model_format
|
862
|
+
)
|
863
|
+
if model_file:
|
864
|
+
if model_file not in model_files:
|
865
|
+
raise AquaRuntimeError(
|
866
|
+
f"The model path {import_model_details.os_path} does not contain the file {model_file}. "
|
867
|
+
f"Please check if the path is correct or the model artifacts are available at this location."
|
868
|
+
)
|
869
|
+
else:
|
870
|
+
validation_result.model_file = model_file
|
871
|
+
elif len(model_files) == 0:
|
872
|
+
raise AquaRuntimeError(
|
873
|
+
f"The model path {import_model_details.os_path} does not contain any GGUF format files. "
|
874
|
+
f"Please check if the path is correct or the model artifacts are available at this location."
|
875
|
+
)
|
876
|
+
elif len(model_files) > 1:
|
877
|
+
raise AquaRuntimeError(
|
878
|
+
f"The model path {import_model_details.os_path} contains multiple GGUF format files. Please specify the file that needs to be deployed."
|
879
|
+
)
|
880
|
+
else:
|
881
|
+
validation_result.model_file = model_files[0]
|
882
|
+
|
883
|
+
if verified_model:
|
884
|
+
validation_result.telemetry_model_name = verified_model.display_name
|
885
|
+
else:
|
886
|
+
validation_result.telemetry_model_name = AQUA_MODEL_TYPE_CUSTOM
|
887
|
+
else:
|
888
|
+
raise AquaValueError("This model format is currently not supported by AQUA")
|
889
|
+
return validation_result
|
890
|
+
|
676
891
|
def register(
|
677
892
|
self, import_model_details: ImportModelDetails = None, **kwargs
|
678
893
|
) -> AquaModel:
|
@@ -692,72 +907,34 @@ class AquaModelApp(AquaApp):
|
|
692
907
|
AquaModel:
|
693
908
|
The registered model as a AquaModel object.
|
694
909
|
"""
|
695
|
-
verified_model_details: DataScienceModel = None
|
696
|
-
|
697
910
|
if not import_model_details:
|
698
911
|
import_model_details = ImportModelDetails(**kwargs)
|
699
912
|
|
700
|
-
try:
|
701
|
-
model_config = load_config(
|
702
|
-
file_path=import_model_details.os_path,
|
703
|
-
config_file_name=AQUA_MODEL_ARTIFACT_CONFIG,
|
704
|
-
)
|
705
|
-
except Exception as ex:
|
706
|
-
logger.error(
|
707
|
-
f"Exception occurred while loading config file from {import_model_details.os_path}"
|
708
|
-
f"Exception message: {ex}"
|
709
|
-
)
|
710
|
-
raise AquaRuntimeError(
|
711
|
-
f"The model path {import_model_details.os_path} does not contain the file config.json. "
|
712
|
-
f"Please check if the path is correct or the model artifacts are available at this location."
|
713
|
-
)
|
714
|
-
|
715
|
-
model_service_id = None
|
716
913
|
# If OCID of a model is passed, we need to copy the defaults for Tags and metadata from the service model.
|
914
|
+
verified_model: Optional[DataScienceModel] = None
|
717
915
|
if (
|
718
916
|
import_model_details.model.startswith("ocid")
|
719
917
|
and "datasciencemodel" in import_model_details.model
|
720
918
|
):
|
721
|
-
|
919
|
+
verified_model = DataScienceModel.from_id(import_model_details.model)
|
722
920
|
else:
|
723
921
|
# If users passes model name, check if there is model with the same name in the service model catalog. If it is there, then use that model
|
724
922
|
model_service_id = self._find_matching_aqua_model(
|
725
923
|
import_model_details.model
|
726
924
|
)
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
try:
|
733
|
-
metadata_model_type = verified_model_details.custom_metadata_list.get(
|
734
|
-
AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE
|
735
|
-
).value
|
736
|
-
if metadata_model_type:
|
737
|
-
if AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE in model_config:
|
738
|
-
if (
|
739
|
-
model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE]
|
740
|
-
!= metadata_model_type
|
741
|
-
):
|
742
|
-
raise AquaRuntimeError(
|
743
|
-
f"The {AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE} attribute in {AQUA_MODEL_ARTIFACT_CONFIG}"
|
744
|
-
f" at {import_model_details.os_path} is invalid, expected {metadata_model_type} for "
|
745
|
-
f"the model {import_model_details.model}. Please check if the path is correct or "
|
746
|
-
f"the correct model artifacts are available at this location."
|
747
|
-
f""
|
748
|
-
)
|
749
|
-
else:
|
750
|
-
logger.debug(
|
751
|
-
f"Could not find {AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE} attribute in "
|
752
|
-
f"{AQUA_MODEL_ARTIFACT_CONFIG}. Proceeding with model registration."
|
753
|
-
)
|
754
|
-
except:
|
755
|
-
pass
|
925
|
+
if model_service_id:
|
926
|
+
logger.info(
|
927
|
+
f"Found service model for {import_model_details.model}: {model_service_id}"
|
928
|
+
)
|
929
|
+
verified_model = DataScienceModel.from_id(model_service_id)
|
756
930
|
|
931
|
+
validation_result = self.validate_model_config(
|
932
|
+
import_model_details, verified_model
|
933
|
+
)
|
757
934
|
# Copy the model name from the service model if `model` is ocid
|
758
935
|
model_name = (
|
759
|
-
|
760
|
-
if
|
936
|
+
verified_model.display_name
|
937
|
+
if verified_model
|
761
938
|
else import_model_details.model
|
762
939
|
)
|
763
940
|
|
@@ -767,9 +944,11 @@ class AquaModelApp(AquaApp):
|
|
767
944
|
model_name=model_name,
|
768
945
|
inference_container=import_model_details.inference_container,
|
769
946
|
finetuning_container=import_model_details.finetuning_container,
|
770
|
-
verified_model=
|
947
|
+
verified_model=verified_model,
|
771
948
|
compartment_id=import_model_details.compartment_id,
|
772
949
|
project_id=import_model_details.project_id,
|
950
|
+
model_file=validation_result.model_file,
|
951
|
+
model_format=validation_result.model_format,
|
773
952
|
)
|
774
953
|
# registered model will always have inference and evaluation container, but
|
775
954
|
# fine-tuning container may be not set
|
@@ -800,20 +979,10 @@ class AquaModelApp(AquaApp):
|
|
800
979
|
evaluation_container=evaluation_container,
|
801
980
|
)
|
802
981
|
|
803
|
-
if verified_model_details:
|
804
|
-
telemetry_model_name = model_name
|
805
|
-
else:
|
806
|
-
if AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME in model_config:
|
807
|
-
telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME]}"
|
808
|
-
elif AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE in model_config:
|
809
|
-
telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE]}"
|
810
|
-
else:
|
811
|
-
telemetry_model_name = AQUA_MODEL_TYPE_CUSTOM
|
812
|
-
|
813
982
|
self.telemetry.record_event_async(
|
814
983
|
category="aqua/model",
|
815
984
|
action="register",
|
816
|
-
detail=telemetry_model_name,
|
985
|
+
detail=validation_result.telemetry_model_name,
|
817
986
|
)
|
818
987
|
|
819
988
|
return AquaModel(**aqua_model_attributes)
|
@@ -856,7 +1025,8 @@ class AquaModelApp(AquaApp):
|
|
856
1025
|
query, type=SEARCH_TYPE.STRUCTURED, tenant_id=TENANCY_OCID, **kwargs
|
857
1026
|
)
|
858
1027
|
|
859
|
-
|
1028
|
+
@staticmethod
|
1029
|
+
def _build_search_text(tags: dict, description: str = None) -> str:
|
860
1030
|
"""Constructs search_text field in response."""
|
861
1031
|
description = description or ""
|
862
1032
|
tags_text = (
|
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
# Copyright (c) 2024 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
|
|
@@ -9,18 +8,3 @@ aqua.modeldeployment.constants
|
|
9
8
|
|
10
9
|
This module contains constants used in Aqua Model Deployment.
|
11
10
|
"""
|
12
|
-
|
13
|
-
VLLMInferenceRestrictedParams = {
|
14
|
-
"--tensor-parallel-size",
|
15
|
-
"--port",
|
16
|
-
"--host",
|
17
|
-
"--served-model-name",
|
18
|
-
"--seed",
|
19
|
-
}
|
20
|
-
TGIInferenceRestrictedParams = {
|
21
|
-
"--port",
|
22
|
-
"--hostname",
|
23
|
-
"--num-shard",
|
24
|
-
"--sharded",
|
25
|
-
"--trust-remote-code",
|
26
|
-
}
|