<?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: david</title>
    <description>The latest articles on DEV Community by david (@mrdushidush).</description>
    <link>https://dev.to/mrdushidush</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%2F3769586%2Fc83b985f-d5a2-4fc9-a18c-f70e5333d0ab.png</url>
      <title>DEV Community: david</title>
      <link>https://dev.to/mrdushidush</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mrdushidush"/>
    <language>en</language>
    <item>
      <title>A 7.5B model beat a 24B on my coding benchmark.</title>
      <dc:creator>david</dc:creator>
      <pubDate>Sat, 01 Aug 2026 13:33:57 +0000</pubDate>
      <link>https://dev.to/mrdushidush/a-75b-model-beat-a-24b-on-my-coding-benchmark-30o4</link>
      <guid>https://dev.to/mrdushidush/a-75b-model-beat-a-24b-on-my-coding-benchmark-30o4</guid>
      <description>&lt;h3&gt;
  
  
  16 local model configurations, 56 hidden-test coding tasks, 36 full runs, one 16 GB card
&lt;/h3&gt;

&lt;p&gt;Every number below was recounted from the committed &lt;code&gt;SCORES-*.tsv&lt;/code&gt; files, not transcribed from notes. The raw data - 36 rows, one per run, each with its full failure list - is &lt;a href="https://github.com/mrdushidush/claudette/blob/battery/q50-quality-corpus/runs/eval-2026-05-29/battery/RESULTS-q56.csv" rel="noopener noreferrer"&gt;&lt;code&gt;RESULTS-q56.csv&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gemma-4-e4b&lt;/code&gt; is &lt;strong&gt;7.5B parameters in a 4.97 GiB file&lt;/strong&gt;. It scored &lt;strong&gt;42/56&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;devstral-small-2-24b&lt;/code&gt; is 24B in 11.90 GiB. It scored &lt;strong&gt;40/56&lt;/strong&gt;. &lt;code&gt;gpt-oss-20b&lt;/code&gt; scored 38. Both&lt;br&gt;
gemma-4-12b variants - one of them at Q8_0, more than twice the precision - landed at 42.5 and 41.&lt;/p&gt;

&lt;p&gt;Three runs each. The ranges do not overlap. &lt;strong&gt;On a small card, the 5 GiB model is not the&lt;br&gt;
compromise option&lt;/strong&gt;, and no public leaderboard would have told you that.&lt;/p&gt;

&lt;p&gt;Everyone has opinions about which local model to code with, which quantisation to run, and what&lt;br&gt;
KV cache setting costs you. Almost all of those opinions come from a public leaderboard, or from&lt;br&gt;
one run of one config on somebody's box.&lt;/p&gt;

&lt;p&gt;So I built a 56-task coding benchmark that grades with hidden tests, and ran &lt;strong&gt;16 model&lt;br&gt;
configurations&lt;/strong&gt; through it on the same card at the same constants, with every held-constant&lt;br&gt;
actually recorded. Then I ran several of them repeatedly - &lt;strong&gt;36 full runs in total&lt;/strong&gt; - to find&lt;br&gt;
out how much of a single number is noise.&lt;/p&gt;

&lt;p&gt;The ranking does not match any public leaderboard; in one case it inverts one outright. And the&lt;br&gt;
noise result surprised me more than the ranking did: &lt;strong&gt;the error bar is a property of the model,&lt;br&gt;
not of the benchmark.&lt;/strong&gt; One model swings 8 points between identical consecutive runs while another&lt;br&gt;
is bit-for-bit reproducible - and it is not the weaker one that swings.&lt;/p&gt;

&lt;h2&gt;
  
  
  The method, and why there is no LLM judge
&lt;/h2&gt;

&lt;p&gt;56 medium-hard coding tasks run through a real agent loop - the model reads files, edits them,&lt;br&gt;
runs tests, and iterates until it says it is done. Grading is &lt;strong&gt;hidden verification&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The fixture the model sees ships only happy-path visible tests.&lt;/li&gt;
&lt;li&gt;At grade time, a verifier injects &lt;strong&gt;hidden reviewer tests&lt;/strong&gt; and builds/runs them against
whatever the model actually left on disk.&lt;/li&gt;
&lt;li&gt;Pass/fail is the compiler and the test runner. No model judges another model's output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point matters more than it sounds. The lesson this project inherited from its own&lt;br&gt;
ancestors: &lt;strong&gt;LLM judges inflate.&lt;/strong&gt; Deterministic ground truth may be &lt;em&gt;lowered&lt;/em&gt; by a model, never&lt;br&gt;
raised. So there is no judge here at all - just &lt;code&gt;cargo test&lt;/code&gt;, &lt;code&gt;pytest&lt;/code&gt;, and &lt;code&gt;node&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Tasks are &lt;strong&gt;test-first gated&lt;/strong&gt;. A task enters the corpus only if its verifier &lt;em&gt;fails&lt;/em&gt; on the&lt;br&gt;
untouched fixture and &lt;em&gt;passes&lt;/em&gt; on fixture + reference solution. That rules out tasks that are&lt;br&gt;
accidentally already passing, and tasks that are impossible.&lt;/p&gt;

&lt;p&gt;The discriminating axis turned out not to be algorithmic difficulty. It is &lt;strong&gt;unstated correctness&lt;br&gt;
traps&lt;/strong&gt; - the degenerate input, the falsy-vs-absent distinction, the boundary the prompt implies&lt;br&gt;
but never enumerates. Prompts state the goal the way a user would; the hidden tests grade the way&lt;br&gt;
a reviewer would.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Corpus:&lt;/strong&gt; 56 tasks - 15 python, 14 rust, 10 js, 9 ts, 8 shell. By kind: 18 implement-spec,&lt;br&gt;
7 boundary, 6 bugfix, 6 api-misuse, 5 error-handling, 4 refactor, 4 perf, 4 multi-file,&lt;br&gt;
2 concurrency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Box:&lt;/strong&gt; RTX 5060 Ti 16 GB, Windows 11, LM Studio. Held constant on every row: ctx 32768,&lt;br&gt;
KV cache q8_0, &lt;code&gt;numParallelSessions&lt;/code&gt; 1, one agent session at a time, identical agent binary.&lt;br&gt;
Every row's actual values are recorded rather than assumed - see "the method lesson that cost the&lt;br&gt;
most", which is the section I would most want another benchmarker to read.&lt;/p&gt;




&lt;h2&gt;
  
  
  The table
&lt;/h2&gt;

