fridiculous.ai

Why run one myself. The model sits on a box in my office, so my code stays there. It works offline, and nothing about the setup changes unless I change it.

What it's for. 32 GB of graphics memory runs a strong 27B model. I still reach for hosted models when the problem is genuinely hard; the box in my office handles the fast, private, repetitive passes.

What comes with it. Running a model yourself means you get to customize and control a lot of things during inference. It also means you manage your own security and configure your own safeguards.

What I did. Took every major model I could fit in VRAM and varied the configurations, with vLLM and llama.cpp as the inference servers, until the results reached statistical significance.

Gaps are paired by item vs a control run, with 95% CIs. = CI excludes zero. Dotted terms define themselves on hover.

OV

The map

Everything runs on one RTX 5090. Below is what's on the bench, then what each setting turned out to cost. Every row links to the tab with the working.

Setup — what's on the bench
Models23 registered checkpoints and each one's permutation surfaceCurrent leader: a dense 27B with the MTP head — pending three validation gates.
Enginesllama.cpp vs vLLM — does the stack change the answers?llama.cpp serves everything today; parity rows keep vLLM honest.
HardwareThe one box everything runs onRTX 5090 32 GB · Ryzen 9900X · 64 GB DDR5 · all Micro Center.
EvalsThe eight tasks every cell is scored onFrozen at run start; no LLM judges; item counts set each task's resolution.
ConfigurationsThe factor grid the experiments walk276 cells; one knob varied at a time, everything else pinned.
Results — what was learned
Weight precisionCan I recover 5–10 GB without losing accuracy?Yes within the GGUF family. NVFP4 is the exception: real instruction-following deficits, being checked against run-to-run noise.
KV cacheCan I shrink the cache for free?No detectable loss in 56 clean comparisons; q8_0 is the current choice. Long-context retrieval still unchecked.
SpeculationHow much free speed does drafting buy?Quality preserved; the speed measurement (depth 0/2/4) is running now.
Dense vs MoEWhich frontier point do I want to serve?Currently the dense 27B — quality costs me more than latency. New MoEs queued that could change this.
LoadDoes quality survive 8 concurrent requests?Untested — the last gate before cutover; queued next.
WatermarkCan output carry a provable signature without a quality tax?Detection pipeline validated on CPU; the quality-cost question runs on GPU after the cutover decision.

Reading the tabs: each has a toy model you can play with (simulated), the run's actual measurements, and my call. Dotted terms define themselves on hover.

S1

Which model?

23 measured — one leader
Record · measured Aug 23 – Sept 9, 2026 · speed: single-request decode, llama.cpp v0.2.0 (vLLM 0.27.1 where mapped) · quality: full suite, temp 0, seed 1234, 32k context · 23 checkpoints · status: complete; leader provisional until the three gates report
What the run measured — the whole field

Every checkpoint benchmarked on this machine: decode speed (log scale) vs mean quality (unweighted mean over shared tasks). The dense 27Bs lead quality, the 30B-class MoEs lead speed.

The full registry, and which permutations each checkpoint supports: an MTP draft head is a property of the checkpoint; a vLLM twin exists only where the same weights are published as an HF checkpoint; KV columns show which cache quantizations have measured cells so far. Click a column header to sort.

My call

The current leader is qwen38-27b with the MTP head — the newest dense 27B, which arrived mid-campaign and beat the incumbent it was measured against. What keeps this honest: the field moves monthly. Four candidates are queued for evaluation after this run's ledger freezes — Nemotron 3.5 Lightning, Ornith 1.5 35B-A3B, GLM-5.3-Flash, and Nex-N2.5-mini 35B, and anything new that fits in 32 GB gets the same paired treatment against the frozen baseline rather than a fresh start.

S4

Evals

Record · suite fixed Aug 23, 2026 for the life of the run · every cell answers the same items, temp 0, seed 1234 · scores are pass rates in [0, 1]
The measuring sticks

Eight tasks, chosen to cover what a coding-assistant server actually does — and frozen at run start, because a suite that shifts mid-campaign can't support paired comparisons. Item counts matter: they set how small a gap each task can resolve.

