TL;DR (3-Zeilen-Version)

  • Performance MLX ist schneller – aber nur im Apple-Silicon-Einzelrechner-Benchmark-Szenario (+3–12%)
  • Agent-Produktion llama.cpp + Ollama eignet sich besser für Agent- und Produktions-Inferenz (HTTP-Runtime ist die entscheidende Variable)
  • Wahrer Engpass In den meisten Szenarien ist die Speicherbandbreite der Flaschenhals, nicht das Framework – bei Swap kollabieren beide gleichzeitig

Kernurteil dieses Artikels

Hardware-Nähe: MLX ist näher (3× weniger Dispatches, kürzerer Quantisierungspfad). Engineering-Nähe: llama.cpp / Ollama ist näher (HTTP-Runtime sofort einsatzbereit, Claude Code Zero-Config). Beide Dimensionen sind nicht austauschbar.

Kernerklärungs-Ebene (Grundprinzipien)

Der wesentliche Unterschied zwischen MLX und llama.cpp ist nicht „ein bisschen schneller oder langsamer", sondern zwei grundlegend verschiedene Ausführungsphilosophien:

  • graph-fusion execution (MLX): lazy Operator-Graph-Sammlung → Laufzeit-Fusion → Batch-Dispatch
  • per-op dispatch execution (llama.cpp): jeder Operator wird unabhängig eingereicht → Plattform-Kompatibilität → vorhersehbarer Overhead

Und zwei grundlegend verschiedene Engineering-Ausrichtungen:

  • hardware-native specialization (MLX): Apple-only, eine Hardware maximal ausreizen
  • engineered portability (llama.cpp): plattformübergreifend CUDA / Metal / Vulkan / CPU, Portabilität hat Vorrang

Alle Leistungsunterschiede lassen sich auf drei Dinge zurückführen:
① Dispatch-Anzahl  ② Kernel-Fusion-Fähigkeit  ③ ob Memory Bandwidth zum Engpass wird

System-Grenzen: Geltungsbereich und Einschränkungen der Aussagen dieses Artikels

Jedes Fazit mit klar definierten Grenzen ist glaubwürdiger als eine grenzenlose Beschreibung. Alle Aussagen zu MLX vs llama.cpp in diesem Artikel gelten unter folgenden Bedingungen:

✅ Anwendbare Szenarien

  • Apple Silicon (M1–M4 / M5-Serie)
  • batch = 1 / Small-Batch-Inferenz (Decode-Phase)
  • Decoder-only Transformer (7B–14B Mainstream-Modelle)
  • Metal Backend (macOS nativer GPU-Pfad)
  • Einzelrechner-Inferenz / kleines Team, gemeinsamer Node
  • Agent-Tools wie Claude Code / Cursor / Open WebUI

❌ Nicht anwendbare Szenarien

  • CUDA / NVIDIA Multi-GPU Serving
  • Large-Batch-Training
  • Distributed Inference (Multi-Node)
  • Speculative Decoding Pipeline
  • MoE-Modelle (Mixture of Experts, andere Architektur)
  • Cloud-GPU-Instanzen (ohne Apple Silicon)

Die Aussagen dieses Artikels gelten nicht für NVIDIA / AMD GPU-Szenarien – das ist die Domäne von CUDA vs. ROCm und hat nichts mit der Unified-Memory-Architektur von Apple Silicon zu tun.

Schlüsselbegriffe: Metal Dispatch · Kernel Fusion · Unified Memory · GGUF vs MLX Format

Vor dem technischen Teil sollten einige Kernkonzepte klargestellt werden. Das sind auch die Begriffe, die im Bereich Apple Silicon LLM-Inferenz am häufigsten verwechselt werden.

