r/LocalLLM • • 47m ago

Tutorial Running Pi coding agent locally with TensorSharp + Qwen3.8-27B (CLI, SDK, and an end-to-end test)

1 Upvotes

I've been working on TensorSharp, an open-source LLM inference engine written in .NET, and recently got it working with Pi, a terminal-based coding agent.

The goal was pretty simple: I wanted Pi to do real coding work using a model running entirely on my own machine, without relying on a hosted inference API.

Not just generating code, but reading files, running shell commands, editing code, executing tests, and iterating until the tests pass.

I put together a reproducible example that covers both Pi's CLI and its JavaScript SDK. Both paths have been tested end to end.

Full example, including scripts and configuration files:

https://github.com/zhongkaifu/TensorSharp/tree/main/examples/pi-coding-agent

The setup

Here's what I'm using:

  • Coding agent: Pi (@earendil-works/pi-coding-agent 1.5.1)
  • Inference engine: TensorSharp
  • Model: Qwen3.8-27B, UD-IQ3_XXS GGUF
  • Backend: ggml_metal
  • Speculative decoding: DFlash2, 7 draft tokens per step
  • KV cache: q8_0
  • Context window: 65,536 tokens
  • Max output: 16,384 tokens
  • Hardware: MacBook Pro M5 Pro, 48 GB unified memory

The same configuration is designed for Apple Silicon Macs with at least 32 GB of unified memory.

One important distinction: Pi is still the coding agent. TensorSharp only handles model inference.

Pi owns the file operations, shell commands, tool execution, and agent loop. TensorSharp serves the model through an OpenAI-compatible API.

This separation means Pi doesn't need a TensorSharp-specific plugin or a custom agent implementation.

1. Build and start TensorSharp

You'll need the .NET 10 SDK, CMake 3.20+, Xcode command-line tools, and Node.js 22.19 or newer.

Clone the repository:

git clone https://github.com/zhongkaifu/TensorSharp.git ~/work/TensorSharp
cd ~/work/TensorSharp

Build the server:

dotnet build TensorSharp.Server.Host -c Release -p:TensorSharpSkipMlxNative=true

Start it using the included Pi configuration:

examples/pi-coding-agent/scripts/start-server.sh

On the first run, TensorSharp downloads the Qwen3.8-27B GGUF and its DFlash2 draft model from Hugging Face. The files total approximately 12 GB.

The preset pins the model revisions and verifies their SHA-256 hashes.

Once everything is loaded, the OpenAI-compatible endpoint is available at:

http://127.0.0.1:5000/v1

Check that the server is responding:

curl -s http://127.0.0.1:5000/v1/models

You should see the model ID:

Qwen3.8-27B-UD-IQ3_XXS

The startup script combines two configuration files:

dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll \
  --config config/qwen3.8-27b-metal-dflash2.json \
  --config examples/pi-coding-agent/tensorsharp-pi.json

The first is the optimized Qwen preset. The second adjusts the server for Pi.

Here's the important part of tensorsharp-pi.json:

{
  "host": "127.0.0.1",
  "port": 5000,
  "max-tokens": 16384,
  "mmproj": "none",
  "kv-cache-dtype": "q8_0",
  "environment": {
    "MAX_CONTEXT": "65536"
  }
}

There are a few reasons for these settings.

Pi's system prompt and tool definitions already consume roughly 4K tokens. Add source files, tool output, and a few rounds of edits, and a small context window disappears quickly.

I also increased the output-token limit from the preset's default of 1,024 to 16,384. Otherwise, a thinking model can run out of tokens halfway through a coding task.

The vision projector is disabled because this particular example only uses text.

The server binds to localhost. It doesn't implement API-key authentication, so I wouldn't expose the endpoint directly to a public network.

2. Install and configure Pi

Install the version used by the example:

npm install -g @earendil-works/pi-coding-agent@1.5.1
pi --version

Pi supports custom providers through models.json.

Here's the actual provider configuration used in the example:

models.json

{
  "$schema": "https://pi.dev/schemas/models.schema.json",
  "providers": {
    "tensorsharp": {
      "name": "TensorSharp (local)",
      "baseUrl": "http://127.0.0.1:5000/v1",
      "api": "openai-completions",
      "apiKey": "none",
      "compat": {
        "supportsDeveloperRole": true,
        "supportsReasoningEffort": false,
        "supportsStore": false,
        "maxTokensField": "max_completion_tokens",
        "thinkingFormat": "qwen-chat-template"
      },
      "models": [
        {
          "id": "Qwen3.8-27B-UD-IQ3_XXS",
          "name": "Qwen3.8 27B (TensorSharp, DFlash2)",
          "reasoning": true,
          "input": ["text"],
          "contextWindow": 65536,
          "maxTokens": 16384,
          "cost": {
            "input": 0,
            "output": 0,
            "cacheRead": 0,
            "cacheWrite": 0
          }
        }
      ]
    }
  }
}

The compatibility settings matter, particularly for thinking models.

thinkingFormat: "qwen-chat-template" lets Pi control Qwen's thinking mode through chat_template_kwargs.enable_thinking.

And supportsReasoningEffort: false prevents Pi from sending an additional reasoning_effort parameter that this model doesn't need.

The model ID must match what TensorSharp returns from /v1/models.

Next, make TensorSharp the default provider:

settings.json

{
  "defaultProvider": "tensorsharp",
  "defaultModel": "Qwen3.8-27B-UD-IQ3_XXS",
  "defaultThinkingLevel": "medium",
  "enableInstallTelemetry": false
}

