Skip to content

Commit f50859f

Browse files
rohangujarathiRohan Gujarathi
authored andcommitted
Pathways cleanup before GA (aws#908)
Co-authored-by: Rohan Gujarathi <[email protected]>
1 parent d0e03a6 commit f50859f

File tree

14 files changed

+164
-176
lines changed

14 files changed

+164
-176
lines changed

requirements/extras/remote_function_requirements.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def read_requirements(filename):
4949
required_packages = [
5050
"attrs>=20.3.0,<23",
5151
"boto3>=1.26.28,<2.0",
52+
"cloudpickle==2.2.1",
5253
"google-pasta",
5354
"numpy>=1.9.0,<2.0",
5455
"protobuf>=3.1,<4.0",
@@ -62,14 +63,14 @@ def read_requirements(filename):
6263
"PyYAML==5.4.1",
6364
"jsonschema",
6465
"platformdirs",
66+
"tblib==1.7.0",
6567
]
6668

6769
# Specific use case dependencies
6870
# Keep format of *_requirements.txt to be tracked by dependabot
6971
extras = {
7072
"local": read_requirements("requirements/extras/local_requirements.txt"),
7173
"scipy": read_requirements("requirements/extras/scipy_requirements.txt"),
72-
"remote_function": read_requirements("requirements/extras/remote_function_requirements.txt"),
7374
}
7475
# Meta dependency groups
7576
extras["all"] = [item for group in extras.values() for item in group]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"versions": {
3+
"1.0": {
4+
"registries": {
5+
"us-east-2": "429704687514",
6+
"me-south-1": "117516905037",
7+
"us-west-2": "236514542706",
8+
"ca-central-1": "310906938811",
9+
"ap-east-1": "493642496378",
10+
"us-east-1": "081325390199",
11+
"ap-northeast-2": "806072073708",
12+
"eu-west-2": "712779665605",
13+
"ap-southeast-2": "52832661640",
14+
"cn-northwest-1": "390780980154",
15+
"eu-north-1": "243637512696",
16+
"cn-north-1": "390048526115",
17+
"ap-south-1": "394103062818",
18+
"eu-west-3": "615547856133",
19+
"ap-southeast-3": "276181064229",
20+
"af-south-1": "559312083959",
21+
"eu-west-1": "470317259841",
22+
"eu-central-1": "936697816551",
23+
"sa-east-1": "782484402741",
24+
"ap-northeast-3": "792733760839",
25+
"eu-south-1": "592751261982",
26+
"ap-northeast-1": "102112518831",
27+
"us-west-1": "742091327244",
28+
"ap-southeast-1": "492261229750",
29+
"me-central-1": "103105715889",
30+
"us-gov-east-1": "107072934176",
31+
"us-gov-west-1": "107173498710"
32+
},
33+
"repository": "sagemaker-base-python"
34+
}
35+
}
36+
}

src/sagemaker/image_uris.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,3 +663,29 @@ def get_training_image_uri(
663663
container_version=container_version,
664664
training_compiler_config=compiler_config,
665665
)
666+
667+
668+
def get_base_python_image_uri(region, py_version="310") -> str:
669+
"""Retrieves the image URI for base python image.
670+
671+
Args:
672+
region (str): The AWS region to use for image URI.
673+
py_version (str): The python version to use for the image. Can be 310 or 38
674+
Default to 310
675+
676+
Returns:
677+
str: The image URI string.
678+
"""
679+
680+
framework = "sagemaker-base-python"
681+
version = "1.0"
682+
hostname = utils._botocore_resolver().construct_endpoint("ecr", region)["hostname"]
683+
config = config_for_framework(framework)
684+
version_config = config["versions"][_version_for_config(version, config)]
685+
686+
registry = _registry_from_region(region, version_config["registries"])
687+
688+
repo = version_config["repository"] + "-" + py_version
689+
repo_and_tag = repo + ":" + version
690+
691+
return ECR_URI_TEMPLATE.format(registry=registry, hostname=hostname, repository=repo_and_tag)

