Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 54 additions & 70 deletions ads/common/model_artifact.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8; -*-

# Copyright (c) 2020, 2023 Oracle and/or its affiliates.
# Copyright (c) 2020, 2026 Oracle and/or its affiliates.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/

import warnings
Expand All @@ -21,34 +20,46 @@
import json
import os
import re
import git
import shutil
import subprocess
import sys
import textwrap
import uuid
import python_jsonschema_objects as pjs
from enum import Enum
from pathlib import Path
from typing import Dict, Optional, Union

import ads.dataset.factory as factory
import fsspec
import git
import numpy as np
import oci.data_science
import oci.exceptions
import pandas as pd
import pkg_resources
import python_jsonschema_objects as pjs
import yaml
from oci.data_science.models import ModelProvenance

from ads.common.decorator.runtime_dependency import (
runtime_dependency,
OptionalDependency,
)
from ads.common import logger, utils
from ads.common import auth as authutil
from ads.common import logger, utils
from ads.common.data import ADSData
from ads.common.decorator.deprecate import deprecated
from ads.common.error import ChangesNotCommitted
from ads.common.object_storage_details import (
InvalidObjectStoragePath,
ObjectStorageDetails,
)
from ads.common.utils import DATA_SCHEMA_MAX_COL_NUM
from ads.config import (
JOB_RUN_COMPARTMENT_OCID,
JOB_RUN_OCID,
NB_SESSION_COMPARTMENT_OCID,
NB_SESSION_OCID,
PROJECT_OCID,
)
from ads.dataset import factory
from ads.feature_engineering.schema import DataSizeTooWide, Schema, SchemaSizeTooLarge
from ads.model.common.utils import fetch_manifest_from_conda_location
from ads.model.extractor.model_info_extractor_factory import ModelInfoExtractorFactory
from ads.model.model_introspect import (
TEST_STATUS,
Introspectable,
Expand All @@ -66,33 +77,12 @@
ModelTaxonomyMetadata,
UseCaseType,
)
from ads.common.object_storage_details import (
InvalidObjectStoragePath,
ObjectStorageDetails,
)
from ads.common.utils import DATA_SCHEMA_MAX_COL_NUM
from ads.config import (
JOB_RUN_COMPARTMENT_OCID,
JOB_RUN_OCID,
NB_SESSION_COMPARTMENT_OCID,
NB_SESSION_OCID,
PROJECT_OCID,
)
from ads.common.decorator.deprecate import deprecated
from ads.feature_engineering.schema import DataSizeTooWide, Schema, SchemaSizeTooLarge
from ads.model.extractor.model_info_extractor_factory import ModelInfoExtractorFactory
from ads.model.model_version_set import ModelVersionSet
from ads.model.common.utils import fetch_manifest_from_conda_location
from git import InvalidGitRepositoryError, Repo

from oci.data_science.models import ModelProvenance

try:
from yaml import CDumper as dumper
from yaml import CLoader as loader
except:
from yaml import Dumper as dumper
from yaml import Loader as loader

MODEL_ARTIFACT_VERSION = "3.0"
INPUT_SCHEMA_FILE_NAME = "input_schema.json"
Expand All @@ -102,7 +92,7 @@
_COMPARTMENT_OCID = NB_SESSION_COMPARTMENT_OCID or JOB_RUN_COMPARTMENT_OCID


class InvalidDataType(Exception): # pragma: no cover
class InvalidDataType(Exception): # pragma: no cover
"""Invalid Data Type."""

