- Optimiert die Tensor-Platzierung zwischen GPU, RAM und NVMe und führt große Sprachmodelle mit einem speicherhierarchiebewussten Inferenz-Scheduler aus
- Auf einem Mac mini mit 32 GB können das Modell Mixtral 8x7B (31 GB) mit 2,2 tok/s und das Modell Llama 70B (40 GB) mit 0,3 tok/s ausgeführt werden
- Analysiert Zugriffsmuster und Hardware-Bandbreite, um auch Modelle stabil auszuführen, die den physischen Speicher überschreiten; selbst Modelle, bei denen bestehendes llama.cpp wegen OOM scheitert, können verarbeitet werden
- Reduziert I/O durch Experten-Routing in MoE-Strukturen, Neuron Cache und Prefetching um bis zu 75 % und erreicht eine Cache-Trefferrate von 99,5 %
- Wählt je nach Modellgröße und Hardware automatisch die Modi Full-resident, Expert-streaming und Dense FFN-streaming, um die optimale Leistung zu halten
- Bietet eine Ollama-kompatible HTTP-API für die Anbindung an OpenClaw und andere Tools und nutzt SSDs nur lesend, sodass NVMe-basierte Inferenz ohne Verschleißnachteile unterstützt wird
Überblick
- Hypura ist ein speicherhierarchiebewusster LLM-Inferenz-Scheduler für Apple-Silicon-Umgebungen und ein Tool zur Optimierung der Tensor-Platzierung zwischen GPU, RAM und NVMe
- Basierend auf Zugriffsmustern, Bandbreitenkosten und Hardware-Leistung verteilt es Tensoren so, dass auch große Modelle, die den physischen Speicher überschreiten, stabil ausgeführt werden können
- Auf einem Mac Mini mit 32 GB können das Modell Mixtral 8x7B (31 GB) mit 2,2 tok/s und das Modell Llama 70B (40 GB) mit 0,3 tok/s ausgeführt werden
- In derselben Umgebung lässt sich llama.cpp wegen OOM (Out of Memory) nicht ausführen
Problemhintergrund
- Consumer-Macs verfügen über schnellen Unified Memory und NVMe-Speicher, die Speicherkapazität ist jedoch begrenzt
- Ein 32-GB-M1-Max kann beispielsweise ein 40-GB-Modell nicht direkt laden, wodurch übermäßiges Swapping und OOM-Abbrüche auftreten
- Hypura löst dieses Problem, indem es die Modellstruktur analysiert und eine optimale Platzierung pro Ebene durchführt
Hierarchische Platzierung auf Basis der Modellstruktur
- Norms und Embeddings: klein, aber bei jedem Token zugänglich, daher fest auf der GPU
- MoE Expert Routing: nutzt Sparsity, pro Token werden nur 2 von 8 Experten aktiviert
- Über Router-Interception werden die aktiven Experten identifiziert und nur die benötigten Teile von NVMe geladen
- 75 % weniger I/O und 99,5 % Trefferquote im Neuron Cache
- Mit Co-Activation Tracking werden die nächsten aktiven Experten vorhergesagt und vorab per Prefetch geladen
- Dense-FFN-Gewichte: machen rund 60 % der Modellgröße aus
- Werden per dynamischem Pool-Buffer von NVMe gestreamt
- Die Prefetch-Lookahead-Tiefe wird automatisch an den verfügbaren Speicher angepasst
- Dadurch können auch Modelle ausgeführt werden, die mit herkömmlichem mmap-Ansatz abstürzen würden; Modelle, die in den Speicher passen, laufen ohne Overhead mit Metal-GPU-Geschwindigkeit
Funktionsweise
- Hypura liest GGUF-Dateien und profiliert die Bandbreite von GPU, RAM und NVMe
- Jeder Tensor wird einer der folgenden drei Ebenen zugewiesen
- GPU (Metal): Attention-, Norm- und Embedding-Ebenen
- RAM: Overflow-Ebenen, die nicht auf die GPU passen
- NVMe: übrige Ebenen, mit direktem I/O über
F_NOCACHE+pread
- Je nach Modellgröße und Hardware wird automatisch ein Inferenzmodus gewählt
- Full-resident: gesamtes Modell in GPU+RAM, kein NVMe-I/O
- Expert-streaming: für MoE-Modelle, nur Nicht-Experten-Tensoren verbleiben auf der GPU, Experten-Tensoren werden von NVMe gestreamt
- Dense FFN-streaming: für große Nicht-MoE-Modelle, Attention+Norm auf der GPU, FFN per NVMe-Streaming
- Pool-Buffer-Größe, Prefetch-Tiefe und Speicherbudget werden automatisch anhand des Hardware-Profils berechnet
Leistung
- Testumgebung: M1 Max, 32 GB Unified Memory, NVMe 5,1 GB/s
- Wichtige Benchmark-Ergebnisse
- Qwen 2.5 14B Q4_K_M (8,4 GB): vollständig auf die GPU geladen, 21 tok/s
- Mixtral 8x7B Q5_K_M (30,9 GB): Expert-streaming-Modus, 2,2 tok/s, 99,5 % Cache-Trefferrate
- Llama 3.3 70B Q4_K_M (39,6 GB): Dense-FFN-streaming-Modus, 0,3 tok/s, Pool mit 24 Slots, Prefetch über 7 Ebenen
- Modelle, die in den Speicher passen, haben 0 Overhead; größere Modelle bleiben dank Hypura lauffähig
Installation und Ausführung
- Rust 1.75+ und CMake erforderlich
- Installationsschritte
git clone --recurse-submodules https://github.com/hypura/hypura.git cd hypura cargo build --release - Ausführungsbeispiele
hypura profile hypura run ./model.gguf --prompt "Hello, world" hypura run ./model.gguf --interactive hypura bench ./model.gguf hypura inspect ./model.gguf - Für nicht verifizierte Modelle wird ein Test mit
--max-tokens 10empfohlen
Ollama-kompatibler Server
- Hypura bietet eine Ollama-kompatible HTTP-API und ist vollständig kompatibel mit Ollama-basierten Tools wie OpenClaw
hypura serve ./model.gguf Endpoint: http://127.0.0.1:8080 API: /api/generate, /api/chat, /api/tags - Wichtige Endpunkte
Endpoint Funktion GET /Statusprüfung GET /api/tagsListe der geladenen Modelle GET /api/versionServer-Version POST /api/showModell-Metadaten POST /api/generateTexterzeugung POST /api/chatDialogbasierte Erzeugung - Für die OpenClaw-Integration wird in
~/.openclaw/openclaw.jsondie Ollama-Base-URL auf Hypura gesetzt - Server-Optionen
hypura serve [OPTIONS] --host Standardwert 127.0.0.1 --port Standardwert 8080 --context Standardwert 4096
Architektur
- Struktur als Cargo-Workspace mit zwei Crates
hypura: Haupt-Binary und Bibliothekhypura-sys: llama.cpp-FFI-Bindings (CMake-Build)
- Wichtige Module
Modul Rolle scheduler/placement.rsOptimierung der Tensor-Platzierung zwischen GPU/RAM/NVMe compute/inference.rsInferenz-Engine sowie Lade-/Erzeugungsfunktionen für den Server compute/nvme_backend.rsNVMe-Streaming, Neuron Cache, Evaluierungs-Callbacks server/routes.rsOllama-kompatible HTTP-Handler profiler/Hardware-Profiling cli/bench.rsBenchmark-Tool model/tensor_role.rsKlassifizierung von Tensor-Rollen
FAQ
-
Kein Problem mit SSD-Verschleiß
- Hypura liest nur von der SSD, es gibt keine Schreibvorgänge
- NVMe-I/O erfolgt ausschließlich lesend über
pread()+F_NOCACHE - Die SSD dient nur als Cold Storage, die Berechnung läuft in RAM/GPU
- Schreibvorgänge beschränken sich auf geringfügige KB-Mengen wie Benchmark-Ergebnis-JSONs oder Statistikdateien
Sicherheitshinweise
bench --baselinewird blockiert, wenn das Modell die RAM-Grenze (–4 GB Reserve) überschreitet- Nicht verifizierte Modelle mit
--max-tokens 10testen - Testmodelle werden im Verzeichnis
./test-models/gespeichert
Lizenz
- MIT License
Ethischer Hinweis
- Der Code im Repository wurde nicht vollständig vom Autor selbst geschrieben
- Erstellt als Experiment zur promptbasierten Codegenerierung mit LLMs
- Das Projekt dient dazu, die Einsatzmöglichkeiten NVMe-basierter Inferenz zu erforschen
1 Kommentare
Hacker-News-Kommentare
Ich würde den Maintainern gern Folgendes vorschlagen. In der aktuellen Vergleichstabelle stehen veraltete Modelle wie Qwen 2.5 14B, Mixtral 8x7B und Llama 3.3 70B.
In letzter Zeit gibt es viele Berichte, dass Qwen-3.5-MoE-Modelle auf Apple-Hardware eine erstaunliche Leistung zeigen.
Ein Blick auf Simon Willisons Beitrag könnte hilfreich sein.
Wenn möglich, wäre es schön, auch das Modell Kimi K2.5 (1T Parameter) in die Tabelle aufzunehmen.
Relevante Tweets: seikixtc, danpacary
Es erschien eine Heroku-bezogene Fehlermeldung, aber inzwischen funktioniert alles wieder normal.
Ich bin wegen dieses Beitrags vorbeigekommen und habe gesehen, dass du den Beitrag zu litellm auch schon geschrieben hattest. Habe ihn gern gelesen.
Für lokale Arbeit ist selbst eine Geschwindigkeit von unter 1 Token pro Sekunde für Hintergrundaufgaben durchaus brauchbar.
Der Unterschied zwischen „sofortigem Abbruch“ und „über Nacht fertig“ ist immer noch ein sinnvoller Leistungssprung.
In der Praxis ist entscheidend, wie sequentiell (sequential) das Lesemuster tatsächlich ist.
NVMe erreicht bei sequentiellem Lesen 5–7 GB/s, fällt bei zufälligem Lesen aber auf etwa 500 MB/s zurück.
Bei einem 1T-Modell müssten für einen Forward Pass in fp16 2 TB gestreamt werden, was theoretisch mehr als 300 Sekunden pro Token bedeutet.
Für interaktive Nutzung ist das ungeeignet, aber für Batch-Inferenz (batch inference) könnte es Potenzial haben.
Bei kleinen MoE-Modellen kann man aber mehrere Tokens pro Sekunde erzeugen, sodass es tatsächlich nutzbar ist.
Es werden nicht die gesamten 2 TB gelesen, sondern nur auf einige Expert-Layer zugegriffen.
Da jede Schicht einige MiB groß ist, ist auch die Effizienz der NVMe-Zugriffe nicht so schlecht.
Ich habe mich gefragt, woher das „1T-Parameter-Modell“ kommt. Im Repo sehe ich nur Modelle bis 70B.
Realistisch sind eher kleinere Modelle aus der MoE-Familie, die mehrere Tokens pro Sekunde erzeugen können.
Der Punkt bei MoE ist, dass durch sparse activation nicht die gesamten 2 TB gelesen werden.
Allerdings wird das Zugriffsmuster dadurch randomisiert, was für NVMe die schlechtesten Bedingungen schafft.
Bei Aufgaben, bei denen Latenz (latency) wichtig ist, etwa Agent-Inferenz, ist genau das der entscheidende Punkt.
Intel Optane dürfte sich im Grab umdrehen.
In der Praxis sind sie allerdings nicht schneller als NVMe. In Software, die paralleles Lesen/Schreiben unterstützt, ist der Unterschied fast nicht spürbar.
Trotzdem könnte man mit vier Stück in RAID 0 wohl die Bandbreite von PCIe 16x vollständig ausreizen.
Consumer-Mac-Hardware hat schnellen Unified Memory und NVMe, aber die Kapazität ist begrenzt.
Wenn man auf einem 32-GB-M1-Max ein 40-GB-Modell lädt, läuft der Swap aus dem Ruder und endet schließlich im Panic-Zustand.
macOS hat keinen OOM-Killer wie Linux; stattdessen geht einfach der Swap-Speicher aus.
Es ist wichtig, „so viel Speicher wie möglich“ zu haben, aber Bandbreite (bandwidth) ist der noch größere Faktor.
Das M4 Pro hat 273 GB/s, das M4 Max 546 GB/s, das M4 Ultra 819 GB/s.
Sobald das Modell im Speicher liegt, bestimmt die Bandbreite die Token-Geschwindigkeit.
Bei Hypura ist das M4 Max der Sweet Spot. Mit 64 GB kann man ein 70B-Modell (Q4) bequem betreiben und im Vergleich zum Pro mit doppelter Geschwindigkeit generieren.
Dieses Projekt funktioniert im Grunde wie smarter Swap-Speicher.
Interessant ist, dass es den NVMe-Einsatz so steuert, dass er nicht übertrieben wird.
Wenn NVMe in der Praxis jedoch stark belastet wird, besteht die Sorge vor verkürzter Lebensdauer.
Bei SSDs nimmt die Lebensdauer der Zellen zwar mit der Anzahl der Schreibvorgänge ab, aber dass der Controller durch Leselast beschädigt wird, kommt praktisch nicht vor.
Falls doch, liegt ein anderes Problem im System vor.
Es wäre gut, dieses Projekt mit früheren Experimenten und einem weiteren Versuch zu vergleichen.
Bei diesem hier gab es Berichte, dass es wegen der mmap-basierten Umsetzung viel Overhead gibt.