src/sagemaker/remote_function/job.py

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
)
4242
from sagemaker.experiments._run_context import _RunContext
4343
from sagemaker.experiments.run import Run
44+
from sagemaker.image_uris import get_base_python_image_uri
4445
from sagemaker.session import get_execution_role, _logs_for_job, Session
4546
from sagemaker.utils import name_from_base, _tmpdir, resolve_value_from_config
4647
from sagemaker.s3 import s3_path_join, S3Uploader
@@ -60,16 +61,11 @@
6061
# training channel names
6162
RUNTIME_SCRIPTS_CHANNEL_NAME = "sagemaker_remote_function_bootstrap"
6263
REMOTE_FUNCTION_WORKSPACE = "sm_rf_user_ws"
63-
SAGEMAKER_WHL_CHANNEL_NAME = "sagemaker_whl_file"
6464

6565
# run context dictionary keys
6666
KEY_EXPERIMENT_NAME = "experiment_name"
6767
KEY_RUN_NAME = "run_name"
6868

69-
SAGEMAKER_SDK_WHL_FILE = (
70-
"s3://sagemaker-pathways/beta/pysdk/sagemaker-2.132.1.dev0-py2.py3-none-any.whl"
71-
)
72-
7369
JOBS_CONTAINER_ENTRYPOINT = [
7470
"/bin/bash",
7571
f"/opt/ml/input/data/{RUNTIME_SCRIPTS_CHANNEL_NAME}/{ENTRYPOINT_SCRIPT_NAME}",
@@ -280,22 +276,18 @@ def _get_default_image(session):
280276
):
281277
return os.environ["SAGEMAKER_INTERNAL_IMAGE_URI"]
282278

283-
py_major_version = sys.version_info[0]
284-
py_minor_version = sys.version_info[1]
279+
py_version = str(sys.version_info[0]) + str(sys.version_info[1])
285280

286-
# TODO:Add Support for 3.8
287-
if py_major_version != 3 or py_minor_version != 10:
288-
raise ValueError("Use supported Python version or provide compatible ImageUri.")
281+
if py_version not in ["310", "38"]:
282+
raise ValueError(
283+
"Default image is supported only for Python versions 3.8 and 3.10. If you "
284+
"are using any other python version, you must provide a compatible image_uri."
285+
)
289286

290-
# TODO: Support only supported by Studio
291287
region = session.boto_region_name
288+
image_uri = get_base_python_image_uri(region=region, py_version=py_version)
292289

293-
# TODO: Remove beta image and use public base python
294-
beta_image = (
295-
f"581474259216.dkr.ecr.{region}.amazonaws.com/"
296-
f"sagemaker-pathways-beta:basepy_3_10_latest"
297-
)
298-
return beta_image
290+
return image_uri
299291

300292

301293
class _Job:
@@ -394,19 +386,6 @@ def start(job_settings: _JobSettings, func, func_args, func_kwargs, run_info=Non
394386
)
395387
)
396388

397-
# temporary solution for public beta to make sagemaker installer available
398-
# in the images, this should be removed before pathways GA.
399-
input_data_config.append(
400-
dict(
401-
ChannelName=SAGEMAKER_WHL_CHANNEL_NAME,
402-
DataSource={
403-
"S3DataSource": {
404-
"S3Uri": SAGEMAKER_SDK_WHL_FILE,
405-
"S3DataType": "S3Prefix",
406-
}
407-
},
408-
)
409-
)
410389
request_dict["InputDataConfig"] = input_data_config
411390

412391
output_config = {"S3OutputPath": s3_base_uri}

src/sagemaker/remote_function/runtime_environment/bootstrap_runtime_environment.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
REMOTE_FUNCTION_WORKSPACE = "sm_rf_user_ws"
3434
BASE_CHANNEL_PATH = "/opt/ml/input/data"
3535
FAILURE_REASON_PATH = "/opt/ml/output/failure"
36-
SAGEMAKER_WHL_FILE_NAME = "sagemaker-2.132.1.dev0-py2.py3-none-any.whl"
37-
SAGEMAKER_WHL_CHANNEL = "sagemaker_whl_file"
3836
PRE_EXECUTION_SCRIPT_NAME = "pre_exec.sh"
3937