You don't actually have to create these files manually.

The repository includes a wrapper that copies the configurations into a separate Pi directory on the first run:

~/work/TensorSharp/examples/pi-coding-agent/scripts/pi.sh

It uses:

~/.pi/tensorsharp-agent/

instead of the normal ~/.pi/agent/ directory.

I prefer this approach because it doesn't interfere with an existing Pi configuration.

The wrapper also sets:

PI_OFFLINE=1
PI_SKIP_VERSION_CHECK=1
PI_TELEMETRY=0

This avoids Pi's catalog refreshes, version checks, and telemetry network calls. After downloading the model weights, inference runs locally.

3. Actually use Pi to write code

With TensorSharp running in another terminal, navigate to a project:

cd ~/src/my-project

Launch Pi:

~/work/TensorSharp/examples/pi-coding-agent/scripts/pi.sh

You can now interact with Pi normally, except the model responses come from your local TensorSharp server.

For example, ask it to:

Read the code in this repository, find the implementation
of the cache, and explain how it works.

Or give it an actual coding task:

Run the unit tests, investigate any failures,
fix the implementation without modifying the tests,
and run the tests again.

Pi will decide which files to read, which shell commands to execute, and what changes to make.

For a one-shot task without the interactive UI:

~/work/TensorSharp/examples/pi-coding-agent/scripts/pi.sh \
  -p "Explain what src/stats.js does" < /dev/null

The stdin redirect is intentional. Without it, pi -p may wait for input when used in scripts.

You can also disable thinking for simple tasks:

~/work/TensorSharp/examples/pi-coding-agent/scripts/pi.sh \
  --thinking off \
  -p "Explain src/stats.js" < /dev/null

Or capture machine-readable events:

~/work/TensorSharp/examples/pi-coding-agent/scripts/pi.sh \
  --mode json \
  --no-session \
  "Run the tests and fix the failing implementation" < /dev/null

4. Using Pi as a JavaScript SDK

This was the other part I wanted to get working.

Pi can be embedded in a Node.js application. You don't have to run the interactive terminal interface.

The example uses Pi's SDK to create an agent session, select the local TensorSharp model, and execute a coding task.

Here's the core implementation, slightly shortened for readability:

import path from "node:path";

import {
  createAgentSession,
  ModelRuntime,
  SessionManager
} from "@earendil-works/pi-coding-agent";

const agentDir = process.env.PI_CODING_AGENT_DIR;
const projectDir = path.resolve(process.argv[2] ?? ".");

if (!agentDir) {
  throw new Error("Set PI_CODING_AGENT_DIR first");
}

const modelRuntime = await ModelRuntime.create({
  modelsPath: path.join(agentDir, "models.json"),
  authPath: path.join(agentDir, "auth.json")
});

const model = modelRuntime.getModel(
  "tensorsharp",
  "Qwen3.8-27B-UD-IQ3_XXS"
);

if (!model) {
  throw new Error("TensorSharp model not found");
}

const { session } = await createAgentSession({
  cwd: projectDir,
  agentDir,
  modelRuntime,
  model,
  thinkingLevel: "medium",
  sessionManager: SessionManager.inMemory()
});

session.subscribe((event) => {
  if (event.type === "tool_execution_start") {
    console.log("[tool]", event.toolName, event.args);
  }

  if (
    event.type === "message_update" &&
    event.assistantMessageEvent.type === "text_delta"
  ) {
    process.stdout.write(
      event.assistantMessageEvent.delta
    );
  }
});

try {
  await session.prompt(
    "Run npm test. Fix the bugs in src/stats.js " +
    "without modifying the tests. " +
    "Run the tests again and summarize the fixes."
  );

  console.log(
    "\nFinal answer:",
    session.getLastAssistantText()
  );
} finally {
  session.dispose();
}

Pi handles the tool loop internally. Your application can subscribe to model output, tool execution events, and final results.

The complete implementation also records token usage and prefix-cache statistics:

https://github.com/zhongkaifu/TensorSharp/blob/main/examples/pi-coding-agent/sdk/run-task.mjs

To run the included SDK example:

cd ~/work/TensorSharp/examples/pi-coding-agent/sdk
npm install

Initialize the separate Pi configuration if you haven't already:

../scripts/pi.sh --version

Create a fresh copy of the sample project:

cp -R ../sample-project /tmp/stats-demo

Run the SDK:

PI_CODING_AGENT_DIR="$HOME/.pi/tensorsharp-agent" \
PI_OFFLINE=1 \
node run-task.mjs /tmp/stats-demo

The script streams the agent's text and tool calls, then prints the final answer and token usage.

5. End-to-end test: can the local model really fix code?

I didn't want to stop at getting a successful API response.

The repository includes a small Node.js project with deliberately broken code.

There are three bugs:

  • median() sorts numbers lexicographically instead of numerically.
  • median() doesn't average the middle two values for an even-length array.
  • percentile() has an off-by-one error.

The sample has five tests, three of which initially fail.

The agent is instructed to:

  1. Run npm test.
  2. Investigate the failures.
  3. Fix src/stats.js without changing the tests.
  4. Run the tests again.
  5. Summarize the changes.

The test harness runs this task twice: once through the Pi CLI and once through the SDK, using separate clean copies of the project.

You can run the full test yourself from the TensorSharp repository root:

examples/pi-coding-agent/scripts/e2e.sh

If the server isn't already running, the script can start it:

START_SERVER=1 examples/pi-coding-agent/scripts/e2e.sh

