modularWEIGHTS · serving

What they cost to actually run

The catalogue says what these models are good at. This says what they deliver on real hardware: how much conversation 16 simultaneous users each get, and how fast. Every figure was measured on one machine rather than estimated from parameter counts.

Measured 2026-09-27 · Q4_K_M through llama-server · 16 slots · KV cache at q8_0 · flash attention on.

The number that surprises people

Memory per token of conversation varies 17× across these models — from 18 KiB to 320 KiB. It does not track model size. A 7B model here costs almost five times more per token than a 31B, because it lacks grouped-query attention.

That is why a single context setting cannot work across a fleet, and why “how much context can I give people?” has to be answered per model rather than per card.

How to read these

Each user gets is the context ceiling for one conversation. The 16 slots share a single pool, so not every user can sit at the ceiling simultaneously. All 16 together is total throughput — the figure that matters for a busy server. One user is what a single person experiences while the other fifteen are active. A +RAM row means the KV cache was pushed to system memory, which buys far more context for roughly half the speed.

Per model

Model names link to their capability scores in the catalogue.

gemma-4-31B

Best here on maths and instructions. Needs both A4500s.

cardeach user getsall 16 togetherone user
2× A450012k164 tok/s22 tok/s
context cost 66 KiB per token

Qwen3.6-27B

Lowest KL of the three 27Bs. Strong all-round.

cardeach user getsall 16 togetherone user
A45001k116 tok/s24 tok/s
2× A450025k122 tok/s25 tok/s
context cost 49 KiB per token

Qwen3.5-27B

Highest code score in the set, by a hair.

cardeach user getsall 16 togetherone user
A45001k118 tok/s24 tok/s
2× A450025k120 tok/s25 tok/s
context cost 49 KiB per token

Qwen3.8-27B

Refusal removal changed nothing on any axis.

cardeach user getsall 16 togetherone user
A45001k102 tok/s23 tok/s
2× A450025k105 tok/s24 tok/s
context cost 49 KiB per token

granite-4.1-30b

Tool-use oriented. Lowest base refusal rate of the large models.

cardeach user getsall 16 togetherone user
2× A45007k215 tok/s26 tok/s
context cost 147 KiB per token

Qwen3.5-9B

Best fit for a single mid-range card. Near-27B code at a third the size.

cardeach user getsall 16 togetherone user
RTX 30805k377 tok/s91 tok/s
RTX 4070 S9k352 tok/s70 tok/s
A450022k303 tok/s70 tok/s
2× A450058k311 tok/s72 tok/s
2× A4500 +RAM131k37 tok/s11 tok/s
context cost 33 KiB per token

gemma-4-E4B

Best instruction-following and code per gigabyte.

cardeach user getsall 16 togetherone user
RTX 30808k487 tok/s115 tok/s
RTX 4070 S13k514 tok/s97 tok/s
A450030k456 tok/s92 tok/s
2× A450078k433 tok/s87 tok/s
context cost 24 KiB per token

Olmo-3-7B-Instruct

Fully open training data and recipe. The context outlier - no grouped-query attention.

cardeach user getsall 16 togetherone user
RTX 3080768663 tok/s110 tok/s
RTX 4070 S1k621 tok/s84 tok/s
A45002k552 tok/s84 tok/s
2× A45006k558 tok/s87 tok/s
context cost 320 KiB per token

Qwen3.5-4B

Strong all-rounder at small size. Good throughput default.

cardeach user getsall 16 togetherone user
RTX 308011k462 tok/s129 tok/s
RTX 4070 S14k437 tok/s106 tok/s
A450027k389 tok/s101 tok/s
2× A450063k394 tok/s105 tok/s
A4500 +RAM131k55 tok/s20 tok/s
2× A4500 +RAM131k46 tok/s15 tok/s
context cost 33 KiB per token

Phi-4-mini-instruct

Decent maths for 3.8B but weak instruction-following. Not for structured output.