&lt;p&gt;Full 56 tasks on every row. Weak scores are data, not failures - a benchmark that reports only&lt;br&gt;
winners tells you nothing about the shape of the field.&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;params&lt;/th&gt;
&lt;th&gt;quant&lt;/th&gt;
&lt;th&gt;GiB&lt;/th&gt;
&lt;th&gt;runs&lt;/th&gt;
&lt;th&gt;median&lt;/th&gt;
&lt;th&gt;range&lt;/th&gt;
&lt;th&gt;n&lt;/th&gt;
&lt;th&gt;wall-clock&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;google/gemma-4-26b-a4b-qat&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;26B-A4B&lt;/td&gt;
&lt;td&gt;Q4_0&lt;/td&gt;
&lt;td&gt;13.45&lt;/td&gt;
&lt;td&gt;55, 54, 55&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;71–76 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;unsloth/gemma-4-26B-A4B-it&lt;/td&gt;
&lt;td&gt;26B-A4B&lt;/td&gt;
&lt;td&gt;UD-Q4_K_M&lt;/td&gt;
&lt;td&gt;15.78&lt;/td&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;⚠️1&lt;/td&gt;
&lt;td&gt;71 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;qwen3.6-35b-a3b-mtp@iq3_s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;35B-A3B&lt;/td&gt;
&lt;td&gt;IQ3_S 3.06bpw&lt;/td&gt;
&lt;td&gt;12.67&lt;/td&gt;
&lt;td&gt;49, 50, 50, 50, 48, 52&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;21–31 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.6-35b-a3b@iq4_xs&lt;/td&gt;
&lt;td&gt;35B-A3B&lt;/td&gt;
&lt;td&gt;UD-IQ4_XS 4.25bpw&lt;/td&gt;
&lt;td&gt;16.51&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;⚠️1&lt;/td&gt;
&lt;td&gt;53 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.6-35b-a3b-mtp (GPU-3)&lt;/td&gt;
&lt;td&gt;35B-A3B&lt;/td&gt;
&lt;td&gt;IQ4_XS 3.53bpw&lt;/td&gt;
&lt;td&gt;14.59&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;⚠️1&lt;/td&gt;
&lt;td&gt;43 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.6-35b-a3b-mtp (GPU-4)&lt;/td&gt;
&lt;td&gt;35B-A3B&lt;/td&gt;
&lt;td&gt;IQ4_XS 3.97bpw&lt;/td&gt;
&lt;td&gt;16.43&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;⚠️1&lt;/td&gt;
&lt;td&gt;51 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3-coder-30b-a3b-instruct&lt;/td&gt;
&lt;td&gt;30B-A3B&lt;/td&gt;
&lt;td&gt;UD-Q4_K_XL&lt;/td&gt;
&lt;td&gt;16.45&lt;/td&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;⚠️1&lt;/td&gt;
&lt;td&gt;58 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;google/gemma-4-12b&lt;/td&gt;
&lt;td&gt;12B&lt;/td&gt;
&lt;td&gt;Q8_0&lt;/td&gt;
&lt;td&gt;11.80&lt;/td&gt;
&lt;td&gt;42, 43&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;42.5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;44–53 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;google/gemma-4-e4b&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7.5B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.97&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;43, 42, 42&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;42&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;30–35 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;north-mini-code-1.0 (Cohere)&lt;/td&gt;
&lt;td&gt;30B-A3B&lt;/td&gt;
&lt;td&gt;UD-Q3_K_M&lt;/td&gt;
&lt;td&gt;13.24&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;⚠️1&lt;/td&gt;
&lt;td&gt;82 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;google/gemma-4-12b-qat&lt;/td&gt;
&lt;td&gt;12B&lt;/td&gt;
&lt;td&gt;Q4_0&lt;/td&gt;
&lt;td&gt;6.50&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;⚠️1&lt;/td&gt;
&lt;td&gt;57 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;devstral-small-2-24b-2512&lt;/td&gt;
&lt;td&gt;24B&lt;/td&gt;
&lt;td&gt;IQ4_XS&lt;/td&gt;
&lt;td&gt;11.90&lt;/td&gt;
&lt;td&gt;40, 39, 40&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;19–22 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;openai/gpt-oss-20b&lt;/td&gt;
&lt;td&gt;20B-A3.6B&lt;/td&gt;
&lt;td&gt;MXFP4&lt;/td&gt;
&lt;td&gt;11.28&lt;/td&gt;
&lt;td&gt;40, 38, 32&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;38&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;★&lt;strong&gt;8&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;10–12 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.5-4b&lt;/td&gt;
&lt;td&gt;4B&lt;/td&gt;
&lt;td&gt;UD-Q8_K_XL&lt;/td&gt;
&lt;td&gt;5.54&lt;/td&gt;
&lt;td&gt;31, 33, 33&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;33&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;33–42 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;google/gemma-4-e2b&lt;/td&gt;
&lt;td&gt;4.6B&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;3.19&lt;/td&gt;
&lt;td&gt;31, 31, 31&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;31&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;23 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;unsloth/granite-4.1-8b&lt;/td&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;td&gt;Q8_0&lt;/td&gt;
&lt;td&gt;8.70&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;⚠️1&lt;/td&gt;
&lt;td&gt;22 min&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sizes are the measured GGUF file in &lt;strong&gt;GiB&lt;/strong&gt;, not a vendor marketing figure and not &lt;code&gt;lms ls&lt;/code&gt;&lt;br&gt;
(which reports decimal GB and folds in the mmproj projector). Quant names are exact, because&lt;br&gt;
"gemma-4-12b" at Q8_0 and at Q4_0 are two different experiments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On the rows marked ⚠️1:&lt;/strong&gt; a single run carries an error bar this benchmark can now put a number&lt;br&gt;
on, and it is not small - see the noise section. Nothing load-bearing in this piece rests on an&lt;br&gt;
n=1 row. Where one does (QAT at 12B), I say so and decline to make the claim.&lt;/p&gt;

&lt;p&gt;One model was excluded rather than scored: &lt;strong&gt;nemotron-3-nano-omni-30b-a3b&lt;/strong&gt; took &lt;strong&gt;299 seconds on&lt;br&gt;
the corpus's easiest task&lt;/strong&gt; (vs 18 s for devstral) and projected to roughly 4.5 hours. At that&lt;br&gt;
speed the per-task timeouts start failing tasks on the clock rather than on quality, which&lt;br&gt;
produces an unreadable row. Its config was verified correct and its template healthy - the&lt;br&gt;
verdict is speed alone. Recording &lt;em&gt;why&lt;/em&gt; a model is absent beats leaving a hole.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 1 - what the models did
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Result 1: size buys nothing - but it is a plateau with cliffs, not a flat line
&lt;/h2&gt;

&lt;p&gt;The single most repeated claim in local-model threads is some version of "just run the biggest&lt;br&gt;
model that fits". Here is what the gemma-4 family does, one architecture, one vendor, four sizes:&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;params&lt;/th&gt;
&lt;th&gt;quant&lt;/th&gt;
&lt;th&gt;GiB&lt;/th&gt;
&lt;th&gt;median&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gemma-4-e2b&lt;/td&gt;
&lt;td&gt;4.6B&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;3.19&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;31&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gemma-4-e4b&lt;/td&gt;
&lt;td&gt;7.5B&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;4.97&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;42&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gemma-4-12b&lt;/td&gt;
&lt;td&gt;12B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Q8_0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;11.80&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;42.5&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gemma-4-26b-a4b-qat&lt;/td&gt;
&lt;td&gt;26B-A4B&lt;/td&gt;
&lt;td&gt;Q4_0&lt;/td&gt;
&lt;td&gt;13.45&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4.6B → 7.5B    +11.0
7.5B →  12B     +0.5      ← the plateau
 12B →  26B    +12.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Scaling 7.5B → 12B buys half a point.&lt;/strong&gt; That is the flat stretch, and it is flat &lt;em&gt;despite the&lt;br&gt;
12B carrying the better quantisation&lt;/em&gt; - Q8_0 against the 7.5B's Q4_K_M, which is the conservative&lt;br&gt;
direction. Give the small model the same precision and the gap would likely go the other way.&lt;/p&gt;

&lt;p&gt;But it is bounded on both sides by real cliffs. Below it, dropping to 4.6B costs &lt;strong&gt;11 points&lt;/strong&gt;.&lt;br&gt;
Above it, the 26B MoE gains &lt;strong&gt;12.5&lt;/strong&gt;. "Size buys nothing" is true in a band, and the band is&lt;br&gt;
narrower than the slogan.&lt;/p&gt;

