Skip to content
Open
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
102 changes: 102 additions & 0 deletions ads/model/datascience_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
ModelProvenanceNotFoundError,
OCIDataScienceModel,
)
from ads.model.service.oci_datascience_model_artifact_signature import (
DataScienceModelArtifactSignature,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -1390,6 +1393,105 @@ def upload_artifact(

self._remove_file_description_artifact()

def create_model_artifact_signature(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, the same approach as we did for the version set can be used here.

self,
kms_key_id: str,
kms_key_version_id: str,
signing_algorithm: str,
compartment_id: Optional[str] = None,
display_name: Optional[str] = None,
freeform_tags: Optional[Dict[str, str]] = None,
defined_tags: Optional[Dict[str, Dict[str, object]]] = None,
**kwargs: Dict,
):
"""Creates a model artifact signature for this model."""
return DataScienceModelArtifactSignature.from_model(self.dsc_model).create(
kms_key_id=kms_key_id,
kms_key_version_id=kms_key_version_id,
signing_algorithm=signing_algorithm,
compartment_id=compartment_id,
display_name=display_name,
freeform_tags=freeform_tags,
defined_tags=defined_tags,
**kwargs,
)

def list_model_artifact_signatures(
self,
compartment_id: Optional[str] = None,
**kwargs: Dict,
) -> List:
"""Lists model artifact signatures for this model."""
return DataScienceModelArtifactSignature.from_model(self.dsc_model).list(
compartment_id=compartment_id,
**kwargs,
)

def get_model_artifact_signature(
self,
artifact_signature_id: str,
**kwargs: Dict,
):
"""Gets a model artifact signature for this model."""
return DataScienceModelArtifactSignature.from_model(self.dsc_model).get(
artifact_signature_id=artifact_signature_id,
**kwargs,
)

def update_model_artifact_signature(
self,
artifact_signature_id: str,
display_name: Optional[str] = None,
freeform_tags: Optional[Dict[str, str]] = None,
defined_tags: Optional[Dict[str, Dict[str, object]]] = None,
**kwargs: Dict,
):
"""Updates a model artifact signature for this model."""
return DataScienceModelArtifactSignature.from_model(self.dsc_model).update(
artifact_signature_id=artifact_signature_id,
display_name=display_name,
freeform_tags=freeform_tags,
defined_tags=defined_tags,
**kwargs,
)

def delete_model_artifact_signature(
self,
artifact_signature_id: str,
**kwargs: Dict,
) -> None:
"""Deletes a model artifact signature for this model."""
DataScienceModelArtifactSignature.from_model(self.dsc_model).delete(
artifact_signature_id=artifact_signature_id,
**kwargs,
)

def change_model_artifact_signature_compartment(
self,
artifact_signature_id: str,
compartment_id: str,
**kwargs: Dict,
) -> None:
"""Moves a model artifact signature to another compartment."""
DataScienceModelArtifactSignature.from_model(
self.dsc_model
).change_compartment(
artifact_signature_id=artifact_signature_id,
compartment_id=compartment_id,
**kwargs,
)

def verify_model_artifact_signature(
self,
artifact_signature_id: str,
**kwargs: Dict,
):
"""Verifies a model artifact signature for this model."""
return DataScienceModelArtifactSignature.from_model(self.dsc_model).verify(
artifact_signature_id=artifact_signature_id,
**kwargs,
)

def _remove_file_description_artifact(self):
"""Removes temporary model file description artifact for model by reference."""
# delete if local copy directory was created
Expand Down
29 changes: 29 additions & 0 deletions ads/model/deployment/model_deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -1817,6 +1817,35 @@ def _drop_none_values(d: Dict) -> Dict:
infrastructure.CONST_SCALING_POLICY: scaling_policy,
}

if runtime.model_artifact_signature_id:
if runtime.model_group_id:
raise ValueError(
"`model_artifact_signature_id` is supported only for single-model deployments."
)
model_configuration_details_cls = getattr(
oci.data_science.models, "ModelConfigurationDetails", None
)
update_model_configuration_details_cls = getattr(
oci.data_science.models, "UpdateModelConfigurationDetails", None
)
if not (
model_configuration_details_cls
and update_model_configuration_details_cls
and hasattr(
model_configuration_details_cls(), "model_artifact_signature_id"
)
and hasattr(
update_model_configuration_details_cls(),
"model_artifact_signature_id",
)
):
raise OSError(
"Model artifact signature is not supported in the installed OCI SDK."
)
model_configuration_details[
runtime.CONST_MODEL_ARTIFACT_SIGNATURE_ID
] = runtime.model_artifact_signature_id

if runtime.env:
if not hasattr(
oci.data_science.models,
Expand Down
78 changes: 76 additions & 2 deletions ads/model/deployment/model_deployment_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class ModelDeploymentProperties(
The model artifact OCID in model catalog.
model_uri : str
uri to model files, can be local or in cloud storage.
model_artifact_signature_id : str
The OCID of the model artifact signature to use for model deployment.

Methods
-------
Expand Down Expand Up @@ -88,12 +90,14 @@ class ModelDeploymentProperties(
"predict_log_id",
"memory_in_gbs",
"ocpus",
"model_artifact_signature_id",
]

def __init__(
self,
model_id: Optional[str] = None,
model_uri: Optional[str] = None,
model_artifact_signature_id: Optional[str] = None,
oci_model_deployment: Union[
data_science_models.ModelDeployment,
data_science_models.CreateModelDeploymentDetails,
Expand All @@ -112,6 +116,8 @@ def __init__(
explicitly or as an attribute of the OCI object.
model_uri: (str, optiona). Defaults to None.
Uri to model files, can be local or in cloud storage.
model_artifact_signature_id: (str, optional). Defaults to None.
Model artifact signature OCID.
oci_model_deployment: (Union[ModelDeployment, CreateModelDeploymentDetails, UpdateModelDeploymentDetails, Dict], optional). Defaults to None.
An OCI model or Dict containing model deployment details.
The OCI model can be an instance of either `ModelDeployment`,
Expand Down Expand Up @@ -148,7 +154,8 @@ def __init__(
- `predict_log_group_id`,
- `predict_log_id`,
- `memory_in_gbs`,
- `ocpus`.
- `ocpus`,
- `model_artifact_signature_id`.

These additional arguments will be saved into appropriate properties
in the OCI model.
Expand All @@ -166,6 +173,7 @@ def __init__(

self.model_id = model_id
self.model_uri = model_uri
self.model_artifact_signature_id = model_artifact_signature_id

oci_kwargs = {}
self.oci_model_deployment = oci_model_deployment
Expand Down Expand Up @@ -208,6 +216,18 @@ def __init__(
if self.model_id:
self._config_model_id()

# Get model artifact signature ID from OCI object
if self.model_artifact_signature_id is None:
try:
self.model_artifact_signature_id = (
self.model_deployment_configuration_details.model_configuration_details.model_artifact_signature_id
)
except AttributeError:
self.model_artifact_signature_id = None

if self.model_artifact_signature_id:
self._config_model_artifact_signature_id()

# Process additional kwargs
# Convert all keys to lower case
kwargs = {str(k).lower(): v for k, v in kwargs.items()}
Expand All @@ -229,6 +249,7 @@ def __init__(
"bandwidth_mbps",
"memory_in_gbs",
"ocpus",
"model_artifact_signature_id",
# Autoscaling-related keys.
"scaling_type",
"cpu_utilization",
Expand Down Expand Up @@ -276,7 +297,8 @@ def with_instance_configuration(self, config):
- instance_count: int,
- bandwidth_mbps: int,
- memory_in_gbs: float,
- ocpus: float
- ocpus: float,
- model_artifact_signature_id: str

In addition, this method supports autoscaling for SINGLE_MODEL deployments.
To enable autoscaling, set `scaling_type` to one of:
Expand Down Expand Up @@ -314,6 +336,16 @@ def with_instance_configuration(self, config):
data_science_models.ModelConfigurationDetails()
)
model_configuration_details_object.model_id = self.model_id
model_artifact_signature_id = (
config.get("model_artifact_signature_id")
or self.model_artifact_signature_id
)
if model_artifact_signature_id:
self._validate_model_artifact_signature_sdk_support()
self.model_artifact_signature_id = model_artifact_signature_id
model_configuration_details_object.model_artifact_signature_id = (
model_artifact_signature_id
)

# instance_configuration is required even though it can be initialized with empty values
instance_configuration_object = data_science_models.InstanceConfiguration()
Expand Down Expand Up @@ -566,6 +598,46 @@ def _config_model_id(self):
else:
self.with_instance_configuration({})

def _validate_model_artifact_signature_sdk_support(self):
"""Validates the installed OCI SDK supports model artifact signature fields."""
model_configuration_details_cls = getattr(
data_science_models, "ModelConfigurationDetails", None
)
update_model_configuration_details_cls = getattr(
data_science_models, "UpdateModelConfigurationDetails", None
)
if not (
model_configuration_details_cls
and update_model_configuration_details_cls
and hasattr(
model_configuration_details_cls(), "model_artifact_signature_id"
)
and hasattr(
update_model_configuration_details_cls(),
"model_artifact_signature_id",
)
):
raise EnvironmentError(
"Model artifact signature is not supported in the installed OCI SDK."
)

def _config_model_artifact_signature_id(self):
"""Sets the model artifact signature ID in model configuration details."""
self._validate_model_artifact_signature_sdk_support()

if (
self.model_deployment_configuration_details
and self.model_deployment_configuration_details.model_configuration_details
):
model_configuration_details = (
self.model_deployment_configuration_details.model_configuration_details
)
model_configuration_details.model_artifact_signature_id = (
self.model_artifact_signature_id
)
else:
self.with_instance_configuration({})

def to_oci_model(self, oci_model):
"""Convert properties into an OCI data model

Expand All @@ -577,6 +649,8 @@ def to_oci_model(self, oci_model):
"""
if self.model_id:
self._config_model_id()
if self.model_artifact_signature_id:
self._config_model_artifact_signature_id()

return super().to_oci_model(oci_model)

Expand Down
Loading
Loading