Metal Dispatch (Metal Compute Dispatch)
Die kleinste Einheit, mit der die CPU einen Compute-Kernel an die Apple-Silicon-GPU übergibt. Jeder Dispatch erfordert eine CPU-GPU-Synchronisierung mit etwa 1–3 µs Scheduling-Overhead. Je mehr Dispatches, desto höher der kumulierte CPU-Warteaufwand.
Kernel Fusion (Operator-Fusion)
Mehrere unabhängige Operatoren (z. B. matmul → bias add → activation) werden zu einem einzigen GPU-Kernel zusammengefasst, um Dispatch-Anzahl und Zwischenergebnis-Zugriffe auf den globalen Speicher zu reduzieren. MLX macht das automatisch via Lazy Evaluation; llama.cpp setzt auf handgeschriebene Fusions-Kernel (z. B. Flash Attention) mit begrenzter Abdeckung.
Unified Memory (Apple Silicon)
CPU und GPU teilen auf Apple Silicon denselben physischen Speicher – es gibt keinen separaten VRAM. Nach dem Laden der Modellgewichte ist kein CPU↔GPU-Kopiervorgang nötig – das ist der Hardwarevorteil beim LLM-Inferenz auf dem Mac. Sowohl MLX als auch das Metal-Backend von llama.cpp nutzen Unified Memory automatisch; MLX-Allokator ist jedoch tiefer darauf abgestimmt.
GGUF (llama.cpp Quantisierungsformat)
Das von llama.cpp verwendete Modellquantisierungsformat, das verschiedene Präzisionsstufen von Q2_K bis Q8_0 unterstützt. Modelldateien haben die Endung .gguf und sind direkt von Hugging Face herunterladbar. Ollama verwaltet Modelle mit GGUF und ist nicht kompatibel mit dem MLX-Format.
MLX Format (mlx-community Quantisierungsformat)
Das von MLX verwendete Modellformat basiert auf safetensors mit MLX-Quantisierungsmetadaten. Konvertierung via mlx_lm.convert oder direkt von mlx-community. Quantisierungs-Kernel sind direkt an Metal-Shader gebunden und vollständig inkompatibel mit GGUF – dasselbe Basismodell muss separat konvertiert werden.

MLX vs llama.cpp Architektur-Überblick: Vollständiger Vergleich der Apple-Silicon-Inferenz-Frameworks

Bevor es ins Detail geht, ein Überblick. Der grundlegende Unterschied zwischen mlx vs llama.cpp liegt im Design-Ziel: Das eine ist für Apple-only-Spitzenoptimierung, das andere für plattformübergreifende Portabilität.

DimensionMLXllama.cpp
Design-Ziel Apple Silicon exklusiv Plattformübergreifend (CUDA / Metal / Vulkan / CPU)
Scheduling-Modell Lazy Graph Fusion (Batch-Dispatch nach Graph-Analyse) Per-Op Dispatch (jeder Operator unabhängig eingereicht)
Metal-Ansatz Runtime JIT Kernel (laufzeitspezifisch für Tensorform kompiliert) Vorcompilierte Kernel (im Binary gebündelt)
Speichermodell Nativer Unified-Memory-Allokator ggml-Allokator (allgemein, nicht Apple-spezifisch)
Quantisierungsformat safetensors + MLX Metadata (mlx-community) GGUF (Q2_K bis Q8_0)
HTTP Runtime Kein eingebauter Server (eigene FastAPI-Gateway nötig) Ollama-Wrapper, sofort einsatzbereit (:11434)
Direkt mit Claude Code / Cursor verbindbar? ❌ Eigenes Gateway nötig ✅ Ollama Zero-Config
Geeignet für Benchmark, Research, LoRA Fine-Tuning Agent-Runtime, Produktions-Inferenz, Team-Sharing

Die letzten beiden Zeilen bestimmen die Stack-Auswahl; tok/s-Unterschiede sind in § Wahrer Ursprung der Leistungsunterschiede behandelt und fließen nicht in die Agent-Runtime-Entscheidung ein.

Apple Silicon LLM Inference Stack Model (2026)

Das obige Vergleichstabelle als Vier-Schichten-Modell: das einfachste Framework zum Verständnis aller Fazits dieses Artikels.

┌─────────────────────────────────────────────────┐
│            Application Layer                    │
│   Claude Code  ·  Cursor  ·  Open WebUI         │
├─────────────────────────────────────────────────┤
│            Runtime Layer                        │
│   Ollama (llama.cpp)  │  FastAPI (MLX wrapper)  │
│   ✅ Empfohlen Agent  │  ⚠️ Selbst bauen nötig  │
├─────────────────────────────────────────────────┤
│            Compute Layer                        │
│   ggml-metal (per-op) │  MLX (graph fusion)     │
│   Plattformübergr.    │  Apple-only, JIT        │
├─────────────────────────────────────────────────┤
│            Hardware Layer                       │
│       Apple Silicon Unified Memory              │
│   CPU + GPU teilen physischen Speicher          │
└─────────────────────────────────────────────────┘
Abb. · Apple Silicon LLM Inferenz Vier-Schichten-Stack — Stack-Auswahl findet im Runtime-Layer statt, Leistungsunterschiede kommen vom Compute-Layer, die Obergrenze liegt im Hardware-Layer

Kernaussage: Stack-Auswahl findet nur im Runtime-Layer statt. Leistungsunterschiede im Compute-Layer (MLX vs ggml-metal) beeinflussen die Runtime-Layer-Wahl nicht – beide Layer dienen verschiedenen Ebenen und ersetzen sich nicht gegenseitig.

