@octocodeai/freellama-mcp-server 0.1.0
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.
- package/README.md +426 -0
- package/adapters/agent_context.py +663 -0
- package/adapters/agent_transport.py +84 -0
- package/adapters/bash_agent.py +370 -0
- package/adapters/octocode_agent.py +394 -0
- package/dist/index.js +22971 -0
- package/docs/ADR_RESOURCE_AWARE_BACKEND_ROUTING.md +55 -0
- package/docs/ARCHITECTURE.md +416 -0
- package/docs/CLI.md +219 -0
- package/docs/CPU_GPU_ROUTING.md +352 -0
- package/docs/ECONOMICS.md +105 -0
- package/docs/INDEX.md +15 -0
- package/docs/MODEL_SELECTION.md +65 -0
- package/docs/OLLAMA_SIDECAR.md +76 -0
- package/docs/OLLAMA_SYSTEM_OPTIMIZATION.md +254 -0
- package/docs/PRODUCTION.md +195 -0
- package/docs/PRODUCT_POSITIONING.md +291 -0
- package/docs/TESTING.md +125 -0
- package/native/index.d.ts +158 -0
- package/native/index.js +45 -0
- package/native/package.json +7 -0
- package/package.json +69 -0
package/docs/INDEX.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# FreeLlama packaged documentation
|
|
2
|
+
|
|
3
|
+
Read only the document relevant to the current operation. Repository `docs/` is the source of truth.
|
|
4
|
+
|
|
5
|
+
- [ADR: Resource-aware backend routing](ADR_RESOURCE_AWARE_BACKEND_ROUTING.md)
|
|
6
|
+
- [FreeLlama architecture](ARCHITECTURE.md)
|
|
7
|
+
- [CLI reference](CLI.md)
|
|
8
|
+
- [Run models on CPU and GPU](CPU_GPU_ROUTING.md)
|
|
9
|
+
- [Token economics](ECONOMICS.md)
|
|
10
|
+
- [Choose local models](MODEL_SELECTION.md)
|
|
11
|
+
- [Ollama sidecar boundary](OLLAMA_SIDECAR.md)
|
|
12
|
+
- [Ollama and FreeLlama optimization boundary](OLLAMA_SYSTEM_OPTIMIZATION.md)
|
|
13
|
+
- [Prepare FreeLlama for production](PRODUCTION.md)
|
|
14
|
+
- [Product positioning](PRODUCT_POSITIONING.md)
|
|
15
|
+
- [Test FreeLlama](TESTING.md)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Choose local models
|
|
2
|
+
|
|
3
|
+
Choose models from local evidence, not model-card popularity. The measurements below come from one
|
|
4
|
+
Apple M4 Pro machine with 48 GB unified memory and are not compiled into routing. Re-run
|
|
5
|
+
`npx @octocodeai/freellama doctor`, `models`, `bench-all`, and your quality suite on the target hardware.
|
|
6
|
+
`doctor.machine.memory_bytes` is host RAM; a discrete GPU's usable VRAM must be observed separately.
|
|
7
|
+
|
|
8
|
+
```mermaid
|
|
9
|
+
flowchart TD
|
|
10
|
+
T{"What must the task do?"}
|
|
11
|
+
T -->|"Generate text, code, or inspect images"| L["Start with one qualified large multimodal model"]
|
|
12
|
+
T -->|"Create retrieval vectors"| E["Use a small embedding model"]
|
|
13
|
+
L --> Q{"Passes held-out quality checks?"}
|
|
14
|
+
E --> Q
|
|
15
|
+
Q -->|"No"| N["Reject or evaluate another model"]
|
|
16
|
+
Q -->|"Yes"| M{"Fits with workload concurrency?"}
|
|
17
|
+
M -->|"No"| N
|
|
18
|
+
M -->|"Yes"| B["Benchmark locally and add policy evidence"]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Text, code, and vision
|
|
22
|
+
|
|
23
|
+
`qwen3.8:27b-mlx` was the strongest general model in the local evaluations. It handled coding,
|
|
24
|
+
grounded research, image description, OCR, and summarization. Using one large multimodal model also
|
|
25
|
+
avoided contention between separate heavy text and vision runners.
|
|
26
|
+
|
|
27
|
+
`muse-glimmer:30b-mlx` was a credible alternative and answered 29 of 30 questions correctly
|
|
28
|
+
(96.7%) with the Bash adapter, but it was slower and did not add a required capability in this
|
|
29
|
+
workload.
|
|
30
|
+
|
|
31
|
+
Do not assume small research models are adequate. The local grounded-lookup sample fell to 2/8 at
|
|
32
|
+
7B, 3/8 at 3B, and 0/8 at 0.5B. `delegate_research` can refuse models whose runtime evidence marks
|
|
33
|
+
them unusable rather than spending tokens on a known-poor route.
|
|
34
|
+
|
|
35
|
+
## Embeddings
|
|
36
|
+
|
|
37
|
+
`nomic-embed-text` matched the highest recall with the lowest measured index time and model size in
|
|
38
|
+
the repository retrieval sample:
|
|
39
|
+
|
|
40
|
+
| Model | Recall at 3 | Index time | Dimensions | Size |
|
|
41
|
+
|---|---:|---:|---:|---:|
|
|
42
|
+
| `nomic-embed-text` | 5/6 | 4.2 seconds | 768 | 274 MB |
|
|
43
|
+
| `embeddinggemma:300m` | 5/6 | 4.9 seconds | 768 | 622 MB |
|
|
44
|
+
| `qwen3-embedding:0.6b` | 4/6 | 14.8 seconds | 1,024 | 639 MB |
|
|
45
|
+
|
|
46
|
+
Use embeddings for semantic similarity, grouping, deduplication, and classification. For exact code
|
|
47
|
+
keywords, repository search was both faster and more accurate in the measured sample.
|
|
48
|
+
|
|
49
|
+
## Place helper models on CPU when useful
|
|
50
|
+
|
|
51
|
+
A small embedding or intent model can be assigned to a second CPU Ollama process while a large
|
|
52
|
+
generation model remains resident on the primary GPU-capable process. This can overlap independent
|
|
53
|
+
work, but it does not make CPU inference fast. Apple silicon shares memory bandwidth; discrete-GPU
|
|
54
|
+
systems have different transfer and contention costs and need their own benchmark.
|
|
55
|
+
|
|
56
|
+
The measured warmed embedding-plus-completion workload improved from a 37.997-second sequential
|
|
57
|
+
median to a 28.233-second parallel median, a 1.346-times speedup. Treat that result as evidence for
|
|
58
|
+
this machine and workload, not a universal model-placement rule. Follow
|
|
59
|
+
[CPU and GPU model routing](CPU_GPU_ROUTING.md) to reproduce it.
|
|
60
|
+
|
|
61
|
+
## Turn measurements into routing evidence
|
|
62
|
+
|
|
63
|
+
`bench-all` measures local performance. A quality benchmark measures correctness. FreeLlama needs
|
|
64
|
+
both the generated task policy and local benchmark data before grading a route medium confidence.
|
|
65
|
+
See the [CLI reference](CLI.md#earn-medium-routing-confidence) for the commands.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Ollama sidecar boundary
|
|
2
|
+
|
|
3
|
+
FreeLlama integrates with Ollama as a loopback HTTP sidecar, not an in-process inference plugin.
|
|
4
|
+
Ollama owns model execution; FreeLlama owns policy and coordination around it.
|
|
5
|
+
|
|
6
|
+
```mermaid
|
|
7
|
+
flowchart LR
|
|
8
|
+
C["Ollama-compatible client"] --> F["FreeLlama loopback sidecar"]
|
|
9
|
+
F -->|"raw /api and /v1"| G["Primary Ollama"]
|
|
10
|
+
F -->|"managed primary task"| G
|
|
11
|
+
F -->|"managed assigned task"| U["Optional CPU Ollama"]
|
|
12
|
+
G --> E["Metal, MLX, CUDA, ROCm, Vulkan, or CPU runner"]
|
|
13
|
+
U --> E2["CPU runner"]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This boundary avoids an Ollama fork and preserves its documented HTTP contract. It also makes a
|
|
17
|
+
second, process-isolated CPU backend possible without changing arbitrary client payloads.
|
|
18
|
+
|
|
19
|
+
## Divide ownership
|
|
20
|
+
|
|
21
|
+
| Problem | Owner |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Kernels, prompt processing, and token generation | Ollama and its runner dependencies |
|
|
24
|
+
| Runner loading, eviction, and scheduling within one server | Ollama |
|
|
25
|
+
| Prompt templates and model defaults | Ollama model metadata or a `Modelfile` |
|
|
26
|
+
| Capability and memory filtering | FreeLlama managed routes |
|
|
27
|
+
| Evidence policy, confidence, and route receipts | FreeLlama managed routes |
|
|
28
|
+
| Session affinity, per-backend bounded admission, and warm runtime feedback | FreeLlama managed routes |
|
|
29
|
+
| Exact model assignment to an optional CPU process | FreeLlama configuration |
|
|
30
|
+
| Guarded CPU/GPU preference within assigned eligible models | FreeLlama managed routes |
|
|
31
|
+
| Authentication and remote exposure | FreeLlama bearer middleware; external ingress owns TLS and tenant authorization |
|
|
32
|
+
|
|
33
|
+
FreeLlama does not make an individual model decode faster. It can improve workload completion by
|
|
34
|
+
avoiding unsuitable routes, reducing avoidable transitions, refusing unsupported work early, and
|
|
35
|
+
overlapping independent CPU and GPU model requests when the machine benefits from that layout.
|
|
36
|
+
|
|
37
|
+
## Preserve compatibility
|
|
38
|
+
|
|
39
|
+
`packages/rust-core/src/proxy.rs` forwards paths, queries, request bodies, and streaming response
|
|
40
|
+
bodies. It removes hop-by-hop headers and adds `x-freellama-proxy: 1` to responses. Raw `/api/*`
|
|
41
|
+
and `/v1/*` requests always target the primary upstream and are not rewritten for CPU placement.
|
|
42
|
+
|
|
43
|
+
```mermaid
|
|
44
|
+
flowchart TD
|
|
45
|
+
R["Incoming request"] --> K{"Managed /_freellama/v1 route?"}
|
|
46
|
+
K -->|"No"| P["Stream unchanged to primary Ollama"]
|
|
47
|
+
K -->|"Yes"| V["Validate, route, assign backend, and admit"]
|
|
48
|
+
V --> X["Build bounded Ollama request"]
|
|
49
|
+
X --> O["Execute on assigned upstream"]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The distinction is intentional: existing Ollama clients retain predictable compatibility, while
|
|
53
|
+
clients that opt into the managed API receive routing and policy behavior.
|
|
54
|
+
|
|
55
|
+
## Know the remaining limits
|
|
56
|
+
|
|
57
|
+
Native passthrough traffic remains under Ollama's scheduler and does not participate in FreeLlama's
|
|
58
|
+
transition locks. The managed sidecar also does not enforce live memory-pressure or thermal
|
|
59
|
+
admission. A configured but unreachable CPU backend makes managed catalog discovery fail closed;
|
|
60
|
+
raw primary passthrough remains usable.
|
|
61
|
+
|
|
62
|
+
Runtime feedback is task-specific, token-normalized, and warm-only. It can steer
|
|
63
|
+
unpinned `fastest` or `balanced` work after three samples on each backend and a greater-than-10%
|
|
64
|
+
advantage; it cannot change CPU eligibility or steer quality routing. The CLI persists a bounded,
|
|
65
|
+
versioned snapshot atomically by default, so verified evidence survives restart without changing
|
|
66
|
+
Ollama residency.
|
|
67
|
+
|
|
68
|
+
Read [Architecture](ARCHITECTURE.md) for all managed flows,
|
|
69
|
+
[CPU and GPU model routing](CPU_GPU_ROUTING.md) for the two-process procedure, and
|
|
70
|
+
[Ollama and FreeLlama optimization](OLLAMA_SYSTEM_OPTIMIZATION.md) for the full tuning boundary.
|
|
71
|
+
|
|
72
|
+
## Sources
|
|
73
|
+
|
|
74
|
+
- [Ollama API introduction](https://docs.ollama.com/api/introduction)
|
|
75
|
+
- [Ollama streaming behavior](https://docs.ollama.com/api/streaming)
|
|
76
|
+
- [Ollama usage metrics](https://docs.ollama.com/api/usage)
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Ollama and FreeLlama optimization boundary
|
|
2
|
+
|
|
3
|
+
Ollama already owns inference optimization. FreeLlama can improve completed
|
|
4
|
+
work per hour by choosing an eligible model and avoiding unnecessary model
|
|
5
|
+
changes, but it does not make an individual model decode faster.
|
|
6
|
+
|
|
7
|
+
This page explains the active request flow, the settings Ollama owns, the
|
|
8
|
+
current machine audit, and the optimization work that remains.
|
|
9
|
+
|
|
10
|
+
The architecture is portable across Ollama's Metal, CUDA, ROCm, Vulkan, and CPU paths. The audit
|
|
11
|
+
later on this page is intentionally Mac-specific. FreeLlama discovers host RAM per operating system
|
|
12
|
+
and keeps device selection in each Ollama process; it does not translate one machine's memory tier,
|
|
13
|
+
core count, or benchmark into another machine's defaults.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
Use stock Ollama as the inference runtime. Keep FreeLlama as an optional Rust
|
|
18
|
+
control plane for evidence-qualified routing, bounded request profiles, session
|
|
19
|
+
affinity, and policy enforcement.
|
|
20
|
+
|
|
21
|
+
Do not advertise FreeLlama as an accelerator or an Ollama inference plugin. It does not tune
|
|
22
|
+
kernels, split one model's layers across CPU and GPU, manage macOS memory pressure, or improve that
|
|
23
|
+
model's tokens per second. It can assign different models to isolated CPU and GPU-capable Ollama
|
|
24
|
+
processes, allowing independent workloads to overlap.
|
|
25
|
+
|
|
26
|
+
## Request flow
|
|
27
|
+
|
|
28
|
+
FreeLlama has four distinct paths:
|
|
29
|
+
|
|
30
|
+
| Request | FreeLlama work | Ollama work | Result |
|
|
31
|
+
|---|---|---|---|
|
|
32
|
+
| Native `/api/*` or `/v1/*` | Streams bytes to the primary compatibility upstream | Performs normal inference and scheduling | Exact Ollama response |
|
|
33
|
+
| `POST /_freellama/v1/routes` | Discovers models, filters capabilities, and applies policy | Supplies installed-model and residency data | Model and request profile; no inference |
|
|
34
|
+
| `POST /_freellama/v1/natural-routes` | Normalizes a schema-bound intent, then runs the deterministic router | Runs the small intent model | Model and request profile; selected task does not run |
|
|
35
|
+
| `POST /_freellama/v1/tasks` | Selects a route and backend, applies managed-task admission, and constructs one bounded request | Runs one nonstreaming chat or embedding request on the assigned process | Route receipt, placement, admission mode, prompt-free metrics, and Ollama response |
|
|
36
|
+
|
|
37
|
+
The natural-language path is intentionally two-stage. The small model cannot
|
|
38
|
+
name a final model. It returns only a task, objective, context hint, and tool or
|
|
39
|
+
vision requirements. Deterministic guards correct explicit requirements before
|
|
40
|
+
the ordinary router selects a model.
|
|
41
|
+
|
|
42
|
+
Calling `natural-routes` does not run the selected task. A client must use the
|
|
43
|
+
returned profile or submit a structured `tasks` request. There is no atomic
|
|
44
|
+
natural-language route-and-run endpoint in the current release.
|
|
45
|
+
|
|
46
|
+
Chat and embedding tasks forward route options. A captured-upstream contract
|
|
47
|
+
test verifies embedding option parity.
|
|
48
|
+
|
|
49
|
+
## What Ollama already optimizes
|
|
50
|
+
|
|
51
|
+
Across supported backends, Ollama provides the following behavior without FreeLlama:
|
|
52
|
+
|
|
53
|
+
- The runtime selects supported acceleration such as Metal, CUDA, ROCm, or Vulkan from the host and
|
|
54
|
+
its process-level device visibility.
|
|
55
|
+
- The scheduler fits model, context, and compute allocations to available
|
|
56
|
+
device memory.
|
|
57
|
+
- The runner selects CPU threads and GPU execution; applications do not need to
|
|
58
|
+
divide one inference manually between the CPU and GPU.
|
|
59
|
+
- Ollama manages request queues plus model loading and eviction. It supports
|
|
60
|
+
same-model parallel requests when memory permits.
|
|
61
|
+
- Ollama reports token counts plus load, prompt-processing, and generation
|
|
62
|
+
durations in API responses.
|
|
63
|
+
- Ollama supports request-specific context length and model residency through
|
|
64
|
+
`num_ctx` and `keep_alive`.
|
|
65
|
+
|
|
66
|
+
Ollama's documented concurrency controls are global server settings. Increasing
|
|
67
|
+
`OLLAMA_NUM_PARALLEL` multiplies context memory by the parallel-request count.
|
|
68
|
+
Increasing `OLLAMA_MAX_LOADED_MODELS` does not create memory; models still need
|
|
69
|
+
to fit. Use `1` for both values on an unmeasured deployment, then increase one variable at a time
|
|
70
|
+
only when a representative concurrent benchmark improves completed tasks per hour without memory
|
|
71
|
+
pressure.
|
|
72
|
+
|
|
73
|
+
Keep three signals distinct when operating FreeLlama: `context_window_fit` only compares requested
|
|
74
|
+
context with advertised model context; FreeLlama's K/V preflight is a conservative metadata lower
|
|
75
|
+
bound; and a completed runner is the only placement observation. None is live free-memory or
|
|
76
|
+
throughput proof. `doctor {view:"scheduler"}` reports configuration and a point-in-time admission
|
|
77
|
+
snapshot, not a fairness or parallel-decoding benchmark.
|
|
78
|
+
|
|
79
|
+
FreeLlama's admission queue and Ollama's internal queue solve different problems. FreeLlama limits
|
|
80
|
+
weighted managed work per backend and applies `--max-queue-wait-seconds`; `OLLAMA_MAX_QUEUE` bounds
|
|
81
|
+
requests that an Ollama process has accepted but cannot schedule. Raw compatibility traffic skips
|
|
82
|
+
FreeLlama admission and reaches the primary Ollama queue directly.
|
|
83
|
+
|
|
84
|
+
Ollama request context and research-adapter context are also separate budgets. Managed tasks set
|
|
85
|
+
request-specific `num_ctx` from the selected task profile. The coding adapters fit their tool
|
|
86
|
+
conversation inside `FREELLAMA_AGENT_NUM_CTX`: by default, they preserve the system prompt and
|
|
87
|
+
original question, compact the oldest observations first, retain recent evidence, and fail before
|
|
88
|
+
the Ollama call if pinned content cannot fit. Raising the Ollama server's global context does not
|
|
89
|
+
disable adapter compaction or increase its configured budget. See [Agent adapters](../AGENTS.md)
|
|
90
|
+
for the complete pagination and compaction contract.
|
|
91
|
+
|
|
92
|
+
## Current Mac audit
|
|
93
|
+
|
|
94
|
+
This audit captures the following snapshot from September 1, 2026. Treat it as machine
|
|
95
|
+
evidence, not a portable default.
|
|
96
|
+
|
|
97
|
+
| Item | Observed value | Interpretation |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| Hardware | Apple M4 Pro, 14 CPU cores, 48 GB unified memory | CPU and GPU share the memory system |
|
|
100
|
+
| macOS | 15.7.2 | Native Ollama supports this Apple-silicon system |
|
|
101
|
+
| Ollama server | 0.33.2 | Active application server on `127.0.0.1:11434`; re-read with `doctor` rather than trusting this row |
|
|
102
|
+
| First CLI on `PATH` | `/usr/local/bin/ollama`, 0.33.2 | Matches the active server |
|
|
103
|
+
| Metal device budget | 36 GiB reported by Ollama | This is the scheduler's observed device budget, not all 48 GB |
|
|
104
|
+
| Default context | 32,768 tokens | Ollama selected its 24–48 GiB device-memory tier |
|
|
105
|
+
| Parallel requests | 1 | Appropriate baseline for interactive and large-model tests |
|
|
106
|
+
| Keep-alive | 5 minutes | Ollama default |
|
|
107
|
+
| Loaded-model limit | `OLLAMA_MAX_LOADED_MODELS=2` | Explicit service configuration for the measured topology |
|
|
108
|
+
| K/V-cache type | `OLLAMA_KV_CACHE_TYPE=q8_0` | Explicit memory-saving configuration; requalify quality per important model |
|
|
109
|
+
| Flash Attention | `auto` | Ollama enables it automatically on supported backends; force `1` only after a measured compatibility check. Required for quantized K/V cache. |
|
|
110
|
+
| GGUF CPU threads | 10 worker threads | Ollama selected the 10 performance cores rather than all 14 cores |
|
|
111
|
+
| MLX | GPU runner observed | MLX models use their own runner path, not the GGUF tuning path |
|
|
112
|
+
| Power mode | Automatic on battery and AC power | High Power Mode remains an unmeasured experiment |
|
|
113
|
+
|
|
114
|
+
The server log also showed Metal fusion, concurrent Metal execution, graph
|
|
115
|
+
optimization, and automatic parameter fitting. FreeLlama must not claim these
|
|
116
|
+
as its own optimizations.
|
|
117
|
+
|
|
118
|
+
### Verify CLI and server alignment
|
|
119
|
+
|
|
120
|
+
The selected CLI is `/usr/local/bin/ollama`, and both the CLI and active server report 0.33.2.
|
|
121
|
+
Verify this alignment after changing Ollama installations or service definitions:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
command -v ollama
|
|
125
|
+
ollama --version
|
|
126
|
+
curl --silent http://127.0.0.1:11434/api/version
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The client and server versions must match before you test a CLI feature. A mismatch does not prove
|
|
130
|
+
an inference slowdown, but it can produce incompatible commands, flags, or diagnostics.
|
|
131
|
+
|
|
132
|
+
## What FreeLlama adds today
|
|
133
|
+
|
|
134
|
+
The active Rust implementation adds:
|
|
135
|
+
|
|
136
|
+
- capability filtering before speed ranking;
|
|
137
|
+
- explicit `fastest`, `balanced`, and `quality` evidence contracts;
|
|
138
|
+
- fail-closed quality routing when the policy has no qualified model;
|
|
139
|
+
- task-specific context, output, thinking, and tool-validation profiles;
|
|
140
|
+
- session affinity and preference for an eligible resident model;
|
|
141
|
+
- separate transition locks for primary and CPU backends, with shared execution permits for
|
|
142
|
+
resident tasks and an exclusive permit for a cold transition;
|
|
143
|
+
- exact-model placement on an optional second CPU Ollama process, including `num_gpu=0` for its
|
|
144
|
+
managed requests;
|
|
145
|
+
- guarded agent placement preferences plus a normalized, three-warm-sample, 10%-advantage feedback
|
|
146
|
+
loop for `fastest` and `balanced` work;
|
|
147
|
+
- independent 3:2:1 priority-fair weighted GPU and CPU admission pools, so a GPU burst cannot
|
|
148
|
+
starve a CPU helper or indefinitely starve background managed work;
|
|
149
|
+
- prompt-free load, prompt-processing, and output-generation metrics derived
|
|
150
|
+
from Ollama's response fields;
|
|
151
|
+
- a local natural-language intent interpreter that cannot choose a model;
|
|
152
|
+
- an Ollama-compatible loopback endpoint and an escape hatch to port 11434.
|
|
153
|
+
|
|
154
|
+
These features can reduce reloads or avoid an unsuitable model. They do not
|
|
155
|
+
change the selected model's prompt-processing or decode rate.
|
|
156
|
+
|
|
157
|
+
The measured dual-backend workload improved median completion time from 37.997 to 28.233 seconds
|
|
158
|
+
(1.346 times, or 25.70%). Qwen reported 19,175,677,668 GPU-resident bytes, Nomic reported zero,
|
|
159
|
+
and all requests carried correct backend receipts with zero FreeLlama queue wait. One of three
|
|
160
|
+
parallel trials was slower than sequential, so this remains a workload-level optimization rather
|
|
161
|
+
than an inference-speed claim.
|
|
162
|
+
|
|
163
|
+
## Unsupported optimizations
|
|
164
|
+
|
|
165
|
+
FreeLlama does not provide:
|
|
166
|
+
|
|
167
|
+
- a live minimum-free-VRAM guard. FreeLlama does calculate a metadata-backed F16 K/V lower bound
|
|
168
|
+
and refuses a known impossible CPU/unified-memory floor, but Ollama remains the authority for
|
|
169
|
+
current free memory, runner graph allocation, and final loading;
|
|
170
|
+
- transition coordination for native passthrough requests or processes that
|
|
171
|
+
bypass the managed `tasks` endpoint;
|
|
172
|
+
- live thermal, power-mode, or swap-aware routing;
|
|
173
|
+
- online token-rate, error-rate, or cold-load-duration scoring;
|
|
174
|
+
- per-engine tuning for GGUF compared with MLX;
|
|
175
|
+
- dynamic `keep_alive` or concurrency limits by workload;
|
|
176
|
+
- an atomic natural-language route-and-run operation;
|
|
177
|
+
- held-out quality policies for completion, coding, tools, browser, vision, or
|
|
178
|
+
long-context tasks in the example policy;
|
|
179
|
+
- quality-aware or thermal-aware CPU/GPU load balancing. Automatic placement uses persisted,
|
|
180
|
+
prompt-free warm-latency aggregates only within exact operator-owned assignments.
|
|
181
|
+
|
|
182
|
+
The RFC describes several of these capabilities as planned phases. Do not treat
|
|
183
|
+
the RFC as evidence that they have shipped.
|
|
184
|
+
|
|
185
|
+
## Optimization decisions
|
|
186
|
+
|
|
187
|
+
Use this table before changing Ollama or FreeLlama:
|
|
188
|
+
|
|
189
|
+
| Candidate change | Default decision | Reason |
|
|
190
|
+
|---|---|---|
|
|
191
|
+
| Expose Ollama beyond loopback | Do not add | Keep `OLLAMA_HOST` on loopback and put authenticated TLS ingress in front of FreeLlama instead |
|
|
192
|
+
| Permit Ollama cloud features in a local-only deployment | Do not add | Set `OLLAMA_NO_CLOUD=1` when the deployment promises local-only operation |
|
|
193
|
+
| Force layers of one model between CPU and GPU | Do not add | Ollama already fits and offloads the model; partial CPU fallback usually reduces decode throughput |
|
|
194
|
+
| Assign different models to isolated CPU and GPU-capable processes | Supported, benchmark per workload | Process isolation is reliable, but CPU speed and shared-memory pressure still determine whether overlap helps |
|
|
195
|
+
| Add macOS kernel or `sysctl` tuning | Do not add | Ollama does not document a supported, product-specific kernel setting. Unified-memory behavior belongs to macOS and Metal |
|
|
196
|
+
| Run Ollama in Docker on macOS | Do not use for performance | Docker Desktop does not provide Ollama GPU acceleration on macOS |
|
|
197
|
+
| Increase context globally | Do not add | Context memory grows with length; set the smallest sufficient `num_ctx` per request |
|
|
198
|
+
| Set parallel requests above 1 | Benchmark first | It can improve concurrent throughput but multiplies context memory and can hurt interactive latency |
|
|
199
|
+
| Keep more than one model loaded per process | Benchmark first | Model weights, runtime buffers, and every active context must fit together; start with `OLLAMA_MAX_LOADED_MODELS=1` |
|
|
200
|
+
| Leave Ollama's queue without a deployment limit | Do not add | Set a measured `OLLAMA_MAX_QUEUE`; it remains separate from FreeLlama's admission deadline |
|
|
201
|
+
| Pin multiple 18–21 GB models | Do not add by default | The observed 36 GiB Metal budget cannot safely establish that two heavy models plus contexts fit |
|
|
202
|
+
| Force Flash Attention | Benchmark per engine and model | The inspected GGUF path already enabled it automatically; MLX has a different runner |
|
|
203
|
+
| Use `q8_0` K/V cache | **8/10; qualify, then prefer for parallel/long-context work** | Ollama documents roughly half the KV memory of `f16` with very small precision loss; it is the practical companion to higher `OLLAMA_NUM_PARALLEL`, but it remains a process-wide quality tradeoff |
|
|
204
|
+
| Use `q4_0` K/V cache | Reject as a default | It saves more memory with a larger possible quality loss |
|
|
205
|
+
| Enable High Power Mode | Sustained-load experiment only | Apple documents higher sustained performance. Local token-rate and energy effects are not measured |
|
|
206
|
+
| Keep the small intent model resident | Keep bounded | It reduces routing latency but consumes memory and can affect a large-model transition |
|
|
207
|
+
|
|
208
|
+
## Measurement contract
|
|
209
|
+
|
|
210
|
+
Measure optimization with Ollama's response fields:
|
|
211
|
+
|
|
212
|
+
- prompt tokens per second = `prompt_eval_count / prompt_eval_duration` in
|
|
213
|
+
seconds;
|
|
214
|
+
- output tokens per second = `eval_count / eval_duration` in seconds;
|
|
215
|
+
- cold-load cost = `load_duration`;
|
|
216
|
+
- end-to-end latency = `total_duration` plus measured FreeLlama overhead;
|
|
217
|
+
- workload throughput = successful, quality-qualified tasks per hour.
|
|
218
|
+
|
|
219
|
+
Compare one variable at a time against stock Ollama. Include cold and warm runs,
|
|
220
|
+
fixed prompts, fixed output budgets, exact-output guardrails, quality guardrails, resident
|
|
221
|
+
memory, swap, and failure counts. A higher token rate is not an improvement if
|
|
222
|
+
quality falls, requests fail, or model transitions dominate the workload.
|
|
223
|
+
|
|
224
|
+
Use `cargo run -- bench-all` (`packages/rust-core/src/model_bench.rs`) for model selection evidence.
|
|
225
|
+
Use [CPU and GPU model routing](CPU_GPU_ROUTING.md) for the separate-process benchmark and
|
|
226
|
+
verification procedure.
|
|
227
|
+
|
|
228
|
+
- Local-model router RFC — lived in the gitignored `.octocode/` workspace and is no longer in the tree; the shipped design it argued for is [ARCHITECTURE.md](ARCHITECTURE.md)
|
|
229
|
+
|
|
230
|
+
## Recommended next work
|
|
231
|
+
|
|
232
|
+
1. Keep the CLI executable aligned with the active Ollama server; `doctor` reports the selected
|
|
233
|
+
path, both versions, and effective memory-related settings.
|
|
234
|
+
2. Back up the versioned prompt-free feedback snapshot with the policy and deployed binary.
|
|
235
|
+
Verified warm work-unit latency and queue wait survive restart; raw prompts are never stored.
|
|
236
|
+
3. Validate the metadata-backed K/V lower bound against a frozen alternating-model workload before
|
|
237
|
+
widening it beyond CPU/unified-memory impossible-floor refusal. Keep Ollama as final authority.
|
|
238
|
+
4. Extend transition coordination only if managed streaming or another parsed
|
|
239
|
+
execution path needs it. Native passthrough remains Ollama-owned.
|
|
240
|
+
5. Evaluate request-specific context and residency profiles before testing global K/V-cache or
|
|
241
|
+
concurrency changes. Keep Flash Attention automatic on supported backends or set it explicitly
|
|
242
|
+
to `1` before selecting a quantized K/V cache.
|
|
243
|
+
6. Promote a hardware-and-engine profile only after `benchmark/hardware/run_validation.py` and its
|
|
244
|
+
held-out quality workload pass on a real self-hosted runner.
|
|
245
|
+
|
|
246
|
+
## Sources
|
|
247
|
+
|
|
248
|
+
- [Ollama FAQ and server settings](https://docs.ollama.com/faq)
|
|
249
|
+
- [Ollama context length](https://docs.ollama.com/context-length)
|
|
250
|
+
- [Ollama hardware and Metal support](https://docs.ollama.com/gpu)
|
|
251
|
+
- [Ollama API usage metrics](https://docs.ollama.com/api/usage)
|
|
252
|
+
- [Ollama embedding API](https://docs.ollama.com/api/embed)
|
|
253
|
+
- [Ollama macOS support](https://docs.ollama.com/macos)
|
|
254
|
+
- [Apple power modes](https://support.apple.com/en-lamr/101613)
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# Prepare FreeLlama for production
|
|
2
|
+
|
|
3
|
+
This runbook prepares a single-operator or trusted-team FreeLlama deployment. FreeLlama now
|
|
4
|
+
supports authenticated nonloopback listeners, but it is not a multi-tenant authorization or
|
|
5
|
+
billing service. Put TLS and tenant-specific rate limits at an external ingress when traffic
|
|
6
|
+
crosses a machine boundary.
|
|
7
|
+
|
|
8
|
+
## Meet the prerequisites
|
|
9
|
+
|
|
10
|
+
- Install one Ollama CLI and server version. Run `freellama doctor` and resolve any mismatch.
|
|
11
|
+
- Install Node.js 20 or later for MCP and npm distribution use.
|
|
12
|
+
- Use the release artifacts for your operating system, or build with Rust 1.85 or later.
|
|
13
|
+
- Preinstall and benchmark exact model tags. Discovery never authorizes a pull.
|
|
14
|
+
- Keep the primary and optional CPU Ollama processes on distinct loopback sockets.
|
|
15
|
+
|
|
16
|
+
After a tag has been published, install that exact checksummed release on macOS or Linux:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
curl -fsSLO https://raw.githubusercontent.com/bgauryy/FreeLlama/main/scripts/install.sh
|
|
20
|
+
sh install.sh --version vX.Y.Z
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The installer downloads the exact-version binary and verifies it against the release's
|
|
24
|
+
`SHA256SUMS`. From a Windows checkout, run the following command after replacing `VERSION` with the
|
|
25
|
+
published tag:
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1 -Version VERSION
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
There is no repository-hosted release automation. Build and test every claimed target in a clean
|
|
32
|
+
environment, place each executable and matching addon under `release-artifacts/<target>/`, run
|
|
33
|
+
`yarn release:assemble release-artifacts release` and `yarn release:verify:publish`, then attach
|
|
34
|
+
`release/SHA256SUMS` and binaries to the release. Publish the eight `@octocodeai/freellama-native-*` packages
|
|
35
|
+
first, followed by the exact-version `@octocodeai/freellama` and `@octocodeai/freellama-mcp-server` packages. Configure
|
|
36
|
+
registry credentials in the release environment; never store them in the repository.
|
|
37
|
+
|
|
38
|
+
## Configure Ollama explicitly
|
|
39
|
+
|
|
40
|
+
Start with one model and one decode stream per Ollama process. Increase either value only after a
|
|
41
|
+
representative workload proves that the additional weights, contexts, and K/V caches fit without
|
|
42
|
+
swap, eviction churn, or unacceptable queueing.
|
|
43
|
+
|
|
44
|
+
| Setting | Starting value | Reason |
|
|
45
|
+
|---|---:|---|
|
|
46
|
+
| `OLLAMA_HOST` | Primary `127.0.0.1:11434`; CPU `127.0.0.1:11436` | Keeps both inference processes on distinct loopback sockets |
|
|
47
|
+
| `OLLAMA_NO_CLOUD` | `1` for local-only deployments | Makes the local-only privacy boundary explicit |
|
|
48
|
+
| `OLLAMA_FLASH_ATTENTION` | auto | Ollama enables it automatically on supported backends. Force `1` only after a measured compatibility check; quantized K/V cache requires Flash Attention. |
|
|
49
|
+
| `OLLAMA_KV_CACHE_TYPE` | `q8_0` after qualification | Reduces K/V memory; retain `f16` until each important model passes a quality comparison |
|
|
50
|
+
| `OLLAMA_NUM_PARALLEL` | `1` | Avoids multiplying context memory before measuring same-model concurrency |
|
|
51
|
+
| `OLLAMA_MAX_LOADED_MODELS` | `1` per process | Prevents an automatic multi-model limit from overcommitting an unmeasured host |
|
|
52
|
+
| `OLLAMA_MAX_QUEUE` | Workload-specific, bounded value | Limits Ollama's internal queue independently of FreeLlama admission |
|
|
53
|
+
|
|
54
|
+
Do not set a global `OLLAMA_CONTEXT_LENGTH` merely to maximize the advertised window. Managed
|
|
55
|
+
FreeLlama tasks send the smallest sufficient request-specific `num_ctx`; a larger context and a
|
|
56
|
+
larger `OLLAMA_NUM_PARALLEL` multiply K/V-cache memory. Direct Ollama clients still follow the
|
|
57
|
+
server's context configuration, which defaults to 4096 tokens in current Ollama.
|
|
58
|
+
|
|
59
|
+
`freellama doctor` returns `local_conservative_config_posture` as a **non-mutating** portable
|
|
60
|
+
starting profile. It names the source of each value (`observed_process` or `configuration_hint`),
|
|
61
|
+
requires `OLLAMA_NO_CLOUD=1` for a local-only deployment, and recommends one loaded model, one
|
|
62
|
+
parallel stream, and a finite internal queue before benchmarking. It also reports
|
|
63
|
+
`host_runtime_signals` with source and permission scope. Treat unavailable GPU-memory, thermal, or
|
|
64
|
+
power signals as unavailable; do not substitute host RAM or a guessed value.
|
|
65
|
+
|
|
66
|
+
FreeLlama and Ollama have separate queues. FreeLlama acquires a weighted backend permit and waits
|
|
67
|
+
for at most `--max-queue-wait-seconds`. An admitted request can then enter Ollama's internal queue,
|
|
68
|
+
which is bounded by `OLLAMA_MAX_QUEUE`. Raw compatibility traffic bypasses FreeLlama admission and
|
|
69
|
+
enters the primary Ollama queue directly. Set both limits from observed latency and overload
|
|
70
|
+
behavior; changing one does not configure the other.
|
|
71
|
+
|
|
72
|
+
The following flow shows where each production setting applies:
|
|
73
|
+
|
|
74
|
+
```mermaid
|
|
75
|
+
flowchart LR
|
|
76
|
+
C["Client"] --> FQ["FreeLlama admission<br/>weighted budget + wait deadline"]
|
|
77
|
+
FQ -->|"refused"| E503["503 server busy"]
|
|
78
|
+
FQ -->|"admitted"| OQ["Ollama queue<br/>OLLAMA_MAX_QUEUE"]
|
|
79
|
+
RAW["Raw /api/* or /v1/*"] --> OQ
|
|
80
|
+
OQ --> S["Ollama scheduler<br/>loaded models + parallel streams"]
|
|
81
|
+
S --> M["Runner memory<br/>num_ctx x K/V cache"]
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
These values are conservative starting points, not universal constants. NVIDIA, AMD, Apple, and
|
|
85
|
+
CPU-only hosts must pass hardware validation before promotion. See
|
|
86
|
+
[Ollama and FreeLlama optimization](OLLAMA_SYSTEM_OPTIMIZATION.md) for the ownership boundary and
|
|
87
|
+
[Run models on CPU and GPU](CPU_GPU_ROUTING.md) for device-specific controls.
|
|
88
|
+
|
|
89
|
+
Put the values in the service manager that owns each Ollama process: launchd on macOS, systemd or
|
|
90
|
+
the container definition on Linux, and the Windows service wrapper. Shell exports and
|
|
91
|
+
`launchctl setenv` are useful diagnostics but are login-session state, not a reboot-persistent
|
|
92
|
+
production configuration. After a real service restart, rerun `doctor` and `scripts/check.sh` and
|
|
93
|
+
require the same visible values before admitting work.
|
|
94
|
+
|
|
95
|
+
## Create the security and state files
|
|
96
|
+
|
|
97
|
+
Generate a token without placing the secret in shell history or the process list:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
freellama auth-token --out ~/.local/share/freellama/auth.token
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The command creates a new file with mode `0600` on Unix and refuses to overwrite an existing
|
|
104
|
+
token. Start the service with persistent feedback and authentication:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
freellama serve \
|
|
108
|
+
--feedback-file ~/.local/share/freellama/feedback.json \
|
|
109
|
+
--auth-token-file ~/.local/share/freellama/auth.token \
|
|
110
|
+
--upstream http://127.0.0.1:11434 \
|
|
111
|
+
--cpu-upstream http://127.0.0.1:11436 \
|
|
112
|
+
--cpu-model nomic-embed-text:latest
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Set `FREELLAMA_AUTH_TOKEN_FILE` to the same file for the CLI, MCP server, and bundled research
|
|
116
|
+
adapters. Authentication covers both `/_freellama/v1/*` and Ollama-compatible passthrough routes.
|
|
117
|
+
Use `--allow-remote` only with an authentication token. The server refuses unauthenticated
|
|
118
|
+
nonloopback listeners.
|
|
119
|
+
|
|
120
|
+
The feedback snapshot is versioned, bounded by backend and task type, and replaced atomically.
|
|
121
|
+
Only physically verified warm samples are saved. A corrupt or unsupported snapshot makes startup
|
|
122
|
+
fail instead of silently discarding routing evidence. Use `--ephemeral-feedback` only for
|
|
123
|
+
disposable tests.
|
|
124
|
+
|
|
125
|
+
## Configure MCP
|
|
126
|
+
|
|
127
|
+
Set these values in the MCP host environment:
|
|
128
|
+
|
|
129
|
+
- `FREELLAMA_AUTH_TOKEN_FILE`: bearer-token file used by native and adapter HTTP clients.
|
|
130
|
+
- `FREELLAMA_AGENT_TOKEN_CALIBRATION_DIR`: persistent, per-model token-estimate records.
|
|
131
|
+
- `FREELLAMA_MCP_ALLOWED_ROOTS`: exact directories available to `delegate_research`.
|
|
132
|
+
- `FREELLAMA_SERVE_ENDPOINT`: authenticated FreeLlama endpoint.
|
|
133
|
+
|
|
134
|
+
Persistent token calibration eliminates the repeated “uncalibrated first call” after a model has
|
|
135
|
+
been observed on that host. A genuinely new model/template still starts from the conservative
|
|
136
|
+
configurable estimate because Ollama exposes no stable preflight tokenizer API. Records contain
|
|
137
|
+
only model identifiers, scale, and sample count; they contain no prompts.
|
|
138
|
+
|
|
139
|
+
Keep adapter context settings distinct from Ollama server context. `FREELLAMA_AGENT_NUM_CTX`
|
|
140
|
+
budgets the adapter conversation; older tool observations are compacted inside that budget while
|
|
141
|
+
the system prompt and original question remain pinned by default. `OLLAMA_CONTEXT_LENGTH` controls
|
|
142
|
+
direct Ollama requests, and managed FreeLlama tasks send their own `num_ctx`.
|
|
143
|
+
|
|
144
|
+
## Verify lifecycle and placement
|
|
145
|
+
|
|
146
|
+
`keep_alive:0` no longer sacrifices placement evidence. FreeLlama temporarily holds the runner,
|
|
147
|
+
observes `/api/ps`, records eligible feedback, explicitly unloads it, and verifies that it is no
|
|
148
|
+
longer resident before returning. Inspect both `execution.observation` and
|
|
149
|
+
`execution.lifecycle.status`.
|
|
150
|
+
|
|
151
|
+
Require these health contracts before admitting traffic:
|
|
152
|
+
|
|
153
|
+
- `placement_feedback_persistence: versioned_atomic_snapshot_v1`
|
|
154
|
+
- `authentication: optional_bearer_all_routes`
|
|
155
|
+
- `immediate_unload_observation: observe_then_unload`
|
|
156
|
+
- `placement_observation: ollama_api_ps_after_execution`
|
|
157
|
+
- `placement_evidence_gate: configured_or_observed`
|
|
158
|
+
|
|
159
|
+
Run `skills/freellama/scripts/check.sh` with `FREELLAMA_AUTH_TOKEN_FILE` set. It verifies the
|
|
160
|
+
active versions, visible Ollama settings, persisted-feedback contract, authentication contract,
|
|
161
|
+
backend topology, and binary freshness. Also inspect the service definition for any setting that
|
|
162
|
+
the Ollama process does not expose to FreeLlama.
|
|
163
|
+
|
|
164
|
+
## Validate every hardware class
|
|
165
|
+
|
|
166
|
+
Run compile and deterministic test checks from clean checkouts on Windows, Linux, and macOS. Live
|
|
167
|
+
accelerator acceptance is separate because build machines do not necessarily represent production
|
|
168
|
+
GPU drivers or memory topology. Prepare Apple Metal, NVIDIA Linux, AMD Linux, and NVIDIA Windows
|
|
169
|
+
hosts, then run `benchmark/hardware/run_validation.py` directly on each host.
|
|
170
|
+
|
|
171
|
+
Each environment supplies its exact GPU and CPU model tags and a running FreeLlama endpoint. The
|
|
172
|
+
portable runner in `benchmark/hardware/run_validation.py` executes GPU coding and CPU embedding
|
|
173
|
+
concurrently, verifies physical processor receipts, checks admission receipts, and writes a JSON
|
|
174
|
+
artifact. Add `--vision-model` and `--vision-image` for that host's OCR/vision gate.
|
|
175
|
+
|
|
176
|
+
Do not mark a hardware row validated until its archived receipt says `verdict: accept`. Missing
|
|
177
|
+
hardware is an explicit release gap, not a result that documentation can waive.
|
|
178
|
+
|
|
179
|
+
## Promotion checklist
|
|
180
|
+
|
|
181
|
+
Promote a release only when all conditions pass:
|
|
182
|
+
|
|
183
|
+
1. `cargo fmt --all --check`, Clippy, Rust tests, typecheck, unit, integration, and live E2E pass.
|
|
184
|
+
2. Release packaging contains every declared target and `SHA256SUMS` verifies.
|
|
185
|
+
3. The active CLI and Ollama server versions match.
|
|
186
|
+
4. Reboot-persistent service definitions carry the explicit Ollama settings and FreeLlama args.
|
|
187
|
+
5. Health reports authentication, atomic feedback persistence, and current placement contracts.
|
|
188
|
+
6. Restart testing proves feedback reloads and a corrupt snapshot fails startup.
|
|
189
|
+
7. Immediate unload reports verified pre-unload placement and verified post-unload absence.
|
|
190
|
+
8. Every claimed hardware row has a real archived acceptance receipt.
|
|
191
|
+
9. The MCP schema remains eight tools and within its context budget.
|
|
192
|
+
|
|
193
|
+
Rollback by returning the listener to loopback, stopping the new service, and starting the prior
|
|
194
|
+
checksummed binary with the same policy and feedback snapshot. Never downgrade across an unsupported
|
|
195
|
+
feedback schema without preserving the old binary and snapshot together.
|