&lt;p&gt;Which is where the title comes from. &lt;code&gt;gemma-4-e4b&lt;/code&gt; clears &lt;code&gt;devstral-small-2-24b&lt;/code&gt; on &lt;strong&gt;under a&lt;br&gt;
third of its parameters and 42% of its file size&lt;/strong&gt; - and it does it across the whole family&lt;br&gt;
boundary, not just against one unlucky model: it also beats &lt;code&gt;gpt-oss-20b&lt;/code&gt; (38), &lt;code&gt;north-mini-code&lt;/code&gt;&lt;br&gt;
(42, n=1), and both 12B gemmas, one of which has twice its precision. Three runs each for the&lt;br&gt;
replicated rows, non-overlapping ranges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And active parameters do not explain it either.&lt;/strong&gt; &lt;code&gt;gemma-4-26b-a4b&lt;/code&gt; activates about 4B&lt;br&gt;
parameters per token - roughly what the 4.6B &lt;code&gt;e2b&lt;/code&gt; activates - and scores &lt;strong&gt;55 against 31&lt;/strong&gt;. Same&lt;br&gt;
active compute, 24 points apart. Whatever is doing the work here, it is neither total size nor&lt;br&gt;
active size on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 2: public leaderboards do not rank this corpus
&lt;/h2&gt;

&lt;p&gt;None of Result 1 is visible from a leaderboard, and that is not an accident - the ranking they&lt;br&gt;
produce is different from mine at the top of the table too.&lt;/p&gt;

&lt;p&gt;A vendor comparison table puts &lt;strong&gt;Gemma-4-31B roughly 21 points below Qwen3.6-35B&lt;/strong&gt; on SWE-bench&lt;br&gt;
Verified. On this corpus the gemma MoE beats the qwen champion &lt;strong&gt;55 to 50&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LiveCodeBench v6 anti-correlates outright&lt;/strong&gt;: gemma scores 77.1 there and 55/56 here; qwen scores&lt;br&gt;
80.4 there and 50/56 here. Higher on the board, lower on my tasks - in both directions, on the two&lt;br&gt;
models I care most about. And LiveCodeBench's own table for these models is &lt;strong&gt;0-verified and&lt;br&gt;
53-self-reported&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is worse than "different benchmarks measure different things", because several of the obvious&lt;br&gt;
alternatives are simply not usable any more: &lt;strong&gt;BigCodeBench has been frozen since 2025-04-14&lt;/strong&gt;&lt;br&gt;
(202 rows, zero 2026 models) and &lt;strong&gt;Aider's polyglot benchmark went dead 2025-10-04&lt;/strong&gt;. Meanwhile&lt;br&gt;
published work shows that &lt;strong&gt;scaffold choice alone swings the same weights about 2×&lt;/strong&gt; on&lt;br&gt;
Terminal-Bench - 24.6% on the official board against 51.5% vendor-claimed for the same model.&lt;/p&gt;

&lt;p&gt;That last number is the actual mechanism, and it is why I do not think my ranking is "righter"&lt;br&gt;
than LiveCodeBench's. A leaderboard measures a model answering in a box. What you experience is a&lt;br&gt;
model driving &lt;em&gt;your&lt;/em&gt; agent, with your tool schema, your context window, your file-edit format. The&lt;br&gt;
scaffold is not a detail wrapped around the model; on Terminal-Bench's own numbers it is worth as&lt;br&gt;
much as the model choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use leaderboards to decide what to download. Never use them to predict what will happen inside&lt;br&gt;
your own harness.&lt;/strong&gt; The ranking above took 34 full runs to discover and could not have been&lt;br&gt;
guessed from any public table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 3: quantisation bits bought nothing, in the band people argue about
&lt;/h2&gt;

&lt;p&gt;Four quantisations of one MoE family, same KV cache and context:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;variant&lt;/th&gt;
&lt;th&gt;bpw&lt;/th&gt;
&lt;th&gt;GiB&lt;/th&gt;
&lt;th&gt;score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MTP-GPU-2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.06&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;12.67&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;50&lt;/strong&gt; (median of 6)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MTP-GPU-3&lt;/td&gt;
&lt;td&gt;3.53&lt;/td&gt;
&lt;td&gt;14.59&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MTP-GPU-4&lt;/td&gt;
&lt;td&gt;3.97&lt;/td&gt;
&lt;td&gt;16.43&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UD-IQ4_XS&lt;/td&gt;
&lt;td&gt;4.25&lt;/td&gt;
&lt;td&gt;16.51&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Flat across the entire 3.06 → 4.25 bpw range&lt;/strong&gt;, while file size varies by nearly 4 GiB and&lt;br&gt;
end-to-end speed varies about 3×. The &lt;em&gt;lowest&lt;/em&gt; bpw of the four is the best deal on this hardware,&lt;br&gt;
and it is not close - it is the only one that stays fully VRAM-resident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caveat, stated plainly:&lt;/strong&gt; this is one MoE family on one 16 GB card, and three of those four rows&lt;br&gt;
are single runs. It is not "quantisation never matters", and I would not assume it transfers to&lt;br&gt;
dense models, which are materially more quant-sensitive. The claim is narrower and better&lt;br&gt;
supported: &lt;em&gt;within the band people actually argue about, on a card this size, for this family, the&lt;br&gt;
extra bits bought no measurable code quality and cost real speed.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The QAT claim I am not making
&lt;/h3&gt;

&lt;p&gt;Quantisation-aware training looks free, and I have two pairs that appear to show it:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;pair&lt;/th&gt;
&lt;th&gt;higher precision&lt;/th&gt;
&lt;th&gt;QAT&lt;/th&gt;
&lt;th&gt;gap&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gemma-4-26b-a4b&lt;/td&gt;
&lt;td&gt;UD-Q4_K_M 15.78 GiB → &lt;strong&gt;54&lt;/strong&gt; (n=1)&lt;/td&gt;
&lt;td&gt;Q4_0 13.45 GiB → &lt;strong&gt;55&lt;/strong&gt; (n=3)&lt;/td&gt;
&lt;td&gt;Q4_K_M vs Q4_0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gemma-4-12b&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Q8_0&lt;/strong&gt; 11.80 GiB → &lt;strong&gt;42.5&lt;/strong&gt; (n=2)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Q4_0&lt;/strong&gt; 6.50 GiB → &lt;strong&gt;41&lt;/strong&gt; (n=1)&lt;/td&gt;
&lt;td&gt;★Q8_0 vs Q4_0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;These are not the same experiment, and collapsing them into one "QAT is free" line is wrong in&lt;br&gt;
both directions.&lt;/strong&gt; At 26B it compares Q4_K_M against Q4_0 - both 4-bit-class, a near-like-for-like&lt;br&gt;
swap, so "QAT matches it" is a modest claim. At 12B it compares &lt;strong&gt;Q8_0 against Q4_0&lt;/strong&gt;, a 45%&lt;br&gt;
smaller file at half the precision, which would be a genuinely strong result.&lt;/p&gt;

&lt;p&gt;Except the 12B QAT arm is &lt;strong&gt;one run&lt;/strong&gt;, against a non-QAT arm whose own two runs span 42–43. One&lt;br&gt;
point of difference, inside both models' measured spread. &lt;strong&gt;So I am not claiming it.&lt;/strong&gt; The&lt;br&gt;
experiment that would settle it is two more runs of &lt;code&gt;gemma-4-12b-qat&lt;/code&gt;, and until those exist the&lt;br&gt;
honest statement is: &lt;em&gt;QAT at 26B costs nothing measurable; QAT at 12B is untested.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I am flagging this at length because it is the shape of claim that gets repeated forever after one&lt;br&gt;
run, and I nearly published it.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 2 - what the benchmark did
&lt;/h1&gt;

&lt;p&gt;This is the half I did not expect to be interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 4: the error bar is a property of the model, not of the benchmark
&lt;/h2&gt;