Kernunterschied: Metal-Dispatch-Anzahl (480 vs 160) – Ursprung der Apple-Silicon-Inferenz-Performance

Das ist die wichtigste Zahl in diesem Artikel. Wer den Dispatch-Unterschied versteht, versteht die Wurzel des MLX-vs-llama.cpp-Leistungsunterschieds.

Für ein 7B-Transformer-Modell erfordert die Generierung eines Tokens einen Forward Pass durch 32 Schichten. Jede Schicht enthält Operatoren wie QKV Projection, Attention Score, Softmax, Output Projection, FFN Gate, FFN Up/Down, RMS Norm und RoPE:

llama.cpp (per-op dispatch):   32 Schichten × ~15 Operatoren/Schicht ≈ 480 Metal Dispatches
MLX (nach lazy graph fusion):  32 Schichten × ~4–5 Fusion-Blöcke/Schicht ≈ 128–160 Metal Dispatches

💡 Kernaussage (zitierbar)

MLX-Vorteil kommt nicht von mehr Rechenleistung, sondern von ~3× weniger CPU↔GPU Dispatches.
Bei batch=1 kostet jedes [commandBuffer commit] etwa 1–3 µs CPU-Scheduling-Overhead. 480 vs. 160 Dispatches sparen pro Token etwa 0,3–1 ms – das ist der Hauptmechanismus hinter dem MLX-Benchmark-Vorsprung, nicht ein besserer Kernel-Algorithmus.

Jeder Metal-Dispatch ist ein CPU-GPU-Synchronisierungspunkt: Die CPU muss warten, bis die GPU den Command Buffer bestätigt, bevor der nächste Operator-Kernel aufgerufen werden kann. Wenn die GPU-Compute-Zeit kurz ist (Small-Batch-Inferenz), wird der Dispatch-Overhead zum Flaschenhals. MLX's Lazy Evaluation fusioniert mehrere Operatoren zu einem einzigen Dispatch und umgeht diesen Synchronisierungsaufwand direkt.

Token-Latenz-Zerlegungsmodell (Dispatch Cost Model)

Die Generierungslatenz eines Tokens aufgeteilt in drei quantifizierbare Komponenten:

Token latency ≈
  dispatch_count × cpu_sync_cost     ← Dispatch-Overhead (Quelle der Framework-Differenz)
  + gpu_compute_time                 ← Tatsächliche GPU-Rechenzeit (Bandbreite / Rechenleistung)
  + memory_bandwidth_time            ← Gewichtstransfer-Zeit (physische Obergrenze)

Typische Verteilung bei batch=1, 7B-Modell, M4 Mac Mini 16 GB:

Komponentellama.cppMLXAnmerkung
dispatch_count × cpu_sync_cost ~480 × 2 µs ≈ 0,96 ms ~160 × 2 µs ≈ 0,32 ms Quelle der Framework-Differenz, ca. 10–30% der Gesamtlatenz
gpu_compute_time ~1–3 ms (beide ähnlich) Abhängig von Rechenleistung und Quantisierungsformat
memory_bandwidth_time ~4 GB ÷ 120 GB/s ≈ 33 ms (dominanter Term) Physische Obergrenze, kein Framework kann das optimieren

Obige Werte sind Näherungsschätzungen (batch=1, 7B Q4_K_M, M4 16 GB). memory_bandwidth_time ist der dominante Term – das erklärt, warum der MLX-Vorteil bei Bandbreitensättigung gegen null geht.

Dimensionllama.cpp (ggml-metal)MLX
Kernel-Lebenszyklus Vorcompiliert, im Binary gebündelt (.metal.metallib) Laufzeit-JIT-Kompilierung bei Bedarf; erster Lauf hat Kompilierungs-Delay, danach gecacht
Operator-Fusion Begrenzt: einige handgeschriebene Fusions-Kernel (z. B. Flash Attention) Automatische Framework-Fusion; Lazy-Graph-Analyse fasst benachbarte Operatoren zusammen
Dispatch-Anzahl pro Forward Pass (7B) ca. 400–600 (per-op) ca. 80–160 (nach Fusion)
CPU-Scheduling-Pfad ggml Scheduling-Thread → Metal Command Buffer MLX Scheduler schreibt direkt in Metal Command Buffer
Multi-Stream-Parallelität Einzelne Metal Command Queue (Haupt-Konfiguration) Mehrere Streams unterstützt; benachbarte Schichten können parallel berechnet werden

Warum MLX entstand: Der Design-Ausgangspunkt eines Apple-Silicon-spezifischen Inferenz-Frameworks

