Zum Inhalt springen
Kurzer Hinweis: flozi00 TechHub ist ein Solo-Nebenprojekt neben einem Vollzeitjob — persönliche Lernnotizen, keine offiziellen Aussagen. Kritische Schritte selbst prüfen.

llama.cpp / Ollama vs vLLM: Was, wann und warum

Ein Zahlen-first-Vergleich der drei dominierenden lokalen LLM-Inferenz-Stacks: Was jede Schicht wirklich ist, wie sich ihre Concurrency-Modelle unterscheiden, die GGUF-Frage und eine durchgerechnete VRAM-Budgetierung für ein 14B-Modell in Q4_K_M auf einer 24-GB-Karte.

7 Min. Lesezeitflozi00
aimachine-learninggpullama-cppollamavllm
Direkt zum Fachartikel
Sehen · ausprobieren · verstehen

Serving-Ebene wählen, dann Anfragen einplanen

Ollama, llama.cpp und vLLM überschneiden sich; Paketverwaltung und Ausführung sind verschiedene Aufgaben.

KI-gestützte Lernvisualisierung · schematische Erklärung zum Artikel

Schritt 1 / 4Verwaltung und Ausführung unterscheiden

Ollama ergänzt Modellverwaltung und Runtime-Schnittstelle. llama.cpp ist eine Ausführungsengine mit eigenem Server; Ollama besitzt auch andere Engine-Pfade.

VergleichAktueller SchrittBaustein anklicken, um ihn zu erklären
Hardware und Workload
Modellformat, Kontext und gleichzeitige Anfragen.
Ollama-Runtime-Ebene
Modellverwaltung und einfach zugängliche lokale Oberfläche.
llama.cpp / llama-server
GGUF-Ausführung mit Backend- und Slot-Einstellungen.
  1. Hardware und Workload Ollama-Runtime-Ebene
    lokaler Ablauf
  2. Hardware und Workload llama.cpp / llama-server
    direkte Kontrolle
  3. Ollama-Runtime-Ebene llama.cpp / llama-server
    ein Backend-Pfad
Das solltest du mitnehmen

Wähle nach tatsächlichem Ausführungspfad und Workload; prüfe anschließend Speicher und Latenz gemeinsam.

Das Diagramm ist keine allgemeine Geschwindigkeitsrangliste. Ollama hat mehrere Backends; Formatunterstützung und Standards sind versionsabhängig.

Begriffe und vollständiger Ablauf
GGUF
Ein von llama.cpp nativ genutztes Modelldateiformat.
Slot
Ein Serverplatz für eine aktive Sequenz mit konfigurationsabhängiger Kapazität.
KV-Pool mit Blockverwaltung
In Blöcken vergebener Cache-Speicher für wachsende Sequenzen.
  1. Verwaltung und Ausführung unterscheiden

    Ollama ergänzt Modellverwaltung und Runtime-Schnittstelle. llama.cpp ist eine Ausführungsengine mit eigenem Server; Ollama besitzt auch andere Engine-Pfade.

  2. Speicherteilung der Anfragen betrachten

    llama-server kann Slots und einen gemeinsamen Pool nutzen; vLLM vergibt KV-Blöcke über seine Serving-Zeitplanung. Beide brauchen Platz für den angesammelten Kontext.

  3. Kontext gleichzeitiger Nutzer addieren

    Vier Anfragen voller Länge passen nicht allein durch Speicherteilung in das Kontextbudget einer Anfrage. Zähle insgesamt gespeicherte Tokens und Runtime-Reserve.

  4. Den tatsächlichen Pfad messen

    Modellformat-Unterstützung und Engine-Standards können sich ändern. Prüfe die installierte Version und miss Modell, Kontext und Parallelität gemeinsam.

Alle Verbindungen

  • Hardware und Workload → Ollama-Runtime-Ebene: lokaler Ablauf
  • Hardware und Workload → vLLM-Serving-Engine: Serving-Workload
  • Hardware und Workload → llama.cpp / llama-server: direkte Kontrolle
  • Ollama-Runtime-Ebene → llama.cpp / llama-server: ein Backend-Pfad
  • llama.cpp / llama-server → Kontextbelegung: Slots oder Pool
  • vLLM-Serving-Engine → Kontextbelegung: Pool mit Blöcken
  • Kontextbelegung → Gewählte Konfiguration messen: voller Workload
Du bestimmst das Tempo. Pausiere jederzeit oder wähle einen Schritt aus.

