15 Punkte von GN⁺ 2026-02-23 | 1 Kommentare | Auf WhatsApp teilen
  • C++/CUDA-basierte LLM-Inferenz-Engine, die dank GPU-Speicher-Streaming und direktem NVMe-I/O das Llama-70B-Modell auf einer RTX 3090 (24 GB VRAM) ausführen kann
  • Nutzt eine 3-stufige adaptive Caching-Struktur, die VRAM, fixierten RAM und NVMe/mmap automatisch aufteilt, und erreicht dabei bis zu 83-fache Beschleunigung gegenüber mmap
  • Das gpu-nvme-direct-Backend umgeht die CPU vollständig und überträgt Daten direkt von NVMe zur GPU, um die PCIe-Bandbreite maximal auszunutzen
  • Mit Layer Skip und Self-Speculative Decoding werden unnötige Berechnungen reduziert und die Verarbeitung ohne Qualitätsverlust beschleunigt
  • Ermöglicht den effizienten Betrieb sehr großer Modelle auf Consumer-Hardware und zeigt damit Potenzial für eine breitere Zugänglichkeit hochperformanter LLM-Inferenz

Überblick über NTransformer

  • Hocheffiziente C++/CUDA-LLM-Inferenz-Engine, die das Llama-70B-Modell auf einer RTX 3090 (24 GB VRAM) ausführt
    • Streamt Modell-Layer über den GPU-Speicher und nutzt optional direktes NVMe-I/O, um die CPU vollständig zu umgehen
  • Keine externen Abhängigkeiten außer dem CUDA Toolkit, PyTorch oder cuBLAS werden nicht benötigt
  • Unterstützt das GGUF-Modellformat und die Quantisierungsformate Q4_0, Q8_0, Q4_K_M, Q5_K, Q6_K, F16 und F32

Leistung und Caching-Struktur

  • 3-stufiges adaptives Caching (3-Tier Adaptive Caching)
    • In VRAM residente Layer (0 I/O)
    • Fixierter RAM (nur für H2D-Transfers)
    • NVMe/mmap-Fallback
  • In einer Umgebung mit RTX 3090 + 48 GB RAM 83-fache Beschleunigung gegenüber mmap
  • PCIe-Gen3-x8-Bandbreite (ca. 6,5 GB/s) wirkt als Flaschenhals
  • Die Q4_K_M-Quantisierung lädt 10 zusätzliche Layer in den VRAM (36 vs. 26) und reduziert so das Transfervolumen
  • Layer Skip (auf Basis der Kosinus-Ähnlichkeit) überspringt 20 von 80 Layern bei minimalem Qualitätsverlust

Hauptfunktionen

  • SLEP-Streaming: Überlappt NVMe-Lesen, PCIe-DMA und GPU-Berechnung mit Double Buffering
  • gpu-nvme-direct-Backend: Liest NVMe-Daten direkt in für die GPU zugänglichen fixierten Speicher
  • Self-Speculative Decoding: Nutzt im VRAM residente Layer als Draft-Modell, ohne zusätzliches Modell
  • Automatische Auswahl des Datenpfads: VRAM-resident > fixierter RAM H2D > mmap fixiert > CPU memcpy
  • Unterstützung der Llama-Architektur: einschließlich RoPE, GQA, SwiGLU, RMSNorm und KV-Cache

Systemanforderungen

  • Linux (Ubuntu, Kernel 6.17+), CUDA Toolkit 13.1, gcc/g++ 14, CMake 3.24+
  • GPU mit Compute Capability 8.0+ (RTX 3090 getestet)
  • Für direktes NVMe-I/O werden eine NVMe-SSD in einem separaten PCIe-Slot sowie die gpu-nvme-direct-Bibliothek benötigt

