Skip to content

Commit 8cc4e18

Browse files
author
Ziqun Ye
committed
ODSC-29065: extra conda slug
1 parent 3fe5738 commit 8cc4e18

File tree

3 files changed

+79
-48
lines changed

3 files changed

+79
-48
lines changed

ads/opctl/backend/ads_model_deployment.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@
44
# Copyright (c) 2022, 2023 Oracle and/or its affiliates.
55
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
66

7+
import json
78
from typing import Dict
9+
10+
from oci.data_science.models import ModelDeployment as OCIModelDeployment
11+
812
import ads
9-
from ads.common.auth import create_signer, AuthContext
13+
from ads.common.auth import AuthContext, create_signer
1014
from ads.common.oci_client import OCIClientFactory
11-
from ads.opctl.backend.base import Backend
1215
from ads.model.deployment import ModelDeployment
13-
from ads.model import GenericModel
14-
import json
15-
import os
16-
import uuid
17-
18-
from oci.data_science.models import ModelDeployment as OCIModelDeployment
16+
from ads.opctl.backend.base import Backend
1917

2018

2119
class ModelDeploymentBackend(Backend):
@@ -178,7 +176,6 @@ def watch(self) -> None:
178176
def predict(self) -> None:
179177
ocid = self.config["execution"].get("ocid")
180178
data = self.config["execution"].get("data")
181-
# if "datasciencemodeldeployment" in ocid:
182179
with AuthContext(auth=self.auth_type, profile=self.profile):
183180
model_deployment = ModelDeployment.from_id(ocid)
184181
data = json.loads(data)

ads/opctl/backend/local.py

Lines changed: 60 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,34 @@
1010
import tempfile
1111
from concurrent.futures import Future, ThreadPoolExecutor
1212
from time import sleep
13-
from typing import List, Dict
13+
from typing import Dict, List
1414

15+
from oci.data_science.models import PipelineStepRun
16+
17+
from ads.common.auth import create_signer
18+
from ads.common.decorator.runtime_dependency import (OptionalDependency,
19+
runtime_dependency)
20+
from ads.common.oci_client import OCIClientFactory
21+
from ads.model.model_metadata import ModelCustomMetadata, ModelTaxonomyMetadata
1522
from ads.opctl import logger
1623
from ads.opctl.backend.base import Backend
1724
from ads.opctl.config.resolver import ConfigResolver
18-
from ads.opctl.distributed.cmds import local_run, load_ini
19-
from ads.opctl.constants import (
20-
ML_JOB_IMAGE,
21-
ML_JOB_GPU_IMAGE,
22-
DEFAULT_IMAGE_HOME_DIR,
23-
DEFAULT_IMAGE_SCRIPT_DIR,
24-
DEFAULT_IMAGE_CONDA_DIR,
25-
DEFAULT_NOTEBOOK_SESSION_CONDA_DIR,
26-
DEFAULT_NOTEBOOK_SESSION_SPARK_CONF_DIR,
27-
)
28-
from ads.opctl.utils import get_docker_client, is_in_notebook_session
29-
from ads.opctl.utils import build_image, run_container, run_command
30-
from ads.opctl.spark.cmds import (
31-
generate_core_site_properties_str,
32-
generate_core_site_properties,
33-
)
34-
from ads.common.decorator.runtime_dependency import (
35-
runtime_dependency,
36-
OptionalDependency,
37-
)
25+
from ads.opctl.constants import (DEFAULT_IMAGE_CONDA_DIR,
26+
DEFAULT_IMAGE_HOME_DIR,
27+
DEFAULT_IMAGE_SCRIPT_DIR,
28+
DEFAULT_NOTEBOOK_SESSION_CONDA_DIR,
29+
DEFAULT_NOTEBOOK_SESSION_SPARK_CONF_DIR,
30+
ML_JOB_GPU_IMAGE, ML_JOB_IMAGE)
31+
from ads.opctl.distributed.cmds import load_ini, local_run
32+
from ads.opctl.spark.cmds import (generate_core_site_properties,
33+
generate_core_site_properties_str)
34+
from ads.opctl.utils import (build_image, get_docker_client,
35+
is_in_notebook_session, run_command,
36+
run_container)
3837
from ads.pipeline.ads_pipeline import Pipeline, PipelineStep
39-
from oci.data_science.models import PipelineStepRun
38+
from ads.model.datascience_model import DataScienceModel
39+
40+
DEFAULT_MODEL_FOLDER = "~/.ads_ops/models"
4041

4142

4243
class CondaPackNotFound(Exception):
@@ -616,16 +617,25 @@ def _log_orchestration_message(self, str: str) -> None:
616617
class LocalModelDeploymentBackend(LocalBackend):
617618
def __init__(self, config: Dict) -> None:
618619
super().__init__(config)
620+
self.oci_auth = create_signer(
621+
config["execution"].get("auth"),
622+
config["execution"].get("oci_config", None),
623+
config["execution"].get("oci_profile", None),
624+
)
625+
self.auth_type = config["execution"].get("auth")
626+
self.profile = config["execution"].get("oci_profile", None)
627+
self.client = OCIClientFactory(**self.oci_auth).data_science
619628

