Skip to content

Commit 95a93f0

Browse files
committed
fix: ensure generated names are < 63 characters when deploying compiled models
1 parent 4f6626e commit 95a93f0

File tree

4 files changed

+34
-7
lines changed

4 files changed

+34
-7
lines changed

src/sagemaker/model.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,10 @@ def deploy(
477477

478478
compiled_model_suffix = "-".join(instance_type.split(".")[:-1])
479479
if self._is_compiled_model:
480-
name_prefix = self.name or utils.name_from_image(self.image)
481-
self.name = "{}{}".format(name_prefix, compiled_model_suffix)
480+
name_prefix = self.name or utils.name_from_image(
481+
self.image, max_length=(62 - len(compiled_model_suffix))
482+
)
483+
self.name = "{}-{}".format(name_prefix, compiled_model_suffix)
482484

483485
self._create_sagemaker_model(instance_type, accelerator_type, tags)
484486
production_variant = sagemaker.production_variant(

src/sagemaker/utils.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,18 @@
4242

4343

4444
# Use the base name of the image as the job name if the user doesn't give us one
45-
def name_from_image(image):
45+
def name_from_image(image, max_length=63):
4646
"""Create a training job name based on the image name and a timestamp.
4747
4848
Args:
4949
image (str): Image name.
5050
5151
Returns:
5252
str: Training job name using the algorithm from the image name and a
53-
timestamp.
53+
timestamp.
54+
max_length (int): Maximum length for the resulting string (default: 63).
5455
"""
55-
return name_from_base(base_name_from_image(image))
56+
return name_from_base(base_name_from_image(image), max_length=max_length)
5657

5758

5859
def name_from_base(base, max_length=63, short=False):
@@ -64,8 +65,8 @@ def name_from_base(base, max_length=63, short=False):
6465
6566
Args:
6667
base (str): String used as prefix to generate the unique name.
67-
max_length (int): Maximum length for the resulting string.
68-
short (bool): Whether or not to use a truncated timestamp.
68+
max_length (int): Maximum length for the resulting string (default: 63).
69+
short (bool): Whether or not to use a truncated timestamp (default: False).
6970
7071
Returns:
7172
str: Input parameter with appended timestamp.

tests/unit/sagemaker/model/test_neo.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,16 @@ def test_check_neo_region(sagemaker_session):
210210
for partition in boto_session.get_available_partitions():
211211
for region_name in boto_session.get_available_regions("ec2", partition_name=partition):
212212
assert (region_name in NEO_REGION_LIST) is model.check_neo_region(region_name)
213+
214+
215+
def test_deploy_valid_model_name(sagemaker_session):
216+
model = Model(
217+
image="long-base-name-that-is-over-the-63-character-limit-for-model-names",
218+
model_data=MODEL_DATA,
219+
role="role",
220+
sagemaker_session=sagemaker_session,
221+
)
222+
model._is_compiled_model = True
223+
224+
model.deploy(1, "ml.c4.xlarge")
225+
assert len(model.name) <= 63

tests/unit/test_utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ def test_bad_import():
6969
pd.DataFrame()
7070

7171

72+
@patch("sagemaker.utils.name_from_base")
73+
@patch("sagemaker.utils.base_name_from_image")
74+
def test_name_from_image(base_name_from_image, name_from_base):
75+
image = "image:latest"
76+
max_length = 32
77+
78+
sagemaker.utils.name_from_image(image, max_length=max_length)
79+
base_name_from_image.assert_called_with(image)
80+
name_from_base.assert_called_with(base_name_from_image.return_value, max_length=max_length)
81+
82+
7283
@patch("sagemaker.utils.sagemaker_timestamp")
7384
def test_name_from_base(sagemaker_timestamp):
7485
sagemaker.utils.name_from_base(NAME, short=False)

0 commit comments

Comments
 (0)