Lokale LLM-Inferenz hat sich auf drei Stacks eingespielt, die ständig verwechselt werden: llama.cpp, Ollama und vLLM. Sie sind keine Konkurrenten auf derselben Ebene – zwei von ihnen umhüllen bzw. ergänzen einander direkt. Dieser Guide legt fest, was jedes Einzelne ist, wo sich Concurrency- und Speichermodelle unterscheiden und was man pro Szenario wählt.

Was jede Schicht wirklich ist

llama.cpp ist die C/C++-Inferenz-Engine: eine GGUF-native Runtime mit Backends für CUDA, Metal, Vulkan, ROCm und reine CPU, plus llama-server, ein eingebauter HTTP-Server mit OpenAI- und Anthropic-kompatiblen Routen, Continuous Batching und parallelem Decoding.1

Ollama ist eine Modell-Distributions- und Runtime-Schicht, keine eigene Engine (jedenfalls überwiegend). Historisch hat es einen gepinnten llama.cpp-Build umhüllt – die Variable LLAMA_CPP_VERSION im Ollama-Repo fixiert die exakte Upstream-Quelle, gepatcht über llama/compat/.2 Über diesen Pin hinaus hat Ollama eigene Engines ergänzt: eine Multimodal-Engine, die Vision-Modelle (Llama 4, Gemma 3, Qwen 2.5 VL) direkt auf der GGML-Tensor-Bibliothek ausführt, statt separaten Text-Decoder- und Vision-Encoder-Prozess zusammenzukleben,3 sowie eine MLX-basierte Engine für Apple Silicon, die Ollama im März 2026 in den Preview gestellt hat und für beschleunigte Modelle den llama.cpp-Metal-Pfad ersetzt.4

vLLM ist eine Python/CUDA-Serving-Engine rund um PagedAttention: KV-Cache-Speicher, OS-artig in Blöcken fester Größe verwaltet mit logisch-zu-physisch Block-Tabellen – dadurch nahezu Null Cache-Verschwendung und 2–4× Throughput gegenüber den Systemen aus dem ursprünglichen Paper.5 Seit der V1-Re-Architektur ist Prefix Caching standardmäßig aktiviert (unter 1% Durchsatzverlust bei 0% Hit-Rate), und V1 erreicht bis zu 1,7× höheren Durchsatz als V0.6

Layerllama.cppOllamavLLM
Was es istC/C++-GGUF-Engine + llama-server HTTPRuntime + Modell-Registry um gepinnte llama.cpp-Version, eigene Multimodal-Engine, MLX-Engine auf Apple SiliconPython/CUDA-Serving-Engine, PagedAttention-KV-Manager
ModellformatGGUF (nativ)GGUF (+ MLX-nativ auf Apple Silicon)HF-Safetensors (GGUF über experimentelles Plugin)
HauptzielEine Maschine, jede Hardware inkl. CPUEase of use, ollama runGPU-Server-Durchsatz
ConcurrencyParallele Slots; gemeinsamer KV-Pool optionalOLLAMA_NUM_PARALLEL-SlotsContinuous Batching über einen gemeinsam genutzten KV-Pool

Concurrency-Modelle: Slots und KV-Allokation

Das ist der größte Verhaltensunterschied überhaupt – und die Quelle der übelsten Falle.

llama-server: --parallel N-Slots mit optional gemeinsamem KV-Pool

llama-server -np N erzeugt N Slots. Aktuelle Master-Defaults: -np/--parallel default -1 (auto), und -cb/--cont-batching (Continuous Batching) ist standardmäßig aktiviert; -b/--batch-size hat default 2048, -ub/--ubatch-size 512. --ctx-size (Default 0 = aus dem Modell geladen) bestimmt die gesamte KV-Kapazität. Mit --no-kv-unified wird sie auf Slots aufgeteilt; mit --kv-unified teilen die Slots einen Pool. Bei automatischer Slot-Zahl ist Unified-KV derzeit standardmäßig aktiv.1

Die Falle betrifft den nicht vereinheitlichten Modus: Mit -c 8192 -np 4 --no-kv-unified erhält jeder Slot 8192/4 = 2048 Token KV-Kapazität. Für vier gleichzeitige 8k-Slots in diesem Modus braucht es -c 32768 -np 4 --no-kv-unified. Mit --kv-unified teilen sich die Slots dagegen den 8192-Token-Pool; vier volle 8k-Sequenzen benötigen trotzdem etwa 32k Token Gesamtkapazität. --kv-unified-per-slot kann ein unabhängiges Slot-Limit setzen.7

