1 Punkte von GN⁺ 2025-05-18 | 1 Kommentare | Auf WhatsApp teilen
  • KVSplit zielt darauf ab, auf Apple Silicon für den Attention-KV-Cache von LLMs unterschiedliche Quantisierungspräzisionen für Key und Value anzuwenden, um bei gleichem Speicherbudget längere Kontexte und größere Modelle auszuführen
  • Das Kernergebnis ist die Konfiguration K8V4, die bei 8K Token den Speicher von 176.00MB bei FP16 auf 71.50MB reduziert, den Tokendurchsatz von 54,360 tokens/sec auf 57,438 tokens/sec erhöht und eine Perplexity-Änderung von +0.86% zeigt
  • Basierend auf dem Ergebnis, dass Keys empfindlicher auf Quantisierung reagieren als Values, wird zusammengefasst, dass K4V8 bei gleicher Gesamtbitzahl einen etwa 7-mal größeren Qualitätsverlust als K8V4 verursacht
  • Zu den bereitgestellten Funktionen gehören ein llama.cpp-Patch, ein Build mit Metal-Unterstützung, Benchmarks für Speicher, Geschwindigkeit und Perplexity, das Speichern der Ergebnisse als CSV/JSON, Visualisierungstools sowie Aufnahmen der Speichereinsparung über Activity Monitor
  • Die empfohlene Konfiguration ist K8V4 als Balance zwischen Qualität und Speichereinsparung; falls maximale Speichereinsparung nötig ist, gibt es mit K4V4 eine Option mit 72% Reduktion bei etwa 6% Qualitätsverlust

Das Problem, das KVSplit lösen will

  • KVSplit ist ein Projekt zur Reduzierung des KV-Cache-Speichers bei der LLM-Inferenz auf Apple-Silicon-Macs
  • Im KV-Cache des Attention-Mechanismus werden für Key und Value unterschiedliche Quantisierungspräzisionen angewendet
  • Die Ziele sind wie folgt
    • den Speicherverbrauch um bis zu 72% zu senken
    • bei gleichem Speicherbudget 2- bis 3-mal längere Kontexte auszuführen
    • die Inferenzgeschwindigkeit gegenüber FP16 beizubehalten oder zu verbessern
    • Metal-Unterstützung passend für Apple Silicon bereitzustellen

Zentrale Benchmark-Ergebnisse

  • Die Ergebnisse pro Konfiguration bei 8K Token sind wie folgt
    • FP16: 176.00MB, 54,360 tokens/sec
    • K8V8: 93.50MB, 51,503 tokens/sec, Perplexity +0.03%
    • K8V4: 71.50MB, 57,438 tokens/sec, Perplexity +0.86%
    • K4V8: 71.50MB, 58,690 tokens/sec, Perplexity +6.06%
    • K4V4: 49.50MB, 55,193 tokens/sec, Perplexity +6.15%
  • In der Tabelle zur Speichereinsparung wird K8V4 bei 8K Token mit einer 59%igen Reduktion und K4V4 mit 72%iger Reduktion angegeben
  • In der Leistungstabelle zeigt K8V4 gegenüber FP16 eine Geschwindigkeitssteigerung von +5.7%, K4V8 von +8.0% und K4V4 von +1.5%
  • K8V8 reduziert gegenüber FP16 den Speicher, ist aber bei der Geschwindigkeit um -5.3% langsamer

Speicherverbrauch nach Sequenzlänge

  • Je länger der Kontext, desto größer ist der Speicherspareffekt beim KV-Cache
  • Der Speicherverbrauch bei 8192 Token ist wie folgt
    • FP16: 176.00MB
    • K8V8: 93.50MB
    • K8V4: 71.50MB
    • K4V8: 71.50MB
    • K4V4: 49.50MB
  • Auch bei 4096 Token verwenden K8V4/K4V8 35.75MB und K4V4 24.75MB gegenüber 88.00MB bei FP16
  • Bei 128 Token werden FP16 mit 5.50MB, K8V4/K4V8 mit 2.23MB und K4V4 mit 1.55MB angegeben

