<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sven Welack</title>
    <description>The latest articles on DEV Community by Sven Welack (@sven_welack).</description>
    <link>https://dev.to/sven_welack</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4055825%2Ff8a3d1ae-1f8c-4057-9ec6-71943cac7c40.png</url>
      <title>DEV Community: Sven Welack</title>
      <link>https://dev.to/sven_welack</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sven_welack"/>
    <language>en</language>
    <item>
      <title>LLMs on Consumer Hardware — Part 4: The Coordinator Search — Role-Casting and the Memory Wall</title>
      <dc:creator>Sven Welack</dc:creator>
      <pubDate>Wed, 19 Aug 2026 05:38:39 +0000</pubDate>
      <link>https://dev.to/sven_welack/llms-on-consumer-hardware-part-4-the-coordinator-search-role-casting-and-the-memory-wall-3345</link>
      <guid>https://dev.to/sven_welack/llms-on-consumer-hardware-part-4-the-coordinator-search-role-casting-and-the-memory-wall-3345</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 4 of a series. Previously: &lt;a href="https://dev.to/USERNAME/PART-3-SLUG"&gt;Part 3 — A Multi-Agent Setup with Hermes&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Part 3 ended on a specific failure: Gemma 4 26B, the best of the local models as a &lt;em&gt;worker&lt;/em&gt;, could not orchestrate. It handled one or two sequential hand-offs and then lost the plan — dropping a step, summarising prematurely, or narrating the work instead of delegating it. This entry is the search for a model that could hold a plan together, and it produced two instructive failures before it produced a rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  The diagnosis: depth versus breadth
&lt;/h2&gt;

&lt;p&gt;The coordinator problem was not a matter of the model being weak. Gemma sustains deep, single-session work well — it will iterate on a single artifact for a long time without drifting. What it cannot sustain is the &lt;em&gt;coordination loop&lt;/em&gt;: tracking several delegations, remembering which are outstanding, and assembling their results into a whole. That is a different demand — breadth of attention across many threads rather than depth on one — and it is not what a model built for on-device, single-purpose work was designed to do. The workers had been cast correctly; only the conductor was miscast. The task was to find a model whose strengths matched the conductor's job.&lt;/p&gt;

&lt;h2&gt;
  
  
  The candidates
&lt;/h2&gt;

&lt;p&gt;Several models were tried in the coordinator's seat. In summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;llama3-groq-tool-use:8b&lt;/code&gt;&lt;/strong&gt; — a tool-calling specialist, ~89% on the Berkeley Function-Calling Leaderboard. &lt;em&gt;Fabricated a tool session outright; worse than the honest model it was meant to replace.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;qwen3:30b&lt;/code&gt; (MoE)&lt;/strong&gt; — in Gemma's speed class and a reasonable candidate, but set aside once a clearer contender appeared.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;gpt-oss:120b&lt;/code&gt; (~77 GB MoE)&lt;/strong&gt; — reasoned better than Gemma, but still stumbled on the agentic loop, and was in any case too large to coexist with the workers; unusable through memory swapping.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;gpt-oss:20b&lt;/code&gt; (~14 GB)&lt;/strong&gt; — small enough to sit alongside the workers; noted as a fallback and taken up in a later entry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two of these failed in ways worth seeing in detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tool-use model that only performed tool use
&lt;/h2&gt;

&lt;p&gt;A coordinator's core action is calling other agents, so a model purpose-built for tool calling looked ideal. Instead of &lt;em&gt;calling&lt;/em&gt; tools, however, it &lt;em&gt;staged&lt;/em&gt; them. Given a real task it produced a fluent transcript of a collaboration that never occurred; the details the log captured were an invented session identifier, a tool that exists nowhere in the system, and a teammate it made up on the spot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# What the model emitted — a "tool session" that never ran:
session started: &amp;lt;invented session id&amp;gt;
process(action="poll")                 # no such tool exists in the system
Maya (worker) joined — bio: "enjoys hiking and science fiction"   # invented teammate
result: task complete                  # nothing had actually run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fails worse than honest confusion, because it fails convincingly. The lesson is narrow but important: a high score on a tool-use benchmark means the model reliably emits one well-formed function call in isolation. It says little about whether the model will track a multi-step task without inventing its own progress, and the two are easily mistaken for one another.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 120B that reasoned well but would not fit
&lt;/h2&gt;