vLLM: ein gepagter KV-Pool, Continuous Batching

vLLM hält einen paged KV-Pool und alloziert Blöcke nach Bedarf; auch llama-server kann einen gemeinsamen Pool nutzen, verwendet aber einen anderen Allokator und Scheduler. Requests verlassen und ergänzen den Batch bei jedem Decode-Schritt. Höhere Concurrency kostet im Leerlauf nichts, weil kein per-Request-Kontext vorreserviert wird: Der KV-Cache eines Requests wächst Token für Token in physischen Blöcken und wird bei Request-Ende sofort freigegeben.5 --max-num-seqs begrenzt die Batchgröße; die eigentliche Grenze für parallele Requests ist, wie viele Sequenzen mit ihrem angewachsenen KV in den Pool passen.

Ollama: Slots wie llama.cpp, dimensioniert über Defaults

Ollama erbt das Slot-Modell: OLLAMA_NUM_PARALLEL (default 1) ist die Zahl paralleler Requests pro Modell, und der RAM-Bedarf skaliert mit OLLAMA_NUM_PARALLEL * OLLAMA_CONTEXT_LENGTH.8 Beim Default von 1 reihen sich gleichzeitige Requests ein; jede zusätzliche parallele Anfrage kann den KV-Speicherbedarf erhöhen.

GGUF: natives Zuhause vs. experimenteller Gast

GGUF ist llama.cpps natives Format – die Referenzimplementierung mit der kompletten Quant-Familie (Q2_K bis Q8_0, i-Quants, Imatrix-Kalibrierung).9

vLLMs GGUF-Support ist ein anderes Kapitel, in den Worten der eigenen Doku: "GGUF support in vLLM is highly experimental and under-optimized at the moment, it might be incompatible with other features." Das GGUF-Loading ist aus dem Kern in das OOT-Paket vllm-gguf-plugin gewandert (uv pip install vllm-gguf-plugin), und die Doku empfiehlt, den Tokenizer des Basismodells explizit mitzugeben, z. B.10:

sh
vllm serve unsloth/Qwen3-0.6B-GGUF:Q4_K_M --tokenizer Qwen/Qwen3-0.6B

Praktische Regel: GGUF ist in vLLM weniger optimiert; die Leistung muss für den konkreten Workload gemessen werden. Für hohen Serving-Durchsatz auch Safetensors mit unterstützter Quantisierung (AWQ, GPTQ, FP8) vergleichen.

Defaults, die beißen

Ollamas Kontext-Default ist VRAM-gestaffelt. Aktuelle Doku: < 24 GiB VRAM → 4k Kontext; 24–48 GiB → 32k; ≥ 48 GiB → 256k, überschreibbar mit OLLAMA_CONTEXT_LENGTH (ältere Releases hatten einen flachen 4096er-Default, und 4096 taucht noch in den Override-Beispielen der FAQ auf).11 Wenn die 24-GB-Karte einen 32k-Default wählt, den man nicht bestellt hat, wächst der KV-Cache entsprechend – ollama ps prüfen (Spalte CONTEXT) und num_ctx pro Request oder die Env-Variable global setzen.

Ollamas KV-Cache-Typ ist default f16. OLLAMA_KV_CACHE_TYPE akzeptiert f16 (default), q8_0 (etwa halber KV-Payload-Speicher) oder q4_0 (etwa ein Viertel des Payloads; bei beiden Qualität am eigenen Workload prüfen) – und wirkt nur, wenn Flash Attention aktiviert ist.8

OLLAMA_NUM_PARALLEL ist default 1 – gleichzeitige Requests laufen nicht parallel, sondern werden gereiht; Erhöhen multipliziert den KV-Speicher mit N.8

vLLMs gpu_memory_utilization ist default 0,92 – vLLM beansprucht beim Start bis zu 92% des Gesamt-Speichers der Karte (pro Instanz, nicht prozess-koordiniert) und zieht danach Gewichte, Aktivierungs-Peak und CUDA-Graph-Pools ab; der KV-Cache ist der Rest. Auf einer Karte mit Display oder weiteren Prozessen kann dadurch zu wenig Speicher frei bleiben. Anteil oder --max-model-len nach gemessenem Bedarf anpassen.12