Direktes NVMe-Streaming

  • Wenn das Modell nicht in den VRAM passt, wird die CPU durch einen direkten Pfad NVMe → GPU vollständig ausgeschlossen
    • Datenfluss: NVMe-SSD → DMA → fixierter Staging-Speicher → PCIe H2D → GPU-Puffer → Berechnung
  • NVMe wird an VFIO gebunden, um direkt aus dem User Space darauf zuzugreifen
  • Jeder Layer (bei 70B Q6_K etwa 670 MB) wird mit rund 670 NVMe-Befehlen in etwa 202 ms gelesen
  • NVMe-Lesen, H2D-DMA und GPU-Berechnung werden in einer Double-Buffer-Pipeline parallelisiert

Systemeinrichtung und Risikohinweise

  • Das automatische Setup-Skript (setup_system.sh) konfiguriert nacheinander GRUB, NVIDIA DKMS, CUDA-Header, VFIO und NVMe-Bindung
  • Enthält Hochrisiko-Operationen wie das Deaktivieren von IOMMU, Kernel-Modul-Patches und NVMe-VFIO-Bindung
  • Bei falscher Konfiguration sind Boot-Fehler, NVMe-Datenverlust und Systeminstabilität möglich
  • Das Boot-Laufwerk darf auf keinen Fall verwendet werden, ein separates dediziertes NVMe-Gerät ist erforderlich
  • Für alle Änderungen werden Backup- und Restore-Skripte bereitgestellt

Architektur und Codestruktur

  • Wichtige Bestandteile im Verzeichnis src/
    • core/: Tensoren, Speicherallokation, GPU-Geräteverwaltung
    • cuda/: GEMV-, RMSNorm-, RoPE-, SwiGLU- und Softmax-Kernel
    • memory/: NVMe- und mmap-basierte SLEP-Streaming-Engine
    • model/: Transformer-Aufbau, GGUF-Loader, Attention, FFN, Normalisierung
    • inference/: Tokenizer, Sampler, Engine
  • scripts/: Enthält Skripte für Systemeinrichtung, NVMe-Bindung und Wiederherstellung

Roadmap der Entwicklungsphasen

  • Phase 1: Llama 8B Q8_0, benutzerdefinierte CUDA-Kernel, 48,9 tok/s (abgeschlossen)
  • Phase 2: SLEP-Streaming, Ausführung von 70B auf einer einzelnen GPU, 33-fache Beschleunigung (abgeschlossen)
  • Phase 3: Unterstützung für Q4_K_M/Q5_K, Layer Skip, Self-Speculative Decoding, F16-KV-Cache (abgeschlossen)
  • Phase 4: NVMe-Direct-Backend, GPU-gesteuertes NVMe-Lesen mit 3,35 GB/s (abgeschlossen)
  • Phase 5: Inferenzoptimierung und öffentliche C-API (geplant)

Lizenz

  • Veröffentlicht unter der BSD-2-Clause-Lizenz