Ende 2023 hat Apples Machine-Learning-Research-Team MLX open-sourced. Die Design-Motivation ist ungewöhnlich – nicht für Plattformübergreifung, sondern um eine Hardware maximal auszureizen.

Vor MLX war LLM-Inferenz auf Apple Silicon auf folgende Optionen angewiesen:

  • Core ML / MPS: Apples offizielle Inferenz-Stack – geschlossenes Modellformat, nicht forschungsfreundlich
  • llama.cpp + Metal: Community-Hauptlösung, aber ggml wurde für die CUDA-Welt entworfen und bringt plattformübergreifende Abstraktions-Overhead mit sich
  • PyTorch + MPS Backend: Unvollständige MPS-Operator-Abdeckung, Inferenzgeschwindigkeit nutzt Apple Silicon nicht voll aus

Apples Ingenieure kamen zu dem Schluss: Um Unified Memory + Hochbandbreiten-Bus + Metal GPU wirklich zu nutzen, braucht es ein von Grund auf für Apple Silicon entwickeltes Array-Computing-Framework.

MLX: Vier Kern-Design-Prinzipien

  • CPU und GPU teilen denselben Speicherbereich – Zero-Copy-Datentransfer
  • Lazy Evaluation: Operationen werden nicht sofort ausgeführt, sondern gesammelt und bei Bedarf batch-weise dispatched – zwischenzeitlich Graph-Optimierung
  • Dynamischer Graph + JIT, NumPy/JAX-ähnliche API – forschungsfreundlich
  • Metal Compute Shader werden zur Laufzeit bei Bedarf kompiliert – kein vorgepacktes festes Kernel-Set

llama.cpp Architektur: ggml Plattform-Abstraktion + Metal Backend + GGUF-Quantisierung

llama.cpp wurde im März 2023 von Georgi Gerganov veröffentlicht mit dem Ziel, LLaMA in reinem C/C++ auf Consumer-Hardware zum Laufen zu bringen. Portabilität hat absoluten Vorrang.

ggml: Allgemeines Tensor-Backend

Das Herzstück von llama.cpp ist ggml – eine leichtgewichtige C-Tensorbibliothek, die via Backend-Plugins verschiedene Hardware unterstützt:

BackendHardwareAktivierung
GGML_METALApple Silicon GPUmacOS, -DLLAMA_METAL=ON
GGML_CUDANVIDIA GPULinux/Windows + CUDA
GGML_VULKANAMD / Intel GPUVulkan Driver
GGML_CPUAlle CPUsStandard-Fallback

Der Vorteil ist ein Codebase für alle Plattformen; der Preis ist, dass jedes Backend ein allgemeines Adapter ist, das keine tiefgreifende Optimierung für spezifische Hardware erlaubt – und die Abstraktionsschicht bringt Scheduling-Overhead.

Metal Backend (ggml-metal) und vorcompilierte Kernel

Auf Apple Silicon aktiviert llama.cpp ggml-metal.metal – eine vorcompilierte Metal-Shader-Datei mit:

  • Matrix-Multiplikation: spezialisierte Kernel für GGUF-Quantisierungsformate wie Q4_K, Q8_0
  • Softmax, RoPE, RMS Norm: eigenständige Kernel pro Operator
  • KV-Cache-Operationen: Speicher-View-Wiederverwendung zur Vermeidung von Kopieroperationen

Entscheidende Einschränkung: Kernel sind vorcompiliert und fest – keine Laufzeit-Reoptimierung für Tensorformen. Bei Änderungen der Sequenzlänge oder Batch-Größe werden Kernel-Parameter über Metal-Buffer übergeben, aber der Kernel selbst bleibt unverändert – genau hier kann MLX's Runtime-Spezialisierung punkten.

GGUF-Quantisierungsformat

llama.cpp verwendet GGUF mit Quantisierungspräzisionen von Q2_K (stark komprimiert) bis Q8_0 (nahe fp16). Jede Quantisierungsstufe hat eine entsprechende Metal-Kernel-Implementierung – das ist der Grund für die solide Apple-Silicon-Performance. Allerdings bedeutet das auch: Jedes neue Quantisierungsformat erfordert einen eigenen Kernel-Satz.

MLX Architektur: Lazy Evaluation + Runtime JIT Kernel + Apple Silicon Unified Memory

Der grundlegende Unterschied zwischen MLX und llama.cpp liegt in der Position der Abstraktionsschicht: Das Metal-Backend von llama.cpp ist ein „Plugin-Backend"; MLX's gesamter Berechnungsgraph lebt von Anfang an in der Metal-Semantik.

