Fork off LLama cpp that newly scales GPU 2x 4x etc also on big models not fully fitting in vram
See the codeBig thanks to @csantiago78: the expert cache here builds on their implementation in llama.cpp PR #27861 ("GPU-resident LRU cache for host-offloaded MoE expert weights"), the first to get a working hot-expert cache into llama.cpp. This fork takes it further: filling all free VRAM, smarter eviction, CPU/GPU overlap and fused kernels.
For MoE models much larger than VRAM: every expert stays in system RAM, and all VRAM left after the KV cache becomes a live cache of the experts actually being used. The GPUs compute cached experts while the CPU computes the rest, in parallel.
Results, 2x RTX 3090 (48 GB) + 125 GB RAM, single stream, temp 0, -c 1024:
| model | size | stock t/s | fork t/s | gain | PPL (stock -> fork) |
|---|---|---|---|---|---|
| GLM-5.3-Flash 3.0-bit, original GGUF | 117 GB | 12.3 | ~25 | 2.0x | 3.5534 -> 3.5534 |
| GLM-5.3-Flash 3.0-bit, Q4_K attention GGUF | 106 GB | 12.3 | 27.72 | 2.3x | 3.5534 -> 3.5871 (+0.95%) |
| MiMo-2.6-Flash-RL IQ3_XXS | 132 GB | 4.7 | 9.9 | 2.1x | unchanged (no requant) |
| Qwen3.8-Flash-Next UD-IQ4_XS | 88 GB | 29.7 | 32.1 | 1.08x | unchanged (no requant) |
GLM prompt: "generate smallest html tetris game."; MiMo/Qwen prompt: "write smallest
html tetris game" (both temp 0). PPL: wikitext-2, 40 x 512-token chunks (GLM only).
MiMo needed -fitt 8000 on both stock and fork to avoid autofit OOM-ing on this
arch/quant combo; the others loaded fine with default fit.
Qwen's gain is small because stock's autofit already placed most of its experts on GPU by default here — little room left for the cache to improve on. The big wins (GLM, MiMo) are on models where default placement leaves most expert work on the CPU.
Models:
Same VRAM, different use. Stock llama.cpp and this fork get the same 48 GB; what differs is what it holds. Each token uses only 8 of the 288 experts in each layer.
| expert work on GPU | expert work on CPU | decode t/s | |
|---|---|---|---|
| stock (static whole layers) | ~33% | ~67% | 12.3 |
| this fork (cache of hot experts) | ~85% | ~15%, in parallel | 26-28 |
So stock can't reach 2x on the same hardware: without an expert cache, extra VRAM mostly holds experts that aren't being used.
Run (with the faster Q4_K attention GGUF from neuralll/GLM-5.3-Flash-GSQ-RCO-3.0bit-Q4Kattn-GGUF):
llama-server -m GLM-5.3-Flash-GSQ-RCO-3.0bit-q4kattn.gguf \
-np 1 -c 1024 -t 6 --cpu-moe -nr --moe-expert-cache -1
--cpu-moe keeps all experts in RAM; --moe-expert-cache -1 sizes the cache
per GPU from the VRAM free after KV and compute buffers. Set -c explicitly:
without it autofit grows the context and takes the VRAM the cache needs.-t 6 suits an 8-core CPU (leave cores to drive the GPUs).LLAMA_MOE_CACHE_STATS=1 logs it.LLAMA_MOE_CACHE_POLICY (add default, halve, window),
LLAMA_MOE_CACHE_MARGIN_MB (VRAM left free, default 1024),
LLAMA_MOE_CACHE_SWAP_FRAC (share of token time for uploads, default 0.25).GGML_SCHED_PROF=1 prints where each token's host time goes.More GPUs (estimate, only 2 tested). Nothing assumes two GPUs: each GPU gets its own cache, sized from its free VRAM. Each extra GPU adds cache room, so more of every token's experts are hits and less work falls to the CPU. For this model, per token today: ~20 ms GPU work on non-expert layers, ~10 ms CPU on missed experts.
| GPUs (24 GB each) | cache room | slots/layer (of 288) | hit rate | CPU miss time | decode t/s |
|---|---|---|---|---|---|
| 2 (measured) | ~34 GB | ~100 | 85-88% | ~10 ms | 26-28 |
| 3 | ~58 GB | ~170 | ~95% | ~3-4 ms | ~33-35 |
| 4 | ~82 GB | ~240 | ~99% | ~1 ms | ~38-42 |
| 5+ | whole model | 288 | 100% | 0 | ~40-45 (plateau) |
The plateau is the ~20 ms GPU part: with the default layer split each layer runs on one GPU at a time, so extra GPUs add cache room, not speed on that part. System RAM must still hold all experts. Cards in x4 PCIe slots upload experts slower, so the cache warms up slower. Reports from 3+ GPU setups are welcome.
What's in it: the GPU expert cache from PR #27861 (csantiago78), extended with VRAM-filling auto-sizing, usage-driven eviction that only swaps when the upload pays back, CPU/GPU overlap per layer, scheduler barrier fixes and fused gate kernels. GLM-5.3-Flash support comes from PRs #27773 and #27917 (timkhronos); stock llama.cpp can't load GLM-5.3-Flash yet.
Prefill warm start, implemented independently for this fork: the cache observes which experts the prompt itself selects during prefill and preloads them before the first generated token, instead of starting cold and only learning from decode. @sdroege explored the same idea independently in the PR #27861 discussion with their own patch; worth checking out too.
Other notable tweaks:
LLAMA_MOE_CACHE_SWAP_FRAC of a token (default 25%) — instead of a fixed
swaps-per-step constant.LLAMA_MOE_CACHE_POLICY: add default, halve,
window): recent use counts more than old use, so the cache follows shifts in
which experts are hot instead of freezing on early-token bias.MUL -> ADD|SCALE -> SIGMOID -> SCALE, one kernel instead of four), and GLM5-Next's
KDA Q/K norm collapsed from rms_norm+scale into one l2_norm op.GGML_SCHED_PROF=1 and LLAMA_MOE_CACHE_STATS=1 for live profiling: barrier vs.
copy wait time, fill %, in-flight uploads, queue depth, hit rate.About the author of this fork: I'm actively looking for an AI engineering/research role and open to relocating out of Eastern Europe. If this work is useful to you or your team, reach out: linkedin.com/in/neuralll
LLM inference in C/C++
ggml / ops / maintainer PRs / dev stats / lib llama API / llama-server REST API
A few options to get llama.cpp installed on your machine:
Once installed:
# Download and run a model directly from Hugging Face
llama cli -hf ggml-org/Qwen3.5-0.8B-GGUF
# Launch OpenAI-compatible API server
llama serve -hf ggml-org/Qwen3.5-0.8B-GGUF
|
|
|
The main goal of llama.cpp is to enable LLM (and VLM) inference with minimal setup and state-of-the-art performance on
a wide range of hardware - locally and in the cloud.
The llama.cpp project is build on top of the ggml library.
| Backend | Target devices |
|---|---|
| BLAS | All |
| BLIS | All |
| CANN | Ascend NPU |
| CUDA | Nvidia GPU |
| HIP | AMD GPU |
| Hexagon | Snapdragon |
| IBM zDNN | IBM Z & LinuxONE |
| MUSA | Moore Threads GPU |
| Metal | Apple Silicon |
| OpenCL | Adreno GPU |
| OpenVINO [In Progress] | Intel CPUs, GPUs, and NPUs |
| RPC | All |
| SYCL | Intel GPU |
| VirtGPU | VirtGPU APIR |
| Vulkan | GPU |
| WebGPU | All |
| ZenDNN | AMD CPU |
llama.cpp repo and merge PRs into the master branchllama-server - MIT license(top 30 of 446)
C++
56.0%
C
16.1%
Python
7.3%
Cuda
5.4%
TypeScript
4.1%
Svelte
2.1%
HTML
2.0%
Metal
1.5%
Jinja
1.2%
Fork off LLama cpp that newly scales GPU 2x 4x etc also on big models not fully fitting in vram
See the codeBig thanks to @csantiago78: the expert cache here builds on their implementation in llama.cpp PR #27861 ("GPU-resident LRU cache for host-offloaded MoE expert weights"), the first to get a working hot-expert cache into llama.cpp. This fork takes it further: filling all free VRAM, smarter eviction, CPU/GPU overlap and fused kernels.
For MoE models much larger than VRAM: every expert stays in system RAM, and all VRAM left after the KV cache becomes a live cache of the experts actually being used. The GPUs compute cached experts while the CPU computes the rest, in parallel.
Results, 2x RTX 3090 (48 GB) + 125 GB RAM, single stream, temp 0, -c 1024:
| model | size | stock t/s | fork t/s | gain | PPL (stock -> fork) |
|---|---|---|---|---|---|
| GLM-5.3-Flash 3.0-bit, original GGUF | 117 GB | 12.3 | ~25 | 2.0x | 3.5534 -> 3.5534 |
| GLM-5.3-Flash 3.0-bit, Q4_K attention GGUF | 106 GB | 12.3 | 27.72 | 2.3x | 3.5534 -> 3.5871 (+0.95%) |
| MiMo-2.6-Flash-RL IQ3_XXS | 132 GB | 4.7 | 9.9 | 2.1x | unchanged (no requant) |
| Qwen3.8-Flash-Next UD-IQ4_XS | 88 GB | 29.7 | 32.1 | 1.08x | unchanged (no requant) |
GLM prompt: "generate smallest html tetris game."; MiMo/Qwen prompt: "write smallest
html tetris game" (both temp 0). PPL: wikitext-2, 40 x 512-token chunks (GLM only).
MiMo needed -fitt 8000 on both stock and fork to avoid autofit OOM-ing on this
arch/quant combo; the others loaded fine with default fit.
Qwen's gain is small because stock's autofit already placed most of its experts on GPU by default here — little room left for the cache to improve on. The big wins (GLM, MiMo) are on models where default placement leaves most expert work on the CPU.
Models:
Same VRAM, different use. Stock llama.cpp and this fork get the same 48 GB; what differs is what it holds. Each token uses only 8 of the 288 experts in each layer.
| expert work on GPU | expert work on CPU | decode t/s | |
|---|---|---|---|
| stock (static whole layers) | ~33% | ~67% | 12.3 |
| this fork (cache of hot experts) | ~85% | ~15%, in parallel | 26-28 |
So stock can't reach 2x on the same hardware: without an expert cache, extra VRAM mostly holds experts that aren't being used.
Run (with the faster Q4_K attention GGUF from neuralll/GLM-5.3-Flash-GSQ-RCO-3.0bit-Q4Kattn-GGUF):
llama-server -m GLM-5.3-Flash-GSQ-RCO-3.0bit-q4kattn.gguf \
-np 1 -c 1024 -t 6 --cpu-moe -nr --moe-expert-cache -1
--cpu-moe keeps all experts in RAM; --moe-expert-cache -1 sizes the cache
per GPU from the VRAM free after KV and compute buffers. Set -c explicitly:
without it autofit grows the context and takes the VRAM the cache needs.-t 6 suits an 8-core CPU (leave cores to drive the GPUs).LLAMA_MOE_CACHE_STATS=1 logs it.LLAMA_MOE_CACHE_POLICY (add default, halve, window),
LLAMA_MOE_CACHE_MARGIN_MB (VRAM left free, default 1024),
LLAMA_MOE_CACHE_SWAP_FRAC (share of token time for uploads, default 0.25).GGML_SCHED_PROF=1 prints where each token's host time goes.More GPUs (estimate, only 2 tested). Nothing assumes two GPUs: each GPU gets its own cache, sized from its free VRAM. Each extra GPU adds cache room, so more of every token's experts are hits and less work falls to the CPU. For this model, per token today: ~20 ms GPU work on non-expert layers, ~10 ms CPU on missed experts.
| GPUs (24 GB each) | cache room | slots/layer (of 288) | hit rate | CPU miss time | decode t/s |
|---|---|---|---|---|---|
| 2 (measured) | ~34 GB | ~100 | 85-88% | ~10 ms | 26-28 |
| 3 | ~58 GB | ~170 | ~95% | ~3-4 ms | ~33-35 |
| 4 | ~82 GB | ~240 | ~99% | ~1 ms | ~38-42 |
| 5+ | whole model | 288 | 100% | 0 | ~40-45 (plateau) |
The plateau is the ~20 ms GPU part: with the default layer split each layer runs on one GPU at a time, so extra GPUs add cache room, not speed on that part. System RAM must still hold all experts. Cards in x4 PCIe slots upload experts slower, so the cache warms up slower. Reports from 3+ GPU setups are welcome.
What's in it: the GPU expert cache from PR #27861 (csantiago78), extended with VRAM-filling auto-sizing, usage-driven eviction that only swaps when the upload pays back, CPU/GPU overlap per layer, scheduler barrier fixes and fused gate kernels. GLM-5.3-Flash support comes from PRs #27773 and #27917 (timkhronos); stock llama.cpp can't load GLM-5.3-Flash yet.
Prefill warm start, implemented independently for this fork: the cache observes which experts the prompt itself selects during prefill and preloads them before the first generated token, instead of starting cold and only learning from decode. @sdroege explored the same idea independently in the PR #27861 discussion with their own patch; worth checking out too.
Other notable tweaks:
LLAMA_MOE_CACHE_SWAP_FRAC of a token (default 25%) — instead of a fixed
swaps-per-step constant.LLAMA_MOE_CACHE_POLICY: add default, halve,
window): recent use counts more than old use, so the cache follows shifts in
which experts are hot instead of freezing on early-token bias.MUL -> ADD|SCALE -> SIGMOID -> SCALE, one kernel instead of four), and GLM5-Next's
KDA Q/K norm collapsed from rms_norm+scale into one l2_norm op.GGML_SCHED_PROF=1 and LLAMA_MOE_CACHE_STATS=1 for live profiling: barrier vs.
copy wait time, fill %, in-flight uploads, queue depth, hit rate.About the author of this fork: I'm actively looking for an AI engineering/research role and open to relocating out of Eastern Europe. If this work is useful to you or your team, reach out: linkedin.com/in/neuralll
LLM inference in C/C++
ggml / ops / maintainer PRs / dev stats / lib llama API / llama-server REST API
A few options to get llama.cpp installed on your machine:
Once installed:
# Download and run a model directly from Hugging Face
llama cli -hf ggml-org/Qwen3.5-0.8B-GGUF
# Launch OpenAI-compatible API server
llama serve -hf ggml-org/Qwen3.5-0.8B-GGUF
|
|
|
The main goal of llama.cpp is to enable LLM (and VLM) inference with minimal setup and state-of-the-art performance on
a wide range of hardware - locally and in the cloud.
The llama.cpp project is build on top of the ggml library.
| Backend | Target devices |
|---|---|
| BLAS | All |
| BLIS | All |
| CANN | Ascend NPU |
| CUDA | Nvidia GPU |
| HIP | AMD GPU |
| Hexagon | Snapdragon |
| IBM zDNN | IBM Z & LinuxONE |
| MUSA | Moore Threads GPU |
| Metal | Apple Silicon |
| OpenCL | Adreno GPU |
| OpenVINO [In Progress] | Intel CPUs, GPUs, and NPUs |
| RPC | All |
| SYCL | Intel GPU |
| VirtGPU | VirtGPU APIR |
| Vulkan | GPU |
| WebGPU | All |
| ZenDNN | AMD CPU |
llama.cpp repo and merge PRs into the master branchllama-server - MIT license(top 30 of 446)
C++
56.0%
C
16.1%
Python
7.3%
Cuda
5.4%
TypeScript
4.1%
Svelte
2.1%
HTML
2.0%
Metal
1.5%
Jinja
1.2%