quantprobe 1.3.0__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quantprobe-1.4.0/PKG-INFO +143 -0
- quantprobe-1.4.0/README.md +125 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/pyproject.toml +1 -1
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/__init__.py +1 -1
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/cli.py +10 -0
- quantprobe-1.4.0/quantprobe/optimize.py +133 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/plan.py +19 -0
- quantprobe-1.4.0/quantprobe.egg-info/PKG-INFO +143 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe.egg-info/SOURCES.txt +1 -0
- quantprobe-1.3.0/PKG-INFO +0 -296
- quantprobe-1.3.0/README.md +0 -278
- quantprobe-1.3.0/quantprobe.egg-info/PKG-INFO +0 -296
- {quantprobe-1.3.0 → quantprobe-1.4.0}/LICENSE +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/dashboard.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/detect.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/fetch.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/probe.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/runtime.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/spec.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe/target.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe.egg-info/dependency_links.txt +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe.egg-info/entry_points.txt +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe.egg-info/requires.txt +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/quantprobe.egg-info/top_level.txt +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/setup.cfg +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/tests/test_engine.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/tests/test_evaluator.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/tests/test_pipeline.py +0 -0
- {quantprobe-1.3.0 → quantprobe-1.4.0}/tests/test_transforms.py +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: quantprobe
|
|
3
|
+
Version: 1.4.0
|
|
4
|
+
Summary: Probe-then-quantize for LLMs: measure a model's fragility curve, plan bit/tier placement by the tiered decode law, and emit ready-to-run llama.cpp recipes.
|
|
5
|
+
Author: Federico Sciuca
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/FedericoTs/quantprobe
|
|
8
|
+
Keywords: llm,quantization,llama.cpp,gguf,inference,moe
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: gguf>=0.9
|
|
16
|
+
Requires-Dist: requests>=2.28
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# quantprobe
|
|
20
|
+
|
|
21
|
+
### Placement beats budget
|
|
22
|
+
|
|
23
|
+
**Where your bits sit — which layers, which memory tier — matters more than how many you have. Four falsification-tested laws for running big LLMs on hardware you already own, every number measured on one 2016 desktop (GTX 1060 6 GB · 16 GB DDR4 · SATA SSD).**
|
|
24
|
+
|
|
25
|
+
     [](https://x.com/federico_sciuca)
|
|
26
|
+
|
|
27
|
+
<p align="center"><img src="weights/data/hero_placement.png" width="880" alt="Placement across memory tiers: disk 2-bit cold experts, RAM 2-bit experts + probed fragile band at 4-bit, VRAM 4-bit attention — one law ties them"></p>
|
|
28
|
+
|
|
29
|
+
> **▶ Try the interactive calculator: [Will it run — and how fast?](https://federicots.github.io/quantprobe/)**
|
|
30
|
+
> Pick any model + your machine → predicted tok/s, memory fit, quality cost, and your cheapest next upgrade — from the law below, with your config plotted against every validated measurement.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
**New here? → [QUICKSTART.md](QUICKSTART.md) gets you running in 60 seconds.** Two tiers: `plan`/`target` and the web calculator need *nothing* installed; `quantize`/`probe`/`run`/`bench`/`dashboard` drive [llama.cpp](https://github.com/ggml-org/llama.cpp/releases) (point quantprobe at it with `--llama-dir`, `QUANTPROBE_LLAMA_DIR`, or `PATH`). Preview any command without llama.cpp using `--dry`. 16 machine presets ship in (`--machine`): GTX 1060 → RTX 5090, Apple `mac-m2/m3/m4-*`, DGX Spark, Epyc — or pass raw specs. Multi-GPU / RAID? Comma lists aggregate: `--vram 24,24 --disk-bw 14,14`. Big-VRAM + disk-streaming rigs get the three-tier expert-cache row (v1.3).
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## What this is
|
|
39
|
+
|
|
40
|
+
My 2016 desktop can't run frontier models the way a datacenter does — so instead of brute force, I asked *where* every bit and byte should go, and answered it by measurement. Months of experiments later, the result is four laws, a 30-minute probe tool, copy-paste llama.cpp recipes, and one equation that predicts decode speed from 7B to 744B — validated against my own pre-registered predictions and against [colibri](https://github.com/JustVugg/colibri)'s independently published 744B numbers.
|
|
41
|
+
|
|
42
|
+
## Headline results
|
|
43
|
+
|
|
44
|
+
| result | number |
|
|
45
|
+
|---|---|
|
|
46
|
+
| 16B MoE, 2-bit, **data-free**, resident on a 6 GB card | ppl 6.31 → 6.96 (**1.10×**) — beats calibrated SOTA's gap-ratio |
|
|
47
|
+
| Same bytes, different layers (Gemma 4 12B, stock llama.cpp) | **byte-identical files, 2.25 ppl apart** (12.27 vs 10.02) |
|
|
48
|
+
| Gemma 4 12B depth-aware 2-bit | 1.91× → **1.45×** quality cost, ~4.5 GB resident |
|
|
49
|
+
| Qwen3-30B-A3B on the 2016 desktop | **19.3 tok/s** — hybrid placement, *predicted 19 before measuring* |
|
|
50
|
+
| GLM-4.5-Air **110B** from a SATA drive, 16 GB RAM | 0.19 tok/s — inside the law's pre-registered 0.2–0.3 band |
|
|
51
|
+
| RAM overclock (XMP, 2133→3000) | dense **+52%**, pre-registered ×1.41+ |
|
|
52
|
+
|
|
53
|
+
## Why the evidence is unusually strong
|
|
54
|
+
|
|
55
|
+
Most benchmark posts report what happened. I report what I **predicted before it happened** — I wrote the number down, then ran the hardware, and this is the strongest form of empirical evidence I know how to produce:
|
|
56
|
+
|
|
57
|
+
| prediction (made first) | measured (after) |
|
|
58
|
+
|---|---|
|
|
59
|
+
| 110B streamed from SATA: **0.2–0.3 tok/s** | **0.19** |
|
|
60
|
+
| RAM overclock scales in-RAM decode **×1.41+** | **×1.52** |
|
|
61
|
+
| 30B hybrid placement: **~19 tok/s** | **19.30 ± 0.88** |
|
|
62
|
+
| a day-old 118B (Laguna S 2.1) streamed from this SATA drive: **0.2–0.4** ([staked pre-download](preregistrations/2026-07-23-laguna-s-2.1-on-2016-desktop.md)) | **0.38 ± 0.17** |
|
|
63
|
+
| colibri's own 128 GB / 25 GB tiers, from our η bands | land **inside** the bands |
|
|
64
|
+
|
|
65
|
+
Add to that: a **byte-identical control** (two GGUFs the same size, 2.25 ppl apart — only placement differs), a full **claim → script → log manifest** (every number reproducible in-tree), and a set of **documented dead ends** (dynamic top-k, semantic paging, self-speculation — all measured-dead, because a law you only confirm is a law you haven't tested).
|
|
66
|
+
|
|
67
|
+
<p align="center"><img src="weights/data/validation_19tok/live_run_20tps.png" width="880" alt="One frame: Task Manager showing 16 GB DDR4-3000 and the GTX 1060 6GB beside llama.cpp chatting Qwen3-30B-A3B live at 20.4 tok/s generation"></p>
|
|
68
|
+
<p align="center"><em>One frame, no cuts: Task Manager (16 GB @ 3000 MT/s, GTX 1060 6 GB, RAM at 91% — the hybrid placement using the whole machine) beside llama.cpp chatting Qwen3-30B-A3B at <b>20.4 tok/s generation</b> — above the pre-registered 19. Raw logs, hardware attestation + GGUF SHA256: <a href="weights/data/validation_19tok/EVIDENCE.txt">EVIDENCE.txt</a>. Third bench run: 19.26 ± 0.45 (series 19.30 → 19.55 → 19.26).</em></p>
|
|
69
|
+
|
|
70
|
+
**Open pre-registrations** — predictions staked publicly *before* measurement: [colibri v1.1, five falsifiable predictions (2026-07-23)](preregistrations/2026-07-23-colibri-v1.1.md) — dual-SSD scaling, int3 speedup, lattice-vs-scalar, AVX-512 tier-scoping, MTP×MoE antagonism.
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
## The four placement laws
|
|
74
|
+
|
|
75
|
+
Full statements, each with its establishing measurement and a falsifiable prediction, in **[LAWS.md](LAWS.md)**.
|
|
76
|
+
|
|
77
|
+
1. **Rotation is rank-conditional.** Incoherence rotation (QuIP#/QTIP/QuaRot) helps full-rank tensors (+0.006 ppl) and destroys low-rank bottlenecks (+1623 ppl) — a ~270,000× swing on effective rank alone.
|
|
78
|
+
2. **Trained networks are dense everywhere.** Experts sit *exactly* at the rate-distortion floor; routing is flat (even across domains — Jaccard 1.00 prose vs code); activations are diffuse. **2-bit is the floor.**
|
|
79
|
+
3. **Fragility is measurable, not predictable.** Gemma late-fragile 4×, Mistral **early-fragile 25×** — architectural near-twins pointing opposite ways. Weight statistics mislead. **Only a 30-minute functional probe decides.**
|
|
80
|
+
4. **The tiered decode law.** `tok/s = η(tier)·BW ÷ active-bytes`, η collapsing per tier across 7B→744B and both projects' hardware. **v1.1 adds the context term**: each generated token also re-reads the whole KV cache from *its* tier — `--ctx` prices it, `bench --depth` measures it (measured here: 20.02 → 16.12 tok/s at 16k depth).
|
|
81
|
+
|
|
82
|
+
<p align="center"><img src="weights/data/x_chart_E_scalinglaw.png" width="700" alt="One scaling law, 7B to 744B, predicted vs measured, including colibri's published tiers"></p>
|
|
83
|
+
|
|
84
|
+
<p align="center"><img src="weights/data/x_chart_D_placement.png" width="700" alt="Byte-identical GGUF files, 2.25 perplexity apart — placement is worth twice the byte budget"></p>
|
|
85
|
+
<p align="center"><img src="weights/data/x_chart_I_kvdepth.png" width="700" alt="Decode speed versus context depth: measured 20.02 tok/s at depth zero falling to 16.12 at 16384, on the Law 4 v2 curve with eta_kv 0.70"></p>
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
## Install — and the ten commands
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install quantprobe
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Zero-config on your own box**: `quantprobe plan --gguf model.gguf` auto-detects the machine and reads the model from the file. Presets/flags estimate any *other* machine. `hw`/`plan`/`target`/`optimize` need nothing else installed; the rest drive stock [llama.cpp](https://github.com/ggml-org/llama.cpp/releases) (point at it with `--llama-dir`/`QUANTPROBE_LLAMA_DIR`/`PATH`; preview any command with `--dry`).
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
quantprobe hw # what the law sees on THIS machine (every value source-tagged)
|
|
98
|
+
quantprobe plan --gguf model.gguf # zero-config prediction: placement + tok/s + the launch command
|
|
99
|
+
quantprobe optimize --tps 20 # CHEAPEST PATH to a target: bits x placement x hardware, Pareto-ranked
|
|
100
|
+
quantprobe target --tps 5 --machine gaming --ladder # inverse: target -> smartest model + speed-intelligence ladder
|
|
101
|
+
quantprobe fetch qwen3-30b ./models # robust, resumable download
|
|
102
|
+
quantprobe quantize --gguf f16.gguf --out 2bit.gguf # COMPRESS: depth-aware ~2-bit GGUF (verified: loads + generates)
|
|
103
|
+
quantprobe probe --gguf f16.gguf --eval wiki.test.raw # measure YOUR model's fragile band (~30 min); --apply builds it
|
|
104
|
+
quantprobe run --gguf 2bit.gguf # plan the placement, then LAUNCH llama.cpp chat
|
|
105
|
+
quantprobe bench --gguf 2bit.gguf --contribute # predicted vs measured on your box; opt-in datapoint
|
|
106
|
+
quantprobe dashboard --gguf 2bit.gguf # chat while every reply is scored against the prediction
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The loop is self-validating: `plan` predicted 17.5 for a file we then measured at **18.32 ± 0.17**; the config months of research converged to is what `optimize` picks blind. A measured example of what that's worth: the same model, mis-specified vs law-routed, is **3.38 vs 18.32 tok/s (×5.4)** — [worked examples](docs/EXAMPLES.md).
|
|
110
|
+
|
|
111
|
+
## Help grow the law
|
|
112
|
+
|
|
113
|
+
`quantprobe bench --contribute` prints exactly what would be shared (hardware label, model, predicted-vs-measured) plus a pre-filled issue link — **you review and submit; nothing is ever sent automatically**. Contributed points land on the law chart; the ones *outside* the bands are the most valuable. Open falsifiable predictions anyone can settle: [preregistrations/](preregistrations/).
|
|
114
|
+
|
|
115
|
+
## Deep dives
|
|
116
|
+
|
|
117
|
+
| | |
|
|
118
|
+
|---|---|
|
|
119
|
+
| [QUICKSTART.md](QUICKSTART.md) | 60-second start, three levels; Ollama interop; llama.cpp version notes |
|
|
120
|
+
| [LAWS.md](LAWS.md) | the four laws — statements, measurements, falsifiable predictions, the general form |
|
|
121
|
+
| [docs/EXAMPLES.md](docs/EXAMPLES.md) | worked examples with real outputs: zero-config, the ×5.4 optimizer A/B, probe walkthrough, troubleshooting |
|
|
122
|
+
| [docs/HARDWARE.md](docs/HARDWARE.md) | the 2016 box: exact specs, measured bandwidths, what the next euro buys |
|
|
123
|
+
| [docs/DEEP-DIVE.md](docs/DEEP-DIVE.md) | what's new vs. what's built-on, parity tables, the 744B-at-home projection, repository map |
|
|
124
|
+
| [preregistrations/](preregistrations/) | every staked prediction with its verdict — hits, the near-miss, and the honest miss |
|
|
125
|
+
| [papers/arxiv/](papers/arxiv/) | the paper (submission-ready LaTeX) |
|
|
126
|
+
| [CHANGELOG.md](CHANGELOG.md) | v1.0 → v1.4, every release |
|
|
127
|
+
|
|
128
|
+
## Honest limitations
|
|
129
|
+
|
|
130
|
+
- Perplexity on WikiText-2 is my primary metric; I haven't run task-level evals (MMLU/HellaSwag) yet.
|
|
131
|
+
- My fragility atlas covers four model families — enough to *disprove* universality, not to chart every architecture.
|
|
132
|
+
- 0.19 tok/s for a 110B is a **capacity demonstration, not usable inference** — the honest speed only arrives with faster storage.
|
|
133
|
+
- Speed numbers are single-stream decode on one machine (±25% across environments); the tiered-decode η values are fitted, not derived.
|
|
134
|
+
- No custom runtime: everything rides stock llama.cpp and streaming eval harnesses. The one CUDA kernel is verified in reference, not built.
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
## Credits
|
|
138
|
+
|
|
139
|
+
[colibri](https://github.com/JustVugg/colibri) (744B on 25 GB, pure C) inspired the tier-streaming exploration. The quantization stack builds on [llama.cpp](https://github.com/ggml-org/llama.cpp) and the QTIP/QuIP# incoherence codecs — whose central tool our first law bounds. Independent research by Federico Sciuca, AI-supported, on one desktop; every claim is measured, and every negative that redirected the work is documented. The Law 4 context term (v1.1) was prompted by **u/RogerAI--fyi** (Reddit), who correctly observed the original formulation omitted per-token KV reads — measured, confirmed, and shipped within a day.
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT — see [LICENSE](LICENSE). © 2026 Federico Sciuca.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# quantprobe
|
|
2
|
+
|
|
3
|
+
### Placement beats budget
|
|
4
|
+
|
|
5
|
+
**Where your bits sit — which layers, which memory tier — matters more than how many you have. Four falsification-tested laws for running big LLMs on hardware you already own, every number measured on one 2016 desktop (GTX 1060 6 GB · 16 GB DDR4 · SATA SSD).**
|
|
6
|
+
|
|
7
|
+
     [](https://x.com/federico_sciuca)
|
|
8
|
+
|
|
9
|
+
<p align="center"><img src="weights/data/hero_placement.png" width="880" alt="Placement across memory tiers: disk 2-bit cold experts, RAM 2-bit experts + probed fragile band at 4-bit, VRAM 4-bit attention — one law ties them"></p>
|
|
10
|
+
|
|
11
|
+
> **▶ Try the interactive calculator: [Will it run — and how fast?](https://federicots.github.io/quantprobe/)**
|
|
12
|
+
> Pick any model + your machine → predicted tok/s, memory fit, quality cost, and your cheapest next upgrade — from the law below, with your config plotted against every validated measurement.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
**New here? → [QUICKSTART.md](QUICKSTART.md) gets you running in 60 seconds.** Two tiers: `plan`/`target` and the web calculator need *nothing* installed; `quantize`/`probe`/`run`/`bench`/`dashboard` drive [llama.cpp](https://github.com/ggml-org/llama.cpp/releases) (point quantprobe at it with `--llama-dir`, `QUANTPROBE_LLAMA_DIR`, or `PATH`). Preview any command without llama.cpp using `--dry`. 16 machine presets ship in (`--machine`): GTX 1060 → RTX 5090, Apple `mac-m2/m3/m4-*`, DGX Spark, Epyc — or pass raw specs. Multi-GPU / RAID? Comma lists aggregate: `--vram 24,24 --disk-bw 14,14`. Big-VRAM + disk-streaming rigs get the three-tier expert-cache row (v1.3).
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## What this is
|
|
21
|
+
|
|
22
|
+
My 2016 desktop can't run frontier models the way a datacenter does — so instead of brute force, I asked *where* every bit and byte should go, and answered it by measurement. Months of experiments later, the result is four laws, a 30-minute probe tool, copy-paste llama.cpp recipes, and one equation that predicts decode speed from 7B to 744B — validated against my own pre-registered predictions and against [colibri](https://github.com/JustVugg/colibri)'s independently published 744B numbers.
|
|
23
|
+
|
|
24
|
+
## Headline results
|
|
25
|
+
|
|
26
|
+
| result | number |
|
|
27
|
+
|---|---|
|
|
28
|
+
| 16B MoE, 2-bit, **data-free**, resident on a 6 GB card | ppl 6.31 → 6.96 (**1.10×**) — beats calibrated SOTA's gap-ratio |
|
|
29
|
+
| Same bytes, different layers (Gemma 4 12B, stock llama.cpp) | **byte-identical files, 2.25 ppl apart** (12.27 vs 10.02) |
|
|
30
|
+
| Gemma 4 12B depth-aware 2-bit | 1.91× → **1.45×** quality cost, ~4.5 GB resident |
|
|
31
|
+
| Qwen3-30B-A3B on the 2016 desktop | **19.3 tok/s** — hybrid placement, *predicted 19 before measuring* |
|
|
32
|
+
| GLM-4.5-Air **110B** from a SATA drive, 16 GB RAM | 0.19 tok/s — inside the law's pre-registered 0.2–0.3 band |
|
|
33
|
+
| RAM overclock (XMP, 2133→3000) | dense **+52%**, pre-registered ×1.41+ |
|
|
34
|
+
|
|
35
|
+
## Why the evidence is unusually strong
|
|
36
|
+
|
|
37
|
+
Most benchmark posts report what happened. I report what I **predicted before it happened** — I wrote the number down, then ran the hardware, and this is the strongest form of empirical evidence I know how to produce:
|
|
38
|
+
|
|
39
|
+
| prediction (made first) | measured (after) |
|
|
40
|
+
|---|---|
|
|
41
|
+
| 110B streamed from SATA: **0.2–0.3 tok/s** | **0.19** |
|
|
42
|
+
| RAM overclock scales in-RAM decode **×1.41+** | **×1.52** |
|
|
43
|
+
| 30B hybrid placement: **~19 tok/s** | **19.30 ± 0.88** |
|
|
44
|
+
| a day-old 118B (Laguna S 2.1) streamed from this SATA drive: **0.2–0.4** ([staked pre-download](preregistrations/2026-07-23-laguna-s-2.1-on-2016-desktop.md)) | **0.38 ± 0.17** |
|
|
45
|
+
| colibri's own 128 GB / 25 GB tiers, from our η bands | land **inside** the bands |
|
|
46
|
+
|
|
47
|
+
Add to that: a **byte-identical control** (two GGUFs the same size, 2.25 ppl apart — only placement differs), a full **claim → script → log manifest** (every number reproducible in-tree), and a set of **documented dead ends** (dynamic top-k, semantic paging, self-speculation — all measured-dead, because a law you only confirm is a law you haven't tested).
|
|
48
|
+
|
|
49
|
+
<p align="center"><img src="weights/data/validation_19tok/live_run_20tps.png" width="880" alt="One frame: Task Manager showing 16 GB DDR4-3000 and the GTX 1060 6GB beside llama.cpp chatting Qwen3-30B-A3B live at 20.4 tok/s generation"></p>
|
|
50
|
+
<p align="center"><em>One frame, no cuts: Task Manager (16 GB @ 3000 MT/s, GTX 1060 6 GB, RAM at 91% — the hybrid placement using the whole machine) beside llama.cpp chatting Qwen3-30B-A3B at <b>20.4 tok/s generation</b> — above the pre-registered 19. Raw logs, hardware attestation + GGUF SHA256: <a href="weights/data/validation_19tok/EVIDENCE.txt">EVIDENCE.txt</a>. Third bench run: 19.26 ± 0.45 (series 19.30 → 19.55 → 19.26).</em></p>
|
|
51
|
+
|
|
52
|
+
**Open pre-registrations** — predictions staked publicly *before* measurement: [colibri v1.1, five falsifiable predictions (2026-07-23)](preregistrations/2026-07-23-colibri-v1.1.md) — dual-SSD scaling, int3 speedup, lattice-vs-scalar, AVX-512 tier-scoping, MTP×MoE antagonism.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
## The four placement laws
|
|
56
|
+
|
|
57
|
+
Full statements, each with its establishing measurement and a falsifiable prediction, in **[LAWS.md](LAWS.md)**.
|
|
58
|
+
|
|
59
|
+
1. **Rotation is rank-conditional.** Incoherence rotation (QuIP#/QTIP/QuaRot) helps full-rank tensors (+0.006 ppl) and destroys low-rank bottlenecks (+1623 ppl) — a ~270,000× swing on effective rank alone.
|
|
60
|
+
2. **Trained networks are dense everywhere.** Experts sit *exactly* at the rate-distortion floor; routing is flat (even across domains — Jaccard 1.00 prose vs code); activations are diffuse. **2-bit is the floor.**
|
|
61
|
+
3. **Fragility is measurable, not predictable.** Gemma late-fragile 4×, Mistral **early-fragile 25×** — architectural near-twins pointing opposite ways. Weight statistics mislead. **Only a 30-minute functional probe decides.**
|
|
62
|
+
4. **The tiered decode law.** `tok/s = η(tier)·BW ÷ active-bytes`, η collapsing per tier across 7B→744B and both projects' hardware. **v1.1 adds the context term**: each generated token also re-reads the whole KV cache from *its* tier — `--ctx` prices it, `bench --depth` measures it (measured here: 20.02 → 16.12 tok/s at 16k depth).
|
|
63
|
+
|
|
64
|
+
<p align="center"><img src="weights/data/x_chart_E_scalinglaw.png" width="700" alt="One scaling law, 7B to 744B, predicted vs measured, including colibri's published tiers"></p>
|
|
65
|
+
|
|
66
|
+
<p align="center"><img src="weights/data/x_chart_D_placement.png" width="700" alt="Byte-identical GGUF files, 2.25 perplexity apart — placement is worth twice the byte budget"></p>
|
|
67
|
+
<p align="center"><img src="weights/data/x_chart_I_kvdepth.png" width="700" alt="Decode speed versus context depth: measured 20.02 tok/s at depth zero falling to 16.12 at 16384, on the Law 4 v2 curve with eta_kv 0.70"></p>
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## Install — and the ten commands
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install quantprobe
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Zero-config on your own box**: `quantprobe plan --gguf model.gguf` auto-detects the machine and reads the model from the file. Presets/flags estimate any *other* machine. `hw`/`plan`/`target`/`optimize` need nothing else installed; the rest drive stock [llama.cpp](https://github.com/ggml-org/llama.cpp/releases) (point at it with `--llama-dir`/`QUANTPROBE_LLAMA_DIR`/`PATH`; preview any command with `--dry`).
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
quantprobe hw # what the law sees on THIS machine (every value source-tagged)
|
|
80
|
+
quantprobe plan --gguf model.gguf # zero-config prediction: placement + tok/s + the launch command
|
|
81
|
+
quantprobe optimize --tps 20 # CHEAPEST PATH to a target: bits x placement x hardware, Pareto-ranked
|
|
82
|
+
quantprobe target --tps 5 --machine gaming --ladder # inverse: target -> smartest model + speed-intelligence ladder
|
|
83
|
+
quantprobe fetch qwen3-30b ./models # robust, resumable download
|
|
84
|
+
quantprobe quantize --gguf f16.gguf --out 2bit.gguf # COMPRESS: depth-aware ~2-bit GGUF (verified: loads + generates)
|
|
85
|
+
quantprobe probe --gguf f16.gguf --eval wiki.test.raw # measure YOUR model's fragile band (~30 min); --apply builds it
|
|
86
|
+
quantprobe run --gguf 2bit.gguf # plan the placement, then LAUNCH llama.cpp chat
|
|
87
|
+
quantprobe bench --gguf 2bit.gguf --contribute # predicted vs measured on your box; opt-in datapoint
|
|
88
|
+
quantprobe dashboard --gguf 2bit.gguf # chat while every reply is scored against the prediction
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The loop is self-validating: `plan` predicted 17.5 for a file we then measured at **18.32 ± 0.17**; the config months of research converged to is what `optimize` picks blind. A measured example of what that's worth: the same model, mis-specified vs law-routed, is **3.38 vs 18.32 tok/s (×5.4)** — [worked examples](docs/EXAMPLES.md).
|
|
92
|
+
|
|
93
|
+
## Help grow the law
|
|
94
|
+
|
|
95
|
+
`quantprobe bench --contribute` prints exactly what would be shared (hardware label, model, predicted-vs-measured) plus a pre-filled issue link — **you review and submit; nothing is ever sent automatically**. Contributed points land on the law chart; the ones *outside* the bands are the most valuable. Open falsifiable predictions anyone can settle: [preregistrations/](preregistrations/).
|
|
96
|
+
|
|
97
|
+
## Deep dives
|
|
98
|
+
|
|
99
|
+
| | |
|
|
100
|
+
|---|---|
|
|
101
|
+
| [QUICKSTART.md](QUICKSTART.md) | 60-second start, three levels; Ollama interop; llama.cpp version notes |
|
|
102
|
+
| [LAWS.md](LAWS.md) | the four laws — statements, measurements, falsifiable predictions, the general form |
|
|
103
|
+
| [docs/EXAMPLES.md](docs/EXAMPLES.md) | worked examples with real outputs: zero-config, the ×5.4 optimizer A/B, probe walkthrough, troubleshooting |
|
|
104
|
+
| [docs/HARDWARE.md](docs/HARDWARE.md) | the 2016 box: exact specs, measured bandwidths, what the next euro buys |
|
|
105
|
+
| [docs/DEEP-DIVE.md](docs/DEEP-DIVE.md) | what's new vs. what's built-on, parity tables, the 744B-at-home projection, repository map |
|
|
106
|
+
| [preregistrations/](preregistrations/) | every staked prediction with its verdict — hits, the near-miss, and the honest miss |
|
|
107
|
+
| [papers/arxiv/](papers/arxiv/) | the paper (submission-ready LaTeX) |
|
|
108
|
+
| [CHANGELOG.md](CHANGELOG.md) | v1.0 → v1.4, every release |
|
|
109
|
+
|
|
110
|
+
## Honest limitations
|
|
111
|
+
|
|
112
|
+
- Perplexity on WikiText-2 is my primary metric; I haven't run task-level evals (MMLU/HellaSwag) yet.
|
|
113
|
+
- My fragility atlas covers four model families — enough to *disprove* universality, not to chart every architecture.
|
|
114
|
+
- 0.19 tok/s for a 110B is a **capacity demonstration, not usable inference** — the honest speed only arrives with faster storage.
|
|
115
|
+
- Speed numbers are single-stream decode on one machine (±25% across environments); the tiered-decode η values are fitted, not derived.
|
|
116
|
+
- No custom runtime: everything rides stock llama.cpp and streaming eval harnesses. The one CUDA kernel is verified in reference, not built.
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
## Credits
|
|
120
|
+
|
|
121
|
+
[colibri](https://github.com/JustVugg/colibri) (744B on 25 GB, pure C) inspired the tier-streaming exploration. The quantization stack builds on [llama.cpp](https://github.com/ggml-org/llama.cpp) and the QTIP/QuIP# incoherence codecs — whose central tool our first law bounds. Independent research by Federico Sciuca, AI-supported, on one desktop; every claim is measured, and every negative that redirected the work is documented. The Law 4 context term (v1.1) was prompted by **u/RogerAI--fyi** (Reddit), who correctly observed the original formulation omitted per-token KV reads — measured, confirmed, and shipped within a day.
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
MIT — see [LICENSE](LICENSE). © 2026 Federico Sciuca.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "quantprobe"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.4.0"
|
|
8
8
|
description = "Probe-then-quantize for LLMs: measure a model's fragility curve, plan bit/tier placement by the tiered decode law, and emit ready-to-run llama.cpp recipes."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -8,4 +8,4 @@ Three commands, all grounded in measured laws (see LAWS.md in the repo):
|
|
|
8
8
|
Every constant in `plan` is fitted from measurements published in the repo, including two
|
|
9
9
|
pre-registered hardware predictions confirmed within 8%.
|
|
10
10
|
"""
|
|
11
|
-
__version__ = "1.
|
|
11
|
+
__version__ = "1.4.0"
|
|
@@ -84,6 +84,13 @@ def main():
|
|
|
84
84
|
z.add_argument("--llama-dir", default=None)
|
|
85
85
|
z.add_argument("--dry", action="store_true")
|
|
86
86
|
|
|
87
|
+
o = sub.add_parser("optimize", help="cheapest path to a target speed: search bits x placement x KV x hardware over the law")
|
|
88
|
+
o.add_argument("--tps", type=float, default=None, help="target tok/s (omit for the speed frontier)")
|
|
89
|
+
o.add_argument("--max-quality", type=float, default=None, help="quality-cost ceiling (default 1.12)")
|
|
90
|
+
o.add_argument("--any-runtime", action="store_true", help="include placements needing expert-caching runtimes (ktransformers-class), not just stock llama.cpp")
|
|
91
|
+
o.add_argument("--allow-prune", action="store_true", help="include REAP-class pruned variants (domain-specialized: +39%% out-of-domain ppl measured)")
|
|
92
|
+
hwargs(o)
|
|
93
|
+
|
|
87
94
|
hwp = sub.add_parser("hw", help="detect THIS machine's memory tiers (no flags needed); every value tagged with its source")
|
|
88
95
|
hwp.add_argument("--measure", default=None, metavar="FILE", help="also MEASURE sequential disk read on a real file (e.g. a GGUF)")
|
|
89
96
|
|
|
@@ -109,6 +116,9 @@ def main():
|
|
|
109
116
|
elif a.cmd == "target":
|
|
110
117
|
from . import target
|
|
111
118
|
target.run(a)
|
|
119
|
+
elif a.cmd == "optimize":
|
|
120
|
+
from . import optimize
|
|
121
|
+
optimize.run(a)
|
|
112
122
|
elif a.cmd == "hw":
|
|
113
123
|
from . import detect
|
|
114
124
|
detect.run(a)
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""quantprobe optimize — the cheapest path to a target speed.
|
|
2
|
+
|
|
3
|
+
A pure SEARCH LAYER over the frozen decode law: enumerate lever combinations, price each with
|
|
4
|
+
plan.evaluate(), rank by (meets target, quality cost, euros, speed). The law is never modified —
|
|
5
|
+
the optimizer only reads it, so every published anchor is untouchable by construction.
|
|
6
|
+
|
|
7
|
+
Levers and their measured gates:
|
|
8
|
+
bits effective bits/weight ladder, priced with the DEPTH-AWARE quality curve (measured;
|
|
9
|
+
uniform quantization costs ~1.3x more quality at <=2.5 bits — Gemma 1.91x vs 1.45x)
|
|
10
|
+
kv-q8 quantized K-cache (kvp x0.75). GATED OFF on weak-decode GPUs: measured -83%
|
|
11
|
+
at 16k depth on Pascal (2026-07-24, no flash attention -> per-token dequant tax).
|
|
12
|
+
Offered [est] only where geta >= 0.5; verify with `bench --depth`.
|
|
13
|
+
prune REAP-class 50% expert pruning (total x0.82, file shrinks, active bytes UNCHANGED).
|
|
14
|
+
Measured +39% out-of-domain perplexity (pre-registration #8) — domain-specialized,
|
|
15
|
+
never ranked first without --allow-prune.
|
|
16
|
+
hardware euro-priced deltas from the projections table: XMP (free), +16GB RAM (~40), NVMe (~100).
|
|
17
|
+
"""
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
from . import plan as planmod
|
|
20
|
+
|
|
21
|
+
BITS_LADDER = [2.0, 2.5, 3.0, 3.5, 4.5]
|
|
22
|
+
REALIZE = {
|
|
23
|
+
2.0: 'quantize --gguf <f16> --protect-late 8 (base Q2_K, narrow probed band)',
|
|
24
|
+
2.5: 'quantize --gguf <f16> --protect-late 12 (base Q2_K - the validated default)',
|
|
25
|
+
3.0: 'quantize --gguf <f16> --protect-late 20 (or base Q3_K_S)',
|
|
26
|
+
3.5: 'fetch a Q3_K_M and probe --apply',
|
|
27
|
+
4.5: 'fetch a Q4_K_M (straight; no probe needed at 4-bit)',
|
|
28
|
+
}
|
|
29
|
+
HW_DELTAS = [
|
|
30
|
+
("as-is", 0, {}),
|
|
31
|
+
("+16GB RAM (~40 EUR used)", 40, {"rc": +16}),
|
|
32
|
+
("NVMe SSD (~100 EUR)", 100, {"db_min": 3.5}),
|
|
33
|
+
("+RAM & NVMe (~140 EUR)", 140, {"rc": +16, "db_min": 3.5}),
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def resolve(a):
|
|
38
|
+
"""Model + machine resolution, same semantics as plan.run (autospec + autodetect included)."""
|
|
39
|
+
from . import spec as specmod
|
|
40
|
+
specmod.apply(a, quiet=True)
|
|
41
|
+
if getattr(a, "bits", None) is None:
|
|
42
|
+
a.bits = 2.5
|
|
43
|
+
m = dict(planmod.MODELS[a.model]) if getattr(a, "model", None) in planmod.MODELS else {}
|
|
44
|
+
t = a.total or m.get("t") or 13.0
|
|
45
|
+
ac = a.active or m.get("a") or t
|
|
46
|
+
ne = a.always_active or m.get("ne") or (ac if ac >= t * 0.9 else ac * 0.35)
|
|
47
|
+
moe = m.get("moe", ac < t * 0.9)
|
|
48
|
+
hw = dict(planmod.MACHINES[a.machine]) if getattr(a, "machine", None) in planmod.MACHINES else {}
|
|
49
|
+
if not hw and all(getattr(a, k, None) is None for k in ("vram", "vram_bw", "ram", "ram_bw", "disk_bw")):
|
|
50
|
+
from . import detect as detmod
|
|
51
|
+
auto, _ = detmod.detect()
|
|
52
|
+
hw = dict(vc=auto["vram"], vb=auto["vram_bw"], rc=auto["ram"], rb=auto["ram_bw"],
|
|
53
|
+
db=auto["disk_bw"], geta=auto.get("geta", 0.45), gl=auto.get("gl"),
|
|
54
|
+
hint="THIS machine [auto-detected]")
|
|
55
|
+
print("[quantprobe] hardware auto-detected (pass --machine/flags to optimize another box)")
|
|
56
|
+
vc = planmod.agg_cap(a.vram) if a.vram is not None else hw.get("vc", 0)
|
|
57
|
+
vb = planmod.agg_bw(a.vram_bw, 0.85) if a.vram_bw is not None else hw.get("vb", 0)
|
|
58
|
+
rc = a.ram if a.ram is not None else hw.get("rc", 16)
|
|
59
|
+
rb = a.ram_bw if a.ram_bw is not None else hw.get("rb", 40)
|
|
60
|
+
db = planmod.agg_bw(a.disk_bw, 0.75) if a.disk_bw is not None else hw.get("db", 0.5)
|
|
61
|
+
geta = hw.get("geta", 0.45); gl = hw.get("gl")
|
|
62
|
+
ctx = getattr(a, "ctx", 0) or 0
|
|
63
|
+
kvp = (a.kv_per_pos * 1024 if getattr(a, "kv_per_pos", None) else m.get("kvp", planmod.DEFAULT_KVP))
|
|
64
|
+
return m, t, ac, ne, moe, (vc or 0, vb or 0, rc or 16, rb or 40, db or 0.5, geta, gl), ctx, kvp
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def run(a):
|
|
68
|
+
m, t, ac, ne, moe, (vc, vb, rc, rb, db, geta, gl), ctx, kvp = resolve(a)
|
|
69
|
+
tgt = getattr(a, "tps", None)
|
|
70
|
+
maxq = getattr(a, "max_quality", None) or 1.12
|
|
71
|
+
allow_prune = getattr(a, "allow_prune", False)
|
|
72
|
+
kvq_ok = geta >= 0.5 # measured gate: Pascal-class collapses (-83% @16k)
|
|
73
|
+
rows = []
|
|
74
|
+
for hw_name, euro, delta in HW_DELTAS:
|
|
75
|
+
rc2 = rc + delta.get("rc", 0)
|
|
76
|
+
db2 = max(db, delta.get("db_min", db))
|
|
77
|
+
if euro and rc2 == rc and db2 == db:
|
|
78
|
+
continue # delta changes nothing on this box
|
|
79
|
+
for bits in BITS_LADDER:
|
|
80
|
+
for prune, pf in ((False, 1.0),) + (((True, 0.82),) if allow_prune and moe else ()):
|
|
81
|
+
for kvq, kf in ((False, 1.0),) + (((True, 0.75),) if kvq_ok and ctx > 0 else ()):
|
|
82
|
+
q = planmod.qual_of(moe, bits) * (1.0 if not prune else 1.0) # in-domain qual; OOD flagged in text
|
|
83
|
+
if q > maxq:
|
|
84
|
+
continue
|
|
85
|
+
_, _, cfgs = planmod.evaluate(t * pf, ac, ne, moe, bits, vc, vb, rc2, rb, db2,
|
|
86
|
+
geta, 1.0, gl, ctx=ctx, kvp=kvp * kf)
|
|
87
|
+
if not cfgs:
|
|
88
|
+
continue
|
|
89
|
+
if not getattr(a, "any_runtime", False):
|
|
90
|
+
cfgs = [c for c in cfgs if "expert cache" not in c[0]] or cfgs
|
|
91
|
+
name, tps, warn, flags = cfgs[0]
|
|
92
|
+
desc = f"{bits:g}-bit depth-aware + {name}"
|
|
93
|
+
tags = []
|
|
94
|
+
if prune:
|
|
95
|
+
tags.append("PRUNED: +39% out-of-domain ppl measured - domain use only")
|
|
96
|
+
if kvq:
|
|
97
|
+
tags.append("KV q8 [est - needs FA; measured trap on Pascal-class]")
|
|
98
|
+
if hw_name != "as-is":
|
|
99
|
+
desc += f" + {hw_name}"
|
|
100
|
+
rows.append(dict(tps=tps, q=q, euro=euro, bits=bits, desc=desc,
|
|
101
|
+
tags=tags, flags=flags, warn=warn))
|
|
102
|
+
# Pareto: drop rows beaten on every axis
|
|
103
|
+
keep = []
|
|
104
|
+
for r in sorted(rows, key=lambda x: (-x["tps"], x["q"], x["euro"])):
|
|
105
|
+
if not any(k["tps"] >= r["tps"] and k["q"] <= r["q"] and k["euro"] <= r["euro"]
|
|
106
|
+
and (k["tps"], k["q"], k["euro"]) != (r["tps"], r["q"], r["euro"]) for k in keep):
|
|
107
|
+
keep.append(r)
|
|
108
|
+
if tgt:
|
|
109
|
+
meeting = [r for r in keep if r["tps"] >= tgt]
|
|
110
|
+
ranked = (sorted(meeting, key=lambda x: (x["q"], x["euro"], -x["tps"])) or
|
|
111
|
+
sorted(keep, key=lambda x: -x["tps"])[:1])
|
|
112
|
+
headline = "cheapest configuration meeting the target" if meeting else \
|
|
113
|
+
"TARGET NOT REACHABLE on this hardware - fastest available:"
|
|
114
|
+
else:
|
|
115
|
+
ranked = sorted(keep, key=lambda x: (-x["tps"], x["q"], x["euro"]))
|
|
116
|
+
headline = "speed frontier (quality ceiling x%.2f)" % maxq
|
|
117
|
+
print(f"\nquantprobe optimize - {m.get('hint', 'custom model')} on "
|
|
118
|
+
f"{'this machine' if not getattr(a, 'machine', None) else a.machine}"
|
|
119
|
+
+ (f" | target {tgt:g} tok/s" if tgt else "") + (f" | ctx {ctx}" if ctx else ""))
|
|
120
|
+
print(f" {headline}\n")
|
|
121
|
+
for i, r in enumerate(ranked[:6]):
|
|
122
|
+
star = "*" if i == 0 else " "
|
|
123
|
+
euro = "free" if r["euro"] == 0 else f"~{r['euro']}EUR"
|
|
124
|
+
print(f" {star} {r['tps']:6.1f} tok/s quality x{r['q']:.2f} {euro:>7s} {r['desc']}")
|
|
125
|
+
for tag in r["tags"]:
|
|
126
|
+
print(f" [{tag}]")
|
|
127
|
+
best = ranked[0]
|
|
128
|
+
print(f"\n realize the pick:")
|
|
129
|
+
print(f" quantprobe {REALIZE.get(best['bits'], 'quantize')}")
|
|
130
|
+
print(f" quantprobe run --gguf <the file> ... # launches with: {best['flags']}")
|
|
131
|
+
print("\n (search over the validated law only - no new physics; quality = depth-aware recipe,")
|
|
132
|
+
print(" uniform quantization costs ~1.3x more at <=2.5 bits. Estimates +/-25%.)")
|
|
133
|
+
return ranked
|
|
@@ -204,5 +204,24 @@ def run(args):
|
|
|
204
204
|
if c2[0][1] > best[1] * 1.08: alts.append(("NVMe SSD", c2[0][1]))
|
|
205
205
|
if alts:
|
|
206
206
|
print(" upgrade advisor: " + " | ".join(f"{n} -> ~{v:.1f} tok/s" for n, v in alts))
|
|
207
|
+
# tier-boundary advisor: the biggest cliffs sit at tier boundaries (REAP finding, pre-reg #8 P-c).
|
|
208
|
+
# If a modest shave of the FILE crosses one, say so and price it.
|
|
209
|
+
kvg = ctx * kvp / 1e9 if ctx > 0 else 0.0
|
|
210
|
+
size_now = size
|
|
211
|
+
for tier_name, cap, lever in (("VRAM (all-in-VRAM)", vc * 0.90, "next quant step down / tighter probed band / pruned variant"),
|
|
212
|
+
("RAM (pure-CPU)", max(rc - 4, 1), "next quant step down / tighter probed band")):
|
|
213
|
+
if cap <= 0 or size_now + kvg <= cap:
|
|
214
|
+
continue
|
|
215
|
+
gap = size_now + kvg - cap
|
|
216
|
+
if gap > size_now * 0.30:
|
|
217
|
+
continue # not a "shave" - a different model class
|
|
218
|
+
fit_scale = max(0.05, (cap - kvg) / size_now) * 0.995
|
|
219
|
+
_, _, c9 = evaluate(t, a, ne, moe, args.bits, vc, vb, rc, rb, db, geta, fit_scale, gl,
|
|
220
|
+
ctx=ctx, kvp=kvp)
|
|
221
|
+
promoted = [x for x in c9 if x[0].startswith("all in VRAM")] if "VRAM" in tier_name else [x for x in c9 if x[0].startswith("pure CPU")]
|
|
222
|
+
if promoted and promoted[0][1] > best[1] * 1.15:
|
|
223
|
+
print(f" tier-boundary advisor: this config is {gap:.1f} GB over the {tier_name} boundary - "
|
|
224
|
+
f"shave it ({lever}) -> ~{promoted[0][1]:.1f} tok/s (x{promoted[0][1]/best[1]:.1f})")
|
|
225
|
+
break # nearest boundary only
|
|
207
226
|
print("\n (eta bands fitted from published measurements; estimates +/-25%. "
|
|
208
227
|
"Hybrid needs --no-mmap.)")
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: quantprobe
|
|
3
|
+
Version: 1.4.0
|
|
4
|
+
Summary: Probe-then-quantize for LLMs: measure a model's fragility curve, plan bit/tier placement by the tiered decode law, and emit ready-to-run llama.cpp recipes.
|
|
5
|
+
Author: Federico Sciuca
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/FedericoTs/quantprobe
|
|
8
|
+
Keywords: llm,quantization,llama.cpp,gguf,inference,moe
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: gguf>=0.9
|
|
16
|
+
Requires-Dist: requests>=2.28
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# quantprobe
|
|
20
|
+
|
|
21
|
+
### Placement beats budget
|
|
22
|
+
|
|
23
|
+
**Where your bits sit — which layers, which memory tier — matters more than how many you have. Four falsification-tested laws for running big LLMs on hardware you already own, every number measured on one 2016 desktop (GTX 1060 6 GB · 16 GB DDR4 · SATA SSD).**
|
|
24
|
+
|
|
25
|
+
     [](https://x.com/federico_sciuca)
|
|
26
|
+
|
|
27
|
+
<p align="center"><img src="weights/data/hero_placement.png" width="880" alt="Placement across memory tiers: disk 2-bit cold experts, RAM 2-bit experts + probed fragile band at 4-bit, VRAM 4-bit attention — one law ties them"></p>
|
|
28
|
+
|
|
29
|
+
> **▶ Try the interactive calculator: [Will it run — and how fast?](https://federicots.github.io/quantprobe/)**
|
|
30
|
+
> Pick any model + your machine → predicted tok/s, memory fit, quality cost, and your cheapest next upgrade — from the law below, with your config plotted against every validated measurement.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
**New here? → [QUICKSTART.md](QUICKSTART.md) gets you running in 60 seconds.** Two tiers: `plan`/`target` and the web calculator need *nothing* installed; `quantize`/`probe`/`run`/`bench`/`dashboard` drive [llama.cpp](https://github.com/ggml-org/llama.cpp/releases) (point quantprobe at it with `--llama-dir`, `QUANTPROBE_LLAMA_DIR`, or `PATH`). Preview any command without llama.cpp using `--dry`. 16 machine presets ship in (`--machine`): GTX 1060 → RTX 5090, Apple `mac-m2/m3/m4-*`, DGX Spark, Epyc — or pass raw specs. Multi-GPU / RAID? Comma lists aggregate: `--vram 24,24 --disk-bw 14,14`. Big-VRAM + disk-streaming rigs get the three-tier expert-cache row (v1.3).
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## What this is
|
|
39
|
+
|
|
40
|
+
My 2016 desktop can't run frontier models the way a datacenter does — so instead of brute force, I asked *where* every bit and byte should go, and answered it by measurement. Months of experiments later, the result is four laws, a 30-minute probe tool, copy-paste llama.cpp recipes, and one equation that predicts decode speed from 7B to 744B — validated against my own pre-registered predictions and against [colibri](https://github.com/JustVugg/colibri)'s independently published 744B numbers.
|
|
41
|
+
|
|
42
|
+
## Headline results
|
|
43
|
+
|
|
44
|
+
| result | number |
|
|
45
|
+
|---|---|
|
|
46
|
+
| 16B MoE, 2-bit, **data-free**, resident on a 6 GB card | ppl 6.31 → 6.96 (**1.10×**) — beats calibrated SOTA's gap-ratio |
|
|
47
|
+
| Same bytes, different layers (Gemma 4 12B, stock llama.cpp) | **byte-identical files, 2.25 ppl apart** (12.27 vs 10.02) |
|
|
48
|
+
| Gemma 4 12B depth-aware 2-bit | 1.91× → **1.45×** quality cost, ~4.5 GB resident |
|
|
49
|
+
| Qwen3-30B-A3B on the 2016 desktop | **19.3 tok/s** — hybrid placement, *predicted 19 before measuring* |
|
|
50
|
+
| GLM-4.5-Air **110B** from a SATA drive, 16 GB RAM | 0.19 tok/s — inside the law's pre-registered 0.2–0.3 band |
|
|
51
|
+
| RAM overclock (XMP, 2133→3000) | dense **+52%**, pre-registered ×1.41+ |
|
|
52
|
+
|
|
53
|
+
## Why the evidence is unusually strong
|
|
54
|
+
|
|
55
|
+
Most benchmark posts report what happened. I report what I **predicted before it happened** — I wrote the number down, then ran the hardware, and this is the strongest form of empirical evidence I know how to produce:
|
|
56
|
+
|
|
57
|
+
| prediction (made first) | measured (after) |
|
|
58
|
+
|---|---|
|
|
59
|
+
| 110B streamed from SATA: **0.2–0.3 tok/s** | **0.19** |
|
|
60
|
+
| RAM overclock scales in-RAM decode **×1.41+** | **×1.52** |
|
|
61
|
+
| 30B hybrid placement: **~19 tok/s** | **19.30 ± 0.88** |
|
|
62
|
+
| a day-old 118B (Laguna S 2.1) streamed from this SATA drive: **0.2–0.4** ([staked pre-download](preregistrations/2026-07-23-laguna-s-2.1-on-2016-desktop.md)) | **0.38 ± 0.17** |
|
|
63
|
+
| colibri's own 128 GB / 25 GB tiers, from our η bands | land **inside** the bands |
|
|
64
|
+
|
|
65
|
+
Add to that: a **byte-identical control** (two GGUFs the same size, 2.25 ppl apart — only placement differs), a full **claim → script → log manifest** (every number reproducible in-tree), and a set of **documented dead ends** (dynamic top-k, semantic paging, self-speculation — all measured-dead, because a law you only confirm is a law you haven't tested).
|
|
66
|
+
|
|
67
|
+
<p align="center"><img src="weights/data/validation_19tok/live_run_20tps.png" width="880" alt="One frame: Task Manager showing 16 GB DDR4-3000 and the GTX 1060 6GB beside llama.cpp chatting Qwen3-30B-A3B live at 20.4 tok/s generation"></p>
|
|
68
|
+
<p align="center"><em>One frame, no cuts: Task Manager (16 GB @ 3000 MT/s, GTX 1060 6 GB, RAM at 91% — the hybrid placement using the whole machine) beside llama.cpp chatting Qwen3-30B-A3B at <b>20.4 tok/s generation</b> — above the pre-registered 19. Raw logs, hardware attestation + GGUF SHA256: <a href="weights/data/validation_19tok/EVIDENCE.txt">EVIDENCE.txt</a>. Third bench run: 19.26 ± 0.45 (series 19.30 → 19.55 → 19.26).</em></p>
|
|
69
|
+
|
|
70
|
+
**Open pre-registrations** — predictions staked publicly *before* measurement: [colibri v1.1, five falsifiable predictions (2026-07-23)](preregistrations/2026-07-23-colibri-v1.1.md) — dual-SSD scaling, int3 speedup, lattice-vs-scalar, AVX-512 tier-scoping, MTP×MoE antagonism.
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
## The four placement laws
|
|
74
|
+
|
|
75
|
+
Full statements, each with its establishing measurement and a falsifiable prediction, in **[LAWS.md](LAWS.md)**.
|
|
76
|
+
|
|
77
|
+
1. **Rotation is rank-conditional.** Incoherence rotation (QuIP#/QTIP/QuaRot) helps full-rank tensors (+0.006 ppl) and destroys low-rank bottlenecks (+1623 ppl) — a ~270,000× swing on effective rank alone.
|
|
78
|
+
2. **Trained networks are dense everywhere.** Experts sit *exactly* at the rate-distortion floor; routing is flat (even across domains — Jaccard 1.00 prose vs code); activations are diffuse. **2-bit is the floor.**
|
|
79
|
+
3. **Fragility is measurable, not predictable.** Gemma late-fragile 4×, Mistral **early-fragile 25×** — architectural near-twins pointing opposite ways. Weight statistics mislead. **Only a 30-minute functional probe decides.**
|
|
80
|
+
4. **The tiered decode law.** `tok/s = η(tier)·BW ÷ active-bytes`, η collapsing per tier across 7B→744B and both projects' hardware. **v1.1 adds the context term**: each generated token also re-reads the whole KV cache from *its* tier — `--ctx` prices it, `bench --depth` measures it (measured here: 20.02 → 16.12 tok/s at 16k depth).
|
|
81
|
+
|
|
82
|
+
<p align="center"><img src="weights/data/x_chart_E_scalinglaw.png" width="700" alt="One scaling law, 7B to 744B, predicted vs measured, including colibri's published tiers"></p>
|
|
83
|
+
|
|
84
|
+
<p align="center"><img src="weights/data/x_chart_D_placement.png" width="700" alt="Byte-identical GGUF files, 2.25 perplexity apart — placement is worth twice the byte budget"></p>
|
|
85
|
+
<p align="center"><img src="weights/data/x_chart_I_kvdepth.png" width="700" alt="Decode speed versus context depth: measured 20.02 tok/s at depth zero falling to 16.12 at 16384, on the Law 4 v2 curve with eta_kv 0.70"></p>
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
## Install — and the ten commands
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install quantprobe
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Zero-config on your own box**: `quantprobe plan --gguf model.gguf` auto-detects the machine and reads the model from the file. Presets/flags estimate any *other* machine. `hw`/`plan`/`target`/`optimize` need nothing else installed; the rest drive stock [llama.cpp](https://github.com/ggml-org/llama.cpp/releases) (point at it with `--llama-dir`/`QUANTPROBE_LLAMA_DIR`/`PATH`; preview any command with `--dry`).
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
quantprobe hw # what the law sees on THIS machine (every value source-tagged)
|
|
98
|
+
quantprobe plan --gguf model.gguf # zero-config prediction: placement + tok/s + the launch command
|
|
99
|
+
quantprobe optimize --tps 20 # CHEAPEST PATH to a target: bits x placement x hardware, Pareto-ranked
|
|
100
|
+
quantprobe target --tps 5 --machine gaming --ladder # inverse: target -> smartest model + speed-intelligence ladder
|
|
101
|
+
quantprobe fetch qwen3-30b ./models # robust, resumable download
|
|
102
|
+
quantprobe quantize --gguf f16.gguf --out 2bit.gguf # COMPRESS: depth-aware ~2-bit GGUF (verified: loads + generates)
|
|
103
|
+
quantprobe probe --gguf f16.gguf --eval wiki.test.raw # measure YOUR model's fragile band (~30 min); --apply builds it
|
|
104
|
+
quantprobe run --gguf 2bit.gguf # plan the placement, then LAUNCH llama.cpp chat
|
|
105
|
+
quantprobe bench --gguf 2bit.gguf --contribute # predicted vs measured on your box; opt-in datapoint
|
|
106
|
+
quantprobe dashboard --gguf 2bit.gguf # chat while every reply is scored against the prediction
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The loop is self-validating: `plan` predicted 17.5 for a file we then measured at **18.32 ± 0.17**; the config months of research converged to is what `optimize` picks blind. A measured example of what that's worth: the same model, mis-specified vs law-routed, is **3.38 vs 18.32 tok/s (×5.4)** — [worked examples](docs/EXAMPLES.md).
|
|
110
|
+
|
|
111
|
+
## Help grow the law
|
|
112
|
+
|
|
113
|
+
`quantprobe bench --contribute` prints exactly what would be shared (hardware label, model, predicted-vs-measured) plus a pre-filled issue link — **you review and submit; nothing is ever sent automatically**. Contributed points land on the law chart; the ones *outside* the bands are the most valuable. Open falsifiable predictions anyone can settle: [preregistrations/](preregistrations/).
|
|
114
|
+
|
|
115
|
+
## Deep dives
|
|
116
|
+
|
|
117
|
+
| | |
|
|
118
|
+
|---|---|
|
|
119
|
+
| [QUICKSTART.md](QUICKSTART.md) | 60-second start, three levels; Ollama interop; llama.cpp version notes |
|
|
120
|
+
| [LAWS.md](LAWS.md) | the four laws — statements, measurements, falsifiable predictions, the general form |
|
|
121
|
+
| [docs/EXAMPLES.md](docs/EXAMPLES.md) | worked examples with real outputs: zero-config, the ×5.4 optimizer A/B, probe walkthrough, troubleshooting |
|
|
122
|
+
| [docs/HARDWARE.md](docs/HARDWARE.md) | the 2016 box: exact specs, measured bandwidths, what the next euro buys |
|
|
123
|
+
| [docs/DEEP-DIVE.md](docs/DEEP-DIVE.md) | what's new vs. what's built-on, parity tables, the 744B-at-home projection, repository map |
|
|
124
|
+
| [preregistrations/](preregistrations/) | every staked prediction with its verdict — hits, the near-miss, and the honest miss |
|
|
125
|
+
| [papers/arxiv/](papers/arxiv/) | the paper (submission-ready LaTeX) |
|
|
126
|
+
| [CHANGELOG.md](CHANGELOG.md) | v1.0 → v1.4, every release |
|
|
127
|
+
|
|
128
|
+
## Honest limitations
|
|
129
|
+
|
|
130
|
+
- Perplexity on WikiText-2 is my primary metric; I haven't run task-level evals (MMLU/HellaSwag) yet.
|
|
131
|
+
- My fragility atlas covers four model families — enough to *disprove* universality, not to chart every architecture.
|
|
132
|
+
- 0.19 tok/s for a 110B is a **capacity demonstration, not usable inference** — the honest speed only arrives with faster storage.
|
|
133
|
+
- Speed numbers are single-stream decode on one machine (±25% across environments); the tiered-decode η values are fitted, not derived.
|
|
134
|
+
- No custom runtime: everything rides stock llama.cpp and streaming eval harnesses. The one CUDA kernel is verified in reference, not built.
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
## Credits
|
|
138
|
+
|
|
139
|
+
[colibri](https://github.com/JustVugg/colibri) (744B on 25 GB, pure C) inspired the tier-streaming exploration. The quantization stack builds on [llama.cpp](https://github.com/ggml-org/llama.cpp) and the QTIP/QuIP# incoherence codecs — whose central tool our first law bounds. Independent research by Federico Sciuca, AI-supported, on one desktop; every claim is measured, and every negative that redirected the work is documented. The Law 4 context term (v1.1) was prompted by **u/RogerAI--fyi** (Reddit), who correctly observed the original formulation omitted per-token KV reads — measured, confirmed, and shipped within a day.
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT — see [LICENSE](LICENSE). © 2026 Federico Sciuca.
|