Entropic 2.14.3
Local-first agentic inference engine
Loading...
Searching...
No Matches
gguf_metadata.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-3.0-or-later
7#include "gguf_metadata.h"
8
9#include "expert_offload.h"
10
11#include <gguf.h>
12
13#include <regex>
14#include <string>
15
16namespace entropic {
17
18namespace {
19
29int u32_or(const gguf_context* ctx, const std::string& key, int fallback) {
30 const int64_t id = gguf_find_key(ctx, key.c_str());
31 if (id < 0) { return fallback; }
32 return static_cast<int>(gguf_get_val_u32(ctx, id));
33}
34
48int block_index_of(const std::string& name) {
49 static const std::regex blk("^blk\\.([0-9]+)\\.");
50 std::smatch m;
51 if (!std::regex_search(name, m, blk)) { return -1; }
52 return std::stoi(m[1].str());
53}
54
55} // namespace
56
64GgufShape read_gguf_shape(const std::string& path) {
66
67 // no_alloc: map the header, the KV metadata and the tensor index; read
68 // none of the tensor data. A 10 GB model costs the same as a 1 GB one.
70 params.no_alloc = true;
71 params.ctx = nullptr;
72
74 if (ctx == nullptr) {
75 return shape; // known stays false — caller must fall back.
76 }
77
78 const int64_t arch_id = gguf_find_key(ctx, "general.architecture");
79 if (arch_id < 0) {
81 return shape; // No architecture means no way to name the other keys.
82 }
83 shape.architecture = gguf_get_val_str(ctx, arch_id);
84
85 shape.block_count =
86 u32_or(ctx, shape.architecture + ".block_count", 0);
87 shape.expert_count =
88 u32_or(ctx, shape.architecture + ".expert_count", 0);
89
90 // Sum the tensor index. Expert bytes are summed by MATCHING llama.cpp's
91 // own expert pattern rather than by assuming experts are some fraction
92 // of a layer — the difference between a measurement and a heuristic.
93 const std::regex experts(kExpertTensorRegex);
95 for (int64_t i = 0; i < n_tensors; ++i) {
96 const std::string name = gguf_get_tensor_name(ctx, i);
97 const auto bytes = static_cast<uint64_t>(gguf_get_tensor_size(ctx, i));
98 if (block_index_of(name) < 0) {
99 shape.non_block_bytes += bytes;
100 continue;
101 }
102 shape.block_bytes += bytes;
103 if (std::regex_search(name, experts)) {
104 shape.expert_bytes += bytes;
105 }
106 }
107
108 gguf_free(ctx);
109
110 // A file whose tensors carry no block prefix tells us nothing about
111 // per-layer cost, so it is not a usable shape even though it parsed.
112 shape.known = shape.block_count > 0 && shape.block_bytes > 0;
113 return shape;
114}
115
116} // namespace entropic
EXPERIMENTAL (v2.13.0): put a MoE layer's routed-expert tensors on the host while its attention,...
long bytes
Content bytes taken.
Read a GGUF's shape without loading its tensors (v2.13.1).
Activate model on GPU (WARM → ACTIVE).
@ optional
optional: every escape asks the host's path approver
constexpr const char * kExpertTensorRegex
Tensor-name pattern tail identifying a layer's ROUTED-expert weights.
GgufShape read_gguf_shape(const std::string &path)
Read a GGUF's shape from its metadata, without loading tensor data.
A GGUF's shape, as far as its metadata states it.