🧪 VelsTech Lab Same card, same engines, two opposite ways to scale: Qwen 27B dense at 16K vs Ornith 35B-A3B MoE (3B active) at 262K, both at q8 KV on a 12GB RX 6800M. Which wins depends on what you ask vs how much you generate.

🔧 Re-run the math for your model

MoE: enter active params (3B, not 35B) + custom KV. Dense: enter full params. Keep q8_0 vs f16 honest.

LLM VRAM Calculator → GPU Performance →

The two runs side-by-side

Same GPU RX 6800M 12GB (~384 GB/s), same q8_0 KV, same n_threads=8, same 335-373 prompt tokens. Only model + context + MoE offload differ.

Model               Params   Context  KV type  Offload          Build   Prompt eval          Decode tg          Total
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Qwen 27B Ridge       27B dense  16K   q8_0     -ngl 999 (+fit abort)  ROCm    1713 ms /373 = 217.6 tok/s   18.12 tok/s   14.23s /601 tok
3.7bpw Ridge                                                Vulkan  2493 ms /373 = 149.6 tok/s   21.84 tok/s   13.57s /616 tok

Ornith 35B-A3B MoE   35B/3B*    262K  q8_0     --n-cpu-moe 28        ROCm    3995 ms /335 = 83.8 tok/s    25.62 tok/s   14.65s /609 tok
Q5_K/Q4_K mix               kv_unified=false              Vulkan  4029 ms /335 = 83.1 tok/s    19.66 tok/s   19.59s /642 tok
* 35B total, 3B active – MoE decodes 3B, not 35B.

First two rows: Qwen 27B 16K full report; last two: Ornith 35B 262K full report. All at -c reserved KV, fa on, 373/335 prompt tokens, ~600 gen tokens.

What actually happens

VRAM math – why 12GB still runs

Qwen 27B 3.7bpw: 27B ×0.4625 ≈12.5 GB weights + q8 KV 16K ≈2.2 GB + 6% overhead → ~15.6 GB (from VRAM Calculator) – well over 12GB, so partial offload explains 18-21 tok/s vs 30 tok/s bound.

Ornith 35B MoE 3B active: 35B mix Q5/Q4 ≈13-14 GB if counted as 35B, but KV per token scales with active 3B, so 262K q8 is ~262K×0.5KB ≈131 GB if naively counted as dense. That’s why we force 28 experts to CPU – you’re not resident, you’re sparse. Enter 3B active + custom layers 48 / kv 4 / hd 128 in the calculator, not 35B, or toggle Custom model….

How we calculate – the formulas behind the numbers

VRAM

weights = params × bytes_per_weight / GiB
kv_per_token = 2 × layers × kv_heads × head_dim × bytes
kv_cache = kv_per_token × context × batch / GiB
total = weights + kv_cache + (weights+kv)×0.06+0.25

For MoE, use active params for KV, not total. See LLM VRAM Calculator → Custom model.

Speed bound

decode_tok/s ≈ (memory_BW ×0.8) / bytes_per_token (weights + KV per token)

MoE bytes_per_token ≈ active 3B, dense ≈27B – hence Ornith can be faster than Qwen despite larger total.

So which should you pick on a 12GB card?

🧪 Dive into the raw runs

Full logs, commands and warnings are in the two source Labs – start with Qwen 16K, then Ornith 262K, then compare here.

Qwen 27B 16K → Ornith 35B 262K →