Asymmetrie zwischen Key und Value

  • Der KV-Cache-Speicher wird hauptsächlich von der Speicherung der Key-Vektoren und Value-Vektoren jedes Tokens bestimmt
  • Die zentrale Beobachtung des Projekts ist, dass Keys deutlich empfindlicher auf Quantisierung reagieren als Values
  • K8V4 verwendet 8-Bit-Keys und 4-Bit-Values und bietet damit folgenden Balancepunkt
    • 0.86% Perplexity-Verschlechterung gegenüber FP16
    • 59% Speichereinsparung
    • schnellere Inferenz als FP16
  • K4V8 nutzt zwar die gleiche Gesamtbitzahl wie K8V4, der Qualitätsverlust ist laut Zusammenfassung jedoch etwa 7-mal größer als bei K8V4
  • Dank dieser Asymmetrie sollen auf Consumer-Hardware längere Kontexte und größere Modelle möglich werden

Installation und Integrationsweise

  • Die Installation erfolgt, indem das Repository geklont und anschließend scripts/install_kvsplit.sh ausgeführt wird
git clone https://github.com/dipampaul17/KVSplit.git
cd kvsplit

chmod +x scripts/install_kvsplit.sh
./scripts/install_kvsplit.sh
  • Das Installationsskript ermöglicht die Auswahl der Python-Umgebung
    • Virtual Environment: erstellt eine unabhängige Python-Umgebung im Projektordner
    • System Python: verwendet die bestehende Python-Installation
    • Skip Python Setup: der Benutzer verwaltet die Python-Umgebung selbst
  • Auch die Integrationsweise mit llama.cpp kann gewählt werden
    • Standardmethode: llama.cpp klonen und den KV-Split-Patch anwenden
    • Git-submodule-Methode: llama.cpp als Submodul für Entwickler oder fortgeschrittene Nutzer hinzufügen
  • Der Installationsprozess umfasst das Einrichten von llama.cpp mit Metal-Unterstützung für Apple Silicon, das Aktivieren der differenzierten KV-Cache-Quantisierung, das optionale Herunterladen eines Testmodells und das Einrichten von Visualisierungstools

Anwendungsbeispiele und CLI-Optionen

  • Ein schneller Vergleich lässt sich mit einem vorhandenen GGUF-Modell ausführen
python scripts/quick_compare.py --model models/your-model.gguf
  • Verglichen werden FP16, K8V8, K8V4, K4V8 und K4V4; dabei werden Speicher-, Geschwindigkeits- und Qualitätsmetriken gemeinsam angezeigt
  • Das Ausführungsbeispiel im README verwendet llama-cli zusammen mit --flash-attn und den KV-Quantisierungsoptionen
./llama.cpp/build/bin/llama-cli -m models/your-model.gguf -p "Your prompt" \
  -t 8 --flash-attn --kvq 8
  • Im Beispiel für K4V8 werden die Bitzahlen für Key und Value getrennt angegeben
./llama.cpp/build/bin/llama-cli -m models/your-model.gguf -p "Your prompt" \
  -t 8 --flash-attn --kvq-key 4 --kvq-val 8
  • Für das 32K-Kontextbeispiel wird angegeben, dass FP16 etwa 1.4GB und K8V4 etwa 400MB benötigt
./llama.cpp/build/bin/llama-cli -m models/your-model.gguf \
  -c 32768 -n 4096 -t 8 --flash-attn --kvq 8 \
  -f your-long-document.txt
  • Die wichtigsten CLI-Flags sind wie folgt
    • -t 8: Anzahl der Threads, auf den meisten Apple-Silicon-Chips werden 8 empfohlen
    • --flash-attn: aktiviert optimiertes Attention, für Apple Silicon empfohlen
    • --kvq N: setzt die Bitzahl für Key und Value
    • --kvq-key N: setzt nur die Bitzahl für Key
    • --kvq-val N: setzt nur die Bitzahl für Value
    • -c N: Kontextgröße
    • -n N: Anzahl der zu generierenden Token
    • -f FILE: Eingabedatei
    • -m MODEL: Pfad zur .gguf-Modelldatei

Benchmark- und Visualisierungstools

  • Der vollständige Benchmark wird mit scripts/benchmark_kvsplit.py ausgeführt
python scripts/benchmark_kvsplit.py
python scripts/benchmark_kvsplit.py --config K8V4 --seq-len 4096
  • Die Visualisierung wird mit scripts/visualize_results.py erzeugt
