Skip to content
Closed
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
22 changes: 18 additions & 4 deletions docs/GLM53_B12X_KDA_ADAPTIVE_MTP_SPARKCACHE_TP4_QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,26 @@ NCCL error, or traceback.

## Cache namespace impact

The overlay does not change SparkCache wire fields, digest salts, 256-token
geometry, or stored object schemas. Its embedded-MTP digest is SHA-256 over
`glm53-embedded-mtp-runtime-v1`, the target identity, the full vLLM commit,
maximum depth five, and `adaptive:3:32`, separated by zero bytes.
The connector explicitly requests publication schema `tail-cow-v1`. The
`glm53-flash-hybrid` block-page profile maps that operator value to
`page-tail-cow-v1` in `CacheIdentity`, so it selects the tail-specific storage
key rather than the `snapshot-v1` storage key. `snapshot-v1` entries cleanly
miss instead of being interpreted as page-tail objects.

The publication schema does not change the embedded-MTP digest. That digest is
SHA-256 over `glm53-embedded-mtp-runtime-v1`, the target identity, the full
vLLM commit, maximum depth five, and `adaptive:3:32`, separated by zero bytes.
SparkCache binds publication schema independently in `CacheIdentity`, so
changing the MTP digest would add an unrelated identity change.

Including the vLLM revision gives this runtime a distinct draft-state cache
identity from the e105 adaptive-MTP profile. Stored entries therefore
recompute instead of crossing the KDA source boundary without byte-equivalence
evidence.

The profile retains the one-shot clear token
`sparkring-b12x-kda-adaptive-mtp-fastsafetensors-initialization`. Clear tokens
are durable operator-action markers, not cache-identity fields. Rotating this
token solely for the publication-schema selection would request another
root-wide clear even though the tail-specific storage key prevents
cross-schema restore.
2 changes: 1 addition & 1 deletion scripts/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ uses these sanitized inputs:
| File | Role |
|---|---|
| `glm53-flash-b12x-kda-adaptive-mtp-tp4-site.example.yaml` | Four-rank TP4/DCP1 site and 20 GiB FP8 KV reservation per rank |
| `glm53-flash-b12x-kda-mtp5-adaptive-fastsafetensors-sparkcache-tp4-dcp1.example.json` | Adaptive MTP 3→5, 32-step window, fastsafetensors queue one, native SparkCache restore |
| `glm53-flash-b12x-kda-mtp5-adaptive-fastsafetensors-sparkcache-tp4-dcp1.example.json` | Adaptive MTP 3→5, 32-step window, fastsafetensors queue one, SparkCache C++/CUDA restore, and page-tail copy-on-write publication |