taskitemswhat it measuresresolution
gsm8k_cot_zeroshot1,319grade-school math word problems, step-by-step reasoningfine (~±1 pt)
bigcodebench_full1,140realistic library-using coding tasks, executed and unit-testedfine
cruxeval_output800predicting what a piece of code prints — code readingfine
ifeval541following precise, checkable instructions ("exactly 3 bullets…")medium
ifbench300harder instruction-followingmedium (~±3–5 pts)
humaneval_instruct164classic small Python functions, executedcoarse
bigcodebench_hard148the hardest bigcodebench slicecoarse
internal_workload5private smoke check of the server's real promptsgo/no-go only

Scoring is automatic end-to-end: code tasks run the generated code against tests; instruction tasks check constraints programmatically; math extracts the final answer. No LLM judges anywhere — a deliberate choice, since a judge model would itself be a confound when comparing engines and quantizations.

What the suite can and cannot see

Coverage is deliberately skewed toward code and instruction-following, because that's the server's job. What it cannot see: long-context retrieval (queued with the 131k pass), conversational quality, and anything a 5-item smoke check merely gestures at. A capped general-knowledge pass (HLE) is queued in the fixup stage as a breadth check, not a decision input.

S5

Configurations

Record · the factor grid as designed Aug 23, 2026 (trimmed Sept 2 to drop provably redundant interaction cells) · 276 cells · ~708 GPU-hours planned
The grid the experiments walk

Every experiment tab is a slice of one crossed design: each cell is a (model × engine × settings) combination run against the full quality suite under identical conditions. These are the factors and the levels being crossed:

factorlevelsexperiment tab
model checkpoint23 registered (see Models)Models · Dense vs MoE
weight precisionQ4_XL · Q5 · Q6 · Q8 · F16 · NVFP4Weight precision
KV cache typef16 · q8_0 · q4_0KV cache
draft depth (MTP)0 · 2 · 4Speculation
enginellama.cpp · vLLM (where mapped)Engines
concurrency (np)1 · 8 (quality); 1·2·4·8 (speed)Load
watermark bias δ0 · 2 · 4 (γ=0.25, h=4)Watermark
held constanttemp 0 · seed 1234 · 32k context · same promptsevery cell

Each factor's range: the grey track is what the software allows, solid dots are levels with measured cells, hollow dots are levels queued but not yet run. Hover a dot.

Not every combination runs — the full cross would be thousands of cells. The design measures each factor where it can matter and drops cells whose outcome is provably implied by others (e.g. depth × quantized-KV interactions, since verification makes depth quality-inert). Replicate cells re-run identical configurations to measure the noise floor that every comparison is judged against.

Why a grid instead of ad-hoc tests

Because the question is never "is model A good" — it's "does this knob change the answer while everything else is pinned." Paired cells that differ in exactly one factor are what let a 0.4-point gap be attributed to the cache instead of to luck.

E1

Weight precision (Q4 → Q8, NVFP4)

no detected in-family loss — one exception
Record · measured Aug 23 – Sept 9, 2026 · paired by item vs same-family control, n = 148–1,319 per task · driver 580 → 595.84 mid-run (drift canary clean across the boundary) · status: complete; NVFP4 stars await the replicate noise floor
Toy model (simulated, not measured)

The question: can I recover 5–10 GB for context without losing accuracy? Quantization stores weights in 4–8 bits instead of 16. There are reasons it can work (rounding errors tend to average out in large sums) — but where it fails is not predictable from theory, which is why every cell below is measured rather than assumed.

What the run measured — quality vs VRAM, within one family

Same family, only bit-width changes: the line stays flat while VRAM moves 5–10 GB. no detectable in-family difference between Q4_XL and Q8 on these tests. The f16 controls agree.

The exception: NVFP4 shows three starred deficits — two instruction-following (IFEval −4.1, IFBench −5.3 points) and one math reasoning (GSM8K −1.4). Large enough to investigate before the cutover; the replicate tier grades them against the run-to-run noise floor.

My call

