From e9a091c35f91589a41501118125ced687bea9f73 Mon Sep 17 00:00:00 2001 From: DATA Date: Sat, 25 Jul 2026 14:25:45 +0200 Subject: [PATCH] Benchmark A3B against dense Qwen3.6-27B on the same box Generation: A3B ~2.3x faster at every depth (3B of 35B params active per token vs all 27B). Prefill: 27B ~1.6x faster, since it is fully GPU-resident while every A3B prefill batch goes through the CPU experts. The 27B cannot do 128k here at all: 65 layers x 4 KV heads gives 4.25 GiB of KV at 128k against the A3B's 1.33 GiB, so even Q4_K_S OOMs on the compute buffer. Measured at 64k instead. Co-Authored-By: Claude Opus 5 --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/README.md b/README.md index ae25c18..1151690 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,49 @@ On a fully GPU-resident model batch verification is nearly free; with costs **38% prefill** (556 → 347 t/s). Keep the default `-ub 512`. - Lower `-ts` toward CUDA1 (e.g. `23,17`): would leave CUDA1 at ~60 MiB free. +## Vergleich: A3B (MoE) vs. Qwen3.6-27B (dense) + +Same box, same llama.cpp image, same `-ctk/-ctv q8_0 -fa on --threads 8`, same +benchmark, measured at identical prompt depths: + +| Prompt-Tiefe | A3B gen | 27B gen | A3B prefill | 27B prefill | +|---|---|---|---|---| +| 512 | **56,3 t/s** | 24,1 t/s | 420 t/s | **539 t/s** | +| 8k | **53,3 t/s** | 23,2 t/s | 497 t/s | **817 t/s** | +| 32k | **47,8 t/s** | 20,5 t/s | 486 t/s | **767 t/s** | + +**Generierung: A3B ist durchgehend ~2,3x schneller.** Nur 3B der 35B Parameter sind +pro Token aktiv, das dichte 27B muss alle 27B lesen — auch wenn es komplett im VRAM +liegt und das A3B ein Drittel seiner Experten im RAM hat. + +**Prefill: das 27B ist ~1,6x schneller**, weil es vollständig GPU-resident ist, +während beim A3B jeder Prefill-Batch durch die CPU-Experten muss. + +**Kontext: das 27B schafft die 128k hier gar nicht.** Es hat 65 Layer mit 4 KV-Heads +gegen 40 Layer mit 2 — bei `full_attention_interval=4` also 16 statt 10 +Full-Attention-Layer und damit **4,25 GiB KV bei 128k statt 1,33 GiB**. Zusammen mit +~15 GiB Gewichten reicht das nicht: schon das kleinere Q4_K_S scheitert beim +Compute-Buffer: + +``` +allocating 1145.13 MiB on device 0: cudaMalloc failed: out of memory +graph_reserve: failed to allocate compute buffers +``` + +Gemessen wurde es deshalb bei 64k ctx. + +### Caveats zu diesem Vergleich + +- Gemessen wurde **Q4_K_S (16,1 GB)**, nicht Q4_K_M (17 GB) — die einzige lokal + vorhandene, mit upstream llama.cpp ladbare 27B-Datei dieser Klasse. Q4_K_M ist ~5% + größer und wäre entsprechend etwas langsamer, der Abstand also eher noch größer. +- Der ollama-Blob von `qwen3.6:27b-q4_K_M` lässt sich mit upstream llama.cpp **nicht** + laden: `key qwen35.rope.dimension_sections has wrong array length; expected 4, got 3`. + Ollama fährt einen eigenen Fork; ein Vergleich exakt dieser Datei ist im selben + Runner nicht möglich. +- Ältere 27B-Zahlen unter `PrismQuant/benchmarks/` (34,3 t/s) stammen von einer + **RX 7900 XTX, gedrosselt** — nicht mit dieser Maschine vergleichbar. + ### A note on the CUDA0 headroom Free VRAM on CUDA0 was observed drifting between ~1100 and ~1300 MiB across restarts