From 0cf76d15f3ceb9a460fa7e669cdaa0b197c7d7da Mon Sep 17 00:00:00 2001 From: Saiyam Pathak Date: Tue, 18 Aug 2026 08:23:58 +0530 Subject: [PATCH 1/2] Explain Gated DeltaNet, YaRN, and the UD-Q4_K_XL quant name The post leaned on three terms it never defined. Added inline at first use rather than as a glossary box: - Gated DeltaNet: gets its own short paragraph, since the fixed-size recurrent state is what explains the context-flatness numbers later. Plants the mental model early so the 32K and 100K results pay it off. - YaRN: expanded to Yet another RoPE extensioN with a one-line explanation of frequency rescaling. - UD-Q4_K_XL: decoded into its three parts (K-quant super-blocks, Unsloth Dynamic per-layer bit allocation, XL tier promoting selected matrices to 5-bit). Both papers linked: arXiv 2412.06464 and 2309.00071. --- content/blog/qwen3-8-27b-on-dgx-spark.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/content/blog/qwen3-8-27b-on-dgx-spark.md b/content/blog/qwen3-8-27b-on-dgx-spark.md index cb2a2a498..029cfdb7e 100644 --- a/content/blog/qwen3-8-27b-on-dgx-spark.md +++ b/content/blog/qwen3-8-27b-on-dgx-spark.md @@ -57,13 +57,15 @@ python3 edit_bench.py http://127.0.0.1:8002/v1 qwen3.8-27b # from 0xBakeer's r Reading the config before running things saves a lot of confusion, and this one is interesting: -- 27B parameters, and it is NOT a MoE. 64 layers with a hybrid attention pattern: every 4th layer is full gated attention, the other 48 layers are Gated DeltaNet (linear attention). Same hybrid lineage as Qwen3.5/3.6. +- 27B parameters, and it is NOT a MoE. 64 layers with a hybrid attention pattern: every 4th layer is full gated attention, the other 48 layers are [Gated DeltaNet](https://arxiv.org/abs/2412.06464) (linear attention). Same hybrid lineage as Qwen3.5/3.6. - Native vision language model. There is a 27-layer vision encoder in the checkpoint, images and video in, text out. -- 262,144 token native context, extensible to 1M with YaRN. +- 262,144 token native context, extensible to 1M with [YaRN](https://arxiv.org/abs/2309.00071), short for Yet another RoPE extensioN: it rescales the model's positional frequencies, stretching each one differently depending on its wavelength, so the model can address positions further out than it was ever trained on without a full retrain. - Thinking mode on by default (`` blocks), with recommended sampling temp 1.0 / top_p 0.95 / top_k 20. Non-thinking: temp 0.7 / top_p 0.80. - Apache 2.0. - Architecture class is `Qwen3_5ForConditionalGeneration` (`model_type: qwen3_5`). This detail matters: it is the same architecture family the inference engines already support, which is why day-zero support mostly just works. +Gated DeltaNet deserves a sentence of its own, because it quietly explains most of the numbers later in this post. Normal attention keeps a KV cache that grows with every token you feed it, so the deeper your context gets, the more memory has to be read before the next token can come out. A linear attention layer keeps a fixed-size running state instead: the gate decides how fast old memory fades, and the delta rule writes targeted corrections into that state rather than appending to an ever-growing list. The state is the same size at token 100,000 as it is at token 10. Hold onto that one, it is why decode speed barely moves as context grows further down. + Qwen's own (vendor-reported, so calibrate accordingly) numbers for the 27B: SWE-bench Pro 61.7, LiveCodeBench v6 90.3, Terminal Bench 2.1 at 73.0, GPQA Diamond 89.2, OSWorld-Verified 84.3. ## What works on the Spark on day zero @@ -95,6 +97,8 @@ Two gotchas I hit so you do not have to: First token arrives fast and the model correctly identified what it was running on (a nice recursive moment: Qwen3.8-27B on a DGX Spark explaining what a DGX Spark is). +Quick decode of that quant name before the numbers, because `UD-Q4_K_XL` is three labels stacked on top of each other. `Q4_K` is llama.cpp's 4-bit K-quant: instead of one scaling factor for a whole tensor, weights are stored in super-blocks of 256, split into blocks of 32 that each carry their own quantized scale, so outlier weights do less damage to their neighbours. `UD` is Unsloth Dynamic, meaning the layers are deliberately not all quantized the same: embeddings and the first and last blocks keep more bits because everything downstream depends on them, while the more redundant middle feed-forward layers get squeezed harder. `XL` is the size tier, which promotes selected important matrices to 5-bit where unsloth judges that safe. The practical upshot is 16.68 GiB of weights that hold up better than a uniform 4-bit quant of the same size. + The `llama-bench` numbers (build b10423, flash attention on, UD-Q4_K_XL, 16.68 GiB weights): | Test | Result | From 1a20030afd41a1d7a306e3e37500a811d76ee432 Mon Sep 17 00:00:00 2001 From: Saiyam Pathak Date: Tue, 18 Aug 2026 14:04:29 +0530 Subject: [PATCH 2/2] Explain the jargon: inline decodes plus a local LLM glossary Feedback from Shubham was that the post assumes a vocabulary the reader does not have. The sparkrun YAML screenshot was the clearest example: ten settings, no indication of what any of them do or why those values. Inline, in the Qwen3.8 post, because a link out of a post is an escape hatch most readers do not come back from: - A table decoding every line of the sparkrun recipe: what the setting does and why that value, not just what it expands to. - A prefill vs decode primer before the first benchmark table, which also decodes pp2048/tg128 so every table downstream reads cleanly. - The llama.cpp flags (-ngl 99, -c 32768, -fa on) explained where they first appear, and mmproj where the vision path comes up. - NVFP4 deep-linked to Day 4 rather than re-taught. Plus content/blog/local-llm-glossary.md as the reference destination: benchmark reading, why the numbers come out that way, a quant format lookup table, context and KV cache, speed tricks, and copy-paste flag tables for vLLM, llama.cpp, and Ollama. It links out to Days 1-5 instead of duplicating the series, and carries an FAQ block for answer engines. GlossaryNote surfaces it as one compact line under the cover, not a banner: on mobile a banner pushes the article below the fold, which is the exact screen the feedback came from. Tag-gated via lib/glossary.js with a `glossary:` frontmatter override, landing on 13 inference posts. Opted out four where the tags matched but a local-inference glossary is noise (k8sgpt, docker-mcp-catalog, claude-code-leak, tailscale SSH). Co-Authored-By: Claude Opus 5 (1M context) --- app/blog/[slug]/page.js | 3 + components/GlossaryNote.jsx | 29 + ...e-leak-what-the-source-actually-teaches.md | 1 + content/blog/docker-mcp-catalog.md | 1 + ...8sgpt-tutorial-when-kubernetes-meets-ai.md | 1 + content/blog/local-llm-glossary.md | 231 +++++ content/blog/qwen3-8-27b-on-dgx-spark.md | 22 +- ...m-anywhere-in-the-world-using-tailscale.md | 1 + lib/_blog-feed-data.js | 74 +- lib/blog.js | 3 + lib/glossary.js | 26 + public/_redirects | 6 + public/_worker.js | 2 +- public/atom.xml | 49 +- public/img/blog/local-llm-glossary/cover.png | Bin 0 -> 195791 bytes public/img/blog/local-llm-glossary/cover.svg | 51 + public/llms-full.txt | 977 +++++++++++++++++- public/llms.txt | 30 +- public/rss.xml | 30 +- scripts/gen-local-llm-glossary-cover.mjs | 212 ++++ vercel.json | 48 + 21 files changed, 1724 insertions(+), 73 deletions(-) create mode 100644 components/GlossaryNote.jsx create mode 100644 content/blog/local-llm-glossary.md create mode 100644 lib/glossary.js create mode 100644 public/img/blog/local-llm-glossary/cover.png create mode 100644 public/img/blog/local-llm-glossary/cover.svg create mode 100644 scripts/gen-local-llm-glossary-cover.mjs diff --git a/app/blog/[slug]/page.js b/app/blog/[slug]/page.js index 3e8694e65..ce98d3565 100644 --- a/app/blog/[slug]/page.js +++ b/app/blog/[slug]/page.js @@ -10,6 +10,7 @@ import BlogToc from '@/components/BlogToc'; import BlogShareBar from '@/components/BlogShareBar'; import NewsletterCTA from '@/components/NewsletterCTA'; import SponsorCallout from '@/components/SponsorCallout'; +import GlossaryNote from '@/components/GlossaryNote'; import AuthorSocials from '@/components/AuthorSocials'; import Comments from '@/components/Comments'; import { safeJsonLd } from '@/lib/jsonld'; @@ -258,6 +259,8 @@ export default async function BlogPost({ params }) { + + {/* Mobile TOC (desktop has it in the right sidebar) */} {toc.length > 2 && (
diff --git a/components/GlossaryNote.jsx b/components/GlossaryNote.jsx new file mode 100644 index 000000000..21d6abfff --- /dev/null +++ b/components/GlossaryNote.jsx @@ -0,0 +1,29 @@ +import Link from 'next/link'; +import { GLOSSARY_SLUG, showsGlossaryLink } from '@/lib/glossary'; + +/** + * One compact line above the post body for jargon-heavy posts. Deliberately not + * a banner: it should not push the article below the fold on mobile. Plain + * inline text rather than flex, so nothing orphans onto its own line when it + * wraps on a narrow screen. + */ +export default function GlossaryNote({ post }) { + if (!showsGlossaryLink(post)) return null; + + return ( +

+ New to the jargon? Every term, flag, and benchmark number here is explained in plain English in the{' '} + + local LLM glossary + + . +

+ ); +} diff --git a/content/blog/claude-code-leak-what-the-source-actually-teaches.md b/content/blog/claude-code-leak-what-the-source-actually-teaches.md index f55b48525..c0d21b62c 100644 --- a/content/blog/claude-code-leak-what-the-source-actually-teaches.md +++ b/content/blog/claude-code-leak-what-the-source-actually-teaches.md @@ -7,6 +7,7 @@ slug: claude-code-leak-what-the-source-actually-teaches author: saiyam-pathak cover: /img/blog/claude-code-leak-what-the-source-actually-teaches/0582a05f-42f3-4b97-8512-9c2133603126.svg tags: ["typescript", "llm", "ai-agents", "ai-engineering", "claude-code"] +glossary: false cuid: cmng6ranm00wj1qkxcebmdpiy --- Let me start with the honest version of what happened. diff --git a/content/blog/docker-mcp-catalog.md b/content/blog/docker-mcp-catalog.md index 042727153..46dfa33eb 100644 --- a/content/blog/docker-mcp-catalog.md +++ b/content/blog/docker-mcp-catalog.md @@ -7,6 +7,7 @@ slug: docker-mcp-catalog author: saloni-narang cover: /img/blog/docker-mcp-catalog/dbdb9d02-71cb-42b5-b660-68290ac7d695.png tags: ["ai", "docker", "docker-images", "docker-desktop", "llm", "mcp"] +glossary: false cuid: cmcd2f66f000u02l45g9529xf --- As large language models (LLMs) evolve from static text generators to dynamic agents capable of executing actions, there's a growing need for a standardized way to let them interact with external tooling securely. That’s where [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) steps in, a protocol designed to turn your existing APIs into AI-accessible tools. Think of MCP as the missing middleware between LLMs and the real-world functionality you’ve already built. Instead of doing the prompt hacks or building custom plugins for each model, MCP allows you to define your capabilities as structured tools that any compliant AI client can discover, invoke, and interact with safely and predictably. While the protocol is still maturing and the documentation can be opaque, the underlying value is clear: MCP turns your backend into a toolbox for AI agents. Whether you're integrating scraping APIs, financial services, or internal business logic, MCP offers a portable, reusable, and scalable pattern for AI integrations. In this blog, we’ll walk through Docker Desktop's latest MCP client-server feature and explore how you can install an MCP server and use that directly from your LLM tool. diff --git a/content/blog/k8sgpt-tutorial-when-kubernetes-meets-ai.md b/content/blog/k8sgpt-tutorial-when-kubernetes-meets-ai.md index 06723d7a9..5e9742d43 100644 --- a/content/blog/k8sgpt-tutorial-when-kubernetes-meets-ai.md +++ b/content/blog/k8sgpt-tutorial-when-kubernetes-meets-ai.md @@ -7,6 +7,7 @@ slug: k8sgpt-tutorial-when-kubernetes-meets-ai author: kunal-verma cover: /img/blog/k8sgpt-tutorial-when-kubernetes-meets-ai/cc4d6ad6-1b11-45ef-9e94-9e9ad31251aa.png tags: ["ai", "kubernetes", "openai", "llm", "ollama"] +glossary: false cuid: clz9trn19000409mi6km2cpkh --- We all agree that in recent years, AI has taken the world by storm. With tools like ChatGPT and platforms developed by OpenAI leading the charge — AI is being used in many industries to make work easier, provide helpful insights, and boost productivity. According to [The State of AI 2023 by McKinsey](https://www.mckinsey.com/~/media/mckinsey/business%20functions/quantumblack/our%20insights/the%20state%20of%20ai%20in%202023%20generative%20ais%20breakout%20year/the-state-of-ai-in-2023-generative-ais-breakout-year_vf.pdf), AI adoption has increased by over 60% in the past year alone, with businesses using AI to stay ahead and innovate! diff --git a/content/blog/local-llm-glossary.md b/content/blog/local-llm-glossary.md new file mode 100644 index 000000000..3c55763e7 --- /dev/null +++ b/content/blog/local-llm-glossary.md @@ -0,0 +1,231 @@ +--- +title: "The Local LLM Glossary: Every Term, Flag, and Number in Plain English" +seoTitle: "Local LLM Glossary: Prefill, Decode, FP8, KV Cache, MTP Explained" +seoDescription: "Plain-English definitions for every term you hit in local LLM posts: prefill and decode, tokens per second, FP8 and NVFP4, Q4_K_M, KV cache, YaRN, Gated DeltaNet, speculative decoding, and every vLLM, llama.cpp, and Ollama flag worth knowing." +datePublished: 2026-08-18T09:00:00.000Z +slug: local-llm-glossary +author: saiyam-pathak +cover: /img/blog/local-llm-glossary/cover.png +tags: ["local-ai", "llm", "inference", "nvidia", "dgxspark", "vllm", "ollama", "quantization", "glossary"] +glossary: false +faq: + - q: "What is the difference between prefill and decode?" + a: "Prefill is the model reading your prompt. It processes every input token in parallel, so it is fast and measured in the hundreds or thousands of tokens per second. Decode is the model writing its answer, one token at a time, where each token has to wait for the one before it. Decode is almost always the slower number and the one you feel while waiting for a reply." + - q: "Why is my local model slower than the tokens-per-second number someone posted?" + a: "Almost always one of four things: they ran a smaller quantization so fewer gigabytes stream per token, they had speculative decoding on and you do not, they measured aggregate throughput across many concurrent requests instead of a single stream, or their workload was edit-heavy where a draft model gets accepted most of the time. A tokens-per-second number without its quantization, concurrency, and workload attached does not mean much." + - q: "What does Q4_K_M actually mean?" + a: "Q4 is 4 bits per weight, K means llama.cpp's K-quant layout where weights are grouped into super-blocks of 256 with per-block scales rather than one scale per tensor, and M is the medium size tier, which keeps a few important tensors at higher precision. Bigger tier letters (L, XL) spend more bits on the tensors that matter most and produce a slightly larger, slightly better file." + - q: "How much memory does a model need?" + a: "Start with bytes per parameter times parameter count: BF16 is 2 bytes, FP8 is 1 byte, 4-bit formats are roughly half a byte. A 27B model is therefore about 54GB in BF16, 27GB in FP8, and 16 to 18GB at 4-bit. Then add the KV cache, which grows with context length and concurrent requests, and leave headroom for the runtime itself." +--- + +Every local LLM post, mine included, is full of shorthand: `pp2048`, `tg128`, FP8, `UD-Q4_K_XL`, KV cache, `gpu_memory_utilization: 0.8`, MTP, YaRN. If you live in this world daily it reads fine. If you do not, it reads like a wall of magic strings. + +So here is the glossary. Every term, flag, and number that shows up across the local LLM and DGX Spark posts on this blog, explained in plain English, with the reason it matters rather than just the expansion of the acronym. + +You do not need to read this top to bottom. Ctrl+F the thing that confused you, get your answer, go back to the post you came from. + +## Start here: the two halves of every request + +Almost everything in this glossary makes more sense once you have these two words straight. + +**Prefill** (also called prompt processing) is the model reading your input. Every token of your prompt can be processed at the same time, in parallel, because they are all already known. This is why prefill numbers look big: 800 to 4,000 tokens per second is normal on a DGX Spark. + +**Decode** (also called generation) is the model writing its answer. It produces one token, feeds that token back in, produces the next. Each step depends on the one before it, so there is nothing to parallelize. This is why decode numbers look small: 8 to 30 tokens per second for a 27B model on the same box. + +When someone says "the model feels slow," they nearly always mean decode. When someone says "it took ages before anything appeared," they mean prefill. + +[Day 2 of the Local LLM series](/blog/day-2-anatomy-of-an-llm-inference-request-from-prompt-to-answer-step-by-step) walks a single request through both halves step by step if you want the long version. + +## Reading a benchmark table + +**Token.** The unit models actually read and write. Roughly three quarters of an English word on average, so 1,000 tokens is about 750 words. Numbers, code, and punctuation eat more tokens than plain prose. + +**t/s (tokens per second).** The throughput unit for both halves above. Always ask which half it refers to, because prefill t/s and decode t/s can differ by 100x on the same machine. + +**TTFT (time to first token).** How long from pressing enter until the first word appears. Dominated by prefill, so it grows with prompt length. + +**pp512, pp2048.** `pp` is prompt processing, the number is how many tokens of prompt. `pp2048` means "prefill throughput measured on a 2,048 token prompt." These names come from `llama-bench` and stuck as a convention. + +**tg128, tg32.** `tg` is token generation, the number is how many tokens were generated. `tg128` means "decode throughput measured while generating 128 tokens." + +**Depth (context depth).** How much conversation or document was already in the context window before the measurement started. `depth 0` is a cold, empty context. `depth 32768` means the model was already holding 32K tokens. Decode usually slows down as depth grows, and how much it slows is one of the more interesting things about a model's architecture. + +**Concurrency.** How many requests were in flight at once. `c=1` is one user. `c=10` is ten simultaneous requests, which is what serving a team or a fleet of agents actually looks like. + +**Aggregate vs per request.** At concurrency 10 you get two decode numbers. Aggregate is all ten requests added together, which is what a server operator cares about. Per request is what each individual user experiences, which is always lower. A box doing 84 t/s aggregate across 10 users is giving each of them about 9 t/s. + +## Why the numbers come out the way they do + +This is the section that makes bad benchmark numbers stop being mysterious. + +**Memory bandwidth.** How many gigabytes per second the chip can read out of memory. The DGX Spark's GB10 does about 273 GB/s. A discrete RTX PRO 6000 does roughly 6x that. This single number sets the ceiling for decode. + +**Weight streaming.** To produce one token, a dense model has to read every one of its weights out of memory. A 16.7GB model at 273 GB/s can therefore do at most about 16 tokens per second, no matter how fast the compute is. Measured 11.6 t/s against a 16 t/s theoretical ceiling is about 70% of peak, which is what real kernels achieve. + +The mental model I keep coming back to: it is like re-reading an entire book off the shelf before you can write each next word. Your reading speed sets the pace, not how fast you can think. + +**Bandwidth-bound vs compute-bound.** Decode is bandwidth-bound: the chip is waiting on memory, and the tensor cores are mostly idle. Prefill is compute-bound: there is enough parallel work to actually saturate the math units. This is why the same box can look fast and slow within one request, and why halving your model size roughly doubles decode but barely moves prefill. + +**Unified memory.** On the GB10 the CPU and GPU share one pool of memory (128GB, of which about 121.7 GiB is addressable) rather than the GPU having its own separate VRAM. Two consequences: big models fit without a discrete card's memory limit, and every process on the box competes for the same pool. If a llama.cpp container is still holding 18GB, your vLLM launch will fail on memory it can see but not have. + +**VRAM.** The dedicated memory on a discrete GPU. On a unified-memory box like the Spark there is no separate VRAM, which trips up tools that assume there is. + +**Dense vs MoE.** A dense model uses all its parameters for every token. A Mixture of Experts model has many parameters but routes each token through only a few of them, so a 30B MoE with 3B active parameters streams roughly 3B worth of weights per token and feels dramatically faster. This is the whole reason a 30B MoE can hit 100+ t/s on a Spark while a real dense 27B sits at 11. + +**Active parameters.** The subset of an MoE's weights actually used per token. Written like `2.4T-A95B`, meaning 2.4 trillion total parameters, 95 billion active. Active is the number that predicts speed. Total is the number that predicts memory. + +## Quantization: decoding the format names + +Quantization is storing the model's numbers in fewer bits. Fewer bits means fewer gigabytes to stream per token, which means faster decode, at some cost in quality. [Day 4](/blog/day-4-quantization-demystified-bf16-fp8-nvfp4-mxfp4-int4-gguf-and-why-it-all-matters) is the full treatment; this is the lookup table. + +| Format | Bits per weight | What to know | +|---|---|---| +| FP32 | 32 (4 bytes) | Full precision. Almost nobody serves at this. | +| BF16 / FP16 | 16 (2 bytes) | The reference quality. A 27B model is about 54GB. | +| FP8 | 8 (1 byte) | Halves the size with very little quality loss. Native on Hopper and Blackwell. A 27B is about 29GB. | +| INT4 | 4 (0.5 bytes) | Generic 4-bit integer. Quality depends heavily on how it was produced. | +| NVFP4 | 4 | NVIDIA's 4-bit float with fine-grained scaling, with native tensor core support on Blackwell (so on GB10). Usually the best speed on this hardware. | +| MXFP4 | 4 | Open Compute Project's 4-bit micro-scaling float. Same idea, different standard body. | + +**GGUF.** The single-file model format llama.cpp and Ollama use. It packs weights plus metadata plus tokenizer into one file you can move around. Not a precision, a container: a GGUF file also has a quantization type inside it. + +**Q4_K_M, Q4_K_XL and friends.** The llama.cpp quantization naming scheme, three parts stacked: + +- `Q4` is 4 bits per weight. +- `_K` is the K-quant layout. Instead of one scaling factor for a whole tensor, weights are stored in super-blocks of 256 that are split into blocks of 32, each carrying its own quantized scale. Outlier weights then only distort their own block of 32 rather than dragging a whole tensor's precision down. +- The last letter is a size tier: `S` small, `M` medium, `L` large, `XL` extra large. Higher tiers spend extra bits on the tensors that matter most, so the file is a bit bigger and the quality a bit better. + +**UD (Unsloth Dynamic).** A prefix like `UD-Q4_K_XL` means the layers were deliberately not all quantized to the same width. Embeddings and the first and last blocks keep more bits because everything downstream depends on them, while the more redundant middle feed-forward layers get squeezed harder. The result holds up better than a uniform 4-bit quant of the same file size. + +**Checkpoint.** A published set of weights, usually a Hugging Face repo at a specific revision. "The official FP8 checkpoint" means the model author's own FP8 publication, as opposed to a community requantization. + +**Marlin.** A family of fast GPU kernels for quantized matrix multiplication in vLLM. `VLLM_MARLIN_USE_ATOMIC_ADD: '1'` switches those kernels to atomic accumulation, which is a correctness and performance workaround on some GPU and shape combinations. It is the kind of environment variable you copy from a working recipe rather than derive. + +**Bytes per parameter arithmetic.** The one calculation worth memorizing: parameters times bytes per parameter equals weight size. 27B at FP8 is about 27GB, at 4-bit about 16GB, at BF16 about 54GB. Then add KV cache and runtime overhead on top. + +## Context, attention, and the KV cache + +**Context window.** The maximum number of tokens the model can have in front of it at once, prompt plus generated output plus any system message. 262,144 tokens is a large modern window, and it is often quoted as "262K" or "256K" loosely. + +**KV cache.** As the model reads your prompt, each attention layer computes key and value vectors per token, and caches them so it does not recompute them for every subsequent token. Very effective, but the cache grows linearly with context length and with the number of concurrent requests, and it lives in the same memory pool as the weights. Long contexts and many users both eat memory here, not in the weights. + +**KV cache dtype.** The precision the cache is stored at. Storing it at `fp8` instead of 16-bit roughly halves cache memory, letting you serve longer contexts or more users on the same box, at a small accuracy cost. + +**Prefix caching.** If two requests share the same beginning (a system prompt, a document, a conversation so far), the runtime can reuse the KV cache from the shared part instead of prefilling it again. Enormous win for chat and agent workloads where 90% of every request is the same prefix. In vLLM this is `--enable-prefix-caching`. + +**Attention.** The mechanism that lets each token look at the other tokens in context and decide what is relevant. Standard ("full") attention lets every token look at every previous token, which is powerful and gets more expensive as context grows. + +**Flash attention.** A way of computing attention that avoids writing the giant intermediate attention matrix to memory, making it much faster and much cheaper in memory. Effectively always worth turning on: `-fa on` in llama.cpp. + +**Attention backend.** Which implementation of attention the serving engine actually calls. In vLLM you might see `flashinfer`, `flash_attn`, or `xformers`. **FlashInfer** is a library of highly tuned attention and GEMM kernels; on the Spark's `sm121` architecture it picks the `xqa` decode kernel and supports an FP8 KV cache. Different backends can differ by 2x on the same hardware, which is why recipes pin one. + +**Linear attention.** An alternative that keeps a fixed-size running state instead of a cache that grows with every token. Cheaper and flat in context length, but with less precise recall than full attention. Modern models often use a hybrid: a few full attention layers for precise recall, the rest linear. + +**Gated DeltaNet.** The specific linear attention design used by recent Qwen models. The *gate* decides how fast old memory fades, and the *delta rule* writes targeted corrections into the fixed-size state rather than appending to an ever-growing list. The state is the same size at token 100,000 as it is at token 10, which is exactly why decode speed on these models barely sags as context grows. In Qwen3.8-27B, 48 of 64 layers are Gated DeltaNet and every 4th layer is full gated attention. + +**RoPE (Rotary Position Embedding).** How most models encode *where* a token sits in the sequence, by rotating the token's vector by an angle that depends on its position. Positions the model never saw in training land at angles it does not understand, which is why context windows have a hard native limit. + +**YaRN (Yet another RoPE extensioN).** A technique for stretching that limit. It rescales the positional frequencies, stretching each one differently depending on its wavelength, so the model can address positions well beyond its training range without a full retrain. "262K native, extensible to 1M with YaRN" means the extra range is available but is an extension, not a native capability. + +**Vision encoder and mmproj.** A vision language model ships a separate encoder that turns images into tokens the language model can read. In GGUF land that encoder is a companion file called `mmproj` (multimodal projector). No `mmproj`, no images, even if the model is capable of them. + +**Thinking mode.** Models that emit reasoning inside `` blocks before their actual answer. Better on hard problems, more tokens spent, so slower and more expensive per reply. Vendors publish different recommended sampling settings for thinking and non-thinking modes. + +**Reasoning parser and tool call parser.** Server-side parsers that pull those `` blocks and any tool or function calls out of the raw token stream and put them in the right fields of the OpenAI-compatible API response. Wrong parser and your client sees reasoning text glued into the answer, or tool calls it cannot recognize. These are per model family: `reasoning_parser: qwen3`, `tool_call_parser: qwen3_coder`. + +## Speed tricks + +**Batching / continuous batching.** Running several requests through one pass over the weights. Since decode is bandwidth-bound, one weight-streaming pass can feed 10 tokens for 10 different users at almost the cost of feeding 1. This is why aggregate throughput climbs with concurrency while per-user throughput barely drops, and it is the main thing production servers like vLLM and SGLang buy you over single-user tools. + +**Speculative decoding.** A cheap model guesses the next few tokens, the real model verifies them all in one pass. Correct guesses are free tokens; wrong ones are discarded, so the output is identical to what the big model would have produced on its own. No quality risk, real speedup. + +**Draft model.** The cheap guesser in that scheme, a small separate model. "DSpark" is a community-built 5-layer, ~2.6GB drafter for Qwen3.8-27B. + +**MTP (Multi-Token Prediction).** The same trick with no separate model: the big model ships an extra head trained to predict several tokens ahead, and drafts for itself. Cheaper to deploy than a draft model since there is nothing extra to load. When Ollama serves a model 2x faster than llama.cpp on the same quantization, MTP being on by default is usually the reason. + +**NEXTN.** SGLang's name for its MTP-style speculative path. Same idea, different engine. + +**Acceptance rate.** The fraction of drafted tokens the real model accepts. This is the whole ballgame for speculative decoding, and it is a property of *your workload*, not of the model. Editing existing code, where the draft mostly copies text already in the prompt, can hit 98% acceptance and 3x speedups. Writing fresh prose or new code, where the drafter is genuinely guessing, might hit 30%. This is why a tokens-per-second number without its workload attached is close to meaningless. + +**k / num_speculative_tokens.** How many tokens the drafter proposes per round. Higher k pays off when acceptance is high and wastes work when it is low. + +**Tensor parallel (TP).** Splitting each layer's matrices across multiple GPUs so they all work on every token together. Needs fast interconnect between the cards. `tensor_parallel_size: 2` means two GPUs. + +**Pipeline parallel (PP).** Splitting the model by layer, so GPU 0 runs the first half and GPU 1 the second. Tolerates slower interconnect, but one card is idle while the other works unless you keep several requests in flight. + +## The flags you copy-paste + +### vLLM and sparkrun recipes + +A [sparkrun](https://sparkrun.dev) recipe is a YAML file that pins a model, a container, and the serving flags, so a working setup is one file rather than an afternoon of dependency fighting. The `defaults:` block is vLLM server arguments, and `env:` is environment variables passed into the container. + +| Key | What it does | How to think about it | +|---|---|---| +| `gpu_memory_utilization: 0.8` | The share of GPU memory vLLM is allowed to claim up front, for weights plus KV cache | Higher means more KV cache, so longer contexts and more concurrent users. Too high and the launch fails or something else on the box starves. On unified memory, remember other processes share the pool. | +| `max_model_len: 131072` | The maximum context length the server will accept, in tokens | Can be lower than the model's native window, and often should be: every token of headroom you reserve costs KV cache memory. 131072 is 128K. | +| `max_num_batched_tokens: 32768` | Cap on how many tokens the scheduler puts into one forward pass | Bigger batches mean better prefill throughput and chunkier latency. This is the prefill throughput vs responsiveness dial. | +| `load_format: instanttensor` | How weights are read off disk into memory | `instanttensor` is a fast-load path that gets a 29GB checkpoint resident in seconds once cached, instead of minutes. Pure startup time, no runtime effect. | +| `kv_cache_dtype: fp8` | Precision of the KV cache | Roughly halves cache memory versus 16-bit, so you fit longer contexts or more users. Small accuracy cost. | +| `attention_backend: flashinfer` | Which attention kernel library to use | On the Spark's `sm121`, FlashInfer gets the fast decode path and FP8 KV cache support. | +| `tool_call_parser: qwen3_coder` | Extracts tool and function calls from the token stream | Must match the model family, or your agent framework sees plain text where it expected a structured call. | +| `reasoning_parser: qwen3` | Extracts `` blocks into the response's reasoning field | Must match the model family, or reasoning text leaks into the answer. | +| `VLLM_MARLIN_USE_ATOMIC_ADD: '1'` | Environment variable switching Marlin quantized kernels to atomic accumulation | A hardware-specific workaround. Copy it from a working recipe. | +| `--enable-prefix-caching` | Reuses KV cache across requests that share a prefix | Big win for chat and agents, effectively free. | +| `speculative_config` | Turns on speculative decoding, e.g. `{"method": "mtp", "num_speculative_tokens": 3}` | See MTP and acceptance rate above. | + +### llama.cpp + +| Flag | What it does | +|---|---| +| `-hf :` | Pulls the GGUF straight from Hugging Face. Note recent builds cache into `/root/.cache/huggingface`, not the old `llama.cpp` path, which matters when you mount a volume. | +| `-ngl 99` | Number of layers to offload to the GPU. 99 is the idiomatic "all of them," since anything left on the CPU is dramatically slower. | +| `-c 32768` | Context size in tokens for this server instance. Larger costs KV cache memory. | +| `-fa on` / `-fa 1` | Flash attention. Turn it on. | +| `--host 0.0.0.0 --port 8091` | Bind address and port for the OpenAI-compatible server. | +| `mmproj-*.gguf` | The vision projector file. Present in the repo means images work. | + +`llama-bench` is llama.cpp's built-in benchmark, and it is where `pp512`/`tg128` style names come from. + +### Ollama + +| Thing | What it does | +|---|---| +| `num_ctx` | Context size, Ollama's equivalent of `-c`. Ollama picks a default from available memory. | +| `num_predict` | Maximum tokens to generate in a reply. | +| `ollama ps` | Shows loaded models and, critically, whether they are on GPU. If it says anything less than `100% GPU`, your benchmark is measuring the CPU and will be 3 to 5x too slow. | +| `prompt_eval_count` / `eval_count` | Ollama's own counters for prompt tokens and generated tokens, with matching `_duration` fields in nanoseconds. Divide to get t/s. | + +### Sampling knobs + +These control how the next token is picked from the model's probability distribution. They change output style, not speed. + +- **temperature.** How much randomness. 0 is deterministic and repetitive, 1.0 is creative, above about 1.2 usually becomes incoherent. Use 0 when benchmarking so runs are comparable. +- **top_p (nucleus sampling).** Only consider tokens inside the top cumulative probability mass, e.g. 0.95. Cuts off the long tail of unlikely tokens. +- **top_k.** Only consider the k most likely tokens, e.g. 20. + +Model authors publish recommended values per mode, and it is worth using theirs. Qwen3.8's thinking mode wants temp 1.0 / top_p 0.95 / top_k 20, non-thinking wants temp 0.7 / top_p 0.80. + +## Hardware words + +**GB10.** The Grace Blackwell superchip inside the DGX Spark: Arm CPU plus Blackwell GPU plus 128GB of unified LPDDR5X at about 273 GB/s. + +**sm_121 / compute capability.** NVIDIA's architecture version tag for a GPU. GB10 is `sm_121`. Kernels have to be compiled for your architecture, so "supports sm121" in a release note is the difference between working and not. [Day 3](/blog/day-3-the-dgx-spark-unpacked-gb10-unified-memory-sm-121-and-the-one-reason-this-hardware-exists) covers the Spark's hardware story in detail. + +**Tensor cores.** The dedicated matrix multiply units. Which precisions they support natively (FP8 and FP4 on Blackwell) decides which quantization is genuinely fast rather than merely smaller. + +**GB vs GiB.** GB is 1,000^3 bytes, GiB is 1,024^3. A "128GB" box reports about 119 GiB, and vendors and tools mix the two freely. When a number looks 7% off, this is usually why. + +**`nvidia-smi` on GB10.** Cannot report memory usage on this chip and prints `Not Supported`. Use `free -h`, since the memory is unified anyway. + +## Where to go next + +If you want these terms in context rather than as a list, the Local LLM series builds them up in order: + +- [Day 1: The Local LLM Revolution](/blog/day-1-the-local-llm-revolution-why-your-desk-just-became-the-new-datacenter), why running models locally became viable at all +- [Day 2: Anatomy of an LLM Inference Request](/blog/day-2-anatomy-of-an-llm-inference-request-from-prompt-to-answer-step-by-step), prefill and decode end to end +- [Day 3: The DGX Spark Unpacked](/blog/day-3-the-dgx-spark-unpacked-gb10-unified-memory-sm-121-and-the-one-reason-this-hardware-exists), the hardware and why bandwidth rules everything +- [Day 4: Quantization Demystified](/blog/day-4-quantization-demystified-bf16-fp8-nvfp4-mxfp4-int4-gguf-and-why-it-all-matters), every format name in depth +- [Day 5: Inference Engines and What to Pick](/blog/day-5-local-llm-inference-engines-wrappers-and-what-to-pick), Ollama vs llama.cpp vs vLLM vs SGLang + +And if a term bit you that is not defined here, tell me and I will add it. That is what this page is for. diff --git a/content/blog/qwen3-8-27b-on-dgx-spark.md b/content/blog/qwen3-8-27b-on-dgx-spark.md index 029cfdb7e..0aca58c8d 100644 --- a/content/blog/qwen3-8-27b-on-dgx-spark.md +++ b/content/blog/qwen3-8-27b-on-dgx-spark.md @@ -53,6 +53,8 @@ curl -s http://127.0.0.1:11435/api/generate -d '{"model":"qwen3.8:27b", python3 edit_bench.py http://127.0.0.1:8002/v1 qwen3.8-27b # from 0xBakeer's repo, bench/ ``` +Two words to have straight before the tables below, because every number in this post is one or the other. **Prefill** is the model reading your prompt: all the input tokens get processed in parallel, so it is fast, hundreds to thousands of tokens per second. **Decode** is the model writing its answer one token at a time, each token waiting on the one before it, so it is slow, single or low double digits here. Prefill is the wait before the first word appears; decode is the speed you watch it type at. In benchmark names, `pp2048` is prefill measured on a 2,048 token prompt and `tg128` is decode measured over 128 generated tokens. Anything else that reads like a magic string in this post is in the [local LLM glossary](/blog/local-llm-glossary). + ## What Qwen3.8-27B actually is Reading the config before running things saves a lot of confusion, and this one is interesting: @@ -90,10 +92,12 @@ docker run -d --name qwen38-llamacpp --gpus all -p 8091:8091 \ --port 8091 --host 0.0.0.0 -ngl 99 -c 32768 -fa on ``` +Three of those flags do the heavy lifting: `-ngl 99` offloads all layers to the GPU (99 is the idiomatic "all of them", and anything left on the CPU is dramatically slower), `-c 32768` sets the context window to 32K tokens, and `-fa on` enables flash attention, which computes attention without materializing the giant intermediate matrix in memory. That last one is free speed, leave it on. + Two gotchas I hit so you do not have to: 1. Recent llama.cpp downloads `-hf` models into the Hugging Face hub cache (`/root/.cache/huggingface`), not the old `/root/.cache/llama.cpp` path. Mount the right one or your 18GB download disappears with the container. -2. The GGUF repo ships `mmproj-BF16.gguf` alongside the weights (llama.cpp pulled it automatically), so the vision path is wired up for llama.cpp as well. I test it below. +2. The GGUF repo ships `mmproj-BF16.gguf` alongside the weights (llama.cpp pulled it automatically), so the vision path is wired up for llama.cpp as well. `mmproj` is the multimodal projector, the companion file that turns images into tokens the language model can read: no mmproj, no images, however capable the model is. I test it below. First token arrives fast and the model correctly identified what it was running on (a nice recursive moment: Qwen3.8-27B on a DGX Spark explaining what a DGX Spark is). @@ -136,6 +140,20 @@ env: VLLM_MARLIN_USE_ATOMIC_ADD: '1' ``` +That is a lot of magic strings in twelve lines, so here is what each one is actually doing, because these are the knobs you will end up turning yourself: + +| Setting | What it does | Why this value | +|---|---|---| +| `gpu_memory_utilization: 0.8` | The share of memory vLLM claims up front, for weights plus KV cache | Higher means more KV cache, so longer contexts and more concurrent users. On unified memory you cannot go greedy: everything else on the box shares this pool. | +| `max_model_len: 131072` | Longest context the server will accept, in tokens | 128K, well under the model's native 262K. Every token of headroom you reserve costs KV cache memory, and I would rather have the memory. | +| `max_num_batched_tokens: 32768` | Cap on tokens the scheduler puts in one forward pass | The prefill-throughput vs responsiveness dial. Bigger batches process prompts faster and make latency chunkier. | +| `load_format: instanttensor` | How the weights get off disk and into memory | Pure startup time. It is why a 29GB checkpoint is resident in under 5 seconds once cached instead of minutes. | +| `kv_cache_dtype: fp8` | Precision the KV cache is stored at | Roughly halves cache memory versus 16-bit, which is what buys the long-context headroom. Small accuracy cost. | +| `attention_backend: flashinfer` | Which attention kernel library runs | On `sm121` FlashInfer picks the `xqa` decode kernel and supports the FP8 cache above. Backends can differ by 2x, which is why recipes pin one. | +| `tool_call_parser: qwen3_coder` | Pulls tool and function calls out of the raw token stream | Has to match the model family, or your agent framework sees plain text where it expected a structured call. | +| `reasoning_parser: qwen3` | Pulls `` blocks into the response's reasoning field | Same story: wrong parser and reasoning text leaks into the answer. | +| `VLLM_MARLIN_USE_ATOMIC_ADD: '1'` | Switches Marlin's quantized kernels to atomic accumulation | A hardware-specific workaround. This one you copy from a working recipe rather than derive. | + Then: ```bash @@ -178,7 +196,7 @@ This is what day zero actually looks like: the happy paths work because the arch ## NVFP4: the best-numbers recipe -GB10 is a Blackwell chip, and Blackwell has native FP4 tensor cores, so the natural question is whether the NVFP4 quant (unsloth/Qwen3.8-27B-NVFP4, ~16GB) buys real speed. Same recipe as above with the model swapped, and FlashInfer autotuned 46 fp4_gemm kernel configs on first boot. It does: +GB10 is a Blackwell chip, and Blackwell has native FP4 tensor cores (NVFP4 being NVIDIA's 4-bit float format, covered properly in [Day 4](/blog/day-4-quantization-demystified-bf16-fp8-nvfp4-mxfp4-int4-gguf-and-why-it-all-matters)), so the natural question is whether the NVFP4 quant (unsloth/Qwen3.8-27B-NVFP4, ~16GB) buys real speed. Same recipe as above with the model swapped, and FlashInfer autotuned 46 fp4_gemm kernel configs on first boot. It does: | Concurrency | Prefill pp2048 (t/s) | Decode tg128 aggregate (t/s) | Decode per request (t/s) | |---|---|---|---| diff --git a/content/blog/ssh-into-your-dgx-spark-from-anywhere-in-the-world-using-tailscale.md b/content/blog/ssh-into-your-dgx-spark-from-anywhere-in-the-world-using-tailscale.md index c39e12324..f655910a5 100644 --- a/content/blog/ssh-into-your-dgx-spark-from-anywhere-in-the-world-using-tailscale.md +++ b/content/blog/ssh-into-your-dgx-spark-from-anywhere-in-the-world-using-tailscale.md @@ -7,6 +7,7 @@ slug: ssh-into-your-dgx-spark-from-anywhere-in-the-world-using-tailscale author: saiyam-pathak cover: /img/blog/ssh-into-your-dgx-spark-from-anywhere-in-the-world-using-tailscale/73a73de4-7383-44be-8853-78e3cf47b306.png tags: ["kubernetes", "devops", "ssh", "nvidia", "tailscale", "dgxspark"] +glossary: false cuid: cmnokj01r00j21qqe2j8dcmcj --- * * * diff --git a/lib/_blog-feed-data.js b/lib/_blog-feed-data.js index 077d2a5d4..434f3996b 100644 --- a/lib/_blog-feed-data.js +++ b/lib/_blog-feed-data.js @@ -1,5 +1,41 @@ // AUTO-GENERATED by scripts/generate-feeds.mjs. Do not edit by hand. export const FEED_POSTS = [ + { + "slug": "local-llm-glossary", + "title": "The Local LLM Glossary: Every Term, Flag, and Number in Plain English", + "description": "Plain-English definitions for every term you hit in local LLM posts: prefill and decode, tokens per second, FP8 and NVFP4, Q4_K_M, KV cache, YaRN, Gated DeltaNet, speculative decoding, and every vLLM, llama.cpp, and Ollama flag worth knowing.", + "datePublished": "2026-08-18T09:00:00.000Z", + "cover": "/img/blog/local-llm-glossary/cover.png", + "tags": [ + "local-ai", + "llm", + "inference" + ] + }, + { + "slug": "qwen3-8-27b-on-dgx-spark", + "title": "Running Qwen3.8-27B on DGX Spark", + "description": "Qwen3.8-27B on DGX Spark with llama.cpp, Ollama, vLLM, and SGLang: the recipes, the tokens per second I measured, MTP speculative decoding, and the sharp edges I hit along the way.", + "datePublished": "2026-08-17T14:00:00.000Z", + "cover": "/img/blog/qwen3-8-27b-on-dgx-spark/cover.png", + "tags": [ + "qwen", + "dgxspark", + "nvidia" + ] + }, + { + "slug": "nudgebee-ai-sre-copilot-hands-on", + "title": "I Ran an AI SRE Copilot on My Own Hardware. Here Is What It Actually Does.", + "description": "Running NudgeBee v1.4.0 end to end - a self-hosted AIOps platform behind AI-SRE, AI-FinOps, AI-K8sOps, and agentic automation - on a Mac, a kiac cluster, and a DGX Spark.", + "datePublished": "2026-08-17T10:00:00.000Z", + "cover": "/img/blog/nudgebee-ai-sre-copilot-hands-on/cover.png", + "tags": [ + "kubernetes", + "ai", + "sre" + ] + }, { "slug": "nemotron-3-5-lightning-on-dgx-spark", "title": "Running Nemotron 3.5 Lightning on DGX Spark", @@ -15,7 +51,7 @@ export const FEED_POSTS = [ { "slug": "dynamic-mig-in-kubernetes-with-hami", "title": "HAMi Dynamic MIG on RTX PRO 6000: A Live Kubernetes Test", - "description": "A hands-on test of topology-aware HAMi Dynamic MIG on RTX PRO 6000 Blackwell, with pinned setup commands, real allocations, mixed profiles, reclamation, and recovery.", + "description": "Hands-on HAMi Dynamic MIG test on Kubernetes and RTX PRO 6000 Blackwell: setup commands, real allocations, mixed profiles, reclamation, and recovery.", "datePublished": "2026-08-11T10:00:00.000Z", "cover": "/img/blog/dynamic-mig-in-kubernetes-with-hami/cover.png", "tags": [ @@ -319,41 +355,5 @@ export const FEED_POSTS = [ "dockerfile", "docker-images" ] - }, - { - "slug": "kubectl-run-nginx-inside", - "title": "What Actually Happens When You Run kubectl run nginx", - "description": "Every step of what happens when you run kubectl run nginx on Kubernetes. From argv to etcd Raft, scheduler, CRI, CNI, runc, and PLEG.", - "datePublished": "2026-04-24T11:30:41.065Z", - "cover": "/img/blog/kubectl-run-nginx-inside/aa7ec61b-b806-4e12-87e5-58c51b8a94d7.png", - "tags": [ - "kubernetes", - "devops", - "containers" - ] - }, - { - "slug": "day-2-your-images-are-a-supply-chain-and-it-s-probably-broken", - "title": "Day 2: Your Images Are a Supply Chain - and It's Probably Broken", - "description": "", - "datePublished": "2026-04-23T09:33:10.632Z", - "cover": "/img/blog/day-2-your-images-are-a-supply-chain-and-it-s-probably-broken/c66a8641-54fb-436f-bdbe-61d55c8d22e0.png", - "tags": [ - "docker", - "opensource", - "2025toptools" - ] - }, - { - "slug": "day-1-what-actually-happens-when-you-type-docker-run", - "title": "Day 1: What Actually Happens When You Type docker run", - "description": "Containers aren't VMs. They're Linux processes. A Docker Captain explains namespaces, cgroups, and how Docker really works on your Mac in 2026. ", - "datePublished": "2026-04-22T10:38:27.885Z", - "cover": "/img/blog/day-1-what-actually-happens-when-you-type-docker-run/2f51276b-c5fb-4038-ac4d-939c7cbb4816.png", - "tags": [ - "linux", - "docker", - "devops" - ] } ]; diff --git a/lib/blog.js b/lib/blog.js index 4f809c728..aec3a3d2e 100644 --- a/lib/blog.js +++ b/lib/blog.js @@ -93,6 +93,9 @@ function loadAll() { author: authors[0], authors, sponsor: data.sponsor || null, + // Opt in/out of the "new to these terms?" glossary line at the top of + // the post. Undefined means "decide from tags" (see lib/glossary.js). + glossary: typeof data.glossary === 'boolean' ? data.glossary : null, // Optional AEO block: frontmatter `faq:` list of {q, a} renders an // FAQ section + FAQPage JSON-LD (extractable by answer engines). faq: Array.isArray(data.faq) diff --git a/lib/glossary.js b/lib/glossary.js new file mode 100644 index 000000000..946f21d42 --- /dev/null +++ b/lib/glossary.js @@ -0,0 +1,26 @@ +// The glossary line that appears at the top of jargon-heavy posts. +// +// A post shows it when its tags overlap GLOSSARY_TAGS, unless frontmatter says +// otherwise: `glossary: false` suppresses it (the glossary post itself does +// this), `glossary: true` forces it on for a post whose tags do not match. +// +// Adding a second glossary later: make this a list and match per topic. + +export const GLOSSARY_SLUG = 'local-llm-glossary'; + +const GLOSSARY_TAGS = new Set([ + 'llm', + 'local-ai', + 'inference', + 'dgxspark', + 'ollama', + 'vllm', + 'quantization', +]); + +export function showsGlossaryLink(post) { + if (!post || post.slug === GLOSSARY_SLUG) return false; + if (post.glossary === false) return false; + if (post.glossary === true) return true; + return post.tags.some((t) => GLOSSARY_TAGS.has(t)); +} diff --git a/public/_redirects b/public/_redirects index 99b953f96..bff5d41f7 100644 --- a/public/_redirects +++ b/public/_redirects @@ -148,6 +148,7 @@ /blog/linux-boot-process-simplified /linux-boot-process-simplified 301! /blog/linux-system-directories-explained /linux-system-directories-explained 301! /blog/llm-costs-and-observability-with-agentgateway-on-kubernetes /llm-costs-and-observability-with-agentgateway-on-kubernetes 301! +/blog/local-llm-glossary /local-llm-glossary 301! /blog/managing-contexts-in-kubernetes-with-plugins /managing-contexts-in-kubernetes-with-plugins 301! /blog/managing-your-operating-system-with-package-managers /managing-your-operating-system-with-package-managers 301! /blog/mastering-kubernetes-costs-from-monitoring-to-automation /mastering-kubernetes-costs-from-monitoring-to-automation 301! @@ -165,6 +166,7 @@ /blog/nemotron3-on-dgx-spark /nemotron3-on-dgx-spark 301! /blog/networking-fundamentals-for-devops /networking-fundamentals-for-devops 301! /blog/nexus-repository-manager-what-is-it-and-how-to-configure-it-on-a-digital-ocean-droplet /nexus-repository-manager-what-is-it-and-how-to-configure-it-on-a-digital-ocean-droplet 301! +/blog/nudgebee-ai-sre-copilot-hands-on /nudgebee-ai-sre-copilot-hands-on 301! /blog/nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform /nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform 301! /blog/operating-systems-101-essential-knowledge-for-devopssre-engineers /operating-systems-101-essential-knowledge-for-devopssre-engineers 301! /blog/optimizing-kubernetes-costs-balancing-spot-and-on-demand-instances-with-topology-spread-constraints /optimizing-kubernetes-costs-balancing-spot-and-on-demand-instances-with-topology-spread-constraints 301! @@ -178,6 +180,7 @@ /blog/prometheus-explained /prometheus-explained 301! /blog/pure-cilium-a-guide-for-local-load-balancing-and-bgp /pure-cilium-a-guide-for-local-load-balancing-and-bgp 301! /blog/quick-bites-of-fluxcd-health-assessment /quick-bites-of-fluxcd-health-assessment 301! +/blog/qwen3-8-27b-on-dgx-spark /qwen3-8-27b-on-dgx-spark 301! /blog/rancher-desktop-evolution /rancher-desktop-evolution 301! /blog/ready-for-wasm-day-2023 /ready-for-wasm-day-2023 301! /blog/sharing-gpus-in-kubernetes-with-hami /sharing-gpus-in-kubernetes-with-hami 301! @@ -370,6 +373,7 @@ /linux-boot-process-simplified /blog/linux-boot-process-simplified 200! /linux-system-directories-explained /blog/linux-system-directories-explained 200! /llm-costs-and-observability-with-agentgateway-on-kubernetes /blog/llm-costs-and-observability-with-agentgateway-on-kubernetes 200! +/local-llm-glossary /blog/local-llm-glossary 200! /managing-contexts-in-kubernetes-with-plugins /blog/managing-contexts-in-kubernetes-with-plugins 200! /managing-your-operating-system-with-package-managers /blog/managing-your-operating-system-with-package-managers 200! /mastering-kubernetes-costs-from-monitoring-to-automation /blog/mastering-kubernetes-costs-from-monitoring-to-automation 200! @@ -387,6 +391,7 @@ /nemotron3-on-dgx-spark /blog/nemotron3-on-dgx-spark 200! /networking-fundamentals-for-devops /blog/networking-fundamentals-for-devops 200! /nexus-repository-manager-what-is-it-and-how-to-configure-it-on-a-digital-ocean-droplet /blog/nexus-repository-manager-what-is-it-and-how-to-configure-it-on-a-digital-ocean-droplet 200! +/nudgebee-ai-sre-copilot-hands-on /blog/nudgebee-ai-sre-copilot-hands-on 200! /nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform /blog/nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform 200! /operating-systems-101-essential-knowledge-for-devopssre-engineers /blog/operating-systems-101-essential-knowledge-for-devopssre-engineers 200! /optimizing-kubernetes-costs-balancing-spot-and-on-demand-instances-with-topology-spread-constraints /blog/optimizing-kubernetes-costs-balancing-spot-and-on-demand-instances-with-topology-spread-constraints 200! @@ -400,6 +405,7 @@ /prometheus-explained /blog/prometheus-explained 200! /pure-cilium-a-guide-for-local-load-balancing-and-bgp /blog/pure-cilium-a-guide-for-local-load-balancing-and-bgp 200! /quick-bites-of-fluxcd-health-assessment /blog/quick-bites-of-fluxcd-health-assessment 200! +/qwen3-8-27b-on-dgx-spark /blog/qwen3-8-27b-on-dgx-spark 200! /rancher-desktop-evolution /blog/rancher-desktop-evolution 200! /ready-for-wasm-day-2023 /blog/ready-for-wasm-day-2023 200! /sharing-gpus-in-kubernetes-with-hami /blog/sharing-gpus-in-kubernetes-with-hami 200! diff --git a/public/_worker.js b/public/_worker.js index d11eef311..f13b5074b 100644 --- a/public/_worker.js +++ b/public/_worker.js @@ -795,7 +795,7 @@ async function handleNewsletterApi(request, env) { const KUBESIMPLIFY_ROUTES = new Set(['/about', '/workshops', '/partnerships', '/resources', '/products', '/learn', '/privacy']); const KUBESIMPLIFY_PREFIXES = ['/products/', '/learn/']; -const BLOG_SLUGS = new Set(["10-things-you-might-not-know-about-k9s","12-practical-grep-command-examples-in-linux","a-beginners-guide-to-dualbooting-windows-with-ubuntu-part-1","a-beginners-guide-to-dualbooting-windows-with-ubuntu-part-2","a-complete-walk-through-of-devops","a-kubeconfig-for-gke-that-doesnt-need-gcloud","a-simple-way-to-structure-your-terraform-code","a-simplified-guide-to-yaml","about-my-pdf-editor-project","an-overview-of-gitops-and-argocd","announcing-buildsafe","api-response-in-go","arkade","automate-repetitive-tasks-shell-scripting","automated-github-releases-with-github-actions-and-conventional-commits","avoid-overspending-with-kubecost","aws-elastic-cloud-compute","bake-your-container-images-with-bake","become-a-hashicorp-certified-terraform-associate-preparation-guide","best-devops-tools-2025","bonsai-27b-rtx-pro-6000-dgx-spark","breaking-down-docker","building-a-zero-cve-strategy","building-apigateway-with-lambda-using-pulumi","certified-kubernetes-security-specialist-cks-2022-exam-guide","cicd-pipeline-github-actions-with-aws-ecs","ckad-exam-april-2022","claude-code-leak-what-the-source-actually-teaches","clawspark-your-private-openclaw-ai-assistant-that-never-phones-home","cloud-computing","cloud-native-buildpacks-concepts","confidential-containers-running-on-kubernetes","container-and-kubernetes-security","controlling-mcp-tools-with-agentgateway-on-kubernetes","coolify","creating-multi-node-kubernetes-cluster-locally","day-1-the-local-llm-revolution-why-your-desk-just-became-the-new-datacenter","day-1-what-actually-happens-when-you-type-docker-run","day-2-anatomy-of-an-llm-inference-request-from-prompt-to-answer-step-by-step","day-2-your-images-are-a-supply-chain-and-it-s-probably-broken","day-3-stop-writing-dockerfiles-from-scratch","day-3-the-dgx-spark-unpacked-gb10-unified-memory-sm-121-and-the-one-reason-this-hardware-exists","day-4-breaking-isolation-on-purpose-volumes-networks-and-the-real-world","day-4-quantization-demystified-bf16-fp8-nvfp4-mxfp4-int4-gguf-and-why-it-all-matters","day-5-docker-compose-how-docker-actually-gets-used","day-5-local-llm-inference-engines-wrappers-and-what-to-pick","day-6-run-an-llm-on-your-laptop-with-docker","day-7-ship-it-and-what-comes-next","deploy-a-maven-project-on-a-tomcat-server-using-jenkins-and-aws","deploy-a-simple-server-using-aws-terraform","deploying-java-application-using-docker-and-kubernetes-devops-project","devin-outposts-on-kubernetes","ditch-the-overheating-laptop-supercharge-your-docker-workflow-with-docker-offload","diy-how-to-build-a-kubernetes-policy-engine","docker-captain-journey","docker-mcp-catalog","docker-networking-demystified","dynamic-mig-in-kubernetes-with-hami","embed-http-servers-in-wasm-with-rust-and-csharp","enhancing-runtime-security-with-falco-my-hands-on-experience","ephemeral-pull-request-environment-using-vcluster","essential-linux-commands-for-devops","event-driven-architecture-simplified-monolith-to-microservices","everything-you-need-to-know-about-docker-compose","everything-you-need-to-know-about-the-linux-ls-command","exploiting-metasploitable2-using-msfconsole-kali-linux-lab","firewall-a-networks-gatekeeper","four-pillars-of-observability-in-kubernetes","get-good-at-git","getting-started-with-kind-creating-a-multi-node-local-kubernetes-cluster","getting-started-with-ko-a-fast-container-image-builder-for-your-go-applications","getting-started-with-kyverno","git-and-github-a-beginners-guide","github-actions-101-what-are-github-actions-and-how-to-use-them-a-beginners-guide","gitops-demystified","ha-kubernetes","how-a-kubernetes-service-actually-works-and-all-5-types-you-need","how-get-started-with-hashicorp-vault","how-kubernetes-endpointslices-actually-work-and-why-endpoints-had-to-die","how-to-backup-kubernetes-with-kasten-community-edition","how-to-change-directory-in-shell-scripts","how-to-install-a-kubernetes-cluster-with-kubeadm-containerd-and-cilium-a-hands-on-guide","how-to-setup-your-ftp-server-in-linux","implementing-kubernetes-network-policies-a-comprehensive-guide","important-concepts-of-operating-systems","ing-switch-119-annotations-gateway-api-traefik-impact-ratings","ing-switch-migrate-from-ingress-nginx-to-traefik-or-gateway-api-in-minutes-not-days","installing-prometheus-with-selinux","introducing-kiac-kubernetes-in-apple-containers","introducing-unikraft-lightweight-virtualization-using-unikernels","introduction-of-jenkins-pipeline","introduction-to-cicd-and-cicd-pipeline","introduction-to-cri","introduction-to-developer-platforms-with-gimlet","introduction-to-helm","introduction-to-jenkins","introduction-to-kubernetes","introduction-to-terraform","iptables-demo","istio-service-mesh","k8sgpt-tutorial-when-kubernetes-meets-ai","keptn-getting-started","ksctl-making-kubernetes-easy-across-clouds","kube-proxy-deep-dive","kube-scheduler-deep-dive","kubecon-cloudnativecon-north-america-2024-recap-themes-innovations-and-community-spirit","kubecon-cloudnativecon-rejekts-and-wasm-io-wrap-up-a-leap-into-the-future-with-webassembly-ai-and-sustainable-cloud-practices","kubectl-run-nginx-inside","kubeflow-machine-learning-on-kubernetes-part-1","kubeflow-notebooks-ml-experimentation-made-easier-part-2","kubeflow-pipelines-orchestrating-machine-learning-workflows-part-3","kubernetes-125-dockerd","kubernetes-126","kubernetes-access-control-with-authentication-authorization-admission-control","kubernetes-adoption-key-challenges-in-migrating-to-kubernetes","kubernetes-backup-using-cloudcasa","kubernetes-containerd-setup","kubernetes-crio","kubernetes-management-with-rust-a-dive-into-generic-client-go-controller-abstractions-and-crd-macros-with-kubers","kubernetes-on-apple-macbooks-m-series","kubernetes-scheduling-the-complete-guide","kubernetes-v133-key-features-updates-and-what-you-need-to-know","kubernetes-v135-whats-new-whats-changing-and-what-you-should-know","kubesimplify-a-journey-to-remember","kubesimplify-at-wasmio-and-kubecon-eu-2024","kyverno-and-cosign","kyverno-cli","lets-learn-terraform","lets-simplify-golang-part-1","lets-simplify-golang-part-2","lets-simplify-golang-part-3","lets-talk-about-ansible","linux-boot-process-simplified","linux-system-directories-explained","llm-costs-and-observability-with-agentgateway-on-kubernetes","managing-contexts-in-kubernetes-with-plugins","managing-your-operating-system-with-package-managers","mastering-kubernetes-costs-from-monitoring-to-automation","microservices","mlxcel-rust-native-inference-engine-tested-on-m1-max","moving-code-between-git-repositories-with-copybara","multi-stage-docker-build","multi-tenancy-in-2025-and-beyond","my-first-international-conference-open-source-summit-2022","my-journey-to-kubestronaut-on-kubernetes-10th-birthday","my-kubecon-euvirtual-experience","my-schedule-for-kubecon-cloudnativecon-eu-2022","navigating-through-cncf-landscape","nemotron-3-5-lightning-on-dgx-spark","nemotron3-on-dgx-spark","networking-fundamentals-for-devops","nexus-repository-manager-what-is-it-and-how-to-configure-it-on-a-digital-ocean-droplet","nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform","operating-systems-101-essential-knowledge-for-devopssre-engineers","optimizing-kubernetes-costs-balancing-spot-and-on-demand-instances-with-topology-spread-constraints","optimizing-scalability-a-deep-dive-into-load-testing-with-locust-on-eks","package-managers-demystified","perform-crud-operations-on-kubernetes-using-golang","platform-engineering-demystified-navigating-the-basics","pods-in-kubernetes","practical-guide-to-kubernetes-api","progressive-rollouts-with-argo-cd-rollouts","prometheus-explained","pure-cilium-a-guide-for-local-load-balancing-and-bgp","quick-bites-of-fluxcd-health-assessment","rancher-desktop-evolution","ready-for-wasm-day-2023","sharing-gpus-in-kubernetes-with-hami","simplified-introduction-to-bacalhau","slicing-gpus-in-kubernetes-with-nvidia-mig","speeding-up-using-microk8s","ssh-into-your-dgx-spark-from-anywhere-in-the-world-using-tailscale","starting-your-devops-journey-as-a-windows-user","statefulsets","supply-chain-security-using-slsa-part-1-fundamentals","supply-chain-security-using-slsa-part-2-the-framework","terraform-best-practices","testing-docker-ais-gordon-how-smart-is-it","the-complete-guide-to-the-dd-command-in-linux","the-secret-gems-behind-building-container-images-enter-buildkit-and-docker-buildx","the-ultimate-guide-to-audit-logging-in-kubernetes-from-setup-to-analysis","the-webassembly-course","tutorial-build-a-cloud-cost-monitoring-system-with-terraform-ansible-and-komiser","understanding-docker-desktop-all-in-one-platform-for-containers","understanding-etcd-in-kubernetes-a-beginners-guide","understanding-how-containers-work-behind-the-scenes","understanding-the-architecture-of-kubernetes-a-beginners-guide","understanding-the-ins-and-outs-of-git-using-github","wandler-local-openai-compatible-inference-transformersjs-webgpu","what-is-reproducibility-and-why-does-it-matter","what-is-shell-scripting","why-are-network-policies-in-kubernetes-so-hard-to-understand","why-devops-case-study","wtf-is-linux-shell-command-substitution","yours-kindly-drone"]); +const BLOG_SLUGS = new Set(["10-things-you-might-not-know-about-k9s","12-practical-grep-command-examples-in-linux","a-beginners-guide-to-dualbooting-windows-with-ubuntu-part-1","a-beginners-guide-to-dualbooting-windows-with-ubuntu-part-2","a-complete-walk-through-of-devops","a-kubeconfig-for-gke-that-doesnt-need-gcloud","a-simple-way-to-structure-your-terraform-code","a-simplified-guide-to-yaml","about-my-pdf-editor-project","an-overview-of-gitops-and-argocd","announcing-buildsafe","api-response-in-go","arkade","automate-repetitive-tasks-shell-scripting","automated-github-releases-with-github-actions-and-conventional-commits","avoid-overspending-with-kubecost","aws-elastic-cloud-compute","bake-your-container-images-with-bake","become-a-hashicorp-certified-terraform-associate-preparation-guide","best-devops-tools-2025","bonsai-27b-rtx-pro-6000-dgx-spark","breaking-down-docker","building-a-zero-cve-strategy","building-apigateway-with-lambda-using-pulumi","certified-kubernetes-security-specialist-cks-2022-exam-guide","cicd-pipeline-github-actions-with-aws-ecs","ckad-exam-april-2022","claude-code-leak-what-the-source-actually-teaches","clawspark-your-private-openclaw-ai-assistant-that-never-phones-home","cloud-computing","cloud-native-buildpacks-concepts","confidential-containers-running-on-kubernetes","container-and-kubernetes-security","controlling-mcp-tools-with-agentgateway-on-kubernetes","coolify","creating-multi-node-kubernetes-cluster-locally","day-1-the-local-llm-revolution-why-your-desk-just-became-the-new-datacenter","day-1-what-actually-happens-when-you-type-docker-run","day-2-anatomy-of-an-llm-inference-request-from-prompt-to-answer-step-by-step","day-2-your-images-are-a-supply-chain-and-it-s-probably-broken","day-3-stop-writing-dockerfiles-from-scratch","day-3-the-dgx-spark-unpacked-gb10-unified-memory-sm-121-and-the-one-reason-this-hardware-exists","day-4-breaking-isolation-on-purpose-volumes-networks-and-the-real-world","day-4-quantization-demystified-bf16-fp8-nvfp4-mxfp4-int4-gguf-and-why-it-all-matters","day-5-docker-compose-how-docker-actually-gets-used","day-5-local-llm-inference-engines-wrappers-and-what-to-pick","day-6-run-an-llm-on-your-laptop-with-docker","day-7-ship-it-and-what-comes-next","deploy-a-maven-project-on-a-tomcat-server-using-jenkins-and-aws","deploy-a-simple-server-using-aws-terraform","deploying-java-application-using-docker-and-kubernetes-devops-project","devin-outposts-on-kubernetes","ditch-the-overheating-laptop-supercharge-your-docker-workflow-with-docker-offload","diy-how-to-build-a-kubernetes-policy-engine","docker-captain-journey","docker-mcp-catalog","docker-networking-demystified","dynamic-mig-in-kubernetes-with-hami","embed-http-servers-in-wasm-with-rust-and-csharp","enhancing-runtime-security-with-falco-my-hands-on-experience","ephemeral-pull-request-environment-using-vcluster","essential-linux-commands-for-devops","event-driven-architecture-simplified-monolith-to-microservices","everything-you-need-to-know-about-docker-compose","everything-you-need-to-know-about-the-linux-ls-command","exploiting-metasploitable2-using-msfconsole-kali-linux-lab","firewall-a-networks-gatekeeper","four-pillars-of-observability-in-kubernetes","get-good-at-git","getting-started-with-kind-creating-a-multi-node-local-kubernetes-cluster","getting-started-with-ko-a-fast-container-image-builder-for-your-go-applications","getting-started-with-kyverno","git-and-github-a-beginners-guide","github-actions-101-what-are-github-actions-and-how-to-use-them-a-beginners-guide","gitops-demystified","ha-kubernetes","how-a-kubernetes-service-actually-works-and-all-5-types-you-need","how-get-started-with-hashicorp-vault","how-kubernetes-endpointslices-actually-work-and-why-endpoints-had-to-die","how-to-backup-kubernetes-with-kasten-community-edition","how-to-change-directory-in-shell-scripts","how-to-install-a-kubernetes-cluster-with-kubeadm-containerd-and-cilium-a-hands-on-guide","how-to-setup-your-ftp-server-in-linux","implementing-kubernetes-network-policies-a-comprehensive-guide","important-concepts-of-operating-systems","ing-switch-119-annotations-gateway-api-traefik-impact-ratings","ing-switch-migrate-from-ingress-nginx-to-traefik-or-gateway-api-in-minutes-not-days","installing-prometheus-with-selinux","introducing-kiac-kubernetes-in-apple-containers","introducing-unikraft-lightweight-virtualization-using-unikernels","introduction-of-jenkins-pipeline","introduction-to-cicd-and-cicd-pipeline","introduction-to-cri","introduction-to-developer-platforms-with-gimlet","introduction-to-helm","introduction-to-jenkins","introduction-to-kubernetes","introduction-to-terraform","iptables-demo","istio-service-mesh","k8sgpt-tutorial-when-kubernetes-meets-ai","keptn-getting-started","ksctl-making-kubernetes-easy-across-clouds","kube-proxy-deep-dive","kube-scheduler-deep-dive","kubecon-cloudnativecon-north-america-2024-recap-themes-innovations-and-community-spirit","kubecon-cloudnativecon-rejekts-and-wasm-io-wrap-up-a-leap-into-the-future-with-webassembly-ai-and-sustainable-cloud-practices","kubectl-run-nginx-inside","kubeflow-machine-learning-on-kubernetes-part-1","kubeflow-notebooks-ml-experimentation-made-easier-part-2","kubeflow-pipelines-orchestrating-machine-learning-workflows-part-3","kubernetes-125-dockerd","kubernetes-126","kubernetes-access-control-with-authentication-authorization-admission-control","kubernetes-adoption-key-challenges-in-migrating-to-kubernetes","kubernetes-backup-using-cloudcasa","kubernetes-containerd-setup","kubernetes-crio","kubernetes-management-with-rust-a-dive-into-generic-client-go-controller-abstractions-and-crd-macros-with-kubers","kubernetes-on-apple-macbooks-m-series","kubernetes-scheduling-the-complete-guide","kubernetes-v133-key-features-updates-and-what-you-need-to-know","kubernetes-v135-whats-new-whats-changing-and-what-you-should-know","kubesimplify-a-journey-to-remember","kubesimplify-at-wasmio-and-kubecon-eu-2024","kyverno-and-cosign","kyverno-cli","lets-learn-terraform","lets-simplify-golang-part-1","lets-simplify-golang-part-2","lets-simplify-golang-part-3","lets-talk-about-ansible","linux-boot-process-simplified","linux-system-directories-explained","llm-costs-and-observability-with-agentgateway-on-kubernetes","local-llm-glossary","managing-contexts-in-kubernetes-with-plugins","managing-your-operating-system-with-package-managers","mastering-kubernetes-costs-from-monitoring-to-automation","microservices","mlxcel-rust-native-inference-engine-tested-on-m1-max","moving-code-between-git-repositories-with-copybara","multi-stage-docker-build","multi-tenancy-in-2025-and-beyond","my-first-international-conference-open-source-summit-2022","my-journey-to-kubestronaut-on-kubernetes-10th-birthday","my-kubecon-euvirtual-experience","my-schedule-for-kubecon-cloudnativecon-eu-2022","navigating-through-cncf-landscape","nemotron-3-5-lightning-on-dgx-spark","nemotron3-on-dgx-spark","networking-fundamentals-for-devops","nexus-repository-manager-what-is-it-and-how-to-configure-it-on-a-digital-ocean-droplet","nudgebee-ai-sre-copilot-hands-on","nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform","operating-systems-101-essential-knowledge-for-devopssre-engineers","optimizing-kubernetes-costs-balancing-spot-and-on-demand-instances-with-topology-spread-constraints","optimizing-scalability-a-deep-dive-into-load-testing-with-locust-on-eks","package-managers-demystified","perform-crud-operations-on-kubernetes-using-golang","platform-engineering-demystified-navigating-the-basics","pods-in-kubernetes","practical-guide-to-kubernetes-api","progressive-rollouts-with-argo-cd-rollouts","prometheus-explained","pure-cilium-a-guide-for-local-load-balancing-and-bgp","quick-bites-of-fluxcd-health-assessment","qwen3-8-27b-on-dgx-spark","rancher-desktop-evolution","ready-for-wasm-day-2023","sharing-gpus-in-kubernetes-with-hami","simplified-introduction-to-bacalhau","slicing-gpus-in-kubernetes-with-nvidia-mig","speeding-up-using-microk8s","ssh-into-your-dgx-spark-from-anywhere-in-the-world-using-tailscale","starting-your-devops-journey-as-a-windows-user","statefulsets","supply-chain-security-using-slsa-part-1-fundamentals","supply-chain-security-using-slsa-part-2-the-framework","terraform-best-practices","testing-docker-ais-gordon-how-smart-is-it","the-complete-guide-to-the-dd-command-in-linux","the-secret-gems-behind-building-container-images-enter-buildkit-and-docker-buildx","the-ultimate-guide-to-audit-logging-in-kubernetes-from-setup-to-analysis","the-webassembly-course","tutorial-build-a-cloud-cost-monitoring-system-with-terraform-ansible-and-komiser","understanding-docker-desktop-all-in-one-platform-for-containers","understanding-etcd-in-kubernetes-a-beginners-guide","understanding-how-containers-work-behind-the-scenes","understanding-the-architecture-of-kubernetes-a-beginners-guide","understanding-the-ins-and-outs-of-git-using-github","wandler-local-openai-compatible-inference-transformersjs-webgpu","what-is-reproducibility-and-why-does-it-matter","what-is-shell-scripting","why-are-network-policies-in-kubernetes-so-hard-to-understand","why-devops-case-study","wtf-is-linux-shell-command-substitution","yours-kindly-drone"]); export default { async fetch(request, env) { diff --git a/public/atom.xml b/public/atom.xml index 96b9de861..20687f4ca 100644 --- a/public/atom.xml +++ b/public/atom.xml @@ -5,11 +5,54 @@ https://blog.kubesimplify.com/ - 2026-08-12T14:47:36.455Z + 2026-08-18T08:33:37.156Z Kubesimplify hello@kubesimplify.com + + The Local LLM Glossary: Every Term, Flag, and Number in Plain English + + https://blog.kubesimplify.com/local-llm-glossary + 2026-08-18T09:00:00.000Z + 2026-08-18T09:00:00.000Z + Plain-English definitions for every term you hit in local LLM posts: prefill and decode, tokens per second, FP8 and NVFP4, Q4_K_M, KV cache, YaRN, Gated DeltaNet, speculative decoding, and every vLLM, llama.cpp, and Ollama flag worth knowing. + + + + + + + + + + + + Running Qwen3.8-27B on DGX Spark + + https://blog.kubesimplify.com/qwen3-8-27b-on-dgx-spark + 2026-08-17T14:00:00.000Z + 2026-08-17T14:00:00.000Z + Qwen3.8-27B on DGX Spark with llama.cpp, Ollama, vLLM, and SGLang: the recipes, the tokens per second I measured, MTP speculative decoding, and the sharp edges I hit along the way. + + + + + + + + I Ran an AI SRE Copilot on My Own Hardware. Here Is What It Actually Does. + + https://blog.kubesimplify.com/nudgebee-ai-sre-copilot-hands-on + 2026-08-17T10:00:00.000Z + 2026-08-17T10:00:00.000Z + Running NudgeBee v1.4.0 end to end - a self-hosted AIOps platform behind AI-SRE, AI-FinOps, AI-K8sOps, and agentic automation - on a Mac, a kiac cluster, and a DGX Spark. + + + + + + Running Nemotron 3.5 Lightning on DGX Spark @@ -29,10 +72,12 @@ https://blog.kubesimplify.com/dynamic-mig-in-kubernetes-with-hami 2026-08-11T10:00:00.000Z 2026-08-11T10:00:00.000Z - A hands-on test of topology-aware HAMi Dynamic MIG on RTX PRO 6000 Blackwell, with pinned setup commands, real allocations, mixed profiles, reclamation, and recovery. + Hands-on HAMi Dynamic MIG test on Kubernetes and RTX PRO 6000 Blackwell: setup commands, real allocations, mixed profiles, reclamation, and recovery. + + diff --git a/public/img/blog/local-llm-glossary/cover.png b/public/img/blog/local-llm-glossary/cover.png new file mode 100644 index 0000000000000000000000000000000000000000..e24c0f5dec029c687fcbab143f6d7f1d1a7c53d8 GIT binary patch literal 195791 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

