oracle-ads 2.12.10rc0__py3-none-any.whl → 2.13.0__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 (66) hide show
  1. ads/aqua/__init__.py +2 -1
  2. ads/aqua/app.py +46 -19
  3. ads/aqua/client/__init__.py +3 -0
  4. ads/aqua/client/client.py +799 -0
  5. ads/aqua/common/enums.py +19 -14
  6. ads/aqua/common/errors.py +3 -4
  7. ads/aqua/common/utils.py +2 -2
  8. ads/aqua/constants.py +1 -0
  9. ads/aqua/evaluation/constants.py +7 -7
  10. ads/aqua/evaluation/errors.py +3 -4
  11. ads/aqua/evaluation/evaluation.py +20 -12
  12. ads/aqua/extension/aqua_ws_msg_handler.py +14 -7
  13. ads/aqua/extension/base_handler.py +12 -9
  14. ads/aqua/extension/model_handler.py +29 -1
  15. ads/aqua/extension/models/ws_models.py +5 -6
  16. ads/aqua/finetuning/constants.py +3 -3
  17. ads/aqua/finetuning/entities.py +3 -0
  18. ads/aqua/finetuning/finetuning.py +32 -1
  19. ads/aqua/model/constants.py +7 -7
  20. ads/aqua/model/entities.py +2 -1
  21. ads/aqua/model/enums.py +4 -5
  22. ads/aqua/model/model.py +158 -76
  23. ads/aqua/modeldeployment/deployment.py +22 -10
  24. ads/aqua/modeldeployment/entities.py +3 -1
  25. ads/cli.py +16 -8
  26. ads/common/auth.py +33 -20
  27. ads/common/extended_enum.py +52 -44
  28. ads/llm/__init__.py +11 -8
  29. ads/llm/langchain/plugins/embeddings/__init__.py +4 -0
  30. ads/llm/langchain/plugins/embeddings/oci_data_science_model_deployment_endpoint.py +184 -0
  31. ads/model/artifact_downloader.py +3 -4
  32. ads/model/datascience_model.py +84 -64
  33. ads/model/generic_model.py +3 -3
  34. ads/model/model_metadata.py +17 -11
  35. ads/model/service/oci_datascience_model.py +12 -14
  36. ads/opctl/backend/marketplace/helm_helper.py +13 -14
  37. ads/opctl/cli.py +4 -5
  38. ads/opctl/cmds.py +28 -32
  39. ads/opctl/config/merger.py +8 -11
  40. ads/opctl/config/resolver.py +25 -30
  41. ads/opctl/operator/cli.py +9 -9
  42. ads/opctl/operator/common/backend_factory.py +56 -60
  43. ads/opctl/operator/common/const.py +5 -5
  44. ads/opctl/operator/lowcode/anomaly/const.py +8 -9
  45. ads/opctl/operator/lowcode/common/transformations.py +38 -3
  46. ads/opctl/operator/lowcode/common/utils.py +11 -1
  47. ads/opctl/operator/lowcode/feature_store_marketplace/operator_utils.py +43 -48
  48. ads/opctl/operator/lowcode/forecast/__main__.py +10 -0
  49. ads/opctl/operator/lowcode/forecast/const.py +6 -6
  50. ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +1 -1
  51. ads/opctl/operator/lowcode/forecast/operator_config.py +31 -0
  52. ads/opctl/operator/lowcode/forecast/schema.yaml +63 -0
  53. ads/opctl/operator/lowcode/forecast/whatifserve/__init__.py +7 -0
  54. ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py +233 -0
  55. ads/opctl/operator/lowcode/forecast/whatifserve/score.py +238 -0
  56. ads/opctl/operator/lowcode/pii/constant.py +6 -7
  57. ads/opctl/operator/lowcode/recommender/constant.py +12 -7
  58. ads/opctl/operator/runtime/marketplace_runtime.py +4 -10
  59. ads/opctl/operator/runtime/runtime.py +4 -6
  60. ads/pipeline/ads_pipeline_run.py +13 -25
  61. ads/pipeline/visualizer/graph_renderer.py +3 -4
  62. {oracle_ads-2.12.10rc0.dist-info → oracle_ads-2.13.0.dist-info}/METADATA +4 -2
  63. {oracle_ads-2.12.10rc0.dist-info → oracle_ads-2.13.0.dist-info}/RECORD +66 -59
  64. {oracle_ads-2.12.10rc0.dist-info → oracle_ads-2.13.0.dist-info}/LICENSE.txt +0 -0
  65. {oracle_ads-2.12.10rc0.dist-info → oracle_ads-2.13.0.dist-info}/WHEEL +0 -0
  66. {oracle_ads-2.12.10rc0.dist-info → oracle_ads-2.13.0.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python
2
- # Copyright (c) 2024 Oracle and/or its affiliates.
2
+ # Copyright (c) 2024, 2025 Oracle and/or its affiliates.
3
3
  # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
4
4
 
5
5
  """
@@ -9,10 +9,10 @@ aqua.model.constants
9
9
  This module contains constants/enums used in Aqua Model.
10
10
  """
11
11
 
12
- from ads.common.extended_enum import ExtendedEnumMeta
12
+ from ads.common.extended_enum import ExtendedEnum
13
13
 
14
14
 
15
- class ModelCustomMetadataFields(str, metaclass=ExtendedEnumMeta):
15
+ class ModelCustomMetadataFields(ExtendedEnum):
16
16
  ARTIFACT_LOCATION = "artifact_location"
17
17
  DEPLOYMENT_CONTAINER = "deployment-container"
18
18
  EVALUATION_CONTAINER = "evaluation-container"
@@ -20,24 +20,24 @@ class ModelCustomMetadataFields(str, metaclass=ExtendedEnumMeta):
20
20
  DEPLOYMENT_CONTAINER_URI = "deployment-container-uri"
21
21
 
22
22
 
23
- class ModelTask(str, metaclass=ExtendedEnumMeta):
23
+ class ModelTask(ExtendedEnum):
24
24
  TEXT_GENERATION = "text-generation"
25
25
  IMAGE_TEXT_TO_TEXT = "image-text-to-text"
26
26
  IMAGE_TO_TEXT = "image-to-text"
27
27
 
28
28
 
29
- class FineTuningMetricCategories(str, metaclass=ExtendedEnumMeta):
29
+ class FineTuningMetricCategories(ExtendedEnum):
30
30
  VALIDATION = "validation"
31
31
  TRAINING = "training"
32
32
 
33
33
 
34
- class ModelType(str, metaclass=ExtendedEnumMeta):
34
+ class ModelType(ExtendedEnum):
35
35
  FT = "FT" # Fine Tuned Model
36
36
  BASE = "BASE" # Base model
37
37
 
38
38
 
39
39
  # TODO: merge metadata key used in create FT
40
- class FineTuningCustomMetadata(str, metaclass=ExtendedEnumMeta):
40
+ class FineTuningCustomMetadata(ExtendedEnum):
41
41
  FT_SOURCE = "fine_tune_source"
42
42
  FT_SOURCE_NAME = "fine_tune_source_name"
43
43
  FT_OUTPUT_PATH = "fine_tune_output_path"
@@ -283,7 +283,7 @@ class ImportModelDetails(CLIBuilderMixin):
283
283
  os_path: str
284
284
  download_from_hf: Optional[bool] = True
285
285
  local_dir: Optional[str] = None
286
- cleanup_model_cache: Optional[bool] = True
286
+ cleanup_model_cache: Optional[bool] = False
287
287
  inference_container: Optional[str] = None
288
288
  finetuning_container: Optional[str] = None
289
289
  compartment_id: Optional[str] = None
@@ -294,6 +294,7 @@ class ImportModelDetails(CLIBuilderMixin):
294
294
  ignore_patterns: Optional[List[str]] = None
295
295
  freeform_tags: Optional[dict] = None
296
296
  defined_tags: Optional[dict] = None
297
+ ignore_model_artifact_check: Optional[bool] = None
297
298
 
298
299
  def __post_init__(self):
299
300
  self._command = "model register"
ads/aqua/model/enums.py CHANGED
@@ -1,18 +1,17 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
- # Copyright (c) 2024 Oracle and/or its affiliates.
2
+ # Copyright (c) 2024, 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
- from ads.common.extended_enum import ExtendedEnumMeta
4
+ from ads.common.extended_enum import ExtendedEnum
6
5
 
7
6
 
8
- class FineTuningDefinedMetadata(str, metaclass=ExtendedEnumMeta):
7
+ class FineTuningDefinedMetadata(ExtendedEnum):
9
8
  """Represents the defined metadata keys used in Fine Tuning."""
10
9
 
11
10
  VAL_SET_SIZE = "val_set_size"
12
11
  TRAINING_DATA = "training_data"
13
12
 
14
13
 
15
- class FineTuningCustomMetadata(str, metaclass=ExtendedEnumMeta):
14
+ class FineTuningCustomMetadata(ExtendedEnum):
16
15
  """Represents the custom metadata keys used in Fine Tuning."""
17
16
 
18
17
  FT_SOURCE = "fine_tune_source"
ads/aqua/model/model.py CHANGED
@@ -15,17 +15,21 @@ from oci.data_science.models import JobRun, Metadata, Model, UpdateModelDetails
15
15
  from ads.aqua import ODSC_MODEL_COMPARTMENT_OCID, logger
16
16
  from ads.aqua.app import AquaApp
17
17
  from ads.aqua.common.enums import (
18
+ ConfigFolder,
18
19
  CustomInferenceContainerTypeFamily,
19
20
  FineTuningContainerTypeFamily,
20
21
  InferenceContainerTypeFamily,
21
22
  Tags,
22
23
  )
23
- from ads.aqua.common.errors import AquaRuntimeError, AquaValueError
24
+ from ads.aqua.common.errors import (
25
+ AquaFileNotFoundError,
26
+ AquaRuntimeError,
27
+ AquaValueError,
28
+ )
24
29
  from ads.aqua.common.utils import (
25
30
  LifecycleStatus,
26
31
  _build_resource_identifier,
27
32
  cleanup_local_hf_model_artifact,
28
- copy_model_config,
29
33
  create_word_icon,
30
34
  generate_tei_cmd_var,
31
35
  get_artifact_path,
@@ -41,6 +45,7 @@ from ads.aqua.constants import (
41
45
  AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME,
42
46
  AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE,
43
47
  AQUA_MODEL_ARTIFACT_FILE,
48
+ AQUA_MODEL_TOKENIZER_CONFIG,
44
49
  AQUA_MODEL_TYPE_CUSTOM,
45
50
  HF_METADATA_FOLDER,
46
51
  LICENSE_TXT,
@@ -162,7 +167,7 @@ class AquaModelApp(AquaApp):
162
167
  target_compartment = compartment_id or COMPARTMENT_OCID
163
168
 
164
169
  if service_model.compartment_id != ODSC_MODEL_COMPARTMENT_OCID:
165
- logger.debug(
170
+ logger.info(
166
171
  f"Aqua Model {model_id} already exists in user's compartment."
167
172
  "Skipped copying."
168
173
  )
@@ -193,8 +198,8 @@ class AquaModelApp(AquaApp):
193
198
  # TODO: decide what kwargs will be needed.
194
199
  .create(model_by_reference=True, **kwargs)
195
200
  )
196
- logger.debug(
197
- f"Aqua Model {custom_model.id} created with the service model {model_id}"
201
+ logger.info(
202
+ f"Aqua Model {custom_model.id} created with the service model {model_id}."
198
203
  )
199
204
 
200
205
  # tracks unique models that were created in the user compartment
@@ -225,11 +230,16 @@ class AquaModelApp(AquaApp):
225
230
 
226
231
  cached_item = self._service_model_details_cache.get(model_id)
227
232
  if cached_item:
233
+ logger.info(f"Fetching model details for model {model_id} from cache.")
228
234
  return cached_item
229
235
 
236
+ logger.info(f"Fetching model details for model {model_id}.")
230
237
  ds_model = DataScienceModel.from_id(model_id)
231
238
  if not self._if_show(ds_model):
232
- raise AquaRuntimeError(f"Target model `{ds_model.id} `is not Aqua model.")
239
+ raise AquaRuntimeError(
240
+ f"Target model `{ds_model.id} `is not an Aqua model as it does not contain "
241
+ f"{Tags.AQUA_TAG} tag."
242
+ )
233
243
 
234
244
  is_fine_tuned_model = bool(
235
245
  ds_model.freeform_tags
@@ -248,16 +258,21 @@ class AquaModelApp(AquaApp):
248
258
  ds_model.custom_metadata_list._to_oci_metadata()
249
259
  )
250
260
  if artifact_path != UNKNOWN:
261
+ model_card_path = (
262
+ f"{artifact_path.rstrip('/')}/config/{README}"
263
+ if is_verified_type
264
+ else f"{artifact_path.rstrip('/')}/{README}"
265
+ )
251
266
  model_card = str(
252
267
  read_file(
253
- file_path=(
254
- f"{artifact_path.rstrip('/')}/config/{README}"
255
- if is_verified_type
256
- else f"{artifact_path.rstrip('/')}/{README}"
257
- ),
268
+ file_path=model_card_path,
258
269
  auth=default_signer(),
259
270
  )
260
271
  )
272
+ if not model_card:
273
+ logger.warn(
274
+ f"Model card for {model_id} is empty or could not be loaded from {model_card_path}."
275
+ )
261
276
 
262
277
  inference_container = ds_model.custom_metadata_list.get(
263
278
  ModelCustomMetadataFields.DEPLOYMENT_CONTAINER,
@@ -303,9 +318,10 @@ class AquaModelApp(AquaApp):
303
318
  try:
304
319
  jobrun_ocid = ds_model.provenance_metadata.training_id
305
320
  jobrun = self.ds_client.get_job_run(jobrun_ocid).data
306
- except Exception:
321
+ except Exception as e:
307
322
  logger.debug(
308
323
  f"Missing jobrun information in the provenance metadata of the given model {model_id}."
324
+ f"\nError: {str(e)}"
309
325
  )
310
326
  jobrun = None
311
327
 
@@ -314,7 +330,10 @@ class AquaModelApp(AquaApp):
314
330
  FineTuningCustomMetadata.FT_SOURCE
315
331
  ).value
316
332
  except ValueError as e:
317
- logger.debug(str(e))
333
+ logger.debug(
334
+ f"Custom metadata is missing {FineTuningCustomMetadata.FT_SOURCE} key for "
335
+ f"model {model_id}.\nError: {str(e)}"
336
+ )
318
337
  source_id = UNKNOWN
319
338
 
320
339
  try:
@@ -322,7 +341,10 @@ class AquaModelApp(AquaApp):
322
341
  FineTuningCustomMetadata.FT_SOURCE_NAME
323
342
  ).value
324
343
  except ValueError as e:
325
- logger.debug(str(e))
344
+ logger.debug(
345
+ f"Custom metadata is missing {FineTuningCustomMetadata.FT_SOURCE_NAME} key for "
346
+ f"model {model_id}.\nError: {str(e)}"
347
+ )
326
348
  source_name = UNKNOWN
327
349
 
328
350
  source_identifier = _build_resource_identifier(
@@ -372,6 +394,7 @@ class AquaModelApp(AquaApp):
372
394
  Tags.AQUA_FINE_TUNED_MODEL_TAG, None
373
395
  )
374
396
  if is_registered_model or is_fine_tuned_model:
397
+ logger.info(f"Deleting model {model_id}.")
375
398
  return ds_model.delete()
376
399
  else:
377
400
  raise AquaRuntimeError(
@@ -478,6 +501,7 @@ class AquaModelApp(AquaApp):
478
501
  freeform_tags=freeform_tags,
479
502
  )
480
503
  AquaApp().update_model(id, update_model_details)
504
+ logger.info(f"Updated model details for the model {id}.")
481
505
  else:
482
506
  raise AquaRuntimeError("Only registered unverified models can be edited.")
483
507
 
@@ -546,6 +570,26 @@ class AquaModelApp(AquaApp):
546
570
  training_final,
547
571
  ]
548
572
 
573
+ def get_hf_tokenizer_config(self, model_id):
574
+ """Gets the default chat template for the given Aqua model.
575
+
576
+ Parameters
577
+ ----------
578
+ model_id: str
579
+ The OCID of the Aqua model.
580
+
581
+ Returns
582
+ -------
583
+ str:
584
+ Chat template string.
585
+ """
586
+ config = self.get_config(
587
+ model_id, AQUA_MODEL_TOKENIZER_CONFIG, ConfigFolder.ARTIFACT
588
+ )
589
+ if not config:
590
+ logger.debug(f"Tokenizer config for model: {model_id} is not available.")
591
+ return config
592
+
549
593
  @staticmethod
550
594
  def to_aqua_model(
551
595
  model: Union[
@@ -735,7 +779,7 @@ class AquaModelApp(AquaApp):
735
779
  )
736
780
 
737
781
  logger.info(
738
- f"Fetch {len(models)} model in compartment_id={compartment_id or ODSC_MODEL_COMPARTMENT_OCID}."
782
+ f"Fetched {len(models)} model in compartment_id={compartment_id or ODSC_MODEL_COMPARTMENT_OCID}."
739
783
  )
740
784
 
741
785
  aqua_models = []
@@ -765,10 +809,12 @@ class AquaModelApp(AquaApp):
765
809
  dict with the key used, and True if cache has the key that needs to be deleted.
766
810
  """
767
811
  res = {}
768
- logger.info("Clearing _service_models_cache")
769
812
  with self._cache_lock:
770
813
  if ODSC_MODEL_COMPARTMENT_OCID in self._service_models_cache:
771
814
  self._service_models_cache.pop(key=ODSC_MODEL_COMPARTMENT_OCID)
815
+ logger.info(
816
+ f"Cleared models cache for service compartment {ODSC_MODEL_COMPARTMENT_OCID}."
817
+ )
772
818
  res = {
773
819
  "key": {
774
820
  "compartment_id": ODSC_MODEL_COMPARTMENT_OCID,
@@ -785,10 +831,10 @@ class AquaModelApp(AquaApp):
785
831
  dict with the key used, and True if cache has the key that needs to be deleted.
786
832
  """
787
833
  res = {}
788
- logger.info(f"Clearing _service_model_details_cache for {model_id}")
789
834
  with self._cache_lock:
790
835
  if model_id in self._service_model_details_cache:
791
836
  self._service_model_details_cache.pop(key=model_id)
837
+ logger.info(f"Clearing model details cache for model {model_id}.")
792
838
  res = {"key": {"model_id": model_id}, "cache_deleted": True}
793
839
 
794
840
  return res
@@ -873,7 +919,8 @@ class AquaModelApp(AquaApp):
873
919
  metadata = ModelCustomMetadata()
874
920
  if not inference_container:
875
921
  raise AquaRuntimeError(
876
- f"Require Inference container information. Model: {model_name} does not have associated inference container defaults. Check docs for more information on how to pass inference container."
922
+ f"Require Inference container information. Model: {model_name} does not have associated inference "
923
+ f"container defaults. Check docs for more information on how to pass inference container."
877
924
  )
878
925
  metadata.add(
879
926
  key=AQUA_DEPLOYMENT_CONTAINER_METADATA_NAME,
@@ -943,24 +990,6 @@ class AquaModelApp(AquaApp):
943
990
  )
944
991
  tags[Tags.LICENSE] = validation_result.tags.get(Tags.LICENSE, UNKNOWN)
945
992
 
946
- try:
947
- # If verified model already has a artifact json, use that.
948
- artifact_path = metadata.get(MODEL_BY_REFERENCE_OSS_PATH_KEY).value
949
- logger.info(
950
- f"Found model artifact in the service bucket. "
951
- f"Using artifact from service bucket instead of {os_path}"
952
- )
953
-
954
- # todo: implement generic copy_folder method
955
- # copy model config from artifact path to user bucket
956
- copy_model_config(
957
- artifact_path=artifact_path, os_path=os_path, auth=default_signer()
958
- )
959
- except Exception:
960
- logger.debug(
961
- f"Proceeding with model registration without copying model config files at {os_path}. "
962
- f"Default configuration will be used for deployment and fine-tuning."
963
- )
964
993
  # Set artifact location to user bucket, and replace existing key if present.
965
994
  metadata.add(
966
995
  key=MODEL_BY_REFERENCE_OSS_PATH_KEY,
@@ -980,7 +1009,7 @@ class AquaModelApp(AquaApp):
980
1009
  .with_freeform_tags(**tags)
981
1010
  .with_defined_tags(**(defined_tags or {}))
982
1011
  ).create(model_by_reference=True)
983
- logger.debug(model)
1012
+ logger.debug(f"Created model catalog entry for the model:\n{model}")
984
1013
  return model
985
1014
 
986
1015
  @staticmethod
@@ -1000,13 +1029,23 @@ class AquaModelApp(AquaApp):
1000
1029
  # todo: revisit this logic to account for .bin files. In the current state, .bin and .safetensor models
1001
1030
  # are grouped in one category and validation checks for config.json files only.
1002
1031
  if model_format == ModelFormat.SAFETENSORS:
1032
+ model_files.extend(
1033
+ list_os_files_with_extension(oss_path=os_path, extension=".safetensors")
1034
+ )
1003
1035
  try:
1004
1036
  load_config(
1005
1037
  file_path=os_path,
1006
1038
  config_file_name=AQUA_MODEL_ARTIFACT_CONFIG,
1007
1039
  )
1008
- except Exception:
1009
- pass
1040
+ except Exception as ex:
1041
+ message = (
1042
+ f"The model path {os_path} does not contain the file config.json. "
1043
+ f"Please check if the path is correct or the model artifacts are available at this location."
1044
+ )
1045
+ logger.warning(
1046
+ f"{message}\n"
1047
+ f"Details: {ex.reason if isinstance(ex, AquaFileNotFoundError) else str(ex)}\n"
1048
+ )
1010
1049
  else:
1011
1050
  model_files.append(AQUA_MODEL_ARTIFACT_CONFIG)
1012
1051
 
@@ -1014,6 +1053,9 @@ class AquaModelApp(AquaApp):
1014
1053
  model_files.extend(
1015
1054
  list_os_files_with_extension(oss_path=os_path, extension=".gguf")
1016
1055
  )
1056
+ logger.debug(
1057
+ f"Fetched {len(model_files)} model files from {os_path} for model format {model_format}."
1058
+ )
1017
1059
  return model_files
1018
1060
 
1019
1061
  @staticmethod
@@ -1050,12 +1092,17 @@ class AquaModelApp(AquaApp):
1050
1092
 
1051
1093
  for model_sibling in model_siblings:
1052
1094
  extension = pathlib.Path(model_sibling.rfilename).suffix[1:].upper()
1053
- if model_format == ModelFormat.SAFETENSORS:
1054
- if model_sibling.rfilename == AQUA_MODEL_ARTIFACT_CONFIG:
1055
- model_files.append(model_sibling.rfilename)
1056
- elif extension == model_format.value:
1095
+ if (
1096
+ model_format == ModelFormat.SAFETENSORS
1097
+ and model_sibling.rfilename == AQUA_MODEL_ARTIFACT_CONFIG
1098
+ ):
1099
+ model_files.append(model_sibling.rfilename)
1100
+ if extension == model_format.value:
1057
1101
  model_files.append(model_sibling.rfilename)
1058
1102
 
1103
+ logger.debug(
1104
+ f"Fetched {len(model_files)} model files for the model {model_name} for model format {model_format}."
1105
+ )
1059
1106
  return model_files
1060
1107
 
1061
1108
  def _validate_model(
@@ -1089,7 +1136,10 @@ class AquaModelApp(AquaApp):
1089
1136
  safetensors_model_files = self.get_hf_model_files(
1090
1137
  model_name, ModelFormat.SAFETENSORS
1091
1138
  )
1092
- if safetensors_model_files:
1139
+ if (
1140
+ safetensors_model_files
1141
+ and AQUA_MODEL_ARTIFACT_CONFIG in safetensors_model_files
1142
+ ):
1093
1143
  hf_download_config_present = True
1094
1144
  gguf_model_files = self.get_hf_model_files(model_name, ModelFormat.GGUF)
1095
1145
  else:
@@ -1145,8 +1195,11 @@ class AquaModelApp(AquaApp):
1145
1195
  Tags.LICENSE: license_value,
1146
1196
  }
1147
1197
  validation_result.tags = hf_tags
1148
- except Exception:
1149
- pass
1198
+ except Exception as ex:
1199
+ logger.debug(
1200
+ f"An error occurred while getting tag information for model {model_name}. "
1201
+ f"Error: {str(ex)}"
1202
+ )
1150
1203
 
1151
1204
  validation_result.model_formats = model_formats
1152
1205
 
@@ -1201,40 +1254,55 @@ class AquaModelApp(AquaApp):
1201
1254
  model_name: str = None,
1202
1255
  ):
1203
1256
  if import_model_details.download_from_hf:
1204
- # validates config.json exists for safetensors model from hugginface
1205
- if not hf_download_config_present:
1257
+ # validates config.json exists for safetensors model from huggingface
1258
+ if not (
1259
+ hf_download_config_present
1260
+ or import_model_details.ignore_model_artifact_check
1261
+ ):
1206
1262
  raise AquaRuntimeError(
1207
1263
  f"The model {model_name} does not contain {AQUA_MODEL_ARTIFACT_CONFIG} file as required "
1208
1264
  f"by {ModelFormat.SAFETENSORS.value} format model."
1209
1265
  f" Please check if the model name is correct in Hugging Face repository."
1210
1266
  )
1267
+ validation_result.telemetry_model_name = model_name
1211
1268
  else:
1269
+ # validate if config.json is available from object storage, and get model name for telemetry
1270
+ model_config = None
1212
1271
  try:
1213
1272
  model_config = load_config(
1214
1273
  file_path=import_model_details.os_path,
1215
1274
  config_file_name=AQUA_MODEL_ARTIFACT_CONFIG,
1216
1275
  )
1217
1276
  except Exception as ex:
1218
- logger.error(
1219
- f"Exception occurred while loading config file from {import_model_details.os_path}"
1220
- f"Exception message: {ex}"
1221
- )
1222
- raise AquaRuntimeError(
1277
+ message = (
1223
1278
  f"The model path {import_model_details.os_path} does not contain the file config.json. "
1224
1279
  f"Please check if the path is correct or the model artifacts are available at this location."
1225
- ) from ex
1226
- else:
1280
+ )
1281
+ if not import_model_details.ignore_model_artifact_check:
1282
+ logger.error(
1283
+ f"{message}\n"
1284
+ f"Details: {ex.reason if isinstance(ex, AquaFileNotFoundError) else str(ex)}"
1285
+ )
1286
+ raise AquaRuntimeError(message) from ex
1287
+ else:
1288
+ logger.warning(
1289
+ f"{message}\n"
1290
+ f"Proceeding with model registration as ignore_model_artifact_check field is set."
1291
+ )
1292
+
1293
+ if verified_model:
1294
+ # model_type validation, log message if metadata field doesn't match.
1227
1295
  try:
1228
1296
  metadata_model_type = verified_model.custom_metadata_list.get(
1229
1297
  AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE
1230
1298
  ).value
1231
- if metadata_model_type:
1299
+ if metadata_model_type and model_config is not None:
1232
1300
  if AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE in model_config:
1233
1301
  if (
1234
1302
  model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE]
1235
1303
  != metadata_model_type
1236
1304
  ):
1237
- raise AquaRuntimeError(
1305
+ logger.debug(
1238
1306
  f"The {AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE} attribute in {AQUA_MODEL_ARTIFACT_CONFIG}"
1239
1307
  f" at {import_model_details.os_path} is invalid, expected {metadata_model_type} for "
1240
1308
  f"the model {model_name}. Please check if the path is correct or "
@@ -1246,22 +1314,26 @@ class AquaModelApp(AquaApp):
1246
1314
  f"Could not find {AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE} attribute in "
1247
1315
  f"{AQUA_MODEL_ARTIFACT_CONFIG}. Proceeding with model registration."
1248
1316
  )
1249
- except Exception:
1250
- pass
1251
- if verified_model:
1252
- validation_result.telemetry_model_name = verified_model.display_name
1253
- elif (
1254
- model_config is not None
1255
- and AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME in model_config
1256
- ):
1257
- validation_result.telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME]}"
1258
- elif (
1259
- model_config is not None
1260
- and AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE in model_config
1261
- ):
1262
- validation_result.telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE]}"
1263
- else:
1264
- validation_result.telemetry_model_name = AQUA_MODEL_TYPE_CUSTOM
1317
+ except Exception as ex:
1318
+ # todo: raise exception if model_type doesn't match. Currently log message and pass since service
1319
+ # models do not have this metadata.
1320
+ logger.debug(
1321
+ f"Error occurred while processing metadata for model {model_name}. "
1322
+ f"Exception: {str(ex)}"
1323
+ )
1324
+ validation_result.telemetry_model_name = verified_model.display_name
1325
+ elif (
1326
+ model_config is not None
1327
+ and AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME in model_config
1328
+ ):
1329
+ validation_result.telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_NAME]}"
1330
+ elif (
1331
+ model_config is not None
1332
+ and AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE in model_config
1333
+ ):
1334
+ validation_result.telemetry_model_name = f"{AQUA_MODEL_TYPE_CUSTOM}_{model_config[AQUA_MODEL_ARTIFACT_CONFIG_MODEL_TYPE]}"
1335
+ else:
1336
+ validation_result.telemetry_model_name = AQUA_MODEL_TYPE_CUSTOM
1265
1337
 