620629
def predict(self) -> None:
630+
621631
ocid = self.config["execution"].get("ocid")
622632
data = self.config["execution"].get("data")
633+
conda_slug, conda_path = self._get_conda_info(ocid)
623634
compartment_id = self.config["execution"].get("compartment_id", self.config["infrastructure"].get("compartment_id"))
624635
project_id = self.config["execution"].get("project_id", self.config["infrastructure"].get("project_id"))
625636
if not compartment_id or not project_id:
626637
raise ValueError("`compartment_id` and `project_id` must be provided.")
627638

628-
self.config["execution"]["image"] = ML_JOB_IMAGE
629639
extra_cmd = ocid + " " + data + " " + compartment_id + " " + project_id
630640
bind_volumes = {}
631641
if not is_in_notebook_session():
@@ -639,11 +649,14 @@ def predict(self) -> None:
639649
self.config["execution"]["source_folder"] = os.path.abspath(os.path.join(dir_path, ".."))
640650
# bind_volumes[os.path.join(dir_path, "..", "script.py")] = {"bind": script}
641651
self.config["execution"]["entrypoint"] = script
642-
if self.config["execution"].get("conda_slug", None):
643-
exit_code = self._run_with_conda_pack(bind_volumes, extra_cmd)
644-
645-
elif self.config["execution"].get("image"):
652+
if self.config["execution"].get("image"):
646653
exit_code = self._run_with_image(bind_volumes)
654+
elif self.config["execution"].get("conda_slug", conda_slug):
655+
self.config["execution"]["image"] = ML_JOB_IMAGE
656+
if not self.config["execution"].get("conda_slug"):
657+
self.config["execution"]["conda_slug"] = conda_slug
658+
self.config["execution"]["conda_path"] = conda_path
659+
exit_code = self._run_with_conda_pack(bind_volumes, extra_cmd)
647660
else:
648661
raise ValueError("Either conda pack info or image should be specified.")
649662

@@ -653,6 +666,26 @@ def predict(self) -> None:
653666
f"Run with the --debug argument to view container logs."
654667
)
655668

669+
def _download_model(self, ocid, region):
670+
dsc_model = DataScienceModel.from_id(ocid)
671+
dsc_model.download_artifact(
672+
target_dir=self.config["execution"].get("source_folder", DEFAULT_MODEL_FOLDER),
673+
force_overwrite=True,
674+
overwrite_existing_artifact=True,
675+
remove_existing_artifact=True,
676+
auth=self.oci_auth,
677+
region=region,
678+
timeout=600,
679+
bucket_urr=None,
680+
)
681+
682+
def _get_conda_info(self, ocid):
683+
response = self.client.get_model(ocid)
684+
custom_metadata = ModelCustomMetadata._from_oci_metadata(response.data.custom_metadata_list)
685+
conda_env_path = custom_metadata['CondaEnvironmentPath'].value
686+
conda_slug = custom_metadata['SlugName'].value
687+
return conda_slug, conda_env_path
688+
656689
def _run_with_image(self, bind_volumes):
657690
ocid = self.config["execution"].get("ocid")
658691
data = self.config["execution"].get("data")

ads/opctl/cmds.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -472,20 +472,21 @@ def deactivate(**kwargs) -> None:
472472
return _BackendFactory(p.config).backend.deactivate()
473473

474474

475-
def predict(**kwargs):
475+
def predict(**kwargs) -> None:
476+
"""
477+
Make prediction using the model with the payload.
478+
479+
Parameters
480+
----------
481+
kwargs: dict
482+
keyword argument, stores command line args
483+
484+
Returns
485+
-------
486+
None
487+
"""
476488
p = ConfigProcessor().step(ConfigMerger, **kwargs)
477-
# if "ocid" in p.config["execution"]:
478-
# resource_to_backend = {
479-
# DataScienceResourceRun.MODEL_DEPLOYMENT: BACKEND_NAME.MODEL_DEPLOYMENT,
480-
# DataScienceResource.MODEL: BACKEND_NAME.MODEL_DEPLOYMENT,
481-
# }
482-
# for r, b in resource_to_backend.items():
483-
# if r in p.config["execution"]["ocid"]:
484-
# p.config["execution"]["backend"] = b.value
485-
486-
# return _BackendFactory(p.config).backend.predict()
487489
if "datasciencemodeldeployment" in p.config["execution"].get("ocid", ""):
488-
489490
return ModelDeploymentBackend(p.config).predict()
490491
elif "datasciencemodel" in p.config["execution"].get("ocid", ""):
491492
return LocalModelDeploymentBackend(p.config).predict()

0 commit comments

Comments
 (0)