Files
neuron-tai/packages/node/meshnet_node/split_gguf/manifest.py
Dobromir Popov 966aa10854 distributed-gguf-runtime: add CMake skeleton, gRPC harness, split-GGUF provisioning, performance contracts
DGR-019  Lock alpha/beta performance contracts (evidence + contract framework)
DGR-020  Run controlled whole-model GGUF baseline (benchmark results & contracts)
DGR-024  Real generated-gRPC protocol harness (shard_runtime_server.py + tests)
DGR-026  split-GGUF provisioning outside /home (provision script + manifest + tests)
DGR-028  Numbered patch-stack apply & verify (llama_cpp_dependency.py + UPSTREAM_LOCK.json)
DGR-029  Native CMake skeleton + deterministic CPU lane (UPSTREAM_LOCK.json + cmake gating)

New modules:
  packages/node/meshnet_node/dgr_performance/  — performance contract framework
  packages/node/meshnet_node/split_gguf/        — split-GGUF manifest & provisioning
  scripts/provision_split_gguf.py               — artifact provisioning CLI
  tests/test_dgr_performance_contract.py        — contract validation tests
  tests/test_split_gguf_manifest.py             — manifest tests
  tests/test_split_gguf_provision.py            — provisioning tests
  tests/test_shard_runtime_harness.py           — gRPC harness tests
2026-07-23 09:55:00 +03:00

324 lines
12 KiB
Python

