Skip to content

Commit 700ab47

Browse files
Merge branch 'master' of github.com:rvasahu-amazon/sagemaker-python-sdk
2 parents 90bafe0 + aed7511 commit 700ab47

File tree

21 files changed

+488
-116
lines changed

21 files changed

+488
-116
lines changed

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,42 @@
11
# Changelog
22

3+
## v2.200.0 (2023-12-13)
4+
5+
### Deprecations and Removals
6+
7+
* remove explicit `partitions` key requirement on pysdk side.
8+
9+
### Features
10+
11+
* add non-repeating config logger
12+
* Add SageMaker Geospatial verison 1.x images
13+
* TGI 1.2.0 Image Uri
14+
* support model.register() with triton model
15+
* Enable retrieving function step results for local mode
16+
17+
### Bug Fixes and Other Changes
18+
19+
* TGI 1.3.1
20+
* excessive jumpstart instance type logging
21+
* Support local mode for remote function
22+
* `Session.download_data` can not download nested objects
23+
* Fix writing into non-closed file with git clone command
24+
* mitigation of xgboost container incompatibility with new version
25+
* update image and hardware validation with inf and graviton
26+
* remove two setuptools deprecations
27+
* minor jumpstart dev ex improvements
28+
* save utils fix
29+
* Correct DJL neuronx regions
30+
* delete unused file inference-experience-dev-tester.sh
31+
* Fix Experiment Run integ test w.r.t unexpected boto3 version
32+
* Bump test dependencies versions
33+
* fast follow on js uncompressed support - ModelBuilder
34+
* Modify Region List for Neuron Images (HF neuron/neuronx, PT Neuron)
35+
36+
### Documentation Changes
37+
38+
* Mention for custom Docker Image
39+
340
## v2.199.0 (2023-11-30)
441

542
### Features

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.199.1.dev0
1+
2.200.1.dev0

src/sagemaker/config/config.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@
2828
from botocore.utils import merge_dicts
2929
from six.moves.urllib.parse import urlparse
3030
from sagemaker.config.config_schema import SAGEMAKER_PYTHON_SDK_CONFIG_SCHEMA
31-
from sagemaker.config.config_utils import get_sagemaker_config_logger
31+
from sagemaker.config.config_utils import non_repeating_log_factory, get_sagemaker_config_logger
3232

3333
logger = get_sagemaker_config_logger()
34+
log_info_function = non_repeating_log_factory(logger, "info")
3435

3536
_APP_NAME = "sagemaker"
3637
# The default name of the config file.
@@ -52,7 +53,9 @@
5253
S3_PREFIX = "s3://"
5354

5455