I use the smallest XL quant and spend the recovered VRAM on context. What surprised me: NVFP4's deficit concentrates in instruction-following, not in the math or code where I expected a 4-bit float format to hurt. If replicates show the IFEval gap is above run-to-run noise, choosing NVFP4 means knowingly paying ~4 IFEval points for its speed — that is the decision, and I haven't made it yet.

E2

KV-cache precision (f16 → q8_0 → q4_0)

no detectable loss
Record · measured Aug 28 – Sept 11, 2026 · control = same model, same weights, f16 cache · llama.cpp v0.2.0 · status: decision rows complete; q4_0 sweep of the remaining field rows still running
Toy model (simulated, not measured)

The question: can I shrink the cache — the other big VRAM consumer — for free? The KV cache holds every previous token's attention state; at 32k context it rivals the weights in size. It should tolerate quantization better than weights do, because attention renormalizes scores — but "should" is exactly the thing under test, and long-range retrieval is where I'd expect it to fail first.

What the run measured — every paired KV comparison

Every clean gap estimate as one dot — the distribution behind the verdict. Hover a dot for its model, task, CI and n.

The payoff: q8_0 saves ~1–3.8 GB, q4_0 up to ~5.9 GB of measured peak VRAM.

My call

KV quantization looks worth using on this machine. Across 56 unconfounded comparisons, none showed a statistically significant quality difference, and every CI excludes a loss worse than 4.1 points (2.1 on the n≥800 tasks). That still leaves room for losses the tests could not detect. The memory savings are useful, so q8_0 is my current choice. Long-context retrieval is the next check.

E3

Speculative decoding (MTP head)

quality preserved — speed being measured
Record · quality checks Aug – Sept 2026 (identity-gated, byte-compare) · status: speed ladder (depth 0/2/4) running on the GPU now
Toy model (simulated, not measured)

The question: how much free speed does drafting buy on my workload? A small head guesses the next few tokens; the big model verifies them in one pass and keeps only tokens it would have sampled anyway, so the output distribution is preserved. Speed is the open question — it depends on acceptance rate and drafting overhead, and that measurement is running now.

What the run measured

MTP-on vs MTP-off at identical weights: every delta inside ±0.01 — consistent with distribution-preserving verification (theory does not bound finite-sample deltas, so this is evidence, not proof).

Speed at depth {0,2,4} is measuring right now (tier 4b, in progress).

My call

Quality results are reassuring. I'll keep it enabled only where the depth-ladder speed numbers justify it — the ladder is on the GPU now, and depth 0 (off) is a live possibility.

E4

Dense vs mixture-of-experts

real trade — speed vs depth
Record · same field measurement as tab 01 (Aug 23 – Sept 9, 2026) · status: complete for this checkpoint set
Toy model (simulated, not measured)

The question: which point on the speed–quality frontier do I actually want to serve? Dense models run every token through all parameters; MoEs activate ~10%, so they read far less memory per token — and memory bandwidth is the wall on one GPU. That mechanism predicts the speed difference well. It does not predict the quality difference; that's what the measurements are for.

What the run measured — the whole field

All 23 models: decode speed (log) vs mean quality — the unweighted mean of each model's benchmark scores over its shared task set (internal workload check excluded). Two clusters among these tested checkpoints — the dense models land slow-and-higher, the MoEs fast-and-slightly-lower. This supports picking a model from this set; it does not isolate architecture as the cause (training data, scale and tuning all differ).

My call

Why I currently prefer the dense 27B: on my workload the quality gap costs me more than the latency gap does, and the other knobs (MTP, NVFP4, quantized KV) claw back most of the speed. The strongest MoE alternatives in this set are qwen3-coder-30b (fastest, weakest on code-execution prediction) and qwen36-35b (closest on quality, ~4× faster). An MoE that closed the bigcodebench gap would change my answer — which is why Nemotron and Ornith are queued for October.

E5

Concurrency & load (np=1 → np=8)

pending — queued next
Record · status: not yet run — queued immediately after the replicate tier; last gate before the cutover decision
What remains untested