cardeach user getsall 16 togetherone user
RTX 30804k878 tok/s181 tok/s
RTX 4070 S5k833 tok/s141 tok/s
A450011k759 tok/s139 tok/s
2× A450024k738 tok/s143 tok/s
A4500 +RAM131k482 tok/s88 tok/s
2× A4500 +RAM131k442 tok/s81 tok/s
context cost 84 KiB per token

gemma-4-E2B

Punches above its size on code. Weak at maths.

cardeach user getsall 16 togetherone user
RTX 308010k679 tok/s169 tok/s
RTX 4070 S14k644 tok/s147 tok/s
A450028k586 tok/s141 tok/s
2× A450066k509 tok/s107 tok/s
2× A4500 +RAM131k434 tok/s94 tok/s
context cost 31 KiB per token

Olmo-3-7B-Think

Reasoning model measured in no-think mode, so these scores understate it.

cardeach user getsall 16 togetherone user
RTX 3080768540 tok/s108 tok/s
RTX 4070 S1k505 tok/s82 tok/s
A45002k432 tok/s82 tok/s
2× A45006k442 tok/s85 tok/s
context cost 320 KiB per token

Llama-Nemotron-Nano-4B

Cleanest refusal removal in the set. Weak maths.

cardeach user getsall 16 togetherone user
RTX 30804k930 tok/s178 tok/s
RTX 4070 S5k870 tok/s142 tok/s
A450010k783 tok/s135 tok/s
2× A450024k795 tok/s139 tok/s
A4500 +RAM131k456 tok/s86 tok/s
2× A4500 +RAM131k433 tok/s79 tok/s
context cost 84 KiB per token

Qwen3.5-2B

Use where footprint dominates but long context still matters.

cardeach user getsall 16 togetherone user
RTX 308025k762 tok/s231 tok/s
RTX 4070 S32k721 tok/s186 tok/s
A450056k665 tok/s193 tok/s
2× A4500121k621 tok/s189 tok/s
RTX 3080 +RAM131k96 tok/s20 tok/s
RTX 4070 S +RAM131k107 tok/s43 tok/s
A4500 +RAM131k106 tok/s47 tok/s
2× A4500 +RAM131k96 tok/s48 tok/s
context cost 18 KiB per token

Qwen3.5-0.8B

Not for maths or code. Viable for routing, classification, drafting.

cardeach user getsall 16 togetherone user
RTX 308027k855 tok/s290 tok/s
RTX 4070 S34k803 tok/s264 tok/s
A450058k723 tok/s258 tok/s
2× A4500124k694 tok/s246 tok/s
RTX 3080 +RAM131k105 tok/s23 tok/s
RTX 4070 S +RAM131k114 tok/s51 tok/s
A4500 +RAM131k101 tok/s52 tok/s
2× A4500 +RAM131k110 tok/s50 tok/s
context cost 18 KiB per token

Qwen3.5-35B-A3B

refusals not removed

Never had its refusals removed - fused experts make it unreachable. Listed because it serves perfectly well.

cardeach user getsall 16 togetherone user
2× A450044k322 tok/s105 tok/s
context cost 21 KiB per token

How much context you can actually give

A full-context 27B runs today, and dividing that context between users is free.

With a unified KV cache the slots share one allocation sized by -c. The pool is what costs memory - not how many people you divide it among. Measured on a 27B across two 18 GB cards, the same 262,144-token pool costs the same memory and runs at the same speed however it is split.

