Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 8 additions & 18 deletions sagemaker-serve/src/sagemaker/serve/model_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4053,15 +4053,12 @@ def build(
)

# Resource reuse: if an existing Model built from the same source is
# found (by model-source tag), skip creating a new one. Also discover the
# endpoint for deploy() to reuse later.
# found (by model-source tag), skip creating a new one. Endpoint reuse is
# resolved separately at deploy() time; build() only handles the Model.
if reuse_resources and not is_inference_component_build:
self.serve_settings = self._get_serve_setting()
reused_model = self._find_reusable_model()
if reused_model is not None:
reusable_endpoint = self._find_reusable_endpoint()
if reusable_endpoint:
self._reused_endpoint_name = reusable_endpoint
logger.info(
"Reusing existing Model %r (matched model-source tag). "
"No new Model will be created. Pass reuse_resources=False "
Expand Down Expand Up @@ -5505,21 +5502,14 @@ def deploy(
"inference_component_name (IC update). The flag is ignored."
)

# Resource reuse is opt-in per call. build() may have cached a candidate
# in _reused_endpoint_name, but without deploy-time context (instance_type
# is a deploy() arg), so re-validate the cache before trusting it and fall
# back to a fresh discovery on a miss or mismatch.
# Resource reuse is opt-in per call. Endpoint discovery happens here at
# deploy() time, where the deploy-time context (instance_type) is known;
# build() does not look for or cache an endpoint.
if reuse_resources and not is_inference_component_deploy:
requested_instance_type = instance_type or self.instance_type
cached_endpoint = getattr(self, "_reused_endpoint_name", None)
if cached_endpoint and self._reused_endpoint_matches_config(
cached_endpoint, instance_type=requested_instance_type
):
reusable_endpoint = cached_endpoint
else:
reusable_endpoint = self._find_reusable_endpoint(
instance_type=requested_instance_type
)
reusable_endpoint = self._find_reusable_endpoint(
instance_type=requested_instance_type
)
if reusable_endpoint:
if endpoint_name and endpoint_name != reusable_endpoint:
logger.warning(
Expand Down
15 changes: 15 additions & 0 deletions sagemaker-serve/src/sagemaker/serve/model_reuse.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,13 @@ def _resolve_ready_arn(
return None

if status in _CREATING_STATUSES:
logger.info(
"Existing resource %s is still Creating; polling every %ds up to %ds "
"before it can be reused",
resource_arn,
poll_interval,
max_wait,
)
return _poll_until_ready(client, resource_arn, status_checker, poll_interval, max_wait)

logger.warning("Resource %s has unexpected status '%s'. Proceeding to create new.", resource_arn, status)
Expand All @@ -406,6 +413,14 @@ def _poll_until_ready(
logger.warning("Could not check resource status during poll: %s. Proceeding without.", e)
return None

logger.info(
"Polling resource %s: status='%s' (%ds/%ds elapsed)",
resource_arn,
status,
elapsed,
max_wait,
)

if status in _ACTIVE_STATUSES:
return resource_arn

Expand Down