Durchgerechnet: 14B Q4_K_M, 4 Slots × 8k, auf einer 24-GB-Karte

Nehmen wir Qwen2.5-14B (48 Layer, GQA mit 8 KV-Heads, Hidden Size 5120 über 40 Heads → Head-Dim 128, 14,7 Mrd. Parameter gesamt).13 Wir rechnen das Budget mit der KV-Formel dieser Seite (siehe KV-Cache-Guide und Inferenz-Mathematik) und setzen llama.cpps gemessene Q4_K_M-≈4,85 Bits pro Gewicht für diese Gewichtsklasse ein.9

Gewichte bei 4,85 bpw:

W=14,7×109×4,858=8,912 GB≈8,30 GiBW = \frac{14{,}7 \times 10^9 \times 4{,}85}{8} = 8{,}912 \,\text{GB} \approx 8{,}30 \,\text{GiB}

KV-Cache pro Token (f16, 2 Byte/Wert), mit 2×L×HKV×dhead×bdtype×s2 \times L \times H_{KV} \times d_{head} \times b_{dtype} \times s:

k=2×48×8×128×2=196,608 B/Tokenk = 2 \times 48 \times 8 \times 128 \times 2 = 196{,}608 \,\text{B/Token}

Pro Slot bei 8.192 Tokens, und gesamt für 4 Slots:

KVSlot=8192×196,608=1,611 GB=1,5 GiBKV_{Slot} = 8192 \times 196{,}608 = 1{,}611 \,\text{GB} = 1{,}5 \,\text{GiB} KVgesamt=4×1,5 GiB=6,0 GiBKV_{gesamt} = 4 \times 1{,}5 \,\text{GiB} = 6{,}0 \,\text{GiB}
KomponenteGröße
Gewichte (Q4_K_M, 4,85 bpw)8,30 GiB
KV-Cache, 4 × 8k Slots, f166,00 GiB
Zwischensumme14,30 GiB
Puffer auf einer 24-GB-Karte (24 dezimale GB − die 14,30-GiB-Zwischensumme = 15,35 GB)~8,65 GB

Es passt – mit deutlichem Puffer, und genau das ist die Aussage: Auf einer 24-GB-Karte liegen ein 14B-Modell in Q4_K_M und 4 parallele 8k-Konversationen komfortabel im Budget; die ~8,65 GB Puffer — 24 dezimale GB auf dem Aufkleber minus der 14,30-GiB-Zwischensumme (15,35 dezimale GB) — decken Compute-Scratch (abhängig von Batch-Größe und Backend) plus CUDA-Kontext. Zwei Hebel, wenn mehr Slots oder Kontext nötig sind: -ctk q8_0 -ctv q8_0 halbiert den KV-Cache auf 3,0 GiB (llama-server-Flags, f16 default1) – derselbe Trade, den Ollamas OLLAMA_KV_CACHE_TYPE=q8_0 macht. Für den vollständigen Sizing-Workflow siehe VRAM-Rechner erklärt und Quantisierung erklärt; das interaktive Tool ist der LLM-Inferenz-Rechner.

Für vier feste 8k-Slots im nicht vereinheitlichten Modus startet man llama-server -m model-Q4_K_M.gguf -c 32768 -np 4 --no-kv-unified. Ein gemeinsamer Pool kann sie ebenfalls aufnehmen, wenn seine Gesamtkapazität reicht.

Entscheidungstabelle

SzenarioWahlWarum
Laptop / Desktop, ein Nutzer gleichzeitigOllamaEin Befehl bis zum laufenden Modell; VRAM-gestaffelte Defaults, Modell-Registry, automatisches GPU-Splitting via darunterliegendem llama.cpp
Mac mit Apple Silicon, schnellstes DecodeOllama (MLX-Engine)Der MLX-Pfad ist für Unified Memory gebaut; Preview erfordert >32 GB Unified Memory und beschleunigt aktuell spezifische Modelle4
Maximale Kontrolle: KV-Quantisierung, Slot-Tuning, exotische Hardware, CPU-Inferenzllama.cpp (llama-server)Direkter Zugriff auf jedes Flag (-ctk, -np, -c, --override-tensor), GGUF-nativ, läuft auf CPU – vLLM-GGUF tut das nicht
Viele gleichzeitige Nutzer, eine oder viele GPUs, Latenz-SLOvLLMGepagerter KV-Pool + Continuous Batching skalieren mit Last; Prefix Caching standardmäßig an6
Produktions-API mit strukturierten Ausgaben / Tool-Use bei hohem QPSvLLMErstklassige Serving-Features, Tensor-Parallelität über GPUs, FP8/AWQ-Quantisierung
Multimodal (Vision) lokalOllama oder llama-serverOllamas Multimodal-Engine macht Vision zur first-class citizen3; llama-servers --mmproj deckt GGUF-Vision-Modelle ab1
Ein HF-only-Modell als GGUF servierenllama.cpp oder OllamavLLMs GGUF-Pfad ist 'highly experimental', Plugin-basiert10