&lt;p&gt;For a long time I carried a single global noise figure - "±3" - and applied it to every&lt;br&gt;
comparison. &lt;strong&gt;That was always wrong&lt;/strong&gt;, and it took replicating several models to see it.&lt;/p&gt;

&lt;p&gt;Consecutive runs, identical config, identical engine, same box, nothing changed between them:&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;runs&lt;/th&gt;
&lt;th&gt;median&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;range&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gemma-4-e2b&lt;/td&gt;
&lt;td&gt;31, 31, 31&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gemma-4-e4b&lt;/td&gt;
&lt;td&gt;43, 42, 42&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;devstral-small-2-24b&lt;/td&gt;
&lt;td&gt;40, 39, 40&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gemma-4-26b-a4b-qat&lt;/td&gt;
&lt;td&gt;55, 54, 55&lt;/td&gt;
&lt;td&gt;55&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.5-4b&lt;/td&gt;
&lt;td&gt;31, 33, 33&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;champion 3.06bpw&lt;/td&gt;
&lt;td&gt;49, 50, 50, 50, 48, 52&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;openai/gpt-oss-20b&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;40, 38, 32&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;38&lt;/td&gt;
&lt;td&gt;★&lt;strong&gt;8&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;gpt-oss-20b swings 8 points across three identical runs.&lt;/strong&gt; Its published single-run number -&lt;br&gt;
the 40 that would have gone in the table if I had run it once, as one normally does - is the&lt;br&gt;
&lt;strong&gt;top&lt;/strong&gt; of its range, not its centre. Single-run reporting flattered it by two points and nothing&lt;br&gt;
in that run signalled it.&lt;/p&gt;

&lt;p&gt;Meanwhile &lt;code&gt;gemma-4-e2b&lt;/code&gt; ran three times and produced not just the same score but the &lt;strong&gt;identical&lt;br&gt;
failure list&lt;/strong&gt; - the same 25 tasks, the same error text. The only diffs between run 2 and run 3&lt;br&gt;
were harness artifacts: cargo's parallel test ordering, an OS thread id, ±1 s timings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Weakness does not cause the variance. The failure &lt;em&gt;mode&lt;/em&gt; does.
&lt;/h3&gt;

&lt;p&gt;The obvious explanation for gpt-oss's swing is "it is borderline on lots of tasks, so it coin-flips&lt;br&gt;
them". &lt;strong&gt;That explanation is dead&lt;/strong&gt;, and &lt;code&gt;e2b&lt;/code&gt; is what killed it: e2b &lt;strong&gt;fails more tasks than&lt;br&gt;
gpt-oss&lt;/strong&gt; - 25 against 16–24 - with &lt;strong&gt;range 0&lt;/strong&gt;. Being bad is stable. Being erratic is something&lt;br&gt;
else.&lt;/p&gt;

&lt;p&gt;What separates them is &lt;em&gt;how&lt;/em&gt; they fail. gpt-oss loses tasks to &lt;strong&gt;agent mechanics&lt;/strong&gt;: a bare&lt;br&gt;
top-level &lt;code&gt;return&lt;/code&gt; producing &lt;code&gt;ERR_INVALID_TYPESCRIPT_SYNTAX&lt;/code&gt;, &lt;code&gt;SyntaxError: Unexpected end of&lt;br&gt;
input&lt;/code&gt;, literal &lt;code&gt;\n&lt;/code&gt; escape sequences written into a &lt;code&gt;.mjs&lt;/code&gt; instead of real newlines. Its worst&lt;br&gt;
run lost five tasks to &lt;em&gt;syntax&lt;/em&gt;, not reasoning. Whether a generation comes out as a parseable&lt;br&gt;
file is close to a coin flip. Missing an edge case, by contrast, is a stable property of what the&lt;br&gt;
model knows.&lt;/p&gt;

&lt;p&gt;⇒ &lt;strong&gt;A model's error bar is predicted by its failure mode.&lt;/strong&gt; This was a hypothesis after the first&lt;br&gt;
replication night and it then &lt;strong&gt;held as a prediction&lt;/strong&gt; on e2b, at the opposite end of the quality&lt;br&gt;
range.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The practical consequence: you cannot import someone else's error bar, and you cannot import&lt;br&gt;
mine.&lt;/strong&gt; If you are comparing two local models and the gap is under 3 points, you do not have a&lt;br&gt;
result until you know each model's own spread. That is 2–3 extra runs per arm, and for some models&lt;br&gt;
it is the difference between a finding and a coin flip.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 5: "deterministic" turned out to mean "deterministic within one session"
&lt;/h2&gt;

&lt;p&gt;This one is new, it is a benchmark-design finding, and I have not seen any local-model leaderboard&lt;br&gt;
report it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;qwen3.5-4b&lt;/code&gt; ran three times at temperature 0: &lt;strong&gt;31, 33, 33&lt;/strong&gt;. Ordinary-looking noise. Then I&lt;br&gt;
looked at &lt;em&gt;which&lt;/em&gt; tasks failed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;r2 and r3 have byte-identical failure lists&lt;/strong&gt; - 23 tasks, same ones. Perfectly reproducible.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;r1 differs from both on ten tasks.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;r1 was run on a &lt;strong&gt;different day&lt;/strong&gt;. r2 and r3 were run consecutively in one session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the confirmation: a fourth run had been started on r1's day and killed partway through. Over&lt;br&gt;
the 33 tasks it graded, &lt;strong&gt;it matches r1 exactly&lt;/strong&gt;. So day one has two agreeing runs, day two has&lt;br&gt;
two agreeing runs, and &lt;strong&gt;the two sessions disagree with each other.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;⇒ ★ &lt;strong&gt;Every determinism claim in this campaign is scoped to a single session.&lt;/strong&gt; &lt;code&gt;e2b&lt;/code&gt;'s "31/56&lt;br&gt;
three times, range 0, identical failure list" and &lt;code&gt;e4b&lt;/code&gt;'s byte-identical replicates were &lt;strong&gt;all&lt;br&gt;
gathered with the replicates consecutive inside one session&lt;/strong&gt;. That design &lt;em&gt;cannot distinguish&lt;/em&gt;&lt;br&gt;
"deterministic" from "deterministic within a session". This is the first cross-day replicate I&lt;br&gt;
ever ran, and it moved.&lt;/p&gt;

&lt;p&gt;I do not know the mechanism yet. Candidates: the model server was restarted between sessions and&lt;br&gt;
something non-obvious differs in its state; a driver or engine load-order effect; machine load&lt;br&gt;
(see the next result, which accounts for 3 of the 10 flips but not the other 7). What I can say is&lt;br&gt;
that &lt;strong&gt;running your replicates back-to-back will understate your error bar&lt;/strong&gt;, and that is exactly&lt;br&gt;
how everybody runs replicates, including me.&lt;/p&gt;

&lt;p&gt;If you take one methodological thing from this piece, take this: &lt;strong&gt;space your replicates across&lt;br&gt;
sessions, or state that you did not.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 6: the aggregate is stable-ish; the failure list is not
&lt;/h2&gt;

&lt;p&gt;The champion configuration, six runs at matched constants: &lt;strong&gt;49, 50, 50, 50, 48, 52.&lt;/strong&gt; Median 50,&lt;br&gt;
range 4.&lt;/p&gt;

