TL;DR
For MoE models, keep expert weights in host memory (pinned buffer) and let cuBLAS read them directly over PCIe DMA — never copy experts into VRAM. Non-expert layers stay in VRAM as usual. Result (RTX 4090, real measurements):
| Model |
Standard (all-in-VRAM) |
This approach |
VRAM saved |
Speed |
| DeepSeek-V2-Lite Q2_K (23.3GB) |
23.3GB VRAM, 65 t/s |
1.6GB VRAM, 37.5 t/s |
−93% |
58% retained |
| Qwen3.6-35B-A3B (11GB) |
OOM on 8GB cards |
2.1GB VRAM, 46.8 t/s |
— |
≈ parity |
| Qwen3-235B-A22B Q2_K (81.7GB) |
impossible on consumer GPUs |
8GB VRAM (verification in progress) |
— |
TBD |
Motivation
The biggest real-world MoE use case is running a large model on a small GPU. With all experts in VRAM, an 8GB card tops out around a 7-8B dense or a ~11GB MoE. But MoE experts are only activated sparsely (2-8 of 256 per token) — the full weight set doesn't need to live on the GPU. The bottleneck is that llama.cpp's offload path copies expert weights H2D per layer (see #25859), and the --n-cpu-moe path computes experts on CPU (slow).
Proposed approach (high level)
- Load expert weights into a host pinned buffer (not GPU VRAM, not anonymous mmap that gets evicted).
- Run the expert matmuls on GPU via cuBLAS operating directly on host pointers — the CUDA driver DMA-reads the expert weights from host RAM over PCIe on demand, per activated expert. No H2D staging copy, no per-layer streaming.
- VRAM holds only non-expert layers + KV cache. For DS-V2-Lite that's ~1.6GB total.
- Optional: a small expert cache (a few slots, LRU) that D2D-copies the hot experts into VRAM once and reuses them — helps when the same experts fire repeatedly (e.g. long prompts / codegen patterns).
Measured results (RTX 4090, 2026-08-02)
- DeepSeek-V2-Lite Q2_K: VRAM 23.3GB → 1.6GB; speed 37.5 t/s (vs 65 t/s fully offloaded — reasonable PCIe price for −93% VRAM). Expert cache at 0.25: prompt throughput 99 → 308 t/s (+211%), gen +5%.
- Qwen3.6-35B-A3B: VRAM 2.1GB, 46.8 t/s — an 11GB MoE that OOMs an 8GB card normally, now runs on ~2GB with near-full speed.
- Qwen3-235B-A22B Q2_K (81.7GB): download in progress; target: run on 8GB VRAM (experts ~80GB in host RAM + PCIe DMA).
Why this is different from existing work
This also composes with existing features: --n-cpu-moe-style flag to select the expert storage mode, GGML_OP_OFFLOAD_MIN_BATCH to control when offload kicks in, and the expert cache as an optional accelerator.
Ask
- Would the maintainers accept a host-pinned expert buffer + DMA-direct expert matmul path as an official load mode (e.g.
--expert-mode host-dma)?
- Happy to open a PR with the CUDA backend changes (it's a focused patch: model loader + CUDA expert matmul path + optional small expert cache).
- Open to discussion on trade-offs: PCIe bandwidth vs VRAM, multi-GPU, pageable vs pinned, and whether a
--host-ram-budget knob makes sense.
Context
- All numbers above are from a single RTX 4090 box, measured with llama.cpp-based server (this is a custom fork, patch described at high level above).
- Env: Linux x86_64, CUDA 12, PCIe 4.0 (gen4 single-GPU).
- Happy to provide full benchmark methodology / logs on request.
TL;DR
For MoE models, keep expert weights in host memory (pinned buffer) and let cuBLAS read them directly over PCIe DMA — never copy experts into VRAM. Non-expert layers stay in VRAM as usual. Result (RTX 4090, real measurements):
Motivation
The biggest real-world MoE use case is running a large model on a small GPU. With all experts in VRAM, an 8GB card tops out around a 7-8B dense or a ~11GB MoE. But MoE experts are only activated sparsely (2-8 of 256 per token) — the full weight set doesn't need to live on the GPU. The bottleneck is that llama.cpp's offload path copies expert weights H2D per layer (see #25859), and the
--n-cpu-moepath computes experts on CPU (slow).Proposed approach (high level)
Measured results (RTX 4090, 2026-08-02)
Why this is different from existing work
This also composes with existing features:
--n-cpu-moe-style flag to select the expert storage mode, GGML_OP_OFFLOAD_MIN_BATCH to control when offload kicks in, and the expert cache as an optional accelerator.Ask
--expert-mode host-dma)?--host-ram-budgetknob makes sense.Context