feat(serve): add opt-in model source tag-based resource reuse#5993
Conversation
| """ | ||
| manifest_uri = build_nova_manifest_s3_uri(s3_output_path, training_job_name) | ||
| try: | ||
| return read_nova_checkpoint_uri_from_manifest(s3_client, manifest_uri) |
There was a problem hiding this comment.
what if there's no manifest.json saved in the output folder and it is not a tar.gz file (for hyperpod)? wouldn't we in that case incorrectly throw an error that manifest file not found in the tar.gz output path?
There was a problem hiding this comment.
Thanks for the callout! I will adjust
There was a problem hiding this comment.
Yup training outputs in SMTJ are tar.gz files by default.
Add reuse_resources to ModelBuilder.build/deploy and BedrockModelBuilder.deploy. On a hit, discover an existing resource by the model-source tag and return it instead of creating a duplicate (warn, do not raise). Honored per call. - New sagemaker/serve/model_reuse.py: tag helpers + service-client discovery - Consolidate Nova manifest/checkpoint reading into sagemaker/core/training/utils.py - SageMaker: build() skips Model creation on reuse (sets built_model to the existing Model); deploy() reuses the endpoint after validating env vars/image/ instance type (PrimaryContainer with Containers[0] fallback for Nova) - Reuse gates are skipped for inference-component builds/deploys so IC create/update (via _deploy_for_ic) is never silently intercepted - Bedrock: reuse custom model + active deployment; response includes modelArn - Reuse discovery uses the cached session/bedrock clients - Support raw S3 URI model input via model_metadata BASE_MODEL_NAME - Unit tests + notebook examples
99bedb4 to
bca9dee
Compare
…euse Route Nova model-customization deploys through the shared single-inference -component path when a ResourceRequirements inference_config is supplied, so each Nova checkpoint (full-rank or LoRA-merged) is hosted as one inference component referencing the built Model. Nova without an inference_config keeps the direct model-on-variant path. - Broaden _is_nova_model to identify Nova from a package-less source (raw S3 checkpoint or trainer) via base_model_name, in addition to the model package recipe/hub-content name. - Set EnableNetworkIsolation on the IC endpoint config to match the built Model (always True for Nova), fixing CreateInferenceComponent rejection on mismatched network isolation. - Guard model-package-dependent logic (restricted-package path, PEFT/recipe metadata, lineage tracking) so package-less Nova checkpoints deploy cleanly. - Apply accumulated tags (including the model-source reuse tag) to endpoints created on the shared IC path so they remain discoverable. - build(reuse_resources=True) only short-circuits when the backing Model can be resolved; IC endpoints and stale/deleted configs fall through and build a real Model, preventing a None built_model on later IC deploys. - deploy() warns that reuse_resources has no effect for inference-component deployments, which manage their own reuse by component name. - Surface both the manifest.json and output.tar.gz errors when Nova checkpoint URI resolution fails, instead of masking the primary failure. Add unit tests covering the Nova IC path (routing, network isolation, IC spec) and the model-on-variant fallback.
| Fully-qualified S3 URI to the job's manifest.json. | ||
| """ | ||
| output_path = s3_output_path.rstrip("/") | ||
| return f"{output_path}/{training_job_name}/output/output/manifest.json" |
There was a problem hiding this comment.
The output path for manifest json may be different for serverless and hyperpod.
For serverless: training_job_name/output/output/manifest.json
For SMHP: training_job_name/manifest.json
Can we test this for both flows.
There was a problem hiding this comment.
Thanks for calling this out! I will push a new revision to address this gap.
I will test all three flows - Serverless, Serverful and HP
…ayouts Nova training jobs write their checkpoint manifest to different locations depending on the training platform: HyperPod: <output>/<job>/manifest.json Serverless: <output>/<job>/output/output/manifest.json Serverful: <output>/<job>/output/output.tar.gz (manifest inside) resolve_nova_checkpoint_uri previously only tried the serverless manifest path and the serverful tar.gz, so HyperPod jobs (manifest directly under the job directory) failed to resolve. Add build_nova_hyperpod_manifest_s3_uri and try all three layouts in turn, aggregating every failure into the raised error so the real cause is not masked by the last attempt's message. Add unit tests for the HyperPod builder and for resolution from the HyperPod and serverless layouts.
| ) | ||
| assert deployment.get("status") == "Active" | ||
|
|
||
| def test_nova_bedrock_custom_model_tagged_for_reuse(self, deployed_nova_model, bedrock_client): |
There was a problem hiding this comment.
can we also invoke this deployed model as part of the test, this would make it e2e.
There was a problem hiding this comment.
This file's test already invokes the deployed model in the Bedrock class sequence (TestNovaBedrockDeployment)
test_nova_bedrock_invoke does the invoking.
4a88ba8 to
6e8ac17
Compare
Simplify reuse discovery by tagging SageMaker Models (not just endpoints) with the model-source identifier, so build(reuse_resources=True) can find and skip recreating an existing Model directly — no IC-state dependency. - Tag non-Nova Models at build time with the model-source tag (matching the Nova path's existing behavior). Both Nova and OSS Models are now discoverable by tag. - Add _find_reusable_model: build(reuse_resources=True) searches Models by source tag, skipping Model creation on a hit. Also discovers the endpoint for deploy() to reuse later. - Simplify _get_model_for_endpoint back to variant-only lookup (returns None for IC endpoints). No longer needs IC-spec resolution since the Model is found directly by tag. - _reused_endpoint_matches_config returns True for IC endpoints (can't read container config from variant; Model was already matched by tag). - deploy() with reuse_resources=True on an IC deploy logs a warning that the flag has no effect (ICs manage reuse by endpoint_name + IC name). - Fix deploy() to set self.instance_type from the caller's explicit value before calling _deploy_model_customization, preventing recipe-resolved defaults from overriding the user's intent. - Add model-source tag assertion to the existing OSS deploy integ test.
6e8ac17 to
8ba3b82
Compare
|
Approved. Tests ran on smoketest (nova) account. Any changes needed for integ tests to run on PySDK acc to be tracked separately. |
Model Source Tag-Based Resource Reuse
Summary
Adds opt-in resource reuse to the V3 serve builders so redeploying the same model artifacts doesn't create duplicate resources (or exhaust quota-limited Bedrock imported models). Each deploy tags the resources it creates (Model + Endpoint) with a stable model-source identifier; when reuse is requested, a later call for the same source discovers and returns the existing resources instead of creating new ones.
Controlled by
reuse_resources: bool = False. On a hit we log a warning and return the existing resource (we do not raise).Behavior
deploy(reuse_resources=)build(reuse_resources=)+deploy(reuse_resources=)list_models+ model-source tag → reuses existing Modellist_custom_models+ tagslist_endpoints+ endpoint tagreuse_resourcesis not inherited: set it onbuild()to skip Model creation and ondeploy()to reuse the endpoint.Inference components: IC deployments (
inference_configis aResourceRequirements, or amodelbuilder_listbuild) are not intercepted byreuse_resourcesat the deploy level. They manage their own reuse byendpoint_name(infrastructure reuse) andinference_component_name(IC update). Passingreuse_resources=Trueon an IC deploy logs a warning that the flag is ignored. However,build(reuse_resources=True)still works for IC-based models — it finds the existing Model by tag and avoids creating a duplicate.Nova inference-component deployment
Nova model-customization deploys support inference components. When a
ResourceRequirementsinference_configis supplied, the Nova checkpoint is hosted as a single inference component referencing the built Model (which carries the Nova image, escrow artifacts, and env); without one, it keeps the direct model-on-variant path._is_nova_modelidentifies Nova from the model package recipe/hub-content name, and also from a package-less source (raw S3 checkpoint or trainer) viabase_model_name.EnableNetworkIsolationto match the built Model (alwaysTruefor Nova), fixing aCreateInferenceComponentrejection on mismatched network isolation.Model-tag reuse
Both Nova and OSS (non-Nova) Models are tagged with the model-source identifier at build time.
build(reuse_resources=True)searches existing Models by tag (_find_reusable_model) and skipsModel.createon a match, regardless of whether the endpoint is model-on-variant or IC-based.Checkpoint URI resolution
resolve_nova_checkpoint_urihandles all three Nova output layouts:<output>/<job>/manifest.json<output>/<job>/output/output/manifest.json<output>/<job>/output/output.tar.gz(manifest inside)Tries each in turn. If all fail, surfaces every error in the raised exception.
When reuse works and when it does not
inference_config=ResourceRequirements(...))build(reuse_resources=True)finds Model by tag.deploy()warns flag is ignored and creates the IC normally.modelbuilder_list/CustomOrchestratorbuildis_inference_component_build=True→ reuse gate skipped at build timeKey changes
sagemaker/serve/model_reuse.py: tag helpers + service-client discovery (find_existing_bedrock_model,find_active_bedrock_deployment_for_model,find_existing_sagemaker_endpoint) with status gating.sagemaker/core/training/utils.py: shared Nova manifest/checkpoint helpers (consolidated from duplicated logic), three-layout resolution (HyperPod/serverless/serverful).ModelBuilder:build(): tags the Model with model-source;_find_reusable_modelsearches by tag (paginated) to skip duplicate creation.deploy(): endpoint reuse gate with config validation; IC deploy warns reuse has no effect.self.instance_typeset from caller's explicit value before_deploy_model_customization.EnableNetworkIsolationon IC endpoint configs matches the built Model.modelinput viamodel_metadata={"BASE_MODEL_NAME": ...}.BedrockModelBuilder: reuse of custom model + deployment; consolidated source resolution; response always includesmodelArn.Tests
test_model_reuse.py,test_model_builder.py(Nova IC routing, network isolation, model-on-variant fallback),test_bedrock_model_builder.py, coretest_training_utils.py(3-layout resolution).test_model_customization_deployment.py), Nova Bedrock e2e (test_nova_model_customization_deployment.py).