1 Kommentare

 
GN⁺ 2026-02-23
Hacker-News-Kommentare
  • Ich finde den Ansatz, direkt von NVMe zur GPU zu übertragen und dabei die CPU zu umgehen, wirklich clever
    Wenn man große Modelle lokal ausführt, war der Flaschenhals immer die Speicherhierarchie, und hier wird NVMe per DMA quasi wie erweiterter VRAM direkt genutzt
    Ich frage mich, wie sich das im Vergleich zum Ansatz mit Unified Memory der Apple-M-Serie verhält. Ein M4 Max kann ein 70B-Modell vollständig in den Speicher laden, hat aber einen geringeren Durchsatz als eine 3090
    Ein Benchmark, der die native Leistung einer 3090 mit NVMe-Ansatz und eines M4 Max bei Batch-Inferenz vergleicht, wäre interessant

    • Ich habe einen M3 und werde das wohl mit Metal testen
  • Mit GPUDirect sind direkte DMA-Transfers zu Speichergeräten möglich
    Ich habe mich gefragt, was wäre, wenn m.2-Speicher in Wirklichkeit DRAM wäre. Wenn die GPU Modellteile auslagert, braucht man keine Persistenz, also könnte der System-RAM für die CPU frei bleiben

    • Mit einer RAM-Disk wäre das wahrscheinlich viel besser. Schade, dass sich Intel Optane nicht als Standard durchgesetzt hat. Für solche Workflows war das genau die richtige Technologie
    • Daran musste ich auch denken. Ich habe einmal auf dem Dask Summit einen Vortrag über dask-cudf gehalten, bei dem die Log-Analyse über ein Setup aus parallelem SSD-Array → GPUDirect Storage → PCIe → A100-GPU beschleunigt wurde. Es wäre spannend, so etwas jetzt auf LLMs oder MoE-Modelle anzuwenden
    • Tatsächlich gibt es DRAM-basierten m.2-Speicher bereits in Form von CXL (Compute Express Link). Das Problem ist nur, dass RAM zu teuer ist, um die Bandbreite von 31 GB/s pro NVMe-Anschluss sinnvoll auszunutzen
  • Eine Geschwindigkeit von 0,2 Token pro Sekunde ist für Chat zu langsam, aber für Batch-/asynchrone Jobs ausreichend
    Ich betreibe eine Pipeline zur automatischen Content-Erzeugung und führe mehrere LLM-Aufrufe gleichzeitig aus. Die Bildgenerierung ist der Flaschenhals, daher dauert der gesamte Job ohnehin etwa 20 Minuten
    Wenn man ein 70B-Modell lokal ausführen kann, spart man API-Token-Kosten, was eine erhebliche Kostensenkung wäre

    • Kostenseitig ist das nicht effizient. Bei 0,5 tok/s sind das 3600 Token pro Stunde, und ein 3090-System verbraucht 200–300 W. Wenn man dieselbe Token-Menge über OpenRouter mit llama 3.1 laufen lässt, ist das deutlich günstiger als der Strompreis. Für datenschutzsensitive Inferenz ist es trotzdem sinnvoll
    • Man sollte auch die Stromkosten berücksichtigen, wenn eine 3090 über längere Zeit mit 350 W läuft
  • 0,2 tok/s ist für Experimente okay, aber für interaktive Nutzung reicht das nicht
    In den meisten Fällen bieten gut quantisierte 8B- oder 13B-Modelle ein besseres Latenz-Qualitäts-Verhältnis

    • Ich wollte einfach ausprobieren, ob es möglich ist. Früher habe ich auf einer PS2 mit einem klassischen Transformer 3000 Token pro Sekunde erreicht, dank einer Architektur, die Befehle direkt vom Speicher an die GPU sendet. Normale PCs sind langsamer, weil sie über die CPU gehen müssen. Professionelle GPUs lösen dieses Problem, sind aber zu teuer
    • Trotzdem gibt es Situationen, in denen die Qualität großer Modelle wichtiger ist
    • Es ist schneller, das Ganze mit einer CPU+GPU-Kombination laufen zu lassen. Ich komme mit einem 7950X+3090-System auf etwa 1,5 tok/s
    • Erst nachdem ich die Leistungstabelle gesehen hatte, habe ich verstanden, dass der oberste Eintrag ein 8B-Modell ist. 5 Sekunden pro Token ist viel zu langsam. Mein 5950X+128GB-RAM-System wäre mit CPU plus 3060-GPU vermutlich schneller. Auch die Behauptung, dass bei einer 3090 2 Sekunden pro Token die Rechengrenze seien, überzeugt mich nicht wirklich
  • Wirklich ein interessantes Experiment. So etwas hätte ich auch früher ausprobieren sollen
    Mich interessieren die tatsächlichen Durchsatzwerte im Verhältnis zur theoretischen PCIe-Bandbreite. Ich würde gern wissen, ob das ein Latenz- oder ein Bandbreitenproblem ist

    • In der Praxis ist es ein Bandbreiten-Flaschenhals. Mein B450-Mainboard unterstützt nur PCIe 3 x8, dadurch wird die GPU ausgebremst. Mit einem Upgrade auf X570 könnte es vermutlich 2- bis 3-mal schneller werden
  • Cooler Hack, aber 0,5 tok/s bei einem 70B-Modell ist langsam im Vergleich dazu, dass dieselbe Karte bei einem 7B-Modell 30+ tok/s schafft
    Laut NVIDIA-Forschung lassen sich 40–70 % der Agentenaufgaben bereits mit Modellen unter 10B abdecken, und die Qualitätslücke schrumpft schnell

  • In diesem Bereich lohnt sich weiteres Experimentieren auf jeden Fall
    Langfristig wird vermutlich die Modelloptimierung entscheidend sein, also Forschung dazu, welche Teile eines Modells man weglassen kann, ohne die Leistung zu beeinträchtigen. Letztlich ist ein Modell auch eine Art verlustbehaftete Kompression. Diese Richtung hilft auch bei der Demokratisierung von KI

    • Die Kompressionsmetapher ist interessant. Man kann auch Fine-Tuning ähnlich betrachten. Wenn man zum Beispiel ein 3B-Modell für eine bestimmte Aufgabe tuned, braucht man die Allgemeinheit eines 70B-Modells nicht mehr
  • Wirklich ein tolles Projekt. Ich frage mich, welches System-/Hardware-Hintergrundwissen man braucht, um auf solche Ideen zu kommen
    Ich arbeite in einer Umgebung, in der Hardware stark abstrahiert ist, daher fällt es mir schwer, überhaupt an solche Ansätze zu denken. Dafür braucht man wohl nicht nur Kreativität, sondern auch Systemverständnis

    • Genau dieses Experiment ist das hier: ps2-llm-Projekt
      Ich wollte ein LLM auf der PS2 laufen lassen, bin aber an den Grenzen von 32 MB RAM und 4 MB VRAM gescheitert und habe deshalb Layer-Streaming entwickelt. Die PS2 konnte 32-Bit-Adressen im VRAM direkt verarbeiten und war dadurch sehr schnell, und ich wollte das auf dem PC nachbilden
    • Ich denke ähnlich. Bei alten Konsolen war die CPU langsam, deshalb waren DMA-Transfers entscheidend. Vermutlich führte genau diese Erfahrung zu solchen Ideen. Auch die Smart Memory Card der PS2 hatte ziemlich komplexe DMA-Funktionen
  • Ich versuche gerade etwas Ähnliches. Ich experimentiere damit, ein 1T-Modell mit weniger als der Hälfte des VRAM auszuführen
    Ich denke, man könnte durch Modifikation der Routing-Layer von SGLang Expert-Swapping auf Basis von JIT-Vorhersagen von Gen5-NVMe in den GPU-Speicher implementieren. Dabei würde ich NVIDIA Dynamo und NIXL-Primitiven nutzen
    Mich würde interessieren, ob das schon jemand versucht hat

    • Das würde ich auch gern sehen. Ich denke darüber nach, noch eine 3090 zu kaufen und das Mainboard aufzurüsten, um den PCIe-3-Flaschenhals zu beseitigen. Dann könnte man glm 4.7~5 wohl mit q4_k_m ausführen
  • Tolles Projekt. Ich würde gern mehr über den DKMS-Patch-Prozess auf Consumer-GPUs erfahren. Ich würde das selbst gern ausprobieren

    • Ich habe die Dokumentation aktualisiert und den Patch-Prozess sowie Hinweise zu Risiken ergänzt
    • Es gab auch Fälle, in denen der Open-Source-Treiber von NVIDIA modifiziert wurde, um Enterprise-Funktionen wie P2P-GPU-Kommunikation oder vGPU-Partitionierung freizuschalten
      Relevante Links: RTX4090 P2P Unlock, vGPU Unlock