story: DGR-034 Implement dense-Llama range-aware GGUF ownership
This commit is contained in:
218
packages/node/meshnet_node/range_report.py
Normal file
218
packages/node/meshnet_node/range_report.py
Normal file
@@ -0,0 +1,218 @@
|
||||
"""Authoritative dense-Llama owned-range reports from the loaded engine state.
|
||||
|
||||
DGR-034 loads only the tensors a shard range owns through the Meshnet
|
||||
owned-range loader (``llama_model_params::meshnet_owned_layer_start/end`` in
|
||||
the pinned llama.cpp patch stack). The project-owned ``meshnet-range-report``
|
||||
native tool runs that load and prints a JSON document derived from the loaded
|
||||
model state — the registered tensor set and the backend buffers — never from
|
||||
caller-asserted values. This module is the strict consumer of that document:
|
||||
it parses it into :class:`OwnedRangeReport` and fails closed on any
|
||||
inconsistency, so a range or endpoint claim that the loaded engine state does
|
||||
not back is rejected before it can reach identity, admission, or routing.
|
||||
|
||||
Ownership contract enforced here (dense Llama only):
|
||||
|
||||
- every registered ``blk.N.*`` tensor lies inside the half-open owned range
|
||||
``[start, end)``, and every layer in that range is present — a gapped or
|
||||
out-of-range registration is rejected;
|
||||
- ``token_embd.weight`` is registered only by the head shard (``start == 0``),
|
||||
or by a tail shard whose model ties the output head to the embedding
|
||||
(``end == n_layer`` and no separate ``output.weight``);
|
||||
- ``output_norm.weight`` and ``output.weight`` are registered only by the
|
||||
tail shard (``end == n_layer``);
|
||||
- any other registered tensor name is unexpected and rejected;
|
||||
- byte counts are consistent: an mmap load maps a file span at least the
|
||||
registered tensor bytes and at most the artifact size; a non-mmap load
|
||||
reports a resident allocation at least the registered tensor bytes.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Mapping
|
||||
|
||||
|
||||
class RangeReportError(ValueError):
|
||||
"""A range report is malformed, or the loaded state breaks ownership."""
|
||||
|
||||
|
||||
_DENSE_ARCHITECTURE = "llama"
|
||||
|
||||
_INT_FIELDS = (
|
||||
"n_layer",
|
||||
"file_bytes",
|
||||
"mapped_bytes",
|
||||
"resident_bytes",
|
||||
"registered_tensors",
|
||||
"registered_bytes",
|
||||
)
|
||||
|
||||
_BOOL_FIELDS = (
|
||||
"mmap",
|
||||
"touched",
|
||||
"has_token_embeddings",
|
||||
"has_output_head",
|
||||
"tied_output_head",
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class OwnedRangeReport:
|
||||
"""One validated owned-range load, derived from loaded engine state.
|
||||
|
||||
``start_layer``/``end_layer`` are the authoritative half-open owned range
|
||||
the engine actually registered (the tool already refused a report whose
|
||||
loaded bounds differ from the requested ones). ``has_token_embeddings`` is
|
||||
true for the head shard, and also for a tail shard on a tied-output model
|
||||
(the embedding tensor *is* its output head); ``tied_output_head``
|
||||
disambiguates those two cases. ``mapped_bytes``/``resident_bytes`` come
|
||||
from the backend buffers: with mmap they are the mapped file span holding
|
||||
the owned tensors, without mmap the resident allocation holding them.
|
||||
"""
|
||||
|
||||
architecture: str
|
||||
n_layer: int
|
||||
start_layer: int
|
||||
end_layer: int
|
||||
has_token_embeddings: bool
|
||||
has_output_head: bool
|
||||
tied_output_head: bool
|
||||
mapped_bytes: int
|
||||
resident_bytes: int
|
||||
registered_tensors: int
|
||||
registered_bytes: int
|
||||
file_bytes: int
|
||||
mmap: bool
|
||||
touched: bool
|
||||
vm_size_bytes: int | None
|
||||
vm_rss_bytes: int | None
|
||||
vm_hwm_bytes: int | None
|
||||
|
||||
@property
|
||||
def is_head(self) -> bool:
|
||||
return self.start_layer == 0
|
||||
|
||||
@property
|
||||
def is_tail(self) -> bool:
|
||||
return self.end_layer == self.n_layer
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if self.architecture != _DENSE_ARCHITECTURE:
|
||||
raise RangeReportError(
|
||||
f"owned-range loading supports dense Llama only, got {self.architecture!r}"
|
||||
)
|
||||
if isinstance(self.n_layer, bool) or self.n_layer < 1:
|
||||
raise RangeReportError("report must record a positive GGUF block count")
|
||||
for name in _INT_FIELDS:
|
||||
value = getattr(self, name)
|
||||
if isinstance(value, bool) or not isinstance(value, int) or value < 0:
|
||||
raise RangeReportError(f"report field {name!r} must be a non-negative integer")
|
||||
for name in _BOOL_FIELDS:
|
||||
if not isinstance(getattr(self, name), bool):
|
||||
raise RangeReportError(f"report field {name!r} must be a boolean")
|
||||
if not 0 <= self.start_layer < self.end_layer <= self.n_layer:
|
||||
raise RangeReportError(
|
||||
f"owned range [{self.start_layer}, {self.end_layer}) is empty or "
|
||||
f"outside the model's {self.n_layer} layers"
|
||||
)
|
||||
if self.tied_output_head and not self.is_tail:
|
||||
raise RangeReportError("a tied output head can only belong to the tail shard")
|
||||
expected_embeddings = self.is_head or self.tied_output_head
|
||||
if self.has_token_embeddings != expected_embeddings:
|
||||
raise RangeReportError(
|
||||
"token-embedding registration disagrees with endpoint ownership: "
|
||||
"embeddings belong to the head shard (or to a tied-output tail)"
|
||||
)
|
||||
if self.has_output_head != self.is_tail:
|
||||
raise RangeReportError(
|
||||
"output-head registration disagrees with endpoint ownership: "
|
||||
"the final norm and output head belong to the tail shard"
|
||||
)
|
||||
if self.registered_tensors < 1 or self.registered_bytes < 1:
|
||||
raise RangeReportError("the owned range registered no tensors")
|
||||
if self.file_bytes < 1:
|
||||
raise RangeReportError("report must record the artifact size")
|
||||
if self.mmap:
|
||||
if self.mapped_bytes < self.registered_bytes:
|
||||
raise RangeReportError(
|
||||
"mapped span undercounts the registered owned tensors"
|
||||
)
|
||||
if self.mapped_bytes > self.file_bytes:
|
||||
raise RangeReportError("mapped span exceeds the artifact size")
|
||||
else:
|
||||
if self.mapped_bytes != 0:
|
||||
raise RangeReportError("a non-mmap load must not claim a mapped span")
|
||||
if self.resident_bytes < self.registered_bytes:
|
||||
raise RangeReportError(
|
||||
"resident allocation undercounts the registered owned tensors"
|
||||
)
|
||||
for name in ("vm_size_bytes", "vm_rss_bytes", "vm_hwm_bytes"):
|
||||
value = getattr(self, name)
|
||||
if value is not None and (
|
||||
isinstance(value, bool) or not isinstance(value, int) or value < 0
|
||||
):
|
||||
raise RangeReportError(f"report field {name!r} must be a non-negative integer or null")
|
||||
|
||||
|
||||
def _require_range(doc: Mapping[str, Any], key: str) -> tuple[int, int]:
|
||||
value = doc.get(key)
|
||||
if (
|
||||
not isinstance(value, (list, tuple))
|
||||
or len(value) != 2
|
||||
or any(isinstance(v, bool) or not isinstance(v, int) for v in value)
|
||||
):
|
||||
raise RangeReportError(f"report field {key!r} must be a [start, end] integer pair")
|
||||
return value[0], value[1]
|
||||
|
||||
|
||||
def parse_owned_range_report(doc: Mapping[str, Any]) -> OwnedRangeReport:
|
||||
"""Parse and validate one ``meshnet-range-report`` JSON document.
|
||||
|
||||
Fails closed: a load the tool rejected (``ok: false``), a requested range
|
||||
the loaded state did not match, a gapped or out-of-range registration, an
|
||||
unexpected registered tensor, and any byte-count inconsistency all raise
|
||||
:class:`RangeReportError` instead of producing a report.
|
||||
"""
|
||||
if not isinstance(doc, Mapping):
|
||||
raise RangeReportError("range report must be a JSON object")
|
||||
if doc.get("ok") is not True:
|
||||
error = doc.get("error")
|
||||
detail = f": {error}" if isinstance(error, str) and error else ""
|
||||
raise RangeReportError(f"the owned-range load was rejected{detail}")
|
||||
|
||||
requested = _require_range(doc, "requested_range")
|
||||
reported = _require_range(doc, "reported_range")
|
||||
if requested != reported:
|
||||
raise RangeReportError(
|
||||
f"reported range {reported} does not match the requested range {requested}; "
|
||||
"ownership must be derived from the loaded engine state"
|
||||
)
|
||||
|
||||
for key in ("unexpected_registered_tensors", "missing_owned_layers"):
|
||||
value = doc.get(key)
|
||||
if not isinstance(value, list):
|
||||
raise RangeReportError(f"report field {key!r} must be a list")
|
||||
if value:
|
||||
raise RangeReportError(
|
||||
f"ownership audit failed: {key} is {value!r}; the registered "
|
||||
"tensor set must exactly cover the owned range and its endpoints"
|
||||
)
|
||||
|
||||
architecture = doc.get("architecture")
|
||||
if not isinstance(architecture, str):
|
||||
raise RangeReportError("report field 'architecture' must be a string")
|
||||
|
||||
fields: dict[str, Any] = {}
|
||||
for name in _INT_FIELDS + _BOOL_FIELDS:
|
||||
if name not in doc:
|
||||
raise RangeReportError(f"range report is missing field {name!r}")
|
||||
fields[name] = doc[name]
|
||||
for name in ("vm_size_bytes", "vm_rss_bytes", "vm_hwm_bytes"):
|
||||
fields[name] = doc.get(name)
|
||||
|
||||
return OwnedRangeReport(
|
||||
architecture=architecture,
|
||||
start_layer=reported[0],
|
||||
end_layer=reported[1],
|
||||
**fields,
|
||||
)
|
||||
@@ -28,6 +28,12 @@ One numbered patch per concern (ADR-0024 local seams only):
|
||||
5. `0005-worker-range-report-hook.patch` (worker hooks) exposes the
|
||||
`llama_model_meshnet_range_report` C API the project-owned worker binds to
|
||||
and registers a model-free native fixture test for it.
|
||||
6. `0006-meshnet-range-report-tool.patch` (range reporting) adds the
|
||||
project-owned `meshnet-range-report` tool: it loads one GGUF artifact
|
||||
through the owned-range loader and prints a JSON document derived from the
|
||||
loaded model state — the owned-range report, the registered tensor set
|
||||
audited against the requested ownership, and backend-buffer byte counts.
|
||||
It never builds or runs a compute graph.
|
||||
|
||||
Meshnet routing, Tracker, gRPC, relay, billing, authentication, and telemetry
|
||||
remain outside this directory; the stack is checked for such control-plane
|
||||
|
||||
@@ -10,21 +10,23 @@
|
||||
"method": "git-clone-detached-commit",
|
||||
"workspace": "build/llama.cpp"
|
||||
},
|
||||
"patched_tree": "c0045714735ae5ee7b7334a480d8ac04e03e1b18",
|
||||
"patched_tree": "8f7e87fea6743f0b9744afe44f9e6f9ca3b7d08a",
|
||||
"upstream_license": "MIT",
|
||||
"patch_series": [
|
||||
"0001-cmake-reserve-meshnet-patch-stack-abi-marker.patch",
|
||||
"0002-dense-llama-owned-range-loading.patch",
|
||||
"0003-owned-range-filtered-state-report.patch",
|
||||
"0004-dense-boundary-io-endpoint-guard.patch",
|
||||
"0005-worker-range-report-hook.patch"
|
||||
"0005-worker-range-report-hook.patch",
|
||||
"0006-meshnet-range-report-tool.patch"
|
||||
],
|
||||
"patch_scope": [
|
||||
"Reserved CMake ABI marker only; no execution or model semantics.",
|
||||
"Range loading: dense-Llama owned-range params, validation, and filtered tensor registration with endpoint ownership.",
|
||||
"Filtered state: owned-range report populated from registered tensors and backend buffers, derived never asserted.",
|
||||
"Boundary I/O: endpoint ownership flags and a fail-closed dense graph guard until typed endpoint adapters exist.",
|
||||
"Worker hooks: public C range-report API and the model-free native fixture test the project-owned worker binds to."
|
||||
"Worker hooks: public C range-report API and the model-free native fixture test the project-owned worker binds to.",
|
||||
"Range reporting: project-owned tool that loads one artifact through the owned-range loader and reports derived ownership and buffer-byte state as JSON."
|
||||
],
|
||||
"patch_assumptions": "patches/UPSTREAM-ASSUMPTIONS.json",
|
||||
"build": {
|
||||
@@ -46,7 +48,7 @@
|
||||
"-DGGML_VULKAN=OFF",
|
||||
"-DGGML_METAL=OFF"
|
||||
],
|
||||
"native_targets": ["llama-gguf-hash", "test-meshnet-range-ownership"],
|
||||
"native_targets": ["llama-gguf-hash", "test-meshnet-range-ownership", "meshnet-range-report"],
|
||||
"smoke_binary": "bin/llama-gguf-hash",
|
||||
"smoke_args": ["--help"],
|
||||
"smoke_output_token": "usage",
|
||||
@@ -81,7 +83,9 @@
|
||||
"src/llama-model.h",
|
||||
"src/models/llama.cpp",
|
||||
"tests/CMakeLists.txt",
|
||||
"tests/test-meshnet-range-ownership.cpp"
|
||||
"tests/test-meshnet-range-ownership.cpp",
|
||||
"tools/meshnet-range-report/CMakeLists.txt",
|
||||
"tools/meshnet-range-report/meshnet-range-report.cpp"
|
||||
],
|
||||
"stock_glm_limitations": "This pin may load GLM-5.2 through the dense-MLA compatibility fallback. It does not prove native DSA, IndexShare, MoE semantic correctness, numerical equivalence, performance, or route certification."
|
||||
}
|
||||
|
||||
@@ -0,0 +1,414 @@
|
||||
From: Meshnet <meshnet@invalid>
|
||||
Subject: [PATCH] llama: add dense-Llama owned-range report tool
|
||||
|
||||
Concern: range reporting. Adds the project-owned meshnet-range-report tool:
|
||||
it loads one GGUF artifact through the Meshnet owned-range loader and prints
|
||||
a JSON document derived from the loaded model state — the owned-range
|
||||
report, the registered tensor set audited against the requested ownership,
|
||||
and backend-buffer byte counts (optionally split from repack buffers, plus
|
||||
process resident readings). It never builds or runs a compute graph and
|
||||
never trusts caller-asserted range or endpoint claims.
|
||||
---
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index a9afcff..868793b 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -281,3 +281,6 @@ configure_file(cmake/llama.pc.in
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/llama.pc"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
+
|
||||
+# Meshnet-owned owned-range report tool (patch stack, range-report concern).
|
||||
+add_subdirectory(tools/meshnet-range-report)
|
||||
diff --git a/tools/meshnet-range-report/CMakeLists.txt b/tools/meshnet-range-report/CMakeLists.txt
|
||||
new file mode 100644
|
||||
index 000000000..24401007e
|
||||
--- /dev/null
|
||||
+++ b/tools/meshnet-range-report/CMakeLists.txt
|
||||
@@ -0,0 +1,7 @@
|
||||
+# Meshnet-owned dense-Llama owned-range load/report tool.
|
||||
+#
|
||||
+# Built unconditionally with the patched tree: it exercises the Meshnet
|
||||
+# owned-range loader against real GGUF artifacts and reports only state
|
||||
+# derived from the loaded model (registered tensors, backend buffers).
|
||||
+add_executable(meshnet-range-report meshnet-range-report.cpp)
|
||||
+target_link_libraries(meshnet-range-report PRIVATE llama)
|
||||
diff --git a/tools/meshnet-range-report/meshnet-range-report.cpp b/tools/meshnet-range-report/meshnet-range-report.cpp
|
||||
new file mode 100644
|
||||
index 000000000..49a5eb2a0
|
||||
--- /dev/null
|
||||
+++ b/tools/meshnet-range-report/meshnet-range-report.cpp
|
||||
@@ -0,0 +1,373 @@
|
||||
+// Meshnet-owned dense-Llama owned-range load/report tool.
|
||||
+//
|
||||
+// Loads one GGUF artifact through the Meshnet owned-range loader
|
||||
+// (llama_model_params::meshnet_owned_layer_start/end) and prints a single
|
||||
+// JSON report derived from the loaded model state — registered tensors and
|
||||
+// backend buffers, never caller-asserted values. The audit fails closed when
|
||||
+// the registered tensor set disagrees with the requested ownership: every
|
||||
+// registered per-layer tensor must lie inside [start, end), the token
|
||||
+// embedding may be registered only by the head shard (start == 0) or by a
|
||||
+// tail shard whose model ties the output head to the embedding, and the
|
||||
+// final norm plus output head may be registered only by the tail shard
|
||||
+// (end == n_layer).
|
||||
+
|
||||
+#include "ggml.h"
|
||||
+#include "llama.h"
|
||||
+
|
||||
+#include "../../src/llama-model.h"
|
||||
+
|
||||
+#include <cstdint>
|
||||
+#include <cstdio>
|
||||
+#include <cstdlib>
|
||||
+#include <cstring>
|
||||
+#include <set>
|
||||
+#include <string>
|
||||
+#include <sys/stat.h>
|
||||
+#include <vector>
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
+constexpr int kExitUsage = 2;
|
||||
+constexpr int kExitLoad = 3;
|
||||
+constexpr int kExitAudit = 4;
|
||||
+
|
||||
+std::string g_log_tail;
|
||||
+
|
||||
+void capture_log(enum ggml_log_level level, const char * text, void *) {
|
||||
+ if (level >= GGML_LOG_LEVEL_ERROR) {
|
||||
+ g_log_tail += text;
|
||||
+ if (g_log_tail.size() > 512) {
|
||||
+ g_log_tail.erase(0, g_log_tail.size() - 512);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+std::string json_escape(const std::string & value) {
|
||||
+ std::string out;
|
||||
+ for (const char c : value) {
|
||||
+ if (c == '"' || c == '\\') {
|
||||
+ out += '\\';
|
||||
+ out += c;
|
||||
+ } else if (c == '\n') {
|
||||
+ out += "\\n";
|
||||
+ } else if (c == '\r') {
|
||||
+ // drop carriage returns from embedded log text
|
||||
+ } else {
|
||||
+ out += c;
|
||||
+ }
|
||||
+ }
|
||||
+ return out;
|
||||
+}
|
||||
+
|
||||
+std::string json_string_array(const std::vector<std::string> & items) {
|
||||
+ std::string out = "[";
|
||||
+ for (size_t i = 0; i < items.size(); ++i) {
|
||||
+ if (i) {
|
||||
+ out += ", ";
|
||||
+ }
|
||||
+ out += "\"" + json_escape(items[i]) + "\"";
|
||||
+ }
|
||||
+ return out + "]";
|
||||
+}
|
||||
+
|
||||
+std::string json_int_array(const std::vector<int> & items) {
|
||||
+ std::string out = "[";
|
||||
+ for (size_t i = 0; i < items.size(); ++i) {
|
||||
+ if (i) {
|
||||
+ out += ", ";
|
||||
+ }
|
||||
+ out += std::to_string(items[i]);
|
||||
+ }
|
||||
+ return out + "]";
|
||||
+}
|
||||
+
|
||||
+int fail(int code, const std::string & error) {
|
||||
+ std::string detail = error;
|
||||
+ if (!g_log_tail.empty()) {
|
||||
+ detail += ": " + g_log_tail;
|
||||
+ }
|
||||
+ std::printf("{\"ok\": false, \"error\": \"%s\"}\n", json_escape(detail).c_str());
|
||||
+ return code;
|
||||
+}
|
||||
+
|
||||
+bool parse_nonnegative(const char * text, int & out) {
|
||||
+ if (text == nullptr || *text == '\0' || *text == '-') {
|
||||
+ return false;
|
||||
+ }
|
||||
+ char * end = nullptr;
|
||||
+ const long value = std::strtol(text, &end, 10);
|
||||
+ if (end == text || *end != '\0' || value > INT32_MAX) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ out = static_cast<int>(value);
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+uint64_t file_size(const std::string & path) {
|
||||
+ struct stat st;
|
||||
+ return ::stat(path.c_str(), &st) == 0 ? static_cast<uint64_t>(st.st_size) : 0;
|
||||
+}
|
||||
+
|
||||
+struct proc_status {
|
||||
+ uint64_t vm_size = 0;
|
||||
+ uint64_t vm_rss = 0;
|
||||
+ uint64_t vm_hwm = 0;
|
||||
+ bool valid = false;
|
||||
+};
|
||||
+
|
||||
+proc_status read_proc_status() {
|
||||
+ proc_status out;
|
||||
+#ifdef __linux__
|
||||
+ FILE * f = std::fopen("/proc/self/status", "r");
|
||||
+ if (!f) {
|
||||
+ return out;
|
||||
+ }
|
||||
+ char line[256];
|
||||
+ while (std::fgets(line, sizeof(line), f)) {
|
||||
+ uint64_t kb = 0;
|
||||
+ if (std::sscanf(line, "VmSize: %lu kB", &kb) == 1) {
|
||||
+ out.vm_size = kb * 1024;
|
||||
+ } else if (std::sscanf(line, "VmRSS: %lu kB", &kb) == 1) {
|
||||
+ out.vm_rss = kb * 1024;
|
||||
+ } else if (std::sscanf(line, "VmHWM: %lu kB", &kb) == 1) {
|
||||
+ out.vm_hwm = kb * 1024;
|
||||
+ }
|
||||
+ }
|
||||
+ std::fclose(f);
|
||||
+ out.valid = true;
|
||||
+#endif
|
||||
+ return out;
|
||||
+}
|
||||
+
|
||||
+void usage(const char * argv0) {
|
||||
+ std::fprintf(stderr,
|
||||
+ "usage: %s --model PATH --start N --end M [--no-mmap] [--no-extra-bufts] [--touch]\n"
|
||||
+ "loads one dense-Llama GGUF through the Meshnet owned-range loader and\n"
|
||||
+ "prints a JSON report derived from the loaded model state\n",
|
||||
+ argv0);
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+int main(int argc, char ** argv) {
|
||||
+ std::string model_path;
|
||||
+ int start = -1;
|
||||
+ int end = -1;
|
||||
+ bool use_mmap = true;
|
||||
+ bool use_extra_bufts = true;
|
||||
+ bool touch = false;
|
||||
+
|
||||
+ for (int i = 1; i < argc; ++i) {
|
||||
+ const std::string arg = argv[i];
|
||||
+ if (arg == "--model" && i + 1 < argc) {
|
||||
+ model_path = argv[++i];
|
||||
+ } else if (arg == "--start" && i + 1 < argc) {
|
||||
+ if (!parse_nonnegative(argv[++i], start)) {
|
||||
+ usage(argv[0]);
|
||||
+ return kExitUsage;
|
||||
+ }
|
||||
+ } else if (arg == "--end" && i + 1 < argc) {
|
||||
+ if (!parse_nonnegative(argv[++i], end)) {
|
||||
+ usage(argv[0]);
|
||||
+ return kExitUsage;
|
||||
+ }
|
||||
+ } else if (arg == "--no-mmap") {
|
||||
+ use_mmap = false;
|
||||
+ } else if (arg == "--no-extra-bufts") {
|
||||
+ use_extra_bufts = false;
|
||||
+ } else if (arg == "--touch") {
|
||||
+ touch = true;
|
||||
+ } else {
|
||||
+ usage(argv[0]);
|
||||
+ return kExitUsage;
|
||||
+ }
|
||||
+ }
|
||||
+ if (model_path.empty() || start < 0 || end < 0) {
|
||||
+ usage(argv[0]);
|
||||
+ return kExitUsage;
|
||||
+ }
|
||||
+
|
||||
+ llama_log_set(capture_log, nullptr);
|
||||
+ llama_backend_init();
|
||||
+
|
||||
+ llama_model_params params = llama_model_default_params();
|
||||
+ params.meshnet_owned_layer_start = start;
|
||||
+ params.meshnet_owned_layer_end = end;
|
||||
+ params.use_mmap = use_mmap;
|
||||
+ params.use_extra_bufts = use_extra_bufts;
|
||||
+ params.progress_callback = nullptr;
|
||||
+
|
||||
+ llama_model * model = llama_model_load_from_file(model_path.c_str(), params);
|
||||
+ if (model == nullptr) {
|
||||
+ return fail(kExitLoad, "owned-range load rejected the artifact or range");
|
||||
+ }
|
||||
+
|
||||
+ llama_meshnet_range_report report = {};
|
||||
+ if (!llama_model_meshnet_range_report(model, &report)) {
|
||||
+ llama_model_free(model);
|
||||
+ return fail(kExitLoad, "loaded model carries no owned-range report");
|
||||
+ }
|
||||
+
|
||||
+ char arch_buf[128] = {};
|
||||
+ std::string arch;
|
||||
+ if (llama_model_meta_val_str(model, "general.architecture", arch_buf, sizeof(arch_buf)) >= 0) {
|
||||
+ arch = arch_buf;
|
||||
+ }
|
||||
+ const int n_layer = llama_model_n_layer(model);
|
||||
+ const uint64_t bytes_on_disk = file_size(model_path);
|
||||
+
|
||||
+ // Audit the registered tensor set against the requested ownership.
|
||||
+ const auto & tensors = llama_internal_get_tensor_map(model);
|
||||
+ bool has_embd = false;
|
||||
+ bool has_out_norm = false;
|
||||
+ bool has_out = false;
|
||||
+ std::set<int> owned_layers;
|
||||
+ std::vector<std::string> unexpected;
|
||||
+ uint64_t registered_bytes = 0;
|
||||
+ for (const auto & entry : tensors) {
|
||||
+ const std::string & name = entry.first;
|
||||
+ registered_bytes += ggml_nbytes(entry.second);
|
||||
+ if (name == "token_embd.weight") {
|
||||
+ has_embd = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (name == "output_norm.weight") {
|
||||
+ has_out_norm = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (name == "output.weight") {
|
||||
+ has_out = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ int block = -1;
|
||||
+ if (std::sscanf(name.c_str(), "blk.%d.", &block) == 1 && block >= 0) {
|
||||
+ owned_layers.insert(block);
|
||||
+ continue;
|
||||
+ }
|
||||
+ unexpected.push_back(name);
|
||||
+ }
|
||||
+
|
||||
+ // A tail shard whose model ties the output head to the token embedding
|
||||
+ // registers token_embd.weight as its output head instead of output.weight.
|
||||
+ const bool tied_tail = end == n_layer && has_embd && !has_out;
|
||||
+ const bool expect_embd = start == 0 || tied_tail;
|
||||
+
|
||||
+ std::vector<int> missing_layers;
|
||||
+ for (int i = start; i < end; ++i) {
|
||||
+ if (!owned_layers.count(i)) {
|
||||
+ missing_layers.push_back(i);
|
||||
+ }
|
||||
+ }
|
||||
+ std::vector<int> outside_layers;
|
||||
+ for (const int block : owned_layers) {
|
||||
+ if (block < start || block >= end) {
|
||||
+ outside_layers.push_back(block);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ std::vector<std::string> mismatches;
|
||||
+ if (report.start_layer != start || report.end_layer != end) {
|
||||
+ mismatches.push_back("reported range differs from the requested range");
|
||||
+ }
|
||||
+ if (has_embd != expect_embd) {
|
||||
+ mismatches.push_back("token-embedding registration disagrees with endpoint ownership");
|
||||
+ }
|
||||
+ if ((end == n_layer) && !has_out_norm) {
|
||||
+ mismatches.push_back("tail range is missing the final norm");
|
||||
+ }
|
||||
+ if ((end == n_layer) && !has_out && !has_embd) {
|
||||
+ mismatches.push_back("tail range is missing the output head");
|
||||
+ }
|
||||
+ if ((end != n_layer) && (has_out_norm || has_out)) {
|
||||
+ mismatches.push_back("non-tail range registered tail-only tensors");
|
||||
+ }
|
||||
+ if (report.has_token_embeddings != has_embd) {
|
||||
+ mismatches.push_back("reported embedding ownership disagrees with registered tensors");
|
||||
+ }
|
||||
+ if (report.has_output_head != (end == n_layer)) {
|
||||
+ mismatches.push_back("reported output-head ownership disagrees with endpoint ownership");
|
||||
+ }
|
||||
+ if (!missing_layers.empty()) {
|
||||
+ mismatches.push_back("owned range has missing per-layer tensors");
|
||||
+ }
|
||||
+ if (!outside_layers.empty()) {
|
||||
+ mismatches.push_back("registered per-layer tensors lie outside the owned range");
|
||||
+ }
|
||||
+ if (!unexpected.empty()) {
|
||||
+ mismatches.push_back("registered tensors outside the dense-Llama ownership vocabulary");
|
||||
+ }
|
||||
+ if (use_mmap && report.mapped_bytes < registered_bytes) {
|
||||
+ mismatches.push_back("mapped span undercounts the registered tensors");
|
||||
+ }
|
||||
+ if (!use_mmap && report.resident_bytes < registered_bytes) {
|
||||
+ mismatches.push_back("resident allocation undercounts the registered tensors");
|
||||
+ }
|
||||
+
|
||||
+ if (touch) {
|
||||
+ volatile uint64_t sink = 0;
|
||||
+ for (const auto & entry : tensors) {
|
||||
+ const auto * data = static_cast<const volatile uint8_t *>(entry.second->data);
|
||||
+ const size_t nbytes = ggml_nbytes(entry.second);
|
||||
+ for (size_t i = 0; i < nbytes; i += 4096) {
|
||||
+ sink += data[i];
|
||||
+ }
|
||||
+ }
|
||||
+ (void) sink;
|
||||
+ }
|
||||
+
|
||||
+ const proc_status proc = read_proc_status();
|
||||
+
|
||||
+ if (!mismatches.empty()) {
|
||||
+ llama_model_free(model);
|
||||
+ return fail(kExitAudit, "ownership audit failed: " + json_string_array(mismatches));
|
||||
+ }
|
||||
+
|
||||
+ std::printf(
|
||||
+ "{\n"
|
||||
+ " \"ok\": true,\n"
|
||||
+ " \"model\": \"%s\",\n"
|
||||
+ " \"architecture\": \"%s\",\n"
|
||||
+ " \"n_layer\": %d,\n"
|
||||
+ " \"file_bytes\": %llu,\n"
|
||||
+ " \"requested_range\": [%d, %d],\n"
|
||||
+ " \"reported_range\": [%d, %d],\n"
|
||||
+ " \"mmap\": %s,\n"
|
||||
+ " \"touched\": %s,\n"
|
||||
+ " \"use_extra_bufts\": %s,\n"
|
||||
+ " \"has_token_embeddings\": %s,\n"
|
||||
+ " \"has_output_head\": %s,\n"
|
||||
+ " \"tied_output_head\": %s,\n"
|
||||
+ " \"mapped_bytes\": %llu,\n"
|
||||
+ " \"resident_bytes\": %llu,\n"
|
||||
+ " \"registered_tensors\": %d,\n"
|
||||
+ " \"registered_bytes\": %llu,\n"
|
||||
+ " \"unexpected_registered_tensors\": [],\n"
|
||||
+ " \"missing_owned_layers\": [],\n"
|
||||
+ " \"vm_size_bytes\": %llu,\n"
|
||||
+ " \"vm_rss_bytes\": %llu,\n"
|
||||
+ " \"vm_hwm_bytes\": %llu\n"
|
||||
+ "}\n",
|
||||
+ json_escape(model_path).c_str(),
|
||||
+ json_escape(arch).c_str(),
|
||||
+ n_layer,
|
||||
+ (unsigned long long) bytes_on_disk,
|
||||
+ start, end,
|
||||
+ report.start_layer, report.end_layer,
|
||||
+ use_mmap ? "true" : "false",
|
||||
+ touch ? "true" : "false",
|
||||
+ use_extra_bufts ? "true" : "false",
|
||||
+ report.has_token_embeddings ? "true" : "false",
|
||||
+ report.has_output_head ? "true" : "false",
|
||||
+ tied_tail ? "true" : "false",
|
||||
+ (unsigned long long) report.mapped_bytes,
|
||||
+ (unsigned long long) report.resident_bytes,
|
||||
+ (int) tensors.size(),
|
||||
+ (unsigned long long) registered_bytes,
|
||||
+ (unsigned long long) proc.vm_size,
|
||||
+ (unsigned long long) proc.vm_rss,
|
||||
+ (unsigned long long) proc.vm_hwm);
|
||||
+
|
||||
+ llama_model_free(model);
|
||||
+ llama_backend_free();
|
||||
+ return 0;
|
||||
+}
|
||||
@@ -4,3 +4,4 @@
|
||||
4871a37544df658980a01b4f94151a90b609fb144c931b4a814309ee608ebb46 0003-owned-range-filtered-state-report.patch
|
||||
19d451ce259150ffede793c4eb547425375c0fcd97caf326b43e8f1a204f05b6 0004-dense-boundary-io-endpoint-guard.patch
|
||||
cf263357a6a8de193f710836c7c467c38cac7099975303ee2628e0609daf5a47 0005-worker-range-report-hook.patch
|
||||
23b4b8c56243d52ba682f0034022a86bf8ded007885be5b659cf5158ff3eb429 0006-meshnet-range-report-tool.patch
|
||||
|
||||
@@ -112,6 +112,30 @@
|
||||
"llama_internal_get_tensor_map(const llama_model *) in src/llama-model.h",
|
||||
"gguf empty-context writer API: gguf_init_empty, gguf_add_tensor, gguf_write_to_file"
|
||||
]
|
||||
},
|
||||
"0006-meshnet-range-report-tool.patch": {
|
||||
"concern": "range-reporting",
|
||||
"files": {
|
||||
"CMakeLists.txt": {
|
||||
"before": "a9afcffa68bed7cbd8fad39ad9f95ad784251234",
|
||||
"after": "868793b826f565df7f041e7ba55820b5ad744b10"
|
||||
},
|
||||
"tools/meshnet-range-report/CMakeLists.txt": {
|
||||
"before": null,
|
||||
"after": "24401007ee85e217c2741a42c7119fad323ff08a"
|
||||
},
|
||||
"tools/meshnet-range-report/meshnet-range-report.cpp": {
|
||||
"before": null,
|
||||
"after": "49a5eb2a05bf6514e166453ea0e35b8bc9c5fdf6"
|
||||
}
|
||||
},
|
||||
"api_assumptions": [
|
||||
"llama_model_params carries meshnet_owned_layer_start/end, use_mmap, and use_extra_bufts",
|
||||
"llama_model_meshnet_range_report C API and llama_meshnet_range_report fields (patch 0005)",
|
||||
"llama_internal_get_tensor_map(const llama_model *) in src/llama-model.h",
|
||||
"llama_model_meta_val_str and llama_model_n_layer public accessors",
|
||||
"top-level CMakeLists add_subdirectory of a project-owned tool directory after the llama target"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
0003-owned-range-filtered-state-report.patch
|
||||
0004-dense-boundary-io-endpoint-guard.patch
|
||||
0005-worker-range-report-hook.patch
|
||||
0006-meshnet-range-report-tool.patch
|
||||
|
||||
Reference in New Issue
Block a user