1266
1338
  @staticmethod
1267
1339
  def _validate_gguf_format(
@@ -1363,6 +1435,10 @@ class AquaModelApp(AquaApp):
1363
1435
  allow_patterns=allow_patterns,
1364
1436
  ignore_patterns=ignore_patterns,
1365
1437
  )
1438
+ # Upload to object storage and skip .cache/huggingface/ folder
1439
+ logger.debug(
1440
+ f"Uploading local artifacts from local directory {local_dir} to {os_path}."
1441
+ )
1366
1442
  # Upload to object storage
1367
1443
  model_artifact_path = upload_folder(
1368
1444
  os_path=os_path,
@@ -1409,6 +1485,7 @@ class AquaModelApp(AquaApp):
1409
1485
  import_model_details.model.startswith("ocid")
1410
1486
  and "datasciencemodel" in import_model_details.model
1411
1487
  ):
1488
+ logger.info(f"Fetching details for model {import_model_details.model}.")
1412
1489
  verified_model = DataScienceModel.from_id(import_model_details.model)
1413
1490
  else:
1414
1491
  # 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
@@ -1446,7 +1523,6 @@ class AquaModelApp(AquaApp):
1446
1523
  ).rstrip("/")
1447
1524
  else:
1448
1525
  artifact_path = import_model_details.os_path.rstrip("/")