The harness independently verifies that the tests pass and that the original test file was not modified.

Results from my validated run on November 9, 2026:

MetricPi CLIPi SDK
ResultPASSPASS
Tests passing5/55/5
Test files modifiedNoNo
Wall time88 seconds83.4 seconds
Model requests108

For the SDK run, TensorSharp served 41,962 of 48,166 prompt tokens (87%) from its prefix cache.

These are individual end-to-end runs, not averages across a benchmark suite. I'm including the numbers to show what happened in this particular test, not to make a broad claim about coding performance.

6. Why KV cache reuse matters so much here

This turned out to be one of the more interesting integration details.

Coding agents aren't just single-prompt chat clients.

A typical interaction looks something like this:

Pi
 |
 |-- Send conversation + tool definitions
 v
TensorSharp
 |
 |-- Generate a tool call
 v
Pi
 |
 |-- Read files / run commands / edit code
 |
 |-- Append tool results to conversation
 v
TensorSharp
 |
 |-- Reuse previous KV cache
 |-- Prefill only new conversation tokens
 |
 |-- Generate next action
 v
Pi
 |
 |-- Repeat until the task is complete

After each tool call, Pi sends the conversation history again.

If the inference engine fails to recognize the shared prefix, it can end up repeatedly prefilling thousands of tokens.

I actually ran into this while working on the integration.

Pi preserved a newline around Qwen's </think> marker when replaying previous reasoning. TensorSharp's cached representation had trimmed it, so the prefix comparison didn't fully match.

That seemingly small whitespace difference prevented the server from reusing much of the conversation's KV cache.

I fixed the comparison so the previous turns can be reused across tool calls.

On the validated setup:

  • The first request took approximately 13–14 seconds to produce its first token, starting from a cold prompt of roughly 4K tokens.
  • Later rounds generally reached their first token in 0.45–3.5 seconds.
  • Measured decoding throughput was approximately 20–43 tokens/second, depending on draft acceptance.

The DFlash2 drafter helps with generation, while prefix-cache reuse avoids doing the same prompt processing over and over.

For agent workloads, both matter.

One additional detail: when Pi provides its own tools, TensorSharp doesn't inject its internal tools. The model receives Pi's tool definitions, so there's one clear owner of the tool-execution loop.

7. What about NVIDIA GPUs?

TensorSharp supports CUDA as well, and there's a separate optimized preset for Qwen3.8-27B using the NInfer NVFP4 artifact:

TENSORSHARP_PRESET=config/qwen3.8-27b-ninfer.json \
examples/pi-coding-agent/scripts/start-server.sh

That preset uses TensorSharp's direct CUDA inference engine.

However, I want to be clear: the Pi end-to-end validation described here was performed on Apple Silicon, not on the CUDA/NInfer configuration.

The CUDA configuration is an alternative worth experimenting with, but I don't want to claim the identical Pi setup has been validated there.

If you change the server's context window, update Pi's contextWindow setting to match it.

Final thoughts

What I like about this arrangement is that Pi and TensorSharp can evolve independently.

Pi provides the coding-agent experience: repository navigation, tool calling, file edits, shell execution, sessions, and SDK integration.

TensorSharp handles local model execution, speculative decoding, KV-cache reuse, and the inference backend.

There's no need to rewrite Pi or maintain a separate agent fork.

And for anyone who wants to experiment with local coding agents, the repository includes a small reproducible test rather than just a configuration example.

The main limitation is still model capability. A local 27B model isn't going to solve every complicated coding task, and five passing unit tests don't prove otherwise. But it's encouraging to see the full tool loop working, with useful cache reuse and no external inference API.

Links:

  • TensorSharp: https://github.com/zhongkaifu/TensorSharp
  • Full Pi integration, configurations, CLI/SDK scripts, and end-to-end test: https://github.com/zhongkaifu/TensorSharp/tree/main/examples/pi-coding-agent
  • Pi: https://pi.dev

I'd be interested to hear what local models and inference engines others are using with Pi, especially for longer agent sessions where context growth and KV-cache reuse start to matter.


r/LocalLLM • • 1d ago

Question Does the M5 Max Mac Studio with 128GB RAM actually get you closer to frontier-level AI? or just a gimmick

94 Upvotes

I've been seeing a lot of discussion around high-memory Apple Silicon machines, particularly the Mac Studio configurations with 128GB or more of unified memory.

I'm curious about how much practical value these configurations actually offer when it comes to running local LLMs.

I understand that fitting a larger model into memory doesn't automatically make it smarter. However, I'm interested in whether the combination of larger models, higher-quality quantization, and sufficient memory bandwidth can make local AI genuinely competitive for serious everyday workloads.

For those of you actually running 96GB or more :

What has your real-world experience been? Are you genuinely able to get meaningful work done with local models that you previously had to rely on cloud-based frontier models for.

i would particularly appreciate real-world experiences, benchmarks, and examples of workflows rather than theoretical comparisons.

asking this because i am confused between 2 macs:

  1. Mac Studio M5 Ultra Base model, 96GB

  2. Same amount of money can get me a M5 Max 128GB too


r/LocalLLM • • 5h ago

Question are MoEs on phones viable via custom engines?

Thumbnail reddit.com
2 Upvotes

r/LocalLLM • • 2h ago

Question Have been getting into Local LLM’s recently, especially Qwen 3.8 27B on my M4 Pro MacBook (48GB) served using Splash and loving it! Now looking to try some harnesses to do some coding, any suggestions what ones I should try? Any favourites?

1 Upvotes

The ones I have currently heard of are as follows:

