- C/Metal-basierte Inferenz-Engine, die ein Mixture-of-Experts-Modell mit 397B Parametern auf einem MacBook Pro (48 GB RAM) mit mehr als 4,4 Tokens pro Sekunde ausführt
- Streamt das vollständige 209-GB-Modell von der SSD und ist nur mit C und Metal Shadern implementiert, ohne Python oder Frameworks
- Maximiert die parallele Effizienz von GPU, SSD und CPU mit SSD Expert Streaming, FMA-optimierten Kernels und Deferred GPU Compute
- Die 4-Bit-Quantisierungskonfiguration bietet ein Gleichgewicht aus Qualität und Geschwindigkeit und erzeugt produktionsreife Ausgaben einschließlich Tool-Calling-Funktionalität
- Ein Beispiel für Leichtbau und Optimierung, das Echtzeit-Inferenz extrem großer MoE-Modelle auch in einer Notebook-Umgebung ermöglicht
Leistungsergebnisse
- In der Konfiguration mit 4-Bit-Experten (FMA-Kernel) werden 4,36 tok/s erreicht, mit hoher Qualität und einer gesamten Plattennutzung von 209 GB
- Die 4-Bit-Basiskonfiguration erreicht 3,90 tok/s und entspricht dem Stand vor der FMA-Optimierung
- Die Konfiguration mit 2-Bit-Experten (trust OS) erreicht 5,74 tok/s und ist schneller, kann aber wegen JSON-Ausgabefehlern kein Tool Calling nutzen
- 2-Bit Spitzenleistung bei einem einzelnen Token erreicht bis zu 7,05 tok/s, ist jedoch für den praktischen Einsatz ungeeignet
- 4-Bit-Quantisierung ist die für den realen Betrieb geeignete Konfiguration
Hardware-Umgebung
- MacBook Pro (Apple M3 Max), 16-Core-CPU (12P+4E), 40-Core-GPU, 16-Core-ANE
- 48 GB Unified Memory, Bandbreite etwa 400 GB/s
- SSD: 1 TB Apple Fabric, 17,5 GB/s sequentielle Lesegeschwindigkeit
- Umgebung: macOS 26.2 (Darwin 25.2.0)
Modellarchitektur
- Insgesamt 60 Transformer-Layer: 45 GatedDeltaNet (lineare Attention) + 15 Full Attention
- Jeder Layer hat 512 Experten, von denen K=4 pro Token aktiviert werden (einschließlich 1 Shared Expert)
- Hidden Dimension 4096
-
Schlüsseltechnologien
-
SSD Expert Streaming
- Lädt Expertengewichte (209 GB bei 4-Bit) bei Bedarf per parallelisiertem
pread() von der NVMe-SSD
- Pro Layer werden nur die 4 aktivierten Experten geladen (jeweils etwa 6,75 MB)
- Der OS Page Cache verwaltet das Caching automatisch, ein separater Cache ist nicht nötig
- Architektur inspiriert von Apples Paper „LLM in a Flash“
-
FMA-optimierter Dequant-Kernel
- Ordnet die Berechnung
(nibble * scale + bias) * x in die Form fma(nibble, scale*x, bias*x) um
scale*x und bias*x werden vorab berechnet, sodass die GPU-FMA-Einheiten dies mit einem einzigen Befehl ausführen
- 12 % Geschwindigkeitsgewinn gegenüber einer einfachen Implementierung
-
Metal Compute Shaders
- 4-Bit/2-Bit-Dequant Matrix-Vektor-Multiplikation, SwiGLU-Aktivierung, RMS-Normalisierung, GPU-Attention (
Q@Kᵀ, softmax, scores@V), RoPE sowie MoE-Kombination + Residual + Gate sind als handgeschriebene Metal-Kernels implementiert
-
Deferred GPU Expert Compute
- Reicht CMD3-Befehle (Experten-Forward-Pass) asynchron ein, damit die CPU den nächsten Layer vorbereitet, während die GPU arbeitet
- Auch Kombination + Normalisierung + Residual werden auf der GPU ausgeführt und direkt an den nächsten Layer übergeben
-
Nutzung von Accelerate BLAS
- Verwendet
cblas_sscal, cblas_sgemv, cblas_sger für rekursive Berechnungen in GatedDeltaNet
- 64 % schneller als skalarer Code
-
Trust the OS
- Entfernt benutzerdefinierte Caches; der OS Page Cache (LRU-basiert, etwa 35 GB) übernimmt das Caching der Expertendaten
- Langsamer als ein eigener Metal-LRU-,
malloc- oder LZ4-komprimierter Cache
- Erreicht eine natürliche Cache-Trefferquote von 71 %
-
Einschränkungen durch Unified Memory
- Auf Apple Silicon teilen sich SSD-DMA und GPU-Berechnungen denselben Speichercontroller
- Bei paralleler Ausführung steigt die Latenz stark an, wenn die GPU-Bandbreite gesättigt ist
- Eine sequentielle Pipeline GPU → SSD → GPU ist die hardwareoptimale Form
1 Kommentare
Hacker-News-Kommentare
Es gibt noch eine andere Möglichkeit, Qwen 3.5 397B sogar auf Consumer-Geräten auszuführen
Es gibt eine etwa 2,5-BPW-Quantisierung (quant), die selbst auf Geräten mit 128 GB Speicher gut machbar ist
Ich habe das auf einem M1 Ultra mit rund 20 tok/s und bei beibehaltenem 256k-Kontext problemlos laufen lassen
Die lm-evaluation-harness-Ergebnisse lagen bei etwa mmlu 87,86 %, gpqa diamond 82,32 %, gsm8k 86,43 % und ifeval 75,90 %
Meine ausführlichen Erfahrungen habe ich im Hugging-Face-Diskussionslink 1 und Link 2 zusammengefasst
Es ist ein hervorragendes Modell für Offline-Inferenz
Die Zahl der Experten pro Token wurde von 10 auf 4 reduziert, wodurch die Qualität weiter sinkt
Für kurze Prompts ist das okay, für lange Sessions aber unbrauchbar
Es gibt auch das Problem, dass bei JSON-Ausgaben statt
"name"\name\erzeugt wird, wodurch Tool-Calling instabil wirdIch würde auch gern wissen, ob es mit langem Kontext noch gut funktioniert
Und es ist schön, den Nickname mal wieder zu sehen — der Entwickler von Neovim, was für ein großartiger Erfolg
Ich nutze es auch jeden Tag
Vielleicht lässt sich das mit CoconutBattery abschätzen
Wenn man sich die Details ansieht, scheint man durch 2-Bit-Quantisierung und die Reduktion der Expertenzahl von 10 auf 4 auf etwa 5 tok/s zu kommen
Ein interessantes Proof of Concept, aber weit entfernt von der Qualität des ursprünglichen 397B-Modells
Solche extremen Optimierungen führen zu einem Verlust an Intelligenz des Modells
Es gibt auch das Problem, dass bei JSON-Ausgaben statt
"name"\name\erzeugt wird, wodurch es für den Praxiseinsatz ungeeignet istIch erkenne an, dass dieser Versuch zeigt, was technisch möglich ist, aber tatsächlich nutzbar ist das nicht
Ich bin inzwischen müde von all diesen AI-geschriebenen Papers
Aber ich habe gehört, dass selbst kommerzielle LLMs bei der Genauigkeit von Tool-Calling schwach sind
Vermutlich ist das schwer umzusetzen oder strukturell gar nicht möglich
Auch im r/LocalLLaMA-Thread gab es dazu eine Diskussion
Laut der GitHub-Seite wird ein simples mmap durch Overhead auf Seitenebene zum Flaschenhals
Ich frage mich, ob man das unter macOS durch huge pages oder Prefetching mit
posix_fadviseverbessern könnteDer Qualitätsverlust bei 2-Bit-Quantisierung ist tatsächlich ein ernstes Problem
In realen Aufgaben habe ich die Erfahrung gemacht, dass ein gut abgestimmtes 30B-4-bit-Modell besser ist als ein 70B+-2-bit-Modell
Wenn man die Zahl der Experten reduziert, ist es faktisch ein anderes Modell
Trotzdem ist es interessant, die Grenzen von Consumer-Hardware auszuloten
Es ist ermüdend, wenn „läuft auf einem Laptop“ jedes Mal ein MacBook für 3000 Dollar bedeutet
Die Kompressionstechniken sind beeindruckend, aber für normale Nutzer ist das keine realistische Option
Aber ich würde beim Lesen des Titels nicht erwarten, dass es auf jedem beliebigen Laptop läuft
Statt übertrieben zynisch zu sein, freue ich mich eher an solchen Experimenten
Viele besitzen solche leistungsstarken MacBooks bereits für Videobearbeitung und Ähnliches
Der Vorteil ist, dass man ohne zusätzliche Hardware direkt auf dem vorhandenen Laptop experimentieren kann
Das lief mit etwa 20 tok/s, und ich halte das auch für Privatpersonen für ausreichend zugänglich
Auch beruflich war die Investition lohnend
„No Python. No frameworks. Just C, Objective-C, and hand-tuned Metal shaders.”
Als ich diesen Satz gelesen habe, war mir sofort klar, woher die Tokens kamen
Da ist von „Hand-written Metal kernels“ die Rede — ob die vielleicht direkt von GPT geschrieben wurden? 😉
Wirklich beeindruckendes Ergebnis
Ich frage mich, ob unter Linux ein ähnlicher Ansatz möglich wäre, bei dem statt SSD systemspeicherbasierter Zugriff genutzt wird
Oder auch die Idee, Gewichte in Form von ROM zu speichern, klingt interessant
Dieses Projekt ist nur deshalb auf macOS beschränkt, weil es Metal verwendet
Aber bei MoE-Modellen gibt es weiterhin starke Bandbreitenbeschränkungen
Allerdings ist in der Decoding-Phase der CPU-Transfer-Overhead höher als auf der GPU, sodass der Nutzen gering ist
Es ist effizienter, die GPU nur zur Beschleunigung der gemeinsam genutzten Teile zu verwenden
Aber sobald das Modell in den System-RAM oder auf die Festplatte ausweicht, bricht die Leistung stark ein
Es wurde erklärt, dass die SSD der Flaschenhals sei, aber der Autor sagt, er habe 15 GB/s erreicht
Soweit ich weiß, liegt die maximale Bandbreite eher bei 8 GB/s. Was übersehe ich?
Sobald das Router-Ergebnis vorliegt, werden Experten von der SSD geladen, und in diesem Moment wird die SSD ausgelastet
Die durchschnittliche IO liegt bei etwa 2970 MB/s und damit deutlich unter dem SSD-Limit
Wenn man einige Tensoren mit asynchronen Lesevorgängen parallelisiert, könnte es noch besser werden
Ich habe unter Linux mit io_uring experimentiert und dabei gesehen, dass etwa 20 % der Lesevorgänge parallel zur Berechnung abgeschlossen wurden