3 Punkte von GN⁺ 2026-03-25 | 1 Kommentare | Auf WhatsApp teilen
  • 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 10 empfohlen

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/tags Liste der geladenen Modelle
    GET /api/version Server-Version
    POST /api/show Modell-Metadaten
    POST /api/generate Texterzeugung
    POST /api/chat Dialogbasierte Erzeugung
  • Für die OpenClaw-Integration wird in ~/.openclaw/openclaw.json die 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 Bibliothek
    • hypura-sys: llama.cpp-FFI-Bindings (CMake-Build)
  • Wichtige Module
    Modul Rolle
    scheduler/placement.rs Optimierung der Tensor-Platzierung zwischen GPU/RAM/NVMe
    compute/inference.rs Inferenz-Engine sowie Lade-/Erzeugungsfunktionen für den Server
    compute/nvme_backend.rs NVMe-Streaming, Neuron Cache, Evaluierungs-Callbacks
    server/routes.rs Ollama-kompatible HTTP-Handler
    profiler/ Hardware-Profiling
    cli/bench.rs Benchmark-Tool
    model/tensor_role.rs Klassifizierung 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 --baseline wird blockiert, wenn das Modell die RAM-Grenze (–4 GB Reserve) überschreitet
  • Nicht verifizierte Modelle mit --max-tokens 10 testen
  • 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

 
GN⁺ 2026-03-25
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

    • Danke fürs Teilen. Falls du bereit bist, Benchmarks direkt mit Hypura durchzuführen, würde ich die Ergebnisse in die Statistiken übernehmen. Andernfalls setze ich es auf meine To-do-Liste.
    • Simon, etwas anderes, aber deine Seite war kurzzeitig down.
      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.
    • Schade, dass im Kimi-Beispiel die Token-Geschwindigkeit (Metrik) fehlt.
  • 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.

    • Auf einem M1 Max liegt 4K-Zufallslesen (QD=1) bei ungefähr 65 MB/s.
    • Stimme zu. Das ist eher ein POC (Proof of Concept) als etwas Praktisches.
      Bei kleinen MoE-Modellen kann man aber mehrere Tokens pro Sekunde erzeugen, sodass es tatsächlich nutzbar ist.
    • Der Kern von MoE ist sparse activation.
      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.

    • Das war eher als Hinweis auf die Möglichkeit gemeint. In der Praxis ist die Leistung aber zu langsam, um außer für spezielle Langzeitaufgaben sinnvoll zu sein.
      Realistisch sind eher kleinere Modelle aus der MoE-Familie, die mehrere Tokens pro Sekunde erzeugen können.
    • Der Titel wirkt etwas übertrieben. Am Ende ist Geschwindigkeit entscheidend, und dazu gibt es keine Informationen.
  • 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.

    • Auch Memristor sah vor zehn Jahren so aus, als stünde die Kommerzialisierung kurz bevor, und ist inzwischen völlig verschwunden.
    • Ich habe tatsächlich noch vier neue Optanes eingelagert. Klingt wie ein Witz, ist aber wahr.
      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.
    • Dass Intel etwas Gutes baut und es dann mittendrin aufgibt, ist inzwischen nichts Neues mehr.
      Trotzdem könnte man mit vier Stück in RAID 0 wohl die Bandbreite von PCIe 16x vollständig ausreizen.
    • Erwähnung von pmem
  • 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.

    • Die Formulierung „NVMe belasten“ wirkt auf mich ungewohnt.
      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.

    • Der betreffende Code wurde von einem LLM geschrieben, daher ist seine Zuverlässigkeit gering.
    • Außerdem verwendet diese Implementierung keine starke Quantisierung (quantization), sodass der Qualitätsverlust geringer ist.