&lt;p&gt;Now look at &lt;em&gt;which&lt;/em&gt; tasks failed:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;run&lt;/th&gt;
&lt;th&gt;failures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Q03 Q05 Q25 Q45 Q50 Q51 Q52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Q03 Q05 Q13 Q25 Q51 Q52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Q03 Q05 Q13 Q25 Q51 Q52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Q03 Q05 Q13 Q26 Q36 Q51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Q01 Q03 Q05 Q13 Q25 Q46 Q49 Q51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Q03 Q25 Q46 Q52&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Thirteen distinct tasks rotate through the failure slots. Exactly one - Q03 - failed all six&lt;br&gt;
times.&lt;/strong&gt; Frequencies: Q03 6/6, Q51 5/6, Q25 5/6, Q05 5/6, Q52 4/6, Q13 4/6, Q46 2/6, and six&lt;br&gt;
tasks that failed exactly once. This is a model sitting at a stable competence level with a pool&lt;br&gt;
of borderline tasks resolving stochastically. It is &lt;em&gt;not&lt;/em&gt; a fixed list of things it cannot do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So almost every "this local model can't handle X" claim you read is derived from a single run,&lt;br&gt;
and on this evidence that claim is unfounded roughly 12 times out of 13.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I know because I made exactly that mistake. Three runs in, I had confidently written down a&lt;br&gt;
"consistent failure set" of five tasks. The next run passed two of them and produced two&lt;br&gt;
first-time failures I had never seen. My five-task set was a three-sample artifact.&lt;/p&gt;

&lt;p&gt;It cost me two wasted evaluations. I built a cheap screening gate on those five tasks; it&lt;br&gt;
green-lit two candidate configurations, both of which then tied the champion exactly on the full&lt;br&gt;
battery. &lt;strong&gt;The gate was measuring rotation, not quality.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Worse, when I rebuilt the screen properly - 12 tasks, scored in aggregate, with a rejection&lt;br&gt;
threshold &lt;em&gt;derived&lt;/em&gt; from a bound rather than picked - it still failed. The bound assumed a&lt;br&gt;
challenger would pass everything outside the screen. &lt;strong&gt;Three different models broke it&lt;/strong&gt;, one by&lt;br&gt;
eight tasks. A subset screen now gets used only to reject fast, never to promote, bound, or crown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you benchmark local models: score in aggregate, over more than one run, and never conclude&lt;br&gt;
anything from the identity of a failing task.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 3 - what the box did
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Result 7: KV cache quantisation and context size moved wall-clock 2.8×, and the score not at all
&lt;/h2&gt;

&lt;p&gt;A popular claim is that q8 KV cache costs quality against fp16. I tested it twice:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;config&lt;/th&gt;
&lt;th&gt;ctx&lt;/th&gt;
&lt;th&gt;score&lt;/th&gt;
&lt;th&gt;wall-clock&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;KV q8_0&lt;/td&gt;
&lt;td&gt;32768&lt;/td&gt;
&lt;td&gt;50/56&lt;/td&gt;
&lt;td&gt;23.2 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV f16&lt;/td&gt;
&lt;td&gt;32768&lt;/td&gt;
&lt;td&gt;50/56&lt;/td&gt;
&lt;td&gt;26.2 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV f16&lt;/td&gt;
&lt;td&gt;65536&lt;/td&gt;
&lt;td&gt;50/56&lt;/td&gt;
&lt;td&gt;58.8 min&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;+0 quality at either context size, and fp16 was slower in both&lt;/strong&gt; - 1.13× at matched context,&lt;br&gt;
&lt;strong&gt;2.79×&lt;/strong&gt; once context went to 65536 and VRAM hit 96.7%.&lt;/p&gt;

&lt;p&gt;Note carefully what that 2.8× actually was. It was &lt;strong&gt;not&lt;/strong&gt; KV precision - it was context size&lt;br&gt;
pushing VRAM to the edge. I only know because the second fp16 run changed &lt;em&gt;one&lt;/em&gt; variable; the&lt;br&gt;
first had moved two at once and would have supported the wrong conclusion, confidently.&lt;/p&gt;

&lt;p&gt;The embarrassing part: I had been daily-driving that slow corner for two days, on the strength of&lt;br&gt;
a promising subset-screen result that turned out to be the rotation from Result 6.&lt;/p&gt;

&lt;p&gt;There is a matching cliff on the other side. Splitting MoE experts between GPU and CPU has a&lt;br&gt;
&lt;strong&gt;usable band of about 15.1–15.6 GB on a 16.3 GB card&lt;/strong&gt;, and both errors are expensive. Too many&lt;br&gt;
experts on CPU strands the card: one model at a bad split ran 113 s/task and at a good one 75&lt;br&gt;
s/task - &lt;strong&gt;35 minutes saved on a single row, with no score change&lt;/strong&gt;. Too few thrashes into Windows&lt;br&gt;
shared memory: at 97.7% VRAM one task took &lt;strong&gt;306 seconds&lt;/strong&gt;, and after re-splitting, &lt;strong&gt;37 seconds.&lt;br&gt;
8.3×.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 8: generation-speed probes do not predict end-to-end speed
&lt;/h2&gt;

&lt;p&gt;I have a standard probe: three prompts, streaming, temperature 0, median tok/s, against a 15 tok/s&lt;br&gt;
floor.&lt;/p&gt;

&lt;p&gt;It was wrong twice, in opposite directions. One configuration probed &lt;strong&gt;faster&lt;/strong&gt; than the champion&lt;br&gt;
(73 vs 70 tok/s) and then ran &lt;strong&gt;2.48× slower&lt;/strong&gt; on same-verdict tasks. Another probed 1.74× faster&lt;br&gt;
after a tuning change and delivered &lt;strong&gt;2.2×&lt;/strong&gt; end-to-end.&lt;/p&gt;

&lt;p&gt;The reason is structural: an agent battery is dominated by &lt;strong&gt;prompt processing over a growing KV&lt;br&gt;
cache&lt;/strong&gt;, not by token generation on short prompts. The probe measures the thing that is not the&lt;br&gt;
bottleneck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use generation-speed probes as a floor for rejecting hopeless candidates. Never cite one as&lt;br&gt;
evidence a configuration is fast.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 9: my wall-clock-graded tasks were measuring the box, not the model
&lt;/h2&gt;

&lt;p&gt;Four of the 56 tasks grade performance by wall-clock - naive vs linear-time, sized for a wide&lt;br&gt;
separation. Comparing &lt;code&gt;qwen3.5-4b&lt;/code&gt;'s cross-day replicates exposed what that really measures:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;task&lt;/th&gt;
&lt;th&gt;day 1&lt;/th&gt;
&lt;th&gt;day 2&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;Q12 (perf, rust)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;90 s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;24 s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;FAIL → PASS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Q32 (perf, js)&lt;/td&gt;
&lt;td&gt;51 s&lt;/td&gt;
&lt;td&gt;29 s&lt;/td&gt;
&lt;td&gt;FAIL → PASS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Q41 (perf, ts)&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;flipped the other way&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Identical weights, identical config, &lt;strong&gt;3.75× on the same task&lt;/strong&gt;. Day 1's whole pass ran 27% slower&lt;br&gt;
because I was actively using the machine. &lt;strong&gt;Those verdicts measured my box.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a real defect in my corpus and I would rather report it than quietly widen the thresholds.&lt;br&gt;
Anyone grading agent performance by wall-clock inherits it. The fixes available are: run perf tasks&lt;br&gt;
only on a verified-idle box, record a load probe per run and reject contaminated runs, or grade&lt;br&gt;
complexity structurally instead of by clock. I have not picked one yet.&lt;/p&gt;

&lt;p&gt;⚠️ It does &lt;strong&gt;not&lt;/strong&gt; explain the session split in Result 5: &lt;strong&gt;7 of the 10 flipped tasks are not perf&lt;br&gt;
tasks.&lt;/strong&gt; Machine load is one contaminant, not the mechanism.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 10: the failure mode a score table hides
&lt;/h2&gt;