Faustregel: llama.cpp, wenn man an die Regler muss oder exotische Hardware bedienen will; Ollama für reibungslose lokale Nutzung; vLLM, wenn andere Menschen oder Services auf den Endpunkt zugreifen und Durchsatz pro GPU zählt.

Footnotes

  1. ggml-org/llama.cpp, tools/server/README.md (master): https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md — -np/--parallel default -1 (auto), -cb (Continuous Batching) default aktiviert, -b default 2048, -ub default 512, -c/--ctx-size default 0 (aus dem Modell geladen). ↩ ↩2 ↩3 ↩4

  2. ollama/ollama, llama/README.md: LLAMA_CPP_VERSION pinnt Ollamas llama.cpp-Quelle: https://github.com/ollama/ollama/blob/main/llama/README.md ↩

  3. Ollama-Blog, „Ollama's new engine for multimodal models" (15. Mai 2025): https://ollama.com/blog/multimodal-models ↩ ↩2

  4. Ollama-Blog, „Ollama is now powered by MLX on Apple Silicon in preview" (März 2026): https://ollama.com/blog/mlx ↩ ↩2

  5. Kwon et al., „Efficient Memory Management for Large Language Model Serving with PagedAttention", SOSP 2023, arXiv:2309.06180: https://arxiv.org/abs/2309.06180 ↩ ↩2

  6. vLLM-Blog, „vLLM V1: A Major Upgrade to vLLM's Core Architecture" (2025-01-27): bis zu 1,7× Throughput vs. V0; Prefix Caching default mit \<1% Durchsatzverlust bei 0% Hit-Rate: https://blog.vllm.ai/2025/01/27/v1-alpha-release.html ↩ ↩2

  7. llama.cpp Issue #11681 („--ctx-size is divided by --parallel") und PR #24124 (Commit 1844325) / Release b10662 (ctx-per-slot, --kv-unified-per-slot): https://github.com/ggml-org/llama.cpp/issues/11681 ↩

  8. Ollama-FAQ: OLLAMA_NUM_PARALLEL default 1, RAM skaliert mit OLLAMA_NUM_PARALLEL * OLLAMA_CONTEXT_LENGTH; OLLAMA_KV_CACHE_TYPE default f16 mit q8_0/q4_0-Optionen: https://docs.ollama.com/faq ↩ ↩2 ↩3

  9. ggml-org/llama.cpp, tools/quantize/README.md: Q4_K_M = 4,8944 bpw an Llama-3.1-8B (≈4,85–4,9 bpw Gewichtsklasse): https://github.com/ggml-org/llama.cpp/blob/master/tools/quantize/README.md ↩ ↩2

  10. vLLM-Doku, GGUF-Feature-Seite: „highly experimental and under-optimized", Migration zum OOT vllm-gguf-plugin, Basismodell-Tokenizer empfohlen: https://github.com/vllm-project/vllm/blob/main/docs/features/quantization/gguf.md ↩ ↩2

  11. Ollama-Doku, Context length: <24 GiB VRAM → 4k, 24–48 GiB → 32k, ≥48 GiB → 256k, OLLAMA_CONTEXT_LENGTH-Override: https://docs.ollama.com/context-length ; älterer flacher 4096-Default gemäß https://docs.ollama.com/faq ↩

  12. vLLM EngineArgs: gpu_memory_utilization default 0,92, „Fraction of GPU memory to be used for the model executor", pro Instanz: https://docs.vllm.ai/en/latest/api/engine_args.html (vllm/config/cache.py, default=0.92) ↩

  13. Qwen2.5-14B-Instruct-Model Card (48 Layer, GQA 40 Q- / 8 KV-Heads, 14,7 Mrd. Parameter) und config.json (hidden_size 5120, num_key_value_heads 8): https://huggingface.co/Qwen/Qwen2.5-14B-Instruct ↩