TnaUlTgl@O_f1h0I~wHU(%@vUFa3*%v2?-XWD(C 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%0DMSW}NUk1p}I3*{O$;p|=4h3)n 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 Qf`FGM9HCaE^5Wh908A?=(EtDd literal 0 HcmV?d00001 diff --git a/public/img/blog/local-llm-glossary/cover.svg b/public/img/blog/local-llm-glossary/cover.svg new file mode 100644 index 000000000..7aeebbdca --- /dev/null +++ b/public/img/blog/local-llm-glossary/cover.svg @@ -0,0 +1,51 @@ + + + +The Local LLM Glossary +every magic string in these posts, in plain English + + + + +tg128 + + + +decode speed, measured over 128 tokens + + + +FP8 + + + +1 byte per weight, so half the size + + + +KV cache + + + +memory that grows with your context + + + +MTP + + + +the model drafts ahead for itself + + + +UD-Q4_K_XL + + + +4-bit, but not evenly 4-bit + +PREFILL - DECODE - QUANT NAMES - YARN - GATED DELTANET - EVERY FLAG +Ctrl+F the thing that confused you, then go back to the post you came from +blog.kubesimplify.com + \ No newline at end of file diff --git a/public/llms-full.txt b/public/llms-full.txt index 329797025..df6842053 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -5,6 +5,955 @@ --- +# The Local LLM Glossary: Every Term, Flag, and Number in Plain English + +- Canonical: https://blog.kubesimplify.com/local-llm-glossary +- Published: 2026-08-18 +- Summary: Plain-English definitions for every term you hit in local LLM posts: prefill and decode, tokens per second, FP8 and NVFP4, Q4_K_M, KV cache, YaRN, Gated DeltaNet, speculative decoding, and every vLLM, llama.cpp, and Ollama flag worth knowing. + +Every local LLM post, mine included, is full of shorthand: `pp2048`, `tg128`, FP8, `UD-Q4_K_XL`, KV cache, `gpu_memory_utilization: 0.8`, MTP, YaRN. If you live in this world daily it reads fine. If you do not, it reads like a wall of magic strings. + +So here is the glossary. Every term, flag, and number that shows up across the local LLM and DGX Spark posts on this blog, explained in plain English, with the reason it matters rather than just the expansion of the acronym. + +You do not need to read this top to bottom. Ctrl+F the thing that confused you, get your answer, go back to the post you came from. + +## Start here: the two halves of every request + +Almost everything in this glossary makes more sense once you have these two words straight. + +**Prefill** (also called prompt processing) is the model reading your input. Every token of your prompt can be processed at the same time, in parallel, because they are all already known. This is why prefill numbers look big: 800 to 4,000 tokens per second is normal on a DGX Spark. + +**Decode** (also called generation) is the model writing its answer. It produces one token, feeds that token back in, produces the next. Each step depends on the one before it, so there is nothing to parallelize. This is why decode numbers look small: 8 to 30 tokens per second for a 27B model on the same box. + +When someone says "the model feels slow," they nearly always mean decode. When someone says "it took ages before anything appeared," they mean prefill. + +[Day 2 of the Local LLM series](/blog/day-2-anatomy-of-an-llm-inference-request-from-prompt-to-answer-step-by-step) walks a single request through both halves step by step if you want the long version. + +## Reading a benchmark table + +**Token.** The unit models actually read and write. Roughly three quarters of an English word on average, so 1,000 tokens is about 750 words. Numbers, code, and punctuation eat more tokens than plain prose. + +**t/s (tokens per second).** The throughput unit for both halves above. Always ask which half it refers to, because prefill t/s and decode t/s can differ by 100x on the same machine. + +**TTFT (time to first token).** How long from pressing enter until the first word appears. Dominated by prefill, so it grows with prompt length. + +**pp512, pp2048.** `pp` is prompt processing, the number is how many tokens of prompt. `pp2048` means "prefill throughput measured on a 2,048 token prompt." These names come from `llama-bench` and stuck as a convention. + +**tg128, tg32.** `tg` is token generation, the number is how many tokens were generated. `tg128` means "decode throughput measured while generating 128 tokens." + +**Depth (context depth).** How much conversation or document was already in the context window before the measurement started. `depth 0` is a cold, empty context. `depth 32768` means the model was already holding 32K tokens. Decode usually slows down as depth grows, and how much it slows is one of the more interesting things about a model's architecture. + +**Concurrency.** How many requests were in flight at once. `c=1` is one user. `c=10` is ten simultaneous requests, which is what serving a team or a fleet of agents actually looks like. + +**Aggregate vs per request.** At concurrency 10 you get two decode numbers. Aggregate is all ten requests added together, which is what a server operator cares about. Per request is what each individual user experiences, which is always lower. A box doing 84 t/s aggregate across 10 users is giving each of them about 9 t/s. + +## Why the numbers come out the way they do + +This is the section that makes bad benchmark numbers stop being mysterious. + +**Memory bandwidth.** How many gigabytes per second the chip can read out of memory. The DGX Spark's GB10 does about 273 GB/s. A discrete RTX PRO 6000 does roughly 6x that. This single number sets the ceiling for decode. + +**Weight streaming.** To produce one token, a dense model has to read every one of its weights out of memory. A 16.7GB model at 273 GB/s can therefore do at most about 16 tokens per second, no matter how fast the compute is. Measured 11.6 t/s against a 16 t/s theoretical ceiling is about 70% of peak, which is what real kernels achieve. + +The mental model I keep coming back to: it is like re-reading an entire book off the shelf before you can write each next word. Your reading speed sets the pace, not how fast you can think. + +**Bandwidth-bound vs compute-bound.** Decode is bandwidth-bound: the chip is waiting on memory, and the tensor cores are mostly idle. Prefill is compute-bound: there is enough parallel work to actually saturate the math units. This is why the same box can look fast and slow within one request, and why halving your model size roughly doubles decode but barely moves prefill. + +**Unified memory.** On the GB10 the CPU and GPU share one pool of memory (128GB, of which about 121.7 GiB is addressable) rather than the GPU having its own separate VRAM. Two consequences: big models fit without a discrete card's memory limit, and every process on the box competes for the same pool. If a llama.cpp container is still holding 18GB, your vLLM launch will fail on memory it can see but not have. + +**VRAM.** The dedicated memory on a discrete GPU. On a unified-memory box like the Spark there is no separate VRAM, which trips up tools that assume there is. + +**Dense vs MoE.** A dense model uses all its parameters for every token. A Mixture of Experts model has many parameters but routes each token through only a few of them, so a 30B MoE with 3B active parameters streams roughly 3B worth of weights per token and feels dramatically faster. This is the whole reason a 30B MoE can hit 100+ t/s on a Spark while a real dense 27B sits at 11. + +**Active parameters.** The subset of an MoE's weights actually used per token. Written like `2.4T-A95B`, meaning 2.4 trillion total parameters, 95 billion active. Active is the number that predicts speed. Total is the number that predicts memory. + +## Quantization: decoding the format names + +Quantization is storing the model's numbers in fewer bits. Fewer bits means fewer gigabytes to stream per token, which means faster decode, at some cost in quality. [Day 4](/blog/day-4-quantization-demystified-bf16-fp8-nvfp4-mxfp4-int4-gguf-and-why-it-all-matters) is the full treatment; this is the lookup table. + +| Format | Bits per weight | What to know | +|---|---|---| +| FP32 | 32 (4 bytes) | Full precision. Almost nobody serves at this. | +| BF16 / FP16 | 16 (2 bytes) | The reference quality. A 27B model is about 54GB. | +| FP8 | 8 (1 byte) | Halves the size with very little quality loss. Native on Hopper and Blackwell. A 27B is about 29GB. | +| INT4 | 4 (0.5 bytes) | Generic 4-bit integer. Quality depends heavily on how it was produced. | +| NVFP4 | 4 | NVIDIA's 4-bit float with fine-grained scaling, with native tensor core support on Blackwell (so on GB10). Usually the best speed on this hardware. | +| MXFP4 | 4 | Open Compute Project's 4-bit micro-scaling float. Same idea, different standard body. | + +**GGUF.** The single-file model format llama.cpp and Ollama use. It packs weights plus metadata plus tokenizer into one file you can move around. Not a precision, a container: a GGUF file also has a quantization type inside it. + +**Q4_K_M, Q4_K_XL and friends.** The llama.cpp quantization naming scheme, three parts stacked: + +- `Q4` is 4 bits per weight. +- `_K` is the K-quant layout. Instead of one scaling factor for a whole tensor, weights are stored in super-blocks of 256 that are split into blocks of 32, each carrying its own quantized scale. Outlier weights then only distort their own block of 32 rather than dragging a whole tensor's precision down. +- The last letter is a size tier: `S` small, `M` medium, `L` large, `XL` extra large. Higher tiers spend extra bits on the tensors that matter most, so the file is a bit bigger and the quality a bit better. + +**UD (Unsloth Dynamic).** A prefix like `UD-Q4_K_XL` means the layers were deliberately not all quantized to the same width. Embeddings and the first and last blocks keep more bits because everything downstream depends on them, while the more redundant middle feed-forward layers get squeezed harder. The result holds up better than a uniform 4-bit quant of the same file size. + +**Checkpoint.** A published set of weights, usually a Hugging Face repo at a specific revision. "The official FP8 checkpoint" means the model author's own FP8 publication, as opposed to a community requantization. + +**Marlin.** A family of fast GPU kernels for quantized matrix multiplication in vLLM. `VLLM_MARLIN_USE_ATOMIC_ADD: '1'` switches those kernels to atomic accumulation, which is a correctness and performance workaround on some GPU and shape combinations. It is the kind of environment variable you copy from a working recipe rather than derive. + +**Bytes per parameter arithmetic.** The one calculation worth memorizing: parameters times bytes per parameter equals weight size. 27B at FP8 is about 27GB, at 4-bit about 16GB, at BF16 about 54GB. Then add KV cache and runtime overhead on top. + +## Context, attention, and the KV cache + +**Context window.** The maximum number of tokens the model can have in front of it at once, prompt plus generated output plus any system message. 262,144 tokens is a large modern window, and it is often quoted as "262K" or "256K" loosely. + +**KV cache.** As the model reads your prompt, each attention layer computes key and value vectors per token, and caches them so it does not recompute them for every subsequent token. Very effective, but the cache grows linearly with context length and with the number of concurrent requests, and it lives in the same memory pool as the weights. Long contexts and many users both eat memory here, not in the weights. + +**KV cache dtype.** The precision the cache is stored at. Storing it at `fp8` instead of 16-bit roughly halves cache memory, letting you serve longer contexts or more users on the same box, at a small accuracy cost. + +**Prefix caching.** If two requests share the same beginning (a system prompt, a document, a conversation so far), the runtime can reuse the KV cache from the shared part instead of prefilling it again. Enormous win for chat and agent workloads where 90% of every request is the same prefix. In vLLM this is `--enable-prefix-caching`. + +**Attention.** The mechanism that lets each token look at the other tokens in context and decide what is relevant. Standard ("full") attention lets every token look at every previous token, which is powerful and gets more expensive as context grows. + +**Flash attention.** A way of computing attention that avoids writing the giant intermediate attention matrix to memory, making it much faster and much cheaper in memory. Effectively always worth turning on: `-fa on` in llama.cpp. + +**Attention backend.** Which implementation of attention the serving engine actually calls. In vLLM you might see `flashinfer`, `flash_attn`, or `xformers`. **FlashInfer** is a library of highly tuned attention and GEMM kernels; on the Spark's `sm121` architecture it picks the `xqa` decode kernel and supports an FP8 KV cache. Different backends can differ by 2x on the same hardware, which is why recipes pin one. + +**Linear attention.** An alternative that keeps a fixed-size running state instead of a cache that grows with every token. Cheaper and flat in context length, but with less precise recall than full attention. Modern models often use a hybrid: a few full attention layers for precise recall, the rest linear. + +**Gated DeltaNet.** The specific linear attention design used by recent Qwen models. The *gate* decides how fast old memory fades, and the *delta rule* writes targeted corrections into the fixed-size state rather than appending to an ever-growing list. The state is the same size at token 100,000 as it is at token 10, which is exactly why decode speed on these models barely sags as context grows. In Qwen3.8-27B, 48 of 64 layers are Gated DeltaNet and every 4th layer is full gated attention. + +**RoPE (Rotary Position Embedding).** How most models encode *where* a token sits in the sequence, by rotating the token's vector by an angle that depends on its position. Positions the model never saw in training land at angles it does not understand, which is why context windows have a hard native limit. + +**YaRN (Yet another RoPE extensioN).** A technique for stretching that limit. It rescales the positional frequencies, stretching each one differently depending on its wavelength, so the model can address positions well beyond its training range without a full retrain. "262K native, extensible to 1M with YaRN" means the extra range is available but is an extension, not a native capability. + +**Vision encoder and mmproj.** A vision language model ships a separate encoder that turns images into tokens the language model can read. In GGUF land that encoder is a companion file called `mmproj` (multimodal projector). No `mmproj`, no images, even if the model is capable of them. + +**Thinking mode.** Models that emit reasoning inside `` blocks before their actual answer. Better on hard problems, more tokens spent, so slower and more expensive per reply. Vendors publish different recommended sampling settings for thinking and non-thinking modes. + +**Reasoning parser and tool call parser.** Server-side parsers that pull those `` blocks and any tool or function calls out of the raw token stream and put them in the right fields of the OpenAI-compatible API response. Wrong parser and your client sees reasoning text glued into the answer, or tool calls it cannot recognize. These are per model family: `reasoning_parser: qwen3`, `tool_call_parser: qwen3_coder`. + +## Speed tricks + +**Batching / continuous batching.** Running several requests through one pass over the weights. Since decode is bandwidth-bound, one weight-streaming pass can feed 10 tokens for 10 different users at almost the cost of feeding 1. This is why aggregate throughput climbs with concurrency while per-user throughput barely drops, and it is the main thing production servers like vLLM and SGLang buy you over single-user tools. + +**Speculative decoding.** A cheap model guesses the next few tokens, the real model verifies them all in one pass. Correct guesses are free tokens; wrong ones are discarded, so the output is identical to what the big model would have produced on its own. No quality risk, real speedup. + +**Draft model.** The cheap guesser in that scheme, a small separate model. "DSpark" is a community-built 5-layer, ~2.6GB drafter for Qwen3.8-27B. + +**MTP (Multi-Token Prediction).** The same trick with no separate model: the big model ships an extra head trained to predict several tokens ahead, and drafts for itself. Cheaper to deploy than a draft model since there is nothing extra to load. When Ollama serves a model 2x faster than llama.cpp on the same quantization, MTP being on by default is usually the reason. + +**NEXTN.** SGLang's name for its MTP-style speculative path. Same idea, different engine. + +**Acceptance rate.** The fraction of drafted tokens the real model accepts. This is the whole ballgame for speculative decoding, and it is a property of *your workload*, not of the model. Editing existing code, where the draft mostly copies text already in the prompt, can hit 98% acceptance and 3x speedups. Writing fresh prose or new code, where the drafter is genuinely guessing, might hit 30%. This is why a tokens-per-second number without its workload attached is close to meaningless. + +**k / num_speculative_tokens.** How many tokens the drafter proposes per round. Higher k pays off when acceptance is high and wastes work when it is low. + +**Tensor parallel (TP).** Splitting each layer's matrices across multiple GPUs so they all work on every token together. Needs fast interconnect between the cards. `tensor_parallel_size: 2` means two GPUs. + +**Pipeline parallel (PP).** Splitting the model by layer, so GPU 0 runs the first half and GPU 1 the second. Tolerates slower interconnect, but one card is idle while the other works unless you keep several requests in flight. + +## The flags you copy-paste + +### vLLM and sparkrun recipes + +A [sparkrun](https://sparkrun.dev) recipe is a YAML file that pins a model, a container, and the serving flags, so a working setup is one file rather than an afternoon of dependency fighting. The `defaults:` block is vLLM server arguments, and `env:` is environment variables passed into the container. + +| Key | What it does | How to think about it | +|---|---|---| +| `gpu_memory_utilization: 0.8` | The share of GPU memory vLLM is allowed to claim up front, for weights plus KV cache | Higher means more KV cache, so longer contexts and more concurrent users. Too high and the launch fails or something else on the box starves. On unified memory, remember other processes share the pool. | +| `max_model_len: 131072` | The maximum context length the server will accept, in tokens | Can be lower than the model's native window, and often should be: every token of headroom you reserve costs KV cache memory. 131072 is 128K. | +| `max_num_batched_tokens: 32768` | Cap on how many tokens the scheduler puts into one forward pass | Bigger batches mean better prefill throughput and chunkier latency. This is the prefill throughput vs responsiveness dial. | +| `load_format: instanttensor` | How weights are read off disk into memory | `instanttensor` is a fast-load path that gets a 29GB checkpoint resident in seconds once cached, instead of minutes. Pure startup time, no runtime effect. | +| `kv_cache_dtype: fp8` | Precision of the KV cache | Roughly halves cache memory versus 16-bit, so you fit longer contexts or more users. Small accuracy cost. | +| `attention_backend: flashinfer` | Which attention kernel library to use | On the Spark's `sm121`, FlashInfer gets the fast decode path and FP8 KV cache support. | +| `tool_call_parser: qwen3_coder` | Extracts tool and function calls from the token stream | Must match the model family, or your agent framework sees plain text where it expected a structured call. | +| `reasoning_parser: qwen3` | Extracts `` blocks into the response's reasoning field | Must match the model family, or reasoning text leaks into the answer. | +| `VLLM_MARLIN_USE_ATOMIC_ADD: '1'` | Environment variable switching Marlin quantized kernels to atomic accumulation | A hardware-specific workaround. Copy it from a working recipe. | +| `--enable-prefix-caching` | Reuses KV cache across requests that share a prefix | Big win for chat and agents, effectively free. | +| `speculative_config` | Turns on speculative decoding, e.g. `{"method": "mtp", "num_speculative_tokens": 3}` | See MTP and acceptance rate above. | + +### llama.cpp + +| Flag | What it does | +|---|---| +| `-hf :` | Pulls the GGUF straight from Hugging Face. Note recent builds cache into `/root/.cache/huggingface`, not the old `llama.cpp` path, which matters when you mount a volume. | +| `-ngl 99` | Number of layers to offload to the GPU. 99 is the idiomatic "all of them," since anything left on the CPU is dramatically slower. | +| `-c 32768` | Context size in tokens for this server instance. Larger costs KV cache memory. | +| `-fa on` / `-fa 1` | Flash attention. Turn it on. | +| `--host 0.0.0.0 --port 8091` | Bind address and port for the OpenAI-compatible server. | +| `mmproj-*.gguf` | The vision projector file. Present in the repo means images work. | + +`llama-bench` is llama.cpp's built-in benchmark, and it is where `pp512`/`tg128` style names come from. + +### Ollama + +| Thing | What it does | +|---|---| +| `num_ctx` | Context size, Ollama's equivalent of `-c`. Ollama picks a default from available memory. | +| `num_predict` | Maximum tokens to generate in a reply. | +| `ollama ps` | Shows loaded models and, critically, whether they are on GPU. If it says anything less than `100% GPU`, your benchmark is measuring the CPU and will be 3 to 5x too slow. | +| `prompt_eval_count` / `eval_count` | Ollama's own counters for prompt tokens and generated tokens, with matching `_duration` fields in nanoseconds. Divide to get t/s. | + +### Sampling knobs + +These control how the next token is picked from the model's probability distribution. They change output style, not speed. + +- **temperature.** How much randomness. 0 is deterministic and repetitive, 1.0 is creative, above about 1.2 usually becomes incoherent. Use 0 when benchmarking so runs are comparable. +- **top_p (nucleus sampling).** Only consider tokens inside the top cumulative probability mass, e.g. 0.95. Cuts off the long tail of unlikely tokens. +- **top_k.** Only consider the k most likely tokens, e.g. 20. + +Model authors publish recommended values per mode, and it is worth using theirs. Qwen3.8's thinking mode wants temp 1.0 / top_p 0.95 / top_k 20, non-thinking wants temp 0.7 / top_p 0.80. + +## Hardware words + +**GB10.** The Grace Blackwell superchip inside the DGX Spark: Arm CPU plus Blackwell GPU plus 128GB of unified LPDDR5X at about 273 GB/s. + +**sm_121 / compute capability.** NVIDIA's architecture version tag for a GPU. GB10 is `sm_121`. Kernels have to be compiled for your architecture, so "supports sm121" in a release note is the difference between working and not. [Day 3](/blog/day-3-the-dgx-spark-unpacked-gb10-unified-memory-sm-121-and-the-one-reason-this-hardware-exists) covers the Spark's hardware story in detail. + +**Tensor cores.** The dedicated matrix multiply units. Which precisions they support natively (FP8 and FP4 on Blackwell) decides which quantization is genuinely fast rather than merely smaller. + +**GB vs GiB.** GB is 1,000^3 bytes, GiB is 1,024^3. A "128GB" box reports about 119 GiB, and vendors and tools mix the two freely. When a number looks 7% off, this is usually why. + +**`nvidia-smi` on GB10.** Cannot report memory usage on this chip and prints `Not Supported`. Use `free -h`, since the memory is unified anyway. + +## Where to go next + +If you want these terms in context rather than as a list, the Local LLM series builds them up in order: + +- [Day 1: The Local LLM Revolution](/blog/day-1-the-local-llm-revolution-why-your-desk-just-became-the-new-datacenter), why running models locally became viable at all +- [Day 2: Anatomy of an LLM Inference Request](/blog/day-2-anatomy-of-an-llm-inference-request-from-prompt-to-answer-step-by-step), prefill and decode end to end +- [Day 3: The DGX Spark Unpacked](/blog/day-3-the-dgx-spark-unpacked-gb10-unified-memory-sm-121-and-the-one-reason-this-hardware-exists), the hardware and why bandwidth rules everything +- [Day 4: Quantization Demystified](/blog/day-4-quantization-demystified-bf16-fp8-nvfp4-mxfp4-int4-gguf-and-why-it-all-matters), every format name in depth +- [Day 5: Inference Engines and What to Pick](/blog/day-5-local-llm-inference-engines-wrappers-and-what-to-pick), Ollama vs llama.cpp vs vLLM vs SGLang + +And if a term bit you that is not defined here, tell me and I will add it. That is what this page is for. + +--- + +# Running Qwen3.8-27B on DGX Spark + +- Canonical: https://blog.kubesimplify.com/qwen3-8-27b-on-dgx-spark +- Published: 2026-08-17 +- Summary: Qwen3.8-27B on DGX Spark with llama.cpp, Ollama, vLLM, and SGLang: the recipes, the tokens per second I measured, MTP speculative decoding, and the sharp edges I hit along the way. + +Qwen announced the 3.8 family on August 3: Qwen3.8-Max, the 2.4T flagship, plus a promise that open weights were coming "next week". The Max weights (2.4T-A95B) landed August 12. The one everyone actually wanted for local inference, the 27B, went quiet. Trackers even reported it as delayed with no new date. + +It dropped on August 14. I had it running on the DGX Spark within the hour, so here is the full recipe, what worked on day zero, what did not, and the numbers. Let's get into it. + +Here is exactly what everything below was run on: + +| Component | What I ran | +|---|---| +| Box | DGX Spark, GB10, 128GB unified memory | +| OS and driver | DGX OS, driver 580.159.03, kernel 6.17.0-1018-nvidia | +| Test dates | August 14-15, 2026 (the MTP, SGLang, and DSpark runs came on August 17) | +| llama.cpp | build b10423 | +| vLLM | spark-arena nightly 0.27.2rc1, plus stable v0.27.1 for the DSpark run | +| Ollama | v0.32.12 | +| SGLang | latest-cu130 | +| Load-test tool | llama-benchy 0.4.0 | +| FP8 checkpoint | Qwen/Qwen3.8-27B-FP8 at 017b9c7a (the launch upload, unchanged since) | +| GGUF quant | unsloth/Qwen3.8-27B-GGUF at 4604b899 | +| NVFP4 quant | unsloth/Qwen3.8-27B-NVFP4 at 60e813d4 (day zero), 7d6f8d4d (MTP runs) | + +unsloth updated both quants after launch, so I re-benchmarked the updated NVFP4 revision: 11.9 t/s single-stream, within 4% of the numbers below, nothing material changed. + +Every measurement in this post came from one of these four commands, so you can rerun any table row yourself: + +```bash +# llama.cpp raw numbers (pp512/pp2048/tg128/tg32 tables) +docker run --rm --gpus all -v $HOME/models/qwen38:/root/.cache/huggingface \ + --entrypoint /app/llama ghcr.io/ggml-org/llama.cpp:server-cuda \ + bench -m /Qwen3.8-27B-UD-Q4_K_XL.gguf -fa 1 -p 512,2048 -n 128,32 + +# vLLM and SGLang numbers (all pp2048/tg128 tables, any depth/concurrency) +uvx llama-benchy@0.4.0 --base-url http://:8000/v1 --model \ + --pp 2048 --tg 128 --depth 0 16384 32768 --concurrency 1 2 5 10 \ + --enable-prefix-caching --save-result results.csv --format csv + +# Ollama numbers (from Ollama's own eval counters, temperature 0, 3 runs) +curl -s http://127.0.0.1:11435/api/generate -d '{"model":"qwen3.8:27b", + "prompt":"","stream":false,"options":{"temperature":0,"num_predict":200}}' \ + | jq '{prompt_tok:.prompt_eval_count, prompt_ns:.prompt_eval_duration, gen_tok:.eval_count, gen_ns:.eval_duration}' + +# Edit-heavy vs fresh-generation workload comparison (DSpark section) +python3 edit_bench.py http://127.0.0.1:8002/v1 qwen3.8-27b # from 0xBakeer's repo, bench/ +``` + +Two words to have straight before the tables below, because every number in this post is one or the other. **Prefill** is the model reading your prompt: all the input tokens get processed in parallel, so it is fast, hundreds to thousands of tokens per second. **Decode** is the model writing its answer one token at a time, each token waiting on the one before it, so it is slow, single or low double digits here. Prefill is the wait before the first word appears; decode is the speed you watch it type at. In benchmark names, `pp2048` is prefill measured on a 2,048 token prompt and `tg128` is decode measured over 128 generated tokens. Anything else that reads like a magic string in this post is in the [local LLM glossary](/blog/local-llm-glossary). + +## What Qwen3.8-27B actually is + +Reading the config before running things saves a lot of confusion, and this one is interesting: + +- 27B parameters, and it is NOT a MoE. 64 layers with a hybrid attention pattern: every 4th layer is full gated attention, the other 48 layers are [Gated DeltaNet](https://arxiv.org/abs/2412.06464) (linear attention). Same hybrid lineage as Qwen3.5/3.6. +- Native vision language model. There is a 27-layer vision encoder in the checkpoint, images and video in, text out. +- 262,144 token native context, extensible to 1M with [YaRN](https://arxiv.org/abs/2309.00071), short for Yet another RoPE extensioN: it rescales the model's positional frequencies, stretching each one differently depending on its wavelength, so the model can address positions further out than it was ever trained on without a full retrain. +- Thinking mode on by default (`` blocks), with recommended sampling temp 1.0 / top_p 0.95 / top_k 20. Non-thinking: temp 0.7 / top_p 0.80. +- Apache 2.0. +- Architecture class is `Qwen3_5ForConditionalGeneration` (`model_type: qwen3_5`). This detail matters: it is the same architecture family the inference engines already support, which is why day-zero support mostly just works. + +Gated DeltaNet deserves a sentence of its own, because it quietly explains most of the numbers later in this post. Normal attention keeps a KV cache that grows with every token you feed it, so the deeper your context gets, the more memory has to be read before the next token can come out. A linear attention layer keeps a fixed-size running state instead: the gate decides how fast old memory fades, and the delta rule writes targeted corrections into that state rather than appending to an ever-growing list. The state is the same size at token 100,000 as it is at token 10. Hold onto that one, it is why decode speed barely moves as context grows further down. + +Qwen's own (vendor-reported, so calibrate accordingly) numbers for the 27B: SWE-bench Pro 61.7, LiveCodeBench v6 90.3, Terminal Bench 2.1 at 73.0, GPQA Diamond 89.2, OSWorld-Verified 84.3. + +## What works on the Spark on day zero + +| Path | Status on day zero | +|---|---| +| llama.cpp + unsloth GGUF | Works (stock release build b10423, vision mmproj included) | +| vLLM + official FP8 checkpoint | Works, on both the stable v0.27.1 release and the spark-arena nightly (recipes below) | +| Ollama | Works, needs v0.32.12 (released the same day) | +| SGLang | Works on upstream latest; the older pinned dev container silently produced garbage (see below) | + +## The llama.cpp path (fastest way to first token) + +Let's start with the fastest way to first token. One command, and the server pulls the GGUF straight from Hugging Face: + +```bash +docker run -d --name qwen38-llamacpp --gpus all -p 8091:8091 \ + -v $HOME/models/qwen38:/root/.cache/huggingface \ + --entrypoint /app/llama-server \ + ghcr.io/ggml-org/llama.cpp:server-cuda \ + -hf unsloth/Qwen3.8-27B-GGUF:Q4_K_XL \ + --port 8091 --host 0.0.0.0 -ngl 99 -c 32768 -fa on +``` + +Three of those flags do the heavy lifting: `-ngl 99` offloads all layers to the GPU (99 is the idiomatic "all of them", and anything left on the CPU is dramatically slower), `-c 32768` sets the context window to 32K tokens, and `-fa on` enables flash attention, which computes attention without materializing the giant intermediate matrix in memory. That last one is free speed, leave it on. + +Two gotchas I hit so you do not have to: + +1. Recent llama.cpp downloads `-hf` models into the Hugging Face hub cache (`/root/.cache/huggingface`), not the old `/root/.cache/llama.cpp` path. Mount the right one or your 18GB download disappears with the container. +2. The GGUF repo ships `mmproj-BF16.gguf` alongside the weights (llama.cpp pulled it automatically), so the vision path is wired up for llama.cpp as well. `mmproj` is the multimodal projector, the companion file that turns images into tokens the language model can read: no mmproj, no images, however capable the model is. I test it below. + +First token arrives fast and the model correctly identified what it was running on (a nice recursive moment: Qwen3.8-27B on a DGX Spark explaining what a DGX Spark is). + +Quick decode of that quant name before the numbers, because `UD-Q4_K_XL` is three labels stacked on top of each other. `Q4_K` is llama.cpp's 4-bit K-quant: instead of one scaling factor for a whole tensor, weights are stored in super-blocks of 256, split into blocks of 32 that each carry their own quantized scale, so outlier weights do less damage to their neighbours. `UD` is Unsloth Dynamic, meaning the layers are deliberately not all quantized the same: embeddings and the first and last blocks keep more bits because everything downstream depends on them, while the more redundant middle feed-forward layers get squeezed harder. `XL` is the size tier, which promotes selected important matrices to 5-bit where unsloth judges that safe. The practical upshot is 16.68 GiB of weights that hold up better than a uniform 4-bit quant of the same size. + +The `llama-bench` numbers (build b10423, flash attention on, UD-Q4_K_XL, 16.68 GiB weights): + +| Test | Result | +|---|---| +| pp512 (prefill) | 838.6 t/s | +| pp2048 (prefill) | 837.4 t/s | +| tg128 (decode) | 11.6 t/s | +| tg32 (decode) | 11.6 t/s | + +Let me be honest about that decode number, because this is where dense models and the Spark have a complicated relationship. The GB10's unified memory is the whole reason a 27B fits comfortably, but its ~273 GB/s of bandwidth is the ceiling for decode on any dense model: every generated token has to stream all 16.7GB of weights. Think of it like re-reading a whole book off the shelf before you can write each next word: your reading speed sets the pace, not how fast you can think. Do the arithmetic and 273 GB/s over 16.7GB puts the theoretical ceiling around 16 t/s, so the measured 11.6 is roughly 70% of peak, which is about what real kernels get. If you have been running MoE models like Nemotron 3.5 Lightning (30B but only ~3B active) on the Spark and got used to 100+ t/s decode, recalibrate: this is a real dense 27B, all parameters working on every token. + +Prefill is a different story: 838 t/s means a 2,000 token prompt is processed in under 2.5 seconds, and the hybrid DeltaNet layers keep that roughly flat as context grows. + +Fun detail: llama-bench identifies the model as "qwen35 27B", the architecture tag from the config showing through in the GGUF metadata. + +## The vLLM path (best throughput) + +Now let's do it properly with vLLM. No official Spark Arena recipe existed for Qwen3.8 when it dropped (the model was hours old), but the `@official/qwen3.6-27b-fp8-vllm` recipe is the same architecture family, so I adapted it. This is the part I want to highlight about the Spark ecosystem right now: [sparkrun](https://sparkrun.dev) recipes made a day-zero model a config-file edit, not an afternoon of dependency fighting. + +```yaml +recipe_version: '2' +model: Qwen/Qwen3.8-27B-FP8 +runtime: vllm +container: ghcr.io/spark-arena/dgx-vllm-eugr-nightly:latest +defaults: + gpu_memory_utilization: 0.8 + max_model_len: 131072 + max_num_batched_tokens: 32768 + load_format: instanttensor + kv_cache_dtype: fp8 + attention_backend: flashinfer + tool_call_parser: qwen3_coder + reasoning_parser: qwen3 +env: + VLLM_MARLIN_USE_ATOMIC_ADD: '1' +``` + +That is a lot of magic strings in twelve lines, so here is what each one is actually doing, because these are the knobs you will end up turning yourself: + +| Setting | What it does | Why this value | +|---|---|---| +| `gpu_memory_utilization: 0.8` | The share of memory vLLM claims up front, for weights plus KV cache | Higher means more KV cache, so longer contexts and more concurrent users. On unified memory you cannot go greedy: everything else on the box shares this pool. | +| `max_model_len: 131072` | Longest context the server will accept, in tokens | 128K, well under the model's native 262K. Every token of headroom you reserve costs KV cache memory, and I would rather have the memory. | +| `max_num_batched_tokens: 32768` | Cap on tokens the scheduler puts in one forward pass | The prefill-throughput vs responsiveness dial. Bigger batches process prompts faster and make latency chunkier. | +| `load_format: instanttensor` | How the weights get off disk and into memory | Pure startup time. It is why a 29GB checkpoint is resident in under 5 seconds once cached instead of minutes. | +| `kv_cache_dtype: fp8` | Precision the KV cache is stored at | Roughly halves cache memory versus 16-bit, which is what buys the long-context headroom. Small accuracy cost. | +| `attention_backend: flashinfer` | Which attention kernel library runs | On `sm121` FlashInfer picks the `xqa` decode kernel and supports the FP8 cache above. Backends can differ by 2x, which is why recipes pin one. | +| `tool_call_parser: qwen3_coder` | Pulls tool and function calls out of the raw token stream | Has to match the model family, or your agent framework sees plain text where it expected a structured call. | +| `reasoning_parser: qwen3` | Pulls `` blocks into the response's reasoning field | Same story: wrong parser and reasoning text leaks into the answer. | +| `VLLM_MARLIN_USE_ATOMIC_ADD: '1'` | Switches Marlin's quantized kernels to atomic accumulation | A hardware-specific workaround. This one you copy from a working recipe rather than derive. | + +Then: + +```bash +uvx sparkrun run ./qwen38-27b-fp8-vllm.yaml +``` + +The official FP8 checkpoint is 29GB, `instanttensor` loads the weights in under 5 seconds once cached, and FlashInfer picks the `xqa` decode backend on sm121 with FP8 KV cache. Changes from the 3.6 recipe: I dropped the qwen3.6-specific chat template mods (3.8 ships a correct template) and set `max_model_len` to 128K, which is plenty while leaving KV headroom. + +The numbers, measured with [llama-benchy](https://pypi.org/project/llama-benchy/) 0.4.0 (the same tool Spark Arena standardizes on), pp2048/tg128 at depth 0: + +| Concurrency | Prefill pp2048 (t/s) | Decode tg128 aggregate (t/s) | Decode per request (t/s) | +|---|---|---|---| +| 1 | 1,914 | 8.2 | 8.2 | +| 2 | 1,305 | 16.1 | 8.2 | +| 5 | 540 | 36.3 | 7.8 | +| 10 | 627 | 57.9 | 7.2 | + +Two things jump out: + +1. vLLM's prefill is 2.3x llama.cpp's (1,914 vs 837 t/s). The FlashInfer path on sm121 is doing its job. +2. vLLM's single-stream decode (8.2 t/s) is SLOWER than llama.cpp's (11.6 t/s). This is not a vLLM problem, it is arithmetic: the FP8 checkpoint streams 28.75GB per token, the Q4_K_XL GGUF streams 16.7GB. On a bandwidth-bound box the smaller quant wins single-stream, always. What vLLM buys you is batching: 10 concurrent requests get 57.9 t/s aggregate, because one weight-streaming pass now feeds 10 tokens instead of 1. + +So the honest serving decision tree on a Spark: single user chatting → llama.cpp with the smallest quant you can tolerate quality-wise. Serving a team or agents in parallel → vLLM FP8. + +### The long-context concurrency wedge (day-zero honesty) + +Not everything works yet. When I pushed 10 concurrent requests at 32K context depth, the engine effectively wedged: requests admitted one at a time, prefill bursts healthy at ~3,277 t/s, but aggregate generation collapsed to 0.2-0.6 t/s and sat there. It had not crashed, it was just stuck. Short-context concurrency: fine. Single-stream: fine (numbers below). Concurrent + deep context: pathological, at least in this nightly build with the hybrid DeltaNet architecture. + +At low concurrency, deep context is actually where this architecture shines. Measured at 32,768 tokens of context depth: + +| Config | Value | +|---|---| +| Prefill into 32K context (c=1) | 534-700 t/s | +| Decode at 32K context (c=1) | 7.9 t/s | +| Decode at 32K context (c=2, aggregate) | 15.1 t/s | + +The decode number is the one to notice here: 8.2 t/s at zero context, 7.9 t/s at 32K context, a 3% drop. On a conventional full-attention model the KV cache reads grow with context and decode sags noticeably; here 48 of the 64 layers are linear attention with constant-size state, so decode speed is nearly flat in context depth. For long-document and agentic workloads on local hardware, that flatness matters more than the headline number. + +This is what day zero actually looks like: the happy paths work because the architecture class was already supported, and the corner cases (linear-attention state management under concurrent long-context load) still need the engines to catch up. If you are evaluating this model for production serving, test YOUR context/concurrency profile before committing. + +## NVFP4: the best-numbers recipe + +GB10 is a Blackwell chip, and Blackwell has native FP4 tensor cores (NVFP4 being NVIDIA's 4-bit float format, covered properly in [Day 4](/blog/day-4-quantization-demystified-bf16-fp8-nvfp4-mxfp4-int4-gguf-and-why-it-all-matters)), so the natural question is whether the NVFP4 quant (unsloth/Qwen3.8-27B-NVFP4, ~16GB) buys real speed. Same recipe as above with the model swapped, and FlashInfer autotuned 46 fp4_gemm kernel configs on first boot. It does: + +| Concurrency | Prefill pp2048 (t/s) | Decode tg128 aggregate (t/s) | Decode per request (t/s) | +|---|---|---|---| +| 1 | 1,794 | 11.5 | 11.5 | +| 2 | 2,393 | 21.6 | 11.0 | +| 5 | 2,719 | 49.8 | 10.5 | +| 10 | 3,999 | 84.3 | 9.6 | + +NVFP4 ties llama.cpp's single-stream decode (11.5 vs 11.6, both stream ~16GB of weights, the physics is consistent), and wins everything else: 84.3 t/s aggregate decode at concurrency 10 (46% over FP8's 57.9), and batched prefill that scales UP with concurrency to nearly 4,000 t/s where FP8's fell. If you serve this model on a Spark, NVFP4 is the recipe. + +The quality tradeoff of 4-bit quantization is real and workload-dependent; benchmark your own evals before standardizing on it. + +## Spark Arena + +The numbers in this post are reproducible: I submitted the NVFP4 run to [Spark Arena](https://spark-arena.com), the community leaderboard where GB10 owners run the same standardized llama-benchy profile (pp2048/tg128, depths 0 to 100K, concurrency 1/2/5/10) and publish results with the full recipe attached. Submission sub1786754097881, status Completed. Grab the recipe from the leaderboard and you should land on the same numbers. + +Two full-grid results worth highlighting: decode at 100K context depth is still 9.8 t/s single-stream (15% below zero-context, at ONE HUNDRED THOUSAND tokens of context), and the 32K-deep concurrency-10 cell that wedged FP8 completed fine on NVFP4 at 63.1 t/s aggregate. + +## The Ollama path (same-day support) + +`ollama pull qwen3.8` failed all afternoon with "pull model manifest: file does not exist", and then Ollama shipped v0.32.12 the same day the weights landed, with qwen3.8 in the library: 27b tag, 18GB, 256K context, vision, thinking mode on by default. Older Ollama versions (including 0.32.11 from a day earlier) refuse the pull with a "requires a newer version" error, so upgrade first. + +```bash +OLLAMA_HOST=127.0.0.1:11435 ollama pull qwen3.8:27b # 18GB, Q4_K_M +``` + +Measured the same way as my previous Spark posts (temperature 0, 3 runs, numbers from Ollama's own eval counters): + +| Metric | Result | +|---|---| +| Prefill (~2,200 token prompt, cold) | 731 t/s | +| Decode (200 tokens) | 26.5 t/s | + +Wait. 26.5 t/s decode, when llama.cpp does 11.6 on the same-size Q4 and the bandwidth ceiling says ~16? The answer is in the model config Ollama ships: `draft_num_predict 4`, and the runner launches with `--spec-type draft-mtp`. The Ollama build of Qwen3.8 includes the model's multi-token prediction head and turns speculative decoding ON by default, so each weight-streaming pass validates up to 4 drafted tokens. Same trick their Nemotron builds used. The plain unsloth GGUF I benchmarked in llama.cpp does not carry the MTP head, so it pays full price per token. + +That makes Ollama the single-stream champion of the day, and it did it with zero flags. Credit where due: they also default the context to 262K on this box (vram-based default) and the vision projector is wired up. + +Here is the day-zero picture across all the engines in one chart (the vLLM MTP and SGLang numbers further down came later): + +![Qwen3.8-27B on DGX Spark: measured prefill and decode across llama.cpp, Ollama, and vLLM](/img/blog/qwen3-8-27b-on-dgx-spark/chart.png) + +One operational note: the GB10 needs Ollama's cuda_v13 runner. My first attempt loaded the model on 100% CPU (7.5 t/s decode) because of a botched duplicate server start, so check `ollama ps` says `100% GPU` before you trust any numbers. + +## Vision test: it read its own benchmark chart + +The GGUF ships with the vision projector and llama.cpp loads it automatically, so I gave the model the chart you just scrolled past, the one measuring the model itself, and asked what it shows. It correctly identified the hardware, both metric panels, every engine and quantization in the comparison, the color coding, and the footnote about bandwidth-bound decode. Then it started reading the exact numbers back to me. + +There is something pleasingly recursive about a model reading a chart of its own decode speed at 11.6 t/s, which is the llama.cpp number on that chart, in the engine it was running in while it read it. The image cost 1,470 prompt tokens, and vision decode runs at effectively the same speed as text. + +## Unified memory sequencing lesson + +The Spark's memory is unified, and CUDA sees essentially all of it: 124,609 MiB, which is 121.7 GiB of the 128GB. That is the whole appeal, a 27B in bf16 fits without quantization. But it also means inference engines fight over the same pool: my vLLM launch failed with "Free memory 74.82/121.69 GiB is less than desired 0.8 utilization (97.35 GiB)" because the llama.cpp server was still resident. On a discrete-GPU box you would notice immediately; on unified memory it is easy to forget a container is holding 18GB. `docker ps` before you launch. + +Also the eternal Spark reminder: `nvidia-smi` cannot report memory usage on GB10 (Not Supported), use `free -h`. + +## Three days later: MTP arrives on vLLM, and finds a cliff + +I sat on this post for three days and the ecosystem moved fast, so here is the update. An official Spark Arena recipe landed with MTP speculative decoding for vLLM (`speculative_config {"method": "mtp", "num_speculative_tokens": 3}`), the same trick Ollama shipped on day one. The gains are real: + +| Config | Single-stream tg128 | c10 aggregate | +|---|---|---| +| vLLM NVFP4 plain | 11.5 t/s | 84.3 t/s | +| vLLM NVFP4 + MTP | 22.0 t/s | 105.8 t/s | +| vLLM FP8 + MTP | 13.8 t/s | 55.8 t/s | +| Ollama Q4 (MTP default) | 26.5 t/s | n/a | + +NVFP4 + MTP at 105.8 t/s aggregate is the best serving number anything has produced on my Spark. Ollama still holds single-stream. + +Now the honest part, and please read this before you run the MTP recipes at long context: **twice in a row, the MTP config hard-rebooted my entire Spark** at exactly the same benchmark cell (16K context, 2 concurrent requests), once on FP8 and once on NVFP4. Not a container crash, a full machine reset, with the journal cut off mid-line and no panic trace, which points at a GPU/SoC lockup. The non-MTP configs ran the same cell and the full 28-cell grid for 6.5 hours without a hiccup. Environment: GB10, driver 580.159.03, kernel 6.17.0-1018-nvidia, the spark-arena vLLM nightly. Until this is understood, treat MTP on vLLM as short-context-only on this box. I will update here when I know more. + +### SGLang joins the matrix (and teaches the scariest lesson) + +SGLang was the last officially recommended engine I had not run, so I adapted the qwen3.5-27b-fp8 sglang recipe the same way. First attempt: the server came up healthy, answered every request, and produced complete token soup ("visit visit visits 訪...逻辑逻辑logic..."). Disabling the recipe's NEXTN speculative config changed nothing. The actual culprit was the pinned container image, an SGLang dev build created before Qwen3.8 existed: it loads the new checkpoint without a single warning and generates garbage. Swapping to upstream `lmsysorg/sglang:latest-cu130` fixed it instantly. + +The scary part is that the health check was green and the API answered every request the whole time - a crash at least tells you something is wrong, silent garbage does not. If you inherit a recipe with a pinned image, coherence-test the output before you benchmark anything. + +Numbers on the working upstream build (FP8, no speculation): + +| Cell | SGLang | vLLM FP8 (for comparison) | +|---|---|---| +| Prefill pp2048 (c=1) | 1,225 t/s | 1,914 t/s | +| Decode tg128 (c=1) | 7.7 t/s | 8.2 t/s | +| Decode c=10 aggregate | 54.3 t/s | 57.9 t/s | +| Decode at 16K context (c=1) | 7.3 t/s | ~7.9 t/s | + +Same shape as vLLM, a few percent behind everywhere on this build, and the same context-flatness. + +Then I re-enabled NEXTN speculation (SGLang's MTP equivalent) on the working upstream build, and this is where SGLang earns its seat: + +| Cell | SGLang FP8 | SGLang FP8 + NEXTN | vLLM FP8 + MTP | +|---|---|---|---| +| Decode tg128 (c=1) | 7.7 t/s | 13.4 t/s | 13.8 t/s | +| Decode c=10 aggregate | 54.3 t/s | 71.0 t/s | 55.8 t/s | +| Decode at 16K context (c=1) | 7.3 t/s | 10.3 t/s | 14.4 t/s | + +Speculation on FP8 gives SGLang almost exactly vLLM's MTP single-stream number (same weights, same trick), and its speculative scheduler scales better under batch: 71 t/s aggregate at concurrency 10 where vLLM's MTP drops to 56. If you see people posting bigger SGLang numbers than mine from earlier in this post, this is why: speculation on versus off. The overall throughput crown still belongs to vLLM NVFP4+MTP, because the 4-bit quant halves the weight traffic that everything else queues behind. And for the record, SGLang with speculation survived the 16K single-stream cell; I deliberately did not run speculation at deep context plus concurrency, the combination that hard-rebooted the box twice under vLLM. + +## The 75 tok/s post, reproduced + +While I was sitting on this draft, a post by [@0xBakeer](https://x.com/0xBakeer) went around claiming 75 tok/s single-stream and 256 tok/s across 16 parallel requests, on the same model, on the same machine. My first reaction was that it contradicted everything above. It does not, and reproducing it taught me the most useful lesson in this post. + +The lever is a dedicated draft model: "DSpark" (community-built, 5 layers, ~2.6GB) proposes blocks of tokens and the full model verifies them in one weight-read. Same speculative idea as MTP, but the drafter is 3x cheaper per guess. Their [recipe repo](https://github.com/0xBakeer/Qwen3.8-27B-FP8-on-a-single-DGX-Spark) is excellent, annotated flag by flag, so I ran it verbatim on my Spark (vLLM v0.27.1 stable, FP8, DSpark k=7): + +| Workload | Their number | My Spark | +|---|---|---| +| Edit-heavy (98.5% draft acceptance) | 46.8 t/s | 45.0-48.6 t/s | +| Fresh generation (~30% acceptance) | n/a | 20.8 t/s | +| llama-benchy free-gen, single stream | n/a | 17.2 t/s | +| llama-benchy, 10 concurrent aggregate | n/a | 65.6 t/s | + +Reproduced within noise. Their 75 t/s headline is the 4-bit checkpoint plus a deeper draft on the edit-heavy workload, and it is real too. + +The lesson: speculative decoding's speedup is the drafter's acceptance rate, and acceptance is a property of YOUR WORKLOAD, not the model. The same server on the same box is 3.5x faster editing existing code (where the draft just copies the prompt) than writing new code (where it genuinely guesses). So a single tokens-per-second number without its workload attached is close to meaningless, including the ones in this post: my numbers are free-form generation, the pessimistic end of the range. If your work is editing, refactoring, or structured rewriting, multiply accordingly. + +Practical takeaway for single-user Sparks: DSpark k=7 on the official FP8 checkpoint beats every configuration I measured above (17.2 t/s on the neutral benchmark, 45+ on edit work) with zero quality risk, since verification discards every wrong guess. And it ran on the stable vLLM release without the hard reboot the nightly's MTP path gave me, though I have not dared re-run the exact crash cell. + +## Wrapping up + +Qwen3.8-27B on a DGX Spark, one day in: + +- Day-zero support was real everywhere: llama.cpp immediately, vLLM immediately, Ollama by end of day with v0.32.12. The qwen3_5 architecture class being pre-supported did most of the work. +- Best single-stream chat: Ollama, 26.5 t/s, because it ships the MTP head with speculative decoding on by default. Nobody else does yet. +- Best serving throughput: vLLM NVFP4, 84.3 t/s aggregate at 10 concurrent, prefill scaling to 4,000 t/s. +- The architecture's superpower on this hardware is context flatness: on NVFP4, decode runs 11.5 t/s at zero context, 10.9 at 32K, and still 9.8 at 100K. Long documents are effectively free at decode time. +- Rough edge: FP8 wedged under concurrent deep-context load in the current vLLM nightly. NVFP4 did not. Test your traffic profile. + +A dense 27B with native vision and 262K context that runs at usable speeds on a desk box, with Apache 2.0 attached, is exactly what this hardware was built for. The MoE models are still faster chatters, but in my opinion this is the most capable thing my Spark has run so far. + +Huge thanks to the unsloth team for having the GGUF and NVFP4 quants up within hours, the Ollama team for shipping same-day support, and the Spark Arena maintainers (Drew Botwinick, Eugene Rakhmatulin, Raphael Amorim) whose recipes and containers turned a day-zero model into a config-file edit. If you have a Spark, give these recipes a try and let me know what numbers you get - and submit them to [Spark Arena](https://spark-arena.com) so we can compare notes. + +## Links + +- Model: [Qwen/Qwen3.8-27B](https://huggingface.co/Qwen/Qwen3.8-27B) and [Qwen/Qwen3.8-27B-FP8](https://huggingface.co/Qwen/Qwen3.8-27B-FP8) +- Quants: [unsloth/Qwen3.8-27B-GGUF](https://huggingface.co/unsloth/Qwen3.8-27B-GGUF), [unsloth/Qwen3.8-27B-NVFP4](https://huggingface.co/unsloth/Qwen3.8-27B-NVFP4) +- Ollama: [ollama.com/library/qwen3.8](https://ollama.com/library/qwen3.8) (needs v0.32.12+) +- Tools: [sparkrun](https://sparkrun.dev), [llama-benchy](https://pypi.org/project/llama-benchy/), [Spark Arena](https://spark-arena.com) +- My submission: sub1786754097881 on the Spark Arena leaderboard + +--- + +# I Ran an AI SRE Copilot on My Own Hardware. Here Is What It Actually Does. + +- Canonical: https://blog.kubesimplify.com/nudgebee-ai-sre-copilot-hands-on +- Published: 2026-08-17 +- Summary: Running NudgeBee v1.4.0 end to end - a self-hosted AIOps platform behind AI-SRE, AI-FinOps, AI-K8sOps, and agentic automation - on a Mac, a kiac cluster, and a DGX Spark. + +**TL;DR** - NudgeBee is an AIOps platform built around AI agents for DevOps and SRE teams - AI-SRE is one surface on it, alongside AI-FinOps, AI-K8sOps, and an automation builder. What sold me is that it implements a full SRE control loop in code: collect signals, rank events, investigate with real tools, recommend fixes, run durable workflows, and keep an audit trail. In this post I run the whole thing locally - the control plane in Docker Compose on my Mac, a 3-node Kubernetes cluster in lightweight VMs via kiac, and the LLM served from a DGX Spark on my desk. Real screenshots, real commands, real sharp edges. + +> Source note: everything below was run against **NudgeBee v1.4.0** (released August 3, 2026) on August 10, 2026. I installed it, connected a cluster, and broke things so you don't have to. For a fast-moving open-source project, always cross-check the upstream README. + +--- + +## The Problem: On-Call Engineers Are Human Glue + +Most teams do not fail on-call because they have zero dashboards. + +They fail because the dashboards, alerts, logs, cloud inventory, cost data, tickets, and runbooks all live in different places. The on-call engineer becomes the integration layer: copy a pod name from Slack, search logs in another tab, check metrics in a third tool, open a ticket, paste a summary, then run a command from a runbook that may or may not still be true. + +That is the real problem an SRE copilot should solve - and it has nothing to do with asking an LLM what Kubernetes is. + +The mental model that makes this class of tool click: + +> **An SRE copilot is a control loop for production systems.** + +![The SRE copilot control loop](/img/blog/nudgebee-ai-sre-copilot-hands-on/diagram-control-loop.svg) + +SRE teams already run this loop by hand every day: + +1. **Observe** - alerts, metrics, logs, Kubernetes events, cloud inventory. +2. **Normalize** - turn tool-specific mess into consistent resources and events. +3. **Rank** - decide what is noise and what pages a human. +4. **Investigate** - gather evidence from the cluster, metrics, logs, tickets. +5. **Recommend** - a fix, a rollback, a rightsizing change, a runbook. +6. **Act** - run the remediation, or guide a human through it. +7. **Record** - keep the investigation and outcome for the next incident. + +NudgeBee's value is that it treats these stages as **one product surface**. The loop is the product - not the dashboard, and not the LLM. + +--- + +## What NudgeBee Is (as of v1.4.0) + +NudgeBee describes itself as a unified AIOps / CloudOps platform: **AI-SRE** (troubleshooting), **AI-FinOps** (cost and rightsizing), **AI-K8sOps** (cluster operations), and an **Agentic Automation Builder** - without fragmented tools or model lock-in. + +Under the hood it is a monorepo of TypeScript, Go, and Python services: + +![NudgeBee v1.4.0 architecture - app, backend services, data layer, collectors, and the in-cluster agent](/img/blog/nudgebee-ai-sre-copilot-hands-on/diagram-architecture.svg) + +Each service owns a stage of the loop: + +| Loop stage | NudgeBee piece | +| --- | --- | +| Observe | `k8s-collector`, `cloud-collector`, in-cluster agent, webhooks | +| Normalize | `services-server`, migrations, resource model | +| Rank | triage scoring, event aggregation (LLM-assisted since v1.4) | +| Investigate | `llm-server` agents + tools, RAG, knowledge graph | +| Act | `workflow-server` (Temporal), relay to the cluster | +| Notify | `notifications-server` - Slack, Teams, Discord, email | +| Record | Postgres: conversations, tool calls, executions, tickets | + +Because these surfaces share the same collectors, knowledge graph, and integrations (more on bCortex below), a team can start with just one - say, triage - and add FinOps or automation later without re-plumbing anything. + +The right way to read the repo is not file by file. It is: "which stage of the loop does this service own?" + +(One naming heads-up if you go source diving: the service that deploys as `workflow-server` lives in the code as `runbook-server`. Same thing - one Temporal worker wearing two names.) + +--- + +## Quick Start: Two Ways to Run It + +Since v1.3.0, every first-party image is published to `ghcr.io/nudgebee/*` and the umbrella Helm chart is on GHCR as an OCI artifact - so you no longer need to build anything from source. + +### Path 1: Kubernetes (the one-liner-ish path) + +```bash +export NUDGEBEE_ENC_KEY=$(openssl rand -hex 32) # store this safely + +helm install nudgebee oci://ghcr.io/nudgebee/charts/nudgebee \ + --namespace nudgebee --create-namespace \ + --set nudgebee_secret.NUDGEBEE_ENCRYPTION_KEY="$NUDGEBEE_ENC_KEY" \ + --wait --timeout 20m + +kubectl -n nudgebee port-forward svc/app 3000:80 +``` + +The post-install hook applies migrations automatically. Grab the bootstrap password from the `nudgebee` secret and sign in at `localhost:3000`. + +### Path 2: Docker Compose on a laptop (what I did) + +```bash +git clone https://github.com/nudgebee/nudgebee.git && cd nudgebee +docker compose --profile full up -d +``` + +The default profile starts the infrastructure (Postgres, Redis, RabbitMQ, Qdrant, Temporal, one-shot migrations). The `full` profile adds all the app services as containers - about 18 in total, all pulled from GHCR. + +Here is my stack once everything settled: + +```text +SERVICE IMAGE STATUS +api-server-services ghcr.io/nudgebee/services-server:1.4.0 Up +app ghcr.io/nudgebee/app:1.4.0 Up +cloud-collector ghcr.io/nudgebee/cloud-collector-server:1.4.0 Up +k8s-collector-app ghcr.io/nudgebee/k8s-collector:1.4.0 Up +llm-server ghcr.io/nudgebee/llm-server:1.4.0 Up +ml-k8s-server ghcr.io/nudgebee/ml-k8s-server:1.4.0 Up +notifications-server ghcr.io/nudgebee/notifications:1.4.0 Up +postgres ghcr.io/nudgebee/postgres:16 Up (healthy) +qdrant ghcr.io/nudgebee/qdrant:v1.18.3 Up +rabbitmq ghcr.io/nudgebee/rabbitmq:3-management Up +rag-server ghcr.io/nudgebee/rag-server:1.4.0 Up +redis ghcr.io/nudgebee/redis:7-alpine Up +relay-server ghcr.io/nudgebee/relay-server:1.4.0 Up +temporal temporalio/auto-setup:1.29.1 Up +temporal-ui temporalio/ui:2.44.0 Up +ticket-server ghcr.io/nudgebee/ticket-server:1.4.0 Up +workflow-server ghcr.io/nudgebee/workflow-server:1.4.0 Up +``` + +**Real-world notes from my install** (the kind of thing READMEs never tell you): + +- Several `full`-profile services ship without environment config in the compose file. I added a `docker-compose.override.yaml` that gives each one its database URL, RabbitMQ host, and the shared `NUDGEBEE_ENCRYPTION_KEY`. The key must be identical everywhere - it encrypts integration credentials at rest. +- On macOS, the k8s-collector wants host port **5000**, which AirPlay already squats on. Remap it in the override. +- The k8s-collector expects the backend at the hostname `services-server`; the compose service is named `api-server-services`. A one-line network alias fixes event ingestion. +- If you disable ClickHouse (`clickhouse.enabled=false`), the agent chart still references the ClickHouse secret. Create a stub secret or leave it enabled. + +Sign in with **Admin Login**, any email, and the local dev password `Test!24#5` (the dummy-credentials provider - local development only). + +![NudgeBee login screen](/img/blog/nudgebee-ai-sre-copilot-hands-on/01-login.jpg) + +One pleasant surprise: v1.4.0 no longer drops you into an empty product. First login lands on a **demo dataset** - active incidents, error-rate events, rightsizing recommendations - so you can explore every surface before connecting anything real. + +![Home dashboard with demo data - incidents, optimize recommendations, quick links](/img/blog/nudgebee-ai-sre-copilot-hands-on/02-home-dashboard.jpg) + +--- + +## The Lab: Cluster on the Mac, Brain on the DGX Spark + +For the demo I wanted everything self-hosted, including the model. My setup: + +![The lab - NudgeBee control plane and kiac cluster on the MacBook, Ollama on the DGX Spark](/img/blog/nudgebee-ai-sre-copilot-hands-on/diagram-lab-setup.svg) + +- **Control plane**: the Compose stack above. +- **Tenant cluster**: a 3-node k3s cluster created with [kiac](https://github.com/saiyam1814/kiac) (Kubernetes in Apple Containers - every node is its own lightweight VM with a routable IP, so the in-cluster agent can reach the control plane over the vmnet gateway like a real remote cluster would). +- **Inference**: Ollama on a DGX Spark across the room. NudgeBee's llm-server calls it over plain HTTP. The model does not need to be anywhere near the cluster - the LLM is just an API. + +The point of this setup is the architecture lesson: **the brain, the hands, and the workloads are three separate places**, glued together by exactly two protocols - a websocket relay for the cluster and an OpenAI-compatible endpoint for the model. + +### Demo workloads + +I deployed a `payments` namespace with three deployments: a healthy nginx `payments-gateway`, a `payments-api` that crashes on boot with a missing `DATABASE_URL`, and a deliberately over-provisioned `report-worker` (1 CPU / 1Gi requested per replica to do nothing) - one problem for each of NudgeBee's three surfaces: troubleshooting, RCA, and FinOps. + +### Connecting the cluster + +Admin → Integrations shows the catalog: Kubernetes and clouds, plus categories for messaging, ticketing, observability backends, repos, CI/CD, databases, and LLM providers. + +![Integrations catalog - Kubernetes, AWS, Azure, GCP, Cloud Foundry](/img/blog/nudgebee-ai-sre-copilot-hands-on/03-integrations-catalog.jpg) + +Adding a Kubernetes account generates an agent key and a copy-paste install command (shell script or Helm). You can toggle components off - Prometheus stack, OpenCost, eBPF node agent, OpenTelemetry collector - and the command updates live. + +![Add Kubernetes Account - component toggles and generated install command](/img/blog/nudgebee-ai-sre-copilot-hands-on/04-connect-cluster-modal.jpg) + +The agent chart installs kube-prometheus-stack and OpenCost alongside the NudgeBee agent, then dials **out** to the control plane over a websocket: + +```json +{"msg":"greeting","payload":"{\"action\":\"auth\",\"version\":\"0.1.11\",...}"} +{"msg":"updated relay connection status to true","agent_type":"k8s"} +``` + +That outbound-only relay design matters: real clusters sit behind NAT and firewalls, so the control plane can never assume it can dial in. Commands flow down the same websocket the agent opened. + +Two minutes later the cluster shows up with a candid message: + +![Connected account - "Give me about an hour to generate insights"](/img/blog/nudgebee-ai-sre-copilot-hands-on/05-connected-home.jpg) + +I like this honesty. Trend-based insights need trends. But live state is immediate: + +![Cluster overview - 3 nodes, 21 pods, real CPU and memory](/img/blog/nudgebee-ai-sre-copilot-hands-on/06-cluster-overview.jpg) + +Three nodes, twenty-one pods, live CPU and memory pulled from the Prometheus the agent just installed. No demo data - this is the kiac cluster. + +--- + +## The Loop, Live: Signal → Triage → AI Investigation + +Within minutes, real events started flowing. The home page surfaced a firing issue with an **Investigate** button next to it: + +![Live issue on home - 1 pod has ImagePullBackoff, with Investigate button](/img/blog/nudgebee-ai-sre-copilot-hands-on/07-live-issue-investigate.jpg) + +The Troubleshoot section turns raw events into a **triage inbox**: every issue gets a triage score, severity, alert status, and an owner path - sliced by error type (OOM Killed, Image Pull Backoff, High Restarts, CPU Throttling, Replica Mismatch): + +![Triage inbox - pod errors with triage score, severity, and Investigate action](/img/blog/nudgebee-ai-sre-copilot-hands-on/08-triage-pod-errors.jpg) + +This is the **Rank** stage of the loop, and it is where alert fatigue goes to die. v1.4.0 added LLM-assisted triage scoring on top of the rule-based signals. + +Clicking **Investigate** opens the AI side. This is where NudgeBee stops being a dashboard: + +![AI investigation in progress - parallel tool calls with live status](/img/blog/nudgebee-ai-sre-copilot-hands-on/11-ai-investigation-parallel-tools.jpg) + +Read that screenshot carefully, because it shows the architecture: + +- The agent states its plan in plain language. +- It then fires **multiple tool calls in parallel**: an events query for the pod, a `kubectl describe` for image and status, a resource-graph search - each with its own live status and a "Tool Details" expander showing the raw evidence. +- Evidence accumulates as **sources** attached to the conversation, not vibes. + +Ten minutes later (on a 26B model running on my own hardware - more on that below), the finished analysis landed: + +![Completed AI investigation - summary, 5-Whys causality chain, evidence, resolution](/img/blog/nudgebee-ai-sre-copilot-hands-on/12-ai-investigation-result.jpg) + +Let's pause on the *structure* of that answer for a second, because it is doing a lot of work: + +- **Investigation Summary** - symptom plus the exact signal: Kubernetes events reporting `NotFound` for the specific image reference. +- **Causality Chain (5-Whys)** - pod is in ImagePullBackOff → runtime cannot pull the image → the registry returned `404 Not Found` for that tag → root cause: the manifest references a non-existent image tag. +- **Evidence** - a clickable source (`Events - E2`) carrying the raw `rpc error: code = NotFound`, with 4 sources attached to the conversation. +- **Resolution** - an immediate fix (point the manifest at a valid tag, verify against the registry) *and* a long-term recommendation (validate image tags in CI/CD before rollout). + +And the diagnosis was correct - I verified the tag really does not exist in the registry. Not "it may be due to an image pull error, OOM kill, config issue, or failing dependency." A specific root cause, with the evidence to check its work. + +One small detail that shows the loop thinking: under the answer, NudgeBee suggests **Related Questions** - verify the fix was applied and the pod is Running, inspect the corrected manifest, analyze the CI/CD logs so the bad tag never ships again: + +![Related Questions - verify the fix, inspect the manifest, prevent the regression](/img/blog/nudgebee-ai-sre-copilot-hands-on/13-related-questions.jpg) + +That last suggestion is the Record stage turning into prevention: today's investigation trying to make sure tomorrow's page never fires. + +### ReWOO is gone - meet the Orchestrating planner + +If you read about NudgeBee before mid-2026, you may remember its two planning styles: ReWOO (plan first, execute after) and ReAct (think, act, observe, repeat). **v1.4.0 retired the ReWOO planner.** Both agent types - *Orchestrating* (the top-level coordinator) and *ReAct* (domain investigators) - now run a hybrid planner the code calls **ReAct3**: a ReAct loop extended with an `` block that lets the model declare several independent tool calls in one step. + +That is the parallel execution visible in the screenshot, and it is the sensible endpoint of the planner debate: keep ReAct's evidence-driven loop, recover ReWOO's efficiency by batching independent lookups. + +The tool layer is wide: `kubectl` and Helm, Prometheus/PromQL, Loki, Elasticsearch, Datadog, New Relic, OpenObserve (new in v1.4.0), cloud APIs, ticket systems, GitHub, spend analysis, and workflow lifecycle actions. The agent decides *what* to look at; tools are *how* it touches reality: + +> The model should not hallucinate your cluster. It should ask tools for evidence. + +### Guardrails you can see in the logs + +Watching llm-server logs during the investigation was its own education: + +```text +plannerexecutor: submitting tool for parallel execution (x4) +plannerexecutor: pre-flight detected tool with LLM-only + classification, assuming potential write +plannerexecutor: tool output truncated at source +``` + +Pre-flight classification of potentially write-capable tools, output truncation before context stuffing, per-account tool scoping, and an egress filter (default "detect" mode) that watches for secrets leaving via LLM calls. None of it is glamorous, and all of it is what makes "AI with kubectl access" survivable. + +--- + +## bCortex: The Context Layer Under Every Agent + +There is a failure mode every naive "agentic ops" tool shares: **the agent rediscovers your infrastructure from scratch on every question.** List the namespaces. Describe the deployments. Page through events. Ask again tomorrow and it does all of it again. Token spend grows with cluster size, latency grows with token spend, and worst of all, whenever discovery is incomplete the model fills the gaps by guessing - which is where operational hallucinations come from. + +NudgeBee's answer is a context layer the team calls **bCortex**, and it has three parts you can find in the codebase: + +- An **auto-generated Knowledge Graph** (`api-server/services/knowledge_graph/`) that models the relationships between resources, events, and findings - so "what depends on this pod" is a graph lookup, not a fresh round of kubectl calls. +- A **Service Map** built from APM and trace data - deliberately a *different* artifact than the KG: the service map is dataflow (who calls whom), the KG is resource state. Both feed the agent. +- A **multi-tiered, usage-based memory layer**. The code describes it as a layered "memory slab" - preferences and identity first, with patterns and decisions layered on - extracted from actual usage rather than hand-written. + +I did not have to take anyone's word for this, because my own run left its fingerprints in the logs. The moment my ImagePullBackOff investigation completed, llm-server ran `long-term memory extraction` on the conversation and logged the stats - the platform was already mining my investigation for reusable knowledge. During the run I also watched `kb_sync` cycles keeping the knowledge base current, `tool call cache` hits skipping discovery calls the platform had already made, and the planner `comparing with history` before deciding what to fetch. My first investigation was the expensive one; everything after it starts warmer. + +The economics follow directly. Right-sized context per call instead of dump-everything-into-the-prompt means fewer tokens. Graph and cache lookups replace repeated discovery tool calls. Model-tier routing (a `reasoning` / `retrieval` / `summary` split in the config) sends heavyweight thinking to the big model and summarization to a cheap one. At the scale where agentic ops gets interesting - hundreds of investigations a week across a fleet - that is the difference between a bill that grows with every question and one that amortizes. And accuracy moves the same direction as cost, because a model grounded in a graph that already knows what exists has far less room to hallucinate. + +> A chatbot loop rediscovers your infrastructure every time. A context layer remembers it. + +This is also why the multi-agent pitch holds up in practice: a new agent - FinOps, K8sOps, a custom automation - does not start from zero. It inherits everything bCortex already knows about the environment. + +--- + +## FinOps Is in the Same Loop + +The Optimize surface treats cost as an operational signal, not a finance spreadsheet: workload/replica/PV rightsizing, abandoned-resource detection, spot recommendations, best practices, and an **Auto Optimize** response that can act on them: + +![Optimize - rightsizing categories, abandoned resources, auto-optimize](/img/blog/nudgebee-ai-sre-copilot-hands-on/10-optimize-rightsizing.jpg) + +Mine shows zeros because recommendations are trend-based (OpenCost plus NudgeBee's ML rightsizing service watch for a day or more before opining). The structure is the takeaway: an over-provisioned pod, an idle disk, and a crashlooping deployment are the *same kind of problem* - operational hygiene - and they belong on the same screen with the same Investigate button. + +--- + +## Why Temporal Ships Inside an SRE Copilot + +The moment a copilot crosses from *answering* to *acting*, durability stops being optional. A remediation workflow that dies silently when a process restarts after step 3 of 7 is worse than no automation at all. + +NudgeBee runs every runbook and scheduled job through **Temporal**. I opened the bundled Temporal UI (`:8233`) and found the platform eating its own dog food - 102 workflow executions from just a few hours of uptime: + +![Temporal UI - 102 workflows: agent status checks, notification batching, insight refresh](/img/blog/nudgebee-ai-sre-copilot-hands-on/09-temporal-workflows.jpg) + +Agent health checks, notification batching, recommendation-resolution updates, insight refreshes, system cleanup - all as versioned, retryable, resumable workflows with full history. The Automations surface builds on the same engine: manual, scheduled, webhook, and event-triggered workflows, with approval steps, retries, child workflows, and persistent state. + +The division of labor here is exactly right: the LLM helps decide what to do, and Temporal makes doing it operationally boring. It is also why "AI will replace runbooks" has it backwards - AI makes durable runbooks *more* important. + +--- + +## Bring Your Own Model (Including the One on Your Desk) + +NudgeBee's pitch includes "no model lock-in," and v1.4.0 implements providers for OpenAI, Anthropic, Bedrock, SageMaker, Azure, Google AI, Vertex AI, and HuggingFace/vLLM-style endpoints. + +Two field findings worth your time: + +**1. For Ollama, use the OpenAI-compatible path - it is what the [official docs](https://docs.nudgebee.com/docs/integrations/LLM/Ollama/) configure, and it works.** The trap I fell into: the sample env file also lists `ollama` as a provider value, and that switch case is not wired up in v1.4.0, so picking it fails with `llm model not found - ollama`. Stick to the documented config, which goes through Ollama's OpenAI-compatible endpoint (the team told me they will make this more explicit): + +```bash +LLM_PROVIDER=openai +LLM_MODEL_NAME=qwen3.5:35b-a3b +LLM_PROVIDER_API_ENDPOINT=http://:11434/v1 +LLM_PROVIDER_API_KEY=anything-non-empty +``` + +**2. Local models need bigger timeouts.** The defaults assume cloud-API latency: 30 seconds to first token, a 10-minute global retry budget. An agent prompt here is 15k+ tokens, and a big local model can blow through both. Raise them: + +```bash +LLM_PROVIDER_TTFT_TIMEOUT_SECONDS=300 +LLM_SERVER_GLOBAL_RETRY_BUDGET_MINUTES=30 +LLM_SERVER_MAX_INDIVIDUAL_CALL_TIMEOUT_MINUTES=15 +``` + +On hardware: my Mac could not prefill the agent's ~16k-token prompts inside the deadlines. The DGX Spark prefilled the same prompt in **0.9 seconds warm (~17,900 tokens/sec)**. Two more lessons from the run: reasoning-mode models (qwen3.5's thinking) generate thousands of deliberation tokens per ReAct step, so decode speed - not prefill - becomes the loop's bottleneck; and a fast non-thinking model often beats a smarter slow one for agentic work. The completed investigation above ran on `gemma4:26b` - the full multi-tool loop plus write-up in about ten minutes, entirely on hardware I own. + +The architecture take-away is bigger than my desk, though: because the model is just an HTTP endpoint, "cluster on one machine, GPU on another, control plane on a third" works with zero special configuration. Your prompts and evidence stay on your network. + +--- + +## Where Would You Actually Use This? Six Scenarios + +Because the surfaces share one platform, these are not six separate products to evaluate - they are six entry points into the same one. + +**1. On-call triage.** Connect the cluster, wire Slack/Teams, and let the triage inbox rank what fires. The score plus event aggregation turns 40 raw alerts into 3 issues with owners. Start here - it is read-only and pays off day one. + +**2. Crashloop and error RCA.** The `payments-api` pattern: pod crashes, event fires, Investigate pulls describe + events + logs + recent changes in parallel and writes up a root cause with evidence attached. The investigation is recorded, so the *next* engineer searching that error finds a documented case, not a blank page. + +**3. FinOps and rightsizing.** After a few days of trends: workload/replica/PV rightsizing with monthly savings estimates, abandoned-volume detection, spot candidates - each with an Optimize action, gated behind approvals if you want them. + +**4. Runbook automation.** Codify the fix once as a Temporal-backed workflow: event-triggered ("on ImagePullBackOff in namespace X, check the registry and page the owning team"), scheduled (nightly hygiene), or webhook-driven (from your existing alertmanager). Approval steps make the write path safe to roll out gradually. + +**5. Ticket and incident hygiene.** The ticket-server syncs Jira, ServiceNow, PagerDuty, and Zenduty, so investigations attach to tickets and resolutions flow back - the Record stage, automated. + +**6. Multi-cluster and hybrid estates.** The relay design (agents dial out) means clusters behind NAT, in customer VPCs, or on edge hardware all connect the same way. One control plane, N clusters, per-account scoping. + +The common thread: **start read-only, earn trust, then open the write path** - observation → investigation → recommendation → automation, in that order. + +--- + +## Things I Would Be Careful About in Production + +The standard sharp edges of the category, plus what I hit: + +- **Start read-only.** Let it observe, investigate, and recommend before it remediates. The approval-gated workflows exist for a reason - use them. +- **Treat the LLM provider as a data boundary.** Prompts carry pod names, log lines, maybe secrets that slipped into logs. Self-hosting the model (above) is the strongest version of this control; the built-in egress filter is defense in depth, not a substitute for thinking. +- **The dummy credentials and sample secrets are for laptops.** `Test!24#5` and friends must never see a routable network. Disable dummy auth, rotate `NUDGEBEE_ENCRYPTION_KEY` handling into a real secret store, set the relay and internal service tokens, and read `docs/auth-and-networkpolicy.md` before exposing anything. +- **The encryption key is a one-way door.** Rotate it and previously encrypted rows are unreadable. There is no automatic re-encryption. +- **No telemetry by default** - data leaves only through integrations you configure (LLM calls, notifications, ticket sync, webhooks). Those paths are exactly where your security review should look. +- **Licensing**: Business Source License 1.1 - free to self-host internally; hosted/managed-service use is restricted; each version converts to Apache 2.0 after its change date. Read `LICENSE` and `LICENSING.md` if you are evaluating for a company. + +--- + +## What This Teaches About Building AIOps Platforms + +Five lessons I keep coming back to after a day inside it: + +1. **Context beats chat.** The interesting part is not the assistant - it is bCortex, the graph and memory around it: resources, events, tickets, tool calls, prior investigations. AI without context is a guesser; AI with context is an operator interface. +2. **Tools need ownership boundaries.** Tenant scoping, credential isolation, pre-flight write detection, output truncation - the boring parts are what make the write path safe. +3. **Runbooks are the safety rail, not the legacy.** The agent discovers and parameterizes workflows; Temporal gives them retries, approvals, versioning, and history. +4. **Cost is an ops signal.** Reliability and FinOps on one surface matches how platform teams actually work. +5. **A monorepo can be a teaching tool.** TypeScript for the app, Go for the backends, Python for ML and collectors, Postgres/RabbitMQ/Redis/Qdrant/Temporal each doing the one job they are best at. Studying why each piece exists is a free course in platform engineering. + +If you want to explore the code, follow the loop: start at `docs/ARCHITECTURE.md` and `docs/GLOSSARY.md`, then `llm/llm-server/agents/` and `tools/` for the AI layer (grep `RegisterNBAgentFactory` and `RegisterNBTool`), then `runbook-server/tests/integration/testdata/` (the code home of workflow-server) for a catalog of what the workflow engine can do, and finally `collector-server/` for how reality enters the system. + +--- + +## Final Mental Model + +```text +signals -> resources -> events -> triage -> investigations -> recommendations -> runbooks -> records +``` + +That is the SRE copilot loop, and NudgeBee is the most complete open implementation of it I have run. It earns the "copilot" name not because there is a chat box, but because every stage - collection, ranking, tool-driven investigation, durable remediation, and the paper trail - lives in one system that a small team can actually self-host. And because that system is agent-agnostic, the same AIOps platform covers SRE, FinOps, K8s ops, and whatever custom automation a team builds next. + +SRE still needs humans. What it should stop needing is humans doing all the glue work by hand. + +Give it a try on a test cluster and let me know what you find - and if you hit the same sharp edges I did, the fixes above should save you an evening. If the project looks useful to you, [star the repo on GitHub](https://github.com/nudgebee/nudgebee) - it is the easiest way to support the team building it - and tag me on [X @SaiyamPathak](https://x.com/SaiyamPathak) with what your investigations turn up. + +--- + +## Useful Links + +- Repo: [github.com/nudgebee/nudgebee](https://github.com/nudgebee/nudgebee) +- Release v1.4.0: [github.com/nudgebee/nudgebee/releases](https://github.com/nudgebee/nudgebee/releases) +- Helm chart: `oci://ghcr.io/nudgebee/charts/nudgebee` +- Architecture: [docs/ARCHITECTURE.md](https://github.com/nudgebee/nudgebee/blob/main/docs/ARCHITECTURE.md) +- Glossary: [docs/GLOSSARY.md](https://github.com/nudgebee/nudgebee/blob/main/docs/GLOSSARY.md) +- Auth & NetworkPolicy: [docs/auth-and-networkpolicy.md](https://github.com/nudgebee/nudgebee/blob/main/docs/auth-and-networkpolicy.md) +- Agent chart: [github.com/nudgebee/k8s-agent](https://github.com/nudgebee/k8s-agent) +- kiac (the local cluster tool): [github.com/saiyam1814/kiac](https://github.com/saiyam1814/kiac) + +--- + # Running Nemotron 3.5 Lightning on DGX Spark - Canonical: https://blog.kubesimplify.com/nemotron-3-5-lightning-on-dgx-spark @@ -225,7 +1174,9 @@ A 3B-active model decoding at 108 tok/s on a desktop box fits that execution lay - Canonical: https://blog.kubesimplify.com/dynamic-mig-in-kubernetes-with-hami - Published: 2026-08-11 -- Summary: A hands-on test of topology-aware HAMi Dynamic MIG on RTX PRO 6000 Blackwell, with pinned setup commands, real allocations, mixed profiles, reclamation, and recovery. +- Summary: Hands-on HAMi Dynamic MIG test on Kubernetes and RTX PRO 6000 Blackwell: setup commands, real allocations, mixed profiles, reclamation, and recovery. + +[HAMi (Heterogeneous AI Computing Virtualization Middleware)](https://project-hami.io/docs/next) Dynamic MIG lets a Kubernetes pod request GPU memory and receive a real [NVIDIA Multi-Instance GPU (MIG)](https://docs.nvidia.com/datacenter/tesla/mig-user-guide/latest/introduction.html) hardware instance created for that pod. In our RTX PRO 6000 Blackwell test, HAMi selected the smallest legal profile, packed different profiles on one card, reclaimed only the deleted pod's instance, and preserved a live allocation across a device-plugin restart. The first two posts in this series explored opposite ends of GPU sharing. @@ -245,12 +1196,12 @@ The results were straightforward: > **Version and migration note:** [PR #2378](https://github.com/Project-HAMi/HAMi/pull/2378) is merged, and this post tests the resulting per-pod implementation at [commit `634bf2b32e68`](https://github.com/Project-HAMi/HAMi/commit/634bf2b32e68e07d3fbcbd6da1ee079392fc07c1). At the time of this rerun, the latest tagged release was `v2.9.0`, which predates that implementation, so reproducing the lab requires the pinned source build below. Once HAMi publishes a release containing PR #2378, prefer its matching official chart and image. Existing `knownMigGeometries` users should follow the [migration guide](https://github.com/Project-HAMi/HAMi/blob/634bf2b32e68e07d3fbcbd6da1ee079392fc07c1/docs/develop/dynamic-mig-migration.md); the walkthrough below covers only the merged per-pod design. -{{dynamic-mig-lifecycle-animation}} - -## Dynamic MIG in one sentence +## What is HAMi Dynamic MIG in Kubernetes? A pod asks for GPU memory. HAMi chooses the smallest allowed MIG profile that has enough NVML-reported memory and a legal free placement, then creates that exact GPU Instance (GI) and Compute Instance (CI) for the pod. +{{dynamic-mig-lifecycle-animation}} + The workload request remains small: ```yaml @@ -288,7 +1239,7 @@ NVIDIA MIG divides a supported GPU into hardware-isolated instances. Each instan MIG can be part of a multi-tenant security design, but it does not make a platform secure or compliant by itself. Identity, admission, network, storage, runtime, and host controls still matter. -## The RTX PRO 6000 profile menu +## Which MIG profiles does the RTX PRO 6000 support? NVIDIA's [supported MIG profile table](https://docs.nvidia.com/datacenter/tesla/mig-user-guide/latest/supported-mig-profiles.html) lists three profile sizes for the RTX PRO 6000 Blackwell Server Edition: @@ -309,7 +1260,7 @@ nvidia: profiles: ["1g.24gb", "2g.48gb", "4g.96gb"] ``` -For every allowed profile, the HAMi device plugin running on the GPU node asks NVIDIA's Management Library (NVML) for memory, compute metadata, instance count, and legal placements. The scheduler then chooses the smallest profile that satisfies the request and fits without overlapping a live placement. +For every allowed profile, the HAMi device plugin running on the GPU node asks [NVIDIA's Management Library (NVML)](https://docs.nvidia.com/deploy/nvml-api/nvml-api-reference.html) for memory, compute metadata, instance count, and legal placements. The scheduler then chooses the smallest profile that satisfies the request and fits without overlapping a live placement. ## Lab environment @@ -547,7 +1498,7 @@ localhost/hami-dynamic-mig:master-634bf2b32e68 The monitor had one transient CDI `StartError` referring to a stale MIG UUID during the handover. Kubernetes retried it, and both plugin containers became ready. We checked the previous container state instead of hiding that transition. -## What HAMi discovered through NVML +## How does HAMi discover legal MIG placements through NVML? The node registration annotation is the clearest view of what the plugin learned from the driver: @@ -569,7 +1520,7 @@ The live discovery was: | `2g.48gb` | 48,512 | 50 | 2 | `(0,6)`, `(6,6)` | | `4g.96gb` | 97,408 | 100 | 4 | `(0,12)` | -NVML reports each legal placement as `start` and `size`: `start` is the index of the first occupied memory slice, and `size` is the number of memory slices occupied. Together they describe the half-open interval `[start, start + size)`. On this RTX PRO 6000, the reported placement range was `[0,12)`; these values are not GiB and are specific to this GPU. Also, `size` is not the same thing as `sliceCount`: `1g.24gb` has `sliceCount: 1` but placement `size: 3` here. +[NVML reports each legal placement as `start` and `size`](https://docs.nvidia.com/deploy/nvml-api/structnvmlGpuInstancePlacement__t.html): `start` is the index of the first occupied memory slice, and `size` is the number of memory slices occupied. Together they describe the half-open interval `[start, start + size)`. On this RTX PRO 6000, the reported placement range was `[0,12)`; these values are not GiB and are specific to this GPU. Also, `size` is not the same thing as `sliceCount`: `1g.24gb` has `sliceCount: 1` but placement `size: 3` here. The registered `count: 4` is a coarse maximum derived from the profiles. It does not mean every arbitrary combination of four profiles fits. The placement arrays and current occupancy determine real capacity. @@ -755,7 +1706,7 @@ kubectl scale deployment/mig-small-pack \ -n hami-mig-retest --replicas=4 ``` -## Test 3: mixed profiles share one physical GPU +## Test 3: Can mixed MIG profiles share one physical GPU? The topology-aware implementation can place different profiles together whenever NVML reports legal, non-overlapping placements. @@ -873,7 +1824,7 @@ large: 37 -> 39 PASS: both mixed-profile CUDA workloads progressed ``` -## Test 4: reclaim only the pod's own instance +## Test 4: Does HAMi reclaim only the deleted pod's MIG instance? Before deleting the small pod, we recorded the large pod's progress. Then we deleted only `mixed-small` and polled the host until its `1g.24gb` instance disappeared: @@ -914,7 +1865,7 @@ HAMi does not synchronously destroy the instance inside the `kubectl delete` cal We also recreated a `1g.24gb` instance at the freed placement. On this GPU and driver, it received the same `MIG-a5fa...` UUID. The UUID's observed disappearance proved reclamation; its later reappearance proved placement reuse. A MIG UUID is not a generation counter, so do not require a different UUID as proof of recreation. -## Test 5: recover a valid allocation after plugin restart +## Test 5: Does a live allocation survive a HAMi device-plugin restart? This is an advanced and disruptive controller test, not a normal workload step. We kept `mixed-large` active, recorded its progress and MIG UUID, then replaced the device-plugin pod: @@ -961,7 +1912,7 @@ This proves the tested happy path for a valid annotation. It is not a guarantee > **Node-wide safety warning:** `filterdevices` limits HAMi registration and scheduling, but at this commit it does not limit Dynamic MIG startup cleanup. The log shows that startup reconciled all eight physical GPUs, including filtered ones. Inventory and drain the entire node before the first install or a plugin restart; filtering a GPU is not a protection boundary. -## Test 6: the fifth pod spills to GPU 5 +## Test 6: What happens when one GPU's legal MIG placements are full? After deleting the mixed-profile workload and confirming no MIG instances remained, we changed the exclusion list from: @@ -1129,7 +2080,7 @@ The most useful result was not just allocation. HAMi reclaimed the small pod's e The caveats are equally important. Profile rounding and NVIDIA placement rules remain. Version alignment must be verified from live images. At this snapshot, plugin startup has a node-wide hardware scope even when only one GPU is registered, so controlled installation and restart procedures are mandatory. -HAMi is a CNCF Incubating project. Its source is at [github.com/Project-HAMi/HAMi](https://github.com/Project-HAMi/HAMi). Existing installations can use the [pinned Dynamic MIG migration guide](https://github.com/Project-HAMi/HAMi/blob/634bf2b32e68e07d3fbcbd6da1ee079392fc07c1/docs/develop/dynamic-mig-migration.md) when moving to this per-pod implementation. +HAMi is a [CNCF Incubating project](https://www.cncf.io/projects/hami/). Its source is at [github.com/Project-HAMi/HAMi](https://github.com/Project-HAMi/HAMi). Existing installations can use the [pinned Dynamic MIG migration guide](https://github.com/Project-HAMi/HAMi/blob/634bf2b32e68e07d3fbcbd6da1ee079392fc07c1/docs/develop/dynamic-mig-migration.md) when moving to this per-pod implementation. If you are joining the series here, read the [static MIG deep dive](/blog/slicing-gpus-in-kubernetes-with-nvidia-mig) and the [HAMi software vGPU guide](/blog/sharing-gpus-in-kubernetes-with-hami) first. diff --git a/public/llms.txt b/public/llms.txt index ed601be2a..6eae55e4c 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -4,7 +4,7 @@ ## About -Kubesimplify is a community-driven publication on cloud-native technologies, with 195 in-depth technical articles by 62 practitioner authors. We cover Kubernetes (kubelet internals, scheduling, networking, operators), container runtimes (containerd, CRI-O, Docker), GitOps (Argo CD, Flux), service meshes, observability, AI/ML infrastructure on Kubernetes, GPU workloads, platform engineering, and the broader CNCF ecosystem. +Kubesimplify is a community-driven publication on cloud-native technologies, with 198 in-depth technical articles by 62 practitioner authors. We cover Kubernetes (kubelet internals, scheduling, networking, operators), container runtimes (containerd, CRI-O, Docker), GitOps (Argo CD, Flux), service meshes, observability, AI/ML infrastructure on Kubernetes, GPU workloads, platform engineering, and the broader CNCF ecosystem. Authoritative, practitioner-written, citation-friendly. Articles include code examples, diagrams, and references. @@ -34,10 +34,13 @@ Authoritative, practitioner-written, citation-friendly. Articles include code ex - Cloud Native Security: https://blog.kubesimplify.com/hub/security (network policies, Falco, Kyverno, SLSA supply-chain) - Linux Fundamentals: https://blog.kubesimplify.com/hub/linux (shell, sysadmin, networking primitives) -## Recent posts (most recent 30 of 195) +## Recent posts (most recent 30 of 198) +- [The Local LLM Glossary: Every Term, Flag, and Number in Plain English](https://blog.kubesimplify.com/local-llm-glossary) (2026-08-18). Plain-English definitions for every term you hit in local LLM posts: prefill and decode, tokens per second, FP8 and NVFP4, Q4_K_M, KV cache, YaRN, Gated DeltaNet, speculative decoding, and every vLLM, llama.cpp, and Ollama flag worth knowing. +- [Running Qwen3.8-27B on DGX Spark](https://blog.kubesimplify.com/qwen3-8-27b-on-dgx-spark) (2026-08-17). Qwen3.8-27B on DGX Spark with llama.cpp, Ollama, vLLM, and SGLang: the recipes, the tokens per second I measured, MTP speculative decoding, and the sharp edges I hit along the way. +- [I Ran an AI SRE Copilot on My Own Hardware. Here Is What It Actually Does.](https://blog.kubesimplify.com/nudgebee-ai-sre-copilot-hands-on) (2026-08-17). Running NudgeBee v1.4.0 end to end - a self-hosted AIOps platform behind AI-SRE, AI-FinOps, AI-K8sOps, and agentic automation - on a Mac, a kiac cluster, and a DGX Spark. - [Running Nemotron 3.5 Lightning on DGX Spark](https://blog.kubesimplify.com/nemotron-3-5-lightning-on-dgx-spark) (2026-08-11). NVIDIA's new Nemotron 3.5 Lightning on DGX Spark: how to run it with Ollama and vLLM, the tokens per second I measured, and how the two paths compare. -- [HAMi Dynamic MIG on RTX PRO 6000: A Live Kubernetes Test](https://blog.kubesimplify.com/dynamic-mig-in-kubernetes-with-hami) (2026-08-11). A hands-on test of topology-aware HAMi Dynamic MIG on RTX PRO 6000 Blackwell, with pinned setup commands, real allocations, mixed profiles, reclamation, and recovery. +- [HAMi Dynamic MIG on RTX PRO 6000: A Live Kubernetes Test](https://blog.kubesimplify.com/dynamic-mig-in-kubernetes-with-hami) (2026-08-11). Hands-on HAMi Dynamic MIG test on Kubernetes and RTX PRO 6000 Blackwell: setup commands, real allocations, mixed profiles, reclamation, and recovery. - [Devin Outposts on Kubernetes: Why Your AI Agent Needs Your Cluster](https://blog.kubesimplify.com/devin-outposts-on-kubernetes) (2026-08-10). Devin Outposts runs AI coding agent sessions as pods on your own Kubernetes cluster, with an open-source operator to manage the fleet. - [How to Share GPUs in Kubernetes at Scale with HAMi (Software vGPU Slicing)](https://blog.kubesimplify.com/sharing-gpus-in-kubernetes-with-hami) (2026-07-23). Share NVIDIA GPUs in Kubernetes with HAMi software vGPU slicing: memory and compute limits, Helm configuration, a verified PyTorch manifest, a real RTX PRO 6000 OOM test, and Prometheus monitoring. - [Slicing GPUs in Kubernetes with NVIDIA Multi-Instance GPU (MIG)](https://blog.kubesimplify.com/slicing-gpus-in-kubernetes-with-nvidia-mig) (2026-07-20). GPU sharing in Kubernetes explained: time-slicing vs MPS vs MIG, every nvidia-smi command to enable and disable MIG on one GPU or eight, GPU Operator automation, pitfalls, and DCGM monitoring. @@ -63,41 +66,38 @@ Authoritative, practitioner-written, citation-friendly. Articles include code ex - [What Actually Happens When kube-scheduler Picks a Node (13 Stages Inside Kubernetes)](https://blog.kubesimplify.com/kube-scheduler-deep-dive) (2026-04-28). How kube-scheduler picks a node: 13 framework stages, 14 Filter plugins, 9 Score plugins, live preemption demo. - [Day 4: Breaking Isolation on Purpose - Volumes, Networks, and the Real World](https://blog.kubesimplify.com/day-4-breaking-isolation-on-purpose-volumes-networks-and-the-real-world) (2026-04-27) - [Day 3: Stop Writing Dockerfiles From Scratch](https://blog.kubesimplify.com/day-3-stop-writing-dockerfiles-from-scratch) (2026-04-24). Stop writing Dockerfiles from scratch. A Docker Captain walks through docker init, layer caching, multi-stage builds, and docker debug for 2026. -- [What Actually Happens When You Run kubectl run nginx](https://blog.kubesimplify.com/kubectl-run-nginx-inside) (2026-04-24). Every step of what happens when you run kubectl run nginx on Kubernetes. From argv to etcd Raft, scheduler, CRI, CNI, runc, and PLEG. -- [Day 2: Your Images Are a Supply Chain - and It's Probably Broken](https://blog.kubesimplify.com/day-2-your-images-are-a-supply-chain-and-it-s-probably-broken) (2026-04-23) -- [Day 1: What Actually Happens When You Type docker run](https://blog.kubesimplify.com/day-1-what-actually-happens-when-you-type-docker-run) (2026-04-22). Containers aren't VMs. They're Linux processes. A Docker Captain explains namespaces, cgroups, and how Docker really works on your Mac in 2026. ## Topics covered (auto-derived from tags) -- kubernetes (99 articles): https://blog.kubesimplify.com/tag/kubernetes +- kubernetes (100 articles): https://blog.kubesimplify.com/tag/kubernetes - devops (71 articles): https://blog.kubesimplify.com/tag/devops - docker (31 articles): https://blog.kubesimplify.com/tag/docker - k8s (27 articles): https://blog.kubesimplify.com/tag/k8s - linux (19 articles): https://blog.kubesimplify.com/tag/linux - containers (17 articles): https://blog.kubesimplify.com/tag/containers - cloud (16 articles): https://blog.kubesimplify.com/tag/cloud -- nvidia (12 articles): https://blog.kubesimplify.com/tag/nvidia +- nvidia (14 articles): https://blog.kubesimplify.com/tag/nvidia +- llm (12 articles): https://blog.kubesimplify.com/tag/llm - aws (12 articles): https://blog.kubesimplify.com/tag/aws -- llm (11 articles): https://blog.kubesimplify.com/tag/llm - cloud-native (11 articles): https://blog.kubesimplify.com/tag/cloud-native - security (11 articles): https://blog.kubesimplify.com/tag/security +- dgxspark (10 articles): https://blog.kubesimplify.com/tag/dgxspark - go (9 articles): https://blog.kubesimplify.com/tag/go - git (9 articles): https://blog.kubesimplify.com/tag/git - linux-for-beginners (9 articles): https://blog.kubesimplify.com/tag/linux-for-beginners -- dgxspark (8 articles): https://blog.kubesimplify.com/tag/dgxspark +- local-ai (8 articles): https://blog.kubesimplify.com/tag/local-ai - github (8 articles): https://blog.kubesimplify.com/tag/github - terraform (8 articles): https://blog.kubesimplify.com/tag/terraform -- local-ai (7 articles): https://blog.kubesimplify.com/tag/local-ai +- ai (7 articles): https://blog.kubesimplify.com/tag/ai +- platform-engineering (7 articles): https://blog.kubesimplify.com/tag/platform-engineering - docker-images (7 articles): https://blog.kubesimplify.com/tag/docker-images - kubesimplify (7 articles): https://blog.kubesimplify.com/tag/kubesimplify - linux-basics (7 articles): https://blog.kubesimplify.com/tag/linux-basics -- ai-agents (6 articles): https://blog.kubesimplify.com/tag/ai-agents -- platform-engineering (6 articles): https://blog.kubesimplify.com/tag/platform-engineering -- ai (6 articles): https://blog.kubesimplify.com/tag/ai +- ollama (6 articles): https://blog.kubesimplify.com/tag/ollama ## Top contributors -- [Saiyam Pathak](https://blog.kubesimplify.com/author/saiyam-pathak) (37 posts) +- [Saiyam Pathak](https://blog.kubesimplify.com/author/saiyam-pathak) (40 posts) - [Saloni Narang](https://blog.kubesimplify.com/author/saloni-narang) (24 posts) - [Kunal Verma](https://blog.kubesimplify.com/author/kunal-verma) (12 posts) - [Dipankar Das](https://blog.kubesimplify.com/author/dipankar-das) (9 posts) diff --git a/public/rss.xml b/public/rss.xml index e6bf6d7bf..2300c9b4a 100644 --- a/public/rss.xml +++ b/public/rss.xml @@ -6,8 +6,32 @@ Deep dives on Kubernetes, AI infrastructure, GitOps, and the cloud-native stack, written by practitioners. en-us - Tue, 11 Aug 2026 17:40:00 GMT + Tue, 18 Aug 2026 09:00:00 GMT Kubesimplify static blog + + The Local LLM Glossary: Every Term, Flag, and Number in Plain English + https://blog.kubesimplify.com/local-llm-glossary + https://blog.kubesimplify.com/local-llm-glossary + Tue, 18 Aug 2026 09:00:00 GMT + Plain-English definitions for every term you hit in local LLM posts: prefill and decode, tokens per second, FP8 and NVFP4, Q4_K_M, KV cache, YaRN, Gated DeltaNet, speculative decoding, and every vLLM, llama.cpp, and Ollama flag worth knowing. + local-aillminferencenvidiadgxsparkvllmollamaquantizationglossary + + + Running Qwen3.8-27B on DGX Spark + https://blog.kubesimplify.com/qwen3-8-27b-on-dgx-spark + https://blog.kubesimplify.com/qwen3-8-27b-on-dgx-spark + Mon, 17 Aug 2026 14:00:00 GMT + Qwen3.8-27B on DGX Spark with llama.cpp, Ollama, vLLM, and SGLang: the recipes, the tokens per second I measured, MTP speculative decoding, and the sharp edges I hit along the way. + qwendgxsparknvidiaollamavllm + + + I Ran an AI SRE Copilot on My Own Hardware. Here Is What It Actually Does. + https://blog.kubesimplify.com/nudgebee-ai-sre-copilot-hands-on + https://blog.kubesimplify.com/nudgebee-ai-sre-copilot-hands-on + Mon, 17 Aug 2026 10:00:00 GMT + Running NudgeBee v1.4.0 end to end - a self-hosted AIOps platform behind AI-SRE, AI-FinOps, AI-K8sOps, and agentic automation - on a Mac, a kiac cluster, and a DGX Spark. + kubernetesaisreaiopsplatform-engineering + Running Nemotron 3.5 Lightning on DGX Spark https://blog.kubesimplify.com/nemotron-3-5-lightning-on-dgx-spark @@ -21,8 +45,8 @@ https://blog.kubesimplify.com/dynamic-mig-in-kubernetes-with-hami https://blog.kubesimplify.com/dynamic-mig-in-kubernetes-with-hami Tue, 11 Aug 2026 10:00:00 GMT - A hands-on test of topology-aware HAMi Dynamic MIG on RTX PRO 6000 Blackwell, with pinned setup commands, real allocations, mixed profiles, reclamation, and recovery. - kubernetesgpunvidiaplatform-engineering + Hands-on HAMi Dynamic MIG test on Kubernetes and RTX PRO 6000 Blackwell: setup commands, real allocations, mixed profiles, reclamation, and recovery. + kubernetesgpunvidiahaminvidia-migplatform-engineering Devin Outposts on Kubernetes: Why Your AI Agent Needs Your Cluster diff --git a/scripts/gen-local-llm-glossary-cover.mjs b/scripts/gen-local-llm-glossary-cover.mjs new file mode 100644 index 000000000..803b42205 --- /dev/null +++ b/scripts/gen-local-llm-glossary-cover.mjs @@ -0,0 +1,212 @@ +// Excalidraw-style cover for the local LLM glossary post. +// Sketch helpers shared with scripts/gen-two-gpu-vllm-cover.mjs. +import { mkdirSync, writeFileSync } from 'node:fs'; +import { join } from 'node:path'; + +let seed = 42; +const random = () => { + seed = (seed * 16807) % 2147483647; + return seed / 2147483647; +}; +const jitter = (amount) => (random() - 0.5) * amount * 2; + +const COLORS = { + ink: '#172033', + muted: '#5c677d', + green: { stroke: '#5d8f00', fill: '#d8f5a2' }, + blue: { stroke: '#1971c2', fill: '#a5d8ff' }, + violet: { stroke: '#862e9c', fill: '#eebefa' }, + orange: { stroke: '#d9480f', fill: '#ffd8a8' }, + red: { stroke: '#c92a2a', fill: '#ffc9c9' }, + teal: { stroke: '#087f5b', fill: '#b2f2bb' }, + gray: { stroke: '#495057', fill: '#e9ecef' }, +}; + +const FONT = 'Chalkboard SE, Comic Sans MS, sans-serif'; + +function roughLine(x1, y1, x2, y2, amount = 1.8) { + const middleX = (x1 + x2) / 2 + jitter(amount * 1.5); + const middleY = (y1 + y2) / 2 + jitter(amount * 1.5); + return `M ${(x1 + jitter(amount)).toFixed(1)} ${(y1 + jitter(amount)).toFixed(1)} Q ${middleX.toFixed(1)} ${middleY.toFixed(1)} ${(x2 + jitter(amount)).toFixed(1)} ${(y2 + jitter(amount)).toFixed(1)}`; +} + +class Sketch { + constructor(width, height, background = '#ffffff') { + this.width = width; + this.height = height; + this.background = background; + this.parts = []; + this.defs = []; + this.clipId = 0; + } + + add(value) { + this.parts.push(value); + } + + rect(x, y, width, height, options = {}) { + const { + stroke = COLORS.ink, + fill, + strokeWidth = 2.4, + dashed = false, + hachure = true, + radius = 7, + } = options; + + if (fill) { + if (hachure) { + // Hatch lines are clipped in math rather than with an SVG clipPath so + // the file renders identically in renderers without clipPath support. + const hatch = []; + for (let offset = -height; offset < width; offset += 11) { + const tMin = Math.max(0, -offset / height); + const tMax = Math.min(1, (width - offset) / height); + if (tMax - tMin < 0.05) continue; + const x1 = x + offset + height * tMin; + const y1 = y + height - height * tMin; + const x2 = x + offset + height * tMax; + const y2 = y + height - height * tMax; + hatch.push(roughLine(x1, y1, x2, y2, 1)); + } + this.add(``); + } else { + this.add(``); + } + } + + const points = [[x, y], [x + width, y], [x + width, y + height], [x, y + height]]; + for (let pass = 0; pass < 2; pass += 1) { + const path = points.map((point, index) => { + const next = points[(index + 1) % points.length]; + return roughLine(point[0], point[1], next[0], next[1], pass === 0 ? 2 : 1.2); + }).join(' '); + this.add(``); + } + } + + line(x1, y1, x2, y2, options = {}) { + const { stroke = COLORS.ink, strokeWidth = 2.4, dashed = false } = options; + this.add(``); + } + + arrow(x1, y1, x2, y2, options = {}) { + const { stroke = COLORS.ink, strokeWidth = 2.6, dashed = false } = options; + this.line(x1, y1, x2, y2, { stroke, strokeWidth, dashed }); + const angle = Math.atan2(y2 - y1, x2 - x1); + const length = 14; + for (const offset of [Math.PI * 0.82, -Math.PI * 0.82]) { + this.line( + x2, + y2, + x2 + length * Math.cos(angle + offset), + y2 + length * Math.sin(angle + offset), + { stroke, strokeWidth } + ); + } + } + + text(x, y, value, options = {}) { + const { + size = 22, + color = COLORS.ink, + anchor = 'middle', + weight = 500, + family = FONT, + } = options; + const safe = String(value) + .replace(/&/g, '&') + .replace(//g, '>'); + this.add(`${safe}`); + } + + lines(x, y, values, options = {}) { + const lineHeight = (options.size || 22) * (options.lineHeight || 1.28); + values.forEach((value, index) => this.text(x, y + index * lineHeight, value, options)); + } + + save(path) { + const svg = ` +${this.defs.join('')} + +${this.parts.join('\n')} +`; + writeFileSync(path, svg); + } +} + +const output = process.argv[2] || '.'; +mkdirSync(output, { recursive: true }); + + +const W = 1200; +const H = 630; +const sketch = new Sketch(W, H, '#fdfdfb'); + +// ── heading ────────────────────────────────────────────── +sketch.text(64, 88, 'The Local LLM Glossary', { size: 54, weight: 800, anchor: 'start' }); +sketch.text(64, 128, 'every magic string in these posts, in plain English', { + size: 23, + color: COLORS.muted, + anchor: 'start', +}); +sketch.line(64, 150, 660, 150, { stroke: COLORS.muted, strokeWidth: 1.6, dashed: true }); + +// ── jargon on the left, plain English on the right ──────── +const ROWS = [ + { term: 'tg128', plain: 'decode speed, measured over 128 tokens', accent: COLORS.blue }, + { term: 'FP8', plain: '1 byte per weight, so half the size', accent: COLORS.green }, + { term: 'KV cache', plain: 'memory that grows with your context', accent: COLORS.violet }, + { term: 'MTP', plain: 'the model drafts ahead for itself', accent: COLORS.orange }, + { term: 'UD-Q4_K_XL', plain: '4-bit, but not evenly 4-bit', accent: COLORS.teal }, +]; + +const chipX = 64; +const chipW = 340; +const chipH = 56; +const rowTop = 186; +const rowGap = 68; + +ROWS.forEach((row, index) => { + const y = rowTop + index * rowGap; + sketch.rect(chipX, y, chipW, chipH, { stroke: row.accent.stroke, fill: row.accent.fill }); + sketch.text(chipX + chipW / 2, y + 37, row.term, { + size: 26, + weight: 800, + color: row.accent.stroke, + family: 'Roboto Mono, Menlo, monospace', + }); + sketch.arrow(chipX + chipW + 16, y + chipH / 2, chipX + chipW + 86, y + chipH / 2, { + stroke: COLORS.muted, + strokeWidth: 2.2, + }); + sketch.text(chipX + chipW + 106, y + 37, row.plain, { + size: 24, + anchor: 'start', + color: COLORS.ink, + }); +}); + +// ── footer strip ───────────────────────────────────────── +sketch.line(64, 528, W - 64, 528, { stroke: COLORS.muted, strokeWidth: 1.6 }); +sketch.text(64, 564, 'PREFILL - DECODE - QUANT NAMES - YARN - GATED DELTANET - EVERY FLAG', { + size: 19, + weight: 800, + anchor: 'start', + color: COLORS.ink, +}); +sketch.text(64, 594, 'Ctrl+F the thing that confused you, then go back to the post you came from', { + size: 17, + anchor: 'start', + color: COLORS.muted, +}); +sketch.text(W - 64, 594, 'blog.kubesimplify.com', { + size: 17, + weight: 700, + anchor: 'end', + color: COLORS.muted, +}); + +sketch.save(join(output, 'cover.svg')); +console.log(`Wrote local LLM glossary cover to ${output}`); diff --git a/vercel.json b/vercel.json index ca297af24..eaa7bd155 100644 --- a/vercel.json +++ b/vercel.json @@ -731,6 +731,11 @@ "destination": "https://blog.kubesimplify.com/llm-costs-and-observability-with-agentgateway-on-kubernetes", "permanent": true }, + { + "source": "/blog/local-llm-glossary", + "destination": "https://blog.kubesimplify.com/local-llm-glossary", + "permanent": true + }, { "source": "/blog/managing-contexts-in-kubernetes-with-plugins", "destination": "https://blog.kubesimplify.com/managing-contexts-in-kubernetes-with-plugins", @@ -816,6 +821,11 @@ "destination": "https://blog.kubesimplify.com/nexus-repository-manager-what-is-it-and-how-to-configure-it-on-a-digital-ocean-droplet", "permanent": true }, + { + "source": "/blog/nudgebee-ai-sre-copilot-hands-on", + "destination": "https://blog.kubesimplify.com/nudgebee-ai-sre-copilot-hands-on", + "permanent": true + }, { "source": "/blog/nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform", "destination": "https://blog.kubesimplify.com/nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform", @@ -881,6 +891,11 @@ "destination": "https://blog.kubesimplify.com/quick-bites-of-fluxcd-health-assessment", "permanent": true }, + { + "source": "/blog/qwen3-8-27b-on-dgx-spark", + "destination": "https://blog.kubesimplify.com/qwen3-8-27b-on-dgx-spark", + "permanent": true + }, { "source": "/blog/rancher-desktop-evolution", "destination": "https://blog.kubesimplify.com/rancher-desktop-evolution", @@ -2516,6 +2531,17 @@ } ] }, + { + "source": "/local-llm-glossary", + "destination": "https://blog.kubesimplify.com/local-llm-glossary", + "permanent": true, + "has": [ + { + "type": "host", + "value": "kubesimplify.com" + } + ] + }, { "source": "/managing-contexts-in-kubernetes-with-plugins", "destination": "https://blog.kubesimplify.com/managing-contexts-in-kubernetes-with-plugins", @@ -2703,6 +2729,17 @@ } ] }, + { + "source": "/nudgebee-ai-sre-copilot-hands-on", + "destination": "https://blog.kubesimplify.com/nudgebee-ai-sre-copilot-hands-on", + "permanent": true, + "has": [ + { + "type": "host", + "value": "kubesimplify.com" + } + ] + }, { "source": "/nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform", "destination": "https://blog.kubesimplify.com/nvcf-is-now-open-source-inside-nvidia-s-gpu-function-platform", @@ -2846,6 +2883,17 @@ } ] }, + { + "source": "/qwen3-8-27b-on-dgx-spark", + "destination": "https://blog.kubesimplify.com/qwen3-8-27b-on-dgx-spark", + "permanent": true, + "has": [ + { + "type": "host", + "value": "kubesimplify.com" + } + ] + }, { "source": "/rancher-desktop-evolution", "destination": "https://blog.kubesimplify.com/rancher-desktop-evolution",