&lt;p&gt;Several models lost tasks not to bad reasoning but to &lt;strong&gt;not being able to emit a valid file&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gpt-oss-20b&lt;/code&gt; lost &lt;strong&gt;3 of 16 failures&lt;/strong&gt; this way in its first run, and &lt;strong&gt;five in its worst&lt;/strong&gt; -
two TypeScript tasks dying on a bare top-level &lt;code&gt;return&lt;/code&gt;, one writing literal &lt;code&gt;\n&lt;/code&gt; escape
sequences into a &lt;code&gt;.mjs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;north-mini-code-1.0&lt;/code&gt; lost 2 the same way - an unterminated triple-quoted string, and a Rust
&lt;code&gt;E0425&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;granite-4.1-8b&lt;/code&gt; likewise.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;devstral&lt;/code&gt; reached for a &lt;strong&gt;crate that was not vendored&lt;/strong&gt;, in an offline sandbox.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are edit-mechanics and environment-awareness failures, not intelligence failures, and they&lt;br&gt;
are invisible in a bare pass rate. They are also the most actionable thing here for anyone building&lt;br&gt;
an agent: &lt;strong&gt;the model that reasons well but cannot reliably write a file is worse in practice than&lt;br&gt;
its benchmark score suggests&lt;/strong&gt; - and, per Result 4, it is also the model whose score you can trust&lt;br&gt;
least.&lt;/p&gt;

&lt;p&gt;It is the strongest argument I have that &lt;strong&gt;agent benchmarks should grade mechanics separately from&lt;br&gt;
reasoning.&lt;/strong&gt; Mine currently does not, and that is a gap.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 4 - the method lesson that cost the most
&lt;/h1&gt;

&lt;p&gt;The spec for this benchmark had always listed "held constant for every row: ctx 32768, KV q8_0,&lt;br&gt;
parallel 1". Nothing ever &lt;strong&gt;recorded&lt;/strong&gt; or &lt;strong&gt;verified&lt;/strong&gt; it.&lt;/p&gt;

&lt;p&gt;The KV cache setting in LM Studio is sticky, global, per-model, survives unloads, is not a load&lt;br&gt;
flag, and is not reported by &lt;code&gt;lms ps --json&lt;/code&gt;. It silently flipped to fp16 on my box and stayed&lt;br&gt;
there for two days. Rows from before and after were compared as though they were comparable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A held-constant nobody measures is not held.&lt;/strong&gt; Every run now emits its actual ctx, KV type,&lt;br&gt;
parallelism, VRAM, GPU/CPU expert split, model path, agent version &lt;em&gt;and binary mtime&lt;/em&gt; into a&lt;br&gt;
metadata file, and historical rows are explicitly marked &lt;code&gt;inferred&lt;/code&gt; rather than &lt;code&gt;measured&lt;/code&gt; so a&lt;br&gt;
reconstruction can never be cited as evidence.&lt;/p&gt;

&lt;p&gt;Enforcement caught more than it had any right to. A pre-load config writer found:&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;field&lt;/th&gt;
&lt;th&gt;found&lt;/th&gt;
&lt;th&gt;should be&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gpt-oss-20b&lt;/td&gt;
&lt;td&gt;&lt;code&gt;numParallelSessions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3-coder-30b&lt;/td&gt;
&lt;td&gt;ctx&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8096&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;32768&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nemotron-3-nano-omni&lt;/td&gt;
&lt;td&gt;ctx&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;24000&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;32768&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.5-4b&lt;/td&gt;
&lt;td&gt;ctx&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;32800&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;32768&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.5-4b&lt;/td&gt;
&lt;td&gt;KV cache&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;unset → f16&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;q8_0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;numParallelSessions: 4&lt;/code&gt; one is my favourite, because it splits the KV allocation across four&lt;br&gt;
slots behind an &lt;code&gt;lms ps&lt;/code&gt; that proudly reports &lt;code&gt;CONTEXT 32768&lt;/code&gt;. Two older numbers I had been citing&lt;br&gt;
as priors turned out never to have been measured at the benchmark's own constants.&lt;/p&gt;

&lt;p&gt;Three ops traps each came within minutes of publishing a fake row:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;lms load&lt;/code&gt; never creates the per-model config file.&lt;/strong&gt; A never-configured model does not have
one, so the pre-seeder has nothing to correct, and parallelism silently defaults to 4. Only
opening the model in the GUI once creates it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;lms load&lt;/code&gt; fuzzy-matches when no key matches exactly.&lt;/strong&gt; The bare id I had written in every
note for months - &lt;code&gt;qwen3.6-35b-a3b-mtp&lt;/code&gt; - &lt;strong&gt;silently loaded a different model&lt;/strong&gt;, because an
earlier fix had given a sibling quantisation its own repo directory and the resulting key
&lt;em&gt;extended the champion's prefix&lt;/em&gt;. There is no bare key; the real one ends &lt;code&gt;@iq3_s&lt;/code&gt;. Caught about
40 seconds into a run that would otherwise have looked completely normal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The GUI holds a stale copy of the config and can write it back.&lt;/strong&gt; After correcting a config on
disk, the CLI and the JSON both read the new value while the GUI still displayed the old one -
and saving from the GUI would have pushed the stale value back over the fix.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The general lesson, and the reason this section exists at all:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A benchmark's integrity failures do not look like errors. They look like successful runs.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The engine control - asked, and answered
&lt;/h2&gt;

&lt;p&gt;Between the early rows and the late ones, LM Studio auto-updated its inference engine from 2.25.2&lt;br&gt;
to 2.27.1 at 01:21, with auto-update on by default. So I owed a control: re-run the champion,&lt;br&gt;
unchanged, on the new engine.&lt;/p&gt;

&lt;p&gt;The first control scored &lt;strong&gt;48/56&lt;/strong&gt; against a baseline whose runs had never gone below 49, with two&lt;br&gt;
never-before-failed tasks and 1.33× slower wall-clock. Two signals pointing the same way. It would&lt;br&gt;
have been very easy to write "the engine update cost 2 points".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The second control scored 52/56 - the highest the champion has ever scored - in 21m23s, its&lt;br&gt;
normal speed.&lt;/strong&gt; Neither the deficit nor the slowdown reproduced. Across all six matched runs the&lt;br&gt;
median is still exactly 50. &lt;strong&gt;No engine effect is established, and nothing gets re-based.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I am reporting the sequence rather than just the conclusion, because the one-run version of this&lt;br&gt;
was a publishable-looking finding that was simply wrong, and it is the same lesson as Result 6&lt;br&gt;
arriving from a different direction. Your inference engine is still a variable: pin it, record it,&lt;br&gt;
and expect it to update itself while you sleep - mine did, and its auto-&lt;em&gt;delete&lt;/em&gt; setting can&lt;br&gt;
garbage-collect the old engine you would need to reproduce anything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Honest limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One box, one card.&lt;/strong&gt; RTX 5060 Ti 16 GB. VRAM-resident vs spilled is the dominant speed variable
here and yours will differ.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;56 tasks is small&lt;/strong&gt;, and seven of the sixteen configurations are single runs. Those rows carry
an error bar I can now size but did not measure for them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replicates are mostly within-session&lt;/strong&gt; - see Result 5. The one cross-session replicate I have
moved by two points and by ten task-verdicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is a short-horizon instrument.&lt;/strong&gt; Iteration depth per task: p50 = 4, p90 = 8, max 15; only
5 of 56 tasks reach 9 or more. It grades first-shot code quality. It &lt;strong&gt;cannot see&lt;/strong&gt; context
compaction, prefix-cache behaviour, model escalation, or permission handling - the harness runs
with auto-approve, so those paths are never exercised. Anyone "proving" a compaction fix on this
benchmark is measuring net zero and concluding wrongly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The top of the range is saturating.&lt;/strong&gt; The crown sits at 55/56; against the two strongest gemma
configs the corpus is nearly out of headroom. Difficulty and discrimination turned out to be
nearly orthogonal - the hard tail I added moved the champion by one point, while its single most
reliable failure is a three-character guard on an empty range.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;But it is not saturated in general.&lt;/strong&gt; Across all 34 ranking runs there are &lt;strong&gt;454 task-failures&lt;/strong&gt;,
&lt;strong&gt;51 of 56 tasks defeat somebody&lt;/strong&gt;, and only five are never failed by anyone (Q21, Q31, Q33, Q39,
Q55). Adding the two weakest models to the sweep dropped that from seven to five.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model licences vary&lt;/strong&gt; and I have not audited every one for score-publication terms.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The corpus is fully open - with a contamination date
&lt;/h2&gt;