1449
-
1450
1526
  # Create Model catalog entry with pass by reference
1451
1527
  ds_model = self._create_model_catalog_entry(
1452
1528
  os_path=artifact_path,
@@ -1539,7 +1615,7 @@ class AquaModelApp(AquaApp):
1539
1615
  elif model_type == ModelType.BASE:
1540
1616
  filter_tag = Tags.BASE_MODEL_CUSTOM
1541
1617
  else:
1542
- raise ValueError(
1618
+ raise AquaValueError(
1543
1619
  f"Model of type {model_type} is unknown. The values should be in {ModelType.values()}"
1544
1620
  )
1545
1621
 
@@ -1579,7 +1655,10 @@ class AquaModelApp(AquaApp):
1579
1655
  oci_model = self.ds_client.get_model(model_id).data
1580
1656
  artifact_path = get_artifact_path(oci_model.custom_metadata_list)
1581
1657
  if not artifact_path:
1582
- raise AquaRuntimeError("Failed to get artifact path from custom metadata.")
1658
+ raise AquaRuntimeError(
1659
+ f"License could not be loaded. Failed to get artifact path from custom metadata for"
1660
+ f"the model {model_id}."
1661
+ )
1583
1662
 
1584
1663
  content = str(
1585
1664
  read_file(
@@ -1610,6 +1689,9 @@ class AquaModelApp(AquaApp):
1610
1689
 
1611
1690
  for aqua_model_summary in aqua_model_list:
1612
1691
  if aqua_model_summary.name.lower() == model_id_lower:
1692
+ logger.info(
1693
+ f"Found matching verified model id {aqua_model_summary.id} for the model {model_id}"
1694
+ )
1613
1695
  return aqua_model_summary.id
1614
1696
 
1615
1697
  return None