11#!/usr/bin/env python
2- # -*- coding: utf-8; -*-
32
4- # Copyright (c) 2021, 2023 Oracle and/or its affiliates.
3+ # Copyright (c) 2021, 2025 Oracle and/or its affiliates.
54# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
65
76
87import collections
98import copy
109import datetime
11- import oci
12- import warnings
1310import time
14- from typing import Dict , List , Union , Any
11+ import warnings
12+ from typing import Any , Dict , List , Union
1513
14+ import oci
1615import oci .loggingsearch
17- from ads .common import auth as authutil
1816import pandas as pd
19- from ads .model .serde .model_input import JsonModelInputSERDE
17+ from oci .data_science .models import (
18+ CreateModelDeploymentDetails ,
19+ LogDetails ,
20+ UpdateModelDeploymentDetails ,
21+ )
22+
23+ from ads .common import auth as authutil
24+ from ads .common import utils as ads_utils
2025from ads .common .oci_logging import (
2126 LOG_INTERVAL ,
2227 LOG_RECORDS_LIMIT ,
3035from ads .model .deployment .common .utils import send_request
3136from ads .model .deployment .model_deployment_infrastructure import (
3237 DEFAULT_BANDWIDTH_MBPS ,
38+ DEFAULT_MEMORY_IN_GBS ,
39+ DEFAULT_OCPUS ,
3340 DEFAULT_REPLICA ,
3441 DEFAULT_SHAPE_NAME ,
35- DEFAULT_OCPUS ,
36- DEFAULT_MEMORY_IN_GBS ,
3742 MODEL_DEPLOYMENT_INFRASTRUCTURE_TYPE ,
3843 ModelDeploymentInfrastructure ,
3944)
4550 ModelDeploymentRuntimeType ,
4651 OCIModelDeploymentRuntimeType ,
4752)
53+ from ads .model .serde .model_input import JsonModelInputSERDE
4854from ads .model .service .oci_datascience_model_deployment import (
4955 OCIDataScienceModelDeployment ,
5056)
51- from ads . common import utils as ads_utils
57+
5258from .common import utils
5359from .common .utils import State
5460from .model_deployment_properties import ModelDeploymentProperties
55- from oci .data_science .models import (
56- LogDetails ,
57- CreateModelDeploymentDetails ,
58- UpdateModelDeploymentDetails ,
59- )
6061
6162DEFAULT_WAIT_TIME = 1200
6263DEFAULT_POLL_INTERVAL = 10
@@ -80,6 +81,11 @@ class ModelDeploymentLogType:
8081 ACCESS = "access"
8182
8283
84+ class ModelDeploymentType :
85+ SINGLE_MODEL = "SINGLE_MODEL"
86+ MODEL_GROUP = "MODEL_GROUP"
87+
88+
8389class LogNotConfiguredError (Exception ): # pragma: no cover
8490 pass
8591
@@ -964,7 +970,9 @@ def predict(
964970 except oci .exceptions .ServiceError as ex :
965971 # When bandwidth exceeds the allocated value, TooManyRequests error (429) will be raised by oci backend.
966972 if ex .status == 429 :
967- bandwidth_mbps = self .infrastructure .bandwidth_mbps or DEFAULT_BANDWIDTH_MBPS
973+ bandwidth_mbps = (
974+ self .infrastructure .bandwidth_mbps or DEFAULT_BANDWIDTH_MBPS
975+ )
968976 utils .get_logger ().warning (
969977 f"Load balancer bandwidth exceeds the allocated { bandwidth_mbps } Mbps."
970978 "To estimate the actual bandwidth, use formula: (payload size in KB) * (estimated requests per second) * 8 / 1024."
@@ -1644,36 +1652,36 @@ def _build_model_deployment_configuration_details(self) -> Dict:
16441652 }
16451653
16461654 if infrastructure .subnet_id :
1647- instance_configuration [
1648- infrastructure .CONST_SUBNET_ID
1649- ] = infrastructure . subnet_id
1655+ instance_configuration [infrastructure . CONST_SUBNET_ID ] = (
1656+ infrastructure .subnet_id
1657+ )
16501658
16511659 if infrastructure .private_endpoint_id :
16521660 if not hasattr (
16531661 oci .data_science .models .InstanceConfiguration , "private_endpoint_id"
16541662 ):
16551663 # TODO: add oci version with private endpoint support.
1656- raise EnvironmentError (
1664+ raise OSError (
16571665 "Private endpoint is not supported in the current OCI SDK installed."
16581666 )
16591667
1660- instance_configuration [
1661- infrastructure .CONST_PRIVATE_ENDPOINT_ID
1662- ] = infrastructure . private_endpoint_id
1668+ instance_configuration [infrastructure . CONST_PRIVATE_ENDPOINT_ID ] = (
1669+ infrastructure .private_endpoint_id
1670+ )
16631671
16641672 scaling_policy = {
16651673 infrastructure .CONST_POLICY_TYPE : "FIXED_SIZE" ,
16661674 infrastructure .CONST_INSTANCE_COUNT : infrastructure .replica
16671675 or DEFAULT_REPLICA ,
16681676 }
16691677
1670- if not runtime .model_uri :
1678+ if not ( runtime .model_uri or runtime . model_group_id ) :
16711679 raise ValueError (
1672- "Missing parameter model uri. Try reruning it after model uri is configured."
1680+ "Missing parameter model uri and model group id . Try reruning it after model or model group is configured."
16731681 )
16741682
16751683 model_id = runtime .model_uri
1676- if not model_id .startswith ("ocid" ):
1684+ if model_id and not model_id .startswith ("ocid" ):
16771685 from ads .model .datascience_model import DataScienceModel
16781686
16791687 dsc_model = DataScienceModel (
@@ -1704,7 +1712,7 @@ def _build_model_deployment_configuration_details(self) -> Dict:
17041712 oci .data_science .models ,
17051713 "ModelDeploymentEnvironmentConfigurationDetails" ,
17061714 ):
1707- raise EnvironmentError (
1715+ raise OSError (
17081716 "Environment variable hasn't been supported in the current OCI SDK installed."
17091717 )
17101718
@@ -1720,9 +1728,9 @@ def _build_model_deployment_configuration_details(self) -> Dict:
17201728 and runtime .inference_server .upper ()
17211729 == MODEL_DEPLOYMENT_INFERENCE_SERVER_TRITON
17221730 ):
1723- environment_variables [
1724- "CONTAINER_TYPE"
1725- ] = MODEL_DEPLOYMENT_INFERENCE_SERVER_TRITON
1731+ environment_variables ["CONTAINER_TYPE" ] = (
1732+ MODEL_DEPLOYMENT_INFERENCE_SERVER_TRITON
1733+ )
17261734 runtime .set_spec (runtime .CONST_ENV , environment_variables )
17271735 environment_configuration_details = {
17281736 runtime .CONST_ENVIRONMENT_CONFIG_TYPE : runtime .environment_config_type ,
@@ -1734,27 +1742,45 @@ def _build_model_deployment_configuration_details(self) -> Dict:
17341742 oci .data_science .models ,
17351743 "OcirModelDeploymentEnvironmentConfigurationDetails" ,
17361744 ):
1737- raise EnvironmentError (
1745+ raise OSError (
17381746 "Container runtime hasn't been supported in the current OCI SDK installed."
17391747 )
17401748 environment_configuration_details ["image" ] = runtime .image
17411749 environment_configuration_details ["imageDigest" ] = runtime .image_digest
17421750 environment_configuration_details ["cmd" ] = runtime .cmd
17431751 environment_configuration_details ["entrypoint" ] = runtime .entrypoint
17441752 environment_configuration_details ["serverPort" ] = runtime .server_port
1745- environment_configuration_details [
1746- "healthCheckPort"
1747- ] = runtime . health_check_port
1753+ environment_configuration_details ["healthCheckPort" ] = (
1754+ runtime . health_check_port
1755+ )
17481756
17491757 model_deployment_configuration_details = {
1750- infrastructure .CONST_DEPLOYMENT_TYPE : " SINGLE_MODEL" ,
1758+ infrastructure .CONST_DEPLOYMENT_TYPE : ModelDeploymentType . SINGLE_MODEL ,
17511759 infrastructure .CONST_MODEL_CONFIG_DETAILS : model_configuration_details ,
17521760 runtime .CONST_ENVIRONMENT_CONFIG_DETAILS : environment_configuration_details ,
17531761 }
17541762
1763+ if runtime .model_group_id :
1764+ model_deployment_configuration_details [
1765+ infrastructure .CONST_DEPLOYMENT_TYPE
1766+ ] = ModelDeploymentType .MODEL_GROUP
1767+ model_deployment_configuration_details ["modelGroupConfigurationDetails" ] = {
1768+ runtime .CONST_MODEL_GROUP_ID : runtime .model_group_id
1769+ }
1770+ model_deployment_configuration_details [
1771+ "infrastructureConfigurationDetails"
1772+ ] = {
1773+ "infrastructureType" : "INSTANCE_POOL" ,
1774+ infrastructure .CONST_BANDWIDTH_MBPS : infrastructure .bandwidth_mbps
1775+ or DEFAULT_BANDWIDTH_MBPS ,
1776+ infrastructure .CONST_INSTANCE_CONFIG : instance_configuration ,
1777+ infrastructure .CONST_SCALING_POLICY : scaling_policy ,
1778+ }
1779+ model_configuration_details .pop (runtime .CONST_MODEL_ID )
1780+
17551781 if runtime .deployment_mode == ModelDeploymentMode .STREAM :
17561782 if not hasattr (oci .data_science .models , "StreamConfigurationDetails" ):
1757- raise EnvironmentError (
1783+ raise OSError (
17581784 "Model deployment mode hasn't been supported in the current OCI SDK installed."
17591785 )
17601786 model_deployment_configuration_details [
@@ -1786,9 +1812,13 @@ def _build_category_log_details(self) -> Dict:
17861812
17871813 logs = {}
17881814 if (
1789- self .infrastructure .access_log and
1790- self .infrastructure .access_log .get (self .infrastructure .CONST_LOG_GROUP_ID , None )
1791- and self .infrastructure .access_log .get (self .infrastructure .CONST_LOG_ID , None )
1815+ self .infrastructure .access_log
1816+ and self .infrastructure .access_log .get (
1817+ self .infrastructure .CONST_LOG_GROUP_ID , None
1818+ )
1819+ and self .infrastructure .access_log .get (
1820+ self .infrastructure .CONST_LOG_ID , None
1821+ )
17921822 ):
17931823 logs [self .infrastructure .CONST_ACCESS ] = {
17941824 self .infrastructure .CONST_LOG_GROUP_ID : self .infrastructure .access_log .get (
@@ -1799,9 +1829,13 @@ def _build_category_log_details(self) -> Dict:
17991829 ),
18001830 }
18011831 if (
1802- self .infrastructure .predict_log and
1803- self .infrastructure .predict_log .get (self .infrastructure .CONST_LOG_GROUP_ID , None )
1804- and self .infrastructure .predict_log .get (self .infrastructure .CONST_LOG_ID , None )
1832+ self .infrastructure .predict_log
1833+ and self .infrastructure .predict_log .get (
1834+ self .infrastructure .CONST_LOG_GROUP_ID , None
1835+ )
1836+ and self .infrastructure .predict_log .get (
1837+ self .infrastructure .CONST_LOG_ID , None
1838+ )
18051839 ):
18061840 logs [self .infrastructure .CONST_PREDICT ] = {
18071841 self .infrastructure .CONST_LOG_GROUP_ID : self .infrastructure .predict_log .get (
0 commit comments