4038

@@ -109,7 +107,6 @@ def _bootstrap_runtime_environment(
109107
break
110108

111109
if dependencies_file:
112-
_create_sm_installer_symlinks()
113110
RuntimeEnvironmentManager().bootstrap(
114111
local_dependencies_file=dependencies_file,
115112
conda_env=conda_env,
@@ -123,29 +120,6 @@ def _bootstrap_runtime_environment(
123120
)
124121

125122

126-
def _create_sm_installer_symlinks():
127-
"""Creates a symlink for sagemaker installer
128-
129-
This function create a symlink of sagemaker whl such that public beta users won't need
130-
to provide whl file path in their dependencies file. This logic should be removed before GA
131-
"""
132-
133-
whl_file_path = os.path.join(BASE_CHANNEL_PATH, SAGEMAKER_WHL_CHANNEL, SAGEMAKER_WHL_FILE_NAME)
134-
135-
destination_path1 = os.path.join(
136-
BASE_CHANNEL_PATH, REMOTE_FUNCTION_WORKSPACE, SAGEMAKER_WHL_FILE_NAME
137-
)
138-
os.symlink(whl_file_path, destination_path1)
139-
logger.info("Successfully created symlink from '%s' to '%s'.", destination_path1, whl_file_path)
140-
141-
destination_path2 = os.path.join(os.getcwd(), SAGEMAKER_WHL_FILE_NAME)
142-
if not os.path.exists(destination_path2):
143-
logger.info(
144-
"Successfully created symlink from '%s' to '%s'.", destination_path2, whl_file_path
145-
)
146-
os.symlink(whl_file_path, destination_path2)
147-
148-
149123
def _write_failure_reason_file(failure_msg):
150124
"""Create a file 'failure' with failure reason written if bootstrap runtime env failed.
151125

src/sagemaker/remote_function/runtime_environment/runtime_environment_manager.py

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import shlex
2121
import os
2222
import subprocess
23-
import tempfile
2423
import time
2524

2625

@@ -127,14 +126,10 @@ def _capture_from_local_runtime(self) -> str:
127126
)
128127

129128
local_dependencies_path = os.path.join(os.getcwd(), "env_snapshot.yml")
130-
with tempfile.NamedTemporaryFile(suffix=".yml", prefix="tmp_export") as tmp_file:
131-
if conda_env_name is not None:
132-
self._export_conda_env_from_env_name(conda_env_name, tmp_file.name)
133-
else:
134-
self._export_conda_env_from_prefix(conda_env_prefix, tmp_file.name)
135-
data = self._replace_sagemaker_in_conda_env_yml(tmp_file.read())
136-
with open(local_dependencies_path, "wb") as file:
137-
file.write(data)
129+
if conda_env_name is not None:
130+
self._export_conda_env_from_env_name(conda_env_name, local_dependencies_path)
131+
else:
132+
self._export_conda_env_from_prefix(conda_env_prefix, local_dependencies_path)
138133

139134
return local_dependencies_path
140135

@@ -263,14 +258,6 @@ def _export_conda_env_from_prefix(self, prefix, local_path):
263258
_run_shell_cmd(cmd)
264259
logger.info("Conda environment %s exported successfully", prefix)
265260

266-
def _replace_sagemaker_in_conda_env_yml(self, data):
267-
"""Replace the sagemaker in conda yml file with local sagemaker installer"""
268-
269-
sagemaker_with_version = b"sagemaker==2.132.1.dev0"
270-
sagemaker_whl_file = b"sagemaker-2.132.1.dev0-py2.py3-none-any.whl[remote_function]"
271-
272-
return data.replace(sagemaker_with_version, sagemaker_whl_file)
273-
274261
def _write_conda_env_to_file(self, env_name):
275262
"""Writes conda env to the text file"""
276263

tests/integ/sagemaker/remote_function/conftest.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
&& unzip awscliv2.zip \
3535
&& ./aws/install\n\n"
3636
"COPY {source_archive} ./\n"
37-
"RUN pip3 install '{source_archive}[remote_function]'\n"
37+
"RUN pip3 install '{source_archive}'\n"
3838
"RUN rm {source_archive}\n"
3939
)
4040

@@ -51,10 +51,10 @@
5151
"RUN mamba create -n integ_test_env python={py_version} -y \
5252
&& mamba create -n default_env python={py_version} -y\n"
5353
"COPY {source_archive} ./\n"
54-
"RUN pip install '{source_archive}[remote_function]' \
55-
&& mamba run -n base pip install '{source_archive}[remote_function]' \
56-
&& mamba run -n default_env pip install '{source_archive}[remote_function]' \
57-
&& mamba run -n integ_test_env pip install '{source_archive}[remote_function]'\n"
54+
"RUN pip install '{source_archive}' \
55+
&& mamba run -n base pip install '{source_archive}' \
56+
&& mamba run -n default_env pip install '{source_archive}' \
57+
&& mamba run -n integ_test_env pip install '{source_archive}'\n"
5858
"ENV SHELL=/bin/bash\n"
5959
"ENV SAGEMAKER_JOB_CONDA_ENV=default_env\n"
6060
)
@@ -66,7 +66,7 @@
6666
"dependencies:\n"
6767
" - scipy=1.7.3\n"
6868
" - pip:\n"
69-
" - /opt/ml/remote_function/sagemaker-{sagemaker_version}.tar.gz[remote_function]\n"
69+
" - /opt/ml/remote_function/sagemaker-{sagemaker_version}.tar.gz\n"
7070
"prefix: /opt/conda/bin/conda\n"
7171
)
7272

@@ -77,7 +77,7 @@
7777
"dependencies:\n"
7878
" - scipy=1.7.3\n"
7979
" - pip:\n"
80-
" - sagemaker-2.132.1.dev0-py2.py3-none-any.whl[remote_function]\n"
80+
" - sagemaker-2.132.1.dev0-py2.py3-none-any.whl\n"
8181
"prefix: /opt/conda/bin/conda\n"
8282
)
8383

tests/integ/sagemaker/remote_function/test_decorator.py

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -290,31 +290,6 @@ def cuberoot(x):
290290
assert cuberoot(27) == 3
291291

292292

293-
# TODO: it pulls the SDK from our beta release bucket, which is outdated already.
294-
# It will be cleaned up before GA release.
295-
@pytest.mark.skip
296-
def test_additional_dependencies_sm_from_input_channel(
297-
sagemaker_session,
298-
dummy_container_with_conda,
299-
cpu_instance_type,
300-
conda_yml_file_sm_from_input_channel,
301-
):
302-
@remote(
303-
role=ROLE,
304-
image_uri=dummy_container_with_conda,
305-
dependencies=conda_yml_file_sm_from_input_channel,
306-
instance_type=cpu_instance_type,
307-
sagemaker_session=sagemaker_session,
308-
job_conda_env="integ_test_env",
309-
)
310-
def cuberoot(x):
311-
from scipy.special import cbrt
312-
313-
return cbrt(x)
314-
315-
assert cuberoot(27) == 3
316-
317-
318293
def test_with_non_existent_dependencies(
319294
sagemaker_session, dummy_container_without_error, cpu_instance_type
320295
):

tests/unit/sagemaker/image_uris/expected_uris.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,9 @@ def djl_framework_uri(repo, account, djl_version, primary_framework, region=REGI
7878
domain = ALTERNATE_DOMAINS.get(region, DOMAIN)
7979
tag = f"{djl_version}-{primary_framework}"
8080
return IMAGE_URI_FORMAT.format(account, region, domain, repo, tag)
81+
82+
83+
def base_python_uri(repo, account, region=REGION):
84+
domain = ALTERNATE_DOMAINS.get(region, DOMAIN)
85+
tag = "1.0"
86+
return IMAGE_URI_FORMAT.format(account, region, domain, repo, tag)

0 commit comments

Comments
 (0)