Lazy Evaluation + Berechnungsgraph-Fusion

  1. Python-Code ruft MLX-Operatoren auf – keine sofortige Ausführung, nur Aufzeichnung der Berechnungsgraph-Knoten
  2. Beim Aufruf von mx.eval() analysiert das Framework den gesamten Graph
  3. Benachbarte fusionierbare Operatoren (matmul + bias + activation usw.) werden zu einem Metal Dispatch zusammengefasst
  4. Der generierte Metal Compute Shader wird zur Laufzeit kompiliert und gecacht

Tiefere Nutzung von Unified Memory

  • Alle Tensoren werden im Unified-Memory-Pool allokiert; CPU und GPU teilen dieselbe physische Adresse
  • Kein „VRAM"-Konzept – nach dem Laden der Modellgewichte liest die GPU direkt, kein cudaMemcpy-Äquivalent nötig
  • Metal Buffer und MLX-Array zeigen auf denselben Pointer – Zero-Copy-Parameter-Übergabe

Das Metal-Backend von llama.cpp nutzt ebenfalls Unified Memory (das ist ein Hardware-Feature von Apple Silicon, das alle Metal-Programme automatisch erhalten), aber der ggml-Allokator wurde nicht speziell dafür designed und hat zusätzliche Alignment- und Allokations-Logik.

GGUF vs. MLX Quantisierungsformat: Zwei inkompatible Ökosysteme

MLX verwendet safetensors + MLX-Quantisierungsmetadaten, vollständig inkompatibel mit GGUF. Dasselbe Basismodell muss separat konvertiert werden:

  • Für llama.cpp: Von HuggingFace herunterladen → convert.py zu GGUF konvertieren, dann quantisieren
  • Für MLX: mlx_lm.convert konvertieren oder direkt von mlx-community vorkonvertierte Versionen holen

Quantisierungsbreiten unterstützen 4-bit, 8-bit und Mixed Precision; Operator-Implementierungen sind direkt an Metal-Shader gebunden – das ist der Grund, warum MLX's Dequantisierungspfad kürzer ist als GGUF's.

Wahrer Ursprung der MLX vs. llama.cpp Leistungsunterschiede: Dispatch-Anzahl vs. Speicherbandbreite

Das ist der Teil in mlx benchmark-Diskussionen, der am häufigsten missverstanden wird. MLX's Geschwindigkeitsvorteil kommt nicht von besseren Matrix-Multiplikations-Algorithmen, sondern von drei quantifizierbaren Engineering-Faktoren:

1. Dispatch-Fusion: 3× weniger CPU-GPU-Synchronisierungen

Wie in § Kernunterschied beschrieben, reduziert MLX die Metal-Dispatches pro Token von ~480 auf ~160. Das bringt am meisten bei batch=1, kurzen Sequenzen – wenn die GPU-Compute-Zeit kurz ist und der CPU-Scheduling-Overhead einen höheren Anteil hat.

2. Laufzeit-Kernel-Spezialisierung: Optimiert für konkrete Tensorformen

MLX kompiliert Metal-Shader beim ersten Lauf mit einer bestimmten Form und kann Tile-Size und Workgroup-Größe für die genauen Matrixdimensionen anpassen. Die vorcompilierten Kernel von llama.cpp verwenden konservative Allgemein-Parameter, die für nicht-standardisierte Sequenzlängen suboptimal sind.

3. Kürzerer Dequantisierungspfad

Um Multi-Plattform zu unterstützen, muss die Dequantisierung (Dequant) von llama.cpp CPU-Fallback-Pfade berücksichtigen; MLX's Quantisierungs-Kernel zielt direkt nur auf Metal ab – Dequant + Matrix-Multiplikation können im selben Shader abgeschlossen werden, mit weniger globalen Speicherzugriffen.

Benchmark-Richtwerte

Folgende Daten stammen aus Macstripe Lab, Llama-3.1-8B / Q4_K_M, batch=1, gemessen Juni 2026. Nur als Trendrichtung, nicht als Kauf- oder Stack-Entscheidungsgrundlage.

Gerätllama.cpp (Ollama) tok/sMLX tok/sDifferenz
M4 Mac Mini 16 GB27–3128–33+3%–7%
M4 Mac Mini 24 GB34–3937–43+5%–10%
M4 Pro 48 GB72–8080–90+8%–12%

Muster: Je mehr Speicher und je größer das Modell, desto deutlicher der MLX-Vorteil. Bei größeren Modellen ist die GPU-Compute-Zeit pro Forward-Pass länger, sodass der absolute Nutzen der Dispatch-Fusion steigt; bei 16 GB / 7B ist die Bandbreite bereits der Flaschenhals und verwässert den Fusionsvorteil.

