KVSplit – 2- bis 3-mal längerer Kontext auf Apple Silicon
(github.com/dipampaul17)- KVSplit ist ein Open-Source-Projekt, das die Ausführung großer LLMs und langer Kontextfenster auf Apple Silicon ermöglicht
- Durch die getrennte Zuweisung der Präzision für Keys und Values erreicht es bis zu 72 % weniger Speicherverbrauch bei weniger als 1 % Qualitätsverlust
- Es ist für M1/M2/M3-Chips und das Metal-Framework optimiert
- Verbesserte Ausführungsgeschwindigkeit und Speicherersparnis werden durch gemessene Benchmarks und Visualisierungstools belegt
- Es bietet einfache Installation, Vergleich per Ein-Kommando-Aufruf sowie verschiedene Benchmark- und Analysetools
Einführung: Warum KVSplit wichtig ist
KVSplit ist ein Open-Source-Tool, das durch Quantisierung mit unterschiedlicher Präzision für Keys und Values innerhalb des KV-Caches die Ausführung großer LLMs und deutlich längerer Kontextfenster in Apple-Silicon-Umgebungen (M1/M2/M3) ermöglicht. Es überwindet die Einschränkung bisheriger Projekte, die Keys und Values identisch quantisieren, und reduziert den Speicherverbrauch drastisch, während der Qualitätsverlust auf ein kaum wahrnehmbares Niveau begrenzt bleibt. Reale Benchmarks, Geschwindigkeits- und Qualitätsmetriken sind vollständig offengelegt, was das Projekt vertrauenswürdig macht; zugleich steigern Metal-Support sowie intuitive Vergleichs- und Visualisierungstools die Effizienz in der Entwicklung.
Die wichtigsten Vorteile gegenüber ähnlichen Projekten sind:
- Getrennte Präzision für Keys und Values für nochmals effizienteres Speichermanagement
- Spezialisierung auf Apple Silicon und vollständige Optimierung für das Metal-Framework
- Integrierte Benchmarks, Perplexity-, Speicher-/Geschwindigkeits-/Qualitätsmessungen und Visualisierung
- Installation per Ein-Kommando-Aufruf, Modellkompatibilität, Integration mit llama.cpp
- Echtzeit-Visualisierung der Speicherersparnis und vielfältige Vergleichstest-Tools
Hauptmerkmale und Kernaussagen
Überblick
- Mit KVSplit lassen sich auf Apple Silicon deutlich größere LLMs und längere Kontextlängen ausführen als bisher
- Durch unterschiedliche Quantisierungspräzision für Keys und Values werden sowohl Speicherersparnis als auch Geschwindigkeitsverbesserungen erreicht
- Bestätigt wurden bis zu 72 % Speicherersparnis und Geschwindigkeitsverbesserungen (5–15 %↑) bei weniger als 1 % Qualitätsverlust
- Vollständige Metal-Unterstützung sorgt für optimale Beschleunigung auf Apple Silicon
Zentrale Benchmark-Ergebnisse
- In der Konfiguration K8V4 (Keys 8 Bit, Values 4 Bit)
- 59 % Speicherersparnis und 0,86 % Qualitätsverlust (gemessen an Perplexity)
- 5,7 % schneller als FP16
- In der Konfiguration K4V4 (Keys/Values beide 4 Bit)
- bis zu 72 % Speicherersparnis
- etwa 6 % Qualitätsverlust; empfohlen für Einsatzzwecke mit geringerer Qualitätssensitivität
Vergleich der Speicherersparnis
- Ausgehend von FP16 mit 176 MB (8K Token)
- K8V8 (8-Bit-Keys/Values): 93,5 MB (47 %)
- K8V4 (8-Bit-Keys, 4-Bit-Values): 71,5 MB (41 %)
- K4V4 (4-Bit-Keys/Values): 49,5 MB (28 %)
Hauptfunktionen
- Separate Quantisierung von Keys und Values im KV-Cache
- Vollständige Optimierung für Apple Silicon und Metal
- Analyseskripte für Benchmarks/Qualität (Perplexity)/Speichernutzung
- Visualisierungstools und Erstellung publikationsreifer Grafiken
- Ein-Kommando-Setup und Echtzeit-Vergleichsfunktionen
Projektordner-Struktur
- llama.cpp: enthält einen für Metal optimierten Build
- models: Speicherort für Modelldateien
- scripts: enthält Skripte für Benchmarks/Installation/Vergleich/Visualisierung
- results, plots: Speicherort für Benchmark-Ergebnisse und Visualisierungsdateien
- README.md
Wissenschaftliche Einsichten und Versuchsergebnisse
Zentrales Phänomen im KV-Cache
- Key-Vektoren sind deutlich empfindlicher gegenüber Quantisierung als Value-Vektoren → zur Erhaltung der Qualität muss Keys eine höhere Präzision zugewiesen werden
- K8V4 ist der Sweet Spot: die Aufteilung mit 8 Bit für Keys und 4 Bit für Values bietet den besten Kompromiss aus Qualität und Speicher
- 59 % Speicherersparnis, nur 0,86 % schlechtere Perplexity und zugleich schneller als FP16
- K4V8 verursacht trotz gleicher Gesamtbitzahl wie K8V4 einen mehr als 7-fach größeren Qualitätsverlust → ein klarer Beleg für die Bedeutung der Präzision auf der Key-Seite
Übergreifende Implikationen
- Speichereffizienz und Erhalt der Modellqualität lassen sich gleichzeitig erreichen → dadurch werden deutlich längere Kontexte und größere Modelle auf Consumer-Hardware möglich
Anwendungsbeispiele und Konfigurationsempfehlungen
Ausführungsbeispiele mit verschiedenen Quantisierungspräzisionen
- Standard (FP16): ./llama.cpp/build/bin/llama-cli -m models/your-model.gguf -p "Prompt" -t 8 --flash-attn
- Empfohlen: K8V4: --kvq 8
- K4V8 (DEMO): --kvq-key 4 --kvq-val 8
- K4V4 (maximale Einsparung): --kvq 4
Beispiel für langen Kontext
- 32K Kontext: FP16 benötigt ~1,4 GB, K8V4 kann jedoch mit ~400 MB laufen
Erklärung der Kommandozeilen-Flags
-t 8: Anzahl der Threads, 8 empfohlen für M1/M2/M3--flash-attn: Optimierung für Apple Silicon--kvq N: setzt Keys und Values beide auf N Bit--kvq-key,--kvq-val: unterstützt separate Einstellungen-c N: Anzahl der Kontext-Token (je länger, desto stärker der Effekt von KVSplit)-n N: Anzahl der generierten Token-f FILE: Eingabedatei für Dokumente-m MODEL: Modellpfad
Fortgeschrittenes Benchmarking und Visualisierung
- Mit benchmark_kvsplit.py werden je Konfiguration und Sequenzlänge Speicher/Geschwindigkeit/Perplexity/Skalierungseigenschaften gemessen
- Mit visualize_results.py lassen sich Grafiken in Papierqualität erzeugen
- Ergebnisse werden automatisch als CSV/JSON gespeichert und zusammengefasst
Optimierung für Apple Silicon und Speichervisualisierung
- Vollständige Nutzung des Metal-Frameworks
- Besonders wirkungsvoll auf M1/M2/M3-Systemen mit hohem Speicherdruck
- Mit capture_memory.sh lässt sich die Speicherersparnis in Echtzeit visualisieren
- Durch angepasste Seitenausrichtung kann die tatsächliche Einsparung leicht von theoretischen Werten abweichen
Zusammenfassung der Funktionen
- Unabhängige Bitpräzision für Keys/Values und maßgeschneiderte Quantisierung
- Vollständige Optimierung für Apple Silicon und Metal
- Umfassende Benchmarks zu Speicher/Geschwindigkeit/Qualität
- Visualisierung in Papierqualität und Echtzeitvergleich sowie Unterstützung für Speicheraufzeichnung
- Extrem einfache Installations- und Bedienoberfläche
Zitate und referenzierte Forschung
- "More for Keys, Less for Values: Adaptive KV Cache Quantization" (2024)
- "Unifying KV Cache Compression for Large Language Models with LeanKV" (2025)
- Basisimplementierung: [llama.cpp], Testmodell: [TinyLlama]
Konfigurationsempfehlungen und weitere Pläne
- K8V4 (Keys 8 Bit / Values 4 Bit): 0,86 % Qualitätsverlust, 59 % weniger Speicher, +5,7 % Geschwindigkeit als optimale Balance
- K4V4: maximale Speicherersparnis (72 %), etwa 6 % Qualitätsverlust; geeignet, wenn Speicher oberste Priorität hat
- Besonders stark bei der Ausführung langer Kontexte, 2- bis 3-mal längere Kontexte sind möglich
Roadmap
- Adaptive Präzision basierend auf Token-Wichtigkeit
- Separate Quantisierung pro Layer
- Modellspezifische Optimierung (Mistral, Phi-3 usw.)
- Geplante Unterstützung für Web-Demo und Mobilgeräte (iOS/iPadOS)
Lizenz und Hinweise zur Mitwirkung
- MIT-Lizenz
- Entwickler und AI-Forscher können über Issues und PRs beitragen
1 Kommentare
Hacker-News-Kommentare
Ausdruck von Interesse, dass es spannend wirkt; Fragen nach einer Intuition dafür, warum dieses Phänomen auftritt, und wie die Entdeckung zustande kam; Vorschläge für nutzerfreundlichere Verbesserungen wie den noch unvollständigen Patch-Anwendungsschritt im Installationsskript und die Nutzung von
git submodule; außerdem der Vorschlag,llama.cppund die Python-Abhängigkeiten zu trennen, um verschiedene Python-Umgebungen zu berücksichtigenllama.cppangewendet werde; der Argument-Parsing-Code sei bereits nacharg.cppverschoben worden und damit sei der Patch bedeutungslos; außerdem seien K/V-Quantisierungsoptionen schon 2023 zullama.cpphinzugefügt worden; der Nutzen des Patches werde daher infrage gestellt und es wirke so, als würden lediglich Kommandozeilenargumente anders gesetzt; starke Empfehlung, für das Anwenden eines derart einfachen Patch-Files nicht extra dieinstall.sheines neuen Repositories auszuführenFrage, ob dieser Patch auch in MLX möglich wäre; Erwartung, dass MLX schneller sei und dieser Ansatz Mac-Nutzern bei langfristig geführten Gesprächen mit praxistauglicher Geschwindigkeit helfen könnte
Frage, ob es praktisch einen Unterschied zu den Optionen
--cache-type-k,--cache-type-vgebebf16sei erst kürzlich hinzugekommen; früher sei auf Apple-GPUs mit demtype_k/v-Ansatz mindestens 16 Bit (f16/bf16) nötig gewesen, daher könne es – ohne genaue Kenntnis des Inneren vonllama.cpp– vielleicht doch ein leicht anderer Ansatz seinNach dem Lesen des Codes die Einschätzung, dass der Patch unnötig sei; per PR-Link bestätigt, dass die Funktion bereits 2023 in
llama.cppeingeflossen sei; Vorsicht sei geboten, weil man perinstall.shzur Anwendung eines Patches statt zur Nutzung eines Fork-Repositories bewegt werde; kritisiert wird die verwirrende Struktur des Repositories mit mehreren Patch-Dateien, doppeltem Code und dem Überschreiben von Patch-Dateien; tatsächlich werde nur eine--kvq-Option ergänzt, obwohl bereits separate K/V-Quantisierungsoptionen existieren; es erscheine unwahrscheinlich, dass dem Autor diese vorhandene Funktionalität unbekannt gewesen sei; die Ausführung von Skripten aus einem Repository mit komplexen Skripten werde nicht empfohlen; trotz hoher Aufmerksamkeit auf HN und vieler GitHub-Stars sei der Inhalt irreführend; zusätzlich sei besorgniserregend, dass der Autor Fragen immer wieder ausweiche; abschließend die Einschätzung, dass Repository und Skripte mit einer altenllama.cpp-Codebasis vermischt seien und nicht zur aktuellen Struktur passten, was zusätzliche Verwirrung stifteFrage, ob sich differenzielle KV-Quantisierung (K8V4 usw.) auch auf bereits konvertierte Modelle im
.gguf-Format anwenden lässt und ob es Einschränkungen je nach Modelltyp oder Tokenizer-Konfiguration gibt.gguf-Modellen ohne spezielle Konvertierung nutzbar sei; die Quantisierung werde nur auf den KV-Cache zur Laufzeit angewendet und sei unabhängig von den Modellgewichten; mit den Flags--kvq-keyund--kvq-valwerde lediglich das Speicherformat festgelegt; erfolgreich getestet worden sei dies mit LLama-3, Mistral, Phi-2/Phi-3, TinyLlama, Qwen und weiteren Modellen; allerdings nur mit dem Metal-Backend vonllama.cpp, und weil Flash Attention derzeit benutzerdefinierte KV-Cache-Formate umgeht, sei die Option-fa 0nötig; ansonsten sei es auf jede Transformer-Architektur mit Attention anwendbarFrage, ob dieser Patch auf Apple-Silicon-Systemen mit viel Speicher wie 64 GB oder 128 GB schneller oder besser sei; Verweis auf Gerüchte, dass größere Kontextfenster auf Apple Silicon in der Praxis langsam seien; gefragt wird, ob großer Speicher hier einen realen Nutzen bringt
Ausdruck von Interesse und Bitte um eine etwas höher abstrahierte Erklärung: Lässt sich ein 2048-Token-Modell auf 4–6k erweitern oder ein 128k-Kontextmodell auf 256k+? Außerdem die Frage nach idealen Einsatzszenarien für lokale Modelle
Lob als wirklich gute Idee und interessanter Versuch; dazu die Frage, ob sich das auch auf GPUs anwenden lasse und ob es mit anderen Quantisierungstechniken kombinierbar sei
llama.cppunterstütze bereits getrennte Einstellungen über--cache-type-kund--cache-type-v; der aktuelle Patch sei zwar auf Metal spezialisiert, aber das Prinzip lasse sich direkt übertragen; auch mit anderen Quantisierungstechniken könne es kombiniert werden, da die KV-Cache-Quantisierung nur zur Laufzeit greife und nicht mit der Quantisierung der Modellgewichte kollidiere; es handle sich um getrennte Stufen der Pipeline; bei Engines wie vLLM oder TensorRT-LLM mit eigener Cache-Struktur wäre allerdings eine separate Implementierung nötig; auf GPUs wäre der größte Effekt zu erwarten, wenn dies direkt in FlashAttention integriert würde, weil die Speicherersparnis dann unmittelbar zu höherer Geschwindigkeit führen könnteHinweis, dass einiges unverständlich und merkwürdig wirke; Empfehlung, das betreffende Skript nicht auszuführen; Mitteilung, dass es gemeldet wurde
Frage, wie sich die Performance verändert: Selbst wenn man längere Kontexte in den Speicher bekommt, sollte die Rechengeschwindigkeit am Ende nicht gleich bleiben?
fp16,q8undq4ähnlich bleibe; der interne Ablauf sei zwar nicht geprüft worden, aber man habe erwartet, dass die Vektoren per 4- oder 8-Bit-SIMD gebündelt gepackt würden; tatsächlich wirke es eher so, als geschehe dieses Packing nicht