Every quality number so far was taken one request at a time. Under batching, kernel shapes and cache sharing change the arithmetic, so the same prompt can legitimately produce different tokens. Throughput at np∈{1,2,4,8} is already measured (see the explorer); quality under 8-way load never has been — that measurement runs right after the replicates.

My call

I won't cut over on single-request quality alone — the production server runs loaded, and the new config stacks three changes at once. If quality at np=8 holds within the replicate noise floor, the provisional config goes final.

E6

Watermarking (green-list bias δ)

pilot done — GPU study queued
Record · pilot run Sept 10, 2026, 74 min on CPU only (Ryzen 9900X, zero GPU time) · Qwen3-1.7B float32, transformers 5.15.1, explicit logits processor · 90 generations banked · status: pilot complete; production-model study queued
Toy model (simulated, not measured)

The question: can the server's output carry a provable signature without a quality tax? Hash the last h tokens → split the vocab into a γ "green" fraction → add bias δ to green logits. Text drifts green in a way only the key-holder can test. Detection strength grows ~√length; δ trades detectability against a possible quality tax.

What the pilot measured — Sept 10, Qwen3 1.7B, 30 prompts × 3 doses

Detection increased with watermark strength and with text length, and every generation is visible: the control cloud sits at z≈0 (0/30 detections), δ=2 straddles the threshold (16/30 at 300 tokens), δ=4 clears it for 29/30 — and the spread within each dose is as informative as the means. (One pilot, one small model — staging evidence, not the study.)

My call

Pipeline validated for zero GPU time. Next: quality cost on the production model (study W1: dose-response), whether quantized KV blunts detection (W2), and whether the mark survives paraphrase and splicing (W5) — after the cutover decision.

S2

Inference engines

two stacks, measured head-to-head where possible
Record · llama.cpp v0.2.0 (pinned) and vLLM 0.27.1 · parity rows measured Aug–Sept 2026 · status: llama.cpp serves every row; vLLM serves 3 of 4 mapped twins
What each stack is, and how they're compared fairly

The engine is a knob like any other — the same weights can serve faster or slower, and in principle differently, depending on who runs them. The trap in comparing engines is comparing files instead: llama.cpp serves GGUF, vLLM serves HF checkpoints, and two files of "the same model" usually aren't. This run's design: for a handful of parity rows, the GGUF was converted losslessly from the exact HF checkpoint vLLM serves, so an f16 gap is purely the stack; the 27B Q8-vs-FP8 row adds one controlled variable (8-bit format) on top.

llama.cpp v0.2.0vLLM 0.27.1
model formatGGUF (all 23 rows)HF checkpoints (4 mapped twins)
quantized weightsK-quants, NVFP4FP8, NVFP4 (blocked on this GPU)
quantized KV cacheq8_0 / q4_0, any modelFP8, where the checkpoint pins it
speculative decodingMTP head (3 checkpoints)not exercised in this run
concurrency modelslot-split cache, np≤8 testedcontinuous batching, paged attention
tool-calling APIqueued (characterization tail)
Blackwell (sm120) statuscleanpartial — see below
What the run found

Three findings, all discovered by trying rather than reading release notes. One: vLLM 0.27.1 routes hybrid-architecture prefill through a JIT compiler (FlashInfer) that cannot build for this GPU's compute capability with the CUDA toolkit the machine has — which makes the NVFP4 twin unservable on vLLM here, full stop. Two: a checkpoint that pins FP8 KV in its own config silently selects an incompatible attention backend unless the launcher detects it and overrides — a class of failure where the config is honored and the server still dies. Three: at 32 GB, the f16 parity rows are the only place both stacks can hold identical weights; everywhere else the honest comparison is "stack + format", not "stack".

The parity quality gaps themselves (f16 rows, Q8-vs-FP8 row) live in the run ledger and land in the decision brief with the fixup pass — not summarized here until they're checked.

My call

