bankml / docs /index.html
Gregory-L's picture
Ask bankML: your own bankML (verified, receipt checked in the page) or a Hugging Face provider (labelled not bankML); source at github main cfe81e1 (serve --allow-origin)
d1c88ba verified
Raw History Blame Contribute Delete
22.7 kB
<!doctype html><html><head><meta charset=utf8><meta name=viewport content="width=device-width,initial-scale=1,viewport-fit=cover"><style>:root{color-scheme:light;box-sizing:border-box;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)}html{scroll-padding-top:env(safe-area-inset-top,0px)}body{margin:0;padding:0;font:14px -apple-system,BlinkMacSystemFont,sans-serif;background:#faf9f5;color:#141413}img{max-width:100%}[hidden]:not([hidden=until-found i]){display:none!important}</style></head><body>
<title>bankml Documentation</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans+Condensed:wght@500;600;700&family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;1,400&display=swap">
<style>
/* Layout: a technical-manual reader — a fixed index of documents on the left, the document in a 72ch column,
its own contents on the right on wide screens; one column with a document picker on phones. */
:root {
--bg: #f6f7f8; /* paper, a hair cooler than white */
--panel: #ffffff;
--ink: #16202a; /* body text */
--muted: #5a6875; /* captions, secondary */
--rule: #d9dee3; /* hairlines */
--code-bg: #eef1f3;
--accent: #0e6f68; /* the verified state: teal */
--accent-soft: rgba(14, 111, 104, 0.10);
--gold: #9a6a12; /* Savante's gold, for the one release marker */
--neg: #b4453a; /* −1 */
--zero: #7a8793; /* 0 */
--pos: #0e6f68; /* +1 */
--f-display: "IBM Plex Sans Condensed", "Arial Narrow", system-ui, sans-serif;
--f-body: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--f-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
color-scheme: light;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #0f1418; --panel: #151c21; --ink: #dfe6ea; --muted: #93a2ae; --rule: #28323a; --code-bg: #1b242b;
--accent: #4cc3b7; --accent-soft: rgba(76, 195, 183, 0.12); --gold: #d9a23a; --neg: #e07a6f; --zero: #8a98a4; --pos: #4cc3b7;
color-scheme: dark;
}
}
:root[data-theme="dark"] {
--bg: #0f1418; --panel: #151c21; --ink: #dfe6ea; --muted: #93a2ae; --rule: #28323a; --code-bg: #1b242b;
--accent: #4cc3b7; --accent-soft: rgba(76, 195, 183, 0.12); --gold: #d9a23a; --neg: #e07a6f; --zero: #8a98a4; --pos: #4cc3b7;
color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { background: var(--bg); color: var(--ink); }
body { font: 16px/1.62 var(--f-body); }
a { color: var(--accent); text-underline-offset: 2px; }
a:focus-visible, button:focus-visible, select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.masthead {
border-bottom: 1px solid var(--rule); background: var(--panel);
padding-inline: 16px; padding-block: 14px 12px;
}
.masthead-inner { max-width: 1320px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px; }
.brand { font: 700 22px/1.1 var(--f-display); letter-spacing: 0.01em; margin: 0; }
.brand .ver { color: var(--gold); font-weight: 600; margin-left: 6px; }
.tag { font-size: 14px; color: var(--muted); }
.trits { display: inline-flex; gap: 3px; vertical-align: middle; margin-right: 8px; }
.trits i { width: 7px; height: 7px; border-radius: 1px; display: inline-block; }
.trits i:nth-child(1) { background: var(--neg); } .trits i:nth-child(2) { background: var(--zero); } .trits i:nth-child(3) { background: var(--pos); }
.proof {
flex-basis: 100%; font: 500 12.5px/1.5 var(--f-mono); color: var(--muted); letter-spacing: 0.01em;
font-variant-numeric: tabular-nums;
}
.proof b { color: var(--accent); font-weight: 600; }
.shell { max-width: 1320px; margin: 0 auto; padding-inline: 16px; display: grid; grid-template-columns: 236px minmax(0, 1fr) 220px; gap: 36px; }
.nav { position: sticky; top: env(safe-area-inset-top, 0px); align-self: start; max-height: 100vh; overflow-y: auto; padding-block: 22px; }
.nav h2 { font: 600 11px/1 var(--f-mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin: 18px 0 8px; }
.nav h2:first-child { margin-top: 0; }
.nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.nav a { display: block; padding: 5px 10px; border-radius: 6px; color: var(--ink); text-decoration: none; font-size: 14.5px; }
.nav a small { display: block; color: var(--muted); font-size: 12px; line-height: 1.35; }
.nav a:hover { background: var(--accent-soft); }
.nav a[aria-current="page"] { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.picker { display: none; }
main { min-width: 0; padding-block: 22px 80px; }
.docmeta { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; font: 12.5px/1.4 var(--f-mono); color: var(--muted); margin-bottom: 10px; }
.docmeta a { color: var(--muted); }
article { max-width: 76ch; }
article h1, article h2, article h3, article h4 { font-family: var(--f-display); line-height: 1.2; text-wrap: balance; scroll-margin-top: 16px; }
article h1 { font-size: 2.05rem; font-weight: 700; margin: 0.2em 0 0.5em; }
article h2 { font-size: 1.45rem; font-weight: 600; margin: 1.9em 0 0.5em; padding-top: 0.4em; border-top: 1px solid var(--rule); }
article h3 { font-size: 1.14rem; font-weight: 600; margin: 1.5em 0 0.4em; }
article h4 { font-size: 1rem; font-weight: 600; margin: 1.3em 0 0.3em; }
article p, article li { max-width: 72ch; }
article ul, article ol { padding-left: 1.4em; }
article li + li { margin-top: 0.2em; }
article code { font: 0.88em/1.4 var(--f-mono); background: var(--code-bg); padding: 0.08em 0.35em; border-radius: 4px; }
article pre { background: var(--code-bg); border: 1px solid var(--rule); border-radius: 8px; padding: 12px 14px; overflow-x: auto; font-size: 13.5px; line-height: 1.5; }
article pre code { background: none; padding: 0; font-size: inherit; }
article blockquote { margin: 1em 0; padding: 0.2em 1em; border-left: 3px solid var(--rule); color: var(--muted); }
article hr { border: 0; border-top: 1px solid var(--rule); margin: 2em 0; }
.tablewrap { overflow-x: auto; margin: 1em 0; border: 1px solid var(--rule); border-radius: 8px; }
article table { border-collapse: collapse; width: 100%; font-size: 14px; font-variant-numeric: tabular-nums; }
article th, article td { text-align: left; vertical-align: top; padding: 7px 10px; border-bottom: 1px solid var(--rule); }
article th { font: 600 12.5px/1.3 var(--f-body); color: var(--muted); background: var(--code-bg); letter-spacing: 0.02em; }
article tr:last-child td { border-bottom: 0; }
article img { max-width: 100%; height: auto; }
article p[align="center"] { text-align: center; }
.badge { display: inline-block; font: 500 11.5px/1.6 var(--f-mono); border: 1px solid var(--rule); border-radius: 4px; padding: 0 6px; margin: 2px; color: var(--muted); }
.status { color: var(--muted); font-style: italic; }
.toc { position: sticky; top: env(safe-area-inset-top, 0px); align-self: start; max-height: 100vh; overflow-y: auto; padding-block: 22px; font-size: 13px; }
.toc h2 { font: 600 11px/1 var(--f-mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin: 0 0 8px; }
.toc ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }
.toc a { display: block; color: var(--muted); text-decoration: none; padding: 3px 8px; border-left: 2px solid var(--rule); line-height: 1.35; }
.toc a.l3 { padding-left: 18px; font-size: 12.5px; }
.toc a:hover { color: var(--accent); border-left-color: var(--accent); }
@media (max-width: 1100px) { .shell { grid-template-columns: 220px minmax(0, 1fr); } .toc { display: none; } }
@media (max-width: 760px) {
.shell { grid-template-columns: minmax(0, 1fr); gap: 0; }
.nav { display: none; }
.picker { display: block; padding-block: 14px 0; }
.picker label { font: 600 11px/1 var(--f-mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); display: block; margin-bottom: 6px; }
.picker select { width: 100%; font: 15px var(--f-body); padding: 8px; border-radius: 6px; border: 1px solid var(--rule); background: var(--panel); color: var(--ink); }
article h1 { font-size: 1.65rem; }
}
.masthead .links { margin: 6px 0 0; font: 500 12.5px/1.4 var(--f-mono); }
.masthead .links a { color: inherit; text-decoration: underline; text-underline-offset: 2px; opacity: .85; }
.masthead .links a:hover { opacity: 1; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
</style>
<header class="masthead">
<div class="masthead-inner">
<p class="brand"><span class="trits" aria-hidden="true"><i></i><i></i><i></i></span>bankml<span class="ver" id="ver">0.2.7</span></p>
<span class="tag">Verified low-bit inference for the CPU you already have — the documentation, as of <span id="asof">0.2.7</span>.</span>
<p class="links"><a href="https://github.com/cryptoAGI/bankml">GitHub</a> · <a href="https://huggingface.co/spaces/PYTHAI/bankml">Hugging Face</a> · <a href="https://deltaverse.pythai.net/bankml">why bankML</a> · <a href="#thesis">the thesis</a> · <a href="https://github.com/minaiml">minaiml</a> (<a href="https://huggingface.co/spaces/PYTHAI/minaiml">Space</a>)</p>
<div class="proof">gate record 0.3.6: the penalties — repeat, frequency and presence, token-identical to llama-server on <b>56 / 56</b> answers on each of three models, live <b>85 / 85</b> · gate record 0.3.5: JSON schemas — llama-server’s grammar on each template (<b>173 / 173</b> schemas × 3 templates against llama.cpp’s own code) and its answers token-identical on all five native models (<b>28 / 28</b>, <b>11 / 11</b>, <b>56 / 56</b> × 3), the content rule matched on <b>30,063 / 30,063</b> texts per template · <code>bankml create</code>: mindX’s persona layer, made from mindXtrain’s merged output, token-identical end to end (<b>27 / 27</b>, two ways) · gate record 0.3.4: mindX’s own model natively — <code>mindx-gen39</code> and SmolLM2-135M-Instruct (the Llama graph in F16) and Bonsai-1.7B (tied embeddings) token-identical to llama-server b11192: whole model <b>800 / 800</b> and <b>840 / 840</b> rows bit-exact, F16 products <b>552,268 / 552,268</b> elements bit-exact against ggml, seeded sampling <b>40 / 40</b> on each, conversations <b>9 / 9</b>, JSON mode <b>23 / 23</b> · JSON mode — answers under llama-server’s own <code>json_object</code> grammar token-identical, greedy and seeded (<b>23 / 23</b> answers on the 1-bit model, <b>13 / 13</b> on the ternary), and llama.cpp’s grammar sampler matched on <b>1,645 / 1,645</b> whole-vocabulary masks · a C API, <code>libbankml</code>, identical to <code>serve --native</code> · Savante answered by bankML’s own forward pass — whole conversations identical to llama-server on <b>9 / 9</b> turns (text, token counts, prompt-cache reuse) · own forward pass <b>1,064 / 1,064</b> rows bit-exact for the 1-bit and the ternary model · seeded sampling identical on <b>40 / 40</b> continuations · <b>8,188,239,872</b> ternary weights and <b>762 / 762</b> dot products bit-exact against llama.cpp b11192’s compiled library · one ternary token <b>0.222 s vs 2.139 s</b></div>
</div>
</header>
<div class="shell">
<nav class="nav" aria-label="Documents" id="nav"></nav>
<main>
<div class="picker"><label for="docpick">Document</label><select id="docpick"></select></div>
<div class="docmeta" id="docmeta"></div>
<article id="doc"><p class="status">Loading the document…</p></article>
</main>
<aside class="toc" aria-label="On this page" id="toc"></aside>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.2/marked.min.js"></script>
<script>
(function () {
const REPO = "https://github.com/cryptoAGI/bankml";
// Two homes, one file. In the claude.ai artifact the documents are published beside this page, so they load by
// relative path. On GitHub Pages (docs/index.html) they are read from the repository at the latest release.
const FALLBACK_TAG = "v0.3.6";
let TAG = FALLBACK_TAG;
let SRC = ""; // "" = beside this page; otherwise a raw.githubusercontent.com base
const RAW = "https://raw.githubusercontent.com/cryptoAGI/bankml/";
const ready = (async () => {
try { const r = await fetch("README.md", { method: "HEAD" }); if (r.ok) return; } catch (e) {}
try {
const r = await fetch("https://api.github.com/repos/cryptoAGI/bankml/releases/latest");
if (r.ok) { const t = (await r.json()).tag_name; if (/^v\d+\.\d+\.\d+$/.test(t)) TAG = t; }
} catch (e) {}
SRC = RAW + TAG + "/";
const v = TAG.slice(1);
document.getElementById("ver").textContent = v;
document.getElementById("asof").textContent = v;
})();
// the documents, by the reader's task; `path` is the file's path in the repository (and in this artifact)
const GROUPS = [
["Start", [
["readme", "README.md", "Overview", "what bankml is, results, releases"],
["why", "docs/why-bankml.md", "Why bankML", "the short version: uses, Rust, the road ahead"],
["usage", "docs/usage.md", "Usage guide", "install, run, models, settings"],
["install", "docs/install.md", "Install and configure", "every option, variable, service and tuning"],
["playback", "docs/playback.md", "New to Savante", "her page, her card, listening to her"],
]],
["Understand", [
["technical", "docs/TECHNICAL.md", "Technical report", "design, method, proofs, thesis"],
["thesis", "docs/thesis.md", "Thesis", "exactness before speed: the argument and its evidence"],
["oracles", "docs/oracles.md", "Oracles", "what bankml is checked against"],
["performance", "docs/PERFORMANCE.md", "Performance", "every number, how it was measured"],
["research", "docs/research.md", "Research", "the field, with papers"],
["embedding", "docs/embedding.md", "Embedding", "bge-m3 meaning search"],
["capi", "docs/CAPI.md", "C API", "embed bankML: libbankml and bankml.h"],
["ollama", "docs/OLLAMA.md", "Ollama and mindX", "the gap matrix against mindX, phases O1–O8"],
["huggingface", "docs/huggingface.md", "Hugging Face GPUs", "the Hub's rented GPUs as bankML devices"],
]],
["Source", [
["modules", "docs/modules/README.md", "Modules", "each source module: usage, advantages, limits"],
["mod-bankml", "docs/modules/bankml.md", "bankML/bankml.rs", "the crate root: the verification gate, shared types, logging"],
["mod-gguf", "docs/modules/gguf.md", "bankML/gguf.rs", "the GGUF header parser, the guard, and the read-only…"],
["mod-sha256", "docs/modules/sha256.md", "bankML/sha256.rs", "SHA-256 for the model pin, and the FORK.json pin scanner"],
["mod-q1_0", "docs/modules/q1_0.md", "bankML/q1_0.rs", "the 1-bit Q1_0 kernel, the q8_0 activation quantizer,…"],
["mod-q2_0", "docs/modules/q2_0.md", "bankML/q2_0.rs", "the ternary Q2_0_g64 kernel"],
["mod-f16", "docs/modules/f16.md", "bankML/f16.rs", "F16 weights, multiplied as the shipped ggml b11192…"],
["mod-par", "docs/modules/par.md", "bankML/par.rs", "the persistent thread pool and row scheduler for the matmuls"],
["mod-prompt_cache", "docs/modules/prompt_cache.md", "bankML/prompt_cache.rs", "llama-server's host prompt cache for the one slot"],
["mod-gpu", "docs/modules/gpu.md", "bankML/gpu/", "the video-card component: find GPUs, verify them, and…"],
["mod-metrics", "docs/modules/metrics.md", "bankML/metrics.rs", "bankML's own measurements of its answers"],
["mod-console", "docs/modules/console.md", "sAGI/console.py", "bankML as itself: four tabs, the measured SELF block"],
["mod-sys", "docs/modules/sys.md", "bankML/sys.rs", "memory, cores and per-process usage from /proc"],
["mod-forward", "docs/modules/forward.md", "bankML/forward.rs", "the forward pass, bit-exact against llama.cpp b11192's…"],
["mod-tokenizer", "docs/modules/tokenizer.md", "bankML/tokenizer.rs", "byte-level BPE, token-identical to llama.cpp b11192"],
["mod-chat", "docs/modules/chat.md", "bankML/chat.rs", "chat templates, byte-identical to llama.cpp b11192"],
["mod-sampler", "docs/modules/sampler.md", "bankML/sampler.rs", "llama-server's sampler chain, token for token with the…"],
["mod-grammar", "docs/modules/grammar.md", "bankML/grammar.rs", "llama.cpp's GBNF engine, JSON mode and the content rule"],
["mod-schema", "docs/modules/schema.md", "bankML/schema.rs", "JSON schema to GBNF, as llama-server b11192 builds it"],
["mod-native", "docs/modules/native.md", "bankML/native.rs", "the engine behind bankml serve --native"],
["mod-serve", "docs/modules/serve.md", "bankML/serve.rs", "bankml serve, the verifying loopback gateway"],
["mod-ollama", "docs/modules/ollama.md", "bankML/ollama.rs", "Ollama's API on bankml serve --native"],
["mod-create", "docs/modules/create.md", "bankML/create.rs", "bankml create: derived models over pinned bases"],
["mod-convert", "docs/modules/convert.md", "bankML/convert.rs", "bankml convert: safetensors to GGUF F16, byte-identical…"],
["mod-main", "docs/modules/main.md", "bankML/main.rs", "the bankml command line"],
["mod-capi", "docs/modules/capi.md", "capi/src/", "the C API: libbankml.so / libbankml.a"],
["mod-train", "docs/modules/train.md", "bankML/train/", "mindXtrain in Rust, one verified stage at a time"],
]],
["Records", [
["changelog", "CHANGELOG.md", "Changelog", "every release"],
["history", "docs/BUILD_HISTORY.md", "Build history", "how each phase was reached, with its evidence"],
["testing", "testing/README.md", "Testing", "the gate and its records"],
["todo", "docs/TODO.md", "TODO", "next, and what was rejected"],
["upstream", "upstream/README.md", "Upstream kernel", "the Q2_0 patch for llama.cpp"],
["licensing", "LICENSING.md", "Licensing", "MIT OR Apache-2.0, and the layers"],
]],
];
const DOCS = GROUPS.flatMap(([, d]) => d);
const BY_PATH = Object.fromEntries(DOCS.map(d => [d[1], d]));
const cache = {};
const $ = (id) => document.getElementById(id);
// the index, and the phone picker
$("nav").innerHTML = GROUPS.map(([g, ds]) =>
`<h2>${g}</h2><ul>` + ds.map(([id, , t, s]) => `<li><a href="#${id}" data-id="${id}">${t}<small>${s}</small></a></li>`).join("") + "</ul>"
).join("");
$("docpick").innerHTML = DOCS.map(([id, , t]) => `<option value="${id}">${t}</option>`).join("");
$("docpick").addEventListener("change", (e) => { location.hash = e.target.value; });
const slug = (t) => t.trim().toLowerCase().replace(/<[^>]+>/g, "").replace(/[^\w\- ]+/g, "").replace(/ /g, "-");
function resolve(base, rel) { // a path relative to a document, as the repository sees it
const parts = base.split("/").slice(0, -1);
for (const p of rel.split("/")) {
if (p === "..") parts.pop(); else if (p !== "." && p !== "") parts.push(p);
}
return parts.join("/");
}
async function show(hash) {
await ready;
const [id, anchor] = (hash || "readme").split(".", 2);
const d = DOCS.find(x => x[0] === id) || DOCS[0];
const [docId, path, title] = d;
document.querySelectorAll("#nav a").forEach(a => a.setAttribute("aria-current", a.dataset.id === docId ? "page" : "false"));
$("docpick").value = docId;
$("docmeta").innerHTML = `<span>${path}</span><a href="${REPO}/blob/${TAG}/${path}" target="_blank" rel="noopener">view on GitHub at ${TAG}</a>`;
let md = cache[path];
if (md === undefined) {
try {
let r = await fetch(SRC + path);
// a document newer than the release (on GitHub Pages) is read from main
if (!r.ok && SRC.startsWith(RAW)) r = await fetch(RAW + "main/" + path);
if (!r.ok) throw new Error(r.status);
md = cache[path] = await r.text();
} catch (e) {
$("doc").innerHTML = `<p class="status">This document could not be loaded here. Read it on <a href="${REPO}/blob/${TAG}/${path}" target="_blank" rel="noopener">GitHub</a>.</p>`;
$("toc").innerHTML = "";
return;
}
}
const art = $("doc");
art.innerHTML = marked.parse(md, { gfm: true });
// headings get GitHub-style ids (the documents' own anchors), and the contents list is built from them
const seen = {};
const heads = [...art.querySelectorAll("h1, h2, h3")];
heads.forEach(h => { let s = slug(h.textContent); if (seen[s] !== undefined) s = s + "-" + (++seen[s]); else seen[s] = 0; h.id = docId + "." + s; });
const toc = heads.filter(h => h.tagName !== "H1");
$("toc").innerHTML = toc.length ? "<h2>On this page</h2><ol>" + toc.map(h =>
`<li><a class="${h.tagName === "H3" ? "l3" : ""}" href="#${h.id}">${h.textContent}</a></li>`).join("") + "</ol>" : "";
// tables scroll inside their own box
art.querySelectorAll("table").forEach(t => { const w = document.createElement("div"); w.className = "tablewrap"; t.replaceWith(w); w.appendChild(t); });
// images: files published with this page load; other hosts cannot (the badges become text)
art.querySelectorAll("img").forEach(img => {
const src = img.getAttribute("src") || "";
if (/^https?:/.test(src)) { const b = document.createElement("span"); b.className = "badge"; b.textContent = img.alt || "badge"; img.replaceWith(b); }
else img.src = SRC + resolve(path, src);
});
// links: another document opens here, an anchor scrolls here, anything else goes to GitHub at the tag
art.querySelectorAll("a[href]").forEach(a => {
const href = a.getAttribute("href");
if (/^(https?:|mailto:)/.test(href)) { a.target = "_blank"; a.rel = "noopener"; return; }
const [p, frag] = href.split("#");
if (!p) { a.href = "#" + docId + "." + frag; return; }
const target = resolve(path, p);
const doc = BY_PATH[target];
if (doc) a.href = "#" + doc[0] + (frag ? "." + frag : "");
else { a.href = `${REPO}/${/\.[a-z0-9]+$/i.test(target) ? "blob" : "tree"}/${TAG}/${target}`; a.target = "_blank"; a.rel = "noopener"; }
});
document.title = (docId === "readme" ? "bankml " + TAG.slice(1) + " Documentation" : title + " · bankml " + TAG.slice(1));
if (anchor) { const el = document.getElementById(docId + "." + anchor); if (el) { el.scrollIntoView(); return; } }
window.scrollTo(0, 0);
}
window.addEventListener("hashchange", () => show(location.hash.slice(1)));
show(location.hash.slice(1));
})();
</script>
</body></html>