Resolve both templates with
`scripts/prepare_glm53_b12x_kda_adaptive_mtp_profile.py`. The resolver rejects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"--async-scheduling",
"--enable-prefix-caching",
"--cudagraph-metrics",
"--kv-transfer-config", "{\"kv_connector\":\"SparkContextCacheConnector\",\"kv_connector_module_path\":\"sparkcache.spark_context_cache_connector\",\"kv_role\":\"kv_both\",\"kv_load_failure_policy\":\"recompute\",\"kv_connector_extra_config\":{\"spark_cache_root\":\"/cache/jit/sparkcache-context\",\"spark_cache_model_profile\":\"glm53-flash-hybrid\",\"spark_cache_target_checkpoint_sha256\":\"a35e6bf2875c1875609b8deaec404c07c6cc80259e4222fc0b51e649498bd6b9\",\"spark_cache_draft_checkpoint_sha256\":\"3255539158b8a4fd199b4d97d89eb5231df3b39a5370881c16099a8059b09e44\",\"spark_cache_draft_policy\":\"separate\",\"spark_cache_store\":true,\"spark_cache_restore\":true,\"spark_cache_scheduler_probe\":\"none\",\"spark_cache_streaming_snapshots\":false,\"spark_cache_native_restore\":true,\"spark_cache_max_bytes\":51539607552,\"spark_cache_low_watermark_bytes\":42949672960,\"spark_cache_ttl_seconds\":0,\"spark_cache_min_span_tokens\":4096,\"spark_cache_max_span_tokens\":524288,\"spark_cache_native_library\":\"/opt/sparkcache-src/sparkcache/native/build-cuda/libspark_cache_placement.so\",\"spark_cache_native_library_sha256\":\"REPLACE_WITH_NATIVE_LIBRARY_SHA256\",\"spark_cache_native_arena_bytes\":268435456,\"spark_cache_native_io_workers\":8,\"spark_cache_load_threads\":2,\"spark_cache_clear_once\":\"sparkring-b12x-kda-adaptive-mtp-fastsafetensors-initialization\"}}"
"--kv-transfer-config", "{\"kv_connector\":\"SparkContextCacheConnector\",\"kv_connector_module_path\":\"sparkcache.spark_context_cache_connector\",\"kv_role\":\"kv_both\",\"kv_load_failure_policy\":\"recompute\",\"kv_connector_extra_config\":{\"spark_cache_root\":\"/cache/jit/sparkcache-context\",\"spark_cache_model_profile\":\"glm53-flash-hybrid\",\"spark_cache_target_checkpoint_sha256\":\"a35e6bf2875c1875609b8deaec404c07c6cc80259e4222fc0b51e649498bd6b9\",\"spark_cache_draft_checkpoint_sha256\":\"3255539158b8a4fd199b4d97d89eb5231df3b39a5370881c16099a8059b09e44\",\"spark_cache_draft_policy\":\"separate\",\"spark_cache_store\":true,\"spark_cache_restore\":true,\"spark_cache_scheduler_probe\":\"none\",\"spark_cache_streaming_snapshots\":false,\"spark_cache_publication_schema\":\"tail-cow-v1\",\"spark_cache_native_restore\":true,\"spark_cache_max_bytes\":51539607552,\"spark_cache_low_watermark_bytes\":42949672960,\"spark_cache_ttl_seconds\":0,\"spark_cache_min_span_tokens\":4096,\"spark_cache_max_span_tokens\":524288,\"spark_cache_native_library\":\"/opt/sparkcache-src/sparkcache/native/build-cuda/libspark_cache_placement.so\",\"spark_cache_native_library_sha256\":\"REPLACE_WITH_NATIVE_LIBRARY_SHA256\",\"spark_cache_native_arena_bytes\":268435456,\"spark_cache_native_io_workers\":8,\"spark_cache_load_threads\":2,\"spark_cache_clear_once\":\"sparkring-b12x-kda-adaptive-mtp-fastsafetensors-initialization\"}}"
],
"extra_volumes": [
{"host": "/REPLACE/GLM53_CACHE_HOST_ROOT", "container": "/cache/jit", "mode": "rw"}
Expand Down
9 changes: 9 additions & 0 deletions scripts/prepare_glm53_b12x_kda_adaptive_mtp_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
MTP_CACHE_IDENTITY_SHA256 = (
"3255539158b8a4fd199b4d97d89eb5231df3b39a5370881c16099a8059b09e44"
)
PUBLICATION_SCHEMA = "tail-cow-v1"


class ResolveError(ValueError):
Expand Down Expand Up @@ -104,6 +105,14 @@ def resolve(
raise ResolveError("adaptive MTP observation window must be 32")
if profile.get("environment", {}).get("VLLM_FASTSAFETENSORS_QUEUE_SIZE") != "1":
raise ResolveError("fastsafetensors queue size must be one")
transfer = json.loads(_argument(profile, "--kv-transfer-config"))
connector_extra = transfer.get("kv_connector_extra_config")
if not isinstance(connector_extra, dict):
raise ResolveError("profile must contain SparkCache connector extra config")
if connector_extra.get("spark_cache_publication_schema") != PUBLICATION_SCHEMA:
raise ResolveError(
"profile must select SparkCache tail-cow-v1 publication"
)
attestation = " ".join(str(value) for value in profile.get("attestation_hook", []))
if SPARKCACHE_SOURCE_SHA256 not in attestation:
raise ResolveError("profile does not attest the integrated SparkCache source")
Expand Down
22 changes: 22 additions & 0 deletions scripts/test_prepare_glm53_b12x_kda_adaptive_mtp_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from prepare_glm53_b12x_kda_adaptive_mtp_profile import (
LEASE_CONTRACT_SHA256,
MTP_CACHE_IDENTITY_SHA256,
PUBLICATION_SCHEMA,
SPARKCACHE_COMMIT,
SPARKCACHE_SOURCE_SHA256,
VLLM_COMMIT,
Expand Down Expand Up @@ -77,6 +78,7 @@ def test_profile_pins_adaptive_mtp_fastsafetensors_and_sparkcache() -> None:
assert extra["spark_cache_native_arena_bytes"] == 256 * 1024**2
assert extra["spark_cache_native_io_workers"] == 8
assert extra["spark_cache_load_threads"] == 2
assert extra["spark_cache_publication_schema"] == PUBLICATION_SCHEMA
assert extra["spark_cache_clear_once"] == (
"sparkring-b12x-kda-adaptive-mtp-fastsafetensors-initialization"
)
Expand Down Expand Up @@ -155,6 +157,26 @@ def test_resolver_rejects_runtime_or_loader_identity_drift() -> None:
resolve(changed, copy.deepcopy(site), **arguments)


def test_resolver_rejects_publication_schema_drift() -> None:
profile = json.loads(PROFILE.read_text(encoding="utf-8"))
site = yaml.safe_load(SITE.read_text(encoding="utf-8"))
transfer_index = profile["extra_vllm_args"].index("--kv-transfer-config") + 1
transfer = json.loads(profile["extra_vllm_args"][transfer_index])
transfer["kv_connector_extra_config"].pop("spark_cache_publication_schema")
profile["extra_vllm_args"][transfer_index] = json.dumps(transfer)

with pytest.raises(ResolveError, match="tail-cow-v1 publication"):
resolve(
profile,
site,
image="image",
image_id="sha256:" + "a" * 64,
parent_image="parent",
parent_image_id="sha256:" + "b" * 64,
native_library_sha256="c" * 64,
)


def test_quickstart_names_the_executable_builder_and_profile_contracts() -> None:
guide = QUICKSTART.read_text(encoding="utf-8")
assert "runtime/glm53-flash-b12x-kda-adaptive-mtp/build-image.sh" in guide
Expand Down
Loading