1010import tempfile
1111from concurrent .futures import Future , ThreadPoolExecutor
1212from 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
1522from ads .opctl import logger
1623from ads .opctl .backend .base import Backend
1724from 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 )
3837from 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
4243class CondaPackNotFound (Exception ):
@@ -616,16 +617,25 @@ def _log_orchestration_message(self, str: str) -> None:
616617class 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" )
0 commit comments