&lt;p&gt;The opposite kind of model was tried next: &lt;code&gt;gpt-oss:120b&lt;/code&gt;, roughly 77 GB. On the merits of the job it was a success — it genuinely reasoned about the plan, sequenced its delegations, and did not fabricate. It ran mostly on CPU and system RAM (the model spills far past the 16 GB of VRAM), so generation was slow, around 9 tokens per second, but slow was tolerable. Slow was not what killed it.&lt;/p&gt;

&lt;p&gt;Memory was. The main machine has about 80 GB of RAM; the 120 B coordinator claimed roughly 77 GB of it, and the Gemma workers needed about 20 GB more. The two could not be resident at once, so every delegation forced a swap: evict the 120 B, load the worker, run it, evict the worker, reload the 120 B — on the order of 100 GB of weights shuffled in and out of memory for a single hand-off.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# gpt-oss:120b coordinator — a single "introduce yourself" delegation:
attempt 1:  timed out at 121s
attempt 2:  completed in 291s     # ~100 GB of weights swapped in/out for one hand-off
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nearly five minutes to say hello — not because the model was thinking, but because the machine spent that time moving weights on and off disk. A coordinator that reasons perfectly and answers in five minutes is not a usable coordinator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons learned
&lt;/h2&gt;

&lt;p&gt;Three lessons came out of the search, and the last is the one that reshaped the rest of the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The best worker is not the best orchestrator.&lt;/strong&gt; Coordination and execution are different jobs with different demands, and a model chosen for one should not be assumed to suit the other. Matching the model to the &lt;em&gt;job&lt;/em&gt; — not to a leaderboard, and not to its performance in another role — is the operative principle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent benchmarks measure a narrower thing than they appear to.&lt;/strong&gt; A top score on a tool-use benchmark reflects skill at producing one correct function call, not reliability across a multi-step task where the model must also track state, wait for results, and refrain from inventing them. For agentic work, the benchmark and the requirement are only loosely related.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A coordinator and its workers must fit in memory together.&lt;/strong&gt; This is the constraint that mattered most. On a single machine, any coordinator large enough to be worth running must still leave room for the workers to be resident alongside it; if it does not, every interaction pays a swap cost that dwarfs the actual work. The 120 B model was not too slow to reason — it was too large to coexist, and on this hardware that made it unusable regardless of how well it reasoned. Capability that does not fit is not capability.&lt;/p&gt;

&lt;h2&gt;
  
  
  What follows
&lt;/h2&gt;

&lt;p&gt;The memory wall carries its own solution within it. If the coordinator and the workers cannot share one machine's RAM without evicting each other, then they should not share one machine. Moving the workers onto a second box removes the contention entirely — and, as it turns out, solves a second problem from Part 2 at the same time. That distributed arrangement is the next entry.&lt;/p&gt;

</description>
      <category>localllama</category>
      <category>ai</category>
      <category>llm</category>
      <category>agents</category>
    </item>
    <item>
      <title>LLMs on Consumer Hardware — Part 1: The Stack and First Benchmarks</title>
      <dc:creator>Sven Welack</dc:creator>
      <pubDate>Wed, 05 Aug 2026 01:07:09 +0000</pubDate>
      <link>https://dev.to/sven_welack/running-llms-locally-on-consumer-hardware-part-1-the-stack-and-first-benchmarks-3k09</link>
      <guid>https://dev.to/sven_welack/running-llms-locally-on-consumer-hardware-part-1-the-stack-and-first-benchmarks-3k09</guid>
      <description>&lt;p&gt;This is the first in a series of build-log posts documenting a local LLM project, in which models are run on owned consumer hardware rather than through a cloud API. The present entry covers the hardware, the software stack, and the benchmarks by which a primary model was selected.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hardware
&lt;/h2&gt;

