Skip to content

Commit f6604b1

Browse files
authored
Deprecated ModelDeploymentProperties and ModelDeployer classes (#221)
2 parents f46439d + 147f6c4 commit f6604b1

File tree

9 files changed

+204
-55
lines changed

9 files changed

+204
-55
lines changed

ads/model/deployment/model_deployer.py

+10
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@
5151
from .model_deployment import DEFAULT_POLL_INTERVAL, DEFAULT_WAIT_TIME, ModelDeployment
5252
from .model_deployment_properties import ModelDeploymentProperties
5353

54+
warnings.warn(
55+
(
56+
"The `ads.model.deployment.model_deployer` is deprecated in `oracle-ads 2.8.6` and will be removed in `oracle-ads 3.0`."
57+
"Use `ModelDeployment` class in `ads.model.deployment` module for initializing and deploying model deployment. "
58+
"Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/introduction.html"
59+
),
60+
DeprecationWarning,
61+
stacklevel=2,
62+
)
63+
5464

5565
class ModelDeployer:
5666
"""ModelDeployer is the class responsible for deploying the ModelDeployment

ads/model/deployment/model_deployment.py

+79-6
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@
7070
MODEL_DEPLOYMENT_INSTANCE_COUNT = 1
7171
MODEL_DEPLOYMENT_BANDWIDTH_MBPS = 10
7272

73+
MODEL_DEPLOYMENT_RUNTIMES = {
74+
ModelDeploymentRuntimeType.CONDA: ModelDeploymentCondaRuntime,
75+
ModelDeploymentRuntimeType.CONTAINER: ModelDeploymentContainerRuntime,
76+
}
77+
7378

7479
class ModelDeploymentLogType:
7580
PREDICT = "predict"
@@ -295,17 +300,20 @@ def __init__(
295300

296301
if config:
297302
warnings.warn(
298-
"`config` will be deprecated in 3.0.0 and will be ignored now. Please use `ads.set_auth()` to config the auth information."
303+
"Parameter `config` was deprecated in 2.8.2 from ModelDeployment constructor and will be removed in 3.0.0. Please use `ads.set_auth()` to config the auth information. "
304+
"Check: https://accelerated-data-science.readthedocs.io/en/latest/user_guide/cli/authentication.html"
299305
)
300306

301307
if properties:
302308
warnings.warn(
303-
"`properties` will be deprecated in 3.0.0. Please use `spec` or the builder pattern to initialize model deployment instance."
309+
"Parameter `properties` was deprecated in 2.8.2 from ModelDeployment constructor and will be removed in 3.0.0. Please use `spec` or the builder pattern to initialize model deployment instance. "
310+
"Check: https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html"
304311
)
305312

306313
if model_deployment_url or model_deployment_id:
307314
warnings.warn(
308-
"`model_deployment_url` and `model_deployment_id` will be deprecated in 3.0.0 and will be ignored now. These two fields will be auto-populated from the service side."
315+
"Parameter `model_deployment_url` and `model_deployment_id` were deprecated in 2.8.2 from ModelDeployment constructor and will be removed in 3.0.0. These two fields will be auto-populated from the service side. "
316+
"Check: https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html"
309317
)
310318

311319
initialize_spec = {}
@@ -697,6 +705,12 @@ def update(
697705
ModelDeployment
698706
The instance of ModelDeployment.
699707
"""
708+
if properties:
709+
warnings.warn(
710+
"Parameter `properties` is deprecated from ModelDeployment `update()` in 2.8.6 and will be removed in 3.0.0. Please use the builder pattern or kwargs to update model deployment instance. "
711+
"Check: https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html"
712+
)
713+
700714
updated_properties = properties
701715
if not isinstance(properties, ModelDeploymentProperties):
702716
updated_properties = ModelDeploymentProperties(
@@ -706,7 +720,7 @@ def update(
706720
update_model_deployment_details = (
707721
updated_properties.to_update_deployment()
708722
if properties or updated_properties.oci_model_deployment or kwargs
709-
else self._update_model_deployment_details()
723+
else self._update_model_deployment_details(**kwargs)
710724
)
711725

712726
response = self.dsc_model_deployment.update(
@@ -1490,7 +1504,7 @@ def _build_model_deployment_details(self) -> CreateModelDeploymentDetails:
14901504
**create_model_deployment_details
14911505
).to_oci_model(CreateModelDeploymentDetails)
14921506

1493-
def _update_model_deployment_details(self) -> UpdateModelDeploymentDetails:
1507+
def _update_model_deployment_details(self, **kwargs) -> UpdateModelDeploymentDetails:
14941508
"""Builds UpdateModelDeploymentDetails from model deployment instance.
14951509
14961510
Returns
@@ -1502,7 +1516,7 @@ def _update_model_deployment_details(self) -> UpdateModelDeploymentDetails:
15021516
raise ValueError(
15031517
"Missing parameter runtime or infrastructure. Try reruning it after parameters are fully configured."
15041518
)
1505-
1519+
self._update_spec(**kwargs)
15061520
update_model_deployment_details = {
15071521
self.CONST_DISPLAY_NAME: self.display_name,
15081522
self.CONST_DESCRIPTION: self.description,
@@ -1514,6 +1528,65 @@ def _update_model_deployment_details(self) -> UpdateModelDeploymentDetails:
15141528
return OCIDataScienceModelDeployment(
15151529
**update_model_deployment_details
15161530
).to_oci_model(UpdateModelDeploymentDetails)
1531+
1532+
def _update_spec(self, **kwargs) -> "ModelDeployment":
1533+
"""Updates model deployment specs from kwargs.
1534+
1535+
Parameters
1536+
----------
1537+
kwargs:
1538+
display_name: (str)
1539+
Model deployment display name
1540+
description: (str)
1541+
Model deployment description
1542+
freeform_tags: (dict)
1543+
Model deployment freeform tags
1544+
defined_tags: (dict)
1545+
Model deployment defined tags
1546+
1547+
Additional kwargs arguments.
1548+
Can be any attribute that `ads.model.deployment.ModelDeploymentCondaRuntime`, `ads.model.deployment.ModelDeploymentContainerRuntime`
1549+
and `ads.model.deployment.ModelDeploymentInfrastructure` accepts.
1550+
1551+
Returns
1552+
-------
1553+
ModelDeployment
1554+
The instance of ModelDeployment.
1555+
"""
1556+
if not kwargs:
1557+
return self
1558+
1559+
converted_specs = ads_utils.batch_convert_case(kwargs, "camel")
1560+
specs = {
1561+
"self": self._spec,
1562+
"runtime": self.runtime._spec,
1563+
"infrastructure": self.infrastructure._spec
1564+
}
1565+
sub_set = {
1566+
self.infrastructure.CONST_ACCESS_LOG,
1567+
self.infrastructure.CONST_PREDICT_LOG,
1568+
self.infrastructure.CONST_SHAPE_CONFIG_DETAILS
1569+
}
1570+
for spec_value in specs.values():
1571+
for key in spec_value:
1572+
if key in converted_specs:
1573+
if key in sub_set:
1574+
for sub_key in converted_specs[key]:
1575+
converted_sub_key = ads_utils.snake_to_camel(sub_key)
1576+
spec_value[key][converted_sub_key] = converted_specs[key][sub_key]
1577+
else:
1578+
spec_value[key] = copy.deepcopy(converted_specs[key])
1579+
self = (
1580+
ModelDeployment(spec=specs["self"])
1581+
.with_runtime(
1582+
MODEL_DEPLOYMENT_RUNTIMES[self.runtime.type](spec=specs["runtime"])
1583+
)
1584+
.with_infrastructure(
1585+
ModelDeploymentInfrastructure(spec=specs["infrastructure"])
1586+
)
1587+
)
1588+
1589+
return self
15171590

15181591
def _build_model_deployment_configuration_details(self) -> Dict:
15191592
"""Builds model deployment configuration details from model deployment instance.

ads/model/deployment/model_deployment_properties.py

+12
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@
1212

1313
from .common.utils import OCIClientManager
1414

15+
import warnings
16+
17+
warnings.warn(
18+
(
19+
"The `ads.model.deployment.model_deployment_properties` is deprecated in `oracle-ads 2.8.6` and will be removed in `oracle-ads 3.0`."
20+
"Use `ModelDeploymentInfrastructure` and `ModelDeploymentRuntime` classes in `ads.model.deployment` module for configuring model deployment. "
21+
"Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/introduction.html"
22+
),
23+
DeprecationWarning,
24+
stacklevel=2,
25+
)
26+
1527

1628
class ModelDeploymentProperties(
1729
OCIDataScienceMixin, data_science_models.ModelDeployment

ads/model/generic_model.py

+33-20
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import tempfile
1111
from enum import Enum
1212
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, TypeVar, Union
13+
import warnings
1314

1415
import numpy as np
1516
import pandas as pd
@@ -44,7 +45,6 @@
4445
from ads.model.deployment import (
4546
DEFAULT_POLL_INTERVAL,
4647
DEFAULT_WAIT_TIME,
47-
ModelDeployer,
4848
ModelDeployment,
4949
ModelDeploymentMode,
5050
ModelDeploymentProperties,
@@ -299,12 +299,12 @@ class GenericModel(MetadataMixin, Introspectable, EvaluatorMixin):
299299
>>> model.deploy()
300300
>>> # Update access log id, freeform tags and description for the model deployment
301301
>>> model.update_deployment(
302-
>>> properties=ModelDeploymentProperties(
303-
>>> access_log_id=<log_ocid>,
304-
>>> description="Description for Custom Model",
305-
>>> freeform_tags={"key": "value"},
306-
>>> )
307-
>>> )
302+
... access_log={
303+
... log_id=<log_ocid>
304+
... },
305+
... description="Description for Custom Model",
306+
... freeform_tags={"key": "value"},
307+
... )
308308
>>> model.predict(2)
309309
>>> # Uncomment the line below to delete the model and the associated model deployment
310310
>>> # model.delete(delete_associated_model_deployment = True)
@@ -1565,9 +1565,7 @@ def from_model_deployment(
15651565
"Only SparkPipelineModel framework supports object storage path as `artifact_dir`."
15661566
)
15671567

1568-
model_deployment = ModelDeployer(config=auth).get_model_deployment(
1569-
model_deployment_id=model_deployment_id
1570-
)
1568+
model_deployment = ModelDeployment.from_id(model_deployment_id)
15711569

15721570
current_state = model_deployment.state.name.upper()
15731571
if current_state != ModelDeploymentState.ACTIVE.name:
@@ -1619,12 +1617,12 @@ def update_deployment(
16191617
--------
16201618
>>> # Update access log id, freeform tags and description for the model deployment
16211619
>>> model.update_deployment(
1622-
>>> properties=ModelDeploymentProperties(
1623-
>>> access_log_id=<log_ocid>,
1624-
>>> description="Description for Custom Model",
1625-
>>> freeform_tags={"key": "value"},
1626-
>>> )
1627-
>>> )
1620+
... access_log={
1621+
... log_id=<log_ocid>
1622+
... },
1623+
... description="Description for Custom Model",
1624+
... freeform_tags={"key": "value"},
1625+
... )
16281626
16291627
Parameters
16301628
----------
@@ -1647,12 +1645,30 @@ def update_deployment(
16471645
If you need to override the default, use the `ads.common.auth.api_keys` or
16481646
`ads.common.auth.resource_principal` to create appropriate authentication signer
16491647
and kwargs required to instantiate IdentityClient object.
1648+
display_name: (str)
1649+
Model deployment display name
1650+
description: (str)
1651+
Model deployment description
1652+
freeform_tags: (dict)
1653+
Model deployment freeform tags
1654+
defined_tags: (dict)
1655+
Model deployment defined tags
1656+
1657+
Additional kwargs arguments.
1658+
Can be any attribute that `ads.model.deployment.ModelDeploymentCondaRuntime`, `ads.model.deployment.ModelDeploymentContainerRuntime`
1659+
and `ads.model.deployment.ModelDeploymentInfrastructure` accepts.
16501660
16511661
Returns
16521662
-------
16531663
ModelDeployment
16541664
An instance of ModelDeployment class.
16551665
"""
1666+
if properties:
1667+
warnings.warn(
1668+
"Parameter `properties` is deprecated from GenericModel `update_deployment()` in 2.8.6 and will be removed in 3.0.0. Please use kwargs to update model deployment. "
1669+
"Check: https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/introduction.html"
1670+
)
1671+
16561672
if not inspect.isclass(cls):
16571673
if cls.model_deployment:
16581674
return cls.model_deployment.update(
@@ -1666,10 +1682,7 @@ def update_deployment(
16661682
if not model_deployment_id:
16671683
raise ValueError("Parameter `model_deployment_id` must be provided.")
16681684

1669-
auth = kwargs.pop("auth", authutil.default_signer())
1670-
model_deployment = ModelDeployer(config=auth).get_model_deployment(
1671-
model_deployment_id=model_deployment_id
1672-
)
1685+
model_deployment = ModelDeployment.from_id(model_deployment_id)
16731686
return model_deployment.update(
16741687
properties=properties,
16751688
wait_for_completion=wait_for_completion,

ads/model/service/oci_datascience_model.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from ads.common.oci_mixin import OCIWorkRequestMixin
1818
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
1919
from ads.common.utils import extract_region
20-
from ads.model.deployment.model_deployer import ModelDeployer
20+
from ads.model.deployment import ModelDeployment
2121
from oci.data_science.models import (
2222
ArtifactExportDetailsObjectStorage,
2323
ArtifactImportDetailsObjectStorage,
@@ -469,9 +469,7 @@ def delete(
469469
logger.info(
470470
f"Deleting model deployment `{oci_model_deployment.identifier}`."
471471
)
472-
ModelDeployer(ds_client=self.client).delete(
473-
model_deployment_id=oci_model_deployment.identifier
474-
)
472+
ModelDeployment.from_id(oci_model_deployment.identifier).delete()
475473

476474
logger.info(f"Deleting model `{self.id}`.")
477475
self.client.delete_model(self.id)

docs/source/user_guide/model_registration/model_deploy.rst

+7-7
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,10 @@ You can update the existing Model Deployment by using ``.update_deployment()`` m
106106
.. code-block:: python3
107107
108108
lightgbm_model.update_deployment(
109-
properties=ModelDeploymentProperties(
110-
access_log_id="ocid1.log.oc1.xxx.xxxxx",
111-
description="Description for Custom Model",
112-
freeform_tags={"key": "value"},
113-
)
114-
wait_for_completion = True,
115-
)
109+
wait_for_completion = True,
110+
access_log={
111+
log_id="ocid1.log.oc1.xxx.xxxxx",
112+
},
113+
description="Description for Custom Model",
114+
freeform_tags={"key": "value"},
115+
)

tests/unitary/default_setup/model/test_oci_datascience_model.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
2525
from ads.dataset.progress import TqdmProgressBar
2626
from ads.model.datascience_model import _MAX_ARTIFACT_SIZE_IN_BYTES
27-
from ads.model.deployment.model_deployer import ModelDeployer
2827
from ads.model.service.oci_datascience_model import (
2928
ModelArtifactNotFoundError,
3029
ModelProvenanceNotFoundError,
@@ -230,10 +229,10 @@ def test_delete_success(self, mock_client):
230229
mock_model_deployment.return_value = [
231230
MagicMock(lifecycle_state="ACTIVE", identifier="md_id")
232231
]
233-
with patch.object(ModelDeployer, "delete") as mock_md_delete:
232+
with patch("ads.model.deployment.ModelDeployment.from_id") as mock_from_id:
234233
with patch.object(OCIDataScienceModel, "sync") as mock_sync:
235234
self.mock_model.delete(delete_associated_model_deployment=True)
236-
mock_md_delete.assert_called_with(model_deployment_id="md_id")
235+
mock_from_id.assert_called_with("md_id")
237236
mock_client.delete_model.assert_called_with(self.mock_model.id)
238237
mock_sync.assert_called()
239238

tests/unitary/default_setup/model_deployment/test_model_deployment_v2.py

+44
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,50 @@ def test_model_deployment_with_subnet_id(self):
13821382
model_deployment.infrastructure.with_subnet_id("test_id")
13831383
assert model_deployment.infrastructure.subnet_id == "test_id"
13841384

1385+
def test_update_spec(self):
1386+
model_deployment = self.initialize_model_deployment()
1387+
model_deployment._update_spec(
1388+
display_name="test_updated_name",
1389+
freeform_tags={"test_updated_key":"test_updated_value"},
1390+
access_log={
1391+
"log_id": "test_updated_access_log_id"
1392+
},
1393+
predict_log={
1394+
"log_group_id": "test_updated_predict_log_group_id"
1395+
},
1396+
shape_config_details={
1397+
"ocpus": 100,
1398+
"memoryInGBs": 200
1399+
},
1400+
replica=20,
1401+
image="test_updated_image",
1402+
env={
1403+
"test_updated_env_key":"test_updated_env_value"
1404+
}
1405+
)
1406+
1407+
assert model_deployment.display_name == "test_updated_name"
1408+
assert model_deployment.freeform_tags == {
1409+
"test_updated_key":"test_updated_value"
1410+
}
1411+
assert model_deployment.infrastructure.access_log == {
1412+
"logId": "test_updated_access_log_id",
1413+
"logGroupId": "fakeid.loggroup.oc1.iad.xxx"
1414+
}
1415+
assert model_deployment.infrastructure.predict_log == {
1416+
"logId": "fakeid.log.oc1.iad.xxx",
1417+
"logGroupId": "test_updated_predict_log_group_id"
1418+
}
1419+
assert model_deployment.infrastructure.shape_config_details == {
1420+
"ocpus": 100,
1421+
"memoryInGBs": 200
1422+
}
1423+
assert model_deployment.infrastructure.replica == 20
1424+
assert model_deployment.runtime.image == "test_updated_image"
1425+
assert model_deployment.runtime.env == {
1426+
"test_updated_env_key":"test_updated_env_value"
1427+
}
1428+
13851429
@patch.object(OCIDataScienceMixin, "sync")
13861430
@patch.object(
13871431
oci.data_science.DataScienceClient,

0 commit comments

Comments
 (0)