pass
Expand All @@ -119,7 +109,7 @@ class InvalidDataType(Exception): # pragma: no cover
"""


class ConflictStrategy(object):
class ConflictStrategy:
IGNORE = "IGNORE"
UPDATE = "UPDATE"
CREATE = "CREATE"
Expand Down Expand Up @@ -305,7 +295,7 @@ def __fetch_training_env_details(self, training_info):
os.path.join(os.path.expanduser("~"), "conda", "config.yaml")
):
with open(
(os.path.join(os.path.expanduser("~"), "conda", "config.yaml"))
os.path.join(os.path.expanduser("~"), "conda", "config.yaml")
) as conf:
user_config = yaml.load(conf, Loader=yaml.FullLoader)
pack_bucket = user_config["bucket_info"]["name"]
Expand All @@ -327,7 +317,7 @@ def __fetch_training_env_details(self, training_info):
if manifest_type == PACK_TYPE.USER_CUSTOM_PACK.value:
if self.data_science_env:
raise Exception(
f"For Published conda environments, assign the path of the environment in "
"For Published conda environments, assign the path of the environment in "
+ "Object Storage to the `inference_conda_env` parameter and set the "
+ "parameter `data_science_env` to `False`."
)
Expand All @@ -338,16 +328,15 @@ def __fetch_training_env_details(self, training_info):
)
if self.ignore_deployment_error:
logger.warn(error_message)
else:
if not self.inference_conda_env:
logger.error(error_message)
logger.info(
"Provide a URI to the conda environment that you wish to use with the model "
"deployment service if you do not want to publish the current training environment."
)
raise Exception(
f"Could not resolve the path in the Object Storage for the conda environment: {conda_prefix}"
)
elif not self.inference_conda_env:
logger.error(error_message)
logger.info(
"Provide a URI to the conda environment that you wish to use with the model "
"deployment service if you do not want to publish the current training environment."
)
raise Exception(
f"Could not resolve the path in the Object Storage for the conda environment: {conda_prefix}"
)
else:
logger.warn(
f"Could not resolve the Object Storage destination of {conda_prefix}. Correct "
Expand Down Expand Up @@ -416,15 +405,15 @@ def _generate_empty_runtime_yaml(
f"The inference conda environment is {inference_conda_env} and the Python version is {inference_python_version}."
)
if inference_conda_env:
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"][
"INFERENCE_ENV_SLUG"
] = ""
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"][
"INFERENCE_ENV_TYPE"
] = ""
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"][
"INFERENCE_ENV_PATH"
] = inference_conda_env
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"]["INFERENCE_ENV_SLUG"] = (
""
)
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"]["INFERENCE_ENV_TYPE"] = (
""
)
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"]["INFERENCE_ENV_PATH"] = (
inference_conda_env
)
if inference_python_version:
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"][
"INFERENCE_PYTHON_VERSION"
Expand Down Expand Up @@ -511,7 +500,7 @@ def _generate_runtime_yaml(self, model_file_name="model.onnx"):
if (
not self.inference_conda_env
and not self.data_science_env
and inference_info.INFERENCE_ENV_TYPE == PACK_TYPE.SERVICE_PACK.value
and PACK_TYPE.SERVICE_PACK.value == inference_info.INFERENCE_ENV_TYPE
and training_env_info.TRAINING_ENV_PATH == inference_info.INFERENCE_ENV_PATH
):
error_message = (
Expand All @@ -526,7 +515,7 @@ def _generate_runtime_yaml(self, model_file_name="model.onnx"):

if not inference_info.INFERENCE_ENV_PATH and not self.inference_conda_env:
error_message = (
f"The inference conda environment is missing. Set the `inference_conda_env` parameter "
"The inference conda environment is missing. Set the `inference_conda_env` parameter "
+ "or publish the conda environment and run the `.prepare()` method."
)
if not self.ignore_deployment_error:
Expand Down Expand Up @@ -808,7 +797,7 @@ def save(

runtime_yaml_file = os.path.join(self.artifact_dir, "runtime.yaml")
if os.path.exists(runtime_yaml_file):
with open(runtime_yaml_file, "r") as mfile:
with open(runtime_yaml_file) as mfile:
runtime_prep_info = yaml.load(mfile, Loader=yaml.FullLoader)
# runtime_info['pack-info'] = deployment_pack_info
else:
Expand Down Expand Up @@ -982,6 +971,8 @@ def install_requirements(self, conflict_strategy=ConflictStrategy.IGNORE):
IGNORE: Use the installed version in case of a conflict.
UPDATE: Force update dependency to the version required by model artifact in case of conflict.
"""
import pkg_resources

importlib.reload(pkg_resources)
from pkg_resources import DistributionNotFound, VersionConflict

