diff --git a/MOJO.md b/MOJO.md new file mode 100644 index 0000000..46aaf78 --- /dev/null +++ b/MOJO.md @@ -0,0 +1,662 @@ +# Rust- und Mojo-Umbauplan für die Inferenz + +Stand: 29. August 2026 + +## Kurzurteil + +Das Ziel ist realistisch, aber nicht als mechanische Übersetzung der `.metal`-Dateien. Realistisch ist eine Architektur, in der Rust weiterhin Modellformat, Ausführungslogik, Tokenverarbeitung, Sessions, Sampling und Checkpoints besitzt, während Mojo den kompletten GPU-Ausführungspfad übernimmt und aus derselben Quellbasis zielabhängige Metal- oder CUDA-Artefakte erzeugt. + +Eine einzige, auf beiden Plattformen identische Modellimplementierung ist erreichbar. Vollständig identische Kernel ohne Hardware-Spezialisierung sind dagegen kein sinnvolles Ziel: Apple-GPUs und NVIDIA Blackwell unterscheiden sich bei Matrixeinheiten, Speicherhierarchie, Synchronisation und optimalen Tile-Größen. Die gemeinsame Mojo-Quelle muss deshalb generische Modellalgorithmen mit kleinen, zur Compile-Zeit gewählten Architektur-Policies kombinieren. Erlaubt sind hardwarespezifische Tiles, MMA-Intrinsics und Launch-Strategien; vermieden werden zwei getrennte Metal- und CUDA-Modellpfade. + +Dass Mojo auf beiden Plattformen nicht langsamer als der jeweilige native Referenzpfad ist, kann vorab nicht garantiert werden. Es ist jedoch ein realistisches Entwicklungsziel, weil Mojo Apple- und NVIDIA-GPUs unterstützt und MAX bereits viele benötigte Attention-, KV-Cache-, MoE-, Quantisierungs- und Matrix-Primitiven enthält. Das größte technische Risiko sind die DS4-spezifischen Quantisierungsformate und die stark fusionierten DeepSeek-/GLM-Kernel. Sie benötigen voraussichtlich eigene Mojo-Kernel und eine iterative Optimierung auf beiden Architekturen. + +Der Umbau darf deshalb nur stufenweise erfolgen. Der bestehende native Metal-Pfad bleibt während der gesamten Migration verfügbar. Auf DGX Spark muss zusätzlich ein reproduzierbarer nativer CUDA-Referenzpfad bereitstehen. Nach der ersten vollständig verifizierten DeepSeek-Implementierung folgt Qwen3.8-27B als zweite Modellstufe. Erst nach bestandener Korrektheits- und Performance-Matrix darf Mojo der Standard werden oder ein Referenzpfad entfernt werden. + +## Nicht verhandelbare Ziele + +1. DS4 bleibt das Verhaltensorakel. Tokenfolge, Tokenverarbeitung, Kontextzählung, KV-Cache-Verhalten, Checkpoint-Semantik und Modellausführung dürfen sich nicht ändern. +2. Das Zielprodukt ist eine Rust- und Mojo-Anwendung. Bestehende native Implementierungen sind während des Umbaus nur Referenz- und Rückfallpfade, nicht die zukünftige Architektur. +3. Eine Mojo-Modellimplementierung muss aus derselben Quelle für Apple Metal und NVIDIA CUDA gebaut werden. Zielabhängige Compile-Time-Spezialisierungen innerhalb dieser Quelle sind ausdrücklich notwendig. +4. Es darf keinen stillen Fallback und keine Mischung von nativen und Mojo-Kerneln in einem Benchmarklauf geben. +5. Korrektheit wird vor Performance geprüft. Ein schnellerer Pfad mit abweichender DS4-Semantik ist nicht akzeptabel. +6. Das Performanceziel lautet auf jeder Hardware separat: Mojo ist bei der End-to-End-Inferenz mindestens so schnell wie der dortige native Referenzpfad. Mac und DGX Spark werden nicht gegeneinander bewertet. +7. Jeder tatsächlich verwendete Inferenzbaustein erhält einen isolierten Korrektheits- und Performancevergleich. Zusätzlich folgt ein vollständiger Modellvergleich beider Pfade. + +## Heutiger Ausgangspunkt + +Der aktuelle Metal-Executor ist bereits an einer grundsätzlich geeigneten Grenze geschnitten: + +- Rust besitzt Modellzustand, Graph-/Ablauflogik, Sessions, Token- und Checkpoint-Verhalten. +- `src/engine/metal.rs` bindet derzeit 19 Metal-Quelldateien ein. +- `src/engine/metal/gpu.rs` deklariert derzeit 117 exportierte GPU-Operationsnamen. +- Die Metal-Quellen umfassen zusammen ungefähr 21.700 Zeilen. Eine Eins-zu-eins-Portierung wäre deshalb teuer und würde Optimierungsentscheidungen der Metal-Implementierung unnötig konservieren. +- `src/engine.rs` enthält bereits einen ignorierten Realmodelltest (`metal_executes_real_flash_token`), der Prompt, Logits, Argmax und Checkpoint-Wiederherstellung abdeckt. Er ist ein guter Ausgangspunkt, ersetzt aber weder Komponentenbenchmarks noch einen Backendvergleich. + +Die bestehende Grenze soll beibehalten, aber gröber genutzt werden: Rust ruft nicht jeden elementaren GPU-Operator einzeln über die Sprachgrenze auf. Mojo soll zusammenhängende Operationen wie `prefill`, `decode_step` und gegebenenfalls `verify` besitzen und die zugehörigen Kernel, Streams/Command-Buffer und temporären Tensoren intern verwalten. Damit werden FFI- und Synchronisationskosten aus dem kritischen Pfad gehalten. + +## Ergebnis der Online-Recherche + +Die folgende Bewertung basiert auf den zum Stichtag verfügbaren offiziellen Modular-Quellen. Vor der Implementierung sind Versionen und APIs erneut zu prüfen und anschließend fest zu pinnen. + +### Plattform und Compiler + +- Mojo nennt NVIDIA-, AMD- und Apple-GPUs als unterstützte Ziele. DGX Spark beziehungsweise `sm_121` und Apple M1 bis M5 werden als bekannte kompatible Ziele geführt. Siehe [Mojo system requirements](https://docs.modular.com/mojo/requirements/). +- Mojo kann GPU-Code zielabhängig für NVIDIA und Apple erzeugen; die Dokumentation beschreibt unter anderem PTX für NVIDIA und Apple-GPU-Ausgabe für Metal. Vollständig gelinkte Cross-Compilation ist weiterhin nicht der verlässlichste Weg. Praktisch werden daher aus derselben Quelle separate Artefakte auf beziehungsweise für jede Zielplattform gebaut. Siehe [Mojo compilation](https://docs.modular.com/mojo/tools/compilation/). +- `DeviceContext` stellt CUDA-, HIP- und Metal-Kontexte bereit. Siehe [GPU fundamentals](https://docs.modular.com/gpu/fundamentals/). + +Damit ist „eine Quelle“ realistisch, „ein universelles Binärartefakt“ aber weder erforderlich noch als Projektziel sinnvoll. + +### Wiederverwendbare Mojo-/MAX-Bausteine + +| Benötigter Bereich | Verfügbarer Stand | Entscheidung für DS4Server | +| --- | --- | --- | +| GPU-Kontext, Layouts, Speicher und Profiling | Die [MAX accelerator library](https://docs.modular.com/stable/api/mojo/) enthält GPU-, Layout-, Linalg-, NN-, Quantisierungs-, KV-Cache- und Benchmark-Pakete. | Verwenden, sofern die gepinnte Version auf beiden Zielsystemen reproduzierbar baut. Keine eigene allgemeine GPU-Laufzeit bauen. | +| Matrixeinheiten | MAX bietet eine einheitliche [MMA-Schnittstelle](https://docs.modular.com/stable/api/mojo/max/gpu/compute/) mit [architekturspezifischen Implementierungen](https://docs.modular.com/api/mojo/max/gpu/compute/arch/), einschließlich Apple-MMA und Blackwell/SM100. | Als Basis nutzen. Tile- und Pipeline-Policies je Architektur zur Compile-Zeit wählen. | +| Attention | Es existieren [Flash-Attention-Kernel](https://docs.modular.com/mojo/kernels/nn/flash_attention/) einschließlich KV-Cache- und Split-KV-Varianten sowie MHA-/MLA-Bausteine im NN-Paket. | Zuerst benchmarken und anpassen. DS4s rohe, komprimierte und indexierte Attention sowie genaue Masken-/Cache-Semantik dürfen nicht als Drop-in-Kompatibilität angenommen werden. | +| KV-Cache | Das [KV-Cache-Paket](https://docs.modular.com/stable/api/mojo/kv_cache/) enthält paged/sparse Cache- und Index-Remapping-Primitiven. | Layout- und Remapping-Code wiederverwenden, wenn Byte-/Index-Semantik, Kontextzählung und Checkpoint-Restore nachweislich identisch bleiben. Das persistente DS4-Checkpointformat bleibt in Rust. | +| Norm, RoPE, Softmax, Top-k und MoE | Die MAX-NN-Kernel decken diese Grundoperationen sowie gruppierte MoE-Pfade ab. | Einzeln gegen die heutigen Operatoren prüfen; nur bei bestandener Parität übernehmen. Modellspezifische Fusionen bleiben wahrscheinlich eigener Mojo-Code. | +| GLM 5.2 | MAX 26.5 nennt explizit `GlmMoeDsaForCausalLM`, GLM-5.2-MTP, Sparse-MLA-/Index-Sharing und GLM-Sparse-Attention-Korrekturen. Siehe [MAX 26.5 release notes](https://docs.modular.com/releases/v26.5/). | Stärkster vorhandener Referenzpunkt. Modell- und Kernelquellen untersuchen und kompatible Bausteine übernehmen; DS4-Semantik nicht durch die MAX-Pipeline ersetzen. | +| Qwen3.8-27B | Die [offizielle Modellkarte](https://huggingface.co/Qwen/Qwen3.8-27B) beschreibt einen dichten 27B-Hybrid aus Gated DeltaNet und voller Attention, MTP, 262.144 nativem Kontext und Vision-Encoder. MAX hat den Qwen3.5-Unterbau einschließlich GPU-GDN-Kerneln und State-Cache bereits umgesetzt; siehe [MAX Linear Attention/GDN tracking](https://github.com/modular/modular/issues/5772). | Als zweite Modellstufe nach dem verifizierten DeepSeek-Basispfad einplanen. Gemeinsame Norm-, Matmul-, FFN-, RoPE-, Attention-, Cache- und MTP-Komponenten wiederverwenden; GDN, Conv-State und Vision klar getrennt ergänzen. | +| DeepSeek | MAX dokumentiert DeepSeek V3/V3.2, MLA, Sparse Attention, MoE und Expert Parallelism. Siehe [DeepSeek-V3 architecture](https://docs.modular.com/api/python/pipelines.architectures.deepseekV3/) und [supported models](https://docs.modular.com/models/). | Als Vorlage für MLA/MoE verwenden. Für die von DS4Server verwendeten DeepSeek-Flash-/Pro-/V4-spezifischen HC-, Kompressor- und Indexerpfade wurde keine komplette fertige Mojo-Engine gefunden. | +| NVIDIA Q4-Matmul | `qmatmul_gpu` enthält NVIDIA-GPU-Kernel für GPTQ-/Q4_0-artige 4-Bit-Matrizen. Siehe [qmatmul_gpu](https://docs.modular.com/mojo/kernels/quantization/qmatmul_gpu/). | Nur für passende Layouts prüfen. Es deckt die DS4-Quantisierungsmatrix nicht vollständig ab. | +| Q4_K | Ein `Q4_KEncoding` existiert, der dokumentierte [`matmul_Q4_K`](https://docs.modular.com/api/mojo/quantization/qmatmul_k/matmul_Q4_K/) ist derzeit jedoch CPU-orientiert und schlägt für andere Ziele beim Kompilieren fehl. | Nicht als vorhandene portable GPU-Lösung einplanen; eigener GPU-Kernel oder neuere offizielle Implementierung erforderlich. | +| IQ2_XXS, Q2_K, Q5_K, Q6_K, Q8_0 und gemischte Expert-Layouts | In den geprüften offiziellen Quellen wurde keine vollständige, direkt nutzbare GPU-Abdeckung für die DS4-Kombination gefunden. | Als kundenspezifische Mojo-Kernel budgetieren. Vor Beginn jeder Phase erneut im Modular-Repository suchen. | +| Benchmark-Hilfen | MAX stellt GPU-Benchmark- und Profiling-Hilfen bereit. | Für reine Kernelzeit verwenden, aber immer mit einem Rust-seitigen End-to-End-Harness und realen Modellmessungen paaren. | + +Der Quellcode der relevanten Pakete liegt im [Modular-Repository](https://github.com/modular/modular), unter anderem für [Flash Attention](https://github.com/modular/modular/blob/main/max/kernels/src/nn/flash_attention.mojo) und [Quantisierung](https://github.com/modular/modular/tree/main/max/kernels/src/quantization). Eine vollständige fertige Mojo-Implementierung der von DS4Server verwendeten DeepSeek-V4-Engine wurde in den geprüften Primärquellen nicht gefunden. Für Qwen3.8-27B existiert noch kein geprüfter DS4Server-Drop-in-Pfad, aber die bereits ausgelieferten MAX-Qwen3.5-/GDN-Komponenten passen zur architektonischen Grundlage von Qwen3.8 und reduzieren das Risiko deutlich. Auch außerhalb der offiziellen Modular-Quellen ergab die Recherche keinen überzeugenden, gepflegten Komplettbaustein, der ohne die hier geforderten Paritätstests übernommen werden sollte. + +Vor Übernahme muss geprüft werden: + +- welche Teile Quellcode, Bibliothek oder Laufzeitabhängigkeit werden sollen; +- ob Lizenz und Redistribution von Compiler, Runtime und Bibliotheken zum Distributionsmodell passen; +- welche konkrete Mojo/MAX-Version auf macOS und DGX Spark identisch reproduzierbar ist; +- ob die benötigten APIs stabil genug sind oder in einer kleinen projektnahen Kompatibilitätsschicht gekapselt werden müssen. + +## Zielarchitektur + +```text +Rust + Modell-/GGUF-Laden, DS4-Ablauflogik, Token, Sampling, + Session, Kontextzählung, Checkpoints, UI/CLI + | + schmale stabile ABI + | +Mojo + Tensor-/Gerätespeicher, Upload, Prefill, Decode, Verify, + Kernelplanung, Command-Buffer/Streams, Ereignisse + | + gemeinsame Algorithmen und Datenlayouts + / \ + Apple-Policy zur Compile-Zeit NVIDIA-Policy zur Compile-Zeit + Metal, Apple MMA, Split-KV CUDA, Tensor Cores, Warp-Pipeline +``` + +### Rust bleibt verantwortlich für + +- GGUF- und Metadateninterpretation; +- die exakte DS4-Modell- und Tokenablauflogik; +- Auswahl und Validierung des Modells; +- Sessions, Kontextgrenzen, Sampling und Ausgabe; +- das stabile Checkpointformat und seine Kompatibilität; +- Auswahl des Backends für Tests und Übergangsbetrieb; +- End-to-End-Telemetrie wie Prefill, Time-to-first-token und Decode-Token/s. + +### Mojo wird verantwortlich für + +- Gerätekontext, Speicherpools und Tensoransichten; +- Gewichtstransfer und gerätespezifische gepackte Gewichtsdarstellung; +- alle GPU-Operatoren und Fusionen; +- Prefill, einzelnen Decode-Schritt und gegebenenfalls MTP-/Speculative-Verify; +- KV-/Index-Cache im Gerätespeicher; +- Stream-/Command-Buffer-Lebenszyklus und geräteseitige Zeitmessung. + +### Grenze zwischen Rust und Mojo + +Die ABI muss klein und explizit bleiben. Als minimale Form werden nur diese Klassen von Aufrufen benötigt: + +- Runtime/Modell erstellen und zerstören; +- Gewichte beziehungsweise Weight-Shards laden; +- `prefill(...)`; +- `decode_step(...)`; +- optional `verify(...)` für MTP/speculative decode; +- Cache exportieren/importieren beziehungsweise Checkpointdaten übertragen; +- Telemetrie und Fehler abfragen. + +Der konkrete Exportmechanismus (`@export`, Shared Library oder der von der gepinnten Mojo-Version vorgesehene stabile Weg) wird in einem frühen Spike bewiesen. Ein Prozessaufruf pro Token ist ausgeschlossen. Die ABI ist nur eine Sprachgrenze; sie macht das Zielprodukt nicht zu einer C-Anwendung. + +### Bedeutung von „eine Mojo-Implementierung“ + +Erlaubt: + +- gemeinsame Modell-, Layer- und Operatorlogik; +- generische Layouts und Algorithmen; +- Compile-Time-Auswahl von Tile-Größe, Vektorbreite, MMA-Primitive, Thread-/Warp-Gruppierung und Launch-Strategie; +- einzelne architekturspezifische Mikro-Kernel, wenn sie durch dieselbe öffentliche Mojo-Funktion verborgen sind; +- separate Build-Artefakte für macOS/Metal und Linux/CUDA. + +Nicht erlaubt: + +- kopierte vollständige DeepSeek-, GLM- oder Qwen-Executoren für Metal und CUDA; +- Laufzeitverzweigungen in inneren Schleifen, die zur Compile-Zeit auflösbar wären; +- ein universelles „GPU Framework“ über Mojo/MAX hinaus; +- stiller Rückgriff auf den nativen Pfad, wenn ein Mojo-Operator fehlt; +- Änderungen an DS4-Modellsemantik, um einen vorhandenen MAX-Kernel passend zu machen. + +## Verbindliche Struktur des Mojo-Quellcodes + +Die Struktur trennt Laufzeit, wiederverwendbare Rechenoperationen, Modellkomposition und Hardware-Tuning. Sie soll beim ersten Modell bereits eingehalten werden, ohne für jede denkbare spätere Variante abstrakte Interfaces anzulegen. + +```text +mojo/ + src/ + api.mojo schmale, von Rust verwendete ABI + runtime/ + device.mojo DeviceContext, Capability-Erkennung + memory.mojo Buffer, Pool, Upload/Download + tensor.mojo TensorView, Formen, Strides, Layout-Metadaten + execution.mojo Streams/Command-Buffer, Events, Fehler + telemetry.mojo GPU-Zeit, Speicher- und Launch-Zähler + targets/ + apple.mojo Apple-MMA-, Tile- und Launch-Policies + nvidia.mojo NVIDIA-MMA-, Warp- und Launch-Policies + ops/ + embedding.mojo + quant.mojo Decode/Packing der unterstützten Q4-/Q8-Formate + linear.mojo Matmul und projizierende Fusionen + norm.mojo + activation.mojo + position.mojo RoPE und Positionshilfen + attention.mojo gemeinsame Full-/Flash-/MLA-Bausteine + cache.mojo KV-, Sparse- und Index-Cache-Primitiven + moe.mojo Router, Top-k, Experts + state/ + causal_conv1d.mojo + gated_delta.mojo wiederverwendbarer Gated-DeltaNet-Kern + recurrent_cache.mojo + models/ + deepseek/ + config.mojo + weights.mojo + layer.mojo + model.mojo + mtp.mojo nur wenn tatsächlich benötigt + glm/ + config.mojo + weights.mojo + layer.mojo + model.mojo + mtp.mojo + qwen3_8/ + config.mojo + weights.mojo + layer.mojo Hybridfolge aus GDN und Full Attention + state.mojo Conv-/Recurrent-State plus KV-Zustand + model.mojo + mtp.mojo + vision.mojo Encoder/Projektor, getrennt vom Textkern + tests/ Korrektheit, nach ops und models gespiegelt + bench/ isolierte Kernel-, Layer- und Modellmessungen +``` + +Die genaue Zahl kleiner Dateien darf sich an der tatsächlichen Implementierung orientieren. Entscheidend sind die Verantwortungsgrenzen, nicht ein Verzeichnis pro Funktion. + +### Abhängigkeitsrichtung + +```text +api -> models -> ops -> runtime/targets -> Mojo/MAX +``` + +- `runtime` kennt kein Modell. +- `targets` enthält keine DeepSeek-, GLM- oder Qwen-Semantik. +- `ops` kennt Formen und Layouts, aber keine vollständige Layerreihenfolge eines Modells. +- Ein Modell importiert kein anderes Modell. +- Gemeinsame Funktionalität wandert ausschließlich über `ops`, nicht über Cross-Imports zwischen Modellverzeichnissen. +- Tests und Benchmarks dürfen interne Module direkt importieren; die Rust-Anwendung sieht nur `api.mojo`. + +### Zuständigkeit der Schichten + +| Schicht | Besitzt | Besitzt ausdrücklich nicht | +| --- | --- | --- | +| `runtime` | Geräte- und Speicherlebenszyklus, Tensoransichten, Ausführung, Fehler, Telemetrie | Modellgraph, Quantformatlogik, Attention-Semantik | +| `targets` | zur Compile-Zeit gewählte Hardwareparameter und Intrinsics | vollständige Operator- oder Modellkopien | +| `ops` | semantisch klar benannte, modellübergreifend nutzbare Operatoren und Fusionen | Modellreihenfolge, GGUF-Parsing, Sessions | +| `models/` | Configvalidierung, Tensorbindung, Layerkomposition und modellspezifische Fusionen | eigene Geräteverwaltung oder kopierte allgemeine Matmuls | +| `api.mojo` | stabile grobe Rust-Aufrufe und Modellhandle-Dispatch | einzelne Kernelaufrufe im Tokenschritt | + +### Regeln für Wiederverwendung + +1. Ein allgemeiner Operator erhält eine fachliche Schnittstelle mit Formen, Layout und Compile-Time-Policy; ein Modell reicht nur seine Parameter ein. +2. Ein Modell darf eine Fusion zunächst lokal besitzen. Erst wenn ein zweites Modell dieselbe Semantik benötigt, wird sie nach `ops` verschoben. Ähnliche, aber numerisch unterschiedliche Fusionen werden nicht künstlich vereinheitlicht. +3. Quant-Decoding und Weight-Packing liegen zentral in `ops/quant.mojo`. Modellcode darf Quantformate auswählen, aber nicht erneut implementieren. +4. KV-Cache und GDN-Recurrent-State bleiben unterschiedliche Zustandstypen. Ein gemeinsamer Speicherpool ist erlaubt; ein künstlicher Universalcache ist es nicht. +5. Zielabhängige Parameter werden als Compile-Time-Werte übergeben. Keine `if metal`-/`if cuda`-Verzweigung innerhalb des Tokenpfads. +6. Der Rust-seitige Modellloader übergibt eine validierte Tensorbeschreibung. Mojo parst GGUF nicht ein zweites Mal. +7. Die einzige modellübergreifende Ausführungsform umfasst Load, Prefill, Decode, optional Verify und State-Import/-Export. Ein allgemeiner Graph-IR ist nicht vorgesehen. + +### Review-Gates für die Struktur + +- Neue Dateien unter `models/` müssen begründen, warum vorhandene `ops` nicht passen. +- Änderungen unter `targets` müssen auf eine gemessene Hardwaredifferenz zurückgehen. +- Ein neuer gemeinsamer Operator braucht mindestens zwei reale Verbraucher oder muss bereits für den ersten vertikalen Schnitt zwingend sein. +- Jeder öffentliche Operator besitzt genau einen Korrektheitstest und einen repräsentativen Benchmarkeintrag; zusätzliche Fälle werden datengetrieben im selben Harness abgebildet. +- Die Coverage-Liste ordnet jeden nativen GPU-Aufruf einem Mojo-Operator oder einer ausdrücklich dokumentierten entfallenen Materialisierung zu. + +## Qwen3.8-27B als zweite Modellstufe + +Mit „Qwen3.8-27B“ ist das offizielle Modell `Qwen/Qwen3.8-27B` gemeint. Laut offizieller Modellkarte besitzt der Sprachkern: + +- 27 Milliarden Parameter, Hidden Size 5.120 und 64 Layer; +- 16 Wiederholungen aus drei `Gated DeltaNet -> FFN`-Layern und einem `Gated Attention -> FFN`-Layer; +- 48 Value- und 16 Q/K-Heads mit Head-Dimension 128 im Gated DeltaNet; +- 24 Q- und 4 KV-Heads mit Head-Dimension 256 und RoPE-Dimension 64 in voller Attention; +- FFN-Zwischendimension 17.408; +- MTP-Unterstützung; +- 262.144 Token nativen Kontext, mit vom Hersteller genannter Erweiterbarkeit bis eine Million; +- einen Vision-Encoder für Bild- und Videoeingaben. + +Qwen3.8 baut architektonisch auf Qwen3.5 auf. Die bereits vorhandenen MAX-GDN-Kernel sind deshalb ein konkreter Wiederverwendungskandidat: [`gated_delta.mojo`](https://github.com/modular/modular/blob/main/max/kernels/src/state_space/gated_delta.mojo), [`gated_delta_conv1d.mojo`](https://github.com/modular/modular/blob/main/max/kernels/src/state_space/gated_delta_conv1d.mojo) und der slot-basierte Recurrent-State-Cache existieren bereits. Der derzeit dokumentierte MAX-Pfad verwendet jedoch eine sequenzielle zweipassige Rekurrenz statt eines WY-/chunk-parallelen Prefill-Kernels. Das kann für Decode passend und für langen Prefill zu langsam sein. Übernahme erfolgt daher nicht ungeprüft. + +### Geplanter Qwen-Umfang + +Die Qwen-Stufe wird intern in zwei Freigaben geteilt: + +1. Textkern: GGUF-Laden in Rust, Q4- und Q8-Gewichte, Embedding, hybride GDN-/Attention-Layer, FFN, LM-Head, KV-/Recurrent-State, Text-Prefill/Decode, Checkpoint und anschließend MTP. +2. Multimodal: Bild-/Videovorverarbeitung in Rust, Vision-Encoder und Projektor in Mojo sowie Einbettung der visuellen Token in denselben Textkern. + +Der Textkern ist die Pflichtabnahme der zweiten Modellstufe. DS4Server darf Qwen3.8-27B erst dann als vollständig multimodal unterstützt ausweisen, wenn auch der zweite Teil seine Korrektheits- und Performancegates bestanden hat. + +### Q4-/Q8-Ziel + +- Q4 ist der primäre lokale Performance- und Speichereffizienzpfad. Als erstes konkretes GGUF-Ziel wird `Q4_K_M` oder das tatsächlich vom gepinnten Qwen-Konverter erzeugte äquivalente K-Quantlayout festgelegt. +- Q8 ist Pflicht als höherpräziser Vergleichs- und Betriebspfad; bevorzugtes GGUF-Ziel ist `Q8_0`, sofern das gepinnte Artefakt dies verwendet. +- Beide Formate werden im gemeinsamen `ops/quant.mojo` implementiert und von DeepSeek, GLM und Qwen wiederverwendet, wenn Byte-Layout und Semantik identisch sind. +- Das offizielle Qwen-Artefakt wird derzeit als Transformers/Safetensors beziehungsweise FP8 angeboten. Für GGUF muss deshalb ein konkreter Konvertercommit, das Ausgangsmodell, das erzeugte Artefakt und dessen SHA-256 gepinnt werden. Ein beliebiges Community-GGUF ohne Provenienz ist keine Referenz. +- Q8 wird nur dort als Performancepfad gewertet, wo Gewichte, Laufzeitzustand und der geprüfte Kontext ohne Swap oder unkontrolliertes Streaming vollständig in den verfügbaren Speicher passen. Andernfalls bleibt Q8 auf dieser Maschine ein kleinerer Korrektheitstest; die vollständige Q8-Performanceabnahme läuft auf geeigneter Hardware. +- Die offizielle FP8-Variante kann später als NVIDIA-spezifische Erweiterung untersucht werden. Sie ersetzt nicht die gemeinsamen Q4-/Q8-Gates und darf die Quellstruktur nicht in einen separaten Qwen-CUDA-Executor aufspalten. + +### Qwen-spezifische neue Komponenten + +| Komponente | Ort | Wiederverwendung beziehungsweise Abgrenzung | +| --- | --- | --- | +| Causal depthwise Conv1D | `ops/state/causal_conv1d.mojo` | Aus MAX evaluieren; für weitere GDN-Modelle wiederverwendbar. | +| Gated-Delta-Rekurrenz | `ops/state/gated_delta.mojo` | Gemeinsamer GDN-Kern; getrennte Prefill- und Decode-Tuningpfade hinter derselben Semantik erlaubt. | +| Recurrent-State-Cache | `ops/state/recurrent_cache.mojo` | Slot-/Sequenzzustand; nicht mit KV-Cache semantisch vermischen. | +| Hybrid-Layerplan | `models/qwen3_8/layer.mojo` | Qwen-spezifische Reihenfolge, komponiert gemeinsame GDN-, Attention-, Norm- und FFN-Operatoren. | +| Qwen-State | `models/qwen3_8/state.mojo` | Bündelt GDN-Conv-/Recurrent-State und KV-Cache für Full-Attention-Layer; besitzt Checkpointmapping. | +| MTP | `models/qwen3_8/mtp.mojo` plus gemeinsame Verify-Abläufe | Modellgewichte/-köpfe bleiben Qwen-spezifisch, Scheduling und Verifikation werden geteilt. | +| Vision | zunächst `models/qwen3_8/vision.mojo` | Erst nach einem zweiten identischen Verbraucher nach `ops/vision` verschieben. | + +Für Qwen ist ein eigener nativer A/B-Referenzpfad nötig. Ein gepinnter Qwen3.8-fähiger llama.cpp-Metal-/CUDA-Stand mit demselben erzeugten GGUF ist ein geeigneter Übergangskandidat. Er bleibt reines Testorakel und wird nicht Bestandteil der Zielarchitektur. Auf CUDA kann zusätzlich die offizielle Safetensors-/FP8-Ausführung als Diagnose dienen, ist wegen des anderen Gewichtsformats aber kein direkter Token/s-Paritätsmaßstab für Q4/Q8. + +DS4 bleibt das Orakel für alle bereits von DS4 definierten Abläufe. Da Qwen3.8-27B kein bestehender DS4-Pfad ist, bilden für dieses Modell die offizielle Modellkonfiguration und ein gepinnter, mit dem identischen GGUF laufender Referenzexecutor gemeinsam das Verhaltensorakel. Abweichungen müssen auf Operator- und Tokenebene aufgeklärt werden; der bequemere Pfad gewinnt nicht automatisch. + +Ein aktueller [llama.cpp-Fehlerbericht zu Qwen3.8-27B](https://github.com/ggml-org/llama.cpp/issues/27623) meldet einen starken Decode-Einbruch jenseits ungefähr 80K Kontext, während Prefill schnell bleibt. Das ist kein Beweis für Mojo-Verhalten, aber ein wichtiger Risikohinweis: Qwen-Benchmarks müssen mindestens die Positionen 64K, 80K, 96K, 128K und 262K getrennt prüfen, sofern der Speicher reicht. Ein guter Nullkontextwert genügt nicht. + +## Übergang mit zwei Referenzpfaden + +Während der Migration muss die Backendauswahl explizit und für Testläufe reproduzierbar sein: + +```text +native-metal bestehender Referenzpfad auf dem Mac +native-cuda gepinnter nativer Referenzpfad auf DGX Spark +mojo gemeinsame Mojo-Quelle, für das aktuelle Ziel gebaut +``` + +Die Auswahl soll über einen internen CLI-/Testparameter oder eine Testumgebungsvariable erfolgen, nicht als neue dauerhaft sichtbare Benutzereinstellung. Jeder Lauf schreibt Backend, Commit, Mojo/MAX-Version, Compilerflags, Modellhash und Hardware in das Ergebnis. + +Der aktuelle Rust-Code besitzt noch keinen gleichwertigen nativen CUDA-Pfad. Vor einer Aussage „Mojo ist so schnell wie CUDA“ muss deshalb eine der folgenden Referenzformen festgelegt werden: + +1. bevorzugt: ein vorübergehend in DS4Server auswählbarer, gepinnter nativer CUDA-Referenzadapter; +2. minimal: ein gepinnter DS4-CUDA-Orakellauf mit exakt demselben Modell, denselben Prompt-Token und demselben Messprotokoll, aufgerufen durch den gemeinsamen Benchmark-Harness. + +Die zweite Variante reicht für einen Go/No-Go-Leistungsvergleich, ist aber weniger stark als ein A/B-Test innerhalb derselben Anwendung. Spätestens für die finale Freigabe muss der native CUDA-Referenzlauf automatisiert und zusammen mit dem Mojo-Lauf aus demselben Manifest reproduzierbar sein. Die native Referenz ist Übergangsinfrastruktur und darf nicht die zukünftige Produktarchitektur bestimmen. + +## Verifikationsstrategie + +### 1. Vollständiges Operationsinventar + +Vor dem ersten Port wird aus `src/engine/metal/gpu.rs`, `src/engine/metal.rs` und den Modell-Executoren eine Coverage-Liste erzeugt. Jeder heute erreichbare GPU-Aufruf erhält genau einen Eintrag mit: + +- aufrufendem Modell und Phase: Load, Prefill, Decode, Verify oder Checkpoint; +- Datentyp, Quantformat und relevante Tensorformen; +- Metal-Referenzbenchmark; +- CUDA-Referenzbenchmark, sofern der Pfad dort verwendet wird; +- Mojo-Korrektheitstest; +- Mojo-Metal- und Mojo-CUDA-Benchmark; +- Status und begründete Ausnahme. + +Diese Liste ist das Lösch-Gate für den nativen Code. Ein Operator ohne Abdeckung darf nicht aufgrund eines grünen Gesamtbenchmarks übergangen werden. + +Die anfänglichen Gruppen sind: + +1. Tensorallokation, Views, Upload/Download, Kopie und Speicherpool; +2. Command-Begin/End, Flush, Events und Synchronisation; +3. Embeddings; +4. RMSNorm, Elementwise, Add und SwiGLU; +5. F16-, F32-, Q8- und quantisierte Matmul-Varianten einschließlich Paired/Fused-Matmul; +6. DeepSeek HC, QKV, RoPE und KV-Kompression/-Store; +7. rohe, komprimierte und indexierte Attention in Prefill und Decode; +8. Router, Top-k, routed MoE und Shared Expert; +9. GLM-RoPE, Compact-KV, Indexer, Sparse/Indexed Attention und GLM-MoE; +10. SSD-/Expert-Streaming; +11. Sampling- oder Logit-Nachverarbeitung, soweit sie tatsächlich auf der GPU liegt; +12. MTP/speculative decode und Steering, sofern für das getestete Modell aktiv; +13. Qwen-GDN: depthwise Conv1D, Gate/Decay, Delta-Rekurrenz, Recurrent-State-Update und Hybridwechsel zur Full Attention; +14. Qwen-Visionencoder und Projektor, sobald der Multimodalteil umgesetzt wird. + +### 2. Reproduzierbare Testdaten + +Mikrobenchmarks dürfen nicht nur zufällige kleine Matrizen messen. Für jede Gruppe werden repräsentative reale Formen aus den unterstützten Modellen erfasst: + +- Batch 1 Decode mit kurzen und langen KV-Caches; +- Prefill mit mindestens 1, 128, 512, 2.048 und 8.192 Token, soweit das Modell dies unterstützt; +- Kontextgrenzen, an denen Indexer, Sparse Attention oder Cache-Layout wechseln; +- für Qwen3.8 zusätzlich Decode an 64K, 80K, 96K, 128K und 262K Position, soweit speicherseitig möglich; +- alle tatsächlich vorkommenden Quantformate und Expert-Layouts; +- Qwen-Q4 und Qwen-Q8 mit getrennten Fixture- und Ergebnisreihen; +- residenter und SSD-gestreamter Expertpfad, sofern beide unterstützt werden. + +Große Modellgewichte werden nicht ins Repository kopiert. Ein Fixture-Manifest hält Modell-ID, Datei-SHA-256, Tensorname, Bytebereich, Form, Strides, Quantformat und Generatorversion fest. Der Benchmark liest das vorhandene Modell oder erzeugt kleine deterministische Ausschnitte. Damit vergleichen beide Backends identische Bytes. + +### 3. Messprotokoll + +Jeder Performancevergleich folgt demselben Protokoll: + +- Release-Builds und identische fachliche Optionen; +- fester Modellhash, feste Prompt-Token und greedy decode; +- EOS für eine feste Anzahl erzeugter Token ignorieren; +- Kompilierung/JIT, Modellladen und erster Upload separat von Steady State messen; +- Warm-up vor den Messungen; +- A/B/B/A- oder B/A/A/B-Reihenfolge, um thermische und zeitliche Drift zu reduzieren; +- gleiche Power-, Thermal- und Hintergrundlastbedingungen; +- mindestens Median, p95, Streuung und gepaarte Konfidenzintervalle aus mehreren Läufen; +- GPU-Ereigniszeit für isolierte Kernel und Rust-Wallclock für Layer und End-to-End; +- Peak-/Resident-GPU-Speicher, Transferbytes und Kernel-/Command-Buffer-Anzahl; +- Rohdaten als maschinenlesbares JSON oder CSV; zusammenfassender Markdown-Bericht wird daraus erzeugt. + +Prefill, erster Decode-Token und stabiler Decode werden getrennt ausgewiesen. Eine einzelne gemischte Token/s-Zahl ist kein ausreichender Nachweis. + +### 4. Performance-Gates + +Für jede Hardware wird nur gegen den nativen Pfad derselben Hardware verglichen: + +```text +Metal: Mojo-Metal / Native-Metal +CUDA: Mojo-CUDA / Native-CUDA +``` + +Verbindliches Produktziel: + +- Median der kritischen isolierten Operationen: Verhältnis mindestens 1,00; +- Median von Prefill und stabilem Decode des vollständigen Modells: Verhältnis mindestens 1,00; +- p95-Latenz: keine reproduzierbare Verschlechterung; +- Peak-GPU-Speicher: nicht höher als die native Referenz, sofern eine Erhöhung nicht ausdrücklich begründet und freigegeben wird; +- kein zusätzlicher Host/GPU-Transfer im Tokenpfad. + +Da Messungen rauschen, gilt für die automatische Freigabe zusätzlich: Punktschätzer mindestens 1,00 und untere Grenze des gepaarten 95-%-Konfidenzintervalls mindestens 0,97. Die drei Prozent sind ausschließlich ein Unsicherheitsband, kein erlaubtes Performancebudget. Ein stabil reproduzierbarer Rückstand, auch innerhalb dieses Bands, bleibt ein Fehler und muss untersucht werden. + +Ein einzelner nicht kritischer Mikro-Kernel darf nur dann langsamer sein, wenn das Profil beweist, dass er nicht auf dem relevanten kritischen Pfad liegt und Layer- sowie Modellgate trotzdem bestehen. Jede solche Ausnahme wird mit Messdaten dokumentiert. Modellladen und Cold Start erhalten eigene Zahlen und dürfen nicht in Steady-State-Token/s versteckt werden. + +### 5. Korrektheits-Gates + +- Tensorformen, Strides, Quant-Decoding, Expertindizes, Cachepositionen und Kontextzähler müssen exakt übereinstimmen. +- Für Floating-Point-Zwischenergebnisse werden pro Operator aus der nativen Präzision abgeleitete `atol`/`rtol`-Grenzen festgelegt; eine globale großzügige Toleranz ist nicht zulässig. +- Argmax, gesampelte Token bei identischem RNG-Zustand und die vollständige greedy Tokenfolge müssen identisch sein. +- Logitfehler dürfen weder Rangfolge der entscheidenden Kandidaten noch spätere Token verändern. +- Prefill-plus-Decode und reiner inkrementeller Decode müssen denselben Zustand erzeugen. +- Checkpoints beider Pfade werden gegenseitig geladen, sofern das Checkpointformat backendneutral bleiben soll. +- NaN, Inf, Out-of-bounds, stiller Precision-Downgrade oder Backend-Fallback sind harte Fehler. + +## Teststufen + +### Stufe A: Mojo-Primitiven + +Kleine deterministische Tests für Layouts, Quant-Decoding, MMA-Tiles, Reduktionen, Masken, RoPE und Cache-Adressierung. Sie laufen pro Zielplattform und prüfen zunächst gegen eine einfache CPU-/Rust-Referenz oder gespeicherte native Ergebnisse. + +### Stufe B: Isolierte verwendete GPU-Operationen + +Jeder Eintrag des Operationsinventars wird mit echten Formen und Quantdaten gegen Native-Metal beziehungsweise Native-CUDA geprüft und gemessen. Erst Korrektheit, dann Performance. + +### Stufe C: Fusion, Layer und Cache + +Verglichen werden vollständige Attention-, MoE- und Transformer-Layer sowie Cacheübergänge. Diese Stufe erkennt Fälle, in denen einzelne schnelle Kernel durch zusätzliche Launches, Materialisierung oder Synchronisation insgesamt langsamer werden. + +### Stufe D: Executor und Session + +Ausgehend vom vorhandenen Realmodelltest wird derselbe Test backendparametrisiert: + +- Modell laden; +- festen Prompt prefillen; +- Logits und Argmax prüfen; +- mehrere Tokens dekodieren; +- Checkpoint erzeugen und wiederherstellen; +- nach Restore identisch weiterdekodieren; +- Kontextzählung und KV-/Index-Cachezustand vergleichen. + +### Stufe E: Vollständiger Modell-A/B-Test + +Der finale Test verwendet auf einer Maschine nacheinander beide dort verfügbaren Pfade: + +1. identische GGUF-Datei und SHA-256; +2. identische bereits tokenisierte Eingabe; +3. greedy decode, fester RNG-Zustand, mindestens 128 erzeugte Token, EOS überspringen; +4. Logits beziehungsweise entscheidende Top-k-Werte und Token nach jedem Schritt vergleichen; +5. Prefill, Time-to-first-token, stabilen Decode, Peak-Speicher und Transfers messen; +6. Reihenfolge über Wiederholungen wechseln; +7. Rohdaten und Systemmetadaten dauerhaft speichern. + +Pflichtmatrix: + +| Hardware | Referenz | Kandidat | Modelle/Funktionen | +| --- | --- | --- | --- | +| Apple-GPU, zunächst die aktuelle M5-Entwicklungsmaschine | Native Metal | Mojo-Metal | primäres DeepSeek-Flash-Modell; danach weitere unterstützte Flash-/Pro-Varianten; kurze und lange Kontexte; Checkpoint | +| DGX Spark | Native CUDA | Mojo-CUDA | dieselben Modellartefakte, soweit unterstützt; resident und Streaming; kurze und lange Kontexte | +| beide Plattformen | jeweiliger nativer Pfad | Mojo | GLM 5.2 einschließlich Compact-/Sparse-KV und Indexer; MTP zunächst aus, danach separat an | +| beide Plattformen | gepinnter Qwen3.8-fähiger nativer Metal-/CUDA-Pfad | Mojo | Qwen3.8-27B Q4 und Q8; GDN-/Attention-Hybrid; kurzer und langer Kontext; Text zuerst, danach MTP und Vision | + +MTP/speculative decode, Steering und SSD-Streaming werden zunächst deaktiviert, um den Basispfad zu beweisen. Danach erhält jede Funktion eine eigene A/B-Matrix; sie wird nicht durch einen guten Baselinewert implizit freigegeben. + +## Umsetzung in Phasen + +### Phase 0: Baselines und Toolchain fixieren + +Ergebnisse: + +- Mojo/MAX-Version, Modular-Quellcommit, Rust-Toolchain und Zielcompiler pinnen; +- Lizenz-/Redistributionsprüfung dokumentieren; +- aktuelle Metal-Baseline mit Rohdaten erstellen; +- auf DGX Spark einen gepinnten nativen CUDA-Referenzlauf herstellen; +- Modell-, Prompt-, Hardware- und Messmanifeste festlegen; +- vollständiges Operationsinventar erzeugen. + +Gate: Baselines sind wiederholbar; die Lauf-zu-Lauf-Streuung ist klein genug, um einen realen Performanceverlust zu erkennen. Ohne CUDA-Referenz keine CUDA-Paritätsaussage. + +### Phase 1: Backendauswahl und gemeinsamer Harness + +Ergebnisse: + +- expliziter interner Backendselektor; +- derselbe Korrektheits- und Benchmark-Harness kann Native Metal, Native CUDA und später Mojo ansteuern; +- keine Änderung am Standardpfad und keine Änderung des DS4-Verhaltens; +- Ergebnisformat enthält alle Reproduktionsdaten. + +Gate: Native-Metal-Läufe vor und nach Einführung des Selektors sind statistisch identisch. Der Harness selbst verfälscht die Messung nicht. + +### Phase 2: Mojo-Integrationsspike + +Nur der kleinste vertikale technische Nachweis: + +- Rust lädt eine Mojo-Bibliothek und behandelt Fehler sauber; +- Mojo erkennt Metal beziehungsweise CUDA; +- ein repräsentativer Tensortransfer und ein MMA-/Matmul-Kernel laufen; +- Speicher bleibt über mehrere Decode-Schritte resident; +- GPU- und Wallclock-Messung funktionieren auf beiden Plattformen. + +Gate: Kein Prozess-pro-Token, keine Synchronisation pro elementarem Operator und kein ungeklärter ABI-/Packaging-Blocker. + +### Phase 3: Risikofrüher vertikaler Schnitt + +Nicht zuerst alle einfachen Elementwise-Kernel portieren. Stattdessen wird ein vollständiger repräsentativer quantisierter Routed-MoE-Layer mit Attention-/KV-Anteil für Prefill und Decode auf beiden Plattformen umgesetzt. Er muss mindestens eines der schwierigsten tatsächlich verwendeten Quantformate und echte Modellformen enthalten. + +Gate: + +- identische fachliche Ergebnisse; +- Mojo-Metal erreicht Native-Metal-Parität; +- Mojo-CUDA erreicht Native-CUDA-Parität; +- kein unvertretbarer Speicher- oder Transferzuwachs. + +Wenn dieses Gate trotz Profiling, Fusion und architekturspezifischer Policies nicht erreichbar ist, wird der Gesamtport gestoppt und neu bewertet. Das verhindert, dass erst nach einer vollständigen Übersetzung sichtbar wird, dass der zentrale Quant-/MoE-Pfad das Performanceziel verfehlt. + +### Phase 4: Vollständiger DeepSeek-Basispfad + +Ergebnisse: + +- Load, Prefill und Decode für das primäre DeepSeek-Modell; +- alle benötigten residenten Gewichte, Attention-, KV-, Router- und Expertpfade; +- jedes verwendete Mojo-Element ist im Operationsinventar abgedeckt; +- Native Metal und Mojo bleiben auswählbar; CUDA-Referenz und Mojo-CUDA bleiben vergleichbar. + +Gate: Stufen A bis E bestehen für Baseline-Inferenz ohne optionale Beschleuniger. + +### Phase 5: Zweite Modellstufe Qwen3.8-27B Textkern + +Die zuvor definierte Mojo-Struktur wird nun durch ein architektonisch anderes Modell validiert. Gemeinsame DeepSeek-Komponenten werden nicht kopiert, sondern über `ops` verwendet. Neu entstehen nur GDN-/Recurrent-State-Komponenten und die Qwen-spezifische Hybridkomposition. + +Ergebnisse: + +- reproduzierbar aus dem offiziellen Ausgangsmodell erzeugte und gehashte Q4- und Q8-GGUF-Artefakte; +- gepinnter nativer Qwen-Metal-/CUDA-Referenzlauf mit denselben Artefakten; +- Text-Prefill und Decode für Q4 und Q8; +- drei GDN-Layer plus ein Full-Attention-Layer als isoliert verifizierter Hybridblock; +- getrennter GDN-Recurrent-State und KV-Cache mit gemeinsamem Checkpointmapping; +- wiederverwendete Embedding-, Norm-, Quant-Matmul-, FFN-, RoPE-, Attention- und LM-Head-Operatoren; +- identische Texttoken gegenüber dem Qwen-Referenzpfad. + +Gate: + +- Q4 besteht Korrektheits- und Performanceparität auf Metal und CUDA; +- Q8 besteht dieselben Gates auf jeder Maschine, auf der das vollständige Arbeitset resident passt; +- GDN-Prefill, GDN-Decode, Full Attention und der vollständige Hybridblock bestehen jeweils isoliert; +- kein Modellcode dupliziert Quant-, Matmul-, Norm- oder Cacheoperatoren; +- kurzer Kontext und die 64K-/80K-/96K-/128K-/262K-Positionen zeigen keinen ungeklärten Leistungseinbruch. + +Diese Phase ist die vom Benutzer gewünschte zweite Stufe nach der ersten verifizierten DeepSeek-Implementierung. + +### Phase 6: Qwen3.8 MTP und Multimodal + +Nacheinander, mit getrennten Messreihen: + +1. Qwen-MTP und Verify; +2. Bildvorverarbeitung und visuelle Tokenisierung in Rust; +3. Vision-Encoder und Projektor in Mojo; +4. kombinierter Bild-/Text-Prefill; +5. Videoeingabe nur, wenn der bestehende DS4Server-Produktumfang sie aufnehmen soll. + +Gate: Textperformance bleibt unverändert, wenn kein visuelles Eingabesignal vorliegt. Multimodale Referenzausgaben, Speicherverbrauch und Prefillleistung bestehen separat. Erst dann gilt das Modell als vollständig multimodal unterstützt. + +### Phase 7: Langkontext und optionale DeepSeek-Pfade + +Nacheinander, jeweils mit eigenem Gate: + +1. komprimierte/indexierte und Sparse Attention; +2. lange Kontexte und Cachegrenzen; +3. SSD-/Expert-Streaming; +4. Checkpoint-Cross-Load; +5. Steering; +6. MTP/speculative decode. + +Kein Punkt wird zusammen mit einem anderen eingeführt, wenn dadurch ein Performanceverlust nicht mehr eindeutig zuordenbar wäre. + +### Phase 8: GLM 5.2 + +Zuerst werden die MAX-26.5-GLM-Quellen und ihre Sparse-MLA-/Indexer-Kernel gegen DS4s GLM-Semantik abgeglichen. Passende Mojo-Bausteine werden wiederverwendet; nur die Differenzen werden projektspezifisch implementiert. + +Gate: Compact-KV, Indexer, Sparse Attention, Router/MoE, MTP und Checkpoints bestehen jeweils isoliert und anschließend im vollständigen Modell. + +### Phase 9: Finale Plattformmatrix + +- frische Builds aus demselben Commit; +- Mac: Native Metal gegen Mojo-Metal; +- DGX Spark: Native CUDA gegen Mojo-CUDA; +- alle unterstützten DeepSeek-, Qwen3.8- und GLM-Modelle und aktivierbaren Inferenzmodi; +- Qwen3.8-27B in Q4 und Q8, soweit das jeweilige Arbeitset resident passt; +- mindestens drei unabhängige Messserien pro Kombination; +- vollständiger Korrektheits-, Performance-, Speicher- und Cold-Start-Bericht. + +Gate: Alle Pflichtverhältnisse, DS4-Verhaltensprüfungen und Qwen-Referenzprüfungen bestehen. Ungeklärte Ausnahmen verhindern die Freigabe. + +### Phase 10: Umschalten und späteres Entfernen + +Mojo wird zunächst opt-in, dann nach bestandener Matrix Standard. Native Pfade bleiben für mindestens einen definierten Validierungszeitraum als explizite Diagnoseoption erhalten. Entfernt werden sie erst, wenn: + +- das Operationsinventar vollständig geschlossen ist; +- CI beziehungsweise Hardware-CI beide Mojo-Ziele regelmäßig prüft; +- keine offenen Korrektheits- oder Performanceabweichungen bestehen; +- Rollback-Artefakte und Baselineberichte vorhanden sind; +- der Benutzer die Entfernung ausdrücklich freigibt. + +## Minimale geplante Artefakte + +Die Implementierung soll keine große neue Abstraktionshierarchie erzeugen. Voraussichtlich genügen: + +- ein kleiner Rust-Backendselektor an der bestehenden Executorgrenze; +- ein Mojo-Quellbaum mit gemeinsamen Modell-/Operatorfunktionen und kleinen Architektur-Policies; +- ein gemeinsamer A/B-Harness; +- ein Operations-/Fixture-Manifest; +- maschinenlesbare Benchmarkresultate und daraus erzeugte Berichte. + +Die oben definierte Top-Level-Struktur ist verbindlich; einzelne Dateien dürfen zusammengelegt werden, wenn sie sonst nur Weiterleitungen enthalten. Der genaue ABI-Export wird festgelegt, nachdem der Mechanismus in Phase 2 funktioniert. Es wird keine Factory-, Plugin- oder allgemeine Accelerator-Schicht auf Vorrat gebaut. + +## Hauptrisiken und notwendige Kompromisse + +### 1. Gemeinsame Quelle bedeutet nicht identischen Maschinenpfad + +Für volle Performance muss ein gemeinsamer Algorithmus unterschiedliche MMA-, Tile-, Speicher- und Launch-Policies zulassen. Der Kompromiss ist etwas zielabhängiger Mojo-Code auf Mikro-Kernel-Ebene. Ohne diesen Kompromiss ist Parität mit handoptimiertem Metal und CUDA unwahrscheinlich. + +### 2. MAX-Bausteine sind Kandidaten, keine automatische Paritätsgarantie + +Ein vorhandener Flash-Attention- oder MoE-Kernel kann ein anderes Layout, eine andere Quantisierung oder andere Cache-Semantik erwarten. Übernahme spart nur dann Arbeit, wenn Adapter und Materialisierungen den Gewinn nicht wieder vernichten. Jeder Baustein durchläuft daher dasselbe isolierte Gate. + +### 3. Quantisierung ist das größte Portierungsrisiko + +Die Kombination aus IQ2_XXS, K-Quantformaten, Q8 und fusionierten Expertpfaden ist in den geprüften Mojo-Paketen nicht vollständig GPU-fertig vorhanden. Hier ist mit dem meisten eigenen Kernel- und Tuningaufwand zu rechnen. + +### 4. Qwen-GDN benötigt getrenntes Prefill- und Decode-Tuning + +Der vorhandene MAX-GDN-Pfad ist ein wertvoller Startpunkt, seine sequenzielle Rekurrenz ist aber keine Garantie für konkurrenzfähigen langen Prefill. Wahrscheinlich bleibt die Semantik gemeinsam, während Prefill einen chunk-/WY-parallelen Pfad und Decode einen spezialisierten Single-Step-Pfad erhält. Diese Spezialisierung gehört in `ops/state/gated_delta.mojo`, nicht in getrennte Metal-/CUDA-Modelle. + +### 5. Toolchain- und API-Reife + +Mojo/MAX entwickelt sich schnell. Reproduzierbarkeit verlangt einen exakten Pin, lokale Artefakt-Caches und eine bewusste Upgrade-Politik. Ein Upgrade wird wie eine Performanceänderung behandelt und muss die relevante Matrix erneut bestehen. + +### 6. Hardwarezugang ist Teil der Definition of Done + +CUDA-Performance kann nicht auf dem Mac simuliert und Metal-Performance nicht aus CUDA-Ergebnissen abgeleitet werden. Jede relevante Phase braucht reale Apple- und DGX-Spark-Läufe. Ohne beide Systeme bleibt die Phase unvollständig. + +### 7. Keine Vorabgarantie von Token/s + +Quellvereinheitlichung ist technisch plausibel; Performanceparität ist eine empirische Eigenschaft. Der Plan reduziert dieses Risiko durch den schwierigen vertikalen Schnitt in Phase 3. Scheitert er, bleiben die nativen Pfade erhalten und es wurde noch nicht die gesamte Engine portiert. + +## Definition of Done + +Der Umbau ist erst abgeschlossen, wenn alle folgenden Aussagen belegt sind: + +- Rust besitzt weiterhin die DS4-Verhaltenslogik, Mojo besitzt die GPU-Inferenz. +- DeepSeek, Qwen3.8 und GLM verwenden dieselbe Mojo-Modell-/Operatorbasis auf Metal und CUDA. +- Der Mojo-Quellbaum hält die Abhängigkeitsrichtung `api -> models -> ops -> runtime/targets` ein; Modelle teilen Code nur über klar benannte Operatoren. +- Zielabhängiger Code ist auf klar begrenzte Compile-Time-Policies und Mikro-Kernel beschränkt. +- Jeder produktiv verwendete Inferenzoperator ist in der Coverage-Liste korrektheits- und performancegeprüft. +- Vollständige Modellläufe erzeugen backendübergreifend dieselben Token und denselben beobachtbaren DS4-Zustand. +- Mojo-Metal ist auf derselben Apple-Hardware nicht langsamer als Native Metal. +- Mojo-CUDA ist auf derselben DGX-Spark-Hardware nicht langsamer als Native CUDA. +- Qwen3.8-27B läuft lokal in Q4 und Q8; Q4 ist auf beiden Zielplattformen vollständig performanceverifiziert, Q8 auf jeder ausreichend großen Zielmaschine. +- Qwen-GDN, Full Attention, Recurrent-State, KV-Cache und Hybridwechsel sind isoliert sowie im vollständigen Modell geprüft. +- Prefill, erster Token, stabiler Decode, lange Kontexte, Speicher, Checkpoints, Streaming, Steering und MTP sind getrennt verifiziert, soweit sie unterstützt werden. +- Es gibt keine stillen Fallbacks, keine gemischten Benchmarkpfade und keine ungeklärten Performanceausnahmen. +- Build, Tests und Benchmarkberichte sind aus gepinnten Toolchains und Manifesten reproduzierbar. + +## Unmittelbar erster Implementierungsschritt + +Der nächste Agent soll nicht mit einer breiten Portierung beginnen. Er soll Phase 0 und Phase 1 abschließen und danach in Phase 2 den kleinsten Rust-Mojo-GPU-Spike bauen. Erst wenn auf Mac und DGX Spark dieselbe Mojo-Quelle einen residenten Matmul-Pfad über die schmale ABI ausführt und messbar ist, beginnt der schwierige quantisierte vertikale Schnitt aus Phase 3. + +Das ist der früheste Punkt, an dem belastbar entschieden werden kann, ob die angestrebte Quellvereinheitlichung ohne Performanceverlust für diese konkrete Engine erreichbar ist.