vipera-ai 1.2.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.
@@ -0,0 +1,50 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg-info/
7
+ .eggs/
8
+ dist/
9
+ build/
10
+ .venv/
11
+ venv/
12
+ ENV/
13
+ .env
14
+ .pytest_cache/
15
+ .mypy_cache/
16
+ .ruff_cache/
17
+ .coverage
18
+ .coverage.*
19
+ htmlcov/
20
+ coverage.xml
21
+
22
+ # Models & artifacts
23
+ *.gguf
24
+ *.safetensors
25
+ *.bin
26
+ *.pt
27
+ *.pth
28
+ models/
29
+ out/
30
+ *.vipera.json
31
+
32
+ # Secrets
33
+ .env
34
+ .env.*
35
+ *.pem
36
+ *.key
37
+ secrets/
38
+ *.log
39
+
40
+ # OS / IDE
41
+ .DS_Store
42
+ Thumbs.db
43
+ .idea/
44
+ .vscode/
45
+ *.swp
46
+
47
+ # Tooling
48
+ demo.cast
49
+ bench/results/
50
+ .git.backup.*
@@ -0,0 +1,87 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [1.2.0] - 2026-10-20
11
+
12
+ ### Changed
13
+ - **Planner budgets VRAM from real per-layer sizes** — registering a model now
14
+ stores `layer_bytes` (mean size of one repeating `blk.N` block, read from the
15
+ GGUF index). `size_bytes / n_layers` charged the ~1 GB of `token_embd` +
16
+ `output.weight` to every layer, so a 14B/Q4 model on a 4 GB card now offloads
17
+ one or two more layers at the same VRAM headroom (11 vs 9 at 8K with 3.7 GB
18
+ free).
19
+ - **VRAM plan keeps room for GPU compute buffers** — the planner reserves
20
+ 0.3 GB on top of the 1 GB driver reserve. Sizing to the last byte of VRAM
21
+ produced a plan llama.cpp cannot create a context for, and the engine's only
22
+ fallback is CPU-only: on the GTX 1650, 11 offloaded layers load and 12 fail.
23
+ - **Prompt-prefix reuse is now guaranteed by the dependency floor** —
24
+ `llama-cpp-python` is pinned to `>=0.3.36`, the release that keeps the KV
25
+ cache for a shared prompt prefix. On 0.5B, a 1230-token prompt cost 1.5 s
26
+ cold and 0.18 s for the +19-token follow-up turn.
27
+ - **`vipera bench` reports the engine's actual placement** — a GPU load that
28
+ fell back to CPU no longer prints the planned layer count (16K/f16 on a
29
+ 4 GB card falls back and now shows 0/40 rather than 9/40).
30
+
31
+ ## [1.1.0] - 2026-10-20
32
+
33
+ ### Added
34
+ - **Tool calling** — `/v1/chat/completions` accepts `tools` and `tool_choice`,
35
+ forwards `tool_calls` back in both streaming and non-streaming responses, and
36
+ accepts assistant tool-call turns plus `tool` results with `tool_call_id`.
37
+ - **Full OpenAI sampling pass-through** — `stop`, `seed`, `presence_penalty`,
38
+ `frequency_penalty`, `top_k`, `min_p`, `logit_bias`, `logprobs`,
39
+ `top_logprobs`, `response_format`, and `stream_options.include_usage` now
40
+ reach `llama.cpp` instead of being dropped by the request model.
41
+ - **GGUF inspection** — `vipera model inspect <path> [--tensors]` reads the GGUF
42
+ index only and reports architecture, per-layer/category size distribution,
43
+ quantization mix, and warnings for quality-sensitive tensors quantized below
44
+ Q4_K. Backed by `vipera.gguf_analyzer.analyze_gguf()`.
45
+ - **GGUF optimization** — `vipera model imatrix`, `model quantize`, and
46
+ `model optimize` wrap `llama-imatrix` / `llama-quantize` with imatrix support,
47
+ MoE `--prior-weight`, layer pruning, target-size quant selection, binary
48
+ discovery (`--bin-dir`, `VIPERA_LLAMA_BIN`, `PATH`), dry runs, and partial
49
+ output cleanup. Planning helpers live in `vipera.optimizer`.
50
+
51
+ ### Changed
52
+ - **Faster readiness** — `serve start` no longer runs the 20-token speed check
53
+ before binding, and the fixed 1.2 s boot animation is gone. The check is now
54
+ opt-in via `vipera serve start --bench`; the `show_bench_on_start` config key
55
+ was removed.
56
+
57
+ ## [1.0.0] - 2026-10-17
58
+
59
+ First public release.
60
+
61
+ ### Added
62
+ - **OpenAI-compatible HTTP gateway** — `/v1/chat/completions`,
63
+ `/v1/models`, `/health`. Real SSE streaming.
64
+ - **Hardware-aware planner** — reads CPU cores, RAM, GPU name, VRAM and emits
65
+ a `Plan` (`gpu_layers`, `context`, `kv_cache`, `flash_attn`, `n_batch`,
66
+ `use_mlock`, `offload_kqv`).
67
+ - **Engine fallback** — retries with a CPU-safe plan when GPU offload fails at
68
+ load; retries without `mlock` when `mlock` is restricted.
69
+ - **Model manager** — `model search` (HuggingFace), `model import`,
70
+ `model list`, `model rm`. Auto-sets the imported model as default.
71
+ - **CLI chat** — interactive `chat repl` and scriptable `chat oneshot`.
72
+ - **Benchmark** — `bench run` measures prefill (TTFT-based) and generation
73
+ throughput across context sizes.
74
+ - **Diagnostics** — `system doctor` for runtime, library, and hardware;
75
+ `system config` for typed, validated config access.
76
+ - **Rich CLI** — banner, model picker, typewriter streaming.
77
+
78
+ ### Known limitations
79
+ - Tool calls / function calling are not implemented.
80
+ - Multi-model serving is not implemented.
81
+ - The `model` field in `/v1/chat/completions` is ignored; one gateway serves
82
+ one model.
83
+
84
+ [Unreleased]: https://github.com/vipera-iso/vipera/compare/v1.2.0...HEAD
85
+ [1.2.0]: https://github.com/vipera-iso/vipera/releases/tag/v1.2.0
86
+ [1.1.0]: https://github.com/vipera-iso/vipera/releases/tag/v1.1.0
87
+ [1.0.0]: https://github.com/vipera-iso/vipera/releases/tag/v1.0.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vipera
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,458 @@
1
+ Metadata-Version: 2.5
2
+ Name: vipera-ai
3
+ Version: 1.2.0
4
+ Summary: Modern local AI gateway — OpenAI-compatible, GGUF-native
5
+ Project-URL: Homepage, https://github.com/vipera-iso/vipera
6
+ Project-URL: Documentation, https://github.com/vipera-iso/vipera#readme
7
+ Project-URL: Repository, https://github.com/vipera-iso/vipera
8
+ Project-URL: Issues, https://github.com/vipera-iso/vipera/issues
9
+ Project-URL: Changelog, https://github.com/vipera-iso/vipera/blob/main/CHANGELOG.md
10
+ Author: Vipera contributors
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: gateway,gguf,inference,llama.cpp,llm,local-ai,moe,openai,openai-api,streaming
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
23
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.11
26
+ Requires-Dist: fastapi>=0.110
27
+ Requires-Dist: huggingface-hub>=0.23
28
+ Requires-Dist: psutil>=5.9
29
+ Requires-Dist: pydantic>=2.6
30
+ Requires-Dist: rich>=13.7
31
+ Requires-Dist: typer>=0.12
32
+ Requires-Dist: uvicorn[standard]>=0.29
33
+ Provides-Extra: dev
34
+ Requires-Dist: httpx>=0.27; extra == 'dev'
35
+ Requires-Dist: mypy>=1.10; extra == 'dev'
36
+ Requires-Dist: pre-commit>=3.7; extra == 'dev'
37
+ Requires-Dist: pytest-cov>=5; extra == 'dev'
38
+ Requires-Dist: pytest>=8; extra == 'dev'
39
+ Requires-Dist: ruff>=0.6; extra == 'dev'
40
+ Provides-Extra: gguf
41
+ Requires-Dist: gguf>=0.10; extra == 'gguf'
42
+ Provides-Extra: llama
43
+ Requires-Dist: llama-cpp-python>=0.3.36; extra == 'llama'
44
+ Provides-Extra: nvidia
45
+ Requires-Dist: nvidia-ml-py>=12; extra == 'nvidia'
46
+ Description-Content-Type: text/markdown
47
+
48
+ <div align="center">
49
+
50
+ # Vipera
51
+
52
+ **Modern local AI gateway — OpenAI-compatible, GGUF-native, one command.**
53
+
54
+ [![CI](https://github.com/vipera-iso/vipera/actions/workflows/ci.yml/badge.svg)](https://github.com/vipera-iso/vipera/actions/workflows/ci.yml)
55
+ [![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12-blue)](https://python.org)
56
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
57
+ [![Status: Beta](https://img.shields.io/badge/status-beta-orange)]()
58
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
59
+
60
+ [Quick start](#-quick-start) · [CLI](#-cli-reference) · [HTTP API](#-http-api) · [Docs](#-documentation) · [Contributing](CONTRIBUTING.md)
61
+
62
+ </div>
63
+
64
+ ---
65
+
66
+ ![Vipera demo](docs/images/demo.gif)
67
+
68
+ ## What is Vipera?
69
+
70
+ Vipera turns a `.gguf` file into a **production-shaped, OpenAI-compatible HTTP
71
+ endpoint** — in a single command. It reads the hardware it's running on, plans
72
+ which layers belong in VRAM, RAM, or disk, and then drives `llama.cpp` with the
73
+ exact flags that plan implies. No reimplemented runtime, no second inference
74
+ engine, no guessing.
75
+
76
+ ```bash
77
+ pip install "vipera-ai[llama,gguf,nvidia] @ git+https://github.com/vipera-iso/vipera.git"
78
+ vipera model search # download a GGUF from HuggingFace
79
+ vipera serve start # → http://127.0.0.1:8686/v1/chat/completions
80
+ ```
81
+
82
+ > The distribution is named `vipera-ai`; it is not on PyPI yet. The PyPI project
83
+ > named `vipera` is an unrelated tool, so do not install that. Use the GitHub
84
+ > source command above, or follow the no-Git
85
+ > [installation guide](docs/install.md).
86
+
87
+ ![Vipera demo](docs/images/demo.gif)
88
+
89
+ That endpoint speaks the OpenAI Chat Completions protocol with real SSE
90
+ streaming, so every existing client — `openai-python`, LangChain, LlamaIndex,
91
+ Continue, the OpenAI Playground — works without code changes.
92
+
93
+ ## Why Vipera?
94
+
95
+ Most local LLM tools make you choose between a friendly CLI and a real server.
96
+ Vipera is both, with a planner in the middle that most tools skip.
97
+
98
+ | | **Vipera** | Ollama | `llama.cpp/server` | LM Studio |
99
+ |---|:---:|:---:|:---:|:---:|
100
+ | GGUF-native | ✅ | ✅ | ✅ | ✅ |
101
+ | OpenAI-compatible API | ✅ | ✅ | ✅ | ✅ |
102
+ | **Hardware-aware planner** (VRAM/RAM/disk) | ✅ | ⚠️ partial | ❌ | ⚠️ |
103
+ | Real SSE streaming | ✅ | ✅ | ✅ | ✅ |
104
+ | First-class CLI (no GUI) | ✅ | ✅ | ✅ | ❌ |
105
+ | HuggingFace search built-in | ✅ | ✅ | ❌ | ✅ |
106
+ | Diagnostics (`doctor`) | ✅ | ⚠️ | ❌ | ❌ |
107
+ | Python-native, embeddable | ✅ | ❌ | ❌ | ❌ |
108
+
109
+ Where Vipera differs in practice:
110
+
111
+ - **It plans before it runs.** `vipera system doctor` tells you whether your
112
+ machine can run the model *before* you wait five minutes for a failed load.
113
+ The planner emits `-ngl`, `--n-cpu-moe`, KV quant types, `mlock` and
114
+ `n_batch` from a hardware profile — not a hardcoded default.
115
+ - **It falls back honestly.** If GPU offload fails at load time, the engine
116
+ retries with a CPU-safe plan and tells you what changed. It does not crash,
117
+ and it does not silently degrade.
118
+ - **The CLI and the API are the same stack.** `vipera chat` and
119
+ `/v1/chat/completions` share one engine instance per model — so benchmarks
120
+ you run in the terminal describe the server you actually serve.
121
+
122
+ ## ⚡ Quick start
123
+
124
+ ```bash
125
+ # 1. install (see docs/install.md for a no-Git option)
126
+ pip install "vipera-ai[llama,gguf,nvidia] @ git+https://github.com/vipera-iso/vipera.git"
127
+
128
+ # 2. fetch a model
129
+ vipera model search
130
+
131
+ # 3. serve it
132
+ vipera serve start
133
+ ```
134
+
135
+ That's it. Then point any OpenAI client at `http://127.0.0.1:8686/v1`:
136
+
137
+ ```python
138
+ from openai import OpenAI
139
+
140
+ client = OpenAI(base_url="http://127.0.0.1:8686/v1", api_key="none")
141
+
142
+ stream = client.chat.completions.create(
143
+ model="default",
144
+ messages=[{"role": "user", "content": "Explain MoE in one paragraph."}],
145
+ stream=True,
146
+ )
147
+ for chunk in stream:
148
+ print(chunk.choices[0].delta.content or "", end="")
149
+ ```
150
+
151
+ ## 🧭 CLI reference
152
+
153
+ Vipera ships a single `vipera` entry point. Every command is discoverable with
154
+ `vipera <command> --help`.
155
+
156
+ ### Top-level
157
+
158
+ | Command | Description |
159
+ |---|---|
160
+ | `vipera` | Start the gateway with the default model. |
161
+ | `vipera -s` / `--select` | Start the gateway with an interactive model picker. |
162
+ | `vipera --version` | Print the version. |
163
+ | `vipera help` | Print the full command reference. |
164
+
165
+ ### `vipera model` — manage GGUF artifacts
166
+
167
+ | Command | Description |
168
+ |---|---|
169
+ | `vipera model search` | Search HuggingFace for GGUF models, then download one. |
170
+ | `vipera model import <path> [--name <alias>]` | Copy a local `.gguf` into the Vipera store. |
171
+ | `vipera model inspect <path> [--tensors]` | Analyze GGUF metadata, tensor categories, and quantization mix. |
172
+ | `vipera model imatrix <path> --calibration-data <file>` | Build an importance matrix for quantization. |
173
+ | `vipera model quantize <path> [--target-quant <type>]` | Quantize a GGUF file with llama-quantize. |
174
+ | `vipera model optimize <path> [--target-size <GB>]` | Inspect, build an optional imatrix, and quantize in one step. |
175
+ | `vipera model list` | List every model registered locally. |
176
+ | `vipera model rm <alias> [--yes]` | Remove a model and its file. |
177
+
178
+ ### `vipera serve` — HTTP gateway
179
+
180
+ | Command | Description |
181
+ |---|---|
182
+ | `vipera serve start [--model] [--host] [--port] [--profile] [--ctx]` | Load a model and start the OpenAI-compatible server. |
183
+ | `vipera serve status` | Probe the configured host/port for a live gateway. |
184
+ | `vipera serve stop [--force]` | Stop the gateway using its pid file. |
185
+
186
+ ### `vipera chat` — terminal chat
187
+
188
+ | Command | Description |
189
+ |---|---|
190
+ | `vipera chat repl [-m <alias>]` | Interactive multi-turn REPL. |
191
+ | `vipera chat oneshot "<prompt>" [-m <alias>]` | One turn, print, exit. |
192
+
193
+ ### `vipera bench` — performance
194
+
195
+ | Command | Description |
196
+ |---|---|
197
+ | `vipera bench run [model] [--ctx 512,2048] [--max-tokens N]` | Measure prompt and generation throughput across context sizes. |
198
+
199
+ ### `vipera system` — diagnostics & config
200
+
201
+ | Command | Description |
202
+ |---|---|
203
+ | `vipera system doctor` | Runtime, library, and hardware check. |
204
+ | `vipera system config [key] [value]` | View or set configuration keys. |
205
+
206
+ ## 🔌 HTTP API
207
+
208
+ ### Endpoints
209
+
210
+ | Method | Path | Description |
211
+ |---|---|---|
212
+ | `GET` | `/health` | `{"status": "ok", "model": "<alias>"}` |
213
+ | `GET` | `/v1/models` | OpenAI-shaped model list. |
214
+ | `POST` | `/v1/chat/completions` | Chat completion, streaming or non-streaming. |
215
+
216
+ ### curl — non-streaming
217
+
218
+ ```bash
219
+ curl http://127.0.0.1:8686/v1/chat/completions \
220
+ -H "Content-Type: application/json" \
221
+ -d '{
222
+ "model": "default",
223
+ "messages": [{"role": "user", "content": "Hello!"}]
224
+ }'
225
+ ```
226
+
227
+ ### curl — streaming
228
+
229
+ ```bash
230
+ curl -N http://127.0.0.1:8686/v1/chat/completions \
231
+ -H "Content-Type: application/json" \
232
+ -d '{
233
+ "model": "default",
234
+ "messages": [{"role": "user", "content": "Count to 5."}],
235
+ "stream": true
236
+ }'
237
+ ```
238
+
239
+ ### JavaScript
240
+
241
+ ```js
242
+ import OpenAI from "openai";
243
+
244
+ const client = new OpenAI({
245
+ baseURL: "http://127.0.0.1:8686/v1",
246
+ apiKey: "none",
247
+ });
248
+
249
+ const stream = await client.chat.completions.create({
250
+ model: "default",
251
+ messages: [{ role: "user", content: "hi" }],
252
+ stream: true,
253
+ });
254
+
255
+ for await (const chunk of stream) {
256
+ process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
257
+ }
258
+ ```
259
+
260
+ ### Compatibility
261
+
262
+ Vipera implements the **OpenAI Chat Completions** schema and SSE framing. The
263
+ `model` field in the request is accepted for client compatibility but ignored:
264
+ one gateway serves one model.
265
+
266
+ ## 🧱 Architecture
267
+
268
+ ```mermaid
269
+ flowchart LR
270
+ subgraph Client
271
+ C1["openai-python"]
272
+ C2["curl"]
273
+ C3["OpenAI SDK"]
274
+ end
275
+
276
+ subgraph Vipera["Vipera Gateway"]
277
+ S["FastAPI server"]
278
+ E["Engine"]
279
+ P["Planner"]
280
+ H["Hardware probe"]
281
+ R["Registry"]
282
+ end
283
+
284
+ M[("GGUF file")]
285
+
286
+ C1 & C2 & C3 -->|"HTTP / SSE"| S
287
+ S -->|"chat()"| E
288
+ E -->|"reads"| M
289
+ P -->|"flags"| E
290
+ H --> P
291
+ R --> P
292
+ ```
293
+
294
+ **Layers:**
295
+
296
+ - `vipera/hardware.py` — probes CPU cores, RAM, GPU name, VRAM. No side effects.
297
+ - `vipera/planner.py` — turns `(model meta, hardware)` into a concrete `Plan`
298
+ (`gpu_layers`, `context`, `kv_cache`, `flash_attn`, `n_batch`, `use_mlock`,
299
+ `offload_kqv`).
300
+ - `vipera/engine.py` — wraps `llama_cpp.Llama` from a `Plan`; handles the
301
+ GPU → CPU fallback path and the `mlock` retry.
302
+ - `vipera/server.py` — FastAPI app; real SSE for streaming, threadpool for
303
+ blocking inference. Sync generator returned directly to `StreamingResponse`,
304
+ so chunks flush per token.
305
+ - `vipera/registry.py` — JSON model store at `~/.vipera/registry.json`.
306
+ - `vipera/ui.py` — Rich-based CLI (banner, panels, picker, typewriter stream).
307
+ - `vipera/commands/*` — one file per CLI subcommand.
308
+
309
+ ## ⚙️ Configuration
310
+
311
+ Config lives at `~/.vipera/config.json`. Set it via `vipera system config`, or
312
+ edit the JSON — unknown keys are rejected, known keys are type-coerced.
313
+
314
+ | Key | Type | Default | Meaning |
315
+ |---|---|---|---|
316
+ | `host` | `str` | `127.0.0.1` | Gateway bind address. |
317
+ | `port` | `int` | `8686` | Gateway port. |
318
+ | `default_model` | `str \| null` | `null` | Alias used when `--model` is not given. |
319
+ | `profile` | `str` | `auto` | Planner profile (`auto`, `cpu`, `gpu`, `lowmem`). |
320
+ | `ctx` | `int` | `8192` | Context size in tokens. |
321
+ | `kv_cache` | `str` | `q8_0` | KV cache type (`f16`, `q8_0`, `q4_0`, ...). |
322
+ | `flash_attn` | `bool` | `true` | Enable flash attention when GPU present. |
323
+ | `n_batch` | `int` | `512` | Prompt batch size. |
324
+ | `temperature` | `float` | `0.7` | Sampling temperature. |
325
+ | `max_tokens` | `int` | `2048` | Generation cap. |
326
+ | `top_p` | `float` | `0.95` | Nucleus sampling. |
327
+
328
+ **Storage layout:**
329
+
330
+ ```
331
+ ~/.vipera/
332
+ ├── config.json # gateway config
333
+ ├── registry.json # model index
334
+ ├── models/ # *.gguf artifacts
335
+ └── logs/ # reserved
336
+ ```
337
+
338
+ Override the home with `VIPERA_HOME=/path/to/dir`.
339
+
340
+ ## 🔬 GGUF optimization
341
+
342
+ ### Inspect
343
+
344
+ `vipera model inspect` reads the GGUF index only — weights are never loaded
345
+ into memory — and prints the architecture, layer/context/embedding sizes, a
346
+ size breakdown by tensor category (embedding, attention, FFN, expert, norm),
347
+ and the quantization mix.
348
+
349
+ ```bash
350
+ vipera model inspect ~/.vipera/models/model.gguf
351
+ vipera model inspect ~/.vipera/models/model.gguf --tensors # every tensor
352
+ ```
353
+
354
+ It warns when quality-sensitive tensors (`attn_v`, `ffn_down`, including their
355
+ `_exps` variants) are quantized below Q4_K. That check is a heuristic, not a
356
+ quality measurement.
357
+
358
+ ### Importance matrix and quantization
359
+
360
+ An importance matrix (imatrix) tells `llama-quantize` which weights matter for
361
+ your data, so low-bit quants keep more of the quality. Generate one from a
362
+ plain-text calibration file, then quantize with it:
363
+
364
+ ```bash
365
+ vipera model imatrix model.gguf --calibration-data calibration.txt
366
+ vipera model quantize model.gguf --imatrix model.imatrix.gguf --target-quant q4_k_m
367
+ ```
368
+
369
+ `quantize` writes `<model>-vipera-<quant>.gguf` next to the source unless
370
+ `--output` is given. Requantizing an already-quantized file needs
371
+ `--allow-requantize`; expect a quality loss. For MoE models, `--prior-weight`
372
+ raises the expert prior (try 128 for models with many rarely-used experts to
373
+ avoid NaNs) when the installed `llama-quantize` supports the flag.
374
+
375
+ ### One-shot optimization
376
+
377
+ `optimize` inspects the file, picks the highest-quality K-quant that fits the
378
+ size budget, optionally builds an imatrix, and quantizes:
379
+
380
+ ```bash
381
+ vipera model optimize model.gguf --target-size 4.5 --calibration-data calibration.txt
382
+ vipera model optimize model.gguf --target-quant q4_k_m
383
+ ```
384
+
385
+ The size estimate assumes a roughly uniform per-weight cost; actual output can
386
+ differ, especially for models with large output embeddings or MoE experts.
387
+ `--prune-layers` is passed through to `llama-quantize` and can substantially
388
+ reduce quality.
389
+
390
+ All three commands need `llama-imatrix` and `llama-quantize` from a llama.cpp
391
+ build. Vipera finds them on `PATH`, in `$VIPERA_LLAMA_BIN`, in a few common
392
+ build directories, or via `--bin-dir`. Every command accepts `--dry-run` to
393
+ print the exact `llama.cpp` invocation without running it.
394
+
395
+ ## 📊 Benchmarks
396
+
397
+ Vipera measures what the gateway actually produces, on the machine it runs on.
398
+ Numbers below are from the reference box; re-run with `vipera bench run` on
399
+ yours — that is the point.
400
+
401
+ **Reference machine**
402
+
403
+ | | |
404
+ |---|---|
405
+ | CPU | Intel i5-11300H — 4C / 8T |
406
+ | RAM | 15 GiB, ~10 GiB free, no swap |
407
+ | GPU | NVIDIA GTX 1650 Max-Q, 4 GB VRAM |
408
+ | Model | DeepSeek-V2-Lite Q4_K_M (9.65 GB, MoE 15.7B / 2.4B active) |
409
+ | Runtime | llama.cpp CPU build, `-ngl 0` |
410
+
411
+ | Config | Gen t/s | Prompt t/s | Peak RSS |
412
+ |---|---:|---:|---:|
413
+ | CPU only, mmap | 16.0 | 44 | 12.6 GiB |
414
+ | CPU only, `-lm mlock` | 22.9 | — | ~10 GiB |
415
+ | CUDA offload (experts on CPU) | 6.8 | — | — |
416
+ | Vulkan offload | 3.4 | — | — |
417
+
418
+ **Read this as:** on a model that already fits in RAM, this class of gateway
419
+ does not beat `llama.cpp` defaults — the load-flag layer (`mlock`, `n_batch`)
420
+ moves throughput 1.4× while placement does not, because there is nothing to
421
+ place. Vipera earns its keep at the edges: when the model *spills* RAM, when
422
+ the machine has multiple accelerators of different capabilities, or when the
423
+ operator does not know which of forty flags to pass. `vipera bench run` is the
424
+ instrument; the numbers are yours.
425
+
426
+ ## 📚 Documentation
427
+
428
+ Start at the [docs index](docs/README.md).
429
+
430
+ - [Installation](docs/install.md) — step-by-step setup for non-technical users.
431
+ - [Architecture](docs/architecture.md) — module map, planner, engine fallback, concurrency.
432
+ - [CLI reference](docs/cli.md) — every command, flag, and default.
433
+ - [HTTP API](docs/http-api.md) — endpoints, schemas, SSE framing, client examples.
434
+ - [Configuration](docs/configuration.md) — config keys, storage layout, registry schema.
435
+ - [Development](docs/development.md) — setup, tests, CI, release process.
436
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — dev setup, PR flow, how to record the demo GIF.
437
+ - [SECURITY.md](SECURITY.md) — reporting vulnerabilities, supported versions.
438
+ - [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) — Contributor Covenant 2.1.
439
+ - [CHANGELOG.md](CHANGELOG.md) — release history.
440
+
441
+ ## 🤝 Contributing
442
+
443
+ Issues and PRs are welcome. First-timers: look for
444
+ [`good first issue`](https://github.com/vipera-iso/vipera/labels/good%20first%20issue).
445
+
446
+ ```bash
447
+ git clone https://github.com/vipera-iso/vipera
448
+ cd vipera
449
+ python -m venv .venv && .venv/bin/pip install -e ".[dev,llama,gguf]"
450
+ .venv/bin/pre-commit install
451
+ .venv/bin/pytest -q
452
+ ```
453
+
454
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide.
455
+
456
+ ## 📄 License
457
+
458
+ MIT © 2026 Vipera — see [LICENSE](LICENSE).