&lt;p&gt;The corpus works because the hidden tests and reference solutions are hidden. Publishing them&lt;br&gt;
destroys the instrument for every model trained afterwards. Publishing nothing makes every number&lt;br&gt;
above an unverifiable claim.&lt;/p&gt;

&lt;p&gt;I had planned a split - ship 15 tasks complete, seal 41. &lt;strong&gt;That plan is moot: the full corpus has&lt;br&gt;
been publicly cloneable since 2026-07-25&lt;/strong&gt;, on a branch of a public repository, hidden tests and&lt;br&gt;
reference solutions included. I found this while preparing to publish. Rather than force-push over&lt;br&gt;
it and pretend otherwise, the honest move is to state it precisely:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Contamination date: 2026-07-25.&lt;/strong&gt; Every model in the table above was released before that date&lt;br&gt;
and therefore could not have trained on this corpus. All 36 runs stand. Any model released after&lt;br&gt;
it must be treated as potentially contaminated on these 56 tasks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So: &lt;strong&gt;everything ships&lt;/strong&gt; - all 56 fixtures, all hidden verifiers, all reference solutions, the&lt;br&gt;
harness, the per-run metadata, and &lt;code&gt;RESULTS-q56.csv&lt;/code&gt; with every run's full failure list. Clone it&lt;br&gt;
and check any number in this piece.&lt;/p&gt;

&lt;p&gt;That makes Q56 a one-shot instrument against future models, which is a real cost and I am not going&lt;br&gt;
to dress it up. The successor corpus is being built sealed, and the design lesson is one I would&lt;br&gt;
pass on to anyone building a benchmark they intend to keep: &lt;strong&gt;decide your publication posture before&lt;br&gt;
the first push, not after 36 runs.&lt;/strong&gt; A public repo is public in every branch.&lt;/p&gt;

&lt;p&gt;What survives publication completely is the part I actually care about: &lt;strong&gt;the methodology and the&lt;br&gt;
measurement results.&lt;/strong&gt; That leaderboards anti-correlate, that error bars are model properties, that&lt;br&gt;
determinism is within-session, that speed probes mispredict, that a held-constant nobody measures is&lt;br&gt;
not held - none of that depends on the tasks staying secret.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would want from readers
&lt;/h2&gt;

