Skip to content

Commit 4ac6376

Browse files
Yadan-Weisagemaker-botYadan Wei
authored
fix: migrate llama-cpp-arm64 to cpu processor schema and align image_uri unit tests (#6290)
* change: update image_uri_configs 09-17-2026 15:24:36 PST * fix: correct whisperx version alias and align serving/tensorflow image_uri tests - whisperx: drop the spurious "3.8": "3.8.6" version alias so version 3.8 resolves to its own moving minor tag (3.8-cu128-amzn2023-sagemaker) rather than the pinned 3.8.6 tag; the latest alias still points to 3.8. - tests: reclassify llama-cpp-arm64 as a cpu-only processor-schema config (migrated from the whole-tag form) with mirrored uri / reject-gpu-instance / literal-tag coverage. - tests: allow the newest tensorflow version to additionally carry a newly launched region that is still inside the image-copy window (subset check instead of exact equality). * fix: scope PR to llama-cpp-arm64 cpu-schema migration + image_uri test alignment Revert the bundled image_uri_config data promotion and the whisperx alias change carried by earlier commits on this branch, leaving the net change as exactly: - llama-cpp-arm64.json migrated to the cpu-only processor schema (resolved tag unchanged), - serving-framework and tensorflow image_uri unit-test alignments. --------- Co-authored-by: sagemaker-bot <sagemaker-bot@amazon.com> Co-authored-by: Yadan Wei <weiyadan@amazon.com>
1 parent 5918e0b commit 4ac6376

3 files changed

Lines changed: 84 additions & 5 deletions

File tree

‎sagemaker-core/src/sagemaker/core/image_uri_config/llama-cpp-arm64.json‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
},
88
"versions": {
99
"1": {
10+
"container_version": {
11+
"cpu": "cpu-v1"
12+
},
13+
"processor_in_tag": false,
14+
"processors": [
15+
"cpu"
16+
],
1017
"registries": {
1118
"af-south-1": "626614931356",
1219
"ap-east-1": "871362719292",
@@ -48,9 +55,16 @@
4855
"us-west-2": "763104351884"
4956
},
5057
"repository": "llama-cpp-arm64",
51-
"tag_prefix": "server-sagemaker-cpu-v1"
58+
"tag_prefix": "server-sagemaker"
5259
},
5360
"1.0": {
61+
"container_version": {
62+
"cpu": "cpu-v1.0"
63+
},
64+
"processor_in_tag": false,
65+
"processors": [
66+
"cpu"
67+
],
5468
"registries": {
5569
"af-south-1": "626614931356",
5670
"ap-east-1": "871362719292",
@@ -92,7 +106,7 @@
92106
"us-west-2": "763104351884"
93107
},
94108
"repository": "llama-cpp-arm64",
95-
"tag_prefix": "server-sagemaker-cpu-v1.0"
109+
"tag_prefix": "server-sagemaker"
96110
}
97111
}
98112
}

‎sagemaker-core/tests/unit/image_uris/test_dlc_serving_frameworks.py‎

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,14 @@
2525

2626
# Single-variant configs whose tag_prefix is the full image tag, taken verbatim
2727
# (no processors / processor_in_tag / container_version). Instance type is ignored.
28-
WHOLE_TAG_CONFIG_FILES = [
28+
# (None currently: llama-cpp-arm64 migrated to the cpu processor schema below.)
29+
WHOLE_TAG_CONFIG_FILES = []
30+
31+
# CPU-only configs on the processor schema: processors=["cpu"], processor_in_tag=false,
32+
# and the tag tail in container_version["cpu"]. Mirror of the gpu-only case: instance_type
33+
# is optional (single processor) and resolves to the cpu image; a gpu instance is rejected
34+
# until a gpu image is added.
35+
CPU_ONLY_PROCESSOR_FILES = [
2936
"llama-cpp-arm64.json",
3037
]
3138

@@ -133,6 +140,51 @@ def test_gpu_only_processor_rejects_cpu_instance(framework):
133140
)
134141

135142