python scripts/visualize_results.py
  • Der Benchmark misst die folgenden Punkte
    • Memory Usage: VRAM und KV-Cache-Speicher
    • Performance: tokens/sec nach Sequenzlänge
    • Quality: Perplexity mit llama-perplexity
    • Scaling: Veränderung von Speicher und Leistung in Abhängigkeit von der Sequenzlänge
  • Die Ergebnisse werden im CSV/JSON-Format gespeichert und erzeugen automatisch zusammenfassende Statistiken und Visualisierungsplots
  • capture_memory.sh ist ein Tool, um Speichereinsparungen im Activity Monitor festzuhalten

Apple-Silicon-Optimierung und Einschränkungen

  • KVSplit ist auf Apples Metal framework optimiert
  • Der Fokus liegt auf Speichereffizienz auf Geräten mit Speicherbeschränkungen wie den Apple-Silicon-Chips der M-Serie
  • Im README wird darauf hingewiesen, dass die tatsächliche Speichereinsparung wegen des 256B page alignment von llama.cpp leicht von der theoretischen Berechnung abweichen kann
  • Unterstützt werden M1-, M2-, M3- und M4-Chips

Empfohlene Konfiguration und Roadmap

  • Die empfohlene Konfiguration ist K8V4
    • 8-Bit-Keys, 4-Bit-Values
    • 59% Speichereinsparung
    • 0.86% Qualitätsverlust
    • +5.7% Inferenzgeschwindigkeit gegenüber FP16
  • Die maximale Speichereinsparung bietet K4V4
    • 4-Bit-Keys und 4-Bit-Values
    • 72% Speichereinsparung
    • etwa 6% Qualitätsverlust
    • laut Angabe für weniger sensible Anwendungen geeignet
  • Für sehr lange Kontexte werden K8V4 oder K4V4 empfohlen; je länger der Kontext, desto stärker summiert sich die Speichereinsparung
  • Zu den künftigen Plänen gehören
    • tokenwichtigkeitsbasierte Adaptive Precision
    • Layer-Specific Quantization mit unterschiedlicher Präzision pro Layer
    • modellspezifische Optimierung für Mistral, Phi-3 und andere
    • Web-Demo
    • Unterstützung für iOS und iPadOS
  • Die Lizenz ist MIT; Beiträge können über Issue oder Pull Request eingereicht werden