&lt;p&gt;The harness runs from any clone and takes a model id, so "bench your own model" is a real ask&lt;br&gt;
rather than an aspiration. The three most useful contributions, in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A cross-session replicate.&lt;/strong&gt; Run any model three times in one sitting, then a fourth a day
later. Result 5 rests on a single model and would be either confirmed or killed by one more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A second high-variance model.&lt;/strong&gt; gpt-oss-20b is the only model I have measured with a large
range. If the failure-mode theory in Result 4 is right, any model that loses tasks to unparseable
output should swing similarly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KV q8 vs fp16 on a card where the model is &lt;em&gt;not&lt;/em&gt; VRAM-resident&lt;/strong&gt; - Result 7 may well be a
resident-model artifact.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;The corpus, the harness, all 36 runs and every run's failure list are at &lt;a href="https://github.com/mrdushidush/claudette/tree/battery/q50-quality-corpus/runs/eval-2026-05-29/battery" rel="noopener noreferrer"&gt;github.com/mrdushidush/claudette&lt;/a&gt; - MIT OR Apache-2.0.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>showdev</category>
      <category>rust</category>
    </item>
    <item>
      <title>How I Run 88% of AI Coding Tasks for Free on a $300 GPU (and Built a C&amp;C Red Alert UI for It)</title>
      <dc:creator>david</dc:creator>
      <pubDate>Thu, 12 Feb 2026 20:04:33 +0000</pubDate>
      <link>https://dev.to/mrdushidush/how-i-run-88-of-ai-coding-tasks-for-free-on-a-300-gpu-and-built-a-cc-red-alert-ui-for-it-3o7j</link>
      <guid>https://dev.to/mrdushidush/how-i-run-88-of-ai-coding-tasks-for-free-on-a-300-gpu-and-built-a-cc-red-alert-ui-for-it-3o7j</guid>
      <description>&lt;p&gt;`# I Route 88% of AI Coding Tasks to a Free Local Model — Here's What I Learned&lt;/p&gt;

&lt;p&gt;Running AI coding agents through cloud APIs gets expensive fast. Claude Sonnet at ~$0.04/task, Opus at ~$0.075 — it adds up when you're running hundreds of tasks.&lt;/p&gt;

&lt;p&gt;So I built a system that routes 88% of tasks to a free local model and only escalates to paid APIs when necessary. Then I wrapped it in a Command &amp;amp; Conquer Red Alert-style interface because… I grew up in the 90s.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc111cduc901t7velczxa.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc111cduc901t7velczxa.gif" alt="Command Center Demo" width="480" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cost Problem
&lt;/h2&gt;

&lt;p&gt;Most AI coding agent frameworks send everything to the best model available. But "create a function that adds two numbers" doesn't need the same model as "implement an LRU cache with O(1) operations."&lt;/p&gt;

&lt;p&gt;I tested this systematically — 40 coding tasks scored on a complexity scale of 1–9, all executed by a local 7B parameter model running on a $300 used GPU:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Example Tasks&lt;/th&gt;
&lt;th&gt;Success Rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C1–2&lt;/td&gt;
&lt;td&gt;Add function, greet function&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C3–4&lt;/td&gt;
&lt;td&gt;Parse CSV, validate emails, factorial&lt;/td&gt;
&lt;td&gt;80–100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C5–6&lt;/td&gt;
&lt;td&gt;Calculator with history, prime checker&lt;/td&gt;
&lt;td&gt;60–100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C7–8&lt;/td&gt;
&lt;td&gt;Merge sorted lists, binary search, word frequency&lt;/td&gt;
&lt;td&gt;80–100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C9&lt;/td&gt;
&lt;td&gt;LRU cache, stack class, RPN calculator&lt;/td&gt;
&lt;td&gt;80%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Result: $0.002 average cost per task instead of $0.04 — that's 20x cheaper.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The 7B model handled everything from trivial one-liners to LeetCode-medium problems. It even added type hints unprompted on some solutions. Only multi-class architectural tasks needed escalation to cloud APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Routing Works
&lt;/h2&gt;

&lt;p&gt;The system scores every task on a 1–10 complexity scale using dual assessment:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
Task → Complexity Assessment&lt;br&gt;
  ├─ Rule-based: keyword matching, structural analysis&lt;br&gt;
  └─ Haiku AI: semantic understanding (~$0.001/call)&lt;br&gt;
      ↓&lt;br&gt;
  Smart weighting: if Haiku rates 2+ higher, trust Haiku&lt;br&gt;
      ↓&lt;br&gt;
  ├─ C1–6  → Ollama (free, local GPU)&lt;br&gt;
  ├─ C7–8  → Haiku (~$0.003/task)&lt;br&gt;
  ├─ C9–10 → Sonnet (~$0.01/task)&lt;br&gt;
  └─ Decomposition → Opus (review only, never writes code)&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The complexity scoring draws from Campbell's Task Complexity Theory in organizational psychology, adapted for code tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Component complexity&lt;/strong&gt; — How many steps, files, and functions are expected?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coordinative complexity&lt;/strong&gt; — How many dependencies exist between parts?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic complexity&lt;/strong&gt; — How much ambiguity and decision-making is required?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The smart weighting was a key breakthrough. The rule-based router uses keyword matching ("LRU", "cache", "linked list"), but sometimes misses semantic complexity. A cheap Haiku call provides that semantic understanding. When Haiku rates a task 2+ points higher than the rules, we trust Haiku's score directly instead of averaging — this prevents complex tasks from being under-routed to Ollama.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hard-Won Lessons Running Ollama in Production
&lt;/h2&gt;

&lt;p&gt;These took weeks of debugging. If you're building anything agentic with local models, this might save you some pain.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Temperature = 0 is mandatory for tool calling
&lt;/h3&gt;

&lt;p&gt;This was the single biggest improvement. Small models with temperature &amp;gt; 0 will randomly output raw code instead of calling tools through the proper function-calling interface. The model might generate a perfect Python function… and dump it into stdout instead of calling &lt;code&gt;file_write&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Temperature 0 gives deterministic, reliable tool usage. It took our success rate from ~60% to 90%+ overnight.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Context pollution is real (and sneaky)
&lt;/h3&gt;

&lt;p&gt;After ~5 consecutive tasks on the same Ollama instance, the model starts generating syntax errors — missing quotes, unclosed parentheses, garbled output. The accumulated context from previous tasks bleeds into new ones.&lt;/p&gt;

&lt;p&gt;The fix is surprisingly simple: a 3-second rest delay between tasks, plus a full memory reset every 3 tasks. This alone took us from 85% to 100% success rate on C1–C8 complexity tasks.&lt;/p&gt;

&lt;p&gt;We even built a cooldown system with WebSocket events so the UI shows when an agent is "resting" between tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. 7B &amp;gt; 14B on 8GB VRAM (counterintuitive)
&lt;/h3&gt;

&lt;p&gt;I tested &lt;code&gt;qwen2.5-coder:14b-instruct-q4_K_M&lt;/code&gt; expecting better results from the larger model. Got a &lt;strong&gt;40% pass rate&lt;/strong&gt; vs &lt;strong&gt;95% for the 7B model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why? The 14B model weighs in at ~9GB. On an 8GB VRAM card, it overflows into system RAM. CPU offloading makes inference slow enough that tool calling breaks down — the model times out or generates truncated responses.&lt;/p&gt;

&lt;p&gt;The 7B model sits at ~6GB VRAM with room for context and tools. No CPU offload needed. &lt;strong&gt;If you have 8GB VRAM, 7B is your ceiling. Don't go bigger.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Agent personas work surprisingly well
&lt;/h3&gt;

&lt;p&gt;This one surprised me the most. Giving the model a "CodeX-7" elite military identity with a specific pattern — "one write, one verify, mission complete" — plus three concrete examples of ideal 3-step execution dramatically improved task completion.&lt;/p&gt;

&lt;p&gt;Without the persona, the model would often loop: write code, read it back, rewrite it, read it again. With the persona, it follows the trained pattern: write the file, run the test, report results. Done.&lt;/p&gt;

&lt;p&gt;The technical explanation is probably that the persona plus examples act as strong few-shot conditioning, biasing the model toward a specific execution trajectory. But honestly, it also just makes the logs more fun to read.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fun Part: C&amp;amp;C Red Alert UI
&lt;/h2&gt;

&lt;p&gt;Because staring at terminal logs is boring, I built a Command &amp;amp; Conquer Red Alert-inspired interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bounty board&lt;/strong&gt; — Task cards with complexity badges and priority colors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active missions strip&lt;/strong&gt; — Real-time agent health indicators (green = idle, amber = working, red = stuck)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool log&lt;/strong&gt; — Terminal-style feed of every &lt;code&gt;file_write&lt;/code&gt;, &lt;code&gt;shell_run&lt;/code&gt;, &lt;code&gt;file_read&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent minimap&lt;/strong&gt; — Visual representation of agents with connection lines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Voice feedback&lt;/strong&gt; — "Conscript reporting!" when an agent picks up a task, "Shake it baby!" on completion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost dashboard&lt;/strong&gt; — Real-time cost tracking with daily budget limits and token burn rate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every agent action triggers a C&amp;amp;C voice line. When an agent gets stuck in a loop, a warning klaxon plays. It's ridiculous and I love it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The whole system runs in Docker:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
UI (React:5173) → API (Express:3001) → Agents (FastAPI:8000) → Ollama/Claude&lt;br&gt;
                         ↓&lt;br&gt;
                   PostgreSQL:5432&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React UI&lt;/strong&gt; — Real-time WebSocket updates, no polling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Express API&lt;/strong&gt; — Task routing, cost tracking, budget enforcement, rate limiting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI + CrewAI&lt;/strong&gt; — Agent orchestration with tool wrapping and execution logging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ollama&lt;/strong&gt; — Local LLM with GPU passthrough&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt; — Tasks, execution logs, code reviews, training data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every tool call is captured to the database with timing, token usage, and cost. The system detects stuck tasks (&amp;gt;10 min timeout) and automatically recovers them. Loop detection prevents agents from repeating failed actions.&lt;/p&gt;

&lt;p&gt;Tasks can run in parallel when they use different resources — an Ollama task and a Claude task can execute simultaneously, yielding a 40–60% speedup on mixed-complexity batches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`bash&lt;br&gt;
git clone &lt;a href="https://github.com/mrdushidush/agent-battle-command-center.git" rel="noopener noreferrer"&gt;https://github.com/mrdushidush/agent-battle-command-center.git&lt;/a&gt;&lt;br&gt;
cd agent-battle-command-center&lt;br&gt;
cp .env.example .env&lt;/p&gt;

&lt;h1&gt;
  
  
  Add your ANTHROPIC_API_KEY to .env
&lt;/h1&gt;

&lt;p&gt;docker compose up --build&lt;/p&gt;

&lt;h1&gt;
  
  
  Open &lt;a href="http://localhost:5173" rel="noopener noreferrer"&gt;http://localhost:5173&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker Desktop&lt;/li&gt;
&lt;li&gt;NVIDIA GPU with 8GB+ VRAM (recommended) — or CPU-only mode (slower)&lt;/li&gt;
&lt;li&gt;Anthropic API key (only needed for complex tasks — Ollama tasks are free)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first startup takes ~5 minutes to download the Ollama model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The project is fully open source (MIT). Some things I'm working on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-language support&lt;/strong&gt; — Currently Python-only; adding JavaScript/TypeScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demo mode&lt;/strong&gt; — Simulated agents so anyone can try the UI without a GPU&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker Hub image&lt;/strong&gt; — One-command deploy without building&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More voice packs&lt;/strong&gt; — Community suggestions include StarCraft and Age of Empires&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are 8 good-first-issues open if you want to contribute. We already merged our first community PR (keyboard shortcuts) on day 3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/mrdushidush/agent-battle-command-center" rel="noopener noreferrer"&gt;agent-battle-command-center&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come hang out in &lt;a href="https://github.com/mrdushidush/agent-battle-command-center/discussions" rel="noopener noreferrer"&gt;Discussions&lt;/a&gt; if you want to chat about AI agent orchestration, cost optimization, or which RTS game had the best unit voice lines.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;"One write, one verify, mission complete." — CodeX-7&lt;/em&gt;`&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