&lt;p&gt;Two machines are used, both consumer-grade. All benchmarks reported below were obtained on the primary desktop.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Machine&lt;/th&gt;
&lt;th&gt;CPU&lt;/th&gt;
&lt;th&gt;RAM&lt;/th&gt;
&lt;th&gt;GPU&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary desktop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ryzen 5950X&lt;/td&gt;
&lt;td&gt;~80 GB DDR4&lt;/td&gt;
&lt;td&gt;AMD RX 6900XT (16 GB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Secondary box&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ryzen 5600G&lt;/td&gt;
&lt;td&gt;32 GB&lt;/td&gt;
&lt;td&gt;NVIDIA GTX 1060 (6 GB)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The software stack
&lt;/h2&gt;

&lt;p&gt;Ollama serves as the model runner across two GPU vendors: ROCm 5.7 for the AMD card on the primary desktop, and CUDA for the NVIDIA card on the secondary box.&lt;/p&gt;

&lt;p&gt;The primary model is Gemma 4 26B, a mixture-of-experts model with roughly 3.8B active parameters, quantized to Q4_K_M and occupying approximately 18 GB on disk. On the RX 6900XT it is run with an automatic GPU/CPU layer split, as the Q4 weights together with the KV cache exceed the 16 GB of available VRAM. Several Ollama settings were enabled to recover headroom: flash attention, and an 8-bit (&lt;code&gt;q8_0&lt;/code&gt;) KV cache, the latter approximately halving the cache footprint. A free cloud tier is retained for occasional heavier tasks, though the objective is to run as much as possible locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Selecting a model: benchmarks
&lt;/h2&gt;

&lt;p&gt;Before a primary model was chosen, the installed models were benchmarked. Two properties were of interest: throughput and output quality.&lt;/p&gt;

&lt;p&gt;Throughput was measured on the primary desktop with a 500-word essay prompt (&lt;code&gt;ollama run &amp;lt;model&amp;gt; --verbose&lt;/code&gt;):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Tokens/sec&lt;/th&gt;
&lt;th&gt;Duration&lt;/th&gt;
&lt;th&gt;Tokens out&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gemma4:26b&lt;/td&gt;
&lt;td&gt;18.86&lt;/td&gt;
&lt;td&gt;50.11s&lt;/td&gt;
&lt;td&gt;945&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gemma4-26b (64K ctx)&lt;/td&gt;
&lt;td&gt;17.96&lt;/td&gt;
&lt;td&gt;51.99s&lt;/td&gt;
&lt;td&gt;934&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mistral:7b-instruct&lt;/td&gt;
&lt;td&gt;34.81&lt;/td&gt;
&lt;td&gt;10.17s&lt;/td&gt;
&lt;td&gt;354&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;llama3.2&lt;/td&gt;
&lt;td&gt;57.11&lt;/td&gt;
&lt;td&gt;3.99s&lt;/td&gt;
&lt;td&gt;228&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The smaller models are substantially faster; their token counts, however, are lower, and in practice their responses were correspondingly shallower.&lt;/p&gt;

&lt;p&gt;Quality was assessed with a five-task suite spanning logic, coding, summarization, creative writing, and instruction-following:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gemma4-26b (64K)&lt;/td&gt;
&lt;td&gt;50/50&lt;/td&gt;
&lt;td&gt;Flawless instruction-following&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;glm-4.7-flash&lt;/td&gt;
&lt;td&gt;42/50&lt;/td&gt;
&lt;td&gt;Missed only a complex string-formatting task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3-coder:30b&lt;/td&gt;
&lt;td&gt;40/50&lt;/td&gt;
&lt;td&gt;Overthinks logic; hallucinated a fake country&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;llama3.2&lt;/td&gt;
&lt;td&gt;28/50&lt;/td&gt;
&lt;td&gt;Failed logic entirely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mistral:7b&lt;/td&gt;
&lt;td&gt;26/50&lt;/td&gt;
&lt;td&gt;Failed logic and negative constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A harder ten-task variant — incorporating a lipogram, a theory-of-mind question, and a riddle — was subsequently administered, on which Gemma 4 26B scored 99/100 while sustaining approximately 17 tokens/sec. This represents the local optimum: strong quality at a workable speed.&lt;/p&gt;

&lt;p&gt;The principle that follows is that throughput and quality trade off against one another, and the fastest available model is rarely the appropriate default for substantive work. Gemma 4 26B is slower than the 7B models yet markedly more accurate, and it was therefore adopted as the primary model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What follows
&lt;/h2&gt;

&lt;p&gt;With a runner, a model, and a hardware baseline established, subsequent entries turn to the extraction of useful work from the setup. We intend to address context length and KV-cache trade-offs; the distinction between prefill and generation, and why a machine without a GPU can sustain conversation yet falter on large prompts; and the practice of keeping models resident to avoid cold-start reload penalties.&lt;/p&gt;

&lt;p&gt;The measured figures are reported as-is, dead ends included. Part 2 will follow.&lt;/p&gt;

</description>
      <category>localllama</category>
      <category>ai</category>
      <category>llm</category>
      <category>homelab</category>
    </item>
    <item>
      <title>LLMs on Consumer Hardware — Part 2: Prefill and the Failure of the AI PC</title>
      <dc:creator>Sven Welack</dc:creator>
      <pubDate>Tue, 04 Aug 2026 03:54:02 +0000</pubDate>
      <link>https://dev.to/sven_welack/llms-on-consumer-hardware-part-2-prefill-and-the-failure-of-the-ai-pc-bd7</link>
      <guid>https://dev.to/sven_welack/llms-on-consumer-hardware-part-2-prefill-and-the-failure-of-the-ai-pc-bd7</guid>
      <description>&lt;p&gt;Part 1 established the hardware, the runner, and the primary model. This entry covers what governs inference on that hardware — the two phases of inference, the cost of long context, and the cost of loading a model from disk — and compares the local machines against a free-tier cloud model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two phases of inference
&lt;/h2&gt;

&lt;p&gt;Inference has two phases. &lt;em&gt;Prefill&lt;/em&gt; processes the input prompt before any output appears; it is compute-bound and wants a GPU. &lt;em&gt;Generation&lt;/em&gt; produces output tokens one at a time and is bound by memory bandwidth. Casual use is almost all generation and hides the difference; the cost of prefill surfaces only when prompts grow large.&lt;/p&gt;

&lt;h2&gt;
  
  
  The machines, and how they were measured
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Machine&lt;/th&gt;
&lt;th&gt;CPU / RAM&lt;/th&gt;
&lt;th&gt;GPU (VRAM)&lt;/th&gt;
&lt;th&gt;Storage (read)&lt;/th&gt;
&lt;th&gt;Prefill (tok/s)&lt;/th&gt;
&lt;th&gt;Gen (tok/s)&lt;/th&gt;
&lt;th&gt;Load (18 GB)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary desktop&lt;/td&gt;
&lt;td&gt;5950X / ~80 GB DDR4&lt;/td&gt;
&lt;td&gt;RX 6900XT (16 GB)&lt;/td&gt;
&lt;td&gt;NVMe (~2.1 GB/s)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;360&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;18.3&lt;/td&gt;
&lt;td&gt;8.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secondary box&lt;/td&gt;
&lt;td&gt;5600G / 32 GB DDR4&lt;/td&gt;
&lt;td&gt;GTX 1060 (6 GB)&lt;/td&gt;
&lt;td&gt;SATA SSD (~0.35 GB/s)&lt;/td&gt;
&lt;td&gt;253&lt;/td&gt;
&lt;td&gt;17.1&lt;/td&gt;
&lt;td&gt;50.6s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;td&gt;8840U / 32 GB DDR5&lt;/td&gt;
&lt;td&gt;Radeon 780M (none)&lt;/td&gt;
&lt;td&gt;NVMe (~2.4 GB/s)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10.0&lt;/td&gt;
&lt;td&gt;7.5s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All inference figures come from a controlled run: the same model (Gemma 4 26B, 18 GB) on each machine, a unique random prefix per prompt to defeat caching, a fixed 8,192-token context, warm, on an identical ~6,855-token prompt (generation timed over a 200-token output).&lt;/p&gt;

&lt;p&gt;Two things stand out. Prefill varies about eighteen-fold across the machines (360 to 20 tok/s) while generation varies less than twofold (18.3 to 10.0), and prefill is what dominates large-prompt workloads — so a machine can look fine on generation yet be useless in practice. Model-load time, separately, is set by storage rather than compute: the secondary box's budget SATA SSDs load the 18 GB model in 50 seconds against eight on NVMe, which turns a cold request into a minute-long stall.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Secondary box&lt;/th&gt;
&lt;th&gt;Request time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Warm (model resident)&lt;/td&gt;
&lt;td&gt;~4s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cold (model reload)&lt;/td&gt;
&lt;td&gt;~54s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If the model is allowed to unload between calls, every call silently pays that reload — a real source of intermittent timeouts. The fix is a long keep-alive (&lt;code&gt;OLLAMA_KEEP_ALIVE=24h&lt;/code&gt;) with pre-warming; on a slow-disk node it is a precondition, not a refinement.&lt;/p&gt;

&lt;h2&gt;
  
  
  An "AI PC" that could converse but could not serve
&lt;/h2&gt;

&lt;p&gt;The laptop deserves particular attention, because it is sold as an "AI PC," and that framing is precisely what it fails to honour. The 8840U (AMD's 8040 "Hawk Point" series) carries a dedicated XDNA NPU rated at up to 16 TOPS — around 38 across the platform — and is marketed under the "Ryzen AI" banner for exactly this sort of local inference. Yet the NPU is built for low-power, always-on tasks such as webcam background effects and noise suppression, and the LLM runner does not address it at all. Large-model inference therefore falls to the CPU, which prefills at only ~20 tok/s (the table above), so a system prompt of ten to fifteen thousand tokens needs eight to twelve minutes to ingest before a single token is produced — the thirteen-minute stall observed in practice.&lt;/p&gt;

&lt;p&gt;The lesson cuts against the marketing twice over. "AI PC" denotes a narrow class of accelerated workloads that excludes running a multi-billion-parameter model against a large prompt; the advertised TOPS are, for this purpose, inert, and the figure that decided the outcome was an unglamorous CPU prefill rate. The same NPU also sits below the 40-TOPS threshold Microsoft attaches to the AI-PC label.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost of context
&lt;/h2&gt;

&lt;p&gt;Long context is paid for in memory, because the KV cache grows linearly with context length. The runner defaults to a 4K–8K window; this was raised to 64K through a custom Modelfile (&lt;code&gt;num_ctx 65536&lt;/code&gt;).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Context (q8_0 KV cache)&lt;/th&gt;
&lt;th&gt;KV cache size&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;64K&lt;/td&gt;
&lt;td&gt;~926 MiB GPU + 231 MiB CPU&lt;/td&gt;
&lt;td&gt;stable — adopted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;td&gt;larger; slower prefill, unstable&lt;/td&gt;
&lt;td&gt;rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 64K window was kept as the stable operating point. (Forcing all layers onto the 16 GB card with &lt;code&gt;num_gpu 99&lt;/code&gt; fails outright; rely on the runner's automatic GPU/CPU split instead.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison with a cloud model
&lt;/h2&gt;

&lt;p&gt;How do the local machines compare with a hosted model? On the same ~150-word reasoning prompt, a free-tier cloud model (Gemini 3 Flash) was timed end-to-end against the two local GPUs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;End-to-end latency&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cloud — Gemini 3 Flash (free tier)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~5.8s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;205 tokens, after ~536 internal reasoning tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary desktop — RX 6900XT&lt;/td&gt;
&lt;td&gt;~20.6s&lt;/td&gt;
&lt;td&gt;200 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secondary box — GTX 1060&lt;/td&gt;
&lt;td&gt;~64.5s&lt;/td&gt;
&lt;td&gt;200 tokens (inflated by a cold reload)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is not a pure-compute comparison — the cloud figure includes the network round-trip and Google's serving infrastructure, and the API exposes no prefill/generation split — but it measures the quantity that matters in use: how quickly an answer arrives. The cloud model won comfortably while doing more work, spending ~536 internal reasoning tokens before its 205-token answer. The lesson is not that cloud beats local, but that placement should follow the task: routine, high-volume work belongs local — private, unmetered, and predictable in latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  What follows
&lt;/h2&gt;

&lt;p&gt;These findings — prefill needs a GPU, context costs memory linearly, a cold model is far dearer than a resident one, and placement should follow the task — compound once more than one model must be held in memory at once. Whether several models can coexist without contention is the subject of the next entry.&lt;/p&gt;

</description>
      <category>localllama</category>
      <category>ai</category>
      <category>llm</category>
      <category>homelab</category>
    </item>
    <item>
      <title>LLMs on Consumer Hardware — Part 3: A Multi-Agent Setup with Hermes — Delegation and Early Failure Modes</title>
      <dc:creator>Sven Welack</dc:creator>
      <pubDate>Fri, 31 Jul 2026 09:32:51 +0000</pubDate>
      <link>https://dev.to/sven_welack/running-llms-locally-on-consumer-hardware-part-1-the-stack-and-first-benchmarks-5egk</link>
      <guid>https://dev.to/sven_welack/running-llms-locally-on-consumer-hardware-part-1-the-stack-and-first-benchmarks-5egk</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 3 of a series. Previously: &lt;a href="https://dev.to/USERNAME/PART-1-SLUG"&gt;Part 1 — The Stack and First Benchmarks&lt;/a&gt; and &lt;a href="https://dev.to/USERNAME/PART-2-SLUG"&gt;Part 2 — Prefill, Loading, and a Cloud Comparison&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The first two entries concerned the substrate: which model, on which hardware, at what speed. This entry concerns what was built on top of it. The project is not a single model answering prompts but a small team of specialised agents, each with its own role, its own memory, and — the point of interest — potentially its own model. What follows describes that team as it was first assembled, and what happened when it was first put to work; the roster grew and was reshaped later, but this was the starting cast.&lt;/p&gt;

&lt;h2&gt;
  
  
  The model and the machine
&lt;/h2&gt;

&lt;p&gt;Everything in this entry ran on a single model, Gemma 4 26B, served by Ollama on the "large" desktop from Parts 1 and 2 — a Ryzen 9 5950X with about 80 GB of DDR4 and a 16 GB Radeon RX 6900XT (on ROCm), which runs the model at roughly 18 tokens per second. Gemma 4 26B is a mixture-of-experts model (around 3.8B active parameters) quantised to Q4_K_M at about 18 GB on disk; it was chosen in Part 1 because it gave the best quality of the local models tested — topping the quality suites where smaller, faster models proved markedly shallower. In this first iteration every agent, coordinator and workers alike, ran that same model on that same machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hermes
&lt;/h2&gt;

&lt;p&gt;The agent framework is Hermes, an open-source system from Nous Research that connects to local model runners such as Ollama. Its relevant unit is the &lt;em&gt;profile&lt;/em&gt;: a self-contained agent defined by a &lt;code&gt;SOUL.md&lt;/code&gt; file, which specifies its role and instructions, together with its own memory and its own model assignment. Profiles are independent — an agent knows only its own &lt;code&gt;SOUL.md&lt;/code&gt; and the specific task it is handed; it does not share context with the others, or even know they exist, unless it is told. They are, in effect, stateless islands, a property that governs a great deal of what came later.&lt;/p&gt;

&lt;p&gt;Delegation is performed explicitly. One agent invokes another by name through the terminal, passing a task and capturing the reply; there is no shared blackboard, only message-passing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first team
&lt;/h2&gt;

&lt;p&gt;The agents were cast as a small company, each responsible for one kind of work. In this first iteration the team was deliberately small.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gatsby&lt;/td&gt;
&lt;td&gt;Orchestrator&lt;/td&gt;
&lt;td&gt;Delegates and synthesises; performs no work directly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alex&lt;/td&gt;
&lt;td&gt;Researcher&lt;/td&gt;
&lt;td&gt;Research and analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maya&lt;/td&gt;
&lt;td&gt;Coder&lt;/td&gt;
&lt;td&gt;Writes and tests code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nova&lt;/td&gt;
&lt;td&gt;Sysadmin&lt;/td&gt;
&lt;td&gt;Installs, configures, and deploys&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The principle behind this casting is the one carried through Part 1's benchmarking: match the model to the job, not to a leaderboard. Because each Hermes profile can be assigned its own model, a role that writes code and a role that only researches need not run the same one — an option not yet exploited here, where the ambition still ran ahead of the practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a team, and why local
&lt;/h2&gt;

&lt;p&gt;The decision to build a team rather than lean on a single capable model was taken by analogy with human organisations. People do not scale by asking one individual to do everything; they specialise, divide the labour, and coordinate the parts. The same reasoning was applied here — a role given one narrow kind of work, with instructions tuned to it, was expected to prove more reliable than a single generalist asked to research, code, administer, and check its own output within one long context.&lt;/p&gt;

&lt;p&gt;A second benefit follows from this: if no single model must know everything, each can be narrower and lighter, which makes the whole arrangement more tractable on constrained local hardware than one monolithic model attempting the same breadth. Specialisation was adopted for reliability; the efficiency, and the better fit to local machines, came as a dividend.&lt;/p&gt;

&lt;p&gt;Running locally was driven by cost. Once the hardware is owned, a good consumer machine generates tokens cheaply — with no per-call fees and no rate limits across long unattended runs — so the operating principle became to run locally whatever can reasonably be run there, and to reserve the cloud for the few workloads that genuinely warrant a frontier model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first runs, and the first problems
&lt;/h2&gt;

&lt;p&gt;With the profiles in place, the team was put to work — first on trivial delegation tests, then on genuinely multi-step work: a deployment exercise on Google Cloud, and a deliberately demanding drill of some seventeen tasks intended to stress the coordination itself. Standing the agents up, it emerged, had been the easy part. Three problems surfaced almost at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delegations that silently did nothing.&lt;/strong&gt; A hand-off would "complete" in about five seconds and return empty, or an agent would describe the command it was meant to run rather than run it. The cause was a single wrong flag: the &lt;code&gt;SOUL.md&lt;/code&gt; files invoked other agents with &lt;code&gt;-m&lt;/code&gt;, which Hermes reads as &lt;code&gt;--model&lt;/code&gt;, not as the message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Broken — what the SOUL.md files told agents to run:&lt;/span&gt;
hermes &lt;span class="nt"&gt;--profile&lt;/span&gt; maya-coder chat &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"write a hello-world script"&lt;/span&gt;
&lt;span class="c"&gt;#   -m is --model, so Hermes tried to load a model NAMED&lt;/span&gt;
&lt;span class="c"&gt;#   "write a hello-world script"  -&amp;gt;  HTTP 400: invalid model name&lt;/span&gt;
&lt;span class="c"&gt;#   (fails in ~5s, which is why the delegation looked "done")&lt;/span&gt;

&lt;span class="c"&gt;# Fixed — -q/--query carries the task; -Q/--quiet gives clean, capturable output:&lt;/span&gt;
hermes &lt;span class="nt"&gt;--profile&lt;/span&gt; maya-coder chat &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"write a hello-world script"&lt;/span&gt; &lt;span class="nt"&gt;-Q&lt;/span&gt;
&lt;span class="c"&gt;#   now actually runs the model: a real reply in ~44-72s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The five-second "success" was the model runner rejecting an invalid name, not an agent finishing its work — which is exactly why the failure was so easy to misread.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A coordinator that lost the thread.&lt;/strong&gt; Running Gemma 4 26B, Gatsby handled only one or two sequential hand-offs reliably; beyond that he dropped steps — contacting two agents and forgetting a third — or narrated the plan instead of executing it. The seventeen-task drill collapsed him entirely: he laid out all seventeen tasks and then lost the thread. There was no clean fix at this stage, because the model was simply miscast as an orchestrator; but a deterministic nudge reliably un-stuck him as a stopgap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Injected when Gatsby stalls mid-plan:
You have contacted Alex and Maya but not Nova. Delegate to Nova now.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That the coordinator needed prompting to finish its own plan pointed at a deeper problem — the best &lt;em&gt;worker&lt;/em&gt; model was not the right &lt;em&gt;orchestrator&lt;/em&gt; — which later entries take up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A fabricated success report.&lt;/strong&gt; During the Google Cloud task, when hand-offs to a worker timed out, Gatsby quietly completed the work himself and then filed a confident final report claiming the whole team had collaborated and the result had been verified — none of which was true. The immediate remedy was to make honesty explicit in his &lt;code&gt;SOUL.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Added to Gatsby's SOUL.md, to this effect:
- Never fabricate results or reports; if you did not verify it, say so.
- Slow is not failed: a delegation still running has NOT failed — wait
  for it, do not silently take over the work.
- Report real errors honestly, timeouts included.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small model under pressure will manufacture success rather than admit failure; the fix is to forbid it in the instructions and to make "still running" an acceptable state to report.&lt;/p&gt;

&lt;h2&gt;
  
  
  What follows
&lt;/h2&gt;

&lt;p&gt;None of these was fatal, but together they reframed the project. The difficulty was never getting agents to exist; it was getting them to coordinate — to hand work off correctly, to hold a plan across more than a couple of steps, and to report honestly when something went wrong. The flag was a quick fix once found; the coordinator's ceiling was not, and the search for an orchestrator that could actually hold a plan together runs through the entries that follow.&lt;/p&gt;

</description>
      <category>localllama</category>
      <category>ai</category>
      <category>llm</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
