feat: DGR-017 - Lock the GLM-5.2 Max target and alpha contract
This commit is contained in:
123
packages/node/meshnet_node/glm_alpha/__init__.py
Normal file
123
packages/node/meshnet_node/glm_alpha/__init__.py
Normal file
@@ -0,0 +1,123 @@
|
||||
"""The locked GLM-5.2 Max alpha target: identity, resource plan, and acceptance contract.
|
||||
|
||||
Three files, three jobs:
|
||||
|
||||
- :mod:`~meshnet_node.glm_alpha.manifest` — *is this the exact artifact?* Pinned
|
||||
repository revisions, six shard digests, and the architecture-critical config
|
||||
snapshot they must agree with.
|
||||
- :mod:`~meshnet_node.glm_alpha.planner` — *can this route hold it?* Deterministic
|
||||
memory, KV, and seam arithmetic over the exact artifact bytes, counting unified
|
||||
memory once.
|
||||
- :mod:`~meshnet_node.glm_alpha.contract` — *what would have counted as success?*
|
||||
The acceptance thresholds, locked before the target runs and digest-bound so a
|
||||
later change cannot be silent.
|
||||
|
||||
Nothing here downloads, loads, or executes a model. This package is the contract
|
||||
DGR-018, DGR-019, and DGR-020 are judged against.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .contract import (
|
||||
ALPHA_CONTRACT_ID,
|
||||
ALPHA_CONTRACT_SCHEMA_VERSION,
|
||||
VERDICT_ALPHA,
|
||||
VERDICT_STOP,
|
||||
AlphaContract,
|
||||
AlphaContractError,
|
||||
compute_contract_digest,
|
||||
load_alpha_contract,
|
||||
parse_alpha_contract,
|
||||
require_contract_target,
|
||||
seal_contract,
|
||||
)
|
||||
from .manifest import (
|
||||
ALPHA_QUANTIZATION,
|
||||
ALPHA_SHARD_COUNT,
|
||||
ArchitectureSnapshot,
|
||||
GlmTargetError,
|
||||
Shard,
|
||||
TargetManifest,
|
||||
canonical_sha256,
|
||||
load_architecture_snapshot,
|
||||
load_target_manifest,
|
||||
parse_architecture_snapshot,
|
||||
parse_target_manifest,
|
||||
require_pinned_target,
|
||||
)
|
||||
from .planner import (
|
||||
AGGREGATE_HARD_FIT_FLOOR_GIB,
|
||||
ALPHA_CONTEXT_TOKENS,
|
||||
ALPHA_KV_DTYPE,
|
||||
MIN_LINK_RATE_GBPS,
|
||||
PLACEMENT_IMBALANCE_FACTOR,
|
||||
RECOMMENDED_LINK_RATE_GBPS,
|
||||
RESERVE_FLOOR_GIB,
|
||||
RESERVE_FRACTION,
|
||||
NodeMemory,
|
||||
ResourcePlanError,
|
||||
RouteFit,
|
||||
SeamPlan,
|
||||
TopologyPlan,
|
||||
kv_bytes,
|
||||
plan_all_tiers,
|
||||
plan_route,
|
||||
plan_seams,
|
||||
plan_topology,
|
||||
)
|
||||
|
||||
|
||||
def load_locked_target() -> tuple[AlphaContract, TargetManifest, ArchitectureSnapshot]:
|
||||
"""Load and cross-bind the packaged alpha contract, manifest, and snapshot."""
|
||||
|
||||
contract = load_alpha_contract()
|
||||
manifest = load_target_manifest()
|
||||
snapshot = load_architecture_snapshot()
|
||||
require_contract_target(contract, manifest, snapshot)
|
||||
return contract, manifest, snapshot
|
||||
|
||||
|
||||
__all__ = [
|
||||
"AGGREGATE_HARD_FIT_FLOOR_GIB",
|
||||
"ALPHA_CONTEXT_TOKENS",
|
||||
"ALPHA_CONTRACT_ID",
|
||||
"ALPHA_CONTRACT_SCHEMA_VERSION",
|
||||
"ALPHA_KV_DTYPE",
|
||||
"ALPHA_QUANTIZATION",
|
||||
"ALPHA_SHARD_COUNT",
|
||||
"MIN_LINK_RATE_GBPS",
|
||||
"PLACEMENT_IMBALANCE_FACTOR",
|
||||
"RECOMMENDED_LINK_RATE_GBPS",
|
||||
"RESERVE_FLOOR_GIB",
|
||||
"RESERVE_FRACTION",
|
||||
"VERDICT_ALPHA",
|
||||
"VERDICT_STOP",
|
||||
"AlphaContract",
|
||||
"AlphaContractError",
|
||||
"ArchitectureSnapshot",
|
||||
"GlmTargetError",
|
||||
"NodeMemory",
|
||||
"ResourcePlanError",
|
||||
"RouteFit",
|
||||
"SeamPlan",
|
||||
"Shard",
|
||||
"TargetManifest",
|
||||
"TopologyPlan",
|
||||
"canonical_sha256",
|
||||
"compute_contract_digest",
|
||||
"kv_bytes",
|
||||
"load_alpha_contract",
|
||||
"load_architecture_snapshot",
|
||||
"load_locked_target",
|
||||
"load_target_manifest",
|
||||
"parse_alpha_contract",
|
||||
"parse_architecture_snapshot",
|
||||
"parse_target_manifest",
|
||||
"plan_all_tiers",
|
||||
"plan_route",
|
||||
"plan_seams",
|
||||
"plan_topology",
|
||||
"require_contract_target",
|
||||
"require_pinned_target",
|
||||
"seal_contract",
|
||||
]
|
||||
332
packages/node/meshnet_node/glm_alpha/contract.py
Normal file
332
packages/node/meshnet_node/glm_alpha/contract.py
Normal file
@@ -0,0 +1,332 @@
|
||||
"""The immutable GLM-5.2 Max alpha acceptance contract.
|
||||
|
||||
The contract exists to answer one question that cannot be answered honestly after
|
||||
the fact: *what would have counted as success?*
|
||||
|
||||
Its thresholds are locked before the target ever runs (DGR-017), and DGR-020 reads
|
||||
them back to publish an ``alpha`` or ``stop`` verdict. The whole point is that the
|
||||
gap between those two moments is where a threshold quietly becomes "0.1 tokens/sec
|
||||
was always the goal". So the document carries ``contract_sha256`` over its own
|
||||
canonical content, and :func:`load_alpha_contract` recomputes it on every load. An
|
||||
agent that edits a threshold and forgets the digest is rejected; an agent that
|
||||
edits both has left a diff on a file whose whole purpose is to not change.
|
||||
|
||||
This is a tamper-*evidence* mechanism, not tamper-proofing. It cannot stop a
|
||||
determined rewrite of the file and the digest together — nothing in-repo can. What
|
||||
it does is remove the possibility of a silent one, which is the failure mode that
|
||||
actually happens: a number nudged mid-run, with no reviewer ever seeing that it
|
||||
moved.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from importlib.resources import files
|
||||
from pathlib import Path
|
||||
from typing import Any, Mapping
|
||||
|
||||
from .manifest import (
|
||||
ALPHA_QUANTIZATION,
|
||||
ALPHA_SHARD_COUNT,
|
||||
ArchitectureSnapshot,
|
||||
GlmTargetError,
|
||||
TargetManifest,
|
||||
canonical_sha256,
|
||||
)
|
||||
|
||||
ALPHA_CONTRACT_SCHEMA_VERSION = 1
|
||||
ALPHA_CONTRACT_VERSION = 1
|
||||
ALPHA_CONTRACT_ID = "glm-5.2-max-alpha/v1"
|
||||
|
||||
_CONTRACT_RESOURCE = "alpha-contract.json"
|
||||
|
||||
DIGEST_FIELD = "contract_sha256"
|
||||
|
||||
VERDICT_ALPHA = "alpha"
|
||||
VERDICT_STOP = "stop"
|
||||
|
||||
# Every section the roadmap's acceptance matrix (section 5) locks. A contract that
|
||||
# omits one is not a weaker contract, it is an unreviewable one.
|
||||
REQUIRED_SECTIONS: tuple[str, ...] = (
|
||||
"identity_and_fit",
|
||||
"semantic_correctness",
|
||||
"target_run",
|
||||
"performance",
|
||||
"reliability",
|
||||
"storage",
|
||||
)
|
||||
|
||||
|
||||
class AlphaContractError(GlmTargetError):
|
||||
"""Raised when the alpha contract is missing, malformed, or has been mutated."""
|
||||
|
||||
|
||||
def contract_signing_payload(document: Mapping[str, Any]) -> dict:
|
||||
"""The contract content the digest covers: everything except the digest itself."""
|
||||
unsigned = dict(document)
|
||||
unsigned.pop(DIGEST_FIELD, None)
|
||||
return unsigned
|
||||
|
||||
|
||||
def compute_contract_digest(document: Mapping[str, Any]) -> str:
|
||||
"""SHA-256 over the canonical contract content."""
|
||||
return canonical_sha256(contract_signing_payload(document))
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class AlphaContract:
|
||||
"""A locked, digest-bound alpha acceptance contract."""
|
||||
|
||||
schema_version: int
|
||||
contract_version: int
|
||||
contract_id: str
|
||||
locked_at: str
|
||||
locked_by: str
|
||||
target: Mapping[str, Any]
|
||||
sections: Mapping[str, Mapping[str, Any]]
|
||||
verdicts: tuple[str, ...]
|
||||
amendment_policy: str
|
||||
digest: str
|
||||
raw: Mapping[str, Any]
|
||||
source: str = "<memory>"
|
||||
|
||||
def section(self, name: str) -> Mapping[str, Any]:
|
||||
if name not in self.sections:
|
||||
raise AlphaContractError(f"contract section {name!r} is missing from {self.source}")
|
||||
return self.sections[name]
|
||||
|
||||
def threshold(self, section: str, key: str) -> Any:
|
||||
block = self.section(section)
|
||||
if key not in block:
|
||||
raise AlphaContractError(
|
||||
f"threshold {section}.{key} is not locked in {self.source}; an unlocked "
|
||||
"threshold cannot be used to judge a result"
|
||||
)
|
||||
return block[key]
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return dict(self.raw)
|
||||
|
||||
|
||||
def parse_alpha_contract(data: Any, source: str = "<memory>") -> AlphaContract:
|
||||
"""Validate a contract document and verify it has not been mutated since locking."""
|
||||
if not isinstance(data, Mapping):
|
||||
raise AlphaContractError(f"contract root in {source} must be a JSON object")
|
||||
|
||||
schema_version = data.get("schema_version")
|
||||
if (
|
||||
not isinstance(schema_version, int)
|
||||
or isinstance(schema_version, bool)
|
||||
or schema_version != ALPHA_CONTRACT_SCHEMA_VERSION
|
||||
):
|
||||
raise AlphaContractError(
|
||||
f"{source} declares alpha-contract schema version {schema_version!r}, but this "
|
||||
f"node reads version {ALPHA_CONTRACT_SCHEMA_VERSION}"
|
||||
)
|
||||
|
||||
contract_version = data.get("contract_version")
|
||||
if (
|
||||
not isinstance(contract_version, int)
|
||||
or isinstance(contract_version, bool)
|
||||
or contract_version != ALPHA_CONTRACT_VERSION
|
||||
):
|
||||
raise AlphaContractError(
|
||||
f"{source} declares contract version {contract_version!r}, but this node "
|
||||
f"reads version {ALPHA_CONTRACT_VERSION}"
|
||||
)
|
||||
|
||||
contract_id = data.get("contract_id")
|
||||
if contract_id != ALPHA_CONTRACT_ID:
|
||||
raise AlphaContractError(
|
||||
f"{source} declares contract_id {contract_id!r}, but this node is locked "
|
||||
f"to {ALPHA_CONTRACT_ID!r}"
|
||||
)
|
||||
|
||||
for field in ("locked_at", "locked_by"):
|
||||
value = data.get(field)
|
||||
if not isinstance(value, str) or not value.strip():
|
||||
raise AlphaContractError(f"{source} must carry a non-empty {field}")
|
||||
|
||||
declared = data.get(DIGEST_FIELD)
|
||||
if not isinstance(declared, str) or not declared:
|
||||
raise AlphaContractError(
|
||||
f"{source} carries no {DIGEST_FIELD}; an unsealed contract cannot prove it "
|
||||
"predates the results it judges"
|
||||
)
|
||||
|
||||
computed = compute_contract_digest(data)
|
||||
if computed != declared:
|
||||
raise AlphaContractError(
|
||||
f"{source} has been modified since it was locked: its content hashes to "
|
||||
f"{computed}, but it declares {declared}. Alpha thresholds are locked before "
|
||||
"target execution and may not be weakened afterwards. To change them, open a "
|
||||
"new contract_id under human review; do not edit this one."
|
||||
)
|
||||
|
||||
if not data.get("locked_before_target_execution"):
|
||||
raise AlphaContractError(
|
||||
f"{source} does not assert locked_before_target_execution; a contract written "
|
||||
"after the results are known is not a contract"
|
||||
)
|
||||
|
||||
missing = [name for name in REQUIRED_SECTIONS if not isinstance(data.get(name), Mapping)]
|
||||
if missing:
|
||||
raise AlphaContractError(
|
||||
f"{source} is missing locked acceptance section(s) {missing}"
|
||||
)
|
||||
|
||||
verdicts = data.get("verdicts")
|
||||
if not isinstance(verdicts, list) or sorted(verdicts) != sorted([VERDICT_ALPHA, VERDICT_STOP]):
|
||||
raise AlphaContractError(
|
||||
f"{source} must offer exactly the verdicts {[VERDICT_ALPHA, VERDICT_STOP]}; a "
|
||||
"third outcome is how 'it loaded' becomes a pass"
|
||||
)
|
||||
|
||||
target = data.get("target")
|
||||
if not isinstance(target, Mapping):
|
||||
raise AlphaContractError(f"{source} is missing its 'target' block")
|
||||
for field in (
|
||||
"source_repo_id",
|
||||
"source_revision",
|
||||
"gguf_repo_id",
|
||||
"gguf_revision",
|
||||
"quantization",
|
||||
"target_manifest_sha256",
|
||||
"architecture_snapshot_sha256",
|
||||
"reasoning_effort",
|
||||
):
|
||||
if not target.get(field):
|
||||
raise AlphaContractError(f"{source} target block is missing {field!r}")
|
||||
for field in ("source_revision", "gguf_revision"):
|
||||
if not re.fullmatch(r"[0-9a-f]{40}", str(target[field])):
|
||||
raise AlphaContractError(f"{source} target.{field} is not a full commit revision")
|
||||
for field in ("target_manifest_sha256", "architecture_snapshot_sha256"):
|
||||
if not re.fullmatch(r"[0-9a-f]{64}", str(target[field])):
|
||||
raise AlphaContractError(f"{source} target.{field} is not a SHA-256 digest")
|
||||
if target["quantization"] != ALPHA_QUANTIZATION:
|
||||
raise AlphaContractError(
|
||||
f"{source} targets {target['quantization']!r}, not locked alpha quantization "
|
||||
f"{ALPHA_QUANTIZATION!r}"
|
||||
)
|
||||
if target["reasoning_effort"] != "max":
|
||||
raise AlphaContractError(f"{source} must lock reasoning_effort='max'")
|
||||
shard_count = target.get("shard_count")
|
||||
if (
|
||||
not isinstance(shard_count, int)
|
||||
or isinstance(shard_count, bool)
|
||||
or shard_count != ALPHA_SHARD_COUNT
|
||||
):
|
||||
raise AlphaContractError(
|
||||
f"{source} target.shard_count must be exactly {ALPHA_SHARD_COUNT}"
|
||||
)
|
||||
total_bytes = target.get("total_bytes")
|
||||
if not isinstance(total_bytes, int) or isinstance(total_bytes, bool) or total_bytes <= 0:
|
||||
raise AlphaContractError(f"{source} target.total_bytes must be a positive integer")
|
||||
|
||||
amendment_policy = data.get("amendment_policy")
|
||||
if not isinstance(amendment_policy, str) or not amendment_policy.strip():
|
||||
raise AlphaContractError(f"{source} must state its amendment policy")
|
||||
|
||||
return AlphaContract(
|
||||
schema_version=schema_version,
|
||||
contract_version=contract_version,
|
||||
contract_id=contract_id,
|
||||
locked_at=str(data["locked_at"]),
|
||||
locked_by=str(data["locked_by"]),
|
||||
target=target,
|
||||
sections={name: data[name] for name in REQUIRED_SECTIONS},
|
||||
verdicts=tuple(verdicts),
|
||||
amendment_policy=amendment_policy,
|
||||
digest=declared,
|
||||
raw=data,
|
||||
source=source,
|
||||
)
|
||||
|
||||
|
||||
def require_contract_target(
|
||||
contract: AlphaContract,
|
||||
manifest: TargetManifest,
|
||||
snapshot: ArchitectureSnapshot,
|
||||
) -> None:
|
||||
"""Bind the sealed contract to the exact manifest and architecture snapshot.
|
||||
|
||||
Repository revisions alone do not bind shard LFS objects or derived architecture
|
||||
semantics. Call this before planning, admission, download, or execution.
|
||||
"""
|
||||
|
||||
expected = contract.target
|
||||
actual = {
|
||||
"source_repo_id": manifest.source_repo_id,
|
||||
"source_revision": manifest.source_revision,
|
||||
"gguf_repo_id": manifest.gguf_repo_id,
|
||||
"gguf_revision": manifest.gguf_revision,
|
||||
"quantization": manifest.quantization,
|
||||
"shard_count": len(manifest.shards),
|
||||
"total_bytes": manifest.total_bytes,
|
||||
"target_manifest_sha256": manifest.digest,
|
||||
"architecture_snapshot_sha256": snapshot.digest,
|
||||
}
|
||||
if snapshot.source_repo_id != manifest.source_repo_id:
|
||||
raise AlphaContractError(
|
||||
"architecture snapshot repository does not match the target manifest repository"
|
||||
)
|
||||
if snapshot.source_revision != manifest.source_revision:
|
||||
raise AlphaContractError(
|
||||
"architecture snapshot revision does not match the target manifest revision"
|
||||
)
|
||||
mismatches = {
|
||||
key: (expected.get(key), value)
|
||||
for key, value in actual.items()
|
||||
if expected.get(key) != value
|
||||
}
|
||||
if mismatches:
|
||||
details = ", ".join(
|
||||
f"{key}: locked={locked!r}, actual={value!r}"
|
||||
for key, (locked, value) in sorted(mismatches.items())
|
||||
)
|
||||
raise AlphaContractError(f"target documents do not match the sealed contract: {details}")
|
||||
|
||||
|
||||
def load_alpha_contract(path: Path | None = None) -> AlphaContract:
|
||||
"""Load the packaged alpha contract, or one at ``path``."""
|
||||
if path is not None:
|
||||
source = str(path)
|
||||
try:
|
||||
raw = path.read_text(encoding="utf-8")
|
||||
except OSError as exc:
|
||||
raise AlphaContractError(f"cannot read {source}: {exc.strerror or exc}") from exc
|
||||
else:
|
||||
source = f"packaged {_CONTRACT_RESOURCE}"
|
||||
try:
|
||||
raw = (
|
||||
files("meshnet_node.glm_alpha")
|
||||
.joinpath("data", _CONTRACT_RESOURCE)
|
||||
.read_text(encoding="utf-8")
|
||||
)
|
||||
except (OSError, FileNotFoundError, ModuleNotFoundError) as exc:
|
||||
raise AlphaContractError(
|
||||
f"{source} is missing from this node installation ({type(exc).__name__})"
|
||||
) from exc
|
||||
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
except json.JSONDecodeError as exc:
|
||||
raise AlphaContractError(
|
||||
f"{source} is not valid JSON: {exc.msg} at line {exc.lineno} column {exc.colno}"
|
||||
) from exc
|
||||
|
||||
return parse_alpha_contract(data, source=source)
|
||||
|
||||
|
||||
def seal_contract(document: Mapping[str, Any]) -> dict:
|
||||
"""Return the document with a freshly computed digest.
|
||||
|
||||
This is the only supported way to produce a contract file. It is deliberately
|
||||
*not* called at load time: sealing on load would turn every mutation into a
|
||||
valid contract, which is precisely the property the digest exists to deny.
|
||||
"""
|
||||
sealed = dict(document)
|
||||
sealed[DIGEST_FIELD] = compute_contract_digest(document)
|
||||
return sealed
|
||||
122
packages/node/meshnet_node/glm_alpha/data/alpha-contract.json
Normal file
122
packages/node/meshnet_node/glm_alpha/data/alpha-contract.json
Normal file
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"contract_version": 1,
|
||||
"contract_id": "glm-5.2-max-alpha/v1",
|
||||
"locked_at": "2026-07-13",
|
||||
"locked_by": "DGR-017",
|
||||
"locked_before_target_execution": true,
|
||||
"target": {
|
||||
"source_repo_id": "zai-org/GLM-5.2",
|
||||
"source_revision": "b4734de4facf877f85769a911abafc5283eab3d9",
|
||||
"gguf_repo_id": "unsloth/GLM-5.2-GGUF",
|
||||
"gguf_revision": "abc55e72527792c6e77069c99b4cb7de16fa9f23",
|
||||
"quantization": "UD-IQ1_S",
|
||||
"shard_count": 6,
|
||||
"total_bytes": 216715360960,
|
||||
"target_manifest_sha256": "0b6aed04479d204902bb64c0203f1a46cab26a47b378ecccf85237b63f6c1962",
|
||||
"architecture_snapshot_sha256": "253fbd94b06b42acc4724ec2c7f33914e2d4cc43f54a36dff6af19a80ae6ceb1",
|
||||
"reasoning_effort": "max"
|
||||
},
|
||||
"identity_and_fit": {
|
||||
"require_exact_revisions": true,
|
||||
"require_all_shard_sha256": true,
|
||||
"require_per_node_owned_tensor_report": true,
|
||||
"require_owned_tensor_union_equals_inventory": true,
|
||||
"max_unintended_tensor_overlap": 0,
|
||||
"require_no_single_node_can_admit_complete_recipe": true,
|
||||
"min_node_reserve_fraction": 0.2,
|
||||
"min_node_reserve_gib": 8.0,
|
||||
"require_measured_peak_scratch_inside_reserve": true,
|
||||
"forbid_swap": true,
|
||||
"forbid_overcommit": true,
|
||||
"forbid_mmap_only_fit_claim": true,
|
||||
"forbid_double_counted_unified_memory": true,
|
||||
"aggregate_hard_fit_floor_gib": 224.0,
|
||||
"aggregate_floor_class": "experimental_hard_fit_floor",
|
||||
"recommended_topologies": [
|
||||
"5x64GiB",
|
||||
"3x96GiB",
|
||||
"3x128GiB"
|
||||
],
|
||||
"arithmetic_minimum_requires_measured_placement_evidence": true
|
||||
},
|
||||
"semantic_correctness": {
|
||||
"require_active_moe_routing": true,
|
||||
"require_active_shared_expert": true,
|
||||
"require_active_dsa_lightning_indexer": true,
|
||||
"require_active_sparse_attention": true,
|
||||
"require_active_indexshare_full_and_shared": true,
|
||||
"dense_attention_fallback_satisfies_alpha": false,
|
||||
"require_rendered_reasoning_effort_marker": "<|system|>Reasoning Effort: Max",
|
||||
"f32_seam_fixture_exact_match_tokens": 32,
|
||||
"f32_seam_fixture_requires_exact_match": true,
|
||||
"min_greedy_token_agreement": 0.9,
|
||||
"min_mean_state_cosine_similarity": 0.999,
|
||||
"forbid_nonfinite_tensors": true,
|
||||
"require_fail_closed_on_fingerprint_mismatch": true
|
||||
},
|
||||
"target_run": {
|
||||
"context_tokens": 16384,
|
||||
"kv_dtype": "Q8_0",
|
||||
"concurrency": 1,
|
||||
"prompt_lane_tokens": 4096,
|
||||
"min_output_tokens": 512,
|
||||
"min_output_tokens_with_natural_eos": 128,
|
||||
"require_same_switch_wired_network": true,
|
||||
"min_link_rate_gbps": 2.5,
|
||||
"recommended_link_rate_gbps": 10.0,
|
||||
"require_sentinels": [
|
||||
"coding",
|
||||
"structured_tool_call_json",
|
||||
"multi_step_reasoning"
|
||||
],
|
||||
"require_openai_compatible_response_fields": [
|
||||
"model",
|
||||
"finish_reason",
|
||||
"usage"
|
||||
]
|
||||
},
|
||||
"performance": {
|
||||
"min_median_decode_tokens_per_second": 0.5,
|
||||
"max_ttft_seconds_at_4096_prompt": 600,
|
||||
"max_unexplained_stall_seconds": 60,
|
||||
"warmups": 1,
|
||||
"require_per_stage_telemetry": [
|
||||
"compute",
|
||||
"queue",
|
||||
"kv",
|
||||
"seam_bytes",
|
||||
"seam_latency",
|
||||
"rss",
|
||||
"vram",
|
||||
"backend_timing"
|
||||
],
|
||||
"quality_pass_with_speed_fail_verdict": "stop",
|
||||
"forbid_generalising_results_to_other_hardware": true
|
||||
},
|
||||
"reliability": {
|
||||
"consecutive_clean_cold_starts": 2,
|
||||
"require_cancellation_releases_buffers_and_kv": true,
|
||||
"require_worker_loss_aborts_route": true,
|
||||
"retry_policy": "from_token_zero_on_new_compatible_route",
|
||||
"forbid_silent_kv_migration": true,
|
||||
"require_reject_stale_epoch": true,
|
||||
"require_reject_duplicate_step_id": true,
|
||||
"synthetic_workers_satisfy_alpha": false,
|
||||
"layer_reduced_fixtures_satisfy_alpha": false
|
||||
},
|
||||
"storage": {
|
||||
"mounted_storage_only": true,
|
||||
"forbidden_path_prefixes": [
|
||||
"/home"
|
||||
],
|
||||
"forbid_secrets_in_logs": true,
|
||||
"forbid_unrestricted_prompt_payloads_in_logs": true
|
||||
},
|
||||
"verdicts": [
|
||||
"alpha",
|
||||
"stop"
|
||||
],
|
||||
"amendment_policy": "Thresholds are locked before target execution. They may not be weakened, moved, or reinterpreted after results are known. A change requires a new contract_id and contract_version under human review, and the superseded contract is retained.",
|
||||
"contract_sha256": "aab23220280c053a3c14ff559df3cb5c9e1bf7f0f7188c6519e2e9d9ad036ed9"
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"observed_at": "2026-07-13",
|
||||
"source_repo_id": "zai-org/GLM-5.2",
|
||||
"source_revision": "b4734de4facf877f85769a911abafc5283eab3d9",
|
||||
"source_files": [
|
||||
{
|
||||
"path": "config.json",
|
||||
"size_bytes": 3732,
|
||||
"sha256": "185f93ee6d12548e16a847e279dc0c3c90b1524c970b0866b42fb545747d859a",
|
||||
"url": "https://huggingface.co/zai-org/GLM-5.2/resolve/b4734de4facf877f85769a911abafc5283eab3d9/config.json"
|
||||
},
|
||||
{
|
||||
"path": "chat_template.jinja",
|
||||
"size_bytes": 5076,
|
||||
"sha256": "172dc74a35e1752df75ecfb2b2cf9326d2852bb1379868ebeec9571654489679",
|
||||
"url": "https://huggingface.co/zai-org/GLM-5.2/resolve/b4734de4facf877f85769a911abafc5283eab3d9/chat_template.jinja"
|
||||
},
|
||||
{
|
||||
"path": "generation_config.json",
|
||||
"size_bytes": 194,
|
||||
"sha256": "ac76b43d8683d3b930126870fc8be73d8679308fe752fa1f381096d8354f6a55",
|
||||
"url": "https://huggingface.co/zai-org/GLM-5.2/resolve/b4734de4facf877f85769a911abafc5283eab3d9/generation_config.json"
|
||||
},
|
||||
{
|
||||
"path": "tokenizer_config.json",
|
||||
"size_bytes": 761,
|
||||
"sha256": "98b1271574f41abf89427ae2dda030d94dc9478f0edc5a8bd240db213c6fd5fc",
|
||||
"url": "https://huggingface.co/zai-org/GLM-5.2/resolve/b4734de4facf877f85769a911abafc5283eab3d9/tokenizer_config.json"
|
||||
}
|
||||
],
|
||||
"architecture": {
|
||||
"architectures": [
|
||||
"GlmMoeDsaForCausalLM"
|
||||
],
|
||||
"model_type": "glm_moe_dsa",
|
||||
"num_hidden_layers": 78,
|
||||
"num_nextn_predict_layers": 1,
|
||||
"total_artifact_layers": 79,
|
||||
"first_k_dense_replace": 3,
|
||||
"dense_layers": 3,
|
||||
"sparse_moe_layers": 75,
|
||||
"hidden_size": 6144,
|
||||
"intermediate_size": 12288,
|
||||
"moe_intermediate_size": 2048,
|
||||
"n_routed_experts": 256,
|
||||
"num_experts_per_tok": 8,
|
||||
"n_shared_experts": 1,
|
||||
"scoring_func": "sigmoid",
|
||||
"topk_method": "noaux_tc",
|
||||
"norm_topk_prob": true,
|
||||
"routed_scaling_factor": 2.5,
|
||||
"num_attention_heads": 64,
|
||||
"head_dim": 192,
|
||||
"qk_nope_head_dim": 192,
|
||||
"qk_rope_head_dim": 64,
|
||||
"qk_head_dim": 256,
|
||||
"v_head_dim": 256,
|
||||
"kv_lora_rank": 512,
|
||||
"q_lora_rank": 2048,
|
||||
"mla_cached_values_per_token_per_layer": 576,
|
||||
"index_topk": 2048,
|
||||
"index_head_dim": 128,
|
||||
"index_n_heads": 32,
|
||||
"index_topk_freq": 4,
|
||||
"index_skip_topk_offset": 3,
|
||||
"index_share_for_mtp_iteration": true,
|
||||
"indexer_full_layers": 21,
|
||||
"indexer_shared_layers": 57,
|
||||
"indexer_types_sha256": "ec3b4927af83cf02baf37fb10454c40176ec8bf501ae89334b27a9df5fa17025",
|
||||
"max_position_embeddings": 1048576,
|
||||
"vocab_size": 154880,
|
||||
"rope_theta": 8000000,
|
||||
"dtype": "bfloat16",
|
||||
"tie_word_embeddings": false
|
||||
},
|
||||
"reasoning_effort": {
|
||||
"alpha_mode": "max",
|
||||
"rendered_marker": "<|system|>Reasoning Effort: Max",
|
||||
"template_rule": "effective_reasoning_effort = 'high' if reasoning_effort == 'high' else 'max'",
|
||||
"default_is_max": true,
|
||||
"suppressed_when": "enable_thinking is defined and false",
|
||||
"note": "The template recognises exactly one non-max level ('high'); every other value, including an absent reasoning_effort, renders Max. Alpha therefore asserts the rendered 'Reasoning Effort: Max' marker, not merely the presence of a request field."
|
||||
},
|
||||
"notes": [
|
||||
"indexer_types has 78 entries: layers 0-2 are 'full', then a repeating [shared, shared, shared, full] pattern, giving 21 Full producer layers and 57 Shared consumer layers.",
|
||||
"MLA caches kv_lora_rank (512) + qk_rope_head_dim (64) = 576 values per token per backbone layer.",
|
||||
"num_nextn_predict_layers=1 is the NextN/MTP layer present in the artifact. Alpha does not run MTP; the tensors are loaded or explicitly excluded by a certified recipe and must never be silently reinterpreted as a 79th backbone layer.",
|
||||
"Values are derived from the pinned config.json. The runtime must re-derive them from the artifact and fail closed on contradictory metadata; marketing names are not compatibility identity."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"manifest_version": 1,
|
||||
"observed_at": "2026-07-13",
|
||||
"observed_by": "DGR-017",
|
||||
"alpha_quantization": "UD-IQ1_S",
|
||||
"source_model": {
|
||||
"repo_id": "zai-org/GLM-5.2",
|
||||
"revision": "b4734de4facf877f85769a911abafc5283eab3d9",
|
||||
"last_modified": "2026-07-02T08:08:14.000Z",
|
||||
"weight_license": "mit",
|
||||
"code_documentation_license": "apache-2.0",
|
||||
"url": "https://huggingface.co/zai-org/GLM-5.2",
|
||||
"revision_url": "https://huggingface.co/zai-org/GLM-5.2/tree/b4734de4facf877f85769a911abafc5283eab3d9",
|
||||
"api_url": "https://huggingface.co/api/models/zai-org/GLM-5.2"
|
||||
},
|
||||
"gguf_artifact": {
|
||||
"repo_id": "unsloth/GLM-5.2-GGUF",
|
||||
"revision": "abc55e72527792c6e77069c99b4cb7de16fa9f23",
|
||||
"last_modified": "2026-06-23T15:18:23.000Z",
|
||||
"license": "mit",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF",
|
||||
"revision_url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/tree/abc55e72527792c6e77069c99b4cb7de16fa9f23",
|
||||
"api_url": "https://huggingface.co/api/models/unsloth/GLM-5.2-GGUF",
|
||||
"quantization": "UD-IQ1_S",
|
||||
"shard_count": 6,
|
||||
"total_bytes": 216715360960,
|
||||
"total_gib": 201.832,
|
||||
"total_gb": 216.715,
|
||||
"shards": [
|
||||
{
|
||||
"index": 1,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00001-of-00006.gguf",
|
||||
"size_bytes": 9423744,
|
||||
"sha256": "46b6148389219ae45167cb8124fbb18ef7d432daf619b4faf9e06ea80d3f4777",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00001-of-00006.gguf"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00002-of-00006.gguf",
|
||||
"size_bytes": 49208128256,
|
||||
"sha256": "f2180207285e04fcaa5b8c53ba6e77ad5cc58666b6e7c6b04a5eded3fe8bef09",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00002-of-00006.gguf"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00003-of-00006.gguf",
|
||||
"size_bytes": 49684417024,
|
||||
"sha256": "b1c0c5a302cc8d5d9ea0bcd4467c01db72c26839f820f7e882079582ea0a8d2b",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00003-of-00006.gguf"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00004-of-00006.gguf",
|
||||
"size_bytes": 49396052864,
|
||||
"sha256": "a6a42da6975e29f89866dcde2956e9e50e6ea26635fb5063b74f3973f4f863b6",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00004-of-00006.gguf"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00005-of-00006.gguf",
|
||||
"size_bytes": 49246275936,
|
||||
"sha256": "a4a9851a50db533f21ef824e5d8038f04e6782e7d602d18e5fdd6643f68ccccb",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00005-of-00006.gguf"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00006-of-00006.gguf",
|
||||
"size_bytes": 19171063136,
|
||||
"sha256": "3b767f55df64e0432d52fcf1a14eb47a1ef3bbc91339e2ae220f38602237d7d7",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00006-of-00006.gguf"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnostic_fallback": {
|
||||
"quantization": "UD-IQ1_M",
|
||||
"shard_count": 6,
|
||||
"total_bytes": 228492966624,
|
||||
"total_gib": 212.801,
|
||||
"total_gb": 228.493,
|
||||
"policy": "First diagnostic fallback only if UD-IQ1_S exposes a runtime or quality defect. It does not satisfy the alpha 'lowest published quantization' target unless human review changes the target contract."
|
||||
},
|
||||
"storage": {
|
||||
"mounted_storage_only": true,
|
||||
"forbidden_path_prefixes": [
|
||||
"/home"
|
||||
],
|
||||
"note": "Model artifacts resolve through the machine-specific .env.<hostname> mounted-drive configuration. A path under /home fails admission closed."
|
||||
}
|
||||
}
|
||||
490
packages/node/meshnet_node/glm_alpha/manifest.py
Normal file
490
packages/node/meshnet_node/glm_alpha/manifest.py
Normal file
@@ -0,0 +1,490 @@
|
||||
"""The pinned GLM-5.2 Max target manifest and architecture snapshot.
|
||||
|
||||
This module is the *identity* half of the alpha target contract. It answers one
|
||||
question: is the artifact on this disk the exact artifact alpha was locked
|
||||
against?
|
||||
|
||||
Identity is pinned by repository revision **and** by every shard's LFS SHA-256.
|
||||
A revision alone is not enough — a repository can be force-pushed, and a tag can
|
||||
be moved — and a size alone is not enough, because two different quantizations of
|
||||
the same model land within a rounding error of each other. The manifest therefore
|
||||
carries both, plus the aggregate byte total, and cross-checks the aggregate
|
||||
against the sum of the shards. A manifest whose declared total disagrees with its
|
||||
own shards is rejected rather than trusted, because that is the exact shape a
|
||||
hand-edited "it fits now" manifest takes.
|
||||
|
||||
Nothing here downloads a weight payload. Sizes and hashes come from the Hugging
|
||||
Face metadata API (see ``scripts/refresh_glm_target_manifest.py``); verification
|
||||
against a local file is DGR-018's job, using the digests locked here.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from importlib.resources import files
|
||||
from pathlib import Path
|
||||
from typing import Any, Mapping
|
||||
|
||||
TARGET_MANIFEST_SCHEMA_VERSION = 1
|
||||
ARCHITECTURE_SNAPSHOT_SCHEMA_VERSION = 1
|
||||
|
||||
ALPHA_QUANTIZATION = "UD-IQ1_S"
|
||||
ALPHA_SHARD_COUNT = 6
|
||||
|
||||
_SHA256_RE = re.compile(r"\A[0-9a-f]{64}\Z")
|
||||
|
||||
_MANIFEST_RESOURCE = "target-manifest.json"
|
||||
_ARCHITECTURE_RESOURCE = "architecture-snapshot.json"
|
||||
|
||||
GIB = 1024**3
|
||||
GB = 1000**3
|
||||
|
||||
|
||||
class GlmTargetError(ValueError):
|
||||
"""Raised when the target manifest or architecture snapshot is not the pinned target."""
|
||||
|
||||
|
||||
def canonical_sha256(value: Any) -> str:
|
||||
"""SHA-256 over canonical JSON — the repository's digest convention."""
|
||||
payload = json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
|
||||
return hashlib.sha256(payload.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def _require_mapping(value: Any, what: str) -> Mapping[str, Any]:
|
||||
if not isinstance(value, Mapping):
|
||||
raise GlmTargetError(f"{what} must be a JSON object, got {type(value).__name__}")
|
||||
return value
|
||||
|
||||
|
||||
def _require_text(value: Any, what: str) -> str:
|
||||
if not isinstance(value, str) or not value.strip():
|
||||
raise GlmTargetError(f"{what} must be a non-empty string")
|
||||
return value
|
||||
|
||||
|
||||
def _require_int(value: Any, what: str) -> int:
|
||||
if not isinstance(value, int) or isinstance(value, bool):
|
||||
raise GlmTargetError(f"{what} must be an integer, got {type(value).__name__}")
|
||||
return value
|
||||
|
||||
|
||||
def _require_sha256(value: Any, what: str) -> str:
|
||||
text = _require_text(value, what)
|
||||
if not _SHA256_RE.match(text):
|
||||
raise GlmTargetError(
|
||||
f"{what} must be a lowercase 64-character hex SHA-256, got {text!r}"
|
||||
)
|
||||
return text
|
||||
|
||||
|
||||
def _require_revision(value: Any, what: str) -> str:
|
||||
text = _require_text(value, what)
|
||||
if not re.fullmatch(r"[0-9a-f]{40}", text):
|
||||
raise GlmTargetError(
|
||||
f"{what} must be a full 40-character commit revision, got {text!r}; "
|
||||
"a branch name or short SHA is not an immutable pin"
|
||||
)
|
||||
return text
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Shard:
|
||||
"""One GGUF shard of the alpha artifact."""
|
||||
|
||||
index: int
|
||||
path: str
|
||||
size_bytes: int
|
||||
sha256: str
|
||||
url: str
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"index": self.index,
|
||||
"path": self.path,
|
||||
"size_bytes": self.size_bytes,
|
||||
"sha256": self.sha256,
|
||||
"url": self.url,
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TargetManifest:
|
||||
"""The pinned, self-consistent GLM-5.2 ``UD-IQ1_S`` target."""
|
||||
|
||||
schema_version: int
|
||||
manifest_version: int
|
||||
observed_at: str
|
||||
quantization: str
|
||||
source_repo_id: str
|
||||
source_revision: str
|
||||
source_license: str
|
||||
gguf_repo_id: str
|
||||
gguf_revision: str
|
||||
gguf_license: str
|
||||
total_bytes: int
|
||||
shards: tuple[Shard, ...]
|
||||
raw: Mapping[str, Any]
|
||||
source: str = "<memory>"
|
||||
|
||||
@property
|
||||
def total_gib(self) -> float:
|
||||
return self.total_bytes / GIB
|
||||
|
||||
@property
|
||||
def total_gb(self) -> float:
|
||||
return self.total_bytes / GB
|
||||
|
||||
def shard(self, index: int) -> Shard:
|
||||
for shard in self.shards:
|
||||
if shard.index == index:
|
||||
return shard
|
||||
raise GlmTargetError(f"shard {index} is not in {self.source}")
|
||||
|
||||
@property
|
||||
def digest(self) -> str:
|
||||
"""Stable identity of this manifest, for the DGR-003 runtime recipe."""
|
||||
return canonical_sha256(self.raw)
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return dict(self.raw)
|
||||
|
||||
|
||||
def _parse_shards(raw: Any, expected_count: int, expected_total: int) -> tuple[Shard, ...]:
|
||||
if not isinstance(raw, list):
|
||||
raise GlmTargetError("gguf_artifact.shards must be a JSON array")
|
||||
if len(raw) != expected_count:
|
||||
raise GlmTargetError(
|
||||
f"the alpha artifact has exactly {expected_count} shards, "
|
||||
f"but the manifest lists {len(raw)}"
|
||||
)
|
||||
|
||||
shards: list[Shard] = []
|
||||
seen_index: set[int] = set()
|
||||
seen_sha: set[str] = set()
|
||||
for position, entry in enumerate(raw):
|
||||
item = _require_mapping(entry, f"shards[{position}]")
|
||||
index = _require_int(item.get("index"), f"shards[{position}].index")
|
||||
if index in seen_index:
|
||||
raise GlmTargetError(f"duplicate shard index {index} in the manifest")
|
||||
seen_index.add(index)
|
||||
size_bytes = _require_int(item.get("size_bytes"), f"shards[{index}].size_bytes")
|
||||
if size_bytes <= 0:
|
||||
raise GlmTargetError(f"shards[{index}].size_bytes must be positive")
|
||||
sha256 = _require_sha256(item.get("sha256"), f"shards[{index}].sha256")
|
||||
if sha256 in seen_sha:
|
||||
raise GlmTargetError(
|
||||
f"shard {index} repeats SHA-256 {sha256}; two distinct shards cannot "
|
||||
"have the same content digest"
|
||||
)
|
||||
seen_sha.add(sha256)
|
||||
shards.append(
|
||||
Shard(
|
||||
index=index,
|
||||
path=_require_text(item.get("path"), f"shards[{index}].path"),
|
||||
size_bytes=size_bytes,
|
||||
sha256=sha256,
|
||||
url=_require_text(item.get("url"), f"shards[{index}].url"),
|
||||
)
|
||||
)
|
||||
|
||||
expected_indices = set(range(1, expected_count + 1))
|
||||
if seen_index != expected_indices:
|
||||
missing = sorted(expected_indices - seen_index)
|
||||
raise GlmTargetError(
|
||||
f"the manifest is missing shard(s) {missing}; all {expected_count} "
|
||||
"shards of the alpha artifact must be pinned"
|
||||
)
|
||||
|
||||
summed = sum(shard.size_bytes for shard in shards)
|
||||
if summed != expected_total:
|
||||
raise GlmTargetError(
|
||||
f"declared total_bytes {expected_total} does not equal the sum of the "
|
||||
f"shard sizes {summed}; the manifest is not self-consistent"
|
||||
)
|
||||
|
||||
return tuple(sorted(shards, key=lambda shard: shard.index))
|
||||
|
||||
|
||||
def parse_target_manifest(data: Any, source: str = "<memory>") -> TargetManifest:
|
||||
"""Validate an already-decoded target manifest, failing closed."""
|
||||
doc = _require_mapping(data, f"manifest root in {source}")
|
||||
|
||||
schema_version = _require_int(doc.get("schema_version"), f"'schema_version' in {source}")
|
||||
if schema_version != TARGET_MANIFEST_SCHEMA_VERSION:
|
||||
raise GlmTargetError(
|
||||
f"{source} declares target-manifest schema version {schema_version}, "
|
||||
f"but this node reads version {TARGET_MANIFEST_SCHEMA_VERSION}"
|
||||
)
|
||||
|
||||
quantization = _require_text(doc.get("alpha_quantization"), f"'alpha_quantization' in {source}")
|
||||
if quantization != ALPHA_QUANTIZATION:
|
||||
raise GlmTargetError(
|
||||
f"{source} pins quantization {quantization!r}, but the locked alpha "
|
||||
f"quantization is {ALPHA_QUANTIZATION!r}; a different quantization is a "
|
||||
"different target and requires a human contract change"
|
||||
)
|
||||
|
||||
source_model = _require_mapping(doc.get("source_model"), f"'source_model' in {source}")
|
||||
gguf = _require_mapping(doc.get("gguf_artifact"), f"'gguf_artifact' in {source}")
|
||||
|
||||
gguf_quant = _require_text(gguf.get("quantization"), f"gguf_artifact.quantization in {source}")
|
||||
if gguf_quant != quantization:
|
||||
raise GlmTargetError(
|
||||
f"{source} declares alpha_quantization {quantization!r} but the GGUF "
|
||||
f"artifact block says {gguf_quant!r}"
|
||||
)
|
||||
|
||||
shard_count = _require_int(gguf.get("shard_count"), f"gguf_artifact.shard_count in {source}")
|
||||
if shard_count != ALPHA_SHARD_COUNT:
|
||||
raise GlmTargetError(
|
||||
f"{source} declares {shard_count} shards; the pinned alpha artifact has "
|
||||
f"exactly {ALPHA_SHARD_COUNT}"
|
||||
)
|
||||
|
||||
total_bytes = _require_int(gguf.get("total_bytes"), f"gguf_artifact.total_bytes in {source}")
|
||||
shards = _parse_shards(gguf.get("shards"), shard_count, total_bytes)
|
||||
|
||||
return TargetManifest(
|
||||
schema_version=schema_version,
|
||||
manifest_version=_require_int(doc.get("manifest_version"), f"'manifest_version' in {source}"),
|
||||
observed_at=_require_text(doc.get("observed_at"), f"'observed_at' in {source}"),
|
||||
quantization=quantization,
|
||||
source_repo_id=_require_text(source_model.get("repo_id"), "source_model.repo_id"),
|
||||
source_revision=_require_revision(source_model.get("revision"), "source_model.revision"),
|
||||
source_license=_require_text(source_model.get("weight_license"), "source_model.weight_license"),
|
||||
gguf_repo_id=_require_text(gguf.get("repo_id"), "gguf_artifact.repo_id"),
|
||||
gguf_revision=_require_revision(gguf.get("revision"), "gguf_artifact.revision"),
|
||||
gguf_license=_require_text(gguf.get("license"), "gguf_artifact.license"),
|
||||
total_bytes=total_bytes,
|
||||
shards=shards,
|
||||
raw=doc,
|
||||
source=source,
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ArchitectureSnapshot:
|
||||
"""Architecture-critical metadata derived from the pinned ``config.json``."""
|
||||
|
||||
schema_version: int
|
||||
source_repo_id: str
|
||||
source_revision: str
|
||||
architecture: Mapping[str, Any]
|
||||
reasoning_effort: Mapping[str, Any]
|
||||
source_files: Mapping[str, Mapping[str, Any]]
|
||||
raw: Mapping[str, Any]
|
||||
source: str = "<memory>"
|
||||
|
||||
def __getitem__(self, key: str) -> Any:
|
||||
if key not in self.architecture:
|
||||
raise GlmTargetError(f"architecture field {key!r} is missing from {self.source}")
|
||||
return self.architecture[key]
|
||||
|
||||
@property
|
||||
def digest(self) -> str:
|
||||
return canonical_sha256(self.raw)
|
||||
|
||||
def file_sha256(self, path: str) -> str:
|
||||
entry = self.source_files.get(path)
|
||||
if entry is None:
|
||||
raise GlmTargetError(f"{path!r} is not pinned in {self.source}")
|
||||
return str(entry["sha256"])
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return dict(self.raw)
|
||||
|
||||
|
||||
# Fields the distributed runtime cannot plan or shard without. Absent or
|
||||
# contradictory values fail closed rather than defaulting.
|
||||
REQUIRED_ARCHITECTURE_FIELDS: tuple[str, ...] = (
|
||||
"model_type",
|
||||
"num_hidden_layers",
|
||||
"num_nextn_predict_layers",
|
||||
"total_artifact_layers",
|
||||
"first_k_dense_replace",
|
||||
"dense_layers",
|
||||
"sparse_moe_layers",
|
||||
"hidden_size",
|
||||
"n_routed_experts",
|
||||
"num_experts_per_tok",
|
||||
"n_shared_experts",
|
||||
"kv_lora_rank",
|
||||
"qk_rope_head_dim",
|
||||
"mla_cached_values_per_token_per_layer",
|
||||
"index_topk",
|
||||
"index_head_dim",
|
||||
"indexer_full_layers",
|
||||
"indexer_shared_layers",
|
||||
"max_position_embeddings",
|
||||
"vocab_size",
|
||||
)
|
||||
|
||||
|
||||
def parse_architecture_snapshot(data: Any, source: str = "<memory>") -> ArchitectureSnapshot:
|
||||
"""Validate an architecture snapshot and its internal arithmetic."""
|
||||
doc = _require_mapping(data, f"snapshot root in {source}")
|
||||
|
||||
schema_version = _require_int(doc.get("schema_version"), f"'schema_version' in {source}")
|
||||
if schema_version != ARCHITECTURE_SNAPSHOT_SCHEMA_VERSION:
|
||||
raise GlmTargetError(
|
||||
f"{source} declares architecture-snapshot schema version {schema_version}, "
|
||||
f"but this node reads version {ARCHITECTURE_SNAPSHOT_SCHEMA_VERSION}"
|
||||
)
|
||||
|
||||
arch = _require_mapping(doc.get("architecture"), f"'architecture' in {source}")
|
||||
missing = [field for field in REQUIRED_ARCHITECTURE_FIELDS if field not in arch]
|
||||
if missing:
|
||||
raise GlmTargetError(
|
||||
f"{source} is missing architecture-critical field(s) {missing}; the "
|
||||
"runtime cannot shard or plan an architecture it cannot fully describe"
|
||||
)
|
||||
|
||||
layers = _require_int(arch["num_hidden_layers"], "num_hidden_layers")
|
||||
nextn = _require_int(arch["num_nextn_predict_layers"], "num_nextn_predict_layers")
|
||||
total_layers = _require_int(arch["total_artifact_layers"], "total_artifact_layers")
|
||||
if total_layers != layers + nextn:
|
||||
raise GlmTargetError(
|
||||
f"total_artifact_layers {total_layers} != num_hidden_layers {layers} + "
|
||||
f"num_nextn_predict_layers {nextn}; the NextN layer must be counted "
|
||||
"explicitly, never folded into the backbone"
|
||||
)
|
||||
|
||||
dense = _require_int(arch["dense_layers"], "dense_layers")
|
||||
sparse = _require_int(arch["sparse_moe_layers"], "sparse_moe_layers")
|
||||
if dense != _require_int(arch["first_k_dense_replace"], "first_k_dense_replace"):
|
||||
raise GlmTargetError("dense_layers must equal first_k_dense_replace")
|
||||
if dense + sparse != layers:
|
||||
raise GlmTargetError(
|
||||
f"dense_layers {dense} + sparse_moe_layers {sparse} != num_hidden_layers {layers}"
|
||||
)
|
||||
|
||||
full = _require_int(arch["indexer_full_layers"], "indexer_full_layers")
|
||||
shared = _require_int(arch["indexer_shared_layers"], "indexer_shared_layers")
|
||||
if full + shared != layers:
|
||||
raise GlmTargetError(
|
||||
f"indexer_full_layers {full} + indexer_shared_layers {shared} != "
|
||||
f"num_hidden_layers {layers}; every layer holds exactly one IndexShare role"
|
||||
)
|
||||
if full <= 0:
|
||||
raise GlmTargetError(
|
||||
"indexer_full_layers must be positive; a route with no Full producer layer "
|
||||
"has no index for its Shared consumers to reuse"
|
||||
)
|
||||
|
||||
mla = _require_int(
|
||||
arch["mla_cached_values_per_token_per_layer"], "mla_cached_values_per_token_per_layer"
|
||||
)
|
||||
expected_mla = _require_int(arch["kv_lora_rank"], "kv_lora_rank") + _require_int(
|
||||
arch["qk_rope_head_dim"], "qk_rope_head_dim"
|
||||
)
|
||||
if mla != expected_mla:
|
||||
raise GlmTargetError(
|
||||
f"mla_cached_values_per_token_per_layer {mla} != kv_lora_rank + "
|
||||
f"qk_rope_head_dim ({expected_mla})"
|
||||
)
|
||||
|
||||
reasoning = _require_mapping(doc.get("reasoning_effort"), f"'reasoning_effort' in {source}")
|
||||
if reasoning.get("alpha_mode") != "max":
|
||||
raise GlmTargetError(
|
||||
f"{source} does not lock reasoning_effort=max; alpha is defined as the "
|
||||
"Max reasoning mode of this exact checkpoint"
|
||||
)
|
||||
_require_text(reasoning.get("rendered_marker"), "reasoning_effort.rendered_marker")
|
||||
|
||||
files_raw = doc.get("source_files")
|
||||
if not isinstance(files_raw, list) or not files_raw:
|
||||
raise GlmTargetError(f"'source_files' in {source} must be a non-empty JSON array")
|
||||
source_files: dict[str, Mapping[str, Any]] = {}
|
||||
for position, entry in enumerate(files_raw):
|
||||
item = _require_mapping(entry, f"source_files[{position}]")
|
||||
path = _require_text(item.get("path"), f"source_files[{position}].path")
|
||||
_require_sha256(item.get("sha256"), f"source_files[{path}].sha256")
|
||||
source_files[path] = item
|
||||
for required in ("config.json", "chat_template.jinja"):
|
||||
if required not in source_files:
|
||||
raise GlmTargetError(
|
||||
f"{source} does not pin {required!r}; config and chat-template drift "
|
||||
"silently changes runtime semantics"
|
||||
)
|
||||
|
||||
return ArchitectureSnapshot(
|
||||
schema_version=schema_version,
|
||||
source_repo_id=_require_text(doc.get("source_repo_id"), "source_repo_id"),
|
||||
source_revision=_require_revision(doc.get("source_revision"), "source_revision"),
|
||||
architecture=arch,
|
||||
reasoning_effort=reasoning,
|
||||
source_files=source_files,
|
||||
raw=doc,
|
||||
source=source,
|
||||
)
|
||||
|
||||
|
||||
def _read_resource(resource: str, path: Path | None) -> tuple[str, str]:
|
||||
if path is not None:
|
||||
try:
|
||||
return str(path), path.read_text(encoding="utf-8")
|
||||
except OSError as exc:
|
||||
raise GlmTargetError(f"cannot read {path}: {exc.strerror or exc}") from exc
|
||||
source = f"packaged {resource}"
|
||||
try:
|
||||
raw = files("meshnet_node.glm_alpha").joinpath("data", resource).read_text(encoding="utf-8")
|
||||
except (OSError, FileNotFoundError, ModuleNotFoundError) as exc:
|
||||
raise GlmTargetError(
|
||||
f"{source} is missing from this node installation ({type(exc).__name__})"
|
||||
) from exc
|
||||
return source, raw
|
||||
|
||||
|
||||
def _load_json(resource: str, path: Path | None) -> tuple[str, Any]:
|
||||
source, raw = _read_resource(resource, path)
|
||||
try:
|
||||
return source, json.loads(raw)
|
||||
except json.JSONDecodeError as exc:
|
||||
raise GlmTargetError(
|
||||
f"{source} is not valid JSON: {exc.msg} at line {exc.lineno} column {exc.colno}"
|
||||
) from exc
|
||||
|
||||
|
||||
def load_target_manifest(path: Path | None = None) -> TargetManifest:
|
||||
"""Load the packaged target manifest, or one at ``path``."""
|
||||
source, data = _load_json(_MANIFEST_RESOURCE, path)
|
||||
return parse_target_manifest(data, source=source)
|
||||
|
||||
|
||||
def load_architecture_snapshot(path: Path | None = None) -> ArchitectureSnapshot:
|
||||
"""Load the packaged architecture snapshot, or one at ``path``."""
|
||||
source, data = _load_json(_ARCHITECTURE_RESOURCE, path)
|
||||
return parse_architecture_snapshot(data, source=source)
|
||||
|
||||
|
||||
def require_pinned_target(
|
||||
manifest: TargetManifest,
|
||||
snapshot: ArchitectureSnapshot,
|
||||
*,
|
||||
expected_source_revision: str,
|
||||
expected_gguf_revision: str,
|
||||
) -> None:
|
||||
"""Reject any target whose revisions are not the ones alpha was locked against.
|
||||
|
||||
Callers pass the revisions from the locked alpha contract, so a swapped
|
||||
manifest cannot quietly re-point the target at a different upstream commit.
|
||||
"""
|
||||
if manifest.source_revision != expected_source_revision:
|
||||
raise GlmTargetError(
|
||||
f"source revision {manifest.source_revision} does not match the locked "
|
||||
f"alpha revision {expected_source_revision}"
|
||||
)
|
||||
if manifest.gguf_revision != expected_gguf_revision:
|
||||
raise GlmTargetError(
|
||||
f"GGUF revision {manifest.gguf_revision} does not match the locked alpha "
|
||||
f"revision {expected_gguf_revision}"
|
||||
)
|
||||
if snapshot.source_revision != manifest.source_revision:
|
||||
raise GlmTargetError(
|
||||
f"the architecture snapshot was taken at {snapshot.source_revision} but the "
|
||||
f"manifest pins {manifest.source_revision}; config metadata and weights must "
|
||||
"come from one revision"
|
||||
)
|
||||
522
packages/node/meshnet_node/glm_alpha/planner.py
Normal file
522
packages/node/meshnet_node/glm_alpha/planner.py
Normal file
@@ -0,0 +1,522 @@
|
||||
"""Deterministic memory, KV, and network planner for the GLM-5.2 Max alpha route.
|
||||
|
||||
Everything here is arithmetic over the exact pinned artifact bytes and the exact
|
||||
pinned architecture. There is no measurement, no probing, and no heuristic tuned
|
||||
to a result — the planner is written *before* the target runs so that a later
|
||||
story cannot discover a topology that "works" and then rationalise it.
|
||||
|
||||
Three ideas do the real work.
|
||||
|
||||
**Unified memory is one pool.** On an integrated-GPU machine the "VRAM" the driver
|
||||
reports is carved out of the same physical DRAM the OS is already counting. Adding
|
||||
them produces a node that appears to hold twice what it holds, and the failure mode
|
||||
is not a clean admission rejection — it is an OOM or a swap-thrash halfway through
|
||||
a 200 GiB load. :class:`NodeMemory` therefore refuses to be constructed from an
|
||||
additive claim about one shared pool.
|
||||
|
||||
**The reserve is not optional headroom.** Weights plus KV are not the whole
|
||||
resident cost: backend workspaces, quantization scratch, the graph plan, the
|
||||
process, and the OS all live outside them, and the largest of those scale with the
|
||||
backend rather than with the shard. Alpha reserves ``max(20% of physically usable
|
||||
memory, 8 GiB)`` per node, and the *remainder* is the placement budget.
|
||||
|
||||
**Equal layer counts are not equal bytes.** Embeddings and the output head are
|
||||
endpoint-only; three layers are dense and 75 are MoE; shared experts, indexer
|
||||
tensors, and quant block alignment all skew the per-node share. Until DGR-018/019
|
||||
report measured per-tensor placement, the planner carries an explicit
|
||||
:data:`PLACEMENT_IMBALANCE_FACTOR` and reports the arithmetic minimum and the
|
||||
recommended count as two separate numbers. The arithmetic minimum is a fit probe;
|
||||
it is admissible only with exact measured placement evidence behind it.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
|
||||
from .manifest import GIB, ArchitectureSnapshot, TargetManifest
|
||||
|
||||
# Q8_0 stores 32 int8 quants plus one fp16 scale per block: 34 bytes / 32 values.
|
||||
Q8_0_BYTES_PER_VALUE = 34 / 32
|
||||
F16_BYTES_PER_VALUE = 2.0
|
||||
|
||||
KV_DTYPES: dict[str, float] = {
|
||||
"Q8_0": Q8_0_BYTES_PER_VALUE,
|
||||
"F16": F16_BYTES_PER_VALUE,
|
||||
}
|
||||
|
||||
# The alpha KV configuration, locked by the roadmap.
|
||||
ALPHA_KV_DTYPE = "Q8_0"
|
||||
ALPHA_CONTEXT_TOKENS = 16384
|
||||
ALPHA_CONCURRENCY = 1
|
||||
|
||||
# The reserve every node holds outside its weight-plus-KV placement budget.
|
||||
RESERVE_FRACTION = 0.20
|
||||
RESERVE_FLOOR_GIB = 8.0
|
||||
|
||||
# The aggregate runtime-accessible memory at which the artifact *just* fits.
|
||||
# This is an experimental hard-fit floor, not an operational envelope: it has no
|
||||
# room for a backend that allocates more scratch than another, and none for the
|
||||
# imbalance below.
|
||||
AGGREGATE_HARD_FIT_FLOOR_GIB = 224.0
|
||||
|
||||
# How much more than an equal share the worst-placed node is expected to hold.
|
||||
# 1.10 is the roadmap's recommended-topology column expressed as arithmetic: it
|
||||
# reproduces 10 / 6 / 5 / 3 / 3 nodes for the 32 / 48 / 64 / 96 / 128 GiB tiers.
|
||||
# DGR-019 must replace it with measured per-tensor placement.
|
||||
PLACEMENT_IMBALANCE_FACTOR = 1.10
|
||||
|
||||
# Alpha network floor. A link rate is a bandwidth claim, never a speed claim.
|
||||
MIN_LINK_RATE_GBPS = 2.5
|
||||
RECOMMENDED_LINK_RATE_GBPS = 10.0
|
||||
|
||||
BF16_BYTES = 2
|
||||
DSA_SIDEBAND_INT32_BYTES = 4
|
||||
|
||||
IndexerLayout = Literal["optimized", "conservative"]
|
||||
|
||||
|
||||
class ResourcePlanError(ValueError):
|
||||
"""Raised when a node or route cannot be accounted for honestly."""
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class NodeMemory:
|
||||
"""One node's physically usable memory, counted once.
|
||||
|
||||
``physical_usable_gib`` is what the node can actually place bytes into after
|
||||
firmware and fixed carve-outs — not the marketing capacity, and not a sum of
|
||||
two views of the same DRAM.
|
||||
"""
|
||||
|
||||
name: str
|
||||
physical_usable_gib: float
|
||||
unified: bool
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if not isinstance(self.name, str) or not self.name.strip():
|
||||
raise ResourcePlanError("node name must be a non-empty physical-host identity")
|
||||
if (
|
||||
isinstance(self.physical_usable_gib, bool)
|
||||
or not isinstance(self.physical_usable_gib, (int, float))
|
||||
or not math.isfinite(self.physical_usable_gib)
|
||||
or self.physical_usable_gib <= 0
|
||||
):
|
||||
raise ResourcePlanError(
|
||||
f"node {self.name!r} must declare finite positive usable memory"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_host(
|
||||
cls,
|
||||
name: str,
|
||||
*,
|
||||
system_ram_gib: float,
|
||||
gpu_memory_gib: float = 0.0,
|
||||
unified: bool,
|
||||
) -> "NodeMemory":
|
||||
"""Build a node from a host's reported RAM and GPU memory.
|
||||
|
||||
On a unified machine the GPU memory *is* system RAM, so it is counted once
|
||||
and never added. Passing a non-zero ``gpu_memory_gib`` alongside
|
||||
``unified=True`` is the double-count this project has already decided is a
|
||||
bug (RALPH-CONTEXT runtime decision 16), so it is rejected rather than
|
||||
silently discarded: a caller who believes an integrated GPU adds memory has
|
||||
a wrong model of the machine, and quietly ignoring the argument would let
|
||||
that belief survive.
|
||||
"""
|
||||
if not isinstance(unified, bool):
|
||||
raise ResourcePlanError(f"node {name!r} unified flag must be boolean")
|
||||
for value, label, allow_zero in (
|
||||
(system_ram_gib, "system RAM", False),
|
||||
(gpu_memory_gib, "GPU memory", True),
|
||||
):
|
||||
if (
|
||||
isinstance(value, bool)
|
||||
or not isinstance(value, (int, float))
|
||||
or not math.isfinite(value)
|
||||
or value < 0
|
||||
or (not allow_zero and value == 0)
|
||||
):
|
||||
qualifier = "finite non-negative" if allow_zero else "finite positive"
|
||||
raise ResourcePlanError(f"node {name!r} must declare {qualifier} {label}")
|
||||
if unified:
|
||||
if gpu_memory_gib:
|
||||
raise ResourcePlanError(
|
||||
f"node {name!r} declares unified memory and {gpu_memory_gib} GiB of "
|
||||
"separate GPU memory. Integrated-GPU memory is carved out of the same "
|
||||
"physical DRAM as system RAM; adding them double-counts one pool. "
|
||||
"Pass unified=True with system_ram_gib only."
|
||||
)
|
||||
usable = system_ram_gib
|
||||
else:
|
||||
usable = system_ram_gib + gpu_memory_gib
|
||||
return cls(name=name, physical_usable_gib=usable, unified=unified)
|
||||
|
||||
@property
|
||||
def reserve_gib(self) -> float:
|
||||
"""``max(20% of physically usable memory, 8 GiB)``."""
|
||||
return max(RESERVE_FRACTION * self.physical_usable_gib, RESERVE_FLOOR_GIB)
|
||||
|
||||
@property
|
||||
def placement_budget_gib(self) -> float:
|
||||
"""What remains for weights plus KV after the reserve."""
|
||||
return self.physical_usable_gib - self.reserve_gib
|
||||
|
||||
|
||||
def kv_bytes(
|
||||
snapshot: ArchitectureSnapshot,
|
||||
*,
|
||||
context_tokens: int = ALPHA_CONTEXT_TOKENS,
|
||||
concurrency: int = ALPHA_CONCURRENCY,
|
||||
dtype: str = ALPHA_KV_DTYPE,
|
||||
indexer_layout: IndexerLayout = "conservative",
|
||||
include_indexer: bool = True,
|
||||
) -> int:
|
||||
"""Bytes of MLA (and DSA indexer) KV cache for the whole model.
|
||||
|
||||
``indexer_layout`` is the honest part. Correct DSA only needs indexer keys for
|
||||
the Full producer layers, but the current experimental implementation may
|
||||
allocate them across every backbone layer. Alpha budgets ``conservative``
|
||||
(all 78) so that a route admitted by this planner cannot be surprised by the
|
||||
implementation it actually gets.
|
||||
"""
|
||||
if (
|
||||
not isinstance(context_tokens, int)
|
||||
or isinstance(context_tokens, bool)
|
||||
or context_tokens <= 0
|
||||
or not isinstance(concurrency, int)
|
||||
or isinstance(concurrency, bool)
|
||||
or concurrency <= 0
|
||||
):
|
||||
raise ResourcePlanError("context_tokens and concurrency must be positive integers")
|
||||
if dtype not in KV_DTYPES:
|
||||
raise ResourcePlanError(
|
||||
f"unsupported KV dtype {dtype!r}; alpha locks {ALPHA_KV_DTYPE} "
|
||||
f"(known: {', '.join(sorted(KV_DTYPES))})"
|
||||
)
|
||||
bytes_per_value = KV_DTYPES[dtype]
|
||||
|
||||
layers = int(snapshot["num_hidden_layers"])
|
||||
mla_values = int(snapshot["mla_cached_values_per_token_per_layer"])
|
||||
total_values = mla_values * layers
|
||||
|
||||
if include_indexer:
|
||||
if indexer_layout == "optimized":
|
||||
indexer_layers = int(snapshot["indexer_full_layers"])
|
||||
elif indexer_layout == "conservative":
|
||||
indexer_layers = layers
|
||||
else: # pragma: no cover - Literal keeps this unreachable from typed callers
|
||||
raise ResourcePlanError(f"unknown indexer_layout {indexer_layout!r}")
|
||||
total_values += int(snapshot["index_head_dim"]) * indexer_layers
|
||||
|
||||
return int(total_values * context_tokens * concurrency * bytes_per_value)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TopologyPlan:
|
||||
"""The node count a homogeneous tier needs, and how it was reached."""
|
||||
|
||||
physical_usable_gib: float
|
||||
reserve_gib: float
|
||||
placement_budget_gib: float
|
||||
weight_gib: float
|
||||
kv_gib: float
|
||||
total_placement_gib: float
|
||||
arithmetic_minimum_nodes: int
|
||||
recommended_nodes: int
|
||||
imbalance_factor: float
|
||||
|
||||
@property
|
||||
def is_arithmetic_minimum_topology(self) -> bool:
|
||||
"""True when the recommendation offers no imbalance headroom at all."""
|
||||
return self.recommended_nodes == self.arithmetic_minimum_nodes
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"physical_usable_gib": round(self.physical_usable_gib, 3),
|
||||
"reserve_gib": round(self.reserve_gib, 3),
|
||||
"placement_budget_gib": round(self.placement_budget_gib, 3),
|
||||
"weight_gib": round(self.weight_gib, 3),
|
||||
"kv_gib": round(self.kv_gib, 3),
|
||||
"total_placement_gib": round(self.total_placement_gib, 3),
|
||||
"arithmetic_minimum_nodes": self.arithmetic_minimum_nodes,
|
||||
"recommended_nodes": self.recommended_nodes,
|
||||
"imbalance_factor": self.imbalance_factor,
|
||||
}
|
||||
|
||||
|
||||
def plan_topology(
|
||||
manifest: TargetManifest,
|
||||
snapshot: ArchitectureSnapshot,
|
||||
*,
|
||||
physical_usable_gib: float,
|
||||
context_tokens: int = ALPHA_CONTEXT_TOKENS,
|
||||
concurrency: int = ALPHA_CONCURRENCY,
|
||||
kv_dtype: str = ALPHA_KV_DTYPE,
|
||||
indexer_layout: IndexerLayout = "conservative",
|
||||
imbalance_factor: float = PLACEMENT_IMBALANCE_FACTOR,
|
||||
) -> TopologyPlan:
|
||||
"""Minimum and recommended node count for a homogeneous tier of this size."""
|
||||
if (
|
||||
isinstance(imbalance_factor, bool)
|
||||
or not isinstance(imbalance_factor, (int, float))
|
||||
or not math.isfinite(imbalance_factor)
|
||||
or imbalance_factor < 1.0
|
||||
):
|
||||
raise ResourcePlanError(
|
||||
"imbalance_factor must be finite and at least 1.0; a lower value would "
|
||||
"assume the worst-placed node holds less than an equal share"
|
||||
)
|
||||
|
||||
node = NodeMemory(
|
||||
name=f"{physical_usable_gib:g}GiB-tier",
|
||||
physical_usable_gib=physical_usable_gib,
|
||||
unified=False,
|
||||
)
|
||||
budget = node.placement_budget_gib
|
||||
if budget <= 0:
|
||||
raise ResourcePlanError(
|
||||
f"a {physical_usable_gib:g} GiB node has no placement budget after its "
|
||||
f"{node.reserve_gib:.1f} GiB reserve"
|
||||
)
|
||||
|
||||
weight_gib = manifest.total_bytes / GIB
|
||||
kv_gib = (
|
||||
kv_bytes(
|
||||
snapshot,
|
||||
context_tokens=context_tokens,
|
||||
concurrency=concurrency,
|
||||
dtype=kv_dtype,
|
||||
indexer_layout=indexer_layout,
|
||||
)
|
||||
/ GIB
|
||||
)
|
||||
total = weight_gib + kv_gib
|
||||
|
||||
return TopologyPlan(
|
||||
physical_usable_gib=physical_usable_gib,
|
||||
reserve_gib=node.reserve_gib,
|
||||
placement_budget_gib=budget,
|
||||
weight_gib=weight_gib,
|
||||
kv_gib=kv_gib,
|
||||
total_placement_gib=total,
|
||||
arithmetic_minimum_nodes=math.ceil(total / budget),
|
||||
recommended_nodes=math.ceil(total * imbalance_factor / budget),
|
||||
imbalance_factor=imbalance_factor,
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class RouteFit:
|
||||
"""Whether a concrete, possibly heterogeneous set of nodes can hold the target."""
|
||||
|
||||
node_count: int
|
||||
aggregate_usable_gib: float
|
||||
aggregate_placement_budget_gib: float
|
||||
required_placement_gib: float
|
||||
fits: bool
|
||||
meets_hard_fit_floor: bool
|
||||
no_single_node_can_admit_target: bool
|
||||
headroom_gib: float
|
||||
reasons: tuple[str, ...]
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"node_count": self.node_count,
|
||||
"aggregate_usable_gib": round(self.aggregate_usable_gib, 3),
|
||||
"aggregate_placement_budget_gib": round(self.aggregate_placement_budget_gib, 3),
|
||||
"required_placement_gib": round(self.required_placement_gib, 3),
|
||||
"fits": self.fits,
|
||||
"meets_hard_fit_floor": self.meets_hard_fit_floor,
|
||||
"no_single_node_can_admit_target": self.no_single_node_can_admit_target,
|
||||
"headroom_gib": round(self.headroom_gib, 3),
|
||||
"reasons": list(self.reasons),
|
||||
}
|
||||
|
||||
|
||||
def plan_route(
|
||||
manifest: TargetManifest,
|
||||
snapshot: ArchitectureSnapshot,
|
||||
nodes: list[NodeMemory],
|
||||
*,
|
||||
context_tokens: int = ALPHA_CONTEXT_TOKENS,
|
||||
concurrency: int = ALPHA_CONCURRENCY,
|
||||
kv_dtype: str = ALPHA_KV_DTYPE,
|
||||
indexer_layout: IndexerLayout = "conservative",
|
||||
) -> RouteFit:
|
||||
"""Evaluate a concrete route. Every node's memory is already counted once."""
|
||||
if len(nodes) < 2:
|
||||
raise ResourcePlanError(
|
||||
"the alpha target is distributed by definition; a route needs at least two "
|
||||
"physical nodes"
|
||||
)
|
||||
names = [node.name for node in nodes]
|
||||
if len(set(names)) != len(names):
|
||||
raise ResourcePlanError(
|
||||
"duplicate node names in the route; one physical machine counted twice is "
|
||||
"the same double-count as adding integrated-GPU memory to system RAM"
|
||||
)
|
||||
|
||||
weight_gib = manifest.total_bytes / GIB
|
||||
kv_gib = (
|
||||
kv_bytes(
|
||||
snapshot,
|
||||
context_tokens=context_tokens,
|
||||
concurrency=concurrency,
|
||||
dtype=kv_dtype,
|
||||
indexer_layout=indexer_layout,
|
||||
)
|
||||
/ GIB
|
||||
)
|
||||
required = weight_gib + kv_gib
|
||||
|
||||
aggregate_usable = sum(node.physical_usable_gib for node in nodes)
|
||||
aggregate_budget = sum(node.placement_budget_gib for node in nodes)
|
||||
fits = aggregate_budget >= required
|
||||
largest_budget = max(node.placement_budget_gib for node in nodes)
|
||||
no_single_node = largest_budget < required
|
||||
|
||||
reasons: list[str] = []
|
||||
if not fits:
|
||||
reasons.append(
|
||||
f"aggregate placement budget {aggregate_budget:.1f} GiB is below the "
|
||||
f"{required:.1f} GiB the target needs after each node's reserve"
|
||||
)
|
||||
if not no_single_node:
|
||||
reasons.append(
|
||||
"at least one node could admit the complete target alone; that is a "
|
||||
"single-host run, not distributed alpha"
|
||||
)
|
||||
if aggregate_usable < AGGREGATE_HARD_FIT_FLOOR_GIB:
|
||||
reasons.append(
|
||||
f"aggregate usable memory {aggregate_usable:.1f} GiB is below the "
|
||||
f"{AGGREGATE_HARD_FIT_FLOOR_GIB:g} GiB experimental hard-fit floor"
|
||||
)
|
||||
|
||||
return RouteFit(
|
||||
node_count=len(nodes),
|
||||
aggregate_usable_gib=aggregate_usable,
|
||||
aggregate_placement_budget_gib=aggregate_budget,
|
||||
required_placement_gib=required,
|
||||
fits=fits,
|
||||
meets_hard_fit_floor=aggregate_usable >= AGGREGATE_HARD_FIT_FLOOR_GIB,
|
||||
no_single_node_can_admit_target=no_single_node,
|
||||
headroom_gib=aggregate_budget - required,
|
||||
reasons=tuple(reasons),
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SeamPlan:
|
||||
"""Bytes and latency across the activation seams of a route.
|
||||
|
||||
Bandwidth and latency are reported separately on purpose. Decode moves almost
|
||||
nothing — 12 KiB per token per seam — so a faster link barely helps it. What
|
||||
decode pays is *serial*: every generated token crosses every seam in order, so
|
||||
the cost that matters is ``seams x per-hop latency``. A route that claims to be
|
||||
fast because it is on 10 GbE has confused the two.
|
||||
"""
|
||||
|
||||
node_count: int
|
||||
seam_count: int
|
||||
hidden_size: int
|
||||
bytes_per_token_per_seam: int
|
||||
prefill_bytes_per_seam: int
|
||||
decode_bytes_per_seam_per_token: int
|
||||
dsa_sideband_bytes_per_query: int
|
||||
link_rate_gbps: float
|
||||
meets_alpha_minimum: bool
|
||||
is_recommended_link: bool
|
||||
decode_serialization_ms_per_token: float
|
||||
decode_latency_ms_per_token: float
|
||||
decode_bandwidth_share_ms_per_token: float
|
||||
prefill_serialization_ms: float
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"node_count": self.node_count,
|
||||
"seam_count": self.seam_count,
|
||||
"hidden_size": self.hidden_size,
|
||||
"bytes_per_token_per_seam": self.bytes_per_token_per_seam,
|
||||
"prefill_bytes_per_seam": self.prefill_bytes_per_seam,
|
||||
"decode_bytes_per_seam_per_token": self.decode_bytes_per_seam_per_token,
|
||||
"dsa_sideband_bytes_per_query": self.dsa_sideband_bytes_per_query,
|
||||
"link_rate_gbps": self.link_rate_gbps,
|
||||
"meets_alpha_minimum": self.meets_alpha_minimum,
|
||||
"is_recommended_link": self.is_recommended_link,
|
||||
"decode_serialization_ms_per_token": round(self.decode_serialization_ms_per_token, 4),
|
||||
"decode_latency_ms_per_token": round(self.decode_latency_ms_per_token, 4),
|
||||
"decode_bandwidth_share_ms_per_token": round(
|
||||
self.decode_bandwidth_share_ms_per_token, 4
|
||||
),
|
||||
"prefill_serialization_ms": round(self.prefill_serialization_ms, 3),
|
||||
}
|
||||
|
||||
|
||||
def plan_seams(
|
||||
snapshot: ArchitectureSnapshot,
|
||||
*,
|
||||
node_count: int,
|
||||
context_tokens: int = ALPHA_CONTEXT_TOKENS,
|
||||
link_rate_gbps: float = MIN_LINK_RATE_GBPS,
|
||||
per_hop_latency_ms: float = 0.5,
|
||||
) -> SeamPlan:
|
||||
"""Model seam bytes, wire serialization, and serial per-hop latency separately."""
|
||||
if not isinstance(node_count, int) or isinstance(node_count, bool) or node_count < 2:
|
||||
raise ResourcePlanError("a seam exists only between two nodes")
|
||||
if not isinstance(context_tokens, int) or isinstance(context_tokens, bool) or context_tokens <= 0:
|
||||
raise ResourcePlanError("context_tokens must be a positive integer")
|
||||
if (
|
||||
isinstance(link_rate_gbps, bool)
|
||||
or not isinstance(link_rate_gbps, (int, float))
|
||||
or not math.isfinite(link_rate_gbps)
|
||||
or link_rate_gbps <= 0
|
||||
):
|
||||
raise ResourcePlanError("link_rate_gbps must be finite and positive")
|
||||
if (
|
||||
isinstance(per_hop_latency_ms, bool)
|
||||
or not isinstance(per_hop_latency_ms, (int, float))
|
||||
or not math.isfinite(per_hop_latency_ms)
|
||||
or per_hop_latency_ms < 0
|
||||
):
|
||||
raise ResourcePlanError("per_hop_latency_ms must be finite and non-negative")
|
||||
|
||||
hidden = int(snapshot["hidden_size"])
|
||||
bytes_per_token = hidden * BF16_BYTES
|
||||
seams = node_count - 1
|
||||
|
||||
bits_per_ms = link_rate_gbps * 1e9 / 1e3
|
||||
decode_serialization_ms = (bytes_per_token * 8) / bits_per_ms
|
||||
prefill_serialization_ms = (bytes_per_token * context_tokens * 8) / bits_per_ms
|
||||
|
||||
return SeamPlan(
|
||||
node_count=node_count,
|
||||
seam_count=seams,
|
||||
hidden_size=hidden,
|
||||
bytes_per_token_per_seam=bytes_per_token,
|
||||
prefill_bytes_per_seam=bytes_per_token * context_tokens,
|
||||
decode_bytes_per_seam_per_token=bytes_per_token,
|
||||
dsa_sideband_bytes_per_query=int(snapshot["index_topk"]) * DSA_SIDEBAND_INT32_BYTES,
|
||||
link_rate_gbps=link_rate_gbps,
|
||||
meets_alpha_minimum=link_rate_gbps >= MIN_LINK_RATE_GBPS,
|
||||
is_recommended_link=link_rate_gbps >= RECOMMENDED_LINK_RATE_GBPS,
|
||||
decode_serialization_ms_per_token=decode_serialization_ms * seams,
|
||||
decode_latency_ms_per_token=per_hop_latency_ms * seams,
|
||||
decode_bandwidth_share_ms_per_token=decode_serialization_ms * seams,
|
||||
prefill_serialization_ms=prefill_serialization_ms * seams,
|
||||
)
|
||||
|
||||
|
||||
ALPHA_TIERS_GIB: tuple[float, ...] = (32.0, 48.0, 64.0, 96.0, 128.0)
|
||||
|
||||
|
||||
def plan_all_tiers(
|
||||
manifest: TargetManifest, snapshot: ArchitectureSnapshot
|
||||
) -> dict[str, TopologyPlan]:
|
||||
"""The alpha tier table, recomputed from the pinned artifact and architecture."""
|
||||
return {
|
||||
f"{tier:g}": plan_topology(manifest, snapshot, physical_usable_gib=tier)
|
||||
for tier in ALPHA_TIERS_GIB
|
||||
}
|
||||
@@ -42,3 +42,4 @@ include = ["meshnet_node*"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
meshnet_node = ["*.json"]
|
||||
"meshnet_node.glm_alpha" = ["data/*.json"]
|
||||
|
||||
Reference in New Issue
Block a user