1 Kommentare

 
GN⁺ 2025-05-18
Meinungen auf Hacker News
  • Interessant. Ich frage mich, ob es eine Intuition dafür gibt, warum diese Ergebnisse zustande kommen. Ebenso, ob man es über diese Intuition entdeckt hat oder durch zufällige Experimente
    Im Schritt „apply patch“ des Installationsskripts scheinen noch Platzhalter übrig zu sein. Statt nach git clone einen Patch anwenden zu lassen, wäre es nutzerfreundlicher, llama.cpp zu forken und als Git-Submodul einzubinden
    Außerdem hat jeder lokal ein anderes Python-Setup; statt eine Abhängigkeit von Homebrew-Python fest zu verdrahten, wäre es gut, die llama.cpp-bezogenen Teile und die Python-bezogenen Teile trennen zu können

    • Gute Frage zur Intuition. Der Unterschied ergibt sich aus den Kernrollen, die die einzelnen Komponenten in der Attention übernehmen
      Keys entscheiden, auf welche Tokens geachtet wird, und erzeugen über Ähnlichkeitsberechnungen das tatsächliche Attention-Muster. Values speichern lediglich die Informationen, die weitergegeben werden, nachdem die Attention festgelegt wurde
      Wenn man Key-Vektoren zu aggressiv quantisiert, werden die Ähnlichkeitsberechnungen aller Token-Interaktionen verzerrt. Kleine Fehler bei Keys können die Attention auf völlig falsche Tokens lenken
      Values sind deutlich nachsichtiger. Quantisierungsfehler in Value-Vektoren beeinflussen nur den Informationsgehalt dieses einzelnen Tokens, nachdem das Attention-Muster bereits feststeht
      Es ist ähnlich wie der Unterschied zwischen einem Katalogsystem in einer Bibliothek und den Büchern selbst. Wenn die Katalognummern (Keys) kaputt sind, landet man in einem völlig falschen Regal; wenn aber einige Wörter im Buch (Values) verschwimmen, liest man immer noch das richtige Buch, nur mit gelegentlichem Rauschen
      Mathematisch gehen Keys in die Softmax-Berechnung ein, und kleine Fehler werden im Normalisierungsprozess exponentiell verstärkt. Values durchlaufen nur einen linear gewichteten Mittelwert, sodass sich Fehler tendenziell gegenseitig aufheben
      Auf diese Asymmetrie bin ich zuerst in Papers wie „More for Keys, Less for Values“ und „KV-AdaQuant“ gestoßen und wollte quantifizieren, wie stark der Effekt konkret bei Inferenz auf Apple Silicon ist. Beeindruckend war, dass es bei gleichem Speicherverbrauch einen 7-fachen Qualitätsunterschied zwischen K8V4 und K4V8 gab
      Danke auch für das Installations-Feedback; ich werde die Platzhalter beheben und die Python-Abhängigkeiten flexibler machen
    • Der Patch wird tatsächlich gar nicht auf llama.cpp angewendet, weil das Argument-Parsing vor 8 Monaten nach arg.cpp verschoben wurde
      Dass es trotzdem egal ist, liegt daran, dass die Optionen zum Einstellen der K- und V-Quantisierung bereits 2023 zu llama.cpp hinzugefügt wurden
      Ich verstehe nicht, warum dieser Patch existiert. Außer vorhandene Einstellungen in andere Kommandozeilenargumente umzubenennen, damit es neu wirkt, sehe ich keinen Grund
      Ich rate dringend davon ab, bei solchen neuen Repositories die Datei install.sh auszuführen. Erst recht, wenn es für etwas so Simples wie das Anwenden einer einzelnen Patch-Datei unnötig ist
  • Unterscheidet sich das von der Nutzung von --cache-type-k und --cache-type-v?

    • Nein. Es sieht nach einem LLM-generierten Versuch aus, GitHub-Stars zu bekommen
      Einige der anderen Merkwürdigkeiten im Repository habe ich in einem anderen Kommentar notiert
    • Ich vermute, es ist etwas anders. MLX/MPS hat keine native 4-Bit-Unterstützung, und wenn ich mich richtig erinnere, möglicherweise nicht einmal 8-Bit. Zum Launch gab es auch keine bf16-Unterstützung
      Deshalb denke ich, dass mit der alten type_k/v-Methode und auf der Apple-GPU das Minimum wohl 16-Bit f16/bf16 gewesen wäre. Ich bin allerdings kein Experte für die Interna von llama.cpp und könnte mich irren
  • Ich frage mich, ob man diesen Patch auch in MLX umsetzen kann. In MLX bekomme ich bessere Geschwindigkeit; kombiniert mit diesem Ansatz könnten Mac-Nutzer lange Unterhaltungen mit brauchbarer Geschwindigkeit führen

    • Vermutlich ja, aber ich stecke gerade tief in MLX und stelle fest: Es ist zwar ein gut designtes Framework, aber längst nicht reif genug, dass man einfach Beispielcode nehmen könnte, in dem schon jemand den „besten Weg“ gebenchmarkt hat
      Persönlich freue ich mich am meisten, so unglaublich es klingen mag, auf Haskell-Bindings. Vor ein paar Tagen wies jemand darauf hin, dass Haskells Lazy Evaluation ziemlich gut zu diesem Paradigma passt und dass auch der nahezu rein funktionale Ansatz für Compile-Graphen hilfreich ist. Machine Learning in Haskell zu machen, klingt nach Spaß
  • Ich frage mich, ob sich differenzielle KV-Quantisierung (z. B. K8V4) auf Modelle anwenden lässt, die bereits ins .gguf-Format konvertiert wurden. Oder muss man das Modell mit spezieller Unterstützung neu bauen?
    Falls es mit jeder .gguf-Datei kompatibel ist, frage ich mich auch, ob es Einschränkungen beim Modelltyp (Mistral, Phi-3 usw.) oder bei den Tokenizer-Einstellungen gibt

    • Ja, das geht. Einer der zentralen Vorteile von KVSplit ist, dass man vorhandene .gguf-Modelle unverändert verwenden kann, ohne sie neu zu konfigurieren oder speziell zu konvertieren. Die Quantisierung passiert nicht beim Laden oder Konvertieren des Modells, sondern zur Laufzeit im KV-Cache
      Das ist möglich, weil der KV-Cache während der Inferenz beim Verarbeiten von Tokens erzeugt wird und vollständig von den Modellgewichten getrennt ist. Die Flags --kvq-key und --kvq-val teilen llama.cpp lediglich mit, wie diese Zwischentensoren im Speicher abgelegt werden sollen
      Erfolgreich getestet wurde es mit Llama-3, Mistral, Phi-2/Phi-3, TinyLlama und Qwen-Varianten
      Die einzige Einschränkung ist, dass das Metal-Backend von llama.cpp benötigt wird und die aktuelle Flash-Attention-Implementierung von llama.cpp die benutzerdefinierten KV-Cache-Formate umgeht; daher muss Flash Attention mit -fa 0 deaktiviert werden. Die Technik selbst sollte mit jeder Transformer-Architektur funktionieren, die einen Standard-Attention-Mechanismus verwendet
  • Ich hatte Zeit, den Code zu lesen. Wenn ich diesen PR richtig verstanden habe, ist der Patch überflüssig, weil diese Funktion bereits seit 2023 in llama.cpp vorhanden ist: https://github.com/ggml-org/llama.cpp/pull/4312
    Statt einen llama.cpp-Fork bereitzustellen, in dem die Änderungen als Commit angewendet sind, lässt das Repository ein install.sh-Skript ausführen. Dieses Skript checkt ohne Angabe einer Revision den Master-Branch von llama.cpp aus und wendet dann einen kurzen Patch an. Allein das ist schon ein Warnsignal, dass etwas nicht stimmt.
    Im Repository liegen vier verschiedene Patch-Dateien, und im Installationsskript steckt zusätzlich noch eine weitere Patch-Version als Heredoc. Außerdem enthält das Skript zwei Versionen des Codes, der das Repository klont und den Patch anzuwenden versucht.
    install.sh überschreibt mit der Zeile cp patch/split_kv_quant.diff patch/fixed_kv_patch.diff eine Patch-Datei mit einer anderen. Dadurch wird die im Repository eingecheckte fixed_kv_patch.diff überschrieben, bevor sie angewendet wird.
    Für mich sieht es so aus, als solle eigentlich dieser Patch verwendet werden: https://github.com/dipampaul17/KVSplit/blob/main/patch/split... (Edit: Den Kommentaren am Ende nach zu urteilen, ist es tatsächlich wohl dieser hier: https://github.com/dipampaul17/KVSplit/blob/main/patch/fixed... )
    Das Einzige, was dieser Patch hinzufügt, ist ein Argument --kvq, das K- und V-Quantisierung gleichzeitig setzt; direkt darüber gibt es aber bereits eingebaute Argumente, um K- und V-Quantisierung jeweils separat zu setzen. Kann es wirklich sein, dass dem Autor beim Hin- und Herschieben dieser Patches nicht aufgefallen ist, dass die Funktion bereits existiert?
    Ich rate dringend davon ab, Shell-Skripte aus einem solchen neuen Repository auszuführen. Erst recht, wenn sie so kompliziert sind.
    Der HN-Beitrag hat über 200 Upvotes bekommen, und das GitHub-Repository sammelt ebenfalls weiter über 200 Sterne, aber der Inhalt wirkt irreführend. Ein Kommentar in diesem Thread, der auf das Problem hingewiesen hat und dafür massenhaft geflaggt wurde, lag tatsächlich richtig. Besorgniserregend ist auch, dass der Autor in diesem Thread weiter antwortet, aber der Frage ausweicht, dass die Funktion bereits existiert.
    Edit: Ich hatte das Shell-Skript falsch gelesen. Tatsächlich scheint es diesen Patch anzuwenden: https://github.com/dipampaul17/KVSplit/blob/main/patch/fixed... Nach dem Anwenden des Patches überschreibt es merkwürdigerweise fixed_kv_patch.diff mit split_kv_quant.diff, tut danach aber nichts mehr. Ich weiß nicht, ob das das Ergebnis von Vibe-Coding ist oder einfach unachtsame Codebearbeitung, aber ich möchte wiederholen: Solche Shell-Skripte aus unbekannten Repositories sollte man nicht ausführen.
    Edit 2: Es wird noch verwirrender. Das install.sh-Skript verweist auf die alte URL des llama.cpp-Repositorys (https://github.com/ggerganov/llama.cpp), die vor einiger Zeit geändert wurde und inzwischen weiterleitet. Die Patches versuchen, das Argument-Parsing in common.cpp zu ändern, aber dieser Code wurde vor acht Monaten nach arg.cpp verschoben (https://github.com/ggml-org/llama.cpp/commit/bfe76d4a17228bf...). Damit basieren dieses Installationsskript und Repository offenbar auf Code von etwa 2024 und verwenden eine Option, die um 2023 zu llama.cpp hinzugefügt wurde. Was zur Hölle ist hier los?

    • Stimmt. Ich hatte die restlichen verdächtigen Punkte nicht extra erwähnt, falls ich etwas übersehen habe und der Autor es hier noch erklären könnte.
      Es gibt viele Warnsignale. Wohlwollend betrachtet wirkt es wie jemand, der mit LLM-generiertem Code sein GitHub-Profil aufblähen will. Man muss sich nur die Aktivitäten dieses Profils vom 12. Mai ansehen.
    • Endlich ergibt etwas Sinn. Allein die Tatsache, dass dieses Projekt funktioniert, indem es Patches anwendet, statt das Originalprojekt zu forken und die Änderungen zu committen, ist schon Grund genug zur Sorge.
      Aber die gesamte GitHub-Aktivität des ursprünglichen Autors ist verdächtig. Am 12. Mai hat er bei mehreren populären Projekten LLM-Mischmasch-PRs eingereicht; nur bei JAX wurde er abgelehnt. Trotzdem konnte er sich dadurch beliebte Projekte im Profil anpinnen, als wäre er ein Contributor.
      Es ist schwer in Worte zu fassen, wie widerlich das ist. Jeder, der im KI-Bereich arbeitet, macht sich an der Informationsverschmutzung mitschuldig, und die Folgen können wir noch nicht einmal absehen. Das tote Internet und die Flut aus KI-Mischmasch sind erst der Anfang.
  • Sind diese auf Apple Silicon mit 64 GB oder 128 GB spürbar schneller oder besser als mit 36 GB oder 48 GB?
    Ich habe gelesen, dass große Kontexte und große Modelle selbst auf dem schnellsten und größten Apple Silicon, den man für Geld kaufen kann, quälend langsam sind.
    Deshalb frage ich mich, ob das den größeren Speicher besser nutzbar macht – oder ob in der Praxis auf Apple Silicon weiterhin vergleichsweise kleine Modelle die Antwort sind.

    • Die Speichereinsparungen von KVSplit wachsen proportional zur Kontextlänge, daher profitieren Macs mit viel RAM wie 64 GB/128 GB in absoluten Zahlen stärker. Ein Mac Studio mit 128 GB könnte potenziell auch Kontextfenster mit Hunderttausenden Tokens bewältigen.
      Allerdings verändert KVSplit die Rechengeschwindigkeit nicht grundlegend, sondern nur die Speichereffizienz. In Benchmarks stieg der Durchsatz mit K8V4 um 14,5 %, aber das lag nicht an weniger Rechenaufwand, sondern an besserer Speicherlokalität.
      Der Hauptgrund, warum große Modelle auf Apple Silicon „quälend langsam“ sind, ist nicht die Speichergrenze, sondern die begrenzte Rechenleistung. Ein Modell mit 70B Parametern wird unabhängig vom verfügbaren RAM oder von KV-Cache-Optimierungen mit ähnlicher Token-Generierungsgeschwindigkeit laufen.
      KVSplit hilft dabei, den verfügbaren Speicher besser zu nutzen. Besonders wertvoll ist es, wenn die Kontextlänge – nicht die Modellgröße – der Flaschenhals ist.
      Für den praktischen Einsatz auf Apple Silicon bleibt der Sweet Spot weiterhin, kleinere Modelle (7B–13B) mit erweitertem Kontextfenster zu verwenden. So lässt sich deutlich mehr Text verarbeiten, während die Generierungsgeschwindigkeit vernünftig bleibt.
      Wenn der Workflow sowohl riesige Kontexte als auch große Modelle erfordert, sollte man weiterhin Server-GPUs in Betracht ziehen; KVSplit verschiebt aber die Grenzen dessen, was auf Apple-Hardware möglich ist, ein Stück weiter.
  • Großartige Arbeit und sehr interessant, aber um es zu verstehen, bräuchte ich eine etwas höherstufige Erklärung.
    Ermöglicht es zum Beispiel, ein Modell mit 2048-Token-Kontextfenster mit 4–6K Kontextfenster laufen zu lassen? Oder ein 128K-Modell wie gemma3 mit einem Kontextfenster von 256K oder mehr?
    Was ist der ideale Use Case für lokale Modelle?

    • Die K8V4-Konfiguration spart 59 % Speicher, sodass man auf derselben Hardware effektiv einen 2,4-mal längeren Kontext ausführen kann. Ein Modell mit 2048-Token-Kontext könnte etwa 5000 Tokens verarbeiten, ein 8K-Kontextmodell käme auf etwa 19,5K.
      Praktisch heißt das, dass man auf einem MacBook ein ganzes Buch auf einmal verarbeiten, eine große Codebase analysieren kann, ohne Dateien aufzuteilen, oder in Chat-Anwendungen einen langen Gesprächsverlauf beibehalten kann.
      Die Speichereinsparung skaliert linear mit der Kontextlänge. Je länger das Kontextfenster, desto größer die absolute Speicherersparnis. Auf meinem M4 MacBook schrumpfte der KV-Cache bei 8K Kontext von 176 MB auf 72 MB. Bei 128K Kontext würde dieselbe prozentuale Einsparung Speicher im Gigabyte-Bereich freigeben.
      Diese Optimierung ist am wertvollsten, wenn man an die Grenze des Kontextfensters stößt, nicht an die Grenze der Modellparameter. Wenn wegen langer Eingaben – nicht wegen großer Modellgewichte – ein Out-of-Memory-Fehler auftritt, behebt KVSplit den direkten Flaschenhals.
    • Es reduziert die Speichernutzung eines bestimmten Modells. Wie man den frei werdenden Spielraum nutzt, entscheidet der Nutzer.
      Das Kontextfenster nach dem Training zu vergrößern ist nicht trivial; wenn man nicht genau weiß, was man tut, ist es besser, ein Modell zu suchen, das mit einem größeren Kontextfenster trainiert wurde.
      Lokale Modelle haben viele Einsatzzwecke, etwa Offline-Arbeit, Datenschutz/Sicherheit usw. Die meisten nutzen sie allerdings eher zum Experimentieren und Anpassen von Modellen.
  • Hier läuft etwas Seltsames, daher sollte man das besser nicht installieren oder dieses Skript ausführen.
    Den eingereichten Beitrag habe ich geflaggt.

  • Eine großartige Idee und ein guter Versuch. Gilt das auch für GPUs? Und es scheint auch mit anderen Quantisierungsmethoden kompatibel zu sein – vermutlich braucht dann jede davon einen eigenen Patch?

    • Ja. Dieser Ansatz dürfte wahrscheinlich auch auf NVIDIA-/AMD-GPUs möglich sein. Das Grundprinzip, dass Keys eine höhere Präzision benötigen als Values, ist hardwareunabhängig.
      Das CUDA-Backend von llama.cpp unterstützt mit den Flags --cache-type-k und --cache-type-v bereits getrennte Cache-Typ-Einstellungen. Dieser konkrete Patch konzentriert sich auf Metal-spezifische Optimierungen, aber die Kerntechnik lässt sich direkt übertragen.
      Auch mit anderen Quantisierungsmethoden besteht Kompatibilität. Diese KV-Cache-Optimierung ergänzt die Quantisierung der Modellgewichte (Q4_K_M, GPTQ, AWQ usw.). Asymmetrische KV-Cache-Präzision kann mit jedem Format für Modellgewichte gemeinsam verwendet werden.
      Die KV-Cache-Quantisierung erfolgt zur Laufzeit während der Token-Verarbeitung und ist von den Modellgewichten getrennt; sie kollidiert daher nicht damit, wie das Modell selbst quantisiert wurde. Sie wirkt in einem anderen Teil der Inferenz-Pipeline.
      Zusätzliche Arbeit ist für die Integration in spezielle Inferenz-Engines mit eigener KV-Cache-Verarbeitung nötig, etwa vLLM oder TensorRT-LLM. Jede müsste asymmetrische KV-Präzision separat implementieren.
      Der unmittelbarste Nutzen auf GPUs dürfte vermutlich daraus entstehen, diese Erkenntnis direkt in FlashAttention-Implementierungen zu integrieren. Auf CUDA-Hardware können Einsparungen bei der Speicherbandbreite zu größeren Geschwindigkeitsgewinnen führen.
  • Ist eine Perplexity von +0,86 % bei kleiner Kontextgröße nicht ziemlich viel? Wie sieht es bei realistischeren Kontextgrößen wie 64–128K aus?

    • Der Kern scheint darin zu liegen, die Speichernutzung zu reduzieren. Dadurch kann man bei demselben begrenzten Speicher längere Kontexte ausführen, die vorher nicht möglich waren.
      Oder man kann den freien Speicher für andere Zwecke wie eine IDE nutzen.