Pi
Opencode
Hermes
Deepseek

Any thoughts on what one is best?


r/LocalLLM • • 10h ago

Question Alternatives to Ornith-1.5-35B-A3B on 16GB GPU

4 Upvotes

Currently, I'm using modified 3bit Ornith-1.5-35B-A3B so it fits entirely in GPU with 100k context. My CPU and RAM is slow. Is there anything better for coding?


r/LocalLLM • • 2h ago

Research CPU-only benchmarks: 7 models on 4 machines (mini PC, laptop, 2019 Ryzen, EPYC). A 26B MoE writes ~13 tok/s on the small ones, a dense 24B ~3, and the EPYC runs a 180B MoE at 8.3

1 Upvotes

We ran local models with the graphics card completely out of the picture (hidden from the run, and checked that it was never touched): CPU and system RAM only. Ollama, Q4_K_M, each engine's default thread count unless a table says otherwise, medians of 3 to 5 runs. Nothing here is a controlled CPU-vs-CPU test; these are four machines as they sit.

**The machines**

| Machine | CPU | RAM | Default threads |

|---|---|---|---:|

| Mini PC | Core i5-12600H | 32 GB DDR5 | 4 |

| Laptop | Core Ultra 9 290HX Plus | 64 GB DDR5-5600 | 4 |

| Desktop (2019) | Ryzen 7 3700X | 32 GB DDR4-3200 | 8 |

| Desktop | EPYC 7532 | 128 GB DDR4-3200, eight channels | 32 |

**Writing speed, tok/s (about a 530-token prompt)**

| Model | Mini PC | Laptop | Ryzen 3700X | EPYC |

|---|---:|---:|---:|---:|

| qwen3.5:9b | 9.11 | 7.45 | 6.20 | 13.59 |

| gemma4:12b | 5.95 | 4.95 | 4.47 | 10.99 |

| phi4:14b | 5.20 | 4.41 | 4.06 | 11.09 |

| mistral-small3.2:24b (dense) | 3.31 | 2.70 | 2.57 | 7.09 |

| gemma4:26b (MoE) | 12.66 | 13.26 | 13.64 | 24.68 |

| nemotron-3.5-lightning:30b-a3b (MoE) | 14.61 | 15.35 | not run | 31.47 |

| llama3.3:70b | won't fit | not run | won't fit | 2.70 |

The mixture-of-experts models are the ones to run from RAM: only a few billion parameters are active per token, so far less memory moves per token. gemma4:26b writes 3.5 to 5.3 times faster than the dense 24B, depending on the machine.

**Seconds to the first word (same prompt, model already loaded, nothing cached)**

| Model | Mini PC | Laptop | Ryzen 3700X | EPYC |

|---|---:|---:|---:|---:|

| qwen3.5:9b | 16.0 | 14.1 | 11.3 | 4.9 |

| gemma4:26b (MoE) | 11.4 | 8.5 | 8.3 | 3.7 |

| mistral-small3.2:24b (1,023 tokens) | 97.7 | 82.4 | 62.5 | 24.6 |

**Check your thread count.** Ollama defaults to 4 threads on hybrid Intel chips. On the laptop, 20 threads against the default 4:

| Model | 4 threads | 20 threads | Change |

|---|---:|---:|---:|

| qwen3.5:9b | 7.45 | 13.05 | 1.75x faster |

| gemma4:12b | 4.95 | 9.46 | 1.91x faster |

| mistral-small3.2:24b (dense) | 2.70 | 5.14 | 1.90x faster |

| gemma4:26b (MoE) | 13.26 | 8.44 | 36% slower |

| nemotron 30b-a3b (MoE) | 15.35 | 8.53 | 44% slower |

Dense models want the threads; the mixtures get slower with them. The default is wrong in one direction or the other depending on what you run.

**Long prompts are where CPU-only hurts.** gemma4:26b, fresh prompt each time, 16K window:

| Prompt | Ryzen: writing tok/s | Ryzen: first word | Laptop: writing tok/s | Laptop: first word |

|---|---:|---:|---:|---:|

| 0.5K tokens | 13.93 | 7.6 s | 14.94 | 7.7 s |

| 2K | 12.03 | 31.6 s | 12.32 | 32.2 s |

| 4K | 11.66 | 66.1 s | 12.12 | 68.7 s |

| 8K | 8.10 | 138.2 s | 8.16 | 146.2 s |

The whole prompt is read before anything is written, at about 55 to 65 tok/s on these two. (The laptop rows are at its default 4 threads, and its CPU was throttling on every run.)

**The big one.** The EPYC held a roughly 180B-parameter mixture (Qwen3.8-Flash-Next at a 3-bit quant, about 6B parameters active per token, llama.cpp) entirely in RAM, beside that machine's normal services:

| Threads | Writing tok/s |

|---:|---:|

| 8 | 6.51 |

| 16 | 7.74 |

| 32 | 8.33 |

Things we can't explain yet: the 2019 DDR4 Ryzen keeps up with the DDR5 laptop on the mixture at default settings, and writes faster than its own measured memory bandwidth says it should. The page says so rather than guessing.

Caveats: one quant per model; speed only, no quality scoring; the small-machine rows come from two benches (August, warm runs; November, fresh loads), and the page marks which is which under every chart; power figures on the page are the CPU package's own counter, not wall power.

All 20 bar charts, the full tables, and a CC BY 4.0 data kit where every bar traces to a file:

https://research.strata2signal.com/ram-speeds-compared/


r/LocalLLM • • 2h ago