"""Exact split-GGUF artifact manifest (DGR-026).
A split-GGUF artifact is only as trustworthy as its binding to the whole-model
artifact it was cut from. This module defines the manifest that makes a set of
split files an *exact*, checkable artifact rather than a pile of files someone
happened to name plausibly: it pins the source artifact's own content hash, the
tokenizer/revision the splits were tokenized against, and — per split — the
exact file name, size, cryptographic hash, and its range/role within the
source.
Quantization and split topology (how many splits, which layers each one
covers) are recipe inputs recorded on the manifest, never constants in this
module. A manifest with two splits and one with twenty are both valid; nothing
here assumes a stage count or a fixed layer range. Provisioning
(:mod:`meshnet_node.split_gguf.provision`) consumes whatever this manifest
declares.
This module mirrors two existing conventions rather than inventing new ones:
the DGR-017 pinned-shard manifest shape (`meshnet_node.glm_alpha.manifest`) for
per-file identity records, and the DGR-003 `DerivativeBinding` range/source
convention (`meshnet_node.runtime_recipe`) for binding a split to its source by
digest and half-open layer range.
"""
from __future__ import annotations
import hashlib
import json
import re
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Mapping
SPLIT_ARTIFACT_MANIFEST_SCHEMA_VERSION = 1
_SHA256_RE = re.compile(r"\A[0-9a-f]{64}\Z")
_REVISION_RE = re.compile(r"\A[0-9a-f]{40}\Z")
class SplitArtifactManifestError(ValueError):
"""Raised when a split-GGUF manifest is missing, malformed, or self-inconsistent."""
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, origin: str) -> Mapping[str, Any]:
if not isinstance(value, Mapping):
raise SplitArtifactManifestError(
f"{what} in {origin} must be a JSON object, got {type(value).__name__}"
)
return value
def _require_text(value: Any, what: str, origin: str) -> str:
if not isinstance(value, str) or not value.strip():
raise SplitArtifactManifestError(f"{what} in {origin} must be a non-empty string")
return value
def _require_int(value: Any, what: str, origin: str, minimum: int = 0) -> int:
if not isinstance(value, int) or isinstance(value, bool):
raise SplitArtifactManifestError(
f"{what} in {origin} must be an integer, got {type(value).__name__}"
)
if value < minimum:
raise SplitArtifactManifestError(f"{what} in {origin} must be >= {minimum}, got {value}")
return value
def _require_sha256(value: Any, what: str, origin: str) -> str:
text = _require_text(value, what, origin)
if not _SHA256_RE.match(text):
raise SplitArtifactManifestError(
f"{what} in {origin} must be a lowercase 64-character hex SHA-256, got {text!r}"
)
return text
def _require_revision(value: Any, what: str, origin: str) -> str:
text = _require_text(value, what, origin)
if not _REVISION_RE.match(text):
raise SplitArtifactManifestError(
f"{what} in {origin} must be a full 40-character commit revision, got {text!r}; "
"a branch name, tag, or short SHA is not an immutable pin"
)
return text
@dataclass(frozen=True)
class SourceArtifact:
"""The whole-model artifact every split in this manifest was cut from."""
artifact_id: str
repo_id: str
revision: str
sha256: str
size_bytes: int
def to_dict(self) -> dict:
return {
"artifact_id": self.artifact_id,
"repo_id": self.repo_id,
"revision": self.revision,
"sha256": self.sha256,
"size_bytes": self.size_bytes,
}
@dataclass(frozen=True)
class TokenizerRef:
"""The exact tokenizer/revision the split artifact's routing assumes."""
repo_id: str
revision: str
sha256: str
def to_dict(self) -> dict:
return {"repo_id": self.repo_id, "revision": self.revision, "sha256": self.sha256}
@dataclass(frozen=True)
class SplitFile:
"""One split-GGUF file: name, size, hash, and its role/range in the source.
`shard_start`/`shard_end` are half-open (end-exclusive), matching the
`DerivativeBinding` protocol convention in `meshnet_node.runtime_recipe`.
They are optional because not every split is a layer range — a shared
embedding or tokenizer-adjacent split may carry only a `role` label — but
when present they must describe a real, non-empty range.
"""
name: str
size_bytes: int
sha256: str
role: str
url: str = ""
shard_start: int | None = None
shard_end: int | None = None
def __post_init__(self) -> None:
if (self.shard_start is None) != (self.shard_end is None):
raise SplitArtifactManifestError(
f"split {self.name!r} must declare both shard_start and shard_end, or neither"
)
if self.shard_start is not None and self.shard_end is not None:
if self.shard_start < 0:
raise SplitArtifactManifestError(f"split {self.name!r} shard_start must be >= 0")
if self.shard_end <= self.shard_start:
raise SplitArtifactManifestError(
f"split {self.name!r} shard_end ({self.shard_end}) must be greater than "
f"shard_start ({self.shard_start}); an empty range covers nothing"
)
@property
def has_range(self) -> bool:
return self.shard_start is not None
def to_dict(self) -> dict:
doc: dict[str, Any] = {
"name": self.name,
"size_bytes": self.size_bytes,
"sha256": self.sha256,
"role": self.role,
"url": self.url,
}
if self.has_range:
doc["shard_start"] = self.shard_start
doc["shard_end"] = self.shard_end
return doc
@dataclass(frozen=True)
class SplitArtifactManifest:
"""A parsed, self-consistent exact split-GGUF artifact manifest."""
schema_version: int
manifest_id: str
manifest_version: str
quantization: str
source: SourceArtifact
tokenizer: TokenizerRef
total_bytes: int
splits: tuple[SplitFile, ...]
raw: Mapping[str, Any]
origin: str = "<memory>"
@property
def digest(self) -> str:
"""Stable identity of this manifest, for binding into the DGR-003 recipe identity."""
return canonical_sha256(self.raw)
def split(self, name: str) -> SplitFile:
for split in self.splits:
if split.name == name:
return split
raise SplitArtifactManifestError(f"split {name!r} is not in {self.origin}")
def to_dict(self) -> dict:
return dict(self.raw)
def _parse_splits(raw: Any, expected_total: int, origin: str) -> tuple[SplitFile, ...]:
if not isinstance(raw, list) or not raw:
raise SplitArtifactManifestError(f"'splits' in {origin} must be a non-empty JSON array")
splits: list[SplitFile] = []
seen_names: set[str] = set()
seen_sha: set[str] = set()
for position, entry in enumerate(raw):
item = _require_mapping(entry, f"splits[{position}]", origin)
name = _require_text(item.get("name"), f"splits[{position}].name", origin)
if name in seen_names:
raise SplitArtifactManifestError(f"duplicate split name {name!r} in {origin}")
seen_names.add(name)
size_bytes = _require_int(item.get("size_bytes"), f"splits[{name}].size_bytes", origin, minimum=1)
sha256 = _require_sha256(item.get("sha256"), f"splits[{name}].sha256", origin)
if sha256 in seen_sha:
raise SplitArtifactManifestError(
f"split {name!r} repeats SHA-256 {sha256}; two distinct splits cannot "
"have the same content digest"
)
seen_sha.add(sha256)
role = _require_text(item.get("role"), f"splits[{name}].role", origin)
url = item.get("url", "")
if not isinstance(url, str):
raise SplitArtifactManifestError(f"splits[{name}].url in {origin} must be a string")
shard_start = item.get("shard_start")
shard_end = item.get("shard_end")
if shard_start is not None:
shard_start = _require_int(shard_start, f"splits[{name}].shard_start", origin, minimum=0)
if shard_end is not None:
shard_end = _require_int(shard_end, f"splits[{name}].shard_end", origin, minimum=1)
splits.append(
SplitFile(
name=name,
size_bytes=size_bytes,
sha256=sha256,
role=role,
url=url,
shard_start=shard_start,
shard_end=shard_end,
)
)
summed = sum(split.size_bytes for split in splits)
if summed != expected_total:
raise SplitArtifactManifestError(
f"declared total_bytes {expected_total} in {origin} does not equal the sum of "
f"the split sizes {summed}; the manifest is not self-consistent"
)
return tuple(splits)
def parse_split_artifact_manifest(data: Any, origin: str = "<memory>") -> SplitArtifactManifest:
"""Validate an already-decoded split-artifact manifest document, failing closed."""
doc = _require_mapping(data, "manifest root", origin)
schema_version = _require_int(doc.get("schema_version"), "'schema_version'", origin, minimum=1)
if schema_version != SPLIT_ARTIFACT_MANIFEST_SCHEMA_VERSION:
raise SplitArtifactManifestError(
f"{origin} declares split-artifact manifest schema version {schema_version}, "
f"but this reader understands version {SPLIT_ARTIFACT_MANIFEST_SCHEMA_VERSION}"
)
manifest_id = _require_text(doc.get("manifest_id"), "'manifest_id'", origin)
manifest_version = _require_text(doc.get("manifest_version"), "'manifest_version'", origin)
quantization = _require_text(doc.get("quantization"), "'quantization'", origin)
source_doc = _require_mapping(doc.get("source"), "'source'", origin)
source = SourceArtifact(
artifact_id=_require_text(source_doc.get("artifact_id"), "source.artifact_id", origin),
repo_id=_require_text(source_doc.get("repo_id"), "source.repo_id", origin),
revision=_require_revision(source_doc.get("revision"), "source.revision", origin),
sha256=_require_sha256(source_doc.get("sha256"), "source.sha256", origin),
size_bytes=_require_int(source_doc.get("size_bytes"), "source.size_bytes", origin, minimum=1),
)
tokenizer_doc = _require_mapping(doc.get("tokenizer"), "'tokenizer'", origin)
tokenizer = TokenizerRef(
repo_id=_require_text(tokenizer_doc.get("repo_id"), "tokenizer.repo_id", origin),
revision=_require_revision(tokenizer_doc.get("revision"), "tokenizer.revision", origin),
sha256=_require_sha256(tokenizer_doc.get("sha256"), "tokenizer.sha256", origin),
)
total_bytes = _require_int(doc.get("total_bytes"), "'total_bytes'", origin, minimum=1)
splits = _parse_splits(doc.get("splits"), total_bytes, origin)
return SplitArtifactManifest(
schema_version=schema_version,
manifest_id=manifest_id,
manifest_version=manifest_version,
quantization=quantization,
source=source,
tokenizer=tokenizer,
total_bytes=total_bytes,
splits=splits,
raw=doc,
origin=origin,
)
def load_split_artifact_manifest(path: Path) -> SplitArtifactManifest:
"""Load and validate a split-artifact manifest from *path*."""
try:
raw = path.read_text(encoding="utf-8")
except OSError as exc:
raise SplitArtifactManifestError(f"cannot read split-artifact manifest {path}: {exc.strerror or exc}") from exc
try:
data = json.loads(raw)
except json.JSONDecodeError as exc:
raise SplitArtifactManifestError(
f"{path} is not valid JSON: {exc.msg} at line {exc.lineno} column {exc.colno}"
) from exc
return parse_split_artifact_manifest(data, origin=str(path))