55-
def load_sagemaker_config(additional_config_paths: List[str] = None, s3_resource=None) -> dict:
56+
def load_sagemaker_config(
57+
additional_config_paths: List[str] = None, s3_resource=None, repeat_log=False
58+
) -> dict:
5659
"""Loads config files and merges them.
5760
5861
By default, this method first searches for config files in the default locations
@@ -99,6 +102,8 @@ def load_sagemaker_config(additional_config_paths: List[str] = None, s3_resource
99102
<https://boto3.amazonaws.com/v1/documentation/api\
100103
/latest/reference/core/session.html#boto3.session.Session.resource>`__.
101104
This argument is not needed if the config files are present in the local file system.
105+
repeat_log (bool): Whether the log with the same contents should be emitted.
106+
Default to ``False``
102107
"""
103108
default_config_path = os.getenv(
104109
ENV_VARIABLE_ADMIN_CONFIG_OVERRIDE, _DEFAULT_ADMIN_CONFIG_FILE_PATH
@@ -109,6 +114,11 @@ def load_sagemaker_config(additional_config_paths: List[str] = None, s3_resource
109114
config_paths += additional_config_paths
110115
config_paths = list(filter(lambda item: item is not None, config_paths))
111116
merged_config = {}
117+
118+
log_info = log_info_function
119+
if repeat_log:
120+
log_info = logger.info
121+
112122
for file_path in config_paths:
113123
config_from_file = {}
114124
if file_path.startswith(S3_PREFIX):
@@ -130,9 +140,9 @@ def load_sagemaker_config(additional_config_paths: List[str] = None, s3_resource
130140
if config_from_file:
131141
validate_sagemaker_config(config_from_file)
132142
merge_dicts(merged_config, config_from_file)
133-
logger.info("Fetched defaults config from location: %s", file_path)
143+
log_info("Fetched defaults config from location: %s", file_path)
134144
else:
135-
logger.info("Not applying SDK defaults from location: %s", file_path)
145+
log_info("Not applying SDK defaults from location: %s", file_path)
136146

137147
return merged_config
138148

src/sagemaker/config/config_utils.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
These utils may be used inside or outside the config module.
1616
"""
1717
from __future__ import absolute_import
18+
from collections import deque
1819

1920
import logging
2021
import sys
22+
from typing import Callable
2123

2224

2325
def get_sagemaker_config_logger():
@@ -197,3 +199,33 @@ def _log_sagemaker_config_merge(
197199
else:
198200
# nothing was specified in the config and nothing is being automatically applied
199201
logger.debug("Skipped value because no value defined\n config key = %s", config_key_path)
202+
203+
204+
def non_repeating_log_factory(logger: logging.Logger, method: str, cache_size=100) -> Callable:
205+
"""Create log function that filters the repeated messages.
206+
207+
By default. It only keeps track of last 100 messages, if a repeated
208+
message arrives after the ``cache_size`` messages, it will be displayed.
209+
210+
Args:
211+
logger (logging.Logger): the logger to be used to dispatch the message.
212+
method (str): the log method, can be info, warning or debug.
213+
cache_size (int): the number of last log messages to keep in cache.
214+
Default to 100
215+
216+
Returns:
217+
(Callable): the new log method
218+
"""
219+
if method not in ["info", "warning", "debug"]:
220+
raise ValueError("Not supported logging method.")
221+
222+
_caches = deque(maxlen=cache_size)
223+
log_method = getattr(logger, method)
224+
225+
def new_log_method(msg, *args, **kwargs):
226+
key = f"{msg}:{args}"
227+
if key not in _caches:
228+
log_method(msg, *args, **kwargs)
229+
_caches.append(key)
230+
231+
return new_log_method

src/sagemaker/git_utils.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from __future__ import absolute_import
1515

1616
import os
17+
from pathlib import Path
1718
import subprocess
1819
import tempfile
1920
import warnings
@@ -279,11 +280,13 @@ def _run_clone_command(repo_url, dest_dir):
279280
subprocess.check_call(["git", "clone", repo_url, dest_dir], env=my_env)
280281
elif repo_url.startswith("git@") or repo_url.startswith("ssh://"):
281282
try:
282-
with tempfile.NamedTemporaryFile() as sshnoprompt:
283-
with open(sshnoprompt.name, "w") as write_pipe:
284-
write_pipe.write("ssh -oBatchMode=yes $@")
285-
os.chmod(sshnoprompt.name, 0o511)
286-
my_env["GIT_SSH"] = sshnoprompt.name
283+
with tempfile.TemporaryDirectory() as tmp_dir:
284+
custom_ssh_executable = Path(tmp_dir) / "ssh_batch"
285+
with open(custom_ssh_executable, "w") as pipe:
286+
print("#!/bin/sh", file=pipe)
287+
print("ssh -oBatchMode=yes $@", file=pipe)
288+
os.chmod(custom_ssh_executable, 0o511)
289+
my_env["GIT_SSH"] = str(custom_ssh_executable)
287290
subprocess.check_call(["git", "clone", repo_url, dest_dir], env=my_env)
288291
except subprocess.CalledProcessError:
289292
del my_env["GIT_SSH"]

src/sagemaker/image_uri_config/huggingface-llm.json

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
"0.8": "0.8.2",
77
"0.9": "0.9.3",
88
"1.0": "1.0.3",
9-
"1.1": "1.1.0"
9+
"1.1": "1.1.0",
10+
"1.2": "1.2.0",
11+
"1.3": "1.3.1"
1012
},
1113
"versions": {
1214
"0.6.0": {
@@ -260,6 +262,48 @@
260262
"tag_prefix": "2.1.1-tgi1.2.0",
261263
"repository": "huggingface-pytorch-tgi-inference",
262264
"container_version": {"gpu": "cu121-ubuntu20.04"}
265+
},
266+
"1.3.1": {
267+
"py_versions": ["py310"],
268+
"registries": {
269+
"af-south-1": "626614931356",
270+
"il-central-1": "780543022126",
271+
"ap-east-1": "871362719292",
272+
"ap-northeast-1": "763104351884",
273+
"ap-northeast-2": "763104351884",
274+
"ap-northeast-3": "364406365360",
275+
"ap-south-1": "763104351884",
276+
"ap-south-2": "772153158452",
277+
"ap-southeast-1": "763104351884",
278+
"ap-southeast-2": "763104351884",
279+
"ap-southeast-3": "907027046896",
280+
"ap-southeast-4": "457447274322",
281+
"ca-central-1": "763104351884",
282+
"cn-north-1": "727897471807",
283+
"cn-northwest-1": "727897471807",
284+
"eu-central-1": "763104351884",
285+
"eu-central-2": "380420809688",
286+
"eu-north-1": "763104351884",
287+
"eu-west-1": "763104351884",
288+
"eu-west-2": "763104351884",
289+
"eu-west-3": "763104351884",
290+
"eu-south-1": "692866216735",
291+
"eu-south-2": "503227376785",
292+
"me-south-1": "217643126080",
293+
"me-central-1": "914824155844",
294+
"sa-east-1": "763104351884",
295+
"us-east-1": "763104351884",
296+
"us-east-2": "763104351884",
297+
"us-gov-east-1": "446045086412",
298+
"us-gov-west-1": "442386744353",
299+
"us-iso-east-1": "886529160074",
300+
"us-isob-east-1": "094389454867",
301+
"us-west-1": "763104351884",
302+
"us-west-2": "763104351884"
303+
},
304+
"tag_prefix": "2.1.1-tgi1.3.1",
305+
"repository": "huggingface-pytorch-tgi-inference",
306+
"container_version": {"gpu": "cu121-ubuntu20.04"}
263307
}
264308
}
265309
}

src/sagemaker/jumpstart/factory/estimator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ def get_deploy_kwargs(
336336
tolerate_vulnerable_model=tolerate_vulnerable_model,
337337
tolerate_deprecated_model=tolerate_deprecated_model,
338338
training_instance_type=training_instance_type,
339+
disable_instance_type_logging=True,
339340
)
340341

341342
estimator_deploy_kwargs: JumpStartEstimatorDeployKwargs = JumpStartEstimatorDeployKwargs(

src/sagemaker/jumpstart/factory/model.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,9 @@ def _add_vulnerable_and_deprecated_status_to_kwargs(
171171
return kwargs
172172

173173

174-
def _add_instance_type_to_kwargs(kwargs: JumpStartModelInitKwargs) -> JumpStartModelInitKwargs:
174+
def _add_instance_type_to_kwargs(
175+
kwargs: JumpStartModelInitKwargs, disable_instance_type_logging: bool = False
176+
) -> JumpStartModelInitKwargs:
175177
"""Sets instance type based on default or override, returns full kwargs."""
176178

177179
orig_instance_type = kwargs.instance_type
@@ -187,7 +189,7 @@ def _add_instance_type_to_kwargs(kwargs: JumpStartModelInitKwargs) -> JumpStartM
187189
training_instance_type=kwargs.training_instance_type,
188190
)
189191

190-
if orig_instance_type is None:
192+
if not disable_instance_type_logging and orig_instance_type is None:
191193
JUMPSTART_LOGGER.info(
192194
"No instance type selected for inference hosting endpoint. Defaulting to %s.",
193195
kwargs.instance_type,
@@ -551,9 +553,7 @@ def get_deploy_kwargs(
551553

552554
deploy_kwargs = _add_endpoint_name_to_kwargs(kwargs=deploy_kwargs)
553555

554-
deploy_kwargs = _add_instance_type_to_kwargs(
555-
kwargs=deploy_kwargs,
556-
)
556+
deploy_kwargs = _add_instance_type_to_kwargs(kwargs=deploy_kwargs)
557557

558558
deploy_kwargs.initial_instance_count = initial_instance_count or 1
559559

@@ -677,6 +677,7 @@ def get_init_kwargs(
677677
git_config: Optional[Dict[str, str]] = None,
678678
model_package_arn: Optional[str] = None,
679679
training_instance_type: Optional[str] = None,
680+
disable_instance_type_logging: bool = False,
680681
resources: Optional[ResourceRequirements] = None,
681682
) -> JumpStartModelInitKwargs:
682683
"""Returns kwargs required to instantiate `sagemaker.estimator.Model` object."""
@@ -720,7 +721,7 @@ def get_init_kwargs(
720721
model_init_kwargs = _add_model_name_to_kwargs(kwargs=model_init_kwargs)
721722

722723
model_init_kwargs = _add_instance_type_to_kwargs(
723-
kwargs=model_init_kwargs,
724+
kwargs=model_init_kwargs, disable_instance_type_logging=disable_instance_type_logging
724725
)
725726

726727
model_init_kwargs = _add_image_uri_to_kwargs(kwargs=model_init_kwargs)

src/sagemaker/model.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -866,16 +866,10 @@ def _create_sagemaker_model(
866866
# _base_name, model_name are not needed under PipelineSession.
867867
# the model_data may be Pipeline variable
868868
# which may break the _base_name generation
869-
model_uri = None
870-
if isinstance(self.model_data, (str, PipelineVariable)):
871-
model_uri = self.model_data
872-
elif isinstance(self.model_data, dict):
873-
model_uri = self.model_data.get("S3DataSource", {}).get("S3Uri", None)
874-
875869
self._ensure_base_name_if_needed(
876870
image_uri=container_def["Image"],
877871
script_uri=self.source_dir,
878-
model_uri=model_uri,
872+
model_uri=self._get_model_uri(),
879873
)
880874
self._set_model_name_if_needed()
881875

@@ -912,6 +906,14 @@ def _create_sagemaker_model(
912906
)
913907
self.sagemaker_session.create_model(**create_model_args)
914908

909+
def _get_model_uri(self):
910+
model_uri = None
911+
if isinstance(self.model_data, (str, PipelineVariable)):
912+
model_uri = self.model_data
913+
elif isinstance(self.model_data, dict):
914+
model_uri = self.model_data.get("S3DataSource", {}).get("S3Uri", None)
915+
return model_uri
916+
915917
def _ensure_base_name_if_needed(self, image_uri, script_uri, model_uri):
916918
"""Create a base name from the image URI if there is no model name provided.
917919
@@ -1496,7 +1498,7 @@ def deploy(
14961498
self._ensure_base_name_if_needed(
14971499
image_uri=self.image_uri,
14981500
script_uri=self.source_dir,
1499-
model_uri=self.model_data,
1501+
model_uri=self._get_model_uri(),
15001502
)
15011503
if self._base_name is not None:
15021504
self._base_name = "-".join((self._base_name, compiled_model_suffix))

src/sagemaker/remote_function/job.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ def wait(self, timeout: int = None):
891891
"""
892892

893893
self._last_describe_response = _logs_for_job(
894-
boto_session=self.sagemaker_session.boto_session,
894+
sagemaker_session=self.sagemaker_session,
895895
job_name=self.job_name,
896896
wait=True,
897897
timeout=timeout,

0 commit comments

Comments
 (0)