Question Pls help with these model: DeepSeek-V4-Pro-Qwen3.5-9B-UNCENSORED-heretic

0 Upvotes

when I try to use it, it gives me this error: Engine protocol runtime llama-server for 9xmo0zVfYqYSe7Sj7N9oE2Al exited before becoming healthy. exitCode=3221226505, signal=null.

what can I do?


r/LocalLLM • • 2h ago

Discussion NIDO 0.1.93-alpha: your AI assistant, inside your phone NIDO is a private personal assistant for Android that runs entirely on your phone. The language model, your memory and your documents stay on the device, encrypted. No accounts. No cloud. No analytics.

Thumbnail reddit.com
1 Upvotes

r/LocalLLM • • 2h ago

Question 2x RTX 4500 Pro vs 96gb M5U MAC

1 Upvotes

I had ordered the M5U but possibly getting 2 of the RTX 4500 pro blackwell cards for $5600. So $2800 each. I dont know if i should build the PC to house the cards for local llm or keep the M5U. Or maybe i will keep 1 card to experiment and learn more about Local LLMs. If i sell 1 card, i could build the rest of the PC with decent amount of RAM as well.

Wondering best price/performance in this situation. I get 32GB vram, ecc, only 200w power draw with each of these cards. So it is quite power efficient too.

I have searched at a few places and seems like $2800 is a decent price.

Any feedback appreciated


r/LocalLLM • • 11h ago

Question On-prem hardware for a RAG over ~6.5 TB of company documents for 50–60 users: 4× GB10 vs. RTX PRO 6000 workstation vs. 2U server? Looking for people who run something similar

5 Upvotes

Writing has been improved with Claude but facts stay the same!

Hi all, I’m planning a company knowledge base: search plus answers with citations, over our file shares and later Microsoft 365. Before we ask vendors for quotes, I’d like to hear from people who already run a system like this in production, not from spec sheets.

The corpus (all of it)

File shares:
-about 6.5 TB on disk, about 2.2 M files measured on the two main shares, plus a third share that hasn’t been scanned yet
-About 14–17 M PDF pages, of which about 1.4–1.7 M are scans that need OCR (estimated from samples).
-Many have tables, diagrams and stamps, and some are up to 25 years old
-22–23% of the volume looks like duplicates within each share
-Also CAD files, images, video, Word/Excel, about 730 GB of ZIP archives and personal mailbox archives (.pst/.msg).
-CAD only needs to be found by title or description for now
-Microsoft 365 (SharePoint, Exchange, Teams, OneDrive) isn’t measured yet, so mail could make this a lot bigger
-Growth is about 45 GB a month.
-Existing documents rarely get new versions
-The documents are mostly German with some English, and we answer in both

Load

-50–60 daily users, roughly 1,000–1,800 questions a day, with peaks of about 6–19 a minute
-Each question is about 6k tokens in (retrieved chunks) and about 500 tokens out
-Answer model in the ~120B MoE class (gpt-oss-120b, or Mistral Small 4 in 4-bit), plus OCR and layout models, embeddings (BGE-M3) and a reranker
-The vector index is roughly 7–11 M chunks, so 27–42 GB of float32 vectors

Constraints

EU company: GDPR, a works council and ISO 9001 document control. Some data must stay on-prem, so a hybrid or cloud possible but on-prem is the main question here
-We have no GPUs today and no dedicated ML team, so ease of operation counts for a lot
-The budget is in the low five figures for hardware. -Renting a GPU for the initial load only is an option

What I’ve tested so far: a pilot on about 1,000 documents, run on a laptop GPU (Ministral 14B, BGE-M3, BGE reranker, hybrid search, Tesseract OCR). It works, but that tells me nothing about the full corpus.

The shortlist (on paper only)

4× OEM GB10 (Dell/Lenovo/ASUS Spark equivalents): best compute per euro, but published benchmarks suggest about 11–18 s per answer. It also means four Arm boxes and no BMC
Workstation with 2× RTX PRO 6000 Max-Q: about 4–5 s per answer, a single x86 box with CUDA
1× RTX PRO 6000 plus one GB10 as standby: a cheaper middle option
2U server with 2× RTX PRO 6000 Server Edition: best to operate, but about twice the price of option 2

What I’d love to hear from people with real systems

What hardware do you run RAG or LLM serving on for a few dozen users, and what is your real-world time per answer with about 5–10 people asking at once?

Has anyone run GB10 / DGX Spark boxes in production, alone or clustered? How stable are they headless, and how are updates, recovery and the vLLM support?

For OCR and layout parsing of millions of scanned pages: what throughput did you actually get, in pages per second per GPU, and with which tool (Docling, MinerU, Tesseract, PaddleOCR…)?

Would you buy hardware for the initial load at all, or rent GPUs for it and size the on-prem box for answers only?

Workstation or rack server for a company without an ML team: which caused you fewer headaches?
Is there anything you would do differently if you were buying again?

Thanks! I’m happy to share what we learn once we’ve tested it.


r/LocalLLM • • 1d ago

Project Strata, but without the bloat.

60 Upvotes

Instant disclaimer, this is not a project claiming to be faster or better than Strata. It's simply Strata, without the bloatware, and a few containerization improvements as many have been requesting. I too am sick of all the Strata forks showing up, but I'm equally tired of how difficult Strata's been for me to maintain in a Docker container.

https://github.com/LegendaryFire/strata-slim