llama.cpp is the serving stack today: it runs every checkpoint, quantizes any cache, and carries the MTP head that the leading model depends on. vLLM stays in the campaign for what it's genuinely better at — continuous batching and a tool-calling API — and because the parity rows keep both stacks honest. The open item that could flip this: a CUDA toolkit upgrade unblocks vLLM's Blackwell path, and its batching may matter more once the server is measured under real concurrent load.

S3

My local AI setup

I run an AI coding assistant on a desktop computer in my office. Here's the hardware, what each part does, and the limits I've run into.

32 GB graphics memory

A Gigabyte RTX 5090 runs the AI model. Its memory decides which models fit entirely on the graphics card.

64 GB system memory

Separate from graphics memory. Two 32 GB DDR5 sticks that load the models and run the software and tests around them.

4 TB storage

Holds the downloaded model files — about 40 of them, 10–30 GB each — and every saved test result.

Cooling affects these results

This is an air-cooled build — a three-fan card and a large air cooler on the processor, in a mesh case. Under sustained testing the graphics card reaches 89–91 °C and slows itself down to stay there. The speed numbers on this page are what this machine does under those conditions, which is why they're measured here rather than quoted from reviews.

The main constraint is graphics memory: 32 GB is the budget, and each setting on this page changes how much of it the model needs. System memory turned out to matter more than I expected — one piece of model-serving software peaked at 56.6 GB of it mid-run and the process was stopped after running out. That's one measurement on one configuration, not a minimum spec.

Full hardware specifications
Record · parts and prices from the purchase receipt, June 7 2026 · inventory confirmed against the live system Sept 11, 2026
PartComponentWhat it does here
Graphics cardGigabyte RTX 5090 Gaming OC, 32 GB GDDR7SKU 805390Runs the model. Its 32 GB is the limit everything else is tuned against.
ProcessorAMD Ryzen 9 9900X, 12 coresSKU 721209Ran the whole watermark pilot on idle cores while the graphics card was busy — 7 CPU-hours, no GPU time.
System memory64 GB DDR5-6400 CL34 (2×32)Loads models and runs the test harness. Peak observed: 56.6 GB.
StorageSanDisk WD_BLACK SN850X 4 TB NVMeSKU 753095Saved model files and run results. At 10–30 GB per model, 2 TB would already be tight.
MotherboardMSI MPG X870E Carbon WiFiSKU 755892Connects the graphics card and the drive at full speed.
Power supply1200 W, 80+ Platinum, ATX 3.xHeadroom for a card that pulls hard in bursts.
CPU coolerNoctua NH-D15 chromax.blackSKU 958470Air, not liquid. Keeps the processor quiet during CPU-only runs.
CaseLian Li LANCOOL 217 InfinitySKU 919928Mesh front. The airflow the card is working against.

Everything from Micro Center, bought together in June 2026. Where the specific model matters, the link goes to Micro Center's search for that SKU; memory and power supply are listed by spec, since any part meeting it would do.

Technical notes. The 5090 is a Blackwell card, which is why NVFP4 is available as a weight format at all — see Precision. It's also a factory-overclocked model, so its speed numbers run a little above a reference card's; that's one more reason every speed on this page is measured on this box. The board gives the card PCIe 5.0 x16 and the drive a direct NVMe link. The CPU-only watermark pilot is under Watermark.

How I test

Paired by item. Two configurations are only ever compared on the exact same questions; the difference is computed per question and summarized, which cancels question difficulty.

Intervals, not points. A gap is reported with a 95% bootstrap confidence interval over items. A ★ means the interval excludes zero. The registry's per-model quality intervals are a looser approximation (binomial per task, averaged) used only to refuse false rankings.

Ties are ties. Models whose intervals overlap the leader's are marked ≈ tie rather than ordered.

No LLM judges. Code is executed against tests, instructions are checked programmatically, math answers are extracted. Nothing is graded by another model.

One writer. Every number on this page comes out of one generated data file; nothing is hand-edited. Dates on each Record strip say when and under what environment each number was measured — a measurement is only ever quoted with its era.

Known limits. One machine, one run, greedy decoding at temperature 0, a suite skewed toward code and instruction-following. The run-to-run noise floor is being measured now (replicate tier) and will retroactively grade every borderline ★.