Performance Convergence Model (Leistungskonvergenzdiagramm)

Der Tabellentrend visualisiert: Wie MLX's Leistungsvorteil mit dem Speicherausbau wächst – und beim Bandbreitendeckel auf null fällt:

  MLX advantage
  (tok/s delta)

  +12% │                                        ● 48GB (14B)
       │                                   ·
   +8% │                              ·
       │                         ·
   +5% │                    ● 24GB (7B–14B)
       │               ·
   +3% │          ● 16GB (7B)
       
    0% │━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  ← memory bandwidth ceiling
       │   (swap)  (swap)
  -∞% │     ↓ Bei Swap kollabieren beide gleichzeitig
       
       └────────────────────────────────────────────
              16GB       24GB       48GB       Speicherausbau
Abb. · MLX vs llama.cpp Leistungsdifferenz-Konvergenzmodell — unterhalb der Speicherbandbreiten-Obergrenze hat MLX einen Vorteil, im Swap-Bereich konvergieren beide auf null

Die Kernaussage des Diagramms: Der Speicherausbau bestimmt, wo man auf der Kurve steht. Der Gewinn von 16 GB → 24 GB (kein Framework-Wechsel kann das erreichen) übersteigt bei weitem den MLX-vs-llama.cpp-Unterschied von 3–12%.

Warum mlx benchmark Differenz in den meisten Szenarien ≈ 0: Speicherbandbreite ist die wahre Obergrenze

Nicht in allen Szenarien ist MLX's Vorteil sichtbar. Das ist der wichtigste „kontraintuitive Wertpunkt" dieses Artikels:

Speicherbandbreitenüttigung: Physikalische Grenzen ebnen Framework-Unterschiede ein

Die Performance-Obergrenze von batch=1-Inferenz ist die Gewichtstransfer-Bandbreite, nicht die GPU-Rechenleistung. Die Generierung eines Tokens erfordert das Lesen aller Schichtgewichte (7B Q4 ≈ 4 GB Datenbewegung). M4's Speicherbandbreite beträgt ~120 GB/s (16-GB-Version) – diese physikalische Obergrenze bestimmt die tok/s-Obergrenze. Weder MLX noch llama.cpp können sie durchbrechen – bei Bandbreitensättigung konvergieren beide.

Bei Swap kollabieren beide gleichzeitig

Bei unzureichendem Unified Memory verschiebt das System Gewichte auf SSD; die Bandbreite fällt von 120 GB/s auf 3–5 GB/s (NVMe Sequenzlese-Limit). Beide Frameworks fallen im tok/s auf einstellige Werte – Framework-Unterschiede verschwinden vollständig. Die einzige Lösung ist mehr Speicher; ein Framework-Wechsel hilft nicht.

Langer Kontext-Prefill: GPU-Rechenleistung wird zum Engpass, Dispatch-Overhead-Anteil geht gegen null

Prefill (Verarbeitung langer Prompts) ist compute-intensive; GPU-Auslastung nähert sich 100%. Für 2048-Token-Prompt-Prefill liegt der Unterschied zwischen beiden typischerweise <5%.

Kleine Modelle (≤3B): Absolute Compute-Zeit zu kurz

3B Q4-Gewichte sind nur ~2 GB; ein Forward-Pass dauert ~5–10 ms auf der GPU. Der Anteil der Dispatch-Fusion-Einsparung von 0,3–1 ms steigt, aber der Absolutwert ist so klein, dass Nutzer es nicht bemerken.

Hochpräzise Quantisierung (Q8_0 / fp16): Bandbreite sättigt früher

Je höher die Präzision, desto größer die Gewichte, desto früher wird die Bandbreite zum Flaschenhals. Q8-Modelle auf 16-GB-Maschinen führen fast zwangsläufig zu Swap – Framework-Unterschiede sind dann bedeutungslos.

Ollama vs. MLX Stack-Auswahl: Warum Agent-Runtime sich nicht um tok/s kümmert

Wenn MLX auf Hardware-Ebene näher ist, warum ist Claude Code's empfohlener Stack dann Ollama (llama.cpp)? Weil das zwei verschiedene Dimensionen sind.

HTTP-Server ist die entscheidende Variable

Ollama liefert über llama.cpp einen vollständigen Inferenz-Service-Stack:

  • Sofort einsatzbereiter HTTP-Inferenzdienst (:11434, OpenAI-kompatible API) – Claude Code verbindet sich direkt, Zero-Config
  • Modell-Lifecycle-Management (ollama pull / rm, automatisches Entladen ungenutzter Modelle)
  • Multi-Request-Concurrent-Scheduling (mehrere Claude-Code-Fenster teilen dieselbe Modellinstanz, kein erneutes Laden)
  • Team-LAN-Sharing (ollama serve --host 0.0.0.0, alle Teammitglieder nutzen denselben :11434)