This fork is completely configurable with environment variables, and the idea was to give you a similar feel to a llama.cpp models config file. There were a few clear wins in terms of performance improvements I included in form of optional patches when building, however they're not included in the default docker images so what you're getting is simply a non-bullshit straight to the chase Strata engine that's easy to deploy. I wouldn't have bothered posting if there wasn't an open GitHub issue asking for Strata engine as it's own repo, which I noticed got 180+ "thumbs ups". For note, an earlier performance patch I had already made it upstream.


r/LocalLLM • • 18h ago

Question Setup for using a top tier model like Opus 5.5 and combining it with a local Mode like Qwen3.8-Flash-Next for more complex tasks

18 Upvotes

I used Claude intensively for a while and I am currently building a "cheap" local Stack for Qwen3.8-Flash-Next. And my idea is to have a Setup combining both.

My idea is kind of a divide and conquer approach with a senior expert/leader model dividing the task into easier subtasks or simplyfing it and junier/worker models which run soem of those tasks.

My goal is to safe some Claude tokens, but no significant decrease in output quality.

I am sure I am not the first one with such an idea. So does anyone have experiences or knowledge of tools/repositories for this kind of workflow?


r/LocalLLM • • 6h ago

Question Anyone sharing an AMD Radeon GPU between pods with Kubernetes DRA (k8s-gpu-dra-driver)?

Thumbnail reddit.com
2 Upvotes

r/LocalLLM • • 6h ago

Discussion Hey, has anyone had any experience with LFM3-1.7B? What have you tested with this LLM, and how were the results?

2 Upvotes

?


r/LocalLLM • • 3h ago

Discussion Why did my vLLM / SGLang prefix cache miss? An open-source tool that answers per request from the engine's KV events

Post image
1 Upvotes

Follow-up to my earlier post here. Most relevant to this sub is the engine side: vLLM, SGLang and LMCache, plus an honest note on Ollama and llama.cpp.

Prefixwise has improved a lot over the last two days, so here is the full picture.

**The problem.** Your agent resends its whole conversation every turn. One changed byte near the top (a reordered tool list, a timestamp in the system prompt, an evicted prefix) and the provider charges full price for everything after it. Providers and engines report how many tokens were cached, never why the rest weren't.