Expand Down Expand Up @@ -1020,7 +1011,7 @@ def install_requirements(self, conflict_strategy=ConflictStrategy.IGNORE):
version_conflicts[
"%s==%s" % (vc.dist.key, vc.dist.parsed_version)
] = "%s%s" % (vc.req.name, vc.req.specifier)
except DistributionNotFound as dnf:
except DistributionNotFound:
pip_install(requirement)
# distributions_not_found.add('%s%s' % (dnf.req.name, dnf.req.specifier))
if len(version_conflicts) > 0:
Expand Down Expand Up @@ -1308,21 +1299,15 @@ def _populate_metadata_custom(self):
)
)
try:
env_type = (
self._runtime_info.MODEL_DEPLOYMENT.INFERENCE_CONDA_ENV.INFERENCE_ENV_TYPE._value
)
env_type = self._runtime_info.MODEL_DEPLOYMENT.INFERENCE_CONDA_ENV.INFERENCE_ENV_TYPE._value
except:
env_type = None
try:
slug_name = (
self._runtime_info.MODEL_DEPLOYMENT.INFERENCE_CONDA_ENV.INFERENCE_ENV_SLUG._value
)
slug_name = self._runtime_info.MODEL_DEPLOYMENT.INFERENCE_CONDA_ENV.INFERENCE_ENV_SLUG._value
except:
slug_name = None
try:
env_path = (
self._runtime_info.MODEL_DEPLOYMENT.INFERENCE_CONDA_ENV.INFERENCE_ENV_PATH._value
)
env_path = self._runtime_info.MODEL_DEPLOYMENT.INFERENCE_CONDA_ENV.INFERENCE_ENV_PATH._value
except:
env_path = None

Expand Down Expand Up @@ -1467,7 +1452,6 @@ def _save_from_local_file(
self._save_data_path(", ".join(oci_storage_paths), data_type)

def _save_data_path(self, oci_storage_path, data_type):

key = (
MetadataCustomKeys.TRAINING_DATASET
if data_type == "training"
Expand Down Expand Up @@ -1728,7 +1712,7 @@ def from_model_catalog(
return result_artifact


class VersionConflictWarning(object):
class VersionConflictWarning:
def __init__(self, version_conflicts):
self.version_conflicts = version_conflicts

Expand Down
18 changes: 7 additions & 11 deletions ads/common/model_export_util.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8; -*-

# Copyright (c) 2020, 2023 Oracle and/or its affiliates.
# Copyright (c) 2020, 2026 Oracle and/or its affiliates.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
import warnings

Expand All @@ -15,35 +14,30 @@
stacklevel=2,
)

import json
import logging
import os
import sys
from typing import Any, Dict, Union
from typing import Any, Union

import cloudpickle
import numpy as np
import pandas as pd

from ads.common import logger, utils
from ads.common.data import ADSData
from ads.common.decorator.deprecate import deprecated
from ads.common.decorator.runtime_dependency import (
OptionalDependency,
runtime_dependency,
)
from ads.common.decorator.deprecate import deprecated
from ads.common.function.fn_util import (
generate_fn_artifacts,
get_function_config,
write_score,
)
from ads.common.model_artifact import ModelArtifact
from ads.model.model_metadata import UseCaseType
from ads.feature_engineering.schema import DataSizeTooWide
from pkg_resources import DistributionNotFound, get_distribution

from ads.model.transformer.onnx_transformer import (
ONNXTransformer,
) # Do not remove this line till ADS 3.0 wll be deployed.
from ads.model.model_metadata import UseCaseType

pd.options.mode.chained_assignment = None

Expand Down Expand Up @@ -232,6 +226,8 @@ def prepare_generic_model(
max_col_num = kwargs.get("max_col_num", utils.DATA_SCHEMA_MAX_COL_NUM)
artifact_type_generic = progress is not None

from pkg_resources import DistributionNotFound, get_distribution

from ads.common.model import ADSModel

if isinstance(model, ADSModel) and underlying_model != "automl":
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ dependencies = [
"numpy>=1.19.2",
"oci>=2.148.0",
"ocifs>=1.1.3",
"pandas>=2.2.0",
"pandas>=2.2.0,<3.0.0",
"psutil>=5.7.2",
"python_jsonschema_objects>=0.3.13",
"requests",
Expand Down
Loading