MLX hat das alles nicht. MLX an Claude Code anzubinden erfordert: eigenes FastAPI-Gateway bauen → Modell-Lade/Entlade-Logik implementieren → Concurrent-Request-Queue verwalten → OpenAI-API-Kompatibilitätsschicht pflegen. Das ist ein vollständiger Inferenz-Service-Stack – keine Einzeilen-Lösung.

tok/s-Unterschied im Agent-Tool-Loop <5%

Im Agent-Tool-Loop umfasst jeder Claude-Code-Aufruf: Prompt-Zusammenstellung → HTTP-Request → Warten auf Antwort → Tool-Call-Parsing → Tool-Ausführung → nächste Runde. Latenzverteilung:

FaktorAnteil (typischer Agent-Task)Durch Framework optimierbar?
Werkzeug-Ausführungszeit (Datei-I/O, Shell-Befehle)50%–70%Nein
HTTP-Roundtrip + Modell-TTFT20%–35%Hauptsächlich durch Speicherausbau
Framework-seitiger tok/s-Unterschied (MLX vs. llama.cpp)<5%Ja, aber Einfluss minimal

Die entscheidende Variable für das Agent-Erlebnis ist Speicherausbau und Modellgröße. Framework-Unterschiede werden durch HTTP-Layer und Werkzeug-Ausführungszeit vollständig überlagert.

Engineering-Grenzen von Ollama vs. MLX

Klare Grenzen eliminieren Verwechslungen:

  • Ollama (llama.cpp): HTTP-Runtime-Layer – löst das Problem „wie schließe ich es an"
  • MLX: Compute-Layer-Tool – löst das Problem „wie läuft es in Python schnell"
  • Beide schließen sich nicht aus: Dieselbe Mac kann MLX für Benchmarks installiert haben und gleichzeitig Ollama für Claude Code betreiben

→ Vollständige Ollama vs. MLX Stack-Auswahl-Logik: Ollama vs MLX: Welcher Stack für Claude Code lokale Modelle?
→ MLX Deployment auf M4 Pro: Apple Silicon M4 Pro lokales LLM: Performance-Test und MLX-Deployment

MLX oder llama.cpp – was soll ich wählen? (30-Sekunden-Entscheidungsleitfaden)

Nach konkretem Anwendungsfall wählen – es gibt keine absolute Antwort auf „welches ist besser":

Apple Silicon LLM Inferenz Schlussfolgerungsmodell: Drei zitierbare Regeln (mac m4 llm inference speed)

Alle Fazits dieses Artikels komprimiert in ein wiederverwendbares, zitierbares Urteilsframework:

Urteilsmodell (direkt zitierbar)

  1. Performance-Obergrenze = Speicherbandbreite
    Die tok/s-Obergrenze von batch=1-Inferenz auf Apple Silicon wird durch die Unified-Memory-Bandbreite bestimmt (~120 GB/s für M4); kein Framework kann physikalische Grenzen durchbrechen.
  2. Framework-Unterschied = Dispatch-Overhead
    Die Leistungsdifferenz MLX vs. llama.cpp (3–12%) kommt aus der Differenz in Metal-Dispatch-Anzahl (480 vs. 160), nicht von besseren Operator-Algorithmen.
  3. System-Auswahl = Runtime vs. Research
    Agent-Runtime → Ollama (llama.cpp) – HTTP-Server ist die entscheidende Variable; Research / Benchmark / Fine-Tuning → MLX – Compute-Layer ist hardware-nah.

Framework-Optimierung liefert maximal 5–15%; Speicherausbau entscheidet 85%.
Jede MLX-vs-llama.cpp-Diskussion läuft letztendlich auf diesen Satz hinaus.

Häufige Fragen zur Apple-Silicon-Inferenz-Stack-Auswahl

Was eignet sich besser für lokales Deployment: MLX oder llama.cpp?

Das hängt davon ab, was „Deployment" bedeutet. Für das Deployment eines Inferenzdienstes (für Claude Code / Cursor / eigene API) eignet sich llama.cpp + Ollama besser – sofort einsatzbereiter HTTP-Server, gutes Modell-Management. Für das Deployment einer Forschungsumgebung (neue Modelle testen, Benchmarks durchführen, Python-Skripte schreiben) ist MLX besser – hardwarenäher, flexible Python-API.