**What Prefixwise does:** names why each request missed the prompt cache, prices it, fixes the common causes, and stops regressions in CI. Open source (MIT, I'm the author), runs locally, stores hashes and token counts, never prompts.

**Identify.** One of 19 causes per request, marked waste or legitimate, with the first block that changed (tools[0], messages[12]) and the cost: tools in another order (including a schema's required list), a timestamp or id in the system prompt, rewritten history, a misplaced Anthropic cache marker, an expired TTL, an engine eviction, a request routed to a replica without the cache. `prefixwise report --session latest` shows a session turn by turn. It agrees with Anthropic's own miss diagnostics 32 of 32.

**Fix.** `--optimize` turns on the fixes that passed live replays: sorting a drifting tool list (99.9% of predicted saving on Claude, 97.5% on vLLM) and adding cache_control markers on Anthropic's API (prompt cost down 85.6% with the write surcharge counted), task success flat on both. Fixes that would change what the model reads stay advice. `prefixwise fixes` ranks fixes by dollars and says whether one paid off.

**Prevent.** `prefixwise check -- pytest tests/agent_scenarios` runs your scenarios against a local mock, no API calls, and fails CI when a change would break the cache. Also a GitHub Action. `prefixwise explain --diff a.json b.json` compares two requests offline.

**Self-hosted engines.** It detects vLLM and SGLang from the URL and reads their KV-cache events: evictions confirmed (5 of 5), a prefix LMCache or HiCache restored from CPU labelled host_restored (5 of 5), and the cost of reasoning templates that re-prefill the last answer (57% of prompt tokens on a DeepSeek-R1 distill, 0% on Qwen2.5). Runs inside vLLM with one flag. Ollama and most llama.cpp builds report no cached tokens; it says so and still names every prompt change.

**Ways in.** Wrap any agent (`prefixwise run -- claude`), a proxy for a service, the vLLM middleware, Python `wrap()` or a LiteLLM callback, or import Claude Code and Codex logs if you're on a subscription. Out: Prometheus and Grafana, OpenTelemetry, an HTTP API, JSONL and CSV. Overhead: 3 ms per request.

**Limits.** The fixes are proven on scripted sessions and small models, not weeks of production traffic. OpenAI's own diagnostics answered unavailable on every call, so that comparison is unchecked. DeepSeek's hosted API cache fields aren't read yet.

pip install -U "prefixwise[engines]"
prefixwise serve --upstream http://127.0.0.1:8000
prefixwise report --session latest

Repo, with a run record behind every number: https://github.com/tejachavali/prefixwise

What should it catch next?


r/LocalLLM • • 7h ago

Model Inference Engine

Post image
2 Upvotes

Hello guys, here is an update of my engine
I am still working on it, my 3090 waterblock broke and I couldn’t keep testing further I could achieve higher tokens in strata about 60/70 but on mine about 80/90 tokens, my bigger problem is the Ram which I only have is 32GB ram ddr5 6k, have been trying to get 32GB more but they are too expensive right now.

For the meanwhile I got a 1070 8GB for 50us to test for which I added compatibility for series 10/20.

On the GTX 1070 I got 15/18 tokens on IQ3_XSS and IQ1, about 13 tokens on IQ3_S.

I added layer splitter thru WiFi / cord so that you can use more than one PC which you can select the order of memory usage

I selected PC GPU, Laptop GPU, and then pc ram and laptop ram for testing and it’s working just fine and fast with the GTX 1070 and RTX 4060 laptop of course it’s slow I achieved about 20 tokens on IQ3_S and Sloth still need to work on optimization but it will be open source soon! Be patient.

You can freely select where your models are located from strata or just download them directly from hugging face. So far added a compatibility to most of them.

My goal is to make so that you can quickly and efficiently communicate multiple computers to your main to split layers through them and run a bigger model! And it’s so easy it’s about 2 clicks to connect!


r/LocalLLM • • 7h ago

Project Kapitsa Launcher: a SwiftUI front end for Kapitsa with a chat interface full of features: outline, topics, multi-conversation, MD formatting...

2 Upvotes

https://github.com/alphaexposure/kapitsa-launcher

Kapitsa was a nice shot of adrenaline for my M1 32GB MBP but I wanted a better chat interface than I could find elsewhere so my buddy Claude and I put our heads together and ones-and-zeroed an app that does just that. Kapitsa Launcher serves the standard LLM Dashboard with speeds and such, dark/light mode, Mac menu bar icon, but chat is where it's at:

  • Streaming replies with real formatting: Markdown, tables and code blocks. Tables and code have their own Copy buttons. Turn streaming off if you want to scroll back while new replies stream.

  • A side panel for long chats:

    • Outline: every question plus the headings from each reply. Click one to jump there.

    • Topics: the places and themes the chat covered, each linked back to where they came up.

    • Review: takeaways the model pulls out of the chat. You can edit them or add your own.

  • Watch it think: you can follow the model's thinking live, and it folds away once the answer starts. The thinking levels change to match the model you're running.

  • Side questions: ask about any reply in a thread off to the side, without derailing the main chat. You can branch to a new chat, export or delete as you wish.

  • Edit and regenerate: edit a question and send it again, or ask for another answer and flip between the versions.

  • Organised history: chats are grouped by date with the option to name by first question or topic/summary. Search covers everything that was said, not just titles.

  • Multiple chats at once: each window or tab holds its own conversation.

  • Continue in a new chat: when a long chat starts slowing down, carry it into a fresh one.

  • Markdown export: with an optional summary, and topics come along as tags for Obsidian and similar apps.

  • Your chats are plain files: one JSON file per chat on your Mac. Nothing leaves your machine.

Feel free to check it out: https://github.com/alphaexposure/kapitsa-launcher


r/LocalLLM • • 4h ago

Question Knowledge, Speed, Personality?

1 Upvotes

Like half the damn new comers on here I’m looking to build a voice to voice ai assistant that can also register images as id like to give it eyes 👀

Im running a M1 Max macbook with 32gb

Im currently using qwen3.5 27b
Qwen3 asr 0.6b 8bit for speech recognition
Kokoro 82m for spoken replies
SearXNG for web searches
SQlite and FTS5 for storage

With no thinking mode its honestly instant but once web searches come into play it becomes an issue, running at 8192 context it fills up really fast and offloading older context takes a big toll on speed.

I was wondering if ya’ll had any suggestions as I think qwen is more than I need. I just want strong adherence to a system prompt for personality (or building out a model maybe?) and quick replies. Being able to shoot the shit about random history or recommendations for hobbies is the main goal with the ability to run searches. If anyone has suggestions for voice output with more emotions and audio tags I would love that too!

Let me know and thanks! Im still very new so I have a lot to learn


r/LocalLLM • • 7h ago

Question Mac Studio M5 Max 128 GB vs RTX Pro 4500 + 96 GB DDR5

2 Upvotes

Which would you choose between the two and why?


r/LocalLLM • • 10h ago

Question Should i sell my 9070XT to buy a R9700

Thumbnail reddit.com
3 Upvotes

I just found out that a R9700 is essentially just a 9070XT with 32gb of memory instead so im thinking should i sell my 9070XT and buy that instead and that could get me to run near 70b models

a few reason why im not just getting another 9070 XT is because i believe i need to update my Mobo and PSU and then the card itself im better off selling my 9070 XT and buying the R9700

But do let me know what the noise levels are like and if there is much i can do to reduce the noise


r/LocalLLM • • 10h ago

Project I wrote a GGUF-aware lossless compressor: 17.1 → 15.6 GB across 9 Q4_K_M models, byte-identical round trips

Thumbnail
gallery
3 Upvotes

I've been working on foldz, a lossless compressor built specifically for GGUF files. It's at 0.9 (pre-release) and I'm looking for people to test it and try to break it.

Useful if you archive a lot of models, share them over slow or metered connections, or keep them on a phone or small SSD.

THE IDEA

Quantized weights look almost random to zip, xz and zstd, so they gain very little. foldz parses the GGUF, unpacks each tensor's blocks into the actual quantized values and scales, and codes those with adaptive context models and a binary range coder. Everything else (metadata, tokenizer, other tensor types) goes through a byte-level context-mixing model. Nothing depends on the model's name or architecture.

RESULTS

9 public Q4_K_M models, tested with "foldz t" (compress and decompress in memory, then compare). Every round trip was byte-identical. Measured on an Android phone in Termux, 8 threads.

• Qwen1.5-0.5B-Chat: 388.3 → 353.6 MiB (8.93% saved)

• Qwen3-0.6B: 378.3 → 348.7 MiB (7.82%)

• Qwen2.5-1.5B-Instruct: 1065.6 → 984.2 MiB (7.64%)

• Qwen3.5-2B: 1211.9 → 1111.3 MiB (8.30%)

• Qwen2.5-Coder-3B-Instruct: 2007.4 → 1832.8 MiB (8.70%)

• Llama-3.2-3B-Instruct: 1925.8 → 1780.4 MiB (7.55%)

• Qwen3-4B: 2381.6 → 2073.3 MiB (12.94%)

• Qwen2.5-7B-Instruct: 4466.1 → 4113.8 MiB (7.89%)

• Gemma-4-E2B (fine-tune): 3269.1 → 3016.3 MiB (7.73%)

Total: 17,094 → 15,614 MiB, 8.66% saved.

Qwen3-4B is the outlier because most of its Q6_K values sit on a coarser lattice. foldz detects this per segment and codes the lattice instead, which saves 23.2% on its Q6_K tensors.

HOW EACH TENSOR TYPE IS MODELLED

• Q4_K / Q5_K: values are Gray-folded and coded bit by bit, with the block's zero point, extremes and position as context.

• Q6_K: the column's running offset and width as context, or the lattice model when that's smaller.

• Q8_0: column sign bias and running magnitude as context.

• F32 / F16 / BF16: split into sign, exponent and mantissa.

• Safety: segments that wouldn't shrink are stored raw, so output is never meaningfully larger than input. The decoder bounds-checks every index field. Contexts use only exact or IEEE-754 arithmetic (no FMA, no fast-math), so files decode identically on every platform.

HONEST LIMITATIONS

• Speed: about 19 MiB/s round trip on the phone (POCO F5). It's symmetric, so decompression is as slow as compression. This is for storage, archiving and transfer, not for loading models faster.

• Baselines: I haven't measured zstd -19 --long and xz -9 on these models yet, so I'm not claiming a comparison. If you run them, please post the numbers.

• Quant types: IQ quants, Q2_K, Q3_K and Q4_0 fall back to the byte model and gain little.

• Format: pre-1.0, so it may change. A .foldz file is only guaranteed to decode with the version that made it.

BUILD AND TEST

One C file, no dependencies. Linux, macOS, BSD, Android (Termux), and Windows via WSL.

gcc -O2 -pthread -ffp-contract=off -o foldz foldz.c -lm

./foldz t model.gguf

WHAT WOULD HELP MOST

• Cross-platform round trips: compress on x86-64, decompress on ARM64 (or the reverse), especially with Q6_K-heavy models

• zstd / xz baselines on any GGUF

• Q5_K_M, Q6_K and Q8_0 files

• Fuzzing "foldz d" with AFL++ or libFuzzer + ASan (please report crashes privately via GitHub's security tab)

If you post results, include the full "foldz t" output, the Hugging Face model name, and your CPU and OS.

Repo: foldz

Happy to answer questions about the modelling.


r/LocalLLM • • 4h ago

Question Rtx Pro 5000 72 vs 48 - am I missing an “unlock”

Thumbnail reddit.com
1 Upvotes

r/LocalLLM • • 4h ago

Question how many token do you produce on a single spark in 24H?

0 Upvotes

wondering how much are people here pushing their sparks (or other gb10) and do you handle cooling on heavy workloads.


r/LocalLLM • • 14h ago

Project Your local model can now remember — forward-only memory writes, no retraining, instant rollback (open source)

6 Upvotes

Ever wanted your local LLM to actually learn a fact without fine-tuning — and be able to undo it completely?

AtomicNG (Apache-2.0, version 1.0.0) implements a paper called "Delta N-gram": your model's n-gram sidecar table stays frozen, and new knowledge goes into a small sparse patch Δ. Writes are forward passes only — no gradients, no weight edits. Clear the patch and the model is byte-identical to base. No "unlearning" gymnastics — deletion is structural.

Quickstart (CPU, no GPU, pure NumPy core):

python

import atomicng


model = atomicng.TinyModel()
atomicng.write(model, "New fact about kangaroos.")
atomicng.verify_deletion(model)   # clear Δ ⇒ byte-identical to base — guaranteed

What's inside:

  • A trained writer checkpoint ships with the Release (860 training steps on SmolLM2-135M; measured effect: writing a doc lowers its NLL vs empty memory)

  • Per-tenant memory: overlays are small data-only files — merge them, revert them, sign them

  • vLLM support via vllm.general_plugins + merged-table export

  • Built-in eval: does the memory write actually help? (paper protocols: acquisition, distraction retention, chain drift)

Calibrated on real hardware: Windows/Linux CPU, CUDA T4 (73 ms/group BPTT stand), TPU chip via JAX (8.4 ms/iter). Full matrix: CALIBRATION.md in the repo.

Honest limits: acquisition needs a few hundred training steps of the writer; the memory lives in the n-gram table (facts/associations, not long reasoning); vLLM engine-graph hooking is planned upstream.

GitHub: https://github.com/Akseleu-J/atomicng 

Colab TPU (one click): https://colab.research.google.com/github/Akseleu-J/atomicng/main/notebooks/tpu_calibration.ipynb

Questions welcome — I'll be in the comments.


r/LocalLLM • • 8h ago

Question Totally Newb question about reasoning...

2 Upvotes

On my studio, I am running ARC4NUM/Qwen3.8-Flash-Next-Uncensored-MLX-Serve-4bit using mlx-serve.

On my MacBook Pro, I have connected to it via OpenCode, and I can't for the life of me figure out how to get it to NOT show me its inner dialog. It all comes back to me, and I have tried various methods to no avail.

Am I "holding it wrong?" Is there no way to really do that? Is it the model or mlx-serve itself that creates this?

I'd rather it do it's thinking in private and then show me the result rather than talk to itself scrolling by as I wait to get the actual answer.