<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>BytePenny blog</title>
		<link>https://bytepenny.com/blog/</link>
		<description>Articles about running AI on your own hardware: Matricxon, pAIring, RAG, MCP and more.</description>
		<language>en</language>
		<atom:link href="https://bytepenny.com/blog/rss.xml" rel="self" type="application/rss+xml" />
		<item>
			<title>What is dequantization?</title>
			<link>https://bytepenny.com/blog/what-is-dequantization/</link>
			<guid isPermaLink="true">https://bytepenny.com/blog/what-is-dequantization/</guid>
			<pubDate>Tue, 20 Oct 2026 00:00:00 GMT</pubDate>
			<author>mail@bytepenny.com (BytePenny)</author>
			<description>How quantized models store their weights, what dequantization does, why it costs speed, and how Matricxon multiplies compressed weights without unpacking the whole model.</description>
			<content:encoded><![CDATA[<p><img src="https://bytepenny.com/img/blog/what-is-dequantization.jpg" alt="Small compressed number blocks expanding into full numbers under the title What is dequantization?"></p><p>A language model is mostly numbers: billions of weights. Stored at full precision, an 8B model takes about 16 GB, more than most laptops have. Quantization shrinks those numbers so the model fits. Dequantization turns them back into usable values when the model runs, and how an engine does that decides a large part of its speed.</p>
<h2 id="quantization-fewer-bits-per-weight">Quantization: fewer bits per weight</h2>
<p>A quantized file does not store each weight as a 16-bit number. It groups weights into small blocks, often 256 at a time, and stores:</p>
<ul>
<li>one shared <strong>scale</strong> for the block (a normal number),</li>
<li>small <strong>integer codes</strong> for each weight, 2 to 8 bits each.</li>
</ul>
<p>A weight is then roughly <em>scale × code</em>. Some formats add a per-block offset, or a second, smaller scale for every 16 or 32 weights, to follow the real values more closely.</p>
<table>
<thead>
<tr>
<th>Format (GGUF)</th>
<th>Bits per weight</th>
<th>8B model size</th>
</tr>
</thead>
<tbody>
<tr>
<td>F16 (no quantization)</td>
<td>16</td>
<td>about 16 GB</td>
</tr>
<tr>
<td>Q8_0</td>
<td>8.5</td>
<td>about 8.5 GB</td>
</tr>
<tr>
<td>Q4_K_M</td>
<td>about 4.8</td>
<td>about 4.9 GB</td>
</tr>
<tr>
<td>IQ2_M</td>
<td>about 2.7</td>
<td>about 2.9 GB</td>
</tr>
</tbody>
</table>
<p>The “I-quants” (IQ1 to IQ3) go further: instead of plain integers they store an index into a fixed table of good value patterns (a <em>codebook</em>), plus sign bits. That is how they reach 2 bits per weight and still produce readable text.</p>
<h2 id="dequantization-getting-the-numbers-back">Dequantization: getting the numbers back</h2>
<p>To compute with a weight, the engine has to know its value, so it reverses the packing: read the scale, read the code, multiply. That is dequantization.</p>
<p>Why bother? Because writing each token means reading nearly all the weights once, and memory speed is the limit (see <a href="https://bytepenny.com/blog/cpu-vs-gpu/">CPU vs GPU</a>). A model that is 4 times smaller is read about 4 times faster, as long as unpacking it doesn’t eat that gain back.</p>
<p>The price is a little accuracy (Q4_K_M is close to the original, 2-bit types lose more) and the extra work of unpacking.</p>
<h2 id="two-ways-to-do-it">Two ways to do it</h2>
<p><strong>Unpack everything at load time.</strong> Turn the whole model back into 16- or 32-bit floats once, then use ordinary fast matrix maths. Simple and fast, but the model needs several times its file size in RAM. A 2.6 GB Ministral 3B file needs about 7.5 GB this way.</p>
<p><strong>Compute on the packed weights.</strong> Keep the file as it is and unpack each small block only at the moment it is multiplied. RAM use stays close to the file size, but the unpacking happens again for every token, so it has to be very cheap.</p>
<h2 id="how-matricxon-does-it">How Matricxon does it</h2>
<p><a href="https://bytepenny.com/matricxon/">Matricxon</a> uses the second way by default (<a href="https://bytepenny.com/docs/matricxon/kernels-and-gpu/#packed-weights">packed weights</a>). The model file is memory-mapped, and native C kernels multiply the packed blocks directly:</p>
<ol>
<li><strong>The input is quantized too.</strong> The activation vector (the token’s current state) is turned into 8-bit integers, 256 at a time, with one scale each.</li>
<li><strong>Integer dot products.</strong> Packed weights and the 8-bit input are multiplied as small integers with SIMD instructions that handle 16 bytes at once. Floats come back only once per block: <em>weight scale × input scale × integer sum</em>.</li>
<li><strong>Unpack once, reuse many times.</strong> When reading a prompt, each weight row is unpacked once and reused for every prompt token while it is still in the CPU cache.</li>
<li><strong>Built for your server.</strong> The C library compiles on first start with <code>-march=native</code>, so it uses whatever your CPU supports.</li>
</ol>
<p>Every one of the <a href="https://bytepenny.com/docs/matricxon/models/#quantization-types">25 quantization types</a> has a plain Python reference that unpacks a block step by step. The fast kernels, and the Numba versions used when no C compiler is available, are tested against it, so a speed-up can’t quietly change a result. If there is RAM to spare, <code>MATRICXON_ENABLE_QUANTIZED_NATIVE_COMPUTE=false</code> switches to unpacking everything at load time. On an NVIDIA GPU (experimental) weights are unpacked into VRAM by default, where the GPU’s float maths is fastest; <code>MATRICXON_GPU_WEIGHT_MODE=packed</code> keeps them compressed to save VRAM.</p>
<h2 id="a-recent-example-making-2-bit-models-usable">A recent example: making 2-bit models usable</h2>
<p>Until this week, Matricxon’s I-quant kernels unpacked every weight to a float and multiplied one at a time. A 2-bit Llama 3.1 8B took over 3 minutes for its first word on an older laptop CPU (partly because the laptop was also short on RAM), then about 15 seconds per word.</p>
<p>The fix came from looking at the formats again: every I-quant weight is exactly <em>a small integer scale × a small whole number</em> from its codebook. So these types now use the same integer path as the 4-bit types, with nothing approximated. On one layer of that model:</p>
<table>
<thead>
<tr>
<th>IQ2_S, one 14336 × 4096 layer</th>
<th>Before</th>
<th>After</th>
</tr>
</thead>
<tbody>
<tr>
<td>Writing one token</td>
<td>44.9 ms</td>
<td>9.6 ms</td>
</tr>
<tr>
<td>Reading a 16-token prompt</td>
<td>529 ms</td>
<td>about 57 ms</td>
</tr>
</tbody>
</table>
<p>End to end, the first word now comes in 10 to 16 seconds and each further word in about 2.</p>
<h2 id="which-quantization-should-you-pick">Which quantization should you pick?</h2>
<ul>
<li><strong>Q4_K_M</strong> is the usual best choice: about a third of the original size, close in quality, and fast to unpack.</li>
<li><strong>Q8_0</strong> if you have the RAM and want quality closest to the original.</li>
<li><strong>IQ2 and IQ3</strong> to fit a bigger model into little memory. They lose more quality and are slower to unpack on a CPU, so a smaller model in Q4_K_M is often the better trade.</li>
</ul>
<p><a href="https://bytepenny.com/pairing/">pAIring</a> shows each model’s expected memory use for the active engine before you download it, so you can see what fits your hardware.</p>
<p><em>Originally published at <a href="https://bytepenny.com/blog/what-is-dequantization/">bytepenny.com</a>.</em></p>]]></content:encoded>
		</item>
		<item>
			<title>CPU vs GPU</title>
			<link>https://bytepenny.com/blog/cpu-vs-gpu/</link>
			<guid isPermaLink="true">https://bytepenny.com/blog/cpu-vs-gpu/</guid>
			<pubDate>Thu, 15 Oct 2026 00:00:00 GMT</pubDate>
			<author>mail@bytepenny.com (BytePenny)</author>
			<description>Do you need a graphics card to run a language model? What a GPU really speeds up, where a CPU holds its own, and how to choose for your own setup.</description>
			<content:encoded><![CDATA[<p><img src="https://bytepenny.com/img/blog/cpu-vs-gpu.jpg" alt="A processor and a graphics card side by side under the title CPU vs GPU"></p><p>“You need a GPU for AI” is half true. A graphics card makes some parts of running a language model much faster, and others barely at all. Knowing which is which saves money, and tells you whether the computer you already have is enough.</p>
<h2 id="both-are-limited-by-memory-not-maths">Both are limited by memory, not maths</h2>
<p>When a model writes a reply, every new token means reading nearly all of its weights once. So the speed of writing is set mostly by how fast the chip can read its memory:</p>
<table>
<thead>
<tr>
<th>Hardware</th>
<th>Memory speed (roughly)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Laptop or desktop, two DDR4/DDR5 channels</td>
<td>40 to 90 GB/s</td>
</tr>
<tr>
<td>Workstation or server, many channels</td>
<td>200 to 500 GB/s</td>
</tr>
<tr>
<td>Apple Silicon (unified memory)</td>
<td>100 to 800 GB/s</td>
</tr>
<tr>
<td>Consumer graphics card</td>
<td>300 to 1,000+ GB/s</td>
</tr>
</tbody>
</table>
<p>That is why a GPU often writes 5 to 15 times faster than a desktop CPU with the same model. It is not that it thinks harder; it reads faster.</p>
<h2 id="the-catch-the-model-has-to-fit">The catch: the model has to fit</h2>
<p>A GPU is only fast while the whole model, plus the chat’s memory (the KV cache), fits in its own memory (VRAM). Consumer cards have 8 to 24 GB. A 4-bit 8B model (about 5 GB) fits easily. A 4-bit 70B model (about 40 GB) does not fit on any consumer card, but runs on a computer with 64 GB of ordinary RAM.</p>
<p>Splitting a model between the GPU and the CPU works, but helps less than you might expect: every token waits for the slowest part, which is the half that sits in system memory.</p>
<h2 id="where-the-gpu-really-shines">Where the GPU really shines</h2>
<ul>
<li><strong>Reading the prompt.</strong> Before the first word of a reply, the model reads your whole message, and with a knowledge base, the documents found for it. This part is pure arithmetic, and a GPU can be 10 to 100 times faster. Long prompts are where a CPU feels slow.</li>
<li><strong>Many users at once.</strong> A GPU can handle several conversations in the same pass over the weights. A CPU mostly takes turns.</li>
<li><strong>Large models at speed.</strong> If you need a 30B to 70B model to answer quickly, you need serious GPU memory, or several cards.</li>
</ul>
<h2 id="where-the-cpu-holds-its-own">Where the CPU holds its own</h2>
<ul>
<li><strong>Capacity.</strong> 64 GB of RAM costs a fraction of 64 GB of VRAM. Large models fit; they are just slower.</li>
<li><strong>Cost and what you already own.</strong> Every computer has a CPU. For one person, or a small team asking short questions, a well-chosen 3B to 8B model on a modern CPU is often fast enough.</li>
<li><strong>Mixture-of-experts models.</strong> They read only a small part of their weights for each token, so they run far faster on a CPU than their size suggests.</li>
<li><strong>Simplicity, power and noise.</strong> No drivers, no fans at full speed, lower power use, and it runs on any physical or virtual server.</li>
</ul>
<p>Privacy is the same on both: a model on your own hardware keeps your data on your own hardware, whatever chip runs it.</p>
<h2 id="how-to-choose">How to choose</h2>
<table>
<thead>
<tr>
<th>Your situation</th>
<th>A good fit</th>
</tr>
</thead>
<tbody>
<tr>
<td>One user, short questions, a recent laptop</td>
<td>CPU, a 3B to 8B model at 4-bit</td>
</tr>
<tr>
<td>A small team, long documents or a knowledge base</td>
<td>A GPU with 12 to 24 GB, or a fast multi-channel CPU</td>
</tr>
<tr>
<td>Large models, but speed is not critical</td>
<td>CPU with plenty of RAM, or a mixture-of-experts model</td>
</tr>
<tr>
<td>Large models, fast, many users</td>
<td>One or more GPUs with enough memory for the whole model</td>
</tr>
<tr>
<td>Occasional need for a very large model</td>
<td>A cloud model for those cases only</td>
</tr>
</tbody>
</table>
<h2 id="what-matricxon-and-pairing-do">What Matricxon and pAIring do</h2>
<p><a href="https://bytepenny.com/matricxon/">Matricxon</a> runs on both CPUs and GPUs. On NVIDIA cards (<code>MATRICXON_DEVICE=cuda</code>, in BETA) weights are either unpacked for speed or kept compressed to save VRAM. On CPUs, a lot of fine-tuning went into making it work well: it multiplies compressed weights directly, keeps chats cached so a prompt is rarely read twice, and runs mixture-of-experts models efficiently. <a href="https://bytepenny.com/pairing/">pAIring</a> works with Matricxon, llama.cpp (with a GPU build it uses your GPU) and a growing list of cloud connectors, so you can start on the hardware you have, add a GPU server later, and switch engines with one setting.</p>
<p>The short answer: start with your CPU. Add a GPU when replies get too slow, usually because of long prompts, many users at once or a large model.</p>
<p><em>Originally published at <a href="https://bytepenny.com/blog/cpu-vs-gpu/">bytepenny.com</a>.</em></p>]]></content:encoded>
		</item>
		<item>
			<title>What is MCP? The Model Context Protocol, explained</title>
			<link>https://bytepenny.com/blog/what-is-mcp/</link>
			<guid isPermaLink="true">https://bytepenny.com/blog/what-is-mcp/</guid>
			<pubDate>Thu, 15 Oct 2026 00:00:00 GMT</pubDate>
			<author>mail@bytepenny.com (BytePenny)</author>
			<description>MCP is an open standard that lets AI apps use tools and data through one common plug. What it is, how a tool call works, and how to use it safely.</description>
			<content:encoded><![CDATA[<p><img src="https://bytepenny.com/img/blog/what-is-mcp.jpg" alt="An AI app in the center connected to several tool servers, under the title What is MCP"></p><p>On its own, a language model can only write text. It can’t look up today’s orders, search your wiki or create a ticket. To do that, it needs <em>tools</em>, and someone has to connect each tool to each AI app. <strong>MCP (the Model Context Protocol)</strong> is an open standard that makes this connection the same everywhere. Anthropic introduced it in late 2024, and it is now supported by many AI apps and tools.</p>
<p>A common way to picture it: MCP is like a USB-C port for AI. Build a tool once as an MCP server, and any app that speaks MCP can use it.</p>
<h2 id="the-problem-it-solves">The problem it solves</h2>
<p>Without a standard, every app needs its own code for every tool. Ten apps and ten tools means up to a hundred separate integrations, each built and kept up to date on its own. With MCP, each app implements the protocol once and each tool implements it once. Ten plus ten instead of ten times ten.</p>
<h2 id="the-three-parts">The three parts</h2>
<ul>
<li><strong>Host:</strong> the AI app people use, such as a chat app or a code editor.</li>
<li><strong>Client:</strong> the connection inside the host that talks to one server.</li>
<li><strong>Server:</strong> a small program that offers capabilities to the model. It can run on the same server or anywhere on the network.</li>
</ul>
<p>A server can offer three kinds of things:</p>
<table>
<thead>
<tr>
<th>Capability</th>
<th>What it is</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Tools</strong></td>
<td>Actions the model can call</td>
<td>Search tickets, run a query, send a message</td>
</tr>
<tr>
<td><strong>Resources</strong></td>
<td>Data the app can read</td>
<td>A file, a database record, a document</td>
</tr>
<tr>
<td><strong>Prompts</strong></td>
<td>Ready-made instructions</td>
<td>“Summarize this pull request”</td>
</tr>
</tbody>
</table>
<p>Messages use JSON-RPC, a simple JSON request and response format. A local server usually talks over standard input and output; a remote one over HTTP (the “streamable HTTP” transport).</p>
<h2 id="how-a-tool-call-works">How a tool call works</h2>
<ol>
<li><strong>Connect and list.</strong> The app connects to the server and asks which tools it has. Each tool comes with a name, a plain-language description and a schema for its inputs.</li>
<li><strong>Offer.</strong> The app passes those tool descriptions to the model with the user’s message.</li>
<li><strong>Decide.</strong> If a tool would help, the model replies with a tool call instead of text, for example <code>search_tickets</code> with <code>{"status": "open"}</code>.</li>
<li><strong>Run.</strong> The app sends the call to the server, which does the work and returns the result.</li>
<li><strong>Answer.</strong> The result goes back to the model, which uses it to write the reply, or calls another tool first.</li>
</ol>
<p>The model never touches your systems directly. The app stays in the middle and decides what runs.</p>
<h2 id="using-mcp-safely">Using MCP safely</h2>
<ul>
<li><strong>The model needs tool support.</strong> Not every model or engine can call tools. Choose one trained for it.</li>
<li><strong>Connect only servers you trust.</strong> Whatever a tool returns is read by the model, so a dishonest server or a poisoned web page can try to steer it (this is called <em>prompt injection</em>).</li>
<li><strong>Give the least access needed.</strong> A read-only key is safer than an admin one, and keys should be stored encrypted.</li>
<li><strong>Keep people in control.</strong> Let users choose when tools are on, and be careful with tools that change or delete things.</li>
</ul>
<h2 id="mcp-in-pairing">MCP in pAIring</h2>
<p><a href="https://bytepenny.com/pairing/">pAIring</a> is an MCP host. An admin adds MCP servers under Admin settings &gt; MCP servers (streamable HTTP), tests the connection, and stores any API key encrypted. A switch in Admin settings &gt; System turns MCP on or off for everyone. Users then turn tools on per chat. Tools work with <a href="https://bytepenny.com/matricxon/">Matricxon</a> and llama.cpp, so a private model on your own hardware can look things up and take actions while your data stays with you.</p>
<p><em>Originally published at <a href="https://bytepenny.com/blog/what-is-mcp/">bytepenny.com</a>.</em></p>]]></content:encoded>
		</item>
		<item>
			<title>What is RAG, and why is it hard on CPUs?</title>
			<link>https://bytepenny.com/blog/what-is-rag/</link>
			<guid isPermaLink="true">https://bytepenny.com/blog/what-is-rag/</guid>
			<pubDate>Thu, 15 Oct 2026 00:00:00 GMT</pubDate>
			<author>mail@bytepenny.com (BytePenny)</author>
			<description>Retrieval-augmented generation lets a language model answer from your own documents. How RAG works step by step, how reranking improves it, and why it is slow on a CPU.</description>
			<content:encoded><![CDATA[<p><img src="https://bytepenny.com/img/blog/what-is-rag.jpg" alt="Documents flowing into a processor chip under the title What is RAG"></p><p>A language model only knows what it saw in training. It has never read your documents, your product manuals or last week’s meeting notes. <strong>RAG (retrieval-augmented generation)</strong> fixes that without retraining anything: before the model answers, the app finds the most relevant passages in your documents and hands them to the model together with the question.</p>
<p>It is the most practical way to make a private model useful at work. It also asks a lot from a CPU. Here is why.</p>
<h2 id="how-rag-works-step-by-step">How RAG works, step by step</h2>
<p>RAG has two phases: preparing your documents once, and then using them for every question.</p>
<p><strong>Preparing the documents (once per file)</strong></p>
<ol>
<li><strong>Extract the text.</strong> PDFs, Word files and web pages are turned into plain text.</li>
<li><strong>Split it into chunks.</strong> Each document is cut into short passages, a few hundred characters each, with a small overlap so that an idea split across a boundary stays whole somewhere.</li>
<li><strong>Embed each chunk.</strong> An <em>embedding model</em> turns every chunk into a vector, a list of numbers that captures its meaning. Passages about similar topics get similar vectors, even when they use different words.</li>
<li><strong>Store the vectors</strong> in an index, ready to search.</li>
</ol>
<p><strong>Answering a question (every time)</strong></p>
<ol start="5">
<li><strong>Embed the question</strong> with the same embedding model.</li>
<li><strong>Retrieve.</strong> Find the chunks whose vectors are closest to the question’s vector, usually the top 3 to 5.</li>
<li><strong>Augment the prompt.</strong> Put those chunks into the prompt: “Using these passages, answer the question…”</li>
<li><strong>Generate.</strong> The language model reads everything and writes the answer, ideally quoting where it came from.</li>
</ol>
<p>The model does not memorize your documents. It reads the few passages it needs, right when it needs them, so new or changed files count at once.</p>
<h2 id="reranking-a-second-closer-look">Reranking: a second, closer look</h2>
<p>Vector search is fast, but rough. It compares two lists of numbers that were made separately, one for the question and one for each passage, so it finds passages <em>about</em> the same topic, not always the ones that <em>answer</em> the question. Ask “How long is the warranty on the X200?” and a passage about the X100’s warranty may score just as high as the right one.</p>
<p>A <strong>reranker</strong> fixes that with one extra step between retrieving and augmenting:</p>
<ol>
<li><strong>Shortlist.</strong> Vector search picks a wider set, say the top 20 passages instead of 4.</li>
<li><strong>Rerank.</strong> A reranker model reads the question <em>together with</em> each passage and gives it a relevance score from 0 to 1. Reading both at once lets it notice details, like the model number, that vector search can miss.</li>
<li><strong>Keep the best.</strong> Only the top few, by the new score, go into the prompt.</li>
</ol>
<p>The result is better answers without a longer prompt. A reranker is a small model that scores instead of writing, but it still reads every shortlisted passage, so it adds a short wait before the answer starts. On a CPU that is usually worth it: a few seconds spent picking the right 4 passages beats a minute spent reading 10 mediocre ones.</p>
<h2 id="why-rag-is-hard-on-a-cpu">Why RAG is hard on a CPU</h2>
<p>When a model runs, there are two kinds of work. <strong>Writing</strong> the reply is limited by memory speed, and a modern CPU handles it well. <strong>Reading</strong> the prompt is pure arithmetic, and that is where a CPU is far behind a GPU. RAG makes the reading part much bigger.</p>
<ul>
<li><strong>The prompt gets long.</strong> A short question is maybe 30 tokens. Add five retrieved chunks and it can grow to a few thousand. A desktop CPU may read tens to a couple of hundred tokens per second with a mid-size model, so the answer can take many seconds to <em>start</em>, even though it then streams quickly.</li>
<li><strong>It happens on every question.</strong> The retrieved passages change with each question, so the work can’t simply be reused. Each new question is read almost from scratch.</li>
<li><strong>Embedding a whole library takes time.</strong> Every chunk of every file goes through the embedding model. For thousands of pages, that is a long first run on a CPU, and it starts again if you change the embedding model.</li>
<li><strong>Longer prompts use more memory.</strong> The model keeps a cache for everything it has read (the KV cache). It grows with each extra chunk, takes RAM, and has to be read again for every word the model writes.</li>
</ul>
<h2 id="what-helps-on-a-cpu">What helps on a CPU</h2>
<ul>
<li><strong>Retrieve fewer, better chunks.</strong> Three good passages beat ten average ones, and every chunk you leave out saves reading time. A reranker is the best way to pick them.</li>
<li><strong>Keep chunks short and focused.</strong> Smaller passages mean less to read and more precise matches.</li>
<li><strong>Use a small embedding model.</strong> Embedding models are tiny compared to chat models, and a small one is usually good enough.</li>
<li><strong>Embed in the background.</strong> Do it once when files are added, not while someone waits for an answer.</li>
<li><strong>Pick a model that reads fast.</strong> A 3B to 8B model at 4-bit, or a mixture-of-experts model, keeps the wait reasonable.</li>
<li><strong>Reuse what you can.</strong> Follow-up questions in the same chat should not read the whole conversation again.</li>
</ul>
<h2 id="how-pairing-and-matricxon-handle-it">How pAIring and Matricxon handle it</h2>
<p><a href="https://bytepenny.com/pairing/">pAIring</a> has a built-in knowledge base. Each user can add private documents, which are split, embedded in the background and searched on every question. By default it retrieves 4 short passages, and each person can change that number in Settings &gt; Knowledge. With <a href="https://bytepenny.com/matricxon/">Matricxon</a> as the engine, an admin can add a reranker in one click (Settings &gt; Models &gt; Reranker models, Qwen3 Reranker 0.6B): pAIring then shortlists 20 passages and the reranker keeps the best ones. Matricxon checks its reranker scores against llama.cpp’s own. It also keeps a cache for each conversation (and can save it to disk), so a follow-up question reads only what is new, not the whole chat again.</p>
<p>RAG is the simplest way to give a private model real knowledge of your work. On a CPU it works well too, as long as you keep the retrieved context lean.</p>
<p><em>Originally published at <a href="https://bytepenny.com/blog/what-is-rag/">bytepenny.com</a>.</em></p>]]></content:encoded>
		</item>
		<item>
			<title>Wolfram|Alpha as an MCP server: exact math for your AI</title>
			<link>https://bytepenny.com/blog/wolfram-alpha-mcp-server/</link>
			<guid isPermaLink="true">https://bytepenny.com/blog/wolfram-alpha-mcp-server/</guid>
			<pubDate>Thu, 15 Oct 2026 00:00:00 GMT</pubDate>
			<author>mail@bytepenny.com (BytePenny)</author>
			<description>Language models guess at math; Wolfram|Alpha computes it. What the Wolfram MCP server is, what its tools do, why it makes math and facts reliable, and how to connect it.</description>
			<content:encoded><![CDATA[<p><img src="https://bytepenny.com/img/blog/wolfram-alpha-mcp-server.jpg" alt="An AI chip connected to a Wolfram|Alpha computation engine with math symbols, under the title Wolfram|Alpha as an MCP server"></p><p>Ask a language model for 2<sup>100</sup>, the integral of x² sin x, and it will answer confidently. Sometimes it is right. A language model doesn’t calculate; it predicts the next piece of text, and digits are just text to it. That works for words, but numbers need to be exact.</p>
<p><strong>Wolfram|Alpha</strong> was built to do the opposite: compute answers instead of predicting them. Thanks to <a href="https://bytepenny.com/blog/what-is-mcp/">MCP (the Model Context Protocol)</a>, any AI app that supports MCP can now hand math and factual questions to Wolfram|Alpha and get back a computed result. This post explains what that is, what you gain, and where the limits are.</p>
<h2 id="what-wolframalpha-is">What Wolfram|Alpha is</h2>
<p>Wolfram|Alpha is a <em>computational knowledge engine</em> from Wolfram Research, online since 2009. It is not a search engine: instead of finding pages that might contain the answer, it works the answer out. Underneath are two things:</p>
<ul>
<li><strong>The Wolfram Language</strong> (the language behind Mathematica), with decades of algorithms for algebra, calculus, statistics, number theory, geometry and much more.</li>
<li><strong>The Wolfram Knowledgebase</strong>, a large, curated collection of data on chemistry, physics, astronomy, geography, finance, units and other fields.</li>
</ul>
<p>It takes plain-language questions such as “solve x^3 - 2x + 1 = 0” or “distance from Earth to Mars now” and returns structured, computed results.</p>
<h2 id="wolframalpha-as-an-mcp-server">Wolfram|Alpha as an MCP server</h2>
<p>An MCP server offers tools that a model can call. In February 2026, Wolfram made its technology available as a “foundation tool” for AI systems, including an official MCP service. Wolfram calls the idea <strong>computation-augmented generation (CAG)</strong>: where <a href="https://bytepenny.com/blog/what-is-rag/">RAG</a> adds <em>retrieved</em> text to the prompt, CAG adds <em>computed</em> results.</p>
<p>The <strong>Wolfram Cloud MCP</strong> server lives at <code>https://agenttools.wolfram.com/mcp</code>. It uses the standard streamable HTTP transport, needs no API key, and is free for limited personal use. It offers three tools:</p>
<table>
<thead>
<tr>
<th>Tool</th>
<th>What it does</th>
<th>Good for</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>WolframAlpha</strong></td>
<td>Sends a plain-language query to Wolfram|Alpha</td>
<td>Math, unit conversions, facts about chemistry, physics, geography, astronomy and more</td>
</tr>
<tr>
<td><strong>WolframLanguageEvaluator</strong></td>
<td>Runs Wolfram Language code in a cloud kernel (60-second default limit)</td>
<td>Multi-step calculations, custom formulas, plots</td>
</tr>
<tr>
<td><strong>WolframContext</strong></td>
<td>Semantic search over Wolfram’s documentation and knowledge</td>
<td>Helping the model write correct queries and code</td>
</tr>
</tbody>
</table>
<p>All three are marked read-only. The cloud service is stateless: each call stands alone, with no saved variables between calls and no file uploads.</p>
<p>There are two other routes. <strong>Wolfram Local MCP</strong> runs on your own server with Mathematica, Wolfram|One or a licensed Wolfram Engine, and adds persistent sessions, local files and notebook tools. And several community MCP servers wrap the <strong>Wolfram|Alpha LLM API</strong>, which needs a free App ID from the Wolfram developer portal (a free non-commercial plan is available).</p>
<h2 id="what-a-tool-call-looks-like">What a tool call looks like</h2>
<p>A user asks: <em>“What is the integral of x² sin(x), and what is it from 0 to π?”</em></p>
<ol>
<li>The model sees the <code>WolframAlpha</code> tool and decides to use it.</li>
<li>It calls the tool with the query <code>integrate x^2 sin(x) dx</code>.</li>
<li>Wolfram|Alpha computes and returns the answer (this is the actual response):</li>
</ol>
<div class="expressive-code"><link rel="stylesheet" href="https://bytepenny.com/_astro/ec.w36nc.css"><script type="module" src="https://bytepenny.com/_astro/ec.0vx5m.js"></script><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="plaintext"><code><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53"># Indefinite integral</span></div></div><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53">∫ x^2 sin(x) dx = 2 x sin(x) - (x^2 - 2) cos(x) + constant</span></div></div><div class="ec-line"><div class="code">
</div></div><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53"># Definite integral</span></div></div><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53">∫_0^π x^2 sin(x) dx = π^2 - 4 ≈ 5.8696</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button title="Copy to clipboard" data-copied="Copied!" data-code="# Indefinite integral∫ x^2 sin(x) dx = 2 x sin(x) - (x^2 - 2) cos(x) + constant# Definite integral∫_0^π x^2 sin(x) dx = π^2 - 4 ≈ 5.8696"><div></div></button></div></figure></div>
<ol start="4">
<li>The model writes the reply around this exact result, and can add a link to the full Wolfram|Alpha page so the user can check it.</li>
</ol>
<p>The model does the talking; Wolfram|Alpha does the math.</p>
<h2 id="the-math-advantages">The math advantages</h2>
<p>Language models break numbers into tokens, chunks of characters, and predict them one at a time. Long multiplication, carrying digits and keeping many steps exact are exactly where that fails. Handing the math to Wolfram|Alpha gives you:</p>
<ul>
<li><strong>Exact arithmetic.</strong> Big integers, fractions and high-precision decimals, computed rather than estimated. 2<sup>100</sup> is 1267650600228229401496703205376, every digit correct.</li>
<li><strong>Symbolic math.</strong> Simplify, factor, expand, differentiate and integrate expressions, with exact forms like π² − 4 instead of a rounded decimal.</li>
<li><strong>Equation solving.</strong> Polynomial, linear and differential equations and systems of equations, including complex roots and exact radicals.</li>
<li><strong>Units and constants.</strong> Unit-aware calculations and conversions, plus physical constants such as the speed of light, without the model typing in values from memory.</li>
<li><strong>Statistics and number theory.</strong> Means, regressions, distributions, primes, factorizations, modular arithmetic.</li>
<li><strong>Plots.</strong> Graphs of functions and data, returned as images the app can show.</li>
<li><strong>Results you can check.</strong> Every answer can come with a link to the full Wolfram|Alpha result, so a person can verify it.</li>
</ul>
<h2 id="beyond-math">Beyond math</h2>
<ul>
<li><strong>Curated, up-to-date data.</strong> Chemical properties, planet positions, country statistics and exchange rates come from Wolfram’s knowledgebase, not from what the model happened to read during training.</li>
<li><strong>Fewer hallucinated facts.</strong> When a number comes from a tool, the model has no need to invent one.</li>
<li><strong>Small models with strong math.</strong> A compact model running on a CPU will never compute as well as Wolfram|Alpha, and it doesn’t have to. It only needs to recognize when to call the tool. This makes a small private model far more capable without bigger hardware. For more on that trade-off, see <a href="https://bytepenny.com/blog/running-llms-on-cpus/">running LLMs on CPUs</a>.</li>
</ul>
<h2 id="limits-and-things-to-know">Limits and things to know</h2>
<ul>
<li><strong>The question leaves your network.</strong> The query text goes to Wolfram’s cloud. Keep confidential details out of math queries, or use Wolfram Local MCP.</li>
<li><strong>Internet access is required</strong> for the cloud service, and it is meant for small-scale use. For heavy or commercial use, look at Wolfram’s paid APIs.</li>
<li><strong>The model must support tool calling,</strong> and has to choose to call the tool. A model that answers math on its own will still guess.</li>
<li><strong>English queries work best.</strong> The model should translate the question for the tool and answer in the user’s language.</li>
<li><strong>Code tools need care.</strong> WolframLanguageEvaluator runs code in Wolfram’s cloud. It is read-only for your systems, but some apps let you require approval for it.</li>
</ul>
<h2 id="using-it-in-pairing">Using it in pAIring</h2>
<p><a href="https://bytepenny.com/pairing/">pAIring</a> is an MCP host, so connecting Wolfram|Alpha takes a minute:</p>
<ol>
<li>Open <strong>Admin settings &gt; MCP servers</strong> and add a server named <code>Wolfram</code> with the URL <code>https://agenttools.wolfram.com/mcp</code>. No API key or headers are needed.</li>
<li>Raise the call timeout to about 60 seconds, since Wolfram Language evaluations can take that long.</li>
<li>Test the connection, then make sure MCP is on under <strong>Admin settings &gt; System</strong>.</li>
<li>In a chat, turn tools on and ask a math question.</li>
</ol>
<p>With a tool-capable model on <a href="https://bytepenny.com/matricxon/">Matricxon</a> or llama.cpp, your chats stay on your own hardware, and only the math and fact queries go out to Wolfram.</p>
<p><em>Originally published at <a href="https://bytepenny.com/blog/wolfram-alpha-mcp-server/">bytepenny.com</a>.</em></p>]]></content:encoded>
		</item>
		<item>
			<title>Running LLMs on CPUs: advice, tricks and what Matricxon does</title>
			<link>https://bytepenny.com/blog/running-llms-on-cpus/</link>
			<guid isPermaLink="true">https://bytepenny.com/blog/running-llms-on-cpus/</guid>
			<pubDate>Wed, 14 Oct 2026 00:00:00 GMT</pubDate>
			<author>mail@bytepenny.com (BytePenny)</author>
			<description>No GPU? A modern CPU can run a useful language model. Why memory bandwidth decides speed, how to pick and tune a model, and the tricks Matricxon uses.</description>
			<content:encoded><![CDATA[<p><img src="https://bytepenny.com/img/blog/running-llms-on-cpus.jpg" alt="A processor chip next to the title Running LLMs on CPUs"></p><p>You do not need a graphics card to run a useful language model. A modern laptop or desktop CPU can chat, summarize and write code with a well-chosen model, privately and at no running cost. It just rewards a bit of understanding. Here is what we have learned building <a href="https://bytepenny.com/matricxon/">Matricxon</a>, our CPU-first inference engine.</p>
<h2 id="the-one-number-that-matters-memory-bandwidth">The one number that matters: memory bandwidth</h2>
<p>When a model writes a reply, every new token means reading (nearly) all of the model’s weights from RAM once. The CPU’s arithmetic is rarely the limit; the memory bus is. A useful rule of thumb:</p>
<blockquote>
<p><strong>Tokens per second ≈ memory bandwidth ÷ model size in memory</strong></p>
</blockquote>
<p>A typical dual-channel DDR4 laptop moves around 40 GB/s, so a 4 GB model tops out near 10 tokens per second, and a 2 GB model near 20. Faster RAM, more memory channels and smaller models all help. Extra cores help much less than you would expect.</p>
<p>Reading your prompt is different: it is compute-bound, so long prompts and big documents take time on a CPU even when replies stream quickly. Keep that in mind when you paste a whole file into a chat.</p>
<h2 id="pick-the-right-model">Pick the right model</h2>
<ul>
<li><strong>Size first.</strong> On a laptop with 8 to 16 GB of RAM, models of 1 to 4 billion parameters feel responsive. A desktop with 32 GB or more handles 7 to 14B well.</li>
<li><strong>Quantize.</strong> GGUF files store weights in compressed blocks. <strong>Q4_K_M</strong> is the sweet spot for most models: about a quarter of the original size with little quality loss. Small models (under 3B) deserve Q5 or Q6, since every bit counts more for them. Below Q3, quality drops quickly.</li>
<li><strong>Consider mixture-of-experts.</strong> A model such as a 30B with 3B active parameters reads only the experts it uses for each token, so it can run nearly as fast as a 3B model while answering like a much larger one. It still needs RAM for the whole file.</li>
</ul>
<h2 id="tune-the-server">Tune the server</h2>
<ul>
<li><strong>Threads: physical cores, not all of them.</strong> Once memory bandwidth is saturated, more threads add heat, not speed. On laptops, leaving one or two cores free keeps the server responsive and avoids thermal throttling, which can cost more speed than it saves.</li>
<li><strong>Never swap.</strong> A model that spills into swap slows to a crawl. Leave a safe margin of free RAM, and close the browser tab with forty other tabs in it.</li>
<li><strong>Fill both memory channels.</strong> One stick of RAM halves your bandwidth. Two matched sticks are one of the cheapest speed-ups there is.</li>
<li><strong>Keep the context modest.</strong> The chat’s memory (the KV cache) grows with every token of context. A 4K to 8K window is plenty for most chats and keeps RAM free for the model.</li>
</ul>
<h2 id="what-matricxon-does-for-you">What Matricxon does for you</h2>
<p>Matricxon is built around these limits, so most of this happens without any setup:</p>
<ul>
<li><strong>Packed weights.</strong> By default, weights stay compressed in the memory-mapped file and are multiplied directly, with no unpacked copy in RAM. Ministral 3B in Q4_K_M needs about 2.6 GB this way instead of about 7.5 GB. If you have RAM to spare, set <code>MATRICXON_ENABLE_QUANTIZED_NATIVE_COMPUTE=false</code>: unpacked weights are about 2 to 4 times faster per step.</li>
<li><strong>Native C kernels.</strong> All the quantized math runs in C with OpenMP threads, for 25 GGUF quantization types, including the very small IQ types.</li>
<li><strong>Fewer threads, cooler server.</strong> <code>MATRICXON_TORCH_THREADS</code> caps the thread count, for laptops that run hot.</li>
<li><strong>Prompt caching.</strong> Each model keeps several conversations’ caches, and a new message reuses the longest matching prefix, so only the new text is read. Since reading prompts is the slow part on a CPU, this is the biggest win of all.</li>
<li><strong>Caches that survive.</strong> Caches evicted from RAM, or still held when the server stops, are saved to disk with AES encryption. Coming back to a long chat tomorrow does not mean re-reading it.</li>
<li><strong>Context shift.</strong> When a chat outgrows its window, the oldest tokens are dropped from the cache instead of re-reading everything.</li>
<li><strong>Safe loading.</strong> A model that would not fit in free RAM is refused rather than pushed into swap, and idle models unload after a while.</li>
<li><strong>Several users at once.</strong> Replies on one model run side by side, with their steps batched together where the architecture allows.</li>
</ul>
<h2 id="quick-checklist">Quick checklist</h2>
<ol>
<li>Choose a model that fits in RAM with room to spare, at Q4_K_M (Q5 or Q6 if small).</li>
<li>Try a mixture-of-experts model if you have the RAM but want speed.</li>
<li>Use your physical cores minus one or two.</li>
<li>Keep chats going instead of starting over, so the prompt cache does its work.</li>
<li>Measure: tokens per second tells you at once whether a change helped.</li>
</ol>
<p>CPU inference will not beat a big GPU, but for private, everyday use it is often fast enough, and it runs on hardware you already own. To try it, start with the <a href="https://bytepenny.com/docs/matricxon/quick-start/">Matricxon quick start</a>, or run it with <a href="https://bytepenny.com/pairing/">pAIring</a> for a full chat workspace.</p>
<p><em>Originally published at <a href="https://bytepenny.com/blog/running-llms-on-cpus/">bytepenny.com</a>.</em></p>]]></content:encoded>
		</item>
	</channel>
</rss>
