LLM inference in C/C++
180
stars
8,816
commits
C++
primary language
Sep 7, 2026
updated
This branch adds an experimental, block-granular KV cache streaming path to the CUDA llama-server. It is intended for running long contexts when model weights leave too little VRAM for the complete KV cache.
With --kv-stream-stage-mib N, the authoritative KV tensors are stored in pinned host memory while a bounded CUDA pool is shared by resident KV pages and a transfer ring. The runtime adapts that split as the context grows: it keeps as many pages resident as the budget allows, reclaims resident space for staging when more streaming is required, and prefetches later layers while the current layer computes. This avoids relying on uncontrolled Unified Memory page thrashing and preserves exact attention over the full context.
Detailed project story, design, implementation, and benchmark results are in Running Qwen 27B on 16G VRAM with Full Context Length: Building Adaptive KV Cache Streaming for llama.cpp.
[!WARNING] This is research code optimized and production-validated primarily for an RTX 5070 Ti with 16 GB VRAM,
unsloth/Qwen3.8-27B-GGUFUD-Q3_K_XL, a 262144-token context, Flash Attention, a Q8_0 K cache, a Q4_0 V cache, and one server slot. CUDA correctness tests cover every KV type currently accepted by the CLI, including native and F16-conversion fallback paths. Production performance for other models, KV combinations, parallel slots, and non-CUDA backends is not yet broadly characterized.
Install a C++ compiler, CMake, and the CUDA toolkit, then run this command from the repository root:
cmake -S . -B build -DGGML_CUDA=ON -DGGML_CUDA_FA_ALL_QUANTS=ON -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release --target llama-server -j
The executable is created at build/bin/llama-server.
Example using the tested cache configuration:
./build/bin/llama-server \
--model /path/to/model.gguf \
--ctx-size 262144 \
-fa on \
-ctk q8_0 \
-ctv q4_0 \
-ngl all \
-b 512 \
-ub 512 \
-np 1 \
--kv-stream-stage-mib 2304
The best value for --kv-stream-stage-mib depends on the model, context capacity, GPU, and other VRAM consumers. Start conservatively and increase it while checking startup and peak VRAM use.
-b sets the logical prompt batch size and -ub sets the largest physical batch submitted to one graph. This branch no longer requires 256/256; -ub may be any positive value no larger than -b.
The Qwen3.8 MMA prefill path processes the full physical batch and allocates only the partial workspace that kernel actually emits. Generic vector and F16-conversion fallback paths use a bounded 256-query workspace: each staged KV span is consumed by all query tiles before its ring slot is released, so wider micro-batches do not multiply KV host-to-device transfers.
The Q8_0/Q4_0 Qwen configuration has been exercised with b/ub values 256/256, 512/512, 768/512, and 1024/1024, including non-divisible final micro-batches. A 122880-token production-shaped run at 512/512 completed with adaptive streaming active. Wider values can require more graph and accumulator memory, so validate them on the target GPU.
Adaptive KV streaming works with or without Unified Memory. Leave GGML_CUDA_ENABLE_UNIFIED_MEMORY unset for ordinary CUDA device allocations. To make GPU-offloaded model buffers CUDA managed allocations, launch the same server with the environment variable enabled:
GGML_CUDA_ENABLE_UNIFIED_MEMORY=1 \
./build/bin/llama-server \
--model /path/to/model.gguf \
--ctx-size 262144 \
-fa on \
-ctk q8_0 \
-ctv q4_0 \
-ngl all \
-b 512 \
-ub 512 \
-np 1 \
--kv-stream-stage-mib 2304
With this flag, CUDA-backed model buffers, including GPU-offloaded weights, are allocated with cudaMallocManaged and their pages can migrate between VRAM and host memory. The adaptive resident-page and transfer-ring pool is intentionally different: it is still allocated with cudaMalloc, so that fixed-size pool remains physically allocated in VRAM instead of becoming managed memory. UVM is therefore optional for this branch and does not change the KV streaming pool into pageable storage.
The benchmark driver automatically selects the largest practical adaptive KV pool for each configured context capacity, sweeps from 8K through the requested maximum, and generates the CSV, PNG, and SVG results:
python3 -m pip install matplotlib
python3 benchmarks/benchmark_kv_stream.py \
--model /path/to/model.gguf \
--max-context 192K \
--batch-size 512 \
--ubatch-size 512
The only required arguments are the model GGUF and maximum context. See benchmarks/README.md for the pool-probing algorithm, generated files, optional settings, and resumable output directories.
LLM inference in C/C++
manifesto / ggml / ops / maintainer PRs / compile times / 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 [In Progress] | 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 447)
C++
55.6%
C
15.7%
Python
7.2%
Cuda
5.8%
TypeScript
4.3%
Svelte
2.3%
HTML
2.2%
Metal
1.4%
Jinja
1.2%
LLM inference in C/C++
180
stars
8,816
commits
C++
primary language
Sep 7, 2026
updated
This branch adds an experimental, block-granular KV cache streaming path to the CUDA llama-server. It is intended for running long contexts when model weights leave too little VRAM for the complete KV cache.
With --kv-stream-stage-mib N, the authoritative KV tensors are stored in pinned host memory while a bounded CUDA pool is shared by resident KV pages and a transfer ring. The runtime adapts that split as the context grows: it keeps as many pages resident as the budget allows, reclaims resident space for staging when more streaming is required, and prefetches later layers while the current layer computes. This avoids relying on uncontrolled Unified Memory page thrashing and preserves exact attention over the full context.
Detailed project story, design, implementation, and benchmark results are in Running Qwen 27B on 16G VRAM with Full Context Length: Building Adaptive KV Cache Streaming for llama.cpp.
[!WARNING] This is research code optimized and production-validated primarily for an RTX 5070 Ti with 16 GB VRAM,
unsloth/Qwen3.8-27B-GGUFUD-Q3_K_XL, a 262144-token context, Flash Attention, a Q8_0 K cache, a Q4_0 V cache, and one server slot. CUDA correctness tests cover every KV type currently accepted by the CLI, including native and F16-conversion fallback paths. Production performance for other models, KV combinations, parallel slots, and non-CUDA backends is not yet broadly characterized.
Install a C++ compiler, CMake, and the CUDA toolkit, then run this command from the repository root:
cmake -S . -B build -DGGML_CUDA=ON -DGGML_CUDA_FA_ALL_QUANTS=ON -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release --target llama-server -j
The executable is created at build/bin/llama-server.
Example using the tested cache configuration:
./build/bin/llama-server \
--model /path/to/model.gguf \
--ctx-size 262144 \
-fa on \
-ctk q8_0 \
-ctv q4_0 \
-ngl all \
-b 512 \
-ub 512 \
-np 1 \
--kv-stream-stage-mib 2304
The best value for --kv-stream-stage-mib depends on the model, context capacity, GPU, and other VRAM consumers. Start conservatively and increase it while checking startup and peak VRAM use.
-b sets the logical prompt batch size and -ub sets the largest physical batch submitted to one graph. This branch no longer requires 256/256; -ub may be any positive value no larger than -b.
The Qwen3.8 MMA prefill path processes the full physical batch and allocates only the partial workspace that kernel actually emits. Generic vector and F16-conversion fallback paths use a bounded 256-query workspace: each staged KV span is consumed by all query tiles before its ring slot is released, so wider micro-batches do not multiply KV host-to-device transfers.
The Q8_0/Q4_0 Qwen configuration has been exercised with b/ub values 256/256, 512/512, 768/512, and 1024/1024, including non-divisible final micro-batches. A 122880-token production-shaped run at 512/512 completed with adaptive streaming active. Wider values can require more graph and accumulator memory, so validate them on the target GPU.
Adaptive KV streaming works with or without Unified Memory. Leave GGML_CUDA_ENABLE_UNIFIED_MEMORY unset for ordinary CUDA device allocations. To make GPU-offloaded model buffers CUDA managed allocations, launch the same server with the environment variable enabled:
GGML_CUDA_ENABLE_UNIFIED_MEMORY=1 \
./build/bin/llama-server \
--model /path/to/model.gguf \
--ctx-size 262144 \
-fa on \
-ctk q8_0 \
-ctv q4_0 \
-ngl all \
-b 512 \
-ub 512 \
-np 1 \
--kv-stream-stage-mib 2304
With this flag, CUDA-backed model buffers, including GPU-offloaded weights, are allocated with cudaMallocManaged and their pages can migrate between VRAM and host memory. The adaptive resident-page and transfer-ring pool is intentionally different: it is still allocated with cudaMalloc, so that fixed-size pool remains physically allocated in VRAM instead of becoming managed memory. UVM is therefore optional for this branch and does not change the KV streaming pool into pageable storage.
The benchmark driver automatically selects the largest practical adaptive KV pool for each configured context capacity, sweeps from 8K through the requested maximum, and generates the CSV, PNG, and SVG results:
python3 -m pip install matplotlib
python3 benchmarks/benchmark_kv_stream.py \
--model /path/to/model.gguf \
--max-context 192K \
--batch-size 512 \
--ubatch-size 512
The only required arguments are the model GGUF and maximum context. See benchmarks/README.md for the pool-probing algorithm, generated files, optional settings, and resumable output directories.
LLM inference in C/C++
manifesto / ggml / ops / maintainer PRs / compile times / 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 [In Progress] | 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 447)
C++
55.6%
C
15.7%
Python
7.2%
Cuda
5.8%
TypeScript
4.3%
Svelte
2.3%
HTML
2.2%
Metal
1.4%
Jinja
1.2%