Skip to content

Commit d385e8f

Browse files
authored
Merge branch 'develop' into ODSC-40043/dataflow_archive
2 parents b5a6c4d + 4354d5f commit d385e8f

File tree

7 files changed

+156
-191
lines changed

7 files changed

+156
-191
lines changed

ads/model/deployment/model_deployment.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,9 @@ def _build_model_deployment_configuration_details(self) -> Dict:
15381538
or MODEL_DEPLOYMENT_INSTANCE_MEMORY_IN_GBS,
15391539
}
15401540

1541+
if infrastructure.subnet_id:
1542+
instance_configuration[infrastructure.CONST_SUBNET_ID] = infrastructure.subnet_id
1543+
15411544
scaling_policy = {
15421545
infrastructure.CONST_POLICY_TYPE: "FIXED_SIZE",
15431546
infrastructure.CONST_INSTANCE_COUNT: infrastructure.replica

ads/model/deployment/model_deployment_infrastructure.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class ModelDeploymentInfrastructure(Builder):
3939
The access and predict log id of model deployment
4040
web_concurrency: int
4141
The web concurrency of model deployment
42+
subnet_id: str
43+
The subnet id of model deployment
4244
4345
Methods
4446
-------
@@ -64,6 +66,8 @@ class ModelDeploymentInfrastructure(Builder):
6466
Sets the access and predict log id of model deployment
6567
with_web_concurrency(web_concurrency)
6668
Sets the web concurrency of model deployment
69+
with_subnet_id(subnet_id)
70+
Sets the subnet id of model deployment
6771
6872
Example
6973
-------
@@ -79,6 +83,7 @@ class ModelDeploymentInfrastructure(Builder):
7983
... .with_replica(1)
8084
... .with_bandwidth_mbps(10)
8185
... .with_web_concurrency(10)
86+
... .with_subnet_id(<subnet_id>)
8287
... .with_access_log(
8388
... log_group_id=<log_group_id>,
8489
... log_id=<log_id>
@@ -121,6 +126,7 @@ class ModelDeploymentInfrastructure(Builder):
121126
CONST_LOG_GROUP_ID = "logGroupId"
122127
CONST_WEB_CONCURRENCY = "webConcurrency"
123128
CONST_STREAM_CONFIG_DETAILS = "streamConfigurationDetails"
129+
CONST_SUBNET_ID = "subnetId"
124130

125131
attribute_map = {
126132
CONST_PROJECT_ID: "project_id",
@@ -136,6 +142,7 @@ class ModelDeploymentInfrastructure(Builder):
136142
CONST_LOG_ID: "log_id",
137143
CONST_LOG_GROUP_ID: "log_group_id",
138144
CONST_WEB_CONCURRENCY: "web_concurrency",
145+
CONST_SUBNET_ID: "subnet_id"
139146
}
140147

141148
shape_config_details_attribute_map = {
@@ -162,6 +169,7 @@ class ModelDeploymentInfrastructure(Builder):
162169
CONST_COMPARTMENT_ID: "compartment_id",
163170
CONST_SHAPE_NAME: f"{MODEL_CONFIG_DETAILS_PATH}.instance_configuration.instance_shape_name",
164171
CONST_SHAPE_CONFIG_DETAILS: f"{MODEL_CONFIG_DETAILS_PATH}.instance_configuration.model_deployment_instance_shape_config_details",
172+
CONST_SUBNET_ID: f"{MODEL_CONFIG_DETAILS_PATH}.instance_configuration.subnet_id",
165173
CONST_REPLICA: f"{MODEL_CONFIG_DETAILS_PATH}.scaling_policy.instance_count",
166174
CONST_BANDWIDTH_MBPS: f"{MODEL_CONFIG_DETAILS_PATH}.bandwidth_mbps",
167175
CONST_ACCESS_LOG: "category_log_details.access",
@@ -518,3 +526,29 @@ def with_web_concurrency(
518526
The ModelDeploymentInfrastructure instance (self).
519527
"""
520528
return self.set_spec(self.CONST_WEB_CONCURRENCY, web_concurrency)
529+
530+
def with_subnet_id(self, subnet_id: str) -> "ModelDeploymentInfrastructure":
531+
"""Sets the subnet id of model deployment.
532+
533+
Parameters
534+
----------
535+
subnet_id : str
536+
The subnet id of model deployment.
537+
538+
Returns
539+
-------
540+
ModelDeploymentInfrastructure
541+
The ModelDeploymentInfrastructure instance (self).
542+
"""
543+
return self.set_spec(self.CONST_SUBNET_ID, subnet_id)
544+
545+
@property
546+
def subnet_id(self) -> str:
547+
"""The model deployment subnet id.
548+
549+
Returns
550+
-------
551+
str
552+
The model deployment subnet id.
553+
"""
554+
return self.get_spec(self.CONST_SUBNET_ID, None)

ads/model/generic_model.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,6 +1902,7 @@ def deploy(
19021902
display_name: Optional[str] = None,
19031903
description: Optional[str] = None,
19041904
deployment_instance_shape: Optional[str] = None,
1905+
deployment_instance_subnet_id: Optional[str] = None,
19051906
deployment_instance_count: Optional[int] = None,
19061907
deployment_bandwidth_mbps: Optional[int] = None,
19071908
deployment_log_group_id: Optional[str] = None,
@@ -1950,6 +1951,8 @@ def deploy(
19501951
The description of the model.
19511952
deployment_instance_shape: (str, optional). Default to `VM.Standard2.1`.
19521953
The shape of the instance used for deployment.
1954+
deployment_instance_subnet_id: (str, optional). Default to None.
1955+
The subnet id of the instance used for deployment.
19531956
deployment_instance_count: (int, optional). Defaults to 1.
19541957
The number of instance used for deployment.
19551958
deployment_bandwidth_mbps: (int, optional). Defaults to 10.
@@ -2084,6 +2087,10 @@ def deploy(
20842087
self.properties.deployment_instance_shape
20852088
or existing_infrastructure.shape_name
20862089
)
2090+
.with_subnet_id(
2091+
self.properties.deployment_instance_subnet_id
2092+
or existing_infrastructure.subnet_id
2093+
)
20872094
.with_replica(
20882095
self.properties.deployment_instance_count
20892096
or existing_infrastructure.replica
@@ -2253,6 +2260,7 @@ def prepare_save_deploy(
22532260
deployment_display_name: Optional[str] = None,
22542261
deployment_description: Optional[str] = None,
22552262
deployment_instance_shape: Optional[str] = None,
2263+
deployment_instance_subnet_id: Optional[str] = None,
22562264
deployment_instance_count: Optional[int] = None,
22572265
deployment_bandwidth_mbps: Optional[int] = None,
22582266
deployment_log_group_id: Optional[str] = None,
@@ -2340,6 +2348,8 @@ def prepare_save_deploy(
23402348
The description of the model.
23412349
deployment_instance_shape: (str, optional). Default to `VM.Standard2.1`.
23422350
The shape of the instance used for deployment.
2351+
deployment_instance_subnet_id: (str, optional). Default to None.
2352+
The subnet id of the instance used for deployment.
23432353
deployment_instance_count: (int, optional). Defaults to 1.
23442354
The number of instance used for deployment.
23452355
deployment_bandwidth_mbps: (int, optional). Defaults to 10.
@@ -2481,6 +2491,7 @@ def prepare_save_deploy(
24812491
display_name=deployment_display_name,
24822492
description=deployment_description,
24832493
deployment_instance_shape=self.properties.deployment_instance_shape,
2494+
deployment_instance_subnet_id=self.properties.deployment_instance_subnet_id,
24842495
deployment_instance_count=self.properties.deployment_instance_count,
24852496
deployment_bandwidth_mbps=self.properties.deployment_bandwidth_mbps,
24862497
deployment_log_group_id=self.properties.deployment_log_group_id,

ads/model/model_properties.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ModelProperties(BaseProperties):
2828
remove_existing_artifact: bool = None
2929
overwrite_existing_artifact: bool = None
3030
deployment_instance_shape: str = None
31+
deployment_instance_subnet_id: str = None
3132
deployment_instance_count: int = None
3233
deployment_bandwidth_mbps: int = None
3334
deployment_log_group_id: str = None

ads/opctl/utils.py

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
import os
1111
import subprocess
1212
import sys
13+
import shlex
1314
import tempfile
1415
import urllib.parse
1516
from distutils import dir_util
1617
from subprocess import Popen, PIPE, STDOUT
1718
from typing import Union, List, Tuple, Dict
18-
import shlex
1919
import yaml
2020

2121
import ads
@@ -33,6 +33,9 @@
3333
)
3434

3535

36+
CONTAINER_NETWORK = "CONTAINER_NETWORK"
37+
38+
3639
def get_service_pack_prefix() -> Dict:
3740
curr_dir = os.path.dirname(os.path.abspath(__file__))
3841
service_config_file = os.path.join(curr_dir, "conda", "config.yaml")
@@ -175,11 +178,13 @@ def build_image(
175178
command += ["--build-arg", f"http_proxy={os.environ['http_proxy']}"]
176179
if os.environ.get("https_proxy"):
177180
command += ["--build-arg", f"https_proxy={os.environ['https_proxy']}"]
181+
if os.environ.get(CONTAINER_NETWORK):
182+
command += ["--network", os.environ[CONTAINER_NETWORK]]
178183
command += [os.path.abspath(curr_dir)]
179-
logger.info(f"Build image with command {command}")
184+
logger.info("Build image with command %s", command)
180185
proc = run_command(command)
181186
if proc.returncode != 0:
182-
raise RuntimeError(f"Docker build failed.")
187+
raise RuntimeError("Docker build failed.")
183188

184189

185190
def _get_image_name_dockerfile_target(type: str, gpu: bool) -> str:
@@ -321,27 +326,51 @@ def run_container(
321326
logger.info(f"command: {command}")
322327
logger.info(f"entrypoint: {entrypoint}")
323328

329+
# Print out the equivalent docker run command for debugging purpose
330+
docker_run_cmd = [">>> docker run --rm"]
331+
if entrypoint:
332+
docker_run_cmd.append(f"--entrypoint {entrypoint}")
333+
if env_vars:
334+
docker_run_cmd.extend([f"-e {key}={val}" for key, val in env_vars.items()])
335+
if bind_volumes:
336+
docker_run_cmd.extend(
337+
[f'-v {source}:{bind.get("bind")}' for source, bind in bind_volumes.items()]
338+
)
339+
docker_run_cmd.append(image)
340+
if command:
341+
docker_run_cmd.append(command)
342+
logger.debug(" ".join(docker_run_cmd))
343+
324344
client = get_docker_client()
325345
try:
326346
client.api.inspect_image(image)
327347
except docker.errors.ImageNotFound:
328-
logger.warn(f"Image {image} not found. Try pulling it now....")
348+
logger.warning(f"Image {image} not found. Try pulling it now....")
329349
run_command(["docker", "pull", f"{image}"], None)
330-
container = client.containers.run(
331-
image=image,
332-
volumes=bind_volumes,
333-
command=shlex.split(command) if command else None,
334-
environment=env_vars,
335-
detach=True,
336-
entrypoint=entrypoint,
337-
user=0,
338-
# auto_remove=True,
339-
)
340-
logger.info(f"Container ID: {container.id}")
341-
342-
for line in container.logs(stream=True, follow=True):
343-
logger.info(line.decode("utf-8").strip())
344-
345-
result = container.wait()
346-
container.remove()
347-
return result.get("StatusCode", -1)
350+
try:
351+
kwargs = {}
352+
if CONTAINER_NETWORK in os.environ:
353+
kwargs["network_mode"] = os.environ[CONTAINER_NETWORK]
354+
container = client.containers.run(
355+
image=image,
356+
volumes=bind_volumes,
357+
command=shlex.split(command) if command else None,
358+
environment=env_vars,
359+
detach=True,
360+
entrypoint=entrypoint,
361+
user=0,
362+
**kwargs
363+
# auto_remove=True,
364+
)
365+
logger.info("Container ID: %s", container.id)
366+
for line in container.logs(stream=True, follow=True):
367+
print(line.decode("utf-8"), end="")
368+
369+
result = container.wait()
370+
return result.get("StatusCode", -1)
371+
except docker.errors.APIError as ex:
372+
logger.error(ex.explanation)
373+
return -1
374+
finally:
375+
# Remove the container
376+
container.remove()

0 commit comments

Comments
 (0)