Warum kein CUDA für LLM-Inferenz auf Apple Silicon?

Apple Silicon hat keine NVIDIA-GPU und unterstützt kein CUDA. Apples GPU wird über die Metal API angesprochen; die Unified-Memory-Architektur lässt CPU und GPU denselben physischen Speicherpool teilen – vollständig verschieden vom NVIDIA-Modell mit separatem VRAM. Sowohl MLX als auch llama.cpp basieren auf Metal und nutzen Unified Memory statt VRAM.

Was ist der Unterschied zwischen GGUF und dem MLX-Quantisierungsformat?

Beide sind nicht kompatibel – zwei völlig unabhängige Quantisierungsökosysteme. GGUF (llama.cpp) unterstützt Q2_K bis Q8_0 mit spezialisierten ggml-metal-Kernel-Implementierungen; MLX verwendet safetensors + MLX-Quantisierungsmetadaten mit direkt an Metal-Shader gebundenen Quantisierungs-Kerneln. Dasselbe Basismodell muss für beide Frameworks separat konvertiert werden.

Warum nutzt der Mac hauptsächlich Ollama für LLMs?

Ollama löst das Engineering-Problem „wie LLM in Betrieb nehmen": Ein Befehl startet den HTTP-Server, OpenAI-kompatible API, Claude Code / Cursor / Open WebUI und andere Tools verbinden sich direkt. Unter der Haube ist llama.cpp mit Metal-Beschleunigung auf Apple Silicon – ausreichend performant und ohne Python-Umgebung oder eigene Service-Infrastruktur.

FAQ

MLX vs. llama.cpp – welches ist schneller und wie groß ist der Unterschied?

In den meisten Benchmark-Szenarien ist MLX um 3–12% schneller, hauptsächlich durch Operator-Fusion (ca. 480 vs. 160 Dispatches) und Runtime-Metal-Kernel-Spezialisierung. Bei batch=1-Bandbreitensättigung, Speicher-Swap oder langem Prefill nähern sich beide jedoch gegen null. Je mehr Speicher (48-GB-Node) und je größer das Modell (14B+), desto deutlicher der MLX-Vorteil; bei 16 GB / 7B beträgt der Unterschied nur 3–7%.

Was ist der grundlegende Unterschied zwischen dem Metal-Backend von llama.cpp und MLX?

llama.cpp abstrahiert mehrere Plattformen über ggml; Metal ist eines von vielen Backends mit vorcompilierten Kernels und eigenständigem Dispatch pro Operator. MLX wurde von Anfang an nur für Apple Silicon konzipiert – Lazy Evaluation fusioniert Operatoren zur Laufzeit, 3× weniger Dispatches, kürzerer Quantisierungspfad, tiefere Unified-Memory-Ausrichtung.

Können GGUF und MLX-Format ineinander konvertiert werden?

Keine direkte Konvertierung möglich – beide Formate sind vollständig unabhängig. GGUF wird mit llama.cpp's convert.py aus ursprünglichen Gewichten generiert; MLX-Format wird mit mlx_lm.convert konvertiert oder direkt von mlx-community gezogen. Dasselbe Basismodell muss für beide separat konvertiert werden.

Warum nutzt Claude Code Ollama statt MLX?

Ollama liefert einen sofort einsatzbereiten HTTP-Dienst (:11434, OpenAI-kompatibel) ohne eigenes Gateway. Im Agent-Tool-Loop macht der Framework-seitige tok/s-Unterschied weniger als 5% der Gesamtlatenz aus – Werkzeugausführungszeit und HTTP-Layer sind die Engpässe. MLX hat keinen eingebauten HTTP-Server; die Integration in Claude Code erfordert einen vollständigen selbst gebauten Inferenz-Stack, dessen Engineering-Aufwand alle Geschwindigkeitsvorteile aufzehrt.

Welches Framework übersteht Swap besser?

Beide degradieren massiv – der Unterschied verschwindet. Die Speicherbandbreite fällt von 120 GB/s auf 3–5 GB/s (NVMe-Limit); kein Framework kann den SSD-Flaschenhals optimieren. Speicher upgraden (24 GB oder 48 GB Node) ist die einzige Lösung.

Kann man MLX und Ollama gleichzeitig installieren?

Ja, beide koexistieren problemlos. Empfohlene Konfiguration: Ollama läuft dauerhaft im Hintergrund für Claude Code; MLX wird bei Bedarf in Python-Umgebungen für Benchmarks oder Fine-Tuning-Skripte genutzt. Beide teilen denselben Unified Memory, verwenden aber unterschiedliche Modellformate, die separat verwaltet werden müssen.

Weiterführende Artikel