143+
@pytest.mark.parametrize("load_config_and_file_name", CPU_ONLY_PROCESSOR_FILES, indirect=True)
144+
def test_cpu_only_processor_serving_framework_uris(load_config_and_file_name):
145+
"""CPU-only framework on the processor schema resolves to the cpu tail, and because it
146+
has a single processor, omitting instance_type still yields the cpu image."""
147+
config, file_name = load_config_and_file_name
148+
framework = file_name[: -len(".json")]
149+
for version, version_config in config["versions"].items():
150+
repo = version_config["repository"]
151+
prefix = version_config["tag_prefix"]
152+
cpu_tail = version_config["container_version"]["cpu"]
153+
expected_tag = f"{prefix}-{cpu_tail}"
154+
for region, account in version_config["registries"].items():
155+
uri = image_uris.retrieve(
156+
framework=framework,
157+
region=region,
158+
version=version,
159+
image_scope="inference",
160+
instance_type=PROCESSOR_INSTANCE_TYPES["cpu"],
161+
)
162+
assert uri.startswith(f"{account}.dkr.ecr.{region}."), uri
163+
assert uri.endswith(f"/{repo}:{expected_tag}"), uri
164+
# instance_type is optional for a single-processor config (backward-compatible
165+
# with the whole-tag form this config used before the processor-schema change).
166+
uri_no_instance = image_uris.retrieve(
167+
framework=framework,
168+
region="us-west-2",
169+
version=version,
170+
image_scope="inference",
171+
)
172+
assert uri_no_instance.endswith(f"/{repo}:{expected_tag}"), uri_no_instance
173+
174+
175+
@pytest.mark.parametrize("framework", [f[: -len(".json")] for f in CPU_ONLY_PROCESSOR_FILES])
176+
def test_cpu_only_processor_rejects_gpu_instance(framework):
177+
"""Until a gpu image is added, a gpu instance type is rejected (not silently served cpu)."""
178+
with pytest.raises(ValueError):
179+
image_uris.retrieve(
180+
framework=framework,
181+
region="us-west-2",
182+
version="latest",
183+
image_scope="inference",
184+
instance_type=PROCESSOR_INSTANCE_TYPES["gpu"],
185+
)
186+
187+
136188
@pytest.mark.parametrize("load_config_and_file_name", MULTI_PROCESSOR_FILES, indirect=True)
137189
def test_processor_serving_framework_uris(load_config_and_file_name):
138190
"""CPU/GPU share one config: the instance type selects the per-processor tag tail."""

‎sagemaker-core/tests/unit/image_uris/test_tensorflow.py‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,23 @@ def test_tensorflow_latest_version_is_registered(load_config, scope):
7777
@pytest.mark.parametrize("scope", ["inference", "training"])
7878
@pytest.mark.parametrize("load_config", ["tensorflow.json"], indirect=True)
7979
def test_tensorflow_latest_version_registries_match_previous_release(load_config, scope):
80-
"""The newest version ships in the same regions and accounts as the previous release."""
80+
"""The newest version ships in at least the same regions and accounts as the previous
81+
release. It may additionally carry a newly launched region that is still inside the
82+
image-copy window and therefore not yet backfilled onto the previous release, so this
83+
checks the reference registries are a subset (superset regressions are still caught)."""
8184
version, _ = LATEST[scope]
8285
versions = load_config[scope]["versions"]
83-
assert versions[version]["registries"] == versions[REGISTRY_REFERENCE_VERSION]["registries"]
86+
latest_registries = versions[version]["registries"]
87+
reference_registries = versions[REGISTRY_REFERENCE_VERSION]["registries"]
88+
missing = {
89+
region: account
90+
for region, account in reference_registries.items()
91+
if latest_registries.get(region) != account
92+
}
93+
assert not missing, (
94+
f"latest {scope} version {version} is missing regions/accounts present in the "
95+
f"previous release {REGISTRY_REFERENCE_VERSION}: {missing}"
96+
)
8497

8598

8699
@pytest.mark.parametrize("scope", ["inference", "training"])

0 commit comments

Comments
 (0)