dividing one 262k pool — Qwen3.8-27Bmemoryspeed
1 user × 262k (the model's full context)28.7 GB25 tok/s
2 users × 131k28.9 GB25 tok/s
4 users × 65k29.2 GB25 tok/s

So “full context for one person” and “half of it each for two” are the same purchase. Size the pool to the hardware, then divide it to suit the work.

the same model at full contextmemory usedspeed
two 18 GB cards, KV on GPU28.7 GB25 tok/s
one 18 GB card, KV on GPUneeds 8.7 GB moredoes not start
one 18 GB card, KV in system memory17.2 GB6 tok/s
two 18 GB cards, KV in system memory19.3 GB6 tok/s
Pushing the KV cache to system memory roughly halves the memory a card needs, which is the only way to fit a full-context 27B on a single 18 GB card. It costs about four times the speed, because every token re-reads the cache across the bus. Host memory is not the limit either - per-slot compute buffers stay on the GPU, so VRAM runs out first however much system memory is free.

Calling tools

Two models cannot call tools, and it is not predictable from their scores.

Agent work needs the server to return parsed tool calls, not prose describing one. Whether that works depends on llama.cpp having a parser for the model's tool syntax, which is independent of how well the model follows instructions.

testedresultdetail
Qwen3.8-27Bcalls toolsreturns a parsed call
granite-4.1-30bcalls toolsreturns a parsed call
gemma-4-E4Bcalls toolsreturns a parsed call
gemma-4-31Bcannot call toolsemits its tool call as raw text; llama.cpp has no parser for Gemma-4's syntax
The best model here on instruction-following is the one that cannot call tools. Capability scores do not predict this - it has to be tested.
Olmo-3-7B and Llama-Nemotron-4B have tool-capable templates but cannot use them: llama.cpp refuses their Jinja and falls back to a plain chat template, which has no tool syntax at all. That makes the fastest small model in the set unusable for agents.

Running them

Substitute the pool and per-slot values from whichever model you want. Three flags make high context possible and all three are easy to get wrong.

llama-server -m <model>.gguf -ngl 999 \
  -c <pool> -np 16 --kv-unified --kv-unified-per-slot <each user gets> \
  --cache-type-k q8_0 --cache-type-v q8_0 --flash-attn on
q8_0 KV needs flash attention. Without --flash-attn on, the V cache silently stays at full precision and you get half the context you asked for.
Set -c yourself. Given only --kv-unified-per-slot, the pool is sized as slots × per-slot: asking for 16 × 32k tried to allocate 34.8 GB and failed. The per-slot value is a ceiling, not an allocation.
Two models need --no-jinja --chat-template chatml. Olmo-3-7B and Llama-Nemotron-4B. llama.cpp cannot build a parser for their templates and refuses to start otherwise.
More GPUs is slower for small models. gemma-4-E2B does 679 tok/s on one 3080 and 509 across both A4500s. Splitting costs more than the extra bandwidth returns. Use the smallest card a model fits on unless you need the context.
Offloading KV to system RAM still needs GPU headroom. It works on the A4500s but fails on the 3080 and 4070 SUPER at large pools - the cache moves to host memory, yet llama.cpp still sizes a GPU compute buffer by context length. Free host RAM is not the binding constraint.

Making a large model faster

A small model can draft for a large one, and the family shares a vocabulary.

Speculative decoding has a small model propose tokens that the large one verifies several at a time. It needs both models to share a tokenizer, and across one family here they do - a 0.8B, a 2B and a 27B all report the same 248,320-token vocabulary.

The 0.8B occupies half a gigabyte and generates at 290 tok/s, so it costs almost nothing to host beside the 27B, and both have had refusals removed already - so the draft model cannot reintroduce them. Typical gains are 1.5-2.5× on greedy decoding when the draft is well matched, which would move a 27B from 24 tok/s toward 40-60.

Not yet measured. Unverified. The gain depends entirely on how often a 0.8B predicts a 27B correctly on real work, and that is a property of the workload - structured output and code accept well, open-ended prose less so. Measure before relying on it.

What will not serve

Nemotron-3-Nano-4B cannot be served this way. Its GGUF will not load - blk.1.ssm_in.weight not found, because the Mamba tensors do not survive conversion. The catalogue rates it best capability per gigabyte in the whole set, so this is the most annoying gap here. Serving it needs a different format.